diff --git a/js/modules/k6/crypto/crypto.go b/js/modules/k6/crypto/crypto.go index d708fdaadc2..8eee7ad7121 100644 --- a/js/modules/k6/crypto/crypto.go +++ b/js/modules/k6/crypto/crypto.go @@ -1,10 +1,11 @@ +// Package crypto provides common hashing function for the k6 package crypto import ( "crypto/hmac" - "crypto/md5" + "crypto/md5" // #nosec G501 // MD5 is weak, but we need it for compatibility "crypto/rand" - "crypto/sha1" + "crypto/sha1" // #nosec G505 // SHA1 is weak, but we need it for compatibility "crypto/sha256" "crypto/sha512" "encoding/base64" @@ -13,8 +14,8 @@ import ( "fmt" "hash" - "golang.org/x/crypto/md4" - "golang.org/x/crypto/ripemd160" + "golang.org/x/crypto/md4" //nolint:staticcheck // #nosec G501 // MD4 is weak, but we need it for compatibility + "golang.org/x/crypto/ripemd160" // no lint:staticcheck // #nosec G501 // RIPEMD160 is weak, but we need it for compatibility "github.com/dop251/goja" @@ -29,7 +30,8 @@ type ( // Crypto represents an instance of the crypto module. Crypto struct { - vu modules.VU + randReader func(b []byte) (n int, err error) + vu modules.VU } ) @@ -46,7 +48,7 @@ func New() *RootModule { // NewModuleInstance implements the modules.Module interface to return // a new instance for each VU. func (*RootModule) NewModuleInstance(vu modules.VU) modules.Instance { - return &Crypto{vu: vu} + return &Crypto{vu: vu, randReader: rand.Read} } // Exports returns the exports of the execution module. @@ -77,7 +79,7 @@ func (c *Crypto) randomBytes(size int) (*goja.ArrayBuffer, error) { return nil, errors.New("invalid size") } bytes := make([]byte, size) - _, err := rand.Read(bytes) + _, err := c.randReader(bytes) if err != nil { return nil, err } @@ -87,65 +89,47 @@ func (c *Crypto) randomBytes(size int) (*goja.ArrayBuffer, error) { // md4 returns the MD4 hash of input in the given encoding. func (c *Crypto) md4(input interface{}, outputEncoding string) (interface{}, error) { - hasher := c.createHash("md4") - hasher.Update(input) - return hasher.Digest(outputEncoding) + return c.buildInputsDigest("md4", input, outputEncoding) } // md5 returns the MD5 hash of input in the given encoding. func (c *Crypto) md5(input interface{}, outputEncoding string) (interface{}, error) { - hasher := c.createHash("md5") - hasher.Update(input) - return hasher.Digest(outputEncoding) + return c.buildInputsDigest("md5", input, outputEncoding) } // sha1 returns the SHA1 hash of input in the given encoding. func (c *Crypto) sha1(input interface{}, outputEncoding string) (interface{}, error) { - hasher := c.createHash("sha1") - hasher.Update(input) - return hasher.Digest(outputEncoding) + return c.buildInputsDigest("sha1", input, outputEncoding) } // sha256 returns the SHA256 hash of input in the given encoding. func (c *Crypto) sha256(input interface{}, outputEncoding string) (interface{}, error) { - hasher := c.createHash("sha256") - hasher.Update(input) - return hasher.Digest(outputEncoding) + return c.buildInputsDigest("sha256", input, outputEncoding) } // sha384 returns the SHA384 hash of input in the given encoding. func (c *Crypto) sha384(input interface{}, outputEncoding string) (interface{}, error) { - hasher := c.createHash("sha384") - hasher.Update(input) - return hasher.Digest(outputEncoding) + return c.buildInputsDigest("sha384", input, outputEncoding) } // sha512 returns the SHA512 hash of input in the given encoding. func (c *Crypto) sha512(input interface{}, outputEncoding string) (interface{}, error) { - hasher := c.createHash("sha512") - hasher.Update(input) - return hasher.Digest(outputEncoding) + return c.buildInputsDigest("sha512", input, outputEncoding) } // sha512_224 returns the SHA512/224 hash of input in the given encoding. func (c *Crypto) sha512_224(input interface{}, outputEncoding string) (interface{}, error) { - hasher := c.createHash("sha512_224") - hasher.Update(input) - return hasher.Digest(outputEncoding) + return c.buildInputsDigest("sha512_224", input, outputEncoding) } // shA512_256 returns the SHA512/256 hash of input in the given encoding. func (c *Crypto) sha512_256(input interface{}, outputEncoding string) (interface{}, error) { - hasher := c.createHash("sha512_256") - hasher.Update(input) - return hasher.Digest(outputEncoding) + return c.buildInputsDigest("sha512_256", input, outputEncoding) } // ripemd160 returns the RIPEMD160 hash of input in the given encoding. func (c *Crypto) ripemd160(input interface{}, outputEncoding string) (interface{}, error) { - hasher := c.createHash("ripemd160") - hasher.Update(input) - return hasher.Digest(outputEncoding) + return c.buildInputsDigest("ripemd160", input, outputEncoding) } // createHash returns a Hasher instance that uses the given algorithm. @@ -157,6 +141,17 @@ func (c *Crypto) createHash(algorithm string) *Hasher { } } +// buildInputsDigest implements basic digest calculation for given algorithm and input/output +func (c *Crypto) buildInputsDigest(alg string, input interface{}, outputEncoding string) (interface{}, error) { + hasher := c.createHash(alg) + + if err := hasher.Update(input); err != nil { + return nil, fmt.Errorf("%s failed: %w", alg, err) + } + + return hasher.Digest(outputEncoding) +} + // hexEncode returns a string with the hex representation of the provided byte // array or ArrayBuffer. func (c *Crypto) hexEncode(data interface{}) (string, error) { diff --git a/js/modules/k6/crypto/crypto_test.go b/js/modules/k6/crypto/crypto_test.go index 430fd3508ce..7e4138c63fc 100644 --- a/js/modules/k6/crypto/crypto_test.go +++ b/js/modules/k6/crypto/crypto_test.go @@ -2,7 +2,6 @@ package crypto import ( "context" - "crypto/rand" "errors" "fmt" "testing" @@ -13,20 +12,15 @@ import ( "go.k6.io/k6/js/common" "go.k6.io/k6/js/modulestest" - "go.k6.io/k6/lib" ) type MockReader struct{} -func (MockReader) Read(p []byte) (n int, err error) { +func (MockReader) Read(_ []byte) (int, error) { return -1, errors.New("Contrived failure") } -func TestCryptoAlgorithms(t *testing.T) { - if testing.Short() { - return - } - +func makeRuntime(t *testing.T) *goja.Runtime { rt := goja.New() rt.SetFieldNameMapper(common.FieldNameMapper{}) @@ -41,7 +35,21 @@ func TestCryptoAlgorithms(t *testing.T) { require.True(t, ok) require.NoError(t, rt.Set("crypto", m.Exports().Named)) + return rt +} + +func TestCryptoAlgorithms(t *testing.T) { + t.Parallel() + + if testing.Short() { + return + } + t.Run("RandomBytesSuccess", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(` var buf = crypto.randomBytes(5); if (buf.byteLength !== 5) { @@ -52,6 +60,10 @@ func TestCryptoAlgorithms(t *testing.T) { }) t.Run("RandomBytesInvalidSize", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(` crypto.randomBytes(-1);`) @@ -59,16 +71,34 @@ func TestCryptoAlgorithms(t *testing.T) { }) t.Run("RandomBytesFailure", func(t *testing.T) { - SavedReader := rand.Reader - rand.Reader = MockReader{} + t.Parallel() + + rt := goja.New() + rt.SetFieldNameMapper(common.FieldNameMapper{}) + + m, ok := New().NewModuleInstance( + &modulestest.VU{ + RuntimeField: rt, + InitEnvField: &common.InitEnvironment{}, + CtxField: context.Background(), + StateField: nil, + }, + ).(*Crypto) + require.True(t, ok) + require.NoError(t, rt.Set("crypto", m.Exports().Named)) + + m.randReader = MockReader{}.Read _, err := rt.RunString(` crypto.randomBytes(5);`) - rand.Reader = SavedReader assert.Error(t, err) }) t.Run("MD4", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(` var correct = "aa010fbc1d14c795d86ef98c95479d17"; var hash = crypto.md4("hello world", "hex"); @@ -79,6 +109,10 @@ func TestCryptoAlgorithms(t *testing.T) { }) t.Run("MD5", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(` var correct = "5eb63bbbe01eeed093cb22bb8f5acdc3"; var hash = crypto.md5("hello world", "hex"); @@ -90,6 +124,10 @@ func TestCryptoAlgorithms(t *testing.T) { }) t.Run("SHA1", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(` var correct = "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed"; var hash = crypto.sha1("hello world", "hex"); @@ -101,6 +139,10 @@ func TestCryptoAlgorithms(t *testing.T) { }) t.Run("SHA256", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(` var correct = "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"; var hash = crypto.sha256("hello world", "hex"); @@ -112,6 +154,10 @@ func TestCryptoAlgorithms(t *testing.T) { }) t.Run("SHA384", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(` var correct = "fdbd8e75a67f29f701a4e040385e2e23986303ea10239211af907fcbb83578b3e417cb71ce646efd0819dd8c088de1bd"; var hash = crypto.sha384("hello world", "hex"); @@ -123,6 +169,10 @@ func TestCryptoAlgorithms(t *testing.T) { }) t.Run("SHA512", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(` var correct = "309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f"; var hash = crypto.sha512("hello world", "hex"); @@ -134,6 +184,10 @@ func TestCryptoAlgorithms(t *testing.T) { }) t.Run("SHA512_224", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(` var hash = crypto.sha512_224("hello world", "hex"); var correct = "22e0d52336f64a998085078b05a6e37b26f8120f43bf4db4c43a64ee"; @@ -145,6 +199,10 @@ func TestCryptoAlgorithms(t *testing.T) { }) t.Run("SHA512_256", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(` var hash = crypto.sha512_256("hello world", "hex"); var correct = "0ac561fac838104e3f2e4ad107b4bee3e938bf15f2b15f009ccccd61a913f017"; @@ -156,6 +214,10 @@ func TestCryptoAlgorithms(t *testing.T) { }) t.Run("RIPEMD160", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(` var hash = crypto.ripemd160("hello world", "hex"); var correct = "98c615784ccb5fe5936fbc0cbe9dfdb408d92f0f"; @@ -168,31 +230,18 @@ func TestCryptoAlgorithms(t *testing.T) { } func TestStreamingApi(t *testing.T) { + t.Parallel() + if testing.Short() { return } - rt := goja.New() - rt.SetFieldNameMapper(common.FieldNameMapper{}) - - root, _ := lib.NewGroup("", nil) - state := &lib.State{Group: root} - - ctx := context.Background() - - m, ok := New().NewModuleInstance( - &modulestest.VU{ - RuntimeField: rt, - InitEnvField: &common.InitEnvironment{}, - CtxField: ctx, - StateField: state, - }, - ).(*Crypto) - require.True(t, ok) - require.NoError(t, rt.Set("crypto", m.Exports().Named)) - // Empty strings are still hashable t.Run("Empty", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(` var correctHex = "d41d8cd98f00b204e9800998ecf8427e"; @@ -207,6 +256,10 @@ func TestStreamingApi(t *testing.T) { }) t.Run("UpdateOnce", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(` var correctHex = "5eb63bbbe01eeed093cb22bb8f5acdc3"; @@ -222,6 +275,10 @@ func TestStreamingApi(t *testing.T) { }) t.Run("UpdateMultiple", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(` var correctHex = "5eb63bbbe01eeed093cb22bb8f5acdc3"; @@ -240,25 +297,17 @@ func TestStreamingApi(t *testing.T) { } func TestOutputEncoding(t *testing.T) { + t.Parallel() + if testing.Short() { return } - rt := goja.New() - rt.SetFieldNameMapper(common.FieldNameMapper{}) + t.Run("Valid", func(t *testing.T) { + t.Parallel() - m, ok := New().NewModuleInstance( - &modulestest.VU{ - RuntimeField: rt, - InitEnvField: &common.InitEnvironment{}, - CtxField: context.Background(), - StateField: nil, - }, - ).(*Crypto) - require.True(t, ok) - require.NoError(t, rt.Set("crypto", m.Exports().Named)) + rt := makeRuntime(t) - t.Run("Valid", func(t *testing.T) { _, err := rt.RunString(` var correctHex = "5eb63bbbe01eeed093cb22bb8f5acdc3"; var correctBase64 = "XrY7u+Ae7tCTyyK7j1rNww=="; @@ -311,6 +360,10 @@ func TestOutputEncoding(t *testing.T) { }) t.Run("Invalid", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(` var hasher = crypto.createHash("md5"); hasher.update("hello world"); @@ -321,24 +374,12 @@ func TestOutputEncoding(t *testing.T) { } func TestHMac(t *testing.T) { + t.Parallel() + if testing.Short() { return } - rt := goja.New() - rt.SetFieldNameMapper(common.FieldNameMapper{}) - - m, ok := New().NewModuleInstance( - &modulestest.VU{ - RuntimeField: rt, - InitEnvField: &common.InitEnvironment{}, - CtxField: context.Background(), - StateField: nil, - }, - ).(*Crypto) - require.True(t, ok) - require.NoError(t, rt.Set("crypto", m.Exports().Named)) - testData := map[string]string{ "md4": "92d8f5c302cf04cca0144d7a9feb1596", "md5": "e04f2ec05c8b12e19e46936b171c9d03", @@ -351,9 +392,17 @@ func TestHMac(t *testing.T) { "ripemd160": "00bb4ce0d6afd4c7424c9d01b8a6caa3e749b08b", } for algorithm, value := range testData { - rt.Set("correctHex", rt.ToValue(value)) - rt.Set("algorithm", rt.ToValue(algorithm)) + algorithm := algorithm + value := value + t.Run(algorithm+" hasher: valid", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + + _ = rt.Set("correctHex", rt.ToValue(value)) + _ = rt.Set("algorithm", rt.ToValue(algorithm)) + _, err := rt.RunString(` var hasher = crypto.createHMAC(algorithm, "a secret"); hasher.update("some data to hash"); @@ -367,6 +416,12 @@ func TestHMac(t *testing.T) { }) t.Run(algorithm+" wrapper: valid", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _ = rt.Set("correctHex", rt.ToValue(value)) + _ = rt.Set("algorithm", rt.ToValue(algorithm)) + _, err := rt.RunString(` var resultHex = crypto.hmac(algorithm, "a secret", "some data to hash", "hex"); if (resultHex !== correctHex) { @@ -377,6 +432,12 @@ func TestHMac(t *testing.T) { }) t.Run(algorithm+" ArrayBuffer: valid", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _ = rt.Set("correctHex", rt.ToValue(value)) + _ = rt.Set("algorithm", rt.ToValue(algorithm)) + _, err := rt.RunString(` var data = new Uint8Array([115,111,109,101,32,100,97,116,97,32,116, 111,32,104,97,115,104]).buffer; @@ -397,9 +458,15 @@ func TestHMac(t *testing.T) { } for algorithm, value := range invalidData { algorithm := algorithm - rt.Set("correctHex", rt.ToValue(value)) - rt.Set("algorithm", rt.ToValue(algorithm)) + value := value + t.Run(algorithm+" hasher: invalid", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _ = rt.Set("correctHex", rt.ToValue(value)) + _ = rt.Set("algorithm", rt.ToValue(algorithm)) + _, err := rt.RunString(` var hasher = crypto.createHMAC(algorithm, "a secret"); hasher.update("some data to hash"); @@ -413,6 +480,12 @@ func TestHMac(t *testing.T) { }) t.Run(algorithm+" wrapper: invalid", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _ = rt.Set("correctHex", rt.ToValue(value)) + _ = rt.Set("algorithm", rt.ToValue(algorithm)) + _, err := rt.RunString(` var resultHex = crypto.hmac(algorithm, "a secret", "some data to hash", "hex"); if (resultHex !== correctHex) { @@ -458,6 +531,8 @@ func TestHexEncode(t *testing.T) { } func TestAWSv4(t *testing.T) { + t.Parallel() + // example values from https://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html rt := goja.New() rt.SetFieldNameMapper(common.FieldNameMapper{}) diff --git a/js/modules/k6/crypto/x509/x509.go b/js/modules/k6/crypto/x509/x509.go index 06dab2951ee..318813028a9 100644 --- a/js/modules/k6/crypto/x509/x509.go +++ b/js/modules/k6/crypto/x509/x509.go @@ -1,7 +1,8 @@ +// Package x509 provides X.509 certificate parsing for the k6 package x509 import ( - "crypto/dsa" + "crypto/dsa" //nolint:staticcheck // #nosec G505 // DSA is weak, but we need it for compatibility "crypto/ecdsa" "crypto/rsa" "crypto/sha1" // #nosec G505 diff --git a/js/modules/k6/crypto/x509/x509_test.go b/js/modules/k6/crypto/x509/x509_test.go index 6ea165e7e8a..7474e1e4afa 100644 --- a/js/modules/k6/crypto/x509/x509_test.go +++ b/js/modules/k6/crypto/x509/x509_test.go @@ -130,12 +130,17 @@ EUEm/VHUnElNquzGyBA50TCfpv6NHPaTvOoB45yQbZ/YB4LO+CsT9eIMDZ4tcU9Z } func TestParse(t *testing.T) { + t.Parallel() + if testing.Short() { return } - rt := makeRuntime(t) t.Run("DecodeFailure", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(` x509.parse("bad-certificate");`) assert.Contains( @@ -143,6 +148,10 @@ func TestParse(t *testing.T) { }) t.Run("ParseFailure", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; x509.parse(pem);`, material.publicKey)) @@ -155,6 +164,10 @@ func TestParse(t *testing.T) { }) t.Run("SignatureAlgorithm", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -166,6 +179,10 @@ func TestParse(t *testing.T) { }) t.Run("Subject", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -176,6 +193,10 @@ func TestParse(t *testing.T) { }) t.Run("SubjectCommonName", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -187,6 +208,10 @@ func TestParse(t *testing.T) { }) t.Run("SubjectCountry", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -198,6 +223,10 @@ func TestParse(t *testing.T) { }) t.Run("SubjectPostalCode", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -209,6 +238,10 @@ func TestParse(t *testing.T) { }) t.Run("SubjectProvince", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -220,6 +253,10 @@ func TestParse(t *testing.T) { }) t.Run("SubjectLocality", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -231,6 +268,10 @@ func TestParse(t *testing.T) { }) t.Run("SubjectStreetAddress", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -242,6 +283,10 @@ func TestParse(t *testing.T) { }) t.Run("SubjectOrganization", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -253,6 +298,10 @@ func TestParse(t *testing.T) { }) t.Run("SubjectOrganizationalUnit", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -271,6 +320,10 @@ func TestParse(t *testing.T) { }) t.Run("SubjectNames", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -300,6 +353,10 @@ func TestParse(t *testing.T) { }) t.Run("Issuer", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -310,6 +367,10 @@ func TestParse(t *testing.T) { }) t.Run("IssuerCommonName", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -321,6 +382,10 @@ func TestParse(t *testing.T) { }) t.Run("IssuerCountry", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -332,6 +397,10 @@ func TestParse(t *testing.T) { }) t.Run("IssuerProvince", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -343,6 +412,10 @@ func TestParse(t *testing.T) { }) t.Run("IssuerLocality", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -354,6 +427,10 @@ func TestParse(t *testing.T) { }) t.Run("IssuerOrganization", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -365,6 +442,10 @@ func TestParse(t *testing.T) { }) t.Run("IssuerNames", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -394,6 +475,10 @@ func TestParse(t *testing.T) { }) t.Run("NotBefore", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -405,6 +490,10 @@ func TestParse(t *testing.T) { }) t.Run("NotAfter", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -416,6 +505,10 @@ func TestParse(t *testing.T) { }) t.Run("AltNames", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -437,6 +530,10 @@ func TestParse(t *testing.T) { }) t.Run("FingerPrint", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -452,6 +549,10 @@ func TestParse(t *testing.T) { }) t.Run("PublicKey", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -462,6 +563,10 @@ func TestParse(t *testing.T) { }) t.Run("RSAPublicKey", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -480,6 +585,10 @@ func TestParse(t *testing.T) { }) t.Run("RSAPublicKeyExponent", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -491,6 +600,10 @@ func TestParse(t *testing.T) { }) t.Run("RSAPublicKeyModulus", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -522,6 +635,10 @@ func TestParse(t *testing.T) { }) t.Run("DSAPublicKey", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -539,6 +656,10 @@ func TestParse(t *testing.T) { }) t.Run("ECDSAPublicKey", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var cert = x509.parse(pem); @@ -558,18 +679,27 @@ func TestParse(t *testing.T) { } func TestGetAltNames(t *testing.T) { + t.Parallel() + if testing.Short() { return } - rt := makeRuntime(t) t.Run("Failure", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(` x509.getAltNames("bad-certificate");`) assert.Error(t, err) }) t.Run("Success", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var altNames = x509.getAltNames(pem); @@ -592,18 +722,27 @@ func TestGetAltNames(t *testing.T) { } func TestGetIssuer(t *testing.T) { + t.Parallel() + if testing.Short() { return } - rt := makeRuntime(t) t.Run("Failure", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(` x509.getIssuer("bad-certificate");`) assert.Error(t, err) }) t.Run("Success", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var issuer = x509.getIssuer(pem); @@ -624,18 +763,27 @@ func TestGetIssuer(t *testing.T) { } func TestGetSubject(t *testing.T) { + t.Parallel() + if testing.Short() { return } - rt := makeRuntime(t) t.Run("Failure", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(` x509.getSubject("bad-certificate");`) assert.Error(t, err) }) t.Run("Success", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) + _, err := rt.RunString(fmt.Sprintf(` var pem = %q; var subject = x509.getSubject(pem); @@ -663,27 +811,37 @@ func TestGetSubject(t *testing.T) { } func TestSignatureAlgorithm(t *testing.T) { + t.Parallel() + t.Run("Known", func(t *testing.T) { + t.Parallel() + result := signatureAlgorithm(gox509.MD5WithRSA) assert.Equal(t, "MD5-RSA", result) }) t.Run("Unknown", func(t *testing.T) { + t.Parallel() + result := signatureAlgorithm(gox509.UnknownSignatureAlgorithm) assert.Equal(t, "UnknownSignatureAlgorithm", result) }) } func TestMakePublicKey(t *testing.T) { + t.Parallel() + t.Run("Unsupported", func(t *testing.T) { + t.Parallel() + _, err := makePublicKey(nil) assert.EqualError(t, err, "unsupported public key algorithm") }) } -func TestMakeCertificate(t *testing.T) { - t.Run("UnsupportedKey", func(t *testing.T) { - _, err := makeCertificate(&gox509.Certificate{}) - assert.EqualError(t, err, "unsupported public key algorithm") - }) +func TestMakeCertificateUnsupportedKey(t *testing.T) { + t.Parallel() + + _, err := makeCertificate(&gox509.Certificate{}) + assert.EqualError(t, err, "unsupported public key algorithm") } diff --git a/js/modules/k6/encoding/encoding.go b/js/modules/k6/encoding/encoding.go index 886b11ee260..a3a82212182 100644 --- a/js/modules/k6/encoding/encoding.go +++ b/js/modules/k6/encoding/encoding.go @@ -1,3 +1,4 @@ +// Package encoding provides encoding/decoding functionality for the k6 package encoding import ( diff --git a/js/modules/k6/encoding/encoding_test.go b/js/modules/k6/encoding/encoding_test.go index 4d614211d9c..807fd787556 100644 --- a/js/modules/k6/encoding/encoding_test.go +++ b/js/modules/k6/encoding/encoding_test.go @@ -12,13 +12,7 @@ import ( "go.k6.io/k6/js/modulestest" ) -func TestEncodingAlgorithms(t *testing.T) { - t.Parallel() - - if testing.Short() { - return - } - +func makeRuntime(t *testing.T) *goja.Runtime { rt := goja.New() rt.SetFieldNameMapper(common.FieldNameMapper{}) m, ok := New().NewModuleInstance( @@ -32,8 +26,23 @@ func TestEncodingAlgorithms(t *testing.T) { require.True(t, ok) require.NoError(t, rt.Set("encoding", m.Exports().Named)) + return rt +} + +func TestEncodingAlgorithms(t *testing.T) { + t.Parallel() + + if testing.Short() { + return + } + t.Run("Base64", func(t *testing.T) { + t.Parallel() + t.Run("DefaultEnc", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) _, err := rt.RunString(` var correct = "aGVsbG8gd29ybGQ="; var encoded = encoding.b64encode("hello world"); @@ -43,6 +52,9 @@ func TestEncodingAlgorithms(t *testing.T) { assert.NoError(t, err) }) t.Run("DefaultDec", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) _, err := rt.RunString(` var correct = "hello world"; var decBin = encoding.b64decode("aGVsbG8gd29ybGQ="); @@ -55,6 +67,9 @@ func TestEncodingAlgorithms(t *testing.T) { assert.NoError(t, err) }) t.Run("DefaultArrayBufferEnc", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) _, err := rt.RunString(` var exp = "aGVsbG8="; var input = new Uint8Array([104, 101, 108, 108, 111]); // "hello" @@ -64,7 +79,10 @@ func TestEncodingAlgorithms(t *testing.T) { }`) assert.NoError(t, err) }) - t.Run("DefaultArrayBufferDec", func(t *testing.T) { //nolint:paralleltest // weird that it triggers here, and these tests can't be parallel + t.Run("DefaultArrayBufferDec", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) _, err := rt.RunString(` var exp = "hello"; var decBin = encoding.b64decode("aGVsbG8="); @@ -76,6 +94,9 @@ func TestEncodingAlgorithms(t *testing.T) { assert.NoError(t, err) }) t.Run("DefaultUnicodeEnc", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) _, err := rt.RunString(` var correct = "44GT44KT44Gr44Gh44Gv5LiW55WM"; var encoded = encoding.b64encode("こんにちは世界", "std"); @@ -85,6 +106,9 @@ func TestEncodingAlgorithms(t *testing.T) { assert.NoError(t, err) }) t.Run("DefaultUnicodeDec", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) _, err := rt.RunString(` var correct = "こんにちは世界"; var decBin = encoding.b64decode("44GT44KT44Gr44Gh44Gv5LiW55WM"); @@ -96,6 +120,9 @@ func TestEncodingAlgorithms(t *testing.T) { assert.NoError(t, err) }) t.Run("StdEnc", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) _, err := rt.RunString(` var correct = "aGVsbG8gd29ybGQ="; var encoded = encoding.b64encode("hello world", "std"); @@ -105,6 +132,9 @@ func TestEncodingAlgorithms(t *testing.T) { assert.NoError(t, err) }) t.Run("StdDec", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) _, err := rt.RunString(` var correct = "hello world"; var decoded = encoding.b64decode("aGVsbG8gd29ybGQ=", "std", "s"); @@ -114,6 +144,9 @@ func TestEncodingAlgorithms(t *testing.T) { assert.NoError(t, err) }) t.Run("RawStdEnc", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) _, err := rt.RunString(` var correct = "aGVsbG8gd29ybGQ"; var encoded = encoding.b64encode("hello world", "rawstd"); @@ -123,6 +156,9 @@ func TestEncodingAlgorithms(t *testing.T) { assert.NoError(t, err) }) t.Run("RawStdDec", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) _, err := rt.RunString(` var correct = "hello world"; var decoded = encoding.b64decode("aGVsbG8gd29ybGQ", "rawstd", "s"); @@ -132,6 +168,9 @@ func TestEncodingAlgorithms(t *testing.T) { assert.NoError(t, err) }) t.Run("URLEnc", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) _, err := rt.RunString(` var correct = "5bCP6aO85by-Li4="; var encoded = encoding.b64encode("小飼弾..", "url"); @@ -141,6 +180,9 @@ func TestEncodingAlgorithms(t *testing.T) { assert.NoError(t, err) }) t.Run("URLDec", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) _, err := rt.RunString(` var correct = "小飼弾.."; var decoded = encoding.b64decode("5bCP6aO85by-Li4=", "url", "s"); @@ -150,6 +192,9 @@ func TestEncodingAlgorithms(t *testing.T) { assert.NoError(t, err) }) t.Run("RawURLEnc", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) _, err := rt.RunString(` var correct = "5bCP6aO85by-Li4"; var encoded = encoding.b64encode("小飼弾..", "rawurl"); @@ -159,6 +204,9 @@ func TestEncodingAlgorithms(t *testing.T) { assert.NoError(t, err) }) t.Run("RawURLDec", func(t *testing.T) { + t.Parallel() + + rt := makeRuntime(t) _, err := rt.RunString(` var correct = "小飼弾.."; var decoded = encoding.b64decode("5bCP6aO85by-Li4", "rawurl", "s");