Add more untit test in Shovel.js
Statements : 45.76% ( 302/660 ) Branches : 35.81% ( 53/148 ) Functions : 40.7% ( 70/172 ) Lines : 45.76% ( 302/660 )
This commit is contained in:
parent
c32d56976e
commit
ad9ad93053
@ -9,8 +9,8 @@ var keystone = require('./../lib/api/openstack/keystone');
|
|||||||
var logger = require('./../lib/services/logger').Logger;
|
var logger = require('./../lib/services/logger').Logger;
|
||||||
var encryption = require('./../lib/services/encryption');
|
var encryption = require('./../lib/services/encryption');
|
||||||
var jsonfile = require('jsonfile');
|
var jsonfile = require('jsonfile');
|
||||||
var Promise = require('bluebird');
|
|
||||||
var _ = require('underscore');
|
var _ = require('underscore');
|
||||||
|
var Promise = require('bluebird');
|
||||||
|
|
||||||
var ironicConfig = config.ironic;
|
var ironicConfig = config.ironic;
|
||||||
var glanceConfig = config.glance;
|
var glanceConfig = config.glance;
|
||||||
@ -51,8 +51,8 @@ module.exports.driversGet = function driversGet(req, res, next) {
|
|||||||
else
|
else
|
||||||
res.end();
|
res.end();
|
||||||
})
|
})
|
||||||
.catch(function(err){
|
.catch(function (err) {
|
||||||
logger.error({message:err,path:req.url});
|
logger.error({ message: err, path: req.url });
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
res.end(JSON.stringify(err));
|
res.end(JSON.stringify(err));
|
||||||
});
|
});
|
||||||
@ -78,8 +78,8 @@ module.exports.ironicnodesGet = function ironicnodesGet(req, res, next) {
|
|||||||
else
|
else
|
||||||
res.end();
|
res.end();
|
||||||
})
|
})
|
||||||
.catch(function(err){
|
.catch(function (err) {
|
||||||
logger.error({message:err,path:req.url});
|
logger.error({ message: err, path: req.url });
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
res.end(JSON.stringify(err));
|
res.end(JSON.stringify(err));
|
||||||
});
|
});
|
||||||
@ -105,8 +105,8 @@ module.exports.ironicchassisGet = function ironicchassisGet(req, res, next) {
|
|||||||
else
|
else
|
||||||
res.end();
|
res.end();
|
||||||
})
|
})
|
||||||
.catch(function(err){
|
.catch(function (err) {
|
||||||
logger.error({message:err,path:req.url});
|
logger.error({ message: err, path: req.url });
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
res.end(JSON.stringify(err));
|
res.end(JSON.stringify(err));
|
||||||
});
|
});
|
||||||
@ -122,7 +122,7 @@ module.exports.ironicnodeGet = function ironicnodeGet(req, res, next) {
|
|||||||
ironicConfig.os_password).
|
ironicConfig.os_password).
|
||||||
then(function (token) {
|
then(function (token) {
|
||||||
token = JSON.parse(token).access.token.id;
|
token = JSON.parse(token).access.token.id;
|
||||||
return ironic.get_nodeAsync(token, req.swagger.params.identifier.value);
|
return ironic.get_node(token, req.swagger.params.identifier.value);
|
||||||
}).
|
}).
|
||||||
then(function (result) {
|
then(function (result) {
|
||||||
if (typeof result !== 'undefined') {
|
if (typeof result !== 'undefined') {
|
||||||
@ -132,8 +132,8 @@ module.exports.ironicnodeGet = function ironicnodeGet(req, res, next) {
|
|||||||
else
|
else
|
||||||
res.end();
|
res.end();
|
||||||
})
|
})
|
||||||
.catch(function(err){
|
.catch(function (err) {
|
||||||
logger.error({message:err,path:req.url});
|
logger.error({ message: err, path: req.url });
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
res.end(JSON.stringify(err));
|
res.end(JSON.stringify(err));
|
||||||
});
|
});
|
||||||
@ -158,8 +158,8 @@ module.exports.ironicnodePatch = function ironicnodePatch(req, res, next) {
|
|||||||
res.end(result);
|
res.end(result);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(function(err){
|
.catch(function (err) {
|
||||||
logger.error({message:err,path:req.url});
|
logger.error({ message: err, path: req.url });
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
res.end(JSON.stringify(err));
|
res.end(JSON.stringify(err));
|
||||||
});
|
});
|
||||||
@ -180,8 +180,8 @@ module.exports.catalogsGet = function catalogsGet(req, res, next) {
|
|||||||
else
|
else
|
||||||
res.end();
|
res.end();
|
||||||
})
|
})
|
||||||
.catch(function(err){
|
.catch(function (err) {
|
||||||
logger.error({message:err,path:req.url});
|
logger.error({ message: err, path: req.url });
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
res.end(JSON.stringify(err));
|
res.end(JSON.stringify(err));
|
||||||
});
|
});
|
||||||
@ -203,8 +203,8 @@ module.exports.catalogsbysourceGet = function catalogsbysourceGet(req, res, next
|
|||||||
else
|
else
|
||||||
res.end();
|
res.end();
|
||||||
})
|
})
|
||||||
.catch(function(err){
|
.catch(function (err) {
|
||||||
logger.error({message:err,path:req.url});
|
logger.error({ message: err, path: req.url });
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
res.end(JSON.stringify(err));
|
res.end(JSON.stringify(err));
|
||||||
});
|
});
|
||||||
@ -225,8 +225,8 @@ module.exports.nodeGet = function nodeGet(req, res, next) {
|
|||||||
else
|
else
|
||||||
res.end();
|
res.end();
|
||||||
})
|
})
|
||||||
.catch(function(err){
|
.catch(function (err) {
|
||||||
logger.error({message:err,path:req.url});
|
logger.error({ message: err, path: req.url });
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
res.end(JSON.stringify(err));
|
res.end(JSON.stringify(err));
|
||||||
});
|
});
|
||||||
@ -241,7 +241,7 @@ module.exports.nodesGet = function nodesGet(req, res, next) {
|
|||||||
return monorail.request_nodes_get().
|
return monorail.request_nodes_get().
|
||||||
then(function (nodes) {
|
then(function (nodes) {
|
||||||
Promise.filter(JSON.parse(nodes), function (node) {
|
Promise.filter(JSON.parse(nodes), function (node) {
|
||||||
return lookupCatalog(node);
|
return monorail.lookupCatalog(node);
|
||||||
})
|
})
|
||||||
.then(function (discoveredNodes) {
|
.then(function (discoveredNodes) {
|
||||||
if (typeof discoveredNodes !== 'undefined') {
|
if (typeof discoveredNodes !== 'undefined') {
|
||||||
@ -259,38 +259,6 @@ module.exports.nodesGet = function nodesGet(req, res, next) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function lookupCatalog(node) {
|
|
||||||
return monorail.get_catalog_data_by_source(node.id, 'dmi')
|
|
||||||
.then(function (dmi) {
|
|
||||||
if (!_.has(JSON.parse(dmi), 'data')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(function () {
|
|
||||||
return monorail.get_catalog_data_by_source(node.id, 'lsscsi')
|
|
||||||
})
|
|
||||||
.then(function (lsscsi) {
|
|
||||||
if (!_.has(JSON.parse(lsscsi), 'data')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(function () {
|
|
||||||
return monorail.get_catalog_data_by_source(node.id, 'bmc')
|
|
||||||
})
|
|
||||||
.then(function (bmc) {
|
|
||||||
if (!_.has(JSON.parse(bmc), 'data')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function (err) {
|
|
||||||
logger.error(err);
|
|
||||||
return false;
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @api {get} /api/1.1/nodes/identifier/sel / GET /
|
* @api {get} /api/1.1/nodes/identifier/sel / GET /
|
||||||
* @apiDescription get specific node by id
|
* @apiDescription get specific node by id
|
||||||
@ -315,8 +283,8 @@ module.exports.getSeldata = function getSeldata(req, res, next) {
|
|||||||
res.end();
|
res.end();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(function(err){
|
.catch(function (err) {
|
||||||
logger.error({message:err,path:req.url});
|
logger.error({ message: err, path: req.url });
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
res.end(JSON.stringify(err));
|
res.end(JSON.stringify(err));
|
||||||
});
|
});
|
||||||
@ -361,57 +329,43 @@ module.exports.registerpost = function registerpost(req, res, next) {
|
|||||||
return monorail.request_node_get(user_entry.uuid).
|
return monorail.request_node_get(user_entry.uuid).
|
||||||
then(function (result) {
|
then(function (result) {
|
||||||
if (!JSON.parse(result).name) {
|
if (!JSON.parse(result).name) {
|
||||||
res.setHeader('Content-Type', 'application/json');
|
var error = { error_message: { message: 'failed to find required node in RackHD' } };
|
||||||
res.end(result);
|
logger.error(err);
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
onrack_node = JSON.parse(result);
|
onrack_node = JSON.parse(result);
|
||||||
}).then(function () {
|
return monorail.nodeDiskSize(onrack_node)
|
||||||
return monorail.get_catalog_data_by_source(user_entry.uuid, 'lsscsi').
|
.catch(function (err) {
|
||||||
then(function (scsi) {
|
var error = { error_message: { message: 'failed to get compute node Disk Size' } };
|
||||||
scsi = JSON.parse(scsi);
|
logger.error(err);
|
||||||
if (scsi.data) {
|
throw error;
|
||||||
for (var elem in scsi.data) {
|
|
||||||
var item = (scsi.data[elem]);
|
|
||||||
if (item['peripheralType'] == 'disk') {
|
|
||||||
local_gb += parseFloat(item['size'].replace('GB', '').trim());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}).then(function () {
|
}).then(function (localDisk) {
|
||||||
monorail.get_catalog_data_by_source(user_entry.uuid, 'dmi').
|
local_gb = localDisk;
|
||||||
then(function (dmi) {
|
return monorail.get_node_memory_cpu(onrack_node)
|
||||||
dmi = JSON.parse(dmi);
|
.catch(function (err) {
|
||||||
if (dmi.data) {
|
var error = { error_message: { message: 'failed to get compute node memory size' } };
|
||||||
var dmi_total = 0;
|
logger.error(err);
|
||||||
if (dmi.data['Memory Device']) {
|
throw error;
|
||||||
var memory_device = dmi.data['Memory Device'];
|
|
||||||
for (var elem in memory_device) {
|
|
||||||
var item = memory_device[elem];
|
|
||||||
//logger.info(item['Size']);
|
|
||||||
if (item['Size'].indexOf('GB') > -1) {
|
|
||||||
dmi_total += parseFloat(item['Size'].replace('GB', '').trim()) * 1000;
|
|
||||||
}
|
|
||||||
if (item['Size'].indexOf('MB') > -1) {
|
|
||||||
dmi_total += parseFloat(item['Size'].replace('MB', '').trim());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
propreties = {
|
|
||||||
'cpus': dmi['data']['Processor Information'].length,
|
|
||||||
'memory_mb': dmi_total,
|
|
||||||
'local_gb': local_gb
|
|
||||||
};
|
|
||||||
}
|
|
||||||
node = {
|
|
||||||
'name': user_entry.uuid,
|
|
||||||
'driver': user_entry.driver,
|
|
||||||
'driver_info': info,
|
|
||||||
'properties': propreties,
|
|
||||||
'extra': extra
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
}).then(function () {
|
}).then(function (dmiData) {
|
||||||
|
if (local_gb == 0 || dmiData.cpus == 0 || dmiData.memory == 0) {
|
||||||
|
var error = { error_message: { message: 'failed to get compute node data', nodeDisk: local_gb, memorySize: dmiData.memory, cpuCount: dmiData.cpus } };
|
||||||
|
throw (error);
|
||||||
|
}
|
||||||
|
propreties = {
|
||||||
|
'cpus': dmiData.cpus,
|
||||||
|
'memory_mb': dmiData.memory,
|
||||||
|
'local_gb': local_gb
|
||||||
|
};
|
||||||
|
node = {
|
||||||
|
'name': user_entry.uuid,
|
||||||
|
'driver': user_entry.driver,
|
||||||
|
'driver_info': info,
|
||||||
|
'properties': propreties,
|
||||||
|
'extra': extra
|
||||||
|
};
|
||||||
return (keystone.authenticatePassword(ironicConfig.os_tenant_name, ironicConfig.os_username,
|
return (keystone.authenticatePassword(ironicConfig.os_tenant_name, ironicConfig.os_username,
|
||||||
ironicConfig.os_password));
|
ironicConfig.os_password));
|
||||||
}).
|
}).
|
||||||
@ -420,10 +374,9 @@ module.exports.registerpost = function registerpost(req, res, next) {
|
|||||||
return ironic.create_node(ironicToken, JSON.stringify(node));
|
return ironic.create_node(ironicToken, JSON.stringify(node));
|
||||||
}).
|
}).
|
||||||
then(function (ret) {
|
then(function (ret) {
|
||||||
logger.info('\r\ncreate node:\r\n' + ret);
|
logger.debug('\r\ncreate node:\r\n' + ret);
|
||||||
if (ret && JSON.parse(ret).error_message) {
|
if (ret && JSON.parse(ret).error_message) {
|
||||||
res.setHeader('Content-Type', 'application/json');
|
throw (JSON.parse(ret));
|
||||||
res.end(ret);
|
|
||||||
}
|
}
|
||||||
ironic_node = JSON.parse(ret);
|
ironic_node = JSON.parse(ret);
|
||||||
port = { 'address': user_entry.port, 'node_uuid': ironic_node.uuid };
|
port = { 'address': user_entry.port, 'node_uuid': ironic_node.uuid };
|
||||||
@ -436,9 +389,7 @@ module.exports.registerpost = function registerpost(req, res, next) {
|
|||||||
then(function (pwr_state) {
|
then(function (pwr_state) {
|
||||||
logger.info('\r\npwr_state: on');
|
logger.info('\r\npwr_state: on');
|
||||||
if (pwr_state && JSON.parse(pwr_state).error_message) {
|
if (pwr_state && JSON.parse(pwr_state).error_message) {
|
||||||
console.error(JSON.parse(pwr_state).error_message);
|
throw (JSON.parse(pwr_state));
|
||||||
res.setHeader('Content-Type', 'application/json');
|
|
||||||
res.end(pwr_state);
|
|
||||||
}
|
}
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
var timer = {};
|
var timer = {};
|
||||||
@ -452,7 +403,8 @@ module.exports.registerpost = function registerpost(req, res, next) {
|
|||||||
}).
|
}).
|
||||||
then(function (result) {
|
then(function (result) {
|
||||||
logger.info('\r\patched node:\r\n' + result);
|
logger.info('\r\patched node:\r\n' + result);
|
||||||
}).then(function () {
|
}).
|
||||||
|
then(function () {
|
||||||
return monorail.request_whitelist_set(user_entry.port)
|
return monorail.request_whitelist_set(user_entry.port)
|
||||||
}).
|
}).
|
||||||
then(function (whitelist) {
|
then(function (whitelist) {
|
||||||
@ -460,8 +412,8 @@ module.exports.registerpost = function registerpost(req, res, next) {
|
|||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
res.end(whitelist);
|
res.end(whitelist);
|
||||||
})
|
})
|
||||||
.catch(function(err){
|
.catch(function (err) {
|
||||||
logger.error({message:err,path:req.url});
|
logger.error({ message: err, path: req.url });
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
res.end(JSON.stringify(err));
|
res.end(JSON.stringify(err));
|
||||||
});
|
});
|
||||||
@ -472,36 +424,36 @@ module.exports.registerpost = function registerpost(req, res, next) {
|
|||||||
* @apiVersion 1.1.0
|
* @apiVersion 1.1.0
|
||||||
*/
|
*/
|
||||||
module.exports.unregisterdel = function unregisterdel(req, res, next) {
|
module.exports.unregisterdel = function unregisterdel(req, res, next) {
|
||||||
|
var ironicToken;
|
||||||
return keystone.authenticatePassword(ironicConfig.os_tenant_name, ironicConfig.os_username,
|
return keystone.authenticatePassword(ironicConfig.os_tenant_name, ironicConfig.os_username,
|
||||||
ironicConfig.os_password).
|
ironicConfig.os_password).
|
||||||
then(function (token) {
|
then(function (token) {
|
||||||
token = JSON.parse(token).access.token.id;;
|
ironicToken = JSON.parse(token).access.token.id;
|
||||||
return ironic.delete_node(token, req.swagger.params.identifier.value);
|
return ironic.get_node(ironicToken, req.swagger.params.identifier.value);
|
||||||
|
}).
|
||||||
|
then(function (ironicNode) {
|
||||||
|
if (JSON.parse(ironicNode).hasOwnProperty('extra')) {
|
||||||
|
return monorail.request_whitelist_del(JSON.parse(ironicNode).extra.nodeid);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw { error_message: 'Node is not registered with Shovel' };
|
||||||
|
}
|
||||||
|
}).
|
||||||
|
then(function () {
|
||||||
|
return ironic.delete_node(ironicToken, req.swagger.params.identifier.value);
|
||||||
}).
|
}).
|
||||||
then(function (del_node) {
|
then(function (del_node) {
|
||||||
if (del_node && JSON.parse(del_node).error_message) {
|
if (del_node && JSON.parse(del_node).error_message) {
|
||||||
logger.info(del_node);
|
throw (del_node);
|
||||||
res.setHeader('Content-Type', 'application/json');
|
|
||||||
res.end(del_node);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
return monorail.request_node_get(req.swagger.params.identifier.value);
|
else {
|
||||||
}).
|
logger.debug('ironicNode: ' + req.swagger.params.identifier.value + ' is been deleted susccessfully');
|
||||||
then(function (onrack_node) {
|
|
||||||
if (onrack_node && !JSON.parse(onrack_node).name) {
|
|
||||||
logger.info(onrack_node);
|
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
res.end(onrack_node);
|
var success = {
|
||||||
return;
|
result: 'success'
|
||||||
|
};
|
||||||
|
res.end(JSON.stringify(success));
|
||||||
}
|
}
|
||||||
return monorail.request_whitelist_del(JSON.parse(onrack_node).name);
|
|
||||||
}).
|
|
||||||
then(function (whitelist) {
|
|
||||||
res.setHeader('Content-Type', 'application/json');
|
|
||||||
var success = {
|
|
||||||
result: 'success'
|
|
||||||
};
|
|
||||||
res.end(JSON.stringify(success));
|
|
||||||
})
|
})
|
||||||
.catch(function (err) {
|
.catch(function (err) {
|
||||||
logger.error({ message: err, path: req.url });
|
logger.error({ message: err, path: req.url });
|
||||||
@ -551,14 +503,14 @@ module.exports.configsetironic = function configsetironic(req, res, next) {
|
|||||||
if (req.body.hasOwnProperty('os_password')) {
|
if (req.body.hasOwnProperty('os_password')) {
|
||||||
var password = req.body.os_password;
|
var password = req.body.os_password;
|
||||||
//replace password with encrypted value
|
//replace password with encrypted value
|
||||||
try{
|
try {
|
||||||
req.body.os_password = encryption.encrypt(password);
|
req.body.os_password = encryption.encrypt(password);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
logger.error(err);
|
logger.error(err);
|
||||||
res.end('failed to update ironic config');
|
res.end('failed to update ironic config');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (setConfig('ironic', req.body)) {
|
if (setConfig('ironic', req.body)) {
|
||||||
res.end('success');
|
res.end('success');
|
||||||
}
|
}
|
||||||
@ -599,19 +551,19 @@ module.exports.configsetglance = function configsetglance(req, res, next) {
|
|||||||
* @apiVersion 1.1.0
|
* @apiVersion 1.1.0
|
||||||
*/
|
*/
|
||||||
module.exports.configset = function configset(req, res, next) {
|
module.exports.configset = function configset(req, res, next) {
|
||||||
res.setHeader('content-type', 'text/plain');
|
res.setHeader('content-type', 'text/plain');
|
||||||
if (setConfig('shovel', req.body) == true) {
|
if (setConfig('shovel', req.body) == true) {
|
||||||
res.end('success');
|
res.end('success');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
res.end('failed to update shovel config');
|
res.end('failed to update shovel config');
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
function setConfig(keyValue, entry) {
|
function setConfig(keyValue, entry) {
|
||||||
var filename = require('path').dirname(require.main.filename) + '/config.json';
|
var filename = 'config.json';
|
||||||
try {
|
jsonfile.readFile(filename, function (err, output) {
|
||||||
jsonfile.readFile(filename, function (err, output) {
|
try {
|
||||||
var content = (keyValue == null) ? output : output[keyValue];
|
var content = (keyValue == null) ? output : output[keyValue];
|
||||||
var filteredList = _.pick(content, Object.keys(entry));
|
var filteredList = _.pick(content, Object.keys(entry));
|
||||||
_.each(Object.keys(filteredList), function (key) {
|
_.each(Object.keys(filteredList), function (key) {
|
||||||
@ -621,14 +573,15 @@ function setConfig(keyValue, entry) {
|
|||||||
});
|
});
|
||||||
output[keyValue] = content;
|
output[keyValue] = content;
|
||||||
jsonfile.writeFile(filename, output, { spaces: 2 }, function (err) {
|
jsonfile.writeFile(filename, output, { spaces: 2 }, function (err) {
|
||||||
logger.info(content);
|
logger.debug(content);
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
}
|
catch (err) {
|
||||||
catch (err) {
|
logger.error(err);
|
||||||
logger.error(err);
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -638,29 +591,34 @@ function setConfig(keyValue, entry) {
|
|||||||
* @apiVersion 1.1.0
|
* @apiVersion 1.1.0
|
||||||
*/
|
*/
|
||||||
module.exports.configget = function configget(req, res, next) {
|
module.exports.configget = function configget(req, res, next) {
|
||||||
var fs = require('fs');
|
var filename = 'config.json';
|
||||||
var path = require('path');
|
jsonfile.readFile(filename, function (err, content) {
|
||||||
var appDir = path.dirname(require.main.filename);
|
try {
|
||||||
var file_content = fs.readFileSync(appDir + '/config.json');
|
|
||||||
var content = JSON.parse(file_content);
|
delete content['key'];
|
||||||
delete content['key'];
|
if (content.ironic.hasOwnProperty("os_password")) {
|
||||||
if (content.ironic.hasOwnProperty("os_password")){
|
content.ironic.os_password = '[REDACTED]';
|
||||||
content.ironic.os_password = '[REDACTED]';
|
}
|
||||||
}
|
if (content.glance.hasOwnProperty("os_password")) {
|
||||||
if (content.glance.hasOwnProperty("os_password")) {
|
content.glance.os_password = '[REDACTED]';
|
||||||
content.glance.os_password = '[REDACTED]';
|
}
|
||||||
}
|
res.setHeader('Content-Type', 'application/json');
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.end(JSON.stringify(content));
|
||||||
res.end(JSON.stringify(content));
|
}
|
||||||
};
|
catch (err) {
|
||||||
|
logger.error(err);
|
||||||
|
res.end();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @api {get} /api/1.1/glance/images / GET /
|
* @api {get} /api/1.1/glance/images / GET /
|
||||||
* @apiDescription get glance images
|
* @apiDescription get glance images
|
||||||
*/
|
*/
|
||||||
module.exports.imagesGet = function imagesGet(req, res, next) {
|
module.exports.imagesGet = function imagesGet(req, res, next) {
|
||||||
return keystone.authenticatePassword(glanceConfig.os_tenant_name,glanceConfig.os_username,
|
return keystone.authenticatePassword(glanceConfig.os_tenant_name, glanceConfig.os_username,
|
||||||
glanceConfig.os_password ).
|
glanceConfig.os_password).
|
||||||
then(function (token) {
|
then(function (token) {
|
||||||
token = JSON.parse(token).access.token.id;
|
token = JSON.parse(token).access.token.id;
|
||||||
return glance.get_images(token);
|
return glance.get_images(token);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
var config = require('./../../../config.json');
|
var config = require('./../../../config.json');
|
||||||
var client = require('./../client');
|
var client = require('./../client');
|
||||||
var Promise = require('bluebird');
|
var Promise = require('bluebird');
|
||||||
|
var _ = require('underscore');
|
||||||
Promise.promisifyAll(client);
|
Promise.promisifyAll(client);
|
||||||
|
|
||||||
var pfx = '/api/' + config.monorail.version;
|
var pfx = '/api/' + config.monorail.version;
|
||||||
@ -48,6 +49,90 @@ var MonorailWrapper = {
|
|||||||
request_poller_data_get: function (identifier, ret) {
|
request_poller_data_get: function (identifier, ret) {
|
||||||
request.path = pfx + '/pollers/' + identifier + '/data/current';
|
request.path = pfx + '/pollers/' + identifier + '/data/current';
|
||||||
return client.GetAsync(request);
|
return client.GetAsync(request);
|
||||||
|
},
|
||||||
|
lookupCatalog: function lookupCatalog(node) {
|
||||||
|
var self = this;
|
||||||
|
return self.get_catalog_data_by_source(node.id, 'dmi')
|
||||||
|
.then(function (dmi) {
|
||||||
|
if (!_.has(JSON.parse(dmi), 'data')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
return self.get_catalog_data_by_source(node.id, 'lsscsi')
|
||||||
|
})
|
||||||
|
.then(function (lsscsi) {
|
||||||
|
if (!_.has(JSON.parse(lsscsi), 'data')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
return self.get_catalog_data_by_source(node.id, 'bmc')
|
||||||
|
})
|
||||||
|
.then(function (bmc) {
|
||||||
|
if (!_.has(JSON.parse(bmc), 'data')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(function (err) {
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
nodeDiskSize: function nodeDiskSize(node) {
|
||||||
|
var local_gb = 0;
|
||||||
|
var self = this;
|
||||||
|
return self.get_catalog_data_by_source(node.id, 'lsscsi').
|
||||||
|
then(function (scsi) {
|
||||||
|
scsi = JSON.parse(scsi);
|
||||||
|
if (scsi.data) {
|
||||||
|
for (var elem in scsi.data) {
|
||||||
|
var item = (scsi.data[elem]);
|
||||||
|
if (item['peripheralType'] == 'disk') {
|
||||||
|
local_gb += parseFloat(item['size'].replace('GB', '').trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Promise.resolve(local_gb);
|
||||||
|
})
|
||||||
|
.catch(function (err) {
|
||||||
|
throw err;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
get_node_memory_cpu: function get_node_memory_cpu(computeNode) {
|
||||||
|
var self = this;
|
||||||
|
var dmiData = { cpus: 0, memory: 0 };
|
||||||
|
return self.get_catalog_data_by_source(computeNode.id, 'dmi').
|
||||||
|
then(function (dmi) {
|
||||||
|
dmi = JSON.parse(dmi);
|
||||||
|
if (dmi.data) {
|
||||||
|
var dmi_total = 0;
|
||||||
|
if (dmi.data['Memory Device']) {
|
||||||
|
var memory_device = dmi.data['Memory Device'];
|
||||||
|
for (var elem in memory_device) {
|
||||||
|
var item = memory_device[elem];
|
||||||
|
//logger.info(item['Size']);
|
||||||
|
if (item['Size'].indexOf('GB') > -1) {
|
||||||
|
dmi_total += parseFloat(item['Size'].replace('GB', '').trim()) * 1000;
|
||||||
|
}
|
||||||
|
if (item['Size'].indexOf('MB') > -1) {
|
||||||
|
dmi_total += parseFloat(item['Size'].replace('MB', '').trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dmiData.memory = dmi_total;
|
||||||
|
}
|
||||||
|
if (dmi['data'].hasOwnProperty('Processor Information')) {
|
||||||
|
dmiData.cpus = dmi['data']['Processor Information'].length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Promise.resolve(dmiData);
|
||||||
|
})
|
||||||
|
.catch(function (err) {
|
||||||
|
throw err;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
module.exports = Object.create(MonorailWrapper);
|
module.exports = Object.create(MonorailWrapper);
|
@ -1,33 +1,35 @@
|
|||||||
{
|
{
|
||||||
"name": "",
|
"name": "",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"swagger"
|
"swagger"
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"connect": "^3.2.0",
|
"connect": "^3.2.0",
|
||||||
"swagger-tools": "0.8.*",
|
"swagger-tools": "0.8.*",
|
||||||
"bluebird": ""
|
"bluebird": ""
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"should": "~7.0.1",
|
"should": "~7.0.1",
|
||||||
"mocha": "^2.1.0",
|
"mocha": "^2.1.0",
|
||||||
"sinon": "1.16.1",
|
"sinon": "1.16.1",
|
||||||
"sinon-as-promised": "^2.0.3",
|
"sinon-as-promised": "^2.0.3",
|
||||||
"sinon-chai": "^2.7.0",
|
"sinon-chai": "^2.7.0",
|
||||||
"supertest": "^0.15.0",
|
"supertest": "^0.15.0",
|
||||||
"underscore": "^1.8.3",
|
"underscore": "^1.8.3",
|
||||||
"xunit-file": "0.0.6",
|
"xunit-file": "0.0.6",
|
||||||
"winston": "2.1.1",
|
"winston": "2.1.1",
|
||||||
"jsonfile": "2.2.3",
|
"jsonfile": "2.2.3",
|
||||||
"crypto": "0.0.3"
|
"crypto": "0.0.3",
|
||||||
},
|
"istanbul": "0.4.1"
|
||||||
"scripts" :{
|
},
|
||||||
"postinstall": "scripts/post-install.sh",
|
"scripts": {
|
||||||
"start" : "start shovel"
|
"postinstall": "scripts/post-install.sh",
|
||||||
}
|
"start": "start shovel",
|
||||||
|
"test": "istanbul cover -x '**/test/**' ./node_modules/.bin/_mocha test/* && istanbul report cobertura"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
119
Shovel/test/api/monorail.js
Normal file
119
Shovel/test/api/monorail.js
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
var request = require('supertest');
|
||||||
|
var should = require('should');
|
||||||
|
var assert = require('assert');
|
||||||
|
var sinon = require('sinon');
|
||||||
|
var monorail = require('./../../lib/api/monorail/monorail');
|
||||||
|
var Promise = require('bluebird');
|
||||||
|
var _ = require('underscore');
|
||||||
|
|
||||||
|
|
||||||
|
var rackhdNode = [{ workflows: [], autoDiscover: false, identifiers: ["2c:60:0c:83:f5:d1"], name: "2c:60:0c:83:f5:d1", sku: null, type: "compute", id: "5668b6ad8bee16a10989e4e5" }];
|
||||||
|
var catalogSource = [{ source: 'dmi', data: {'Memory Device': [{ Size: '1 GB' }, { Size: '1 GB' }],
|
||||||
|
'Processor Information': [{}, {}] }}, { source: 'lsscsi', data: [{ peripheralType: 'disk', size: '1GB' }] }];
|
||||||
|
var rackhdNode =[ { workflows: [], autoDiscover: false, identifiers: ["2c:60:0c:83:f5:d1"], name: "2c:60:0c:83:f5:d1", sku: null, type: "compute", id: "5668b6ad8bee16a10989e4e5" }];
|
||||||
|
var identifier = '123456789';
|
||||||
|
|
||||||
|
describe('monorail nodeDiskSize', function () {
|
||||||
|
|
||||||
|
beforeEach('set up mocks', function () {
|
||||||
|
//monorail
|
||||||
|
sinon.stub(monorail, 'get_catalog_data_by_source').returns(Promise.resolve(JSON.stringify(catalogSource[1])));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach('teardown mocks', function () {
|
||||||
|
//monorail
|
||||||
|
monorail['get_catalog_data_by_source'].restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('nodeDiskSize', function () {
|
||||||
|
it('response should returns an integer with value equal to disk size 1GB', function (done) {
|
||||||
|
return monorail.nodeDiskSize(rackhdNode).
|
||||||
|
then(function (result) {
|
||||||
|
result.should.be.exactly(1);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('monorail get_node_memory_cpu', function () {
|
||||||
|
beforeEach('set up mocks', function () {
|
||||||
|
//monorail
|
||||||
|
sinon.stub(monorail, 'get_catalog_data_by_source').returns(Promise.resolve(JSON.stringify(catalogSource[0])));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach('teardown mocks', function () {
|
||||||
|
//monorail
|
||||||
|
monorail['get_catalog_data_by_source'].restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('get_node_memory_cpu', function () {
|
||||||
|
it('response should returns an integer with value equal to memory size 2000MB and cpus=2', function (done) {
|
||||||
|
return monorail.get_node_memory_cpu(rackhdNode).
|
||||||
|
then(function (result) {
|
||||||
|
result.cpus.should.be.exactly(2);
|
||||||
|
result.memory.should.be.exactly(2000);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('lookupCatalog true', function () {
|
||||||
|
beforeEach('set up mocks', function () {
|
||||||
|
//monorail
|
||||||
|
sinon.stub(monorail, 'get_catalog_data_by_source').returns(Promise.resolve(JSON.stringify(catalogSource[0])));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach('teardown mocks', function () {
|
||||||
|
//monorail
|
||||||
|
monorail['get_catalog_data_by_source'].restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('lookupCatalog', function () {
|
||||||
|
it('lookupCatalog response should be equal to true', function (done) {
|
||||||
|
return monorail.lookupCatalog(rackhdNode[0]).
|
||||||
|
then(function (result) {
|
||||||
|
console.log(result);
|
||||||
|
JSON.parse(result).should.be.exactly(true);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(function (err) {
|
||||||
|
throw err;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('lookupCatalog false', function () {
|
||||||
|
beforeEach('set up mocks', function () {
|
||||||
|
//monorail
|
||||||
|
sinon.stub(monorail, 'get_catalog_data_by_source').returns(Promise.resolve(JSON.stringify({})));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach('teardown mocks', function () {
|
||||||
|
//monorail
|
||||||
|
monorail['get_catalog_data_by_source'].restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('lookupCatalog', function () {
|
||||||
|
it('lookupCatalog response should be equal to fasle if catalog does not have property data', function (done) {
|
||||||
|
return monorail.lookupCatalog(rackhdNode[0]).
|
||||||
|
then(function (result) {
|
||||||
|
console.log(result);
|
||||||
|
JSON.parse(result).should.be.exactly(false);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(function (err) {
|
||||||
|
throw err;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
});
|
442
Shovel/test/controllers/Shovel.js
Normal file
442
Shovel/test/controllers/Shovel.js
Normal file
@ -0,0 +1,442 @@
|
|||||||
|
var request = require('supertest');
|
||||||
|
var should = require('should');
|
||||||
|
var assert = require('assert');
|
||||||
|
var sinon = require('sinon');
|
||||||
|
var monorail = require('./../../lib/api/monorail/monorail');
|
||||||
|
var ironic = require('./../../lib/api/openstack/ironic');
|
||||||
|
var keystone = require('./../../lib/api/openstack/keystone');
|
||||||
|
var Promise = require('bluebird');
|
||||||
|
var _ = require('underscore');
|
||||||
|
var helper = require('./../helper');
|
||||||
|
var url = 'http://localhost:9008';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var rackhdNode =[ { workflows: [], autoDiscover: false, identifiers: ["2c:60:0c:83:f5:d1"], name: "2c:60:0c:83:f5:d1", sku: null, type: "compute", id: "5668b6ad8bee16a10989e4e5" }];
|
||||||
|
var identifier = '9a761508-4eee-4065-b47b-45c22dff54c2';
|
||||||
|
var ironic_node_list = [ { uuid: "9a761508-4eee-4065-b47b-45c22dff54c2", extra: { name: "D51B-2U (dual 10G LoM)", eventre: "", nodeid: "564cefa014ee77be18e48efd",
|
||||||
|
timer: { start: "2015-11-30T21:14:11.753Z", finish: "2015-11-30T21:14:11.772Z", stop: false, isDone: true, timeInteval: 5000 }, eventcnt: 0 } }];
|
||||||
|
var nodePollers = [{ config: { command: "sel" }, id: "564dd86285fb1e7c72721543" }];
|
||||||
|
var _sel = { sel:[ { logId: "1", date: "12/03/2015", time: "08:54:11", sensorType: "Memory", sensorNumber: "#0x53", event: "Correctable ECC", value: "Asserted"} ] };
|
||||||
|
var keyToken = { access:{ token:{id:'123456'} } };
|
||||||
|
var selEvent = { message: "There is no cache record for the poller with ID 564cf02a4978dadc187976f5.Perhaps it has not been run yet?" };
|
||||||
|
var extraPatch = {extra: {name: "QuantaPlex T41S-2U", eventre: "Correctable ECC",nodeid: "565f3f3b4c95bce26f35c6a0",
|
||||||
|
timer: {timeInterval: 15000, start: "2015-12-03T17:38:20.569Z",finish: "2015-12-03T17:38:20.604Z",stop: false,isDone: true} } };
|
||||||
|
var patchedData = [{ 'path': '/extra', 'value': extraPatch.extra, 'op': 'replace' }];
|
||||||
|
var catalog = [{ node: "9a761508-4eee-4065-b47b-45c22dff54c2", source: "dmi", data: {} }];
|
||||||
|
var ironicDrivers = { drivers: [{ "hosts": ["localhost"], "name": "pxe_ssh", "links": [] }] };
|
||||||
|
var ironicChassis = { uuid: "1ac07daf-264e-4bd5-b0c4-d53095c217ac", link: [], extra: {}, created_at: "", "nodes": [], description: "ironic test chassis" };
|
||||||
|
var catalogSource = [{ source: 'dmi', data: {'Memory Device': [{ Size: '1 GB' }, { Size: '1 GB' }],
|
||||||
|
'Processor Information': [{}, {}] }}, { source: 'lsscsi', data: [{ peripheralType: 'disk', size: '1GB' }] }];
|
||||||
|
|
||||||
|
describe('Shovel api unit testing', function () {
|
||||||
|
var dmiData = { cpus: 1, memory: 1 };
|
||||||
|
|
||||||
|
before('start HTTP server', function () {
|
||||||
|
helper.startServer();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach('set up mocks', function () {
|
||||||
|
//monorail
|
||||||
|
sinon.stub(monorail, 'request_node_get').returns(Promise.resolve(JSON.stringify(rackhdNode[0])));
|
||||||
|
sinon.stub(monorail, 'request_nodes_get').returns(Promise.resolve(JSON.stringify(rackhdNode)));
|
||||||
|
sinon.stub(monorail, 'lookupCatalog').returns(Promise.resolve(true));
|
||||||
|
sinon.stub(monorail, 'request_catalogs_get').returns(Promise.resolve(JSON.stringify(catalog)));
|
||||||
|
sinon.stub(monorail, 'request_poller_get').returns(Promise.resolve(JSON.stringify(nodePollers)));
|
||||||
|
sinon.stub(monorail, 'request_poller_data_get').returns(Promise.resolve(JSON.stringify(_sel)));
|
||||||
|
sinon.stub(monorail, 'request_whitelist_del').returns(Promise.resolve(''));
|
||||||
|
sinon.stub(monorail, 'nodeDiskSize').returns(Promise.resolve(0));
|
||||||
|
sinon.stub(monorail, 'get_node_memory_cpu').returns(Promise.resolve(dmiData));
|
||||||
|
sinon.stub(monorail, 'get_catalog_data_by_source').returns(Promise.resolve(JSON.stringify(catalogSource[0])));
|
||||||
|
//keystone
|
||||||
|
sinon.stub(keystone, 'authenticatePassword').returns(Promise.resolve(JSON.stringify(keyToken)));
|
||||||
|
//ironic
|
||||||
|
sinon.stub(ironic, 'get_driver_list').returns(Promise.resolve(JSON.stringify(ironicDrivers)));
|
||||||
|
sinon.stub(ironic, 'get_chassis_by_id').returns(Promise.resolve(JSON.stringify(ironicChassis)));
|
||||||
|
sinon.stub(ironic, 'patch_node').returns(Promise.resolve(JSON.stringify(extraPatch)));
|
||||||
|
sinon.stub(ironic, 'get_node_list').returns(Promise.resolve(JSON.stringify(ironic_node_list)));
|
||||||
|
sinon.stub(ironic, 'get_node').returns(Promise.resolve(JSON.stringify(ironic_node_list[0])));
|
||||||
|
sinon.stub(ironic, 'delete_node').returns(Promise.resolve(''));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach('teardown mocks', function () {
|
||||||
|
//monorail
|
||||||
|
monorail['request_node_get'].restore();
|
||||||
|
monorail['request_nodes_get'].restore();
|
||||||
|
monorail['request_poller_get'].restore();
|
||||||
|
monorail['request_poller_data_get'].restore();
|
||||||
|
monorail['request_catalogs_get'].restore();
|
||||||
|
monorail['lookupCatalog'].restore();
|
||||||
|
monorail['request_whitelist_del'].restore();
|
||||||
|
monorail['nodeDiskSize'].restore();
|
||||||
|
monorail['get_node_memory_cpu'].restore();
|
||||||
|
monorail['get_catalog_data_by_source'].restore();
|
||||||
|
//ironic
|
||||||
|
ironic['patch_node'].restore();
|
||||||
|
ironic['get_node_list'].restore();
|
||||||
|
ironic['get_node'].restore();
|
||||||
|
ironic['get_chassis_by_id'].restore();
|
||||||
|
ironic['get_driver_list'].restore();
|
||||||
|
ironic['delete_node'].restore();
|
||||||
|
//keystone
|
||||||
|
keystone['authenticatePassword'].restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
after('stop HTTP server', function () {
|
||||||
|
helper.stopServer();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('shovel-info', function () {
|
||||||
|
it('response should have property \'name\': \'shovel\'', function (done) {
|
||||||
|
request(url)
|
||||||
|
.get('/api/1.1/info')
|
||||||
|
// end handles the response
|
||||||
|
.end(function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
// this is should.js syntax, very clear
|
||||||
|
JSON.parse(res.text).should.have.property('name', 'shovel');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('shovel-catalogs/{identifier}', function () {
|
||||||
|
it('in case of a correct rackHD id, response should include property node, source and data', function (done) {
|
||||||
|
request(url)
|
||||||
|
.get('/api/1.1/catalogs/' + identifier)
|
||||||
|
// end handles the response
|
||||||
|
.end(function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
// this is should.js syntax, very clear
|
||||||
|
JSON.parse(res.text)[0].should.have.property('node', identifier);
|
||||||
|
JSON.parse(res.text)[0].should.have.property('data');
|
||||||
|
JSON.parse(res.text)[0].should.have.property('source');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('shovel-catalogs/{identifier}/source', function () {
|
||||||
|
it('in case of a correct rackHD id, response should include property source and data', function (done) {
|
||||||
|
request(url)
|
||||||
|
.get('/api/1.1/catalogs/' + identifier + '/dmi')
|
||||||
|
// end handles the response
|
||||||
|
.end(function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
// this is should.js syntax, very clear
|
||||||
|
JSON.parse(res.text).should.have.property('data');
|
||||||
|
JSON.parse(res.text).should.have.property('source');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('shovel-nodes/{identifier}', function () {
|
||||||
|
it('in case of correct id, response should include property: id,identifiers', function (done) {
|
||||||
|
request(url)
|
||||||
|
.get('/api/1.1/nodes/' + identifier)
|
||||||
|
// end handles the response
|
||||||
|
.end(function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
// this is should.js syntax, very clear
|
||||||
|
JSON.parse(res.text).should.have.property('id');
|
||||||
|
JSON.parse(res.text).should.have.property('identifiers');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('shovel-ironic/chassis/{identifier}', function () {
|
||||||
|
it('in case of a correct id, response should include property: uuid , description ', function (done) {
|
||||||
|
request(url)
|
||||||
|
.get('/api/1.1/ironic/chassis/' + identifier)
|
||||||
|
// end handles the response
|
||||||
|
.end(function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
// this is should.js syntax, very clear
|
||||||
|
JSON.parse(res.text).should.have.property('uuid');
|
||||||
|
JSON.parse(res.text).should.have.property('description');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('shovel-ironic/drivers', function () {
|
||||||
|
it('response should have property \'drivers\'', function (done) {
|
||||||
|
request(url)
|
||||||
|
.get('/api/1.1/ironic/drivers')
|
||||||
|
// end handles the response
|
||||||
|
.end(function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
// this is should.js syntax, very clear
|
||||||
|
JSON.parse(res.text).should.have.property('drivers');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('shovel-ironic/nodes', function () {
|
||||||
|
it('response should have property \'uuid\'', function (done) {
|
||||||
|
request(url)
|
||||||
|
.get('/api/1.1/ironic/nodes')
|
||||||
|
// end handles the response
|
||||||
|
.end(function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
// this is should.js syntax, very clear
|
||||||
|
JSON.parse(res.text)[0].should.have.property('uuid');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('shovel-ironic/nodes/identifier', function () {
|
||||||
|
it('response should have property \'uuid\'', function (done) {
|
||||||
|
request(url)
|
||||||
|
.get('/api/1.1/ironic/nodes/' + identifier)
|
||||||
|
// end handles the response
|
||||||
|
.end(function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
// this is should.js syntax, very clear
|
||||||
|
JSON.parse(res.text).should.have.property('uuid');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('shovel-ironic/patch', function () {
|
||||||
|
it('response should have property nodeid timer', function (done) {
|
||||||
|
var body = {};
|
||||||
|
request(url)
|
||||||
|
.patch('/api/1.1/ironic/node/' + identifier)
|
||||||
|
.send(body)
|
||||||
|
// end handles the response
|
||||||
|
.end(function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
// this is should.js syntax, very clear
|
||||||
|
JSON.parse(res.text).extra.should.have.property('nodeid');
|
||||||
|
JSON.parse(res.text).extra.should.have.property('timer');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('shovel-nodes', function () {
|
||||||
|
it('response should have property "identifiers"', function (done) {
|
||||||
|
request(url)
|
||||||
|
.get('/api/1.1/nodes')
|
||||||
|
// end handles the response
|
||||||
|
.end(function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
// this is should.js syntax, very clear
|
||||||
|
for (item in JSON.parse(res.text)) {
|
||||||
|
JSON.parse(res.text)[item].should.have.property('identifiers');
|
||||||
|
}
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('shovel-unregister/{identifier}', function () {
|
||||||
|
it('if ironic id exist, response should include property: result: success', function (done) {
|
||||||
|
request(url)
|
||||||
|
.delete('/api/1.1/unregister/' + identifier)
|
||||||
|
// end handles the response
|
||||||
|
.end(function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
// this is should.js syntax, very clear
|
||||||
|
JSON.parse(res.text).result.should.be.equal('success');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('shovel-getconfig', function () {
|
||||||
|
it('', function (done) {
|
||||||
|
request(url)
|
||||||
|
.get('/api/1.1/shovel/config')
|
||||||
|
// end handles the response
|
||||||
|
.end(function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
JSON.parse(res.text).should.have.property('shovel');
|
||||||
|
JSON.parse(res.text).should.have.property('ironic');
|
||||||
|
JSON.parse(res.text).should.have.property('glance');
|
||||||
|
JSON.parse(res.text).should.have.property('keystone')
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('shovel-set ironic config', function () {
|
||||||
|
it('', function (done) {
|
||||||
|
var body = { httpHost: "localhost" };
|
||||||
|
request(url)
|
||||||
|
.post('/api/1.1/shovel/ironic/set-config')
|
||||||
|
.send(body)
|
||||||
|
.expect('Content-Type', /text/)
|
||||||
|
.expect(200) //Status code
|
||||||
|
// end handles the response
|
||||||
|
.end(function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
res.text.should.be.exactly('success');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('shovel-set monorail config', function () {
|
||||||
|
it('', function (done) {
|
||||||
|
var body = { httpHost: "localhost" };
|
||||||
|
request(url)
|
||||||
|
.post('/api/1.1/shovel/monorail/set-config')
|
||||||
|
.send(body)
|
||||||
|
.expect('Content-Type', /text/)
|
||||||
|
.expect(200) //Status code
|
||||||
|
// end handles the response
|
||||||
|
.end(function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
res.text.should.be.exactly('success');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('shovel-set glance config', function () {
|
||||||
|
it('', function (done) {
|
||||||
|
var body = { httpHost: "localhost" };
|
||||||
|
request(url)
|
||||||
|
.post('/api/1.1/shovel/glance/set-config')
|
||||||
|
.send(body)
|
||||||
|
.expect('Content-Type', /text/)
|
||||||
|
.expect(200) //Status code
|
||||||
|
// end handles the response
|
||||||
|
.end(function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
res.text.should.be.exactly('success');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('shovel-set keystone config', function () {
|
||||||
|
it('', function (done) {
|
||||||
|
var body = { httpHost: "localhost" };
|
||||||
|
request(url)
|
||||||
|
.post('/api/1.1/shovel/keystone/set-config')
|
||||||
|
.send(body)
|
||||||
|
.expect('Content-Type', /text/)
|
||||||
|
.expect(200) //Status code
|
||||||
|
// end handles the response
|
||||||
|
.end(function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
res.text.should.be.exactly('success');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Shovel api register', function () {
|
||||||
|
var error_message = '{"error_message": "{\\"debuginfo\\": null, \\"faultcode\\": \\"Client\\", \\"faultstring\\": \\"A node with name 5668b42d8bee16a10989e4e4 already exists.\\"}"}';
|
||||||
|
var body = { "id": identifier, "driver": "string", "ipmihost": "string", "ipmiusername": "string", "ipmipasswd": "string" };
|
||||||
|
|
||||||
|
|
||||||
|
beforeEach('set up mocks', function () {
|
||||||
|
//monorail
|
||||||
|
//keystone
|
||||||
|
sinon.stub(keystone, 'authenticatePassword').returns(Promise.resolve(JSON.stringify(keyToken)));
|
||||||
|
//ironic
|
||||||
|
sinon.stub(ironic, 'create_node').returns(Promise.resolve(error_message));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach('teardown mocks', function () {
|
||||||
|
//monorail
|
||||||
|
monorail['nodeDiskSize'].restore();
|
||||||
|
monorail['get_node_memory_cpu'].restore();
|
||||||
|
monorail['request_node_get'].restore();
|
||||||
|
//keystone
|
||||||
|
keystone['authenticatePassword'].restore();
|
||||||
|
//ironic
|
||||||
|
ironic['create_node'].restore();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('shovel-resgister', function () {
|
||||||
|
it('response in register should have property error_message when any of node info equal to 0 ', function (done) {
|
||||||
|
sinon.stub(monorail, 'request_node_get').returns(Promise.resolve(JSON.stringify(rackhdNode[0])));
|
||||||
|
sinon.stub(monorail, 'nodeDiskSize').returns(Promise.resolve(0));
|
||||||
|
sinon.stub(monorail, 'get_node_memory_cpu').returns(Promise.resolve({ cpus: 0, memory: 0 }));
|
||||||
|
|
||||||
|
request(url)
|
||||||
|
.post('/api/1.1/register')
|
||||||
|
.send(body)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(200) //Status code
|
||||||
|
// end handles the response
|
||||||
|
.end(function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
// this is should.js syntax, very clear
|
||||||
|
JSON.parse(res.text).should.have.property('error_message');
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('response in register should have property error_message create node return error in ironic', function (done) {
|
||||||
|
sinon.stub(monorail, 'request_node_get').returns(Promise.resolve(JSON.stringify(rackhdNode[0])));
|
||||||
|
sinon.stub(monorail, 'nodeDiskSize').returns(Promise.resolve(1));
|
||||||
|
sinon.stub(monorail, 'get_node_memory_cpu').returns(Promise.resolve({ cpus: 1, memory: 1 }));
|
||||||
|
|
||||||
|
request(url)
|
||||||
|
.post('/api/1.1/register')
|
||||||
|
.send(body)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(200) //Status code
|
||||||
|
// end handles the response
|
||||||
|
.end(function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
// this is should.js syntax, very clear
|
||||||
|
JSON.parse(res.text).should.have.property('error_message');
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@ -11,68 +11,20 @@ var _ = require('underscore');
|
|||||||
|
|
||||||
describe('Shovel poller unit testing', function () {
|
describe('Shovel poller unit testing', function () {
|
||||||
|
|
||||||
|
var rackhdNode =[ { workflows: [], autoDiscover: false, identifiers: ["2c:60:0c:83:f5:d1"], name: "2c:60:0c:83:f5:d1", sku: null, type: "compute", id: "5668b6ad8bee16a10989e4e5" }];
|
||||||
var identifier = '9a761508-4eee-4065-b47b-45c22dff54c2';
|
var identifier = '9a761508-4eee-4065-b47b-45c22dff54c2';
|
||||||
var ironic_node_list = [
|
var ironic_node_list = [ { uuid: "9a761508-4eee-4065-b47b-45c22dff54c2", extra: { name: "D51B-2U (dual 10G LoM)", eventre: "", nodeid: "564cefa014ee77be18e48efd",
|
||||||
{
|
timer: { start: "2015-11-30T21:14:11.753Z", finish: "2015-11-30T21:14:11.772Z", stop: false, isDone: true, timeInteval: 5000 }, eventcnt: 0 } }];
|
||||||
uuid: "9a761508-4eee-4065-b47b-45c22dff54c2",
|
var nodePollers = [{ config: { command: "sel" }, id: "564dd86285fb1e7c72721543" }];
|
||||||
extra: {
|
var _sel = { sel:[ { logId: "1", date: "12/03/2015", time: "08:54:11", sensorType: "Memory", sensorNumber: "#0x53", event: "Correctable ECC", value: "Asserted"} ] };
|
||||||
name: "D51B-2U (dual 10G LoM)",
|
var keyToken = { access:{ token:{id:'123456'} } };
|
||||||
eventre: "",
|
|
||||||
nodeid: "564cefa014ee77be18e48efd",
|
|
||||||
timer: {
|
|
||||||
start: "2015-11-30T21:14:11.753Z",
|
|
||||||
finish: "2015-11-30T21:14:11.772Z",
|
|
||||||
stop: false,
|
|
||||||
isDone: true,
|
|
||||||
timeInteval: 5000
|
|
||||||
},
|
|
||||||
eventcnt: 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
var nodePollers = [{
|
|
||||||
config: {
|
|
||||||
command: "sel"
|
|
||||||
},
|
|
||||||
id: "564dd86285fb1e7c72721543"
|
|
||||||
}]
|
|
||||||
var _sel = {
|
|
||||||
sel:[
|
|
||||||
{
|
|
||||||
logId: "1",
|
|
||||||
date: "12/03/2015",
|
|
||||||
time: "08:54:11",
|
|
||||||
sensorType: "Memory",
|
|
||||||
sensorNumber: "#0x53",
|
|
||||||
event: "Correctable ECC",
|
|
||||||
value: "Asserted"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
var keyToken = {
|
|
||||||
access:{
|
|
||||||
token:{id:'123456'}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var selEvent = { message: "There is no cache record for the poller with ID 564cf02a4978dadc187976f5.Perhaps it has not been run yet?" };
|
var selEvent = { message: "There is no cache record for the poller with ID 564cf02a4978dadc187976f5.Perhaps it has not been run yet?" };
|
||||||
var extraPatch = {
|
var extraPatch = {extra: {name: "QuantaPlex T41S-2U", eventre: "Correctable ECC",nodeid: "565f3f3b4c95bce26f35c6a0",
|
||||||
extra: {
|
timer: {timeInterval: 15000, start: "2015-12-03T17:38:20.569Z",finish: "2015-12-03T17:38:20.604Z",stop: false,isDone: true} } };
|
||||||
name: "QuantaPlex T41S-2U",
|
|
||||||
eventre: "Correctable ECC",
|
|
||||||
nodeid: "565f3f3b4c95bce26f35c6a0",
|
|
||||||
timer: {
|
|
||||||
timeInterval: 15000,
|
|
||||||
start: "2015-12-03T17:38:20.569Z",
|
|
||||||
finish: "2015-12-03T17:38:20.604Z",
|
|
||||||
stop: false,
|
|
||||||
isDone: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var patchedData = [{ 'path': '/extra', 'value': extraPatch.extra, 'op': 'replace' }];
|
var patchedData = [{ 'path': '/extra', 'value': extraPatch.extra, 'op': 'replace' }];
|
||||||
var pollerInstance;
|
var pollerInstance;
|
||||||
|
|
||||||
before('start HTTP server', function () {
|
before('start Poller service', function () {
|
||||||
pollerInstance = new Poller(5000);//timeInterval to 5s
|
pollerInstance = new Poller(5000);//timeInterval to 5s
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -80,15 +32,15 @@ describe('Shovel poller unit testing', function () {
|
|||||||
sinon.stub(monorail, 'request_poller_get').returns(Promise.resolve(JSON.stringify(nodePollers)));
|
sinon.stub(monorail, 'request_poller_get').returns(Promise.resolve(JSON.stringify(nodePollers)));
|
||||||
sinon.stub(monorail, 'request_poller_data_get').returns(Promise.resolve(JSON.stringify(_sel)));
|
sinon.stub(monorail, 'request_poller_data_get').returns(Promise.resolve(JSON.stringify(_sel)));
|
||||||
sinon.stub(ironic,'patch_node').returns(Promise.resolve(JSON.stringify(extraPatch)));
|
sinon.stub(ironic,'patch_node').returns(Promise.resolve(JSON.stringify(extraPatch)));
|
||||||
sinon.stub(keystone,'authenticate').returns(Promise.resolve(JSON.stringify(keyToken)));
|
sinon.stub(keystone,'authenticatePassword').returns(Promise.resolve(JSON.stringify(keyToken)));
|
||||||
sinon.stub(ironic,'get_node_list').returns(Promise.resolve(JSON.stringify(ironic_node_list)))
|
sinon.stub(ironic,'get_node_list').returns(Promise.resolve(JSON.stringify(ironic_node_list)));
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach('teardown mocks', function () {
|
afterEach('teardown mocks', function () {
|
||||||
monorail['request_poller_get'].restore();
|
monorail['request_poller_get'].restore();
|
||||||
monorail['request_poller_data_get'].restore();
|
monorail['request_poller_data_get'].restore();
|
||||||
ironic['patch_node'].restore();
|
ironic['patch_node'].restore();
|
||||||
keystone['authenticate'].restore();
|
keystone['authenticatePassword'].restore();
|
||||||
ironic['get_node_list'].restore();
|
ironic['get_node_list'].restore();
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -104,8 +56,8 @@ describe('Shovel poller unit testing', function () {
|
|||||||
item.should.have.property('event');
|
item.should.have.property('event');
|
||||||
});
|
});
|
||||||
done();
|
done();
|
||||||
}).
|
})
|
||||||
catch (function(err){
|
.catch (function(err){
|
||||||
throw(err);
|
throw(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -119,8 +71,8 @@ describe('Shovel poller unit testing', function () {
|
|||||||
item.should.have.property('value');
|
item.should.have.property('value');
|
||||||
});
|
});
|
||||||
done();
|
done();
|
||||||
}).
|
})
|
||||||
catch(function(err){
|
.catch(function(err){
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -131,8 +83,8 @@ describe('Shovel poller unit testing', function () {
|
|||||||
data.should.have.property('nodeid');
|
data.should.have.property('nodeid');
|
||||||
data.should.have.property('timer');
|
data.should.have.property('timer');
|
||||||
done();
|
done();
|
||||||
}).
|
})
|
||||||
catch(function(err){
|
.catch(function(err){
|
||||||
throw(err);
|
throw(err);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@ -146,8 +98,8 @@ describe('Shovel poller unit testing', function () {
|
|||||||
item.should.have.property('extra');
|
item.should.have.property('extra');
|
||||||
});
|
});
|
||||||
done();
|
done();
|
||||||
}).
|
})
|
||||||
catch(function(err){
|
.catch(function(err){
|
||||||
throw(err);
|
throw(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -157,8 +109,8 @@ describe('Shovel poller unit testing', function () {
|
|||||||
then(function(token){
|
then(function(token){
|
||||||
token.should.be.equal('123456');
|
token.should.be.equal('123456');
|
||||||
done();
|
done();
|
||||||
}).
|
})
|
||||||
catch(function(err){
|
.catch(function(err){
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user