Commit 5e21032b authored by Bryan C. Mills's avatar Bryan C. Mills

Revert "cmd/go: move automatic testing.Init call into generated test code"

This reverts CL 176098.

Reason for revert: added complexity, but did not completely fix the
underlying problem. A complete solution would not be worth the
complexity, and as a partial solution this is probably not worth the
complexity either.

Updates #31859

Change-Id: Ifd34c292fd1b811c60afe3c339e5edd3f37190c8
Reviewed-on: https://go-review.googlesource.com/c/go/+/186817
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
Reviewed-by: default avatarCaleb Spare <cespare@gmail.com>
parent f518a96e
...@@ -3176,6 +3176,12 @@ func TestGoTestFooTestWorks(t *testing.T) { ...@@ -3176,6 +3176,12 @@ func TestGoTestFooTestWorks(t *testing.T) {
tg.run("test", "testdata/standalone_test.go") tg.run("test", "testdata/standalone_test.go")
} }
func TestGoTestTestMainSeesTestingFlags(t *testing.T) {
tg := testgo(t)
defer tg.cleanup()
tg.run("test", "testdata/standalone_testmain_flag_test.go")
}
// Issue 22388 // Issue 22388
func TestGoTestMainWithWrongSignature(t *testing.T) { func TestGoTestMainWithWrongSignature(t *testing.T) {
tg := testgo(t) tg := testgo(t)
......
...@@ -459,7 +459,7 @@ func runList(cmd *base.Command, args []string) { ...@@ -459,7 +459,7 @@ func runList(cmd *base.Command, args []string) {
} }
if pmain != nil { if pmain != nil {
pkgs = append(pkgs, pmain) pkgs = append(pkgs, pmain)
data := pmain.Internal.TestmainGo data := *pmain.Internal.TestmainGo
h := cache.NewHash("testmain") h := cache.NewHash("testmain")
h.Write([]byte("testmain\n")) h.Write([]byte("testmain\n"))
h.Write(data) h.Write(data)
......
...@@ -177,8 +177,7 @@ type PackageInternal struct { ...@@ -177,8 +177,7 @@ type PackageInternal struct {
OmitDebug bool // tell linker not to write debug information OmitDebug bool // tell linker not to write debug information
GobinSubdir bool // install target would be subdir of GOBIN GobinSubdir bool // install target would be subdir of GOBIN
BuildInfo string // add this info to package main BuildInfo string // add this info to package main
TestinginitGo []byte // content for _testinginit.go TestmainGo *[]byte // content for _testmain.go
TestmainGo []byte // content for _testmain.go
Asmflags []string // -asmflags for this package Asmflags []string // -asmflags for this package
Gcflags []string // -gcflags for this package Gcflags []string // -gcflags for this package
......
...@@ -102,7 +102,6 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * ...@@ -102,7 +102,6 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest *
var stk ImportStack var stk ImportStack
stk.Push(p.ImportPath + " (test)") stk.Push(p.ImportPath + " (test)")
rawTestImports := str.StringList(p.TestImports) rawTestImports := str.StringList(p.TestImports)
var ptestImportsTesting, pxtestImportsTesting bool
for i, path := range p.TestImports { for i, path := range p.TestImports {
p1 := loadImport(pre, path, p.Dir, p, &stk, p.Internal.Build.TestImportPos[path], ResolveImport) p1 := loadImport(pre, path, p.Dir, p, &stk, p.Internal.Build.TestImportPos[path], ResolveImport)
if str.Contains(p1.Deps, p.ImportPath) || p1.ImportPath == p.ImportPath { if str.Contains(p1.Deps, p.ImportPath) || p1.ImportPath == p.ImportPath {
...@@ -117,9 +116,6 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * ...@@ -117,9 +116,6 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest *
} }
p.TestImports[i] = p1.ImportPath p.TestImports[i] = p1.ImportPath
imports = append(imports, p1) imports = append(imports, p1)
if path == "testing" {
ptestImportsTesting = true
}
} }
stk.Pop() stk.Pop()
stk.Push(p.ImportPath + "_test") stk.Push(p.ImportPath + "_test")
...@@ -133,9 +129,6 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * ...@@ -133,9 +129,6 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest *
ximports = append(ximports, p1) ximports = append(ximports, p1)
} }
p.XTestImports[i] = p1.ImportPath p.XTestImports[i] = p1.ImportPath
if path == "testing" {
pxtestImportsTesting = true
}
} }
stk.Pop() stk.Pop()
...@@ -145,9 +138,6 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * ...@@ -145,9 +138,6 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest *
*ptest = *p *ptest = *p
ptest.Error = ptestErr ptest.Error = ptestErr
ptest.ForTest = p.ImportPath ptest.ForTest = p.ImportPath
if ptestImportsTesting {
ptest.Internal.TestinginitGo = formatTestinginit(p)
}
ptest.GoFiles = nil ptest.GoFiles = nil
ptest.GoFiles = append(ptest.GoFiles, p.GoFiles...) ptest.GoFiles = append(ptest.GoFiles, p.GoFiles...)
ptest.GoFiles = append(ptest.GoFiles, p.TestGoFiles...) ptest.GoFiles = append(ptest.GoFiles, p.TestGoFiles...)
...@@ -212,9 +202,6 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * ...@@ -212,9 +202,6 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest *
Gccgoflags: p.Internal.Gccgoflags, Gccgoflags: p.Internal.Gccgoflags,
}, },
} }
if pxtestImportsTesting {
pxtest.Internal.TestinginitGo = formatTestinginit(pxtest)
}
if pxtestNeedsPtest { if pxtestNeedsPtest {
pxtest.Internal.Imports = append(pxtest.Internal.Imports, ptest) pxtest.Internal.Imports = append(pxtest.Internal.Imports, ptest)
} }
...@@ -337,7 +324,9 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * ...@@ -337,7 +324,9 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest *
if err != nil && pmain.Error == nil { if err != nil && pmain.Error == nil {
pmain.Error = &PackageError{Err: err.Error()} pmain.Error = &PackageError{Err: err.Error()}
} }
pmain.Internal.TestmainGo = data if data != nil {
pmain.Internal.TestmainGo = &data
}
return pmain, ptest, pxtest return pmain, ptest, pxtest
} }
...@@ -485,15 +474,6 @@ func loadTestFuncs(ptest *Package) (*testFuncs, error) { ...@@ -485,15 +474,6 @@ func loadTestFuncs(ptest *Package) (*testFuncs, error) {
return t, err return t, err
} }
// formatTestinginit returns the content of the _testinginit.go file for p.
func formatTestinginit(p *Package) []byte {
var buf bytes.Buffer
if err := testinginitTmpl.Execute(&buf, p); err != nil {
panic("testinginit template execution failed") // shouldn't be possible
}
return buf.Bytes()
}
// formatTestmain returns the content of the _testmain.go file for t. // formatTestmain returns the content of the _testmain.go file for t.
func formatTestmain(t *testFuncs) ([]byte, error) { func formatTestmain(t *testFuncs) ([]byte, error) {
var buf bytes.Buffer var buf bytes.Buffer
...@@ -623,23 +603,6 @@ func checkTestFunc(fn *ast.FuncDecl, arg string) error { ...@@ -623,23 +603,6 @@ func checkTestFunc(fn *ast.FuncDecl, arg string) error {
return nil return nil
} }
var testinginitTmpl = lazytemplate.New("init", `
package {{.Name}}
import _go_testing "testing"
{{/*
Call testing.Init before any other user initialization code runs.
(This file is passed to the compiler first.)
This provides the illusion of the old behavior where testing flags
were registered as part of the testing package's initialization.
*/}}
var _ = func() bool {
_go_testing.Init()
return true
}()
`)
var testmainTmpl = lazytemplate.New("main", ` var testmainTmpl = lazytemplate.New("main", `
// Code generated by 'go test'. DO NOT EDIT. // Code generated by 'go test'. DO NOT EDIT.
......
...@@ -843,7 +843,7 @@ func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, prin ...@@ -843,7 +843,7 @@ func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, prin
if !cfg.BuildN { if !cfg.BuildN {
// writeTestmain writes _testmain.go, // writeTestmain writes _testmain.go,
// using the test description gathered in t. // using the test description gathered in t.
if err := ioutil.WriteFile(testDir+"_testmain.go", pmain.Internal.TestmainGo, 0666); err != nil { if err := ioutil.WriteFile(testDir+"_testmain.go", *pmain.Internal.TestmainGo, 0666); err != nil {
return nil, nil, nil, err return nil, nil, nil, err
} }
} }
......
...@@ -542,15 +542,6 @@ func (b *Builder) build(a *Action) (err error) { ...@@ -542,15 +542,6 @@ func (b *Builder) build(a *Action) (err error) {
} }
} }
// Write out the _testinginit.go file for any test packages that import "testing".
if a.Package.Internal.TestinginitGo != nil {
initfile := objdir + "_testinginit.go"
if err := b.writeFile(initfile, a.Package.Internal.TestinginitGo); err != nil {
return err
}
gofiles = append([]string{initfile}, gofiles...)
}
// Run cgo. // Run cgo.
if a.Package.UsesCgo() || a.Package.UsesSwig() { if a.Package.UsesCgo() || a.Package.UsesSwig() {
// In a package using cgo, cgo compiles the C, C++ and assembly files with gcc. // In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.
......
// Copyright 2019 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 flag_test package flag_test
import ( import (
"flag" "flag"
"log"
"testing" "testing"
) )
var v = flag.Int("v", 0, "v flag") var v = flag.Int("v", 0, "v flag")
// Run this as go test pkg -args -v=7 // Run this as go test pkg -v=7
func TestVFlagIsSet(t *testing.T) { func TestVFlagIsSet(t *testing.T) {
if *v != 7 { if *v != 7 {
t.Fatal("v flag not set") log.Fatal("v flag not set")
} }
} }
# Tests for automatic testing.Init calls when using 'go test'.
env GO111MODULE=on
# A TestMain should be able to access testing flags if it calls flag.Parse
# without needing to use testing.Init.
# Test code can use the name 'testing' without colliding with generated
# testinginit code.
# Tests running under 'go test' should observe that testing.Init is called
# before any user package initialization code runs.
go test
stdout TestMain
stdout TestInit
stdout TestExt
-- go.mod --
module m
-- init_test.go --
package testinitflag
import (
"flag"
"fmt"
"os"
Testing "testing"
)
func testFlagsInitialized() bool {
found := false
flag.VisitAll(func(f *flag.Flag) {
if f.Name == "test.count" {
found = true
}
})
return found
}
var testing int
var testingInitAtInitialization = testFlagsInitialized()
func TestInit(t *Testing.T) {
if !testingInitAtInitialization {
t.Fatal("testing.Init not called before package initialization")
}
fmt.Printf("TestInit\n")
}
func TestMain(m *Testing.M) {
fmt.Printf("TestMain\n")
flag.Parse()
if !testFlagsInitialized() {
fmt.Println("testing flags not registered")
os.Exit(1)
}
os.Exit(m.Run())
}
-- external_test.go --
package testinitflag_test
import (
"flag"
"fmt"
Testing "testing"
)
func testFlagsInitialized() bool {
found := false
flag.VisitAll(func(f *flag.Flag) {
if f.Name == "test.count" {
found = true
}
})
return found
}
var testing int
var testingInitAtInitialization = testFlagsInitialized()
func TestExt(t *Testing.T) {
fmt.Printf("TestExt\n")
if !testingInitAtInitialization {
t.Fatal("testing.Init not called before package initialization")
}
}
// Copyright 2019 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 standalone_testmain_flag_test
import (
"flag"
"fmt"
"os"
"testing"
)
func TestMain(m *testing.M) {
// A TestMain should be able to access testing flags if it calls
// flag.Parse without needing to use testing.Init.
flag.Parse()
found := false
flag.VisitAll(func(f *flag.Flag) {
if f.Name == "test.count" {
found = true
}
})
if !found {
fmt.Println("testing flags not registered")
os.Exit(1)
}
os.Exit(m.Run())
}
...@@ -1075,11 +1075,6 @@ type testDeps interface { ...@@ -1075,11 +1075,6 @@ type testDeps interface {
// It is not meant to be called directly and is not subject to the Go 1 compatibility document. // 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. // It may change signature from release to release.
func MainStart(deps testDeps, tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) *M { func MainStart(deps testDeps, tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) *M {
// In most cases, Init has already been called by the testinginit code
// that 'go test' injects into test packages.
// Call it again here to handle cases such as:
// - test packages that don't import "testing" (such as example-only packages)
// - direct use of MainStart (though that isn't well-supported)
Init() Init()
return &M{ return &M{
deps: deps, deps: deps,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment