Fixed the whole unit testing issues with the persistence module. seriosuly how could you forget that node treats modules as singletons...

This commit is contained in:
Dominic Bosch 2014-03-23 22:52:16 +01:00
parent 69121425b9
commit 8011a36915
15 changed files with 594 additions and 461 deletions

View file

@ -38,10 +38,24 @@ exports = module.exports = ( args ) =>
dynmod args
module.exports
###
Add an event handler (eh) for a certain event (evt).
Current events are:
- init: as soon as an event handler is added, the init events are emitted for all existing rules.
- newRule: If a new rule is activated, the newRule event is emitted
@public addListener ( *evt, eh* )
@param {String} evt
@param {function} eh
###
exports.addListener = ( evt, eh ) =>
@ee.addListener evt, eh
db.getRules ( err, obj ) =>
@ee.emit 'init', rule for id, rule of obj
if evt is 'init'
db.getRules ( err, obj ) =>
@ee.emit 'init', rule for id, rule of obj
# cb ( obj ) where obj should contain at least the HTTP response code and a message
@ -151,28 +165,36 @@ commandFunctions =
get_rules: ( user, obj, cb ) ->
console.log 'CM | Implement get_rules'
# A rule needs to be in following format:
#
forge_rule: ( user, obj, cb ) =>
obj.event = JSON.parse obj.event
console.log obj
db.getRule obj.id, ( err, objRule ) =>
if objRule isnt null
try
if objRule isnt null
answ =
code: 409
message: 'Rule name already existing!'
else
rule =
id: obj.id
# users: [ user.username ] # This should be fetched from the db in each listener
event: "#{ obj.event.module } -> #{ obj.event.function }"
conditions: obj.conditions
actions: obj.actions
modules = JSON.parse obj.action_params
db.storeRule rule.id, JSON.stringify rule
db.linkRule rule.id, user.username
db.activateRule rule.id, user.username
db.eventPollers.storeUserParams obj.event.module, user.username, obj.event_params
db.actionInvokers.storeUserParams id, user.username, JSON.stringify params for id, params of modules
@ee.emit 'newRule', JSON.stringify rule
answ =
code: 400
message: 'Rule stored and activated!'
catch err
answ =
code: 409
message: 'Rule name already existing!'
else
answ =
code: 200
message: 'Rule stored and activated!'
rule =
id: obj.id
# users: [ user.username ] # This should be fetched from the db in each listener
event: "#{ obj.event.module } -> #{ obj.event.function }"
conditions: JSON.parse obj.conditions
actions: JSON.parse obj.actions
modules = JSON.parse obj.action_params
db.storeRule rule.id, JSON.stringify rule
db.linkRule rule.id, user.username
db.activateRule rule.id, user.username
db.eventPollers.storeUserParams obj.event.module, user.username, obj.event_params
db.actionInvokers.storeUserParams id, user.username, JSON.stringify params for id, params of modules
@ee.emit 'newRule', JSON.stringify rule
code: 400
message: 'bad bad request...'
console.log err
cb answ

View file

