From 3b4c43f4a366b5abbbaa97cf4c9fa29467898b01 Mon Sep 17 00:00:00 2001 From: Ivan <2103732+codebien@users.noreply.github.com> Date: Wed, 3 Aug 2022 11:38:20 +0200 Subject: [PATCH] lib/options: Migrated RunTags to map[string]string type It facilitates the transition to a more efficient SampleTags. --- cmd/config_consolidation_test.go | 14 ++++++++++++++ cmd/options.go | 2 +- core/engine_test.go | 14 ++++++++++---- core/local/local.go | 7 ++++--- js/modules/k6/execution/execution_test.go | 2 +- js/runner.go | 12 ++++++++++-- lib/executor/base_executor.go | 5 ++++- lib/netext/httpext/request_test.go | 7 ------- lib/netext/httpext/transport_test.go | 1 - lib/options.go | 6 +++--- lib/options_test.go | 2 +- 11 files changed, 48 insertions(+), 24 deletions(-) diff --git a/cmd/config_consolidation_test.go b/cmd/config_consolidation_test.go index 881dd1e5ce3..95af36e3521 100644 --- a/cmd/config_consolidation_test.go +++ b/cmd/config_consolidation_test.go @@ -370,6 +370,20 @@ func getConfigConsolidationTestCases() []configConsolidationTestCase { ) }, }, + + // Test-wide Tags + { + opts{ + fs: defaultConfig(`{"tags": { "codeTagKey": "codeTagValue"}}`), + cli: []string{"--tag", "clitagkey=clitagvalue"}, + }, + exp{}, + func(t *testing.T, c Config) { + exp := map[string]string{"clitagkey": "clitagvalue"} + assert.Equal(t, exp, c.RunTags) + }, + }, + // Test summary trend stats {opts{}, exp{}, func(t *testing.T, c Config) { assert.Equal(t, lib.DefaultSummaryTrendStats, c.Options.SummaryTrendStats) diff --git a/cmd/options.go b/cmd/options.go index f035aea9f16..90a91f71991 100644 --- a/cmd/options.go +++ b/cmd/options.go @@ -245,7 +245,7 @@ func getOptions(flags *pflag.FlagSet) (lib.Options, error) { } parsedRunTags[name] = value } - opts.RunTags = metrics.IntoSampleTags(&parsedRunTags) + opts.RunTags = parsedRunTags } redirectConFile, err := flags.GetString("console-output") diff --git a/core/engine_test.go b/core/engine_test.go index f1c8f14730d..84ab62ab9c5 100644 --- a/core/engine_test.go +++ b/core/engine_test.go @@ -690,8 +690,14 @@ func TestRunTags(t *testing.T) { t.Parallel() tb := httpmultibin.NewHTTPMultiBin(t) - runTagsMap := map[string]string{"foo": "bar", "test": "mest", "over": "written"} - runTags := metrics.NewSampleTags(runTagsMap) + expectedRunTags := map[string]string{"foo": "bar", "test": "mest", "over": "written"} + + // it copies the map so in the case the runner will overwrite + // some run tags' values it doesn't affect the assertion. + runTags := make(map[string]string) + for k, v := range expectedRunTags { + runTags[k] = v + } script := []byte(tb.Replacer.Replace(` import http from "k6/http"; @@ -780,14 +786,14 @@ func TestRunTags(t *testing.T) { getExpectedOverVal := func(metricName string) string { for _, sysMetric := range systemMetrics { if sysMetric == metricName { - return runTagsMap["over"] + return expectedRunTags["over"] } } return "the rainbow" } for _, s := range mockOutput.Samples { - for key, expVal := range runTagsMap { + for key, expVal := range expectedRunTags { val, ok := s.Tags.Get(key) if key == "over" { diff --git a/core/local/local.go b/core/local/local.go index c4c01b17829..83499074bfd 100644 --- a/core/local/local.go +++ b/core/local/local.go @@ -224,6 +224,7 @@ func (e *ExecutionScheduler) initVUsConcurrently( func (e *ExecutionScheduler) emitVUsAndVUsMax(ctx context.Context, out chan<- metrics.SampleContainer) { e.state.Test.Logger.Debug("Starting emission of VUs and VUsMax metrics...") + runTags := metrics.NewSampleTags(e.state.Test.Options.RunTags) emitMetrics := func() { t := time.Now() @@ -233,15 +234,15 @@ func (e *ExecutionScheduler) emitVUsAndVUsMax(ctx context.Context, out chan<- me Time: t, Metric: e.state.Test.BuiltinMetrics.VUs, Value: float64(e.state.GetCurrentlyActiveVUsCount()), - Tags: e.state.Test.Options.RunTags, + Tags: runTags, }, { Time: t, Metric: e.state.Test.BuiltinMetrics.VUsMax, Value: float64(e.state.GetInitializedVUsCount()), - Tags: e.state.Test.Options.RunTags, + Tags: runTags, }, }, - Tags: e.state.Test.Options.RunTags, + Tags: runTags, Time: t, } metrics.PushIfNotDone(ctx, out, samples) diff --git a/js/modules/k6/execution/execution_test.go b/js/modules/k6/execution/execution_test.go index 525a8ca68ef..320f3728f61 100644 --- a/js/modules/k6/execution/execution_test.go +++ b/js/modules/k6/execution/execution_test.go @@ -352,7 +352,7 @@ func TestOptionsTestFull(t *testing.T) { sysm := metrics.TagIter | metrics.TagVU return &sysm }(), - RunTags: metrics.NewSampleTags(map[string]string{"runtag-key": "runtag-value"}), + RunTags: map[string]string{"runtag-key": "runtag-value"}, MetricSamplesBufferSize: null.IntFrom(8), ConsoleOutput: null.StringFrom("loadtest.log"), LocalIPs: func() types.NullIPPool { diff --git a/js/runner.go b/js/runner.go index 5154abe4792..70b4a659539 100644 --- a/js/runner.go +++ b/js/runner.go @@ -257,7 +257,7 @@ func (r *Runner) newVU(idLocal, idGlobal uint64, samplesOut chan<- metrics.Sampl VUID: vu.ID, VUIDGlobal: vu.IDGlobal, Samples: vu.Samples, - Tags: lib.NewTagMap(vu.Runner.Bundle.Options.RunTags.CloneTags()), + Tags: lib.NewTagMap(copyStringMap(vu.Runner.Bundle.Options.RunTags)), Group: r.defaultGroup, BuiltinMetrics: r.preInitState.BuiltinMetrics, } @@ -630,7 +630,7 @@ func (u *VU) Activate(params *lib.VUActivationParams) lib.ActiveVU { opts := u.Runner.Bundle.Options // TODO: maybe we can cache the original tags only clone them and add (if any) new tags on top ? - u.state.Tags = lib.NewTagMap(opts.RunTags.CloneTags()) + u.state.Tags = lib.NewTagMap(copyStringMap(opts.RunTags)) for k, v := range params.Tags { u.state.Tags.Set(k, v) } @@ -861,3 +861,11 @@ func (s *scriptException) Hint() string { func (s *scriptException) ExitCode() exitcodes.ExitCode { return exitcodes.ScriptException } + +func copyStringMap(m map[string]string) map[string]string { + clone := make(map[string]string, len(m)) + for ktag, vtag := range m { + clone[ktag] = vtag + } + return clone +} diff --git a/lib/executor/base_executor.go b/lib/executor/base_executor.go index e8e57cddf0e..f9662598a8c 100644 --- a/lib/executor/base_executor.go +++ b/lib/executor/base_executor.go @@ -93,7 +93,10 @@ func (bs *BaseExecutor) GetProgress() *pb.ProgressBar { // getMetricTags returns a tag set that can be used to emit metrics by the // executor. The VU ID is optional. func (bs *BaseExecutor) getMetricTags(vuID *uint64) *metrics.SampleTags { - tags := bs.executionState.Test.Options.RunTags.CloneTags() + tags := make(map[string]string, len(bs.executionState.Test.Options.RunTags)) + for k, v := range bs.executionState.Test.Options.RunTags { + tags[k] = v + } if bs.executionState.Test.Options.SystemTags.Has(metrics.TagScenario) { tags["scenario"] = bs.config.GetName() } diff --git a/lib/netext/httpext/request_test.go b/lib/netext/httpext/request_test.go index 5c6f3b0227d..b2c254c0d8a 100644 --- a/lib/netext/httpext/request_test.go +++ b/lib/netext/httpext/request_test.go @@ -118,7 +118,6 @@ func TestMakeRequestError(t *testing.T) { Compressions: []CompressionType{badCompressionType}, } state := &lib.State{ - Options: lib.Options{RunTags: &metrics.SampleTags{}}, Transport: http.DefaultTransport, Logger: logrus.New(), Tags: lib.NewTagMap(nil), @@ -141,7 +140,6 @@ func TestMakeRequestError(t *testing.T) { logger := logrus.New() logger.Level = logrus.DebugLevel state := &lib.State{ - Options: lib.Options{RunTags: &metrics.SampleTags{}}, Transport: srv.Client().Transport, Logger: logger, Tags: lib.NewTagMap(nil), @@ -192,7 +190,6 @@ func TestResponseStatus(t *testing.T) { samples := make(chan<- metrics.SampleContainer, 1) registry := metrics.NewRegistry() state := &lib.State{ - Options: lib.Options{RunTags: &metrics.SampleTags{}}, Transport: server.Client().Transport, Logger: logger, Samples: samples, @@ -271,7 +268,6 @@ func TestMakeRequestTimeoutInTheMiddle(t *testing.T) { registry := metrics.NewRegistry() state := &lib.State{ Options: lib.Options{ - RunTags: &metrics.SampleTags{}, SystemTags: &metrics.DefaultSystemTagSet, }, Transport: srv.Client().Transport, @@ -348,7 +344,6 @@ func TestTrailFailed(t *testing.T) { registry := metrics.NewRegistry() state := &lib.State{ Options: lib.Options{ - RunTags: &metrics.SampleTags{}, SystemTags: &metrics.DefaultSystemTagSet, }, Transport: srv.Client().Transport, @@ -410,7 +405,6 @@ func TestMakeRequestDialTimeout(t *testing.T) { registry := metrics.NewRegistry() state := &lib.State{ Options: lib.Options{ - RunTags: &metrics.SampleTags{}, SystemTags: &metrics.DefaultSystemTagSet, }, Transport: &http.Transport{ @@ -469,7 +463,6 @@ func TestMakeRequestTimeoutInTheBegining(t *testing.T) { registry := metrics.NewRegistry() state := &lib.State{ Options: lib.Options{ - RunTags: &metrics.SampleTags{}, SystemTags: &metrics.DefaultSystemTagSet, }, Transport: srv.Client().Transport, diff --git a/lib/netext/httpext/transport_test.go b/lib/netext/httpext/transport_test.go index 71dd7a99d76..eb319d08171 100644 --- a/lib/netext/httpext/transport_test.go +++ b/lib/netext/httpext/transport_test.go @@ -46,7 +46,6 @@ func BenchmarkMeasureAndEmitMetrics(b *testing.B) { registry := metrics.NewRegistry() state := &lib.State{ Options: lib.Options{ - RunTags: &metrics.SampleTags{}, SystemTags: &metrics.DefaultSystemTagSet, }, BuiltinMetrics: metrics.RegisterBuiltinMetrics(registry), diff --git a/lib/options.go b/lib/options.go index 77508f91ab3..17429595e10 100644 --- a/lib/options.go +++ b/lib/options.go @@ -411,8 +411,8 @@ type Options struct { // Use pointer for identifying whether user provide any tag or not. SystemTags *metrics.SystemTagSet `json:"systemTags" envconfig:"K6_SYSTEM_TAGS"` - // Tags to be applied to all samples for this running - RunTags *metrics.SampleTags `json:"tags" envconfig:"K6_TAGS"` + // Tags are key-value pairs to be applied to all samples for the run. + RunTags map[string]string `json:"tags" envconfig:"K6_TAGS"` // Buffer size of the channel for metric samples; 0 means unbuffered MetricSamplesBufferSize null.Int `json:"metricSamplesBufferSize" envconfig:"K6_METRIC_SAMPLES_BUFFER_SIZE"` @@ -567,7 +567,7 @@ func (o Options) Apply(opts Options) Options { if opts.SystemTags != nil { o.SystemTags = opts.SystemTags } - if !opts.RunTags.IsEmpty() { + if len(opts.RunTags) > 0 { o.RunTags = opts.RunTags } if opts.MetricSamplesBufferSize.Valid { diff --git a/lib/options_test.go b/lib/options_test.go index 6e31cb0ec64..07386976699 100644 --- a/lib/options_test.go +++ b/lib/options_test.go @@ -562,7 +562,7 @@ func TestOptions(t *testing.T) { }) t.Run("RunTags", func(t *testing.T) { t.Parallel() - tags := metrics.IntoSampleTags(&map[string]string{"myTag": "hello"}) + tags := map[string]string{"myTag": "hello"} opts := Options{}.Apply(Options{RunTags: tags}) assert.Equal(t, tags, opts.RunTags) })