diff --git a/src/tasks.js b/src/tasks.js index 7f42319d3..590e030fe 100644 --- a/src/tasks.js +++ b/src/tasks.js @@ -16,7 +16,12 @@ exports = module.exports = { TASK_BACKUP: 'backup', TASK_UPDATE: 'update', TASK_MIGRATE: 'migrate', - TASK_RENEW_CERTS: 'renewcerts' + TASK_RENEW_CERTS: 'renewcerts', + + // testing + _TASK_IDENTITY: '_identity', + _TASK_CRASH: '_crash', + _TASK_ERROR: '_error', }; let assert = require('assert'), diff --git a/src/taskworker.js b/src/taskworker.js index 9b5f0c636..1c272e682 100755 --- a/src/taskworker.js +++ b/src/taskworker.js @@ -15,7 +15,11 @@ const NOOP_CALLBACK = function (error) { if (error) debug(error); }; const TASKS = { // indexed by task type backup: backups.backupBoxAndApps, update: updater.update, - renewcerts: reverseProxy.renewCerts + renewcerts: reverseProxy.renewCerts, + + _identity: (arg, progressCallback, callback) => callback(null, arg), + _error: (arg, progressCallback, callback) => callback(new Error(`Failed for arg: ${arg}`)), + _crash: (arg) => { throw new Error(`Crashing for arg: ${arg}`); } }; process.on('SIGTERM', function () { @@ -36,7 +40,7 @@ database.initialize(function (error) { const progressCallback = (progress) => tasks.update(taskId, progress, NOOP_CALLBACK); const resultCallback = (error, result) => { - const progress = { percent: 100, result: result || '', errorMessage: error ? error.message : '' }; + const progress = { percent: 100, result: result || null, errorMessage: error ? error.message : null }; tasks.update(taskId, progress, () => process.exit(error ? 50 : 0)); }; diff --git a/src/test/tasks-test.js b/src/test/tasks-test.js new file mode 100644 index 000000000..4e657ff6f --- /dev/null +++ b/src/test/tasks-test.js @@ -0,0 +1,80 @@ +/* jslint node:true */ +/* global it:false */ +/* global before:false */ +/* global after:false */ +/* global describe:false */ + +'use strict'; + +var async = require('async'), + database = require('../database.js'), + expect = require('expect.js'), + fs = require('fs'), + paths = require('../paths.js'), + tasks = require('../tasks.js'); + +let AUDIT_SOURCE = { ip: '1.2.3.4' }; + +function setup(done) { + async.series([ + database.initialize, + database._clear + ], done); +} + +function cleanup(done) { + async.series([ + database._clear, + database.uninitialize + ], done); +} + +describe('task', function () { + before(setup); + after(cleanup); + + it('can run valid task - success', function (done) { + let taskId = null; + let task = tasks.startTask(tasks._TASK_IDENTITY, [ 'ping' ], AUDIT_SOURCE); + task.on('error', done); + task.on('start', (tid) => { taskId = tid; }); + task.on('finish', function (error, result) { + if (error) return done(error); + expect(result).to.equal('ping'); + expect(taskId).to.be.ok(); + done(); + }); + }); + + it('can run valid task - error', function (done) { + let taskId = null; + let task = tasks.startTask(tasks._TASK_ERROR, [ 'ping' ], AUDIT_SOURCE); + task.on('error', done); + task.on('start', (tid) => { taskId = tid; }); + task.on('finish', function (error, result) { + expect(error).to.be.ok(); + expect(error.message).to.be('Failed for arg: ping'); + expect(result).to.be(null); + expect(taskId).to.be.ok(); + done(); + }); + }); + + it('can run valid task - crash', function (done) { + let taskId = null; + let task = tasks.startTask(tasks._TASK_CRASH, [ 'ping' ], AUDIT_SOURCE); + task.on('error', done); + task.on('start', (tid) => { taskId = tid; }); + task.on('finish', function (error, result) { + expect(error).to.be.ok(); + expect(error.message).to.contain('task crashed'); + expect(result).to.be(null); + expect(taskId).to.be.ok(); + + let logs = fs.readFileSync(`${paths.TASKS_LOG_DIR}/${taskId}.log`, 'utf8'); + expect(logs).to.contain('Crashing for arg: ping'); + done(); + }); + }); + +});