Skip to content

Commit

Permalink
added daemon tests (first hacky version)
Browse files Browse the repository at this point in the history
  • Loading branch information
spion committed Jul 1, 2013
1 parent 34800ad commit e91d661
Show file tree
Hide file tree
Showing 17 changed files with 388 additions and 92 deletions.
4 changes: 2 additions & 2 deletions lib/client-parsers.js
Expand Up @@ -6,8 +6,8 @@ exports.logs = function (apps, done) {
lines.reverse().forEach(function (l) {
var dateString = new Date(l.timestamp).toISOString()
.replace('T', ' ').replace('Z', '');
var l = [dateString, l.tag, l.text].join('\t');
console.log(l);
var larr = [dateString, l.tag, l.text].join('\t');
console.log(larr);
});
});
done();
Expand Down
43 changes: 33 additions & 10 deletions lib/daemon/app.js
Expand Up @@ -155,7 +155,8 @@ App.prototype._runProcess = function (done) {
return setTimeout(function () {
this.active = false;
this.started = null;
return done && done(new Error('unable to read configuration parameter "command"'));
return done && done(
new Error('unable to read configuration parameter "command"'));
}.bind(this))

var proc = this.process = spawn(
Expand All @@ -165,36 +166,51 @@ App.prototype._runProcess = function (done) {
uid: this.uid,
gid: this.uid
});
proc.on('error', this._onExit.bind(this));
proc.on('error', function(err) {
if (answerOk) {
clearTimeout(answerOk);
answerOk = null;
if (done) done(err);
}
this._onExit(err)
}.bind(this));
proc.on('exit', this._onExit.bind(this));
proc.stdout.pipe(this.logger.stream('stdout'));
proc.stderr.pipe(this.logger.stream('stderr'));


var self = this;

done && done(null);
// Hack: the node.js api docs don't say when
// the error event is expected, if the spawn fails so we use a
// "reasonable" timeout of 100ms here
if (done) var answerOk = setTimeout(function() {
answerOk = null;
done(null);
}, 100);
return proc;
}
;

