mirror of
https://github.com/golang/go
synced 2024-11-19 00:44:40 -07:00
go/packages: fix flaky failure creating non-test package from overlay
The core of processGolistOverlay was a map iteration, which is nondeterministic. When creating both a non-test and test package, we would sometimes encounter the test file before the non-test file. In that case, for reasons I didn't bother tracking down, we would never create the non-test package. Rather than doing complicated bookkeeping to fix the problem, simply process non-test before test, and make the loop deterministic to save all of our sanity. Updates golang/go#36661. Change-Id: I1f76869fa52794ac8ae96e22ad06a2b1e1861995 Reviewed-on: https://go-review.googlesource.com/c/tools/+/216717 Reviewed-by: Rebecca Stambler <rstambler@golang.org> Run-TryBot: Heschi Kreinick <heschi@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
ae42f3cd5c
commit
520188d60f
@ -7,6 +7,7 @@ import (
|
||||
"go/token"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
@ -34,7 +35,24 @@ func (state *golistState) processGolistOverlay(response *responseDeduper) (modif
|
||||
// potentially modifying the transitive set of dependencies).
|
||||
var overlayAddsImports bool
|
||||
|
||||
for opath, contents := range state.cfg.Overlay {
|
||||
// If both a package and its test package are created by the overlay, we
|
||||
// need the real package first. Process all non-test files before test
|
||||
// files, and make the whole process deterministic while we're at it.
|
||||
var overlayFiles []string
|
||||
for opath := range state.cfg.Overlay {
|
||||
overlayFiles = append(overlayFiles, opath)
|
||||
}
|
||||
sort.Slice(overlayFiles, func(i, j int) bool {
|
||||
iTest := strings.HasSuffix(overlayFiles[i], "_test.go")
|
||||
jTest := strings.HasSuffix(overlayFiles[j], "_test.go")
|
||||
if iTest != jTest {
|
||||
return !iTest // non-tests are before tests.
|
||||
}
|
||||
return overlayFiles[i] < overlayFiles[j]
|
||||
})
|
||||
|
||||
for _, opath := range overlayFiles {
|
||||
contents := state.cfg.Overlay[opath]
|
||||
base := filepath.Base(opath)
|
||||
dir := filepath.Dir(opath)
|
||||
var pkg *Package // if opath belongs to both a package and its test variant, this will be the test variant
|
||||
|
@ -1104,6 +1104,33 @@ func testNewPackagesInOverlay(t *testing.T, exporter packagestest.Exporter) {
|
||||
}
|
||||
}
|
||||
|
||||
// Test that we can create a package and its test package in an overlay.
|
||||
func TestOverlayNewPackageAndTest(t *testing.T) { packagestest.TestAll(t, testOverlayNewPackageAndTest) }
|
||||
func testOverlayNewPackageAndTest(t *testing.T, exporter packagestest.Exporter) {
|
||||
exported := packagestest.Export(t, exporter, []packagestest.Module{
|
||||
{
|
||||
Name: "golang.org/fake",
|
||||
Files: map[string]interface{}{
|
||||
"foo.txt": "placeholder",
|
||||
},
|
||||
},
|
||||
})
|
||||
defer exported.Cleanup()
|
||||
|
||||
dir := filepath.Dir(exported.File("golang.org/fake", "foo.txt"))
|
||||
exported.Config.Overlay = map[string][]byte{
|
||||
filepath.Join(dir, "a.go"): []byte(`package a;`),
|
||||
filepath.Join(dir, "a_test.go"): []byte(`package a; import "testing";`),
|
||||
}
|
||||
initial, err := packages.Load(exported.Config, "file="+filepath.Join(dir, "a.go"), "file="+filepath.Join(dir, "a_test.go"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(initial) != 2 {
|
||||
t.Errorf("got %v packages, wanted %v", len(initial), 2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdHocPackagesBadImport(t *testing.T) {
|
||||
// This test doesn't use packagestest because we are testing ad-hoc packages,
|
||||
// which are outside of $GOPATH and outside of a module.
|
||||
|
Loading…
Reference in New Issue
Block a user