mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Move node installer to its own module
This commit is contained in:
parent
075a2abf71
commit
437b01a0ff
@ -322,7 +322,30 @@ function stop(type,diff) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function checkTypeInUse(id) {
|
||||||
|
var nodeInfo = typeRegistry.getNodeInfo(id);
|
||||||
|
if (!nodeInfo) {
|
||||||
|
throw new Error(log._("nodes.index.unrecognised-id", {id:id}));
|
||||||
|
} else {
|
||||||
|
var inUse = {};
|
||||||
|
var config = getConfig();
|
||||||
|
config.forEach(function(n) {
|
||||||
|
inUse[n.type] = (inUse[n.type]||0)+1;
|
||||||
|
});
|
||||||
|
var nodesInUse = [];
|
||||||
|
nodeInfo.types.forEach(function(t) {
|
||||||
|
if (inUse[t]) {
|
||||||
|
nodesInUse.push(t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (nodesInUse.length > 0) {
|
||||||
|
var msg = nodesInUse.join(", ");
|
||||||
|
var err = new Error(log._("nodes.index.type-in-use", {msg:msg}));
|
||||||
|
err.code = "type_in_use";
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init: init,
|
init: init,
|
||||||
@ -362,5 +385,8 @@ module.exports = {
|
|||||||
|
|
||||||
|
|
||||||
handleError: handleError,
|
handleError: handleError,
|
||||||
handleStatus: handleStatus
|
handleStatus: handleStatus,
|
||||||
|
|
||||||
|
checkTypeInUse: checkTypeInUse
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -71,163 +71,23 @@ function init(_settings,storage) {
|
|||||||
registry.init(_settings);
|
registry.init(_settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkTypeInUse(id) {
|
function disableNode(id) {
|
||||||
var nodeInfo = registry.getNodeInfo(id);
|
flows.checkTypeInUse(id);
|
||||||
if (!nodeInfo) {
|
return registry.disableNode(id);
|
||||||
throw new Error(log._("nodes.index.unrecognised-id", {id:id}));
|
|
||||||
} else {
|
|
||||||
var inUse = {};
|
|
||||||
var config = flows.getFlows();
|
|
||||||
config.forEach(function(n) {
|
|
||||||
inUse[n.type] = (inUse[n.type]||0)+1;
|
|
||||||
});
|
|
||||||
var nodesInUse = [];
|
|
||||||
nodeInfo.types.forEach(function(t) {
|
|
||||||
if (inUse[t]) {
|
|
||||||
nodesInUse.push(t);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (nodesInUse.length > 0) {
|
|
||||||
var msg = nodesInUse.join(", ");
|
|
||||||
var err = new Error(log._("nodes.index.type-in-use", {msg:msg}));
|
|
||||||
err.code = "type_in_use";
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeNode(id) {
|
function uninstallModule(module) {
|
||||||
checkTypeInUse(id);
|
|
||||||
return registry.removeNode(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeModule(module) {
|
|
||||||
var info = registry.getModuleInfo(module);
|
var info = registry.getModuleInfo(module);
|
||||||
if (!info) {
|
if (!info) {
|
||||||
throw new Error(log._("nodes.index.unrecognised-module", {module:module}));
|
throw new Error(log._("nodes.index.unrecognised-module", {module:module}));
|
||||||
} else {
|
} else {
|
||||||
for (var i=0;i<info.nodes.length;i++) {
|
for (var i=0;i<info.nodes.length;i++) {
|
||||||
checkTypeInUse(module+"/"+info.nodes[i].name);
|
flows.checkTypeInUse(module+"/"+info.nodes[i].name);
|
||||||
}
|
}
|
||||||
return registry.removeModule(module);
|
return registry.uninstallModule(module);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function disableNode(id) {
|
|
||||||
checkTypeInUse(id);
|
|
||||||
return registry.disableNode(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
function installModule(module) {
|
|
||||||
//TODO: ensure module is 'safe'
|
|
||||||
return when.promise(function(resolve,reject) {
|
|
||||||
if (/[\s;]/.test(module)) {
|
|
||||||
reject(new Error(log._("server.install.invalid")));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (registry.getModuleInfo(module)) {
|
|
||||||
// TODO: nls
|
|
||||||
var err = new Error("Module already loaded");
|
|
||||||
err.code = "module_already_loaded";
|
|
||||||
reject(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
log.info(log._("server.install.installing",{name: module}));
|
|
||||||
|
|
||||||
var installDir = settings.userDir || process.env.NODE_RED_HOME || ".";
|
|
||||||
var child = child_process.execFile('npm',['install','--production',module],
|
|
||||||
{
|
|
||||||
cwd: installDir
|
|
||||||
},
|
|
||||||
function(err, stdin, stdout) {
|
|
||||||
if (err) {
|
|
||||||
var lookFor404 = new RegExp(" 404 .*"+module+"$","m");
|
|
||||||
if (lookFor404.test(stdout)) {
|
|
||||||
log.warn(log._("server.install.install-failed-not-found",{name:module}));
|
|
||||||
var e = new Error();
|
|
||||||
e.code = 404;
|
|
||||||
reject(e);
|
|
||||||
} else {
|
|
||||||
log.warn(log._("server.install.install-failed-long",{name:module}));
|
|
||||||
log.warn("------------------------------------------");
|
|
||||||
log.warn(err.toString());
|
|
||||||
log.warn("------------------------------------------");
|
|
||||||
reject(new Error(log._("server.install.install-failed")));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.info(log._("server.install.installed",{name:module}));
|
|
||||||
resolve(registry.addModule(module).then(reportAddedModules));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function reportAddedModules(info) {
|
|
||||||
//comms.publish("node/added",info.nodes,false);
|
|
||||||
if (info.nodes.length > 0) {
|
|
||||||
log.info(log._("server.added-types"));
|
|
||||||
for (var i=0;i<info.nodes.length;i++) {
|
|
||||||
for (var j=0;j<info.nodes[i].types.length;j++) {
|
|
||||||
log.info(" - "+
|
|
||||||
(info.nodes[i].module?info.nodes[i].module+":":"")+
|
|
||||||
info.nodes[i].types[j]+
|
|
||||||
(info.nodes[i].err?" : "+info.nodes[i].err:"")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
function reportRemovedModules(removedNodes) {
|
|
||||||
//comms.publish("node/removed",removedNodes,false);
|
|
||||||
log.info(log._("server.removed-types"));
|
|
||||||
for (var j=0;j<removedNodes.length;j++) {
|
|
||||||
for (var i=0;i<removedNodes[j].types.length;i++) {
|
|
||||||
log.info(" - "+(removedNodes[j].module?removedNodes[j].module+":":"")+removedNodes[j].types[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return removedNodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
function uninstallModule(module) {
|
|
||||||
return when.promise(function(resolve,reject) {
|
|
||||||
if (/[\s;]/.test(module)) {
|
|
||||||
reject(new Error(log._("server.install.invalid")));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var installDir = settings.userDir || process.env.NODE_RED_HOME || ".";
|
|
||||||
var moduleDir = path.join(installDir,"node_modules",module);
|
|
||||||
if (!fs.existsSync(moduleDir)) {
|
|
||||||
return reject(new Error(log._("server.install.uninstall-failed",{name:module})));
|
|
||||||
}
|
|
||||||
|
|
||||||
var list = removeModule(module);
|
|
||||||
log.info(log._("server.install.uninstalling",{name:module}));
|
|
||||||
var child = child_process.execFile('npm',['remove',module],
|
|
||||||
{
|
|
||||||
cwd: installDir
|
|
||||||
},
|
|
||||||
function(err, stdin, stdout) {
|
|
||||||
if (err) {
|
|
||||||
log.warn(log._("server.install.uninstall-failed-long",{name:module}));
|
|
||||||
log.warn("------------------------------------------");
|
|
||||||
log.warn(err.toString());
|
|
||||||
log.warn("------------------------------------------");
|
|
||||||
reject(new Error(log._("server.install.uninstall-failed",{name:module})));
|
|
||||||
} else {
|
|
||||||
log.info(log._("server.install.uninstalled",{name:module}));
|
|
||||||
reportRemovedModules(list);
|
|
||||||
resolve(list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
// Lifecycle
|
// Lifecycle
|
||||||
init: init,
|
init: init,
|
||||||
@ -238,7 +98,7 @@ module.exports = {
|
|||||||
getNode: flows.get,
|
getNode: flows.get,
|
||||||
eachNode: flows.eachNode,
|
eachNode: flows.eachNode,
|
||||||
|
|
||||||
installModule: installModule,
|
installModule: registry.installModule,
|
||||||
uninstallModule: uninstallModule,
|
uninstallModule: uninstallModule,
|
||||||
|
|
||||||
enableNode: registry.enableNode,
|
enableNode: registry.enableNode,
|
||||||
|
@ -21,11 +21,13 @@ var path = require("path");
|
|||||||
var events = require("../../events");
|
var events = require("../../events");
|
||||||
var registry = require("./registry");
|
var registry = require("./registry");
|
||||||
var loader = require("./loader");
|
var loader = require("./loader");
|
||||||
|
var installer = require("./installer");
|
||||||
|
|
||||||
var settings;
|
var settings;
|
||||||
|
|
||||||
function init(_settings) {
|
function init(_settings) {
|
||||||
settings = _settings;
|
settings = _settings;
|
||||||
|
installer.init(settings);
|
||||||
loader.init(settings);
|
loader.init(settings);
|
||||||
registry.init(settings,loader);
|
registry.init(settings,loader);
|
||||||
}
|
}
|
||||||
@ -76,5 +78,8 @@ module.exports = {
|
|||||||
addModule: addModule,
|
addModule: addModule,
|
||||||
removeModule: registry.removeModule,
|
removeModule: registry.removeModule,
|
||||||
|
|
||||||
|
installModule: installer.installModule,
|
||||||
|
uninstallModule: installer.uninstallModule,
|
||||||
|
|
||||||
cleanModuleList: registry.cleanModuleList
|
cleanModuleList: registry.cleanModuleList
|
||||||
};
|
};
|
||||||
|
149
red/nodes/registry/installer.js
Normal file
149
red/nodes/registry/installer.js
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2015 IBM Corp.
|
||||||
|
*
|
||||||
|
* 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 when = require("when");
|
||||||
|
var path = require("path");
|
||||||
|
var fs = require("fs");
|
||||||
|
|
||||||
|
var registry = require("./registry");
|
||||||
|
var log = require("../../log");
|
||||||
|
|
||||||
|
var events = require("../../events");
|
||||||
|
|
||||||
|
var child_process = require('child_process');
|
||||||
|
|
||||||
|
var settings;
|
||||||
|
|
||||||
|
function init(_settings) {
|
||||||
|
settings = _settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
function installModule(module) {
|
||||||
|
//TODO: ensure module is 'safe'
|
||||||
|
return when.promise(function(resolve,reject) {
|
||||||
|
if (/[\s;]/.test(module)) {
|
||||||
|
reject(new Error(log._("server.install.invalid")));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (registry.getModuleInfo(module)) {
|
||||||
|
// TODO: nls
|
||||||
|
var err = new Error("Module already loaded");
|
||||||
|
err.code = "module_already_loaded";
|
||||||
|
reject(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log.info(log._("server.install.installing",{name: module}));
|
||||||
|
|
||||||
|
var installDir = settings.userDir || process.env.NODE_RED_HOME || ".";
|
||||||
|
var child = child_process.execFile('npm',['install','--production',module],
|
||||||
|
{
|
||||||
|
cwd: installDir
|
||||||
|
},
|
||||||
|
function(err, stdin, stdout) {
|
||||||
|
if (err) {
|
||||||
|
var lookFor404 = new RegExp(" 404 .*"+module+"$","m");
|
||||||
|
if (lookFor404.test(stdout)) {
|
||||||
|
log.warn(log._("server.install.install-failed-not-found",{name:module}));
|
||||||
|
var e = new Error();
|
||||||
|
e.code = 404;
|
||||||
|
reject(e);
|
||||||
|
} else {
|
||||||
|
log.warn(log._("server.install.install-failed-long",{name:module}));
|
||||||
|
log.warn("------------------------------------------");
|
||||||
|
log.warn(err.toString());
|
||||||
|
log.warn("------------------------------------------");
|
||||||
|
reject(new Error(log._("server.install.install-failed")));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.info(log._("server.install.installed",{name:module}));
|
||||||
|
resolve(require("./index").addModule(module).then(reportAddedModules));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function reportAddedModules(info) {
|
||||||
|
//comms.publish("node/added",info.nodes,false);
|
||||||
|
if (info.nodes.length > 0) {
|
||||||
|
log.info(log._("server.added-types"));
|
||||||
|
for (var i=0;i<info.nodes.length;i++) {
|
||||||
|
for (var j=0;j<info.nodes[i].types.length;j++) {
|
||||||
|
log.info(" - "+
|
||||||
|
(info.nodes[i].module?info.nodes[i].module+":":"")+
|
||||||
|
info.nodes[i].types[j]+
|
||||||
|
(info.nodes[i].err?" : "+info.nodes[i].err:"")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
function reportRemovedModules(removedNodes) {
|
||||||
|
//comms.publish("node/removed",removedNodes,false);
|
||||||
|
log.info(log._("server.removed-types"));
|
||||||
|
for (var j=0;j<removedNodes.length;j++) {
|
||||||
|
for (var i=0;i<removedNodes[j].types.length;i++) {
|
||||||
|
log.info(" - "+(removedNodes[j].module?removedNodes[j].module+":":"")+removedNodes[j].types[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return removedNodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
function uninstallModule(module) {
|
||||||
|
return when.promise(function(resolve,reject) {
|
||||||
|
if (/[\s;]/.test(module)) {
|
||||||
|
reject(new Error(log._("server.install.invalid")));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var installDir = settings.userDir || process.env.NODE_RED_HOME || ".";
|
||||||
|
var moduleDir = path.join(installDir,"node_modules",module);
|
||||||
|
if (!fs.existsSync(moduleDir)) {
|
||||||
|
return reject(new Error(log._("server.install.uninstall-failed",{name:module})));
|
||||||
|
}
|
||||||
|
|
||||||
|
var list = registry.removeModule(module);
|
||||||
|
log.info(log._("server.install.uninstalling",{name:module}));
|
||||||
|
var child = child_process.execFile('npm',['remove',module],
|
||||||
|
{
|
||||||
|
cwd: installDir
|
||||||
|
},
|
||||||
|
function(err, stdin, stdout) {
|
||||||
|
if (err) {
|
||||||
|
log.warn(log._("server.install.uninstall-failed-long",{name:module}));
|
||||||
|
log.warn("------------------------------------------");
|
||||||
|
log.warn(err.toString());
|
||||||
|
log.warn("------------------------------------------");
|
||||||
|
reject(new Error(log._("server.install.uninstall-failed",{name:module})));
|
||||||
|
} else {
|
||||||
|
log.info(log._("server.install.uninstalled",{name:module}));
|
||||||
|
reportRemovedModules(list);
|
||||||
|
resolve(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
init: init,
|
||||||
|
|
||||||
|
installModule: installModule,
|
||||||
|
uninstallModule: uninstallModule
|
||||||
|
}
|
@ -451,4 +451,50 @@ describe('flows/index', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('#checkTypeInUse', function() {
|
||||||
|
|
||||||
|
before(function() {
|
||||||
|
sinon.stub(typeRegistry,"getNodeInfo",function(id) {
|
||||||
|
if (id === 'unused-module') {
|
||||||
|
return {types:['one','two','three']}
|
||||||
|
} else {
|
||||||
|
return {types:['one','test','three']}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
after(function() {
|
||||||
|
typeRegistry.getNodeInfo.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns cleanly if type not is use', function(done) {
|
||||||
|
var originalConfig = [
|
||||||
|
{id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]},
|
||||||
|
{id:"t1",type:"tab"}
|
||||||
|
];
|
||||||
|
flows.init({},storage);
|
||||||
|
flows.setFlows(originalConfig).then(function() {
|
||||||
|
flows.checkTypeInUse("unused-module");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('throws error if type is in use', function(done) {
|
||||||
|
var originalConfig = [
|
||||||
|
{id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]},
|
||||||
|
{id:"t1",type:"tab"}
|
||||||
|
];
|
||||||
|
flows.init({},storage);
|
||||||
|
flows.setFlows(originalConfig).then(function() {
|
||||||
|
/*jshint immed: false */
|
||||||
|
try {
|
||||||
|
flows.checkTypeInUse("used-module");
|
||||||
|
done("type_in_use error not thrown");
|
||||||
|
} catch(err) {
|
||||||
|
err.code.should.eql("type_in_use");
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -19,7 +19,6 @@ var fs = require('fs-extra');
|
|||||||
var path = require('path');
|
var path = require('path');
|
||||||
var when = require("when");
|
var when = require("when");
|
||||||
var sinon = require('sinon');
|
var sinon = require('sinon');
|
||||||
var child_process = require('child_process');
|
|
||||||
|
|
||||||
var index = require("../../../red/nodes/index");
|
var index = require("../../../red/nodes/index");
|
||||||
var flows = require("../../../red/nodes/flows");
|
var flows = require("../../../red/nodes/flows");
|
||||||
@ -277,126 +276,4 @@ describe("red/nodes/index", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("installs module", function() {
|
|
||||||
it("rejects invalid module names", function(done) {
|
|
||||||
var promises = [];
|
|
||||||
promises.push(index.installModule("this_wont_exist "));
|
|
||||||
promises.push(index.installModule("this_wont_exist;no_it_really_wont"));
|
|
||||||
when.settle(promises).then(function(results) {
|
|
||||||
results[0].state.should.be.eql("rejected");
|
|
||||||
results[1].state.should.be.eql("rejected");
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("rejects when npm returns a 404", function(done) {
|
|
||||||
var exec = sinon.stub(child_process,"execFile",function(cmd,args,opt,cb) {
|
|
||||||
cb(new Error(),""," 404 this_wont_exist");
|
|
||||||
});
|
|
||||||
|
|
||||||
index.installModule("this_wont_exist").otherwise(function(err) {
|
|
||||||
err.code.should.be.eql(404);
|
|
||||||
done();
|
|
||||||
}).finally(function() {
|
|
||||||
exec.restore();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("rejects with generic error", function(done) {
|
|
||||||
var exec = sinon.stub(child_process,"execFile",function(cmd,args,opt,cb) {
|
|
||||||
cb(new Error("test_error"),"","");
|
|
||||||
});
|
|
||||||
|
|
||||||
index.installModule("this_wont_exist").then(function() {
|
|
||||||
done(new Error("Unexpected success"));
|
|
||||||
}).otherwise(function(err) {
|
|
||||||
done();
|
|
||||||
}).finally(function() {
|
|
||||||
exec.restore();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("succeeds when module is found", function(done) {
|
|
||||||
var nodeInfo = {nodes:{module:"foo",types:["a"]}};
|
|
||||||
var exec = sinon.stub(child_process,"execFile",function(cmd,args,opt,cb) {
|
|
||||||
cb(null,"","");
|
|
||||||
});
|
|
||||||
var addModule = sinon.stub(registry,"addModule",function(md) {
|
|
||||||
return when.resolve(nodeInfo);
|
|
||||||
});
|
|
||||||
|
|
||||||
index.installModule("this_wont_exist").then(function(info) {
|
|
||||||
info.should.eql(nodeInfo);
|
|
||||||
// commsMessages.should.have.length(1);
|
|
||||||
// commsMessages[0].topic.should.equal("node/added");
|
|
||||||
// commsMessages[0].msg.should.eql(nodeInfo.nodes);
|
|
||||||
done();
|
|
||||||
}).otherwise(function(err) {
|
|
||||||
done(err);
|
|
||||||
}).finally(function() {
|
|
||||||
exec.restore();
|
|
||||||
addModule.restore();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe("uninstalls module", function() {
|
|
||||||
it("rejects invalid module names", function(done) {
|
|
||||||
var promises = [];
|
|
||||||
promises.push(index.uninstallModule("this_wont_exist "));
|
|
||||||
promises.push(index.uninstallModule("this_wont_exist;no_it_really_wont"));
|
|
||||||
when.settle(promises).then(function(results) {
|
|
||||||
results[0].state.should.be.eql("rejected");
|
|
||||||
results[1].state.should.be.eql("rejected");
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("rejects with generic error", function(done) {
|
|
||||||
var nodeInfo = [{module:"foo",types:["a"]}];
|
|
||||||
var removeModule = sinon.stub(registry,"removeModule",function(md) {
|
|
||||||
return when.resolve(nodeInfo);
|
|
||||||
});
|
|
||||||
var exec = sinon.stub(child_process,"execFile",function(cmd,args,opt,cb) {
|
|
||||||
cb(new Error("test_error"),"","");
|
|
||||||
});
|
|
||||||
|
|
||||||
index.uninstallModule("this_wont_exist").then(function() {
|
|
||||||
done(new Error("Unexpected success"));
|
|
||||||
}).otherwise(function(err) {
|
|
||||||
done();
|
|
||||||
}).finally(function() {
|
|
||||||
exec.restore();
|
|
||||||
removeModule.restore();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("succeeds when module is found", function(done) {
|
|
||||||
var nodeInfo = [{module:"foo",types:["a"]}];
|
|
||||||
var removeModule = sinon.stub(registry,"removeModule",function(md) {
|
|
||||||
return nodeInfo;
|
|
||||||
});
|
|
||||||
var getModuleInfo = sinon.stub(registry,"getModuleInfo",function(md) {
|
|
||||||
return {nodes:[]};
|
|
||||||
});
|
|
||||||
var exec = sinon.stub(child_process,"execFile",function(cmd,args,opt,cb) {
|
|
||||||
cb(null,"","");
|
|
||||||
});
|
|
||||||
|
|
||||||
var exists = sinon.stub(require('fs'),"existsSync", function(fn) { return true; });
|
|
||||||
|
|
||||||
index.uninstallModule("this_wont_exist").then(function(info) {
|
|
||||||
info.should.eql(nodeInfo);
|
|
||||||
// commsMessages.should.have.length(1);
|
|
||||||
// commsMessages[0].topic.should.equal("node/removed");
|
|
||||||
// commsMessages[0].msg.should.eql(nodeInfo);
|
|
||||||
done();
|
|
||||||
}).otherwise(function(err) {
|
|
||||||
done(err);
|
|
||||||
}).finally(function() {
|
|
||||||
exec.restore();
|
|
||||||
removeModule.restore();
|
|
||||||
exists.restore();
|
|
||||||
getModuleInfo.restore();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
152
test/red/nodes/registry/installer_spec.js
Normal file
152
test/red/nodes/registry/installer_spec.js
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2014, 2015 IBM Corp.
|
||||||
|
*
|
||||||
|
* 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 when = require("when");
|
||||||
|
|
||||||
|
var child_process = require('child_process');
|
||||||
|
var installer = require("../../../../red/nodes/registry/installer");
|
||||||
|
var registry = require("../../../../red/nodes/registry/index");
|
||||||
|
var typeRegistry = require("../../../../red/nodes/registry/registry");
|
||||||
|
|
||||||
|
describe('nodes/registry/installer', function() {
|
||||||
|
|
||||||
|
before(function() {
|
||||||
|
installer.init({});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("installs module", function() {
|
||||||
|
it("rejects invalid module names", function(done) {
|
||||||
|
var promises = [];
|
||||||
|
promises.push(installer.installModule("this_wont_exist "));
|
||||||
|
promises.push(installer.installModule("this_wont_exist;no_it_really_wont"));
|
||||||
|
when.settle(promises).then(function(results) {
|
||||||
|
results[0].state.should.be.eql("rejected");
|
||||||
|
results[1].state.should.be.eql("rejected");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("rejects when npm returns a 404", function(done) {
|
||||||
|
var exec = sinon.stub(child_process,"execFile",function(cmd,args,opt,cb) {
|
||||||
|
cb(new Error(),""," 404 this_wont_exist");
|
||||||
|
});
|
||||||
|
|
||||||
|
installer.installModule("this_wont_exist").otherwise(function(err) {
|
||||||
|
err.code.should.be.eql(404);
|
||||||
|
done();
|
||||||
|
}).finally(function() {
|
||||||
|
exec.restore();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("rejects with generic error", function(done) {
|
||||||
|
var exec = sinon.stub(child_process,"execFile",function(cmd,args,opt,cb) {
|
||||||
|
cb(new Error("test_error"),"","");
|
||||||
|
});
|
||||||
|
|
||||||
|
installer.installModule("this_wont_exist").then(function() {
|
||||||
|
done(new Error("Unexpected success"));
|
||||||
|
}).otherwise(function(err) {
|
||||||
|
done();
|
||||||
|
}).finally(function() {
|
||||||
|
exec.restore();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("succeeds when module is found", function(done) {
|
||||||
|
var nodeInfo = {nodes:{module:"foo",types:["a"]}};
|
||||||
|
var exec = sinon.stub(child_process,"execFile",function(cmd,args,opt,cb) {
|
||||||
|
cb(null,"","");
|
||||||
|
});
|
||||||
|
var addModule = sinon.stub(registry,"addModule",function(md) {
|
||||||
|
return when.resolve(nodeInfo);
|
||||||
|
});
|
||||||
|
|
||||||
|
installer.installModule("this_wont_exist").then(function(info) {
|
||||||
|
info.should.eql(nodeInfo);
|
||||||
|
// commsMessages.should.have.length(1);
|
||||||
|
// commsMessages[0].topic.should.equal("node/added");
|
||||||
|
// commsMessages[0].msg.should.eql(nodeInfo.nodes);
|
||||||
|
done();
|
||||||
|
}).otherwise(function(err) {
|
||||||
|
done(err);
|
||||||
|
}).finally(function() {
|
||||||
|
exec.restore();
|
||||||
|
addModule.restore();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe("uninstalls module", function() {
|
||||||
|
it("rejects invalid module names", function(done) {
|
||||||
|
var promises = [];
|
||||||
|
promises.push(installer.uninstallModule("this_wont_exist "));
|
||||||
|
promises.push(installer.uninstallModule("this_wont_exist;no_it_really_wont"));
|
||||||
|
when.settle(promises).then(function(results) {
|
||||||
|
results[0].state.should.be.eql("rejected");
|
||||||
|
results[1].state.should.be.eql("rejected");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("rejects with generic error", function(done) {
|
||||||
|
var nodeInfo = [{module:"foo",types:["a"]}];
|
||||||
|
var removeModule = sinon.stub(registry,"removeModule",function(md) {
|
||||||
|
return when.resolve(nodeInfo);
|
||||||
|
});
|
||||||
|
var exec = sinon.stub(child_process,"execFile",function(cmd,args,opt,cb) {
|
||||||
|
cb(new Error("test_error"),"","");
|
||||||
|
});
|
||||||
|
|
||||||
|
installer.uninstallModule("this_wont_exist").then(function() {
|
||||||
|
done(new Error("Unexpected success"));
|
||||||
|
}).otherwise(function(err) {
|
||||||
|
done();
|
||||||
|
}).finally(function() {
|
||||||
|
exec.restore();
|
||||||
|
removeModule.restore();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("succeeds when module is found", function(done) {
|
||||||
|
var nodeInfo = [{module:"foo",types:["a"]}];
|
||||||
|
var removeModule = sinon.stub(typeRegistry,"removeModule",function(md) {
|
||||||
|
return nodeInfo;
|
||||||
|
});
|
||||||
|
var getModuleInfo = sinon.stub(registry,"getModuleInfo",function(md) {
|
||||||
|
return {nodes:[]};
|
||||||
|
});
|
||||||
|
var exec = sinon.stub(child_process,"execFile",function(cmd,args,opt,cb) {
|
||||||
|
cb(null,"","");
|
||||||
|
});
|
||||||
|
|
||||||
|
var exists = sinon.stub(require('fs'),"existsSync", function(fn) { return true; });
|
||||||
|
|
||||||
|
installer.uninstallModule("this_wont_exist").then(function(info) {
|
||||||
|
info.should.eql(nodeInfo);
|
||||||
|
// commsMessages.should.have.length(1);
|
||||||
|
// commsMessages[0].topic.should.equal("node/removed");
|
||||||
|
// commsMessages[0].msg.should.eql(nodeInfo);
|
||||||
|
done();
|
||||||
|
}).otherwise(function(err) {
|
||||||
|
done(err);
|
||||||
|
}).finally(function() {
|
||||||
|
exec.restore();
|
||||||
|
removeModule.restore();
|
||||||
|
exists.restore();
|
||||||
|
getModuleInfo.restore();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user