Skip to content

Commit

Permalink
feat: Integrating the web dashboard feature (#3505)
Browse files Browse the repository at this point in the history
* feat: Integrating the web dashboard feature

As per our product DNA, we aim, by integrating the web dashboard (xk6-dashboard) directly into k6, to enhance and
streamline the user experience, making real-time and end-of-test visualizations immediately accessible as part of the k6
command-line experience.

* fix: linter issue

* upgrading xk6-dashboard to v0.7.0-alpha.1 pre-release

* the web dashboard is now inactive by default

* make more consistent with other outputs

* simplify web-dashboard ui output

* upgrade xk6-dashboard to v0.7.0-apha.2

* increased indent by 1 (due to "web-dashboard" length)

* test: added web dashboard CLI and env test

* log failed web dashboard test (locally runs without fail)

* test: log web dashboard test run to stdout

* fix: Excluded xk6-dashboard config.json from .gitignore

* web-dashboard output name renamed to internal-web-dashboard

* move dashboard config.json line close to the rule it is overwriting

* upgrade xk6-dashboard to v0.7.0-alpha.4

* use xk6-dashboard output name from xk6-dashboard source code

* document excluding ule

* upgrade xk6-dashboard dependency to v0.7.0-alpha.5

* hide web-dashboard flag

* Update .gitignore

Co-authored-by: Ivan <[email protected]>

* fix linter issue

* upgrade xk6-dashboard to v0.7.0-alpha.6

* upgraded xk6-dashboard to v0.7.0 release

* remove web-dashboard flag

* test: fix web-dashboard flag test

* upgrade xk6-dashboard to v0.7.1 to fix abort issue

---------

Co-authored-by: Théo Crevon <[email protected]>
Co-authored-by: Ivan <[email protected]>
  • Loading branch information
3 people authored Jan 16, 2024
1 parent d031d2b commit be8527a
Show file tree
Hide file tree
Showing 85 changed files with 6,867 additions and 12 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ script.js
/vendor/**/.editorconfig
/vendor/**/*.jpg
/vendor/**/*.json
# Excluding as it is required (embedded) configuration file for web-dashboard
!/vendor/github.com/grafana/xk6-dashboard/dashboard/assets/packages/config/dist/config.json
/vendor/**/.*.json
/vendor/**/Makefile
/vendor/**/*.png
Expand Down
4 changes: 4 additions & 0 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type Config struct {
Out []string `json:"out" envconfig:"K6_OUT"`
Linger null.Bool `json:"linger" envconfig:"K6_LINGER"`
NoUsageReport null.Bool `json:"noUsageReport" envconfig:"K6_NO_USAGE_REPORT"`
WebDashboard null.Bool `json:"webDashboard" envconfig:"K6_WEB_DASHBOARD"`

// TODO: deprecate
Collectors map[string]json.RawMessage `json:"collectors"`
Expand All @@ -67,6 +68,9 @@ func (c Config) Apply(cfg Config) Config {
if cfg.NoUsageReport.Valid {
c.NoUsageReport = cfg.NoUsageReport
}
if cfg.WebDashboard.Valid {
c.WebDashboard = cfg.WebDashboard
}
if len(cfg.Collectors) > 0 {
c.Collectors = cfg.Collectors
}
Expand Down
5 changes: 5 additions & 0 deletions cmd/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ func TestConfigEnv(t *testing.T) {
"true": func(c Config) { assert.Equal(t, null.BoolFrom(true), c.NoUsageReport) },
"false": func(c Config) { assert.Equal(t, null.BoolFrom(false), c.NoUsageReport) },
},
{"WebDashboard", "K6_WEB_DASHBOARD"}: {
"": func(c Config) { assert.Equal(t, null.Bool{}, c.WebDashboard) },
"true": func(c Config) { assert.Equal(t, null.BoolFrom(true), c.WebDashboard) },
"false": func(c Config) { assert.Equal(t, null.BoolFrom(false), c.WebDashboard) },
},
{"Out", "K6_OUT"}: {
"": func(c Config) { assert.Equal(t, []string{}, c.Out) },
"influxdb": func(c Config) { assert.Equal(t, []string{"influxdb"}, c.Out) },
Expand Down
12 changes: 10 additions & 2 deletions cmd/outputs.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"go.k6.io/k6/output/json"
"go.k6.io/k6/output/statsd"

"github.com/grafana/xk6-dashboard/dashboard"
"github.com/grafana/xk6-output-prometheus-remote/pkg/remotewrite"
)

Expand Down Expand Up @@ -61,6 +62,7 @@ func getAllOutputConstructors() (map[string]output.Constructor, error) {
builtinOutputExperimentalPrometheusRW.String(): func(params output.Params) (output.Output, error) {
return remotewrite.New(params)
},
"web-dashboard": dashboard.New,
}

exts := ext.Get(ext.OutputExtension)
Expand Down Expand Up @@ -108,9 +110,15 @@ func createOutputs(
RuntimeOptions: test.preInitState.RuntimeOptions,
ExecutionPlan: executionPlan,
}
result := make([]output.Output, 0, len(test.derivedConfig.Out))

for _, outputFullArg := range test.derivedConfig.Out {
outputs := test.derivedConfig.Out
if test.derivedConfig.WebDashboard.Bool {
outputs = append(outputs, dashboard.OutputName)
}

result := make([]output.Output, 0, len(outputs))

for _, outputFullArg := range outputs {
outputType, outputArg := parseOutputArgument(outputFullArg)
outputConstructor, ok := outputConstructors[outputType]
if !ok {
Expand Down
38 changes: 38 additions & 0 deletions cmd/tests/cmd_run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1865,6 +1865,44 @@ func TestUIRenderOutput(t *testing.T) {
}
}

func TestUIRenderWebDashboard(t *testing.T) {
t.Parallel()

tests := []struct {
env string
active bool
expRender string
}{
{expRender: "web dashboard:"},
{env: "false", expRender: "web dashboard:"},
{env: "true", active: true, expRender: "web dashboard: http://127.0.0.1:"},
}

for _, tc := range tests {
tc := tc

t.Run(tc.expRender, func(t *testing.T) {
t.Parallel()

ts := NewGlobalTestState(t)
if tc.env != "" {
ts.Env["K6_WEB_DASHBOARD"] = tc.env
}
ts.Env["K6_WEB_DASHBOARD_PORT"] = "0"
ts.CmdArgs = []string{"k6", "run", "--log-output=stdout"}
ts.CmdArgs = append(ts.CmdArgs, "-")
ts.Stdin = bytes.NewBufferString(`export default function() {};`)
cmd.ExecuteWithGlobalState(ts.GlobalState)

if tc.active {
assert.Contains(t, ts.Stdout.String(), tc.expRender)
} else {
assert.NotContains(t, ts.Stdout.String(), tc.expRender)
}
})
}
}

// TestRunStaticArchives tests that the static archives are working as expected.
// each archive contains the following files/catalogs:
// ├── a.js
Expand Down
26 changes: 16 additions & 10 deletions cmd/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"unicode/utf8"

"github.com/fatih/color"
"github.com/grafana/xk6-dashboard/dashboard"
"github.com/sirupsen/logrus"
"golang.org/x/term"

Expand Down Expand Up @@ -103,8 +104,8 @@ func printExecutionDescription(
valueColor := getColor(noColor, color.FgCyan)

buf := &strings.Builder{}
fmt.Fprintf(buf, " execution: %s\n", valueColor.Sprint(execution))
fmt.Fprintf(buf, " script: %s\n", valueColor.Sprint(filename))
fmt.Fprintf(buf, " execution: %s\n", valueColor.Sprint(execution))
fmt.Fprintf(buf, " script: %s\n", valueColor.Sprint(filename))

var outputDescriptions []string
switch {
Expand All @@ -114,18 +115,23 @@ func printExecutionDescription(
for _, out := range outputs {
desc := out.Description()
if desc == engine.IngesterDescription {
if len(outputs) != 1 {
continue
}
desc = "-"
continue
}
if strings.HasPrefix(desc, dashboard.OutputName) {
fmt.Fprintf(buf, " web dashboard:%s\n", valueColor.Sprint(strings.TrimPrefix(desc, dashboard.OutputName)))

continue
}
outputDescriptions = append(outputDescriptions, desc)
}
if len(outputDescriptions) == 0 {
outputDescriptions = append(outputDescriptions, "-")
}
}

fmt.Fprintf(buf, " output: %s\n", valueColor.Sprint(strings.Join(outputDescriptions, ", ")))
fmt.Fprintf(buf, " output: %s\n", valueColor.Sprint(strings.Join(outputDescriptions, ", ")))
if gs.Flags.ProfilingEnabled && gs.Flags.Address != "" {
fmt.Fprintf(buf, " profiling: %s\n", valueColor.Sprintf("http://%s/debug/pprof/", gs.Flags.Address))
fmt.Fprintf(buf, " profiling: %s\n", valueColor.Sprintf("http://%s/debug/pprof/", gs.Flags.Address))
}

fmt.Fprintf(buf, "\n")
Expand All @@ -138,13 +144,13 @@ func printExecutionDescription(
scenarioDesc = fmt.Sprintf("%d scenarios", len(executorConfigs))
}

fmt.Fprintf(buf, " scenarios: %s\n", valueColor.Sprintf(
fmt.Fprintf(buf, " scenarios: %s\n", valueColor.Sprintf(
"(%.2f%%) %s, %d max VUs, %s max duration (incl. graceful stop):",
conf.ExecutionSegment.FloatLength()*100, scenarioDesc,
lib.GetMaxPossibleVUs(execPlan), maxDuration.Round(100*time.Millisecond)),
)
for _, ec := range executorConfigs {
fmt.Fprintf(buf, " * %s: %s\n",
fmt.Fprintf(buf, " * %s: %s\n",
ec.GetName(), ec.GetDescription(et))
}
fmt.Fprintf(buf, "\n")
Expand Down
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require (
github.com/golang/protobuf v1.5.3
github.com/gorilla/websocket v1.5.1
github.com/grafana/xk6-browser v1.3.0
github.com/grafana/xk6-dashboard v0.7.1
github.com/grafana/xk6-output-prometheus-remote v0.3.1
github.com/grafana/xk6-redis v0.2.0
github.com/grafana/xk6-timers v0.2.3
Expand Down Expand Up @@ -78,11 +79,13 @@ require (
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.16.0 // indirect
github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.10.1 // indirect
github.com/r3labs/sse/v2 v2.10.0 // indirect
github.com/redis/go-redis/v9 v9.0.5 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
Expand All @@ -93,5 +96,6 @@ require (
golang.org/x/text v0.14.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 // indirect
gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
)
10 changes: 10 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/grafana/xk6-browser v1.3.0 h1:NFDvx56O77e4dBWFIUYQ733lzgbClcVH2Kn/yaACWjM=
github.com/grafana/xk6-browser v1.3.0/go.mod h1:Y7fN+spgo9LVLfpxWdkki1bY5EKUk+5B6xaYp4DotPA=
github.com/grafana/xk6-dashboard v0.7.1 h1:0FBJx7EpOAMsdYwKl/yKwcK+HzYpcT8j5yJ7x6nTH1U=
github.com/grafana/xk6-dashboard v0.7.1/go.mod h1:A1SIEX7kaC8RdER5J7l+bnkh54NV7chxA1VQncYBwqE=
github.com/grafana/xk6-output-prometheus-remote v0.3.1 h1:X23rQzlJD8dXWB31DkxR4uPnuRFo8L0Y0H22fSG9xl0=
github.com/grafana/xk6-output-prometheus-remote v0.3.1/go.mod h1:0JLAm4ONsNUlNoxJXAwOCfA6GtDwTPs557OplAvE+3o=
github.com/grafana/xk6-redis v0.2.0 h1:iXmAKVlAxafZ/h8ptuXTFhGu63IFsyDI8QjUgWm66BU=
Expand Down Expand Up @@ -154,6 +156,8 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/gomega v1.20.2 h1:8uQq0zMgLEfa0vRrrBgaJF2gyW9Da9BmfGV+OyUzfkY=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
Expand All @@ -166,6 +170,8 @@ github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
github.com/r3labs/sse/v2 v2.10.0 h1:hFEkLLFY4LDifoHdiCN/LlGBAdVJYsANaLqNYa1l/v0=
github.com/r3labs/sse/v2 v2.10.0/go.mod h1:Igau6Whc+F17QUgML1fYe1VPZzTV6EMCnYktEmkNJ7I=
github.com/redis/go-redis/v9 v9.0.5 h1:CuQcn5HIEeK7BgElubPP8CGtE0KakrnbBSTLjathl5o=
github.com/redis/go-redis/v9 v9.0.5/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
Expand Down Expand Up @@ -244,6 +250,7 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191116160921-f9c825593386/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
Expand All @@ -270,6 +277,7 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down Expand Up @@ -332,6 +340,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.31.1-0.20231027082548-f4a6c1f6e5c1 h1:fk72uXZyuZiTtW5tgd63jyVK6582lF61nRC/kGv6vCA=
google.golang.org/protobuf v1.31.1-0.20231027082548-f4a6c1f6e5c1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/cenkalti/backoff.v1 v1.1.0 h1:Arh75ttbsvlpVA7WtVpH4u9h6Zl46xuptxqLxPiSo4Y=
gopkg.in/cenkalti/backoff.v1 v1.1.0/go.mod h1:J6Vskwqd+OMVJl8C33mmtxTBs2gyzfv7UDAkHu8BrjI=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
Expand Down
Loading

0 comments on commit be8527a

Please sign in to comment.