From 7f39243d612e1f37c518b701d770f9b09a8d3b41 Mon Sep 17 00:00:00 2001 From: Nevkontakte Date: Fri, 19 Jul 2024 22:56:41 +0100 Subject: [PATCH] Make slow stdlib tests faster. The main improvement here applies to crypto/internal/edwards25519/..., which use testing/quick for fuzz-style tests. Because those tests rely heavily on 64-bit math, they are much, much slower under GopherJS than upstream. I added a hook into testing/quick that allows us to cap the number of iterations a test would be allowed to execute. Although that does technically reduce coverage, it's better than disabling the test entirely and we don't change any logic in those packages in the first place. I deleted some overlays that corresponded to the old location of the same packages, the changes in this commit serve the same purpose. I also shortened a couple of tests in image/gif and crypto/x509, for the same reasons. --- .../src/crypto/ed25519/ed25519vectors_test.go | 10 ----- .../internal/edwards25519/field/fe_test.go | 10 ----- .../internal/edwards25519/scalar_test.go | 10 ----- .../edwards25519/field/fe_alias_test.go | 16 ++++++++ .../internal/edwards25519/field/fe_test.go | 9 +++++ .../internal/edwards25519/scalar_test.go | 9 +++++ .../internal/edwards25519/scalarmult_test.go | 9 +++++ .../src/crypto/x509/name_constraints_test.go | 16 ++++++++ compiler/natives/src/image/gif/fuzz_test.go | 14 +++++++ compiler/natives/src/testing/quick/quick.go | 37 +++++++++++++++++++ 10 files changed, 110 insertions(+), 30 deletions(-) delete mode 100644 compiler/natives/src/crypto/ed25519/ed25519vectors_test.go delete mode 100644 compiler/natives/src/crypto/ed25519/internal/edwards25519/field/fe_test.go delete mode 100644 compiler/natives/src/crypto/ed25519/internal/edwards25519/scalar_test.go create mode 100644 compiler/natives/src/crypto/internal/edwards25519/field/fe_alias_test.go create mode 100644 compiler/natives/src/crypto/internal/edwards25519/field/fe_test.go create mode 100644 compiler/natives/src/crypto/internal/edwards25519/scalar_test.go create mode 100644 compiler/natives/src/crypto/internal/edwards25519/scalarmult_test.go create mode 100644 compiler/natives/src/crypto/x509/name_constraints_test.go create mode 100644 compiler/natives/src/image/gif/fuzz_test.go create mode 100644 compiler/natives/src/testing/quick/quick.go diff --git a/compiler/natives/src/crypto/ed25519/ed25519vectors_test.go b/compiler/natives/src/crypto/ed25519/ed25519vectors_test.go deleted file mode 100644 index 90f455b9d..000000000 --- a/compiler/natives/src/crypto/ed25519/ed25519vectors_test.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build js -// +build js - -package ed25519_test - -import "testing" - -func TestEd25519Vectors(t *testing.T) { - t.Skip("exec.Command() is not supported by GopherJS") -} diff --git a/compiler/natives/src/crypto/ed25519/internal/edwards25519/field/fe_test.go b/compiler/natives/src/crypto/ed25519/internal/edwards25519/field/fe_test.go deleted file mode 100644 index c448d519c..000000000 --- a/compiler/natives/src/crypto/ed25519/internal/edwards25519/field/fe_test.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build js -// +build js - -package field - -import ( - "testing/quick" -) - -var quickCheckConfig1024 = &quick.Config{MaxCount: 100} diff --git a/compiler/natives/src/crypto/ed25519/internal/edwards25519/scalar_test.go b/compiler/natives/src/crypto/ed25519/internal/edwards25519/scalar_test.go deleted file mode 100644 index 612663d1c..000000000 --- a/compiler/natives/src/crypto/ed25519/internal/edwards25519/scalar_test.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build js -// +build js - -package edwards25519 - -import ( - "testing/quick" -) - -var quickCheckConfig32 = &quick.Config{MaxCount: 100} diff --git a/compiler/natives/src/crypto/internal/edwards25519/field/fe_alias_test.go b/compiler/natives/src/crypto/internal/edwards25519/field/fe_alias_test.go new file mode 100644 index 000000000..db4af600d --- /dev/null +++ b/compiler/natives/src/crypto/internal/edwards25519/field/fe_alias_test.go @@ -0,0 +1,16 @@ +//go:build js + +package field + +import ( + "testing" + "testing/quick" +) + +//gopherjs:keep-original +func TestAliasing(t *testing.T) { + // The test heavily uses 64-bit math, which is slow under GopherJS. Reducing + // the number of iterations makes run time more manageable. + t.Cleanup(quick.GopherJSInternalMaxCountCap(100)) + _gopherjs_original_TestAliasing(t) +} diff --git a/compiler/natives/src/crypto/internal/edwards25519/field/fe_test.go b/compiler/natives/src/crypto/internal/edwards25519/field/fe_test.go new file mode 100644 index 000000000..9f8c898d5 --- /dev/null +++ b/compiler/natives/src/crypto/internal/edwards25519/field/fe_test.go @@ -0,0 +1,9 @@ +//go:build js + +package field + +import "testing/quick" + +// Tests in this package use 64-bit math, which is slow under GopherJS. To keep +// test run time reasonable, we reduce the number of test iterations. +var quickCheckConfig1024 = &quick.Config{MaxCountScale: 10} diff --git a/compiler/natives/src/crypto/internal/edwards25519/scalar_test.go b/compiler/natives/src/crypto/internal/edwards25519/scalar_test.go new file mode 100644 index 000000000..ec862a349 --- /dev/null +++ b/compiler/natives/src/crypto/internal/edwards25519/scalar_test.go @@ -0,0 +1,9 @@ +//go:build js + +package edwards25519 + +import "testing/quick" + +// Tests in this package use 64-bit math, which is slow under GopherJS. To keep +// test run time reasonable, we reduce the number of test iterations. +var quickCheckConfig1024 = &quick.Config{MaxCountScale: 1} diff --git a/compiler/natives/src/crypto/internal/edwards25519/scalarmult_test.go b/compiler/natives/src/crypto/internal/edwards25519/scalarmult_test.go new file mode 100644 index 000000000..9cacfb24c --- /dev/null +++ b/compiler/natives/src/crypto/internal/edwards25519/scalarmult_test.go @@ -0,0 +1,9 @@ +//go:build js + +package edwards25519 + +import "testing/quick" + +// Tests in this package use 64-bit math, which is slow under GopherJS. To keep +// test run time reasonable, we reduce the number of test iterations. +var quickCheckConfig32 = &quick.Config{MaxCountScale: 0.5} diff --git a/compiler/natives/src/crypto/x509/name_constraints_test.go b/compiler/natives/src/crypto/x509/name_constraints_test.go new file mode 100644 index 000000000..9b1190a6d --- /dev/null +++ b/compiler/natives/src/crypto/x509/name_constraints_test.go @@ -0,0 +1,16 @@ +//go:build js + +package x509 + +import "testing" + +//gopherjs:keep-original +func TestConstraintCases(t *testing.T) { + if testing.Short() { + // These tests are slow under GopherJS. Since GopherJS doesn't touch + // business logic behind them, there's little value in running them all. + // Instead, in the short mode we just just the first few as a smoke test. + nameConstraintsTests = nameConstraintsTests[0:5] + } + _gopherjs_original_TestConstraintCases(t) +} diff --git a/compiler/natives/src/image/gif/fuzz_test.go b/compiler/natives/src/image/gif/fuzz_test.go new file mode 100644 index 000000000..b79977bfc --- /dev/null +++ b/compiler/natives/src/image/gif/fuzz_test.go @@ -0,0 +1,14 @@ +//go:build js + +package gif + +import "testing" + +//gopherjs:keep-original +func FuzzDecode(t *testing.F) { + if testing.Short() { + t.Skip("FuzzDecode is slow, skipping in the short mode.") + } + + _gopherjs_original_FuzzDecode(t) +} diff --git a/compiler/natives/src/testing/quick/quick.go b/compiler/natives/src/testing/quick/quick.go new file mode 100644 index 000000000..51fa843aa --- /dev/null +++ b/compiler/natives/src/testing/quick/quick.go @@ -0,0 +1,37 @@ +//go:build js + +package quick + +var maxCountCap int = 0 + +// GopherJSInternalMaxCountCap sets an upper bound of iterations quick test may +// perform. THIS IS GOPHERJS-INTERNAL API, DO NOT USE IT OUTSIDE OF THE GOPHERJS +// CODEBASE, IT MAY CHANGE OR DISAPPEAR WITHOUT NOTICE. +// +// This function can be used to limit run time of standard library tests which +// use testing/quick with too many iterations for GopherJS to complete in a +// reasonable amount of time. This is a better compromise than disabling a slow +// test entirely. +// +// //gopherjs:keep-original +// func TestFoo(t *testing.T) { +// t.Cleanup(quick.GopherJSInternalMaxCountCap(100)) +// _gopherjs_original_TestFoo(t) +// } + +func GopherJSInternalMaxCountCap(newCap int) (restore func()) { + previousCap := maxCountCap + maxCountCap = newCap + return func() { + maxCountCap = previousCap + } +} + +//gopherjs:keep-original +func (c *Config) getMaxCount() (maxCount int) { + maxCount = c._gopherjs_original_getMaxCount() + if maxCountCap > 0 && maxCount > maxCountCap { + maxCount = maxCountCap + } + return maxCount +}