diff --git a/js/init_and_modules_test.go b/js/init_and_modules_test.go index 0a72fd90cc7..29e8162e068 100644 --- a/js/init_and_modules_test.go +++ b/js/init_and_modules_test.go @@ -30,7 +30,7 @@ import ( "github.com/loadimpact/k6/js" "github.com/loadimpact/k6/js/common" - "github.com/loadimpact/k6/js/internal/modules" + "github.com/loadimpact/k6/js/modules" "github.com/loadimpact/k6/lib" "github.com/loadimpact/k6/lib/testutils" "github.com/loadimpact/k6/loader" @@ -66,7 +66,7 @@ var uniqueModuleNumber int64 //nolint:gochecknoglobals func TestNewJSRunnerWithCustomModule(t *testing.T) { t.Parallel() checkModule := &CheckModule{t: t} - moduleName := fmt.Sprintf("k6/check-%d", atomic.AddInt64(&uniqueModuleNumber, 1)) + moduleName := fmt.Sprintf("k6/x/check-%d", atomic.AddInt64(&uniqueModuleNumber, 1)) modules.Register(moduleName, checkModule) script := fmt.Sprintf(` diff --git a/js/initcontext.go b/js/initcontext.go index 9fae7c78ab2..eeb286694d0 100644 --- a/js/initcontext.go +++ b/js/initcontext.go @@ -34,7 +34,7 @@ import ( "github.com/loadimpact/k6/js/common" "github.com/loadimpact/k6/js/compiler" - "github.com/loadimpact/k6/js/internal/modules" + "github.com/loadimpact/k6/js/modules" "github.com/loadimpact/k6/lib" "github.com/loadimpact/k6/loader" ) diff --git a/js/internal/modules/modules.go b/js/internal/modules/modules.go deleted file mode 100644 index f3b3623f7f3..00000000000 --- a/js/internal/modules/modules.go +++ /dev/null @@ -1,85 +0,0 @@ -/* - * - * k6 - a next-generation load testing tool - * Copyright (C) 2020 Load Impact - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - -package modules - -import ( - "fmt" - "sync" - - "github.com/loadimpact/k6/js/modules/k6" - "github.com/loadimpact/k6/js/modules/k6/crypto" - "github.com/loadimpact/k6/js/modules/k6/crypto/x509" - "github.com/loadimpact/k6/js/modules/k6/data" - "github.com/loadimpact/k6/js/modules/k6/encoding" - "github.com/loadimpact/k6/js/modules/k6/grpc" - "github.com/loadimpact/k6/js/modules/k6/html" - "github.com/loadimpact/k6/js/modules/k6/http" - "github.com/loadimpact/k6/js/modules/k6/metrics" - "github.com/loadimpact/k6/js/modules/k6/ws" -) - -//nolint:gochecknoglobals -var ( - modules = make(map[string]interface{}) - mx sync.RWMutex -) - -// HasModuleInstancePerVU should be implemented by all native Golang modules that -// would require per-VU state. k6 will call their NewModuleInstancePerVU() methods -// every time a VU imports the module and use its result as the returned object. -type HasModuleInstancePerVU interface { - NewModuleInstancePerVU() interface{} -} - -// Register the given mod as a JavaScript module, available -// for import from JS scripts by name. -// This function panics if a module with the same name is already registered. -func Register(name string, mod interface{}) { - mx.Lock() - defer mx.Unlock() - - if _, ok := modules[name]; ok { - panic(fmt.Sprintf("module already registered: %s", name)) - } - modules[name] = mod -} - -// GetJSModules returns a map of all js modules -func GetJSModules() map[string]interface{} { - result := map[string]interface{}{ - "k6": k6.New(), - "k6/crypto": crypto.New(), - "k6/crypto/x509": x509.New(), - "k6/data": data.New(), - "k6/encoding": encoding.New(), - "k6/net/grpc": grpc.New(), - "k6/html": html.New(), - "k6/http": http.New(), - "k6/metrics": metrics.New(), - "k6/ws": ws.New(), - } - - for name, module := range modules { - result[name] = module - } - - return result -} diff --git a/js/modules/modules.go b/js/modules/modules.go index c1ddcb83623..c65f4fbae74 100644 --- a/js/modules/modules.go +++ b/js/modules/modules.go @@ -23,12 +23,28 @@ package modules import ( "fmt" "strings" + "sync" - "github.com/loadimpact/k6/js/internal/modules" + "github.com/loadimpact/k6/js/modules/k6" + "github.com/loadimpact/k6/js/modules/k6/crypto" + "github.com/loadimpact/k6/js/modules/k6/crypto/x509" + "github.com/loadimpact/k6/js/modules/k6/data" + "github.com/loadimpact/k6/js/modules/k6/encoding" + "github.com/loadimpact/k6/js/modules/k6/grpc" + "github.com/loadimpact/k6/js/modules/k6/html" + "github.com/loadimpact/k6/js/modules/k6/http" + "github.com/loadimpact/k6/js/modules/k6/metrics" + "github.com/loadimpact/k6/js/modules/k6/ws" ) const extPrefix string = "k6/x/" +//nolint:gochecknoglobals +var ( + modules = make(map[string]interface{}) + mx sync.RWMutex +) + // Register the given mod as an external JavaScript module that can be imported // by name. The name must be unique across all registered modules and must be // prefixed with "k6/x/", otherwise this function will panic. @@ -37,5 +53,44 @@ func Register(name string, mod interface{}) { panic(fmt.Errorf("external module names must be prefixed with '%s', tried to register: %s", extPrefix, name)) } - modules.Register(name, mod) + mx.Lock() + defer mx.Unlock() + + if _, ok := modules[name]; ok { + panic(fmt.Sprintf("module already registered: %s", name)) + } + modules[name] = mod +} + +// HasModuleInstancePerVU should be implemented by all native Golang modules that +// would require per-VU state. k6 will call their NewModuleInstancePerVU() methods +// every time a VU imports the module and use its result as the returned object. +type HasModuleInstancePerVU interface { + NewModuleInstancePerVU() interface{} +} + +// checks that modules implement HasModuleInstancePerVU +// this is done here as otherwise there will be a loop if the module imports this package +var _ HasModuleInstancePerVU = http.New() + +// GetJSModules returns a map of all js modules +func GetJSModules() map[string]interface{} { + result := map[string]interface{}{ + "k6": k6.New(), + "k6/crypto": crypto.New(), + "k6/crypto/x509": x509.New(), + "k6/data": data.New(), + "k6/encoding": encoding.New(), + "k6/net/grpc": grpc.New(), + "k6/html": html.New(), + "k6/http": http.New(), + "k6/metrics": metrics.New(), + "k6/ws": ws.New(), + } + + for name, module := range modules { + result[name] = module + } + + return result }