diff --git a/go.mod b/go.mod index 7fda9544a6c..5c9e1b11f12 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/gorilla/websocket v1.5.1 github.com/grafana/sobek v0.0.0-20240626131919-5be1e93c7efc github.com/grafana/xk6-browser v1.6.1-0.20240701105714-29f6ef3049fe - github.com/grafana/xk6-dashboard v0.7.4 + github.com/grafana/xk6-dashboard v0.7.5 github.com/grafana/xk6-output-prometheus-remote v0.4.0 github.com/grafana/xk6-redis v0.3.0 github.com/grafana/xk6-webcrypto v0.4.0 diff --git a/go.sum b/go.sum index bc848f19a66..aa3d4f0de04 100644 --- a/go.sum +++ b/go.sum @@ -86,8 +86,8 @@ github.com/grafana/sobek v0.0.0-20240626131919-5be1e93c7efc h1:4aFnXIV4UQu+5NL3Z github.com/grafana/sobek v0.0.0-20240626131919-5be1e93c7efc/go.mod h1:tUEHKWaMrxFGrMgjeAH85OEceCGQiSl6a/6Wckj/Vf4= github.com/grafana/xk6-browser v1.6.1-0.20240701105714-29f6ef3049fe h1:uE7e1Lzris7YuM5mRLulkUGBIL9WmPHvLrA2RyZLyy8= github.com/grafana/xk6-browser v1.6.1-0.20240701105714-29f6ef3049fe/go.mod h1:TNngUsbmV3I5NDVklGxjpAR2znEjYEsBtHQirGw8nAI= -github.com/grafana/xk6-dashboard v0.7.4 h1:0ZRPTAXW+6A3Xqq/a/OaIZhxUt1SOMwUFff0IPwBHrs= -github.com/grafana/xk6-dashboard v0.7.4/go.mod h1:300QyQ+OQAYz/L/AzB5tKzPeBY5eKh2wl1NsRmCbsx4= +github.com/grafana/xk6-dashboard v0.7.5 h1:TcILyffT/Ea/XD7xG1jMA5lwtusOPRbEQsQDHmO30Mk= +github.com/grafana/xk6-dashboard v0.7.5/go.mod h1:Y75F8xmgCraKT+pBzFH6me9AyH5PkXD+Bxo1dm6Il/M= github.com/grafana/xk6-output-prometheus-remote v0.4.0 h1:7k3xjuKaD9BwcX8iuu5v6PtAK1L53kvx1r8BaTUfRH4= github.com/grafana/xk6-output-prometheus-remote v0.4.0/go.mod h1:esXXthLoVp9JUdGkECRthESVYu0TQTR24wrx2nRM9ak= github.com/grafana/xk6-redis v0.3.0 h1:eV1YO0miPqGFilN8sL/3OdO6Mm+hZH2nsvJm5dkE0CM= diff --git a/vendor/github.com/grafana/xk6-dashboard/dashboard/customize.go b/vendor/github.com/grafana/xk6-dashboard/dashboard/customize.go index 78cd4e90861..e900cf69bf2 100644 --- a/vendor/github.com/grafana/xk6-dashboard/dashboard/customize.go +++ b/vendor/github.com/grafana/xk6-dashboard/dashboard/customize.go @@ -6,30 +6,14 @@ package dashboard import ( "encoding/json" - "errors" - "fmt" "io" - "path/filepath" - "reflect" - "strings" - "github.com/grafana/sobek" - "github.com/sirupsen/logrus" - "go.k6.io/k6/js/compiler" - "go.k6.io/k6/lib" "go.k6.io/k6/lib/fsext" ) -const ( - defaultConfig = ".dashboard.js" - defaultAltConfig = ".dashboard.json" -) +const defaultAltConfig = ".dashboard.json" func findDefaultConfig(fs fsext.Fs) string { - if exists(fs, defaultConfig) { - return defaultConfig - } - if exists(fs, defaultAltConfig) { return defaultAltConfig } @@ -46,11 +30,7 @@ func customize(uiConfig json.RawMessage, proc *process) (json.RawMessage, error) } } - if filepath.Ext(filename) == ".json" { - return loadConfigJSON(filename, proc) - } - - return loadConfigJS(filename, uiConfig, proc) + return loadConfigJSON(filename, proc) } func loadConfigJSON(filename string, proc *process) (json.RawMessage, error) { @@ -80,222 +60,3 @@ func exists(fs fsext.Fs, filename string) bool { return true } - -type configLoader struct { - runtime *sobek.Runtime - compiler *compiler.Compiler - defaultConfig *sobek.Object - proc *process -} - -func newConfigLoader(defaultConfig json.RawMessage, proc *process) (*configLoader, error) { - comp := compiler.New(proc.logger) - - comp.Options.CompatibilityMode = lib.CompatibilityModeExtended - comp.Options.Strict = true - - con := newConfigConsole(proc.logger) - - runtime := sobek.New() - - runtime.SetFieldNameMapper(sobek.UncapFieldNameMapper()) - - if err := runtime.Set("console", con); err != nil { - return nil, err - } - - def, err := toObject(runtime, defaultConfig) - if err != nil { - return nil, err - } - - loader := &configLoader{ - runtime: runtime, - compiler: comp, - defaultConfig: def, - proc: proc, - } - - return loader, nil -} - -func (loader *configLoader) load(filename string) (json.RawMessage, error) { - file, err := loader.proc.fs.Open(filename) - if err != nil { - return nil, err - } - - src, err := io.ReadAll(file) - if err != nil { - return nil, err - } - - val, err := loader.eval(src, filename) - if err != nil { - return nil, err - } - - obj := val.ToObject(loader.runtime) - - return obj.MarshalJSON() -} - -func isObject(val sobek.Value) bool { - return val != nil && val.ExportType() != nil && val.ExportType().Kind() == reflect.Map -} - -func (loader *configLoader) eval(src []byte, filename string) (*sobek.Object, error) { - prog, _, err := loader.compiler.Compile(string(src), filename, false) - if err != nil { - return nil, err - } - - exports := loader.runtime.NewObject() - module := loader.runtime.NewObject() - - if err = module.Set("exports", exports); err != nil { - return nil, err - } - - val, err := loader.runtime.RunProgram(prog) - if err != nil { - return nil, err - } - - call, isCallable := sobek.AssertFunction(val) - if !isCallable { - return nil, fmt.Errorf("%w, file: %s", errNotFunction, filename) - } - - _, err = call(exports, module, exports) - if err != nil { - return nil, err - } - - def := exports.Get("default") - if def == nil { - return nil, fmt.Errorf("%w, file: %s", errNoExport, filename) - } - - if call, isCallable = sobek.AssertFunction(def); isCallable { - def, err = call(exports, loader.defaultConfig) - if err != nil { - return nil, err - } - - if !isObject(def) { - return nil, errConfigNotObject - } - } - - return def.ToObject(loader.runtime), nil -} - -// toObject use JavaScript JSON.parse to create native goja object -// there could be a better solution.... (but Object.UnmarshallJSON is missing). -func toObject(runtime *sobek.Runtime, bin json.RawMessage) (*sobek.Object, error) { - val := runtime.Get("JSON").ToObject(runtime).Get("parse") - - call, _ := sobek.AssertFunction(val) - - val, err := call(runtime.GlobalObject(), runtime.ToValue(string(bin))) - if err != nil { - return nil, err - } - - return val.ToObject(runtime), nil -} - -func loadConfigJS( - filename string, - config json.RawMessage, - proc *process, -) (json.RawMessage, error) { - loader, err := newConfigLoader(config, proc) - if err != nil { - return nil, err - } - - return loader.load(filename) -} - -// configConsole represents a JS configConsole implemented as a logrus.Logger. -type configConsole struct { - logger logrus.FieldLogger -} - -// Creates a console with the standard logrus logger. -func newConfigConsole(logger logrus.FieldLogger) *configConsole { - return &configConsole{logger.WithField("source", "console").WithField("extension", "dashboard")} -} - -func (c configConsole) log(level logrus.Level, args ...sobek.Value) { - var strs strings.Builder - - for i := 0; i < len(args); i++ { - if i > 0 { - strs.WriteString(" ") - } - - strs.WriteString(c.valueString(args[i])) - } - - msg := strs.String() - - switch level { - case logrus.DebugLevel: - c.logger.Debug(msg) - - case logrus.InfoLevel: - c.logger.Info(msg) - - case logrus.WarnLevel: - c.logger.Warn(msg) - - case logrus.ErrorLevel: - c.logger.Error(msg) - - default: - c.logger.Info(msg) - } -} - -func (c configConsole) Log(args ...sobek.Value) { - c.Info(args...) -} - -func (c configConsole) Debug(args ...sobek.Value) { - c.log(logrus.DebugLevel, args...) -} - -func (c configConsole) Info(args ...sobek.Value) { - c.log(logrus.InfoLevel, args...) -} - -func (c configConsole) Warn(args ...sobek.Value) { - c.log(logrus.WarnLevel, args...) -} - -func (c configConsole) Error(args ...sobek.Value) { - c.log(logrus.ErrorLevel, args...) -} - -func (c configConsole) valueString(value sobek.Value) string { - mv, ok := value.(json.Marshaler) - if !ok { - return value.String() - } - - bin, err := json.Marshal(mv) - if err != nil { - return value.String() - } - - return string(bin) -} - -var ( - errNotFunction = errors.New("not a function") - errNoExport = errors.New("missing default export") - errConfigNotObject = errors.New("returned configuration is not an object") -) diff --git a/vendor/modules.txt b/vendor/modules.txt index 19620585ffa..e0c553b4cbf 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -186,7 +186,7 @@ github.com/grafana/xk6-browser/keyboardlayout github.com/grafana/xk6-browser/log github.com/grafana/xk6-browser/storage github.com/grafana/xk6-browser/trace -# github.com/grafana/xk6-dashboard v0.7.4 +# github.com/grafana/xk6-dashboard v0.7.5 ## explicit; go 1.20 github.com/grafana/xk6-dashboard/dashboard # github.com/grafana/xk6-output-prometheus-remote v0.4.0