App.prototype.start = function (cb) {
var self = this;
if (this.started)
if (this.started || this.active)
return cb(new Error("app " + this.name + " already started"));
this.active = true;
this.started = Date.now();
this.emit('before-start');

this.save(function (err) {
if (err) {
this.logger.log('start', "application failed to save: " + err.message);
this.logger.log('start', "application failed to save: "
+ err.message);
return cb(err);
}
this._runProcess(function (err) {
if (err) {
this.logger.log('start', "application failed to start: " + err.message);
cb(null, this);
this.logger.log('start', "application failed to start: "
+ err.message);
cb(err, this);
} else {
this.logger.log('start', "application started");
this.emit('start');
Expand Down Expand Up @@ -235,7 +251,8 @@ App.prototype._onExit = function (code, signal) {
code: code
});

setTimeout(this._runProcess.bind(this), realTimeout);

this._respawner = setTimeout(this._runProcess.bind(this), realTimeout);


if (!restarting) {
Expand All @@ -246,7 +263,8 @@ App.prototype._onExit = function (code, signal) {

} else {

this.logger.log('exit', 'process died with code ' + code + ' after receiving ' + signal);
this.logger.log('exit', 'process died with code ' + code
+ ' after receiving ' + signal);
this.emit('exit', {code: code, signal: signal});

}
Expand Down Expand Up @@ -275,6 +293,10 @@ App.prototype.stop = function stop(cb) {
this.logger.log('stop', 'receied stop command');

this.active = false;
if (this._respawner) {
clearTimeout(this._respawner);
this._respawner = null;
}
this.save(function (err) {
if (err) return cb(err);
if (this.process)
Expand Down Expand Up @@ -341,7 +363,8 @@ App.prototype.run = function run(script) {
}.bind(this));

scriptp.on('exit', function (code) {
setImmediate(this.logger.log.bind(this.logger, "script", "--- exited " + script + ' ' + args.join(' ')
setImmediate(this.logger.log.bind(this.logger, "script",
"--- exited " + script + ' ' + args.join(' ')
+ "with error code " + code));
}.bind(this));

Expand Down
2 changes: 1 addition & 1 deletion lib/daemon/logger.js
Expand Up @@ -6,7 +6,7 @@ var logstore = require('./logstore');

var _ = require('lodash');

module.exports = logs = {};
var logs = module.exports = {};

logs.construct = function construct(appId) {
return new Logger(appId);
Expand Down
5 changes: 4 additions & 1 deletion lib/daemon/logstore.js
Expand Up @@ -2,6 +2,9 @@ var db = require('../db'),
async = require('async'),
duration = require('../duration');


var flushTimeout = process.env.NACD_LOGFLUSH || 333;

var logs = db.define({
name: 'logs',
columns: [
Expand All @@ -20,7 +23,7 @@ var flusher, queue = [];
exports.write = function write(item) {
queue.push(item);
if (!flusher)
flusher = setTimeout(flush, 333);
flusher = setTimeout(flush, flushTimeout);
};


Expand Down
5 changes: 3 additions & 2 deletions lib/db/index.js
Expand Up @@ -2,8 +2,9 @@ var anydbSQL = require('anydb-sql');
var userstore = require('./userstore');
var path = require('path');

var dbpath = process.env.NACD_DATABASE
|| path.join(userstore('nac'), 'nacd.db');
var dbpath = process.env.NACD_DATABASE == null
? path.join(userstore('nac'), 'nacd.db')
: process.env.NACD_DATABASE;

module.exports = anydbSQL({
url: "sqlite3://" + dbpath,
Expand Down
2 changes: 1 addition & 1 deletion lib/duration.js
Expand Up @@ -22,7 +22,7 @@ var multipliers = {

exports.parse = function(str) {
var dur = 0, segment;
while (segment = parseFloat(str)) {
while ((segment = parseFloat(str))) {
str = str.replace(segment, '');
var unit = str[0];
dur += multipliers[unit] * segment;
Expand Down
33 changes: 18 additions & 15 deletions test/appconf-override.js
@@ -1,19 +1,22 @@
var acoverride = require('../lib/appconf-override');
var t = require('tap');


t.test('appconf-override', function(t) {
var overriden = acoverride(['first', 'second'], {
item: 1,
servers: {
first: {
item:2
},
second: {
item:3
module.exports = function(t) {
t.test('appconf-override', function(t){
var overriden = acoverride(['first', 'second'], {
item: 1,
servers: {
first: {
item:2
},
second: {
item:3
}
}
}
});
t.equals(overriden.item, 2, 'highest priority tag chosen');
t.end();
});
t.equals(overriden.item, 2, 'highest priority tag chosen');
t.end();
});
};

if (!process.env.COVER)
module.exports(require('tap'));
18 changes: 18 additions & 0 deletions test/cover/index.js
@@ -0,0 +1,18 @@
var fs = require('fs');
var path = require('path');
var tap = require('tap');

process.env.COVER = true;

fs.readdirSync(path.join(__dirname, '..'))
.filter(function(f) { return f.indexOf('.js') > 0; })
.forEach(function (f) {
var test = require('../' + f);
test(tap);
tap.test(function(t) {
t.ok(true, 'All tests run');
setTimeout(process.exit, 1000)
t.end();

})
});
35 changes: 20 additions & 15 deletions test/duration.js
Expand Up @@ -4,20 +4,25 @@ var duration = require('../lib/duration');

var ms = 12 * 24 * 60 * 60 * 1000 + 12 * 60 * 60 * 1000 + 14 * 60 * 1000;

t.test('duration.stringify', function (t) {
t.equals(duration.stringify(ms), '12d 12h 14m');
t.end();
});

t.test('duration.parse', function (t) {
t.equals(duration.parse('12d12h14m'), ms);
t.end();
});

t.test('stringify(parse(str)) == str', function (t) {
t.equals(duration.stringify(duration.parse('12d12h14m')), '12d 12h 14m');
t.end();
})

module.exports = function(t) {
t.test('duration.stringify', function (t) {
t.equals(duration.stringify(ms), '12d 12h 14m');
t.end();
});

t.test('duration.parse', function (t) {
t.equals(duration.parse('12d12h14m'), ms);
t.end();
});

t.test('stringify(parse(str)) == str', function (t) {
t.equals(duration.stringify(duration.parse('12d12h14m')),
'12d 12h 14m');
t.end();
});
};

if (!process.env.COVER)
module.exports(require('tap'));


3 changes: 3 additions & 0 deletions test/harness/config-err.yaml
@@ -0,0 +1,3 @@
command: './process.js'
args:
die: 1
1 change: 1 addition & 0 deletions test/harness/config.yaml
@@ -0,0 +1 @@
command: './process.js'
23 changes: 23 additions & 0 deletions test/harness/process.js
@@ -0,0 +1,23 @@
#!/usr/bin/env node

var args = require('optimist').argv;


console.log(process.env.ENV_TEST || "Hello world");


// Stay in the background
setInterval(function () {

}, 10000);


if (args.die) setTimeout(function () {
console.error("Had fatal error!");
process.exit(args.code || 0);
}, args.die || 1);


process.on('SIGUSR2', function() {
console.log("SIGUSR2");
});
22 changes: 22 additions & 0 deletions test/harness/testlib.js
@@ -0,0 +1,22 @@
var mkdirp = require('mkdirp');
var path = require('path');

process.env.NACD_DATABASE = '';
process.env.NACD_CONFIG = path.join(__dirname, 'harness', 'nacd.conf');
process.env.NACD_LOGFLUSH = 1;

var Daemon = require('../../lib/daemon/daemon');

exports.daemon = function create(cb) {
Daemon.create(function (err, daemon) {
if (err)
return cb(err);
cb(null, function createClient() {
return Daemon.interface(process.getuid(), daemon);
});
});

};

exports.config = path.join(__dirname, 'config.yaml');
exports.configErr = path.join(__dirname, 'config-err.yaml');
23 changes: 0 additions & 23 deletions test/nac.js

This file was deleted.

0 comments on commit e91d661

Please sign in to comment.