mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Improve core test coverage
This commit is contained in:
parent
78cf310c58
commit
36f299c031
@ -40,12 +40,11 @@ function start() {
|
|||||||
var Tokens = require("./api/auth/tokens");
|
var Tokens = require("./api/auth/tokens");
|
||||||
var Users = require("./api/auth/users");
|
var Users = require("./api/auth/users");
|
||||||
var Permissions = require("./api/auth/permissions");
|
var Permissions = require("./api/auth/permissions");
|
||||||
|
|
||||||
if (!settings.disableEditor) {
|
if (!settings.disableEditor) {
|
||||||
Users.default().then(function(anonymousUser) {
|
Users.default().then(function(anonymousUser) {
|
||||||
var webSocketKeepAliveTime = settings.webSocketKeepAliveTime || 15000;
|
var webSocketKeepAliveTime = settings.webSocketKeepAliveTime || 15000;
|
||||||
var path = settings.httpAdminRoot || "/";
|
var path = settings.httpAdminRoot || "/";
|
||||||
path = path + (path.slice(-1) == "/" ? "":"/") + "comms";
|
path = (path.slice(0,1) != "/" ? "/":"") + path + (path.slice(-1) == "/" ? "":"/") + "comms";
|
||||||
wsServer = new ws.Server({server:server,path:path});
|
wsServer = new ws.Server({server:server,path:path});
|
||||||
|
|
||||||
wsServer.on('connection',function(ws) {
|
wsServer.on('connection',function(ws) {
|
||||||
@ -127,9 +126,11 @@ function start() {
|
|||||||
function stop() {
|
function stop() {
|
||||||
if (heartbeatTimer) {
|
if (heartbeatTimer) {
|
||||||
clearInterval(heartbeatTimer);
|
clearInterval(heartbeatTimer);
|
||||||
|
heartbeatTimer = null;
|
||||||
}
|
}
|
||||||
if (wsServer) {
|
if (wsServer) {
|
||||||
wsServer.close();
|
wsServer.close();
|
||||||
|
wsServer = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,6 @@ var ConsoleLogHandler = function(settings) {
|
|||||||
this.metricsOn = settings.metrics||false;
|
this.metricsOn = settings.metrics||false;
|
||||||
metricsEnabled = this.metricsOn;
|
metricsEnabled = this.metricsOn;
|
||||||
this.on("log",function(msg) {
|
this.on("log",function(msg) {
|
||||||
/* istanbul ignore else */
|
|
||||||
if (this.shouldReportMessage(msg.level)) {
|
if (this.shouldReportMessage(msg.level)) {
|
||||||
if (msg.level == log.METRIC) {
|
if (msg.level == log.METRIC) {
|
||||||
util.log("[metric] "+JSON.stringify(msg));
|
util.log("[metric] "+JSON.stringify(msg));
|
||||||
|
@ -54,7 +54,7 @@ function start() {
|
|||||||
if (log.metric()) {
|
if (log.metric()) {
|
||||||
runtimeMetricInterval = setInterval(function() {
|
runtimeMetricInterval = setInterval(function() {
|
||||||
reportMetrics();
|
reportMetrics();
|
||||||
}, 15000);
|
}, settings.runtimeMetricInterval||15000);
|
||||||
}
|
}
|
||||||
console.log("\n\nWelcome to Node-RED\n===================\n");
|
console.log("\n\nWelcome to Node-RED\n===================\n");
|
||||||
if (settings.version) {
|
if (settings.version) {
|
||||||
@ -92,7 +92,7 @@ function start() {
|
|||||||
if (missingModules.hasOwnProperty(i)) {
|
if (missingModules.hasOwnProperty(i)) {
|
||||||
log.warn(" - "+i+": "+missingModules[i].join(", "));
|
log.warn(" - "+i+": "+missingModules[i].join(", "));
|
||||||
if (settings.autoInstallModules && i != "node-red") {
|
if (settings.autoInstallModules && i != "node-red") {
|
||||||
installModule(i).otherwise(function(err) {
|
serverAPI.installModule(i).otherwise(function(err) {
|
||||||
// Error already reported. Need the otherwise handler
|
// Error already reported. Need the otherwise handler
|
||||||
// to stop the error propagating any further
|
// to stop the error propagating any further
|
||||||
});
|
});
|
||||||
@ -216,22 +216,21 @@ function uninstallModule(module) {
|
|||||||
function reportMetrics() {
|
function reportMetrics() {
|
||||||
var memUsage = process.memoryUsage();
|
var memUsage = process.memoryUsage();
|
||||||
|
|
||||||
// only need to init these once per report
|
log.log({
|
||||||
var metrics = {};
|
level: log.METRIC,
|
||||||
metrics.level = log.METRIC;
|
event: "runtime.memory.rss",
|
||||||
|
value: memUsage.rss
|
||||||
//report it
|
});
|
||||||
metrics.event = "runtime.memory.rss"
|
log.log({
|
||||||
metrics.value = memUsage.rss;
|
level: log.METRIC,
|
||||||
log.log(metrics);
|
event: "runtime.memory.heapTotal",
|
||||||
|
value: memUsage.heapTotal
|
||||||
metrics.event = "runtime.memory.heapTotal"
|
});
|
||||||
metrics.value = memUsage.heapTotal;
|
log.log({
|
||||||
log.log(metrics);
|
level: log.METRIC,
|
||||||
|
event: "runtime.memory.heapUsed",
|
||||||
metrics.event = "runtime.memory.heapUsed"
|
value: memUsage.heapUsed
|
||||||
metrics.value = memUsage.heapUsed;
|
});
|
||||||
log.log(metrics);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function stop() {
|
function stop() {
|
||||||
@ -243,7 +242,7 @@ function stop() {
|
|||||||
comms.stop();
|
comms.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
var serverAPI = module.exports = {
|
||||||
init: init,
|
init: init,
|
||||||
start: start,
|
start: start,
|
||||||
stop: stop,
|
stop: stop,
|
||||||
|
@ -135,6 +135,137 @@ describe("comms", function() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
describe("disabled editor", function() {
|
||||||
|
var server;
|
||||||
|
var url;
|
||||||
|
var port;
|
||||||
|
before(function(done) {
|
||||||
|
server = http.createServer(function(req,res){app(req,res)});
|
||||||
|
comms.init(server, {disableEditor:true});
|
||||||
|
server.listen(listenPort, address);
|
||||||
|
server.on('listening', function() {
|
||||||
|
port = server.address().port;
|
||||||
|
url = 'http://' + address + ':' + port + '/comms';
|
||||||
|
comms.start();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
after(function() {
|
||||||
|
comms.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects websocket connections',function(done) {
|
||||||
|
var ws = new WebSocket(url);
|
||||||
|
ws.on('open', function() {
|
||||||
|
done(new Error("Socket connection unexpectedly accepted"));
|
||||||
|
ws.close();
|
||||||
|
});
|
||||||
|
ws.on('error', function() {
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("non-default httpAdminRoot set: /adminPath", function() {
|
||||||
|
var server;
|
||||||
|
var url;
|
||||||
|
var port;
|
||||||
|
before(function(done) {
|
||||||
|
server = http.createServer(function(req,res){app(req,res)});
|
||||||
|
comms.init(server, {httpAdminRoot:"/adminPath"});
|
||||||
|
server.listen(listenPort, address);
|
||||||
|
server.on('listening', function() {
|
||||||
|
port = server.address().port;
|
||||||
|
url = 'http://' + address + ':' + port + '/adminPath/comms';
|
||||||
|
comms.start();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
after(function() {
|
||||||
|
comms.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('accepts connections',function(done) {
|
||||||
|
var ws = new WebSocket(url);
|
||||||
|
ws.on('open', function() {
|
||||||
|
ws.close();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
ws.on('error', function() {
|
||||||
|
done(new Error("Socket connection failed"));
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("non-default httpAdminRoot set: /adminPath/", function() {
|
||||||
|
var server;
|
||||||
|
var url;
|
||||||
|
var port;
|
||||||
|
before(function(done) {
|
||||||
|
server = http.createServer(function(req,res){app(req,res)});
|
||||||
|
comms.init(server, {httpAdminRoot:"/adminPath/"});
|
||||||
|
server.listen(listenPort, address);
|
||||||
|
server.on('listening', function() {
|
||||||
|
port = server.address().port;
|
||||||
|
url = 'http://' + address + ':' + port + '/adminPath/comms';
|
||||||
|
comms.start();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
after(function() {
|
||||||
|
comms.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('accepts connections',function(done) {
|
||||||
|
var ws = new WebSocket(url);
|
||||||
|
ws.on('open', function() {
|
||||||
|
ws.close();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
ws.on('error', function() {
|
||||||
|
done(new Error("Socket connection failed"));
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("non-default httpAdminRoot set: adminPath", function() {
|
||||||
|
var server;
|
||||||
|
var url;
|
||||||
|
var port;
|
||||||
|
before(function(done) {
|
||||||
|
server = http.createServer(function(req,res){app(req,res)});
|
||||||
|
comms.init(server, {httpAdminRoot:"adminPath"});
|
||||||
|
server.listen(listenPort, address);
|
||||||
|
server.on('listening', function() {
|
||||||
|
port = server.address().port;
|
||||||
|
url = 'http://' + address + ':' + port + '/adminPath/comms';
|
||||||
|
comms.start();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
after(function() {
|
||||||
|
comms.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('accepts connections',function(done) {
|
||||||
|
var ws = new WebSocket(url);
|
||||||
|
ws.on('open', function() {
|
||||||
|
ws.close();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
ws.on('error', function() {
|
||||||
|
done(new Error("Socket connection failed"));
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("keep alives", function() {
|
describe("keep alives", function() {
|
||||||
var server;
|
var server;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright 2014 IBM Corp.
|
* Copyright 2014, 205 IBM Corp.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -17,17 +17,17 @@ var should = require("should");
|
|||||||
var sinon = require("sinon");
|
var sinon = require("sinon");
|
||||||
var util = require("util");
|
var util = require("util");
|
||||||
|
|
||||||
|
var log = require("../../red/log");
|
||||||
|
|
||||||
describe("red/log", function() {
|
describe("red/log", function() {
|
||||||
it('can be required without errors', function() {
|
it('can be required without errors', function() {
|
||||||
require("../../red/log");
|
require("../../red/log");
|
||||||
});
|
});
|
||||||
|
|
||||||
var log = require("../../red/log");
|
|
||||||
var sett = {logging: { console: { level: 'metric', metrics: true } } };
|
|
||||||
log.init(sett);
|
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
var spy = sinon.spy(util, 'log');
|
var spy = sinon.stub(util, 'log', function(arg){});
|
||||||
|
var settings = {logging: { console: { level: 'metric', metrics: true } } };
|
||||||
|
log.init(settings);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function() {
|
afterEach(function() {
|
||||||
@ -36,17 +36,27 @@ describe("red/log", function() {
|
|||||||
|
|
||||||
it('it can raise an error', function() {
|
it('it can raise an error', function() {
|
||||||
var ret = log.error("This is an error");
|
var ret = log.error("This is an error");
|
||||||
sinon.assert.calledWithMatch(util.log,"");
|
sinon.assert.calledWithMatch(util.log,"[error] This is an error");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('it can raise a trace', function() {
|
it('it can raise a trace', function() {
|
||||||
var ret = log.trace("This is a trace");
|
var ret = log.trace("This is a trace");
|
||||||
sinon.assert.calledWithMatch(util.log,"");
|
sinon.assert.calledWithMatch(util.log,"[trace] This is a trace");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('it can raise a debug', function() {
|
it('it can raise a debug', function() {
|
||||||
var ret = log.debug("This is a debug");
|
var ret = log.debug("This is a debug");
|
||||||
sinon.assert.calledWithMatch(util.log,"");
|
sinon.assert.calledWithMatch(util.log,"[debug] This is a debug");
|
||||||
|
});
|
||||||
|
|
||||||
|
it('it can raise a info', function() {
|
||||||
|
var ret = log.info("This is an info");
|
||||||
|
sinon.assert.calledWithMatch(util.log,"[info] This is an info");
|
||||||
|
});
|
||||||
|
|
||||||
|
it('it can raise a warn', function() {
|
||||||
|
var ret = log.warn("This is a warn");
|
||||||
|
sinon.assert.calledWithMatch(util.log,"[warn] This is a warn");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('it can raise a metric', function() {
|
it('it can raise a metric', function() {
|
||||||
@ -57,17 +67,81 @@ describe("red/log", function() {
|
|||||||
metrics.msgid = "12345";
|
metrics.msgid = "12345";
|
||||||
metrics.value = "the metric payload";
|
metrics.value = "the metric payload";
|
||||||
var ret = log.log(metrics);
|
var ret = log.log(metrics);
|
||||||
sinon.assert.calledWithMatch(util.log,"");
|
util.log.calledOnce.should.be.true;
|
||||||
|
util.log.firstCall.args[0].indexOf("[metric] ").should.equal(0);
|
||||||
|
var body = JSON.parse(util.log.firstCall.args[0].substring(9));
|
||||||
|
body.should.have.a.property("nodeid","testid");
|
||||||
|
body.should.have.a.property("event","node.test.testevent");
|
||||||
|
body.should.have.a.property("msgid","12345");
|
||||||
|
body.should.have.a.property("value","the metric payload");
|
||||||
|
body.should.have.a.property("timestamp");
|
||||||
|
body.should.have.a.property("level",log.METRIC);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('it checks metrics are enabled', function() {
|
it('it checks metrics are enabled', function() {
|
||||||
log.metric().should.equal(true);
|
log.metric().should.equal(true);
|
||||||
var sett = {logging: { console: { level: 'info', metrics: false } } };
|
var sett = {logging: { console: { level: 'info', metrics: false } } };
|
||||||
log.init(sett);
|
log.init(sett);
|
||||||
});
|
|
||||||
|
|
||||||
it('it checks metrics are disabled', function() {
|
|
||||||
log.metric().should.equal(false);
|
log.metric().should.equal(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('it logs node type and name if provided',function() {
|
||||||
|
log.log({level:log.INFO,type:"nodeType",msg:"test",name:"nodeName",id:"nodeId"});
|
||||||
|
util.log.calledOnce.should.be.true;
|
||||||
|
util.log.firstCall.args[0].indexOf("[nodeType:nodeName]").should.not.equal(-1);
|
||||||
|
});
|
||||||
|
it('it logs node type and id if no name provided',function() {
|
||||||
|
log.log({level:log.INFO,type:"nodeType",msg:"test",id:"nodeId"});
|
||||||
|
util.log.calledOnce.should.be.true;
|
||||||
|
util.log.firstCall.args[0].indexOf("[nodeType:nodeId]").should.not.equal(-1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('ignores lower level messages and metrics', function() {
|
||||||
|
var settings = {logging: { console: { level: 'warn', metrics: false } } };
|
||||||
|
log.init(settings);
|
||||||
|
log.error("This is an error");
|
||||||
|
log.warn("This is a warn");
|
||||||
|
log.info("This is an info");
|
||||||
|
log.debug("This is a debug");
|
||||||
|
log.trace("This is a trace");
|
||||||
|
log.log({level:log.METRIC,msg:"testMetric"});
|
||||||
|
sinon.assert.calledWithMatch(util.log,"[error] This is an error");
|
||||||
|
sinon.assert.calledWithMatch(util.log,"[warn] This is a warn");
|
||||||
|
sinon.assert.neverCalledWithMatch(util.log,"[info] This is an info");
|
||||||
|
sinon.assert.neverCalledWithMatch(util.log,"[debug] This is a debug");
|
||||||
|
sinon.assert.neverCalledWithMatch(util.log,"[trace] This is a trace");
|
||||||
|
sinon.assert.neverCalledWithMatch(util.log,"[metric] ");
|
||||||
|
});
|
||||||
|
it('ignores lower level messages but accepts metrics', function() {
|
||||||
|
var settings = {logging: { console: { level: 'log', metrics: true } } };
|
||||||
|
log.init(settings);
|
||||||
|
log.error("This is an error");
|
||||||
|
log.warn("This is a warn");
|
||||||
|
log.info("This is an info");
|
||||||
|
log.debug("This is a debug");
|
||||||
|
log.trace("This is a trace");
|
||||||
|
log.log({level:log.METRIC,msg:"testMetric"});
|
||||||
|
sinon.assert.calledWithMatch(util.log,"[error] This is an error");
|
||||||
|
sinon.assert.calledWithMatch(util.log,"[warn] This is a warn");
|
||||||
|
sinon.assert.calledWithMatch(util.log,"[info] This is an info");
|
||||||
|
sinon.assert.neverCalledWithMatch(util.log,"[debug] This is a debug");
|
||||||
|
sinon.assert.neverCalledWithMatch(util.log,"[trace] This is a trace");
|
||||||
|
sinon.assert.calledWithMatch(util.log,"[metric] ");
|
||||||
|
});
|
||||||
|
|
||||||
|
it('default settings set to INFO and metrics off', function() {
|
||||||
|
log.init({logging:{}});
|
||||||
|
log.error("This is an error");
|
||||||
|
log.warn("This is a warn");
|
||||||
|
log.info("This is an info");
|
||||||
|
log.debug("This is a debug");
|
||||||
|
log.trace("This is a trace");
|
||||||
|
log.log({level:log.METRIC,msg:"testMetric"});
|
||||||
|
sinon.assert.calledWithMatch(util.log,"[error] This is an error");
|
||||||
|
sinon.assert.calledWithMatch(util.log,"[warn] This is a warn");
|
||||||
|
sinon.assert.calledWithMatch(util.log,"[info] This is an info");
|
||||||
|
sinon.assert.neverCalledWithMatch(util.log,"[debug] This is a debug");
|
||||||
|
sinon.assert.neverCalledWithMatch(util.log,"[trace] This is a trace");
|
||||||
|
sinon.assert.neverCalledWithMatch(util.log,"[metric] ");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright 2014 IBM Corp.
|
* Copyright 2014, 2015 IBM Corp.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -23,7 +23,9 @@ var comms = require("../../red/comms");
|
|||||||
var redNodes = require("../../red/nodes");
|
var redNodes = require("../../red/nodes");
|
||||||
var api = require("../../red/api");
|
var api = require("../../red/api");
|
||||||
var server = require("../../red/server");
|
var server = require("../../red/server");
|
||||||
|
var storage = require("../../red/storage");
|
||||||
|
var settings = require("../../red/settings");
|
||||||
|
var log = require("../../red/log");
|
||||||
|
|
||||||
describe("red/server", function() {
|
describe("red/server", function() {
|
||||||
var commsMessages = [];
|
var commsMessages = [];
|
||||||
@ -44,9 +46,8 @@ describe("red/server", function() {
|
|||||||
|
|
||||||
it("initialises components", function() {
|
it("initialises components", function() {
|
||||||
var commsInit = sinon.stub(comms,"init",function() {});
|
var commsInit = sinon.stub(comms,"init",function() {});
|
||||||
|
|
||||||
var dummyServer = {};
|
var dummyServer = {};
|
||||||
server.init(dummyServer,{httpAdminRoot:"/"});
|
server.init(dummyServer,{testSettings: true, httpAdminRoot:"/", load:function() { return when.resolve();}});
|
||||||
|
|
||||||
commsInit.called.should.be.true;
|
commsInit.called.should.be.true;
|
||||||
|
|
||||||
@ -58,6 +59,173 @@ describe("red/server", function() {
|
|||||||
commsInit.restore();
|
commsInit.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("start",function() {
|
||||||
|
var commsInit;
|
||||||
|
var storageInit;
|
||||||
|
var settingsLoad;
|
||||||
|
var apiInit;
|
||||||
|
var logMetric;
|
||||||
|
var logWarn;
|
||||||
|
var logInfo;
|
||||||
|
var logLog;
|
||||||
|
var redNodesInit;
|
||||||
|
var redNodesLoad;
|
||||||
|
var redNodesCleanModuleList;
|
||||||
|
var redNodesGetNodeList;
|
||||||
|
var redNodesLoadFlows;
|
||||||
|
var commsStart;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
commsInit = sinon.stub(comms,"init",function() {});
|
||||||
|
storageInit = sinon.stub(storage,"init",function(settings) {return when.resolve();});
|
||||||
|
apiInit = sinon.stub(api,"init",function() {});
|
||||||
|
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(){});
|
||||||
|
redNodesLoadFlows = sinon.stub(redNodes,"loadFlows",function() {});
|
||||||
|
commsStart = sinon.stub(comms,"start",function(){});
|
||||||
|
});
|
||||||
|
afterEach(function() {
|
||||||
|
commsInit.restore();
|
||||||
|
storageInit.restore();
|
||||||
|
apiInit.restore();
|
||||||
|
logMetric.restore();
|
||||||
|
logWarn.restore();
|
||||||
|
logInfo.restore();
|
||||||
|
logLog.restore();
|
||||||
|
redNodesInit.restore();
|
||||||
|
redNodesLoad.restore();
|
||||||
|
redNodesGetNodeList.restore();
|
||||||
|
redNodesCleanModuleList.restore();
|
||||||
|
redNodesLoadFlows.restore();
|
||||||
|
commsStart.restore();
|
||||||
|
});
|
||||||
|
it("reports errored/missing modules",function(done) {
|
||||||
|
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function() {
|
||||||
|
return [
|
||||||
|
{ err:"errored",name:"errName" }, // error
|
||||||
|
{ module:"module",enabled:true,loaded:false,types:["typeA","typeB"]} // missing
|
||||||
|
];
|
||||||
|
});
|
||||||
|
server.init({},{testSettings: true, httpAdminRoot:"/", load:function() { return when.resolve();}});
|
||||||
|
server.start().then(function() {
|
||||||
|
try {
|
||||||
|
apiInit.calledOnce.should.be.true;
|
||||||
|
storageInit.calledOnce.should.be.true;
|
||||||
|
redNodesInit.calledOnce.should.be.true;
|
||||||
|
redNodesLoad.calledOnce.should.be.true;
|
||||||
|
commsStart.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");
|
||||||
|
redNodesCleanModuleList.calledOnce.should.be.true;
|
||||||
|
done();
|
||||||
|
} catch(err) {
|
||||||
|
done(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("initiates load of missing modules",function(done) {
|
||||||
|
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function() {
|
||||||
|
return [
|
||||||
|
{ err:"errored",name:"errName" }, // error
|
||||||
|
{ err:"errored",name:"errName" }, // error
|
||||||
|
{ module:"module",enabled:true,loaded:false,types:["typeA","typeB"]}, // missing
|
||||||
|
{ module:"node-red",enabled:true,loaded:false,types:["typeC","typeD"]} // missing
|
||||||
|
];
|
||||||
|
});
|
||||||
|
var serverInstallModule = sinon.stub(server,"installModule",function(name) { return when.resolve();});
|
||||||
|
server.init({},{testSettings: true, autoInstallModules:true, httpAdminRoot:"/", load:function() { return when.resolve();}});
|
||||||
|
server.start().then(function() {
|
||||||
|
try {
|
||||||
|
apiInit.calledOnce.should.be.true;
|
||||||
|
logWarn.calledWithMatch("Failed to register 2 node types");
|
||||||
|
logWarn.calledWithMatch("Missing node modules");
|
||||||
|
logWarn.calledWithMatch(" - module: typeA, typeB");
|
||||||
|
logWarn.calledWithMatch(" - node-red: typeC, typeD");
|
||||||
|
redNodesCleanModuleList.calledOnce.should.be.false;
|
||||||
|
serverInstallModule.calledOnce.should.be.true;
|
||||||
|
serverInstallModule.calledWithMatch("module");
|
||||||
|
done();
|
||||||
|
} catch(err) {
|
||||||
|
done(err);
|
||||||
|
} finally {
|
||||||
|
serverInstallModule.restore();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("reports errored modules when verbose is enabled",function(done) {
|
||||||
|
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function() {
|
||||||
|
return [
|
||||||
|
{ err:"errored",name:"errName" } // error
|
||||||
|
];
|
||||||
|
});
|
||||||
|
server.init({},{testSettings: true, verbose:true, httpAdminRoot:"/", load:function() { return when.resolve();}});
|
||||||
|
server.start().then(function() {
|
||||||
|
|
||||||
|
try {
|
||||||
|
apiInit.calledOnce.should.be.true;
|
||||||
|
logWarn.neverCalledWithMatch("Failed to register 1 node type");
|
||||||
|
logWarn.calledWithMatch("[errName] errored");
|
||||||
|
done();
|
||||||
|
} catch(err) {
|
||||||
|
done(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("reports runtime metrics",function(done) {
|
||||||
|
var commsStop = sinon.stub(comms,"stop",function() {} );
|
||||||
|
var stopFlows = sinon.stub(redNodes,"stopFlows",function() {} );
|
||||||
|
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function() {return []});
|
||||||
|
logMetric.restore();
|
||||||
|
logMetric = sinon.stub(log,"metric",function() { return true; });
|
||||||
|
server.init({},{testSettings: true, runtimeMetricInterval:400, httpAdminRoot:"/", load:function() { return when.resolve();}});
|
||||||
|
server.start().then(function() {
|
||||||
|
setTimeout(function() {
|
||||||
|
try {
|
||||||
|
apiInit.calledOnce.should.be.true;
|
||||||
|
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");
|
||||||
|
done();
|
||||||
|
} catch(err) {
|
||||||
|
done(err);
|
||||||
|
} finally {
|
||||||
|
server.stop();
|
||||||
|
commsStop.restore();
|
||||||
|
stopFlows.restore();
|
||||||
|
}
|
||||||
|
},500);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("doesn't init api if httpAdminRoot set to false",function(done) {
|
||||||
|
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function() {return []});
|
||||||
|
server.init({},{testSettings: true, httpAdminRoot:false, load:function() { return when.resolve();}});
|
||||||
|
server.start().then(function() {
|
||||||
|
setTimeout(function() {
|
||||||
|
try {
|
||||||
|
apiInit.calledOnce.should.be.false;
|
||||||
|
done();
|
||||||
|
} catch(err) {
|
||||||
|
done(err);
|
||||||
|
}
|
||||||
|
},500);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("stops components", function() {
|
it("stops components", function() {
|
||||||
var commsStop = sinon.stub(comms,"stop",function() {} );
|
var commsStop = sinon.stub(comms,"stop",function() {} );
|
||||||
var stopFlows = sinon.stub(redNodes,"stopFlows",function() {} );
|
var stopFlows = sinon.stub(redNodes,"stopFlows",function() {} );
|
||||||
|
@ -80,11 +80,13 @@ describe("red/settings", function() {
|
|||||||
c: [1,2,3]
|
c: [1,2,3]
|
||||||
}
|
}
|
||||||
var savedSettings = null;
|
var savedSettings = null;
|
||||||
|
var saveCount = 0;
|
||||||
var storage = {
|
var storage = {
|
||||||
getSettings: function() {
|
getSettings: function() {
|
||||||
return when.resolve({globalA:789});
|
return when.resolve({globalA:789});
|
||||||
},
|
},
|
||||||
saveSettings: function(settings) {
|
saveSettings: function(settings) {
|
||||||
|
saveCount++;
|
||||||
savedSettings = settings;
|
savedSettings = settings;
|
||||||
return when.resolve();
|
return when.resolve();
|
||||||
}
|
}
|
||||||
@ -102,8 +104,14 @@ describe("red/settings", function() {
|
|||||||
settings.available().should.be.true;
|
settings.available().should.be.true;
|
||||||
settings.get("globalA").should.equal(789);
|
settings.get("globalA").should.equal(789);
|
||||||
settings.set("globalA","abc").then(function() {
|
settings.set("globalA","abc").then(function() {
|
||||||
|
savedSettings.globalA.should.equal("abc");
|
||||||
|
saveCount.should.equal(1);
|
||||||
|
settings.set("globalA","abc").then(function() {
|
||||||
savedSettings.globalA.should.equal("abc");
|
savedSettings.globalA.should.equal("abc");
|
||||||
|
// setting to existing value should not trigger save
|
||||||
|
saveCount.should.equal(1);
|
||||||
done();
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}).otherwise(function(err) {
|
}).otherwise(function(err) {
|
||||||
done(err);
|
done(err);
|
||||||
|
Loading…
Reference in New Issue
Block a user