Recover unhealthy containers during create and rebuild
This commit is contained in:
@@ -44,6 +44,20 @@ it('enforces per-host removal and recovery limits independently of other hosts',
|
||||
expect(concurrencyBlocker('b','restart','other')).toBeNull();
|
||||
});
|
||||
|
||||
it('counts a creation recovery rebuild against rebuild capacity without losing its startup reservation', async () => {
|
||||
const { db } = await import('../../src/lib/server/db/index.js');
|
||||
const { fleetSettings, saveFleetSettings } = await import('../../src/lib/server/settings.js');
|
||||
const { concurrencyBlocker, lifecycleHolders } = await import('../../src/lib/server/provisioning/concurrency.js');
|
||||
db().prepare("INSERT INTO native_instances(id,server,host_id,library_id,image,port,created_at) VALUES('i','t5_test','host','lib','img',1,'2026-01-01')").run();
|
||||
db().prepare("INSERT INTO server_deployments(id,server,action,state,stage,started_at,triggered_by) VALUES('a','t5_test','create','running','recovery','2026-01-01','test')").run();
|
||||
db().prepare("INSERT INTO native_provisioning(deployment_id,instance_id,generation,recovery_step) VALUES('a','i',1,'rebuild')").run();
|
||||
saveFleetSettings({ ...fleetSettings(), rebuildConcurrency: 1, createConcurrencyPerHost: 1 });
|
||||
expect(lifecycleHolders()).toEqual([expect.objectContaining({ id: 'a', action: 'rebuild' })]);
|
||||
expect(concurrencyBlocker('b', 'rebuild', 'other')).toContain('rebuild');
|
||||
expect(concurrencyBlocker('b', 'create', 'host')).toContain('startup');
|
||||
expect(concurrencyBlocker('a', 'rebuild', 'host')).toBeNull();
|
||||
});
|
||||
|
||||
it('retains every capacity owner across failure, cancellation and migration without counting completed history', async () => {
|
||||
const { db } = await import('../../src/lib/server/db/index.js');
|
||||
const { createHost } = await import('../../src/lib/server/hosts/index.js');
|
||||
@@ -99,7 +113,7 @@ it('seeks capacity owners through active indexes instead of scanning retained jo
|
||||
let sql: string;
|
||||
try {
|
||||
expect(lifecycleHolders()).toEqual([]);
|
||||
sql = prepare.mock.calls.find(([sql])=>sql.startsWith('SELECT d.id,d.action'))![0];
|
||||
sql = prepare.mock.calls.find(([sql])=>sql.startsWith('SELECT d.id,'))![0];
|
||||
} finally { prepare.mockRestore(); }
|
||||
const plan = h.prepare(`EXPLAIN QUERY PLAN ${sql}`).all('[]') as {detail:string}[];
|
||||
const details = plan.map(row=>row.detail).join('\n');
|
||||
|
||||
Reference in New Issue
Block a user