From 41298239cf8b0de14fd3ac43e4af65fad6ab5cc4 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 28 Jan 2025 11:27:22 -0800 Subject: [PATCH] all: remove coverageredesign experiment The coverageredesign experiment was turned on by default by CL 436236 in September, 2022. We've documented it and people are using it. This CL removes the ability to turn off the experiment. This removes some old code that is no longer being executed. For #51430 Change-Id: I88d4998c8b5ea98eef8145d7ca6ebd96f64fbc2b Cq-Include-Trybots: luci.golang.try:gotip-linux-amd64-longtest,gotip-darwin-amd64-longtest,gotip-linux-arm64-longtest,gotip-windows-amd64-longtest Reviewed-on: https://go-review.googlesource.com/c/go/+/644997 LUCI-TryBot-Result: Go LUCI Reviewed-by: Ian Lance Taylor Auto-Submit: Ian Lance Taylor Reviewed-by: Than McIntosh Reviewed-by: Cherry Mui Commit-Queue: Ian Lance Taylor --- src/cmd/compile/internal/test/inl_test.go | 4 - src/cmd/covdata/tool_test.go | 4 - src/cmd/go/alldocs.go | 1 - src/cmd/go/internal/help/helpdoc.go | 1 - src/cmd/go/internal/list/list.go | 6 +- src/cmd/go/internal/load/pkg.go | 97 +++------- src/cmd/go/internal/load/test.go | 171 +----------------- src/cmd/go/internal/run/run.go | 6 +- src/cmd/go/internal/test/test.go | 10 +- src/cmd/go/internal/work/build.go | 35 +--- src/cmd/go/internal/work/exec.go | 81 +++------ .../script/cover_build_cmdline_pkgs.txt | 1 - .../script/cover_build_pkg_select.txt | 3 - .../go/testdata/script/cover_build_simple.txt | 3 - .../script/cover_coverpkg_partial.txt | 1 - .../script/cover_coverpkg_with_init.txt | 1 - src/cmd/go/testdata/script/cover_list.txt | 1 - .../script/cover_main_import_path.txt | 1 - .../go/testdata/script/cover_statements.txt | 15 +- .../script/cover_sync_atomic_import.txt | 1 - .../testdata/script/cover_test_pkgselect.txt | 3 - .../testdata/script/cover_var_init_order.txt | 3 - .../go/testdata/script/testing_coverage.txt | 1 - src/cmd/internal/cov/read_test.go | 4 - src/internal/buildcfg/exp.go | 13 +- src/internal/coverage/cfile/emitdata_test.go | 7 - src/internal/coverage/cfile/ts_test.go | 7 - .../goexperiment/exp_coverageredesign_off.go | 8 - .../goexperiment/exp_coverageredesign_on.go | 8 - src/internal/goexperiment/flags.go | 4 - src/testing/cover.go | 87 --------- src/testing/newcover.go | 41 +++-- src/testing/testing.go | 8 +- 33 files changed, 106 insertions(+), 531 deletions(-) delete mode 100644 src/internal/goexperiment/exp_coverageredesign_off.go delete mode 100644 src/internal/goexperiment/exp_coverageredesign_on.go diff --git a/src/cmd/compile/internal/test/inl_test.go b/src/cmd/compile/internal/test/inl_test.go index 9a1a8bb105..f1f6c34bfc 100644 --- a/src/cmd/compile/internal/test/inl_test.go +++ b/src/cmd/compile/internal/test/inl_test.go @@ -375,10 +375,6 @@ func TestIssue56044(t *testing.T) { if testing.Short() { t.Skipf("skipping test: too long for short mode") } - if !goexperiment.CoverageRedesign { - t.Skipf("skipping new coverage tests (experiment not enabled)") - } - testenv.MustHaveGoBuild(t) modes := []string{"-covermode=set", "-covermode=atomic"} diff --git a/src/cmd/covdata/tool_test.go b/src/cmd/covdata/tool_test.go index 757a245047..730adf4c8e 100644 --- a/src/cmd/covdata/tool_test.go +++ b/src/cmd/covdata/tool_test.go @@ -9,7 +9,6 @@ import ( "flag" "fmt" "internal/coverage/pods" - "internal/goexperiment" "internal/testenv" "log" "os" @@ -150,9 +149,6 @@ const debugWorkDir = false func TestCovTool(t *testing.T) { testenv.MustHaveGoBuild(t) - if !goexperiment.CoverageRedesign { - t.Skipf("stubbed out due to goexperiment.CoverageRedesign=false") - } dir := tempDir(t) if testing.Short() { t.Skip() diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go index 2220863b8e..b9cf7202c2 100644 --- a/src/cmd/go/alldocs.go +++ b/src/cmd/go/alldocs.go @@ -2484,7 +2484,6 @@ // GOCOVERDIR // Directory into which to write code coverage data files // generated by running a "go build -cover" binary. -// Requires that GOEXPERIMENT=coverageredesign is enabled. // // Special-purpose environment variables: // diff --git a/src/cmd/go/internal/help/helpdoc.go b/src/cmd/go/internal/help/helpdoc.go index ccc04c25d2..d2f0fd173b 100644 --- a/src/cmd/go/internal/help/helpdoc.go +++ b/src/cmd/go/internal/help/helpdoc.go @@ -657,7 +657,6 @@ Environment variables for use with code coverage: GOCOVERDIR Directory into which to write code coverage data files generated by running a "go build -cover" binary. - Requires that GOEXPERIMENT=coverageredesign is enabled. Special-purpose environment variables: diff --git a/src/cmd/go/internal/list/list.go b/src/cmd/go/internal/list/list.go index 04fdadef3f..d6cba5a4e0 100644 --- a/src/cmd/go/internal/list/list.go +++ b/src/cmd/go/internal/list/list.go @@ -347,9 +347,7 @@ func init() { CmdList.Run = runList // break init cycle // Omit build -json because list has its own -json work.AddBuildFlags(CmdList, work.OmitJSONFlag) - if cfg.Experiment != nil && cfg.Experiment.CoverageRedesign { - work.AddCoverFlags(CmdList, nil) - } + work.AddCoverFlags(CmdList, nil) CmdList.Flag.Var(&listJsonFields, "json", "") } @@ -728,7 +726,7 @@ func runList(ctx context.Context, cmd *base.Command, args []string) { b.IsCmdList = true b.NeedExport = *listExport b.NeedCompiledGoFiles = *listCompiled - if cfg.Experiment.CoverageRedesign && cfg.BuildCover { + if cfg.BuildCover { load.PrepareForCoverageBuild(pkgs) } a := &work.Action{} diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go index 15f6b2e87b..0c4639ce82 100644 --- a/src/cmd/go/internal/load/pkg.go +++ b/src/cmd/go/internal/load/pkg.go @@ -8,7 +8,6 @@ package load import ( "bytes" "context" - "crypto/sha256" "encoding/json" "errors" "fmt" @@ -218,27 +217,26 @@ func (p *Package) IsTestOnly() bool { type PackageInternal struct { // Unexported fields are not part of the public API. Build *build.Package - Imports []*Package // this package's direct imports - CompiledImports []string // additional Imports necessary when using CompiledGoFiles (all from standard library); 1:1 with the end of PackagePublic.Imports - RawImports []string // this package's original imports as they appear in the text of the program; 1:1 with the end of PackagePublic.Imports - ForceLibrary bool // this package is a library (even if named "main") - CmdlineFiles bool // package built from files listed on command line - CmdlinePkg bool // package listed on command line - CmdlinePkgLiteral bool // package listed as literal on command line (not via wildcard) - Local bool // imported via local path (./ or ../) - LocalPrefix string // interpret ./ and ../ imports relative to this prefix - ExeName string // desired name for temporary executable - FuzzInstrument bool // package should be instrumented for fuzzing - Cover CoverSetup // coverage mode and other setup info of -cover is being applied to this package - CoverVars map[string]*CoverVar // variables created by coverage analysis - OmitDebug bool // tell linker not to write debug information - GobinSubdir bool // install target would be subdir of GOBIN - BuildInfo *debug.BuildInfo // add this info to package main - TestmainGo *[]byte // content for _testmain.go - Embed map[string][]string // //go:embed comment mapping - OrigImportPath string // original import path before adding '_test' suffix - PGOProfile string // path to PGO profile - ForMain string // the main package if this package is built specifically for it + Imports []*Package // this package's direct imports + CompiledImports []string // additional Imports necessary when using CompiledGoFiles (all from standard library); 1:1 with the end of PackagePublic.Imports + RawImports []string // this package's original imports as they appear in the text of the program; 1:1 with the end of PackagePublic.Imports + ForceLibrary bool // this package is a library (even if named "main") + CmdlineFiles bool // package built from files listed on command line + CmdlinePkg bool // package listed on command line + CmdlinePkgLiteral bool // package listed as literal on command line (not via wildcard) + Local bool // imported via local path (./ or ../) + LocalPrefix string // interpret ./ and ../ imports relative to this prefix + ExeName string // desired name for temporary executable + FuzzInstrument bool // package should be instrumented for fuzzing + Cover CoverSetup // coverage mode and other setup info of -cover is being applied to this package + OmitDebug bool // tell linker not to write debug information + GobinSubdir bool // install target would be subdir of GOBIN + BuildInfo *debug.BuildInfo // add this info to package main + TestmainGo *[]byte // content for _testmain.go + Embed map[string][]string // //go:embed comment mapping + OrigImportPath string // original import path before adding '_test' suffix + PGOProfile string // path to PGO profile + ForMain string // the main package if this package is built specifically for it Asmflags []string // -asmflags for this package Gcflags []string // -gcflags for this package @@ -372,12 +370,6 @@ func (p *Package) Resolve(imports []string) []string { return all } -// CoverVar holds the name of the generated coverage variables targeting the named file. -type CoverVar struct { - File string // local file name - Var string // name of count struct -} - // CoverSetup holds parameters related to coverage setup for a given package (covermode, etc). type CoverSetup struct { Mode string // coverage mode for this package @@ -2627,7 +2619,7 @@ func LinkerDeps(p *Package) ([]string, error) { deps = append(deps, "runtime/asan") } // Building for coverage forces an import of runtime/coverage. - if cfg.BuildCover && cfg.Experiment.CoverageRedesign { + if cfg.BuildCover { deps = append(deps, "runtime/coverage") } @@ -3568,14 +3560,6 @@ func SelectCoverPackages(roots []*Package, match []func(*Package) bool, op strin if cfg.BuildCoverMode == "atomic" { EnsureImport(p, "sync/atomic") } - - // Generate covervars if using legacy coverage design. - if !cfg.Experiment.CoverageRedesign { - var coverFiles []string - coverFiles = append(coverFiles, p.GoFiles...) - coverFiles = append(coverFiles, p.CgoFiles...) - p.Internal.CoverVars = DeclareCoverVars(p, coverFiles...) - } } // Warn about -coverpkg arguments that are not actually used. @@ -3587,42 +3571,3 @@ func SelectCoverPackages(roots []*Package, match []func(*Package) bool, op strin return covered } - -// DeclareCoverVars attaches the required cover variables names -// to the files, to be used when annotating the files. This -// function only called when using legacy coverage test/build -// (e.g. GOEXPERIMENT=coverageredesign is off). -func DeclareCoverVars(p *Package, files ...string) map[string]*CoverVar { - coverVars := make(map[string]*CoverVar) - coverIndex := 0 - // We create the cover counters as new top-level variables in the package. - // We need to avoid collisions with user variables (GoCover_0 is unlikely but still) - // and more importantly with dot imports of other covered packages, - // so we append 12 hex digits from the SHA-256 of the import path. - // The point is only to avoid accidents, not to defeat users determined to - // break things. - sum := sha256.Sum256([]byte(p.ImportPath)) - h := fmt.Sprintf("%x", sum[:6]) - for _, file := range files { - if base.IsTestFile(file) { - continue - } - // For a package that is "local" (imported via ./ import or command line, outside GOPATH), - // we record the full path to the file name. - // Otherwise we record the import path, then a forward slash, then the file name. - // This makes profiles within GOPATH file system-independent. - // These names appear in the cmd/cover HTML interface. - var longFile string - if p.Internal.Local { - longFile = filepath.Join(p.Dir, file) - } else { - longFile = pathpkg.Join(p.ImportPath, file) - } - coverVars[file] = &CoverVar{ - File: longFile, - Var: fmt.Sprintf("GoCover_%d_%x", coverIndex, h), - } - coverIndex++ - } - return coverVars -} diff --git a/src/cmd/go/internal/load/test.go b/src/cmd/go/internal/load/test.go index ddd14a0304..f895e3a246 100644 --- a/src/cmd/go/internal/load/test.go +++ b/src/cmd/go/internal/load/test.go @@ -23,7 +23,6 @@ import ( "unicode" "unicode/utf8" - "cmd/go/internal/cfg" "cmd/go/internal/fsys" "cmd/go/internal/str" "cmd/go/internal/trace" @@ -42,7 +41,6 @@ type TestCover struct { Local bool Pkgs []*Package Paths []string - Vars []coverInfo } // TestPackagesFor is like TestPackagesAndErrors but it returns @@ -309,7 +307,7 @@ func TestPackagesAndErrors(ctx context.Context, done func(), opts PackageOpts, p // Also the linker introduces implicit dependencies reported by LinkerDeps. stk.Push(ImportInfo{Pkg: "testmain"}) deps := TestMainDeps // cap==len, so safe for append - if cover != nil && cfg.Experiment.CoverageRedesign { + if cover != nil { deps = append(deps, "internal/coverage/cfile") } ldDeps, err := LinkerDeps(p) @@ -334,22 +332,6 @@ func TestPackagesAndErrors(ctx context.Context, done func(), opts PackageOpts, p stk.Pop() parallelizablePart := func() { - if cover != nil && cover.Pkgs != nil && !cfg.Experiment.CoverageRedesign { - // Add imports, but avoid duplicates. - seen := map[*Package]bool{p: true, ptest: true} - for _, p1 := range pmain.Internal.Imports { - seen[p1] = true - } - for _, p1 := range cover.Pkgs { - if seen[p1] { - // Don't add duplicate imports. - continue - } - seen[p1] = true - pmain.Internal.Imports = append(pmain.Internal.Imports, p1) - } - } - allTestImports := make([]*Package, 0, len(pmain.Internal.Imports)+len(imports)+len(ximports)) allTestImports = append(allTestImports, pmain.Internal.Imports...) allTestImports = append(allTestImports, imports...) @@ -397,35 +379,19 @@ func TestPackagesAndErrors(ctx context.Context, done func(), opts PackageOpts, p } if cover != nil { - if cfg.Experiment.CoverageRedesign { - // Here ptest needs to inherit the proper coverage mode (since - // it contains p's Go files), whereas pmain contains only - // test harness code (don't want to instrument it, and - // we don't want coverage hooks in the pkg init). - ptest.Internal.Cover.Mode = p.Internal.Cover.Mode - pmain.Internal.Cover.Mode = "testmain" - } + // Here ptest needs to inherit the proper coverage mode (since + // it contains p's Go files), whereas pmain contains only + // test harness code (don't want to instrument it, and + // we don't want coverage hooks in the pkg init). + ptest.Internal.Cover.Mode = p.Internal.Cover.Mode + pmain.Internal.Cover.Mode = "testmain" + // Should we apply coverage analysis locally, only for this // package and only for this test? Yes, if -cover is on but // -coverpkg has not specified a list of packages for global // coverage. if cover.Local { ptest.Internal.Cover.Mode = cover.Mode - - if !cfg.Experiment.CoverageRedesign { - var coverFiles []string - coverFiles = append(coverFiles, ptest.GoFiles...) - coverFiles = append(coverFiles, ptest.CgoFiles...) - ptest.Internal.CoverVars = DeclareCoverVars(ptest, coverFiles...) - } - } - - if !cfg.Experiment.CoverageRedesign { - for _, cp := range pmain.Internal.Imports { - if len(cp.Internal.CoverVars) > 0 { - t.Cover.Vars = append(t.Cover.Vars, coverInfo{cp, cp.Internal.CoverVars}) - } - } } } @@ -625,11 +591,6 @@ func isTest(name, prefix string) bool { return !unicode.IsLower(rune) } -type coverInfo struct { - Package *Package - Vars map[string]*CoverVar -} - // loadTestFuncs returns the testFuncs describing the tests that will be run. // The returned testFuncs is always non-nil, even if an error occurred while // processing test files. @@ -655,9 +616,6 @@ func loadTestFuncs(ptest *Package) (*testFuncs, error) { func formatTestmain(t *testFuncs) ([]byte, error) { var buf bytes.Buffer tmpl := testmainTmpl - if cfg.Experiment.CoverageRedesign { - tmpl = testmainTmplNewCoverage - } if err := tmpl.Execute(&buf, t); err != nil { return nil, err } @@ -825,119 +783,6 @@ var testmainTmpl = lazytemplate.New("main", ` package main -import ( - "os" -{{if .TestMain}} - "reflect" -{{end}} - "testing" - "testing/internal/testdeps" - -{{if .ImportTest}} - {{if .NeedTest}}_test{{else}}_{{end}} {{.Package.ImportPath | printf "%q"}} -{{end}} -{{if .ImportXtest}} - {{if .NeedXtest}}_xtest{{else}}_{{end}} {{.Package.ImportPath | printf "%s_test" | printf "%q"}} -{{end}} -{{if .Cover}} -{{range $i, $p := .Cover.Vars}} - _cover{{$i}} {{$p.Package.ImportPath | printf "%q"}} -{{end}} -{{end}} -) - -var tests = []testing.InternalTest{ -{{range .Tests}} - {"{{.Name}}", {{.Package}}.{{.Name}}}, -{{end}} -} - -var benchmarks = []testing.InternalBenchmark{ -{{range .Benchmarks}} - {"{{.Name}}", {{.Package}}.{{.Name}}}, -{{end}} -} - -var fuzzTargets = []testing.InternalFuzzTarget{ -{{range .FuzzTargets}} - {"{{.Name}}", {{.Package}}.{{.Name}}}, -{{end}} -} - -var examples = []testing.InternalExample{ -{{range .Examples}} - {"{{.Name}}", {{.Package}}.{{.Name}}, {{.Output | printf "%q"}}, {{.Unordered}}}, -{{end}} -} - -func init() { - testdeps.ImportPath = {{.ImportPath | printf "%q"}} -} - -{{if .Cover}} - -// Only updated by init functions, so no need for atomicity. -var ( - coverCounters = make(map[string][]uint32) - coverBlocks = make(map[string][]testing.CoverBlock) -) - -func init() { - {{range $i, $p := .Cover.Vars}} - {{range $file, $cover := $p.Vars}} - coverRegisterFile({{printf "%q" $cover.File}}, _cover{{$i}}.{{$cover.Var}}.Count[:], _cover{{$i}}.{{$cover.Var}}.Pos[:], _cover{{$i}}.{{$cover.Var}}.NumStmt[:]) - {{end}} - {{end}} -} - -func coverRegisterFile(fileName string, counter []uint32, pos []uint32, numStmts []uint16) { - if 3*len(counter) != len(pos) || len(counter) != len(numStmts) { - panic("coverage: mismatched sizes") - } - if coverCounters[fileName] != nil { - // Already registered. - return - } - coverCounters[fileName] = counter - block := make([]testing.CoverBlock, len(counter)) - for i := range counter { - block[i] = testing.CoverBlock{ - Line0: pos[3*i+0], - Col0: uint16(pos[3*i+2]), - Line1: pos[3*i+1], - Col1: uint16(pos[3*i+2]>>16), - Stmts: numStmts[i], - } - } - coverBlocks[fileName] = block -} -{{end}} - -func main() { -{{if .Cover}} - testing.RegisterCover(testing.Cover{ - Mode: {{printf "%q" .Cover.Mode}}, - Counters: coverCounters, - Blocks: coverBlocks, - CoveredPackages: {{printf "%q" .Covered}}, - }) -{{end}} - m := testing.MainStart(testdeps.TestDeps{}, tests, benchmarks, fuzzTargets, examples) -{{with .TestMain}} - {{.Package}}.{{.Name}}(m) - os.Exit(int(reflect.ValueOf(m).Elem().FieldByName("exitCode").Int())) -{{else}} - os.Exit(m.Run()) -{{end}} -} - -`) - -var testmainTmplNewCoverage = lazytemplate.New("main", ` -// Code generated by 'go test'. DO NOT EDIT. - -package main - import ( "os" {{if .TestMain}} diff --git a/src/cmd/go/internal/run/run.go b/src/cmd/go/internal/run/run.go index 5067cb2835..b81b1a007b 100644 --- a/src/cmd/go/internal/run/run.go +++ b/src/cmd/go/internal/run/run.go @@ -66,9 +66,7 @@ func init() { CmdRun.Run = runRun // break init loop work.AddBuildFlags(CmdRun, work.DefaultBuildFlags) - if cfg.Experiment != nil && cfg.Experiment.CoverageRedesign { - work.AddCoverFlags(CmdRun, nil) - } + work.AddCoverFlags(CmdRun, nil) CmdRun.Flag.Var((*base.StringsFlag)(&work.ExecCmd), "exec", "") } @@ -141,7 +139,7 @@ func runRun(ctx context.Context, cmd *base.Command, args []string) { cmdArgs := args[i:] load.CheckPackageErrors([]*load.Package{p}) - if cfg.Experiment.CoverageRedesign && cfg.BuildCover { + if cfg.BuildCover { load.PrepareForCoverageBuild([]*load.Package{p}) } diff --git a/src/cmd/go/internal/test/test.go b/src/cmd/go/internal/test/test.go index 90f2d88d6b..e3cd50d59c 100644 --- a/src/cmd/go/internal/test/test.go +++ b/src/cmd/go/internal/test/test.go @@ -867,7 +867,7 @@ func runTest(ctx context.Context, cmd *base.Command, args []string) { // patterns. plist := load.TestPackageList(ctx, pkgOpts, pkgs) testCoverPkgs = load.SelectCoverPackages(plist, match, "test") - if cfg.Experiment.CoverageRedesign && len(testCoverPkgs) > 0 { + if len(testCoverPkgs) > 0 { // create a new singleton action that will collect up the // meta-data files from all of the packages mentioned in // "-coverpkg" and write them to a summary file. This new @@ -984,9 +984,7 @@ func runTest(ctx context.Context, cmd *base.Command, args []string) { // later package. Note that if -coverpkg is in effect // p.Internal.Cover.GenMeta will wind up being set for // all matching packages. - if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 && - cfg.BuildCoverPkg == nil && - cfg.Experiment.CoverageRedesign { + if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 && cfg.BuildCoverPkg == nil { p.Internal.Cover.GenMeta = true } } @@ -1092,7 +1090,7 @@ var windowsBadWords = []string{ func builderTest(b *work.Builder, ctx context.Context, pkgOpts load.PackageOpts, p *load.Package, imported bool, writeCoverMetaAct *work.Action) (buildAction, runAction, printAction *work.Action, perr *load.Package, err error) { if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 { - if cfg.BuildCover && cfg.Experiment.CoverageRedesign { + if cfg.BuildCover { if p.Internal.Cover.GenMeta { p.Internal.Cover.Mode = cfg.BuildCoverMode } @@ -1487,7 +1485,7 @@ func (r *runTestActor) Act(b *work.Builder, ctx context.Context, a *work.Action) if p := a.Package; len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 { reportNoTestFiles := true - if cfg.BuildCover && cfg.Experiment.CoverageRedesign && p.Internal.Cover.GenMeta { + if cfg.BuildCover && p.Internal.Cover.GenMeta { if err := sh.Mkdir(a.Objdir); err != nil { return err } diff --git a/src/cmd/go/internal/work/build.go b/src/cmd/go/internal/work/build.go index 3508d51fbb..873feb8a26 100644 --- a/src/cmd/go/internal/work/build.go +++ b/src/cmd/go/internal/work/build.go @@ -247,10 +247,8 @@ func init() { AddBuildFlags(CmdBuild, DefaultBuildFlags) AddBuildFlags(CmdInstall, DefaultBuildFlags) - if cfg.Experiment != nil && cfg.Experiment.CoverageRedesign { - AddCoverFlags(CmdBuild, nil) - AddCoverFlags(CmdInstall, nil) - } + AddCoverFlags(CmdBuild, nil) + AddCoverFlags(CmdInstall, nil) } // Note that flags consulted by other parts of the code @@ -361,26 +359,13 @@ func AddBuildFlags(cmd *base.Command, mask BuildFlagMask) { cmd.Flag.StringVar(&cfg.DebugTrace, "debug-trace", "", "") } -// AddCoverFlags adds coverage-related flags to "cmd". If the -// CoverageRedesign experiment is enabled, we add -cover{mode,pkg} to -// the build command and only -coverprofile to the test command. If -// the CoverageRedesign experiment is disabled, -cover* flags are -// added only to the test command. +// AddCoverFlags adds coverage-related flags to "cmd". +// We add -cover{mode,pkg} to the build command and only +// -coverprofile to the test command. func AddCoverFlags(cmd *base.Command, coverProfileFlag *string) { - addCover := false - if cfg.Experiment != nil && cfg.Experiment.CoverageRedesign { - // New coverage enabled: both build and test commands get - // coverage flags. - addCover = true - } else { - // New coverage disabled: only test command gets cover flags. - addCover = coverProfileFlag != nil - } - if addCover { - cmd.Flag.BoolVar(&cfg.BuildCover, "cover", false, "") - cmd.Flag.Var(coverFlag{(*coverModeFlag)(&cfg.BuildCoverMode)}, "covermode", "") - cmd.Flag.Var(coverFlag{commaListFlag{&cfg.BuildCoverPkg}}, "coverpkg", "") - } + cmd.Flag.BoolVar(&cfg.BuildCover, "cover", false, "") + cmd.Flag.Var(coverFlag{(*coverModeFlag)(&cfg.BuildCoverMode)}, "covermode", "") + cmd.Flag.Var(coverFlag{commaListFlag{&cfg.BuildCoverPkg}}, "coverpkg", "") if coverProfileFlag != nil { cmd.Flag.Var(coverFlag{V: stringFlag{coverProfileFlag}}, "coverprofile", "") } @@ -515,7 +500,7 @@ func runBuild(ctx context.Context, cmd *base.Command, args []string) { cfg.BuildO = "" } - if cfg.Experiment.CoverageRedesign && cfg.BuildCover { + if cfg.BuildCover { load.PrepareForCoverageBuild(pkgs) } @@ -732,7 +717,7 @@ func runInstall(ctx context.Context, cmd *base.Command, args []string) { } load.CheckPackageErrors(pkgs) - if cfg.Experiment.CoverageRedesign && cfg.BuildCover { + if cfg.BuildCover { load.PrepareForCoverageBuild(pkgs) } diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go index 7b073165d5..c79d6f73ef 100644 --- a/src/cmd/go/internal/work/exec.go +++ b/src/cmd/go/internal/work/exec.go @@ -647,31 +647,18 @@ OverlayLoop: var sourceFile string var coverFile string - var key string if base, found := strings.CutSuffix(file, ".cgo1.go"); found { // cgo files have absolute paths base = filepath.Base(base) sourceFile = file coverFile = objdir + base + ".cgo1.go" - key = base + ".go" } else { sourceFile = filepath.Join(p.Dir, file) coverFile = objdir + file - key = file } coverFile = strings.TrimSuffix(coverFile, ".go") + ".cover.go" - if cfg.Experiment.CoverageRedesign { - infiles = append(infiles, sourceFile) - outfiles = append(outfiles, coverFile) - } else { - cover := p.Internal.CoverVars[key] - if cover == nil { - continue // Not covering this file. - } - if err := b.cover(a, coverFile, sourceFile, cover.Var); err != nil { - return err - } - } + infiles = append(infiles, sourceFile) + outfiles = append(outfiles, coverFile) if i < len(gofiles) { gofiles[i] = coverFile } else { @@ -679,36 +666,27 @@ OverlayLoop: } } - if cfg.Experiment.CoverageRedesign { - if len(infiles) != 0 { - // Coverage instrumentation creates new top level - // variables in the target package for things like - // meta-data containers, counter vars, etc. To avoid - // collisions with user variables, suffix the var name - // with 12 hex digits from the SHA-256 hash of the - // import path. Choice of 12 digits is historical/arbitrary, - // we just need enough of the hash to avoid accidents, - // as opposed to precluding determined attempts by - // users to break things. - sum := sha256.Sum256([]byte(a.Package.ImportPath)) - coverVar := fmt.Sprintf("goCover_%x_", sum[:6]) - mode := a.Package.Internal.Cover.Mode - if mode == "" { - panic("covermode should be set at this point") - } - if newoutfiles, err := b.cover2(a, infiles, outfiles, coverVar, mode); err != nil { - return err - } else { - outfiles = newoutfiles - gofiles = append([]string{newoutfiles[0]}, gofiles...) - } + if len(infiles) != 0 { + // Coverage instrumentation creates new top level + // variables in the target package for things like + // meta-data containers, counter vars, etc. To avoid + // collisions with user variables, suffix the var name + // with 12 hex digits from the SHA-256 hash of the + // import path. Choice of 12 digits is historical/arbitrary, + // we just need enough of the hash to avoid accidents, + // as opposed to precluding determined attempts by + // users to break things. + sum := sha256.Sum256([]byte(a.Package.ImportPath)) + coverVar := fmt.Sprintf("goCover_%x_", sum[:6]) + mode := a.Package.Internal.Cover.Mode + if mode == "" { + panic("covermode should be set at this point") + } + if newoutfiles, err := b.cover(a, infiles, outfiles, coverVar, mode); err != nil { + return err } else { - // If there are no input files passed to cmd/cover, - // then we don't want to pass -covercfg when building - // the package with the compiler, so set covermode to - // the empty string so as to signal that we need to do - // that. - p.Internal.Cover.Mode = "" + outfiles = newoutfiles + gofiles = append([]string{newoutfiles[0]}, gofiles...) } if ba, ok := a.Actor.(*buildActor); ok && ba.covMetaFileName != "" { b.cacheObjdirFile(a, cache.Default(), ba.covMetaFileName) @@ -1909,26 +1887,13 @@ func (b *Builder) installHeader(ctx context.Context, a *Action) error { // cover runs, in effect, // -// go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go -func (b *Builder) cover(a *Action, dst, src string, varName string) error { - return b.Shell(a).run(a.Objdir, "", nil, - cfg.BuildToolexec, - base.Tool("cover"), - "-mode", a.Package.Internal.Cover.Mode, - "-var", varName, - "-o", dst, - src) -} - -// cover2 runs, in effect, -// // go tool cover -pkgcfg= -mode=b.coverMode -var="varName" -o // // Return value is an updated output files list; in addition to the // regular outputs (instrumented source files) the cover tool also // writes a separate file (appearing first in the list of outputs) // that will contain coverage counters and meta-data. -func (b *Builder) cover2(a *Action, infiles, outfiles []string, varName string, mode string) ([]string, error) { +func (b *Builder) cover(a *Action, infiles, outfiles []string, varName string, mode string) ([]string, error) { pkgcfg := a.Objdir + "pkgcfg.txt" covoutputs := a.Objdir + "coveroutfiles.txt" odir := filepath.Dir(outfiles[0]) diff --git a/src/cmd/go/testdata/script/cover_build_cmdline_pkgs.txt b/src/cmd/go/testdata/script/cover_build_cmdline_pkgs.txt index e14a0784f2..ba382639e9 100644 --- a/src/cmd/go/testdata/script/cover_build_cmdline_pkgs.txt +++ b/src/cmd/go/testdata/script/cover_build_cmdline_pkgs.txt @@ -5,7 +5,6 @@ # inside and outside the standard library. [short] skip -[!GOEXPERIMENT:coverageredesign] skip # Compile an object. go tool compile -p tiny tiny/tiny.go tiny/tiny2.go diff --git a/src/cmd/go/testdata/script/cover_build_pkg_select.txt b/src/cmd/go/testdata/script/cover_build_pkg_select.txt index 447ca7788c..3a59e72e88 100644 --- a/src/cmd/go/testdata/script/cover_build_pkg_select.txt +++ b/src/cmd/go/testdata/script/cover_build_pkg_select.txt @@ -3,9 +3,6 @@ [short] skip -# Skip if new coverage is not enabled. -[!GOEXPERIMENT:coverageredesign] skip - #------------------------------------------- # Build for coverage. diff --git a/src/cmd/go/testdata/script/cover_build_simple.txt b/src/cmd/go/testdata/script/cover_build_simple.txt index b61e631abd..ee451a68ab 100644 --- a/src/cmd/go/testdata/script/cover_build_simple.txt +++ b/src/cmd/go/testdata/script/cover_build_simple.txt @@ -2,9 +2,6 @@ [short] skip -# Hard-wire new coverage for this test. -env GOEXPERIMENT=coverageredesign - # Build for coverage. go build -gcflags=-m -o example.exe -cover example/main & [race] go build -o examplewithrace.exe -race -cover example/main & diff --git a/src/cmd/go/testdata/script/cover_coverpkg_partial.txt b/src/cmd/go/testdata/script/cover_coverpkg_partial.txt index ef7a4dd2aa..efdfe2f27d 100644 --- a/src/cmd/go/testdata/script/cover_coverpkg_partial.txt +++ b/src/cmd/go/testdata/script/cover_coverpkg_partial.txt @@ -16,7 +16,6 @@ # [short] skip -[!GOEXPERIMENT:coverageredesign] skip # Test all packages with -coverpkg=./... go test -coverprofile=cov.p -coverpkg=./... ./... diff --git a/src/cmd/go/testdata/script/cover_coverpkg_with_init.txt b/src/cmd/go/testdata/script/cover_coverpkg_with_init.txt index 7a89102547..bb5bcfa823 100644 --- a/src/cmd/go/testdata/script/cover_coverpkg_with_init.txt +++ b/src/cmd/go/testdata/script/cover_coverpkg_with_init.txt @@ -5,7 +5,6 @@ # do not, some have tests and some do not. [short] skip -[!GOEXPERIMENT:coverageredesign] skip # Verify correct statements percentages. We have a total of 10 # statements in the packages matched by "./..."; package "a" (for diff --git a/src/cmd/go/testdata/script/cover_list.txt b/src/cmd/go/testdata/script/cover_list.txt index 1b1f326662..7ecc5c05eb 100644 --- a/src/cmd/go/testdata/script/cover_list.txt +++ b/src/cmd/go/testdata/script/cover_list.txt @@ -3,7 +3,6 @@ # build arguments (such as -cover, -covermode). See issue #57785. [short] skip -[!GOEXPERIMENT:coverageredesign] skip env GOBIN=$WORK/bin diff --git a/src/cmd/go/testdata/script/cover_main_import_path.txt b/src/cmd/go/testdata/script/cover_main_import_path.txt index e8696e27e2..3a2f3c3ee2 100644 --- a/src/cmd/go/testdata/script/cover_main_import_path.txt +++ b/src/cmd/go/testdata/script/cover_main_import_path.txt @@ -4,7 +4,6 @@ # the "main" package is handled. See issue 57169 for details. [short] skip -[!GOEXPERIMENT:coverageredesign] skip # Build this program with -cover and run to collect a profile. diff --git a/src/cmd/go/testdata/script/cover_statements.txt b/src/cmd/go/testdata/script/cover_statements.txt index 030177cb8b..f0391ede22 100644 --- a/src/cmd/go/testdata/script/cover_statements.txt +++ b/src/cmd/go/testdata/script/cover_statements.txt @@ -10,35 +10,32 @@ env GOCACHE=$WORK/cache # Initial run with simple coverage. go test -cover ./pkg1 ./pkg2 ./pkg3 ./pkg4 -[!GOEXPERIMENT:coverageredesign] stdout 'pkg1 \[no test files\]' -[GOEXPERIMENT:coverageredesign] stdout 'pkg1 coverage: 0.0% of statements' +stdout 'pkg1 coverage: 0.0% of statements' stdout 'pkg2 \S+ coverage: 0.0% of statements \[no tests to run\]' stdout 'pkg3 \S+ coverage: 100.0% of statements' stdout 'pkg4 \S+ coverage: \[no statements\]' # Second run to make sure that caching works properly. go test -x -cover ./pkg1 ./pkg2 ./pkg3 ./pkg4 -[!GOEXPERIMENT:coverageredesign] stdout 'pkg1 \[no test files\]' -[GOEXPERIMENT:coverageredesign] stdout 'pkg1 coverage: 0.0% of statements' +stdout 'pkg1 coverage: 0.0% of statements' stdout 'pkg2 \S+ coverage: 0.0% of statements \[no tests to run\]' stdout 'pkg3 \S+ coverage: 100.0% of statements' stdout 'pkg4 \S+ coverage: \[no statements\]' -[GOEXPERIMENT:coverageredesign] ! stderr 'link(\.exe"?)? -' +! stderr 'link(\.exe"?)? -' ! stderr 'compile(\.exe"?)? -' ! stderr 'cover(\.exe"?)? -' -[GOEXPERIMENT:coverageredesign] stderr 'covdata(\.exe"?)? percent' +stderr 'covdata(\.exe"?)? percent' # Now add in -coverprofile. go test -cover -coverprofile=cov.dat ./pkg1 ./pkg2 ./pkg3 ./pkg4 -[!GOEXPERIMENT:coverageredesign] stdout 'pkg1 \[no test files\]' -[GOEXPERIMENT:coverageredesign] stdout 'pkg1 coverage: 0.0% of statements' +stdout 'pkg1 coverage: 0.0% of statements' stdout 'pkg2 \S+ coverage: 0.0% of statements \[no tests to run\]' stdout 'pkg3 \S+ coverage: 100.0% of statements' stdout 'pkg4 \S+ coverage: \[no statements\]' # Validate go tool cover -func=cov.dat -[GOEXPERIMENT:coverageredesign] stdout 'pkg1/a.go:5:\s+F\s+0.0%' +stdout 'pkg1/a.go:5:\s+F\s+0.0%' -- go.mod -- module m diff --git a/src/cmd/go/testdata/script/cover_sync_atomic_import.txt b/src/cmd/go/testdata/script/cover_sync_atomic_import.txt index a098979797..7beea137e2 100644 --- a/src/cmd/go/testdata/script/cover_sync_atomic_import.txt +++ b/src/cmd/go/testdata/script/cover_sync_atomic_import.txt @@ -1,6 +1,5 @@ [short] skip [compiler:gccgo] skip # gccgo has no cover tool -[!GOEXPERIMENT:coverageredesign] skip go test -short -cover -covermode=atomic -coverpkg=coverdep/p1 coverdep diff --git a/src/cmd/go/testdata/script/cover_test_pkgselect.txt b/src/cmd/go/testdata/script/cover_test_pkgselect.txt index 97a1d2cbbb..8e47d142d4 100644 --- a/src/cmd/go/testdata/script/cover_test_pkgselect.txt +++ b/src/cmd/go/testdata/script/cover_test_pkgselect.txt @@ -1,9 +1,6 @@ [short] skip -# Hard-wire new coverage for this test. -env GOEXPERIMENT=coverageredesign - # Baseline run. go test -cover example/foo stdout 'coverage: 50.0% of statements$' diff --git a/src/cmd/go/testdata/script/cover_var_init_order.txt b/src/cmd/go/testdata/script/cover_var_init_order.txt index 37e07b71f6..a9ee63c78c 100644 --- a/src/cmd/go/testdata/script/cover_var_init_order.txt +++ b/src/cmd/go/testdata/script/cover_var_init_order.txt @@ -4,9 +4,6 @@ [short] skip -# Skip if new coverage is turned off. -[!GOEXPERIMENT:coverageredesign] skip - go test -cover example -- go.mod -- diff --git a/src/cmd/go/testdata/script/testing_coverage.txt b/src/cmd/go/testdata/script/testing_coverage.txt index 6cf6adbbd7..bf4dc83107 100644 --- a/src/cmd/go/testdata/script/testing_coverage.txt +++ b/src/cmd/go/testdata/script/testing_coverage.txt @@ -2,7 +2,6 @@ # Rudimentary test of testing.Coverage(). [short] skip -[!GOEXPERIMENT:coverageredesign] skip # Simple test. go test -v -cover -count=1 diff --git a/src/cmd/internal/cov/read_test.go b/src/cmd/internal/cov/read_test.go index fa2151a09e..cef03fa323 100644 --- a/src/cmd/internal/cov/read_test.go +++ b/src/cmd/internal/cov/read_test.go @@ -11,7 +11,6 @@ import ( "internal/coverage/decodecounter" "internal/coverage/decodemeta" "internal/coverage/pods" - "internal/goexperiment" "internal/testenv" "os" "path/filepath" @@ -45,9 +44,6 @@ 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. diff --git a/src/internal/buildcfg/exp.go b/src/internal/buildcfg/exp.go index 332c9afa57..9c9ec2c711 100644 --- a/src/internal/buildcfg/exp.go +++ b/src/internal/buildcfg/exp.go @@ -74,13 +74,12 @@ func ParseGOEXPERIMENT(goos, goarch, goexp string) (*ExperimentFlags, error) { } baseline := goexperiment.Flags{ - RegabiWrappers: regabiSupported, - RegabiArgs: regabiSupported, - CoverageRedesign: true, - AliasTypeParams: true, - SwissMap: true, - SpinbitMutex: haveXchg8, - SyncHashTrieMap: true, + RegabiWrappers: regabiSupported, + RegabiArgs: regabiSupported, + AliasTypeParams: true, + SwissMap: true, + SpinbitMutex: haveXchg8, + SyncHashTrieMap: true, } // Start with the statically enabled set of experiments. diff --git a/src/internal/coverage/cfile/emitdata_test.go b/src/internal/coverage/cfile/emitdata_test.go index c522048173..d127c6b2a9 100644 --- a/src/internal/coverage/cfile/emitdata_test.go +++ b/src/internal/coverage/cfile/emitdata_test.go @@ -7,7 +7,6 @@ package cfile import ( "fmt" "internal/coverage" - "internal/goexperiment" "internal/platform" "internal/testenv" "os" @@ -25,9 +24,6 @@ func TestCoverageApis(t *testing.T) { if testing.Short() { t.Skipf("skipping test: too long for short mode") } - if !goexperiment.CoverageRedesign { - t.Skipf("skipping new coverage tests (experiment not enabled)") - } testenv.MustHaveGoBuild(t) dir := t.TempDir() if fixedTestDir { @@ -465,9 +461,6 @@ func TestIssue56006EmitDataRaceCoverRunningGoroutine(t *testing.T) { if testing.Short() { t.Skipf("skipping test: too long for short mode") } - if !goexperiment.CoverageRedesign { - t.Skipf("skipping new coverage tests (experiment not enabled)") - } // This test requires "go test -race -cover", meaning that we need // go build, go run, and "-race" support. diff --git a/src/internal/coverage/cfile/ts_test.go b/src/internal/coverage/cfile/ts_test.go index d3441821a4..d106d3b132 100644 --- a/src/internal/coverage/cfile/ts_test.go +++ b/src/internal/coverage/cfile/ts_test.go @@ -8,7 +8,6 @@ import ( "encoding/json" "flag" "internal/coverage" - "internal/goexperiment" "internal/testenv" "os" "os/exec" @@ -32,9 +31,6 @@ func testGoCoverDir(t *testing.T) string { // relying on other test paths will provide a better signal when // running "go test -cover" for this package). func TestTestSupport(t *testing.T) { - if !goexperiment.CoverageRedesign { - return - } if testing.CoverMode() == "" { return } @@ -128,9 +124,6 @@ func genAuxMeta(t *testing.T, dstdir string) (string, string) { } func TestAuxMetaDataFiles(t *testing.T) { - if !goexperiment.CoverageRedesign { - return - } if testing.CoverMode() == "" { return } diff --git a/src/internal/goexperiment/exp_coverageredesign_off.go b/src/internal/goexperiment/exp_coverageredesign_off.go deleted file mode 100644 index 2c33177322..0000000000 --- a/src/internal/goexperiment/exp_coverageredesign_off.go +++ /dev/null @@ -1,8 +0,0 @@ -// Code generated by mkconsts.go. DO NOT EDIT. - -//go:build !goexperiment.coverageredesign - -package goexperiment - -const CoverageRedesign = false -const CoverageRedesignInt = 0 diff --git a/src/internal/goexperiment/exp_coverageredesign_on.go b/src/internal/goexperiment/exp_coverageredesign_on.go deleted file mode 100644 index 3fc6c2f70a..0000000000 --- a/src/internal/goexperiment/exp_coverageredesign_on.go +++ /dev/null @@ -1,8 +0,0 @@ -// Code generated by mkconsts.go. DO NOT EDIT. - -//go:build goexperiment.coverageredesign - -package goexperiment - -const CoverageRedesign = true -const CoverageRedesignInt = 1 diff --git a/src/internal/goexperiment/flags.go b/src/internal/goexperiment/flags.go index 948ed5c802..dff5255e00 100644 --- a/src/internal/goexperiment/flags.go +++ b/src/internal/goexperiment/flags.go @@ -83,10 +83,6 @@ type Flags struct { // by default. HeapMinimum512KiB bool - // CoverageRedesign enables the new compiler-based code coverage - // tooling. - CoverageRedesign bool - // Arenas causes the "arena" standard library package to be visible // to the outside world. Arenas bool diff --git a/src/testing/cover.go b/src/testing/cover.go index 6ad43ab9ff..74c97d471e 100644 --- a/src/testing/cover.go +++ b/src/testing/cover.go @@ -6,13 +6,6 @@ package testing -import ( - "fmt" - "internal/goexperiment" - "os" - "sync/atomic" -) - // CoverBlock records the coverage data for a single basic block. // The fields are 1-indexed, as in an editor: The opening line of // the file is number 1, for example. Columns are measured @@ -27,8 +20,6 @@ type CoverBlock struct { Stmts uint16 // Number of statements included in this block. } -var cover Cover - // Cover records information about test coverage checking. // NOTE: This struct is internal to the testing infrastructure and may change. // It is not covered (yet) by the Go 1 compatibility guidelines. @@ -39,86 +30,8 @@ type Cover struct { CoveredPackages string } -// Coverage reports the current code coverage as a fraction in the range [0, 1]. -// If coverage is not enabled, Coverage returns 0. -// -// When running a large set of sequential test cases, checking Coverage after each one -// can be useful for identifying which test cases exercise new code paths. -// It is not a replacement for the reports generated by 'go test -cover' and -// 'go tool cover'. -func Coverage() float64 { - if goexperiment.CoverageRedesign { - return coverage2() - } - var n, d int64 - for _, counters := range cover.Counters { - for i := range counters { - if atomic.LoadUint32(&counters[i]) > 0 { - n++ - } - d++ - } - } - if d == 0 { - return 0 - } - return float64(n) / float64(d) -} - // RegisterCover records the coverage data accumulators for the tests. // NOTE: This function is internal to the testing infrastructure and may change. // It is not covered (yet) by the Go 1 compatibility guidelines. func RegisterCover(c Cover) { - cover = c -} - -// mustBeNil checks the error and, if present, reports it and exits. -func mustBeNil(err error) { - if err != nil { - fmt.Fprintf(os.Stderr, "testing: %s\n", err) - os.Exit(2) - } -} - -// coverReport reports the coverage percentage and writes a coverage profile if requested. -func coverReport() { - if goexperiment.CoverageRedesign { - coverReport2() - return - } - var f *os.File - var err error - if *coverProfile != "" { - f, err = os.Create(toOutputDir(*coverProfile)) - mustBeNil(err) - fmt.Fprintf(f, "mode: %s\n", cover.Mode) - defer func() { mustBeNil(f.Close()) }() - } - - var active, total int64 - var count uint32 - for name, counts := range cover.Counters { - blocks := cover.Blocks[name] - for i := range counts { - stmts := int64(blocks[i].Stmts) - total += stmts - count = atomic.LoadUint32(&counts[i]) // For -mode=atomic. - if count > 0 { - active += stmts - } - if f != nil { - _, err := fmt.Fprintf(f, "%s:%d.%d,%d.%d %d %d\n", name, - blocks[i].Line0, blocks[i].Col0, - blocks[i].Line1, blocks[i].Col1, - stmts, - count) - mustBeNil(err) - } - } - } - if total == 0 { - fmt.Println("coverage: [no statements]") - return - } - fmt.Printf("coverage: %.1f%% of statements%s\n", 100*float64(active)/float64(total), cover.CoveredPackages) } diff --git a/src/testing/newcover.go b/src/testing/newcover.go index ad2f622640..5a8d728831 100644 --- a/src/testing/newcover.go +++ b/src/testing/newcover.go @@ -8,49 +8,52 @@ package testing import ( "fmt" - "internal/goexperiment" "os" _ "unsafe" // for linkname ) -// cover2 variable stores the current coverage mode and a +// cover variable stores the current coverage mode and a // tear-down function to be called at the end of the testing run. -var cover2 struct { +var cover struct { mode string tearDown func(coverprofile string, gocoverdir string) (string, error) snapshotcov func() float64 } -// registerCover2 is invoked during "go test -cover" runs. +// registerCover is invoked during "go test -cover" runs. // It is used to record a 'tear down' function // (to be called when the test is complete) and the coverage mode. -func registerCover2(mode string, tearDown func(coverprofile string, gocoverdir string) (string, error), snapcov func() float64) { +func registerCover(mode string, tearDown func(coverprofile string, gocoverdir string) (string, error), snapcov func() float64) { if mode == "" { return } - cover2.mode = mode - cover2.tearDown = tearDown - cover2.snapshotcov = snapcov + cover.mode = mode + cover.tearDown = tearDown + cover.snapshotcov = snapcov } -// coverReport2 invokes a callback in _testmain.go that will +// coverReport reports the coverage percentage and +// writes a coverage profile if requested. +// This invokes a callback in _testmain.go that will // emit coverage data at the point where test execution is complete, // for "go test -cover" runs. -func coverReport2() { - if !goexperiment.CoverageRedesign { - panic("unexpected") - } - if errmsg, err := cover2.tearDown(*coverProfile, *gocoverdir); err != nil { +func coverReport() { + if errmsg, err := cover.tearDown(*coverProfile, *gocoverdir); err != nil { fmt.Fprintf(os.Stderr, "%s: %v\n", errmsg, err) os.Exit(2) } } -// coverage2 returns a rough "coverage percentage so far" -// number to support the testing.Coverage() function. -func coverage2() float64 { - if cover2.mode == "" { +// Coverage reports the current code coverage as a fraction in the range [0, 1]. +// If coverage is not enabled, Coverage returns 0. +// +// When running a large set of sequential test cases, checking Coverage after each one +// can be useful for identifying which test cases exercise new code paths. +// It is not a replacement for the reports generated by 'go test -cover' and +// 'go tool cover'. +func Coverage() float64 { + if cover.mode == "" { return 0.0 } - return cover2.snapshotcov() + return cover.snapshotcov() } diff --git a/src/testing/testing.go b/src/testing/testing.go index 3833bfc84b..2bfa4b6db0 100644 --- a/src/testing/testing.go +++ b/src/testing/testing.go @@ -403,7 +403,6 @@ import ( "errors" "flag" "fmt" - "internal/goexperiment" "internal/race" "io" "math/rand" @@ -700,10 +699,7 @@ func Testing() bool { // values are "set", "count", or "atomic". The return value will be // empty if test coverage is not enabled. func CoverMode() string { - if goexperiment.CoverageRedesign { - return cover2.mode - } - return cover.Mode + return cover.mode } // Verbose reports whether the -test.v flag is set. @@ -2021,7 +2017,7 @@ type testDeps interface { // It is not meant to be called directly and is not subject to the Go 1 compatibility document. // It may change signature from release to release. func MainStart(deps testDeps, tests []InternalTest, benchmarks []InternalBenchmark, fuzzTargets []InternalFuzzTarget, examples []InternalExample) *M { - registerCover2(deps.InitRuntimeCoverage()) + registerCover(deps.InitRuntimeCoverage()) Init() return &M{ deps: deps, -- 2.51.0