diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 41cd1cd9..9f64475a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -96,7 +96,6 @@ jobs: env: WORKERD_COMPAT_DATE: ${{ matrix.compat_date }} WORKERD_COMPAT_FLAGS: ${{ matrix.flags }} - WORKERD_KNOWN_FAILURES: ${{ matrix.known_failures }} WORKERD_CLOSE_REJECTIONS: ${{ matrix.close_rejections }} WORKERD_TLS_PORT: 55433 WORKERD_TLS_CA: ${{ runner.temp }}/server.crt diff --git a/.github/workflows/workerd-edge-cleanup.yml b/.github/workflows/workerd-edge-cleanup.yml index 09da2066..e3eea365 100644 --- a/.github/workflows/workerd-edge-cleanup.yml +++ b/.github/workflows/workerd-edge-cleanup.yml @@ -14,14 +14,10 @@ concurrency: jobs: cleanup: - name: Delete the edge Previews (${{ matrix.compat_date }}) + name: Delete the edge Preview if: github.event.pull_request.head.repo.full_name == github.repository runs-on: ubuntu-24.04 timeout-minutes: 5 - strategy: - fail-fast: false - matrix: - compat_date: ['2025-01-01', '2026-10-12'] env: CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} @@ -29,5 +25,4 @@ jobs: - name: Delete the Preview env: PR_NUMBER: ${{ github.event.pull_request.number }} - COMPAT_DATE: ${{ matrix.compat_date }} - run: npx --yes wrangler@4.151.1 preview delete --worker-name postgresjs-edge --name "pr-$PR_NUMBER-${COMPAT_DATE//-/}" --skip-confirmation + run: npx --yes wrangler@4.151.1 preview delete --worker-name postgresjs-edge --name "pr-$PR_NUMBER" --skip-confirmation diff --git a/.github/workflows/workerd-edge.yml b/.github/workflows/workerd-edge.yml index 75385d39..ac419802 100644 --- a/.github/workflows/workerd-edge.yml +++ b/.github/workflows/workerd-edge.yml @@ -4,10 +4,6 @@ on: pull_request: paths-ignore: ['**/*.md', 'codemod/**', '.github/workflows/codemod.yml'] workflow_dispatch: - inputs: - hyperdrive_rounds: - description: Hyperdrive rounds per build - default: '1' push: branches: [main] tags: ['v*'] @@ -22,18 +18,13 @@ concurrency: jobs: edge: - name: Cloudflare edge Preview (${{ matrix.compat_date }}) on Neon and Supabase + name: Cloudflare edge Preview on Neon and Supabase if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository runs-on: ubuntu-24.04 timeout-minutes: 15 - strategy: - fail-fast: false - matrix: - compat_date: ['2025-01-01', '2026-10-12'] env: CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - EDGE_HYPERDRIVE_ROUNDS: ${{ inputs.hyperdrive_rounds || '1' }} steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 @@ -41,17 +32,15 @@ jobs: node-version: '24' - run: npx --yes wrangler@4.151.1 whoami - run: npm run build:cf - - run: node tests-startup/workerd-edge.mjs prepare "$RUNNER_TEMP/edge" "${{ matrix.compat_date }}" + - run: node tests-startup/workerd-edge.mjs prepare "$RUNNER_TEMP/edge" 2026-10-12 - name: Deploy the Preview and run the scenarios env: NEON_DATABASE_URL: ${{ secrets.NEON_DATABASE_URL }} NEON_POOLED_URL: ${{ secrets.NEON_POOLED_URL }} SUPABASE_DATABASE_URL: ${{ secrets.SUPABASE_DATABASE_URL }} PR_NUMBER: ${{ github.event.pull_request.number }} - COMPAT_DATE: ${{ matrix.compat_date }} run: | - base=$([ -n "$PR_NUMBER" ] && echo "pr-$PR_NUMBER" || echo "$GITHUB_REF_NAME" | tr 'A-Z._/' 'a-z---') - name="$base-${COMPAT_DATE//-/}" + name=$([ -n "$PR_NUMBER" ] && echo "pr-$PR_NUMBER" || echo "$GITHUB_REF_NAME" | tr 'A-Z._/' 'a-z---') EDGE_TOKEN=$(openssl rand -hex 24) echo "::add-mask::$EDGE_TOKEN" export EDGE_TOKEN diff --git a/docs/api.md b/docs/api.md index f1a3da73..3f36a330 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1275,7 +1275,7 @@ On Cloudflare Workers the package connects through Cloudflare's [`cloudflare:soc compatibility_flags = ["nodejs_compat"] ``` -CI runs the Workers scenarios at compatibility dates 2025-01-01 (with and without `unhandled_rejection_after_microtask_checkpoint`), 2025-09-15 and 2026-10-12 in local workerd, and on Cloudflare's network against Neon, directly, through its pooler and through Hyperdrive, and against Supabase through Hyperdrive. +CI runs the Workers scenarios at compatibility dates 2025-01-01 (with and without `unhandled_rejection_after_microtask_checkpoint`), 2025-09-15 and 2026-10-12 in local workerd. On Cloudflare's network, at 2026-10-12, it runs the ones that depend on the network: verified TLS, a private certificate authority, transactions through poolers, Hyperdrive and a client left open, against Neon directly, through its pooler and through Hyperdrive, and against Supabase through its pooler and through Hyperdrive. On compatibility dates before 2026-03-03, workerd can report a rejection as unhandled before the code awaiting it has handled it ([cloudflare/workerd#6020](https://github.com/cloudflare/workerd/issues/6020)). Closing a socket rejects the read the driver always has pending, so each closed connection logs `Stream was cancelled.` or `This socket has been closed.` as an unhandled rejection on those dates, whether `sql.end()` closed it, a timeout did, or the request finished with the client still open. A connection the network or a pooler such as Hyperdrive drops logs the socket error instead, such as `Network connection lost.`, with the stack of the query it failed. The driver handles it, and queries and their errors are unaffected. `sql.end()` sends Terminate and closes at once rather than waiting a round trip for the server to close first, so the log line is the cost of a fast `end()`. To remove it, move to 2026-03-03 or later, or add the flag: diff --git a/tests-startup/README.md b/tests-startup/README.md index 0182da67..cc50b4ac 100644 --- a/tests-startup/README.md +++ b/tests-startup/README.md @@ -75,9 +75,9 @@ Graceful `end()` runs every query accepted before the call, including plain quer The portable integration suite checks all 22 built-in element/array OID pairs against PostgreSQL, roundtrips built-in arrays with fetching on/off, preserves independent custom parser/serializer overrides, and covers transforms, SQL NULL positions, quoted NULL text, and user-defined arrays. Numeric NULL assertions use strict null checks so JSON serialization cannot hide NaN. Before this change, discovery returned text NULL as a string, integer NULL as NaN, and JSON NULL threw; the shared parser now recognizes unquoted NULL before applying scalar parsers. -`npm run test:workerd -- . ` runs the driver in local workerd through `createTestHarness()` from pinned Wrangler 4.151.1, which it installs without saving (requires Node 22 or newer). It imports `@steadybrew/postgresjs` through the package's export map, which the `workerd` condition resolves to the generated `cf/` library over `cloudflare:sockets`. `WORKERD_COMPAT_DATE` sets the worker's `compatibility_date` (default `2025-01-01`); CI runs 2025-01-01, 2025-09-15 and the newest date the bundled runtime accepts. It covers cold reservation, built-in arrays/NULL values with fetching on/off, handled catalog failure, and the Cloudflare timer and socket-close fixes: `timers` (idle_timeout and max_lifetime firing, then a query on a recycled connection), `connect-timeout` (a server that accepts and never answers), `end-timeout` (`sql.end({ timeout: 0.2 })` over an in-flight `pg_sleep`), `end-plain` (several clients each ending within a bound) and `end-while-connecting` (`sql.end({ timeout: 0 })` before the socket opens). `copy-out` reads a `COPY TO` stream with a slow consumer, so the socket must pause and resume ([#975](https://github.com/porsager/postgres/issues/975)); `ssl-prefer-declined` connects with `ssl: 'prefer'` to a server without SSL; `subscribe` delivers one logical replication insert (the cluster needs `wal_level = logical` and a replication `pg_hba` entry); `diagnostics-channel` checks that `node:diagnostics_channel` publishes and traces in workerd. `end-tls` and `tls-untrusted-ca` run only when `WORKERD_TLS_PORT` points at an SSL-enabled PostgreSQL and `WORKERD_TLS_CA` at its certificate (which needs a `subjectAltName` for `127.0.0.1`): `end-tls` runs in a harness whose workerd gets the certificate as `SSL_CERT_FILE`, and `tls-untrusted-ca` in one that does not, so it must fail with the certificate error rather than `CONNECT_TIMEOUT` ([#1213](https://github.com/porsager/postgres/issues/1213)). `WORKERD_KNOWN_FAILURES` lists scenarios expected to fail on the build under test; the run fails if one of them passes, as it does if any other scenario fails. Each scenario starts from `reset()` (fresh storage and logs), runs one bounded request, and fails on any unhandled rejection or uncaught error in the captured runtime logs; the worker also returns the unhandled rejections it saw in its response, and the runner reports each scenario's close-time rejections as `closeRejections`. A close-time rejection ("Stream was cancelled", from workerd 1.20261008.1 "This socket has been closed", or "Network connection lost" when the connection is dropped rather than closed) is logged on every close on compatibility dates before 2026-03-03 without the `unhandled_rejection_after_microtask_checkpoint` flag; `WORKERD_CLOSE_REJECTIONS=logged` marks those matrix entries, and elsewhere any close-time rejection fails the run. The matrix also runs 2025-01-01 with that flag. `no-end` runs a query and returns without ending the client, then polls `pg_stat_activity` by `application_name` until the backend is gone, failing after 10 s. The worker replaces `setTimeout` with a version that throws on extra arguments, as the Cloudflare runtime does ([#1088](https://github.com/porsager/postgres/issues/1088)). The runner retains logs under its printed temporary artifact directory. +`npm run test:workerd -- . ` runs the driver in local workerd through `createTestHarness()` from pinned Wrangler 4.151.1, which it installs without saving (requires Node 22 or newer). It imports `@steadybrew/postgresjs` through the package's export map, which the `workerd` condition resolves to the generated `cf/` library over `cloudflare:sockets`. `WORKERD_COMPAT_DATE` sets the worker's `compatibility_date` (default `2025-01-01`); CI runs 2025-01-01, 2025-09-15 and the newest date the bundled runtime accepts. It covers cold reservation, built-in arrays/NULL values with fetching on/off, handled catalog failure, and the Cloudflare timer and socket-close fixes: `timers` (idle_timeout and max_lifetime firing, then a query on a recycled connection), `connect-timeout` (a server that accepts and never answers), `end-timeout` (`sql.end({ timeout: 0.2 })` over an in-flight `pg_sleep`), `end-plain` (several clients each ending within a bound) and `end-while-connecting` (`sql.end({ timeout: 0 })` before the socket opens). `copy-out` reads a `COPY TO` stream with a slow consumer, so the socket must pause and resume ([#975](https://github.com/porsager/postgres/issues/975)); `ssl-prefer-declined` connects with `ssl: 'prefer'` to a server without SSL; `subscribe` delivers one logical replication insert (the cluster needs `wal_level = logical` and a replication `pg_hba` entry); `diagnostics-channel` checks that `node:diagnostics_channel` publishes and traces in workerd. `end-tls` and `tls-untrusted-ca` run only when `WORKERD_TLS_PORT` points at an SSL-enabled PostgreSQL and `WORKERD_TLS_CA` at its certificate (which needs a `subjectAltName` for `127.0.0.1`): `end-tls` runs in a harness whose workerd gets the certificate as `SSL_CERT_FILE`, and `tls-untrusted-ca` in one that does not, so it must fail with the certificate error rather than `CONNECT_TIMEOUT` ([#1213](https://github.com/porsager/postgres/issues/1213)). The run fails if any scenario fails. Each scenario starts from `reset()` (fresh storage and logs), runs one bounded request, and fails on any unhandled rejection or uncaught error in the captured runtime logs; the worker also returns the unhandled rejections it saw in its response, and the runner reports each scenario's close-time rejections as `closeRejections`. A close-time rejection ("Stream was cancelled", from workerd 1.20261008.1 "This socket has been closed", or "Network connection lost" when the connection is dropped rather than closed) is logged on every close on compatibility dates before 2026-03-03 without the `unhandled_rejection_after_microtask_checkpoint` flag; `WORKERD_CLOSE_REJECTIONS=logged` marks those matrix entries, and elsewhere any close-time rejection fails the run. The matrix also runs 2025-01-01 with that flag. `no-end` runs a query and returns without ending the client, then polls `pg_stat_activity` by `application_name` until the backend is gone, failing after 10 s. The worker replaces `setTimeout` with a version that throws on extra arguments, as the Cloudflare runtime does ([#1088](https://github.com/porsager/postgres/issues/1088)). The runner retains logs under its printed temporary artifact directory. -`.github/workflows/workerd-edge.yml` runs the same worker on Cloudflare's network as a Preview of the `postgresjs-edge` Worker, with `tests-startup/workerd-edge.mjs`. On pull requests, on main and on release tags it runs the scenarios against Neon, its pooler and Hyperdrive, and `workerd-edge-cleanup.yml` deletes a pull request's Previews when it closes. The CPU measurement runs only when dispatched by hand, so it does not appear among a commit's checks. `workerd-ab.yml` compares the `cf/` build of the dispatched branch with that of `ab_base`, which may be a release tag or an upstream tag such as `v3.4.9`: the CPU case turns off the worker's strict `setTimeout`, which upstream's timers fail. Each request connects, runs its queries and ends. The `supabase-false` and `supabase-true` targets run `select 1` unprepared against the Supabase CI project's pooler (plaintext) with `fetch_types` off and on, `neon-false` does the same with TLS against Neon, and `hyperdrive-true` connects through Hyperdrive with `prepare: true` and runs parameterized queries in parallel, as a production Worker does; `all` runs all four. Its `ab_copies` input bundles that many separate copies of each build, and each measured round runs on a copy no earlier round used, so every request measures the build's first use in a warm isolate; it takes a single target, and with 40 copies of each build the Worker is about 8 MB, 2 MB gzipped. Each request's `cpuTimeMs`, `wallTimeMs` and outcome come from Workers Logs, so the token needs Workers Metadata and Workers Content read access at account level. The job reports median, p95 and p99 per build and target, and a one-sided Mann-Whitney rank test each way. With `ab_gate` it is the release gate: it fails when the branch is at least 1 ms worse than `ab_base` at the median or p95 on any target and the rank test gives p < 0.01, or when it is killed for exceeding CPU in 2 percentage points more requests. `cpuTimeMs` is whole milliseconds, so a 1 ms difference alone can be rounding; the rank test uses every request. Failed requests are listed, and fail the job only when one variant loses more than 2% of its rounds. +`.github/workflows/workerd-edge.yml` runs the same worker on Cloudflare's network as a Preview of the `postgresjs-edge` Worker, with `tests-startup/workerd-edge.mjs`. On pull requests, on main and on release tags it runs, at compatibility date 2026-10-12, only the scenarios that depend on Cloudflare's network: `diagnostics-channel` in the production runtime, `ssl-verify` (verified TLS and SNI against Neon, which refuses plaintext), `tls-private-ca`, `pooled`, `no-end`, the `abort-*` transactions against Neon, its pooler, the Supabase pooler and Hyperdrive, and the three `hyperdrive*` cases; the others run only in local workerd, which covers them without a network. `workerd-edge-cleanup.yml` deletes a pull request's Preview when it closes. The CPU measurement runs only when dispatched by hand, so it does not appear among a commit's checks. `workerd-ab.yml` compares the `cf/` build of the dispatched branch with that of `ab_base`, which may be a release tag or an upstream tag such as `v3.4.9`: the CPU case turns off the worker's strict `setTimeout`, which upstream's timers fail. Each request connects, runs its queries and ends. The `supabase-false` and `supabase-true` targets run `select 1` unprepared against the Supabase CI project's pooler (plaintext) with `fetch_types` off and on, `neon-false` does the same with TLS against Neon, and `hyperdrive-true` connects through Hyperdrive with `prepare: true` and runs parameterized queries in parallel, as a production Worker does; `all` runs all four. Its `ab_copies` input bundles that many separate copies of each build, and each measured round runs on a copy no earlier round used, so every request measures the build's first use in a warm isolate; it takes a single target, and with 40 copies of each build the Worker is about 8 MB, 2 MB gzipped. Each request's `cpuTimeMs`, `wallTimeMs` and outcome come from Workers Logs, so the token needs Workers Metadata and Workers Content read access at account level. The job reports median, p95 and p99 per build and target, and a one-sided Mann-Whitney rank test each way. With `ab_gate` it is the release gate: it fails when the branch is at least 1 ms worse than `ab_base` at the median or p95 on any target and the rank test gives p < 0.01, or when it is killed for exceeding CPU in 2 percentage points more requests. `cpuTimeMs` is whole milliseconds, so a 1 ms difference alone can be rounding; the rank test uses every request. Failed requests are listed, and fail the job only when one variant loses more than 2% of its rounds. The scope follows [#1219](https://github.com/porsager/postgres/issues/1219), [#751](https://github.com/porsager/postgres/issues/751), and [#1203](https://github.com/porsager/postgres/issues/1203) reservation ownership; [#1195](https://github.com/porsager/postgres/issues/1195) queued reconnect; [#789](https://github.com/porsager/postgres/issues/789) first-query type registration; [#1192](https://github.com/porsager/postgres/issues/1192) and [#1205](https://github.com/porsager/postgres/issues/1205) internal rejection handling; [#1223](https://github.com/porsager/postgres/issues/1223), [#1193](https://github.com/porsager/postgres/issues/1193), and [#1226](https://github.com/porsager/postgres/issues/1226) retry/state isolation; and [#1164](https://github.com/porsager/postgres/issues/1164) built-in arrays without discovery. Catalog traffic/caching from [#903](https://github.com/porsager/postgres/issues/903) is deferred. diff --git a/tests-startup/workerd-edge.mjs b/tests-startup/workerd-edge.mjs index 281722c7..cd17014b 100644 --- a/tests-startup/workerd-edge.mjs +++ b/tests-startup/workerd-edge.mjs @@ -4,9 +4,9 @@ import { appendFile, cp, mkdir, readFile, writeFile } from 'node:fs/promises' import path from 'node:path' const scenarios = [ - 'arrays-false', 'arrays-true', 'timers', 'end-timeout', 'end-plain', 'end-while-connecting', 'end-tls', - 'copy-out', 'subscribe', 'diagnostics-channel', 'ssl-verify', 'tls-private-ca', 'pooled', 'no-end', - 'abort-neon', 'abort-neon-pooled', 'abort-supabase-pooler', 'abort-hyperdrive', 'abort-hyperdrive-pooled', 'abort-hyperdrive-supabase' + 'diagnostics-channel', 'ssl-verify', 'tls-private-ca', 'pooled', 'no-end', + 'abort-neon', 'abort-neon-pooled', 'abort-supabase-pooler', 'abort-hyperdrive', 'abort-hyperdrive-pooled', 'abort-hyperdrive-supabase', + 'hyperdrive', 'hyperdrive-pooled', 'hyperdrive-supabase' ] const hyperdrive = [ { binding: 'HYPERDRIVE', id: '6cac003bd1af42849ca7e83e125d5a3d' }, @@ -76,42 +76,24 @@ async function ready(base) { async function fetchWorker(url, headers) { let res , platformErrors = 0 - , networkErrors = 0 , waitedMs = 0 for (;;) { - let error - try { - res = await fetch(url, { headers, signal: AbortSignal.timeout(30000) }) - } catch (e) { - if (e.name !== 'TypeError') - throw e - error = e - } - const fromWorker = !error && (res.ok || (res.headers.get('content-type') || '').includes('json')) - const wait = (error ? undefined : retryAfter(res.headers.get('retry-after'))) - ?? Math.min(2000 * 2 ** (platformErrors + networkErrors), 30000) - if (error && waitedMs + wait > 180000) - throw new Error(error.message + (error.cause ? ': ' + (error.cause.code || error.cause.message) : ''), { cause: error }) + res = await fetch(url, { headers, signal: AbortSignal.timeout(30000) }) + const fromWorker = res.ok || (res.headers.get('content-type') || '').includes('json') + const wait = retryAfter(res.headers.get('retry-after')) ?? Math.min(2000 * 2 ** platformErrors, 30000) if (fromWorker || waitedMs + wait > 180000) - return { res, platformErrors, networkErrors, waitedMs } - if (error) { - networkErrors++ - } else { - platformErrors++ - await res.body?.cancel() - } + return { res, platformErrors, waitedMs } + platformErrors++ waitedMs += wait + await res.body?.cancel() await new Promise((resolve) => setTimeout(resolve, wait)) } } async function run(base) { const headers = await ready(base) - const known = (process.env.EDGE_KNOWN_FAILURES || '').split(',').filter(Boolean) - const rounds = Number(process.env.EDGE_HYPERDRIVE_ROUNDS) || 1 - const round = ['hyperdrive', 'hyperdrive-pooled', 'hyperdrive-supabase'] const build = 'cf' - for (const name of ['wake', ...scenarios, ...Array(rounds).fill(round).flat()]) { + for (const name of scenarios) { let body , failure , fetched @@ -129,18 +111,14 @@ async function run(base) { } catch (error) { failure = error } - const expected = known.includes(name) - if (Boolean(failure) !== expected) process.exitCode = 1 + if (failure) process.exitCode = 1 console.log(JSON.stringify({ build, name, passed: !failure, - ...(expected ? { knownFailure: true } : {}), result: body?.result, closeRejections: (body?.unhandled || []).filter((x) => closing.test(x)).length, - ...(fetched?.platformErrors || fetched?.networkErrors - ? { platformErrors: fetched.platformErrors, networkErrors: fetched.networkErrors, waitedMs: fetched.waitedMs } - : {}), + ...(fetched?.platformErrors ? { platformErrors: fetched.platformErrors, waitedMs: fetched.waitedMs } : {}), error: failure?.message })) } diff --git a/tests-startup/workerd-run.mjs b/tests-startup/workerd-run.mjs index da5db830..5a332075 100644 --- a/tests-startup/workerd-run.mjs +++ b/tests-startup/workerd-run.mjs @@ -43,7 +43,6 @@ async function main() { const tlsPort = Number(process.env.WORKERD_TLS_PORT) || 0 const tlsScenarios = ['end-tls', 'tls-untrusted-ca'] const peerScenarios = ['cold-reserve-false', 'catalog-error'] - const knownFailures = (process.env.WORKERD_KNOWN_FAILURES || '').split(',').filter(Boolean) const closeRejectionsLogged = process.env.WORKERD_CLOSE_REJECTIONS === 'logged' const servers = new Map() @@ -92,15 +91,13 @@ async function main() { for (const name of scenarios) { if (tlsScenarios.includes(name)) assert(tlsPort > 0 && process.env.WORKERD_TLS_CA, name + ' requires WORKERD_TLS_PORT and WORKERD_TLS_CA') const { failure, detail, output, unhandled } = await run(name) - const expected = knownFailures.includes(name) - if (Boolean(failure) !== expected) process.exitCode = 1 + if (failure) process.exitCode = 1 const closeRejections = unhandled.filter((x) => /Stream was cancelled|This socket has been closed|Network connection lost/.test(x)).length if (closeRejections && !closeRejectionsLogged) process.exitCode = 1 await writeFile(path.join(work, name + '.log'), output) console.log(JSON.stringify({ name, passed: !failure, - ...(expected ? { knownFailure: true } : {}), result: detail, closeRejections, error: failure?.message, diff --git a/tests-startup/workerd-worker.js b/tests-startup/workerd-worker.js index 1ea980f9..8813fe83 100644 --- a/tests-startup/workerd-worker.js +++ b/tests-startup/workerd-worker.js @@ -90,12 +90,8 @@ const scenarios = { const times = [] for (let i = 0; i < 3; i++) { const sql = client(port, { max: 1, ssl: 'require' }) - if (target.url) { - await sql`select 1` - } else { - const [{ ssl }] = await sql`select ssl from pg_stat_ssl where pid = pg_backend_pid()` - if (ssl !== true) throw new Error('Connection was not encrypted') - } + const [{ ssl }] = await sql`select ssl from pg_stat_ssl where pid = pg_backend_pid()` + if (ssl !== true) throw new Error('Connection was not encrypted') const started = Date.now() await within(sql.end(), 3000, 'tls sql.end() #' + i) times.push(Date.now() - started) @@ -206,14 +202,6 @@ const scenarios = { if (!error) throw new Error('The server accepted a connection without TLS') return { x, plaintext: error.code || error.message } }, - async wake(port) { - const sql = client(port, { max: 1, connect_timeout: 20 }) - const started = Date.now() - await within(sql`select 1`, 25000, 'first query') - const ms = Date.now() - started - await within(sql.end(), 3000, 'end') - return { ms } - }, async pooled() { const sql = target.postgres(target.pooledUrl, { max: 2, prepare: false, fetch_types: false }) const rows = await within(Promise.all(Array.from({ length: 20 }, (_, i) => sql`select ${ i }::int as i`)), 10000, 'pooled queries')