Conversation
… line SQL Server prints "SQL Server is now ready for client connections" (and "Service Broker manager has started") while the `sa` login is still being provisioned, so both driver and smoke suites could connect the moment that line appeared and fail with `ConnectionError: Login failed for user 'sa'`. Reproduced 3/3 on mcr.microsoft.com/mssql/server:2022-latest: connecting the instant the log line lands fails, a second later it succeeds. Gate readiness on the login itself instead: | Suite | Before | After | | --- | --- | --- | | `cubejs-testing-drivers` (mssql fixture) | `Wait.forLogMessage` | container HEALTHCHECK running `sqlcmd -Q "SELECT 1"` as `sa` | | `cubejs-testing-shared` `MssqlDbRunner` | `Wait.forLogMessage` | `Wait.forSuccessfulCommand` with the same `sqlcmd` probe | Verified against both `2019-latest` and `2022-latest`: the container is reported ready in ~7s and an immediate `sa` connection succeeds. The compose startup timeout is raised for mssql because the compose environment overwrites each wait strategy's own timeout with the global one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…l healthcheck Use `Wait.forSuccessfulCommand` with the same sqlcmd probe as the shared `MssqlDbRunner` instead of a compose HEALTHCHECK, so the readiness gate lives next to the wait strategy and the fixture stays a plain service definition. The raised startup timeout is no longer needed: the probe reports ready in ~8.5s (verified through a real `DockerComposeEnvironment`, with an immediate `sa` connection returning a row), well inside the 30s/60s global timeout. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Claude finished @ovr's task in 2m 42s —— View job Approach is right; 2 medium findings on the testing-shared runnerReview details
VerdictGating on the Both findings are on
Nits not posted inline: raising the startup timeout 30s → 120s quadruples time-to-fail for a container that is genuinely broken, and Not verified locally: Review threadsThe unresolved-thread listing returned 0 threads of mine (no prior threads); nothing resolved, nothing re-affirmed as a duplicate. |
…container-side `TEST_MSSQL_VERSION`/`options.version` makes the image tag configurable, and `2017-latest` ships the tools at `/opt/mssql-tools/bin`, not `/opt/mssql-tools18/bin` - the hardcoded path would have exited 127 on every retry there. Neither family puts the tools dir on `PATH` (verified in `2017-latest`, `2019-latest` and `2022-latest`), so the probe prepends both candidates and lets the shell resolve `sqlcmd`. The password is no longer interpolated into the shell string either: the probe reads `$MSSQL_SA_PASSWORD` container-side, like the testing-drivers one, so shell metacharacters in `TEST_DB_PASSWORD` cannot corrupt the credential. Verified with `TEST_DB_PASSWORD` = ``Te$t1`te"st!`` (a `$`, a backtick, a quote and a `!`): | Image tag | Tools path | Result | | --- | --- | --- | | `2017-latest` | `/opt/mssql-tools` | ready in 9.4s, immediate `sa` login OK | | `2019-latest` | `/opt/mssql-tools18` | ready in 5.9s, immediate `sa` login OK | | `2022-latest` | `/opt/mssql-tools18` | ready in 9.0s, immediate `sa` login OK | Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Claude finished @ovr's task in 3m 56s —— View job Approach is right — 2 low-severity findings (0 high, 0 medium, 2 low), both posted inlineFull review
What holds upGating on the Details that check out:
Findings
Considered and not posted: Not verified here: the Review threadsThe listing returned 2 of my own threads from the previous round; both are resolved, neither re-affirmed:
Neither was cited as a duplicate of this round's findings. |
| // TODO extract as a config | ||
| if (type === 'mssql') { | ||
| compose.withWaitStrategy('data', Wait.forLogMessage('SQL Server is now ready for client connections')); | ||
| compose.withWaitStrategy('data', Wait.forSuccessfulCommand( |
There was a problem hiding this comment.
This mssql wait strategy keeps the global compose budget set at line 118 ((isCI() ? 60 : 30) * 1000), while the companion hunk in packages/cubejs-testing-shared/src/db-container-runners/mssql.ts:19 bumped the same probe to withStartupTimeout(120 * 1000). So the two helpers now wait for the identical readiness signal with very different budgets — 30s locally / 60s in CI here vs. 120s there.
That matters because the reported ready times in this PR (9.4s for 2017-latest, 9.0s for 2022-latest on a warm image) are measured after the pull; on a cold CI runner, SQL Server routinely needs well past 60s before the sa login is accepted, and the failure mode is a compose-wide startup timeout rather than the old log-line wait, which shared the same budget but tripped earlier on a weaker signal.
Other slow services in this same block already opt out of the global budget per strategy — oracle (line 171, 240s), pinot (line 176, 180s), crate (line 195, 120s) — so the mechanism is right here:
| compose.withWaitStrategy('data', Wait.forSuccessfulCommand( | |
| compose.withWaitStrategy('data', Wait.forSuccessfulCommand( |
(and append .withStartupTimeout(120 * 1000) to the strategy on the closing line, matching the shared runner)
If the intent was instead that mssql is fast enough for the global budget, the 120s in the shared runner is the one that wants explaining — either way the asymmetry looks unintentional.
| .withWaitStrategy(Wait.forLogMessage(logMsg)) | ||
| .withStartupTimeout(30 * 1000); | ||
| .withWaitStrategy(Wait.forSuccessfulCommand( | ||
| 'PATH=/opt/mssql-tools18/bin:/opt/mssql-tools/bin:$PATH sqlcmd -C -S localhost -U sa -P "$MSSQL_SA_PASSWORD" -Q "SELECT 1" -b -o /dev/null' |
There was a problem hiding this comment.
This probe string is now duplicated verbatim in packages/cubejs-testing-drivers/src/helpers/runEnvironment.ts:159 — same PATH prefix, same flags, same $MSSQL_SA_PASSWORD indirection. Both copies encode three separate pieces of knowledge that were fixed together in 2dcc6bc (the two candidate tools dirs, -C for the self-signed cert, and reading the password container-side), so any future change — a fourth tools path for a new image family, dropping -o /dev/null, switching to sqlcmd -No — has to be found and applied twice, and a miss is silent: the divergent copy just times out.
cubejs-testing-drivers already depends on @cubejs-backend/testing-shared, and runEnvironment.ts imports from it, so exporting the string from here and importing it there costs nothing:
| 'PATH=/opt/mssql-tools18/bin:/opt/mssql-tools/bin:$PATH sqlcmd -C -S localhost -U sa -P "$MSSQL_SA_PASSWORD" -Q "SELECT 1" -b -o /dev/null' | |
| .withWaitStrategy(Wait.forSuccessfulCommand(MSSQL_READY_COMMAND)) |
with export const MSSQL_READY_COMMAND = 'PATH=/opt/mssql-tools18/bin:/opt/mssql-tools/bin:$PATH sqlcmd -C -S localhost -U sa -P "$MSSQL_SA_PASSWORD" -Q "SELECT 1" -b -o /dev/null'; above the class (and re-exported from the package index), then using it at the runEnvironment.ts call site.
Codecov Report✅ All modified and coverable lines are covered by tests.
Additional details and impacted files@@ Coverage Diff @@
## master #11917 +/- ##
===========================================
- Coverage 84.88% 60.69% -24.20%
===========================================
Files 261 247 -14
Lines 87535 19763 -67772
Branches 0 4027 +4027
===========================================
- Hits 74306 11995 -62311
+ Misses 13229 7203 -6026
- Partials 0 565 +565
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Check List
Description of Changes Made
The
tests (mssql, *)drivers-tests jobs fail intermittently withConnectionError: Login failed for user 'sa', because both MSSQL container helpers waited on a startup log line (SQL Server is now ready for client connections/Service Broker manager has started) that SQL Server prints before thesalogin fromMSSQL_SA_PASSWORDis usable — reproduced 3/3 onmcr.microsoft.com/mssql/server:2022-latest, where connecting the instant that line lands fails and the same login succeeds a second later. Bothcubejs-testing-drivers(runEnvironment) andcubejs-testing-shared(MssqlDbRunner) now wait onWait.forSuccessfulCommandrunningsqlcmd -Q "SELECT 1"assa, i.e. on the login itself. Verified against2019-latestand2022-latest(both ship/opt/mssql-tools18, and the older v17mssql-toolspath is gone) and through a realDockerComposeEnvironmentusing the mssql fixture'sdataservice: ready in ~7-8.5s with an immediatesaconnection returning a row, well inside the existing 30s/60s compose startup timeout. The fullmssql-fullsuite was not run locally since it needs thecubejs/cube:testing-driversimage, so please let CI exercise it.🤖 Generated with Claude Code