diff --git a/lib/forever/monitor.js b/lib/forever/monitor.js deleted file mode 100644 index 229f7788..00000000 --- a/lib/forever/monitor.js +++ /dev/null @@ -1,389 +0,0 @@ -/* - * monitor.js: Core functionality for the Monitor object. - * - * (C) 2010 Nodejitsu Inc. - * MIT LICENCE - * - */ - -var events = require('events'), - fs = require('fs'), - path = require('path'), - child_process = require('child_process'), - fork = child_process.fork, - spawn = child_process.spawn, - broadway = require('broadway'), - psTree = require('ps-tree'), - winston = require('winston'), - utile = require('utile'), - forever = require('../forever'); - -// -// ### function Monitor (script, options) -// #### @script {string} Location of the target script to run. -// #### @options {Object} Configuration for this instance. -// Creates a new instance of forever with specified `options`. -// -var Monitor = exports.Monitor = function (script, options) { - // - // Simple bootstrapper for attaching logger - // and watch plugins by default. Other plugins - // can be attached through `monitor.use(plugin, options)`. - // - function bootstrap(monitor) { - forever.plugins.logger.attach.call(monitor, options); - if (options.watch) { - forever.plugins.watch.attach.call(monitor, options); - } - } - - var self = this; - - // - // Setup basic configuration options - // - options = options || {}; - this.silent = options.silent || false; - this.killTree = options.killTree !== false; - this.uid = options.uid || utile.randomString(4); - this.pidFile = options.pidFile || path.join(forever.config.get('pidPath'), this.uid + '.pid'); - this.max = options.max; - this.killTTL = options.killTTL; - this.childExists = false; - this.checkFile = options.checkFile !== false; - this.times = 0; - this.warn = console.error; - - this.logFile = options.logFile || path.join(forever.config.get('root'), this.uid + '.log'); - this.outFile = options.outFile; - this.errFile = options.errFile; - this.append = options.append; - - // - // Setup restart timing. These options control how quickly forever restarts - // a child process as well as when to kill a "spinning" process - // - this.minUptime = typeof options.minUptime !== 'number' ? 0 : options.minUptime; - this.spinSleepTime = options.spinSleepTime || null; - - // - // Setup the command to spawn and the options to pass - // to that command. - // - this.command = options.command || process.execPath; - this.args = options.options || []; - this.spawnWith = options.spawnWith || {}; - this.sourceDir = options.sourceDir; - this.fork = options.fork || false; - this.cwd = options.cwd || null; - this.hideEnv = options.hideEnv || []; - this._env = options.env || {}; - this._hideEnv = {}; - - // - // Setup watch configuration options - // - this.watchIgnoreDotFiles = options.watchIgnoreDotFiles || true; - this.watchIgnorePatterns = options.watchIgnorePatterns || []; - this.watchDirectory = options.watchDirectory || this.sourceDir; - - // - // Create a simple mapping of `this.hideEnv` to an easily indexable - // object - // - this.hideEnv.forEach(function (key) { - self._hideEnv[key] = true; - }); - - if (Array.isArray(script)) { - this.command = script[0]; - this.args = script.slice(1); - } - else { - this.args.unshift(script); - } - - if (this.sourceDir) { - this.args[0] = path.join(this.sourceDir, this.args[0]); - } - - // - // Bootstrap this instance now that options - // have been set - // - broadway.App.call(this, { bootstrapper: { bootstrap: bootstrap } }); -}; - -// Inherit from events.EventEmitter -utile.inherits(Monitor, broadway.App); - -// -// ### function start ([restart]) -// #### @restart {boolean} Value indicating whether this is a restart. -// Start the process that this instance is configured for -// -Monitor.prototype.start = function (restart) { - var self = this, - child; - - if (this.running && !restart) { - process.nextTick(function () { - self.emit('error', new Error('Cannot start process that is already running.')); - }); - return this; - } - - child = this.trySpawn(); - if (!child) { - process.nextTick(function () { - self.emit('error', new Error('Target script does not exist: ' + self.args[0])); - }); - return this; - } - - this.ctime = Date.now(); - this.child = child; - this.running = true; - process.nextTick(function () { - self.emit(restart ? 'restart' : 'start', self, self.data); - }); - - function onMessage(msg) { - self.emit('message', msg); - } - - // Re-emit messages from the child process - this.child.on('message', onMessage); - - child.on('exit', function (code) { - var spinning = Date.now() - self.ctime < self.minUptime; - self.warn('Forever detected script exited with code: ' + code); - child.removeListener('message', onMessage); - - function letChildDie() { - self.running = false; - self.forceStop = false; - - self.emit('exit', self, spinning); - } - - function restartChild() { - self.forceRestart = false; - process.nextTick(function () { - self.warn('Forever restarting script for ' + self.times + ' time'); - self.start(true); - }); - } - - self.times++; - - if (self.forceStop || (self.times >= self.max) - || (spinning && typeof self.spinSleepTime !== 'number') && !self.forceRestart) { - letChildDie(); - } - else if (spinning) { - setTimeout(restartChild, self.spinSleepTime); - } - else { - restartChild(); - } - }); - - return this; -}; - -// -// ### function trySpawn() -// Tries to spawn the target Forever child process. Depending on -// configuration, it checks the first argument of the options -// to see if the file exists. This is useful is you are -// trying to execute a script with an env: e.g. node myfile.js -// -Monitor.prototype.trySpawn = function () { - if (this.command === 'node' && this.checkFile && !this.childExists) { - try { - var stats = fs.statSync(this.args[0]); - this.childExists = true; - } - catch (ex) { - return false; - } - } - - this.spawnWith.cwd = this.cwd || this.spawnWith.cwd; - this.spawnWith.env = this._getEnv(); - - if (this.fork) { - this.spawnWith.stdio = [ 'pipe', 'pipe', 'pipe', 'ipc' ]; - return spawn(this.command, this.args, this.spawnWith); - } - - return spawn(this.command, this.args, this.spawnWith); -}; - -// -// ### @data {Object} -// Responds with the appropriate information about -// this `Monitor` instance and it's associated child process. -// -Monitor.prototype.__defineGetter__('data', function () { - var self = this, - childData; - - if (!this.running) { - // - // TODO: Return settings from this forever instance - // with a state indicator that it is currently stopped. - // - return {}; - } - - childData = { - ctime: this.ctime, - command: this.command, - file: this.args[0], - foreverPid: process.pid, - logFile: this.logFile, - options: this.args.slice(1), - pid: this.child.pid, - silent: this.silent, - uid: this.uid, - spawnWith: this.spawnWith - }; - - ['pidFile', 'outFile', 'errFile', 'env', 'cwd'].forEach(function (key) { - if (self[key]) { - childData[key] = self[key]; - } - }); - - if (this.sourceDir) { - childData.sourceDir = this.sourceDir; - childData.file = childData.file.replace(this.sourceDir + '/', ''); - } - - this.childData = childData; - return this.childData; - - // - // Setup the forever process to listen to - // SIGINT and SIGTERM events so that we can - // clean up the *.pid file - // - // Remark: This should work, but the fd gets screwed up - // with the daemon process. - // - // process.on('SIGINT', function () { - // process.exit(0); - // }); - // - // process.on('SIGTERM', function () { - // process.exit(0); - // }); - // process.on('exit', function () { - // fs.unlinkSync(childPath); - // }); -}); - -// -// ### function restart () -// Restarts the target script associated with this instance. -// -Monitor.prototype.restart = function () { - this.forceRestart = true; - return this.kill(false); -}; - -// -// ### function stop () -// Stops the target script associated with this instance. Prevents it from auto-respawning -// -Monitor.prototype.stop = function () { - return this.kill(true); -}; - -// -// ### function kill (forceStop) -// #### @forceStop {boolean} Value indicating whether short circuit forever auto-restart. -// Kills the ChildProcess object associated with this instance. -// -Monitor.prototype.kill = function (forceStop) { - var self = this, - child = this.child; - - if (!child || !this.running) { - process.nextTick(function () { - self.emit('error', new Error('Cannot stop process that is not running.')); - }); - } - else { - // - // Set an instance variable here to indicate this - // stoppage is forced so that when `child.on('exit', ..)` - // fires in `Monitor.prototype.start` we can short circuit - // and prevent auto-restart - // - var toKill = [this.child.pid]; - if (forceStop) { - this.forceStop = true; - // - // If we have a time before we truly kill forcefully, set up a timer - // - if (this.killTTL) { - var timer = setTimeout(function () { - toKill.forEach(function (pid) { - try { - process.kill(pid, 'SIGKILL'); - } - catch (e) { - //conditions for races may exist, this is most likely an ESRCH - //these should be ignored, and then we should emit that it is dead - } - }); - - self.emit('stop', this.childData); - }, this.killTTL); - - child.on('exit', function () { - clearTimeout(timer); - }); - } - } - - forever.kill(this.child.pid, this.killTree, function () { - self.emit('stop', self.childData); - }); - } - - return this; -}; - -// -// ### @private function _getEnv () -// Returns the environment variables that should be passed along -// to the target process spawned by this instance. -// -Monitor.prototype._getEnv = function () { - var self = this, - merged = {}; - - function addKey(key, source) { - merged[key] = source[key]; - } - - // - // Mixin the key:value pairs from `process.env` and the custom - // environment variables in `this._env`. - // - Object.keys(process.env).forEach(function (key) { - if (!self._hideEnv[key]) { - addKey(key, process.env); - } - }); - - Object.keys(this._env).forEach(function (key) { - addKey(key, self._env); - }); - - return merged; -}; diff --git a/lib/forever/plugins/logger.js b/lib/forever/plugins/logger.js deleted file mode 100644 index adf693b2..00000000 --- a/lib/forever/plugins/logger.js +++ /dev/null @@ -1,63 +0,0 @@ - -var fs = require('fs'); - -exports.name = 'logger'; - -exports.attach = function (options) { - options = options || {}; - var monitor = this; - - - if (options.outFile) { - monitor.stdout = options.stdout || fs.createWriteStream(options.outFile, { - flags: monitor.append ? 'a+' : 'w+', - encoding: 'utf8', - mode: 0644 - }); - } - - if (options.errFile) { - monitor.stderr = options.stderr || fs.createWriteStream(options.errFile, { - flags: monitor.append ? 'a+' : 'w+', - encoding: 'utf8', - mode: 0644 - }); - } - - monitor.on('start', startLogs); - - monitor.on('restart', startLogs); - - monitor.on('exit', function () { - if (monitor.stdout) { - monitor.stdout.destroySoon(); - } - if (monitor.stderr) { - monitor.stderr.destroySoon(); - } - }); - - function startLogs(child, childData) { - if (monitor.child) { - monitor.child.stdout.on('data', function onStdout(data) { - monitor.emit('stdout', data); - }); - monitor.child.stderr.on('data', function onStderr(data) { - monitor.emit('stderr', data); - }); - if (!monitor.silent) { - monitor.child.stdout.pipe(process.stdout, { end: false }); - monitor.child.stderr.pipe(process.stderr, { end: false }); - } - if (monitor.stdout) { - monitor.child.stdout.pipe(monitor.stdout, { end: false }); - } - if (monitor.stderr) { - monitor.child.stderr.pipe(monitor.stderr, { end: false }); - } - } - } - -}; - - diff --git a/lib/forever/plugins/watch.js b/lib/forever/plugins/watch.js deleted file mode 100644 index 0d0aea6e..00000000 --- a/lib/forever/plugins/watch.js +++ /dev/null @@ -1,58 +0,0 @@ - -var fs = require('fs'), - path = require('path'), - minimatch = require('minimatch'), - watch = require('watch'), - forever = require('../../forever'); - -exports.name = 'watch'; - -// -// ### @private function _watchFilter -// #### @file {string} File name -// Determines whether we should restart if `file` change (@mikeal's filtering -// is pretty messed up). -// -function watchFilter(fileName) { - if (this.watchIgnoreDotFiles && path.basename(fileName)[0] === '.') { - return false; - } - - fileName = path.relative(this.watchDirectory, fileName); - - for (var key in this.watchIgnorePatterns) { - if (minimatch(fileName, this.watchIgnorePatterns[key], { matchBase: true })) { - return false; - } - } - - return true; -}; - -exports.attach = function () { - var monitor = this; - - fs.readFile(path.join(this.watchDirectory, '.foreverignore'), 'utf8', function (err, data) { - if (err) { - forever.log.warn('Could not read .foreverignore file.'); - return forever.log.silly(err.message); - } - - Array.prototype.push.apply(monitor.watchIgnorePatterns, data.split('\n')); - }); - - watch.watchTree(this.watchDirectory, function (f, curr, prev) { - if (!(curr === null && prev === null && typeof f === 'object')) { - // - // `curr` == null && `prev` == null && typeof f == "object" when watch - // finishes walking the tree to add listeners. We don't need to know - // about it, so we simply ignore it (anything different means that - // some file changed/was removed/created - that's what we want to know). - // - if (watchFilter.call(monitor, f)) { - forever.log.info('restaring script because ' + f + ' changed'); - monitor.restart(); - } - } - }); -}; diff --git a/package.json b/package.json index 57e46332..5525948d 100644 --- a/package.json +++ b/package.json @@ -22,23 +22,23 @@ "dependencies": { "broadway": "0.1.x", "cliff": "0.x.x", - "flatiron": "0.1.x", + "flatiron": "0.2.x", + "forever-monitor": "x.x.x", "minimatch": "0.2.x", "nconf": "0.5.x", "nssocket": "0.3.x", "optimist": "0.3.x", "pkginfo": "0.x.x", - "portfinder": "0.x.x", "ps-tree": "0.0.x", "timespan": "2.0.x", "watch": "0.5.x", - "utile": "0.0.x", - "winston": "0.5.x" + "utile": "0.1.x", + "winston": "0.6.x" }, "devDependencies": { "eventemitter2": "0.4.x", "request": "2.x.x", - "vows": "0.5.x" + "vows": "0.6.x" }, "bin": { "forever": "./bin/forever", diff --git a/test/monitor/env-spawn-test.js b/test/monitor/env-spawn-test.js deleted file mode 100644 index 37b5a490..00000000 --- a/test/monitor/env-spawn-test.js +++ /dev/null @@ -1,104 +0,0 @@ -/* - * env-spawn-test.js: Tests for supporting environment variables in the forever module - * - * (C) 2010 Nodejitsu Inc. - * MIT LICENCE - * - */ - -var assert = require('assert'), - path = require('path'), - vows = require('vows'), - forever = require('../../lib/forever'); - -vows.describe('forever/monitor/spawn-options').addBatch({ - "When using forever": { - "an instance of forever.Monitor with valid options": { - "passing environment variables to env-vars.js": { - topic: function () { - var that = this, child; - - this.env = { - FOO: 'foo', - BAR: 'bar' - }; - - child = new (forever.Monitor)(path.join(__dirname, '..', '..', 'examples', 'env-vars.js'), { - max: 1, - silent: true, - minUptime: 0, - env: this.env - }); - - child.on('stdout', function (data) { - that.stdout = data.toString(); - }); - - child.on('exit', this.callback.bind({}, null)); - child.start(); - }, - "should pass the environment variables to the child": function (err, child) { - assert.equal(child.times, 1); - assert.equal(this.stdout, JSON.stringify(this.env)); - } - }, - "passing a custom cwd to custom-cwd.js": { - topic: function () { - var that = this, child; - - this.cwd = path.join(__dirname, '..'); - - child = new (forever.Monitor)(path.join(__dirname, '..', '..', 'examples', 'custom-cwd.js'), { - max: 1, - silent: true, - minUptime: 0, - cwd: this.cwd - }); - - child.on('stdout', function (data) { - that.stdout = data.toString(); - }); - - child.on('exit', this.callback.bind({}, null)); - child.start(); - }, - "should setup the child to run in the target directory": function (err, child) { - assert.equal(child.times, 1); - assert.equal(this.stdout, this.cwd); - } - }, - "setting `hideEnv` when spawning all-env-vars.js": { - topic: function () { - var that = this, child; - - this.hideEnv = [ - 'USER', - 'OLDPWD' - ]; - - child = new (forever.Monitor)(path.join(__dirname, '..', '..', 'examples', 'all-env-vars.js'), { - max: 1, - silent: true, - minUptime: 0, - hideEnv: this.hideEnv - }); - - child.on('stdout', function (data) { - that.env = Object.keys(JSON.parse(data.toString())); - }); - - child.on('exit', this.callback.bind(this, null)); - child.start(); - }, - "should hide the environment variables passed to the child": function (err, child) { - var that = this; - - assert.equal(child.times, 1); - this.hideEnv.forEach(function (key) { - assert.isTrue(that.env.indexOf(key) === -1); - }); - } - }, - } - } -}).export(module); diff --git a/test/monitor/fork-test.js b/test/monitor/fork-test.js deleted file mode 100644 index 27dad550..00000000 --- a/test/monitor/fork-test.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - * spin-test.js: Tests for spin restarts in forever. - * - * (C) 2010 Nodejitsu Inc. - * MIT LICENCE - * - */ - -var assert = require('assert'), - path = require('path'), - vows = require('vows'), - forever = require('../../lib/forever'); - -vows.describe('forever/monitor/fork').addBatch({ - "When using forever": { - "and spawning a script that uses `process.send()`": { - "using the 'native' fork": { - topic: function () { - var script = path.join(__dirname, '..', '..', 'examples', 'process-send.js'), - child = new (forever.Monitor)(script, { silent: false, minUptime: 2000, max: 1, fork: true }); - - child.on('message', this.callback.bind(null, null)); - child.start(); - }, - "should reemit the message correctly": function (err, msg) { - assert.isObject(msg); - assert.deepEqual(msg, { from: 'child' }); - } - } - } - } -}).export(module); diff --git a/test/monitor/signal-test.js b/test/monitor/signal-test.js deleted file mode 100644 index a1c1759a..00000000 --- a/test/monitor/signal-test.js +++ /dev/null @@ -1,50 +0,0 @@ -/* - * signal-test.js: Tests for spin restarts in forever. - * - * (C) 2010 Nodejitsu Inc. - * MIT LICENCE - * - */ - -var assert = require('assert'), - path = require('path'), - vows = require('vows'), - forever = require('../../lib/forever'); - -vows.describe('forever/monitor/signal').addBatch({ - "When using forever": { - "and spawning a script that ignores signals SIGINT and SIGTERM": { - "with killTTL defined": { - topic: function () { - var script = path.join(__dirname, '..', '..', 'examples', 'signal-ignore.js'), - child = new (forever.Monitor)(script, { silent: true, killTTL: 1000 }), - callback = this.callback, - timer; - - timer = setTimeout(function () { - callback(new Error('Child did not die when killed by forever'), child); - }, 3000); - - child.on('exit', function () { - callback.apply(null, [null].concat([].slice.call(arguments))); - clearTimeout(timer); - }); - - child.on('start', function () { - // - // Give it time to set up signal handlers - // - setTimeout(function() { - child.stop(); - }, 1000); - }); - - child.start(); - }, - "should forcibly kill the processes": function (err, child, spinning) { - assert.isNull(err); - } - } - } - } -}).export(module); diff --git a/test/monitor/simple-test.js b/test/monitor/simple-test.js deleted file mode 100644 index 6349fdc9..00000000 --- a/test/monitor/simple-test.js +++ /dev/null @@ -1,96 +0,0 @@ -/* - * simple-test.js: Simple tests for using forever.Monitor instances. - * - * (C) 2010 Nodejitsu Inc. - * MIT LICENCE - * - */ - -var assert = require('assert'), - path = require('path'), - vows = require('vows'), - forever = require('../../lib/forever'), - macros = require('../helpers/macros'); - -var examplesDir = path.join(__dirname, '..', '..', 'examples'); - -vows.describe('forever/monitor/simple').addBatch({ - "When using forever": { - "an instance of forever.Monitor with valid options": { - topic: new (forever.Monitor)(path.join(examplesDir, 'server.js'), { - max: 10, - silent: true, - options: ['-p', 8090] - }), - "should have correct properties set": function (child) { - assert.isArray(child.args); - assert.equal(child.max, 10); - assert.isTrue(child.silent); - assert.isFunction(child.start); - assert.isObject(child.data); - assert.isFunction(child.stop); - }, - "calling the restart() method in less than `minUptime`": { - topic: function (child) { - var that = this; - child.once('start', function () { - child.once('restart', that.callback.bind(this, null)); - child.restart(); - }); - child.start(); - }, - "should restart the child process": function (_, child, data) { - assert.isObject(data); - child.kill(true); - } - } - }, - "running error-on-timer sample three times": macros.assertTimes( - path.join(examplesDir, 'error-on-timer.js'), - 3, - { - minUptime: 200, - silent: true, - outFile: 'test/fixtures/stdout.log', - errFile: 'test/fixtures/stderr.log', - options: [] - } - ), - "running error-on-timer sample once": macros.assertTimes( - path.join(examplesDir, 'error-on-timer.js'), - 1, - { - minUptime: 200, - silent: true, - outFile: 'test/fixtures/stdout.log', - errFile: 'test/fixtures/stderr.log', - options: [] - } - ), - "non-node usage with a perl one-liner": { - topic: function () { - var child = forever.start([ 'perl', '-le', 'print "moo"' ], { - max: 1, - silent: true, - }); - child.on('stdout', this.callback.bind({}, null)); - }, - "should get back moo": function (err, buf) { - assert.equal(buf.toString(), 'moo\n'); - } - }, - "attempting to start a script that doesn't exist": { - topic: function () { - var child = forever.start('invalid-path.js', { - max: 1, - silent: true - }); - child.on('error', this.callback.bind({}, null)); - }, - "should throw an error about the invalid file": function (err) { - assert.isNotNull(err); - assert.isTrue(err.message.indexOf('does not exist') !== -1); - } - } - } -}).export(module); diff --git a/test/monitor/spin-test.js b/test/monitor/spin-test.js deleted file mode 100644 index da5cbe31..00000000 --- a/test/monitor/spin-test.js +++ /dev/null @@ -1,46 +0,0 @@ -/* - * spin-test.js: Tests for spin restarts in forever. - * - * (C) 2010 Nodejitsu Inc. - * MIT LICENCE - * - */ - -var assert = require('assert'), - path = require('path'), - vows = require('vows'), - forever = require('../../lib/forever'); - -vows.describe('forever/monitor/spin-restart').addBatch({ - "When using forever": { - "and spawning a script that spin restarts": { - "with no spinSleepTime specified": { - topic: function () { - var script = path.join(__dirname, '..', '..', 'examples', 'always-throw.js'), - child = new (forever.Monitor)(script, { silent: true, minUptime: 2000, max: 3 }); - - child.on('exit', this.callback.bind({}, null)); - child.start(); - }, - "should spawn both processes appropriately": function (err, child, spinning) { - assert.isTrue(spinning); - }, - "should only run the bad process once": function (err, child, spinning) { - assert.equal(child.times, 1); - } - }, - "with a spinSleepTime specified": { - topic: function () { - var script = path.join(__dirname, '..', '..', 'examples', 'always-throw.js'), - child = new (forever.Monitor)(script, { silent: true, max: 3, spinSleepTime: 1 }); - - child.on('exit', this.callback.bind({}, null)); - child.start(); - }, - "should restart spinning processes": function (err, child, spinning) { - assert.equal(child.times, 3); - } - } - } - } -}).export(module); diff --git a/test/monitor/watch-test.js b/test/monitor/watch-test.js deleted file mode 100644 index f7045b60..00000000 --- a/test/monitor/watch-test.js +++ /dev/null @@ -1,72 +0,0 @@ -/* - * watch-test.js: Tests for restarting forever processes when a file changes. - * - * (C) 2010 Nodejitsu Inc. - * MIT LICENSE - * - */ - -var assert = require('assert'), - path = require('path'), - fs = require('fs'), - vows = require('vows'), - forever = require('../../lib/forever'); - -vows.describe('forever/monitor/watch').addBatch({ - 'When using forever with watch enabled': { - 'forever should': { - topic: forever.start('daemon.js', { - silent: true, - options: ['-p', '8090'], - watch: true, - sourceDir: path.join(__dirname, '..', 'fixtures', 'watch') - }), - 'have correct options set': function (child) { - assert.isTrue(child.watchIgnoreDotFiles); - assert.equal(fs.realpathSync(path.join(__dirname, '..', 'fixtures', 'watch')), - fs.realpathSync(child.watchDirectory)); - }, - 'when file changes': { - topic: function (child) { - child.once('restart', this.callback); - fs.writeFileSync(path.join(__dirname, '..', 'fixtures', 'watch', 'file'), - '// hello, I know nodejitsu.'); - }, - 'restart the script': function (child, _) { - fs.writeFileSync(path.join(__dirname, '..', 'fixtures', 'watch', 'file'), - '/* hello, I know nodejitsu. */'); - } - }, - 'when file is added': { - topic: function (child) { - child.once('restart', this.callback); - fs.writeFileSync(path.join(__dirname, '..', 'fixtures', 'watch', 'newFile'), ''); - }, - 'restart the script': function (child, _) { - fs.unlinkSync(path.join(__dirname, '..', 'fixtures', 'watch', 'newFile')); - } - }, - 'when file is removed': { - topic: function (child) { - child.once('restart', this.callback); - try { fs.unlinkSync(path.join(__dirname, '..', 'fixtures', 'watch', 'removeMe')) } - catch (ex) { } - }, - 'restart the script': function (child, _) { - fs.writeFileSync(path.join(__dirname, '..', 'fixtures', 'watch', 'removeMe'), ''); - } - }, - 'read .foreverignore file': { - 'and store ignore patterns': function (child) { - assert.deepEqual( - child.watchIgnorePatterns, - fs.readFileSync( - path.join(__dirname, '..', 'fixtures', 'watch', '.foreverignore'), - 'utf8' - ).split("\n") - ); - } - } - } - } -}).export(module); \ No newline at end of file diff --git a/test/plugins/logger-test.js b/test/plugins/logger-test.js deleted file mode 100644 index 1a6b4f81..00000000 --- a/test/plugins/logger-test.js +++ /dev/null @@ -1,80 +0,0 @@ -var assert = require('assert'), - fs = require('fs'), - path = require('path'), - vows = require('vows'), - forever = require('../../lib/forever'); - -var fixturesDir = path.join(__dirname, '..', 'fixtures'); - -function checkLogOutput(file, stream, expectedLength) { - var output = fs.readFileSync(path.join(fixturesDir, file), 'utf8'), - lines = output.split('\n').slice(0, -1); - - assert.equal(lines.length, expectedLength); - lines.forEach(function (line, i) { - assert.equal(lines[i], stream + ' ' + (i % 10)); - }); -} - -vows.describe('forever/plugins/logger').addBatch({ - 'When using the logger plugin': { - 'with custom log files': { - topic: function () { - var outlogs, errlogs, monitor; - - monitor = new forever.Monitor(path.join(fixturesDir, 'logs.js'), { - max: 1, - silent: true, - outFile: path.join(fixturesDir, 'logs-stdout.log'), - errFile: path.join(fixturesDir, 'logs-stderr.log') - }); - - monitor.on('exit', this.callback.bind({}, null)); - monitor.start(); - }, - 'log files should contain correct output': function (err) { - checkLogOutput('logs-stdout.log', 'stdout', 10); - checkLogOutput('logs-stderr.log', 'stderr', 10); - } - }, - 'with custom log files and a process that exits': { - topic: function () { - var monitor = new forever.Monitor(path.join(fixturesDir, 'logs.js'), { - max: 5, - silent: true, - outFile: path.join(fixturesDir, 'logs-stdout-2.log'), - errFile: path.join(fixturesDir, 'logs-stderr-2.log') - }); - - monitor.on('exit', this.callback.bind({}, null)); - monitor.start(); - }, - 'logging should continue through process restarts': function (err) { - checkLogOutput('logs-stdout-2.log', 'stdout', 50); - checkLogOutput('logs-stderr-2.log', 'stderr', 50); - } - }, - } -}).addBatch({ - 'When using the logger plugin': { - 'with custom log files and the append option set': { - topic: function () { - var monitor = new forever.Monitor(path.join(fixturesDir, 'logs.js'), { - max: 3, - silent: true, - append: true, - outFile: path.join(fixturesDir, 'logs-stdout.log'), - errFile: path.join(fixturesDir, 'logs-stderr.log') - }); - - monitor.on('exit', this.callback.bind({}, null)); - monitor.start(); - }, - 'log files should not be truncated': function (err) { - checkLogOutput('logs-stdout.log', 'stdout', 40); - checkLogOutput('logs-stderr.log', 'stderr', 40); - } - } - } -}).export(module); -