Source file src/cmd/internal/cov/read_test.go

     1  // Copyright 2022 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 cov_test
     6  
     7  import (
     8  	"cmd/internal/cov"
     9  	"fmt"
    10  	"internal/coverage"
    11  	"internal/coverage/decodecounter"
    12  	"internal/coverage/decodemeta"
    13  	"internal/coverage/pods"
    14  	"internal/goexperiment"
    15  	"internal/testenv"
    16  	"os"
    17  	"path/filepath"
    18  	"testing"
    19  )
    20  
    21  // visitor implements the CovDataVisitor interface in a very stripped
    22  // down way, just keeps track of interesting events.
    23  type visitor struct {
    24  	metaFileCount    int
    25  	counterFileCount int
    26  	funcCounterData  int
    27  	metaFuncCount    int
    28  }
    29  
    30  func (v *visitor) BeginPod(p pods.Pod) {}
    31  func (v *visitor) EndPod(p pods.Pod)   {}
    32  func (v *visitor) VisitMetaDataFile(mdf string, mfr *decodemeta.CoverageMetaFileReader) {
    33  	v.metaFileCount++
    34  }
    35  func (v *visitor) BeginCounterDataFile(cdf string, cdr *decodecounter.CounterDataReader, dirIdx int) {
    36  	v.counterFileCount++
    37  }
    38  func (v *visitor) EndCounterDataFile(cdf string, cdr *decodecounter.CounterDataReader, dirIdx int) {}
    39  func (v *visitor) VisitFuncCounterData(payload decodecounter.FuncPayload)                          { v.funcCounterData++ }
    40  func (v *visitor) EndCounters()                                                                    {}
    41  func (v *visitor) BeginPackage(pd *decodemeta.CoverageMetaDataDecoder, pkgIdx uint32)              {}
    42  func (v *visitor) EndPackage(pd *decodemeta.CoverageMetaDataDecoder, pkgIdx uint32)                {}
    43  func (v *visitor) VisitFunc(pkgIdx uint32, fnIdx uint32, fd *coverage.FuncDesc)                    { v.metaFuncCount++ }
    44  func (v *visitor) Finish()                                                                         {}
    45  
    46  func TestIssue58411(t *testing.T) {
    47  	testenv.MustHaveGoBuild(t)
    48  	if !goexperiment.CoverageRedesign {
    49  		t.Skipf("skipping since this test requires 'go build -cover'")
    50  	}
    51  
    52  	// Build a tiny test program with -cover. Smallness is important;
    53  	// it is one of the factors that triggers issue 58411.
    54  	d := t.TempDir()
    55  	exepath := filepath.Join(d, "small.exe")
    56  	path := filepath.Join("testdata", "small.go")
    57  	cmd := testenv.Command(t, testenv.GoToolPath(t), "build",
    58  		"-o", exepath, "-cover", path)
    59  	b, err := cmd.CombinedOutput()
    60  	if len(b) != 0 {
    61  		t.Logf("## build output:\n%s", b)
    62  	}
    63  	if err != nil {
    64  		t.Fatalf("build error: %v", err)
    65  	}
    66  
    67  	// Run to produce coverage data. Note the large argument; we need a large
    68  	// argument (more than 4k) to trigger the bug, but the overall file
    69  	// has to remain small (since large files will be read with mmap).
    70  	covdir := filepath.Join(d, "covdata")
    71  	if err = os.Mkdir(covdir, 0777); err != nil {
    72  		t.Fatalf("creating covdir: %v", err)
    73  	}
    74  	large := fmt.Sprintf("%07999d", 0)
    75  	cmd = testenv.Command(t, exepath, "1", "2", "3", large)
    76  	cmd.Dir = covdir
    77  	cmd.Env = append(os.Environ(), "GOCOVERDIR="+covdir)
    78  	b, err = cmd.CombinedOutput()
    79  	if err != nil {
    80  		t.Logf("## run output:\n%s", b)
    81  		t.Fatalf("build error: %v", err)
    82  	}
    83  
    84  	vis := &visitor{}
    85  
    86  	// Read resulting coverage data. Without the fix, this would
    87  	// yield a "short read" error.
    88  	const verbosityLevel = 0
    89  	const flags = 0
    90  	cdr := cov.MakeCovDataReader(vis, []string{covdir}, verbosityLevel, flags, nil)
    91  	err = cdr.Visit()
    92  	if err != nil {
    93  		t.Fatalf("visit failed: %v", err)
    94  	}
    95  
    96  	// make sure we saw a few things just for grins
    97  	const want = "{metaFileCount:1 counterFileCount:1 funcCounterData:1 metaFuncCount:1}"
    98  	got := fmt.Sprintf("%+v", *vis)
    99  	if want != got {
   100  		t.Errorf("visitor contents: want %v got %v\n", want, got)
   101  	}
   102  }
   103  

View as plain text