From 41425783f446d47ee0ce95d5e5062d739b858878 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20SZKIBA?= Date: Wed, 16 Oct 2024 07:08:09 +0200 Subject: [PATCH 1/6] feat: create driver packages --- drivers/azuresql/register.go | 12 ++++++++++++ drivers/clickhouse/register.go | 13 +++++++++++++ drivers/drivers.go | 23 ----------------------- drivers/mysql/register.go | 13 +++++++++++++ drivers/postgres/register.go | 13 +++++++++++++ drivers/sqlite3/register.go | 13 +++++++++++++ drivers/sqlserver/register.go | 13 +++++++++++++ register.go | 9 +++++++-- 8 files changed, 84 insertions(+), 25 deletions(-) create mode 100644 drivers/azuresql/register.go create mode 100644 drivers/clickhouse/register.go delete mode 100644 drivers/drivers.go create mode 100644 drivers/mysql/register.go create mode 100644 drivers/postgres/register.go create mode 100644 drivers/sqlite3/register.go create mode 100644 drivers/sqlserver/register.go diff --git a/drivers/azuresql/register.go b/drivers/azuresql/register.go new file mode 100644 index 0000000..0e44148 --- /dev/null +++ b/drivers/azuresql/register.go @@ -0,0 +1,12 @@ +// Package azuresql contains azuresql SQL driver registration for xk6-sql. +package azuresql + +import ( + "github.com/grafana/xk6-sql/sql" + + "github.com/microsoft/go-mssqldb/azuread" +) + +func init() { + sql.RegisterModule(azuread.DriverName) +} diff --git a/drivers/clickhouse/register.go b/drivers/clickhouse/register.go new file mode 100644 index 0000000..51a08f6 --- /dev/null +++ b/drivers/clickhouse/register.go @@ -0,0 +1,13 @@ +// Package clickhouse contains ClickHouse SQL driver registration for xk6-sql. +package clickhouse + +import ( + "github.com/grafana/xk6-sql/sql" + + // Blank imports required for initialization of driver. + _ "github.com/ClickHouse/clickhouse-go/v2" +) + +func init() { + sql.RegisterModule("clickhouse") +} diff --git a/drivers/drivers.go b/drivers/drivers.go deleted file mode 100644 index f6bf280..0000000 --- a/drivers/drivers.go +++ /dev/null @@ -1,23 +0,0 @@ -// Package drivers contains SQL driver initializations. -package drivers - -import ( - "github.com/grafana/xk6-sql/sql" - - // Blank imports required for initialization of drivers - _ "github.com/ClickHouse/clickhouse-go/v2" - _ "github.com/go-sql-driver/mysql" - _ "github.com/lib/pq" - _ "github.com/mattn/go-sqlite3" - _ "github.com/microsoft/go-mssqldb" - _ "github.com/microsoft/go-mssqldb/azuread" -) - -func init() { - sql.RegisterDriver("mysql") - sql.RegisterDriver("postgres") - sql.RegisterDriver("sqlite3") - sql.RegisterDriver("sqlserver") - sql.RegisterDriver("azuresql") - sql.RegisterDriver("clickhouse") -} diff --git a/drivers/mysql/register.go b/drivers/mysql/register.go new file mode 100644 index 0000000..5d8e514 --- /dev/null +++ b/drivers/mysql/register.go @@ -0,0 +1,13 @@ +// Package mysql contains MySQL driver registration for xk6-sql. +package mysql + +import ( + "github.com/grafana/xk6-sql/sql" + + // Blank import required for initialization of driver. + _ "github.com/go-sql-driver/mysql" +) + +func init() { + sql.RegisterModule("mysql") +} diff --git a/drivers/postgres/register.go b/drivers/postgres/register.go new file mode 100644 index 0000000..bed7b8f --- /dev/null +++ b/drivers/postgres/register.go @@ -0,0 +1,13 @@ +// Package postgres contains PostgreSQL SQL driver registration for xk6-sql. +package postgres + +import ( + "github.com/grafana/xk6-sql/sql" + + // Blank import required for initialization of driver. + _ "github.com/lib/pq" +) + +func init() { + sql.RegisterModule("postgres") +} diff --git a/drivers/sqlite3/register.go b/drivers/sqlite3/register.go new file mode 100644 index 0000000..b5c0a85 --- /dev/null +++ b/drivers/sqlite3/register.go @@ -0,0 +1,13 @@ +// Package sqlite3 contains SQLite3 driver registration for xk6-sql. +package sqlite3 + +import ( + "github.com/grafana/xk6-sql/sql" + + // Blank import required for initialization of driver. + _ "github.com/mattn/go-sqlite3" +) + +func init() { + sql.RegisterModule("sqlite3") +} diff --git a/drivers/sqlserver/register.go b/drivers/sqlserver/register.go new file mode 100644 index 0000000..8434a30 --- /dev/null +++ b/drivers/sqlserver/register.go @@ -0,0 +1,13 @@ +// Package sqlserver contains Miscrosoft SQL server driver registration for xk6-sql. +package sqlserver + +import ( + "github.com/grafana/xk6-sql/sql" + + // Blank import required for initialization of driver. + _ "github.com/microsoft/go-mssqldb" +) + +func init() { + sql.RegisterModule("sqlserver") +} diff --git a/register.go b/register.go index ac52a9c..4f4fc34 100644 --- a/register.go +++ b/register.go @@ -3,8 +3,13 @@ package sql import ( - // Blank imports required for initialization of drivers - _ "github.com/grafana/xk6-sql/drivers" + // Blank imports required for initialization of drivers. + _ "github.com/grafana/xk6-sql/drivers/azuresql" + _ "github.com/grafana/xk6-sql/drivers/clickhouse" + _ "github.com/grafana/xk6-sql/drivers/mysql" + _ "github.com/grafana/xk6-sql/drivers/postgres" + _ "github.com/grafana/xk6-sql/drivers/sqlite3" + _ "github.com/grafana/xk6-sql/drivers/sqlserver" "github.com/grafana/xk6-sql/sql" "go.k6.io/k6/js/modules" From 99827692f845566622e11a1930f8e449117f6823 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20SZKIBA?= Date: Wed, 16 Oct 2024 07:08:43 +0200 Subject: [PATCH 2/6] feat: use SYmbol driver id instead of string driver name --- examples/azuresql_test.js | 3 +- examples/clickhouse_test.js | 3 +- examples/mssql_test.js | 3 +- examples/mysql_test.js | 3 +- examples/postgres_test.js | 3 +- examples/sqlite3_test.js | 5 +-- sql/drivers.go | 68 ++++++++++++++++++++++++++++++++----- sql/module.go | 10 ++++-- sql/module_test.go | 16 +++++++-- 9 files changed, 93 insertions(+), 21 deletions(-) diff --git a/examples/azuresql_test.js b/examples/azuresql_test.js index fb4c2f0..6c5eb90 100644 --- a/examples/azuresql_test.js +++ b/examples/azuresql_test.js @@ -1,8 +1,9 @@ import sql from 'k6/x/sql'; +import driver from "k6/x/sql/driver/azuresql"; // The second argument is a MS SQL connection string, e.g. // Server=127.0.0.1;Database=myDB;fedauth=ActiveDirectoryDefault; -const db = sql.open('azuresql', ''); +const db = sql.open(driver, ''); export function setup() { db.exec(`IF object_id('keyvalues') is null diff --git a/examples/clickhouse_test.js b/examples/clickhouse_test.js index ef9a87a..4a40999 100644 --- a/examples/clickhouse_test.js +++ b/examples/clickhouse_test.js @@ -1,6 +1,7 @@ import sql from 'k6/x/sql'; +import driver from "k6/x/sql/driver/clickhouse"; -const db = sql.open("clickhouse", "clickhouse://127.0.0.1:19000"); +const db = sql.open(driver, "clickhouse://127.0.0.1:19000"); export function setup() { db.exec(`CREATE TABLE IF NOT EXISTS hits_by_user_url diff --git a/examples/mssql_test.js b/examples/mssql_test.js index 8f56e77..650e739 100644 --- a/examples/mssql_test.js +++ b/examples/mssql_test.js @@ -1,8 +1,9 @@ import sql from 'k6/x/sql'; +import driver from "k6/x/sql/driver/sqlserver"; // The second argument is a MS SQL connection string, e.g. // Server=127.0.0.1;Database=myDB;User Id=myUser;Password=myPassword; -const db = sql.open('sqlserver', ''); +const db = sql.open(driver, ''); export function setup() { db.exec(`IF object_id('keyvalues') is null diff --git a/examples/mysql_test.js b/examples/mysql_test.js index 29fbac3..a6066bd 100644 --- a/examples/mysql_test.js +++ b/examples/mysql_test.js @@ -1,8 +1,9 @@ import sql from 'k6/x/sql'; +import driver from "k6/x/sql/driver/mysql"; // The second argument is a MySQL connection string, e.g. // myuser:mypass@tcp(127.0.0.1:3306)/mydb -const db = sql.open('mysql', ''); +const db = sql.open(driver, ''); export function setup() { db.exec(` diff --git a/examples/postgres_test.js b/examples/postgres_test.js index e15c359..117b46c 100644 --- a/examples/postgres_test.js +++ b/examples/postgres_test.js @@ -1,8 +1,9 @@ import sql from 'k6/x/sql'; +import driver from "k6/x/sql/driver/postgres"; // The second argument is a PostgreSQL connection string, e.g. // postgres://myuser:mypass@127.0.0.1:5432/postgres?sslmode=disable -const db = sql.open('postgres', ''); +const db = sql.open(driver, ''); export function setup() { db.exec(`CREATE TABLE IF NOT EXISTS keyvalues ( diff --git a/examples/sqlite3_test.js b/examples/sqlite3_test.js index 5521a0c..c6a437d 100644 --- a/examples/sqlite3_test.js +++ b/examples/sqlite3_test.js @@ -1,6 +1,7 @@ -import sql from 'k6/x/sql'; +import sql from "k6/x/sql"; +import driver from "k6/x/sql/driver/sqlite3"; -const db = sql.open("sqlite3", "./test.db"); +const db = sql.open(driver, "./test.db"); export function setup() { db.exec(`CREATE TABLE IF NOT EXISTS keyvalues ( diff --git a/sql/drivers.go b/sql/drivers.go index 97c3387..b91394e 100644 --- a/sql/drivers.go +++ b/sql/drivers.go @@ -2,31 +2,36 @@ package sql import ( "sync" + + "github.com/grafana/sobek" + "go.k6.io/k6/js/modules" ) type registry struct { mu sync.RWMutex - drivers map[string]struct{} + drivers map[*sobek.Symbol]struct{} } var driverRegistry *registry //nolint:gochecknoglobals func init() { driverRegistry = ®istry{ - drivers: make(map[string]struct{}), + drivers: make(map[*sobek.Symbol]struct{}), } } -func (r *registry) register(driverName string) { +func (r *registry) register(driverName string) *sobek.Symbol { r.mu.Lock() defer r.mu.Unlock() - id := driverName + id := sobek.NewSymbol(driverName) r.drivers[id] = struct{}{} + + return id } -func (r *registry) lookup(id string) (bool, string) { +func (r *registry) lookup(id *sobek.Symbol) (bool, string) { r.mu.RLock() defer r.mu.RUnlock() @@ -35,17 +40,62 @@ func (r *registry) lookup(id string) (bool, string) { return false, "" } - return true, id + return true, id.String() } // RegisterDriver registers an SQL database driver. -func RegisterDriver(driverName string) { - driverRegistry.register(driverName) +func RegisterDriver(driverName string) *sobek.Symbol { + return driverRegistry.register(driverName) +} + +// driverImportPathPrefix contains driver module's common JavaScript import path prefix. +const driverImportPathPrefix = "k6/x/sql/driver/" + +// RegisterModule registers an SQL database driver module. +// The module import path will be k6/x/sql/driver/ + driverName. +// The module's default export will be the driver id Symbol. +func RegisterModule(driverName string) modules.Module { + id := RegisterDriver(driverName) + root := &driverRootModule{driverID: id} + + modules.Register(driverImportPathPrefix+driverName, root) + + return root } // lookupDriver search SQL database driver by id in the registry. // Returns true and the driver name if the driver is registered, // otherwise returns false and an empty string. -func lookupDriver(id string) (bool, string) { +func lookupDriver(id *sobek.Symbol) (bool, string) { return driverRegistry.lookup(id) } + +// driverRootModule is the global module object type. It is instantiated once per test +// run and will be used to create `k6/x/sql/driver/XXX` module instances for each VU. +type driverRootModule struct { + driverID *sobek.Symbol +} + +var _ modules.Module = &driverRootModule{} + +// NewModuleInstance implements the modules.Module interface to return +// a new instance for each VU. +func (root *driverRootModule) NewModuleInstance(_ modules.VU) modules.Instance { + instance := &driverModule{ + exports: modules.Exports{ + Default: root.driverID, + }, + } + + return instance +} + +// module represents an instance of the JavaScript module for every VU. +type driverModule struct { + exports modules.Exports +} + +// Exports is representation of ESM exports of a module. +func (mod *driverModule) Exports() modules.Exports { + return mod.exports +} diff --git a/sql/module.go b/sql/module.go index 7aea1b3..b2cee7c 100644 --- a/sql/module.go +++ b/sql/module.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" + "github.com/grafana/sobek" "go.k6.io/k6/js/modules" ) @@ -50,8 +51,13 @@ type KeyValue map[string]interface{} // open establishes a connection to the specified database type using // the provided connection string. -func (mod *module) Open(driverName string, connectionString string) (*sql.DB, error) { - registered, database := lookupDriver(driverName) +func (mod *module) Open(driverID sobek.Value, connectionString string) (*sql.DB, error) { + driverSym, ok := driverID.(*sobek.Symbol) + if !ok { + return nil, fmt.Errorf("%w: invalid driver parameter type", errUnsupportedDatabase) + } + + registered, database := lookupDriver(driverSym) if !registered { return nil, fmt.Errorf("%w: %s", errUnsupportedDatabase, database) } diff --git a/sql/module_test.go b/sql/module_test.go index f503eb0..a0a4628 100644 --- a/sql/module_test.go +++ b/sql/module_test.go @@ -25,7 +25,7 @@ func TestIntegration(t *testing.T) { rt := setupTestEnv(t) _, err := rt.RunString(` -const db = sql.open("ramsql", "testdb"); +const db = sql.open(driver, "testdb"); db.exec("CREATE TABLE test_table (id integer PRIMARY KEY AUTOINCREMENT, name varchar NOT NULL, value varchar);") @@ -56,8 +56,6 @@ db.close() func setupTestEnv(t *testing.T) *sobek.Runtime { t.Helper() - sql.RegisterDriver("ramsql") - rt := sobek.New() rt.SetFieldNameMapper(common.FieldNameMapper{}) @@ -87,5 +85,17 @@ func setupTestEnv(t *testing.T) *sobek.Runtime { require.NoError(t, rt.Set("sql", m.Exports().Default)) + root = sql.RegisterModule("ramsql") + m = root.NewModuleInstance( + &modulestest.VU{ + RuntimeField: rt, + InitEnvField: &common.InitEnvironment{}, + CtxField: context.Background(), + StateField: state, + }, + ) + + require.NoError(t, rt.Set("driver", m.Exports().Default)) + return rt } From a0f3d74a0bee0cd934b6a5039c58fb6d857e85eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20SZKIBA?= Date: Wed, 16 Oct 2024 10:50:37 +0200 Subject: [PATCH 3/6] feat: added integration test helper function --- sql/module_test.go | 94 ++++-------------------------------------- sql/testdata/script.js | 24 +++++++++++ sqltest/sqltest.go | 48 +++++++++++++++++++++ 3 files changed, 80 insertions(+), 86 deletions(-) create mode 100644 sql/testdata/script.js create mode 100644 sqltest/sqltest.go diff --git a/sql/module_test.go b/sql/module_test.go index a0a4628..2cec5f2 100644 --- a/sql/module_test.go +++ b/sql/module_test.go @@ -1,101 +1,23 @@ package sql_test import ( - "context" - "io" + _ "embed" "testing" - "github.com/grafana/sobek" "github.com/grafana/xk6-sql/sql" - "github.com/sirupsen/logrus" - "github.com/stretchr/testify/require" - "go.k6.io/k6/js/common" - "go.k6.io/k6/js/modulestest" - "go.k6.io/k6/lib" - "go.k6.io/k6/lib/testutils" - "go.k6.io/k6/metrics" + "github.com/grafana/xk6-sql/sqltest" _ "github.com/proullon/ramsql/driver" ) -// TestIntegration performs an integration test creating an ramsql database +//go:embed testdata/script.js +var script string + +// TestIntegration performs an integration test creating a ramsql database. func TestIntegration(t *testing.T) { t.Parallel() - rt := setupTestEnv(t) - - _, err := rt.RunString(` -const db = sql.open(driver, "testdb"); - -db.exec("CREATE TABLE test_table (id integer PRIMARY KEY AUTOINCREMENT, name varchar NOT NULL, value varchar);") - -for (let i = 0; i < 5; i++) { - db.exec("INSERT INTO test_table (name, value) VALUES ('name-" + i + "', 'value-" + i + "');") -} - -let all_rows = sql.query(db, "SELECT * FROM test_table;") -if (all_rows.length != 5) { - throw new Error("Expected all five rows to be returned; got " + all_rows.length) -} - -let one_row = sql.query(db, "SELECT * FROM test_table WHERE name = $1;", "name-2"); -if (one_row.length != 1) { - throw new Error("Expected single row to be returned; got " + one_row.length) -} - -let no_rows = sql.query(db, "SELECT * FROM test_table WHERE name = $1;", 'bogus-name'); -if (no_rows.length != 0) { - throw new Error("Expected no rows to be returned; got " + no_rows.length) -} - -db.close() -`) - require.NoError(t, err) -} - -func setupTestEnv(t *testing.T) *sobek.Runtime { - t.Helper() - - rt := sobek.New() - rt.SetFieldNameMapper(common.FieldNameMapper{}) - - testLog := logrus.New() - testLog.AddHook(&testutils.SimpleLogrusHook{ - HookedLevels: []logrus.Level{logrus.WarnLevel}, - }) - testLog.SetOutput(io.Discard) - - state := &lib.State{ - Options: lib.Options{ - SystemTags: metrics.NewSystemTagSet(metrics.TagVU), - }, - Logger: testLog, - Tags: lib.NewVUStateTags(metrics.NewRegistry().RootTagSet()), - } - - root := sql.New() - m := root.NewModuleInstance( - &modulestest.VU{ - RuntimeField: rt, - InitEnvField: &common.InitEnvironment{}, - CtxField: context.Background(), - StateField: state, - }, - ) - - require.NoError(t, rt.Set("sql", m.Exports().Default)) - - root = sql.RegisterModule("ramsql") - m = root.NewModuleInstance( - &modulestest.VU{ - RuntimeField: rt, - InitEnvField: &common.InitEnvironment{}, - CtxField: context.Background(), - StateField: state, - }, - ) - - require.NoError(t, rt.Set("driver", m.Exports().Default)) + sql.RegisterModule("ramsql") - return rt + sqltest.RunScript(t, "ramsql", "testdb", script) } diff --git a/sql/testdata/script.js b/sql/testdata/script.js new file mode 100644 index 0000000..ca15c56 --- /dev/null +++ b/sql/testdata/script.js @@ -0,0 +1,24 @@ +const db = sql.open(driver, connection); + +db.exec("CREATE TABLE test_table (id integer PRIMARY KEY AUTOINCREMENT, name varchar NOT NULL, value varchar);"); + +for (let i = 0; i < 5; i++) { + db.exec("INSERT INTO test_table (name, value) VALUES ('name-" + i + "', 'value-" + i + "');"); +} + +let all_rows = sql.query(db, "SELECT * FROM test_table;"); +if (all_rows.length != 5) { + throw new Error("Expected all five rows to be returned; got " + all_rows.length); +} + +let one_row = sql.query(db, "SELECT * FROM test_table WHERE name = $1;", "name-2"); +if (one_row.length != 1) { + throw new Error("Expected single row to be returned; got " + one_row.length); +} + +let no_rows = sql.query(db, "SELECT * FROM test_table WHERE name = $1;", "bogus-name"); +if (no_rows.length != 0) { + throw new Error("Expected no rows to be returned; got " + no_rows.length); +} + +db.close(); diff --git a/sqltest/sqltest.go b/sqltest/sqltest.go new file mode 100644 index 0000000..e4aae26 --- /dev/null +++ b/sqltest/sqltest.go @@ -0,0 +1,48 @@ +// Package sqltest contains helper functions for driver integration tests of the xk6-sql extension. +package sqltest + +import ( + "testing" + + "github.com/grafana/sobek" + "github.com/grafana/xk6-sql/sql" + "github.com/stretchr/testify/require" + "go.k6.io/k6/ext" + "go.k6.io/k6/js/modules" + "go.k6.io/k6/js/modulestest" +) + +// RunScript executes JavaScript code in a specially initialized interpreter. +// The "sql" variable contains the xk6-sql module, +// the "driver" variable contains the Symbol identifying the driver, +// and the "connection" variable contains the database connection string. +func RunScript(t *testing.T, driver string, connection string, script string) sobek.Value { + t.Helper() + + runtime := modulestest.NewRuntime(t) + vu := runtime.VU + + root := sql.New() + m := root.NewModuleInstance(runtime.VU) + + require.NoError(t, vu.RuntimeField.Set("sql", m.Exports().Default)) + + jsext, found := ext.Get(ext.JSExtension)["k6/x/sql/driver/"+driver] + + require.True(t, found, "Driver extension found: "+driver) + + jsmod, ok := jsext.Module.(modules.Module) + + require.True(t, ok, "Driver extension module is JavaScript module") + + m = jsmod.NewModuleInstance(vu) + + require.NoError(t, vu.RuntimeField.Set("driver", m.Exports().Default)) + require.NoError(t, vu.RuntimeField.Set("connection", connection)) + + value, err := runtime.VU.RuntimeField.RunString(script) + + require.NoError(t, err) + + return value +} From 16d12dc50091325985f681ce96c5b0cc188515fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20SZKIBA?= Date: Wed, 16 Oct 2024 10:51:11 +0200 Subject: [PATCH 4/6] test: added Testcontainers based integration tests --- drivers/mysql/register_test.go | 30 ++++++++ drivers/mysql/testdata/script.js | 26 +++++++ drivers/postgres/register_test.go | 36 ++++++++++ drivers/postgres/testdata/script.js | 24 +++++++ go.mod | 42 ++++++++++-- go.sum | 102 ++++++++++++++++++++++++++-- 6 files changed, 252 insertions(+), 8 deletions(-) create mode 100644 drivers/mysql/register_test.go create mode 100644 drivers/mysql/testdata/script.js create mode 100644 drivers/postgres/register_test.go create mode 100644 drivers/postgres/testdata/script.js diff --git a/drivers/mysql/register_test.go b/drivers/mysql/register_test.go new file mode 100644 index 0000000..2a22be2 --- /dev/null +++ b/drivers/mysql/register_test.go @@ -0,0 +1,30 @@ +package mysql + +import ( + "context" + _ "embed" + "testing" + + "github.com/grafana/xk6-sql/sqltest" + "github.com/stretchr/testify/require" + + "github.com/testcontainers/testcontainers-go/modules/mysql" +) + +//go:embed testdata/script.js +var script string + +func TestIntegration(t *testing.T) { //nolint:paralleltest + ctx := context.Background() + + ctr, err := mysql.Run(ctx, "mysql:8.0.36") + + require.NoError(t, err) + defer func() { require.NoError(t, ctr.Terminate(ctx)) }() + + conn, err := ctr.ConnectionString(ctx) + + require.NoError(t, err) + + sqltest.RunScript(t, "mysql", conn, script) +} diff --git a/drivers/mysql/testdata/script.js b/drivers/mysql/testdata/script.js new file mode 100644 index 0000000..c42a73b --- /dev/null +++ b/drivers/mysql/testdata/script.js @@ -0,0 +1,26 @@ +const db = sql.open(driver, connection); + +db.exec( + "CREATE TABLE test_table (id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50) NOT NULL, value VARCHAR(50));" +); + +for (let i = 0; i < 5; i++) { + db.exec("INSERT INTO test_table (name, value) VALUES ('name-" + i + "', 'value-" + i + "');"); +} + +let all_rows = sql.query(db, "SELECT * FROM test_table;"); +if (all_rows.length != 5) { + throw new Error("Expected all five rows to be returned; got " + all_rows.length); +} + +let one_row = sql.query(db, "SELECT * FROM test_table WHERE name = ?;", "name-2"); +if (one_row.length != 1) { + throw new Error("Expected single row to be returned; got " + one_row.length); +} + +let no_rows = sql.query(db, "SELECT * FROM test_table WHERE name = ?;", "bogus-name"); +if (no_rows.length != 0) { + throw new Error("Expected no rows to be returned; got " + no_rows.length); +} + +db.close(); diff --git a/drivers/postgres/register_test.go b/drivers/postgres/register_test.go new file mode 100644 index 0000000..10574e2 --- /dev/null +++ b/drivers/postgres/register_test.go @@ -0,0 +1,36 @@ +package postgres + +import ( + "context" + _ "embed" + "testing" + + "github.com/grafana/xk6-sql/sqltest" + "github.com/stretchr/testify/require" + + "github.com/testcontainers/testcontainers-go" + "github.com/testcontainers/testcontainers-go/modules/postgres" + "github.com/testcontainers/testcontainers-go/wait" +) + +//go:embed testdata/script.js +var script string + +func TestIntegration(t *testing.T) { //nolint:paralleltest + ctx := context.Background() + + ctr, err := postgres.Run(ctx, "docker.io/postgres:16-alpine", + testcontainers.WithWaitStrategy( + wait.ForLog("database system is ready to accept connections"). + WithOccurrence(2)), + ) + + require.NoError(t, err) + defer func() { require.NoError(t, ctr.Terminate(ctx)) }() + + conn, err := ctr.ConnectionString(ctx, "sslmode=disable") + + require.NoError(t, err) + + sqltest.RunScript(t, "postgres", conn, script) +} diff --git a/drivers/postgres/testdata/script.js b/drivers/postgres/testdata/script.js new file mode 100644 index 0000000..01d6016 --- /dev/null +++ b/drivers/postgres/testdata/script.js @@ -0,0 +1,24 @@ +const db = sql.open(driver, connection); + +db.exec("CREATE TABLE test_table (id SERIAL PRIMARY KEY, name VARCHAR(50) NOT NULL, value VARCHAR(50));"); + +for (let i = 0; i < 5; i++) { + db.exec("INSERT INTO test_table (name, value) VALUES ('name-" + i + "', 'value-" + i + "');"); +} + +let all_rows = sql.query(db, "SELECT * FROM test_table;"); +if (all_rows.length != 5) { + throw new Error("Expected all five rows to be returned; got " + all_rows.length); +} + +let one_row = sql.query(db, "SELECT * FROM test_table WHERE name = $1;", "name-2"); +if (one_row.length != 1) { + throw new Error("Expected single row to be returned; got " + one_row.length); +} + +let no_rows = sql.query(db, "SELECT * FROM test_table WHERE name = $1;", "bogus-name"); +if (no_rows.length != 0) { + throw new Error("Expected no rows to be returned; got " + no_rows.length); +} + +db.close(); diff --git a/go.mod b/go.mod index dc63359..30184af 100644 --- a/go.mod +++ b/go.mod @@ -3,39 +3,55 @@ module github.com/grafana/xk6-sql go 1.22 require ( - github.com/go-sql-driver/mysql v1.7.1 - github.com/lib/pq v1.10.9 - github.com/mattn/go-sqlite3 v1.14.18 - github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.9.0 go.k6.io/k6 v0.54.0 ) require ( github.com/ClickHouse/clickhouse-go/v2 v2.22.0 + github.com/go-sql-driver/mysql v1.7.1 github.com/grafana/sobek v0.0.0-20240927094302-19dd311f018f + github.com/lib/pq v1.10.9 + github.com/mattn/go-sqlite3 v1.14.18 github.com/microsoft/go-mssqldb v1.6.0 github.com/proullon/ramsql v0.1.4 + github.com/testcontainers/testcontainers-go v0.33.0 + github.com/testcontainers/testcontainers-go/modules/mysql v0.33.0 + github.com/testcontainers/testcontainers-go/modules/postgres v0.33.0 ) require ( + dario.cat/mergo v1.0.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect + github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0 // indirect github.com/ClickHouse/ch-go v0.61.5 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect github.com/andybalholm/brotli v1.1.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/containerd/containerd v1.7.18 // indirect + github.com/containerd/log v0.1.0 // indirect + github.com/containerd/platforms v0.2.1 // indirect + github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/distribution/reference v0.6.0 // indirect github.com/dlclark/regexp2 v1.11.4 // indirect + github.com/docker/docker v27.1.1+incompatible // indirect + github.com/docker/go-connections v0.5.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/dop251/goja v0.0.0-20240516125602-ccbae20bcec2 // indirect github.com/evanw/esbuild v0.21.2 // indirect github.com/fatih/color v1.17.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-faster/city v1.0.1 // indirect github.com/go-faster/errors v0.7.1 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-sourcemap/sourcemap v2.1.4+incompatible // indirect + github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v5 v5.0.0 // indirect github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect @@ -45,22 +61,40 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/klauspost/compress v1.17.9 // indirect github.com/kylelemons/godebug v1.1.0 // indirect + github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/moby/docker-image-spec v1.3.1 // indirect + github.com/moby/patternmatcher v0.6.0 // indirect + github.com/moby/sys/sequential v0.5.0 // indirect + github.com/moby/sys/user v0.1.0 // indirect + github.com/moby/term v0.5.0 // indirect + github.com/morikuni/aec v1.0.0 // indirect github.com/mstoykov/atlas v0.0.0-20220811071828-388f114305dd // indirect github.com/mstoykov/k6-taskqueue-lib v0.1.0 // indirect github.com/onsi/ginkgo v1.16.5 // indirect github.com/onsi/gomega v1.27.6 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0 // indirect github.com/paulmach/orb v0.11.1 // indirect github.com/pierrec/lz4/v4 v4.1.21 // indirect github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/segmentio/asm v1.2.0 // indirect github.com/serenize/snaker v0.0.0-20201027110005-a7ad2135616e // indirect + github.com/shirou/gopsutil/v3 v3.23.12 // indirect + github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/shopspring/decimal v1.3.1 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/afero v1.11.0 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect + github.com/yusufpapurcu/wmi v1.2.3 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect go.opentelemetry.io/otel v1.29.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 // indirect diff --git a/go.sum b/go.sum index fe92ef0..4431737 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,7 @@ +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1 h1:/iHxaJhsFr0+xVFfbMr5vxz848jyiWuIEDhYq3y5odY= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 h1:vcYCAze6p19qBW7MhZybIsqD8sMV8js0NyQM8JDnVtg= @@ -8,6 +12,8 @@ github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.0 h1:yfJe15a github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.0/go.mod h1:Q28U+75mpCaSCDowNEmhIo/rmgdkqmkmzI7N6TGR4UY= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0 h1:T028gtTPiYt/RMUfs8nVsAL7FDQrfLlrm/NnRG/zcC4= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0/go.mod h1:cw4zVQgBby0Z5f2v0itn6se2dDP17nTjbZFXW5uPyHA= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0 h1:HCc0+LpPfpCKs6LGGLAhwBARt9632unrVcI6i8s/8os= github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/ClickHouse/ch-go v0.61.5 h1:zwR8QbYI0tsMiEcze/uIMK+Tz1D3XZXLdNrlaOpeEI4= @@ -16,27 +22,49 @@ github.com/ClickHouse/clickhouse-go/v2 v2.22.0 h1:LAdk0qT125PpSPnYepFQs5X5z1EwpA github.com/ClickHouse/clickhouse-go/v2 v2.22.0/go.mod h1:tBhdF3f3RdP7sS59+oBAtTyhWpy0024ZxDMhgxra0QE= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/containerd/containerd v1.7.18 h1:jqjZTQNfXGoEaZdW1WwPU0RqSn1Bm2Ay/KJPUuO8nao= +github.com/containerd/containerd v1.7.18/go.mod h1:IYEk9/IO6wAPUz2bCMVUbsfXjzw5UNP5fLz4PsUygQ4= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= +github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= +github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= +github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo= github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/docker/docker v27.1.1+incompatible h1:hO/M4MtV36kzKldqnA37IWhebRA+LnqqcqDja6kVaKY= +github.com/docker/docker v27.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= +github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dop251/goja v0.0.0-20240516125602-ccbae20bcec2 h1:OFTHt+yJDo/uaIKMGjEKzc3DGhrpQZoqvMUIloZv6ZY= github.com/dop251/goja v0.0.0-20240516125602-ccbae20bcec2/go.mod h1:o31y53rb/qiIAONF7w3FHJZRqqP3fzHUr1HqanthByw= github.com/evanw/esbuild v0.21.2 h1:CLplcGi794CfHLVmUbvVfTMKkykm+nyIHU8SU60KUTA= github.com/evanw/esbuild v0.21.2/go.mod h1:D2vIQZqV/vIf/VRHtViaUtViZmG7o+kKmlBfVQuRi48= github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= -github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw= github.com/go-faster/city v1.0.1/go.mod h1:jKcUJId49qdW3L1qKHH/3wPeUstCVpVSXTM6vO3VcTw= github.com/go-faster/errors v0.7.1 h1:MkJTnDoEdi9pDabt1dpWf7AA8/BaSYZqibYyhZ20AYg= @@ -48,11 +76,14 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-sourcemap/sourcemap v2.1.4+incompatible h1:a+iTbH5auLKxaNwQFg0B+TCYl6lbukKPc7b5x0n1s6Q= github.com/go-sourcemap/sourcemap v2.1.4+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= @@ -76,6 +107,8 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20231127191134-f3a68a39ae15 h1:t2sLhFuGXwoomaKLTuoxFfFqqlG1Gp2DpsupXq3UvZ0= @@ -93,8 +126,10 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.3.1 h1:Fcr8QJ1ZeLi5zsPZqQeUZhNhxfkkKBOgJuYkJHoBOtU= -github.com/jackc/pgx/v5 v5.3.1/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8= +github.com/jackc/pgx/v5 v5.5.4 h1:Xp2aQS8uXButQdnCMWNmvx6UysWQQC+u1EoizjguY+8= +github.com/jackc/pgx/v5 v5.5.4/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= +github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= +github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= @@ -117,6 +152,10 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -130,7 +169,19 @@ github.com/mccutchen/go-httpbin v1.1.2-0.20190116014521-c5cb2f4802fa h1:lx8ZnNPw github.com/mccutchen/go-httpbin v1.1.2-0.20190116014521-c5cb2f4802fa/go.mod h1:fhpOYavp5g2K74XDl/ao2y4KvhqVtKlkg1e+0UaQv7I= github.com/microsoft/go-mssqldb v1.6.0 h1:mM3gYdVwEPFrlg/Dvr2DNVEgYFG7L42l+dGc67NNNpc= github.com/microsoft/go-mssqldb v1.6.0/go.mod h1:00mDtPbeQCRGC1HwOOR5K/gr30P1NcEG0vx6Kbv2aJU= +github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= +github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= +github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= +github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= +github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= +github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= +github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg= +github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mstoykov/atlas v0.0.0-20220811071828-388f114305dd h1:AC3N94irbx2kWGA8f/2Ks7EQl2LxKIRQYuT9IJDwgiI= github.com/mstoykov/atlas v0.0.0-20220811071828-388f114305dd/go.mod h1:9vRHVuLCjoFfE3GT06X0spdOAO+Zzo4AMjdIwUHBvAk= github.com/mstoykov/envconfig v1.5.0 h1:E2FgWf73BQt0ddgn7aoITkQHmgwAcHup1s//MsS5/f8= @@ -148,6 +199,10 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= github.com/paulmach/orb v0.11.1 h1:3koVegMC4X/WeiXYz9iswopaTwMem53NzTJuTF20JzU= github.com/paulmach/orb v0.11.1/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU= github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY= @@ -159,6 +214,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.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= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/proullon/ramsql v0.1.4 h1:yTFRTn46gFH/kPbzCx+mGjuFlyTBUeDr3h2ldwxddl0= github.com/proullon/ramsql v0.1.4/go.mod h1:CFGqeQHQpdRfWqYmWD3yXqPTEaHkF4zgXy1C6qDWc9E= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= @@ -167,6 +224,12 @@ github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= github.com/serenize/snaker v0.0.0-20201027110005-a7ad2135616e h1:zWKUYT07mGmVBH+9UgnHXd/ekCK99C8EbDSAt5qsjXE= github.com/serenize/snaker v0.0.0-20201027110005-a7ad2135616e/go.mod h1:Yow6lPLSAXx2ifx470yD/nUe22Dv5vBvxK/UK9UUTVs= +github.com/shirou/gopsutil/v3 v3.23.12 h1:z90NtUkp3bMtmICZKpC4+WaknU1eXtp5vtbQ11DgpE4= +github.com/shirou/gopsutil/v3 v3.23.12/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM= +github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= +github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= @@ -174,21 +237,40 @@ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/testcontainers/testcontainers-go v0.33.0 h1:zJS9PfXYT5O0ZFXM2xxXfk4J5UMw/kRiISng037Gxdw= +github.com/testcontainers/testcontainers-go v0.33.0/go.mod h1:W80YpTa8D5C3Yy16icheD01UTDu+LmXIA2Keo+jWtT8= +github.com/testcontainers/testcontainers-go/modules/mysql v0.33.0 h1:1JN7YEEepTMJmGI2hW678IiiYoLM5HDp3vbCPmUokJ8= +github.com/testcontainers/testcontainers-go/modules/mysql v0.33.0/go.mod h1:9tZZwRW5s3RaI5X0Wnc+GXNJFXqbkKmob2nBHbfA/5E= +github.com/testcontainers/testcontainers-go/modules/postgres v0.33.0 h1:c+Gt+XLJjqFAejgX4hSpnHIpC9eAhvgI/TFWL/PbrFI= +github.com/testcontainers/testcontainers-go/modules/postgres v0.33.0/go.mod h1:I4DazHBoWDyf69ByOIyt3OdNjefiUx372459txOpQ3o= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= +github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.k6.io/k6 v0.54.0 h1:ajkfOD5RiNocHD01+qk4Yr+Mlnn3nY+D9x8DQyhVpck= go.k6.io/k6 v0.54.0/go.mod h1:FvmG/4rcYTMvNdi3EGYvZEr1OxINTtwTcMne8Q3bLQM= go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E= @@ -231,25 +313,35 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/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-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -304,3 +396,5 @@ gorm.io/driver/postgres v1.5.2 h1:ytTDxxEv+MplXOfFe3Lzm7SjG09fcdb3Z/c056DTBx0= gorm.io/driver/postgres v1.5.2/go.mod h1:fmpX0m2I1PKuR7mKZiEluwrP3hbs+ps7JIGMUBpCgl8= gorm.io/gorm v1.25.2 h1:gs1o6Vsa+oVKG/a9ElL3XgyGfghFfkKA2SInQaCyMho= gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= +gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= From 01fb2be45306bafe112af68cafdd838c0ef5ab1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20SZKIBA?= Date: Wed, 16 Oct 2024 11:35:27 +0200 Subject: [PATCH 5/6] test: skip Testcontainers based tests on os other than linux --- drivers/mysql/register_test.go | 9 +++++++++ drivers/postgres/register_test.go | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/drivers/mysql/register_test.go b/drivers/mysql/register_test.go index 2a22be2..35338fd 100644 --- a/drivers/mysql/register_test.go +++ b/drivers/mysql/register_test.go @@ -3,6 +3,7 @@ package mysql import ( "context" _ "embed" + "runtime" "testing" "github.com/grafana/xk6-sql/sqltest" @@ -15,6 +16,14 @@ import ( var script string func TestIntegration(t *testing.T) { //nolint:paralleltest + if testing.Short() { + t.Skip() + } + + if runtime.GOOS != "linux" { + t.Skip("Works only on Linux (Testcontainers)") + } + ctx := context.Background() ctr, err := mysql.Run(ctx, "mysql:8.0.36") diff --git a/drivers/postgres/register_test.go b/drivers/postgres/register_test.go index 10574e2..b7070ee 100644 --- a/drivers/postgres/register_test.go +++ b/drivers/postgres/register_test.go @@ -3,6 +3,7 @@ package postgres import ( "context" _ "embed" + "runtime" "testing" "github.com/grafana/xk6-sql/sqltest" @@ -17,6 +18,14 @@ import ( var script string func TestIntegration(t *testing.T) { //nolint:paralleltest + if testing.Short() { + t.Skip() + } + + if runtime.GOOS != "linux" { + t.Skip("Works only on Linux (Testcontainers)") + } + ctx := context.Background() ctr, err := postgres.Run(ctx, "docker.io/postgres:16-alpine", From e7561dacfb3ef00eb713bc01d6bc81b20c4f9674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20SZKIBA?= Date: Thu, 17 Oct 2024 07:24:53 +0200 Subject: [PATCH 6/6] test: added integration test --- drivers/sqlite3/register_test.go | 15 +++++++++++++++ drivers/sqlite3/testdata/script.js | 26 ++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 drivers/sqlite3/register_test.go create mode 100644 drivers/sqlite3/testdata/script.js diff --git a/drivers/sqlite3/register_test.go b/drivers/sqlite3/register_test.go new file mode 100644 index 0000000..4a90789 --- /dev/null +++ b/drivers/sqlite3/register_test.go @@ -0,0 +1,15 @@ +package sqlite3 + +import ( + _ "embed" + "testing" + + "github.com/grafana/xk6-sql/sqltest" +) + +//go:embed testdata/script.js +var script string + +func TestIntegration(t *testing.T) { //nolint:paralleltest + sqltest.RunScript(t, "sqlite3", "integration-test.db", script) +} diff --git a/drivers/sqlite3/testdata/script.js b/drivers/sqlite3/testdata/script.js new file mode 100644 index 0000000..d2e29cd --- /dev/null +++ b/drivers/sqlite3/testdata/script.js @@ -0,0 +1,26 @@ +const db = sql.open(driver, connection); + +db.exec( + "CREATE TABLE IF NOT EXISTS test_table (id SERIAL PRIMARY KEY, name VARCHAR(50) NOT NULL, value VARCHAR(50));DELETE FROM test_table;" +); + +for (let i = 0; i < 5; i++) { + db.exec("INSERT INTO test_table (name, value) VALUES ('name-" + i + "', 'value-" + i + "');"); +} + +let all_rows = sql.query(db, "SELECT * FROM test_table;"); +if (all_rows.length != 5) { + throw new Error("Expected all five rows to be returned; got " + all_rows.length); +} + +let one_row = sql.query(db, "SELECT * FROM test_table WHERE name = $1;", "name-2"); +if (one_row.length != 1) { + throw new Error("Expected single row to be returned; got " + one_row.length); +} + +let no_rows = sql.query(db, "SELECT * FROM test_table WHERE name = $1;", "bogus-name"); +if (no_rows.length != 0) { + throw new Error("Expected no rows to be returned; got " + no_rows.length); +} + +db.close();