@ -27,6 +27,9 @@ Persistence
crypto = require 'crypto-js'
redis = require 'redis'
# yeah I know you know it now... good luck
crypto_key = "}f6y1y}B{.an$}2c$Yl.$mSnF\\HX149u*y8C:@kmN/520Gt\\v'+KFBnQ!\\r<>5X/xRI`sT<Iw;:DPV;4gy:qf]Zq{\"6sgK{,}^\"!]O;qBM3G?]h_`Psw=b6bVXKXry7*"
###
Module call
-----------
@ -34,23 +37,30 @@ Initializes the DB connection with the given `db-port` property in the `args` ob
@param {Object} args
###
exports = module.exports = ( args ) =>
@log = args.logger
exports = module.exports = ( args ) =>
if not @db
#TODO we need to have a secure concept here, private keys per user
if not args[ 'db-port' ]
args[ 'db-port' ] = 6379
@log = args.logger
exports.eventPollers = new IndexedModules 'event-poller', @log
exports.actionInvokers = new IndexedModules 'action-invoker', @log
exports.initPort args[ 'db-port' ]
exports.initPort = ( port ) =>
@connRefused = false
@db?.quit()
#TODO we need to have a secure concept here, private keys per user
@crypto_key = "}f6y1y}B{.an$}2c$Yl.$mSnF\\HX149u*y8C:@kmN/520Gt\\v'+KFBnQ!\\r<>5X/xRI`sT<Iw;:DPV;4gy:qf]Zq{\"6sgK{,}^\"!]O;qBM3G?]h_`Psw=b6bVXKXry7*"
@db = redis.createClient args[ 'db-port' ],
@db = redis.createClient port,
'localhost', { connect_timeout: 2000 }
# Eventually we try to connect to the wrong port, redis will emit an error that we
# need to catch and take into account when answering the isConnected function call
@db.on 'error', ( err ) =>
if err.message.indexOf( 'ECONNREFUSED' ) > -1
@connRefused = true
@log.error err, 'DB | Wrong port?'
exports.eventPollers = new IndexedModules( 'event-poller', @db, @log )
exports.actionInvokers = new IndexedModules( 'action-invoker', @db, @log )
exports.eventPollers.setDB @db
exports.actionInvokers.setDB @db
###
Checks whether the db is connected and passes either an error on failure after
ten attempts within five seconds, or nothing on success to the callback(err).
@ -59,22 +69,25 @@ ten attempts within five seconds, or nothing on success to the callback(err).
@param {function} cb
###
exports.isConnected = ( cb ) =>
if @db.connected
cb()
if not @db
cb new Error 'DB | DB initialization did not occur or failed miserably!'
else
numAttempts = 0
fCheckConnection = =>
if @connRefused
cb new Error 'DB | Connection refused! Wrong port?'
else
if @db.connected
@log.info 'DB | Successfully connected to DB!'
cb()
else if numAttempts++ < 10
setTimeout fCheckConnection, 100
if @db.connected
cb()
else
numAttempts = 0
fCheckConnection = =>
if @connRefused
cb new Error 'DB | Connection refused! Wrong port?'
else
cb new Error 'DB | Connection to DB failed!'
setTimeout fCheckConnection, 100
if @db.connected
@log.info 'DB | Successfully connected to DB!'
cb()
else if numAttempts++ < 10
setTimeout fCheckConnection, 100
else
cb new Error 'DB | Connection to DB failed!'
setTimeout fCheckConnection, 100
###
Abstracts logging for simple action replies from the DB.
@ -98,7 +111,7 @@ Push an event into the event queue.
exports.pushEvent = ( oEvent ) =>
if oEvent
@log.info "DB | Event pushed into the queue: '#{ oEvent.eventid }'"
@db.rpush 'event_queue', JSON.stringify( oEvent )
@db.rpush 'event_queue', JSON.stringify oEvent
else
@log.warn 'DB | Why would you give me an empty event...'
@ -112,8 +125,8 @@ Pop an event from the event queue and pass it to cb(err, obj).
exports.popEvent = ( cb ) =>
makeObj = ( pcb ) ->
( err, obj ) ->
pcb err, JSON.parse( obj )
@db.lpop 'event_queue', makeObj( cb )
pcb err, JSON.parse obj
@db.lpop 'event_queue', makeObj cb
###
Purge the event queue.
@ -147,7 +160,7 @@ Encrypts a string using the crypto key from the config file, based on aes-256-cb
encrypt = ( plainText ) =>
if !plainText? then return null
try
crypto.AES.encrypt plainText, @crypto_key
crypto.AES.encrypt plainText, crypto_key
catch err
@log.warn err, 'DB | during encryption'
null
@ -161,7 +174,7 @@ Decrypts an encrypted string and hands it back on success or null.
decrypt = ( crypticText ) =>
if !crypticText? then return null;
try
dec = crypto.AES.decrypt crypticText, @crypto_key
dec = crypto.AES.decrypt crypticText, crypto_key
dec.toString crypto.enc.Utf8
catch err
@log.warn err, 'DB | during decryption'
@ -225,11 +238,14 @@ getSetRecords = ( set, fSingle, cb ) =>
# TODO remove specific functions and allow direct access to instances of this class
class IndexedModules
constructor: ( @setname, @db, @log ) ->
@log.info "DB | CALL: Instantiated indexed modules for '#{ @setname }'"
constructor: ( @setname, @log ) ->
@log.info "DB | (IdxedMods) Instantiated indexed modules for '#{ @setname }'"
setDB: ( @db ) ->
@log.info "DB | (IdxedMods) Registered new DB connection for '#{ @setname }'"
storeModule: ( mId, userId, data ) =>
@log.info "DB | CALL: #{ @setname }.storeModule( #{ mId }, #{ userId }, data )"
@log.info "DB | (IdxedMods) #{ @setname }.storeModule( #{ mId }, #{ userId }, data )"
@db.sadd "#{ @setname }s", mId,
replyHandler "sadd '#{ mId }' to '#{ @setname }'"
@db.hmset "#{ @setname }:#{ mId }", 'code', data['code'],
@ -240,7 +256,7 @@ class IndexedModules
#TODO add testing
linkModule: ( mId, userId ) =>
@log.info "DB | CALL: #{ @setname }.linkModule( #{ mId }, #{ userId } )"
@log.info "DB | (IdxedMods) #{ @setname }.linkModule( #{ mId }, #{ userId } )"
@db.sadd "#{ @setname }:#{ mId }:users", userId,
replyHandler "sadd #{ userId } to '#{ @setname }:#{ mId }:users'"
@db.sadd "user:#{ userId }:#{ @setname }s", mId,
@ -248,7 +264,7 @@ class IndexedModules
#TODO add testing
unlinkModule: ( mId, userId ) =>
@log.info "DB | CALL: #{ @setname }.unlinkModule( #{ mId }, #{ userId } )"
@log.info "DB | (IdxedMods) #{ @setname }.unlinkModule( #{ mId }, #{ userId } )"
@db.srem "#{ @setname }:#{ mId }:users", userId,
replyHandler "srem #{ userId } from '#{ @setname }:#{ mId }:users'"
@db.srem "user:#{ userId }:#{ @setname }s", mId,
@ -256,40 +272,40 @@ class IndexedModules
#TODO add testing
publish: ( mId ) =>
@log.info "DB | CALL: #{ @setname }.publish( #{ mId } )"
@log.info "DB | (IdxedMods) #{ @setname }.publish( #{ mId } )"
@db.sadd "public-#{ @setname }s", mId,
replyHandler "sadd '#{ mId }' to 'public-#{ @setname }s'"
#TODO add testing
unpublish: ( mId ) =>
@log.info "DB | CALL: #{ @setname }.unpublish( #{ mId } )"
@log.info "DB | (IdxedMods) #{ @setname }.unpublish( #{ mId } )"
@db.srem "public-#{ @setname }s", mId,
replyHandler "srem '#{ mId }' from 'public-#{ @setname }s'"
getModule: ( mId, cb ) =>
@log.info "DB | CALL: #{ @setname }.getModule( #{ mId } )"
@log.info "DB | (IdxedMods) #{ @setname }.getModule( #{ mId } )"
@db.hgetall "#{ @setname }:#{ mId }", cb
#TODO add testing
getModuleParams: ( mId, cb ) =>
@log.info "DB | CALL: #{ @setname }.getModule( #{ mId } )"
@log.info "DB | (IdxedMods) #{ @setname }.getModule( #{ mId } )"
@db.hget "#{ @setname }:#{ mId }", "params", cb
#TODO add testing
getAvailableModuleIds: ( userId, cb ) =>
@log.info "DB | CALL: #{ @setname }.getPublicModuleIds( #{ @suserId } )"
@log.info "DB | (IdxedMods) #{ @setname }.getPublicModuleIds( #{ @suserId } )"
@db.sunion "public-#{ @setname }s", "user:#{ userId }:#{ @setname }s", cb
getModuleIds: ( cb ) =>
@log.info "DB | CALL: #{ @setname }.getModuleIds()"
@log.info "DB | (IdxedMods) #{ @setname }.getModuleIds()"
@db.smembers "#{ @setname }s", cb
getModules: ( cb ) =>
@log.info "DB | CALL: #{ @setname }.getModules()"
@log.info "DB | (IdxedMods) #{ @setname }.getModules()"
getSetRecords "#{ @setname }s", @getModule, cb
deleteModule: ( mId ) =>
@log.info "DB | CALL: #{ @setname }.deleteModule( #{ mId } )"
@log.info "DB | (IdxedMods) #{ @setname }.deleteModule( #{ mId } )"
@db.srem "#{ @setname }s", mId,
replyHandler "srem '#{ mId }' from #{ @setname }s"
@db.del "#{ @setname }:#{ mId }",
@ -307,23 +323,23 @@ class IndexedModules
# replyHandler "Linking 'user:#{ userId }:#{ @setname }s' #{ mId }"
storeUserParams: ( mId, userId, data ) =>
@log.info "DB | CALL: #{ @setname }.storeUserParams( #{ mId }, #{ userId }, data )"
@log.info "DB | (IdxedMods) #{ @setname }.storeUserParams( #{ mId }, #{ userId }, data )"
@db.sadd "#{ @setname }-params", "#{ mId }:#{ userId }",
replyHandler "sadd '#{ mId }:#{ userId }' to '#{ @setname }-params'"
@db.set "#{ @setname }-params:#{ mId }:#{ userId }", encrypt( data ),
replyHandler "set user params in '#{ @setname }-params:#{ mId }:#{ userId }'"
getUserParams: ( mId, userId, cb ) =>
@log.info "DB | CALL: #{ @setname }.getUserParams( #{ mId }, #{ userId } )"
@log.info "DB | (IdxedMods) #{ @setname }.getUserParams( #{ mId }, #{ userId } )"
@db.get "#{ @setname }-params:#{ mId }:#{ userId }", ( err, data ) ->
cb err, decrypt data
getUserParamsIds: ( cb ) =>
@log.info "DB | CALL: #{ @setname }.getUserParamsIds()"
@log.info "DB | (IdxedMods) #{ @setname }.getUserParamsIds()"
@db.smembers "#{ @setname }-params", cb
deleteUserParams: ( mId, userId ) =>
@log.info "DB | CALL: #{ @setname }.deleteUserParams(#{ mId }, #{ userId } )"
@log.info "DB | (IdxedMods) #{ @setname }.deleteUserParams(#{ mId }, #{ userId } )"
@db.srem "#{ @setname }-params", "#{ mId }:#{ userId }",
replyHandler "srem '#{ mId }:#{ userId }' from '#{ @setname }-params'"
@db.del "#{ @setname }-params:#{ mId }:#{ userId }",
@ -373,7 +389,6 @@ Store a string representation of a rule in the DB.
@param {String} data
###
exports.storeRule = ( ruleId, data ) =>
console.log "ready: #{ @db.ready }, connected: #{ @db.connected }"
@log.info "DB | storeRule: '#{ ruleId }'"
@db.sadd 'rules', "#{ ruleId }",
replyHandler "storing rule key '#{ ruleId }'"
@ -544,7 +559,7 @@ The password should be hashed before it is passed to this function.
###
exports.storeUser = ( objUser ) =>
#TODO Only store user if not already existing, or at least only then add a private key
#for his encryption. we would want to have one private key per user, right?
#for his encryption. we would want to have one private key per user, right?
@log.info "DB | storeUser: '#{ objUser.username }'"
if objUser and objUser.username and objUser.password
@db.sadd 'users', objUser.username,
@ -584,36 +599,35 @@ Deletes a user and all his associated linked and active rules.
###
exports.deleteUser = ( userId ) =>
@log.info "DB | deleteUser: '#{ userId }'"
console.log "ready: #{ @db.ready }, connected: #{ @db.connected }"
@db.srem "users", userId, replyHandler "Deleting user key '#{ userId }'"
@db.del "user:#{ userId }", replyHandler "Deleting user '#{ userId }'"
# # We also need to delete all linked rules
# @db.smembers "user:#{ userId }:rules", ( err, obj ) =>
# delLinkedRuleUser = ( ruleId ) =>
# @db.srem "rule:#{ ruleId }:users", userId,
# replyHandler "Deleting user key '#{ userId }' in linked rule '#{ ruleId }'"
# delLinkedRuleUser id for id in obj
# @db.del "user:#{ userId }:rules",
# replyHandler "Deleting user '#{ userId }' rules"
# We also need to delete all linked rules
@db.smembers "user:#{ userId }:rules", ( err, obj ) =>
delLinkedRuleUser = ( ruleId ) =>
@db.srem "rule:#{ ruleId }:users", userId,
replyHandler "Deleting user key '#{ userId }' in linked rule '#{ ruleId }'"
delLinkedRuleUser id for id in obj
@db.del "user:#{ userId }:rules",
replyHandler "Deleting user '#{ userId }' rules"
# # We also need to delete all active rules
# @db.smembers "user:#{ userId }:active-rules", ( err, obj ) =>
# delActivatedRuleUser = ( ruleId ) =>
# @db.srem "rule:#{ ruleId }:active-users", userId,
# replyHandler "Deleting user key '#{ userId }' in active rule '#{ ruleId }'"
# delActivatedRuleUser id for id in obj
# @db.del "user:#{ userId }:active-rules",
# replyHandler "Deleting user '#{ userId }' rules"
# We also need to delete all active rules
@db.smembers "user:#{ userId }:active-rules", ( err, obj ) =>
delActivatedRuleUser = ( ruleId ) =>
@db.srem "rule:#{ ruleId }:active-users", userId,
replyHandler "Deleting user key '#{ userId }' in active rule '#{ ruleId }'"
delActivatedRuleUser id for id in obj
@db.del "user:#{ userId }:active-rules",
replyHandler "Deleting user '#{ userId }' rules"
# # We also need to delete all associated roles
# @db.smembers "user:#{ userId }:roles", ( err, obj ) =>
# delRoleUser = ( roleId ) =>
# @db.srem "role:#{ roleId }:users", userId,
# replyHandler "Deleting user key '#{ userId }' in role '#{ roleId }'"
# delRoleUser id for id in obj
# @db.del "user:#{ userId }:roles",
# replyHandler "Deleting user '#{ userId }' roles"
# We also need to delete all associated roles
@db.smembers "user:#{ userId }:roles", ( err, obj ) =>
delRoleUser = ( roleId ) =>
@db.srem "role:#{ roleId }:users", userId,
replyHandler "Deleting user key '#{ userId }' in role '#{ roleId }'"
delRoleUser id for id in obj
@db.del "user:#{ userId }:roles",
replyHandler "Deleting user '#{ userId }' roles"
###
Checks the credentials and on success returns the user object to the
@ -633,7 +647,7 @@ exports.loginUser = ( userId, password, cb ) =>
if err
cb err, null
else if obj and obj.password
if pw == obj.password
if pw is obj.password
@log.info "DB | User '#{ obj.username }' logged in!"
cb null, obj
else
@ -683,11 +697,8 @@ Fetch all users of a role and pass them to cb(err, obj).
@param {function} cb
###
exports.getRoleUsers = ( role, cb ) =>
console.log role
console.log cb
@log.info "DB | getRoleUsers: '#{ role }'"
@db.smembers "role:#{ role }:users", cb
console.log 'command issued'
###
Remove a role from a user.
@ -709,4 +720,6 @@ Shuts down the db link.
@public shutDown()
###
exports.shutDown = () => @db?.quit()
exports.shutDown = () =>
@db?.quit()
# @db?.end()

