@@ -16,7 +16,8 @@ import (
16
16
17
17
var coverMerge struct {
18
18
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
20
21
}
21
22
22
23
// initCoverProfile initializes the test coverage profile.
@@ -36,11 +37,12 @@ func initCoverProfile() {
36
37
if err != nil {
37
38
base .Fatalf ("%v" , err )
38
39
}
39
- _ , err = fmt .Fprintf (f , "mode: %s\n " , testCoverMode )
40
+ n , err : = fmt .Fprintf (f , "mode: %s\n " , testCoverMode )
40
41
if err != nil {
41
42
base .Fatalf ("%v" , err )
42
43
}
43
44
coverMerge .f = f
45
+ coverMerge .fsize += int64 (n )
44
46
}
45
47
46
48
// mergeCoverProfile merges file into the profile stored in testCoverProfile.
@@ -67,17 +69,26 @@ func mergeCoverProfile(file string) error {
67
69
if err != nil || string (buf ) != expect {
68
70
return errMalformedCoverProfile
69
71
}
70
- _ , err = io .Copy (coverMerge .f , r )
72
+ m , err : = io .Copy (coverMerge .f , r )
71
73
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 )
73
79
}
80
+ coverMerge .fsize += m
74
81
return nil
75
82
}
76
83
77
84
func closeCoverProfile () {
78
85
if coverMerge .f == nil {
79
86
return
80
87
}
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
+ }
81
92
if err := coverMerge .f .Close (); err != nil {
82
93
base .Errorf ("closing coverage profile: %v" , err )
83
94
}
0 commit comments