import { describe, it, before, after } from 'mocha'; import BoxError from '../boxerror.js'; import common from './common.js'; import assert from 'node:assert/strict'; import fs from 'node:fs'; import paths from '../paths.js'; import safe from 'safetydance'; import tasks from '../tasks.js'; import _ from '../underscore.js'; describe('task', function () { const { setup, cleanup } = common; before(setup); after(cleanup); let taskId; const TASK = { type: 'tasktype', args: [ 1 ], percent: 0, message: 'Queued' }; it('add succeeds', async function () { const id = await tasks.add(TASK.type, TASK.args); assert.ok(id); taskId = id; }); it('get succeeds', async function () { const task = await tasks.get(taskId); assert.deepEqual(_.pick(task, Object.keys(TASK)), TASK); }); it('get random task fails', async function () { const task = await tasks.get('random'); assert.equal(task, null); }); it('update succeeds', async function () { TASK.percent = 34; TASK.message = 'almost ther'; await tasks.update(taskId, { percent: TASK.percent, message: TASK.message }); const task = await tasks.get(taskId); assert.deepEqual(_.pick(task, Object.keys(TASK)), TASK); }); it('list succeeds - does not exist', async function () { const result = await tasks.list(1, 1, { type: 'randomtask' }); assert.equal(result.length, 0); }); it('list succeeds - by type', async function () { const result = await tasks.list(1, 1, { type: TASK.type }); assert.equal(result.length, 1); assert.deepEqual(_.pick(result[0], Object.keys(TASK)), TASK); }); it('list succeeds - all', async function () { const result = await tasks.list(1, 1, { type: null }); assert.equal(result.length, 1); assert.deepEqual(_.pick(result[0], Object.keys(TASK)), TASK); }); it('del succeeds', async function () { await tasks._del(taskId); const task = await tasks.get(taskId); assert.equal(task, null); }); it('del missing task fails', async function () { const [error] = await safe(tasks._del('1235')); assert.equal(error.reason, BoxError.NOT_FOUND); }); it('can run valid task - success', async function () { const successTaskId = await tasks.add(tasks._TASK_IDENTITY, [ 'ping' ]); const [error, result] = await safe(tasks.startTask(successTaskId, {})); if (error) throw error; assert.equal(result, 'ping'); }); it('can run valid task - error', async function () { const errorTaskId = await tasks.add(tasks._TASK_ERROR, [ 'ping' ]); const [error, result] = await safe(tasks.startTask(errorTaskId, {})); if (!error) throw new Error('expecting task to fail'); assert.equal(error.message, 'Task crashed. Failed for arg: ping'); assert.ok(!(result)); }); it('can get logs of crash', async function () { const crashTaskId = await tasks.add(tasks._TASK_CRASH, [ 'ping' ]); const [error, result] = await safe(tasks.startTask(crashTaskId, {})); if (!error) throw new Error('expecting task to crash'); assert.ok(error.message.includes(`Task ${crashTaskId} crashed`)); assert.ok(!(result)); const logs = fs.readFileSync(`${paths.TASKS_LOG_DIR}/${crashTaskId}.log`, 'utf8'); assert.ok(logs.includes('Crashing for arg: ping')); }); it('can stop task', async function () { const sleepTaskId = await tasks.add(tasks._TASK_SLEEP, [ 10000 ]); setTimeout(async function () { await tasks.stopTask(sleepTaskId); }, 2000); const [error, result] = await safe(tasks.startTask(sleepTaskId, {})); if (!error) throw new Error('expecting task to stop'); assert.ok(error.message.includes('stopped')); assert.equal(error.code, tasks.ESTOPPED); assert.ok(!(result)); }); it('task timesout', async function () { const timeoutTaskId = await tasks.add(tasks._TASK_SLEEP, [ 10000 ]); const [error, result] = await safe(tasks.startTask(timeoutTaskId, { timeout: 2000 })); if (!error) throw new Error('expecting task to timeout'); assert.equal(error.code, tasks.ETIMEOUT); assert.ok(error.message.includes('timed out')); assert.ok(!(result)); }); });