Arquivos
deepforge/test/plugins/ExecuteJob/ExecuteJob.spec.js
T
Brian Broll 73f7ba38ba Refactored code gen out of ExecuteJob. Fixes #1014 (#1018)
* WIP created GenerateJob plugin for generating exec code

* WIP moved templates to GenerateJob

* WIP #1014 GenerateJob tests passing

* WIP #1014 Added attribute file test

* WIP #1014 Added more GenerateJob tests

* WIP #1014 removed extra logs

* WIP #1014 Follow base for plugin, namespace

* WIP #1014 Added CodeGen component settings

* WIP #1014 Removed component settings

* WIP #1014 Fixed the loading of inputs

* WIP #1014 Fixed namespace detection

* WIP #1014 Fixed code gen of job refs

* WIP #1014 Fixed 2nd degree code gen

* WIP #1014 Removed old code generation file

* WIP #1014 Fixed code linting issues

* WIP #1014 Fixed blob fetch error handling

* WIP #1014 fixed error handling for bad blob fetch

* WIP #1014 Updated the commit hash for the ptr code gen

* WIP #1014 save after forwarding data from the successful job

* WIP #1014 updated error msg on blob retrieval fail

* WIP #1014 fixed code linting issues
2017-04-26 21:46:17 -05:00

406 linhas
14 KiB
JavaScript

