Make mixed Homeworld HTTP fixture deterministic
Verify and publish checkpoint container / container (push) Successful in 11m55s
Verify and publish checkpoint container / container (push) Successful in 11m55s
This commit is contained in:
1 parent
02695aea7c
commit
8fb9f59106
2 files changed
+17
-6
No files matched your search
@@ -64,7 +64,13 @@ job and test-container loopback addresses are in separate nested Docker
|
|||||||
network namespaces. With user approval the dedicated runner now shares its
|
network namespaces. With user approval the dedicated runner now shares its
|
||||||
own network namespace with its jobs, while retaining its separate Docker
|
own network namespace with its jobs, while retaining its separate Docker
|
||||||
daemon; the runner reconnected. A fresh end-to-end build and registry
|
daemon; the runner reconnected. A fresh end-to-end build and registry
|
||||||
publication remain unverified. Existing NAS deployment and its persistent
|
publication remain unverified. Build `02695ae` passed container startup and
|
||||||
|
25 administrator checks, then failed one of 69 HTTP cases: the mixed Richese
|
||||||
|
Homeworld fixture allowed an unrelated earlier automated shipment before its
|
||||||
|
scripted two-force move. The fixture now suppresses those unrelated turns and
|
||||||
|
asserts the zero-to-two transition; its focused HTTP case passes locally. The
|
||||||
|
CI log did not preserve the precise earlier action, so the exact cause of its
|
||||||
|
extra visitor remains unproven. Existing NAS deployment and its persistent
|
||||||
storage remain untouched.
|
storage remain untouched.
|
||||||
|
|
||||||
**Semuta before Basic Moritani ally retention — 28 October. Prototyped /
|
**Semuta before Basic Moritani ally retention — 28 October. Prototyped /
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ void test('authenticated mixed transfer moves a concealed marker and physical vi
|
|||||||
for (const seat of seats) await act(seat.cookie, { type: 'ready' });
|
for (const seat of seats) await act(seat.cookie, { type: 'ready' });
|
||||||
await act(hostSeat.cookie, { type: 'start' });
|
await act(hostSeat.cookie, { type: 'start' });
|
||||||
|
|
||||||
let firstMarkerPlaced = false;
|
|
||||||
async function advance(until: (ownerView: GameView) => boolean) {
|
async function advance(until: (ownerView: GameView) => boolean) {
|
||||||
for (let count = 0; count < 800; count++) {
|
for (let count = 0; count < 800; count++) {
|
||||||
const currentOwner = await read(ownerSeat.cookie);
|
const currentOwner = await read(ownerSeat.cookie);
|
||||||
@@ -90,14 +89,16 @@ void test('authenticated mixed transfer moves a concealed marker and physical vi
|
|||||||
}
|
}
|
||||||
assert.ok(proposed, `No native continuation at ${currentOwner.status}/${currentOwner.phase}/${currentOwner.decision?.kind ?? 'no decision'}.`);
|
assert.ok(proposed, `No native continuation at ${currentOwner.status}/${currentOwner.phase}/${currentOwner.decision?.kind ?? 'no decision'}.`);
|
||||||
if (view.response && !view.response.passed.includes(view.me)) proposed.action = { type: 'passResponse' };
|
if (view.response && !view.response.passed.includes(view.me)) proposed.action = { type: 'passResponse' };
|
||||||
// Keep the actual Atreides shipment affordable and avoid extra foreign
|
// Keep the actual Atreides shipment affordable and reserve every
|
||||||
// arrivals to the temporary marker World; all passes/skips are legal.
|
// Richese movement turn for the explicit shipments below. Richese may
|
||||||
|
// act before Atreides empties Caladan; letting its bot ship on that
|
||||||
|
// earlier turn would add unrelated visitors to the test's source pool.
|
||||||
else if ((proposed.actor === hostSeat.id || proposed.actor === ownerSeat.id) && proposed.action.type === 'bid') proposed.action = { type: 'passBid' };
|
else if ((proposed.actor === hostSeat.id || proposed.actor === ownerSeat.id) && proposed.action.type === 'bid') proposed.action = { type: 'passBid' };
|
||||||
else if ((proposed.actor === hostSeat.id || proposed.actor === ownerSeat.id) && proposed.action.type === 'richeseBid')
|
else if ((proposed.actor === hostSeat.id || proposed.actor === ownerSeat.id) && proposed.action.type === 'richeseBid')
|
||||||
proposed.action = { type: 'richeseBid', event: proposed.action.event, amount: 0, allyPayment: 0 };
|
proposed.action = { type: 'richeseBid', event: proposed.action.event, amount: 0, allyPayment: 0 };
|
||||||
else if (view.phase === 5 && view.active === proposed.actor && !view.response && !view.decision &&
|
else if (view.phase === 5 && view.active === proposed.actor && !view.response && !view.decision &&
|
||||||
!view.truthtrance && !view.phaseOpening &&
|
!view.truthtrance && !view.phaseOpening &&
|
||||||
(proposed.actor === guildSeat.id || proposed.actor === ownerSeat.id && firstMarkerPlaced))
|
(proposed.actor === guildSeat.id || proposed.actor === ownerSeat.id))
|
||||||
proposed.action = { type: 'endMovement' };
|
proposed.action = { type: 'endMovement' };
|
||||||
await act(proposed.cookie, proposed.action);
|
await act(proposed.cookie, proposed.action);
|
||||||
}
|
}
|
||||||
@@ -108,12 +109,16 @@ void test('authenticated mixed transfer moves a concealed marker and physical vi
|
|||||||
!own.players.find(player => player.id === own.me)!.shipped &&
|
!own.players.find(player => player.id === own.me)!.shipped &&
|
||||||
own.players.find(player => player.id === hostSeat.id)!.reserves === 0 &&
|
own.players.find(player => player.id === hostSeat.id)!.reserves === 0 &&
|
||||||
!!own.homeworldShipment && !own.homeworldShipment.blocked && !!own.richeseNoField?.canShip);
|
!!own.homeworldShipment && !own.homeworldShipment.blocked && !!own.richeseNoField?.canShip);
|
||||||
|
const beforePhysical = first.homeworlds?.worlds?.find(world => world.id === 'homeworld:atreides')?.forces[first.me];
|
||||||
|
assert.equal(beforePhysical?.normal ?? 0, 0, 'No unrelated Richese visit precedes the scripted shipment.');
|
||||||
|
assert.equal(beforePhysical?.elite ?? 0, 0, 'No unrelated Richese elite visit precedes the scripted shipment.');
|
||||||
const physical = homeworldShipmentChoice(first, 'homeworld:atreides',
|
const physical = homeworldShipmentChoice(first, 'homeworld:atreides',
|
||||||
{ 'homeworld:richese': { normal: 2, elite: 0 } });
|
{ 'homeworld:richese': { normal: 2, elite: 0 } });
|
||||||
assert.ok(physical.action, physical.blocked ?? 'The physical shipment is available.');
|
assert.ok(physical.action, physical.blocked ?? 'The physical shipment is available.');
|
||||||
await act(ownerSeat.cookie, physical.action);
|
await act(ownerSeat.cookie, physical.action);
|
||||||
firstMarkerPlaced = true; // Keep later owner turns for the test's explicit shipments.
|
|
||||||
const firstLanded = await advance(own => own.phase === 5 && own.players.find(player => player.id === own.me)?.shipped === true);
|
const firstLanded = await advance(own => own.phase === 5 && own.players.find(player => player.id === own.me)?.shipped === true);
|
||||||
|
assert.deepEqual(firstLanded.homeworlds?.worlds?.find(world => world.id === 'homeworld:atreides')?.forces[firstLanded.me],
|
||||||
|
{ normal: 2, elite: 0 }, 'The scripted shipment adds exactly two visitors.');
|
||||||
const physicalTurn = firstLanded.turn;
|
const physicalTurn = firstLanded.turn;
|
||||||
const markerTurn = await advance(own => own.status === 'playing' && own.turn > physicalTurn && own.phase === 5 &&
|
const markerTurn = await advance(own => own.status === 'playing' && own.turn > physicalTurn && own.phase === 5 &&
|
||||||
own.active === own.me && !own.players.find(player => player.id === own.me)!.shipped &&
|
own.active === own.me && !own.players.find(player => player.id === own.me)!.shipped &&
|
||||||
|
|||||||
Reference in new issue
Block a user