Phase6
Some checks failed
CI / Node — lint, typecheck, test, build (push) Failing after 9s
CI / Go — node-agent tests (push) Failing after 8s
CI / Go — edge-gateway build (push) Successful in 13s

This commit is contained in:
smueller
2026-06-26 13:11:28 +02:00
parent d29a02f2a4
commit 49a98ee31d
81 changed files with 1462 additions and 53 deletions

View File

@@ -0,0 +1,56 @@
import { describe, expect, it } from 'vitest';
import {
canAllocateOnNode,
canStartOnNode,
selectNodeForAllocation,
} from './index';
import type { NodeSnapshot } from './types';
function node(partial: Partial<NodeSnapshot> & Pick<NodeSnapshot, 'id'>): NodeSnapshot {
return {
status: 'ONLINE',
maxServers: 10,
maxRamMb: 16384,
platformRamMb: 2048,
activeServers: 0,
lastHeartbeatAt: new Date(),
reservedRamMb: 0,
activeAllocationCount: 0,
...partial,
};
}
describe('scheduler capacity', () => {
it('rejects maintenance and draining nodes for new allocations', () => {
const maintenance = node({ id: 'a', status: 'MAINTENANCE' });
const draining = node({ id: 'b', status: 'DRAINING' });
expect(canAllocateOnNode(maintenance, 1024)).toBe(false);
expect(canAllocateOnNode(draining, 1024)).toBe(false);
expect(canStartOnNode(draining, 1024)).toBe(true);
});
it('picks the least loaded node for placement', () => {
const lightlyLoaded = node({ id: 'light', reservedRamMb: 1024 });
const heavilyLoaded = node({ id: 'heavy', reservedRamMb: 8192 });
const selected = selectNodeForAllocation(
[heavilyLoaded, lightlyLoaded],
2048,
);
expect(selected?.id).toBe('light');
});
it('returns null when no node has enough RAM', () => {
const saturated = node({
id: 'full',
reservedRamMb: 14000,
maxRamMb: 16384,
platformRamMb: 2048,
});
expect(selectNodeForAllocation([saturated], 4096)).toBeNull();
});
});