@@ -126,9 +126,9 @@ elapsed time in the summary line.
126
126
127
127
The rule for a match in the cache is that the run involves the same
128
128
test binary and the flags on the command line come entirely from a
129
- restricted set of 'cacheable' test flags, defined as -benchtime, -cover,
130
- -covermode , -coverprofile , -cpu, -list, -parallel, -run, -short, -timeout ,
131
- -failfast, -fullpath and -v.
129
+ restricted set of 'cacheable' test flags, defined as -benchtime,
130
+ -coverprofile , -outputdir , -cpu, -list, -parallel, -run, -short,
131
+ -timeout, - failfast, -fullpath and -v.
132
132
If a run of go test has any test or non-test flags outside this set,
133
133
the result is not cached. To disable test caching, use any test flag
134
134
or argument other than the cacheable flags. The idiomatic way to disable
@@ -1672,7 +1672,7 @@ func (r *runTestActor) Act(b *work.Builder, ctx context.Context, a *work.Action)
1672
1672
a .TestOutput = & buf
1673
1673
t := fmt .Sprintf ("%.3fs" , time .Since (t0 ).Seconds ())
1674
1674
1675
- mergeCoverProfile (a . Objdir + "_cover_.out" )
1675
+ mergeCoverProfile (coverProfTempFile ( a ) )
1676
1676
1677
1677
if err == nil {
1678
1678
norun := ""
@@ -1694,7 +1694,7 @@ func (r *runTestActor) Act(b *work.Builder, ctx context.Context, a *work.Action)
1694
1694
cmd .Stdout .Write ([]byte ("\n " ))
1695
1695
}
1696
1696
fmt .Fprintf (cmd .Stdout , "ok \t %s\t %s%s%s\n " , a .Package .ImportPath , t , coveragePercentage (out ), norun )
1697
- r .c .saveOutput (a , coverProfTempFile ( a ) )
1697
+ r .c .saveOutput (a )
1698
1698
} else {
1699
1699
if testFailFast {
1700
1700
testShouldFailFast .Store (true )
@@ -1794,14 +1794,7 @@ func (c *runCache) tryCacheWithID(b *work.Builder, a *work.Action, id string) bo
1794
1794
cacheArgs = append (cacheArgs , arg )
1795
1795
case "-test.coverprofile" ,
1796
1796
"-test.outputdir" :
1797
- // The `-coverprofile` and `-outputdir` arguments, which
1798
- // only affect the location of profile output, are cacheable. This
1799
- // is based on the process where, upon a cache hit, stored profile
1800
- // data is copied to the specified output location. This mechanism
1801
- // ensures that output location preferences are honored without
1802
- // modifying the profile's content, thereby justifying their
1803
- // cacheability without impacting cache integrity. This allows
1804
- // cached coverage profiles to be written to different files.
1797
+ // These are cacheable and do not invalidate the cache when they change.
1805
1798
// Note that this list is documented above,
1806
1799
// so if you add to this list, update the docs too.
1807
1800
default :
@@ -1875,6 +1868,20 @@ func (c *runCache) tryCacheWithID(b *work.Builder, a *work.Action, id string) bo
1875
1868
// Parse cached result in preparation for changing run time to "(cached)".
1876
1869
// If we can't parse the cached result, don't use it.
1877
1870
data , entry , err = cache .GetBytes (cache .Default (), testAndInputKey (testID , testInputsID ))
1871
+
1872
+ // Merge cached cover profile data to cover profile.
1873
+ if testCoverProfile != "" {
1874
+ // Specifically ignore entry as it will be the same as above.
1875
+ cpData , _ , err := cache .GetFile (cache .Default (), coverProfileAndInputKey (testID , testInputsID ))
1876
+ if err != nil {
1877
+ if cache .DebugTest {
1878
+ fmt .Fprintf (os .Stderr , "testcache: %s: cached cover profile missing: %v\n " , a .Package .ImportPath , err )
1879
+ }
1880
+ return false
1881
+ }
1882
+ mergeCoverProfile (cpData )
1883
+ }
1884
+
1878
1885
if len (data ) == 0 || data [len (data )- 1 ] != '\n' {
1879
1886
if cache .DebugTest {
1880
1887
if err != nil {
@@ -1915,21 +1922,6 @@ func (c *runCache) tryCacheWithID(b *work.Builder, a *work.Action, id string) bo
1915
1922
j ++
1916
1923
}
1917
1924
c .buf .Write (data [j :])
1918
-
1919
- // Write coverage data to profile.
1920
- if cfg .BuildCover {
1921
- // The cached coverprofile has the same expiration time as the
1922
- // test result it corresponds to. That time is already checked
1923
- // above, so we can ignore the entry returned by GetFile here.
1924
- f , _ , err := cache .GetFile (cache .Default (), coverProfileAndInputKey (testID , testInputsID ))
1925
- if err != nil {
1926
- if cache .DebugTest {
1927
- fmt .Fprintf (os .Stderr , "testcache: %s: cached test result valid but cached coverage profile missing: %v\n " , a .Package .ImportPath , err )
1928
- }
1929
- return false
1930
- }
1931
- mergeCoverProfile (f )
1932
- }
1933
1925
return true
1934
1926
}
1935
1927
@@ -2083,7 +2075,7 @@ func coverProfileAndInputKey(testID, testInputsID cache.ActionID) cache.ActionID
2083
2075
return cache .Subkey (testAndInputKey (testID , testInputsID ), "coverprofile" )
2084
2076
}
2085
2077
2086
- func (c * runCache ) saveOutput (a * work.Action , coverProfileFile string ) {
2078
+ func (c * runCache ) saveOutput (a * work.Action ) {
2087
2079
if c .id1 == (cache.ActionID {}) && c .id2 == (cache.ActionID {}) {
2088
2080
return
2089
2081
}
@@ -2104,21 +2096,14 @@ func (c *runCache) saveOutput(a *work.Action, coverProfileFile string) {
2104
2096
if err != nil {
2105
2097
return
2106
2098
}
2107
- var saveCoverProfile = func ( testID cache. ActionID ) {}
2108
- if coverProfileFile != "" {
2109
- coverProfile , err : = os .Open ( coverProfileFile )
2110
- if err == nil {
2111
- saveCoverProfile = func ( testID cache.ActionID ) {
2112
- cache . Default (). Put ( coverProfileAndInputKey ( testID , testInputsID ), coverProfile )
2099
+ var coverProfile [] byte
2100
+ if testCoverProfile != "" {
2101
+ coverProfile , err = os .ReadFile ( coverProfTempFile ( a ) )
2102
+ if err != nil && ! os . IsNotExist ( err ) {
2103
+ if cache .DebugTest {
2104
+ fmt . Fprintf ( os . Stderr , "testcache: %s: reading cover profile: %v \n " , a . Package . ImportPath , err )
2113
2105
}
2114
- defer func () {
2115
- if err := coverProfile .Close (); err != nil && cache .DebugTest {
2116
- base .Errorf ("closing temporary coverprofile: %v" , err )
2117
- }
2118
- }()
2119
- } else if cache .DebugTest {
2120
- // Not indicative of a problem, as the test may not have generated a cover profile yet.
2121
- fmt .Fprintf (os .Stderr , "testcache: %s: opening temporary coverprofile: %s\n " , a .Package .ImportPath , err )
2106
+ return
2122
2107
}
2123
2108
}
2124
2109
if c .id1 != (cache.ActionID {}) {
@@ -2127,15 +2112,19 @@ func (c *runCache) saveOutput(a *work.Action, coverProfileFile string) {
2127
2112
}
2128
2113
cache .PutNoVerify (cache .Default (), c .id1 , bytes .NewReader (testlog ))
2129
2114
cache .PutNoVerify (cache .Default (), testAndInputKey (c .id1 , testInputsID ), bytes .NewReader (a .TestOutput .Bytes ()))
2130
- saveCoverProfile (c .id1 )
2115
+ if coverProfile != nil {
2116
+ cache .PutNoVerify (cache .Default (), coverProfileAndInputKey (c .id1 , testInputsID ), bytes .NewReader (coverProfile ))
2117
+ }
2131
2118
}
2132
2119
if c .id2 != (cache.ActionID {}) {
2133
2120
if cache .DebugTest {
2134
2121
fmt .Fprintf (os .Stderr , "testcache: %s: save test ID %x => input ID %x => %x\n " , a .Package .ImportPath , c .id2 , testInputsID , testAndInputKey (c .id2 , testInputsID ))
2135
2122
}
2136
2123
cache .PutNoVerify (cache .Default (), c .id2 , bytes .NewReader (testlog ))
2137
2124
cache .PutNoVerify (cache .Default (), testAndInputKey (c .id2 , testInputsID ), bytes .NewReader (a .TestOutput .Bytes ()))
2138
- saveCoverProfile (c .id2 )
2125
+ if coverProfile != nil {
2126
+ cache .PutNoVerify (cache .Default (), coverProfileAndInputKey (c .id2 , testInputsID ), bytes .NewReader (coverProfile ))
2127
+ }
2139
2128
}
2140
2129
}
2141
2130
0 commit comments