fix(k1): harden live handoff and camera recovery
This commit is contained in:
@@ -20,6 +20,7 @@ let operatorIntentGeneration;
|
||||
let configuration;
|
||||
let compatibility;
|
||||
let networkProvisionFailureMessage;
|
||||
let awaitNetworkProvisionSettlementAfterLostResponse;
|
||||
let discoveryScanFailureMessage;
|
||||
let connectionVerificationFailureMessage;
|
||||
let operationById;
|
||||
@@ -99,6 +100,7 @@ before(async () => {
|
||||
));
|
||||
({
|
||||
networkProvisionFailureMessage,
|
||||
awaitNetworkProvisionSettlementAfterLostResponse,
|
||||
discoveryScanFailureMessage,
|
||||
connectionVerificationFailureMessage,
|
||||
operationById,
|
||||
@@ -1043,6 +1045,56 @@ test("K1 API uses bounded no-retry timeout classes per operation family", async
|
||||
assert.doesNotMatch(apiSource, /automaticRetry\s*=\s*true/);
|
||||
});
|
||||
|
||||
test("lost Quick response follows the admitted Apply by journal reads only", async () => {
|
||||
const idempotencyKey = "network-provision:quick-lost-response";
|
||||
let nowMs = 1_000;
|
||||
let reads = 0;
|
||||
const accepted = [];
|
||||
const operation = {
|
||||
operation_id: "op-quick-lost-response",
|
||||
action: "network.provision",
|
||||
status: "running",
|
||||
idempotency_key: idempotencyKey,
|
||||
deadline_at: new Date(5_000).toISOString(),
|
||||
};
|
||||
const initialState = {
|
||||
snapshot_runtime_id: "runtime-quick-lost-response",
|
||||
operations: [operation],
|
||||
};
|
||||
const terminalState = {
|
||||
...initialState,
|
||||
operations: [{
|
||||
...operation,
|
||||
status: "succeeded",
|
||||
result: { phase: "network_applied" },
|
||||
}],
|
||||
};
|
||||
|
||||
const settled = await awaitNetworkProvisionSettlementAfterLostResponse(
|
||||
initialState,
|
||||
idempotencyKey,
|
||||
async () => {
|
||||
reads += 1;
|
||||
if (reads === 1) {
|
||||
throw new ApiError("transient localhost handoff", 0, true);
|
||||
}
|
||||
return terminalState;
|
||||
},
|
||||
(state) => accepted.push(state),
|
||||
() => {},
|
||||
{
|
||||
now: () => nowMs,
|
||||
wait: async (delayMs) => {
|
||||
nowMs += delayMs;
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
assert.equal(reads, 2);
|
||||
assert.deepEqual(accepted, [terminalState]);
|
||||
assert.equal(settled.operations[0].status, "succeeded");
|
||||
});
|
||||
|
||||
test("one explicit K1 operator action supplies the backend physical acceptance", () => {
|
||||
assert.deepEqual(physicalCommandConfirmation.operatorActionPhysicalAcceptance(), {
|
||||
operator_present: true,
|
||||
|
||||
Reference in New Issue
Block a user