Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package k6 for openSUSE:Factory checked in at 2026-02-18 17:09:59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/k6 (Old) and /work/SRC/openSUSE:Factory/.k6.new.1977 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "k6" Wed Feb 18 17:09:59 2026 rev:11 rq:1333654 version:1.6.1 Changes: -------- --- /work/SRC/openSUSE:Factory/k6/k6.changes 2026-02-10 21:13:37.570589124 +0100 +++ /work/SRC/openSUSE:Factory/.k6.new.1977/k6.changes 2026-02-18 17:10:34.406568688 +0100 @@ -1,0 +2,22 @@ +Mon Feb 16 12:05:12 UTC 2026 - Johannes Kastl <[email protected]> + +- Update to version 1.6.1: + * k6 v1.6.1 is here! This patch release includes: + - Bug fix for a race condition in the experimental CSV module + - Bug fix for manifest k6 version override + - Version updates for Go toolchain and Docker images + * Bug fixes + - #5632 Fixes a race condition in the experimental/csv module + when multiple files with async code use csv.parse in parallel + during initialization. + - #5642 Fixes an issue where k6 was not always added as a build + dependency, preventing manifests from overriding the k6 + version. + * Maintenance and security updates + - #5641 Adds chromium as an explicit dependency for + with-browser Docker image. + - #5646 Updates Go toolchain version to 1.24.13. + - #5654 Updates the used Go version in the Docker image to + v1.25.7. + +------------------------------------------------------------------- Old: ---- k6-1.6.0.obscpio New: ---- k6-1.6.1.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ k6.spec ++++++ --- /var/tmp/diff_new_pack.VXHpcH/_old 2026-02-18 17:10:37.802710039 +0100 +++ /var/tmp/diff_new_pack.VXHpcH/_new 2026-02-18 17:10:37.802710039 +0100 @@ -17,7 +17,7 @@ Name: k6 -Version: 1.6.0 +Version: 1.6.1 Release: 0 Summary: Modern load testing tool, using Go and JavaScript License: AGPL-3.0 @@ -26,7 +26,7 @@ Source1: vendor.tar.gz BuildRequires: bash-completion BuildRequires: fish -BuildRequires: go >= 1.23 +BuildRequires: golang(API) >= 1.24 BuildRequires: zsh # # github.com/grafana/xk6-output-prometheus-remote/pkg/remote ++++++ _service ++++++ --- /var/tmp/diff_new_pack.VXHpcH/_old 2026-02-18 17:10:37.858712370 +0100 +++ /var/tmp/diff_new_pack.VXHpcH/_new 2026-02-18 17:10:37.866712703 +0100 @@ -3,7 +3,7 @@ <param name="url">https://github.com/grafana/k6.git</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">v1.6.0</param> + <param name="revision">v1.6.1</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> <param name="changesgenerate">enable</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.VXHpcH/_old 2026-02-18 17:10:37.890713702 +0100 +++ /var/tmp/diff_new_pack.VXHpcH/_new 2026-02-18 17:10:37.898714034 +0100 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/grafana/k6.git</param> - <param name="changesrevision">d97957fc61c3d122313632f6ff2f83e54969ca8b</param></service></servicedata> + <param name="changesrevision">2ac2bb560e70b33735692642231c8bd53acbe4fd</param></service></servicedata> (No newline at EOF) ++++++ k6-1.6.0.obscpio -> k6-1.6.1.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k6-1.6.0/Dockerfile new/k6-1.6.1/Dockerfile --- old/k6-1.6.0/Dockerfile 2026-02-10 09:55:59.000000000 +0100 +++ new/k6-1.6.1/Dockerfile 2026-02-16 11:35:02.000000000 +0100 @@ -1,4 +1,4 @@ -FROM --platform=$BUILDPLATFORM golang:1.25.6-alpine@sha256:98e6cffc31ccc44c7c15d83df1d69891efee8115a5bb7ede2bf30a38af3e3c92 as builder +FROM --platform=$BUILDPLATFORM golang:1.25.7-alpine@sha256:f6751d823c26342f9506c03797d2527668d095b0a15f1862cddb4d927a7a4ced as builder WORKDIR $GOPATH/src/go.k6.io/k6 COPY . . ARG TARGETOS TARGETARCH @@ -22,7 +22,7 @@ USER root COPY --from=release /usr/bin/k6 /usr/bin/k6 -RUN apk --no-cache add chromium-swiftshader +RUN apk --no-cache add chromium chromium-swiftshader USER 12345 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k6-1.6.0/go.mod new/k6-1.6.1/go.mod --- old/k6-1.6.0/go.mod 2026-02-10 09:55:59.000000000 +0100 +++ new/k6-1.6.1/go.mod 2026-02-16 11:35:02.000000000 +0100 @@ -2,7 +2,7 @@ go 1.24.0 -toolchain go1.24.11 +toolchain go1.24.13 require ( buf.build/gen/go/prometheus/prometheus/protocolbuffers/go v1.36.11-20251118093737-4105057cc7d4.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k6-1.6.0/internal/build/version.go new/k6-1.6.1/internal/build/version.go --- old/k6-1.6.0/internal/build/version.go 2026-02-10 09:55:59.000000000 +0100 +++ new/k6-1.6.1/internal/build/version.go 2026-02-16 11:35:02.000000000 +0100 @@ -3,4 +3,4 @@ // Version contains the current version of k6 // represented using Semantic Versioning expression. -const Version = "1.6.0" +const Version = "1.6.1" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k6-1.6.0/internal/cmd/deps_test.go new/k6-1.6.1/internal/cmd/deps_test.go --- old/k6-1.6.0/internal/cmd/deps_test.go 2026-02-10 09:55:59.000000000 +0100 +++ new/k6-1.6.1/internal/cmd/deps_test.go 2026-02-16 11:35:02.000000000 +0100 @@ -19,6 +19,7 @@ testCases := []struct { name string files map[string][]byte + manifest string expectedDeps map[string]string expectCustomBuild bool expectedImports []string @@ -35,7 +36,7 @@ } `), }, - expectedDeps: map[string]string{"k6/x/foo": "*"}, + expectedDeps: map[string]string{"k6": "*", "k6/x/foo": "*"}, expectCustomBuild: true, expectedImports: []string{"/main.js", "k6/http", "k6/x/foo"}, }, @@ -49,7 +50,7 @@ } `), }, - expectedDeps: map[string]string{}, + expectedDeps: map[string]string{"k6": "*"}, expectCustomBuild: false, expectedImports: []string{"/main.js", "k6/http"}, }, @@ -75,7 +76,7 @@ } `), }, - expectedDeps: map[string]string{"k6/x/bar": "*"}, + expectedDeps: map[string]string{"k6": "*", "k6/x/bar": "*"}, expectCustomBuild: true, expectedImports: []string{"/lib/helper.js", "/main.js", "/shared/nested.js", "k6/x/bar"}, }, @@ -102,10 +103,25 @@ } `), }, - expectedDeps: map[string]string{"k6/x/alpha": ">=1.2.3", "k6/x/beta": "*"}, + expectedDeps: map[string]string{"k6": "*", "k6/x/alpha": ">=1.2.3", "k6/x/beta": "*"}, expectCustomBuild: true, expectedImports: []string{"/main.js", "/modules/util.js", "/modules/with-directive.js", "k6/x/beta"}, }, + { + name: "manifest overrides default k6 constraint without use directive", + files: map[string][]byte{ + "/main.js": []byte(`import http from "k6/http"; + +export default function () { + http.get("https://example.com"); +} +`), + }, + manifest: `{"k6": ">=1.6.0"}`, + expectedDeps: map[string]string{"k6": ">=1.6.0"}, + expectCustomBuild: false, // current k6 version satisfies >=1.6.0 + expectedImports: []string{"/main.js", "k6/http"}, + }, } for _, tc := range testCases { @@ -113,6 +129,7 @@ t.Parallel() ts := tests.NewGlobalTestState(t) ts.FS = testutils.MakeMemMapFs(t, prependCWDToFileMap(ts.Cwd, tc.files)) + ts.Flags.DependenciesManifest = tc.manifest cmd := getCmdDeps(ts.GlobalState) cmd.SetArgs([]string{"--json", "main.js"}) @@ -160,6 +177,7 @@ output := ts.Stdout.String() // Verify human-readable format require.Contains(t, output, "Build Dependencies:") + require.Contains(t, output, "k6: *") require.Contains(t, output, "k6/x/foo: *") require.Contains(t, output, "Imports:") require.Contains(t, output, "Custom Build Required:") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k6-1.6.0/internal/cmd/test_load.go new/k6-1.6.1/internal/cmd/test_load.go --- old/k6-1.6.0/internal/cmd/test_load.go 2026-02-10 09:55:59.000000000 +0100 +++ new/k6-1.6.1/internal/cmd/test_load.go 2026-02-16 11:35:02.000000000 +0100 @@ -296,6 +296,12 @@ return nil, err } + // Ensure k6 is always a dependency with "*" constraint by default. + // This can be overridden by "use k6" or "use k6 with k6/x/..." directives in the script. + if _, ok := deps["k6"]; !ok { + deps["k6"] = nil + } + if err := analyseUseContraints(imports, fileSystems, deps); err != nil { return nil, err } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k6-1.6.0/internal/cmd/tests/cmd_run_test.go new/k6-1.6.1/internal/cmd/tests/cmd_run_test.go --- old/k6-1.6.0/internal/cmd/tests/cmd_run_test.go 2026-02-10 09:55:59.000000000 +0100 +++ new/k6-1.6.1/internal/cmd/tests/cmd_run_test.go 2026-02-16 11:35:02.000000000 +0100 @@ -1086,6 +1086,63 @@ require.Contains(t, stdout, `p = 5`) } +func TestRunCSVParseConcurrentFromMultipleModules(t *testing.T) { + t.Parallel() + + csvData := `col1,col2 +a,b +c,d +` + module1Script := ` + import csv from "k6/experimental/csv"; + import fs from "k6/experimental/fs"; + + const file = await fs.open("data.csv"); + export const data = await csv.parse(file); + ` + module2Script := ` + import csv from "k6/experimental/csv"; + import fs from "k6/experimental/fs"; + + const file = await fs.open("data.csv"); + export const data = await csv.parse(file); + ` + module3Script := ` + import csv from "k6/experimental/csv"; + import fs from "k6/experimental/fs"; + + const file = await fs.open("data.csv"); + export const data = await csv.parse(file); + ` + // Main: imports all 3 modules - each has await csv.parse at top level + mainScript := ` + import { data as data1 } from "./modules/module1.js"; + import { data as data2 } from "./modules/module2.js"; + import { data as data3 } from "./modules/module3.js"; + + if (data1.length !== 3 || data2.length !== 3 || data3.length !== 3) { + throw new Error("Expected 3 records from each parse"); + } + + if (data1[0][0] !== "col1" || data2[0][0] !== "col1" || data3[0][0] !== "col1") { + throw new Error("Unexpected CSV data"); + } + export default function() { } // just to not error out + ` + + ts := NewGlobalTestState(t) + require.NoError(t, fsext.WriteFile(ts.FS, filepath.Join(ts.Cwd, "data.csv"), []byte(csvData), 0o644)) + require.NoError(t, fsext.WriteFile(ts.FS, filepath.Join(ts.Cwd, "modules/module1.js"), []byte(module1Script), 0o644)) + require.NoError(t, fsext.WriteFile(ts.FS, filepath.Join(ts.Cwd, "modules/module2.js"), []byte(module2Script), 0o644)) + require.NoError(t, fsext.WriteFile(ts.FS, filepath.Join(ts.Cwd, "modules/module3.js"), []byte(module3Script), 0o644)) + require.NoError(t, fsext.WriteFile(ts.FS, filepath.Join(ts.Cwd, "main.js"), []byte(mainScript), 0o644)) + + ts.CmdArgs = []string{"k6", "run", "--vus", "1", "--iterations", "1", "main.js"} + ts.ExpectedExitCode = 0 + + cmd.ExecuteWithGlobalState(ts.GlobalState) +} + func TestRunFromSeparateDriveWindows(t *testing.T) { t.Parallel() if runtime.GOOS != "windows" { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k6-1.6.0/internal/js/modules/k6/data/data.go new/k6-1.6.1/internal/js/modules/k6/data/data.go --- old/k6-1.6.0/internal/js/modules/k6/data/data.go 2026-02-10 09:55:59.000000000 +0100 +++ new/k6-1.6.1/internal/js/modules/k6/data/data.go 2026-02-16 11:35:02.000000000 +0100 @@ -11,6 +11,7 @@ "sync" "github.com/grafana/sobek" + "go.k6.io/k6/js/common" "go.k6.io/k6/js/modules" ) @@ -92,8 +93,12 @@ common.Throw(rt, errors.New("a function is expected as the second argument of SharedArray's constructor")) } - builder := func() sharedArray { return getSharedArrayFromCall(rt, fn) } - array := d.shared.loadOrStore(name, builder) + builder := func() (sharedArray, error) { return getSharedArrayFromCall(rt, fn) } + array, err := d.shared.loadOrStore(name, builder) + if err != nil { + common.Throw(rt, err) + } + return array.wrap(rt).ToObject(rt) } @@ -118,16 +123,16 @@ // The name argument uniquely identifies the shared array and must not be empty. // // The r argument is a [RecordReader] from which records are read and stored in the shared array. -func (d *Data) NewSharedArrayFrom(rt *sobek.Runtime, name string, r RecordReader) *sobek.Object { +func (d *Data) NewSharedArrayFrom(rt *sobek.Runtime, name string, r RecordReader) (func() *sobek.Object, error) { if name == "" { - common.Throw(rt, errors.New("empty name provided to SharedArray's constructor")) + return nil, errors.New("empty name provided to SharedArray's constructor") } // The builder function is passed to loadOrStore, which ensures it is only // executed once for a given name. This guarantees the underlying data is // initialized exactly once, even if multiple VUs call this function concurrently // with the same name. - builder := func() sharedArray { + builder := func() (sharedArray, error) { var arr []string for { record, err := r.Read() @@ -135,22 +140,28 @@ break } if err != nil { - common.Throw(rt, fmt.Errorf("failed to read record; reason: %w", err)) + return sharedArray{}, fmt.Errorf("failed to read record; reason: %w", err) } marshaled, err := json.Marshal(record) if err != nil { - common.Throw(rt, fmt.Errorf("failed to marshal record; reason: %w", err)) + return sharedArray{}, fmt.Errorf("failed to marshal record; reason: %w", err) } arr = append(arr, string(marshaled)) } - return sharedArray{arr: arr} + return sharedArray{arr: arr}, nil } - array := d.shared.loadOrStore(name, builder) - return array.wrap(rt).ToObject(rt) + array, err := d.shared.loadOrStore(name, builder) + if err != nil { + return nil, err + } + + return func() *sobek.Object { + return array.wrap(rt).ToObject(rt) + }, nil } // loadOrStore returns the shared array associated with the given name. If no array @@ -159,13 +170,13 @@ // This method is thread-safe. The builder function is guaranteed to be called at most // once for each unique name, even if multiple goroutines call loadOrStore concurrently // with the same name. -func (s *sharedArrays) loadOrStore(name string, builder func() sharedArray) sharedArray { +func (s *sharedArrays) loadOrStore(name string, builder func() (sharedArray, error)) (sharedArray, error) { // Try read-only lookup first s.mu.RLock() arr, ok := s.data[name] s.mu.RUnlock() if ok { - return arr + return arr, nil } // Not found, acquire write lock @@ -174,22 +185,25 @@ // Double-check after acquiring write lock if arr, ok = s.data[name]; ok { - return arr + return arr, nil } - arr = builder() + arr, err := builder() + if err != nil { + return arr, err + } s.data[name] = arr - return arr + return arr, nil } -func getSharedArrayFromCall(rt *sobek.Runtime, call sobek.Callable) sharedArray { +func getSharedArrayFromCall(rt *sobek.Runtime, call sobek.Callable) (sharedArray, error) { sobekValue, err := call(sobek.Undefined()) if err != nil { - common.Throw(rt, err) + return sharedArray{}, err } obj := sobekValue.ToObject(rt) if obj.ClassName() != "Array" { - common.Throw(rt, errors.New("only arrays can be made into SharedArray")) // TODO better error + return sharedArray{}, errors.New("only arrays can be made into SharedArray") // TODO better error } arr := make([]string, obj.Get("length").ToInteger()) @@ -198,10 +212,10 @@ for i := range arr { val, err = stringifyFunc(sobek.Undefined(), obj.Get(strconv.Itoa(i))) if err != nil { - panic(err) + return sharedArray{}, err } arr[i] = val.String() } - return sharedArray{arr: arr} + return sharedArray{arr: arr}, nil } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k6-1.6.0/internal/js/modules/k6/data/data_test.go new/k6-1.6.1/internal/js/modules/k6/data/data_test.go --- old/k6-1.6.0/internal/js/modules/k6/data/data_test.go 2026-02-10 09:55:59.000000000 +0100 +++ new/k6-1.6.1/internal/js/modules/k6/data/data_test.go 2026-02-16 11:35:02.000000000 +0100 @@ -23,14 +23,16 @@ {"a", "b"}, }) - dataModule.NewSharedArrayFrom(runtime.VU.Runtime(), "shared", reader) + _, err := dataModule.NewSharedArrayFrom(runtime.VU.Runtime(), "shared", reader) + require.NoError(t, err) require.Positive(t, reader.reads.Load()) anotherReader := newCountingRecordReader([][]string{ {"x", "y"}, }) - dataModule.NewSharedArrayFrom(runtime.VU.Runtime(), "shared", anotherReader) + _, err = dataModule.NewSharedArrayFrom(runtime.VU.Runtime(), "shared", anotherReader) + require.NoError(t, err) require.Zero(t, anotherReader.reads.Load()) } @@ -42,9 +44,9 @@ } var buildsCount atomic.Int32 - builder := func() sharedArray { + builder := func() (sharedArray, error) { //nolint:unparam buildsCount.Add(1) - return sharedArray{arr: []string{"v"}} + return sharedArray{arr: []string{"v"}}, nil } var wg sync.WaitGroup @@ -53,7 +55,7 @@ wg.Add(1) go func() { defer wg.Done() - arrays.loadOrStore("shared", builder) + _, _ = arrays.loadOrStore("shared", builder) }() } @@ -103,7 +105,8 @@ records: [][]string{{"a", "b"}, {"c", "d"}}, reads: &totalReads, } - dataModule.NewSharedArrayFrom(runtime.VU.Runtime(), "concurrent-test", reader) + _, err := dataModule.NewSharedArrayFrom(runtime.VU.Runtime(), "concurrent-test", reader) + require.NoError(t, err) }() } @@ -142,9 +145,8 @@ errAt: 1, // Error on second read } - require.Panics(t, func() { - dataModule.NewSharedArrayFrom(runtime.VU.Runtime(), "error-test", errReader) - }) + _, err := dataModule.NewSharedArrayFrom(runtime.VU.Runtime(), "error-test", errReader) + require.Error(t, err) } type errorRecordReader struct { @@ -175,9 +177,8 @@ // channels cannot be marshaled to JSON unmarshalableReader := &unmarshalableRecordReader{} - require.Panics(t, func() { - dataModule.NewSharedArrayFrom(runtime.VU.Runtime(), "marshal-error", unmarshalableReader) - }) + _, err := dataModule.NewSharedArrayFrom(runtime.VU.Runtime(), "marshal-error", unmarshalableReader) + require.Error(t, err) } type unmarshalableRecordReader struct { @@ -202,7 +203,10 @@ emptyReader := newCountingRecordReader([][]string{}) - result := dataModule.NewSharedArrayFrom(runtime.VU.Runtime(), "empty", emptyReader) + fn, err := dataModule.NewSharedArrayFrom(runtime.VU.Runtime(), "empty", emptyReader) + require.NoError(t, err) + require.NotNil(t, fn) + result := fn() require.NotNil(t, result) length := result.Get("length") @@ -219,8 +223,10 @@ reader1 := newCountingRecordReader([][]string{{"a"}}) reader2 := newCountingRecordReader([][]string{{"b"}}) - dataModule.NewSharedArrayFrom(runtime.VU.Runtime(), "name1", reader1) - dataModule.NewSharedArrayFrom(runtime.VU.Runtime(), "name2", reader2) + _, err := dataModule.NewSharedArrayFrom(runtime.VU.Runtime(), "name1", reader1) + require.NoError(t, err) + _, err = dataModule.NewSharedArrayFrom(runtime.VU.Runtime(), "name2", reader2) + require.NoError(t, err) // Both readers should have been consumed since names are different require.Positive(t, reader1.reads.Load()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k6-1.6.0/internal/js/modules/k6/experimental/csv/module.go new/k6-1.6.1/internal/js/modules/k6/experimental/csv/module.go --- old/k6-1.6.0/internal/js/modules/k6/experimental/csv/module.go 2026-02-10 09:55:59.000000000 +0100 +++ new/k6-1.6.1/internal/js/modules/k6/experimental/csv/module.go 2026-02-16 11:35:02.000000000 +0100 @@ -95,16 +95,13 @@ // Parse parses the provided CSV file, and returns a promise that resolves to a shared array // containing the parsed data. -func (mi *ModuleInstance) Parse(file sobek.Value, options sobek.Value) *sobek.Promise { - promise, resolve, reject := promises.New(mi.vu) - +func (mi *ModuleInstance) Parse(file sobek.Value, options sobek.Value) (*sobek.Promise, error) { rt := mi.vu.Runtime() // 1. Make sure the Sobek object is a fs.File (Sobek operation) var fileObj fs.File if err := mi.vu.Runtime().ExportTo(file, &fileObj); err != nil { - reject(fmt.Errorf("first argument expected to be a fs.File instance, got %T instead", file)) - return promise + return nil, fmt.Errorf("first argument expected to be a fs.File instance, got %T instead", file) } parserOptions := newDefaultParserOptions() @@ -112,33 +109,42 @@ var err error parserOptions, err = newParserOptionsFrom(options.ToObject(rt)) if err != nil { - reject(fmt.Errorf("failed to interpret the provided Parser options; reason: %w", err)) - return promise + return nil, fmt.Errorf("failed to interpret the provided Parser options; reason: %w", err) } } r, err := NewReaderFrom(fileObj.ReadSeekStater, parserOptions) if err != nil { - reject(fmt.Errorf("failed to create a new parser; reason: %w", err)) - return promise + return nil, fmt.Errorf("failed to create a new parser; reason: %w", err) } underlyingSharedArrayName, err := buildSharedArrayName(fileObj, parserOptions) if err != nil { - reject(fmt.Errorf("failed to derive shared array name; reason: %w", err)) - return promise + return nil, fmt.Errorf("failed to derive shared array name; reason: %w", err) } + callback := mi.vu.RegisterCallback() + promise, resolve, reject := rt.NewPromise() + go func() { // Because we rely on the data module to create the shared array, we need to // make sure that the data module is initialized before we can proceed, and that we don't instantiate // it multiple times. // // As such we hold a single instance of it in the RootModule, and we use it to create the shared array. - resolve(mi.dataModuleInstance.NewSharedArrayFrom(mi.vu.Runtime(), underlyingSharedArrayName, r)) + fn, err := mi.dataModuleInstance.NewSharedArrayFrom(mi.vu.Runtime(), underlyingSharedArrayName, r) + if err != nil { + callback(func() error { + return reject(rt.NewGoError(err)) + }) + return + } + callback(func() error { + return resolve(fn()) + }) }() - return promise + return promise, nil } // NewParser creates a new CSV parser instance. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/k6-1.6.0/internal/js/modules/k6/experimental/csv/module_test.go new/k6-1.6.1/internal/js/modules/k6/experimental/csv/module_test.go --- old/k6-1.6.0/internal/js/modules/k6/experimental/csv/module_test.go 2026-02-10 09:55:59.000000000 +0100 +++ new/k6-1.6.1/internal/js/modules/k6/experimental/csv/module_test.go 2026-02-16 11:35:02.000000000 +0100 @@ -635,6 +635,59 @@ `, testFilePath))) require.NoError(t, err) }) + + t.Run("parse with invalid first argument should fail", func(t *testing.T) { + t.Parallel() + + r, err := newConfiguredRuntime(t) + require.NoError(t, err) + + r.VU.InitEnvField.FileSystems["file"] = newTestFs(t, func(fs fsext.Fs) error { + return fsext.WriteFile(fs, testFilePath, []byte(csvTestData), 0o644) + }) + + _, err = r.RunOnEventLoop(wrapInAsyncLambda(` + try { + await csv.parse(5); + throw new Error("Expected csv.parse to reject, but it resolved"); + } catch (e) { + if (!e.message.includes("fs.File instance")) { + throw new Error("Expected error about fs.File, got: " + e.message); + } + } + `)) + + require.NoError(t, err) + }) + + t.Run("parse with asObjects and malformed CSV should fail", func(t *testing.T) { + t.Parallel() + + // CSV with header (3 cols) but row has only 2 cols - record length mismatch + malformedCSV := "a,b,c\n1,2\n" + malformedPath := fsext.FilePathSeparator + "malformed.csv" + + r, err := newConfiguredRuntime(t) + require.NoError(t, err) + + r.VU.InitEnvField.FileSystems["file"] = newTestFs(t, func(fs fsext.Fs) error { + return fsext.WriteFile(fs, malformedPath, []byte(malformedCSV), 0o644) + }) + + _, err = r.RunOnEventLoop(wrapInAsyncLambda(fmt.Sprintf(` + try { + const file = await fs.open(%q); + await csv.parse(file, { asObjects: true }); + throw new Error("Expected csv.parse to reject, but it resolved"); + } catch (e) { + if (!e.message.includes("doesn't match header length") && !e.message.includes("failed to read")) { + throw new Error("Expected error about record/header mismatch, got: " + e.message); + } + } + `, malformedPath))) + + require.NoError(t, err) + }) } func TestBuildSharedArrayNameDeterministic(t *testing.T) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' "old/k6-1.6.0/release notes/v1.6.1.md" "new/k6-1.6.1/release notes/v1.6.1.md" --- "old/k6-1.6.0/release notes/v1.6.1.md" 1970-01-01 01:00:00.000000000 +0100 +++ "new/k6-1.6.1/release notes/v1.6.1.md" 2026-02-16 11:35:02.000000000 +0100 @@ -0,0 +1,16 @@ +k6 `v1.6.1` is here! This patch release includes: + +- Bug fix for a race condition in the experimental CSV module +- Bug fix for manifest k6 version override +- Version updates for Go toolchain and Docker images + +## Bug fixes + +- [#5632](https://github.com/grafana/k6/pull/5632) Fixes a race condition in the `experimental/csv` module when multiple files with async code use `csv.parse` in parallel during initialization. +- [#5642](https://github.com/grafana/k6/pull/5642) Fixes an issue where k6 was not always added as a build dependency, preventing manifests from overriding the k6 version. + +## Maintenance and security updates + +- [#5641](https://github.com/grafana/k6/pull/5641) Adds chromium as an explicit dependency for `with-browser` Docker image. +- [#5646](https://github.com/grafana/k6/pull/5646) Updates Go toolchain version to 1.24.13. +- [#5654](https://github.com/grafana/k6/pull/5654) Updates the used Go version in the Docker image to v1.25.7. ++++++ k6.obsinfo ++++++ --- /var/tmp/diff_new_pack.VXHpcH/_old 2026-02-18 17:10:48.943173717 +0100 +++ /var/tmp/diff_new_pack.VXHpcH/_new 2026-02-18 17:10:48.991175714 +0100 @@ -1,5 +1,5 @@ name: k6 -version: 1.6.0 -mtime: 1770713759 -commit: d97957fc61c3d122313632f6ff2f83e54969ca8b +version: 1.6.1 +mtime: 1771238102 +commit: 2ac2bb560e70b33735692642231c8bd53acbe4fd ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/k6/vendor.tar.gz /work/SRC/openSUSE:Factory/.k6.new.1977/vendor.tar.gz differ: char 135, line 1