/*jshint node:true, mocha:true*/
'use strict';
var testFixture = require('../../globals');
describe('ExecuteJob', function () {
var gmeConfig = testFixture.getGmeConfig(),
expect = testFixture.expect,
Q = testFixture.Q,
logger = testFixture.logger.fork('ExecuteJob'),
PluginCliManager = testFixture.WebGME.PluginCliManager,
projectName = 'testProject',
pluginName = 'ExecuteJob',
manager = new PluginCliManager(null, logger, gmeConfig),
PULSE = require('../../../src/common/Constants').PULSE,
project,
gmeAuth,
storage,
commitHash,
nopPromise = () => {
return Q();
};
before(function (done) {
this.timeout(10000);
testFixture.clearDBAndGetGMEAuth(gmeConfig, projectName)
.then(function (gmeAuth_) {
gmeAuth = gmeAuth_;
// This uses in memory storage. Use testFixture.getMongoStorage to persist test to database.
storage = testFixture.getMemoryStorage(logger, gmeConfig, gmeAuth);
return storage.openDatabase();
})
.then(function () {
var importParam = {
projectSeed: testFixture.path.join(testFixture.DF_SEED_DIR, 'devProject', 'devProject.webgmex'),
projectName: projectName,
branchName: 'master',
logger: logger,
gmeConfig: gmeConfig
};
return testFixture.importProject(storage, importParam);
})
.then(function (importResult) {
project = importResult.project;
commitHash = importResult.commitHash;
return project.createBranch('test', commitHash);
})
.nodeify(done);
});
after(function (done) {
storage.closeDatabase()
.then(function () {
return gmeAuth.unload();
})
.nodeify(done);
});
it('should verify activeNode is "Job"', function (done) {
var pluginConfig = {},
context = {
project: project,
commitHash: commitHash,
branchName: 'test',
activeNode: '/1'
};
manager.executePlugin(pluginName, pluginConfig, context, function (err, pluginResult) {
expect(err).to.equal('Cannot execute FCO (expected Job)');
expect(typeof pluginResult).to.equal('object');
expect(pluginResult.success).to.equal(false);
done();
});
});
////////// Helper Functions //////////
var plugin,
node,
preparePlugin = function(done) {
var context = {
project: project,
commitHash: commitHash,
namespace: 'pipeline',
branchName: 'test',
activeNode: '/K/R/p' // hello world job
};
return manager.initializePlugin(pluginName)
.then(plugin_ => {
plugin = plugin_;
return manager.configurePlugin(plugin, {}, context);
})
.then(() => node = plugin.activeNode)
.nodeify(done);
};
////////// END Helper Functions //////////
// Race condition checks w/ saving...
describe('get/set', function() {
beforeEach(preparePlugin);
it('should get correct attribute after set', function() {
plugin.setAttribute(node, 'status', 'queued');
var attrValue = plugin.getAttribute(node, 'status');
expect(attrValue).to.equal('queued');
});
it('should get correct attribute before updating nodes', function(done) {
// Run setAttribute on some node
plugin.setAttribute(node, 'status', 'queued');
// Check that the value is correct before applying node changes
var updateNodes = plugin.updateNodes;
plugin.updateNodes = function() {
var attrValue = plugin.getAttribute(node, 'status');
expect(attrValue).to.equal('queued');
return updateNodes.apply(this, arguments);
};
plugin.save().nodeify(done);
});
it('should get correct attribute (from new node) before updating nodes', function(done) {
// Run setAttribute on some node
var graphTmp = plugin.createNode('Graph', node),
newVal = 'testGraph',
id = 'testId';
// Get the
plugin.setAttribute(graphTmp, 'name', newVal);
plugin._metadata[id] = graphTmp;
plugin.createIdToMetadataId[graphTmp] = id;
// Check that the value is correct before applying node changes
var updateNodes = plugin.updateNodes;
plugin.updateNodes = function() {
var graph = plugin._metadata[id],
attrValue = plugin.getAttribute(graph, 'name');
expect(attrValue).to.equal(newVal);
return updateNodes.apply(this, arguments);
};
plugin.save().nodeify(done);
});
it('should get correct attribute after save', function(done) {
// Run setAttribute on some node
plugin.setAttribute(node, 'status', 'queued');
// Check that the value is correct before applying node changes
plugin.save()
.then(() => {
var attrValue = plugin.getAttribute(node, 'status');
expect(attrValue).to.equal('queued');
})
.nodeify(done);
});
it('should get correct attribute while applying node changes', function(done) {
// Run setAttribute on some node
plugin.setAttribute(node, 'status', 'queued');
// Check that the value is correct before applying node changes
var oldApplyChanges = plugin._applyNodeChanges;
plugin._applyNodeChanges = function() {
var attrValue = plugin.getAttribute(node, 'status');
expect(attrValue).to.equal('queued');
return oldApplyChanges.apply(this, arguments);
};
plugin.save().nodeify(done);
});
});
describe('createNode', function() {
beforeEach(preparePlugin);
it('should update _metadata after applying changes', function(done) {
// Run setAttribute on some node
var graphTmp = plugin.createNode('Graph', node),
id = 'testId';
plugin._metadata[id] = graphTmp;
plugin.createIdToMetadataId[graphTmp] = id;
// Check that the value is correct before applying node changes
var applyModelChanges = plugin.applyModelChanges;
plugin.applyModelChanges = function() {
return applyModelChanges.apply(this, arguments)
.then(() => {
var graph = plugin._metadata[id];
expect(graph).to.not.equal(graphTmp);
});
};
plugin.save().nodeify(done);
});
it('should update _metadata in updateNodes', function(done) {
var id = 'testId';
plugin._metadata[id] = node;
node.old = true;
plugin.updateNodes()
.then(() => {
var graph = plugin._metadata[id];
expect(graph.old).to.not.equal(true);
})
.nodeify(done);
});
// Check that it gets the correct value from a newly created node after
// it has been saved/created
it('should get changed attribute', function(done) {
// Run setAttribute on some node
var graphTmp = plugin.createNode('Graph', node),
id = 'testId';
plugin._metadata[id] = node;
plugin.createIdToMetadataId[graphTmp] = id;
plugin.setAttribute(graphTmp, 'name', 'firstName');
// Check that the value is correct before applying node changes
plugin.save()
.then(() => {
var graph = plugin._metadata[id],
val = plugin.getAttribute(graph, 'name');
expect(val).to.equal('firstName');
})
.nodeify(done);
});
it('should get inherited attribute', function(done) {
// Run setAttribute on some node
var graphTmp = plugin.createNode('Graph', node),
id = 'testId',
val;
// Check that the value is correct before applying node changes
plugin._metadata[id] = node;
plugin.createIdToMetadataId[graphTmp] = id;
val = plugin.getAttribute(graphTmp, 'name');
expect(val).to.equal('Graph');
plugin.save()
.then(() => {
var graph = plugin._metadata[id];
val = plugin.getAttribute(graph, 'name');
expect(val).to.equal('Graph');
})
.nodeify(done);
});
});
// Canceling
describe('cancel', function() {
beforeEach(preparePlugin);
it('should stop the job if the execution is canceled', function(done) {
var job = node,
hash = 'abc123';
plugin.setAttribute(node, 'secret', 'abc');
plugin.isExecutionCanceled = () => true;
plugin.onOperationCanceled = () => done();
plugin.executor = {
cancelJob: jobHash => expect(jobHash).equal(hash)
};
plugin.watchOperation(hash, job, job);
});
it('should stop the job if a job is canceled', function(done) {
var job = node,
hash = 'abc123';
plugin.setAttribute(job, 'secret', 'abc');
plugin.canceled = true;
plugin.onOperationCanceled = () => done();
plugin.executor = {
cancelJob: jobHash => expect(jobHash).equal(hash)
};
plugin.watchOperation(hash, job, job);
});
it('should set exec to running', function(done) {
var job = node,
execNode = plugin.core.getParent(job);
// Set the execution to canceled
plugin.setAttribute(execNode, 'status', 'canceled');
plugin.prepare = () => {
var status = plugin.getAttribute(execNode, 'status');
expect(status).to.not.equal('canceled');
return {then: () => done()};
};
plugin.main();
});
});
describe('resume detection', function() {
var mockPluginForJobStatus = function(gmeStatus, pulse, originBranch, shouldResume, done) {
plugin.setAttribute(node, 'status', gmeStatus);
plugin.setAttribute(node, 'jobId', 'asdfaa');
// Mocks:
// - prepare should basically nop
// - Should call 'resumeJob' or 'executeJob'
// - should return origin branch
plugin.prepare = nopPromise;
plugin.pulseClient.check = () => Q().then(() => pulse);
plugin.originManager.getOrigin = () => Q().then(() => {
return {branch: originBranch};
});
plugin.pulseClient.update = nopPromise;
plugin.resumeJob = () => done(shouldResume ? null : 'Should not resume job!');
plugin.executeJob = () => done(shouldResume ? 'Should resume job!' : null);
plugin.main();
};
beforeEach(preparePlugin);
// test using a table of gme status|pulse status|job status|should resume?
var names = ['gme', 'pulse', 'origin branch', 'expected to resume'],
title;
// gme status, pulse status, job status, should resume
[
// Should restart if running and the pulse is not found
['running', PULSE.DEAD, 'test', true],
// Should restart if the pulse is not found
['running', PULSE.DOESNT_EXIST, 'test', true],
// Should not restart if the plugin is alive
['running', PULSE.ALIVE, 'test', false],
// Should not restart if the ui is not 'running'
['failed', PULSE.DOESNT_EXIST, 'test', false],
// Should not restart if on incorrect branch (wrt origin branch)
['running', PULSE.DOESNT_EXIST, 'master', false]
].forEach(row => {
title = names.map((v, i) => `${v}: ${row[i]}`).join(' | ');
it(title, function(done) {
row.push(done);
mockPluginForJobStatus.apply(null, row);
});
});
});
describe('preparing', function() {
beforeEach(preparePlugin);
// should not delete child nodes during 'prepare' if resuming
it('should delete child metadata nodes', function(done) {
// Create a metadata node w/ a child
var graphId = plugin.createNode('Graph', plugin.activeNode);
plugin.createNode('Line', graphId);
plugin.save()
.then(() => plugin.prepare(true))
.then(() => {
expect(plugin.deletions.length).to.equal(1);
})
.nodeify(done);
});
// should not mark any nodes for deletion during `prepare` if resuming
it('should mark nodes for deletion', function(done) {
var jobId = plugin.core.getPath(plugin.activeNode),
deleteIds;
// Create a metadata node
plugin.createNode('Graph', plugin.activeNode);
plugin.save()
.then(() => plugin.prepare(true))
.then(() => {
deleteIds = Object.keys(plugin._markForDeletion[jobId]);
expect(deleteIds.length).to.equal(1);
})
.nodeify(done);
});
});
describe('resume errors', function() {
beforeEach(preparePlugin);
it('should handle error if missing jobId', function(done) {
// Remove jobId
plugin.delAttribute(plugin.activeNode, 'runId');
plugin.startExecHeartBeat = () => {};
plugin.isResuming = () => Q(true);
plugin.main(function(err) {
expect(err).to.not.equal(null);
done();
});
});
});
});