View file

@ -46,7 +46,10 @@ exports = module.exports = ( args ) =>
# Load the standard users from the user config file
users = JSON.parse fs.readFileSync path.resolve __dirname, '..', 'config', 'users.json'
db.storeUser user for user in users
fStoreUser = ( username, oUser ) ->
oUser.username = username
db.storeUser oUser
fStoreUser user, users[user] for user of users
module.exports

View file

@ -1,6 +1,6 @@
{
"dominic": {
"password": "[change this]",
"admin": {
"password": "7407946a7a90b037ba5e825040f184a142161e4c61d81feb83ec8c7f011a99b0d77f39c9170c3231e1003c5cf859c69bd93043b095feff5cce6f6d45ec513764",
"roles": [ "admin" ]
}
}

View file

@ -43,18 +43,33 @@ Components Manager
};
})(this);
/*
Add an event handler (eh) for a certain event (evt).
Current events are:
- init: as soon as an event handler is added, the init events are emitted for all existing rules.
- newRule: If a new rule is activated, the newRule event is emitted
@public addListener ( *evt, eh* )
@param {String} evt
@param {function} eh
*/
exports.addListener = (function(_this) {
return function(evt, eh) {
_this.ee.addListener(evt, eh);
return db.getRules(function(err, obj) {
var id, rule, _results;
_results = [];
for (id in obj) {
rule = obj[id];
_results.push(_this.ee.emit('init', rule));
}
return _results;
});
if (evt === 'init') {
return db.getRules(function(err, obj) {
var id, rule, _results;
_results = [];
for (id in obj) {
rule = obj[id];
_results.push(_this.ee.emit('init', rule));
}
return _results;
});
}
};
})(this);
@ -220,35 +235,44 @@ Components Manager
},
forge_rule: (function(_this) {
return function(user, obj, cb) {
obj.event = JSON.parse(obj.event);
console.log(obj);
return db.getRule(obj.id, function(err, objRule) {
var answ, id, modules, params, rule;
if (objRule !== null) {
answ = {
code: 409,
message: 'Rule name already existing!'
};
} else {
answ = {
code: 200,
message: 'Rule stored and activated!'
};
rule = {
id: obj.id,
event: "" + obj.event.module + " -> " + obj.event["function"],
conditions: JSON.parse(obj.conditions),
actions: JSON.parse(obj.actions)
};
modules = JSON.parse(obj.action_params);
db.storeRule(rule.id, JSON.stringify(rule));
db.linkRule(rule.id, user.username);
db.activateRule(rule.id, user.username);
db.eventPollers.storeUserParams(obj.event.module, user.username, obj.event_params);
for (id in modules) {
params = modules[id];
db.actionInvokers.storeUserParams(id, user.username, JSON.stringify(params));
try {
if (objRule !== null) {
answ = {
code: 409,
message: 'Rule name already existing!'
};
} else {
rule = {
id: obj.id,
event: "" + obj.event.module + " -> " + obj.event["function"],
conditions: obj.conditions,
actions: obj.actions
};
modules = JSON.parse(obj.action_params);
db.storeRule(rule.id, JSON.stringify(rule));
db.linkRule(rule.id, user.username);
db.activateRule(rule.id, user.username);
db.eventPollers.storeUserParams(obj.event.module, user.username, obj.event_params);
for (id in modules) {
params = modules[id];
db.actionInvokers.storeUserParams(id, user.username, JSON.stringify(params));
}
_this.ee.emit('newRule', JSON.stringify(rule));
answ = {
code: 400,
message: 'Rule stored and activated!'
};
}
_this.ee.emit('newRule', JSON.stringify(rule));
} catch (_error) {
err = _error;
answ = {
code: 400,
message: 'bad bad request...'
};
console.log(err);
}
return cb(answ);
});

View file

@ -116,7 +116,7 @@ function initMessageActions() {
process.on('message', function( msg ) {
console.log( 'message: ');
console.log (msg);
console.log (JSON.parse(msg));
console.log (JSON.parse(msg.data));
// var arrProps = obj .split('|');
// if(arrProps.length < 2) log.error('EP', 'too few parameter in message!');
// else {

View file

@ -21,13 +21,15 @@ Persistence
*/
(function() {
var IndexedModules, crypto, decrypt, encrypt, exports, getSetRecords, hash, redis, replyHandler,
var IndexedModules, crypto, crypto_key, decrypt, encrypt, exports, getSetRecords, hash, redis, replyHandler,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
crypto = require('crypto-js');
redis = require('redis');
crypto_key = "}f6y1y}B{.an$}2c$Yl.$mSnF\\HX149u*y8C:@kmN/520Gt\\v'+KFBnQ!\\r<>5X/xRI`sT<Iw;:DPV;4gy:qf]Zq{\"6sgK{,}^\"!]O;qBM3G?]h_`Psw=b6bVXKXry7*";
/*
Module call
@ -39,13 +41,26 @@ Persistence
exports = module.exports = (function(_this) {
return function(args) {
if (!_this.db) {
if (!args['db-port']) {
args['db-port'] = 6379;
}
_this.log = args.logger;
exports.eventPollers = new IndexedModules('event-poller', _this.log);
exports.actionInvokers = new IndexedModules('action-invoker', _this.log);
return exports.initPort(args['db-port']);
}
};
})(this);
exports.initPort = (function(_this) {
return function(port) {
var _ref;
_this.log = args.logger;
_this.connRefused = false;
if ((_ref = _this.db) != null) {
_ref.quit();
}
_this.crypto_key = "}f6y1y}B{.an$}2c$Yl.$mSnF\\HX149u*y8C:@kmN/520Gt\\v'+KFBnQ!\\r<>5X/xRI`sT<Iw;:DPV;4gy:qf]Zq{\"6sgK{,}^\"!]O;qBM3G?]h_`Psw=b6bVXKXry7*";
_this.db = redis.createClient(args['db-port'], 'localhost', {
_this.db = redis.createClient(port, 'localhost', {
connect_timeout: 2000
});
_this.db.on('error', function(err) {
@ -54,8 +69,8 @@ Persistence
return _this.log.error(err, 'DB | Wrong port?');
}
});
exports.eventPollers = new IndexedModules('event-poller', _this.db, _this.log);
return exports.actionInvokers = new IndexedModules('action-invoker', _this.db, _this.log);
exports.eventPollers.setDB(_this.db);
return exports.actionInvokers.setDB(_this.db);
};
})(this);
@ -71,25 +86,29 @@ Persistence
exports.isConnected = (function(_this) {
return function(cb) {
var fCheckConnection, numAttempts;
if (_this.db.connected) {
return cb();
if (!_this.db) {
return cb(new Error('DB | DB initialization did not occur or failed miserably!'));
} else {
numAttempts = 0;
fCheckConnection = function() {
if (_this.connRefused) {
return cb(new Error('DB | Connection refused! Wrong port?'));
} else {
if (_this.db.connected) {
_this.log.info('DB | Successfully connected to DB!');
return cb();
} else if (numAttempts++ < 10) {
return setTimeout(fCheckConnection, 100);
if (_this.db.connected) {
return cb();
} else {
numAttempts = 0;
fCheckConnection = function() {
if (_this.connRefused) {
return cb(new Error('DB | Connection refused! Wrong port?'));
} else {
return cb(new Error('DB | Connection to DB failed!'));
if (_this.db.connected) {
_this.log.info('DB | Successfully connected to DB!');
return cb();
} else if (numAttempts++ < 10) {
return setTimeout(fCheckConnection, 100);
} else {
return cb(new Error('DB | Connection to DB failed!'));
}
}
}
};
return setTimeout(fCheckConnection, 100);
};
return setTimeout(fCheckConnection, 100);
}
}
};
})(this);
@ -207,7 +226,7 @@ Persistence
return null;
}
try {
return crypto.AES.encrypt(plainText, _this.crypto_key);
return crypto.AES.encrypt(plainText, crypto_key);
} catch (_error) {
err = _error;
_this.log.warn(err, 'DB | during encryption');
@ -231,7 +250,7 @@ Persistence
return null;
}
try {
dec = crypto.AES.decrypt(crypticText, _this.crypto_key);
dec = crypto.AES.decrypt(crypticText, crypto_key);
return dec.toString(crypto.enc.Utf8);
} catch (_error) {
err = _error;
@ -299,9 +318,8 @@ Persistence
})(this);
IndexedModules = (function() {
function IndexedModules(setname, db, log) {
function IndexedModules(setname, log) {
this.setname = setname;
this.db = db;
this.log = log;
this.deleteUserParams = __bind(this.deleteUserParams, this);
this.getUserParamsIds = __bind(this.getUserParamsIds, this);
@ -318,11 +336,16 @@ Persistence
this.unlinkModule = __bind(this.unlinkModule, this);
this.linkModule = __bind(this.linkModule, this);
this.storeModule = __bind(this.storeModule, this);
this.log.info("DB | CALL: Instantiated indexed modules for '" + this.setname + "'");
this.log.info("DB | (IdxedMods) Instantiated indexed modules for '" + this.setname + "'");
}
IndexedModules.prototype.setDB = function(db) {
this.db = db;
return this.log.info("DB | (IdxedMods) Registered new DB connection for '" + this.setname + "'");
};
IndexedModules.prototype.storeModule = function(mId, userId, data) {
this.log.info("DB | CALL: " + this.setname + ".storeModule( " + mId + ", " + userId + ", data )");
this.log.info("DB | (IdxedMods) " + this.setname + ".storeModule( " + mId + ", " + userId + ", data )");
this.db.sadd("" + this.setname + "s", mId, replyHandler("sadd '" + mId + "' to '" + this.setname + "'"));
this.db.hmset("" + this.setname + ":" + mId, 'code', data['code'], replyHandler("hmset 'code' in hash '" + this.setname + ":" + mId + "'"));
this.db.hmset("" + this.setname + ":" + mId, 'reqparams', data['reqparams'], replyHandler("hmset 'reqparams' in hash '" + this.setname + ":" + mId + "'"));
@ -330,54 +353,54 @@ Persistence
};
IndexedModules.prototype.linkModule = function(mId, userId) {
this.log.info("DB | CALL: " + this.setname + ".linkModule( " + mId + ", " + userId + " )");
this.log.info("DB | (IdxedMods) " + this.setname + ".linkModule( " + mId + ", " + userId + " )");
this.db.sadd("" + this.setname + ":" + mId + ":users", userId, replyHandler("sadd " + userId + " to '" + this.setname + ":" + mId + ":users'"));
return this.db.sadd("user:" + userId + ":" + this.setname + "s", mId, replyHandler("sadd " + mId + " to 'user:" + userId + ":" + this.setname + "s'"));
};
IndexedModules.prototype.unlinkModule = function(mId, userId) {
this.log.info("DB | CALL: " + this.setname + ".unlinkModule( " + mId + ", " + userId + " )");
this.log.info("DB | (IdxedMods) " + this.setname + ".unlinkModule( " + mId + ", " + userId + " )");
this.db.srem("" + this.setname + ":" + mId + ":users", userId, replyHandler("srem " + userId + " from '" + this.setname + ":" + mId + ":users'"));
return this.db.srem("user:" + userId + ":" + this.setname + "s", mId, replyHandler("srem " + mId + " from 'user:" + userId + ":" + this.setname + "s'"));
};
IndexedModules.prototype.publish = function(mId) {
this.log.info("DB | CALL: " + this.setname + ".publish( " + mId + " )");
this.log.info("DB | (IdxedMods) " + this.setname + ".publish( " + mId + " )");
return this.db.sadd("public-" + this.setname + "s", mId, replyHandler("sadd '" + mId + "' to 'public-" + this.setname + "s'"));
};
IndexedModules.prototype.unpublish = function(mId) {
this.log.info("DB | CALL: " + this.setname + ".unpublish( " + mId + " )");
this.log.info("DB | (IdxedMods) " + this.setname + ".unpublish( " + mId + " )");
return this.db.srem("public-" + this.setname + "s", mId, replyHandler("srem '" + mId + "' from 'public-" + this.setname + "s'"));
};
IndexedModules.prototype.getModule = function(mId, cb) {
this.log.info("DB | CALL: " + this.setname + ".getModule( " + mId + " )");
this.log.info("DB | (IdxedMods) " + this.setname + ".getModule( " + mId + " )");
return this.db.hgetall("" + this.setname + ":" + mId, cb);
};
IndexedModules.prototype.getModuleParams = function(mId, cb) {
this.log.info("DB | CALL: " + this.setname + ".getModule( " + mId + " )");
this.log.info("DB | (IdxedMods) " + this.setname + ".getModule( " + mId + " )");
return this.db.hget("" + this.setname + ":" + mId, "params", cb);
};
IndexedModules.prototype.getAvailableModuleIds = function(userId, cb) {
this.log.info("DB | CALL: " + this.setname + ".getPublicModuleIds( " + this.suserId + " )");
this.log.info("DB | (IdxedMods) " + this.setname + ".getPublicModuleIds( " + this.suserId + " )");
return this.db.sunion("public-" + this.setname + "s", "user:" + userId + ":" + this.setname + "s", cb);
};
IndexedModules.prototype.getModuleIds = function(cb) {
this.log.info("DB | CALL: " + this.setname + ".getModuleIds()");
this.log.info("DB | (IdxedMods) " + this.setname + ".getModuleIds()");
return this.db.smembers("" + this.setname + "s", cb);
};
IndexedModules.prototype.getModules = function(cb) {
this.log.info("DB | CALL: " + this.setname + ".getModules()");
this.log.info("DB | (IdxedMods) " + this.setname + ".getModules()");
return getSetRecords("" + this.setname + "s", this.getModule, cb);
};
IndexedModules.prototype.deleteModule = function(mId) {
this.log.info("DB | CALL: " + this.setname + ".deleteModule( " + mId + " )");
this.log.info("DB | (IdxedMods) " + this.setname + ".deleteModule( " + mId + " )");
this.db.srem("" + this.setname + "s", mId, replyHandler("srem '" + mId + "' from " + this.setname + "s"));
this.db.del("" + this.setname + ":" + mId, replyHandler("del of '" + this.setname + ":" + mId + "'"));
return this.db.smembers("" + this.setname + ":" + mId + ":users", (function(_this) {
@ -394,25 +417,25 @@ Persistence
};
IndexedModules.prototype.storeUserParams = function(mId, userId, data) {
this.log.info("DB | CALL: " + this.setname + ".storeUserParams( " + mId + ", " + userId + ", data )");
this.log.info("DB | (IdxedMods) " + this.setname + ".storeUserParams( " + mId + ", " + userId + ", data )");
this.db.sadd("" + this.setname + "-params", "" + mId + ":" + userId, replyHandler("sadd '" + mId + ":" + userId + "' to '" + this.setname + "-params'"));
return this.db.set("" + this.setname + "-params:" + mId + ":" + userId, encrypt(data), replyHandler("set user params in '" + this.setname + "-params:" + mId + ":" + userId + "'"));
};
IndexedModules.prototype.getUserParams = function(mId, userId, cb) {
this.log.info("DB | CALL: " + this.setname + ".getUserParams( " + mId + ", " + userId + " )");
this.log.info("DB | (IdxedMods) " + this.setname + ".getUserParams( " + mId + ", " + userId + " )");
return this.db.get("" + this.setname + "-params:" + mId + ":" + userId, function(err, data) {
return cb(err, decrypt(data));
});
};
IndexedModules.prototype.getUserParamsIds = function(cb) {
this.log.info("DB | CALL: " + this.setname + ".getUserParamsIds()");
this.log.info("DB | (IdxedMods) " + this.setname + ".getUserParamsIds()");
return this.db.smembers("" + this.setname + "-params", cb);
};
IndexedModules.prototype.deleteUserParams = function(mId, userId) {
this.log.info("DB | CALL: " + this.setname + ".deleteUserParams(" + mId + ", " + userId + " )");
this.log.info("DB | (IdxedMods) " + this.setname + ".deleteUserParams(" + mId + ", " + userId + " )");
this.db.srem("" + this.setname + "-params", "" + mId + ":" + userId, replyHandler("srem '" + mId + ":" + userId + "' from '" + this.setname + "-params'"));
return this.db.del("" + this.setname + "-params:" + mId + ":" + userId, replyHandler("del '" + this.setname + "-params:" + mId + ":" + userId + "'"));
};
@ -483,7 +506,6 @@ Persistence
exports.storeRule = (function(_this) {
return function(ruleId, data) {
console.log("ready: " + _this.db.ready + ", connected: " + _this.db.connected);
_this.log.info("DB | storeRule: '" + ruleId + "'");
_this.db.sadd('rules', "" + ruleId, replyHandler("storing rule key '" + ruleId + "'"));
return _this.db.set("rule:" + ruleId, data, replyHandler("storing rule '" + ruleId + "'"));
@ -773,9 +795,47 @@ Persistence
exports.deleteUser = (function(_this) {
return function(userId) {
_this.log.info("DB | deleteUser: '" + userId + "'");
console.log("ready: " + _this.db.ready + ", connected: " + _this.db.connected);
_this.db.srem("users", userId, replyHandler("Deleting user key '" + userId + "'"));
return _this.db.del("user:" + userId, replyHandler("Deleting user '" + userId + "'"));
_this.db.del("user:" + userId, replyHandler("Deleting user '" + userId + "'"));
_this.db.smembers("user:" + userId + ":rules", function(err, obj) {
var delLinkedRuleUser, id, _i, _len, _results;
delLinkedRuleUser = function(ruleId) {
return _this.db.srem("rule:" + ruleId + ":users", userId, replyHandler("Deleting user key '" + userId + "' in linked rule '" + ruleId + "'"));
};
_results = [];
for (_i = 0, _len = obj.length; _i < _len; _i++) {
id = obj[_i];
_results.push(delLinkedRuleUser(id));
}
return _results;
});
_this.db.del("user:" + userId + ":rules", replyHandler("Deleting user '" + userId + "' rules"));
_this.db.smembers("user:" + userId + ":active-rules", function(err, obj) {
var delActivatedRuleUser, id, _i, _len, _results;
delActivatedRuleUser = function(ruleId) {
return _this.db.srem("rule:" + ruleId + ":active-users", userId, replyHandler("Deleting user key '" + userId + "' in active rule '" + ruleId + "'"));
};
_results = [];
for (_i = 0, _len = obj.length; _i < _len; _i++) {
id = obj[_i];
_results.push(delActivatedRuleUser(id));
}
return _results;
});
_this.db.del("user:" + userId + ":active-rules", replyHandler("Deleting user '" + userId + "' rules"));
_this.db.smembers("user:" + userId + ":roles", function(err, obj) {
var delRoleUser, id, _i, _len, _results;
delRoleUser = function(roleId) {
return _this.db.srem("role:" + roleId + ":users", userId, replyHandler("Deleting user key '" + userId + "' in role '" + roleId + "'"));
};
_results = [];
for (_i = 0, _len = obj.length; _i < _len; _i++) {
id = obj[_i];
_results.push(delRoleUser(id));
}
return _results;
});
return _this.db.del("user:" + userId + ":roles", replyHandler("Deleting user '" + userId + "' roles"));
};
})(this);
@ -866,11 +926,8 @@ Persistence
exports.getRoleUsers = (function(_this) {
return function(role, cb) {
console.log(role);
console.log(cb);
_this.log.info("DB | getRoleUsers: '" + role + "'");
_this.db.smembers("role:" + role + ":users", cb);
return console.log('command issued');
return _this.db.smembers("role:" + role + ":users", cb);
};
})(this);

View file

@ -29,7 +29,7 @@ Request Handler
exports = module.exports = (function(_this) {
return function(args) {
var user, users, _i, _len;
var fStoreUser, user, users;
_this.log = args.logger;
_this.userRequestHandler = args['request-service'];
_this.objAdminCmds = {
@ -45,9 +45,12 @@ Request Handler
};
db(args);
users = JSON.parse(fs.readFileSync(path.resolve(__dirname, '..', 'config', 'users.json')));
for (_i = 0, _len = users.length; _i < _len; _i++) {
user = users[_i];
db.storeUser(user);
fStoreUser = function(username, oUser) {
oUser.username = username;
return db.storeUser(oUser);
};
for (user in users) {
fStoreUser(user, users[user]);
}
return module.exports;
};

View file

@ -0,0 +1,13 @@
path = require 'path'
logger = require path.join '..', '..', 'js-coffee', 'logging'
log = logger.getLogger
nolog: true
db = require path.join '..', '..', 'js-coffee', 'persistence'
opts =
logger: log
opts[ 'db-port' ] = 6379
db opts
# This needs to be done because else the DB connection will remain alive and
# prevent the unit test from ending
setTimeout db.shutDown, 2000

View file

@ -0,0 +1,57 @@
{
"events": {
"evt1":{
"eventid": "test_1",
"event": "test_1"
},
"evt2":{
"eventid": "test_2",
"event": "test_2"
}
},
"eps": {
"ep1": {
"code": "unit-test event poller 1 content",
"reqparams": "[param11,param12]"
},
"ep2": {
"code": "unit-test event poller 2 content",
"reqparams": "[param21,param22]"
}
},
"rules": {
"ruleOne": {
"id": "ruleOne_id",
"event": "custom-test-1",
"conditions": {
"property": "yourValue"
},
"actions": []
},
"ruleTwo": {
"id": "ruleTwo_id",
"event": "custom-test-2",
"conditions": {
"property": "yourValue2"
},
"actions": []
}
},
"users": {
"userOne": {
"username": "tester-1",
"password": "password-1"
},
"userTwo": {
"username": "tester-2",
"password": "password-2"
},
"userAdmin": {
"username": "tester-admin",
"password": "password-admin",
"roles": [ "admin" ],
"isAdmin": true
}
}
}

View file

@ -0,0 +1,40 @@
fs = require 'fs'
path = require 'path'
try
data = fs.readFileSync path.resolve( 'testing', 'files', 'testObjects.json' ), 'utf8'
try
objects = JSON.parse data
catch err
console.log 'Error parsing standard objects file: ' + err.message
catch err
console.log 'Error fetching standard objects file: ' + err.message
logger = require path.join '..', 'js-coffee', 'logging'
log = logger.getLogger
nolog: true
cm = require path.join '..', 'js-coffee', 'components-manager'
opts =
logger: log
cm opts
db = require path.join '..', 'js-coffee', 'persistence'
db opts
exports.testListener = ( test ) ->
test.expect 2
oRuleOne = objects.rules.ruleOne
oRuleTwo = objects.rules.ruleOne
db.storeRule 'test-cm-rule', JSON.stringify oRuleOne
cm.addListener 'init', ( evt ) =>
test.deepEqual evt, oRuleOne, 'Event is not the same!'
console.log 'got and checked init'
cm.addListener 'newRule', ( evt ) =>
console.log 'new rule listener added'
test.deepEqual evt, oRuleTwo, 'Event is not the same!'
test.done()
cm.processRequest oUser, oRuleTwo, ( answ ) =>
console.log answ

View file

@ -19,7 +19,6 @@ exports.testParameters = ( test ) =>
'mode'
'io-level'
'file-level'
# 'file-path'
]
test.expect 3 + reqProp.length
test.ok @conf.getHttpPort(), 'HTTP port does not exist!'

View file

@ -1,17 +1,22 @@
fs = require 'fs'
path = require 'path'
try
data = fs.readFileSync path.resolve( 'testing', 'files', 'testObjects.json' ), 'utf8'
try
objects = JSON.parse data
catch err
console.log 'Error parsing standard objects file: ' + err.message
catch err
console.log 'Error fetching standard objects file: ' + err.message
logger = require path.join '..', 'js-coffee', 'logging'
log = logger.getLogger()
# nolog: true
dbs = []
i = 0
getDBInstance = () ->
dbs[++i] = require path.join '..', 'js-coffee', 'persistence'
opts =
logger: log
opts[ 'db-port' ] = 6379
dbs[i] opts
dbs[i]
log = logger.getLogger
nolog: true
db = require path.join '..', 'js-coffee', 'persistence'
opts =
logger: log
opts[ 'db-port' ] = 6379
db opts
# ###
# # Test AVAILABILITY
@ -19,47 +24,33 @@ getDBInstance = () ->
exports.Availability =
testRequire: ( test ) =>
test.expect 1
db = getDBInstance()
test.ok db, 'DB interface loaded'
db.shutDown()
test.done()
testConnect: ( test ) =>
test.expect 1
db = getDBInstance()
db.isConnected ( err ) ->
test.ifError err, 'Connection failed!'
db.shutDown()
test.done()
# We cannot test for no db-port, since node-redis then assumes standard port
testWrongDbPort: ( test ) =>
test.expect 1
opts =
logger: log
opts[ 'db-port' ] = 13410
db = getDBInstance()
db opts
db.initPort 13410
db.isConnected ( err ) ->
test.ok err, 'Still connected!?'
db.shutDown()
db.initPort 6379
test.done()
testPurgeQueue: ( test ) =>
test.expect 2
evt =
eventid: '1'
event: 'mail'
db = getDBInstance()
db.pushEvent evt
db.pushEvent objects.events.evt1
db.purgeEventQueue()
db.popEvent ( err, obj ) =>
test.ifError err, 'Error during pop after purging!'
test.strictEqual obj, null, 'There was an event in the queue!?'
db.shutDown()
test.done()
@ -67,54 +58,42 @@ exports.Availability =
# Test EVENT QUEUE
###
exports.EventQueue =
setUp: ( cb ) =>
@evt1 =
eventid: '1'
event: 'mail'
@evt2 =
eventid: '2'
event: 'mail'
cb()
testEmptyPopping: ( test ) =>
test.expect 2
db = getDBInstance()
db.purgeEventQueue()
db.popEvent ( err, obj ) =>
test.ifError err,
'Error during pop after purging!'
test.strictEqual obj, null,
'There was an event in the queue!?'
db.shutDown()
test.done()
testEmptyPushing: ( test ) =>
test.expect 2
db = getDBInstance()
db.pushEvent null
db.popEvent ( err, obj ) =>
test.ifError err,
'Error during non-empty pushing!'
test.strictEqual obj, null,
'There was an event in the queue!?'
db.shutDown()
test.done()
testNonEmptyPopping: ( test ) =>
test.expect 3
db = getDBInstance()
db.pushEvent @evt1
db.pushEvent objects.events.evt1
db.popEvent ( err, obj ) =>
test.ifError err,
'Error during non-empty popping!'
test.notStrictEqual obj, null,
'There was no event in the queue!'
test.deepEqual @evt1, obj,
test.deepEqual objects.events.evt1, obj,
'Wrong event in queue!'
db.shutDown()
test.done()
testMultiplePushAndPops: ( test ) =>
@ -123,19 +102,18 @@ exports.EventQueue =
semaphore = 2
forkEnds = () ->
if --semaphore is 0
db.shutDown()
test.done()
db = getDBInstance()
db.pushEvent @evt1
db.pushEvent @evt2
db.pushEvent objects.events.evt1
db.pushEvent objects.events.evt2
# eventually it would be wise to not care about the order of events
db.popEvent ( err, obj ) =>
test.ifError err,
'Error during multiple push and pop!'
test.notStrictEqual obj, null,
'There was no event in the queue!'
test.deepEqual @evt1, obj,
test.deepEqual objects.events.evt1, obj,
'Wrong event in queue!'
forkEnds()
db.popEvent ( err, obj ) =>
@ -143,7 +121,7 @@ exports.EventQueue =
'Error during multiple push and pop!'
test.notStrictEqual obj, null,
'There was no event in the queue!'
test.deepEqual @evt2, obj,
test.deepEqual objects.events.evt2, obj,
'Wrong event in queue!'
forkEnds()
@ -157,72 +135,61 @@ exports.EventPoller =
@userId = 'tester1'
@event1id = 'test-event-poller_1'
@event2id = 'test-event-poller_2'
@event1 =
code: 'unit-test event poller 1 content'
reqparams:'[param11,param12]'
@event2 =
code: 'unit-test event poller 2 content'
reqparams:'[param21,param22]'
cb()
tearDown: ( cb ) =>
db = getDBInstance()
db.eventPollers.unlinkModule @event1id, @userId
db.eventPollers.deleteModule @event1id
db.eventPollers.unlinkModule @event2id, @userId
db.eventPollers.deleteModule @event2id
setTimeout db.shutDown, 500
cb()
testCreateAndRead: ( test ) =>
test.expect 3
db = getDBInstance()
db.eventPollers.storeModule @event1id, @userId, @event1
# test that the ID shows up in the set
db.eventPollers.storeModule @event1id, @userId, objects.eps.ep1
# test that the ID shows up in the set
db.eventPollers.getModuleIds ( err , obj ) =>
test.ok @event1id in obj,
'Expected key not in event-pollers set'
# the retrieved object really is the one we expected
db.eventPollers.getModule @event1id, ( err , obj ) =>
test.deepEqual obj, @event1,
test.deepEqual obj, objects.eps.ep1,
'Retrieved Event Poller is not what we expected'
# Ensure the event poller is in the list of all existing ones
db.eventPollers.getModules ( err , obj ) =>
test.deepEqual @event1, obj[@event1id],
test.deepEqual objects.eps.ep1, obj[@event1id],
'Event Poller ist not in result set'
db.shutDown()
test.done()
testUpdate: ( test ) =>
test.expect 2
db = getDBInstance()
# store an entry to start with
db.eventPollers.storeModule @event1id, @userId, @event1
db.eventPollers.storeModule @event1id, @userId, @event2
db.eventPollers.storeModule @event1id, @userId, objects.eps.ep1
db.eventPollers.storeModule @event1id, @userId, objects.eps.ep2
# the retrieved object really is the one we expected
db.eventPollers.getModule @event1id, ( err , obj ) =>
test.deepEqual obj, @event2,
test.deepEqual obj, objects.eps.ep2,
'Retrieved Event Poller is not what we expected'
# Ensure the event poller is in the list of all existing ones
db.eventPollers.getModules ( err , obj ) =>
test.deepEqual @event2, obj[@event1id],
test.deepEqual objects.eps.ep2, obj[@event1id],
'Event Poller ist not in result set'
db.shutDown()
test.done()
testDelete: ( test ) =>
test.expect 2
db = getDBInstance()
# store an entry to start with
db.eventPollers.storeModule @event1id, @userId, @event1
db.eventPollers.storeModule @event1id, @userId, objects.eps.ep1
# Ensure the event poller has been deleted
db.eventPollers.deleteModule @event1id
@ -234,7 +201,7 @@ exports.EventPoller =
db.eventPollers.getModuleIds ( err , obj ) =>
test.ok @event1id not in obj,
'Event Poller key still exists in set'
db.shutDown()
test.done()
@ -247,21 +214,20 @@ exports.EventPoller =
myTest = test
forkEnds = () ->
if --semaphore is 0
db.shutDown()
myTest.done()
( err, obj ) =>
myTest.deepEqual mod, obj,
"Invoker #{ modname } does not equal the expected one"
forkEnds()
db = getDBInstance()
db.eventPollers.storeModule @event1id, @userId, @event1
db.eventPollers.storeModule @event2id, @userId, @event2
db.eventPollers.storeModule @event1id, @userId, objects.eps.ep1
db.eventPollers.storeModule @event2id, @userId, objects.eps.ep2
db.eventPollers.getModuleIds ( err, obj ) =>
test.ok @event1id in obj and @event2id in obj,
'Not all event poller Ids in set'
db.eventPollers.getModule @event1id, fCheckInvoker @event1id, @event1
db.eventPollers.getModule @event2id, fCheckInvoker @event2id, @event2
db.eventPollers.getModule @event1id, fCheckInvoker @event1id, objects.eps.ep1
db.eventPollers.getModule @event2id, fCheckInvoker @event2id, objects.eps.ep2
###
@ -275,7 +241,6 @@ exports.EventPollerParams =
eventId = 'test-event-poller_1'
params = 'shouldn\'t this be an object?'
db = getDBInstance()
# store an entry to start with
db.eventPollers.storeUserParams eventId, userId, params
@ -289,7 +254,6 @@ exports.EventPollerParams =
test.strictEqual obj, params,
'Retrieved event params is not what we expected'
db.eventPollers.deleteUserParams eventId, userId
setTimeout db.shutDown, 500
test.done()
testUpdate: ( test ) =>
@ -300,7 +264,6 @@ exports.EventPollerParams =
params = 'shouldn\'t this be an object?'
paramsNew = 'shouldn\'t this be a new object?'
db = getDBInstance()
# store an entry to start with
db.eventPollers.storeUserParams eventId, userId, params
db.eventPollers.storeUserParams eventId, userId, paramsNew
@ -310,7 +273,7 @@ exports.EventPollerParams =
test.strictEqual obj, paramsNew,
'Retrieved event params is not what we expected'
db.eventPollers.deleteUserParams eventId, userId
db.shutDown()
test.done()
testDelete: ( test ) =>
@ -320,7 +283,6 @@ exports.EventPollerParams =
eventId = 'test-event-poller_1'
params = 'shouldn\'t this be an object?'
db = getDBInstance()
# store an entry to start with and delete it right away
db.eventPollers.storeUserParams eventId, userId, params
db.eventPollers.deleteUserParams eventId, userId
@ -333,7 +295,7 @@ exports.EventPollerParams =
db.eventPollers.getUserParamsIds ( err, obj ) =>
test.ok eventId+':'+userId not in obj,
'Event Params key still exists in set'
db.shutDown()
test.done()
@ -342,35 +304,19 @@ exports.EventPollerParams =
###
exports.Rules =
setUp: ( cb ) =>
# @db logType: 1
@userId = 'tester-1'
@ruleId = 'test-rule_1'
@rule =
"id": "rule_id",
"event": "custom",
"condition":
"property": "yourValue",
"actions": []
@ruleNew =
"id": "rule_new",
"event": "custom",
"condition":
"property": "yourValue",
"actions": []
cb()
tearDown: ( cb ) =>
db = getDBInstance()
db.deleteRule @ruleId
setTimeout db.shutDown, 500
cb()
testCreateAndRead: ( test ) =>
test.expect 3
db = getDBInstance()
# store an entry to start with
db.storeRule @ruleId, JSON.stringify(@rule)
db.storeRule @ruleId, JSON.stringify objects.rules.ruleOne
# test that the ID shows up in the set
db.getRuleIds ( err, obj ) =>
@ -379,37 +325,35 @@ exports.Rules =
# the retrieved object really is the one we expected
db.getRule @ruleId, ( err, obj ) =>
test.deepEqual JSON.parse(obj), @rule,
test.deepEqual JSON.parse(obj), objects.rules.ruleOne,
'Retrieved rule is not what we expected'
# Ensure the rule is in the list of all existing ones
db.getRules ( err , obj ) =>
test.deepEqual @rule, JSON.parse(obj[@ruleId]),
test.deepEqual objects.rules.ruleOne, JSON.parse( obj[@ruleId] ),
'Rule not in result set'
db.shutDown()
test.done()
testUpdate: ( test ) =>
test.expect 1
db = getDBInstance()
# store an entry to start with
db.storeRule @ruleId, JSON.stringify(@rule)
db.storeRule @ruleId, JSON.stringify(@ruleNew)
db.storeRule @ruleId, JSON.stringify objects.rules.ruleOne
db.storeRule @ruleId, JSON.stringify objects.rules.ruleTwo
# the retrieved object really is the one we expected
db.getRule @ruleId, ( err, obj ) =>
test.deepEqual JSON.parse(obj), @ruleNew,
test.deepEqual JSON.parse(obj), objects.rules.ruleTwo,
'Retrieved rule is not what we expected'
db.shutDown()
test.done()
testDelete: ( test ) =>
test.expect 2
db = getDBInstance()
# store an entry to start with and delete it right away
db.storeRule @ruleId, JSON.stringify(@rule)
db.storeRule @ruleId, JSON.stringify objects.rules.ruleOne
db.deleteRule @ruleId
# Ensure the event params have been deleted
@ -421,13 +365,12 @@ exports.Rules =
db.getRuleIds ( err, obj ) =>
test.ok @ruleId not in obj,
'Rule key still exists in set'
db.shutDown()
test.done()
testLink: ( test ) =>
test.expect 2
db = getDBInstance()
# link a rule to the user
db.linkRule @ruleId, @userId
@ -440,13 +383,12 @@ exports.Rules =
db.getUserLinkedRules @userId, ( err, obj ) =>
test.ok @ruleId in obj,
"User not linked to rule #{ @ruleId }"
db.shutDown()
test.done()
testUnlink: ( test ) =>
test.expect 2
db = getDBInstance()
# link and unlink immediately afterwards
db.linkRule @ruleId, @userId
db.unlinkRule @ruleId, @userId
@ -460,7 +402,7 @@ exports.Rules =
db.getUserLinkedRules @userId, ( err, obj ) =>
test.ok @ruleId not in obj,
"User still linked to rule #{ @ruleId }"
db.shutDown()
test.done()
testActivate: ( test ) =>
@ -469,7 +411,6 @@ exports.Rules =
usr =
username: "tester-1"
password: "tester-1"
db = getDBInstance()
db.storeUser usr
db.activateRule @ruleId, @userId
# activate a rule for a user
@ -494,13 +435,12 @@ exports.Rules =
# else
# test.ok true,
# "Dummy so we meet the expected num of tests"
db.shutDown()
test.done()
testDeactivate: ( test ) =>
test.expect 3
db = getDBInstance()
# store an entry to start with and link it to te user
db.activateRule @ruleId, @userId
db.deactivateRule @ruleId, @userId
@ -523,15 +463,14 @@ exports.Rules =
else
test.ok true,
"We are fine since there are no entries for this user anymore"
db.shutDown()
test.done()
testUnlinkAndDeactivateAfterDeletion: ( test ) =>
test.expect 2
db = getDBInstance()
# store an entry to start with and link it to te user
db.storeRule @ruleId, JSON.stringify(@rule)
db.storeRule @ruleId, JSON.stringify objects.rules.ruleOne
db.linkRule @ruleId, @userId
db.activateRule @ruleId, @userId
@ -547,12 +486,12 @@ exports.Rules =
db.getUserActivatedRules @userId, ( err, obj ) =>
test.ok @ruleId not in obj,
"Rule #{ @ruleId } still activated for user #{ @userId }"
db.shutDown()
test.done()
fWaitForDeletion = () =>
db.deleteRule @ruleId
setTimeout fWaitForTest, 100
setTimeout fWaitForTest, 300
setTimeout fWaitForDeletion, 100
@ -561,16 +500,9 @@ exports.Rules =
# Test USER
###
exports.User =
setUp: ( cb ) =>
@oUser =
username: "tester-1"
password: "password"
cb()
tearDown: ( cb ) =>
db = getDBInstance()
console.log 'tearDown'
# db.deleteUser @oUser.username
setTimeout db.shutDown, 500
db.deleteUser objects.users.userOne.username
cb()
testCreateInvalid: ( test ) =>
@ -581,7 +513,6 @@ exports.User =
oUserInvTwo =
password: "password"
db = getDBInstance()
# try to store invalid users, ensure they weren't
db.storeUser oUserInvOne
db.storeUser oUserInvTwo
@ -599,119 +530,102 @@ exports.User =
'User key was stored!?'
test.ok oUserInvTwo.username not in obj,
'User key was stored!?'
db.shutDown()
test.done()
testDelete: ( test ) =>
test.expect 2
db = getDBInstance()
oUsr = objects.users.userOne
# Store the user
db.storeUser @oUser
db.storeUser oUsr
db.getUser @oUser.username, ( err, obj ) =>
test.deepEqual obj, @oUser,
"User #{ @oUser.username } is not what we expect!"
db.getUser oUsr.username, ( err, obj ) =>
test.deepEqual obj, oUsr,
"User #{ objects.users.userOne.username } is not what we expect!"
db.getUserIds ( err, obj ) =>
test.ok @oUser.username in obj,
test.ok oUsr.username in obj,
'User key was not stored!?'
db.shutDown()
test.done()
testUpdate: ( test ) =>
test.expect 2
oUserOne =
username: "tester-1-update"
password: "password"
oUsr = objects.users.userOne
db = getDBInstance()
# Store the user
db.storeUser oUserOne
oUserOne.password = "password-update"
db.storeUser oUserOne
db.storeUser oUsr
oUsr.password = "password-update"
db.storeUser oUsr
db.getUser oUserOne.username, ( err, obj ) =>
test.deepEqual obj, oUserOne,
"User #{ @oUser.username } is not what we expect!"
db.getUser oUsr.username, ( err, obj ) =>
test.deepEqual obj, oUsr,
"User #{ oUsr.username } is not what we expect!"
db.getUserIds ( err, obj ) =>
test.ok oUserOne.username in obj,
test.ok oUsr.username in obj,
'User key was not stored!?'
db.deleteUser oUserOne.username
setTimeout db.shutDown, 500
db.deleteUser oUsr.username
test.done()
testDelete: ( test ) =>
test.expect 2
db = getDBInstance()
oUsr = objects.users.userOne
# Wait until the user and his rules and roles are deleted
fWaitForDeletion = () =>
db.getUserIds ( err, obj ) =>
test.ok @oUser.username not in obj,
test.ok oUsr.username not in obj,
'User key still in set!'
db.getUser @oUser.username, ( err, obj ) =>
db.getUser oUsr.username, ( err, obj ) =>
test.strictEqual obj, null,
'User key still exists!'
test.done()
# Store the user and make some links
db.storeUser @oUser
db.deleteUser @oUser.username
db.storeUser oUsr
db.deleteUser oUsr.username
setTimeout fWaitForDeletion, 100
testDeleteLinks: ( test ) =>
test.expect 4
db = getDBInstance()
oUsr = objects.users.userOne
# Wait until the user and his rules and roles are stored
fWaitForPersistence = () =>
console.log 'fWaitForPer'
# db.deleteUser @oUser.username
db.getRoleUsers 'tester', (err, obj) ->
console.log 'getRoleUsers tester'
console.log err
console.log obj
# setTimeout fWaitForDeletion, 200
db.deleteUser oUsr.username
setTimeout fWaitForDeletion, 200
# # Wait until the user and his rules and roles are deleted
# fWaitForDeletion = () =>
# console.log 'fWaitForDel'
# db.getRoleUsers 'tester', ( err, obj ) =>
# # db.getUserRoles @oUser.username, ( err, obj ) =>
# console.log 'got users: '
# console.log obj
# test.ok @oUser.username not in obj,
# 'User key still in role tester!'
# Wait until the user and his rules and roles are deleted
fWaitForDeletion = () =>
db.getRoleUsers 'tester', ( err, obj ) =>
test.ok oUsr.username not in obj,
'User key still in role tester!'
# console.log '21'
# db.getUserRoles @oUser.username, ( err, obj ) =>
# test.ok obj.length is 0,
# 'User still associated to roles!'
db.getUserRoles oUsr.username, ( err, obj ) =>
test.ok obj.length is 0,
'User still associated to roles!'
# console.log '22'
# db.getUserLinkedRules @oUser.username, ( err, obj ) =>
# test.ok obj.length is 0,
# 'User still associated to rules!'
# console.log '23'
# db.getUserActivatedRules @oUser.username, ( err, obj ) =>
# test.ok obj.length is 0,
# 'User still associated to activated rules!'
# db.shutDown()
# test.done()
db.getUserLinkedRules oUsr.username, ( err, obj ) =>
test.ok obj.length is 0,
'User still associated to rules!'
db.getUserActivatedRules oUsr.username, ( err, obj ) =>
test.ok obj.length is 0,
'User still associated to activated rules!'
test.done()
# # Store the user and make some links
# db.storeUser @oUser
# db.linkRule 'rule-1', @oUser.username
# db.linkRule 'rule-2', @oUser.username
# db.linkRule 'rule-3', @oUser.username
# db.activateRule 'rule-1', @oUser.username
# db.storeUserRole @oUser.username, 'tester'
# Store the user and make some links
db.storeUser oUsr
db.linkRule 'rule-1', oUsr.username
db.linkRule 'rule-2', oUsr.username
db.linkRule 'rule-3', oUsr.username
db.activateRule 'rule-1', oUsr.username
db.storeUserRole oUsr.username, 'tester'
setTimeout fWaitForPersistence, 100
@ -719,21 +633,21 @@ exports.User =
testLogin: ( test ) =>
test.expect 3
db = getDBInstance()
oUsr = objects.users.userOne
# Store the user and make some links
db.storeUser @oUser
db.loginUser @oUser.username, @oUser.password, ( err, obj ) =>
test.deepEqual obj, @oUser,
db.storeUser oUsr
db.loginUser oUsr.username, oUsr.password, ( err, obj ) =>
test.deepEqual obj, oUsr,
'User not logged in!'
db.loginUser 'dummyname', @oUser.password, ( err, obj ) =>
db.loginUser 'dummyname', oUsr.password, ( err, obj ) =>
test.strictEqual obj, null,
'User logged in?!'
db.loginUser @oUser.username, 'wrongpass', ( err, obj ) =>
db.loginUser oUsr.username, 'wrongpass', ( err, obj ) =>
test.strictEqual obj, null,
'User logged in?!'
db.shutDown()
test.done()
@ -741,49 +655,42 @@ exports.User =
# Test ROLES
###
exports.Roles =
setUp: ( cb ) =>
@oUser =
username: "tester-1"
password: "password"
cb()
tearDown: ( cb ) =>
db = getDBInstance()
db.deleteUser @oUser.username
setTimeout db.shutDown, 500
db.deleteUser objects.users.userOne.username
cb()
testStore: ( test ) =>
test.expect 2
db = getDBInstance()
db.storeUser @oUser
db.storeUserRole @oUser.username, 'tester'
oUsr = objects.users.userOne
db.storeUser oUsr
db.storeUserRole oUsr.username, 'tester'
db.getUserRoles @oUser.username, ( err, obj ) =>
db.getUserRoles oUsr.username, ( err, obj ) =>
test.ok 'tester' in obj,
'User role tester not stored!'
db.getRoleUsers 'tester', ( err, obj ) =>
test.ok @oUser.username in obj,
"User #{ @oUser.username } not stored in role tester!"
db.shutDown()
test.ok oUsr.username in obj,
"User #{ oUsr.username } not stored in role tester!"
test.done()
testDelete: ( test ) =>
test.expect 2
db = getDBInstance()
db.storeUser @oUser
db.storeUserRole @oUser.username, 'tester'
db.removeUserRole @oUser.username, 'tester'
oUsr = objects.users.userOne
db.storeUser oUsr
db.storeUserRole oUsr.username, 'tester'
db.removeUserRole oUsr.username, 'tester'
db.getUserRoles @oUser.username, ( err, obj ) =>
db.getUserRoles oUsr.username, ( err, obj ) =>
test.ok 'tester' not in obj,
'User role tester not stored!'
db.getRoleUsers 'tester', ( err, obj ) =>
test.ok @oUser.username not in obj,
"User #{ @oUser.username } not stored in role tester!"
db.shutDown()
test.ok oUsr.username not in obj,
"User #{ oUsr.username } not stored in role tester!"
test.done()
# store an entry to start with

View file

@ -1,12 +1,26 @@
http = require 'http'
fs = require 'fs'
path = require 'path'
events = require 'events'
cp = require 'child_process'
qs = require 'querystring'
try
data = fs.readFileSync path.resolve( 'testing', 'files', 'testObjects.json' ), 'utf8'
try
objects = JSON.parse data
catch err
console.log 'Error parsing standard objects file: ' + err.message
catch err
console.log 'Error fetching standard objects file: ' + err.message
logger = require path.join '..', 'js-coffee', 'logging'
log = logger.getLogger
nolog: true
i = 0
opts =
logger: log
opts[ 'db-port' ] = 6379
db = require path.join '..', 'js-coffee', 'persistence'
db opts
createRequest = ( query, origUrl ) ->
req = new events.EventEmitter()
@ -18,18 +32,13 @@ createRequest = ( query, origUrl ) ->
createLoggedInRequest = ( query, origUrl ) ->
req = createRequest query, origUrl
req.session =
user:
username: 'unittester'
password: 'unittesterpw'
user: objects.users.userOne
req
createAdminRequest = ( query, origUrl ) ->
req = createRequest()
req.session =
user:
username: 'adminunittester'
password: 'adminunittesterpw'
isAdmin: true
user: objects.users.userAdmin
req
postRequestData = ( req, data ) ->
@ -48,34 +57,20 @@ createResponse = ( cb ) ->
cb code, msg
exports.setUp = ( cb ) =>
@db = require path.join '..', 'js-coffee', 'persistence'
args =
logger: log
args[ 'db-port' ] = 6379
@db args
@rh = require path.join '..', 'js-coffee', 'request-handler'
cb()
exports.tearDown = ( cb ) =>
@db.shutDown()
cb()
exports.session =
setUp: ( cb ) =>
@user =
username: 'unittester'
password: 'unittesterpw'
@db = require path.join '..', 'js-coffee', 'persistence'
args =
logger: log
args[ 'db-port' ] = 6379
@db args
@db.storeUser @user
@oUsr = objects.users.userOne
db.storeUser @oUsr
cb()
tearDown: ( cb ) =>
@db.deleteUser @user.username
@db.shutDown()
db.deleteUser @oUsr.username
cb()
testLoginAndOut: ( test ) =>
@ -94,13 +89,13 @@ exports.session =
# Check Login
test.strictEqual code, 200, 'Login failed'
test.deepEqual req.session.user, @user, 'Session user not what we expected'
test.deepEqual req.session.user, @oUsr, 'Session user not what we expected'
req = createLoggedInRequest()
resp = createResponse ( code, msg ) =>
# Check Login again
test.strictEqual code, 200, 'Login again did nothing different'
test.deepEqual req.session.user, @user, 'Session user not what we expected after relogin'
test.deepEqual req.session.user, @oUsr, 'Session user not what we expected after relogin'
req = createRequest()
resp = createResponse ( code, msg ) ->
@ -110,10 +105,10 @@ exports.session =
test.done()
@rh.handleLogout req, resp # set the handler to listening
@rh.handleLogin req, resp # set the handler to listening
postRequestData req, qs.stringify @user # emit the data post event
postRequestData req, qs.stringify @oUsr # emit the data post event
@rh.handleLogin req, resp # set the handler to listening
postRequestData req, qs.stringify @user # emit the data post event
postRequestData req, qs.stringify @oUsr # emit the data post event
testWrongLogin: ( test ) =>
@ -133,19 +128,19 @@ exports.session =
test.done()
usr =
username: @user.username
username: @oUsr.username
password: 'wrongpassword'
@rh.handleLogin req, resp # set the handler to listening
postRequestData req, qs.stringify usr # emit the data post event
exports.events =
setUp: ( cb ) =>
@db.purgeEventQueue()
db.purgeEventQueue()
cb()
testCorrectEvent: ( test ) =>
test.expect 2
args =
logger: log
args[ 'request-service' ] = ( usr, obj, cb ) ->
@ -165,7 +160,7 @@ exports.events =
test.deepEqual obj, oEvt, 'Caught event is not what we expected'
if --semaphore is 0
test.done()
@db.popEvent fCb
db.popEvent fCb
req = createLoggedInRequest()
resp = createResponse ( code, msg ) ->
@ -197,7 +192,7 @@ exports.events =
test.deepEqual obj, null, 'We caught an event!?'
if --semaphore is 0
test.done()
@db.popEvent fCb
db.popEvent fCb
req = createLoggedInRequest()
resp = createResponse ( code, msg ) ->

View file

@ -7,10 +7,10 @@ var args = process.argv.slice( 2 );
if( args[ 0 ] !== undefined ) {
var fl = path.resolve( args[ 0 ] );
if ( fs.existsSync( fl ) ) {
nodeunit.reporters.default.run( [ fl ] );
nodeunit.reporters.default.run( [ fl, 'testing/end-unittest' ] );
} else {
console.error( 'File not found!!' );
}
} else {
nodeunit.reporters.default.run( [ 'testing' ] );
nodeunit.reporters.default.run( [ 'testing', 'testing/end-unittest' ] );
}