From d55e66334aae083d164c365dd4a040bee44dc10d Mon Sep 17 00:00:00 2001 From: Gogs Date: Sat, 31 Jul 2021 17:18:42 +0530 Subject: [PATCH 1/8] Pass setup data object into handleSummary callback Issue: #2088 --- js/runner.go | 2 +- js/summary.go | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/js/runner.go b/js/runner.go index c91e9fcb235..4729e1b476f 100644 --- a/js/runner.go +++ b/js/runner.go @@ -316,7 +316,7 @@ func (r *Runner) IsExecutable(name string) bool { // HandleSummary calls the specified summary callback, if supplied. func (r *Runner) HandleSummary(ctx context.Context, summary *lib.Summary) (map[string]io.Reader, error) { - summaryDataForJS := summarizeMetricsToObject(summary, r.Bundle.Options) + summaryDataForJS := summarizeMetricsToObject(summary, r.Bundle.Options, r.setupData) out := make(chan stats.SampleContainer, 100) defer close(out) diff --git a/js/summary.go b/js/summary.go index 2a2b537173b..b9558a70ce7 100644 --- a/js/summary.go +++ b/js/summary.go @@ -25,7 +25,7 @@ import ( "fmt" "io" "time" - + "encoding/json" "github.com/dop251/goja" "go.k6.io/k6/js/common" "go.k6.io/k6/lib" @@ -79,7 +79,7 @@ func metricValueGetter(summaryTrendStats []string) func(stats.Sink, time.Duratio // summarizeMetricsToObject transforms the summary objects in a way that's // suitable to pass to the JS runtime or export to JSON. -func summarizeMetricsToObject(data *lib.Summary, options lib.Options) map[string]interface{} { +func summarizeMetricsToObject(data *lib.Summary, options lib.Options, setupData []byte) map[string]interface{} { m := make(map[string]interface{}) m["root_group"] = exportGroup(data.RootGroup) m["options"] = map[string]interface{}{ @@ -117,6 +117,17 @@ func summarizeMetricsToObject(data *lib.Summary, options lib.Options) map[string } m["metrics"] = metricsData + var setupDataI interface{} + if setupData != nil { + if err := json.Unmarshal(setupData, &setupDataI); err != nil { + return nil + } + } else { + setupDataI = goja.Undefined() + } + + m["setup_data"] = setupDataI + return m } From 29d6caf5a388c1eee4d4479f7799eabb0de7acc7 Mon Sep 17 00:00:00 2001 From: Gogs Date: Sun, 22 Aug 2021 01:53:25 +0530 Subject: [PATCH 2/8] Added tests for passing setup data to handleSummary callback --- js/summary_test.go | 146 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) diff --git a/js/summary_test.go b/js/summary_test.go index 790973613fa..3869a2021dd 100644 --- a/js/summary_test.go +++ b/js/summary_test.go @@ -395,6 +395,124 @@ const expectedHandleSummaryRawData = ` } }` +const expectedHandleSummaryDataWithSetup = ` +{ + "root_group": { + "groups": [ + { + "name": "child", + "path": "::child", + "id": "f41cbb53a398ec1c9fb3d33e20c9b040", + "groups": [], + "checks": [ + { + "id": "6289a7a06253a1c3f6137dfb25695563", + "passes": 30, + "fails": 0, + "name": "check1", + "path": "::child::check1" + }, + { + "fails": 5, + "name": "check3", + "path": "::child::check3", + "id": "c7553eca92d3e034b5808332296d304a", + "passes": 10 + }, + { + "name": "check2", + "path": "::child::check2", + "id": "06f5922794bef0d4584ba76a49893e1f", + "passes": 5, + "fails": 10 + } + ] + } + ], + "checks": [], + "name": "", + "path": "", + "id": "d41d8cd98f00b204e9800998ecf8427e" + }, + "options": { + "summaryTrendStats": [ + "avg", + "min", + "med", + "max", + "p(90)", + "p(95)", + "p(99)", + "count" + ], + "summaryTimeUnit": "", + "noColor": false + }, + "state": { + "isStdErrTTY": false, + "isStdOutTTY": false, + "testRunDurationMs": 1000 + }, + "setup_data": 5, + "metrics": { + "checks": { + "contains": "default", + "values": { + "passes": 45, + "fails": 15, + "rate": 0.75 + }, + "type": "rate", + "thresholds": { + "rate>70": { + "ok": true + } + } + }, + "my_trend": { + "thresholds": { + "my_trend<1000": { + "ok": false + } + }, + "type": "trend", + "contains": "time", + "values": { + "max": 20, + "p(90)": 19, + "p(95)": 19.5, + "p(99)": 19.9, + "count": 3, + "avg": 15, + "min": 10, + "med": 15 + } + }, + "vus": { + "contains": "default", + "values": { + "value": 1, + "min": 1, + "max": 1 + }, + "type": "gauge" + }, + "http_reqs": { + "type": "counter", + "contains": "default", + "values": { + "count": 3, + "rate": 3 + }, + "thresholds": { + "rate<100": { + "ok": false + } + } + } + } +}` + func TestRawHandleSummaryData(t *testing.T) { t.Parallel() runner, err := getSimpleRunner( @@ -432,6 +550,34 @@ func TestRawHandleSummaryData(t *testing.T) { assert.JSONEq(t, expectedHandleSummaryRawData, string(newRawData)) } +func TestRawHandleSummaryDataWithSetupData(t *testing.T) { + t.Parallel() + runner, err := getSimpleRunner( + t, "/script.js", + ` + exports.options = {summaryTrendStats: ["avg", "min", "med", "max", "p(90)", "p(95)", "p(99)", "count"]}; + exports.default = function() { /* we don't run this, metrics are mocked */ }; + exports.handleSummary = function(data) { + if(data.setup_data != 5) { + throw new Error("handleSummary: wrong data: " + JSON.stringify(data)) + } + return {'dataWithSetup.json': JSON.stringify(data)}; + }; + `, + + ) + runner.SetSetupData([]byte("5")) + require.NoError(t, err) + + summary := createTestSummary(t) + result, err := runner.HandleSummary(context.Background(), summary) + dataWithSetup, err := ioutil.ReadAll(result["dataWithSetup.json"]) + require.NoError(t, err) + t.Log(expectedHandleSummaryDataWithSetup) + t.Log(string(dataWithSetup)) + assert.JSONEq(t, expectedHandleSummaryDataWithSetup, string(dataWithSetup)) +} + func TestWrongSummaryHandlerExportTypes(t *testing.T) { t.Parallel() testCases := []string{"{}", `"foo"`, "null", "undefined", "123"} From adb4a7e91f9c68c512e902039a435fc7c95bef08 Mon Sep 17 00:00:00 2001 From: Gogs Date: Wed, 25 Aug 2021 20:58:26 +0530 Subject: [PATCH 3/8] Returning m instead of nil when error during unmarshal --- js/summary.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/js/summary.go b/js/summary.go index b9558a70ce7..d334cd14e96 100644 --- a/js/summary.go +++ b/js/summary.go @@ -116,11 +116,12 @@ func summarizeMetricsToObject(data *lib.Summary, options lib.Options, setupData metricsData[name] = metricData } m["metrics"] = metricsData - + var setupDataI interface{} if setupData != nil { if err := json.Unmarshal(setupData, &setupDataI); err != nil { - return nil + //TODO: log the error + return m } } else { setupDataI = goja.Undefined() From 7ff0af664021a9b7b0f3dc1d9b77782f26fc6ee4 Mon Sep 17 00:00:00 2001 From: Samuel Johnson R Date: Wed, 25 Aug 2021 23:26:08 +0530 Subject: [PATCH 4/8] Update js/summary_test.go Checking error before Co-authored-by: Ivan <2103732+codebien@users.noreply.github.com> --- js/summary_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/summary_test.go b/js/summary_test.go index 3869a2021dd..b2974736879 100644 --- a/js/summary_test.go +++ b/js/summary_test.go @@ -566,8 +566,8 @@ func TestRawHandleSummaryDataWithSetupData(t *testing.T) { `, ) - runner.SetSetupData([]byte("5")) require.NoError(t, err) + runner.SetSetupData([]byte("5")) summary := createTestSummary(t) result, err := runner.HandleSummary(context.Background(), summary) From c5892447d1d1fedeafda094ea3d5da4063452338 Mon Sep 17 00:00:00 2001 From: Samuel Johnson R Date: Wed, 25 Aug 2021 23:26:54 +0530 Subject: [PATCH 5/8] Update js/summary_test.go check error after the test. Co-authored-by: Ivan <2103732+codebien@users.noreply.github.com> --- js/summary_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/js/summary_test.go b/js/summary_test.go index b2974736879..1caf762317e 100644 --- a/js/summary_test.go +++ b/js/summary_test.go @@ -571,6 +571,7 @@ func TestRawHandleSummaryDataWithSetupData(t *testing.T) { summary := createTestSummary(t) result, err := runner.HandleSummary(context.Background(), summary) + require.NoError(t, err) dataWithSetup, err := ioutil.ReadAll(result["dataWithSetup.json"]) require.NoError(t, err) t.Log(expectedHandleSummaryDataWithSetup) From e8f0410d9426c010b44707cf6d523e2cd05e7e1a Mon Sep 17 00:00:00 2001 From: Gogs Date: Wed, 25 Aug 2021 23:28:45 +0530 Subject: [PATCH 6/8] Removed logs in test Reverted the newline in import --- js/summary.go | 3 ++- js/summary_test.go | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/js/summary.go b/js/summary.go index d334cd14e96..7e2a8a88d3d 100644 --- a/js/summary.go +++ b/js/summary.go @@ -25,6 +25,7 @@ import ( "fmt" "io" "time" + "encoding/json" "github.com/dop251/goja" "go.k6.io/k6/js/common" @@ -116,7 +117,7 @@ func summarizeMetricsToObject(data *lib.Summary, options lib.Options, setupData metricsData[name] = metricData } m["metrics"] = metricsData - + var setupDataI interface{} if setupData != nil { if err := json.Unmarshal(setupData, &setupDataI); err != nil { diff --git a/js/summary_test.go b/js/summary_test.go index 1caf762317e..5c1dd89fcfa 100644 --- a/js/summary_test.go +++ b/js/summary_test.go @@ -574,8 +574,6 @@ func TestRawHandleSummaryDataWithSetupData(t *testing.T) { require.NoError(t, err) dataWithSetup, err := ioutil.ReadAll(result["dataWithSetup.json"]) require.NoError(t, err) - t.Log(expectedHandleSummaryDataWithSetup) - t.Log(string(dataWithSetup)) assert.JSONEq(t, expectedHandleSummaryDataWithSetup, string(dataWithSetup)) } From 96b62c8f918a97d912a5ecccbcee13dec9b4e1e1 Mon Sep 17 00:00:00 2001 From: Gogs Date: Thu, 26 Aug 2021 23:52:59 +0530 Subject: [PATCH 7/8] Lint formatting --- js/summary.go | 4 ++-- js/summary_test.go | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/js/summary.go b/js/summary.go index 7e2a8a88d3d..9ad67ff8b09 100644 --- a/js/summary.go +++ b/js/summary.go @@ -25,7 +25,7 @@ import ( "fmt" "io" "time" - + "encoding/json" "github.com/dop251/goja" "go.k6.io/k6/js/common" @@ -122,7 +122,7 @@ func summarizeMetricsToObject(data *lib.Summary, options lib.Options, setupData if setupData != nil { if err := json.Unmarshal(setupData, &setupDataI); err != nil { //TODO: log the error - return m + return m } } else { setupDataI = goja.Undefined() diff --git a/js/summary_test.go b/js/summary_test.go index 5c1dd89fcfa..74746793bf7 100644 --- a/js/summary_test.go +++ b/js/summary_test.go @@ -564,7 +564,6 @@ func TestRawHandleSummaryDataWithSetupData(t *testing.T) { return {'dataWithSetup.json': JSON.stringify(data)}; }; `, - ) require.NoError(t, err) runner.SetSetupData([]byte("5")) From c30991094e42360f408b8b82d083b2536ddfc7c9 Mon Sep 17 00:00:00 2001 From: Gogs Date: Fri, 27 Aug 2021 00:16:46 +0530 Subject: [PATCH 8/8] Added gofumpt format (lint) --- js/summary.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/summary.go b/js/summary.go index 9ad67ff8b09..405006cbfb9 100644 --- a/js/summary.go +++ b/js/summary.go @@ -22,11 +22,11 @@ package js import ( _ "embed" // this is used to embed the contents of summary.js + "encoding/json" "fmt" "io" "time" - "encoding/json" "github.com/dop251/goja" "go.k6.io/k6/js/common" "go.k6.io/k6/lib" @@ -121,7 +121,7 @@ func summarizeMetricsToObject(data *lib.Summary, options lib.Options, setupData var setupDataI interface{} if setupData != nil { if err := json.Unmarshal(setupData, &setupDataI); err != nil { - //TODO: log the error + // TODO: log the error return m } } else {