57 lines
1.5 KiB
TypeScript
57 lines
1.5 KiB
TypeScript
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();
|
|
});
|
|
});
|