mirror of
https://github.com/garrytan/gstack.git
synced 2026-06-17 07:10:12 +02:00
fix: ios-qa daemon scenarios use unique pidfiles under --concurrent
All scenarios shared join(workDir, 'daemon.pid') through a module-scope workDir binding that beforeEach reassigns mid-flight under bun --concurrent. First daemon claims; siblings get already_running against the test process's own always-alive pid and fail in milliseconds — the failure mode seen at 15-way gate concurrency. Per-claim unique pidfiles keep the single-instance semantics under test. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -36,6 +36,16 @@ afterEach(() => {
|
||||
rmSync(workDir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
// Under `bun test --concurrent`, overlapping tests read the SAME shared
|
||||
// `workDir` binding (beforeEach reassigns it mid-flight), so a fixed
|
||||
// 'daemon.pid' name collides: the first daemon claims it and every sibling
|
||||
// gets already_running against the test process's own (always-alive) pid —
|
||||
// the exact failure seen in full gate runs at 15-way concurrency. Unique
|
||||
// per-claim pidfiles keep the single-instance semantics under test while
|
||||
// removing the cross-test collision.
|
||||
let pidfileSeq = 0;
|
||||
const uniquePidfile = () => join(workDir, `daemon-${++pidfileSeq}.pid`);
|
||||
|
||||
interface StubState {
|
||||
loggedIn: boolean;
|
||||
username: string;
|
||||
@@ -205,7 +215,7 @@ class AppState {
|
||||
const daemon = await startDaemon({
|
||||
loopbackPort: 0,
|
||||
tailnetEnabled: false,
|
||||
pidfilePath: join(workDir, 'daemon.pid'),
|
||||
pidfilePath: uniquePidfile(),
|
||||
tunnelProvider: async () => tunnel,
|
||||
});
|
||||
if ('error' in daemon) throw new Error(daemon.error);
|
||||
@@ -249,7 +259,7 @@ describe('ios-qa E2E (agent-flow simulation)', () => {
|
||||
const daemon = await startDaemon({
|
||||
loopbackPort: 0,
|
||||
tailnetEnabled: false,
|
||||
pidfilePath: join(workDir, 'daemon.pid'),
|
||||
pidfilePath: uniquePidfile(),
|
||||
tunnelProvider: async () => tunnel,
|
||||
});
|
||||
if ('error' in daemon) throw new Error(daemon.error);
|
||||
@@ -314,7 +324,7 @@ describe('ios-qa E2E (agent-flow simulation)', () => {
|
||||
const daemon = await startDaemon({
|
||||
loopbackPort: 0,
|
||||
tailnetEnabled: false,
|
||||
pidfilePath: join(workDir, 'daemon.pid'),
|
||||
pidfilePath: uniquePidfile(),
|
||||
tunnelProvider: async () => tunnel,
|
||||
});
|
||||
if ('error' in daemon) throw new Error(daemon.error);
|
||||
@@ -352,7 +362,7 @@ describe('ios-qa E2E (agent-flow simulation)', () => {
|
||||
const daemon = await startDaemon({
|
||||
loopbackPort: 0,
|
||||
tailnetEnabled: true,
|
||||
pidfilePath: join(workDir, 'daemon.pid'),
|
||||
pidfilePath: uniquePidfile(),
|
||||
tunnelProvider: async () => tunnel,
|
||||
probeImpl: async () => ({ ok: true, ownIdentity: 'mac@e2e' }),
|
||||
whoIsImpl: async () => ({ identity: 'agent@e2e', raw: {} }),
|
||||
@@ -430,7 +440,7 @@ describe('ios-qa E2E (agent-flow simulation)', () => {
|
||||
const daemon = await startDaemon({
|
||||
loopbackPort: 0,
|
||||
tailnetEnabled: true,
|
||||
pidfilePath: join(workDir, 'daemon.pid'),
|
||||
pidfilePath: uniquePidfile(),
|
||||
tunnelProvider: async () => tunnel,
|
||||
probeImpl: async () => ({ ok: true, ownIdentity: 'mac@e2e' }),
|
||||
whoIsImpl: async () => ({ identity: 'readonly@e2e', raw: {} }),
|
||||
|
||||
Reference in New Issue
Block a user