Skip to content
This repository has been archived by the owner on Sep 17, 2021. It is now read-only.

Commit

Permalink
Convert to V2 JS module
Browse files Browse the repository at this point in the history
  • Loading branch information
Ivan Mirić committed Aug 6, 2021
1 parent da83b1b commit 4b540ad
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 32 deletions.
58 changes: 32 additions & 26 deletions pkg/execution/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,60 +29,66 @@ import (
"github.com/dop251/goja"

"go.k6.io/k6/js/common"
"go.k6.io/k6/js/modules"
"go.k6.io/k6/lib"
)

type (
// RootExecution is the global module instance that will create module
// RootModule is the global module instance that will create module
// instances for each VU.
RootExecution struct{}
// Execution is a JS module that returns information about the currently
// executing test run.
Execution struct{ *goja.Proxy }
RootModule struct{}

// ModuleInstance represents an instance of the execution module.
ModuleInstance struct {
modules.InstanceCore
proxy *goja.Proxy
}
)

// NewModuleInstancePerVU fulfills the k6 modules.HasModuleInstancePerVU
// interface so that each VU will get a separate copy of the module.
func (*RootExecution) NewModuleInstancePerVU() interface{} {
return &Execution{}
}
var (
_ modules.IsModuleV2 = &RootModule{}
_ modules.Instance = &ModuleInstance{}
)

// New returns a pointer to a new RootExecution instance.
func New() *RootExecution {
return &RootExecution{}
// New returns a pointer to a new RootModule instance.
func New() *RootModule {
return &RootModule{}
}

// WithContext fulfills the k6 modules.HasWithContext interface to allow
// retrieving the VU, scenario and test state from the context used by each VU.
// It initializes a goja.Proxy object for the per-VU module instance, which in
// turn retrieves goja.DynamicObject instances for each property (scenario, vu,
// test).
func (e *Execution) WithContext(getCtx func() context.Context) {
// NewModuleInstance implements the modules.IsModuleV2 interface to return
// a new instance for each VU.
// It initializes a goja.Proxy instance, which in turn returns
// goja.DynamicObject instances for each property (scenario, vu, test).
func (*RootModule) NewModuleInstance(m modules.InstanceCore) modules.Instance {
keys := []string{"scenario", "vu", "test"}

pcfg := goja.ProxyTrapConfig{
OwnKeys: func(target *goja.Object) *goja.Object {
ctx := getCtx()
rt := common.GetRuntime(ctx)
rt := m.GetRuntime()
return rt.ToValue(keys).ToObject(rt)
},
Has: func(target *goja.Object, prop string) (available bool) {
return sort.SearchStrings(keys, prop) != -1
},
Get: func(target *goja.Object, prop string, r goja.Value) goja.Value {
return dynObjValue(getCtx, target, prop)
return dynObjValue(m.GetContext, target, prop)
},
GetOwnPropertyDescriptor: func(target *goja.Object, prop string) (desc goja.PropertyDescriptor) {
desc.Enumerable, desc.Configurable = goja.FLAG_TRUE, goja.FLAG_TRUE
desc.Value = dynObjValue(getCtx, target, prop)
desc.Value = dynObjValue(m.GetContext, target, prop)
return desc
},
}

ctx := getCtx()
rt := common.GetRuntime(ctx)
rt := m.GetRuntime()
proxy := rt.NewProxy(rt.NewObject(), &pcfg)
e.Proxy = &proxy

return &ModuleInstance{InstanceCore: m, proxy: &proxy}
}

// GetExports returns the exports of the execution module.
func (mi *ModuleInstance) GetExports() modules.Exports {
return modules.Exports{Default: mi.proxy}
}

// dynObjValue returns a goja.Value for a specific prop on target.
Expand Down
13 changes: 7 additions & 6 deletions pkg/execution/execution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,8 +310,9 @@ func TestExecutionInfo(t *testing.T) {
testCases := []struct {
name, script, expErr string
}{
// TODO: Get rid of having to get .default
{name: "vu_ok", script: `
var exec = require('k6/x/execution');
var exec = require('k6/x/execution').default;
exports.default = function() {
if (exec.vu.id !== 1) throw new Error('unexpected VU ID: '+exec.vu.id);
Expand All @@ -320,11 +321,11 @@ func TestExecutionInfo(t *testing.T) {
if (exec.vu.iterationScenario !== 0) throw new Error('unexpected scenario iteration: '+exec.vu.iterationScenario);
}`},
{name: "vu_err", script: `
var exec = require('k6/x/execution');
var exec = require('k6/x/execution').default;
exec.vu;
`, expErr: "getting VU information in the init context is not supported"},
{name: "scenario_ok", script: `
var exec = require('k6/x/execution');
var exec = require('k6/x/execution').default;
var sleep = require('k6').sleep;
exports.default = function() {
Expand All @@ -338,11 +339,11 @@ func TestExecutionInfo(t *testing.T) {
if (si.iterationGlobal !== 4) throw new Error('unexpected scenario local iteration: '+si.iterationGlobal);
}`},
{name: "scenario_err", script: `
var exec = require('k6/x/execution');
var exec = require('k6/x/execution').default;
exec.scenario;
`, expErr: "getting scenario information in the init context is not supported"},
{name: "test_ok", script: `
var exec = require('k6/x/execution');
var exec = require('k6/x/execution').default;
exports.default = function() {
var ti = exec.test;
Expand All @@ -353,7 +354,7 @@ func TestExecutionInfo(t *testing.T) {
if (ti.iterationsInterrupted !== 0) throw new Error('unexpected iterationsInterrupted: '+ti.iterationsInterrupted);
}`},
{name: "test_err", script: `
var exec = require('k6/x/execution');
var exec = require('k6/x/execution').default;
exec.test;
`, expErr: "getting test information in the init context is not supported"},
}
Expand Down

0 comments on commit 4b540ad

Please sign in to comment.