diff options
Diffstat (limited to 'src/cmd/internal/cov/read_test.go')
-rw-r--r-- | src/cmd/internal/cov/read_test.go | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/src/cmd/internal/cov/read_test.go b/src/cmd/internal/cov/read_test.go new file mode 100644 index 0000000..fa2151a --- /dev/null +++ b/src/cmd/internal/cov/read_test.go @@ -0,0 +1,102 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cov_test + +import ( + "cmd/internal/cov" + "fmt" + "internal/coverage" + "internal/coverage/decodecounter" + "internal/coverage/decodemeta" + "internal/coverage/pods" + "internal/goexperiment" + "internal/testenv" + "os" + "path/filepath" + "testing" +) + +// visitor implements the CovDataVisitor interface in a very stripped +// down way, just keeps track of interesting events. +type visitor struct { + metaFileCount int + counterFileCount int + funcCounterData int + metaFuncCount int +} + +func (v *visitor) BeginPod(p pods.Pod) {} +func (v *visitor) EndPod(p pods.Pod) {} +func (v *visitor) VisitMetaDataFile(mdf string, mfr *decodemeta.CoverageMetaFileReader) { + v.metaFileCount++ +} +func (v *visitor) BeginCounterDataFile(cdf string, cdr *decodecounter.CounterDataReader, dirIdx int) { + v.counterFileCount++ +} +func (v *visitor) EndCounterDataFile(cdf string, cdr *decodecounter.CounterDataReader, dirIdx int) {} +func (v *visitor) VisitFuncCounterData(payload decodecounter.FuncPayload) { v.funcCounterData++ } +func (v *visitor) EndCounters() {} +func (v *visitor) BeginPackage(pd *decodemeta.CoverageMetaDataDecoder, pkgIdx uint32) {} +func (v *visitor) EndPackage(pd *decodemeta.CoverageMetaDataDecoder, pkgIdx uint32) {} +func (v *visitor) VisitFunc(pkgIdx uint32, fnIdx uint32, fd *coverage.FuncDesc) { v.metaFuncCount++ } +func (v *visitor) Finish() {} + +func TestIssue58411(t *testing.T) { + testenv.MustHaveGoBuild(t) + if !goexperiment.CoverageRedesign { + t.Skipf("skipping since this test requires 'go build -cover'") + } + + // Build a tiny test program with -cover. Smallness is important; + // it is one of the factors that triggers issue 58411. + d := t.TempDir() + exepath := filepath.Join(d, "small.exe") + path := filepath.Join("testdata", "small.go") + cmd := testenv.Command(t, testenv.GoToolPath(t), "build", + "-o", exepath, "-cover", path) + b, err := cmd.CombinedOutput() + if len(b) != 0 { + t.Logf("## build output:\n%s", b) + } + if err != nil { + t.Fatalf("build error: %v", err) + } + + // Run to produce coverage data. Note the large argument; we need a large + // argument (more than 4k) to trigger the bug, but the overall file + // has to remain small (since large files will be read with mmap). + covdir := filepath.Join(d, "covdata") + if err = os.Mkdir(covdir, 0777); err != nil { + t.Fatalf("creating covdir: %v", err) + } + large := fmt.Sprintf("%07999d", 0) + cmd = testenv.Command(t, exepath, "1", "2", "3", large) + cmd.Dir = covdir + cmd.Env = append(os.Environ(), "GOCOVERDIR="+covdir) + b, err = cmd.CombinedOutput() + if err != nil { + t.Logf("## run output:\n%s", b) + t.Fatalf("build error: %v", err) + } + + vis := &visitor{} + + // Read resulting coverage data. Without the fix, this would + // yield a "short read" error. + const verbosityLevel = 0 + const flags = 0 + cdr := cov.MakeCovDataReader(vis, []string{covdir}, verbosityLevel, flags, nil) + err = cdr.Visit() + if err != nil { + t.Fatalf("visit failed: %v", err) + } + + // make sure we saw a few things just for grins + const want = "{metaFileCount:1 counterFileCount:1 funcCounterData:1 metaFuncCount:1}" + got := fmt.Sprintf("%+v", *vis) + if want != got { + t.Errorf("visitor contents: want %v got %v\n", want, got) + } +} |