From 7105b11b26d88cec007214571e3f8ef9138e1f38 Mon Sep 17 00:00:00 2001 From: gfanton <8671905+gfanton@users.noreply.github.com> Date: Wed, 18 Oct 2023 08:30:21 -0400 Subject: [PATCH 01/13] feat: setup testscripts coverage Signed-off-by: gfanton <8671905+gfanton@users.noreply.github.com> --- .github/workflows/gnovm.yml | 39 +++++++-- gnovm/Makefile | 18 ++-- gnovm/cmd/gno/build_test.go | 15 +++- gnovm/cmd/gno/main_test.go | 44 ---------- gnovm/cmd/gno/test_test.go | 15 +++- gnovm/pkg/integration/coverage.go | 61 +++++++++++++ gnovm/pkg/integration/integration_gno.go | 106 +++++++++++++++++++++++ 7 files changed, 236 insertions(+), 62 deletions(-) create mode 100644 gnovm/pkg/integration/coverage.go create mode 100644 gnovm/pkg/integration/integration_gno.go diff --git a/.github/workflows/gnovm.yml b/.github/workflows/gnovm.yml index 71b03b5ca05..77c8caffad8 100644 --- a/.github/workflows/gnovm.yml +++ b/.github/workflows/gnovm.yml @@ -67,6 +67,8 @@ jobs: - _test.gnolang.other runs-on: ubuntu-latest timeout-minutes: 15 + env: + COVERAGE_DIR: "/tmp/coverage" steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v4 @@ -74,28 +76,55 @@ jobs: go-version: ${{ matrix.goversion }} - name: test working-directory: gnovm + env: + GOCOVERDIR_TXTAR: ${{ env.COVERAGE_DIR }} run: | + mkdir -p $COVERAGE_DIR + + # setup testing environements variables export GOPATH=$HOME/go - export GOTEST_FLAGS="-v -p 1 -timeout=30m -coverprofile=coverage.out -covermode=atomic" + export GOTEST_FLAGS="-v -p 1 -timeout=30m -covermode=atomic -args -test.gocoverdir=$COVERAGE_DIR" + + # run target test make ${{ matrix.args }} - uses: actions/upload-artifact@v3 if: ${{ runner.os == 'Linux' && matrix.goversion == '1.21.x' }} with: name: ${{runner.os}}-coverage-gnovm-${{ matrix.args}}-${{matrix.goversion}} - path: ./gnovm/coverage.out + path: ${{ env.COVERAGE_DIR }} upload-coverage: needs: test runs-on: ubuntu-latest + env: + COVERAGE_DATA: /tmp/coverage/coverage-raw + COVERAGE_OUTPUT: /tmp/coverage/coverage-out + COVERAGE_PROFILE: /tmp/coverage/coverage.txt steps: - - name: Download all previous coverage artifacts + - run: mkdir -p $COVERAGE_DATA $COVERAGE_OUTPUT + - name: Download all previous coverage data artifacts uses: actions/download-artifact@v3 with: - path: ${{ runner.temp }}/coverage + path: ${{ env.COVERAGE_DATA }} + - uses: actions/setup-go@v4 + with: + go-version: "1.21.x" + - name: Merge coverages + working-directory: ${{ env.COVERAGE_DATA }} + run: | + # create coverage directory list separate by coma. + export COVERAGE_DIRS="$(ls | tr '\n' ',' | sed s/,$//)" + + # merge all directory coverages + go tool covdata merge -i="$COVERAGE_DIRS" -o $COVERAGE_OUTPUT + + # generate coverage profile + go tool covdata textfmt -i=$COVERAGE_OUTPUT -o $COVERAGE_PROFILE + - name: Upload combined coverage to Codecov uses: codecov/codecov-action@v3 with: - directory: ${{ runner.temp }}/coverage + files: ${{ env.COVERAGE_PROFILE }} token: ${{ secrets.CODECOV_TOKEN }} fail_ci_if_error: ${{ github.repository == 'gnolang/gno' }} diff --git a/gnovm/Makefile b/gnovm/Makefile index 5fcacf94f62..34e94f88633 100644 --- a/gnovm/Makefile +++ b/gnovm/Makefile @@ -46,15 +46,15 @@ _test.pkg: .PHONY: _test.gnolang _test.gnolang: _test.gnolang.native _test.gnolang.stdlibs _test.gnolang.realm _test.gnolang.pkg0 _test.gnolang.pkg1 _test.gnolang.pkg2 _test.gnolang.other -_test.gnolang.other:; go test $(GOTEST_FLAGS) tests/*.go -run "(TestFileStr|TestSelectors)" -_test.gnolang.realm:; go test $(GOTEST_FLAGS) tests/*.go -run "TestFiles/^zrealm" -_test.gnolang.pkg0:; go test $(GOTEST_FLAGS) tests/*.go -run "TestPackages/(bufio|crypto|encoding|errors|internal|io|math|sort|std|stdshim|strconv|strings|testing|unicode)" -_test.gnolang.pkg1:; go test $(GOTEST_FLAGS) tests/*.go -run "TestPackages/regexp" -_test.gnolang.pkg2:; go test $(GOTEST_FLAGS) tests/*.go -run "TestPackages/bytes" -_test.gnolang.native:; go test $(GOTEST_FLAGS) tests/*.go -test.short -run "TestFilesNative/" -_test.gnolang.stdlibs:; go test $(GOTEST_FLAGS) tests/*.go -test.short -run 'TestFiles$$/' -_test.gnolang.native.sync:; go test $(GOTEST_FLAGS) tests/*.go -test.short -run "TestFilesNative/" --update-golden-tests -_test.gnolang.stdlibs.sync:; go test $(GOTEST_FLAGS) tests/*.go -test.short -run 'TestFiles$$/' --update-golden-tests +_test.gnolang.other:; go test tests/*.go -run "(TestFileStr|TestSelectors)" $(GOTEST_FLAGS) +_test.gnolang.realm:; go test tests/*.go -run "TestFiles/^zrealm" $(GOTEST_FLAGS) +_test.gnolang.pkg0:; go test tests/*.go -run "TestPackages/(bufio|crypto|encoding|errors|internal|io|math|sort|std|stdshim|strconv|strings|testing|unicode)" $(GOTEST_FLAGS) +_test.gnolang.pkg1:; go test tests/*.go -run "TestPackages/regexp" $(GOTEST_FLAGS) +_test.gnolang.pkg2:; go test tests/*.go -run "TestPackages/bytes" $(GOTEST_FLAGS) +_test.gnolang.native:; go test tests/*.go -test.short -run "TestFilesNative/" $(GOTEST_FLAGS) +_test.gnolang.stdlibs:; go test tests/*.go -test.short -run 'TestFiles$$/' $(GOTEST_FLAGS) +_test.gnolang.native.sync:; go test tests/*.go -test.short -run "TestFilesNative/" --update-golden-tests $(GOTEST_FLAGS) +_test.gnolang.stdlibs.sync:; go test tests/*.go -test.short -run 'TestFiles$$/' --update-golden-tests $(GOTEST_FLAGS) ######################################## # Code gen diff --git a/gnovm/cmd/gno/build_test.go b/gnovm/cmd/gno/build_test.go index 5bb03ef0d35..67b65382f36 100644 --- a/gnovm/cmd/gno/build_test.go +++ b/gnovm/cmd/gno/build_test.go @@ -3,9 +3,20 @@ package main import ( "testing" + "github.com/gnolang/gno/gnovm/pkg/integration" "github.com/rogpeppe/go-internal/testscript" + "github.com/stretchr/testify/require" ) -func TestBuild(t *testing.T) { - testscript.Run(t, setupTestScript(t, "testdata/gno_build")) +func Test_ScriptsBuild(t *testing.T) { + p := testscript.Params{ + Dir: "testdata/gno_build", + } + + err := integration.SetupCoverage(&p) + require.NoError(t, err) + err = integration.SetupGno(&p, t.TempDir()) + require.NoError(t, err) + + testscript.Run(t, p) } diff --git a/gnovm/cmd/gno/main_test.go b/gnovm/cmd/gno/main_test.go index 8d19a50e814..371cdf913e8 100644 --- a/gnovm/cmd/gno/main_test.go +++ b/gnovm/cmd/gno/main_test.go @@ -5,12 +5,10 @@ import ( "context" "fmt" "os" - "os/exec" "path/filepath" "strings" "testing" - "github.com/rogpeppe/go-internal/testscript" "github.com/stretchr/testify/require" "github.com/gnolang/gno/tm2/pkg/commands" @@ -144,45 +142,3 @@ func testMainCaseRun(t *testing.T, tc []testMainCase) { }) } } - -func setupTestScript(t *testing.T, txtarDir string) testscript.Params { - t.Helper() - // Get root location of github.com/gnolang/gno - goModPath, err := exec.Command("go", "env", "GOMOD").CombinedOutput() - require.NoError(t, err) - rootDir := filepath.Dir(string(goModPath)) - // Build a fresh gno binary in a temp directory - gnoBin := filepath.Join(t.TempDir(), "gno") - err = exec.Command("go", "build", "-o", gnoBin, filepath.Join(rootDir, "gnovm", "cmd", "gno")).Run() - require.NoError(t, err) - // Define script params - return testscript.Params{ - Setup: func(env *testscript.Env) error { - env.Vars = append(env.Vars, - "GNOROOT="+rootDir, // thx PR 1014 :) - // by default, $HOME=/no-home, but we need an existing $HOME directory - // because some commands needs to access $HOME/.cache/go-build - "HOME="+t.TempDir(), - ) - return nil - }, - Cmds: map[string]func(ts *testscript.TestScript, neg bool, args []string){ - // add a custom "gno" command so txtar files can easily execute "gno" - // without knowing where is the binary or how it is executed. - "gno": func(ts *testscript.TestScript, neg bool, args []string) { - err := ts.Exec(gnoBin, args...) - if err != nil { - ts.Logf("[%v]\n", err) - if !neg { - ts.Fatalf("unexpected gno command failure") - } - } else { - if neg { - ts.Fatalf("unexpected gno command success") - } - } - }, - }, - Dir: txtarDir, - } -} diff --git a/gnovm/cmd/gno/test_test.go b/gnovm/cmd/gno/test_test.go index f5b069a5f03..d608ae16b4d 100644 --- a/gnovm/cmd/gno/test_test.go +++ b/gnovm/cmd/gno/test_test.go @@ -3,9 +3,20 @@ package main import ( "testing" + "github.com/gnolang/gno/gnovm/pkg/integration" "github.com/rogpeppe/go-internal/testscript" + "github.com/stretchr/testify/require" ) -func TestTest(t *testing.T) { - testscript.Run(t, setupTestScript(t, "testdata/gno_test")) +func Test_ScriptsTest(t *testing.T) { + p := testscript.Params{ + Dir: "testdata/gno_test", + } + + err := integration.SetupCoverage(&p) + require.NoError(t, err) + err = integration.SetupGno(&p, t.TempDir()) + require.NoError(t, err) + + testscript.Run(t, p) } diff --git a/gnovm/pkg/integration/coverage.go b/gnovm/pkg/integration/coverage.go new file mode 100644 index 00000000000..acfd5a4fc79 --- /dev/null +++ b/gnovm/pkg/integration/coverage.go @@ -0,0 +1,61 @@ +package integration + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "sync" + "testing" + + "github.com/rogpeppe/go-internal/testscript" +) + +var coverageEnv struct { + coverdir string + once sync.Once +} + +// SetupCoverage sets up the given test environment for coverage +func SetupCoverage(p *testscript.Params) error { + coverdir := os.Getenv("GOCOVERDIR_TXTAR") + if testing.CoverMode() == "" || coverdir == "" { + return nil + } + + var err error + + if !filepath.IsAbs(coverdir) { + coverdir, err = filepath.Abs(coverdir) + if err != nil { + return fmt.Errorf("unable to determine absolute path of %q: %w", coverdir, err) + } + } + + info, err := os.Stat(coverdir) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + if mkErr := os.Mkdir(coverdir, 0o755); mkErr != nil { + return fmt.Errorf("failed to testscripts coverage dir %q: %w", coverdir, mkErr) + } + } else { + // Handle other potential errors from os.Stat + return fmt.Errorf("failed to stat %q: %w", coverdir, err) + } + } else if !info.IsDir() { + return fmt.Errorf("coverage: %q is not a directory", coverdir) + } + + origSetup := p.Setup + p.Setup = func(env *testscript.Env) error { + if origSetup != nil { + origSetup(env) + } + + // override GOCOVEDIR directory + env.Setenv("GOCOVERDIR", coverdir) + return nil + } + + return nil +} diff --git a/gnovm/pkg/integration/integration_gno.go b/gnovm/pkg/integration/integration_gno.go new file mode 100644 index 00000000000..5e0e4b55a9f --- /dev/null +++ b/gnovm/pkg/integration/integration_gno.go @@ -0,0 +1,106 @@ +package integration + +import ( + "errors" + "fmt" + "os" + "os/exec" + "path/filepath" + "sync" + "testing" + + "github.com/rogpeppe/go-internal/testscript" +) + +var gnoEnv struct { + err error + gnoBin string + once sync.Once +} + +func SetupGno(p *testscript.Params, buildDir string) error { + gnoroot := os.Getenv("GNOROOT") + if gnoroot == "" { + // Get root location of github.com/gnolang/gno + goModPath, err := exec.Command("go", "env", "GOMOD").CombinedOutput() + if err != nil { + return fmt.Errorf("unable to determine gno root directory") + } + + gnoroot = filepath.Dir(string(goModPath)) + } + + info, err := os.Stat(buildDir) + if err != nil { + return fmt.Errorf("unable to stat: %q", buildDir) + } + + if !info.IsDir() { + return fmt.Errorf("given buildDir is not a directory: %q", buildDir) + } + + gnoBin := filepath.Join(buildDir, "gno") + if _, err = os.Stat(gnoBin); errors.Is(err, os.ErrNotExist) { + // Build a fresh gno binary in a temp directory + gnoArgsBuilder := []string{"build", "-o", gnoBin} + + // Add coverage if needed + if coverMode := testing.CoverMode(); coverMode != "" { + gnoArgsBuilder = append(gnoArgsBuilder, "-covermode", coverMode) + } + + // Add target command + gnoArgsBuilder = append(gnoArgsBuilder, filepath.Join(gnoroot, "gnovm", "cmd", "gno")) + + if err = exec.Command("go", gnoArgsBuilder...).Run(); err != nil { + return fmt.Errorf("uanble to build gno binary: %w", err) + } + } else if err != nil { + return err + + } + + // Define setup scripts + origSetup := p.Setup + p.Setup = func(env *testscript.Env) error { + if origSetup != nil { + if err := origSetup(env); err != nil { + return err + } + } + + home, err := os.MkdirTemp("", "gno") + if err != nil { + return fmt.Errorf("unable to create temporary home directory: %w", err) + } + + env.Vars = append(env.Vars, + "GNOROOT="+gnoroot, // thx PR 1014 :) + // by default, $HOME=/no-home, but we need an existing $HOME directory + // because some commands needs to access $HOME/.cache/go-build + "HOME="+home, + ) + + return nil + } + + if p.Cmds == nil { + p.Cmds = make(map[string]func(ts *testscript.TestScript, neg bool, args []string)) + } + + // Set gno command + p.Cmds["gno"] = func(ts *testscript.TestScript, neg bool, args []string) { + err := ts.Exec(gnoBin, args...) + if err != nil { + ts.Logf("[%v]\n", err) + if !neg { + ts.Fatalf("unexpected gno command failure") + } + } else { + if neg { + ts.Fatalf("unexpected gno command success") + } + } + } + return nil +} From 4e140594f9577803dde86fb0937117c64874a0a3 Mon Sep 17 00:00:00 2001 From: gfanton <8671905+gfanton@users.noreply.github.com> Date: Wed, 18 Oct 2023 14:06:23 -0400 Subject: [PATCH 02/13] chore: lint Signed-off-by: gfanton <8671905+gfanton@users.noreply.github.com> --- gnovm/pkg/integration/integration_gno.go | 1 - 1 file changed, 1 deletion(-) diff --git a/gnovm/pkg/integration/integration_gno.go b/gnovm/pkg/integration/integration_gno.go index 5e0e4b55a9f..6028f686f4e 100644 --- a/gnovm/pkg/integration/integration_gno.go +++ b/gnovm/pkg/integration/integration_gno.go @@ -57,7 +57,6 @@ func SetupGno(p *testscript.Params, buildDir string) error { } } else if err != nil { return err - } // Define setup scripts From 46241a26ea727633ad5397f2b97a4b38aa09896f Mon Sep 17 00:00:00 2001 From: gfanton <8671905+gfanton@users.noreply.github.com> Date: Wed, 18 Oct 2023 14:34:14 -0400 Subject: [PATCH 03/13] chore: add debug informations Signed-off-by: gfanton <8671905+gfanton@users.noreply.github.com> --- .github/workflows/gnovm.yml | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/.github/workflows/gnovm.yml b/.github/workflows/gnovm.yml index 77c8caffad8..d4d802f7a2f 100644 --- a/.github/workflows/gnovm.yml +++ b/.github/workflows/gnovm.yml @@ -81,11 +81,11 @@ jobs: run: | mkdir -p $COVERAGE_DIR - # setup testing environements variables + # Setup testing environements variables export GOPATH=$HOME/go export GOTEST_FLAGS="-v -p 1 -timeout=30m -covermode=atomic -args -test.gocoverdir=$COVERAGE_DIR" - # run target test + # Run target test make ${{ matrix.args }} - uses: actions/upload-artifact@v3 if: ${{ runner.os == 'Linux' && matrix.goversion == '1.21.x' }} @@ -112,14 +112,20 @@ jobs: - name: Merge coverages working-directory: ${{ env.COVERAGE_DATA }} run: | - # create coverage directory list separate by coma. + # Create coverage directory list separate by coma export COVERAGE_DIRS="$(ls | tr '\n' ',' | sed s/,$//)" - # merge all directory coverages - go tool covdata merge -i="$COVERAGE_DIRS" -o $COVERAGE_OUTPUT + # Merge all coverage data directories from previous tests + echo "merging coverage data from: $COVERAGE_DIRS to '$COVERAGE_OUTPUT'" + go tool covdata merge -v 1 -i="$COVERAGE_DIRS" -o $COVERAGE_OUTPUT - # generate coverage profile - go tool covdata textfmt -i=$COVERAGE_OUTPUT -o $COVERAGE_PROFILE + # Print coverage percent for debug purpose if needed + echo 'coverage results:' + go tool covdata percent -i=$COVERAGE_OUTPUT + + # Generating coverage profile + echo "coverting $COVERAGE_OUTPUT to legacy profile: '$COVERAGE_PROFILE'" + go tool covdata textfmt -v 1 -i=$COVERAGE_OUTPUT -o $COVERAGE_PROFILE - name: Upload combined coverage to Codecov uses: codecov/codecov-action@v3 From 2ab7c4c20009fac33fb60029bc243e5c2666c33d Mon Sep 17 00:00:00 2001 From: gfanton <8671905+gfanton@users.noreply.github.com> Date: Wed, 18 Oct 2023 15:50:59 -0400 Subject: [PATCH 04/13] chore: lint Signed-off-by: gfanton <8671905+gfanton@users.noreply.github.com> --- .github/workflows/gnovm.yml | 4 +--- gnovm/pkg/integration/coverage.go | 2 +- .../pkg/integration/{integration_gno.go => gno.go} | 14 ++++++-------- 3 files changed, 8 insertions(+), 12 deletions(-) rename gnovm/pkg/integration/{integration_gno.go => gno.go} (95%) diff --git a/.github/workflows/gnovm.yml b/.github/workflows/gnovm.yml index d4d802f7a2f..cb7bd7346e1 100644 --- a/.github/workflows/gnovm.yml +++ b/.github/workflows/gnovm.yml @@ -112,11 +112,10 @@ jobs: - name: Merge coverages working-directory: ${{ env.COVERAGE_DATA }} run: | - # Create coverage directory list separate by coma + # Create coverage directory list separate by comma export COVERAGE_DIRS="$(ls | tr '\n' ',' | sed s/,$//)" # Merge all coverage data directories from previous tests - echo "merging coverage data from: $COVERAGE_DIRS to '$COVERAGE_OUTPUT'" go tool covdata merge -v 1 -i="$COVERAGE_DIRS" -o $COVERAGE_OUTPUT # Print coverage percent for debug purpose if needed @@ -124,7 +123,6 @@ jobs: go tool covdata percent -i=$COVERAGE_OUTPUT # Generating coverage profile - echo "coverting $COVERAGE_OUTPUT to legacy profile: '$COVERAGE_PROFILE'" go tool covdata textfmt -v 1 -i=$COVERAGE_OUTPUT -o $COVERAGE_PROFILE - name: Upload combined coverage to Codecov diff --git a/gnovm/pkg/integration/coverage.go b/gnovm/pkg/integration/coverage.go index acfd5a4fc79..1541984b193 100644 --- a/gnovm/pkg/integration/coverage.go +++ b/gnovm/pkg/integration/coverage.go @@ -52,7 +52,7 @@ func SetupCoverage(p *testscript.Params) error { origSetup(env) } - // override GOCOVEDIR directory + // Override `GOCOVEDIR` directory env.Setenv("GOCOVERDIR", coverdir) return nil } diff --git a/gnovm/pkg/integration/integration_gno.go b/gnovm/pkg/integration/gno.go similarity index 95% rename from gnovm/pkg/integration/integration_gno.go rename to gnovm/pkg/integration/gno.go index 6028f686f4e..7b7e4aeadb8 100644 --- a/gnovm/pkg/integration/integration_gno.go +++ b/gnovm/pkg/integration/gno.go @@ -6,18 +6,11 @@ import ( "os" "os/exec" "path/filepath" - "sync" "testing" "github.com/rogpeppe/go-internal/testscript" ) -var gnoEnv struct { - err error - gnoBin string - once sync.Once -} - func SetupGno(p *testscript.Params, buildDir string) error { gnoroot := os.Getenv("GNOROOT") if gnoroot == "" { @@ -56,10 +49,11 @@ func SetupGno(p *testscript.Params, buildDir string) error { return fmt.Errorf("uanble to build gno binary: %w", err) } } else if err != nil { + // Return any other errors return err } - // Define setup scripts + // Wrap setup scripts origSetup := p.Setup p.Setup = func(env *testscript.Env) error { if origSetup != nil { @@ -72,6 +66,9 @@ func SetupGno(p *testscript.Params, buildDir string) error { if err != nil { return fmt.Errorf("unable to create temporary home directory: %w", err) } + env.Defer(func() { + os.RemoveAll(home) + }) env.Vars = append(env.Vars, "GNOROOT="+gnoroot, // thx PR 1014 :) @@ -101,5 +98,6 @@ func SetupGno(p *testscript.Params, buildDir string) error { } } } + return nil } From 2f509c62afbfbfc0e1c2389bee53aa007f85dc9a Mon Sep 17 00:00:00 2001 From: gfanton <8671905+gfanton@users.noreply.github.com> Date: Wed, 18 Oct 2023 16:15:14 -0400 Subject: [PATCH 05/13] chore: lint Signed-off-by: gfanton <8671905+gfanton@users.noreply.github.com> --- gnovm/pkg/integration/coverage.go | 9 +++++++-- gnovm/pkg/integration/gno.go | 17 ++++++++++------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/gnovm/pkg/integration/coverage.go b/gnovm/pkg/integration/coverage.go index 1541984b193..6fe5ec1f7ec 100644 --- a/gnovm/pkg/integration/coverage.go +++ b/gnovm/pkg/integration/coverage.go @@ -16,7 +16,9 @@ var coverageEnv struct { once sync.Once } -// SetupCoverage sets up the given test environment for coverage +// SetupCoverage sets up the given testscripts environment for coverage. +// It will need both, covermode and a target directory defined with +// `GOCOVERDIR_TXTAR` environements variable to be set to be effective func SetupCoverage(p *testscript.Params) error { coverdir := os.Getenv("GOCOVERDIR_TXTAR") if testing.CoverMode() == "" || coverdir == "" { @@ -25,6 +27,8 @@ func SetupCoverage(p *testscript.Params) error { var err error + // We need to have an absolute path here, because current directory + // context will change while execution test scripts. if !filepath.IsAbs(coverdir) { coverdir, err = filepath.Abs(coverdir) if err != nil { @@ -32,6 +36,7 @@ func SetupCoverage(p *testscript.Params) error { } } + // If the given coverage directory doesn't exist, create it info, err := os.Stat(coverdir) if err != nil { if errors.Is(err, os.ErrNotExist) { @@ -52,7 +57,7 @@ func SetupCoverage(p *testscript.Params) error { origSetup(env) } - // Override `GOCOVEDIR` directory + // Override `GOCOVEDIR` directory for sub-execution env.Setenv("GOCOVERDIR", coverdir) return nil } diff --git a/gnovm/pkg/integration/gno.go b/gnovm/pkg/integration/gno.go index 7b7e4aeadb8..0b61a59850c 100644 --- a/gnovm/pkg/integration/gno.go +++ b/gnovm/pkg/integration/gno.go @@ -11,6 +11,11 @@ import ( "github.com/rogpeppe/go-internal/testscript" ) +// SetupGno sets up the given testscripts environment for tests that use the gno +// command. It build `gno` using `go build` command into the given buildDir if +// not existing already. +// It will add `gno` command to p.Cmds. It also wraps p.Setup to set up the environment +// variables for running the go command appropriately. func SetupGno(p *testscript.Params, buildDir string) error { gnoroot := os.Getenv("GNOROOT") if gnoroot == "" { @@ -62,6 +67,10 @@ func SetupGno(p *testscript.Params, buildDir string) error { } } + env.Setenv("GNOROOT", gnoroot) // thx PR 1014 :) + + // by default, $HOME=/no-home, but we need an existing $HOME directory + // because some commands needs to access $HOME/.cache/go-build home, err := os.MkdirTemp("", "gno") if err != nil { return fmt.Errorf("unable to create temporary home directory: %w", err) @@ -69,13 +78,7 @@ func SetupGno(p *testscript.Params, buildDir string) error { env.Defer(func() { os.RemoveAll(home) }) - - env.Vars = append(env.Vars, - "GNOROOT="+gnoroot, // thx PR 1014 :) - // by default, $HOME=/no-home, but we need an existing $HOME directory - // because some commands needs to access $HOME/.cache/go-build - "HOME="+home, - ) + env.Setenv("HOME", home) return nil } From e7c5983294a59f7034b9298ec3d1acdc67cc4a38 Mon Sep 17 00:00:00 2001 From: gfanton <8671905+gfanton@users.noreply.github.com> Date: Thu, 19 Oct 2023 10:32:32 -0400 Subject: [PATCH 06/13] chore: lint Signed-off-by: gfanton <8671905+gfanton@users.noreply.github.com> --- gnovm/pkg/integration/gno.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gnovm/pkg/integration/gno.go b/gnovm/pkg/integration/gno.go index 0b61a59850c..43bd8e523f9 100644 --- a/gnovm/pkg/integration/gno.go +++ b/gnovm/pkg/integration/gno.go @@ -75,10 +75,8 @@ func SetupGno(p *testscript.Params, buildDir string) error { if err != nil { return fmt.Errorf("unable to create temporary home directory: %w", err) } - env.Defer(func() { - os.RemoveAll(home) - }) env.Setenv("HOME", home) + env.Defer(func() { os.RemoveAll(home) }) // cleanup return nil } From 5b6a572ed6457d66bc74839bebad454a1f1ac75d Mon Sep 17 00:00:00 2001 From: gfanton <8671905+gfanton@users.noreply.github.com> Date: Sat, 28 Oct 2023 14:15:53 +0200 Subject: [PATCH 07/13] chore: use osm DirExists Signed-off-by: gfanton <8671905+gfanton@users.noreply.github.com> --- gnovm/pkg/integration/gno.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/gnovm/pkg/integration/gno.go b/gnovm/pkg/integration/gno.go index 43bd8e523f9..6af9b6deb9a 100644 --- a/gnovm/pkg/integration/gno.go +++ b/gnovm/pkg/integration/gno.go @@ -8,6 +8,7 @@ import ( "path/filepath" "testing" + osm "github.com/gnolang/gno/tm2/pkg/os" "github.com/rogpeppe/go-internal/testscript" ) @@ -28,17 +29,12 @@ func SetupGno(p *testscript.Params, buildDir string) error { gnoroot = filepath.Dir(string(goModPath)) } - info, err := os.Stat(buildDir) - if err != nil { - return fmt.Errorf("unable to stat: %q", buildDir) - } - - if !info.IsDir() { - return fmt.Errorf("given buildDir is not a directory: %q", buildDir) + if !osm.DirExists(buildDir) { + return fmt.Errorf("%q does not exist or is not a directory", buildDir) } gnoBin := filepath.Join(buildDir, "gno") - if _, err = os.Stat(gnoBin); errors.Is(err, os.ErrNotExist) { + if _, err := os.Stat(gnoBin); errors.Is(err, os.ErrNotExist) { // Build a fresh gno binary in a temp directory gnoArgsBuilder := []string{"build", "-o", gnoBin} From 1ba1d61c95d45dbc9d2fbc37f149c0697b0fdf6a Mon Sep 17 00:00:00 2001 From: gfanton <8671905+gfanton@users.noreply.github.com> Date: Thu, 2 Nov 2023 15:28:58 +0100 Subject: [PATCH 08/13] chore: lint comment Signed-off-by: gfanton <8671905+gfanton@users.noreply.github.com> --- gnovm/pkg/integration/coverage.go | 17 ++++++--------- gnovm/pkg/integration/gno.go | 35 +++++++++++++++++-------------- 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/gnovm/pkg/integration/coverage.go b/gnovm/pkg/integration/coverage.go index 6fe5ec1f7ec..c0cce5fafec 100644 --- a/gnovm/pkg/integration/coverage.go +++ b/gnovm/pkg/integration/coverage.go @@ -6,7 +6,6 @@ import ( "os" "path/filepath" "sync" - "testing" "github.com/rogpeppe/go-internal/testscript" ) @@ -17,23 +16,19 @@ var coverageEnv struct { } // SetupCoverage sets up the given testscripts environment for coverage. -// It will need both, covermode and a target directory defined with -// `GOCOVERDIR_TXTAR` environements variable to be set to be effective -func SetupCoverage(p *testscript.Params) error { - coverdir := os.Getenv("GOCOVERDIR_TXTAR") - if testing.CoverMode() == "" || coverdir == "" { - return nil - } - +// It will mostly override `GOCOVERDIR` with the target cover directory +func SetupCoverage(p *testscript.Params, coverdir string) error { var err error // We need to have an absolute path here, because current directory - // context will change while execution test scripts. + // context will change while executing testscripts. if !filepath.IsAbs(coverdir) { - coverdir, err = filepath.Abs(coverdir) + abspath, err := filepath.Abs(coverdir) if err != nil { return fmt.Errorf("unable to determine absolute path of %q: %w", coverdir, err) } + coverdir = abspath + } // If the given coverage directory doesn't exist, create it diff --git a/gnovm/pkg/integration/gno.go b/gnovm/pkg/integration/gno.go index 6af9b6deb9a..8da8f116e6c 100644 --- a/gnovm/pkg/integration/gno.go +++ b/gnovm/pkg/integration/gno.go @@ -12,15 +12,15 @@ import ( "github.com/rogpeppe/go-internal/testscript" ) -// SetupGno sets up the given testscripts environment for tests that use the gno -// command. It build `gno` using `go build` command into the given buildDir if -// not existing already. -// It will add `gno` command to p.Cmds. It also wraps p.Setup to set up the environment -// variables for running the go command appropriately. +// SetupGno prepares the given testscript environment for tests that utilize the gno command. +// If the `gno` binary doesn't exist, it's built using the `go build` command into the specified buildDir. +// The function also include the `gno` command into `p.Cmds` to and wrap environment into p.Setup +// to correctly set up the environment variables needed for the `gno` command. func SetupGno(p *testscript.Params, buildDir string) error { + // Try to fetch `GNOROOT` from the environment variables gnoroot := os.Getenv("GNOROOT") if gnoroot == "" { - // Get root location of github.com/gnolang/gno + // If `GNOROOT` isn't set, determine the root directory of github.com/gnolang/gno goModPath, err := exec.Command("go", "env", "GOMOD").CombinedOutput() if err != nil { return fmt.Errorf("unable to determine gno root directory") @@ -33,55 +33,58 @@ func SetupGno(p *testscript.Params, buildDir string) error { return fmt.Errorf("%q does not exist or is not a directory", buildDir) } + // Determine the path to the gno binary within the build directory gnoBin := filepath.Join(buildDir, "gno") if _, err := os.Stat(gnoBin); errors.Is(err, os.ErrNotExist) { // Build a fresh gno binary in a temp directory gnoArgsBuilder := []string{"build", "-o", gnoBin} - // Add coverage if needed + // Forward `-covermode` settings if set if coverMode := testing.CoverMode(); coverMode != "" { gnoArgsBuilder = append(gnoArgsBuilder, "-covermode", coverMode) } - // Add target command + // Append the path to the gno command source gnoArgsBuilder = append(gnoArgsBuilder, filepath.Join(gnoroot, "gnovm", "cmd", "gno")) if err = exec.Command("go", gnoArgsBuilder...).Run(); err != nil { - return fmt.Errorf("uanble to build gno binary: %w", err) + return fmt.Errorf("unable to build gno binary: %w", err) } } else if err != nil { - // Return any other errors + // Handle other potential errors from os.Stat return err } - // Wrap setup scripts + // Store the original setup scripts for potential wrapping origSetup := p.Setup p.Setup = func(env *testscript.Env) error { + // If there's an original setup, execute it if origSetup != nil { if err := origSetup(env); err != nil { return err } } - env.Setenv("GNOROOT", gnoroot) // thx PR 1014 :) + // Set the GNOROOT environment variable + env.Setenv("GNOROOT", gnoroot) - // by default, $HOME=/no-home, but we need an existing $HOME directory - // because some commands needs to access $HOME/.cache/go-build + // Create a temporary home directory because certain commands require access to $HOME/.cache/go-build home, err := os.MkdirTemp("", "gno") if err != nil { return fmt.Errorf("unable to create temporary home directory: %w", err) } env.Setenv("HOME", home) - env.Defer(func() { os.RemoveAll(home) }) // cleanup + env.Defer(func() { os.RemoveAll(home) }) return nil } + // Initialize cmds map if needed if p.Cmds == nil { p.Cmds = make(map[string]func(ts *testscript.TestScript, neg bool, args []string)) } - // Set gno command + // Register the gno command for testscripts p.Cmds["gno"] = func(ts *testscript.TestScript, neg bool, args []string) { err := ts.Exec(gnoBin, args...) if err != nil { From c37a33153d6c4d03893db1b240deab9aa539fb5b Mon Sep 17 00:00:00 2001 From: gfanton <8671905+gfanton@users.noreply.github.com> Date: Fri, 3 Nov 2023 16:46:13 +0100 Subject: [PATCH 09/13] chore: revert make flags order Signed-off-by: gfanton <8671905+gfanton@users.noreply.github.com> --- gnovm/Makefile | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/gnovm/Makefile b/gnovm/Makefile index 34e94f88633..2fec34ad004 100644 --- a/gnovm/Makefile +++ b/gnovm/Makefile @@ -46,15 +46,16 @@ _test.pkg: .PHONY: _test.gnolang _test.gnolang: _test.gnolang.native _test.gnolang.stdlibs _test.gnolang.realm _test.gnolang.pkg0 _test.gnolang.pkg1 _test.gnolang.pkg2 _test.gnolang.other -_test.gnolang.other:; go test tests/*.go -run "(TestFileStr|TestSelectors)" $(GOTEST_FLAGS) -_test.gnolang.realm:; go test tests/*.go -run "TestFiles/^zrealm" $(GOTEST_FLAGS) -_test.gnolang.pkg0:; go test tests/*.go -run "TestPackages/(bufio|crypto|encoding|errors|internal|io|math|sort|std|stdshim|strconv|strings|testing|unicode)" $(GOTEST_FLAGS) -_test.gnolang.pkg1:; go test tests/*.go -run "TestPackages/regexp" $(GOTEST_FLAGS) -_test.gnolang.pkg2:; go test tests/*.go -run "TestPackages/bytes" $(GOTEST_FLAGS) -_test.gnolang.native:; go test tests/*.go -test.short -run "TestFilesNative/" $(GOTEST_FLAGS) -_test.gnolang.stdlibs:; go test tests/*.go -test.short -run 'TestFiles$$/' $(GOTEST_FLAGS) -_test.gnolang.native.sync:; go test tests/*.go -test.short -run "TestFilesNative/" --update-golden-tests $(GOTEST_FLAGS) -_test.gnolang.stdlibs.sync:; go test tests/*.go -test.short -run 'TestFiles$$/' --update-golden-tests $(GOTEST_FLAGS) +_test.gnolang.other:; go test $(GOTEST_FLAGS) tests/*.go -run "(TestFileStr|TestSelectors)" +_test.gnolang.realm:; go test $(GOTEST_FLAGS) tests/*.go -run "TestFiles/^zrealm" +_test.gnolang.pkg0:; go test $(GOTEST_FLAGS) tests/*.go -run "TestPackages/(bufio|crypto|encoding|errors|internal|io|math|sort|std|stdshim|strconv|strings|testing|unicode)" +_test.gnolang.pkg1:; go test $(GOTEST_FLAGS) tests/*.go -run "TestPackages/regexp" +_test.gnolang.pkg2:; go test $(GOTEST_FLAGS) tests/*.go -run "TestPackages/bytes" +_test.gnolang.native:; go test $(GOTEST_FLAGS) tests/*.go -test.short -run "TestFilesNative/" +_test.gnolang.stdlibs:; go test $(GOTEST_FLAGS) tests/*.go -test.short -run 'TestFiles$$/' +_test.gnolang.native.sync:; go test $(GOTEST_FLAGS) tests/*.go -test.short -run "TestFilesNative/" --update-golden-tests +_test.gnolang.stdlibs.sync:; go test $(GOTEST_FLAGS) tests/*.go -test.short -run 'TestFiles$$/' --update-golden-tests + ######################################## # Code gen From 3199d0ea3996ee5d4798ede2f574147bf50b5d20 Mon Sep 17 00:00:00 2001 From: gfanton <8671905+gfanton@users.noreply.github.com> Date: Fri, 3 Nov 2023 16:46:55 +0100 Subject: [PATCH 10/13] feat: use `test.gocoverdir-txtar` flag instead of environment variable Signed-off-by: gfanton <8671905+gfanton@users.noreply.github.com> --- .github/workflows/gnovm.yml | 6 ++-- gnovm/cmd/gno/build_test.go | 3 +- gnovm/cmd/gno/test_test.go | 3 +- gnovm/pkg/integration/coverage.go | 56 +++++++++++++++++-------------- 4 files changed, 37 insertions(+), 31 deletions(-) diff --git a/.github/workflows/gnovm.yml b/.github/workflows/gnovm.yml index cb7bd7346e1..632807d8f14 100644 --- a/.github/workflows/gnovm.yml +++ b/.github/workflows/gnovm.yml @@ -76,14 +76,12 @@ jobs: go-version: ${{ matrix.goversion }} - name: test working-directory: gnovm - env: - GOCOVERDIR_TXTAR: ${{ env.COVERAGE_DIR }} run: | mkdir -p $COVERAGE_DIR # Setup testing environements variables export GOPATH=$HOME/go - export GOTEST_FLAGS="-v -p 1 -timeout=30m -covermode=atomic -args -test.gocoverdir=$COVERAGE_DIR" + export GOTEST_FLAGS="-v -p 1 -timeout=30m -covermode=atomic -test.gocoverdir-txtar=$COVERAGE_DIR -test.gocoverdir=$COVERAGE_DIR" # Run target test make ${{ matrix.args }} @@ -122,7 +120,7 @@ jobs: echo 'coverage results:' go tool covdata percent -i=$COVERAGE_OUTPUT - # Generating coverage profile + # Generate coverage profile go tool covdata textfmt -v 1 -i=$COVERAGE_OUTPUT -o $COVERAGE_PROFILE - name: Upload combined coverage to Codecov diff --git a/gnovm/cmd/gno/build_test.go b/gnovm/cmd/gno/build_test.go index 67b65382f36..9c4ef8f1d76 100644 --- a/gnovm/cmd/gno/build_test.go +++ b/gnovm/cmd/gno/build_test.go @@ -13,8 +13,9 @@ func Test_ScriptsBuild(t *testing.T) { Dir: "testdata/gno_build", } - err := integration.SetupCoverage(&p) + err := integration.SetupTestscriptsCoverageFromFlag(&p) require.NoError(t, err) + err = integration.SetupGno(&p, t.TempDir()) require.NoError(t, err) diff --git a/gnovm/cmd/gno/test_test.go b/gnovm/cmd/gno/test_test.go index d608ae16b4d..9a57d7f656f 100644 --- a/gnovm/cmd/gno/test_test.go +++ b/gnovm/cmd/gno/test_test.go @@ -13,8 +13,9 @@ func Test_ScriptsTest(t *testing.T) { Dir: "testdata/gno_test", } - err := integration.SetupCoverage(&p) + err := integration.SetupTestscriptsCoverageFromFlag(&p) require.NoError(t, err) + err = integration.SetupGno(&p, t.TempDir()) require.NoError(t, err) diff --git a/gnovm/pkg/integration/coverage.go b/gnovm/pkg/integration/coverage.go index c0cce5fafec..844ac0107ea 100644 --- a/gnovm/pkg/integration/coverage.go +++ b/gnovm/pkg/integration/coverage.go @@ -1,54 +1,60 @@ package integration import ( - "errors" + "flag" "fmt" "os" "path/filepath" - "sync" "github.com/rogpeppe/go-internal/testscript" ) var coverageEnv struct { coverdir string - once sync.Once } -// SetupCoverage sets up the given testscripts environment for coverage. +func init() { + flag.StringVar(&coverageEnv.coverdir, + "test.gocoverdir-txtar", "", "write testscripts coverage intermediate files to this directory") +} + +// SetupTestscriptsCoverageFromFlag checks the `test.gocoverdir-txtar` flag to determine +// whether to configure testscript parameters for coverage analysis. If the flag is not set, +// it will skip the setup process. +func SetupTestscriptsCoverageFromFlag(p *testscript.Params) error { + if coverageEnv.coverdir == "" { + // Skip coverage setup if `test.gocoverdir-txtar` flag wasn't specified + return nil + } + + return SetupTestscriptsCoverage(p, coverageEnv.coverdir) +} + +// SetupTestscriptsCoverage sets up the given testscripts environment for coverage. // It will mostly override `GOCOVERDIR` with the target cover directory -func SetupCoverage(p *testscript.Params, coverdir string) error { - var err error +func SetupTestscriptsCoverage(p *testscript.Params, coverdir string) error { + // Check if the given coverage directory exist + info, err := os.Stat(coverdir) + if err != nil { + return fmt.Errorf("output directory %q inaccessible: %w", coverdir, err) + } else if !info.IsDir() { + return fmt.Errorf("output directory %q not a directory", coverdir) + } // We need to have an absolute path here, because current directory // context will change while executing testscripts. if !filepath.IsAbs(coverdir) { - abspath, err := filepath.Abs(coverdir) - if err != nil { + var err error + if coverdir, err = filepath.Abs(coverdir); err != nil { return fmt.Errorf("unable to determine absolute path of %q: %w", coverdir, err) } - coverdir = abspath - - } - - // If the given coverage directory doesn't exist, create it - info, err := os.Stat(coverdir) - if err != nil { - if errors.Is(err, os.ErrNotExist) { - if mkErr := os.Mkdir(coverdir, 0o755); mkErr != nil { - return fmt.Errorf("failed to testscripts coverage dir %q: %w", coverdir, mkErr) - } - } else { - // Handle other potential errors from os.Stat - return fmt.Errorf("failed to stat %q: %w", coverdir, err) - } - } else if !info.IsDir() { - return fmt.Errorf("coverage: %q is not a directory", coverdir) } + // Backup the original setup function origSetup := p.Setup p.Setup = func(env *testscript.Env) error { if origSetup != nil { + // Call previous setup first origSetup(env) } From d3ec1fd32aaaed1703a228a6b4619bcb05e40ba1 Mon Sep 17 00:00:00 2001 From: gfanton <8671905+gfanton@users.noreply.github.com> Date: Fri, 3 Nov 2023 16:47:35 +0100 Subject: [PATCH 11/13] chore: rework gno txtar setup Signed-off-by: gfanton <8671905+gfanton@users.noreply.github.com> --- gnovm/pkg/integration/gno.go | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/gnovm/pkg/integration/gno.go b/gnovm/pkg/integration/gno.go index 8da8f116e6c..56e18bbb5db 100644 --- a/gnovm/pkg/integration/gno.go +++ b/gnovm/pkg/integration/gno.go @@ -35,7 +35,12 @@ func SetupGno(p *testscript.Params, buildDir string) error { // Determine the path to the gno binary within the build directory gnoBin := filepath.Join(buildDir, "gno") - if _, err := os.Stat(gnoBin); errors.Is(err, os.ErrNotExist) { + if _, err := os.Stat(gnoBin); err != nil { + if !errors.Is(err, os.ErrNotExist) { + // Handle other potential errors from os.Stat + return err + } + // Build a fresh gno binary in a temp directory gnoArgsBuilder := []string{"build", "-o", gnoBin} @@ -50,9 +55,6 @@ func SetupGno(p *testscript.Params, buildDir string) error { if err = exec.Command("go", gnoArgsBuilder...).Run(); err != nil { return fmt.Errorf("unable to build gno binary: %w", err) } - } else if err != nil { - // Handle other potential errors from os.Stat - return err } // Store the original setup scripts for potential wrapping @@ -74,6 +76,8 @@ func SetupGno(p *testscript.Params, buildDir string) error { return fmt.Errorf("unable to create temporary home directory: %w", err) } env.Setenv("HOME", home) + + // Cleanup home folder env.Defer(func() { os.RemoveAll(home) }) return nil @@ -88,14 +92,15 @@ func SetupGno(p *testscript.Params, buildDir string) error { p.Cmds["gno"] = func(ts *testscript.TestScript, neg bool, args []string) { err := ts.Exec(gnoBin, args...) if err != nil { - ts.Logf("[%v]\n", err) - if !neg { - ts.Fatalf("unexpected gno command failure") - } - } else { - if neg { - ts.Fatalf("unexpected gno command success") - } + ts.Logf("gno command error: %v", err) + } + + commandSucceeded := (err == nil) + successExpected := !neg + + // Compare the command's success status with the expected outcome. + if commandSucceeded != successExpected { + ts.Fatalf("unexpected gno command outcome (err=%t expected=%t)", commandSucceeded, successExpected) } } From 60a5ee5492c42195beb3abbe88733f30cdb837cc Mon Sep 17 00:00:00 2001 From: gfanton <8671905+gfanton@users.noreply.github.com> Date: Fri, 3 Nov 2023 17:48:05 +0100 Subject: [PATCH 12/13] chore: rename methods and update comments Signed-off-by: gfanton <8671905+gfanton@users.noreply.github.com> --- .github/workflows/gnovm.yml | 4 +++- gnovm/cmd/gno/build_test.go | 8 +++++--- gnovm/cmd/gno/test_test.go | 8 +++++--- gnovm/pkg/integration/coverage.go | 21 +++++++++++---------- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/.github/workflows/gnovm.yml b/.github/workflows/gnovm.yml index 632807d8f14..5fa68ac305a 100644 --- a/.github/workflows/gnovm.yml +++ b/.github/workflows/gnovm.yml @@ -76,12 +76,14 @@ jobs: go-version: ${{ matrix.goversion }} - name: test working-directory: gnovm + env: + TXTARCOVERDIR: ${{ env.COVERAGE_DIR }} run: | mkdir -p $COVERAGE_DIR # Setup testing environements variables export GOPATH=$HOME/go - export GOTEST_FLAGS="-v -p 1 -timeout=30m -covermode=atomic -test.gocoverdir-txtar=$COVERAGE_DIR -test.gocoverdir=$COVERAGE_DIR" + export GOTEST_FLAGS="-v -p 1 -timeout=30m -covermode=atomic -test.gocoverdir=$COVERAGE_DIR" # Run target test make ${{ matrix.args }} diff --git a/gnovm/cmd/gno/build_test.go b/gnovm/cmd/gno/build_test.go index 9c4ef8f1d76..81aed7d1c79 100644 --- a/gnovm/cmd/gno/build_test.go +++ b/gnovm/cmd/gno/build_test.go @@ -13,10 +13,12 @@ func Test_ScriptsBuild(t *testing.T) { Dir: "testdata/gno_build", } - err := integration.SetupTestscriptsCoverageFromFlag(&p) - require.NoError(t, err) + if coverdir, ok := integration.ResolveCoverageDir(); ok { + err := integration.SetupTestscriptsCoverage(&p, coverdir) + require.NoError(t, err) + } - err = integration.SetupGno(&p, t.TempDir()) + err := integration.SetupGno(&p, t.TempDir()) require.NoError(t, err) testscript.Run(t, p) diff --git a/gnovm/cmd/gno/test_test.go b/gnovm/cmd/gno/test_test.go index 9a57d7f656f..b1dcfb21d29 100644 --- a/gnovm/cmd/gno/test_test.go +++ b/gnovm/cmd/gno/test_test.go @@ -13,10 +13,12 @@ func Test_ScriptsTest(t *testing.T) { Dir: "testdata/gno_test", } - err := integration.SetupTestscriptsCoverageFromFlag(&p) - require.NoError(t, err) + if coverdir, ok := integration.ResolveCoverageDir(); ok { + err := integration.SetupTestscriptsCoverage(&p, coverdir) + require.NoError(t, err) + } - err = integration.SetupGno(&p, t.TempDir()) + err := integration.SetupGno(&p, t.TempDir()) require.NoError(t, err) testscript.Run(t, p) diff --git a/gnovm/pkg/integration/coverage.go b/gnovm/pkg/integration/coverage.go index 844ac0107ea..017f5f9de88 100644 --- a/gnovm/pkg/integration/coverage.go +++ b/gnovm/pkg/integration/coverage.go @@ -15,19 +15,20 @@ var coverageEnv struct { func init() { flag.StringVar(&coverageEnv.coverdir, - "test.gocoverdir-txtar", "", "write testscripts coverage intermediate files to this directory") + "txtarcoverdir", "", "write testscripts coverage intermediate files to this directory") } -// SetupTestscriptsCoverageFromFlag checks the `test.gocoverdir-txtar` flag to determine -// whether to configure testscript parameters for coverage analysis. If the flag is not set, -// it will skip the setup process. -func SetupTestscriptsCoverageFromFlag(p *testscript.Params) error { - if coverageEnv.coverdir == "" { - // Skip coverage setup if `test.gocoverdir-txtar` flag wasn't specified - return nil +// ResolveCoverageDir attempts to resolve the coverage directory from the 'TXTARCOVERDIR' +// environment variable first, and if not set, from the 'test.txtarcoverdir' flag. +// It returns the resolved directory and a boolean indicating if the resolution was successful. +func ResolveCoverageDir() (string, bool) { + // Attempt to resolve the cover directory from the environment variable or flag + coverdir := os.Getenv("TXTARCOVERDIR") + if coverdir == "" { + coverdir = coverageEnv.coverdir } - return SetupTestscriptsCoverage(p, coverageEnv.coverdir) + return coverdir, coverdir != "" } // SetupTestscriptsCoverage sets up the given testscripts environment for coverage. @@ -38,7 +39,7 @@ func SetupTestscriptsCoverage(p *testscript.Params, coverdir string) error { if err != nil { return fmt.Errorf("output directory %q inaccessible: %w", coverdir, err) } else if !info.IsDir() { - return fmt.Errorf("output directory %q not a directory", coverdir) + return fmt.Errorf("output %q not a directory", coverdir) } // We need to have an absolute path here, because current directory From c69275c2b385aeae1f420e46aea4535988510b3b Mon Sep 17 00:00:00 2001 From: gfanton <8671905+gfanton@users.noreply.github.com> Date: Fri, 3 Nov 2023 17:51:28 +0100 Subject: [PATCH 13/13] Revert "chore: revert make flags order" This reverts commit c37a33153d6c4d03893db1b240deab9aa539fb5b. Signed-off-by: gfanton <8671905+gfanton@users.noreply.github.com> --- gnovm/Makefile | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/gnovm/Makefile b/gnovm/Makefile index 2fec34ad004..34e94f88633 100644 --- a/gnovm/Makefile +++ b/gnovm/Makefile @@ -46,16 +46,15 @@ _test.pkg: .PHONY: _test.gnolang _test.gnolang: _test.gnolang.native _test.gnolang.stdlibs _test.gnolang.realm _test.gnolang.pkg0 _test.gnolang.pkg1 _test.gnolang.pkg2 _test.gnolang.other -_test.gnolang.other:; go test $(GOTEST_FLAGS) tests/*.go -run "(TestFileStr|TestSelectors)" -_test.gnolang.realm:; go test $(GOTEST_FLAGS) tests/*.go -run "TestFiles/^zrealm" -_test.gnolang.pkg0:; go test $(GOTEST_FLAGS) tests/*.go -run "TestPackages/(bufio|crypto|encoding|errors|internal|io|math|sort|std|stdshim|strconv|strings|testing|unicode)" -_test.gnolang.pkg1:; go test $(GOTEST_FLAGS) tests/*.go -run "TestPackages/regexp" -_test.gnolang.pkg2:; go test $(GOTEST_FLAGS) tests/*.go -run "TestPackages/bytes" -_test.gnolang.native:; go test $(GOTEST_FLAGS) tests/*.go -test.short -run "TestFilesNative/" -_test.gnolang.stdlibs:; go test $(GOTEST_FLAGS) tests/*.go -test.short -run 'TestFiles$$/' -_test.gnolang.native.sync:; go test $(GOTEST_FLAGS) tests/*.go -test.short -run "TestFilesNative/" --update-golden-tests -_test.gnolang.stdlibs.sync:; go test $(GOTEST_FLAGS) tests/*.go -test.short -run 'TestFiles$$/' --update-golden-tests - +_test.gnolang.other:; go test tests/*.go -run "(TestFileStr|TestSelectors)" $(GOTEST_FLAGS) +_test.gnolang.realm:; go test tests/*.go -run "TestFiles/^zrealm" $(GOTEST_FLAGS) +_test.gnolang.pkg0:; go test tests/*.go -run "TestPackages/(bufio|crypto|encoding|errors|internal|io|math|sort|std|stdshim|strconv|strings|testing|unicode)" $(GOTEST_FLAGS) +_test.gnolang.pkg1:; go test tests/*.go -run "TestPackages/regexp" $(GOTEST_FLAGS) +_test.gnolang.pkg2:; go test tests/*.go -run "TestPackages/bytes" $(GOTEST_FLAGS) +_test.gnolang.native:; go test tests/*.go -test.short -run "TestFilesNative/" $(GOTEST_FLAGS) +_test.gnolang.stdlibs:; go test tests/*.go -test.short -run 'TestFiles$$/' $(GOTEST_FLAGS) +_test.gnolang.native.sync:; go test tests/*.go -test.short -run "TestFilesNative/" --update-golden-tests $(GOTEST_FLAGS) +_test.gnolang.stdlibs.sync:; go test tests/*.go -test.short -run 'TestFiles$$/' --update-golden-tests $(GOTEST_FLAGS) ######################################## # Code gen