Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
3c162f0
fix(run): preserve pool settings for borrowed-protocol engines
Cianidos Oct 28, 2026
d5ece65
docs(changelog): link pool fix to PR 236
Cianidos Oct 28, 2026
6ad6680
fix(run): resolve pool overrides using final driver and CLI order
Cianidos Oct 28, 2026
bf16d1b
fix(ydb): allow managed endpoints a longer primary connect budget
Cianidos Oct 28, 2026
dc8b6bb
docs(changelog): link YDB timeout fix to PR 237
Cianidos Oct 28, 2026
6098ab3
fix(driver): return actual drained row counts from parallel inserts
Cianidos Oct 28, 2026
6d8f63a
docs(changelog): link insert accounting fix to PR 238
Cianidos Oct 28, 2026
f9d2cb1
fix(tpcb): permit procedures on CockroachDB and YugabyteDB
Cianidos Oct 28, 2026
5f5158f
docs(changelog): link TPC-B compatibility fix to PR 239
Cianidos Oct 28, 2026
afca125
docs(readme): use supported MySQL DSN in quick start
Cianidos Oct 28, 2026
7b190aa
docs(changelog): link MySQL README fix to PR 240
Cianidos Oct 28, 2026
03af1b4
fix(tpcc): expose explicit built-in SQL dialect selection
Cianidos Oct 28, 2026
f3730ea
docs(changelog): link embedded dialect fix to PR 241
Cianidos Oct 28, 2026
5ccf202
test(workloads): include built-in SQL dialect parameter in schema con…
Cianidos Oct 28, 2026
5d65fa2
feat(bench): warn when workers exceed effective driver pool capacity
Cianidos Oct 28, 2026
78b8cf4
docs(changelog): link pool warning to PR 242
Cianidos Oct 28, 2026
44f19d3
fix(tpcb): qualify transaction fallback guidance for unsupported drivers
Cianidos Oct 28, 2026
6a4a615
fix(tpcc): reject procedure-free SQL selections before setup
Cianidos Oct 28, 2026
5dbfe43
Merge PR #242: warn when workers exceed driver pool capacity
Cianidos Oct 30, 2026
336e7d7
Merge PR #241: expose built-in TPC-C SQL dialect selection
Cianidos Oct 30, 2026
63a5e69
Merge PR #240: fix documented MySQL connection URL
Cianidos Oct 30, 2026
4e5aca2
Merge PR #239: allow TPC-B procedures on compatible engines
Cianidos Oct 30, 2026
8de6dc4
Merge PR #238: report actual inserted row counts
Cianidos Oct 30, 2026
397639c
Merge PR #237: extend managed YDB connection budget
Cianidos Oct 30, 2026
672682d
Merge PR #236: preserve borrowed-protocol engine pool settings
Cianidos Oct 30, 2026
5a8f6cc
docs(changelog): release 6.3.0
Cianidos Oct 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,22 @@ Group lines under `Added` / `Changed` / `Fixed` / `Removed`. Append a PR link

## [Unreleased]

## [6.3.0] - 2026-10-30

### Added

