Files
ihaleist/tests/ai-jobs.test.mjs
T

48 lines
2.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import test,{after} from 'node:test';
import assert from 'node:assert/strict';
import {mkdtempSync,rmSync} from 'node:fs';
import {join} from 'node:path';
import {tmpdir} from 'node:os';
const dir=mkdtempSync(join(tmpdir(),'ihaleist-jobs-'));process.env.IHALEIST_USER_DATA_DIR=dir;
const jobs=await import('../server/ai-job-store.mjs');
after(()=>rmSync(dir,{recursive:true,force:true}));
test('durable jobs are idempotent and account scoped',()=>{
const first=jobs.createAiJob('a','request-1','teklif-denetim',{ikn:'2026/1',taslak:'private'});
assert.equal(jobs.createAiJob('a','request-1','teklif-denetim',{ikn:'2026/1',taslak:'private'}).id,first.id);
assert.throws(()=>jobs.createAiJob('a','request-1','teklif-denetim',{taslak:'other'}),/farklı kaynak/);
assert.equal(jobs.getAiJob('b',first.id),null);assert.deepEqual(jobs.listAiJobs('b'),[]);
assert.equal(jobs.cancelAiJob('b',first.id),false);
const claimed=jobs.claimAiJob();assert.equal(claimed.input.taslak,'private');
assert.equal(jobs.finishAiJob(first.id,'wrong',{success:true}),false);
assert.equal(jobs.finishAiJob(first.id,claimed.runId,{success:true,answer:'done'}),true);
assert.equal(jobs.getAiJob('a',first.id).result.answer,'done');
assert.equal(jobs.getAiJob('a',first.id).input.taslak,'private');
assert.equal(jobs.listAiJobs('a')[0].input,undefined);
});
test('lost workers become interrupted without automatic provider replay; retry and cancellation reject late results',()=>{
const first=jobs.createAiJob('a','request-2','teklif-taslak',{ikn:'2026/2'});
const claimed=jobs.claimAiJob(Date.now()-120000);
assert.equal(jobs.claimAiJob(),null);
assert.equal(jobs.getAiJob('a',first.id).state,'interrupted');
assert.equal(jobs.finishAiJob(first.id,claimed.runId,{success:true}),false);
assert.equal(jobs.retryAiJob('a',first.id),true);
const restarted=jobs.claimAiJob();assert.notEqual(restarted.runId,claimed.runId);
assert.equal(jobs.cancelAiJob('a',first.id),true);
assert.equal(jobs.heartbeatAiJob(first.id,restarted.runId),false);
assert.equal(jobs.finishAiJob(first.id,restarted.runId,{success:true}),false);
assert.equal(jobs.getAiJob('a',first.id).state,'cancelled');
});
test('runner stores results independently of an HTTP connection',async()=>{
const {startAiJobRunner}=await import('../server/ai-job-runner.mjs');
const job=jobs.createAiJob('runner','request-run','belge-sor',{ikn:'2026/8',soru:'teslim'});
let finish;
const runner=startAiJobRunner(async()=>new Promise(resolve=>{finish=resolve;}),{intervalMs:100000});
try {
runner.wake();assert.equal(jobs.getAiJob('runner',job.id).state,'running');
finish({success:true,cevap:'Stored answer'});
await new Promise(resolve=>setImmediate(resolve));
assert.equal(jobs.getAiJob('runner',job.id).result.cevap,'Stored answer');
} finally {runner.stop();}
});