Fix up runtime tests

This commit is contained in:
Nick O'Leary 2018-04-23 14:24:51 +01:00
parent e3b1179a21
commit 34832d5942
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
15 changed files with 144 additions and 101 deletions

View File

@ -18,7 +18,7 @@ var when = require("when");
var crypto = require('crypto');
var runtime;
var settings;
var log = require("../../util").log; // TODO: separate module
var log;
var encryptedCredentials = null;

View File

@ -17,7 +17,7 @@
var when = require("when");
var clone = require("clone");
var typeRegistry = require("../registry");
var Log = require("../../../util").log; // TODO: separate module
var Log;
var redUtil = require("../../util");
var flowUtil = require("./util");
@ -495,8 +495,9 @@ function createSubflow(sf,sfn,subflows,globalSubflows,activeNodes) {
module.exports = {
init: function(settings) {
nodeCloseTimeout = settings.nodeCloseTimeout || 15000;
init: function(runtime) {
nodeCloseTimeout = runtime.settings.nodeCloseTimeout || 15000;
Log = runtime.log;
},
create: function(global,conf) {
return new Flow(global,conf);

View File

@ -24,7 +24,7 @@ var context = require("../context")
var credentials = require("../credentials");
var flowUtil = require("./util");
var log = require("../../../util").log; // TODO: separate module
var log;
var events = require("../../events");
var redUtil = require("../../util");
var deprecated = require("../registry/deprecated");
@ -50,6 +50,7 @@ function init(runtime) {
}
settings = runtime.settings;
storage = runtime.storage;
log = runtime.log;
started = false;
if (!typeEventRegistered) {
events.on('type-registered',function(type) {
@ -67,7 +68,7 @@ function init(runtime) {
});
typeEventRegistered = true;
}
Flow.init(settings);
Flow.init(runtime);
}
function loadFlows() {

View File

@ -25,7 +25,7 @@ var flows = require("./flows");
var flowUtil = require("./flows/util")
var context = require("./context");
var Node = require("./Node");
var log = require("../../util").log; // TODO: separate module
var log;
var library = require("./library");
var events = require("../events");
@ -94,6 +94,7 @@ function createNode(node,def) {
function init(runtime) {
settings = runtime.settings;
log = runtime.log;
credentials.init(runtime);
flows.init(runtime);
registry.init(runtime);

View File

@ -27,7 +27,7 @@ var settings;
function init(runtime) {
settings = runtime.settings;
installer.init(runtime.settings);
installer.init(runtime);
loader.init(runtime);
registry.init(settings,loader);
}

View File

@ -20,7 +20,7 @@ var path = require("path");
var fs = require("fs");
var registry = require("./registry");
var log = require("../../../util").log; // TODO: separate module
var log;
var events = require("../../events");
@ -32,8 +32,9 @@ var settings;
var moduleRe = /^(@[^/]+?[/])?[^/]+?$/;
var slashRe = process.platform === "win32" ? /\\|[/]/ : /[/]/;
function init(_settings) {
settings = _settings;
function init(runtime) {
settings = runtime.settings;
log = runtime.log;
}
function checkModulePath(folder) {

View File

@ -19,8 +19,8 @@ var fs = require("fs");
var path = require("path");
var events;
var log = require("../../../util").log; // TODO: separate module
var i18n = require("../../../util").i18n; // TODO: separate module
var log;
var i18n;
var settings;
var disableNodePathScan = false;
@ -29,6 +29,8 @@ var iconFileExtensions = [".png", ".gif"];
function init(runtime) {
settings = runtime.settings;
events = runtime.events;
log = runtime.log;
i18n = runtime.i18n;
}
function isIncluded(name) {

View File

@ -24,7 +24,7 @@ var runtime = require("../../../red/runtime");
var redNodes = require("../../../red/runtime/nodes");
var storage = require("../../../red/runtime/storage");
var settings = require("../../../red/runtime/settings");
var log = require("../../../red/runtime/log");
var log = require("../../../red/util/log");
describe("runtime", function() {
afterEach(function() {
@ -39,7 +39,22 @@ describe("runtime", function() {
after(function() {
delete process.env.NODE_RED_HOME;
});
function mockUtil(metrics) {
return {
log:{
log: sinon.stub(),
warn: sinon.stub(),
info: sinon.stub(),
metric: sinon.stub().returns(!!metrics),
_: function() { return "abc"}
},
i18n: {
registerMessageCatalog: function(){
return Promise.resolve();
}
}
}
}
describe("init", function() {
beforeEach(function() {
sinon.stub(log,"init",function() {});
@ -53,14 +68,13 @@ describe("runtime", function() {
})
it("initialises components", function() {
runtime.init({testSettings: true, httpAdminRoot:"/"});
log.init.called.should.be.true();
runtime.init({testSettings: true, httpAdminRoot:"/"},mockUtil());
settings.init.called.should.be.true();
redNodes.init.called.should.be.true();
});
it("returns version", function() {
runtime.init({testSettings: true, httpAdminRoot:"/"});
runtime.init({testSettings: true, httpAdminRoot:"/"},mockUtil());
/^\d+\.\d+\.\d+(-git)?$/.test(runtime.version()).should.be.true();
})
@ -69,23 +83,14 @@ describe("runtime", function() {
describe("start",function() {
var storageInit;
var settingsLoad;
var logMetric;
var logWarn;
var logInfo;
var logLog;
var redNodesInit;
var redNodesLoad;
var redNodesCleanModuleList;
var redNodesGetNodeList;
var redNodesLoadFlows;
var redNodesStartFlows;
beforeEach(function() {
storageInit = sinon.stub(storage,"init",function(settings) {return when.resolve();});
logMetric = sinon.stub(log,"metric",function() { return false; });
logWarn = sinon.stub(log,"warn",function() { });
logInfo = sinon.stub(log,"info",function() { });
logLog = sinon.stub(log,"log",function(m) {});
redNodesInit = sinon.stub(redNodes,"init", function() {});
redNodesLoad = sinon.stub(redNodes,"load", function() {return when.resolve()});
redNodesCleanModuleList = sinon.stub(redNodes,"cleanModuleList",function(){});
@ -94,10 +99,6 @@ describe("runtime", function() {
});
afterEach(function() {
storageInit.restore();
logMetric.restore();
logWarn.restore();
logInfo.restore();
logLog.restore();
redNodesInit.restore();
redNodesLoad.restore();
redNodesGetNodeList.restore();
@ -112,25 +113,26 @@ describe("runtime", function() {
{ module:"module",enabled:true,loaded:false,types:["typeA","typeB"]} // missing
].filter(cb);
});
runtime.init({testSettings: true, httpAdminRoot:"/", load:function() { return when.resolve();}});
sinon.stub(console,"log");
var util = mockUtil();
runtime.init({testSettings: true, httpAdminRoot:"/", load:function() { return when.resolve();}},util);
// sinon.stub(console,"log");
runtime.start().then(function() {
console.log.restore();
// console.log.restore();
try {
storageInit.calledOnce.should.be.true();
redNodesInit.calledOnce.should.be.true();
redNodesLoad.calledOnce.should.be.true();
redNodesLoadFlows.calledOnce.should.be.true();
logWarn.calledWithMatch("Failed to register 1 node type");
logWarn.calledWithMatch("Missing node modules");
logWarn.calledWithMatch(" - module: typeA, typeB");
util.log.warn.calledWithMatch("Failed to register 1 node type");
util.log.warn.calledWithMatch("Missing node modules");
util.log.warn.calledWithMatch(" - module: typeA, typeB");
redNodesCleanModuleList.calledOnce.should.be.true();
done();
} catch(err) {
done(err);
}
});
}).catch(err=>{done(err)});
});
it("initiates load of missing modules",function(done) {
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function(cb) {
@ -142,15 +144,16 @@ describe("runtime", function() {
].filter(cb);
});
var serverInstallModule = sinon.stub(redNodes,"installModule",function(name) { return when.resolve({nodes:[]});});
runtime.init({testSettings: true, autoInstallModules:true, httpAdminRoot:"/", load:function() { return when.resolve();}});
var util = mockUtil();
runtime.init({testSettings: true, autoInstallModules:true, httpAdminRoot:"/", load:function() { return when.resolve();}},util);
sinon.stub(console,"log");
runtime.start().then(function() {
console.log.restore();
try {
logWarn.calledWithMatch("Failed to register 2 node types");
logWarn.calledWithMatch("Missing node modules");
logWarn.calledWithMatch(" - module: typeA, typeB");
logWarn.calledWithMatch(" - node-red: typeC, typeD");
util.log.warn.calledWithMatch("Failed to register 2 node types");
util.log.warn.calledWithMatch("Missing node modules");
util.log.warn.calledWithMatch(" - module: typeA, typeB");
util.log.warn.calledWithMatch(" - node-red: typeC, typeD");
redNodesCleanModuleList.calledOnce.should.be.false();
serverInstallModule.calledOnce.should.be.true();
serverInstallModule.calledWithMatch("module");
@ -160,7 +163,7 @@ describe("runtime", function() {
} finally {
serverInstallModule.restore();
}
});
}).catch(err=>{done(err)});
});
it("reports errored modules when verbose is enabled",function(done) {
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function(cb) {
@ -168,38 +171,35 @@ describe("runtime", function() {
{ err:"errored",name:"errName" } // error
].filter(cb);
});
runtime.init({testSettings: true, verbose:true, httpAdminRoot:"/", load:function() { return when.resolve();}});
var util = mockUtil();
runtime.init({testSettings: true, verbose:true, httpAdminRoot:"/", load:function() { return when.resolve();}},util);
sinon.stub(console,"log");
runtime.start().then(function() {
console.log.restore();
try {
logWarn.neverCalledWithMatch("Failed to register 1 node type");
logWarn.calledWithMatch("[errName] errored");
util.log.warn.neverCalledWithMatch("Failed to register 1 node type");
util.log.warn.calledWithMatch("[errName] errored");
done();
} catch(err) {
done(err);
}
});
}).catch(err=>{done(err)});
});
it("reports runtime metrics",function(done) {
var stopFlows = sinon.stub(redNodes,"stopFlows",function() {} );
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function() {return []});
logMetric.restore();
logMetric = sinon.stub(log,"metric",function() { return true; });
runtime.init({testSettings: true, runtimeMetricInterval:200, httpAdminRoot:"/", load:function() { return when.resolve();}});
var util = mockUtil(true);
runtime.init({testSettings: true, runtimeMetricInterval:200, httpAdminRoot:"/", load:function() { return when.resolve();}},util);
sinon.stub(console,"log");
runtime.start().then(function() {
console.log.restore();
setTimeout(function() {
try {
logLog.args.should.have.lengthOf(3);
logLog.args[0][0].should.have.property("level",log.METRIC);
logLog.args[0][0].should.have.property("event","runtime.memory.rss");
logLog.args[1][0].should.have.property("level",log.METRIC);
logLog.args[1][0].should.have.property("event","runtime.memory.heapTotal");
logLog.args[2][0].should.have.property("level",log.METRIC);
logLog.args[2][0].should.have.property("event","runtime.memory.heapUsed");
util.log.log.args.should.have.lengthOf(3);
util.log.log.args[0][0].should.have.property("event","runtime.memory.rss");
util.log.log.args[1][0].should.have.property("event","runtime.memory.heapTotal");
util.log.log.args[2][0].should.have.property("event","runtime.memory.heapUsed");
done();
} catch(err) {
done(err);
@ -208,7 +208,7 @@ describe("runtime", function() {
stopFlows.restore();
}
},300);
});
}).catch(err=>{done(err)});
});

View File

@ -17,7 +17,7 @@
var should = require("should");
var sinon = require('sinon');
var RedNode = require("../../../../red/runtime/nodes/Node");
var Log = require("../../../../red/runtime/log");
var Log = require("../../../../red/util/log");
var flows = require("../../../../red/runtime/nodes/flows");
describe('Node', function() {

View File

@ -21,7 +21,7 @@ var util = require("util");
var index = require("../../../../red/runtime/nodes/index");
var credentials = require("../../../../red/runtime/nodes/credentials");
var log = require("../../../../red/runtime/log");
var log = require("../../../../red/util/log");
describe('red/runtime/nodes/credentials', function() {

View File

@ -41,7 +41,15 @@ describe('Flow', function() {
stoppedNodes = {};
rewiredNodes = {};
createCount = 0;
Flow.init({});
Flow.init({settings:{},log:{
log: sinon.stub(),
debug: sinon.stub(),
trace: sinon.stub(),
warn: sinon.stub(),
info: sinon.stub(),
metric: sinon.stub(),
_: function() { return "abc"}
}});
});
var TestNode = function(n) {
@ -162,15 +170,19 @@ describe('Flow', function() {
currentNodes["3"].should.have.a.property("handled",1);
flow.stop().then(function() {
currentNodes.should.not.have.a.property("1");
currentNodes.should.not.have.a.property("2");
currentNodes.should.not.have.a.property("3");
currentNodes.should.not.have.a.property("4");
stoppedNodes.should.have.a.property("1");
stoppedNodes.should.have.a.property("2");
stoppedNodes.should.have.a.property("3");
stoppedNodes.should.have.a.property("4");
done();
try {
currentNodes.should.not.have.a.property("1");
currentNodes.should.not.have.a.property("2");
currentNodes.should.not.have.a.property("3");
currentNodes.should.not.have.a.property("4");
stoppedNodes.should.have.a.property("1");
stoppedNodes.should.have.a.property("2");
stoppedNodes.should.have.a.property("3");
stoppedNodes.should.have.a.property("4");
done();
} catch(err) {
done(err);
}
});
});
@ -552,10 +564,15 @@ describe('Flow', function() {
});
it("Times out a node that fails to close", function(done) {
Flow.init({nodeCloseTimeout:50});
Flow.init({settings:{nodeCloseTimeout:50},log:{
log: sinon.stub(),
debug: sinon.stub(),
trace: sinon.stub(),
warn: sinon.stub(),
info: sinon.stub(),
metric: sinon.stub(),
_: function() { return "abc"}
}});
var config = flowUtils.parseConfig([
{id:"t1",type:"tab"},
{id:"1",x:10,y:10,z:"t1",type:"testAsync",closeDelay: 80, foo:"a",wires:["2"]},
@ -1084,6 +1101,6 @@ describe('Flow', function() {
done();
});
});
it.skip("prevents an error looping more than 10 times",function(){});
it("prevents an error looping more than 10 times",function(){});
});
});

View File

@ -36,6 +36,17 @@ describe('flows/index', function() {
var flowCreate;
var getType;
var mockLog = {
log: sinon.stub(),
debug: sinon.stub(),
trace: sinon.stub(),
warn: sinon.stub(),
info: sinon.stub(),
metric: sinon.stub(),
_: function() { return "abc"}
}
before(function() {
getType = sinon.stub(typeRegistry,"get",function(type) {
return type.indexOf('missing') === -1;
@ -112,7 +123,7 @@ describe('flows/index', function() {
{id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]},
{id:"t1",type:"tab"}
];
flows.init({settings:{},storage:storage});
flows.init({log:mockLog, settings:{},storage:storage});
flows.setFlows(originalConfig).then(function() {
credentialsClean.called.should.be.true();
storage.hasOwnProperty('conf').should.be.true();
@ -135,7 +146,7 @@ describe('flows/index', function() {
return when.resolve({flows:originalConfig,rev:123})
}
}
flows.init({settings:{},storage:loadStorage});
flows.init({log:mockLog, settings:{},storage:loadStorage});
flows.setFlows(originalConfig,"load").then(function() {
credentialsClean.called.should.be.false();
// 'load' type does not trigger a save
@ -151,7 +162,7 @@ describe('flows/index', function() {
{id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[],credentials:{"a":1}},
{id:"t1",type:"tab"}
];
flows.init({settings:{},storage:storage});
flows.init({log:mockLog, settings:{},storage:storage});
flows.setFlows(originalConfig).then(function() {
credentialsClean.called.should.be.true();
storage.hasOwnProperty('conf').should.be.true();
@ -187,7 +198,7 @@ describe('flows/index', function() {
})
});
flows.init({settings:{},storage:storage});
flows.init({log:mockLog, settings:{},storage:storage});
flows.load().then(function() {
flows.startFlows();
});
@ -216,7 +227,7 @@ describe('flows/index', function() {
})
});
flows.init({settings:{},storage:storage});
flows.init({log:mockLog, settings:{},storage:storage});
flows.load().then(function() {
flows.startFlows();
});
@ -233,7 +244,7 @@ describe('flows/index', function() {
storage.getFlows = function() {
return when.resolve({flows:originalConfig});
}
flows.init({settings:{},storage:storage});
flows.init({log:mockLog, settings:{},storage:storage});
flows.load().then(function() {
credentialsLoad.called.should.be.true();
// 'load' type does not trigger a save
@ -259,7 +270,7 @@ describe('flows/index', function() {
done();
});
flows.init({settings:{},storage:storage});
flows.init({log:mockLog, settings:{},storage:storage});
flows.load().then(function() {
flows.startFlows();
});
@ -274,7 +285,7 @@ describe('flows/index', function() {
return when.resolve({flows:originalConfig});
}
flows.init({settings:{},storage:storage});
flows.init({log:mockLog, settings:{},storage:storage});
flows.load().then(function() {
flows.startFlows();
flowCreate.called.should.be.false();
@ -292,7 +303,7 @@ describe('flows/index', function() {
storage.getFlows = function() {
return when.resolve({flows:originalConfig});
}
flows.init({settings:{},storage:storage});
flows.init({log:mockLog, settings:{},storage:storage});
flows.load().then(function() {
flows.startFlows();
flowCreate.called.should.be.false();
@ -326,7 +337,7 @@ describe('flows/index', function() {
storage.getFlows = function() {
return when.resolve({flows:originalConfig});
}
flows.init({settings:{},storage:storage});
flows.init({log:mockLog, settings:{},storage:storage});
flows.load().then(function() {
var c = 0;
flows.eachNode(function(node) {
@ -357,7 +368,7 @@ describe('flows/index', function() {
done();
});
flows.init({settings:{},storage:storage});
flows.init({log:mockLog, settings:{},storage:storage});
flows.load().then(function() {
flows.startFlows();
});
@ -388,7 +399,7 @@ describe('flows/index', function() {
}
});
flows.init({settings:{},storage:storage});
flows.init({log:mockLog, settings:{},storage:storage});
flows.load().then(function() {
flows.startFlows();
});
@ -410,7 +421,7 @@ describe('flows/index', function() {
done();
});
flows.init({settings:{},storage:storage});
flows.init({log:mockLog, settings:{},storage:storage});
flows.load().then(function() {
flows.startFlows();
});
@ -442,7 +453,7 @@ describe('flows/index', function() {
}
});
flows.init({settings:{},storage:storage});
flows.init({log:mockLog, settings:{},storage:storage});
flows.load().then(function() {
flows.startFlows();
});
@ -470,7 +481,7 @@ describe('flows/index', function() {
{id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]},
{id:"t1",type:"tab"}
];
flows.init({settings:{},storage:storage});
flows.init({log:mockLog, settings:{},storage:storage});
flows.setFlows(originalConfig).then(function() {
flows.checkTypeInUse("unused-module");
done();
@ -481,7 +492,7 @@ describe('flows/index', function() {
{id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]},
{id:"t1",type:"tab"}
];
flows.init({settings:{},storage:storage});
flows.init({log:mockLog, settings:{},storage:storage});
flows.setFlows(originalConfig).then(function() {
/*jshint immed: false */
try {
@ -504,7 +515,7 @@ describe('flows/index', function() {
storage.getFlows = function() {
return when.resolve({flows:originalConfig});
}
flows.init({settings:{},storage:storage});
flows.init({log:mockLog, settings:{},storage:storage});
flows.load().then(function() {
flows.addFlow({
label:'new flow',
@ -531,7 +542,7 @@ describe('flows/index', function() {
storage.setFlows = function() {
return when.resolve();
}
flows.init({settings:{},storage:storage});
flows.init({log:mockLog, settings:{},storage:storage});
flows.load().then(function() {
return flows.startFlows();
}).then(function() {
@ -539,8 +550,7 @@ describe('flows/index', function() {
label:'new flow',
nodes:[
{id:"t2-1",x:10,y:10,z:"t1",type:"test",wires:[]},
{id:"t2-2",x:10,y:10,z:"t1",type:"test",wires:[]}
,
{id:"t2-2",x:10,y:10,z:"t1",type:"test",wires:[]},
{id:"t2-3",z:"t1",type:"test"}
]
}).then(function(id) {

View File

@ -19,7 +19,7 @@ var fs = require('fs-extra');
var path = require('path');
var when = require("when");
var sinon = require('sinon');
console.log(__dirname);
var index = require("../../../../red/runtime/nodes/index");
var flows = require("../../../../red/runtime/nodes/flows");
var registry = require("../../../../red/runtime/nodes/registry");
@ -131,7 +131,7 @@ describe("red/nodes/index", function() {
var runtime = require("../../../../red/runtime");
var credentials = require("../../../../red/runtime/nodes/credentials");
var localfilesystem = require("../../../../red/runtime/storage/localfilesystem");
var log = require("../../../../red/runtime/log");
var log = require("../../../../red/util/log");
var RED = require("../../../../red/red.js");
var userDir = path.join(__dirname,".testUserHome");

View File

@ -28,8 +28,18 @@ var typeRegistry = require("../../../../../red/runtime/nodes/registry/registry")
describe('nodes/registry/installer', function() {
var mockLog = {
log: sinon.stub(),
debug: sinon.stub(),
trace: sinon.stub(),
warn: sinon.stub(),
info: sinon.stub(),
metric: sinon.stub(),
_: function() { return "abc"}
}
before(function() {
installer.init({});
installer.init({log:mockLog, settings:{}});
});
afterEach(function() {
if (child_process.spawn.restore) {
@ -74,7 +84,7 @@ describe('nodes/registry/installer', function() {
});
installer.installModule("this_wont_exist").otherwise(function(err) {
err.code.should.be.eql(404);
err.should.have.property("code",404);
done();
});
});

View File

@ -20,7 +20,7 @@ var path = require('path');
var sinon = require('sinon');
var localfilesystem = require("../../../../../red/runtime/storage/localfilesystem");
var log = require("../../../../../red/runtime/log");
var log = require("../../../../../red/util/log");
describe('storage/localfilesystem', function() {
var mockRuntime = {