- Go workloads can initialize worker-local state before measurement and use dedicated sessions with reusable prepared statements, same-session transactions, and automatic cleanup through the public SDK. ([#243](https://github.com/stroppy-io/stroppy/pull/243))
- PostgreSQL and MySQL drivers can retain dedicated sessions with explicitly prepared statements reused across transactions; recording captures session and statement lifecycle. ([#243](https://github.com/stroppy-io/stroppy/pull/243))
- Runs warn once per step and database when worker concurrency exceeds the driver's effective connection-pool limit, making possible client-side queueing visible without resizing the pool. ([#242](https://github.com/stroppy-io/stroppy/pull/242))

### Fixed

- TPC-C can select built-in dialects with `--sql-dialect`, including `crdb24` for CockroachDB 24.1 procedures, without copying SQL files to disk. ([#241](https://github.com/stroppy-io/stroppy/pull/241))
- The README MySQL quick-start command uses the connection-string format accepted by the driver. ([#240](https://github.com/stroppy-io/stroppy/pull/240))
- `tpcb/procs` accepts CockroachDB and YugabyteDB while continuing to reject engines without stored procedures. ([#239](https://github.com/stroppy-io/stroppy/pull/239))
- Insert results and `insert_rows_total` count rows actually drained by successful loaders, rather than source estimates for variable-size tables such as TPC-H lineitem. ([#238](https://github.com/stroppy-io/stroppy/pull/238))
- YDB connections allow 30 seconds for authentication, discovery, and readiness on managed endpoints, while metadata fallback remains bounded to 3 seconds. ([#237](https://github.com/stroppy-io/stroppy/pull/237))
- CockroachDB and YugabyteDB retain their pool and PostgreSQL settings, TiDB retains its pool settings, and CLI pool overrides use the selected driver's actual backend. ([#236](https://github.com/stroppy-io/stroppy/pull/236))

## [6.2.1] - 2026-10-26

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ Use `-d` to select a driver preset and `-D` to override driver options:

```bash
stroppy run tpcc/tx -d pg
stroppy run tpcc/tx -d mysql -D url=mysql://root:pass@localhost:3306/bench
stroppy run tpcc/tx -d mysql -D 'url=root:pass@tcp(localhost:3306)/bench'
stroppy run tpcc/tx -d pico
stroppy run simple -d noop # framework/runner overhead only
```
Expand Down
162 changes: 162 additions & 0 deletions cmd/stroppy/commands/run/driver_pool_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
package run

import (
"testing"

"github.com/jackc/pgx/v5"
"github.com/stretchr/testify/require"
"go.uber.org/zap"

"github.com/stroppy-io/stroppy/v6/internal/runner"
"github.com/stroppy-io/stroppy/v6/pkg/config"
"github.com/stroppy-io/stroppy/v6/pkg/driver/postgres/pool"
)

func TestPGXDriverPoolConfiguration(t *testing.T) {
for _, kind := range []string{"postgres", "picodata", "crdb", "yugabyte"} {
for _, source := range []string{"pool", "postgres", "postgres_only", "cli"} {
t.Run(kind+"/"+source, func(t *testing.T) {
mode := "exec"
maxConnections := int32(9)
minConnections := int32(2)
url := "postgres://admin:test@localhost:4327"
file := &config.DriverRunConfig{
DriverType: &kind,
URL: &url,
Pool: &config.PoolConfig{
DefaultQueryExecMode: &mode,
MaxConns: &maxConnections,
MinConns: &minConnections,
},
}
wantMode := pgx.QueryExecModeExec
wantMax := maxConnections

if source != "pool" {
overrideMode := "simple_protocol"
overrideMax := int32(7)
file.Postgres = &config.PostgresConfig{
DefaultQueryExecMode: &overrideMode,
MaxConns: &overrideMax,
}
wantMode = pgx.QueryExecModeSimpleProtocol
wantMax = overrideMax
}

if source == "postgres_only" {
file.Pool = nil
file.Postgres.MinConns = &minConnections
}

configs, err := runner.DriverCLIConfigsFromFile(map[string]*config.DriverRunConfig{"": file})
require.NoError(t, err)

if source == "cli" {
require.NoError(t, applyDriverOpt(configs, "", "pool.maxConns", "5"))

wantMax = 5
}

cfg, err := buildDriverConfig("", configs[""])
require.NoError(t, err)
require.NotNil(t, cfg.Postgres)
require.Nil(t, cfg.SQL)
parsed, err := pool.ParseConfig(cfg, zap.NewNop())
require.NoError(t, err)
require.Equal(t, wantMode, parsed.ConnConfig.DefaultQueryExecMode)
require.Equal(t, wantMax, parsed.MaxConns)
require.Equal(t, minConnections, parsed.MinConns)
})
}
}
}

func TestDriverPoolOverridesUseFinalDriver(t *testing.T) {
for _, kind := range []string{"postgres", "picodata", "crdb", "yugabyte", "mysql", "tidb", "ydb"} {
specific, field := "postgres", "maxConns"
if kind == "mysql" || kind == "tidb" || kind == "ydb" {
specific, field = "sql", "maxOpenConns"
}

for _, poolLast := range []bool{false, true} {
for _, driverLast := range []bool{false, true} {
t.Run(kind+map[bool]string{false: "/specific_last", true: "/pool_last"}[poolLast]+
map[bool]string{false: "/driver_first", true: "/driver_last"}[driverLast], func(t *testing.T) {
configs := runner.DriverCLIConfigs{}
if !driverLast {
require.NoError(t, applyDriverOpt(configs, "", "driverType", kind))
}

overrides := []runner.DriverOverride{
{Key: "pool." + field, Value: "5"},
{Key: specific + "." + field, Value: "7"},
}
want := int32(7)

if poolLast {
overrides[0], overrides[1] = overrides[1], overrides[0]
want = 5
}

for _, override := range overrides {
require.NoError(t, applyDriverOpt(configs, "", override.Key, override.Value))
}

if driverLast {
require.NoError(t, applyDriverOpt(configs, "", "driverType", kind))
}

cfg, err := buildDriverConfig("", configs[""])
require.NoError(t, err)

if specific == "postgres" {
require.Equal(t, want, cfg.Postgres.GetMaxConns())
} else {
require.Equal(t, want, cfg.SQL.GetMaxOpenConns())
}
})
}
}
}
}

func TestSQLDriverPoolConfiguration(t *testing.T) {
for _, kind := range []string{"mysql", "tidb", "ydb"} {
for _, source := range []string{"pool", "sql", "cli"} {
t.Run(kind+"/"+source, func(t *testing.T) {
maxConnections := int32(9)
idleConnections := int32(2)
file := &config.DriverRunConfig{
DriverType: &kind,
Pool: &config.PoolConfig{
MaxOpenConns: &maxConnections,
MaxIdleConns: &idleConnections,
},
}
wantMax := maxConnections

if source != "pool" {
overrideMax := int32(7)
file.SQL = &config.SQLConfig{MaxOpenConns: &overrideMax}
wantMax = overrideMax
}

configs, err := runner.DriverCLIConfigsFromFile(map[string]*config.DriverRunConfig{"": file})
require.NoError(t, err)

if source == "cli" {
require.NoError(t, applyDriverOpt(configs, "", "pool.maxOpenConns", "5"))

wantMax = 5
}

cfg, err := buildDriverConfig("", configs[""])
require.NoError(t, err)
require.NotNil(t, cfg.SQL)
require.Nil(t, cfg.Postgres)
require.Equal(t, wantMax, cfg.SQL.GetMaxOpenConns())
require.Equal(t, idleConnections, cfg.SQL.GetMaxIdleConns())
})
}
}
}
42 changes: 0 additions & 42 deletions cmd/stroppy/commands/run/picodata_pool_test.go

This file was deleted.

62 changes: 45 additions & 17 deletions cmd/stroppy/commands/run/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -1003,6 +1003,7 @@ func writeReportFile(path string, data []byte) (retErr error) {
// name ("noop"). Retained -D entries undergo strict decoding before their
// nested driver fields merge with config-file values.
func buildDriverConfig(idx string, cfg *runner.DriverCLIConfig) (*config.DriverConfig, error) {
// Validate original keys before collapsing pool aliases so duplicate options still fail.
overrides, err := cfg.DecodeOverrides()
if err != nil {
return nil, invalidConfig(fmt.Errorf("driver %s: %w", idx, err))
Expand Down Expand Up @@ -1053,6 +1054,13 @@ func buildDriverConfig(idx string, cfg *runner.DriverCLIConfig) (*config.DriverC
}

if overrides != nil {
cli := &runner.DriverCLIConfig{Overrides: driverPoolOverrides(dc.DriverType.String(), cfg.Overrides)}

overrides, err = cli.DecodeOverrides()
if err != nil {
return nil, invalidConfig(fmt.Errorf("driver %s: %w", idx, err))
}

if err := applyDriverRunConfigExtras(idx, dc, overrides); err != nil {
return nil, invalidConfig(err)
}
Expand Down Expand Up @@ -1151,12 +1159,12 @@ func applicableDriverPool(
driverType config.DriverType,
fileConfig *config.DriverRunConfig,
) *config.PoolConfig {
if driverType == config.DriverTypePostgres || driverType == config.DriverTypePicodata {
if driverUsesPGXPool(driverType) {
if fileConfig.SQL != nil {
warnIgnoredDriverExtra(
idx,
"sql",
"PostgreSQL and Picodata use pgx pool settings",
"selected driver uses pgx pool settings",
)

fileConfig.SQL = nil
Expand All @@ -1165,7 +1173,7 @@ func applicableDriverPool(
warnIgnoredDriverExtra(
idx,
"postgres",
"only PostgreSQL and Picodata use pgx pool settings",
"selected driver does not use pgx pool settings",
)

fileConfig.Postgres = nil
Expand All @@ -1184,24 +1192,26 @@ func applicableDriverPool(
return fileConfig.Pool
}

func driverSupportsPool(driverType config.DriverType) bool {
func driverUsesPGXPool(driverType config.DriverType) bool {
switch driverType {
case config.DriverTypePostgres,
config.DriverTypeMySQL,
config.DriverTypePicodata,
config.DriverTypeYDB:
case config.DriverTypePostgres, config.DriverTypePicodata, config.DriverTypeCRDB, config.DriverTypeYugabyte:
return true
default:
return false
}
}

func driverSupportsPool(driverType config.DriverType) bool {
return driverUsesPGXPool(driverType) || driverType == config.DriverTypeMySQL ||
driverType == config.DriverTypeTiDB || driverType == config.DriverTypeYDB
}

func mergePoolDriverSpecific(
driverType config.DriverType,
pool *config.PoolConfig,
driverConfig *config.DriverConfig,
) {
if driverType == config.DriverTypePostgres || driverType == config.DriverTypePicodata {
if driverUsesPGXPool(driverType) {
postgres := poolPostgresConfig(pool)
if specific := driverConfig.Postgres; specific != nil {
postgres = runner.MergePostgresConfig(postgres, specific)
Expand Down Expand Up @@ -1799,15 +1809,33 @@ func applyDriverOpt(configs runner.DriverCLIConfigs, idx, key, value string) err
configs[idx] = cfg
}

if err := cfg.ApplyOverride(key, value); err != nil {
return err
}
return cfg.ApplyOverride(key, value)
}

func driverPoolOverrides(driverType string, overrides []runner.DriverOverride) []runner.DriverOverride {
mapped := make([]runner.DriverOverride, 0, len(overrides))
for _, override := range overrides {
if specificKey := poolSpecificDriverOverride(driverType, override.Key); specificKey != "" {
override.Key = specificKey
}

found := false

for index := range mapped {
if mapped[index].Key == override.Key {
mapped[index] = override
found = true

if specificKey := poolSpecificDriverOverride(cfg.DriverType, key); specificKey != "" {
return cfg.ApplyOverride(specificKey, value)
break
}
}

if !found {
mapped = append(mapped, override)
}
}

return nil
return mapped
}

func poolSpecificDriverOverride(driverType, key string) string {
Expand All @@ -1817,7 +1845,7 @@ func poolSpecificDriverOverride(driverType, key string) string {
}

switch driverType {
case "postgres":
case "postgres", "picodata", "crdb", "yugabyte":
switch field {
case "maxConns", "minConns", "minIdleConns",
"maxConnLifetime", "maxConnIdleTime", "traceLogLevel",
Expand All @@ -1826,7 +1854,7 @@ func poolSpecificDriverOverride(driverType, key string) string {
default:
return ""
}
case "mysql", "picodata", "ydb":
case "mysql", "tidb", "ydb":
switch field {
case "maxOpenConns", "maxIdleConns", "connMaxLifetime", "connMaxIdleTime":
return "sql." + field
Expand Down
Loading
Loading