Skip to content

Commit

Permalink
Closing connections when one of the workers fails. Correctly handling…
Browse files Browse the repository at this point in the history
… Cucumber exit code when tests fail
  • Loading branch information
simondean committed Jul 19, 2013
1 parent aa7d910 commit c557275
Show file tree
Hide file tree
Showing 2 changed files with 224 additions and 178 deletions.
201 changes: 23 additions & 178 deletions lib/myriad_cucumber.js
@@ -1,13 +1,12 @@
var Async = require('async');
var Myriad = require('myriad');
var MyriadServer = require('myriad-server');
var Path = require('path');
var FS = require('fs');
var Debug = require('debug')('myriad-cucumber');
var FeatureFinder = require('./feature_finder');
var Freeport = require('freeport');
var JSYAML = require('js-yaml');
var Colors = require('colors');

var FeatureFinder = require('./feature_finder');
var Worker = require('./worker.js');

var MyriadCucumber = function(options) {
if (!(this instanceof MyriadCucumber)) return new MyriadCucumber(options);
Expand Down Expand Up @@ -153,22 +152,26 @@ MyriadCucumber.prototype._executeFeaturesOnMyriadServer = function(options, call
var workerCount = 0;

var firstReport = true;
var workers = [];

Async.eachLimit(
tasks,
options.workers,
function(task, callback) {
var workerIndex = workerCount++;

self._executeFeatureOnWorker(
{
workerIndex: workerIndex,
myriadServerUrl: options.myriadServerUrl,
taskOptions: task.options,
featurePath: task.featurePath,
dryRun: options.dryRun,
profileName: task.profileName
},
var worker = new Worker({
workerIndex: workerIndex,
myriadServerUrl: options.myriadServerUrl,
taskOptions: task.options,
featurePath: task.featurePath,
dryRun: options.dryRun,
profileName: task.profileName
});

workers.push(worker);

worker.run(
function(report, callback) {
report = JSON.stringify(report);
// Remove [ and ] from start and end of the JSON string
Expand Down Expand Up @@ -201,11 +204,18 @@ MyriadCucumber.prototype._executeFeaturesOnMyriadServer = function(options, call
}
},
function(err) {
workers.splice(workers.indexOf(worker));
callback(err);
}
);
},
function(err) {
if (workers.length > 0) {
workers.forEach(function(worker) {
worker.end();
});
}

done(err);
}
);
Expand Down Expand Up @@ -248,138 +258,6 @@ MyriadCucumber.prototype._getWorkerTasks = function(options, callback) {
callback(null, tasks);
}

MyriadCucumber.prototype._executeFeatureOnWorker = function(options, outCallback, callback) {
var self = this;

var debugPrefix = '#' + options.workerIndex + ' ';
var myriadConnection;
var finished = false;

function done(err, report) {
if (finished) return;
finished = true;

Debug(debugPrefix + 'Closing connection');
myriadConnection.close(function() {
Debug(debugPrefix + 'Closed connection');
callback(err, report);
});
}

if (!options.dryRun) {
self._logEvent('featurePath', {
worker: options.workerIndex,
status: 'starting',
uri: options.featurePath
});
}

Debug(debugPrefix + 'Connecting to ' + options.myriadServerUrl);
myriadConnection = Myriad({ url: options.myriadServerUrl });

var stdout = [];

myriadConnection.on('connect', function() {
Debug(debugPrefix + 'Spawning cucumber instance');
myriadConnection.spawn(options.taskOptions);
});

myriadConnection.on('message', function(event) {
var data;

if (event.data) {
data = new Buffer(event.data, 'base64');
}

if (event.event === 'error') {
console.error(event.error);
Debug(debugPrefix + 'Error: ' + JSON.stringify(event.error));
done(event.error);
}
else if (event.event === 'child_stdout') {
Debug(debugPrefix + 'Child stdout: ' + data.toString());
stdout.push(data);
}
else if (event.event === 'child_stderr') {
console.error(data.toString());
}
else if (event.event === 'child_error') {
console.error(event.error);
Debug(debugPrefix + 'Child rrror: ' + JSON.stringify(event.error));
done(event.error);
}
else if (event.event === 'child_close') {
Debug(debugPrefix + 'Child closed. Exit code ' + event.code);

if (event.code === 0) {
stdout = stdout.join('');
Debug(stdout);
var report = JSON.parse(stdout);

report.forEach(function(item) {
item.profile = options.profileName
});

self._logReportProgress({ workerIndex: options.workerIndex, report: report, dryRun: options.dryRun });

outCallback(report, function() {
done();
});
}
else {
done({ message: "Cucumber returned a failure exit code. Exit code " + event.code, exitCode: event.code });
}
}
});
}

MyriadCucumber.prototype._logReportProgress = function(options) {
var self = this;

options.report.forEach(function(item) {
var featureUri = cleanUri(Path.relative(process.cwd(), item.uri));

if (item.elements) {
item.elements.forEach(function(element) {
var elementStatus = 'stepless';

if (element.steps) {
var foundElementStatus = false;

element.steps.forEach(function(step) {
if (!foundElementStatus) {
if (step.result) {
elementStatus = step.result.status;
foundElementStatus = elementStatus !== 'passed';
}
else {
elementStatus = 'unknown';
foundElementStatus = true;
}
}
});
}

if (!options.dryRun) {
self._logEvent(element.type, {
worker: options.workerIndex,
status: elementStatus,
uri: featureUri + '/' + cleanUri(element.name)
});
}
});
}

if (!options.dryRun) {
self._logEvent('feature', {
worker: options.workerIndex,
status: 'finished',
uri: featureUri
});
}
});
}

MyriadCucumber.prototype._prepareMyriadServer = function(options, callback) {
var self = this;

Expand Down Expand Up @@ -455,37 +333,4 @@ MyriadCucumber.prototype._preparePackage = function(options, callback) {
}
}

MyriadCucumber.prototype._logEvent = function(key, item) {
var self = this;

var event = {};
event[key] = item;

var eventYaml = JSYAML.safeDump(
event,
{
flowLevel: 0
}
);

if (item.status == 'passed') {
eventYaml = eventYaml.green;
}
else if (item.status == 'failed') {
eventYaml = eventYaml.red;
}
else if (item.status == 'stepless') {
eventYaml = eventYaml.blue;
}
else {
eventYaml = eventYaml.grey;
}

process.stderr.write(eventYaml);
}

function cleanUri(value) {
return value.replace(/[^a-zA-Z0-9\\/]/g, '_').replace(/\\/g, '/');
}

module.exports = MyriadCucumber;

0 comments on commit c557275

Please sign in to comment.