diff --git a/cmd/config_test.go b/cmd/config_test.go index 61eb55f494b..7d7be3187f7 100644 --- a/cmd/config_test.go +++ b/cmd/config_test.go @@ -83,6 +83,8 @@ func TestConfigCmd(t *testing.T) { } } +//TODO: write end-to-end configuration tests - how the config file, in-script options, environment variables and CLI flags are parsed and interact... and how the end result is then propagated back into the script + func TestConfigEnv(t *testing.T) { testdata := map[struct{ Name, Key string }]map[string]func(Config){ {"Linger", "K6_LINGER"}: { diff --git a/cmd/options.go b/cmd/options.go index 16a39fd2d72..ea3dcdacf1b 100644 --- a/cmd/options.go +++ b/cmd/options.go @@ -96,18 +96,22 @@ func getOptions(flags *pflag.FlagSet) (lib.Options, error) { MetricSamplesBufferSize: null.NewInt(1000, false), } - stageStrings, err := flags.GetStringSlice("stage") - if err != nil { - return opts, err - } - if len(stageStrings) > 0 { - opts.Stages = make([]lib.Stage, len(stageStrings)) + // Using Lookup() because GetStringSlice() doesn't differentiate between --stage="" and no value + if flags.Lookup("stage").Changed { + stageStrings, err := flags.GetStringSlice("stage") + if err != nil { + return opts, err + } + opts.Stages = []lib.Stage{} for i, s := range stageStrings { var stage lib.Stage if err := stage.UnmarshalText([]byte(s)); err != nil { return opts, errors.Wrapf(err, "stage %d", i) } - opts.Stages[i] = stage + if !stage.Duration.Valid { + return opts, fmt.Errorf("stage %d doesn't have a specified duration", i) + } + opts.Stages = append(opts.Stages, stage) } } diff --git a/cmd/run.go b/cmd/run.go index 759ac54021b..bdfe7103051 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -143,7 +143,7 @@ a commandline interface for interacting with it.`, } // If -d/--duration, -i/--iterations and -s/--stage are all unset, run to one iteration. - if !conf.Duration.Valid && !conf.Iterations.Valid && conf.Stages == nil { + if !conf.Duration.Valid && !conf.Iterations.Valid && len(conf.Stages) == 0 { conf.Iterations = null.IntFrom(1) } diff --git a/core/local/local.go b/core/local/local.go index 683d45cb1f6..5776b0d85c7 100644 --- a/core/local/local.go +++ b/core/local/local.go @@ -279,7 +279,7 @@ func (e *Executor) Run(parent context.Context, engineOut chan<- stats.SampleCont } stages := e.stages - if stages != nil { + if len(stages) > 0 { vus, keepRunning := ProcessStages(startVUs, stages, at) if !keepRunning { e.Logger.WithField("at", at).Debug("Local: Ran out of stages") diff --git a/release notes/upcoming.md b/release notes/upcoming.md index 372bb7372fb..eac4073d149 100644 --- a/release notes/upcoming.md +++ b/release notes/upcoming.md @@ -103,4 +103,5 @@ Thanks to @AndriiChuzhynov for implementing this! (#766) * Config: Stages were appended instead of overwritten from upper config "tiers", and were doubled when supplied via the CLI flag (#759) * HAR converter: Fixed a panic due to a missing array length check (#760) * HTTP: `http.batch()` calls could panic because of a data race when the `batchPerHost` global option was used (#770) -* Docker: Fixed the grafana image in the docker-compose setup. Thanks @entone and @mariolopjr! (#783) \ No newline at end of file +* Docker: Fixed the grafana image in the docker-compose setup. Thanks @entone and @mariolopjr! (#783) +* Config: Stages configured via the script `options` or environment variables couldn't be disabled via the CLI flags (#786)