Skip to content

Commit

Permalink
Add JS scenario options
Browse files Browse the repository at this point in the history
This is a quick and possibly naive change to support browser options per
scenario (#3022).

It doesn't try to enable generic options for any JS module as #3000 did,
but it seems Ned abandoned this idea. We can open this discussion again
once #883 is resolved.
  • Loading branch information
Ivan Mirić committed Apr 26, 2023
1 parent ec094ce commit 941c830
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 2 deletions.
2 changes: 1 addition & 1 deletion cmd/tests/cmd_run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ func TestExecutionTestOptionsDefaultValues(t *testing.T) {
loglines := ts.LoggerHook.Drain()
require.Len(t, loglines, 1)

expected := `{"paused":null,"executionSegment":null,"executionSegmentSequence":null,"noSetup":null,"setupTimeout":null,"noTeardown":null,"teardownTimeout":null,"rps":null,"dns":{"ttl":null,"select":null,"policy":null},"maxRedirects":null,"userAgent":null,"batch":null,"batchPerHost":null,"httpDebug":null,"insecureSkipTLSVerify":null,"tlsCipherSuites":null,"tlsVersion":null,"tlsAuth":null,"throw":null,"thresholds":null,"blacklistIPs":null,"blockHostnames":null,"hosts":null,"noConnectionReuse":null,"noVUConnectionReuse":null,"minIterationDuration":null,"ext":null,"summaryTrendStats":["avg", "min", "med", "max", "p(90)", "p(95)"],"summaryTimeUnit":null,"systemTags":["check","error","error_code","expected_response","group","method","name","proto","scenario","service","status","subproto","tls_version","url"],"tags":null,"metricSamplesBufferSize":null,"noCookiesReset":null,"discardResponseBodies":null,"consoleOutput":null,"scenarios":{"default":{"vus":null,"iterations":1,"executor":"shared-iterations","maxDuration":null,"startTime":null,"env":null,"tags":null,"gracefulStop":null,"exec":null}},"localIPs":null}`
expected := `{"paused":null,"executionSegment":null,"executionSegmentSequence":null,"noSetup":null,"setupTimeout":null,"noTeardown":null,"teardownTimeout":null,"rps":null,"dns":{"ttl":null,"select":null,"policy":null},"maxRedirects":null,"userAgent":null,"batch":null,"batchPerHost":null,"httpDebug":null,"insecureSkipTLSVerify":null,"tlsCipherSuites":null,"tlsVersion":null,"tlsAuth":null,"throw":null,"thresholds":null,"blacklistIPs":null,"blockHostnames":null,"hosts":null,"noConnectionReuse":null,"noVUConnectionReuse":null,"minIterationDuration":null,"ext":null,"summaryTrendStats":["avg", "min", "med", "max", "p(90)", "p(95)"],"summaryTimeUnit":null,"systemTags":["check","error","error_code","expected_response","group","method","name","proto","scenario","service","status","subproto","tls_version","url"],"tags":null,"metricSamplesBufferSize":null,"noCookiesReset":null,"discardResponseBodies":null,"consoleOutput":null,"scenarios":{"default":{"vus":null,"iterations":1,"executor":"shared-iterations","maxDuration":null,"options":{"browser":null},"startTime":null,"env":null,"tags":null,"gracefulStop":null,"exec":null}},"localIPs":null}`
assert.JSONEq(t, expected, loglines[0].Message)
}

Expand Down
2 changes: 1 addition & 1 deletion js/modules/k6/execution/execution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ func TestAbortTest(t *testing.T) { //nolint:tparallel
func TestOptionsTestFull(t *testing.T) {
t.Parallel()

expected := `{"paused":true,"scenarios":{"const-vus":{"executor":"constant-vus","startTime":"10s","gracefulStop":"30s","env":{"FOO":"bar"},"exec":"default","tags":{"tagkey":"tagvalue"},"vus":50,"duration":"10m0s"}},"executionSegment":"0:1/4","executionSegmentSequence":"0,1/4,1/2,1","noSetup":true,"setupTimeout":"1m0s","noTeardown":true,"teardownTimeout":"5m0s","rps":100,"dns":{"ttl":"1m","select":"roundRobin","policy":"any"},"maxRedirects":3,"userAgent":"k6-user-agent","batch":15,"batchPerHost":5,"httpDebug":"full","insecureSkipTLSVerify":true,"tlsCipherSuites":["TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"],"tlsVersion":{"min":"tls1.2","max":"tls1.3"},"tlsAuth":[{"domains":["example.com"],"cert":"mycert.pem","key":"mycert-key.pem","password":"mypwd"}],"throw":true,"thresholds":{"http_req_duration":[{"threshold":"rate>0.01","abortOnFail":true,"delayAbortEval":"10s"}]},"blacklistIPs":["192.0.2.0/24"],"blockHostnames":["test.k6.io","*.example.com"],"hosts":{"test.k6.io":"1.2.3.4:8443"},"noConnectionReuse":true,"noVUConnectionReuse":true,"minIterationDuration":"10s","ext":{"ext-one":{"rawkey":"rawvalue"}},"summaryTrendStats":["avg","min","max"],"summaryTimeUnit":"ms","systemTags":["iter","vu"],"tags":null,"metricSamplesBufferSize":8,"noCookiesReset":true,"discardResponseBodies":true,"consoleOutput":"loadtest.log","tags":{"runtag-key":"runtag-value"},"localIPs":"192.168.20.12-192.168.20.15,192.168.10.0/27"}`
expected := `{"paused":true,"scenarios":{"const-vus":{"executor":"constant-vus","options":{"browser":null},"startTime":"10s","gracefulStop":"30s","env":{"FOO":"bar"},"exec":"default","tags":{"tagkey":"tagvalue"},"vus":50,"duration":"10m0s"}},"executionSegment":"0:1/4","executionSegmentSequence":"0,1/4,1/2,1","noSetup":true,"setupTimeout":"1m0s","noTeardown":true,"teardownTimeout":"5m0s","rps":100,"dns":{"ttl":"1m","select":"roundRobin","policy":"any"},"maxRedirects":3,"userAgent":"k6-user-agent","batch":15,"batchPerHost":5,"httpDebug":"full","insecureSkipTLSVerify":true,"tlsCipherSuites":["TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"],"tlsVersion":{"min":"tls1.2","max":"tls1.3"},"tlsAuth":[{"domains":["example.com"],"cert":"mycert.pem","key":"mycert-key.pem","password":"mypwd"}],"throw":true,"thresholds":{"http_req_duration":[{"threshold":"rate>0.01","abortOnFail":true,"delayAbortEval":"10s"}]},"blacklistIPs":["192.0.2.0/24"],"blockHostnames":["test.k6.io","*.example.com"],"hosts":{"test.k6.io":"1.2.3.4:8443"},"noConnectionReuse":true,"noVUConnectionReuse":true,"minIterationDuration":"10s","ext":{"ext-one":{"rawkey":"rawvalue"}},"summaryTrendStats":["avg","min","max"],"summaryTimeUnit":"ms","systemTags":["iter","vu"],"tags":null,"metricSamplesBufferSize":8,"noCookiesReset":true,"discardResponseBodies":true,"consoleOutput":"loadtest.log","tags":{"runtag-key":"runtag-value"},"localIPs":"192.168.20.12-192.168.20.15,192.168.10.0/27"}`

var (
rt = goja.New()
Expand Down
7 changes: 7 additions & 0 deletions lib/executor/base_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ var DefaultGracefulStopValue = 30 * time.Second //nolint:gochecknoglobals
var executorNameWhitelist = regexp.MustCompile(`^[0-9a-zA-Z_-]+$`) //nolint:gochecknoglobals
const executorNameErr = "the executor name should contain only numbers, latin letters, underscores, and dashes"

// ScenarioOptions are options specific to a scenario. These include k6 browser
// options, which are validated by the browser module, and not by k6 core.
type ScenarioOptions struct {
Browser map[string]any `json:"browser"`
}

// BaseConfig contains the common config fields for all executors
type BaseConfig struct {
Name string `json:"-"` // set via the JS object key
Expand All @@ -29,6 +35,7 @@ type BaseConfig struct {
Env map[string]string `json:"env"`
Exec null.String `json:"exec"` // function name, externally validated
Tags map[string]string `json:"tags"`
Options ScenarioOptions `json:"options"`

// TODO: future extensions like distribution, others?
}
Expand Down
14 changes: 14 additions & 0 deletions lib/executor/executors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,20 @@ var configMapTestCases = []configMapTestCase{
{`{"varrival": {"executor": "ramping-arrival-rate", "preAllocatedVUs": 20, "maxVUs": 50, "stages": [{"duration": "5m", "target": 10}], "timeUnit": "-1s"}}`, exp{validationError: true}},
{`{"varrival": {"executor": "ramping-arrival-rate", "preAllocatedVUs": 30, "maxVUs": 20, "stages": [{"duration": "5m", "target": 10}]}}`, exp{validationError: true}},
// TODO: more tests of mixed executors and execution plans

// scenario options
{
`{"ui": {"executor": "shared-iterations", "iterations": 22, "vus": 12, "maxDuration": "100s", "options": {"browser": {"someBrowserOption": true}}}}`,
exp{custom: func(t *testing.T, cm lib.ScenarioConfigs) {
require.Empty(t, cm["ui"].Validate())
siCfg, ok := cm["ui"].(SharedIterationsConfig)
require.True(t, ok)
require.NotEmpty(t, siCfg.Options.Browser)
assert.EqualValues(t, true, siCfg.Options.Browser["someBrowserOption"])
}},
},
// only the "browser" scenario option is supported
{`{"ui": {"executor": "shared-iterations", "iterations": 22, "vus": 12, "maxDuration": "100s", "options": {"unsupported": {}}}}`, exp{parseError: true}},
}

func TestConfigMapParsingAndValidation(t *testing.T) {
Expand Down

0 comments on commit 941c830

Please sign in to comment.