github.com/goproxy0/go@v0.0.0-20171111080102-49cc0c489d2c/src/cmd/go/internal/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 "cmd/go/internal/base" 9 "fmt" 10 "io" 11 "os" 12 "sync" 13 ) 14 15 var coverMerge struct { 16 f *os.File 17 sync.Mutex // for f.Write 18 } 19 20 // initCoverProfile initializes the test coverage profile. 21 // It must be run before any calls to mergeCoverProfile or closeCoverProfile. 22 // Using this function clears the profile in case it existed from a previous run, 23 // or in case it doesn't exist and the test is going to fail to create it (or not run). 24 func initCoverProfile() { 25 if testCoverProfile == "" { 26 return 27 } 28 29 // No mutex - caller's responsibility to call with no racing goroutines. 30 f, err := os.Create(testCoverProfile) 31 if err != nil { 32 base.Fatalf("%v", err) 33 } 34 _, err = fmt.Fprintf(f, "mode: %s\n", testCoverMode) 35 if err != nil { 36 base.Fatalf("%v", err) 37 } 38 coverMerge.f = f 39 } 40 41 // mergeCoverProfile merges file into the profile stored in testCoverProfile. 42 // It prints any errors it encounters to ew. 43 func mergeCoverProfile(ew io.Writer, file string) { 44 if coverMerge.f == nil { 45 return 46 } 47 coverMerge.Lock() 48 defer coverMerge.Unlock() 49 50 expect := fmt.Sprintf("mode: %s\n", testCoverMode) 51 buf := make([]byte, len(expect)) 52 r, err := os.Open(file) 53 if err != nil { 54 // Test did not create profile, which is OK. 55 return 56 } 57 defer r.Close() 58 59 n, err := io.ReadFull(r, buf) 60 if n == 0 { 61 return 62 } 63 if err != nil || string(buf) != expect { 64 fmt.Fprintf(ew, "error: test wrote malformed coverage profile.\n") 65 return 66 } 67 _, err = io.Copy(coverMerge.f, r) 68 if err != nil { 69 fmt.Fprintf(ew, "error: saving coverage profile: %v\n", err) 70 } 71 } 72 73 func closeCoverProfile() { 74 if coverMerge.f == nil { 75 return 76 } 77 if err := coverMerge.f.Close(); err != nil { 78 base.Errorf("closing coverage profile: %v", err) 79 } 80 }