Defeat the exec node test dragons

This commit is contained in:
Nick O'Leary 2016-10-11 20:30:58 +01:00
parent fdea19a45b
commit 325c6135cf
2 changed files with 53 additions and 36 deletions

View File

@ -32,7 +32,6 @@ module.exports = function(RED) {
var node = this;
var cleanup = function(p) {
//console.log("CLEANUP!!!",p);
node.activeProcesses[p].kill();
node.status({fill:"red",shape:"dot",text:"timeout"});
node.error("Exec node timeout");
@ -53,37 +52,44 @@ module.exports = function(RED) {
/* istanbul ignore else */
if (RED.settings.verbose) { node.log(cmd+" ["+arg+"]"); }
child = spawn(cmd,arg);
var unknownCommand = (child.pid === undefined);
if (node.timer !== 0) {
child.tout = setTimeout(function() { cleanup(child.pid); }, node.timer);
}
node.activeProcesses[child.pid] = child;
child.stdout.on('data', function (data) {
//console.log('[exec] stdout: ' + data);
if (isUtf8(data)) { msg.payload = data.toString(); }
else { msg.payload = data; }
node.send([RED.util.cloneMessage(msg),null,null]);
if (node.activeProcesses.hasOwnProperty(child.pid) && node.activeProcesses[child.pid] !== null) {
// console.log('[exec] stdout: ' + data,child.pid);
if (isUtf8(data)) { msg.payload = data.toString(); }
else { msg.payload = data; }
node.send([RED.util.cloneMessage(msg),null,null]);
}
});
child.stderr.on('data', function (data) {
//console.log('[exec] stderr: ' + data);
if (isUtf8(data)) { msg.payload = data.toString(); }
else { msg.payload = new Buffer(data); }
node.send([null,RED.util.cloneMessage(msg),null]);
if (node.activeProcesses.hasOwnProperty(child.pid) && node.activeProcesses[child.pid] !== null) {
if (isUtf8(data)) { msg.payload = data.toString(); }
else { msg.payload = new Buffer(data); }
node.send([null,RED.util.cloneMessage(msg),null]);
}
});
child.on('close', function (code) {
//console.log('[exec] result: ' + code);
delete node.activeProcesses[child.pid];
if (child.tout) { clearTimeout(child.tout); }
msg.payload = code;
if (code === 0) { node.status({}); }
if (code === null) { node.status({fill:"red",shape:"dot",text:"timeout"}); }
else if (code < 0) { node.status({fill:"red",shape:"dot",text:"rc: "+code}); }
else { node.status({fill:"yellow",shape:"dot",text:"rc: "+code}); }
node.send([null,null,RED.util.cloneMessage(msg)]);
if (unknownCommand || (node.activeProcesses.hasOwnProperty(child.pid) && node.activeProcesses[child.pid] !== null)) {
delete node.activeProcesses[child.pid];
if (child.tout) { clearTimeout(child.tout); }
msg.payload = code;
if (code === 0) { node.status({}); }
if (code === null) { node.status({fill:"red",shape:"dot",text:"timeout"}); }
else if (code < 0) { node.status({fill:"red",shape:"dot",text:"rc: "+code}); }
else { node.status({fill:"yellow",shape:"dot",text:"rc: "+code}); }
node.send([null,null,RED.util.cloneMessage(msg)]);
}
});
child.on('error', function (code) {
delete node.activeProcesses[child.pid];
if (child.tout) { clearTimeout(child.tout); }
node.error(code,RED.util.cloneMessage(msg));
delete node.activeProcesses[child.pid];
if (node.activeProcesses.hasOwnProperty(child.pid) && node.activeProcesses[child.pid] !== null) {
node.error(code,RED.util.cloneMessage(msg));
}
});
}
else {
@ -120,7 +126,10 @@ module.exports = function(RED) {
/* istanbul ignore else */
if (node.activeProcesses.hasOwnProperty(pid)) {
if (node.activeProcesses[pid].tout) { clearTimeout(node.activeProcesses[pid].tout); }
node.activeProcesses[pid].kill();
// console.log("KILLLING",pid);
var process = node.activeProcesses[pid];
node.activeProcesses[pid] = null;
process.kill();
}
}
node.activeProcesses = {};

View File

@ -327,23 +327,31 @@ describe('exec node', function() {
});
});
it('should return an error for a bad command', function(done) {
var flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"madeupcommandshouldfail", addpay:false, append:"", useSpawn:true},
{id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}];
helper.load(execNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
var n3 = helper.getNode("n3");
var n4 = helper.getNode("n4");
n4.on("input", function(msg) {
msg.should.have.property("payload");
msg.payload.should.be.a.Number();
msg.payload.should.be.below(0);
done();
if (!/^v0.10/.test(process.version)) {
it('should return an error for a bad command', function(done) {
var flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"madeupcommandshouldfail", addpay:false, append:"", useSpawn:true},
{id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}];
helper.load(execNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
var n3 = helper.getNode("n3");
var n4 = helper.getNode("n4");
n4.on("input", function(msg) {
if (/^v0.10/.test(process.version)) {
msg.should.have.property("payload");
msg.payload.should.be.a.Number();
msg.payload.should.be.below(0);
} else {
msg.should.have.property("payload");
msg.payload.should.be.a.Number();
msg.payload.should.be.below(0);
}
done();
});
n1.receive({payload:null});
});
n1.receive({payload:null});
});
});
}
it('should return an error for a failing command', function(done) {
var flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"mkdir /foo/bar/doo/dah", addpay:false, append:"", useSpawn:true},