pull/5471/head
Laurent Cozic 2021-09-18 11:27:26 +01:00
parent c35c5a5821
commit d71ac2e218
3 changed files with 87 additions and 1 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 297 B

View File

@ -0,0 +1,82 @@
import config from '../config';
import { Models } from '../models/factory';
import { afterAllTests, beforeAllDb, beforeEachDb, expectThrow, models, msleep } from '../utils/testing/testUtils';
import { Env } from '../utils/types';
import TaskService, { RunType, Task } from './TaskService';
const newService = () => {
return new TaskService(Env.Dev, models(), config());
};
describe('TaskService', function() {
beforeAll(async () => {
await beforeAllDb('TaskService');
});
afterAll(async () => {
await afterAllTests();
});
beforeEach(async () => {
await beforeEachDb();
});
test('should register a task', async function() {
const service = newService();
const task: Task = {
id: 'test',
description: '',
run: (_models: Models) => {},
schedule: '',
};
service.registerTask(task);
expect(service.tasks['test']).toBeTruthy();
await expectThrow(async () => service.registerTask(task));
});
test('should run a task', async function() {
const service = newService();
let finishTask = false;
let taskHasRan = false;
const task: Task = {
id: 'test',
description: '',
run: async (_models: Models) => {
const iid = setInterval(() => {
if (finishTask) {
clearInterval(iid);
taskHasRan = true;
}
}, 1);
},
schedule: '',
};
service.registerTask(task);
expect(service.taskState('test').running).toBe(false);
const startTime = new Date();
void service.runTask('test', RunType.Manual);
expect(service.taskState('test').running).toBe(true);
expect(service.taskState('test').lastCompletionTime).toBeFalsy();
expect(service.taskState('test').lastRunTime.getTime()).toBeGreaterThanOrEqual(startTime.getTime());
await msleep(1);
finishTask = true;
await msleep(3);
expect(taskHasRan).toBe(true);
expect(service.taskState('test').running).toBe(false);
expect(service.taskState('test').lastCompletionTime.getTime()).toBeGreaterThan(startTime.getTime());
});
});

View File

@ -22,7 +22,7 @@ export interface Task {
id: TaskId;
description: string;
schedule: string;
run(models: Models): Promise<void>;
run(models: Models): void;
}
export type Tasks = Record<TaskId, Task>;
@ -63,6 +63,8 @@ export default class TaskService extends BaseService {
return this.taskStates_[id];
}
// TODO: add tests
public async runTask(id: TaskId, runType: RunType) {
const state = this.taskState(id);
if (state.running) throw new Error(`Task is already running: ${id}`);
@ -93,6 +95,8 @@ export default class TaskService extends BaseService {
public async runInBackground() {
for (const [taskId, task] of Object.entries(this.tasks_)) {
if (!task.schedule) continue;
logger.info(`Scheduling task "${taskId}": ${task.schedule}`);
cron.schedule(task.schedule, async () => {