Avoid scanning operation history on agent polls
This commit is contained in:
@@ -23,6 +23,47 @@ async function enrolled() {
|
||||
return { ...hosts, ...context, hostId: host.id, credential };
|
||||
}
|
||||
|
||||
describe('agent preparation admission', () => {
|
||||
it('skips fleet preparation lookups for empty, health, read and unlimited library polls', async () => {
|
||||
const api = await enrolled();
|
||||
const { db } = await import('../../src/lib/server/db/index.js');
|
||||
const { fleetSettings, saveFleetSettings } = await import('../../src/lib/server/settings.js');
|
||||
saveFleetSettings({...fleetSettings(),preparationConcurrency:1});
|
||||
const prepare = vi.spyOn(db(),'prepare');
|
||||
expect(api.pendingHostOperations(api.hostId)).toEqual([]);
|
||||
api.queueHostOperation(api.hostId,'instance.inspect',{});
|
||||
api.pendingHostOperations(api.hostId,'health');
|
||||
api.queueHostOperation(api.hostId,'files.read',{path:'server.cfg'});
|
||||
api.pendingHostOperations(api.hostId,'read');
|
||||
saveFleetSettings({...fleetSettings(),preparationConcurrency:0});
|
||||
const download = api.queueHostOperation(api.hostId,'library.download',{});
|
||||
expect(api.pendingHostOperations(api.hostId,'write').map(op=>op.id)).toContain(download.id);
|
||||
expect(prepare.mock.calls.some(([sql])=>sql.includes('SELECT DISTINCT host_id'))).toBe(false);
|
||||
});
|
||||
|
||||
it('uses an indexed lookup and counts delivered preparation by host until all its jobs finish', async () => {
|
||||
const api = await enrolled();
|
||||
const other = api.createHost({name:'Other host'});
|
||||
api.enrollHost(api.createEnrollment(other.id).token,inventory);
|
||||
const { db } = await import('../../src/lib/server/db/index.js');
|
||||
const { fleetSettings, saveFleetSettings } = await import('../../src/lib/server/settings.js');
|
||||
saveFleetSettings({...fleetSettings(),preparationConcurrency:1});
|
||||
const download = api.queueHostOperation(api.hostId,'library.download',{});
|
||||
const imported = api.queueHostOperation(api.hostId,'library.import',{});
|
||||
const waiting = api.queueHostOperation(other.id,'library.download',{});
|
||||
const prepare = vi.spyOn(db(),'prepare');
|
||||
expect(api.pendingHostOperations(api.hostId,'write').map(op=>op.id)).toEqual([download.id,imported.id]);
|
||||
const sql = prepare.mock.calls.find(([sql])=>sql.includes('SELECT DISTINCT host_id'))![0];
|
||||
const plan = db().prepare(`EXPLAIN QUERY PLAN ${sql}`).all() as {detail:string}[];
|
||||
expect(plan.map(row=>row.detail).join('\n')).toContain('USING INDEX ec_host_operations_kind_state (kind=? AND state=?)');
|
||||
expect(api.pendingHostOperations(other.id,'write')).toEqual([]);
|
||||
api.reportHostOperation(api.hostId,download.id,{state:'completed'});
|
||||
expect(api.pendingHostOperations(other.id,'write')).toEqual([]);
|
||||
api.reportHostOperation(api.hostId,imported.id,{state:'failed'});
|
||||
expect(api.pendingHostOperations(other.id,'write').map(op=>op.id)).toEqual([waiting.id]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('agent credential usage writes', () => {
|
||||
it('writes on first use and at most once per minute, including after reopening the database', async () => {
|
||||
const api = await enrolled();
|
||||
|
||||
Reference in New Issue
Block a user