Skip to content

Commit 4f9bcb0

Browse files
authored
test(packaging): give the tests that run 7-Zip their own 40 s bound instead of bun's 5 s default (#2258)
* test(packaging): give the tests that run 7-Zip their own 40 s bound instead of bun's 5 s default The first test of the flat-zip packer's suite timed out at bun's 5000 ms default in the Linux unit job (run 42084796608) on a change that touches no packaging code, with the script unfinished, while the next test, packing the same fixture, took 980 ms. In twelve runs of that job the file ran beside the same three long-running files on four CPUs, and the eleven green ones took 0.6 s to 1.5 s for the whole file; on a developer machine the spawn takes about 17 ms idle and under 190 ms beside three times as many busy loops as CPUs, so the script did not get slow. The four tests that run 7-Zip now pass platformTimeoutMs(40_000), the bound other tests already carry past the default under load: eight times where the slow spawn died, and doubled on Windows, where a test's own bound replaces the runner's 60 s. No assertion changed: a copy of the script that stops before packing or packs a wrapper layout still fails in milliseconds, and a 7-Zip that never answers fails at the bound. * test(packaging): say where a hung 7-Zip is reported on Windows On Windows the bound doubles to 80 s, so four hanging tests add up past the runner's 300 s per-file budget, which then ends the file before the fourth test's own bound. * docs(backlog): record the stale Biome schema and the hand-kept list of Windows bounds P14: biome.json names the 2.5.1 schema while the lockfile installs Biome 2.6.4, so every format run prints a schema-version diagnostic. REL10: the Windows-raise test checks a hand-kept list of bounds that already misses the 60 s one the Kafka write-reach test passes, and would not ask for a new bound outside the listed range.
1 parent 9806714 commit 4f9bcb0

2 files changed

Lines changed: 104 additions & 48 deletions

File tree

