Source file src/cmd/go/internal/test/cover.go

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

View as plain text