From 66649d2d92bf92d8ffe3c51e7208895366889e58 Mon Sep 17 00:00:00 2001 From: Oleg Bespalov Date: Fri, 25 Oct 2024 18:40:16 +0200 Subject: [PATCH 1/5] Refactor web platform test --- .github/workflows/wpt.yml | 2 +- webcrypto/{tests => }/cmd_run_test.go | 18 +- webcrypto/subtle_crypto_test.go | 311 -------------------------- webcrypto/{ => tests}/crypto_test.go | 4 +- webcrypto/tests/subtle_crypto_test.go | 194 ++++++++++++++++ webcrypto/{ => tests}/test_setup.go | 13 +- 6 files changed, 215 insertions(+), 327 deletions(-) rename webcrypto/{tests => }/cmd_run_test.go (92%) delete mode 100644 webcrypto/subtle_crypto_test.go rename webcrypto/{ => tests}/crypto_test.go (99%) create mode 100644 webcrypto/tests/subtle_crypto_test.go rename webcrypto/{ => tests}/test_setup.go (88%) diff --git a/.github/workflows/wpt.yml b/.github/workflows/wpt.yml index 73680a4..66af526 100644 --- a/.github/workflows/wpt.yml +++ b/.github/workflows/wpt.yml @@ -23,4 +23,4 @@ jobs: set -x cd webcrypto/tests sh checkout.sh - go test -race ../... -tags=wpt + go test -race ./... -tags=wpt diff --git a/webcrypto/tests/cmd_run_test.go b/webcrypto/cmd_run_test.go similarity index 92% rename from webcrypto/tests/cmd_run_test.go rename to webcrypto/cmd_run_test.go index a0d71af..ad9437e 100644 --- a/webcrypto/tests/cmd_run_test.go +++ b/webcrypto/cmd_run_test.go @@ -1,4 +1,4 @@ -package tests +package webcrypto_test import ( "os" @@ -57,14 +57,14 @@ func TestExamplesInputOutput(t *testing.T) { // and not the unexpected one // it could be a file (ending with .js) or a directory examples := []string{ - "../../examples/digest.js", - "../../examples/getRandomValues.js", - "../../examples/randomUUID.js", - "../../examples/generateKey", - "../../examples/derive_bits", - "../../examples/encrypt_decrypt", - "../../examples/sign_verify", - "../../examples/import_export", + "../examples/digest.js", + "../examples/getRandomValues.js", + "../examples/randomUUID.js", + "../examples/generateKey", + "../examples/derive_bits", + "../examples/encrypt_decrypt", + "../examples/sign_verify", + "../examples/import_export", } for _, path := range examples { diff --git a/webcrypto/subtle_crypto_test.go b/webcrypto/subtle_crypto_test.go deleted file mode 100644 index 7c2bc15..0000000 --- a/webcrypto/subtle_crypto_test.go +++ /dev/null @@ -1,311 +0,0 @@ -//go:build wpt - -package webcrypto - -import ( - "os" - "testing" - - "github.com/grafana/sobek" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "go.k6.io/k6/js/modulestest" -) - -const webPlatformTestSuite = "./tests/wpt/WebCryptoAPI/" - -func newWebPlatformTestRuntime(t testing.TB) *modulestest.Runtime { - // check if the test is running in the correct environment - info, err := os.Stat(webPlatformTestSuite) - if os.IsNotExist(err) || err != nil || !info.IsDir() { - t.Fatalf("The Web Platform Test directory does not exist, err: %s", err) - } - - return newConfiguredRuntime(t) -} - -func TestSubtleDigest(t *testing.T) { - t.Parallel() - - ts := newWebPlatformTestRuntime(t) - - gotErr := ts.EventLoop.Start(func() error { - return executeTestScripts( - ts.VU.Runtime(), - webPlatformTestSuite+"digest", - "digest.https.any.js", - ) - }) - - assert.NoError(t, gotErr) -} - -func TestSubtleCryptoGenerateKey(t *testing.T) { - t.Parallel() - - t.Run("successes", func(t *testing.T) { - t.Parallel() - - ts := newWebPlatformTestRuntime(t) - - gotErr := ts.EventLoop.Start(func() error { - err := executeTestScripts(ts.VU.Runtime(), webPlatformTestSuite+"generateKey", "successes.js") - require.NoError(t, err) - - _, err = ts.VU.Runtime().RunString(`run_test()`) - - return err - }) - - assert.NoError(t, gotErr) - }) - - t.Run("failures", func(t *testing.T) { - t.Parallel() - - ts := newWebPlatformTestRuntime(t) - - gotErr := ts.EventLoop.Start(func() error { - err := executeTestScripts(ts.VU.Runtime(), webPlatformTestSuite+"generateKey", "failures.js") - require.NoError(t, err) - - _, err = ts.VU.Runtime().RunString(`run_test()`) - - return err - }) - - assert.NoError(t, gotErr) - }) -} - -func TestSubtleCryptoImportExportKey(t *testing.T) { - t.Parallel() - - t.Run("symmetric", func(t *testing.T) { - t.Parallel() - - ts := newWebPlatformTestRuntime(t) - - gotErr := ts.EventLoop.Start(func() error { - err := executeTestScripts(ts.VU.Runtime(), webPlatformTestSuite+"import_export", "symmetric_importKey.https.any.js") - - return err - }) - - assert.NoError(t, gotErr) - }) - - t.Run("elliptic-curves", func(t *testing.T) { - t.Parallel() - - ts := newWebPlatformTestRuntime(t) - - gotErr := ts.EventLoop.Start(func() error { - err := executeTestScripts(ts.VU.Runtime(), webPlatformTestSuite+"import_export", "ec_importKey.https.any.js") - - return err - }) - - assert.NoError(t, gotErr) - }) - - t.Run("rsa", func(t *testing.T) { - t.Parallel() - - ts := newWebPlatformTestRuntime(t) - - gotErr := ts.EventLoop.Start(func() error { - return executeTestScripts( - ts.VU.Runtime(), - webPlatformTestSuite+"import_export", - "rsa_importKey.https.any.js", - ) - }) - - assert.NoError(t, gotErr) - }) -} - -func TestSubtleCryptoEncryptDecrypt(t *testing.T) { - t.Parallel() - - t.Run("AES CBC", func(t *testing.T) { - t.Parallel() - - ts := newWebPlatformTestRuntime(t) - - gotErr := ts.EventLoop.Start(func() error { - err := executeTestScripts(ts.VU.Runtime(), webPlatformTestSuite+"encrypt_decrypt", "aes_cbc_vectors.js", "aes.js") - require.NoError(t, err) - - _, err = ts.VU.Runtime().RunString(`run_test()`) - - return err - }) - - assert.NoError(t, gotErr) - }) - - t.Run("AES CTR", func(t *testing.T) { - t.Parallel() - - ts := newWebPlatformTestRuntime(t) - - gotErr := ts.EventLoop.Start(func() error { - err := executeTestScripts(ts.VU.Runtime(), webPlatformTestSuite+"encrypt_decrypt", "aes_ctr_vectors.js", "aes.js") - require.NoError(t, err) - - _, err = ts.VU.Runtime().RunString(`run_test()`) - - return err - }) - - assert.NoError(t, gotErr) - }) - - // Note @oleiade: although the specification targets support - // for various iv sizes, go AES GCM cipher only supports 96bits. - // Thus, although the official WebPlatform test suite contains - // vectors for various iv sizes, we only test the 96bits one. - t.Run("AES GCM 96bits iv", func(t *testing.T) { - t.Parallel() - - ts := newWebPlatformTestRuntime(t) - - gotErr := ts.EventLoop.Start(func() error { - err := executeTestScripts(ts.VU.Runtime(), webPlatformTestSuite+"encrypt_decrypt", "aes_gcm_96_iv_fixtures.js", "aes_gcm_vectors.js", "aes.js") - require.NoError(t, err) - - _, err = ts.VU.Runtime().RunString(`run_test()`) - - return err - }) - - assert.NoError(t, gotErr) - }) - - t.Run("RSA-OAEP", func(t *testing.T) { - t.Parallel() - - ts := newWebPlatformTestRuntime(t) - - gotErr := ts.EventLoop.Start(func() error { - err := executeTestScripts(ts.VU.Runtime(), webPlatformTestSuite+"encrypt_decrypt", "rsa_vectors.js", "rsa.js") - require.NoError(t, err) - - _, err = ts.VU.Runtime().RunString(`run_test()`) - - return err - }) - - assert.NoError(t, gotErr) - }) -} - -func TestSubtleCryptoSignVerify(t *testing.T) { - t.Parallel() - - t.Run("HMAC", func(t *testing.T) { - t.Parallel() - - ts := newWebPlatformTestRuntime(t) - - gotErr := ts.EventLoop.Start(func() error { - err := executeTestScripts(ts.VU.Runtime(), webPlatformTestSuite+"sign_verify", "hmac_vectors.js", "hmac.js") - require.NoError(t, err) - - _, err = ts.VU.Runtime().RunString(`run_test()`) - - return err - }) - - assert.NoError(t, gotErr) - }) - - t.Run("ECDSA", func(t *testing.T) { - t.Parallel() - - ts := newWebPlatformTestRuntime(t) - - gotErr := ts.EventLoop.Start(func() error { - err := executeTestScripts(ts.VU.Runtime(), webPlatformTestSuite+"sign_verify", "ecdsa_vectors.js", "ecdsa.js") - require.NoError(t, err) - - _, err = ts.VU.Runtime().RunString(`run_test()`) - - return err - }) - - assert.NoError(t, gotErr) - }) - - t.Run("RSA-PKCS", func(t *testing.T) { - t.Parallel() - - ts := newWebPlatformTestRuntime(t) - - gotErr := ts.EventLoop.Start(func() error { - err := executeTestScripts(ts.VU.Runtime(), webPlatformTestSuite+"sign_verify", "rsa_pkcs_vectors.js", "rsa.js") - require.NoError(t, err) - - _, err = ts.VU.Runtime().RunString(`run_test()`) - - return err - }) - - assert.NoError(t, gotErr) - }) - - t.Run("RSA-PSS", func(t *testing.T) { - t.Parallel() - - ts := newWebPlatformTestRuntime(t) - - gotErr := ts.EventLoop.Start(func() error { - err := executeTestScripts(ts.VU.Runtime(), webPlatformTestSuite+"sign_verify", "rsa_pss_vectors.js", "rsa.js") - require.NoError(t, err) - - _, err = ts.VU.Runtime().RunString(`run_test()`) - - return err - }) - - assert.NoError(t, gotErr) - }) -} - -func TestSubtleCryptoDeriveBitsKeys(t *testing.T) { - t.Parallel() - - t.Run("ecdh", func(t *testing.T) { - t.Parallel() - - ts := newWebPlatformTestRuntime(t) - - gotErr := ts.EventLoop.Start(func() error { - err := executeTestScripts(ts.VU.Runtime(), webPlatformTestSuite+"derive_bits_keys", "ecdh_bits.js") - require.NoError(t, err) - - _, err = ts.VU.Runtime().RunString(`define_tests()`) - - return err - }) - - assert.NoError(t, gotErr) - }) -} - -func executeTestScripts(rt *sobek.Runtime, base string, scripts ...string) error { - for _, script := range scripts { - program, err := CompileFile(base, script) - if err != nil { - return err - } - - if _, err = rt.RunProgram(program); err != nil { - return err - } - } - - return nil -} diff --git a/webcrypto/crypto_test.go b/webcrypto/tests/crypto_test.go similarity index 99% rename from webcrypto/crypto_test.go rename to webcrypto/tests/crypto_test.go index ef9e44f..6de1cf7 100644 --- a/webcrypto/crypto_test.go +++ b/webcrypto/tests/crypto_test.go @@ -1,4 +1,6 @@ -package webcrypto +//go:build wpt + +package tests import ( "fmt" diff --git a/webcrypto/tests/subtle_crypto_test.go b/webcrypto/tests/subtle_crypto_test.go new file mode 100644 index 0000000..368840d --- /dev/null +++ b/webcrypto/tests/subtle_crypto_test.go @@ -0,0 +1,194 @@ +// Part of the Web Platform Tests suite for the k6's WebCrypto API +//go:build wpt + +package tests + +import ( + "os" + "strings" + "testing" + + "github.com/grafana/sobek" + "github.com/stretchr/testify/assert" + "go.k6.io/k6/js/modulestest" +) + +const webPlatformTestSuite = "./wpt/WebCryptoAPI/" + +func newWebPlatformTestRuntime(t testing.TB) *modulestest.Runtime { + // check if the test is running in the correct environment + info, err := os.Stat(webPlatformTestSuite) + if os.IsNotExist(err) || err != nil || !info.IsDir() { + t.Fatalf("The Web Platform Test directory does not exist, err: %s", err) + } + + return newConfiguredRuntime(t) +} + +func TestWebPlatformTestSuite(t *testing.T) { + t.Parallel() + + tests := []struct { + // catalog is the catalog relatively webPlatformTestSuite where to look files + catalog string + // files is the list of files to execute + files []string + // callFn is the function to call after the files are executed + // if empty, no function will be called + callFn string + }{ + { + catalog: "digest", + files: []string{ + "digest.https.any.js", + }, + }, + { + catalog: "generateKey", + files: []string{ + "successes.js", + }, + callFn: "run_test", + }, + { + catalog: "generateKey", + files: []string{ + "failures.js", + }, + callFn: "run_test", + }, + { + catalog: "import_export", + files: []string{ + "symmetric_importKey.https.any.js", + }, + }, + { + catalog: "import_export", + files: []string{ + "ec_importKey.https.any.js", + }, + }, + { + catalog: "import_export", + files: []string{ + "rsa_importKey.https.any.js", + }, + }, + { + catalog: "encrypt_decrypt", + files: []string{ + "aes_cbc_vectors.js", + "aes.js", + }, + callFn: "run_test", + }, + { + catalog: "encrypt_decrypt", + files: []string{ + "aes_ctr_vectors.js", + "aes.js", + }, + callFn: "run_test", + }, + { + // Note @oleiade: although the specification targets support + // for various iv sizes, go AES GCM cipher only supports 96bits. + // Thus, although the official WebPlatform test suite contains + // vectors for various iv sizes, we only test the 96bits one. + catalog: "encrypt_decrypt", + files: []string{ + "aes_gcm_96_iv_fixtures.js", + "aes_gcm_vectors.js", + "aes.js", + }, + callFn: "run_test", + }, + { + // RSA-OAEP + catalog: "encrypt_decrypt", + files: []string{ + "rsa_vectors.js", + "rsa.js", + }, + callFn: "run_test", + }, + { + catalog: "sign_verify", + files: []string{ + "hmac_vectors.js", "hmac.js", + }, + callFn: "run_test", + }, + { + catalog: "sign_verify", + files: []string{ + "ecdsa_vectors.js", + "ecdsa.js", + }, + callFn: "run_test", + }, + { + catalog: "sign_verify", + files: []string{ + "rsa_pss_vectors.js", + "rsa.js", + }, + callFn: "run_test", + }, + { + catalog: "sign_verify", + files: []string{ + "rsa_pss_vectors.js", "rsa.js", + }, + callFn: "run_test", + }, + { + catalog: "derive_bits_keys", + files: []string{ + "ecdh_bits.js", + }, + callFn: "define_tests", + }, + } + + for _, tt := range tests { + tt := tt + testName := tt.catalog + "/" + strings.Join(tt.files, "_") + + t.Run(testName, func(t *testing.T) { + t.Parallel() + + ts := newWebPlatformTestRuntime(t) + + gotErr := ts.EventLoop.Start(func() error { + if err := executeTestScripts(ts.VU.Runtime(), webPlatformTestSuite+tt.catalog, tt.files...); err != nil { + return err + } + + if tt.callFn == "" { + return nil + } + + _, err := ts.VU.Runtime().RunString(tt.callFn + `()`) + return err + }) + assert.NoError(t, gotErr) + }) + } +} + +func executeTestScripts(rt *sobek.Runtime, base string, scripts ...string) error { + for _, script := range scripts { + program, err := CompileFile(base, script) + if err != nil { + return err + } + + if _, err = rt.RunProgram(program); err != nil { + return err + } + } + + return nil +} diff --git a/webcrypto/test_setup.go b/webcrypto/tests/test_setup.go similarity index 88% rename from webcrypto/test_setup.go rename to webcrypto/tests/test_setup.go index 84d3977..db066af 100644 --- a/webcrypto/test_setup.go +++ b/webcrypto/tests/test_setup.go @@ -1,4 +1,6 @@ -package webcrypto +//go:build wpt + +package tests import ( "io" @@ -10,6 +12,7 @@ import ( "go.k6.io/k6/js/compiler" "github.com/grafana/sobek" + "github.com/grafana/xk6-webcrypto/webcrypto" "github.com/stretchr/testify/require" k6encoding "go.k6.io/k6/js/modules/k6/encoding" "go.k6.io/k6/js/modulestest" @@ -28,14 +31,14 @@ func newConfiguredRuntime(t testing.TB) *modulestest.Runtime { runtime := modulestest.NewRuntime(t) err = runtime.SetupModuleSystem( - map[string]interface{}{"k6/x/webcrypto": New()}, + map[string]interface{}{"k6/x/webcrypto": webcrypto.New()}, nil, compiler.New(runtime.VU.InitEnv().Logger), ) require.NoError(t, err) // We compile the Web Platform testharness script into a sobek.Program - harnessProgram, err := CompileFile("./tests/util", "testharness.js") + harnessProgram, err := CompileFile("./util", "testharness.js") require.NoError(t, err) // We execute the harness script in the goja runtime @@ -45,7 +48,7 @@ func newConfiguredRuntime(t testing.TB) *modulestest.Runtime { require.NoError(t, err) // We compile the Web Platform helpers script into a sobek.Program - helpersProgram, err := CompileFile("./tests/util", "helpers.js") + helpersProgram, err := CompileFile("./util", "helpers.js") require.NoError(t, err) // We execute the helpers script in the goja runtime @@ -54,7 +57,7 @@ func newConfiguredRuntime(t testing.TB) *modulestest.Runtime { _, err = runtime.VU.Runtime().RunProgram(helpersProgram) require.NoError(t, err) - m := new(RootModule).NewModuleInstance(runtime.VU) + m := new(webcrypto.RootModule).NewModuleInstance(runtime.VU) err = runtime.VU.Runtime().Set("crypto", m.Exports().Named["crypto"]) require.NoError(t, err) From 340001dcc7b495f07bc94c00eabaae8fa57ecf40 Mon Sep 17 00:00:00 2001 From: Oleg Bespalov Date: Fri, 25 Oct 2024 18:58:10 +0200 Subject: [PATCH 2/5] wpt: minimize patches diff --- webcrypto/tests/util/testharness.js | 14 +++++++++++++- ...CryptoAPI__derive_bits_keys__ecdh_bits.js.patch | 11 +---------- ...WebCryptoAPI__digest__digest.https.any.js.patch | 14 -------------- .../WebCryptoAPI__encrypt_decrypt__aes.js.patch | 10 +--------- .../WebCryptoAPI__encrypt_decrypt__rsa.js.patch | 10 +--------- .../WebCryptoAPI__generateKey__failures.js.patch | 11 +---------- .../WebCryptoAPI__generateKey__successes.js.patch | 11 +---------- .../WebCryptoAPI__sign_verify__ecdsa.js.patch | 13 +------------ .../WebCryptoAPI__sign_verify__hmac.js.patch | 13 +------------ .../WebCryptoAPI__sign_verify__rsa.js.patch | 13 +------------ 10 files changed, 21 insertions(+), 99 deletions(-) delete mode 100644 webcrypto/tests/wpt-patches/WebCryptoAPI__digest__digest.https.any.js.patch diff --git a/webcrypto/tests/util/testharness.js b/webcrypto/tests/util/testharness.js index c95983c..1a112cf 100644 --- a/webcrypto/tests/util/testharness.js +++ b/webcrypto/tests/util/testharness.js @@ -92,6 +92,8 @@ function assert_unreached(description) { throw `reached unreachable code, reason: ${description}` } +// overloads of the some test functions + // this is a minimal implementation of the promise_test function // which used in many web platform tests function promise_test(fn, name) { @@ -100,4 +102,14 @@ function promise_test(fn, name) { } catch (e) { throw Error(`Error in test "${name}": ${e}`); } -} \ No newline at end of file +} + +// this is a minimal implementation of the done function +// which used in many web platform tests +function done() {} + +// this is a minimal implementation of the setup function +function setup() {} + +// some tests use the global object, so we need to define it +const self = globalThis; \ No newline at end of file diff --git a/webcrypto/tests/wpt-patches/WebCryptoAPI__derive_bits_keys__ecdh_bits.js.patch b/webcrypto/tests/wpt-patches/WebCryptoAPI__derive_bits_keys__ecdh_bits.js.patch index c07e7f3..f687786 100644 --- a/webcrypto/tests/wpt-patches/WebCryptoAPI__derive_bits_keys__ecdh_bits.js.patch +++ b/webcrypto/tests/wpt-patches/WebCryptoAPI__derive_bits_keys__ecdh_bits.js.patch @@ -1,16 +1,7 @@ diff --git a/WebCryptoAPI/derive_bits_keys/ecdh_bits.js b/WebCryptoAPI/derive_bits_keys/ecdh_bits.js -index 36b29c20a..e3bd4ccb5 100644 +index 36b29c20a..c9c413599 100644 --- a/WebCryptoAPI/derive_bits_keys/ecdh_bits.js +++ b/WebCryptoAPI/derive_bits_keys/ecdh_bits.js -@@ -1,7 +1,7 @@ - - function define_tests() { - // May want to test prefixed implementations. -- var subtle = self.crypto.subtle; -+ var subtle = crypto.subtle; - - var pkcs8 = { - "P-521": new Uint8Array([48, 129, 238, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 4, 129, 214, 48, 129, 211, 2, 1, 1, 4, 66, 1, 166, 126, 211, 33, 145, 90, 100, 170, 53, 155, 125, 100, 141, 220, 38, 24, 250, 142, 141, 24, 103, 232, 247, 24, 48, 177, 13, 37, 237, 40, 145, 250, 241, 47, 60, 126, 117, 66, 26, 46, 162, 100, 249, 169, 21, 50, 13, 39, 79, 225, 71, 7, 66, 185, 132, 233, 107, 152, 145, 32, 129, 250, 205, 71, 141, 161, 129, 137, 3, 129, 134, 0, 4, 0, 32, 157, 72, 63, 40, 102, 104, 129, 198, 100, 31, 58, 18, 111, 64, 15, 81, 228, 101, 17, 112, 254, 103, 140, 117, 232, 87, 18, 226, 134, 138, 220, 133, 8, 36, 153, 123, 235, 240, 188, 130, 180, 48, 40, 166, 210, 236, 23, 119, 202, 69, 39, 159, 114, 6, 163, 234, 139, 92, 210, 7, 63, 73, 62, 69, 0, 12, 181, 76, 58, 90, 202, 162, 104, 197, 103, 16, 66, 136, 120, 217, 139, 138, 251, 246, 138, 97, 33, 83, 99, 40, 70, 216, 7, 233, 38, 114, 105, 143, 27, 156, 97, 29, 231, 211, 142, 52, 205, 108, 115, 136, 144, 146, 197, 110, 82, 214, 128, 241, 223, 208, 146, 184, 122, 200, 239, 159, 243, 200, 251, 72]), @@ -65,15 +65,17 @@ function define_tests() { }); }, namedCurve + " short result"); diff --git a/webcrypto/tests/wpt-patches/WebCryptoAPI__digest__digest.https.any.js.patch b/webcrypto/tests/wpt-patches/WebCryptoAPI__digest__digest.https.any.js.patch deleted file mode 100644 index c6c31ab..0000000 --- a/webcrypto/tests/wpt-patches/WebCryptoAPI__digest__digest.https.any.js.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/WebCryptoAPI/digest/digest.https.any.js b/WebCryptoAPI/digest/digest.https.any.js -index 379d9311f..949b1669f 100644 ---- a/WebCryptoAPI/digest/digest.https.any.js -+++ b/WebCryptoAPI/digest/digest.https.any.js -@@ -119,9 +119,6 @@ - }); - - -- done(); -- -- - // Returns a copy of the sourceBuffer it is sent. - function copyBuffer(sourceBuffer) { - var source = new Uint8Array(sourceBuffer); diff --git a/webcrypto/tests/wpt-patches/WebCryptoAPI__encrypt_decrypt__aes.js.patch b/webcrypto/tests/wpt-patches/WebCryptoAPI__encrypt_decrypt__aes.js.patch index f4a1413..773d7b8 100644 --- a/webcrypto/tests/wpt-patches/WebCryptoAPI__encrypt_decrypt__aes.js.patch +++ b/webcrypto/tests/wpt-patches/WebCryptoAPI__encrypt_decrypt__aes.js.patch @@ -1,15 +1,7 @@ diff --git a/WebCryptoAPI/encrypt_decrypt/aes.js b/WebCryptoAPI/encrypt_decrypt/aes.js -index fdeb7963f..1fb5ffc8f 100644 +index fdeb7963f..b2257a320 100644 --- a/WebCryptoAPI/encrypt_decrypt/aes.js +++ b/WebCryptoAPI/encrypt_decrypt/aes.js -@@ -1,6 +1,6 @@ - - function run_test() { -- var subtle = self.crypto.subtle; // Change to test prefixed implementations -+ var subtle = crypto.subtle; // Change to test prefixed implementations - - // When are all these tests really done? When all the promises they use have resolved. - var all_promises = []; @@ -267,12 +267,6 @@ function run_test() { all_promises.push(promise); }); diff --git a/webcrypto/tests/wpt-patches/WebCryptoAPI__encrypt_decrypt__rsa.js.patch b/webcrypto/tests/wpt-patches/WebCryptoAPI__encrypt_decrypt__rsa.js.patch index bb48237..839913a 100644 --- a/webcrypto/tests/wpt-patches/WebCryptoAPI__encrypt_decrypt__rsa.js.patch +++ b/webcrypto/tests/wpt-patches/WebCryptoAPI__encrypt_decrypt__rsa.js.patch @@ -1,15 +1,7 @@ diff --git a/WebCryptoAPI/encrypt_decrypt/rsa.js b/WebCryptoAPI/encrypt_decrypt/rsa.js -index 5eae06e47..4be7c37a5 100644 +index 5eae06e47..819878cf4 100644 --- a/WebCryptoAPI/encrypt_decrypt/rsa.js +++ b/WebCryptoAPI/encrypt_decrypt/rsa.js -@@ -1,6 +1,6 @@ - - function run_test() { -- var subtle = self.crypto.subtle; // Change to test prefixed implementations -+ var subtle = crypto.subtle; // Change to test prefixed implementations - - // When are all these tests really done? When all the promises they use have resolved. - var all_promises = []; @@ -291,13 +291,7 @@ function run_test() { }); diff --git a/webcrypto/tests/wpt-patches/WebCryptoAPI__generateKey__failures.js.patch b/webcrypto/tests/wpt-patches/WebCryptoAPI__generateKey__failures.js.patch index e8275b3..87c6f47 100644 --- a/webcrypto/tests/wpt-patches/WebCryptoAPI__generateKey__failures.js.patch +++ b/webcrypto/tests/wpt-patches/WebCryptoAPI__generateKey__failures.js.patch @@ -1,16 +1,7 @@ diff --git a/WebCryptoAPI/generateKey/failures.js b/WebCryptoAPI/generateKey/failures.js -index e0f0279a6..8effd593c 100644 +index e0f0279a6..eaab20068 100644 --- a/WebCryptoAPI/generateKey/failures.js +++ b/WebCryptoAPI/generateKey/failures.js -@@ -1,7 +1,7 @@ - function run_test(algorithmNames) { - var subtle = crypto.subtle; // Change to test prefixed implementations - -- setup({explicit_timeout: true}); -+ // setup({explicit_timeout: true}); - - // These tests check that generateKey throws an error, and that - // the error is of the right type, for a wide set of incorrect parameters. @@ -25,17 +25,17 @@ function run_test(algorithmNames) { {name: "AES-CTR", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, {name: "AES-CBC", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, diff --git a/webcrypto/tests/wpt-patches/WebCryptoAPI__generateKey__successes.js.patch b/webcrypto/tests/wpt-patches/WebCryptoAPI__generateKey__successes.js.patch index e625263..50d839c 100644 --- a/webcrypto/tests/wpt-patches/WebCryptoAPI__generateKey__successes.js.patch +++ b/webcrypto/tests/wpt-patches/WebCryptoAPI__generateKey__successes.js.patch @@ -1,16 +1,7 @@ diff --git a/WebCryptoAPI/generateKey/successes.js b/WebCryptoAPI/generateKey/successes.js -index a9a168e1a..77d7b909a 100644 +index a9a168e1a..88861ab87 100644 --- a/WebCryptoAPI/generateKey/successes.js +++ b/WebCryptoAPI/generateKey/successes.js -@@ -2,7 +2,7 @@ - function run_test(algorithmNames, slowTest) { - var subtle = crypto.subtle; // Change to test prefixed implementations - -- setup({explicit_timeout: true}); -+ // setup({explicit_timeout: true}); - - // These tests check that generateKey successfully creates keys - // when provided any of a wide set of correct parameters @@ -21,17 +21,17 @@ function run_test(algorithmNames, slowTest) { {name: "AES-CTR", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, {name: "AES-CBC", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, diff --git a/webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__ecdsa.js.patch b/webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__ecdsa.js.patch index 225340e..8a5ef7f 100644 --- a/webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__ecdsa.js.patch +++ b/webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__ecdsa.js.patch @@ -1,18 +1,7 @@ diff --git a/WebCryptoAPI/sign_verify/ecdsa.js b/WebCryptoAPI/sign_verify/ecdsa.js -index 6bf662adc..7a1eb0178 100644 +index 6bf662adc..dcda1a1b1 100644 --- a/WebCryptoAPI/sign_verify/ecdsa.js +++ b/WebCryptoAPI/sign_verify/ecdsa.js -@@ -1,8 +1,8 @@ - - function run_test() { -- setup({explicit_done: true}); -+ // setup({explicit_done: true}); - -- var subtle = self.crypto.subtle; // Change to test prefixed implementations -+ var subtle = crypto.subtle; // Change to test prefixed implementations - - // When are all these tests really done? When all the promises they use have resolved. - var all_promises = []; @@ -435,12 +435,6 @@ function run_test() { all_promises.push(promise); }); diff --git a/webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__hmac.js.patch b/webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__hmac.js.patch index 70af7d4..8b14c6a 100644 --- a/webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__hmac.js.patch +++ b/webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__hmac.js.patch @@ -1,18 +1,7 @@ diff --git a/WebCryptoAPI/sign_verify/hmac.js b/WebCryptoAPI/sign_verify/hmac.js -index f5e2ad276..f51cc7bbe 100644 +index f5e2ad276..fcdf65a78 100644 --- a/WebCryptoAPI/sign_verify/hmac.js +++ b/WebCryptoAPI/sign_verify/hmac.js -@@ -1,8 +1,8 @@ - - function run_test() { -- setup({explicit_done: true}); -+ // setup({explicit_done: true}); - -- var subtle = self.crypto.subtle; // Change to test prefixed implementations -+ var subtle = crypto.subtle; // Change to test prefixed implementations - - // When are all these tests really done? When all the promises they use have resolved. - var all_promises = []; @@ -292,13 +292,6 @@ function run_test() { }); diff --git a/webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__rsa.js.patch b/webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__rsa.js.patch index 02f57a2..0ebbb5e 100644 --- a/webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__rsa.js.patch +++ b/webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__rsa.js.patch @@ -1,18 +1,7 @@ diff --git a/WebCryptoAPI/sign_verify/rsa.js b/WebCryptoAPI/sign_verify/rsa.js -index 5abadd3d4..c1673065a 100644 +index 5abadd3d4..494b707ee 100644 --- a/WebCryptoAPI/sign_verify/rsa.js +++ b/WebCryptoAPI/sign_verify/rsa.js -@@ -1,8 +1,8 @@ - - function run_test() { -- setup({explicit_done: true}); -+ // setup({explicit_done: true}); - -- var subtle = self.crypto.subtle; // Change to test prefixed implementations -+ var subtle = crypto.subtle; // Change to test prefixed implementations - - // When are all these tests really done? When all the promises they use have resolved. - var all_promises = []; @@ -156,7 +156,9 @@ function run_test() { // Check for successful signing and verification. testVectors.forEach(function(vector) { From b607927626ecb44073f857ad846ae425d619cd13 Mon Sep 17 00:00:00 2001 From: Oleg Bespalov Date: Sat, 26 Oct 2024 08:52:27 +0200 Subject: [PATCH 3/5] wpt: refactoring and docs --- .github/workflows/wpt.yml | 2 +- webcrypto/tests/README.md | 4 ++++ webcrypto/tests/subtle_crypto_test.go | 20 ++++++++-------- .../{test_setup.go => test_setup_test.go} | 14 +++++++---- webcrypto/tests/util/overloads.js | 23 +++++++++++++++++++ webcrypto/tests/util/testharness.js | 22 ------------------ 6 files changed, 47 insertions(+), 38 deletions(-) rename webcrypto/tests/{test_setup.go => test_setup_test.go} (84%) create mode 100644 webcrypto/tests/util/overloads.js diff --git a/.github/workflows/wpt.yml b/.github/workflows/wpt.yml index 66af526..79b4d76 100644 --- a/.github/workflows/wpt.yml +++ b/.github/workflows/wpt.yml @@ -23,4 +23,4 @@ jobs: set -x cd webcrypto/tests sh checkout.sh - go test -race ./... -tags=wpt + go test -timeout 120s -race ./... -tags=wpt diff --git a/webcrypto/tests/README.md b/webcrypto/tests/README.md index 6f6f8c7..b6e5527 100644 --- a/webcrypto/tests/README.md +++ b/webcrypto/tests/README.md @@ -10,6 +10,10 @@ The entry point is the [`checkout.sh`](./checkout.sh) script, which checks out t If you work on a new web platfrom test, you could easily re-generate patches by running `./generate-patches.sh`. +We try to keep the diff as small as possible, and we aim to upstream the changes to the wpt repository, but still sometimes +we need to overload some wpt's functions locally with the minimal or noop implementation to make the tests work. You could find the overloaded functions in the +[`util/overloads.js`](./utils/overloads.js) file. + **How to use** 1. Run `./checkout.sh` to check out the web-platform-tests sources. 2. Run `go test ../... -tags=wpt` to run the tests. diff --git a/webcrypto/tests/subtle_crypto_test.go b/webcrypto/tests/subtle_crypto_test.go index 368840d..840ab9f 100644 --- a/webcrypto/tests/subtle_crypto_test.go +++ b/webcrypto/tests/subtle_crypto_test.go @@ -10,24 +10,22 @@ import ( "github.com/grafana/sobek" "github.com/stretchr/testify/assert" - "go.k6.io/k6/js/modulestest" ) const webPlatformTestSuite = "./wpt/WebCryptoAPI/" -func newWebPlatformTestRuntime(t testing.TB) *modulestest.Runtime { +func TestWebPlatformTestSuite(t *testing.T) { + t.Parallel() + // check if the test is running in the correct environment info, err := os.Stat(webPlatformTestSuite) if os.IsNotExist(err) || err != nil || !info.IsDir() { - t.Fatalf("The Web Platform Test directory does not exist, err: %s", err) + t.Fatalf( + "The Web Platform Test directory does not exist, err: %s. Please check webcrypto/tests/README.md how to setup it", + err, + ) } - return newConfiguredRuntime(t) -} - -func TestWebPlatformTestSuite(t *testing.T) { - t.Parallel() - tests := []struct { // catalog is the catalog relatively webPlatformTestSuite where to look files catalog string @@ -159,7 +157,7 @@ func TestWebPlatformTestSuite(t *testing.T) { t.Run(testName, func(t *testing.T) { t.Parallel() - ts := newWebPlatformTestRuntime(t) + ts := newConfiguredRuntime(t) gotErr := ts.EventLoop.Start(func() error { if err := executeTestScripts(ts.VU.Runtime(), webPlatformTestSuite+tt.catalog, tt.files...); err != nil { @@ -180,7 +178,7 @@ func TestWebPlatformTestSuite(t *testing.T) { func executeTestScripts(rt *sobek.Runtime, base string, scripts ...string) error { for _, script := range scripts { - program, err := CompileFile(base, script) + program, err := compileFile(base, script) if err != nil { return err } diff --git a/webcrypto/tests/test_setup.go b/webcrypto/tests/test_setup_test.go similarity index 84% rename from webcrypto/tests/test_setup.go rename to webcrypto/tests/test_setup_test.go index db066af..e135869 100644 --- a/webcrypto/tests/test_setup.go +++ b/webcrypto/tests/test_setup_test.go @@ -38,7 +38,7 @@ func newConfiguredRuntime(t testing.TB) *modulestest.Runtime { require.NoError(t, err) // We compile the Web Platform testharness script into a sobek.Program - harnessProgram, err := CompileFile("./util", "testharness.js") + harnessProgram, err := compileFile("./util", "testharness.js") require.NoError(t, err) // We execute the harness script in the goja runtime @@ -48,7 +48,7 @@ func newConfiguredRuntime(t testing.TB) *modulestest.Runtime { require.NoError(t, err) // We compile the Web Platform helpers script into a sobek.Program - helpersProgram, err := CompileFile("./util", "helpers.js") + helpersProgram, err := compileFile("./util", "helpers.js") require.NoError(t, err) // We execute the helpers script in the goja runtime @@ -57,6 +57,12 @@ func newConfiguredRuntime(t testing.TB) *modulestest.Runtime { _, err = runtime.VU.Runtime().RunProgram(helpersProgram) require.NoError(t, err) + // some function overloads for the Web Platform tests + overloads, err := compileFile("./util", "overloads.js") + require.NoError(t, err) + _, err = runtime.VU.Runtime().RunProgram(overloads) + require.NoError(t, err) + m := new(webcrypto.RootModule).NewModuleInstance(runtime.VU) err = runtime.VU.Runtime().Set("crypto", m.Exports().Named["crypto"]) @@ -74,8 +80,8 @@ func newConfiguredRuntime(t testing.TB) *modulestest.Runtime { return runtime } -// CompileFile compiles a javascript file as a sobek.Program. -func CompileFile(base, name string) (*sobek.Program, error) { +// compileFile compiles a javascript file as a sobek.Program. +func compileFile(base, name string) (*sobek.Program, error) { filename := path.Join(base, name) //nolint:forbidigo // Allow os.Open in tests diff --git a/webcrypto/tests/util/overloads.js b/webcrypto/tests/util/overloads.js new file mode 100644 index 0000000..0cab17d --- /dev/null +++ b/webcrypto/tests/util/overloads.js @@ -0,0 +1,23 @@ +// file contains overloads for the web platform test, to make it work with k6 +// javascript runtime. + + +// this is a minimal implementation of the promise_test function +// which used in many web platform tests +function promise_test(fn, name) { + try { + fn(); + } catch (e) { + throw Error(`Error in test "${name}": ${e}`); + } +} + +// this is a minimal implementation of the done function +// which used in many web platform tests +function done() {} + +// this is a minimal implementation of the setup function +function setup() {} + +// some tests use the self object, so we need to define it +globalThis.self = globalThis; \ No newline at end of file diff --git a/webcrypto/tests/util/testharness.js b/webcrypto/tests/util/testharness.js index 1a112cf..92ce2b3 100644 --- a/webcrypto/tests/util/testharness.js +++ b/webcrypto/tests/util/testharness.js @@ -91,25 +91,3 @@ function assert_in_array(actual, expected, description) { function assert_unreached(description) { throw `reached unreachable code, reason: ${description}` } - -// overloads of the some test functions - -// this is a minimal implementation of the promise_test function -// which used in many web platform tests -function promise_test(fn, name) { - try { - fn(); - } catch (e) { - throw Error(`Error in test "${name}": ${e}`); - } -} - -// this is a minimal implementation of the done function -// which used in many web platform tests -function done() {} - -// this is a minimal implementation of the setup function -function setup() {} - -// some tests use the global object, so we need to define it -const self = globalThis; \ No newline at end of file From 49d0c6c9c00e406c944325f69775836385103cc1 Mon Sep 17 00:00:00 2001 From: Oleg Bespalov Date: Mon, 28 Oct 2024 08:21:43 +0100 Subject: [PATCH 4/5] wpt: keep local promise_test --- ...ebCryptoAPI__encrypt_decrypt__aes.js.patch | 17 ----------------- ...ebCryptoAPI__encrypt_decrypt__rsa.js.patch | 19 ------------------- ...bCryptoAPI__generateKey__failures.js.patch | 12 ++---------- .../WebCryptoAPI__sign_verify__ecdsa.js.patch | 17 ----------------- .../WebCryptoAPI__sign_verify__hmac.js.patch | 18 ------------------ .../WebCryptoAPI__sign_verify__rsa.js.patch | 15 +-------------- 6 files changed, 3 insertions(+), 95 deletions(-) delete mode 100644 webcrypto/tests/wpt-patches/WebCryptoAPI__encrypt_decrypt__aes.js.patch delete mode 100644 webcrypto/tests/wpt-patches/WebCryptoAPI__encrypt_decrypt__rsa.js.patch delete mode 100644 webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__ecdsa.js.patch delete mode 100644 webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__hmac.js.patch diff --git a/webcrypto/tests/wpt-patches/WebCryptoAPI__encrypt_decrypt__aes.js.patch b/webcrypto/tests/wpt-patches/WebCryptoAPI__encrypt_decrypt__aes.js.patch deleted file mode 100644 index 773d7b8..0000000 --- a/webcrypto/tests/wpt-patches/WebCryptoAPI__encrypt_decrypt__aes.js.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff --git a/WebCryptoAPI/encrypt_decrypt/aes.js b/WebCryptoAPI/encrypt_decrypt/aes.js -index fdeb7963f..b2257a320 100644 ---- a/WebCryptoAPI/encrypt_decrypt/aes.js -+++ b/WebCryptoAPI/encrypt_decrypt/aes.js -@@ -267,12 +267,6 @@ function run_test() { - all_promises.push(promise); - }); - -- promise_test(function() { -- return Promise.all(all_promises) -- .then(function() {done();}) -- .catch(function() {done();}) -- }, "setup"); -- - // A test vector has all needed fields for encryption, EXCEPT that the - // key field may be null. This function replaces that null with the Correct - // CryptoKey object. diff --git a/webcrypto/tests/wpt-patches/WebCryptoAPI__encrypt_decrypt__rsa.js.patch b/webcrypto/tests/wpt-patches/WebCryptoAPI__encrypt_decrypt__rsa.js.patch deleted file mode 100644 index 839913a..0000000 --- a/webcrypto/tests/wpt-patches/WebCryptoAPI__encrypt_decrypt__rsa.js.patch +++ /dev/null @@ -1,19 +0,0 @@ -diff --git a/WebCryptoAPI/encrypt_decrypt/rsa.js b/WebCryptoAPI/encrypt_decrypt/rsa.js -index 5eae06e47..819878cf4 100644 ---- a/WebCryptoAPI/encrypt_decrypt/rsa.js -+++ b/WebCryptoAPI/encrypt_decrypt/rsa.js -@@ -291,13 +291,7 @@ function run_test() { - }); - - all_promises.push(promise); -- }); -- -- promise_test(function() { -- return Promise.all(all_promises) -- .then(function() {done();}) -- .catch(function() {done();}) -- }, "setup"); -+ }); - - // A test vector has all needed fields for encryption, EXCEPT that the - // key field may be null. This function replaces that null with the Correct diff --git a/webcrypto/tests/wpt-patches/WebCryptoAPI__generateKey__failures.js.patch b/webcrypto/tests/wpt-patches/WebCryptoAPI__generateKey__failures.js.patch index 87c6f47..201d5f9 100644 --- a/webcrypto/tests/wpt-patches/WebCryptoAPI__generateKey__failures.js.patch +++ b/webcrypto/tests/wpt-patches/WebCryptoAPI__generateKey__failures.js.patch @@ -1,16 +1,8 @@ diff --git a/WebCryptoAPI/generateKey/failures.js b/WebCryptoAPI/generateKey/failures.js -index e0f0279a6..eaab20068 100644 +index e0f0279a6..61495ca75 100644 --- a/WebCryptoAPI/generateKey/failures.js +++ b/WebCryptoAPI/generateKey/failures.js -@@ -25,17 +25,17 @@ function run_test(algorithmNames) { - {name: "AES-CTR", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, - {name: "AES-CBC", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, - {name: "AES-GCM", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, -- {name: "AES-KW", resultType: CryptoKey, usages: ["wrapKey", "unwrapKey"], mandatoryUsages: []}, -+ // {name: "AES-KW", resultType: CryptoKey, usages: ["wrapKey", "unwrapKey"], mandatoryUsages: []}, - {name: "HMAC", resultType: CryptoKey, usages: ["sign", "verify"], mandatoryUsages: []}, - {name: "RSASSA-PKCS1-v1_5", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, - {name: "RSA-PSS", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, +@@ -32,10 +32,10 @@ function run_test(algorithmNames) { {name: "RSA-OAEP", resultType: "CryptoKeyPair", usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: ["decrypt", "unwrapKey"]}, {name: "ECDSA", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, {name: "ECDH", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]}, diff --git a/webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__ecdsa.js.patch b/webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__ecdsa.js.patch deleted file mode 100644 index 8a5ef7f..0000000 --- a/webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__ecdsa.js.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff --git a/WebCryptoAPI/sign_verify/ecdsa.js b/WebCryptoAPI/sign_verify/ecdsa.js -index 6bf662adc..dcda1a1b1 100644 ---- a/WebCryptoAPI/sign_verify/ecdsa.js -+++ b/WebCryptoAPI/sign_verify/ecdsa.js -@@ -435,12 +435,6 @@ function run_test() { - all_promises.push(promise); - }); - -- promise_test(function() { -- return Promise.all(all_promises) -- .then(function() {done();}) -- .catch(function() {done();}) -- }, "setup"); -- - // A test vector has all needed fields for signing and verifying, EXCEPT that the - // key field may be null. This function replaces that null with the Correct - // CryptoKey object. diff --git a/webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__hmac.js.patch b/webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__hmac.js.patch deleted file mode 100644 index 8b14c6a..0000000 --- a/webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__hmac.js.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff --git a/WebCryptoAPI/sign_verify/hmac.js b/WebCryptoAPI/sign_verify/hmac.js -index f5e2ad276..fcdf65a78 100644 ---- a/WebCryptoAPI/sign_verify/hmac.js -+++ b/WebCryptoAPI/sign_verify/hmac.js -@@ -292,13 +292,6 @@ function run_test() { - }); - - -- -- promise_test(function() { -- return Promise.all(all_promises) -- .then(function() {done();}) -- .catch(function() {done();}) -- }, "setup"); -- - // A test vector has all needed fields for signing and verifying, EXCEPT that the - // key field may be null. This function replaces that null with the Correct - // CryptoKey object. diff --git a/webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__rsa.js.patch b/webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__rsa.js.patch index 0ebbb5e..7c20fed 100644 --- a/webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__rsa.js.patch +++ b/webcrypto/tests/wpt-patches/WebCryptoAPI__sign_verify__rsa.js.patch @@ -1,5 +1,5 @@ diff --git a/WebCryptoAPI/sign_verify/rsa.js b/WebCryptoAPI/sign_verify/rsa.js -index 5abadd3d4..494b707ee 100644 +index 5abadd3d4..6076bd7de 100644 --- a/WebCryptoAPI/sign_verify/rsa.js +++ b/WebCryptoAPI/sign_verify/rsa.js @@ -156,7 +156,9 @@ function run_test() { @@ -13,16 +13,3 @@ index 5abadd3d4..494b707ee 100644 var promise = importVectorKeys(vector, ["verify"], ["sign"]) .then(function(vectors) { promise_test(function(test) { -@@ -364,12 +366,6 @@ function run_test() { - }); - - -- promise_test(function() { -- return Promise.all(all_promises) -- .then(function() {done();}) -- .catch(function() {done();}) -- }, "setup"); -- - // A test vector has all needed fields for signing and verifying, EXCEPT that the - // key field may be null. This function replaces that null with the Correct - // CryptoKey object. From d371faf2f255864364c53ec1856182e836823e21 Mon Sep 17 00:00:00 2001 From: Oleg Bespalov Date: Mon, 28 Oct 2024 10:47:58 +0100 Subject: [PATCH 5/5] wpt: use testharness from the repository, instead of local copy --- Makefile | 2 +- webcrypto/tests/README.md | 4 +- webcrypto/tests/checkout.sh | 2 +- webcrypto/tests/subtle_crypto_test.go | 20 +----- webcrypto/tests/test_setup_test.go | 87 +++++++------------------ webcrypto/tests/util/overloads.js | 23 ------- webcrypto/tests/util/testharness.js | 93 --------------------------- 7 files changed, 28 insertions(+), 203 deletions(-) delete mode 100644 webcrypto/tests/util/overloads.js delete mode 100644 webcrypto/tests/util/testharness.js diff --git a/Makefile b/Makefile index f4b4e5f..bf44368 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ test: ## test: Executes any tests. wpt-test: - go test -race -timeout 60s ./... -tags=wpt + go test -race -timeout 120s ./... -tags=wpt ## lint: Runs the linters. lint: linter-config check-linter-version diff --git a/webcrypto/tests/README.md b/webcrypto/tests/README.md index b6e5527..f6eeac1 100644 --- a/webcrypto/tests/README.md +++ b/webcrypto/tests/README.md @@ -10,9 +10,7 @@ The entry point is the [`checkout.sh`](./checkout.sh) script, which checks out t If you work on a new web platfrom test, you could easily re-generate patches by running `./generate-patches.sh`. -We try to keep the diff as small as possible, and we aim to upstream the changes to the wpt repository, but still sometimes -we need to overload some wpt's functions locally with the minimal or noop implementation to make the tests work. You could find the overloaded functions in the -[`util/overloads.js`](./utils/overloads.js) file. +We try to keep the diff as small as possible, and we aim to upstream the changes to the wpt repository. **How to use** 1. Run `./checkout.sh` to check out the web-platform-tests sources. diff --git a/webcrypto/tests/checkout.sh b/webcrypto/tests/checkout.sh index 42c337f..7d6ebe9 100755 --- a/webcrypto/tests/checkout.sh +++ b/webcrypto/tests/checkout.sh @@ -9,7 +9,7 @@ cd ./wpt git init git remote add origin https://github.com/web-platform-tests/wpt git sparse-checkout init --cone -git sparse-checkout set WebCryptoAPI +git sparse-checkout set resources WebCryptoAPI git fetch origin --depth=1 "${sha}" git checkout ${sha} diff --git a/webcrypto/tests/subtle_crypto_test.go b/webcrypto/tests/subtle_crypto_test.go index 840ab9f..13dc8e7 100644 --- a/webcrypto/tests/subtle_crypto_test.go +++ b/webcrypto/tests/subtle_crypto_test.go @@ -8,7 +8,6 @@ import ( "strings" "testing" - "github.com/grafana/sobek" "github.com/stretchr/testify/assert" ) @@ -160,8 +159,8 @@ func TestWebPlatformTestSuite(t *testing.T) { ts := newConfiguredRuntime(t) gotErr := ts.EventLoop.Start(func() error { - if err := executeTestScripts(ts.VU.Runtime(), webPlatformTestSuite+tt.catalog, tt.files...); err != nil { - return err + for _, script := range tt.files { + compileAndRun(t, ts, webPlatformTestSuite+tt.catalog, script) } if tt.callFn == "" { @@ -175,18 +174,3 @@ func TestWebPlatformTestSuite(t *testing.T) { }) } } - -func executeTestScripts(rt *sobek.Runtime, base string, scripts ...string) error { - for _, script := range scripts { - program, err := compileFile(base, script) - if err != nil { - return err - } - - if _, err = rt.RunProgram(program); err != nil { - return err - } - } - - return nil -} diff --git a/webcrypto/tests/test_setup_test.go b/webcrypto/tests/test_setup_test.go index e135869..ec0dff9 100644 --- a/webcrypto/tests/test_setup_test.go +++ b/webcrypto/tests/test_setup_test.go @@ -3,15 +3,10 @@ package tests import ( - "io" - "os" - "path" - "path/filepath" "testing" "go.k6.io/k6/js/compiler" - "github.com/grafana/sobek" "github.com/grafana/xk6-webcrypto/webcrypto" "github.com/stretchr/testify/require" k6encoding "go.k6.io/k6/js/modules/k6/encoding" @@ -28,84 +23,48 @@ const initGlobals = ` // main context of k6. func newConfiguredRuntime(t testing.TB) *modulestest.Runtime { var err error - runtime := modulestest.NewRuntime(t) + rt := modulestest.NewRuntime(t) - err = runtime.SetupModuleSystem( + // We want to make the [self] available for Web Platform Tests, as it is used in test harness. + _, err = rt.VU.Runtime().RunString("var self = this;") + require.NoError(t, err) + + err = rt.SetupModuleSystem( map[string]interface{}{"k6/x/webcrypto": webcrypto.New()}, nil, - compiler.New(runtime.VU.InitEnv().Logger), + compiler.New(rt.VU.InitEnv().Logger), ) require.NoError(t, err) // We compile the Web Platform testharness script into a sobek.Program - harnessProgram, err := compileFile("./util", "testharness.js") - require.NoError(t, err) - - // We execute the harness script in the goja runtime - // in order to make the Web Platform assertion functions available - // to the tests. - _, err = runtime.VU.Runtime().RunProgram(harnessProgram) - require.NoError(t, err) + compileAndRun(t, rt, "./wpt/resources", "testharness.js") // We compile the Web Platform helpers script into a sobek.Program - helpersProgram, err := compileFile("./util", "helpers.js") - require.NoError(t, err) - - // We execute the helpers script in the goja runtime - // in order to make the Web Platform helpers available - // to the tests. - _, err = runtime.VU.Runtime().RunProgram(helpersProgram) - require.NoError(t, err) - - // some function overloads for the Web Platform tests - overloads, err := compileFile("./util", "overloads.js") - require.NoError(t, err) - _, err = runtime.VU.Runtime().RunProgram(overloads) - require.NoError(t, err) + // TODO: check if we need to compile the helpers.js script each time + // or it can be just yet another test + compileAndRun(t, rt, "./util", "helpers.js") - m := new(webcrypto.RootModule).NewModuleInstance(runtime.VU) + m := new(webcrypto.RootModule).NewModuleInstance(rt.VU) - err = runtime.VU.Runtime().Set("crypto", m.Exports().Named["crypto"]) + err = rt.VU.Runtime().Set("crypto", m.Exports().Named["crypto"]) require.NoError(t, err) // we define the btoa function in the goja runtime // so that the Web Platform tests can use it. - encodingModule := k6encoding.New().NewModuleInstance(runtime.VU) - err = runtime.VU.Runtime().Set("btoa", encodingModule.Exports().Named["b64encode"]) + encodingModule := k6encoding.New().NewModuleInstance(rt.VU) + err = rt.VU.Runtime().Set("btoa", encodingModule.Exports().Named["b64encode"]) require.NoError(t, err) - _, err = runtime.VU.Runtime().RunString(initGlobals) + _, err = rt.VU.Runtime().RunString(initGlobals) require.NoError(t, err) - return runtime + return rt } -// compileFile compiles a javascript file as a sobek.Program. -func compileFile(base, name string) (*sobek.Program, error) { - filename := path.Join(base, name) - - //nolint:forbidigo // Allow os.Open in tests - f, err := os.Open(filepath.Clean(filename)) - if err != nil { - return nil, err - } - defer func() { - err = f.Close() - if err != nil { - panic(err) - } - }() - - b, err := io.ReadAll(f) - if err != nil { - return nil, err - } - - str := string(b) - program, err := sobek.Compile(name, str, false) - if err != nil { - return nil, err - } - - return program, nil +func compileAndRun(t testing.TB, runtime *modulestest.Runtime, base, file string) { + program, err := modulestest.CompileFile(base, file) + require.NoError(t, err) + + _, err = runtime.VU.Runtime().RunProgram(program) + require.NoError(t, err) } diff --git a/webcrypto/tests/util/overloads.js b/webcrypto/tests/util/overloads.js deleted file mode 100644 index 0cab17d..0000000 --- a/webcrypto/tests/util/overloads.js +++ /dev/null @@ -1,23 +0,0 @@ -// file contains overloads for the web platform test, to make it work with k6 -// javascript runtime. - - -// this is a minimal implementation of the promise_test function -// which used in many web platform tests -function promise_test(fn, name) { - try { - fn(); - } catch (e) { - throw Error(`Error in test "${name}": ${e}`); - } -} - -// this is a minimal implementation of the done function -// which used in many web platform tests -function done() {} - -// this is a minimal implementation of the setup function -function setup() {} - -// some tests use the self object, so we need to define it -globalThis.self = globalThis; \ No newline at end of file diff --git a/webcrypto/tests/util/testharness.js b/webcrypto/tests/util/testharness.js deleted file mode 100644 index 92ce2b3..0000000 --- a/webcrypto/tests/util/testharness.js +++ /dev/null @@ -1,93 +0,0 @@ -// This file contains a partial adaptation of the testharness.js implementation from -// the W3C WebCrypto API test suite. It is not intended to be a complete -// implementation, but rather a minimal set of functions to support the -// tests for this extension. -// -// Some of the function have been modified to support the k6 javascript runtime, -// and to limit its dependency to the rest of the W3C WebCrypto API test suite internal -// codebase. -// -// The original testharness.js implementation is available at: -// https://github.com/web-platform-tests/wpt/blob/3a3453c62176c97ab51cd492553c2dacd24366b1/resources/testharness.js - - -/** - * Assert that ``actual`` is the same value as ``expected``. - * - * For objects this compares by cobject identity; for primitives - * this distinguishes between 0 and -0, and has correct handling - * of NaN. - * - * @param {Any} actual - Test value. - * @param {Any} expected - Expected value. - * @param {string} [description] - Description of the condition being tested. - */ -function assert_equals(actual, expected, description) { - if (actual !== expected) { - throw `assert_equals ${description} expected (${typeof expected}) ${expected} but got (${typeof actual}) ${actual}`; - } -} - -/** - * Assert that ``actual`` is not the same value as ``expected``. - * - * Comparison is as for :js:func:`assert_equals`. - * - * @param {Any} actual - Test value. - * @param {Any} expected - The value ``actual`` is expected to be different to. - * @param {string} [description] - Description of the condition being tested. - */ -function assert_not_equals(actual, expected, description) { - if (actual === expected) { - throw `assert_not_equals ${description} got disallowed value ${actual}`; - } -} - -/** - * Assert that ``actual`` is strictly true - * - * @param {Any} actual - Value that is asserted to be true - * @param {string} [description] - Description of the condition being tested - */ -function assert_true(actual, description) { - if (!actual) { - throw `assert_true ${description} expected true got ${actual}`; - } -} - -/** - * Assert that ``actual`` is strictly false - * - * @param {Any} actual - Value that is asserted to be false - * @param {string} [description] - Description of the condition being tested - */ -function assert_false(actual, description) { - if (actual) { - throw `assert_true ${description} expected false got ${actual}`; - } -} - -/** - * Assert that ``expected`` is an array and ``actual`` is one of the members. - * This is implemented using ``indexOf``, so doesn't handle NaN or ±0 correctly. - * - * @param {Any} actual - Test value. - * @param {Array} expected - An array that ``actual`` is expected to - * be a member of. - * @param {string} [description] - Description of the condition being tested. - */ -function assert_in_array(actual, expected, description) { - if (expected.indexOf(actual) === -1) { - throw `assert_in_array ${description} value ${actual} not in array ${expected}`; - } -} - -/** - * Asserts if called. Used to ensure that a specific codepath is - * not taken e.g. that an error event isn't fired. - * - * @param {string} [description] - Description of the condition being tested. - */ -function assert_unreached(description) { - throw `reached unreachable code, reason: ${description}` -}