Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(gnovm): test performance improvements #3210

Merged
merged 7 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/gnovm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ jobs:
uses: ./.github/workflows/main_template.yml
with:
modulepath: "gnovm"
# in pull requests, append -short so that the CI runs quickly.
tests-extra-args: ${{ github.event_name == 'pull_request' && '-short' || '' }}
secrets:
codecov-token: ${{ secrets.CODECOV_TOKEN }}
fmt:
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/test_template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,14 @@ jobs:
# Craft a filter flag based on the module path to avoid expanding coverage on unrelated tags.
export filter="-pkg=github.com/gnolang/gno/${{ inputs.modulepath }}/..."

# codecov only supports "boolean" coverage (whether a line is
# covered or not); so using -covermode=count or atomic would be
# pointless here.
# XXX: Simplify coverage of txtar - the current setup is a bit
# confusing and meticulous. There will be some improvements in Go
# 1.23 regarding coverage, so we can use this as a workaround until
# then.
go test -covermode=atomic -timeout ${{ inputs.tests-timeout }} ${{ inputs.tests-extra-args }} ./... -test.gocoverdir=$GOCOVERDIR
go test -covermode=set -timeout ${{ inputs.tests-timeout }} ${{ inputs.tests-extra-args }} ./... -test.gocoverdir=$GOCOVERDIR

# Print results
(set +x; echo 'go coverage results:')
Expand Down
79 changes: 60 additions & 19 deletions gnovm/pkg/gnolang/files_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,26 @@ func (nopReader) Read(p []byte) (int, error) { return 0, io.EOF }
// fix a specific test:
// go test -run TestFiles/'^bin1.gno' -short -v -update-golden-tests .
func TestFiles(t *testing.T) {
t.Parallel()

rootDir, err := filepath.Abs("../../../")
require.NoError(t, err)

opts := &test.TestOptions{
RootDir: rootDir,
Output: io.Discard,
Error: io.Discard,
Sync: *withSync,
newOpts := func() *test.TestOptions {
o := &test.TestOptions{
RootDir: rootDir,
Output: io.Discard,
Error: io.Discard,
Sync: *withSync,
}
o.BaseStore, o.TestStore = test.Store(
rootDir, true,
nopReader{}, o.WriterForStore(), io.Discard,
)
return o
}
opts.BaseStore, opts.TestStore = test.Store(
rootDir, true,
nopReader{}, opts.WriterForStore(), io.Discard,
)
// sharedOpts is used for all "short" tests.
sharedOpts := newOpts()

dir := "../../tests/"
fsys := os.DirFS(dir)
Expand All @@ -59,7 +66,8 @@ func TestFiles(t *testing.T) {
return nil
}
subTestName := path[len("files/"):]
if strings.HasSuffix(path, "_long.gno") && testing.Short() {
isLong := strings.HasSuffix(path, "_long.gno")
if isLong && testing.Short() {
t.Run(subTestName, func(t *testing.T) {
t.Skip("skipping in -short")
})
Expand All @@ -73,6 +81,12 @@ func TestFiles(t *testing.T) {

var criticalError error
t.Run(subTestName, func(t *testing.T) {
opts := sharedOpts
if isLong {
// Long tests are run in parallel, and with their own store.
t.Parallel()
opts = newOpts()
}
changed, err := opts.RunFiletest(path, content)
if err != nil {
t.Fatal(err.Error())
Expand All @@ -94,16 +108,24 @@ func TestFiles(t *testing.T) {

// TestStdlibs tests all the standard library packages.
func TestStdlibs(t *testing.T) {
t.Parallel()

rootDir, err := filepath.Abs("../../../")
require.NoError(t, err)

var capture bytes.Buffer
out := io.Writer(&capture)
if testing.Verbose() {
out = os.Stdout
newOpts := func() (capture *bytes.Buffer, opts *test.TestOptions) {
var out io.Writer
if testing.Verbose() {
out = os.Stdout
} else {
capture = new(bytes.Buffer)
out = capture
}
opts = test.NewTestOptions(rootDir, nopReader{}, out, out)
opts.Verbose = true
return
}
opts := test.NewTestOptions(rootDir, nopReader{}, out, out)
opts.Verbose = true
sharedCapture, sharedOpts := newOpts()

dir := "../../stdlibs/"
fsys := os.DirFS(dir)
Expand All @@ -118,12 +140,31 @@ func TestStdlibs(t *testing.T) {
fp := filepath.Join(dir, path)
memPkg := gnolang.ReadMemPackage(fp, path)
t.Run(strings.ReplaceAll(memPkg.Path, "/", "-"), func(t *testing.T) {
if testing.Short() {
switch memPkg.Path {
case "bytes", "strconv", "regexp/syntax":
capture, opts := sharedCapture, sharedOpts
switch memPkg.Path {
// Excluded in short
case
"bufio",
"bytes",
"strconv":
if testing.Short() {
t.Skip("Skipped because of -short, and this stdlib is very long currently.")
}
fallthrough
// Run using separate store, as it's faster
case
"math/rand",
"regexp",
"regexp/syntax",
"sort":
t.Parallel()
capture, opts = newOpts()
}

if capture != nil {
capture.Reset()
}

err := test.Test(memPkg, "", opts)
if !testing.Verbose() {
t.Log(capture.String())
Expand Down
2 changes: 2 additions & 0 deletions gnovm/pkg/test/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ func (opts *TestOptions) runTestFiles(
if opts.Metrics {
alloc = gno.NewAllocator(math.MaxInt64)
}
// reset store ops, if any - we only need them for some filetests.
opts.TestStore.SetLogStoreOps(false)

// Check if we already have the package - it may have been eagerly
// loaded.
Expand Down
2 changes: 2 additions & 0 deletions gnovm/stdlibs/bytes/compare_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ func TestCompareIdenticalSlice(t *testing.T) {
}

func TestCompareBytes(t *testing.T) {
t.Skip("This test takes very long to run on Gno at time of writing, even in its short form")

lengths := make([]int, 0) // lengths to test in ascending order
for i := 0; i <= 128; i++ {
lengths = append(lengths, i)
Expand Down
114 changes: 114 additions & 0 deletions gnovm/tests/stdlibs/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions gnovm/tests/stdlibs/unicode/natives.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package unicode

// Optimized as native bindings in tests.

func IsPrint(r rune) bool
func IsGraphic(r rune) bool
func SimpleFold(r rune) rune
func IsUpper(r rune) bool
8 changes: 8 additions & 0 deletions gnovm/tests/stdlibs/unicode/natives.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package unicode

import "unicode"

func IsPrint(r rune) bool { return unicode.IsPrint(r) }
func IsGraphic(r rune) bool { return unicode.IsGraphic(r) }
func SimpleFold(r rune) rune { return unicode.SimpleFold(r) }
func IsUpper(r rune) bool { return unicode.IsUpper(r) }
Loading