1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Merge branch '0.17' of github.com:node-red/node-red into 0.17

This commit is contained in:
Nick O'Leary 2017-05-11 21:00:40 +01:00
commit c80fa9914b
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
6 changed files with 183 additions and 69 deletions

View File

@ -15,17 +15,18 @@
--> -->
<script type="text/x-red" data-template-name="delay"> <script type="text/x-red" data-template-name="delay">
<div class="form-row"> <div class="form-row">
<label for="node-input-pauseType"><i class="fa fa-tasks"></i> <span data-i18n="delay.action"></span></label> <label for="node-input-pauseType"><i class="fa fa-tasks"></i> <span data-i18n="delay.action"></span></label>
<select id="node-input-pauseType" style="width:270px !important"> <select id="node-input-pauseType" style="width:270px !important">
<option value="delay" data-i18n="delay.delaymsg"></option> <option value="delay" data-i18n="delay.delaymsg"></option>
<option value="delayv" data-i18n="delay.delayvarmsg"></option>
<option value="random" data-i18n="delay.randomdelay"></option> <option value="random" data-i18n="delay.randomdelay"></option>
<option value="rate" data-i18n="delay.limitrate"></option> <option value="rate" data-i18n="delay.limitrate"></option>
<option value="queue" data-i18n="delay.fairqueue"></option> <option value="queue" data-i18n="delay.fairqueue"></option>
<option value="timed" data-i18n="delay.timedqueue"></option> <option value="timed" data-i18n="delay.timedqueue"></option>
</select> </select>
</div> </div>
<div id="delay-details" class="form-row"> <div id="delay-details" class="form-row">
<label for="node-input-timeout"><i class="fa fa-clock-o"></i> <span data-i18n="delay.for"></span></label> <label for="node-input-timeout"><i class="fa fa-clock-o"></i> <span data-i18n="delay.for"></span></label>
<input type="text" id="node-input-timeout" placeholder="Time" style="text-align:end; width:50px !important"> <input type="text" id="node-input-timeout" placeholder="Time" style="text-align:end; width:50px !important">
@ -53,7 +54,6 @@
<div id="node-input-dr"><input style="margin: 20px 0 20px 100px; width: 30px;" type="checkbox" id="node-input-drop"><label style="width: 250px;" for="node-input-drop"><span data-i18n="delay.dropmsg"></span></label></div> <div id="node-input-dr"><input style="margin: 20px 0 20px 100px; width: 30px;" type="checkbox" id="node-input-drop"><label style="width: 250px;" for="node-input-drop"><span data-i18n="delay.dropmsg"></span></label></div>
</div> </div>
<div id="random-details" class="form-row"> <div id="random-details" class="form-row">
<label for="node-input-randomFirst"><i class="fa fa-clock-o"></i> <span data-i18n="delay.between"></span></label> <label for="node-input-randomFirst"><i class="fa fa-clock-o"></i> <span data-i18n="delay.between"></span></label>
<input type="text" id="node-input-randomFirst" placeholder="" style="text-align:end; width:30px !important"> <input type="text" id="node-input-randomFirst" placeholder="" style="text-align:end; width:30px !important">
@ -72,7 +72,6 @@
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
</div> </div>
</script> </script>
<script type="text/x-red" data-help-name="delay"> <script type="text/x-red" data-help-name="delay">
@ -80,6 +79,7 @@
<p>The default delay is 5 seconds and rate limit of 1 msg/second, but both can be configured.</p> <p>The default delay is 5 seconds and rate limit of 1 msg/second, but both can be configured.</p>
<p>When set to rate limit messages, they are spread across the configured time period. It can <p>When set to rate limit messages, they are spread across the configured time period. It can
also be set to discard any intermediate messages that arrive.</p> also be set to discard any intermediate messages that arrive.</p>
<p>If configured to use <code>msg.delay</code> the delay is specified in milliseconds.</p>
<p>The "topic based fair queue" adds messages to a release queue tagged by their <code>msg.topic</code> property. <p>The "topic based fair queue" adds messages to a release queue tagged by their <code>msg.topic</code> property.
At each "tick", derived from the rate, the next "topic" is released. At each "tick", derived from the rate, the next "topic" is released.
Any messages arriving on the same topic before release replace those in that position in the queue. Any messages arriving on the same topic before release replace those in that position in the queue.
@ -110,7 +110,9 @@
outputs:1, outputs:1,
icon: "timer.png", icon: "timer.png",
label: function() { label: function() {
if (this.pauseType == "delay") { if (this.pauseType == "delayv") {
return this.name||this._("delay.label.variable");
} else if (this.pauseType == "delay") {
var units = this.timeoutUnits ? this.timeoutUnits.charAt(0) : "s"; var units = this.timeoutUnits ? this.timeoutUnits.charAt(0) : "s";
if (this.timeoutUnits == "milliseconds") { units = "ms"; } if (this.timeoutUnits == "milliseconds") { units = "ms"; }
return this.name||this._("delay.label.delay")+" "+this.timeout+" "+units; return this.name||this._("delay.label.delay")+" "+this.timeout+" "+units;
@ -154,10 +156,10 @@
var $this = $(this); var $this = $(this);
var val = parseInt($this.val()); var val = parseInt($this.val());
var type = "singular"; var type = "singular";
if(val > 1) { if (val > 1) {
type = "plural"; type = "plural";
} }
if($this.attr("data-type") == type) { if ($this.attr("data-type") == type) {
return; return;
} }
$this.attr("data-type", type); $this.attr("data-type", type);
@ -166,16 +168,19 @@
var key = "delay.label.units." + $option.val() + "." + type; var key = "delay.label.units." + $option.val() + "." + type;
$option.attr('data-i18n', 'node-red:' + key); $option.attr('data-i18n', 'node-red:' + key);
$option.html(node._(key)); $option.html(node._(key));
})
}); });
});
if (this.pauseType == "delay") { if (this.pauseType == "delay") {
$("#delay-details").show(); $("#delay-details").show();
$("#rate-details").hide(); $("#rate-details").hide();
$("#random-details").hide(); $("#random-details").hide();
$("#node-input-dr").hide(); $("#node-input-dr").hide();
} else if (this.pauseType == "delayv") {
$("#delay-details").hide();
$("#rate-details").hide();
$("#random-details").hide();
$("#node-input-dr").hide();
} else if (this.pauseType == "rate") { } else if (this.pauseType == "rate") {
$("#delay-details").hide(); $("#delay-details").hide();
$("#rate-details").show(); $("#rate-details").show();
@ -216,6 +221,11 @@
$("#rate-details").hide(); $("#rate-details").hide();
$("#random-details").hide(); $("#random-details").hide();
$("#node-input-dr").hide(); $("#node-input-dr").hide();
} else if (this.value == "delayv") {
$("#delay-details").hide();
$("#rate-details").hide();
$("#random-details").hide();
$("#node-input-dr").hide();
} else if (this.value == "rate") { } else if (this.value == "rate") {
$("#delay-details").hide(); $("#delay-details").hide();
$("#rate-details").show(); $("#rate-details").show();

View File

@ -80,10 +80,17 @@ module.exports = function(RED) {
this.drop = n.drop; this.drop = n.drop;
var node = this; var node = this;
var clearDelayList = function() {
for (var i=0; i<node.idList.length; i++ ) {
clearTimeout(node.idList[i]);
}
node.idList = [];
node.status({text:"reset"});
}
if (node.pauseType === "delay") { if (node.pauseType === "delay") {
node.on("input", function(msg) { node.on("input", function(msg) {
var id; var id = setTimeout(function() {
id = setTimeout(function() {
node.idList.splice(node.idList.indexOf(id),1); node.idList.splice(node.idList.indexOf(id),1);
if (node.idList.length === 0) { node.status({}); } if (node.idList.length === 0) { node.status({}); }
node.send(msg); node.send(msg);
@ -92,17 +99,28 @@ module.exports = function(RED) {
if ((node.timeout > 1000) && (node.idList.length !== 0)) { if ((node.timeout > 1000) && (node.idList.length !== 0)) {
node.status({fill:"blue",shape:"dot",text:" "}); node.status({fill:"blue",shape:"dot",text:" "});
} }
if (msg.hasOwnProperty("reset")) { clearDelayList(); }
}); });
node.on("close", function() { clearDelayList(); });
node.on("close", function() {
for (var i=0; i<node.idList.length; i++ ) {
clearTimeout(node.idList[i]);
} }
node.idList = []; else if (node.pauseType === "delayv") {
node.status({}); node.on("input", function(msg) {
var delayvar = Number(msg.delay || 0);
if (delayvar < 0) { delayvar = 0; }
var id = setTimeout(function() {
node.idList.splice(node.idList.indexOf(id),1);
if (node.idList.length === 0) { node.status({}); }
node.send(msg);
}, delayvar);
node.idList.push(id);
if ((delayvar >= 1) && (node.idList.length !== 0)) {
node.status({fill:"blue",shape:"dot",text:delayvar/1000+"s"});
}
if (msg.hasOwnProperty("reset")) { clearDelayList(); }
}); });
node.on("close", function() { clearDelayList(); });
} else if (node.pauseType === "rate") { }
else if (node.pauseType === "rate") {
var olddepth = 0; var olddepth = 0;
node.on("input", function(msg) { node.on("input", function(msg) {
if (!node.drop) { if (!node.drop) {
@ -119,7 +137,8 @@ module.exports = function(RED) {
olddepth = 10000; olddepth = 10000;
node.warn(node.name + " " + RED._("delay.error.buffer1")); node.warn(node.name + " " + RED._("delay.error.buffer1"));
} }
} else { }
else {
node.send(msg); node.send(msg);
node.intervalID = setInterval(function() { node.intervalID = setInterval(function() {
if (node.buffer.length === 0) { if (node.buffer.length === 0) {
@ -134,7 +153,8 @@ module.exports = function(RED) {
} }
},node.rate); },node.rate);
} }
} else { }
else {
var timeSinceLast; var timeSinceLast;
if (node.lastSent) { if (node.lastSent) {
timeSinceLast = process.hrtime(node.lastSent); timeSinceLast = process.hrtime(node.lastSent);
@ -142,20 +162,25 @@ module.exports = function(RED) {
if (!node.lastSent) { // ensuring that we always send the first message if (!node.lastSent) { // ensuring that we always send the first message
node.lastSent = process.hrtime(); node.lastSent = process.hrtime();
node.send(msg); node.send(msg);
} else if ( ( (timeSinceLast[0] * SECONDS_TO_NANOS) + timeSinceLast[1] ) > (node.rate * MILLIS_TO_NANOS) ) { }
else if ( ( (timeSinceLast[0] * SECONDS_TO_NANOS) + timeSinceLast[1] ) > (node.rate * MILLIS_TO_NANOS) ) {
node.lastSent = process.hrtime(); node.lastSent = process.hrtime();
node.send(msg); node.send(msg);
} }
} }
if (msg.hasOwnProperty("reset")) {
clearInterval(node.intervalID);
node.buffer = [];
node.status({text:"reset"});
}
}); });
node.on("close", function() { node.on("close", function() {
clearInterval(node.intervalID); clearInterval(node.intervalID);
node.buffer = []; node.buffer = [];
node.status({}); node.status({});
}); });
}
} else if ((node.pauseType === "queue") || (node.pauseType === "timed")) { else if ((node.pauseType === "queue") || (node.pauseType === "timed")) {
node.intervalID = setInterval(function() { node.intervalID = setInterval(function() {
if (node.pauseType === "queue") { if (node.pauseType === "queue") {
if (node.buffer.length > 0) { if (node.buffer.length > 0) {
@ -181,30 +206,32 @@ module.exports = function(RED) {
} }
if (!hit) { node.buffer.push(msg); } // if not add to end of queue if (!hit) { node.buffer.push(msg); } // if not add to end of queue
node.status({text:node.buffer.length}); node.status({text:node.buffer.length});
if (msg.hasOwnProperty("reset")) {
node.buffer = [];
node.status({text:"reset"});
}
}); });
node.on("close", function() { node.on("close", function() {
clearInterval(node.intervalID); clearInterval(node.intervalID);
node.buffer = []; node.buffer = [];
node.status({}); node.status({});
}); });
}
} else if (node.pauseType === "random") { else if (node.pauseType === "random") {
node.on("input", function(msg) { node.on("input", function(msg) {
var wait = node.randomFirst + (node.diff * Math.random()); var wait = node.randomFirst + (node.diff * Math.random());
var id = setTimeout(function() { var id = setTimeout(function() {
node.idList.splice(node.idList.indexOf(id),1); node.idList.splice(node.idList.indexOf(id),1);
node.send(msg); node.send(msg);
node.status({});
}, wait); }, wait);
node.idList.push(id); node.idList.push(id);
}); if ((node.timeout >= 1000) && (node.idList.length !== 0)) {
node.status({fill:"blue",shape:"dot",text:parseInt(wait/10)/100+"s"});
node.on("close", function() {
for (var i=0; i<node.idList.length; i++ ) {
clearTimeout(node.idList[i]);
} }
node.idList = []; if (msg.hasOwnProperty("reset")) { clearDelayList(); }
}); });
node.on("close", function() { clearDelayList(); });
} }
} }
RED.nodes.registerType("delay",DelayNode); RED.nodes.registerType("delay",DelayNode);

View File

@ -21,7 +21,7 @@
<option value="server" data-i18n="tcpin.type.listen"></option> <option value="server" data-i18n="tcpin.type.listen"></option>
<option value="client" data-i18n="tcpin.type.connect"></option> <option value="client" data-i18n="tcpin.type.connect"></option>
</select> </select>
<span data-i18n="tcpin.label.port"></span> <input type="text" id="node-input-port" style="width: 65px"> <span data-i18n="tcpin.label.port"></span> <input type="text" id="node-input-port" style="width:65px">
</div> </div>
<div class="form-row hidden" id="node-input-host-row" style="padding-left: 110px;"> <div class="form-row hidden" id="node-input-host-row" style="padding-left: 110px;">
<span data-i18n="tcpin.label.host"></span> <input type="text" id="node-input-host" placeholder="localhost" style="width: 60%;"> <span data-i18n="tcpin.label.host"></span> <input type="text" id="node-input-host" placeholder="localhost" style="width: 60%;">
@ -41,8 +41,8 @@
<span data-i18n="tcpin.label.payload"></span> <span data-i18n="tcpin.label.payload"></span>
</div> </div>
<div id="node-row-newline" class="form-row hidden" style="padding-left: 110px;"> <div id="node-row-newline" class="form-row hidden" style="padding-left:110px;">
<span data-i18n="tcpin.label.delimited"></span> <input type="text" id="node-input-newline" style="width: 110px;"> <span data-i18n="tcpin.label.delimited"></span> <input type="text" id="node-input-newline" style="width:110px;">
</div> </div>
<div class="form-row"> <div class="form-row">
@ -167,7 +167,7 @@
color:"Silver", color:"Silver",
defaults: { defaults: {
host: {value:"",validate:function(v) { return (this.beserver != "client")||v.length > 0;} }, host: {value:"",validate:function(v) { return (this.beserver != "client")||v.length > 0;} },
port: {value:"",validate:function(v) { return (this.beserver == "reply")||RED.validators.number()(v) } }, port: {value:"",validate:function(v) { return (this.beserver == "reply")||RED.validators.number()(v); } },
beserver: {value:"client",required:true}, beserver: {value:"client",required:true},
base64: {value:false,required:true}, base64: {value:false,required:true},
end: {value:false,required:true}, end: {value:false,required:true},
@ -221,6 +221,7 @@
<option value="char" data-i18n="tcpin.return.character"></option> <option value="char" data-i18n="tcpin.return.character"></option>
<option value="count" data-i18n="tcpin.return.number"></option> <option value="count" data-i18n="tcpin.return.number"></option>
<option value="sit" data-i18n="tcpin.return.never"></option> <option value="sit" data-i18n="tcpin.return.never"></option>
<option value="immed" data-i18n="tcpin.return.immed"></option>
</select> </select>
<input type="text" id="node-input-splitc" style="width:50px;"> <input type="text" id="node-input-splitc" style="width:50px;">
<span id="node-units"></span> <span id="node-units"></span>
@ -235,7 +236,8 @@
<p>A simple TCP request node - sends the <code>msg.payload</code> to a server tcp port and expects a response.</p> <p>A simple TCP request node - sends the <code>msg.payload</code> to a server tcp port and expects a response.</p>
<p>Connects, sends the "request", and reads the "response". It can either count a number of <p>Connects, sends the "request", and reads the "response". It can either count a number of
returned characters into a fixed buffer, match a specified character before returning, returned characters into a fixed buffer, match a specified character before returning,
wait a fixed timeout from first reply and then return, or just sit and wait for data.</p> wait a fixed timeout from first reply and then return, sit and wait for data, or send then close the connection
immediately, without waiting for a reply.</p>
<p>The response will be output in <code>msg.payload</code> as a buffer, so you may want to .toString() it.</p> <p>The response will be output in <code>msg.payload</code> as a buffer, so you may want to .toString() it.</p>
<p>If you leave tcp host or port blank they must be set by using the <code>msg.host</code> and <code>msg.port</code> properties.</p> <p>If you leave tcp host or port blank they must be set by using the <code>msg.host</code> and <code>msg.port</code> properties.</p>
<p><b>Note: </b>Setting a timeout of 0 mS will return immediately and close the connection, without waiting for any reply.</p> <p><b>Note: </b>Setting a timeout of 0 mS will return immediately and close the connection, without waiting for any reply.</p>
@ -264,21 +266,25 @@
oneditprepare: function() { oneditprepare: function() {
var previous = null; var previous = null;
$("#node-input-out").on('focus', function () { previous = this.value; }).change(function() { $("#node-input-out").on('focus', function () { previous = this.value; }).change(function() {
if (previous == null) { previous = $("#node-input-out").val(); } if (previous === null) { previous = $("#node-input-out").val(); }
if ($("#node-input-out").val() == "char") { if ($("#node-input-out").val() == "char") {
if (previous != "char") $("#node-input-splitc").val("\\n"); if (previous != "char") { $("#node-input-splitc").val("\\n"); }
$("#node-units").text(""); $("#node-units").text("");
} }
else if ($("#node-input-out").val() == "time") { else if ($("#node-input-out").val() == "time") {
if (previous != "time") $("#node-input-splitc").val("0"); if (previous != "time") { $("#node-input-splitc").val("0"); }
$("#node-units").text("ms"); $("#node-units").text("ms");
} }
else if ($("#node-input-out").val() == "immed") {
if (previous != "immed") { $("#node-input-splitc").val(" "); }
$("#node-units").text("");
}
else if ($("#node-input-out").val() == "count") { else if ($("#node-input-out").val() == "count") {
if (previous != "count") $("#node-input-splitc").val("12"); if (previous != "count") { $("#node-input-splitc").val("12"); }
$("#node-units").text("chars"); $("#node-units").text("chars");
} }
else { else {
if (previous != "sit") $("#node-input-splitc").val("0"); if (previous != "sit") { $("#node-input-splitc").val(" "); }
$("#node-units").text(""); $("#node-units").text("");
} }
}); });

View File

@ -391,7 +391,8 @@ module.exports = function(RED) {
this.out = n.out; this.out = n.out;
this.splitc = n.splitc; this.splitc = n.splitc;
if (this.out != "char") { this.splitc = Number(this.splitc); } if (this.out === "immed") { this.splitc = -1; this.out = "time"; }
if (this.out !== "char") { this.splitc = Number(this.splitc); }
else { else {
if (this.splitc[0] == '\\') { if (this.splitc[0] == '\\') {
this.splitc = parseInt(this.splitc.replace("\\n",0x0A).replace("\\r",0x0D).replace("\\t",0x09).replace("\\e",0x1B).replace("\\f",0x0C).replace("\\0",0x00)); this.splitc = parseInt(this.splitc.replace("\\n",0x0A).replace("\\r",0x0D).replace("\\t",0x09).replace("\\e",0x1B).replace("\\f",0x0C).replace("\\0",0x00));
@ -445,9 +446,10 @@ module.exports = function(RED) {
if (clients[connection_id] && clients[connection_id].client) { if (clients[connection_id] && clients[connection_id].client) {
clients[connection_id].connected = true; clients[connection_id].connected = true;
clients[connection_id].client.write(clients[connection_id].msg.payload); clients[connection_id].client.write(clients[connection_id].msg.payload);
if (node.out === "time" && node.splitc === 0) { if (node.out === "time" && node.splitc < 0) {
clients[connection_id].client.destroy();
clients[connection_id].connected = false; clients[connection_id].connected = false;
clients[connection_id].client.end();
delete clients[connection_id];
node.status({}); node.status({});
} }
} }
@ -465,10 +467,10 @@ module.exports = function(RED) {
node.send(RED.util.cloneMessage(clients[connection_id].msg)); node.send(RED.util.cloneMessage(clients[connection_id].msg));
} }
} }
else if (node.splitc === 0) { // else if (node.splitc === 0) {
clients[connection_id].msg.payload = data; // clients[connection_id].msg.payload = data;
node.send(clients[connection_id].msg); // node.send(clients[connection_id].msg);
} // }
else { else {
for (var j = 0; j < data.length; j++ ) { for (var j = 0; j < data.length; j++ ) {
if (node.out === "time") { if (node.out === "time") {
@ -571,7 +573,6 @@ module.exports = function(RED) {
node.status({fill:"red",shape:"ring",text:"common.status.error"}); node.status({fill:"red",shape:"ring",text:"common.status.error"});
node.error(RED._("tcpin.errors.connect-fail") + " " + connection_id, msg); node.error(RED._("tcpin.errors.connect-fail") + " " + connection_id, msg);
if (clients[connection_id] && clients[connection_id].client) { if (clients[connection_id] && clients[connection_id].client) {
clients[connection_id].connected = false;
clients[connection_id].client.destroy(); clients[connection_id].client.destroy();
delete clients[connection_id]; delete clients[connection_id];
} }
@ -601,13 +602,14 @@ module.exports = function(RED) {
this.on("close", function(done) { this.on("close", function(done) {
node.done = done; node.done = done;
for (var client in clients) { for (var cl in clients) {
if (clients.hasOwnProperty("client")) { if (clients[cl].hasOwnProperty("client")) {
clients[client].client.destroy(); clients[cl].client.destroy();
} }
} }
node.status({}); node.status({});
// this is probably not necessary and may be removed
var anyConnected = false; var anyConnected = false;
for (var c in clients) { for (var c in clients) {
if (clients[c].connected) { if (clients[c].connected) {
@ -615,11 +617,8 @@ module.exports = function(RED) {
break; break;
} }
} }
if (!anyConnected) { clients = {}; }
if (!anyConnected) {
clients = {};
done(); done();
}
}); });
} }

View File

@ -186,6 +186,7 @@
"action": "Action", "action": "Action",
"for": "For", "for": "For",
"delaymsg": "Delay message", "delaymsg": "Delay message",
"delayvarmsg": "Set delay with msg.delay",
"randomdelay": "Random delay", "randomdelay": "Random delay",
"limitrate": "Limit rate to", "limitrate": "Limit rate to",
"fairqueue": "Topic based fair queue", "fairqueue": "Topic based fair queue",
@ -205,6 +206,7 @@
"dropmsg": "drop intermediate messages", "dropmsg": "drop intermediate messages",
"label": { "label": {
"delay": "delay", "delay": "delay",
"variable": "variable",
"limit": "limit", "limit": "limit",
"random": "random", "random": "random",
"queue": "queue", "queue": "queue",
@ -415,7 +417,8 @@
"timeout": "after a fixed timeout of", "timeout": "after a fixed timeout of",
"character": "when character received is", "character": "when character received is",
"number": "a fixed number of chars", "number": "a fixed number of chars",
"never": "never - keep connection open" "never": "never - keep connection open",
"immed": "immediately - don't wait for reply"
}, },
"status": { "status": {
"connecting": "connecting to __host__:__port__", "connecting": "connecting to __host__:__port__",

View File

@ -339,6 +339,75 @@ describe('delay Node', function() {
} }
} }
/**
* Runs a VARIABLE DELAY test, checks if the delay is in between the given timeout values
* @param aTimeoutFrom - the timeout quantity which is the minimal acceptable wait period
* @param aTimeoutTo - the timeout quantity which is the maximum acceptable wait period
* @param aTimeoutUnit - the unit of the timeout: milliseconds, seconds, minutes, hours, days
* @param delay - the variable delay: milliseconds
*/
function variableDelayTest(aTimeoutFrom, aTimeoutTo, aTimeoutUnit, delay, done) {
var flow = [{"id":"delayNode1","type":"delay","name":"delayNode","pauseType":"delayv","timeout":5,"timeoutUnits":"seconds","rate":"1","rateUnits":"second","randomFirst":aTimeoutFrom,"randomLast":aTimeoutTo,"randomUnits":aTimeoutUnit,"drop":false,"wires":[["helperNode1"]]},
{id:"helperNode1", type:"helper", wires:[]}];
helper.load(delayNode, flow, function() {
var delayNode1 = helper.getNode("delayNode1");
var helperNode1 = helper.getNode("helperNode1");
helperNode1.on("input", function(msg) {
try {
var endTime = process.hrtime(startTime);
var runtimeNanos = ( (endTime[0] * nanosToSeconds) + endTime[1] );
var runtimeSeconds = runtimeNanos / nanosToSeconds;
var aTimeoutFromUnifiedToSeconds;
var aTimeoutToUnifiedToSeconds;
// calculating the timeout in seconds
if (aTimeoutUnit == TimeUnitEnum.MILLIS) {
aTimeoutFromUnifiedToSeconds = aTimeoutFrom / millisToSeconds;
aTimeoutToUnifiedToSeconds = aTimeoutTo / millisToSeconds;
} else if (aTimeoutUnit == TimeUnitEnum.SECONDS) {
aTimeoutFromUnifiedToSeconds = aTimeoutFrom;
aTimeoutToUnifiedToSeconds = aTimeoutTo;
} else if (aTimeoutUnit == TimeUnitEnum.MINUTES) {
aTimeoutFromUnifiedToSeconds = aTimeoutFrom * secondsToMinutes;
aTimeoutToUnifiedToSeconds = aTimeoutTo * secondsToMinutes;
} else if (aTimeoutUnit == TimeUnitEnum.HOURS) {
aTimeoutFromUnifiedToSeconds = aTimeoutFrom * secondsToHours;
aTimeoutToUnifiedToSeconds = aTimeoutTo * secondsToHours;
} else if (aTimeoutUnit == TimeUnitEnum.DAYS) {
aTimeoutFromUnifiedToSeconds = aTimeoutFrom * secondsToDays;
aTimeoutToUnifiedToSeconds = aTimeoutTo * secondsToDays;
}
if (inBetweenDelays(aTimeoutFromUnifiedToSeconds, aTimeoutToUnifiedToSeconds, runtimeSeconds, GRACE_PERCENTAGE)) {
done();
} else {
try {
should.fail(null, null, "Delayed runtime seconds " + runtimeSeconds + " was not \"in between enough\" enough to expected values of: " + aTimeoutFromUnifiedToSeconds + " and " + aTimeoutToUnifiedToSeconds);
} catch (err) {
done(err);
}
}
} catch(err) {
done(err);
}
});
var startTime = process.hrtime();
delayNode1.receive({payload:"delayMe", delay:delay});
});
}
it('variable delay set by msg.delay the message in milliseconds', function(done) {
variableDelayTest("200", "300", "milliseconds", 250, done);
});
it('variable delay is zero if msg.delay not specified', function(done) {
variableDelayTest("0", "50", "milliseconds", null, done);
});
it('variable delay is zero if msg.delay is negative', function(done) {
variableDelayTest("0", "50", "milliseconds", -250, done);
});
/** /**
* Runs a RANDOM DELAY test, checks if the delay is in between the given timeout values * Runs a RANDOM DELAY test, checks if the delay is in between the given timeout values
* @param aTimeoutFrom - the timeout quantity which is the minimal acceptable wait period * @param aTimeoutFrom - the timeout quantity which is the minimal acceptable wait period