test: await verified ChatGPT storage recovery completion
This commit is contained in:
@@ -337,9 +337,25 @@ for (const holdVerification of [false, true]) test(`invalid rotating replacement
|
|||||||
} finally { f.service.close(); }
|
} finally { f.service.close(); }
|
||||||
});
|
});
|
||||||
|
|
||||||
test("observed file write failure invalidates all work; status, consent and resume cannot reload stale credentials or repair authority", async () => {
|
for (const holdVerification of [false, true]) test(`observed file write failure invalidates all work; status, consent and resume cannot reload stale credentials or repair authority${holdVerification ? " (held JWKS regression)" : ""}`, { timeout: 10000 }, async () => {
|
||||||
let lost = false, reads = 0; const pushes: any[] = [];
|
let lost = false, reads = 0; const pushes: any[] = [];
|
||||||
const f = await loggedIn({ read: () => { reads++; }, write: async () => { if (lost) throw Object.assign(new Error("storage"), { code: "storage" }); }, change: (push) => pushes.push(push) });
|
const reconnectComplete = deferred<any>();
|
||||||
|
const verificationEntered = deferred(), verificationRelease = deferred();
|
||||||
|
let reconnectArmed = false, sawPending = false, completed = false;
|
||||||
|
const f = await loggedIn({ read: () => { reads++; }, write: async () => { if (lost) throw Object.assign(new Error("storage"), { code: "storage" }); },
|
||||||
|
change: (push) => {
|
||||||
|
pushes.push(push);
|
||||||
|
if (!reconnectArmed) return;
|
||||||
|
if (push.status.pending) sawPending = true;
|
||||||
|
else if (sawPending) { completed = true; reconnectComplete.resolve(push.status); }
|
||||||
|
},
|
||||||
|
provider: async (url) => {
|
||||||
|
if (holdVerification && reconnectArmed && url.endsWith("jwks.json")) {
|
||||||
|
verificationEntered.resolve(); await verificationRelease.promise;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
});
|
||||||
try {
|
try {
|
||||||
await f.service.lease(false); const epoch = f.service.stamp().epoch;
|
await f.service.lease(false); const epoch = f.service.stamp().epoch;
|
||||||
lost = true;
|
lost = true;
|
||||||
@@ -351,10 +367,26 @@ test("observed file write failure invalidates all work; status, consent and resu
|
|||||||
await assert.rejects(f.service.lease(false));
|
await assert.rejects(f.service.lease(false));
|
||||||
assert.equal((await f.service.status()).accounts[0].connected, false);
|
assert.equal((await f.service.status()).accounts[0].connected, false);
|
||||||
assert.equal(reads, 1, "a recovered disk never causes a stale credential reload");
|
assert.equal(reads, 1, "a recovered disk never causes a stale credential reload");
|
||||||
await f.service.login(f.saved.activeId); await f.callback();
|
const writesBeforeReconnect = f.writeCount;
|
||||||
for (let i = 0; i < 100 && (await f.service.status()).pending; i++) await new Promise((resolve) => setImmediate(resolve));
|
// The initial login already settled fixture.changed; observe this attempt instead.
|
||||||
assert.equal((await f.service.status()).accounts[0].connected, true, "verified login plus durable save can explicitly reconnect");
|
reconnectArmed = true;
|
||||||
} finally { f.service.close(); }
|
await f.service.login(f.saved.activeId); assert.equal(sawPending, true); await f.callback();
|
||||||
|
if (holdVerification) {
|
||||||
|
await verificationEntered.promise;
|
||||||
|
assert.equal(completed, false, "HTTP acknowledgement cannot complete a pending identity verification");
|
||||||
|
const held = await f.service.status();
|
||||||
|
assert.equal(held.pending, true); assert.equal(held.error, null);
|
||||||
|
assert.equal(held.accounts[0].connected, false);
|
||||||
|
assert.equal(f.writeCount, writesBeforeReconnect, "unverified recovery cannot persist credentials");
|
||||||
|
}
|
||||||
|
verificationRelease.resolve();
|
||||||
|
const terminal = await reconnectComplete.promise;
|
||||||
|
assert.equal(terminal.pending, false); assert.equal(terminal.error, null);
|
||||||
|
assert.equal(terminal.accounts[0].connected, true, "verified login plus durable save can explicitly reconnect");
|
||||||
|
assert.equal(f.writeCount, writesBeforeReconnect + 1, "recovery requires a new durable credential write");
|
||||||
|
assert.equal(f.saved.activeId, terminal.activeId);
|
||||||
|
assert.equal(reads, 1, "explicit recovery still never reloads stale credentials");
|
||||||
|
} finally { verificationRelease.resolve(); f.service.close(); }
|
||||||
});
|
});
|
||||||
|
|
||||||
test("strict JSON schema rejects malformed marker/duplicates/token/active identity without changing original bytes", async () => {
|
test("strict JSON schema rejects malformed marker/duplicates/token/active identity without changing original bytes", async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user