job-store.test.mjs 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. import test from 'node:test';
  2. import assert from 'node:assert/strict';
  3. import { mkdtemp, rm } from 'node:fs/promises';
  4. import { tmpdir } from 'node:os';
  5. import { join } from 'node:path';
  6. import { JobStore } from '../src/job-store.mjs';
  7. test('清理旧重试任务时不删除新任务的幂等映射', async t => {
  8. const directory = await mkdtemp(join(tmpdir(), 'yuban-job-store-test-'));
  9. t.after(() => rm(directory, { recursive: true, force: true }));
  10. const store = new JobStore(directory, 86_400_000);
  11. await store.init();
  12. const common = {
  13. ownerKey: 'owner',
  14. idempotencyKey: 'same-key',
  15. status: 'failed',
  16. stage: 'failed',
  17. progress: 10,
  18. createdAt: '2026-08-05T00:00:00.000Z',
  19. updatedAt: '2026-08-05T00:00:00.000Z',
  20. };
  21. await store.create({ ...common, id: 'old', expiresAt: '2026-08-05T00:01:00.000Z' });
  22. await store.create({
  23. ...common,
  24. id: 'new',
  25. status: 'queued',
  26. expiresAt: '2026-08-07T00:00:00.000Z',
  27. });
  28. await store.cleanupExpired(Date.parse('2026-08-06T00:00:00.000Z'));
  29. assert.equal(store.findByIdempotency('same-key')?.id, 'new');
  30. });
  31. test('同一任务的并发状态写入使用独立临时文件', async t => {
  32. const directory = await mkdtemp(join(tmpdir(), 'yuban-job-store-race-test-'));
  33. t.after(() => rm(directory, { recursive: true, force: true }));
  34. const store = new JobStore(directory, 86_400_000);
  35. await store.init();
  36. const now = new Date().toISOString();
  37. await store.create({
  38. id: 'race-job',
  39. status: 'running',
  40. stage: 'transcribing',
  41. progress: 50,
  42. createdAt: now,
  43. updatedAt: now,
  44. expiresAt: new Date(Date.now() + 86_400_000).toISOString(),
  45. });
  46. await Promise.all([
  47. store.update('race-job', { progress: 60 }),
  48. store.update('race-job', { heartbeatAt: now }),
  49. ]);
  50. assert.equal(store.get('race-job').id, 'race-job');
  51. });