‎docs/BACKLOG.md‎

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ None of it is a GitHub issue.
3232
- [Value interpolation](#value-interpolation) — V1
3333
- [Row editing](#row-editing) — R1–R3 · 3
3434
- [Studio UI and query execution](#studio-ui-and-query-execution) — X2-X26, U2-U202 · 188
35-
- [Dependencies](#dependencies) — P1-P13 · 11
35+
- [Dependencies](#dependencies) — P1-P14 · 12
3636
- [Documentation](#documentation) — DOC3-DOC37 · 31
37-
- [Release pipeline](#release-pipeline) — REL1-REL9 · 9
37+
- [Release pipeline](#release-pipeline) — REL1-REL10 · 10
3838
- [Security Phase 1 deferrals](#security-phase-1-deferrals) — H1–H14 · 4
3939
- [Security Phase 2 deferrals](#security-phase-2-deferrals) — C3–C11 · 6
4040
- [Security Phase 3 deferrals](#security-phase-3-deferrals) — K4-K8 · 5
@@ -7235,6 +7235,16 @@ Found 2026-11-02 while taking the Dependabot production group (#2167); the pin s
72357235

72367236
**Done when:** the agent-boundary captures are recorded on 6.3.0 or a later release against the Enterprise fixture and match the committed ones (or the differences are taken into the provider and `docs/providers/neo4j.md`), the pin moves to it with the measurement its `//dependencies` note asks for, with `neo4j-driver-core` and `neo4j-driver-bolt-connection` on the same version, and the `neo4j-driver-lite` ignore entry in `.github/dependabot.yml` is removed with it.
72377237

7238+
### P14. biome.json names the 2.5.1 schema while the lockfile installs Biome 2.6.4
7239+
7240+
`biome.json` points `$schema` at `https://biomejs.dev/schemas/2.5.1/schema.json`, while `package.json` asks for `@biomejs/biome` `^2.5.12` and `bun.lock` resolves 2.6.4.
7241+
So every Biome run, `bun run format` in the required check among them, prints "The configuration schema version does not match the CLI version 2.6.4" as an info diagnostic on `biome.json`, where a new diagnostic is easy to miss beside it.
7242+
The `biome.json` excerpt in `docs/TOOLCHAIN.md` names the same 2.5.1 schema.
7243+
7244+
Found 2026-11-05 while reading the format step of a local gate run.
7245+
7246+
**Done when:** `biome.json` names the schema of the installed Biome, through `biome migrate` or by hand, the `docs/TOOLCHAIN.md` excerpt matches it, and `bun run format` prints no schema-version diagnostic.
7247+
72387248
## Documentation
72397249

72407250
### DOC3. Six channel listings carry corrected copy that nobody has resubmitted
@@ -7779,6 +7789,16 @@ The cause above is a reading of the code, not a measurement: the run kept no tra
77797789

77807790
**Done when:** the second context makes no request between the removal and its own navigation, for example because it waits for its editor to settle and then stays on `about:blank` until the check, or the check accepts either redirect and asserts what both prove, that the session is refused; and the test passes 20 of 20 runs with `--repeat-each=20`.
77817791

7792+
### REL10. The Windows-raise test checks a hand-kept list of bounds, which already misses one
7793+
7794+
`tests/unit/platform-timeout.test.ts` checks, for each bound in its `BOUNDS_IN_USE` list, that the Windows raise stays under the runner's per-file budget and above the runner's Windows per-test default.
7795+
Its docblock calls the list the bounds that pass through the helper today, and it holds 40_000 and 120_000, while the Kafka write-reach test (`tests/unit/db/kafka/write-reach.test.ts`) also passes 60_000.
7796+
60_000 lies between the two listed bounds, and both checks grow with the bound, so a change to the factor or to either limit that broke it would break a listed bound too; what the hand-kept list cannot catch is a new bound below 40_000 or above 120_000, which nothing asks anyone to list.
7797+
7798+
Found 2026-11-05 while sizing a per-test bound for the standalone zip packing tests.
7799+
7800+
**Done when:** every bound passed to `platformTimeoutMs` under `tests/` is held by those checks, either because `BOUNDS_IN_USE` lists it or because the test collects the bounds from the tests that pass them, and a new bound outside the list fails the test.
7801+
77827802
---
77837803

77847804
## Security Phase 1 deferrals

‎tests/unit/packaging-standalone-zip.test.ts‎

Lines changed: 82 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { afterEach, expect, test } from "bun:test";
1313
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
1414
import { tmpdir } from "node:os";
1515
import { join } from "node:path";
16+
import { platformTimeoutMs } from "../helpers/platform-timeout";
1617
import { describeIf, missingPosixShell, missingUnixTool, posixShell } from "../helpers/posix-tools";
1718

1819
const SCRIPT = join(import.meta.dir, "../../scripts/lib/pack-standalone-zip.sh");
@@ -59,6 +60,25 @@ function listZipEntries(zipPath: string): string[] {
5960
return names;
6061
}
6162

63+
/**
64+
* The bound of each test below that runs 7-Zip, declared rather than left at bun's 5000ms default.
65+
*
66+
* Each of those tests spawns the script, which runs 7-Zip twice, and on a loaded runner one such spawn outlasted the
67+
* default: in CI run 42084796608 the first test here timed out at 5000ms with the script unfinished, while the next
68+
* test, packing the same fixture, took 980ms. That job ran four files at a time on four CPUs under coverage, and this
69+
* file ran beside the same three long-running files in every one of the twelve runs read, the eleven green ones
70+
* taking 0.6s to 1.5s for the whole file. On a developer machine the same spawn takes about 17ms idle and stays under
71+
* 190ms beside three times as many busy loops as CPUs, so the script itself is not what got slow.
72+
*
73+
* Forty seconds is eight times the default the slow spawn died at and over twenty-five times the slowest green run of
74+
* the whole file, and `platformTimeoutMs` doubles it on Windows, where a test's own bound replaces the 60s the
75+
* runner gives every test there. It masks no broken script: one that packs the wrong layout or exits with the wrong
76+
* status still fails its assertions at once, and one that hangs still fails, at the bound (on Windows the runner's
77+
* per-file budget can end the file first, once four bounds add up past it). The last two tests stop before 7-Zip and
78+
* answer in milliseconds even under that load, so they keep the default.
79+
*/
80+
const PACK_TIMEOUT_MS = platformTimeoutMs(40_000);
81+
6282
describeIf(CANNOT_PACK, "scripts/lib/pack-standalone-zip.sh (#114)", () => {
6383
const fixtureRoots: string[] = [];
6484

@@ -78,52 +98,68 @@ describeIf(CANNOT_PACK, "scripts/lib/pack-standalone-zip.sh (#114)", () => {
7898
return { root, payloadDir, zip: join(root, "out.zip") };
7999
}
80100

81-
test("packs the payload contents FLAT at the archive root, including dot-directories", () => {
82-
const { payloadDir, zip } = makeFixturePayload();
83-
84-
const run = Bun.spawnSync([SHELL!, SCRIPT, payloadDir, zip], { stdout: "pipe", stderr: "pipe" });
85-
expect(run.stderr.toString()).toBe("");
86-
expect(run.exitCode).toBe(0);
87-
88-
const entries = listZipEntries(zip).map((entry) => entry.replaceAll("\\", "/"));
89-
expect(entries).toContain("server.js");
90-
expect(entries).toContain("package.json");
91-
expect(entries).toContain(".next");
92-
expect(entries).toContain(".next/BUILD_ID");
93-
// Flat contract: nothing may hide under a versioned wrapper root.
94-
for (const entry of entries) {
95-
expect(entry.startsWith("libredb-studio-")).toBe(false);
96-
expect(entry.startsWith("payload/")).toBe(false);
97-
}
98-
});
99-
100-
test("overwrites a stale zip at the output path", () => {
101-
const { payloadDir, zip } = makeFixturePayload();
102-
writeFileSync(zip, "not a zip");
103-
104-
const run = Bun.spawnSync([SHELL!, SCRIPT, payloadDir, zip], { stdout: "pipe", stderr: "pipe" });
105-
expect(run.exitCode).toBe(0);
106-
expect(listZipEntries(zip)).toContain("server.js");
107-
});
108-
109-
test("refuses a payload missing a required root entry (server.js)", () => {
110-
const { payloadDir, zip } = makeFixturePayload();
111-
rmSync(join(payloadDir, "server.js"));
112-
113-
const run = Bun.spawnSync([SHELL!, SCRIPT, payloadDir, zip], { stdout: "pipe", stderr: "pipe" });
114-
expect(run.exitCode).not.toBe(0);
115-
expect(run.stderr.toString()).toContain("server.js");
116-
});
117-
118-
test("matches required entries as fixed strings, not regexes (serverXjs must not satisfy server.js)", () => {
119-
const { payloadDir, zip } = makeFixturePayload();
120-
rmSync(join(payloadDir, "server.js"));
121-
writeFileSync(join(payloadDir, "serverXjs"), "// imposter");
122-
123-
const run = Bun.spawnSync([SHELL!, SCRIPT, payloadDir, zip], { stdout: "pipe", stderr: "pipe" });
124-
expect(run.exitCode).not.toBe(0);
125-
expect(run.stderr.toString()).toContain("server.js");
126-
});
101+
test(
102+
"packs the payload contents FLAT at the archive root, including dot-directories",
103+
() => {
104+
const { payloadDir, zip } = makeFixturePayload();
105+
106+
const run = Bun.spawnSync([SHELL!, SCRIPT, payloadDir, zip], { stdout: "pipe", stderr: "pipe" });
107+
expect(run.stderr.toString()).toBe("");
108+
expect(run.exitCode).toBe(0);
109+
110+
const entries = listZipEntries(zip).map((entry) => entry.replaceAll("\\", "/"));
111+
expect(entries).toContain("server.js");
112+
expect(entries).toContain("package.json");
113+
expect(entries).toContain(".next");
114+
expect(entries).toContain(".next/BUILD_ID");
115+
// Flat contract: nothing may hide under a versioned wrapper root.
116+
for (const entry of entries) {
117+
expect(entry.startsWith("libredb-studio-")).toBe(false);
118+
expect(entry.startsWith("payload/")).toBe(false);
119+
}
120+
},
121+
PACK_TIMEOUT_MS,
122+
);
123+
124+
test(
125+
"overwrites a stale zip at the output path",
126+
() => {
127+
const { payloadDir, zip } = makeFixturePayload();
128+
writeFileSync(zip, "not a zip");
129+
130+
const run = Bun.spawnSync([SHELL!, SCRIPT, payloadDir, zip], { stdout: "pipe", stderr: "pipe" });
131+
expect(run.exitCode).toBe(0);
132+
expect(listZipEntries(zip)).toContain("server.js");
133+
},
134+
PACK_TIMEOUT_MS,
135+
);
136+
137+
test(
138+
"refuses a payload missing a required root entry (server.js)",
139+
() => {
140+
const { payloadDir, zip } = makeFixturePayload();
141+
rmSync(join(payloadDir, "server.js"));
142+
143+
const run = Bun.spawnSync([SHELL!, SCRIPT, payloadDir, zip], { stdout: "pipe", stderr: "pipe" });
144+
expect(run.exitCode).not.toBe(0);
145+
expect(run.stderr.toString()).toContain("server.js");
146+
},
147+
PACK_TIMEOUT_MS,
148+
);
149+
150+
test(
151+
"matches required entries as fixed strings, not regexes (serverXjs must not satisfy server.js)",
152+
() => {
153+
const { payloadDir, zip } = makeFixturePayload();
154+
rmSync(join(payloadDir, "server.js"));
155+
writeFileSync(join(payloadDir, "serverXjs"), "// imposter");
156+
157+
const run = Bun.spawnSync([SHELL!, SCRIPT, payloadDir, zip], { stdout: "pipe", stderr: "pipe" });
158+
expect(run.exitCode).not.toBe(0);
159+
expect(run.stderr.toString()).toContain("server.js");
160+
},
161+
PACK_TIMEOUT_MS,
162+
);
127163

128164
test("fails loudly for a missing payload directory", () => {
129165
const { root, zip } = makeFixturePayload();

0 commit comments

Comments
 (0)