From f4b6406cd2bea1fbdd2c84fb418a3a872014bc0c Mon Sep 17 00:00:00 2001 From: Nadia Santalla Date: Wed, 18 Feb 2026 15:21:29 +0100 Subject: [PATCH 1/2] feat: k6runner: add `Versions` function --- internal/adhoc/adhoc_test.go | 7 +++++-- internal/checks/checks_test.go | 4 ++++ internal/k6runner/http.go | 7 +++++++ internal/k6runner/k6runner.go | 7 +++++++ internal/k6runner/k6runner_test.go | 4 ++++ internal/k6runner/local.go | 7 +++++++ internal/prober/browser/browser_test.go | 4 ++++ internal/prober/multihttp/multihttp_test.go | 4 ++++ internal/prober/scripted/scripted_test.go | 4 ++++ internal/scraper/scraper_test.go | 4 ++++ 10 files changed, 50 insertions(+), 2 deletions(-) diff --git a/internal/adhoc/adhoc_test.go b/internal/adhoc/adhoc_test.go index 741487d83..6cd323d84 100644 --- a/internal/adhoc/adhoc_test.go +++ b/internal/adhoc/adhoc_test.go @@ -185,8 +185,7 @@ func (timeoutBackoff) Duration() time.Duration { func (timeoutBackoff) Reset() {} -type grpcTestConn struct { -} +type grpcTestConn struct{} func (grpcTestConn) GetState() connectivity.State { return connectivity.Ready @@ -708,3 +707,7 @@ func (r *testK6Runner) WithLogger(logger *zerolog.Logger) k6runner.Runner { func (r *testK6Runner) Run(ctx context.Context, script k6runner.Script, secretStore k6runner.SecretStore) (*k6runner.RunResponse, error) { return &k6runner.RunResponse{}, nil } + +func (*testK6Runner) Versions(_ context.Context) <-chan []string { + return nil // Blocks forever if read. +} diff --git a/internal/checks/checks_test.go b/internal/checks/checks_test.go index 9e6d8170a..b4d1879ab 100644 --- a/internal/checks/checks_test.go +++ b/internal/checks/checks_test.go @@ -537,6 +537,10 @@ func (noopRunner) Run(ctx context.Context, script k6runner.Script, secretStore k return &k6runner.RunResponse{}, nil } +func (noopRunner) Versions(_ context.Context) <-chan []string { + return nil // Blocks forever if read. +} + type testBackoff time.Duration func (b *testBackoff) Reset() { diff --git a/internal/k6runner/http.go b/internal/k6runner/http.go index dc600d439..62a9eb906 100644 --- a/internal/k6runner/http.go +++ b/internal/k6runner/http.go @@ -227,6 +227,13 @@ func (r HttpRunner) request(ctx context.Context, script Script, secretStore Secr return &response, nil } +func (r HttpRunner) Versions(_ context.Context) <-chan []string { + ch := make(chan []string) + close(ch) + + return ch +} + type HTTPMetrics struct { Requests *prometheus.CounterVec RequestsPerRun *prometheus.HistogramVec diff --git a/internal/k6runner/k6runner.go b/internal/k6runner/k6runner.go index ebe934d95..5a7e9c7b3 100644 --- a/internal/k6runner/k6runner.go +++ b/internal/k6runner/k6runner.go @@ -94,8 +94,15 @@ func (ci *CheckInfo) MarshalZerologObject(e *zerolog.Event) { var ErrNoTimeout = errors.New("check has no timeout") type Runner interface { + // WithLogger returns a copy of the runner configured to use the specified logger. WithLogger(logger *zerolog.Logger) Runner + // Run makes the runner run the script. Run(ctx context.Context, script Script, secretStore SecretStore) (*RunResponse, error) + // Versions returns a channel to which the list of versions supported by this runner are pushed. Runner + // implementations that have a predictable list of versions over time may push a single list to the channel and then + // close it, while others may push lists of versions regularly as a result of polling a decoupled system. + // Cancelling the context stops this background polling, if any. + Versions(context.Context) <-chan []string } type RunnerOpts struct { diff --git a/internal/k6runner/k6runner_test.go b/internal/k6runner/k6runner_test.go index 140f62731..12432bcc4 100644 --- a/internal/k6runner/k6runner_test.go +++ b/internal/k6runner/k6runner_test.go @@ -149,6 +149,10 @@ func (r *testRunner) WithLogger(logger *zerolog.Logger) Runner { return r } +func (*testRunner) Versions(_ context.Context) <-chan []string { + return nil // Blocks forever if read. +} + func TestTextToRegistry(t *testing.T) { data := testhelper.MustReadFile(t, "testdata/test.out") diff --git a/internal/k6runner/local.go b/internal/k6runner/local.go index d70fe1921..5d8470021 100644 --- a/internal/k6runner/local.go +++ b/internal/k6runner/local.go @@ -219,6 +219,13 @@ func (r Local) Run(ctx context.Context, script Script, secretStore SecretStore) return rr, nil } +func (r Local) Versions(_ context.Context) <-chan []string { + ch := make(chan []string) + close(ch) + + return ch +} + func (r Local) buildK6Args(script Script, metricsFn, logsFn, scriptFn, configFile string) ([]string, error) { args := []string{ "run", diff --git a/internal/prober/browser/browser_test.go b/internal/prober/browser/browser_test.go index 917afb43f..d17aa5d0a 100644 --- a/internal/prober/browser/browser_test.go +++ b/internal/prober/browser/browser_test.go @@ -83,3 +83,7 @@ func (noopRunner) WithLogger(logger *zerolog.Logger) k6runner.Runner { func (noopRunner) Run(ctx context.Context, script k6runner.Script, secretStore k6runner.SecretStore) (*k6runner.RunResponse, error) { return &k6runner.RunResponse{}, nil } + +func (noopRunner) Versions(_ context.Context) <-chan []string { + return nil // Blocks forever if read. +} diff --git a/internal/prober/multihttp/multihttp_test.go b/internal/prober/multihttp/multihttp_test.go index 85818d3bf..1124d1aef 100644 --- a/internal/prober/multihttp/multihttp_test.go +++ b/internal/prober/multihttp/multihttp_test.go @@ -158,3 +158,7 @@ func (noopRunner) WithLogger(logger *zerolog.Logger) k6runner.Runner { func (noopRunner) Run(ctx context.Context, script k6runner.Script, secretStore k6runner.SecretStore) (*k6runner.RunResponse, error) { return &k6runner.RunResponse{}, nil } + +func (noopRunner) Versions(_ context.Context) <-chan []string { + return nil // Blocks forever if read. +} diff --git a/internal/prober/scripted/scripted_test.go b/internal/prober/scripted/scripted_test.go index 8fd26d638..faca88f15 100644 --- a/internal/prober/scripted/scripted_test.go +++ b/internal/prober/scripted/scripted_test.go @@ -84,6 +84,10 @@ func (noopRunner) Run(ctx context.Context, script k6runner.Script, secretStore k return &k6runner.RunResponse{}, nil } +func (noopRunner) Versions(_ context.Context) <-chan []string { + return nil // Blocks forever if read. +} + func testContext(t *testing.T) (context.Context, func()) { if deadline, ok := t.Deadline(); ok { return context.WithDeadline(context.Background(), deadline) diff --git a/internal/scraper/scraper_test.go b/internal/scraper/scraper_test.go index 840fd9484..596257a36 100644 --- a/internal/scraper/scraper_test.go +++ b/internal/scraper/scraper_test.go @@ -1793,6 +1793,10 @@ func (r *testRunner) WithLogger(logger *zerolog.Logger) k6runner.Runner { return r } +func (*testRunner) Versions(_ context.Context) <-chan []string { + return nil // Blocks forever if read. +} + type testCounter struct { count atomic.Int32 } From cde102101000a8bfac3f30f5de62b736049d6076 Mon Sep 17 00:00:00 2001 From: Nadia Santalla Date: Thu, 19 Feb 2026 10:45:42 +0100 Subject: [PATCH 2/2] feat: k6runner/local: report versions present in k6 repository --- internal/k6runner/local.go | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/internal/k6runner/local.go b/internal/k6runner/local.go index 5d8470021..b86ceac1c 100644 --- a/internal/k6runner/local.go +++ b/internal/k6runner/local.go @@ -219,9 +219,36 @@ func (r Local) Run(ctx context.Context, script Script, secretStore SecretStore) return rr, nil } -func (r Local) Versions(_ context.Context) <-chan []string { +func (r Local) Versions(ctx context.Context) <-chan []string { ch := make(chan []string) - close(ch) + + go func() { + // The list of k6 versions in the local repository is static: We will push to the channel at most once. + defer close(ch) + + entries, err := r.repository.Entries() + if err != nil { + r.logger.Error(). + Err(err). + Str("k6Repository", r.repository.Root). + Str("k6RepositoryOverride", r.repository.Override). + Msg("Could not retrieve k6 versions from repository") + + return + } + + versions := make([]string, 0, len(entries)) + for _, e := range entries { + versions = append(versions, e.Version.String()) + } + + select { + case <-ctx.Done(): + r.logger.Error().Err(err).Msg("Aborting k6 version reporting") + + case ch <- versions: + } + }() return ch }