mirror of
https://github.com/golang/go
synced 2024-11-19 02:04:42 -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"
|
"go/token"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@ -34,7 +35,24 @@ func (state *golistState) processGolistOverlay(response *responseDeduper) (modif
|
|||||||
// potentially modifying the transitive set of dependencies).
|
// potentially modifying the transitive set of dependencies).
|
||||||
var overlayAddsImports bool
|
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)
|
base := filepath.Base(opath)
|
||||||
dir := filepath.Dir(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
|
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) {
|
func TestAdHocPackagesBadImport(t *testing.T) {
|
||||||
// This test doesn't use packagestest because we are testing ad-hoc packages,
|
// This test doesn't use packagestest because we are testing ad-hoc packages,
|
||||||
// which are outside of $GOPATH and outside of a module.
|
// which are outside of $GOPATH and outside of a module.
|
||||||
|
Loading…
Reference in New Issue
Block a user