Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New unit testing with nodeunit and a log.syslog change #164

Merged
merged 10 commits into from
Feb 22, 2012
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
36 changes: 23 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');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't you just add in:

ini.general ||= {};

ini.general = ini.general || {};
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This passes tests and is more clear.

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,9 @@ exports.syslog = function (next, logger, log) {
Syslog.log(Syslog.LOG_DEBUG, log.data);
}

return next();
}
if (plugin.always_ok) {
return next(OK);
} else {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uncuddle please :)

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;
};
158 changes: 158 additions & 0 deletions tests/plugins/log.syslog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
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