@@ -16,7 +16,8 @@ import (
1616
1717var coverMerge struct {
1818 f * os.File
19- sync.Mutex // for f.Write
19+ fsize int64 // size of valid data written to f
20+ sync.Mutex // for f.Write
2021}
2122
2223// initCoverProfile initializes the test coverage profile.
@@ -36,11 +37,12 @@ func initCoverProfile() {
3637 if err != nil {
3738 base .Fatalf ("%v" , err )
3839 }
39- _ , err = fmt .Fprintf (f , "mode: %s\n " , cfg .BuildCoverMode )
40+ n , err : = fmt .Fprintf (f , "mode: %s\n " , cfg .BuildCoverMode )
4041 if err != nil {
4142 base .Fatalf ("%v" , err )
4243 }
4344 coverMerge .f = f
45+ coverMerge .fsize += int64 (n )
4446}
4547
4648// mergeCoverProfile merges file into the profile stored in testCoverProfile.
@@ -67,17 +69,26 @@ func mergeCoverProfile(file string) error {
6769 if err != nil || string (buf ) != expect {
6870 return fmt .Errorf ("error: test wrote malformed coverage profile %s.\n " , file )
6971 }
70- _ , err = io .Copy (coverMerge .f , r )
72+ m , err : = io .Copy (coverMerge .f , r )
7173 if err != nil {
72- return fmt .Errorf ("saving coverage profile: %v\n " , err )
74+ if m > 0 {
75+ // Attempt to rollback partial write.
76+ coverMerge .f .Seek (coverMerge .fsize , 0 )
77+ }
78+ return fmt .Errorf ("saving coverage profile: %w" , err )
7379 }
80+ coverMerge .fsize += m
7481 return nil
7582}
7683
7784func closeCoverProfile () {
7885 if coverMerge .f == nil {
7986 return
8087 }
88+ // Discard any partially written data from a failed merge.
89+ if err := coverMerge .f .Truncate (coverMerge .fsize ); err != nil {
90+ base .Errorf ("closing coverage profile: %v" , err )
91+ }
8192 if err := coverMerge .f .Close (); err != nil {
8293 base .Errorf ("closing coverage profile: %v" , err )
8394 }
0 commit comments