Add fleet topology epidemiology: strain plague map and mining interrupt fixes.
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Strain nodes replace host nodes in FleetTopologyMap; server queues epidemiology_fix on auth and reports interrupts to AI and Seer.
This commit is contained in:
@@ -365,6 +365,15 @@ export const api = {
|
||||
'/fleet/modules/push',
|
||||
{ method: 'POST', body: JSON.stringify(body) },
|
||||
),
|
||||
postFleetGraft: (body: { source_agent_id: string; target_agent_id: string }) =>
|
||||
fetchJSON<{
|
||||
success: boolean;
|
||||
source_id?: string;
|
||||
target_id?: string;
|
||||
graft_policy?: Record<string, unknown>;
|
||||
pushed?: boolean;
|
||||
error?: string;
|
||||
}>('/fleet/graft', { method: 'POST', body: JSON.stringify(body) }),
|
||||
listStrainCards: (agentId?: string) =>
|
||||
fetchJSON<import('../types').StrainCard[]>(
|
||||
agentId ? `/fleet/strain-cards?agent_id=${encodeURIComponent(agentId)}` : '/fleet/strain-cards',
|
||||
|
||||
@@ -231,6 +231,21 @@ describe('AccessDepthPanel', () => {
|
||||
expect(screen.getByText(/parent 11112222/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows genealogy graft note when fleet AI and roles enabled', async () => {
|
||||
vi.mocked(api.getConfig).mockResolvedValueOnce({
|
||||
server: { ai_control_enabled: true, fleet_roles_enabled: true },
|
||||
} as Awaited<ReturnType<typeof api.getConfig>>);
|
||||
renderPanel(
|
||||
mockAgent({
|
||||
platform: 'windows',
|
||||
graft_tier: 'winrm',
|
||||
graft_source_strain: '#aabbcc',
|
||||
}),
|
||||
);
|
||||
expect(await screen.findByText(/genealogy graft pending/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/winrm/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders lineage strain card with play control', async () => {
|
||||
vi.mocked(api.listStrainCards).mockResolvedValueOnce([
|
||||
{
|
||||
|
||||
@@ -99,6 +99,7 @@ describe('PathTracerPage', () => {
|
||||
installIntervalHook();
|
||||
useWebSocketMock.mockReturnValue(wsValue());
|
||||
vi.spyOn(api, 'listAgents').mockResolvedValue([]);
|
||||
vi.spyOn(api, 'getConfig').mockResolvedValue({ server: {} });
|
||||
vi.spyOn(api, 'startTrace').mockResolvedValue({ session_id: 'sess-1', hops: [] });
|
||||
vi.spyOn(api, 'getTraceStatus').mockResolvedValue({ session_id: 'sess-1', ready: false, hops: [] });
|
||||
vi.spyOn(api, 'getTraceQR').mockResolvedValue({ config: 'wg-conf', qr_png_b64: 'abc123' });
|
||||
@@ -150,6 +151,14 @@ describe('PathTracerPage', () => {
|
||||
expect(screen.getByText(/Path Tracer/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows genealogy graft note when AI control and fleet roles enabled', async () => {
|
||||
vi.mocked(api.getConfig).mockResolvedValue({
|
||||
server: { ai_control_enabled: true, fleet_roles_enabled: true },
|
||||
} as Awaited<ReturnType<typeof api.getConfig>>);
|
||||
renderPage();
|
||||
expect(await screen.findByText(/Genealogy grafting is active/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows online agents from WebSocket and offline agents separately', () => {
|
||||
useWebSocketMock.mockReturnValue(
|
||||
wsValue({ agents: [windowsAgent, linuxAgent, offlineAgent] }),
|
||||
|
||||
Reference in New Issue
Block a user