From f002560616c91b22f62ca7dda9ea675ae34801f1 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 11 Oct 2016 14:49:48 +0100 Subject: [PATCH] Exec node spawn mode should clone messages it reuses --- nodes/core/core/75-exec.js | 10 +-- test/nodes/core/core/75-exec_spec.js | 126 +++++++++++++++++++-------- 2 files changed, 95 insertions(+), 41 deletions(-) diff --git a/nodes/core/core/75-exec.js b/nodes/core/core/75-exec.js index 6f2ac9393..75f8830ec 100644 --- a/nodes/core/core/75-exec.js +++ b/nodes/core/core/75-exec.js @@ -1,5 +1,5 @@ /** - * Copyright 2013,2015 IBM Corp. + * Copyright 2013,2016 IBM Corp. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,13 +61,13 @@ module.exports = function(RED) { //console.log('[exec] stdout: ' + data); if (isUtf8(data)) { msg.payload = data.toString(); } else { msg.payload = data; } - node.send([msg,null,null]); + 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,msg,null]); + node.send([null,RED.util.cloneMessage(msg),null]); }); child.on('close', function (code) { //console.log('[exec] result: ' + code); @@ -78,12 +78,12 @@ module.exports = function(RED) { 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,msg]); + 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,msg); + node.error(code,RED.util.cloneMessage(msg)); }); } else { diff --git a/test/nodes/core/core/75-exec_spec.js b/test/nodes/core/core/75-exec_spec.js index e69202bc4..242f366c4 100644 --- a/test/nodes/core/core/75-exec_spec.js +++ b/test/nodes/core/core/75-exec_spec.js @@ -58,24 +58,42 @@ describe('exec node', function() { arg3(null,arg1,arg1.toUpperCase()); }); - 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"); - n2.on("input", function(msg) { - //console.log(msg); - msg.should.have.property("payload"); - msg.payload.should.be.a.String(); - msg.payload.should.equal("echo"); - }); - n3.on("input", function(msg) { - //console.log(msg); - msg.should.have.property("payload"); - msg.payload.should.be.a.String, - msg.payload.should.equal("ECHO"); - child_process.exec.restore(); - done(); + 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"); + var received = 0; + var messages = [null,null]; + var completeTest = function() { + received++; + if (received < 2) { + return; + } + try{ + var msg = messages[0]; + msg.should.have.property("payload"); + msg.payload.should.be.a.String(); + msg.payload.should.equal("echo"); + + msg = messages[1]; + msg.should.have.property("payload"); + msg.payload.should.be.a.String, + msg.payload.should.equal("ECHO"); + child_process.exec.restore(); + done(); + } catch(err) { + child_process.exec.restore(); + done(err); + } + }; + n2.on("input", function(msg) { + messages[0] = msg; + completeTest(); + }); + n3.on("input", function(msg) { + messages[1] = msg; + completeTest(); }); n1.receive({payload:"and"}); }); @@ -96,19 +114,39 @@ describe('exec node', function() { var n2 = helper.getNode("n2"); var n3 = helper.getNode("n3"); var n4 = helper.getNode("n4"); + var received = 0; + var messages = [null,null]; + var completeTest = function() { + received++; + if (received < 2) { + return; + } + try{ + var msg = messages[0]; + msg.should.have.property("payload"); + msg.payload.should.be.a.String(); + msg.payload.should.equal("echo and more"); + + msg = messages[1]; + msg.should.have.property("payload"); + msg.payload.should.be.a.String(); + msg.payload.should.equal("ECHO AND MORE"); + child_process.exec.restore(); + done(); + } catch(err) { + child_process.exec.restore(); + done(err); + } + }; + + n2.on("input", function(msg) { - //console.log(msg); - msg.should.have.property("payload"); - msg.payload.should.be.a.String(); - msg.payload.should.equal("echo and more"); + messages[0] = msg; + completeTest(); }); n3.on("input", function(msg) { - //console.log(msg); - msg.should.have.property("payload"); - msg.payload.should.be.a.String(); - msg.payload.should.equal("ECHO AND MORE"); - child_process.exec.restore(); - done(); + messages[1] = msg; + completeTest(); }); n1.receive({payload:"and"}); }); @@ -252,15 +290,21 @@ describe('exec node', function() { var n2 = helper.getNode("n2"); var n3 = helper.getNode("n3"); var n4 = helper.getNode("n4"); - n2.on("input", function(msg) { - msg.should.have.property("payload"); - msg.payload.should.be.a.String(); - msg.payload.should.equal("this now works\n"); - }); - n4.on("input", function(msg) { - try { + var received = 0; + var messages = [null,null]; + var completeTest = function() { + received++; + if (received < 2) { + return; + } + try{ + var msg = messages[0]; msg.should.have.property("payload"); + msg.payload.should.be.a.String(); + msg.payload.should.equal("this now works\n"); + msg = messages[1]; + msg.should.have.property("payload"); should.exist(msg.payload); msg.payload.should.be.a.Number(); msg.payload.should.equal(0); @@ -268,8 +312,18 @@ describe('exec node', function() { } catch(err) { done(err); } + }; + + + n2.on("input", function(msg) { + messages[0] = msg; + completeTest(); }); - n1.receive({payload:null}); + n4.on("input", function(msg) { + messages[1] = msg; + completeTest(); + }); + n1.receive({payload:null,fred:123}); }); });