41 lines
3.2 KiB
TypeScript
41 lines
3.2 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import {test} from 'node:test';
|
|
import {database} from '../lib/store.ts';
|
|
import {dashboard,getRun,start,step} from '../lib/scanner.ts';
|
|
import type {Run} from '../lib/model.ts';
|
|
import {result} from '../lib/access.ts';
|
|
import {useTestDatabase} from './test-database.ts';
|
|
useTestDatabase('scanner');
|
|
test('only one shared manual run can be started',async()=>{
|
|
const [first,second]=await Promise.all([start(false),start(false)]);
|
|
assert.equal(first?.id,second?.id);assert.equal(second?.force,false);
|
|
});
|
|
test('a failed record transaction preserves its queue and can resume',async()=>{
|
|
const run=(await getRun())!;run.phase='links';run.links=['http://127.0.0.1/'];run.totalLinks=1;run.checked=0;
|
|
const db=await database();await db.query("UPDATE scan SET data=$1,lease=0,token='' WHERE id=1",[JSON.stringify(run)]);
|
|
await db.query("CREATE FUNCTION reject_record() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN RAISE EXCEPTION 'simulated disk failure'; END $$");
|
|
await db.query('CREATE TRIGGER fail_record BEFORE INSERT ON records FOR EACH ROW EXECUTE FUNCTION reject_record()');
|
|
try{await assert.rejects(step(),/simulated disk failure/);const afterFailure=(await getRun())!;assert.deepEqual(afterFailure.links,run.links);assert.equal(afterFailure.checked,0);assert.equal((await dashboard()).checks['http://127.0.0.1/'],undefined);}
|
|
finally{await db.query('DROP TRIGGER fail_record ON records');await db.query('DROP FUNCTION reject_record()');}
|
|
const resumed=(await step())!;assert.equal(resumed.status,'complete');assert.equal(resumed.checked,1);assert.equal((await dashboard()).checks['http://127.0.0.1/'].status,'network');
|
|
});
|
|
test('an active lease prevents two workers from processing the same queue',async()=>{
|
|
const run=(await start(false))!;run.phase='links';run.links=['http://127.0.0.1/'];
|
|
await (await database()).query('UPDATE scan SET data=$1,lease=$2,token=$3 WHERE id=1',[JSON.stringify(run),Date.now()+60000,'another-worker']);
|
|
const unchanged=(await step()) as Run;assert.deepEqual(unchanged.links,run.links);assert.equal(unchanged.checked,0);
|
|
});
|
|
|
|
test('a step consumes only one bibliography link',async()=>{
|
|
const db=await database(),run=(await getRun())!;run.phase='links';run.links=['http://127.0.0.1/a','http://127.0.0.1/b'];run.checked=0;
|
|
await db.query("UPDATE scan SET data=$1,lease=0,token='' WHERE id=1",[JSON.stringify(run)]);
|
|
const after=(await step())!;assert.equal(after.checked,1);assert.deepEqual(after.links,['http://127.0.0.1/b']);assert.equal(after.status,'running');
|
|
});
|
|
|
|
test('previous HTTP-only results are not presented as available after a rules upgrade',async()=>{
|
|
const db=await database(),old={url:'https://books.org/old',status:'ok',reason:'HTTP 200',checkedAt:new Date().toISOString()};
|
|
await db.query('INSERT INTO records(key,value) VALUES($1,$2)', ['link:'+old.url,JSON.stringify(old)]);
|
|
assert.equal((await dashboard()).checks[old.url].status,'unknown');
|
|
const current=result(old.url,'auth','Для чтения книги требуется авторизация.');await db.query('UPDATE records SET value=$1 WHERE key=$2',[JSON.stringify(current),'link:'+old.url]);
|
|
assert.equal((await dashboard()).checks[old.url].status,'auth');
|
|
});
|