From d27630f9bdc810d2a30b1de3d94131e4c0b4f559 Mon Sep 17 00:00:00 2001 From: "Marcelo E. Magallon" Date: Mon, 23 Sep 2024 17:18:58 -0600 Subject: [PATCH] Add script metadata In order for the runner to know the type of the script that it's dealing with, add a "metadata" field to the JSON representation of the request, which contains a "type" field specifying that information. Also pass check_id and tenant_id, which will allow us to identify checks causing issues. Signed-off-by: Marcelo E. Magallon --- internal/k6runner/k6runner.go | 25 ++++++++++++-- internal/k6runner/k6runner_test.go | 45 +++++++++++++++++++++++++- internal/prober/browser/browser.go | 8 +---- internal/prober/multihttp/multihttp.go | 8 +---- internal/prober/scripted/scripted.go | 8 +---- 5 files changed, 70 insertions(+), 24 deletions(-) diff --git a/internal/k6runner/k6runner.go b/internal/k6runner/k6runner.go index a7106589a..4cf8d701a 100644 --- a/internal/k6runner/k6runner.go +++ b/internal/k6runner/k6runner.go @@ -10,11 +10,13 @@ import ( "math/rand" "net/http" "os/exec" + "strconv" "strings" "time" "github.com/go-logfmt/logfmt" "github.com/grafana/synthetic-monitoring-agent/internal/prober/logger" + sm "github.com/grafana/synthetic-monitoring-agent/pkg/pb/synthetic_monitoring" "github.com/prometheus/client_golang/prometheus" dto "github.com/prometheus/client_model/go" "github.com/prometheus/common/expfmt" @@ -25,8 +27,9 @@ import ( // Script is a k6 script that a runner is able to run, with some added instructions for that runner to act on. type Script struct { - Script []byte `json:"script"` - Settings Settings `json:"settings"` + Script []byte `json:"script"` + Settings Settings `json:"settings"` + Metadata map[string]string `json:"metadata"` // TODO: Add Metadata and Features. } @@ -38,6 +41,24 @@ type Settings struct { Timeout int64 `json:"timeout"` } +// NewScript creates a new Script for the specified script, using settings and +// metadata from the provided check. +func NewScript(script []byte, check sm.Check) Script { + return Script{ + Script: script, + Settings: Settings{ + Timeout: check.Timeout, + }, + // TODO: Add metadata & features here. + Metadata: map[string]string{ + "type": check.Type().String(), + "check_id": strconv.FormatInt(check.Id, 10), + "tenant_id": strconv.FormatInt(check.TenantId, 10), + // TODO(mem): Add region ID. + }, + } +} + // ErrNoTimeout is returned by [Runner] implementations if the supplied script has a timeout of zero. var ErrNoTimeout = errors.New("check has no timeout") diff --git a/internal/k6runner/k6runner_test.go b/internal/k6runner/k6runner_test.go index 52ab98a97..7c561b959 100644 --- a/internal/k6runner/k6runner_test.go +++ b/internal/k6runner/k6runner_test.go @@ -21,6 +21,7 @@ import ( "github.com/go-logfmt/logfmt" "github.com/grafana/synthetic-monitoring-agent/internal/prober/logger" "github.com/grafana/synthetic-monitoring-agent/internal/testhelper" + sm "github.com/grafana/synthetic-monitoring-agent/pkg/pb/synthetic_monitoring" "github.com/prometheus/client_golang/prometheus" dto "github.com/prometheus/client_model/go" "github.com/prometheus/common/expfmt" @@ -47,7 +48,7 @@ func TestNew(t *testing.T) { require.IsType(t, &HttpRunner{}, r4) } -func TestNewScript(t *testing.T) { +func TestNewWithScript(t *testing.T) { runner := New(RunnerOpts{Uri: "k6"}) script := Script{ Script: []byte("test"), @@ -63,6 +64,48 @@ func TestNewScript(t *testing.T) { require.Equal(t, runner, processor.runner) } +func TestNewScript(t *testing.T) { + check := sm.Check{ + Id: 1, + TenantId: 2, + Timeout: 1000, + Settings: sm.CheckSettings{ + Scripted: &sm.ScriptedSettings{ + Script: []byte("test"), + }, + }, + } + + // Note that NewScript doesn't know how to get the script out of the + // sm.Check (because that depends on the specific type of check), so we + // are only testing that it uses the correct information from the + // provided check and that it places the script in the correct field. + + script := NewScript(check.Settings.Scripted.Script, check) + require.Equal(t, check.Settings.Scripted.Script, script.Script) + require.Equal(t, check.Timeout, script.Settings.Timeout) + require.Len(t, script.Metadata, 3) // If more metadata is added, this test needs to be updated. + require.Equal(t, check.Type().String(), script.Metadata["type"]) + require.Equal(t, strconv.FormatInt(check.Id, 10), script.Metadata["check_id"]) + require.Equal(t, strconv.FormatInt(check.TenantId, 10), script.Metadata["tenant_id"]) + + // Validate that there are no new fields by marshalling to JSON and + // unmarshalling back to map[string]interface{}. It's easier to do it + // like this instead of using reflection. + + data, err := json.Marshal(script) + require.NoError(t, err) + + var m map[string]interface{} + err = json.Unmarshal(data, &m) + require.NoError(t, err) + + require.Len(t, m, 3) // If more fields are added, this test needs to be updated. + require.Contains(t, m, "script") + require.Contains(t, m, "settings") + require.Contains(t, m, "metadata") +} + func TestScriptRun(t *testing.T) { runner := testRunner{ metrics: testhelper.MustReadFile(t, "testdata/test.out"), diff --git a/internal/prober/browser/browser.go b/internal/prober/browser/browser.go index bff751eae..5bb854665 100644 --- a/internal/prober/browser/browser.go +++ b/internal/prober/browser/browser.go @@ -35,13 +35,7 @@ func NewProber(ctx context.Context, check sm.Check, logger zerolog.Logger, runne p.module = Module{ Prober: sm.CheckTypeBrowser.String(), - Script: k6runner.Script{ - Script: check.Settings.Browser.Script, - Settings: k6runner.Settings{ - Timeout: check.Timeout, - }, - // TODO: Add metadata & features here. - }, + Script: k6runner.NewScript(check.Settings.Browser.Script, check), } processor, err := k6runner.NewProcessor(p.module.Script, runner) diff --git a/internal/prober/multihttp/multihttp.go b/internal/prober/multihttp/multihttp.go index 93970f7e0..eeddd39a1 100644 --- a/internal/prober/multihttp/multihttp.go +++ b/internal/prober/multihttp/multihttp.go @@ -50,13 +50,7 @@ func NewProber(ctx context.Context, check sm.Check, logger zerolog.Logger, runne p.module = Module{ Prober: sm.CheckTypeMultiHttp.String(), - Script: k6runner.Script{ - Script: script, - Settings: k6runner.Settings{ - Timeout: check.Timeout, - }, - // TODO: Add metadata & features here. - }, + Script: k6runner.NewScript(script, check), } processor, err := k6runner.NewProcessor(p.module.Script, runner) diff --git a/internal/prober/scripted/scripted.go b/internal/prober/scripted/scripted.go index da50456ea..eb62f2fb3 100644 --- a/internal/prober/scripted/scripted.go +++ b/internal/prober/scripted/scripted.go @@ -35,13 +35,7 @@ func NewProber(ctx context.Context, check sm.Check, logger zerolog.Logger, runne p.module = Module{ Prober: sm.CheckTypeScripted.String(), - Script: k6runner.Script{ - Script: check.Settings.Scripted.Script, - Settings: k6runner.Settings{ - Timeout: check.Timeout, - }, - // TODO: Add metadata & features here. - }, + Script: k6runner.NewScript(check.Settings.Scripted.Script, check), } processor, err := k6runner.NewProcessor(p.module.Script, runner)