fix(team): align runtime telemetry tests with process rows
This commit is contained in:
parent
7f68d9823e
commit
76299a4e44
2 changed files with 79 additions and 45 deletions
|
|
@ -48,8 +48,8 @@ interface CachedTaskFile {
|
||||||
task: TeamTask | null;
|
task: TeamTask | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function cloneTasks<T>(tasks: T[]): T[] {
|
function cloneTasks<T>(tasks: readonly T[]): T[] {
|
||||||
return structuredClone(tasks);
|
return structuredClone([...tasks]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function cloneTask(task: TeamTask): TeamTask {
|
function cloneTask(task: TeamTask): TeamTask {
|
||||||
|
|
|
||||||
|
|
@ -78,13 +78,33 @@ const WORKSPACE_TRUST_TEST_ENV_NAMES = [
|
||||||
|
|
||||||
type WorkspaceTrustTestEnvName = (typeof WORKSPACE_TRUST_TEST_ENV_NAMES)[number];
|
type WorkspaceTrustTestEnvName = (typeof WORKSPACE_TRUST_TEST_ENV_NAMES)[number];
|
||||||
type RuntimeUsageStatsForTest = { rssBytes: number; cpuPercent?: number };
|
type RuntimeUsageStatsForTest = { rssBytes: number; cpuPercent?: number };
|
||||||
|
type RuntimeUsageProcessRowForTest = RuntimeUsageStatsForTest & {
|
||||||
|
pid: number;
|
||||||
|
ppid: number;
|
||||||
|
command: string;
|
||||||
|
runtimeTelemetrySource?: 'native' | 'wsl' | 'windows-host';
|
||||||
|
};
|
||||||
type RuntimeUsageStatsStubTarget = {
|
type RuntimeUsageStatsStubTarget = {
|
||||||
readRuntimeProcessRowsForUsageSnapshot: () => Promise<null>;
|
aliveRunByTeam?: Map<string, string>;
|
||||||
|
provisioningRunByTeam?: Map<string, string>;
|
||||||
|
runs?: Map<string, { child?: { pid?: number } }>;
|
||||||
|
getLiveTeamAgentRuntimeMetadata?: (
|
||||||
|
teamName: string
|
||||||
|
) => Promise<Map<string, { pid?: number; metricsPid?: number }>>;
|
||||||
|
readRuntimeProcessRowsForUsageSnapshot: (
|
||||||
|
teamName: string
|
||||||
|
) => Promise<RuntimeUsageProcessRowForTest[]>;
|
||||||
readProcessUsageStatsByPid: (
|
readProcessUsageStatsByPid: (
|
||||||
pids: readonly number[]
|
pids: readonly number[]
|
||||||
) => Promise<Map<number, RuntimeUsageStatsForTest>>;
|
) => Promise<Map<number, RuntimeUsageStatsForTest>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function addRuntimeUsagePidForTest(pids: Set<number>, pid: unknown): void {
|
||||||
|
if (typeof pid === 'number' && Number.isFinite(pid) && pid > 0) {
|
||||||
|
pids.add(pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function createRuntimeUsageStatsMap(
|
function createRuntimeUsageStatsMap(
|
||||||
entries: readonly (readonly [number, number])[]
|
entries: readonly (readonly [number, number])[]
|
||||||
): Map<number, RuntimeUsageStatsForTest> {
|
): Map<number, RuntimeUsageStatsForTest> {
|
||||||
|
|
@ -93,23 +113,53 @@ function createRuntimeUsageStatsMap(
|
||||||
|
|
||||||
function stubRuntimeUsageStatsByPid(
|
function stubRuntimeUsageStatsByPid(
|
||||||
service: TeamProvisioningService,
|
service: TeamProvisioningService,
|
||||||
entries: readonly (readonly [number, number])[]
|
entries: readonly (readonly [number, number])[] = []
|
||||||
): void {
|
): void {
|
||||||
const statsByPid = createRuntimeUsageStatsMap(entries);
|
const configuredStatsByPid = createRuntimeUsageStatsMap(entries);
|
||||||
const target = service as unknown as RuntimeUsageStatsStubTarget;
|
const target = service as unknown as RuntimeUsageStatsStubTarget;
|
||||||
target.readRuntimeProcessRowsForUsageSnapshot = async () => null;
|
|
||||||
|
target.readRuntimeProcessRowsForUsageSnapshot = async (teamName: string) => {
|
||||||
|
const statsByPid = new Map(configuredStatsByPid);
|
||||||
|
const candidatePids = new Set<number>();
|
||||||
|
const runId = target.aliveRunByTeam?.get(teamName) ?? target.provisioningRunByTeam?.get(teamName);
|
||||||
|
const run = runId ? target.runs?.get(runId) : undefined;
|
||||||
|
addRuntimeUsagePidForTest(candidatePids, run?.child?.pid);
|
||||||
|
|
||||||
|
const liveMetadataByMember = await target.getLiveTeamAgentRuntimeMetadata?.(teamName);
|
||||||
|
for (const metadata of liveMetadataByMember?.values() ?? []) {
|
||||||
|
addRuntimeUsagePidForTest(candidatePids, metadata.pid);
|
||||||
|
addRuntimeUsagePidForTest(candidatePids, metadata.metricsPid);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const pid of candidatePids) {
|
||||||
|
if (!statsByPid.has(pid)) {
|
||||||
|
statsByPid.set(pid, { rssBytes: pid * 1_000 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [...statsByPid].map(([pid, stats]) => ({
|
||||||
|
pid,
|
||||||
|
ppid: 0,
|
||||||
|
command: `test-runtime-${pid}`,
|
||||||
|
...stats,
|
||||||
|
runtimeTelemetrySource: 'native' as const,
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
target.readProcessUsageStatsByPid = async (pids: readonly number[]) => {
|
target.readProcessUsageStatsByPid = async (pids: readonly number[]) => {
|
||||||
const requestedPids = new Set(pids);
|
const requestedPids = new Set(pids);
|
||||||
return new Map([...statsByPid].filter(([pid]) => requestedPids.has(pid)));
|
return new Map(
|
||||||
|
[...pids]
|
||||||
|
.filter((pid) => Number.isFinite(pid) && pid > 0)
|
||||||
|
.map((pid) => [
|
||||||
|
pid,
|
||||||
|
configuredStatsByPid.get(pid) ?? { rssBytes: pid * 1_000 },
|
||||||
|
] as const)
|
||||||
|
.filter(([pid]) => requestedPids.has(pid))
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function createRuntimeUsageStatsByPid(
|
|
||||||
pids: readonly number[]
|
|
||||||
): Map<number, RuntimeUsageStatsForTest> {
|
|
||||||
return createRuntimeUsageStatsMap(pids.map((pid) => [pid, pid * 1_000] as const));
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('Team agent launch matrix safe e2e', () => {
|
describe('Team agent launch matrix safe e2e', () => {
|
||||||
let tempDir: string;
|
let tempDir: string;
|
||||||
let tempClaudeRoot: string;
|
let tempClaudeRoot: string;
|
||||||
|
|
@ -14709,8 +14759,7 @@ describe('Team agent launch matrix safe e2e', () => {
|
||||||
['alice', { alive: true, pid: 64102, model: 'haiku-stale' }],
|
['alice', { alive: true, pid: 64102, model: 'haiku-stale' }],
|
||||||
['bob', { alive: true, pid: 64103, model: 'sonnet-stale' }],
|
['bob', { alive: true, pid: 64103, model: 'sonnet-stale' }],
|
||||||
]);
|
]);
|
||||||
(svc as any).readProcessUsageStatsByPid = async (pids: number[]) =>
|
stubRuntimeUsageStatsByPid(svc);
|
||||||
createRuntimeUsageStatsByPid(pids);
|
|
||||||
|
|
||||||
const staleSnapshot = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
const staleSnapshot = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
||||||
expect(staleSnapshot).toMatchObject({
|
expect(staleSnapshot).toMatchObject({
|
||||||
|
|
@ -14758,8 +14807,7 @@ describe('Team agent launch matrix safe e2e', () => {
|
||||||
['alice', { alive: true, pid: 64502, model: 'haiku-before-stop' }],
|
['alice', { alive: true, pid: 64502, model: 'haiku-before-stop' }],
|
||||||
['bob', { alive: true, pid: 64503, model: 'sonnet-before-stop' }],
|
['bob', { alive: true, pid: 64503, model: 'sonnet-before-stop' }],
|
||||||
]);
|
]);
|
||||||
(svc as any).readProcessUsageStatsByPid = async (pids: number[]) =>
|
stubRuntimeUsageStatsByPid(svc);
|
||||||
createRuntimeUsageStatsByPid(pids);
|
|
||||||
|
|
||||||
const beforeStop = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
const beforeStop = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
||||||
expect(beforeStop).toMatchObject({
|
expect(beforeStop).toMatchObject({
|
||||||
|
|
@ -14885,8 +14933,7 @@ describe('Team agent launch matrix safe e2e', () => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
(svc as any).readProcessUsageStatsByPid = async (pids: number[]) =>
|
stubRuntimeUsageStatsByPid(svc);
|
||||||
createRuntimeUsageStatsByPid(pids);
|
|
||||||
|
|
||||||
const afterSwitch = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
const afterSwitch = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
||||||
expect(afterSwitch).toMatchObject({
|
expect(afterSwitch).toMatchObject({
|
||||||
|
|
@ -14935,8 +14982,7 @@ describe('Team agent launch matrix safe e2e', () => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
(svc as any).readProcessUsageStatsByPid = async (pids: number[]) =>
|
stubRuntimeUsageStatsByPid(svc);
|
||||||
createRuntimeUsageStatsByPid(pids);
|
|
||||||
|
|
||||||
const afterSwitch = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
const afterSwitch = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
||||||
expect(afterSwitch).toMatchObject({
|
expect(afterSwitch).toMatchObject({
|
||||||
|
|
@ -14976,8 +15022,7 @@ describe('Team agent launch matrix safe e2e', () => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
(svc as any).readProcessUsageStatsByPid = async (pids: number[]) =>
|
stubRuntimeUsageStatsByPid(svc);
|
||||||
createRuntimeUsageStatsByPid(pids);
|
|
||||||
|
|
||||||
const snapshot = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
const snapshot = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
||||||
expect(snapshot.members.alice).toMatchObject({
|
expect(snapshot.members.alice).toMatchObject({
|
||||||
|
|
@ -15014,8 +15059,7 @@ describe('Team agent launch matrix safe e2e', () => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
(svc as any).readProcessUsageStatsByPid = async (pids: number[]) =>
|
stubRuntimeUsageStatsByPid(svc);
|
||||||
createRuntimeUsageStatsByPid(pids);
|
|
||||||
|
|
||||||
const snapshot = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
const snapshot = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
||||||
expect(snapshot.members.alice).toMatchObject({
|
expect(snapshot.members.alice).toMatchObject({
|
||||||
|
|
@ -15050,8 +15094,7 @@ describe('Team agent launch matrix safe e2e', () => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
(svc as any).readProcessUsageStatsByPid = async (pids: number[]) =>
|
stubRuntimeUsageStatsByPid(svc);
|
||||||
createRuntimeUsageStatsByPid(pids);
|
|
||||||
|
|
||||||
const snapshot = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
const snapshot = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
||||||
expect(snapshot.members.bob).toMatchObject({
|
expect(snapshot.members.bob).toMatchObject({
|
||||||
|
|
@ -15086,8 +15129,7 @@ describe('Team agent launch matrix safe e2e', () => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
(svc as any).readProcessUsageStatsByPid = async (pids: number[]) =>
|
stubRuntimeUsageStatsByPid(svc);
|
||||||
createRuntimeUsageStatsByPid(pids);
|
|
||||||
|
|
||||||
const snapshot = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
const snapshot = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
||||||
expect(snapshot.members.bob).toMatchObject({
|
expect(snapshot.members.bob).toMatchObject({
|
||||||
|
|
@ -15131,8 +15173,7 @@ describe('Team agent launch matrix safe e2e', () => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
(svc as any).readProcessUsageStatsByPid = async (pids: number[]) =>
|
stubRuntimeUsageStatsByPid(svc);
|
||||||
createRuntimeUsageStatsByPid(pids);
|
|
||||||
|
|
||||||
const snapshot = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
const snapshot = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
||||||
expect(snapshot.members.reviewer).toMatchObject({
|
expect(snapshot.members.reviewer).toMatchObject({
|
||||||
|
|
@ -15176,8 +15217,7 @@ describe('Team agent launch matrix safe e2e', () => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
(svc as any).readProcessUsageStatsByPid = async (pids: number[]) =>
|
stubRuntimeUsageStatsByPid(svc);
|
||||||
createRuntimeUsageStatsByPid(pids);
|
|
||||||
|
|
||||||
const snapshot = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
const snapshot = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
||||||
expect(snapshot.members.reviewer).toMatchObject({
|
expect(snapshot.members.reviewer).toMatchObject({
|
||||||
|
|
@ -15312,8 +15352,7 @@ describe('Team agent launch matrix safe e2e', () => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
(svc as any).readProcessUsageStatsByPid = async (pids: number[]) =>
|
stubRuntimeUsageStatsByPid(svc);
|
||||||
createRuntimeUsageStatsByPid(pids);
|
|
||||||
|
|
||||||
const afterSwitch = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
const afterSwitch = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
||||||
expect(afterSwitch).toMatchObject({
|
expect(afterSwitch).toMatchObject({
|
||||||
|
|
@ -15362,8 +15401,7 @@ describe('Team agent launch matrix safe e2e', () => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
(svc as any).readProcessUsageStatsByPid = async (pids: number[]) =>
|
stubRuntimeUsageStatsByPid(svc);
|
||||||
createRuntimeUsageStatsByPid(pids);
|
|
||||||
|
|
||||||
const afterSwitch = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
const afterSwitch = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
||||||
expect(afterSwitch).toMatchObject({
|
expect(afterSwitch).toMatchObject({
|
||||||
|
|
@ -15406,8 +15444,7 @@ describe('Team agent launch matrix safe e2e', () => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
(svc as any).readProcessUsageStatsByPid = async (pids: number[]) =>
|
stubRuntimeUsageStatsByPid(svc);
|
||||||
createRuntimeUsageStatsByPid(pids);
|
|
||||||
|
|
||||||
const snapshot = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
const snapshot = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
||||||
expect(snapshot).toMatchObject({
|
expect(snapshot).toMatchObject({
|
||||||
|
|
@ -15451,8 +15488,7 @@ describe('Team agent launch matrix safe e2e', () => {
|
||||||
['bob', { alive: true, pid: 64704, model: 'opencode/minimax-stale' }],
|
['bob', { alive: true, pid: 64704, model: 'opencode/minimax-stale' }],
|
||||||
['tom', { alive: true, pid: 64705, model: 'opencode/nemotron-stale' }],
|
['tom', { alive: true, pid: 64705, model: 'opencode/nemotron-stale' }],
|
||||||
]);
|
]);
|
||||||
(svc as any).readProcessUsageStatsByPid = async (pids: number[]) =>
|
stubRuntimeUsageStatsByPid(svc);
|
||||||
createRuntimeUsageStatsByPid(pids);
|
|
||||||
|
|
||||||
const staleSnapshot = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
const staleSnapshot = await svc.getTeamAgentRuntimeSnapshot(teamName);
|
||||||
expect(staleSnapshot).toMatchObject({
|
expect(staleSnapshot).toMatchObject({
|
||||||
|
|
@ -15576,8 +15612,7 @@ describe('Team agent launch matrix safe e2e', () => {
|
||||||
['bob', { alive: true, pid: 50203, model: 'sonnet-runtime' }],
|
['bob', { alive: true, pid: 50203, model: 'sonnet-runtime' }],
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
(svc as any).readProcessUsageStatsByPid = async (pids: number[]) =>
|
stubRuntimeUsageStatsByPid(svc);
|
||||||
createRuntimeUsageStatsByPid(pids);
|
|
||||||
|
|
||||||
const firstSnapshot = await svc.getTeamAgentRuntimeSnapshot(firstTeamName);
|
const firstSnapshot = await svc.getTeamAgentRuntimeSnapshot(firstTeamName);
|
||||||
const secondSnapshot = await svc.getTeamAgentRuntimeSnapshot(secondTeamName);
|
const secondSnapshot = await svc.getTeamAgentRuntimeSnapshot(secondTeamName);
|
||||||
|
|
@ -15656,8 +15691,7 @@ describe('Team agent launch matrix safe e2e', () => {
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
(svc as any).readProcessUsageStatsByPid = async (pids: number[]) =>
|
stubRuntimeUsageStatsByPid(svc);
|
||||||
createRuntimeUsageStatsByPid(pids);
|
|
||||||
|
|
||||||
const beforeStop = await svc.getTeamAgentRuntimeSnapshot(stoppedTeamName);
|
const beforeStop = await svc.getTeamAgentRuntimeSnapshot(stoppedTeamName);
|
||||||
expect(beforeStop.members['team-lead']).toMatchObject({
|
expect(beforeStop.members['team-lead']).toMatchObject({
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue