Skip to content

Commit

Permalink
Merge pull request #164 from godsflaw/godsflaw
Browse files Browse the repository at this point in the history
New unit testing with nodeunit and a log.syslog change
  • Loading branch information
baudehlo committed Feb 22, 2012
2 parents ddeb187 + 319e47e commit facca75
Show file tree
Hide file tree
Showing 13 changed files with 370 additions and 13 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules
!node_modules/nodeunit
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "node_modules/nodeunit"]
path = node_modules/nodeunit
url = git://github.com/godsflaw/nodeunit.git
1 change: 1 addition & 0 deletions config/log.syslog.ini
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ odelay=1
cons=0
ndelay=0
nowait=0
always_ok=false
8 changes: 8 additions & 0 deletions docs/plugins/log.syslog.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,11 @@ chosen for you.

Don't wait for child processes that may have been created while
logging the message.


* log.syslog.general.always_ok (default: false)

If false, then this plugin will return with just next() allowing other
plugins that have registered for the log hook to run. To speed things up,
if no other log hooks need to run (daemon), then one can make this true.
This will case the plugin to always call next(OK).
1 change: 1 addition & 0 deletions node_modules/nodeunit
Submodule nodeunit added at bdb457
37 changes: 24 additions & 13 deletions plugins/log.syslog.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
// send logs to syslog
var Syslog = require('node-syslog');
var Syslog = exports.Syslog = require('node-syslog');

exports.register = function() {
var options = 0;
var ini = this.config.get('log.syslog.ini');
var name = ini.general && (ini.general['name'] || 'haraka');
var facility = ini.general && (ini.general['facility'] || 'MAIL');
var pid = ini.general && (ini.general['log_pid'] || 1);
var odelay = ini.general && (ini.general['log_odelay'] || 1);
var cons = ini.general && (ini.general['log_cons'] || 0);
var ndelay = ini.general && (ini.general['log_ndelay'] || 0);
var nowait = ini.general && (ini.general['log_nowait'] || 0);
var options = 0;
var ini = this.config.get('log.syslog.ini');
ini.general = ini.general || {};
var name = ini.general['name'] || 'haraka';
var facility = ini.general['facility'] || 'MAIL';
var pid = ini.general['log_pid'] || 1;
var odelay = ini.general['log_odelay'] || 1;
var cons = ini.general['log_cons'] || 0;
var ndelay = ini.general['log_ndelay'] || 0;
var nowait = ini.general['log_nowait'] || 0;
var always_ok = ini.general['always_ok'] || false;

this.always_ok = always_ok;

if (pid)
options |= Syslog.LOG_PID;
Expand Down Expand Up @@ -84,9 +88,11 @@ exports.register = function() {
}

this.register_hook('log', 'syslog');
}
};

exports.syslog = function (next, logger, log) {
var plugin = this;

switch(log.level.toUpperCase()) {
case 'INFO':
Syslog.log(Syslog.LOG_INFO, log.data);
Expand Down Expand Up @@ -116,5 +122,10 @@ exports.syslog = function (next, logger, log) {
Syslog.log(Syslog.LOG_DEBUG, log.data);
}

return next();
}
if (plugin.always_ok) {
return next(OK);
}
else {
return next();
}
};
21 changes: 21 additions & 0 deletions run_tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env node

require.paths.unshift(__dirname);

try {
var reporter = require('nodeunit').reporters.default;
}
catch(e) {
console.log("Error: " + e.message);
console.log("");
console.log("Cannot find nodeunit module.");
console.log("You can download submodules for this project by doing:");
console.log("");
console.log(" git submodule init");
console.log(" git submodule update");
console.log("");
process.exit();
}

process.chdir(__dirname);
reporter.run(['tests/plugins']);
12 changes: 12 additions & 0 deletions tests/fixtures/stub.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = function (returnValue) {
function stub() {
stub.called = true;
stub.args = arguments;
stub.thisArg = this;
return returnValue;
}

stub.called = false;

return stub;
};
24 changes: 24 additions & 0 deletions tests/fixtures/stub_connection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"use strict";

var stub = require('tests/fixtures/stub');

var connection = exports;

function Connection(client, server) {
this.client = client;
this.server = server;
this.relaying = false;
}

connection.createConnection = function(client, server) {
if (typeof(client) === 'undefined') {
client = {};
}

if (typeof(server) === 'undefined') {
server = {};
}

var obj = new Connection(client, server);
return obj;
};
13 changes: 13 additions & 0 deletions tests/fixtures/stub_logger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"use strict";

var stub = require('tests/fixtures/stub');

var logger = exports;

function Logger() {
}

logger.createLogger = function() {
var obj = new Logger();
return obj;
};
21 changes: 21 additions & 0 deletions tests/fixtures/stub_plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"use strict";

var stub = require('tests/fixtures/stub');

var plugin = exports;

function Plugin(name) {
}

plugin.createPlugin = function(name) {
var obj = new Plugin(name);
var plug = require(name);

for (var k in plug) {
if (plug.hasOwnProperty(k)) {
obj[k] = plug[k];
}
}

return obj;
};
159 changes: 159 additions & 0 deletions tests/plugins/log.syslog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
var stub = require('tests/fixtures/stub'),
constants = require('../../constants'),
Logger = require('tests/fixtures/stub_logger'),
Plugin = require('tests/fixtures/stub_plugin');

// huge hack here, but plugin tests need constants
constants.import(global);

function _set_up(callback) {
this.backup = {};

// needed for tests
this.plugin = Plugin.createPlugin('plugins/log.syslog');
this.logger = Logger.createLogger();

// backup modifications
this.backup.plugin = {};
this.backup.plugin.Syslog = {};
this.backup.plugin.register_hook = this.plugin.register_hook;

// stub out functions
this.plugin.register_hook = stub();
this.plugin.config = stub();
this.log = stub();
this.log.level = 'info';
this.log.data = "this is a test log message";

// some test data
this.configfile = {
general : {
name : 'haraka',
facility : 'MAIL',
log_pid : 1,
log_odelay : 1,
log_cons : 0,
log_ndelay : 0,
log_nowait : 0,
always_ok : false
}
};
this.plugin.config.get = function (file) {
return this.configfile;
}.bind(this);

// going to need these in multiple tests
this.plugin.register();

callback();
}

function _tear_down(callback) {
// restore backed up functions
this.plugin.register_hook = this.backup.plugin.register_hook;

callback();
}

exports.log_syslog = {
setUp : _set_up,
tearDown : _tear_down,
'should have register function' : function (test) {
test.expect(2);
test.isNotNull(this.plugin);
test.isFunction(this.plugin.register);
test.done();
},
'register function should call register_hook()' : function (test) {
test.expect(1);
test.ok(this.plugin.register_hook.called);
test.done();
},
'register_hook() should register for propper hook' : function (test) {
test.expect(1);
test.equals(this.plugin.register_hook.args[0], 'log');
test.done();
},
'register_hook() should register available function' : function (test) {
test.expect(3);
test.equals(this.plugin.register_hook.args[1], 'syslog');
test.isNotNull(this.plugin.syslog);
test.isFunction(this.plugin.syslog);
test.done();
},
'register calls Syslog.init()' : function (test) {
// local setup
this.backup.plugin.Syslog.init = this.plugin.Syslog.init;
this.plugin.Syslog.init = stub();
this.plugin.register();

test.expect(1);
test.ok(this.plugin.Syslog.init.called);
test.done();

// local teardown
this.plugin.Syslog.init = this.backup.plugin.Syslog.init;
},
'register calls Syslog.init() with correct args' : function (test) {
// local setup
this.backup.plugin.Syslog.init = this.plugin.Syslog.init;
this.plugin.Syslog.init = stub();
this.plugin.register();

test.expect(4);
test.ok(this.plugin.Syslog.init.called);
test.equals(this.plugin.Syslog.init.args[0],
this.plugin.config.get("test").general.name);
test.equals(this.plugin.Syslog.init.args[1],
this.plugin.Syslog.LOG_PID | this.plugin.Syslog.LOG_ODELAY);
test.equals(this.plugin.Syslog.init.args[2],
this.plugin.Syslog.LOG_MAIL);
test.done();

// local teardown
this.plugin.Syslog.init = this.backup.plugin.Syslog.init;
},
'hook returns just next() if configured to do so' : function (test) {
var next = function (action) {
test.expect(1);
test.isUndefined(action);
test.done();
};

this.plugin.syslog(next, this.logger, this.log);
},
'hook returns next(OK) if configured to do so' : function (test) {
// local setup
this.backup.configfile = this.configfile;
this.configfile.general.always_ok = true;
this.plugin.register();

var next = function (action) {
test.expect(1);
test.equals(action, constants.ok);
test.done();
};

this.plugin.syslog(next, this.logger, this.log);

// local teardown
this.configfile = this.backup.configfile;
},
'syslog hook logs correct thing' : function (test) {
// local setup
var next = stub();
this.backup.plugin.Syslog.log = this.plugin.Syslog.log;
this.plugin.Syslog.log = stub();
this.plugin.syslog(next, this.logger, this.log);

test.expect(3);
test.ok(this.plugin.Syslog.log.called);
test.equals(this.plugin.Syslog.log.args[0],
this.plugin.Syslog.LOG_INFO);
test.equals(this.plugin.Syslog.log.args[1], this.log.data);
test.done();

// local teardown
this.plugin.Syslog.log = this.backup.plugin.Syslog.log;
}
};
Loading

0 comments on commit facca75

Please sign in to comment.