Skip to content

Commit

Permalink
Pass setup data object into handleSummary callback (#2103)
Browse files Browse the repository at this point in the history
  • Loading branch information
sammieboy97 authored Aug 27, 2021
1 parent c932a28 commit 3994f1a
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 2 deletions.
2 changes: 1 addition & 1 deletion js/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
15 changes: 14 additions & 1 deletion js/summary.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package js

import (
_ "embed" // this is used to embed the contents of summary.js
"encoding/json"
"fmt"
"io"
"time"
Expand Down Expand Up @@ -79,7 +80,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{}{
Expand Down Expand Up @@ -117,6 +118,18 @@ 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 {
// TODO: log the error
return m
}
} else {
setupDataI = goja.Undefined()
}

m["setup_data"] = setupDataI

return m
}

Expand Down
144 changes: 144 additions & 0 deletions js/summary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -432,6 +550,32 @@ 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)};
};
`,
)
require.NoError(t, err)
runner.SetSetupData([]byte("5"))

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)
assert.JSONEq(t, expectedHandleSummaryDataWithSetup, string(dataWithSetup))
}

func TestWrongSummaryHandlerExportTypes(t *testing.T) {
t.Parallel()
testCases := []string{"{}", `"foo"`, "null", "undefined", "123"}
Expand Down

0 comments on commit 3994f1a

Please sign in to comment.