mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Move exec and events components to util module
The exec and events components are common components that are used by both runtime and registry. It makes sense to move them into the util package. This also adds some docs to the registry module
This commit is contained in:
@@ -19,6 +19,7 @@ var sinon = require("sinon");
|
||||
|
||||
var NR_TEST_UTILS = require("nr-test-utils");
|
||||
var comms = NR_TEST_UTILS.require("@node-red/runtime/lib/api/comms");
|
||||
var events = NR_TEST_UTILS.require("@node-red/util/lib/events");
|
||||
|
||||
describe("runtime-api/comms", function() {
|
||||
describe("listens for events", function() {
|
||||
@@ -30,21 +31,19 @@ describe("runtime-api/comms", function() {
|
||||
}
|
||||
var eventHandlers = {};
|
||||
before(function(done) {
|
||||
sinon.stub(events,"removeListener", function() {})
|
||||
sinon.stub(events,"on", function(evt,handler) { eventHandlers[evt] = handler })
|
||||
comms.init({
|
||||
log: {
|
||||
trace: function(){}
|
||||
},
|
||||
events: {
|
||||
removeListener: function() {},
|
||||
on: function(evt,handler) {
|
||||
eventHandlers[evt] = handler;
|
||||
}
|
||||
}
|
||||
})
|
||||
comms.addConnection({client: clientConnection}).then(done);
|
||||
})
|
||||
after(function(done) {
|
||||
comms.removeConnection({client: clientConnection}).then(done);
|
||||
events.removeListener.restore();
|
||||
events.on.restore();
|
||||
})
|
||||
afterEach(function() {
|
||||
messages = [];
|
||||
@@ -98,18 +97,18 @@ describe("runtime-api/comms", function() {
|
||||
}
|
||||
}
|
||||
before(function() {
|
||||
sinon.stub(events,"removeListener", function() {})
|
||||
sinon.stub(events,"on", function(evt,handler) { eventHandlers[evt] = handler })
|
||||
comms.init({
|
||||
log: {
|
||||
trace: function(){}
|
||||
},
|
||||
events: {
|
||||
removeListener: function() {},
|
||||
on: function(evt,handler) {
|
||||
eventHandlers[evt] = handler;
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
after(function() {
|
||||
events.removeListener.restore();
|
||||
events.on.restore();
|
||||
})
|
||||
afterEach(function(done) {
|
||||
comms.removeConnection({client: clientConnection1}).then(function() {
|
||||
comms.removeConnection({client: clientConnection2}).then(done);
|
||||
@@ -178,18 +177,18 @@ describe("runtime-api/comms", function() {
|
||||
}
|
||||
var eventHandlers = {};
|
||||
before(function() {
|
||||
sinon.stub(events,"removeListener", function() {})
|
||||
sinon.stub(events,"on", function(evt,handler) { eventHandlers[evt] = handler })
|
||||
comms.init({
|
||||
log: {
|
||||
trace: function(){}
|
||||
},
|
||||
events: {
|
||||
removeListener: function() {},
|
||||
on: function(evt,handler) {
|
||||
eventHandlers[evt] = handler;
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
after(function() {
|
||||
events.removeListener.restore();
|
||||
events.on.restore();
|
||||
})
|
||||
afterEach(function(done) {
|
||||
messages = [];
|
||||
comms.removeConnection({client: clientConnection}).then(done);
|
||||
|
@@ -1,25 +0,0 @@
|
||||
/**
|
||||
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
var should = require("should");
|
||||
|
||||
var NR_TEST_UTILS = require("nr-test-utils");
|
||||
|
||||
describe("runtime/events", function() {
|
||||
it('can be required without errors', function() {
|
||||
NR_TEST_UTILS.require("@node-red/runtime/lib/events");
|
||||
});
|
||||
it.skip('more tests needed', function(){})
|
||||
});
|
@@ -1,138 +0,0 @@
|
||||
/**
|
||||
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
var should = require("should");
|
||||
var sinon = require("sinon");
|
||||
var path = require("path");
|
||||
var events = require("events");
|
||||
|
||||
|
||||
var child_process = require('child_process');
|
||||
|
||||
var NR_TEST_UTILS = require("nr-test-utils");
|
||||
|
||||
var exec = NR_TEST_UTILS.require("@node-red/runtime/lib/exec");
|
||||
|
||||
describe("runtime/exec", function() {
|
||||
var logEvents;
|
||||
var mockProcess;
|
||||
|
||||
beforeEach(function() {
|
||||
var logEventHandler = new events.EventEmitter();
|
||||
logEvents = [];
|
||||
logEventHandler.on('event-log', function(ev) {
|
||||
logEvents.push(ev);
|
||||
});
|
||||
exec.init({events:logEventHandler});
|
||||
|
||||
mockProcess = new events.EventEmitter();
|
||||
mockProcess.stdout = new events.EventEmitter();
|
||||
mockProcess.stderr = new events.EventEmitter();
|
||||
sinon.stub(child_process,'spawn',function(command,args,options) {
|
||||
mockProcess._args = {command,args,options};
|
||||
return mockProcess;
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
if (child_process.spawn.restore) {
|
||||
child_process.spawn.restore();
|
||||
}
|
||||
});
|
||||
|
||||
it("runs command and resolves on success - no emit", function(done) {
|
||||
var command = "cmd";
|
||||
var args = [1,2,3];
|
||||
var opts = { a: true };
|
||||
exec.run(command,args,opts).then(function(result) {
|
||||
command.should.eql(mockProcess._args.command);
|
||||
args.should.eql(mockProcess._args.args);
|
||||
opts.should.eql(mockProcess._args.options);
|
||||
logEvents.length.should.eql(0);
|
||||
result.code.should.eql(0);
|
||||
result.stdout.should.eql("123");
|
||||
result.stderr.should.eql("abc");
|
||||
done();
|
||||
}).catch(done);
|
||||
|
||||
mockProcess.stdout.emit('data',"1");
|
||||
mockProcess.stderr.emit('data',"a");
|
||||
mockProcess.stderr.emit('data',"b");
|
||||
mockProcess.stdout.emit('data',"2");
|
||||
mockProcess.stdout.emit('data',"3");
|
||||
mockProcess.stderr.emit('data',"c");
|
||||
mockProcess.emit('close',0);
|
||||
});
|
||||
|
||||
it("runs command and resolves on success - emit", function(done) {
|
||||
var command = "cmd";
|
||||
var args = [1,2,3];
|
||||
var opts = { a: true };
|
||||
exec.run(command,args,opts,true).then(function(result) {
|
||||
logEvents.length.should.eql(8);
|
||||
done();
|
||||
}).catch(done);
|
||||
|
||||
mockProcess.stdout.emit('data',"1");
|
||||
mockProcess.stderr.emit('data',"a");
|
||||
mockProcess.stderr.emit('data',"b");
|
||||
mockProcess.stdout.emit('data',"2");
|
||||
mockProcess.stdout.emit('data',"3");
|
||||
mockProcess.stderr.emit('data',"c");
|
||||
mockProcess.emit('close',0);
|
||||
})
|
||||
|
||||
it("runs command and rejects on error - close", function(done) {
|
||||
var command = "cmd";
|
||||
var args = [1,2,3];
|
||||
var opts = { a: true };
|
||||
exec.run(command,args,opts).then(function() {
|
||||
done("Command should have rejected");
|
||||
}).catch(function(result) {
|
||||
result
|
||||
result.code.should.eql(123);
|
||||
result.stdout.should.eql("123");
|
||||
result.stderr.should.eql("abc");
|
||||
done();
|
||||
}).catch(done);
|
||||
|
||||
mockProcess.stdout.emit('data',"1");
|
||||
mockProcess.stderr.emit('data',"a");
|
||||
mockProcess.stderr.emit('data',"b");
|
||||
mockProcess.stdout.emit('data',"2");
|
||||
mockProcess.stdout.emit('data',"3");
|
||||
mockProcess.stderr.emit('data',"c");
|
||||
mockProcess.emit('close',123);
|
||||
})
|
||||
|
||||
it("runs command and rejects on error - error", function(done) {
|
||||
var command = "cmd";
|
||||
var args = [1,2,3];
|
||||
var opts = { a: true };
|
||||
exec.run(command,args,opts).then(function() {
|
||||
done("Command should have rejected");
|
||||
}).catch(function(result) {
|
||||
result
|
||||
result.code.should.eql(456);
|
||||
result.stdout.should.eql("");
|
||||
result.stderr.should.eql("test-error");
|
||||
done();
|
||||
}).catch(done);
|
||||
|
||||
mockProcess.emit('error',"test-error");
|
||||
mockProcess.emit('close',456);
|
||||
})
|
||||
|
||||
});
|
@@ -22,7 +22,7 @@ var NR_TEST_UTILS = require("nr-test-utils");
|
||||
var flows = NR_TEST_UTILS.require("@node-red/runtime/lib/flows");
|
||||
var RedNode = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/Node");
|
||||
var RED = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes");
|
||||
var events = NR_TEST_UTILS.require("@node-red/runtime/lib/events");
|
||||
var events = NR_TEST_UTILS.require("@node-red/util/lib/events");
|
||||
var credentials = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/credentials");
|
||||
var typeRegistry = NR_TEST_UTILS.require("@node-red/registry")
|
||||
var Flow = NR_TEST_UTILS.require("@node-red/runtime/lib/flows/Flow");
|
||||
|
@@ -28,6 +28,7 @@ var settings = NR_TEST_UTILS.require("@node-red/runtime/lib/settings");
|
||||
var util = NR_TEST_UTILS.require("@node-red/util");
|
||||
|
||||
var log = NR_TEST_UTILS.require("@node-red/util").log;
|
||||
var i18n = NR_TEST_UTILS.require("@node-red/util").i18n;
|
||||
|
||||
describe("runtime", function() {
|
||||
afterEach(function() {
|
||||
@@ -43,43 +44,45 @@ describe("runtime", function() {
|
||||
delete process.env.NODE_RED_HOME;
|
||||
});
|
||||
function mockUtil(metrics) {
|
||||
|
||||
return {
|
||||
log:{
|
||||
log: sinon.stub(),
|
||||
warn: sinon.stub(),
|
||||
info: sinon.stub(),
|
||||
trace: sinon.stub(),
|
||||
metric: sinon.stub().returns(!!metrics),
|
||||
_: function() { return "abc"}
|
||||
},
|
||||
i18n: {
|
||||
registerMessageCatalog: function(){
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
}
|
||||
sinon.stub(log,"log",function(){})
|
||||
sinon.stub(log,"warn",function(){})
|
||||
sinon.stub(log,"info",function(){})
|
||||
sinon.stub(log,"trace",function(){})
|
||||
sinon.stub(log,"metric",function(){ return !!metrics })
|
||||
sinon.stub(log,"_",function(){ return "abc"})
|
||||
sinon.stub(i18n,"registerMessageCatalog",function(){ return Promise.resolve()})
|
||||
}
|
||||
function unmockUtil() {
|
||||
log.log.restore && log.log.restore();
|
||||
log.warn.restore && log.warn.restore();
|
||||
log.info.restore && log.info.restore();
|
||||
log.trace.restore && log.trace.restore();
|
||||
log.metric.restore && log.metric.restore();
|
||||
log._.restore && log._.restore();
|
||||
i18n.registerMessageCatalog.restore && i18n.registerMessageCatalog.restore();
|
||||
}
|
||||
describe("init", function() {
|
||||
beforeEach(function() {
|
||||
sinon.stub(log,"init",function() {});
|
||||
sinon.stub(settings,"init",function() {});
|
||||
sinon.stub(redNodes,"init",function() {})
|
||||
mockUtil();
|
||||
});
|
||||
afterEach(function() {
|
||||
log.init.restore();
|
||||
settings.init.restore();
|
||||
redNodes.init.restore();
|
||||
unmockUtil();
|
||||
})
|
||||
|
||||
it("initialises components", function() {
|
||||
runtime.init({testSettings: true, httpAdminRoot:"/"},mockUtil());
|
||||
runtime.init({testSettings: true, httpAdminRoot:"/"});
|
||||
settings.init.called.should.be.true();
|
||||
redNodes.init.called.should.be.true();
|
||||
});
|
||||
|
||||
it("returns version", function() {
|
||||
runtime.init({testSettings: true, httpAdminRoot:"/"},mockUtil());
|
||||
runtime.init({testSettings: true, httpAdminRoot:"/"});
|
||||
return runtime.version().then(version => {
|
||||
/^\d+\.\d+\.\d+(-.*)?$/.test(version).should.be.true();
|
||||
});
|
||||
@@ -98,7 +101,6 @@ describe("runtime", function() {
|
||||
var redNodesLoadFlows;
|
||||
var redNodesStartFlows;
|
||||
var redNodesLoadContextsPlugin;
|
||||
var i18nRegisterMessageCatalog;
|
||||
|
||||
beforeEach(function() {
|
||||
storageInit = sinon.stub(storage,"init",function(settings) {return Promise.resolve();});
|
||||
@@ -108,7 +110,7 @@ describe("runtime", function() {
|
||||
redNodesLoadFlows = sinon.stub(redNodes,"loadFlows",function() {return Promise.resolve()});
|
||||
redNodesStartFlows = sinon.stub(redNodes,"startFlows",function() {});
|
||||
redNodesLoadContextsPlugin = sinon.stub(redNodes,"loadContextsPlugin",function() {return Promise.resolve()});
|
||||
i18nRegisterMessageCatalog = sinon.stub(util.i18n,"registerMessageCatalog",function() {return Promise.resolve()});
|
||||
mockUtil();
|
||||
});
|
||||
afterEach(function() {
|
||||
storageInit.restore();
|
||||
@@ -119,7 +121,7 @@ describe("runtime", function() {
|
||||
redNodesLoadFlows.restore();
|
||||
redNodesStartFlows.restore();
|
||||
redNodesLoadContextsPlugin.restore();
|
||||
i18nRegisterMessageCatalog.restore();
|
||||
unmockUtil();
|
||||
});
|
||||
it("reports errored/missing modules",function(done) {
|
||||
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function(cb) {
|
||||
@@ -128,8 +130,7 @@ describe("runtime", function() {
|
||||
{ module:"module",enabled:true,loaded:false,types:["typeA","typeB"]} // missing
|
||||
].filter(cb);
|
||||
});
|
||||
var util = mockUtil();
|
||||
runtime.init({testSettings: true, httpAdminRoot:"/", load:function() { return Promise.resolve();}},util);
|
||||
runtime.init({testSettings: true, httpAdminRoot:"/", load:function() { return Promise.resolve();}});
|
||||
// sinon.stub(console,"log");
|
||||
runtime.start().then(function() {
|
||||
// console.log.restore();
|
||||
@@ -139,9 +140,9 @@ describe("runtime", function() {
|
||||
redNodesLoad.calledOnce.should.be.true();
|
||||
redNodesLoadFlows.calledOnce.should.be.true();
|
||||
|
||||
util.log.warn.calledWithMatch("Failed to register 1 node type");
|
||||
util.log.warn.calledWithMatch("Missing node modules");
|
||||
util.log.warn.calledWithMatch(" - module: typeA, typeB");
|
||||
log.warn.calledWithMatch("Failed to register 1 node type");
|
||||
log.warn.calledWithMatch("Missing node modules");
|
||||
log.warn.calledWithMatch(" - module: typeA, typeB");
|
||||
redNodesCleanModuleList.calledOnce.should.be.true();
|
||||
done();
|
||||
} catch(err) {
|
||||
@@ -159,16 +160,15 @@ describe("runtime", function() {
|
||||
].filter(cb);
|
||||
});
|
||||
var serverInstallModule = sinon.stub(redNodes,"installModule",function(name) { return Promise.resolve({nodes:[]});});
|
||||
var util = mockUtil();
|
||||
runtime.init({testSettings: true, autoInstallModules:true, httpAdminRoot:"/", load:function() { return Promise.resolve();}},util);
|
||||
runtime.init({testSettings: true, autoInstallModules:true, httpAdminRoot:"/", load:function() { return Promise.resolve();}});
|
||||
sinon.stub(console,"log");
|
||||
runtime.start().then(function() {
|
||||
console.log.restore();
|
||||
try {
|
||||
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");
|
||||
log.warn.calledWithMatch("Failed to register 2 node types");
|
||||
log.warn.calledWithMatch("Missing node modules");
|
||||
log.warn.calledWithMatch(" - module: typeA, typeB");
|
||||
log.warn.calledWithMatch(" - node-red: typeC, typeD");
|
||||
redNodesCleanModuleList.calledOnce.should.be.false();
|
||||
serverInstallModule.calledOnce.should.be.true();
|
||||
serverInstallModule.calledWithMatch("module");
|
||||
@@ -186,14 +186,13 @@ describe("runtime", function() {
|
||||
{ err:"errored",name:"errName" } // error
|
||||
].filter(cb);
|
||||
});
|
||||
var util = mockUtil();
|
||||
runtime.init({testSettings: true, verbose:true, httpAdminRoot:"/", load:function() { return Promise.resolve();}},util);
|
||||
runtime.init({testSettings: true, verbose:true, httpAdminRoot:"/", load:function() { return Promise.resolve();}});
|
||||
sinon.stub(console,"log");
|
||||
runtime.start().then(function() {
|
||||
console.log.restore();
|
||||
try {
|
||||
util.log.warn.neverCalledWithMatch("Failed to register 1 node type");
|
||||
util.log.warn.calledWithMatch("[errName] errored");
|
||||
log.warn.neverCalledWithMatch("Failed to register 1 node type");
|
||||
log.warn.calledWithMatch("[errName] errored");
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
@@ -204,21 +203,21 @@ describe("runtime", function() {
|
||||
it("reports runtime metrics",function(done) {
|
||||
var stopFlows = sinon.stub(redNodes,"stopFlows",function() { return Promise.resolve();} );
|
||||
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function() {return []});
|
||||
var util = mockUtil(true);
|
||||
unmockUtil();
|
||||
mockUtil(true);
|
||||
runtime.init(
|
||||
{testSettings: true, runtimeMetricInterval:200, httpAdminRoot:"/", load:function() { return Promise.resolve();}},
|
||||
{},
|
||||
undefined,
|
||||
util);
|
||||
undefined);
|
||||
// sinon.stub(console,"log");
|
||||
runtime.start().then(function() {
|
||||
// console.log.restore();
|
||||
setTimeout(function() {
|
||||
try {
|
||||
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");
|
||||
log.log.args.should.have.lengthOf(3);
|
||||
log.log.args[0][0].should.have.property("event","runtime.memory.rss");
|
||||
log.log.args[1][0].should.have.property("event","runtime.memory.heapTotal");
|
||||
log.log.args[2][0].should.have.property("event","runtime.memory.heapUsed");
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
|
Reference in New Issue
Block a user