Skip to content

Commit 0e89a0d

Browse files
committed
test(runtime): compare ?version= response bodies against ONE installed row (#17416)
CI's Test Core (2/6) failed §3 on a 1 ms timestamp difference. Cause measured: `get()` built a fresh host per call, so the package was installed twice, and `SchemaRegistry.installPackage` stamps `installedAt`/`updatedAt` from one `new Date()` per install. Two hosts therefore hold two rows whose stamps differ whenever the installs straddle a millisecond boundary — a flake, not a product defect: nothing on the read path reads a clock (`toPackageResponse` is an allowlist copy, `withWritableVerdict` a spread, and `success()` adds no timestamp), so one install cannot produce two answers. Every case that compares two response bodies now issues both requests through one host, which is the shape §2's byte-identical pin already had and the reason it stayed green in the same shard. §1's pair moves onto one host too: the criterion is «the SAME request with and without `?version=`», and two hosts let a difference come from the rows instead of from the parameter. §4's array-vs-string pin carried the identical latent flake and is repaired with it. Whole-body `toEqual` is preserved everywhere — the stamps stay in the comparison, which is what makes "the same request" mean the same response. Claude-Session: https://claude.ai/code/session_01TSf4DV7ziu4V5j73e46b7c Co-authored-by: Claude <noreply@anthropic.com>
1 parent ffdc9a5 commit 0e89a0d

1 file changed

Lines changed: 46 additions & 14 deletions

File tree

packages/runtime/src/domains/packages-get-version-scope.test.ts

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -76,18 +76,48 @@ const reader = (): any => ({
7676
executionContext: { userId: 'u_admin', isSystem: false, systemPermissions: ['manage_metadata', 'studio.access'] },
7777
});
7878

79-
/** `GET /packages/:id` with whatever query the case is about. */
80-
async function get(query: Record<string, unknown>) {
81-
const dispatcher = make();
79+
/**
80+
* `GET /packages/:id` against an EXISTING host.
81+
*
82+
* ⛔ Every case that compares two RESPONSE BODIES must issue both requests
83+
* through this, against ONE `make()`. `SchemaRegistry.installPackage` stamps
84+
* `installedAt` and `updatedAt` from a single `new Date()` per install
85+
* (`packages/objectql/src/registry.ts`), and both are declared record fields
86+
* that `toPackageResponse` carries to the wire. So two hosts hold two rows
87+
* whose stamps differ whenever the installs straddle a millisecond boundary,
88+
* and a whole-body `toEqual` between them fails on the clock rather than on
89+
* anything this door did — a flake that passes on a re-run and comes back.
90+
*
91+
* One host makes it deterministic rather than merely likelier: both responses
92+
* are projections of ONE row, so there is no second install and no second
93+
* clock read to disagree. Nothing on the read path reads a clock at all —
94+
* neither `toPackageResponse` (an allowlist copy) nor `withWritableVerdict` (a
95+
* spread) nor the dispatcher's `success()` envelope — so with one install the
96+
* stamps cannot move, at any scheduling.
97+
*
98+
* ⛔ The repair for such a failure is this shape, ⛔ never dropping the two
99+
* stamps out of the comparison: whole-body equality is what makes «the same
100+
* request» mean the same RESPONSE rather than the same status.
101+
*/
102+
async function read(dispatcher: HttpDispatcher, query: Record<string, unknown> | undefined) {
82103
const r = await dispatcher.handlePackages(`/${PKG}`, 'GET', undefined, query, reader());
83104
return { status: r.response?.status ?? 200, body: r.response?.body };
84105
}
85106

107+
/** One request on a host of its own — for the cases that compare against no other body. */
108+
async function get(query: Record<string, unknown>) {
109+
return read(make(), query);
110+
}
111+
86112
describe('#17416 GET /packages/:id — ?version= scopes the read', () => {
87113
describe('§1 the discriminating pin — with and without ?version= are not the same answer', () => {
88114
it('a non-installed ?version= is NOT answered with the installed row', async () => {
89-
const scoped = await get({ version: ABSENT });
90-
const unscoped = await get({});
115+
// ONE host: the criterion is «the SAME request with and without
116+
// `?version=`», so both answers have to be about the same row —
117+
// two hosts would let a difference come from the rows instead.
118+
const host = make();
119+
const scoped = await read(host, { version: ABSENT });
120+
const unscoped = await read(host, {});
91121

92122
// The discriminating field, not the status alone.
93123
expect(scoped.status).toBe(404);
@@ -132,18 +162,19 @@ describe('#17416 GET /packages/:id — ?version= scopes the read', () => {
132162
});
133163

134164
it('is byte-identical to the read with no query object at all', async () => {
135-
const dispatcher = make();
136-
const withEmpty = await dispatcher.handlePackages(`/${PKG}`, 'GET', undefined, {}, reader());
137-
const withNone = await dispatcher.handlePackages(`/${PKG}`, 'GET', undefined, undefined, reader());
138-
expect(withNone.response?.status ?? 200).toBe(200);
139-
expect(withNone.response?.body).toEqual(withEmpty.response?.body);
165+
const host = make();
166+
const withEmpty = await read(host, {});
167+
const withNone = await read(host, undefined);
168+
expect(withNone.status).toBe(200);
169+
expect(withNone.body).toEqual(withEmpty.body);
140170
});
141171
});
142172

143173
describe('§3 `latest` and absent name the SAME request', () => {
144174
it('?version=latest serves the installed row, exactly as no parameter does', async () => {
145-
const latest = await get({ version: 'latest' });
146-
const unscoped = await get({});
175+
const host = make();
176+
const latest = await read(host, { version: 'latest' });
177+
const unscoped = await read(host, {});
147178
expect(latest.status).toBe(200);
148179
expect(latest.body).toEqual(unscoped.body);
149180
});
@@ -160,8 +191,9 @@ describe('#17416 GET /packages/:id — ?version= scopes the read', () => {
160191
});
161192

162193
it('ONE occurrence encoded as a one-element array is one occurrence', async () => {
163-
const arr = await get({ version: [INSTALLED] });
164-
const str = await get({ version: INSTALLED });
194+
const host = make();
195+
const arr = await read(host, { version: [INSTALLED] });
196+
const str = await read(host, { version: INSTALLED });
165197
expect(arr.status).toBe(200);
166198
expect(arr.body).toEqual(str.body);
167199
});

0 commit comments

Comments
 (0)