github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/cmd/go/test/cover.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package test 6 7 import ( 8 "fmt" 9 "io" 10 "os" 11 "path/filepath" 12 "sync" 13 14 "github.com/go-asm/go/cmd/go/base" 15 "github.com/go-asm/go/cmd/go/cfg" 16 ) 17 18 var coverMerge struct { 19 f *os.File 20 sync.Mutex // for f.Write 21 } 22 23 // initCoverProfile initializes the test coverage profile. 24 // It must be run before any calls to mergeCoverProfile or closeCoverProfile. 25 // Using this function clears the profile in case it existed from a previous run, 26 // or in case it doesn't exist and the test is going to fail to create it (or not run). 27 func initCoverProfile() { 28 if testCoverProfile == "" || testC { 29 return 30 } 31 if !filepath.IsAbs(testCoverProfile) { 32 testCoverProfile = filepath.Join(testOutputDir.getAbs(), testCoverProfile) 33 } 34 35 // No mutex - caller's responsibility to call with no racing goroutines. 36 f, err := os.Create(testCoverProfile) 37 if err != nil { 38 base.Fatalf("%v", err) 39 } 40 _, err = fmt.Fprintf(f, "mode: %s\n", cfg.BuildCoverMode) 41 if err != nil { 42 base.Fatalf("%v", err) 43 } 44 coverMerge.f = f 45 } 46 47 // mergeCoverProfile merges file into the profile stored in testCoverProfile. 48 // It prints any errors it encounters to ew. 49 func mergeCoverProfile(ew io.Writer, file string) { 50 if coverMerge.f == nil { 51 return 52 } 53 coverMerge.Lock() 54 defer coverMerge.Unlock() 55 56 expect := fmt.Sprintf("mode: %s\n", cfg.BuildCoverMode) 57 buf := make([]byte, len(expect)) 58 r, err := os.Open(file) 59 if err != nil { 60 // Test did not create profile, which is OK. 61 return 62 } 63 defer r.Close() 64 65 n, err := io.ReadFull(r, buf) 66 if n == 0 { 67 return 68 } 69 if err != nil || string(buf) != expect { 70 fmt.Fprintf(ew, "error: test wrote malformed coverage profile %s.\n", file) 71 return 72 } 73 _, err = io.Copy(coverMerge.f, r) 74 if err != nil { 75 fmt.Fprintf(ew, "error: saving coverage profile: %v\n", err) 76 } 77 } 78 79 func closeCoverProfile() { 80 if coverMerge.f == nil { 81 return 82 } 83 if err := coverMerge.f.Close(); err != nil { 84 base.Errorf("closing coverage profile: %v", err) 85 } 86 }