@@ -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