pmain.Imports = pmain.Imports[:w]
pmain.Internal.RawImports = str.StringList(pmain.Imports)
- if ptest != p {
- // We have made modifications to the package p being tested
- // and are rebuilding p (as ptest).
- // Arrange to rebuild all packages q such that
- // the test depends on q and q depends on p.
- // This makes sure that q sees the modifications to p.
- // Strictly speaking, the rebuild is only necessary if the
- // modifications to p change its export metadata, but
- // determining that is a bit tricky, so we rebuild always.
- recompileForTest(pmain, p, ptest, pxtest)
- }
+ // Replace pmain's transitive dependencies with test copies, as necessary.
+ recompileForTest(pmain, p, ptest, pxtest)
// Should we apply coverage analysis locally,
// only for this package and only for this test?
return stk
}
+// recompileForTest copies and replaces certain packages in pmain's dependency
+// graph. This is necessary for two reasons. First, if ptest is different than
+// preal, packages that import the package under test should get ptest instead
+// of preal. This is particularly important if pxtest depends on functionality
+// exposed in test sources in ptest. Second, if there is a main package
+// (other than pmain) anywhere, we need to clear p.Internal.BuildInfo in
+// the test copy to prevent link conflicts. This may happen if both -coverpkg
+// and the command line patterns include multiple main packages.
func recompileForTest(pmain, preal, ptest, pxtest *Package) {
// The "test copy" of preal is ptest.
// For each package that depends on preal, make a "test copy"
// Don't compile build info from a main package. This can happen
// if -coverpkg patterns include main packages, since those packages
- // are imported by pmain.
+ // are imported by pmain. See golang.org/issue/30907.
if p.Internal.BuildInfo != "" && p != pmain {
split()
}
[short] skip
-go test -coverpkg=all ./main1 ./main2
+go test -coverpkg=all ./...
-- go.mod --
module example.com/cov
--- main1/main1.go --
+-- mainonly/mainonly.go --
package main
func main() {}
--- main1/main1_test.go --
+-- mainwithtest/mainwithtest.go --
package main
-import "testing"
+func main() {}
-func TestMain1(t *testing.T) {}
+func Foo() {}
--- main2/main2.go --
+-- mainwithtest/mainwithtest_test.go --
package main
-func main() {}
+import "testing"
--- main2/main2_test.go --
-package main
+func TestFoo(t *testing.T) {
+ Foo()
+}
-import "testing"
+-- xtest/x.go --
+package x
-func TestMain2(t *testing.T) {}
+-- xtest/x_test.go --
+package x_test
+
+import "testing"
+func TestX(t *testing.T) {}