From 4743911fe125050c427ad30a5bd2e132f64fcb54 Mon Sep 17 00:00:00 2001 From: Albert Le Batteux Date: Thu, 23 Nov 2023 18:11:10 +0000 Subject: [PATCH] fix(cmd/gno): allow testing packages which contain test files with `package x_test` (#1330) Reproduce error from #638 package ./. already exists in cache EDIT: And fixed it :tada: ``` $ go run ./gnovm/cmd/gno test --verbose ./examples/gno.land/p/demo/lol panic: package gno.land/p/demo/lol already exists in cache goroutine 1 [running]: github.com/gnolang/gno/gnovm/pkg/gnolang.(*defaultStore).SetCachePackage(0x1400020a240, 0x14005f23e00) /Users/albttx/go/src/github.com/gnolang/gno/gnovm/pkg/gnolang/store.go:207 +0x10c github.com/gnolang/gno/gnovm/pkg/gnolang.(*Machine).RunMemPackage(0x14006aba6c0, 0x1400038ff80, 0x1) /Users/albttx/go/src/github.com/gnolang/gno/gnovm/pkg/gnolang/machine.go:225 +0x190 main.gnoTestPkg({0x16fa42ab0, 0x1e}, {0x1400025f4a0?, 0x1, 0x100a8567c?}, {0x0, 0x0, 0x101374df8?}, 0x1400038e640, 0x14000306820) /Users/albttx/go/src/github.com/gnolang/gno/gnovm/cmd/gno/test.go:354 +0x3f8 main.execTest(0x1400038e640, {0x1400025f3b0, 0x1, 0x1}, 0x0?) /Users/albttx/go/src/github.com/gnolang/gno/gnovm/cmd/gno/test.go:255 +0x804 main.newTestCmd.func1({0x0?, 0x0?}, {0x1400025f3b0?, 0x14000696e58?, 0x0?}) /Users/albttx/go/src/github.com/gnolang/gno/gnovm/cmd/gno/test.go:97 +0x38 github.com/gnolang/gno/tm2/pkg/commands.(*Command).Run(0x0?, {0x100e55608?, 0x14000190010?}) /Users/albttx/go/src/github.com/gnolang/gno/tm2/pkg/commands/command.go:233 +0x17c github.com/gnolang/gno/tm2/pkg/commands.(*Command).Run(0x14000696b00?, {0x100e55608?, 0x14000190010?}) /Users/albttx/go/src/github.com/gnolang/gno/tm2/pkg/commands/command.go:237 +0x12c github.com/gnolang/gno/tm2/pkg/commands.(*Command).ParseAndRun(0x14000180000?, {0x100e55608, 0x14000190010}, {0x140001a6050?, 0x60?, 0x0?}) /Users/albttx/go/src/github.com/gnolang/gno/tm2/pkg/commands/command.go:118 +0x4c main.main() /Users/albttx/go/src/github.com/gnolang/gno/gnovm/cmd/gno/main.go:14 +0x74 exit status 2 ```
Contributors' checklist... - [ ] Added new tests, or not needed, or not feasible - [ ] Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory - [ ] Updated the official documentation or not needed - [ ] No breaking changes were made, or a `BREAKING CHANGE: xxx` message was included in the description - [ ] Added references to related issues and PRs - [ ] Provided any useful hints for running manual tests - [ ] Added new benchmarks to [generated graphs](https://gnoland.github.io/benchmarks), if any. More info [here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
--------- Co-authored-by: Manfred Touron <94029+moul@users.noreply.github.com> Co-authored-by: Morgan Bazalgette --- examples/gno.land/p/demo/tests/tests.gno | 2 + examples/gno.land/p/demo/tests/tests_test.gno | 18 +++++ gnovm/cmd/gno/test.go | 60 +++++++++++----- .../cmd/gno/testdata/gno_test/flag_run.txtar | 8 --- .../gno_test/pkg_underscore_test.txtar | 69 +++++++++++++++++++ 5 files changed, 130 insertions(+), 27 deletions(-) create mode 100644 examples/gno.land/p/demo/tests/tests_test.gno create mode 100644 gnovm/cmd/gno/testdata/gno_test/pkg_underscore_test.txtar diff --git a/examples/gno.land/p/demo/tests/tests.gno b/examples/gno.land/p/demo/tests/tests.gno index f0e4173f313..1a2c2526d01 100644 --- a/examples/gno.land/p/demo/tests/tests.gno +++ b/examples/gno.land/p/demo/tests/tests.gno @@ -8,6 +8,8 @@ import ( rtests "gno.land/r/demo/tests" ) +const World = "world" + // IncCounter demonstrates that it's possible to call a realm function from // a package. So a package can potentially write into the store, by calling // an other realm. diff --git a/examples/gno.land/p/demo/tests/tests_test.gno b/examples/gno.land/p/demo/tests/tests_test.gno new file mode 100644 index 00000000000..49caf2a0294 --- /dev/null +++ b/examples/gno.land/p/demo/tests/tests_test.gno @@ -0,0 +1,18 @@ +package tests_test + +import ( + "testing" + + "gno.land/p/demo/tests" +) + +var World = "WORLD" + +func TestGetHelloWorld(t *testing.T) { + // tests.World is 'world' + s := "hello " + tests.World + World + const want = "hello worldWORLD" + if s != want { + t.Errorf("got %q want %q", s, want) + } +} diff --git a/gnovm/cmd/gno/test.go b/gnovm/cmd/gno/test.go index bd3284ce84a..38615c88c4e 100644 --- a/gnovm/cmd/gno/test.go +++ b/gnovm/cmd/gno/test.go @@ -299,15 +299,6 @@ func gnoTestPkg( // XXX: display a warn? mode = tests.ImportModeStdlibsPreferred } - testStore := tests.TestStore( - rootDir, "", - stdin, stdout, stderr, - mode, - ) - if verbose { - testStore.SetLogStoreOps(true) - } - if !verbose { // TODO: speedup by ignoring if filter is file/*? mockOut := bytes.NewBufferString("") @@ -329,9 +320,19 @@ func gnoTestPkg( // tfiles, ifiles := gno.ParseMemPackageTests(memPkg) tfiles, ifiles := parseMemPackageTests(memPkg) + testPkgName := getPkgNameFromFileset(ifiles) // run test files in pkg - { + if len(tfiles.Files) > 0 { + testStore := tests.TestStore( + rootDir, "", + stdin, stdout, stderr, + mode, + ) + if verbose { + testStore.SetLogStoreOps(true) + } + m := tests.TestMachine(testStore, stdout, gnoPkgPath) if printRuntimeMetrics { // from tm2/pkg/sdk/vm/keeper.go @@ -347,17 +348,38 @@ func gnoTestPkg( } } - // run test files in xxx_test pkg - { - testPkgName := getPkgNameFromFileset(ifiles) - if testPkgName != "" { - m := tests.TestMachine(testStore, stdout, testPkgName) - m.RunMemPackage(memPkg, true) - err := runTestFiles(m, ifiles, testPkgName, verbose, printRuntimeMetrics, runFlag, io) - if err != nil { - errs = multierr.Append(errs, err) + // test xxx_test pkg + if len(ifiles.Files) > 0 { + testStore := tests.TestStore( + rootDir, "", + stdin, stdout, stderr, + mode, + ) + if verbose { + testStore.SetLogStoreOps(true) + } + + m := tests.TestMachine(testStore, stdout, testPkgName) + + memFiles := make([]*std.MemFile, 0, len(ifiles.FileNames())+1) + for _, f := range memPkg.Files { + for _, ifileName := range ifiles.FileNames() { + if f.Name == "gno.mod" || f.Name == ifileName { + memFiles = append(memFiles, f) + break + } } } + + memPkg.Files = memFiles + memPkg.Name = testPkgName + memPkg.Path = memPkg.Path + "_test" + m.RunMemPackage(memPkg, true) + + err := runTestFiles(m, ifiles, testPkgName, verbose, printRuntimeMetrics, runFlag, io) + if err != nil { + errs = multierr.Append(errs, err) + } } } diff --git a/gnovm/cmd/gno/testdata/gno_test/flag_run.txtar b/gnovm/cmd/gno/testdata/gno_test/flag_run.txtar index 838206d15f9..23e5734011e 100644 --- a/gnovm/cmd/gno/testdata/gno_test/flag_run.txtar +++ b/gnovm/cmd/gno/testdata/gno_test/flag_run.txtar @@ -2,16 +2,8 @@ gno test . -stdout '=== RUN TestRun/hello' # show that t.Run doesn't care about -verbose -stdout '=== RUN TestRun/hi_you' -stdout '=== RUN TestRun/hi_me' - gno test ./run_test.gno -stdout '=== RUN TestRun/hello' # show that t.Run doesn't care about -verbose -stdout '=== RUN TestRun/hi_you' -stdout '=== RUN TestRun/hi_me' - gno test -verbose . stdout '=== RUN TestRun/hello' diff --git a/gnovm/cmd/gno/testdata/gno_test/pkg_underscore_test.txtar b/gnovm/cmd/gno/testdata/gno_test/pkg_underscore_test.txtar new file mode 100644 index 00000000000..d0455dce53c --- /dev/null +++ b/gnovm/cmd/gno/testdata/gno_test/pkg_underscore_test.txtar @@ -0,0 +1,69 @@ +# Test a pkg name with _test as suffix + +# Set up GNOROOT in the current directory. +mkdir $WORK/gnovm +symlink $WORK/gnovm/stdlibs -> $GNOROOT/gnovm/stdlibs +env GNOROOT=$WORK + +gno test -verbose ./examples/gno.land/p/demo/hello + +stderr '=== RUN TestHello' +stderr '--- PASS: TestHello.*' + +stderr '=== RUN TestHullo' +stderr '--- PASS: TestHullo.*' + +stderr '=== RUN file/z0_filetest.*' + +-- examples/gno.land/p/demo/hello/gno.mod -- +module gno.land/p/demo/hello + +-- examples/gno.land/p/demo/hello/hello.gno -- +package hello + +var Name = "foo" + +-- examples/gno.land/p/demo/hello/hello_test.gno -- +package hello_test + +import ( + "testing" + + "gno.land/p/demo/hello" +) + +var Name = "bar" + +func TestHello(t *testing.T) { + s := "hello " + hello.Name + " " + Name + const want = "hello foo bar" + if s != want { + t.Errorf("got: %q want %q", s, want) + } +} + +-- examples/gno.land/p/demo/hello/hullo_test.gno -- +package hello + +import ( + "testing" +) + +func TestHullo(t *testing.T) { + s := "hullo " + Name + const want = "hullo foo" + if s != want { + t.Errorf("got: %q want %q", s, want) + } +} + +-- examples/gno.land/p/demo/hello/z0_filetest.gno -- +package main + +import "gno.land/p/demo/hello" + +func main() { + println("filetest " + hello.Name) +} + +// Output: filetest foo