diff options
Diffstat (limited to 'node_modules/winston/test')
-rw-r--r-- | node_modules/winston/test/helpers.js | 256 | ||||
-rw-r--r-- | node_modules/winston/test/transports/console-test.js | 202 | ||||
-rw-r--r-- | node_modules/winston/test/transports/file-archive-test.js | 83 | ||||
-rw-r--r-- | node_modules/winston/test/transports/file-maxfiles-test.js | 102 | ||||
-rw-r--r-- | node_modules/winston/test/transports/file-maxsize-test.js | 82 | ||||
-rw-r--r-- | node_modules/winston/test/transports/file-open-test.js | 57 | ||||
-rw-r--r-- | node_modules/winston/test/transports/file-stress-test.js | 72 | ||||
-rw-r--r-- | node_modules/winston/test/transports/file-tailrolling-test.js | 92 | ||||
-rw-r--r-- | node_modules/winston/test/transports/file-test.js | 134 | ||||
-rw-r--r-- | node_modules/winston/test/transports/http-test.js | 70 | ||||
-rw-r--r-- | node_modules/winston/test/transports/memory-test.js | 31 | ||||
-rw-r--r-- | node_modules/winston/test/transports/transport.js | 212 |
12 files changed, 1393 insertions, 0 deletions
diff --git a/node_modules/winston/test/helpers.js b/node_modules/winston/test/helpers.js new file mode 100644 index 0000000..8575fb6 --- /dev/null +++ b/node_modules/winston/test/helpers.js @@ -0,0 +1,256 @@ +/* + * helpers.js: Test helpers for winston + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var assert = require('assert'), + fs = require('fs'), + path = require('path'), + spawn = require('child_process').spawn, + util = require('util'), + vows = require('vows'), + winston = require('../lib/winston'); + +var helpers = exports; + +helpers.size = function (obj) { + var size = 0, key; + for (key in obj) { + if (obj.hasOwnProperty(key)) { + size++; + } + } + + return size; +}; + +helpers.tryUnlink = function (file) { + try { fs.unlinkSync(file) } + catch (ex) { } +}; + +helpers.assertDateInfo = function (info) { + assert.isNumber(Date.parse(info)); +}; + +helpers.assertProcessInfo = function (info) { + assert.isNumber(info.pid); + assert.isNumber(info.uid); + assert.isNumber(info.gid); + assert.isString(info.cwd); + assert.isString(info.execPath); + assert.isString(info.version); + assert.isArray(info.argv); + assert.isObject(info.memoryUsage); +}; + +helpers.assertOsInfo = function (info) { + assert.isArray(info.loadavg); + assert.isNumber(info.uptime); +}; + +helpers.assertTrace = function (trace) { + trace.forEach(function (site) { + assert.isTrue(!site.column || typeof site.column === 'number'); + assert.isTrue(!site.line || typeof site.line === 'number'); + assert.isTrue(!site.file || typeof site.file === 'string'); + assert.isTrue(!site.method || typeof site.method === 'string'); + assert.isTrue(!site.function || typeof site.function === 'string'); + assert.isTrue(typeof site.native === 'boolean'); + }); +}; + +helpers.assertLogger = function (logger, level) { + assert.instanceOf(logger, winston.Logger); + assert.isFunction(logger.log); + assert.isFunction(logger.add); + assert.isFunction(logger.remove); + assert.equal(logger.level, level || "info"); + Object.keys(logger.levels).forEach(function (method) { + assert.isFunction(logger[method]); + }); +}; + +helpers.assertConsole = function (transport) { + assert.instanceOf(transport, winston.transports.Console); + assert.isFunction(transport.log); +}; + +helpers.assertMemory = function (transport) { + assert.instanceOf(transport, winston.transports.Memory); + assert.isFunction(transport.log); +}; + +helpers.assertFile = function (transport) { + assert.instanceOf(transport, winston.transports.File); + assert.isFunction(transport.log); +}; + +helpers.assertCouchdb = function (transport) { + assert.instanceOf(transport, winston.transports.Couchdb); + assert.isFunction(transport.log); +}; + +helpers.assertHandleExceptions = function (options) { + return { + topic: function () { + var that = this, + child = spawn('node', [options.script]); + + helpers.tryUnlink(options.logfile); + child.on('exit', function () { + fs.readFile(options.logfile, that.callback); + }); + }, + "should save the error information to the specified file": function (err, data) { + assert.isTrue(!err); + data = JSON.parse(data); + + assert.isObject(data); + helpers.assertProcessInfo(data.process); + helpers.assertOsInfo(data.os); + helpers.assertTrace(data.trace); + if (options.message) { + assert.equal('uncaughtException: ' + options.message, data.message); + } + } + }; +}; + +helpers.assertFailedTransport = function (transport) { + return { + topic: function () { + var self = this; + transport.on('error', function(emitErr){ + transport.log('error', 'test message 2', {}, function(logErr, logged){ + self.callback(emitErr, logErr); + }); + }); + transport.log('error', 'test message'); + }, + "should emit an error": function (emitErr, logErr) { + assert.instanceOf(emitErr, Error); + assert.equal(emitErr.code, 'ENOENT'); + }, + "should enter noop failed state": function (emitErr, logErr) { + assert.instanceOf(logErr, Error); + assert.equal(transport._failures, transport.maxRetries); + } + }; +}; + +helpers.testNpmLevels = function (transport, assertMsg, assertFn) { + return helpers.testLevels(winston.config.npm.levels, transport, assertMsg, assertFn); +}; + +helpers.testSyslogLevels = function (transport, assertMsg, assertFn) { + return helpers.testLevels(winston.config.syslog.levels, transport, assertMsg, assertFn); +}; + +helpers.testLevels = function (levels, transport, assertMsg, assertFn) { + var tests = {}; + + Object.keys(levels).forEach(function (level) { + var test = { + topic: function () { + transport.log(level, 'test message', {}, this.callback.bind(this, null)); + } + }; + + test[assertMsg] = assertFn; + tests['with the ' + level + ' level'] = test; + }); + + var metadatatest = { + topic: function () { + transport.log('info', 'test message', { metadata: true }, this.callback.bind(this, null)); + } + }; + + metadatatest[assertMsg] = assertFn; + tests['when passed metadata'] = metadatatest; + + var primmetadatatest = { + topic: function () { + transport.log('info', 'test message', 'metadata', this.callback.bind(this, null)); + } + }; + + primmetadatatest[assertMsg] = assertFn; + tests['when passed primitive metadata'] = primmetadatatest; + + var circmetadata = { }; + circmetadata['metadata'] = circmetadata; + + var circmetadatatest = { + topic: function () { + transport.log('info', 'test message', circmetadata, this.callback.bind(this, null)); + } + }; + + circmetadatatest[assertMsg] = assertFn; + tests['when passed circular metadata'] = circmetadatatest; + + return tests; +}; + +helpers.assertOptionsThrow = function (options, errMsg) { + return function () { + assert.throws( + function () { + try { + new (winston.transports.Console)(options); + } catch (err) { + throw(err); + } + }, + new RegExp('^' + errMsg.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + '$') + ); + } +}; + +helpers.assertStderrLevels = function (transport, stderrLevels) { + return function () { + assert.equal( + JSON.stringify(Object.keys(transport.stderrLevels).sort()), + JSON.stringify(stderrLevels.sort()) + ); + } +}; + +helpers.testLoggingToStreams = function (levels, transport, stderrLevels, stdMocks) { + return { + topic: function () { + stdMocks.use(); + transport.showLevel = true; + Object.keys(levels).forEach(function (level) { + transport.log( + level, + level + ' should go to ' + (stderrLevels.indexOf(level) > -1 ? 'stderr' : 'stdout'), + {}, + function () {} + ); + }); + var output = stdMocks.flush(); + stdMocks.restore(); + this.callback(null, output, levels); + }, + "output should go to the appropriate streams": function (ign, output, levels) { + var outCount = 0, + errCount = 0; + Object.keys(levels).forEach(function (level) { + var line; + if (stderrLevels.indexOf(level) > -1) { + line = output.stderr[errCount++]; + assert.equal(line, level + ': ' + level + ' should go to stderr\n'); + } else { + line = output.stdout[outCount++]; + assert.equal(line, level + ': ' + level + ' should go to stdout\n'); + } + }); + } + } +}; diff --git a/node_modules/winston/test/transports/console-test.js b/node_modules/winston/test/transports/console-test.js new file mode 100644 index 0000000..de868b3 --- /dev/null +++ b/node_modules/winston/test/transports/console-test.js @@ -0,0 +1,202 @@ +/* + * console-test.js: Tests for instances of the Console transport + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var path = require('path'), + vows = require('vows'), + assert = require('assert'), + winston = require('../../lib/winston'), + helpers = require('../helpers'), + stdMocks = require('std-mocks'); + +var npmTransport = new (winston.transports.Console)(), + syslogTransport = new (winston.transports.Console)({ levels: winston.config.syslog.levels }), + alignTransport = new (winston.transports.Console)({ showLevel: true, align: true }), + defaultTransport = new (winston.transports.Console)(), + rawTransport = new (winston.transports.Console)({ level: 'verbose', raw: true }), + debugStdoutTransport = new (winston.transports.Console)({ debugStdout: true }), + stderrLevelsTransport = new (winston.transports.Console)({ stderrLevels: ['info', 'warn'] }), + customLevels = { + alpha: 0, + beta: 1, + gamma: 2, + delta: 3, + epsilon: 4, + }, + customLevelsAndStderrTransport = new (winston.transports.Console)({ + levels: customLevels, + stderrLevels: ['delta', 'epsilon'] + }), + noStderrTransport = new (winston.transports.Console)({ stderrLevels: [] }); + +vows.describe('winston/transports/console').addBatch({ + "An instance of the Console Transport": { + "with showLevel off": { + topic : function() { + npmTransport.showLevel = false; + stdMocks.use(); + npmTransport.log('info', 'Le message', { meta: true }, this.callback); + }, + "should not have level prepended": function () { + stdMocks.restore(); + var output = stdMocks.flush(), + line = output.stdout[0]; + + assert.equal(line, 'Le message meta=true\n'); + } + } + } +}).addBatch({ + "An instance of the Console Transport": { + "with showLevel on": { + topic : function() { + npmTransport.showLevel = true; + stdMocks.use(); + npmTransport.log('info', ''); + }, + "should have level prepended": function () { + stdMocks.restore(); + var output = stdMocks.flush(), + line = output.stdout[0]; + + assert.equal(line, 'info: \n'); + } + }, + } +}).addBatch({ + "An instance of the Console Transport": { + "with npm levels": { + "should have the proper methods defined": function () { + helpers.assertConsole(npmTransport); + }, + "the log() method": helpers.testNpmLevels(npmTransport, "should respond with true", function (ign, err, logged) { + assert.isNull(err); + assert.isTrue(logged); + }) + }, + "with syslog levels": { + "should have the proper methods defined": function () { + helpers.assertConsole(syslogTransport); + }, + "the log() method": helpers.testSyslogLevels(syslogTransport, "should respond with true", function (ign, err, logged) { + assert.isNull(err); + assert.isTrue(logged); + }) + }, + "with end-of-line": { + topic : function() { + npmTransport.eol = 'X'; + stdMocks.use(); + npmTransport.log('info', 'Le message', { meta: true }, this.callback); + }, + "should have end-of-line character appended": function () { + stdMocks.restore(); + var output = stdMocks.flush(), + line = output.stdout[0]; + console.dir(line); + + assert.equal(line, 'info: Le message meta=trueX'); + } + } + } +}).addBatch({ + "An instance of the Console Transport with the align option on": { + topic : function() { + stdMocks.use(); + alignTransport.log('info', ''); + }, + "should have logs aligned": function () { + stdMocks.restore(); + var output = stdMocks.flush(), + line = output.stdout[0]; + + assert.equal(line, 'info\011: \n'); + } + } +}).addBatch({ + "with align off": { + topic : function() { + alignTransport.align = false; + stdMocks.use(); + alignTransport.log('info', ''); + }, + "should not have logs aligned": function () { + stdMocks.restore(); + var output = stdMocks.flush(), + line = output.stdout[0]; + + assert.equal(line, 'info: \n'); + } + } +}).addBatch({ + 'An instance of a raw Console transport': { + 'logging to stdout': { + topic: function () { + stdMocks.use(); + rawTransport.log('verbose', 'hello there'); + }, 'should output json with message property': function () { + stdMocks.restore(); + var output = stdMocks.flush(); + assert.ok(output.stdout[0].indexOf('"message":"hello there"') > -1); + } + } + } +}).addBatch({ + "An instance of the Console Transport with no options": { + "should set stderrLevels to 'error' and 'debug' by default": helpers.assertStderrLevels( + defaultTransport, + ['error', 'debug'] + ), + "should log only 'error' and 'debug' to stderr": helpers.testLoggingToStreams( + winston.config.npm.levels, defaultTransport, ['debug', 'error'], stdMocks + ) + } +}).addBatch({ + "An instance of the Console Transport with debugStdout set": { + "should throw an Error if stderrLevels is set": helpers.assertOptionsThrow( + { debugStdout: true, stderrLevels: ['debug'] }, + "Error: Cannot set debugStdout and stderrLevels together" + ), + "should set stderrLevels to 'error' by default": helpers.assertStderrLevels( + debugStdoutTransport, + ['error'] + ), + "should log only the 'error' level to stderr": helpers.testLoggingToStreams( + winston.config.npm.levels, debugStdoutTransport, ['error'], stdMocks + ) + } +}).addBatch({ + "An instance of the Console Transport with stderrLevels set": { + "should throw an Error if stderrLevels is set but not an Array": helpers.assertOptionsThrow( + { debugStdout: false, stderrLevels: new String('Not an Array') }, + "Error: Cannot set stderrLevels to type other than Array" + ), + "should throw an Error if stderrLevels contains non-string elements": helpers.assertOptionsThrow( + { debugStdout: false, stderrLevels: ["good", /^invalid$/, "valid"] }, + "Error: Cannot have non-string elements in stderrLevels Array" + ), + "should correctly set stderrLevels": helpers.assertStderrLevels( + stderrLevelsTransport, + ['info', 'warn'] + ), + "should log only the levels in stderrLevels to stderr": helpers.testLoggingToStreams( + winston.config.npm.levels, stderrLevelsTransport, ['info', 'warn'], stdMocks + ) + } +}).addBatch({ + "An instance of the Console Transport with stderrLevels set to an empty array": { + "should log only to stdout, and not to stderr": helpers.testLoggingToStreams( + winston.config.npm.levels, noStderrTransport, [], stdMocks + ) + } +}).addBatch({ + "An instance of the Console Transport with custom levels and stderrLevels set": { + "should log only the levels in stderrLevels to stderr": helpers.testLoggingToStreams( + customLevels, customLevelsAndStderrTransport, ['delta', 'epsilon'], stdMocks + ) + } +}).export(module); diff --git a/node_modules/winston/test/transports/file-archive-test.js b/node_modules/winston/test/transports/file-archive-test.js new file mode 100644 index 0000000..d076ce0 --- /dev/null +++ b/node_modules/winston/test/transports/file-archive-test.js @@ -0,0 +1,83 @@ +/* + * file-archive-test.js: Tests for instances of the File transport setting the archive option, + * + * (C) 2015 Nimrod Becker + * MIT LICENSE + * + */ + +var assert = require('assert'), + exec = require('child_process').exec, + fs = require('fs'), + path = require('path'), + vows = require('vows'), + winston = require('../../lib/winston'), + helpers = require('../helpers'); + +var archiveTransport = new winston.transports.File({ + timestamp: true, + json: false, + zippedArchive: true, + tailable: true, + filename: 'testarchive.log', + dirname: path.join(__dirname, '..', 'fixtures', 'logs'), + maxsize: 4096, + maxFiles: 3 +}); + +function data(ch) { + return new Array(1018).join(String.fromCharCode(65 + ch)); +} + +function logKbytes(kbytes, txt) { + // + // With no timestamp and at the info level, + // winston adds exactly 7 characters: + // [info](4)[ :](2)[\n](1) + // + for (var i = 0; i < kbytes; i++) { + archiveTransport.log('info', data(txt), null, function() {}); + } +} + +vows.describe('winston/transports/file/zippedArchive').addBatch({ + "An instance of the File Transport with tailable true": { + "when created archived files are rolled": { + topic: function() { + var that = this, + created = 0; + + archiveTransport.on('logged', function() { + if (++created === 6) { + return that.callback(); + } + + logKbytes(4, created); + }); + + logKbytes(4, created); + }, + "should be only 3 files called testarchive.log, testarchive1.log.gz and testarchive2.log.gz": function() { + //Give the archive a little time to settle + // setTimeout(function() { + for (var num = 0; num < 6; num++) { + var file = !num ? 'testarchive.log' : 'testarchive' + num + '.log.gz', + fullpath = path.join(__dirname, '..', 'fixtures', 'logs', file); + + // There should be no files with that name + if (num >= 3) { + assert.throws(function() { + fs.statSync(fullpath); + }, Error); + } else { + // The other files should exist + assert.doesNotThrow(function() { + fs.statSync(fullpath); + }, Error); + } + } + //},5000); + }, + } + }, +}).export(module); diff --git a/node_modules/winston/test/transports/file-maxfiles-test.js b/node_modules/winston/test/transports/file-maxfiles-test.js new file mode 100644 index 0000000..62564a2 --- /dev/null +++ b/node_modules/winston/test/transports/file-maxfiles-test.js @@ -0,0 +1,102 @@ +/* + * file-maxfiles-test.js: Tests for instances of the File transport setting the max file size, + * and setting a number for max files created. + * maxSize * maxFiles = total storage used by winston. + * + * (C) 2011 Daniel Aristizabal + * MIT LICENSE + * + */ + +var assert = require('assert'), + exec = require('child_process').exec, + fs = require('fs'), + path = require('path'), + vows = require('vows'), + winston = require('../../lib/winston'), + helpers = require('../helpers'); + +var maxfilesTransport = new winston.transports.File({ + timestamp: false, + json: false, + filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxfiles.log'), + maxsize: 4096, + maxFiles: 3 +}); + +vows.describe('winston/transports/file/maxfiles').addBatch({ + "An instance of the File Transport": { + "when passed a valid filename": { + topic: maxfilesTransport, + "should be a valid transporter": function (transportTest) { + helpers.assertFile(transportTest); + }, + "should set the maxFiles option correctly": function (transportTest) { + assert.isNumber(transportTest.maxFiles); + } + }, + "when delete old test files": { + topic: function () { + exec('rm -rf ' + path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxfiles*'), this.callback); + }, + "and when passed more files than the maxFiles": { + topic: function () { + var that = this, + created = 0; + + function data(ch) { + return new Array(1018).join(String.fromCharCode(65 + ch)); + }; + + function logKbytes(kbytes, txt) { + // + // With no timestamp and at the info level, + // winston adds exactly 7 characters: + // [info](4)[ :](2)[\n](1) + // + for (var i = 0; i < kbytes; i++) { + maxfilesTransport.log('info', data(txt), null, function () { }); + } + } + + maxfilesTransport.on('logged', function () { + if (++created === 6) { + return that.callback(); + } + + logKbytes(4, created); + }); + + logKbytes(4, created); + }, + "should be only 3 files called 5.log, 4.log and 3.log": function () { + for (var num = 0; num < 6; num++) { + var file = !num ? 'testmaxfiles.log' : 'testmaxfiles' + num + '.log', + fullpath = path.join(__dirname, '..', 'fixtures', 'logs', file); + + // There should be no files with that name + if (num >= 0 && num < 3) { + assert.throws(function () { + fs.statSync(fullpath); + }, Error); + } else { + // The other files should be exist + assert.doesNotThrow(function () { + fs.statSync(fullpath); + }, Error); + } + } + }, + "should have the correct content": function () { + ['D', 'E', 'F'].forEach(function (name, inx) { + var counter = inx + 3, + logsDir = path.join(__dirname, '..', 'fixtures', 'logs'), + content = fs.readFileSync(path.join(logsDir, 'testmaxfiles' + counter + '.log'), 'utf-8'); + // The content minus the 7 characters added by winston + assert.lengthOf(content.match(new RegExp(name, 'g')), 4068); + }); + } + } + } + } +}).export(module); diff --git a/node_modules/winston/test/transports/file-maxsize-test.js b/node_modules/winston/test/transports/file-maxsize-test.js new file mode 100644 index 0000000..7d20e08 --- /dev/null +++ b/node_modules/winston/test/transports/file-maxsize-test.js @@ -0,0 +1,82 @@ +/* + * file-test.js: Tests for instances of the File transport + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var assert = require('assert'), + exec = require('child_process').exec, + fs = require('fs'), + path = require('path'), + vows = require('vows'), + winston = require('../../lib/winston'), + helpers = require('../helpers'); + +var maxsizeTransport = new winston.transports.File({ + timestamp: false, + json: false, + filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxsize.log'), + maxsize: 4096 +}); + +vows.describe('winston/transports/file/maxsize').addBatch({ + "An instance of the File Transport": { + "when passed a valid filename": { + "the log() method": { + topic: function () { + exec('rm -rf ' + path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxsize*'), this.callback); + }, + "when passed more than the maxsize": { + topic: function () { + var that = this, + data = new Array(1018).join('-'); + + // + // Setup a list of files which we will later stat. + // + that.files = []; + + function logKbytes (kbytes) { + // + // With no timestamp and at the info level, + // winston adds exactly 7 characters: + // [info](4)[ :](2)[\n](1) + // + for (var i = 0; i < kbytes; i++) { + maxsizeTransport.log('info', data, null, function () { }); + } + } + + maxsizeTransport.on('open', function (file) { + var match = file.match(/(\d+)\.log$/), + count = match ? match[1] : 0; + + that.files.push(file); + + if (that.files.length === 5) { + return that.callback(); + } + + logKbytes(4); + }); + + logKbytes(4); + }, + "should create multiple files correctly": function () { + this.files.forEach(function (file) { + try { + var stats = fs.statSync(file); + assert.equal(stats.size, 4096); + } + catch (ex) { + assert.isNull(ex); + } + }); + } + } + } + } + } +}).export(module);
\ No newline at end of file diff --git a/node_modules/winston/test/transports/file-open-test.js b/node_modules/winston/test/transports/file-open-test.js new file mode 100644 index 0000000..15427a0 --- /dev/null +++ b/node_modules/winston/test/transports/file-open-test.js @@ -0,0 +1,57 @@ +/* + * file-open-test.js: Tests for File transport "open" event + * + * (C) 2014 William Wong + * MIT LICENSE + * + */ + +var assert = require('assert'), + fs = require('fs'), + os = require('os'), + path = require('path'), + vows = require('vows'), + winston = require('../../lib/winston'); + +vows.describe('winston/transports/file').addBatch({ + 'An instance of the File Transport': { + topic: function () { + var callback = this.callback.bind(this), + logPath = path.resolve(__dirname, '../fixtures/logs/file-open-test.log'); + + try { + fs.unlinkSync(logPath); + } catch (ex) { + if (ex && ex.code !== 'ENOENT') { return callback(ex); } + } + + var fileTransport = new (winston.transports.File)({ + filename: logPath + }), + logger = new (winston.Logger)({ + transports: [fileTransport] + }), + timeline = {}; + + fileTransport.open(function () { + timeline.open = Date.now(); + + setTimeout(function () { + logger.info('Hello, World!', function () { + timeline.logged = Date.now(); + }); + }, 100); + + setTimeout(function () { + callback(null, timeline); + }, 1000); + }); + }, + 'should fire "open" event': function (results) { + assert.isTrue(!!results.open); + }, + 'should fire "logged" event': function (results) { + assert.isTrue(!!results.logged); + } + } +}).export(module);
\ No newline at end of file diff --git a/node_modules/winston/test/transports/file-stress-test.js b/node_modules/winston/test/transports/file-stress-test.js new file mode 100644 index 0000000..8c4dcb9 --- /dev/null +++ b/node_modules/winston/test/transports/file-stress-test.js @@ -0,0 +1,72 @@ +/* + * file-stress-test.js: Tests for stressing File transport + * + * (C) 2014 William Wong + * MIT LICENSE + * + */ + +var assert = require('assert'), + fs = require('fs'), + os = require('os'), + path = require('path'), + vows = require('vows'), + winston = require('../../lib/winston'); + +vows.describe('winston/transports/file').addBatch({ + 'A stressed instance of the File Transport': { + topic: function () { + var callback = this.callback.bind(this), + logPath = path.resolve(__dirname, '../fixtures/logs/file-stress-test.log'); + + try { + fs.unlinkSync(logPath); + } catch (ex) { + if (ex && ex.code !== 'ENOENT') { return callback(ex); } + } + + var fileTransport = new (winston.transports.File)({ + filename: logPath + }), + logger = new (winston.Logger)({ + transports: [fileTransport] + }); + + fileTransport.on('open', function () { + setTimeout(function () { + clearInterval(interval); + + logger.query({ order: 'asc' }, function (err, results) { + callback(null, results); + }); + }, 100); + }); + + var logIndex = 0, + interval = setInterval(function () { + logger.info(++logIndex); + stress(200); + }, 0); + + logger.info(++logIndex); + stress(200); + + function stress(duration) { + var startTime = Date.now(); + + while (Date.now() - startTime < duration) { + Math.sqrt(Math.PI); + } + } + }, + 'should not skip any log lines': function (results) { + var testIndex = 0; + + results.file.forEach(function (log) { + if (+log.message !== ++testIndex) { + throw new Error('Number skipped'); + } + }); + } + } +}).export(module); diff --git a/node_modules/winston/test/transports/file-tailrolling-test.js b/node_modules/winston/test/transports/file-tailrolling-test.js new file mode 100644 index 0000000..60a0674 --- /dev/null +++ b/node_modules/winston/test/transports/file-tailrolling-test.js @@ -0,0 +1,92 @@ +var assert = require('assert'), + fs = require('fs'), + path = require('path'), + vows = require('vows'), + winston = require('../../lib/winston'), + helpers = require('../helpers'); + +var maxfilesTransport = new winston.transports.File({ + timestamp: false, + json: false, + filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testtailrollingfiles.log'), + maxsize: 4096, + maxFiles: 3, + tailable: true +}); + +process.on('uncaughtException', function (err) { + console.log('caught exception'); + console.error(err); +}); + +vows.describe('winston/transports/file/tailrolling').addBatch({ + "An instance of the File Transport": { + "when delete old test files": { + topic: function () { + var logs = path.join(__dirname, '..', 'fixtures', 'logs'); + fs.readdirSync(logs).forEach(function (file) { + if (~file.indexOf('testtailrollingfiles')) { + fs.unlinkSync(path.join(logs, file)); + } + }); + + this.callback(); + }, + "and when passed more files than the maxFiles": { + topic: function () { + var that = this, + created = 0; + + function data(ch) { + return new Array(1018).join(String.fromCharCode(65 + ch)); + }; + + function logKbytes(kbytes, txt) { + // + // With no timestamp and at the info level, + // winston adds exactly 7 characters: + // [info](4)[ :](2)[\n](1) + // + for (var i = 0; i < kbytes; i++) { + maxfilesTransport.log('info', data(txt), null, function () { }); + } + } + + maxfilesTransport.on('logged', function () { + if (++created == 4) { + return that.callback(); + } + + logKbytes(4, created); + }); + + logKbytes(4, created); + }, + "should be 3 log files, base to maxFiles - 1": function () { + var file, fullpath; + for (var num = 0; num < 4; num++) { + file = !num ? 'testtailrollingfiles.log' : 'testtailrollingfiles' + num + '.log'; + fullpath = path.join(__dirname, '..', 'fixtures', 'logs', file); + + if (num == 3) { + return assert.ok(!fs.existsSync(fullpath)); + } + + assert.ok(fs.existsSync(fullpath)); + } + + return false; + }, + "should have files in correct order": function () { + var file, fullpath, content; + ['D', 'C', 'B'].forEach(function (letter, i) { + file = !i ? 'testtailrollingfiles.log' : 'testtailrollingfiles' + i + '.log'; + content = fs.readFileSync(path.join(__dirname, '..', 'fixtures', 'logs', file), 'ascii'); + + assert.lengthOf(content.match(new RegExp(letter, 'g')), 4068); + }); + } + } + } + } +}).export(module);
\ No newline at end of file diff --git a/node_modules/winston/test/transports/file-test.js b/node_modules/winston/test/transports/file-test.js new file mode 100644 index 0000000..e6f6b3a --- /dev/null +++ b/node_modules/winston/test/transports/file-test.js @@ -0,0 +1,134 @@ +/* + * file-test.js: Tests for instances of the File transport + * + * (C) 2010 Charlie Robbins + * MIT LICENSE + * + */ + +var path = require('path'), + vows = require('vows'), + fs = require('fs'), + assert = require('assert'), + winston = require('../../lib/winston'), + stdMocks = require('std-mocks'), + helpers = require('../helpers'); + +var transport = require('./transport'); + +var stream = fs.createWriteStream( + path.join(__dirname, '..', 'fixtures', 'logs', 'testfile.log') + ), + fileTransport = new (winston.transports.File)({ + filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testfilename.log') + }), + failedFileTransport = new (winston.transports.File)({ + filename: path.join(__dirname, '..', 'fixtures', 'logs', 'dir404', 'testfile.log') + }), + streamTransport = new (winston.transports.File)({ stream: stream }); + +vows.describe('winston/transports/file').addBatch({ + "An instance of the File Transport": { + "when passed a valid filename": { + "should have the proper methods defined": function () { + helpers.assertFile(fileTransport); + }, + "the log() method": helpers.testNpmLevels(fileTransport, "should respond with true", function (ign, err, logged) { + assert.isNull(err); + assert.isTrue(logged); + }) + }, + "when passed an invalid filename": { + "should have proper methods defined": function () { + helpers.assertFile(failedFileTransport); + }, + "should enter noop failed state": function () { + helpers.assertFailedTransport(failedFileTransport); + } + }, + "when passed a valid file stream": { + "should have the proper methods defined": function () { + helpers.assertFile(streamTransport); + }, + "the log() method": helpers.testNpmLevels(streamTransport, "should respond with true", function (ign, err, logged) { + assert.isNull(err); + assert.isTrue(logged); + }) + }, + "streaming to stdout": { + topic: function () { + var transport = new (winston.transports.File)({ + stream: process.stdout, timestamp: false, json: false + }); + stdMocks.use(); + return transport; + }, + "with showLevel off": { + topic: function (stdoutStreamTransport) { + stdoutStreamTransport.showLevel = false; + stdoutStreamTransport.log('info', '', undefined, this.callback); + }, + "should not have level prepended": function () { + var output = stdMocks.flush(), + line = output.stdout[0]; + + assert.equal(line, '\n'); + } + }, + // there would be a "with showLevel on" here but I think it's a bug in + // this version of vows. ugprading causes even more problems + teardown: function() { + stdMocks.restore(); + } + } + } +}).addBatch({ + "These tests have a non-deterministic end": { + topic: function () { + setTimeout(this.callback, 200); + }, + "and this should be fixed before releasing": function () { + assert.isTrue(true); + } + } +}).addBatch({ + "Error object in metadata #610": { + topic: function () { + var myErr = new Error("foo"); + + fileTransport.log('info', 'test message', myErr, this.callback.bind(this, null, myErr)); + }, + "should not be modified": function (err, myErr) { + assert.equal(myErr.message, "foo"); + // Not sure if this is the best possible way to check if additional props appeared + assert.deepEqual(Object.getOwnPropertyNames(myErr), Object.getOwnPropertyNames(new Error("foo"))); + } + } +}).addBatch({ + "Date object in metadata": { + topic: function () { + var obj = new Date(1000); + + fileTransport.log('info', 'test message', obj, this.callback.bind(this, null, obj)); + }, + "should not be modified": function (err, obj) { + // Not sure if this is the best possible way to check if additional props appeared + assert.deepEqual(Object.getOwnPropertyNames(obj), Object.getOwnPropertyNames(new Date())); + } + } +}).addBatch({ + "Plain object in metadata": { + topic: function () { + var obj = { message: "foo" }; + + fileTransport.log('info', 'test message', obj, this.callback.bind(this, null, obj)); + }, + "should not be modified": function (err, obj) { + assert.deepEqual(obj, { message: "foo" }); + } + } +}).addBatch({ + "An instance of the File Transport": transport(winston.transports.File, { + filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testfile.log') + }) +}).export(module); diff --git a/node_modules/winston/test/transports/http-test.js b/node_modules/winston/test/transports/http-test.js new file mode 100644 index 0000000..65f3cc7 --- /dev/null +++ b/node_modules/winston/test/transports/http-test.js @@ -0,0 +1,70 @@ +/* + * http-test.js: Tests for instances of the HTTP transport + * + * MIT LICENSE + */ + +var path = require('path'), + vows = require('vows'), + http = require('http'), + fs = require('fs'), + assert = require('assert'), + winston = require('../../lib/winston'), + helpers = require('../helpers'), + hock = require('hock'); + +var transport = require('./transport'); + +var host = '127.0.0.1'; + +vows.describe('winston/transports/http').addBatch({ + "When the HTTP endpoint": { + topic: function () { + var mock = this.mock = hock.createHock(), + self = this; + + mock + .post('/log', { + "method":"collect", + "params":{ + "level":"info", + "message":"hello", + "meta":{} + } + }) + .min(1) + .max(1) + .reply(200); + + var server = this.server = http.createServer(mock.handler); + server.listen(0, '0.0.0.0', this.callback); + }, + "is running": function (err) { + assert.ifError(err); + }, + "an instance of the Http transport": { + topic: function () { + + var port = this.server.address().port; + var self = this, + httpTransport = new (winston.transports.Http)({ + host: host, + port: port, + path: 'log' + }); + + httpTransport.log('info', 'hello', function (logErr, logged) { + self.mock.done(function (doneErr) { + self.callback(null, logErr, logged, doneErr); + }); + }); + }, + "should log to the specified URL": function (_, err, logged, requested) { + assert.ifError(err); + assert.isTrue(logged); + assert.ifError(requested); + this.server.close(); + } + } + } +}).export(module); diff --git a/node_modules/winston/test/transports/memory-test.js b/node_modules/winston/test/transports/memory-test.js new file mode 100644 index 0000000..e8e1043 --- /dev/null +++ b/node_modules/winston/test/transports/memory-test.js @@ -0,0 +1,31 @@ +var path = require('path'), + vows = require('vows'), + assert = require('assert'), + winston = require('../../lib/winston'), + helpers = require('../helpers'); + +var npmTransport = new (winston.transports.Memory)(), + syslogTransport = new (winston.transports.Memory)({ levels: winston.config.syslog.levels }); + +vows.describe('winston/transports/memory').addBatch({ + "An instance of the Memory Transport": { + "with npm levels": { + "should have the proper methods defined": function () { + helpers.assertMemory(npmTransport); + }, + "the log() method": helpers.testNpmLevels(npmTransport, "should respond with true", function (ign, err, logged) { + assert.isNull(err); + assert.isTrue(logged); + }) + }, + "with syslog levels": { + "should have the proper methods defined": function () { + helpers.assertMemory(syslogTransport); + }, + "the log() method": helpers.testSyslogLevels(syslogTransport, "should respond with true", function (ign, err, logged) { + assert.isNull(err); + assert.isTrue(logged); + }) + } + } +}).export(module);
\ No newline at end of file diff --git a/node_modules/winston/test/transports/transport.js b/node_modules/winston/test/transports/transport.js new file mode 100644 index 0000000..0abf80a --- /dev/null +++ b/node_modules/winston/test/transports/transport.js @@ -0,0 +1,212 @@ +var assert = require('assert'), + winston = require('../../lib/winston'), + helpers = require('../helpers'); + +module.exports = function (transport, options) { + var logger = transport instanceof winston.Logger + ? transport + : new winston.Logger({ + transports: [ + new transport(options) + ] + }); + + // hack to fix transports that don't log + // any unit of time smaller than seconds + var common = require('../../lib/winston/common'); + common.timestamp = function() { + return new Date().toISOString(); + }; + + var transport = logger.transports[logger._names[0]]; + + var out = { + 'topic': logger, + 'when passed valid options': { + 'should have the proper methods defined': function () { + switch (transport.name) { + case 'console': + helpers.assertConsole(transport); + break; + case 'file': + helpers.assertFile(transport); + break; + case 'couchdb': + helpers.assertCouchdb(transport); + break; + } + assert.isFunction(transport.log); + } + }, + 'the log() method': helpers.testNpmLevels(transport, + 'should respond with true', function (ign, err, logged) { + assert.isNull(err); + assert.isNotNull(logged); + } + ), + 'the stream() method': { + 'using no options': { + 'topic': function () { + if (!transport.stream) return; + + logger.log('info', 'hello world', {}); + + var cb = this.callback, + j = 10, + i = 10, + results = [], + stream = logger.stream(); + + stream.on('log', function (log) { + results.push(log); + results.stream = stream; + if (!--j) cb(null, results); + }); + + stream.on('error', function (err) { + j = -1; //don't call the callback again + cb(err); + }); + + while (i--) logger.log('info', 'hello world ' + i, {}); + }, + 'should stream logs': function (err, results) { + if (!transport.stream) return; + assert.isNull(err); + results.forEach(function (log) { + assert.ok(log.message.indexOf('hello world') === 0 + || log.message.indexOf('test message') === 0); + }); + results.stream.destroy(); + } + }, + 'using the `start` option': { + 'topic': function () { + if (!transport.stream) return; + + var cb = this.callback, + stream = logger.stream({ start: 0 }); + + stream.on('log', function (log) { + log.stream = stream; + if (cb) cb(null, log); + cb = null; + }); + }, + 'should stream logs': function (err, log) { + if (!transport.stream) return; + assert.isNull(err); + assert.isNotNull(log.message); + log.stream.destroy(); + } + } + }, + 'after the logs have flushed': { + topic: function () { + setTimeout(this.callback, 1000); + }, + 'the query() method': { + 'using basic querying': { + 'topic': function () { + if (!transport.query) return; + var cb = this.callback; + logger.log('info', 'hello world', {}, function () { + logger.query(cb); + }); + }, + 'should return matching results': function (err, results) { + if (!transport.query) return; + assert.isNull(err); + results = results[transport.name]; + while (!Array.isArray(results)) { + results = results[Object.keys(results).pop()]; + } + var log = results.pop(); + assert.ok(log.message.indexOf('hello world') === 0 + || log.message.indexOf('test message') === 0); + } + }, + 'using the `rows` option': { + 'topic': function () { + if (!transport.query) return; + var cb = this.callback; + logger.log('info', 'hello world', {}, function () { + logger.query({ rows: 1 }, cb); + }); + }, + 'should return one result': function (err, results) { + if (!transport.query) return; + assert.isNull(err); + results = results[transport.name]; + while (!Array.isArray(results)) { + results = results[Object.keys(results).pop()]; + } + assert.equal(results.length, 1); + } + }, + 'using `fields` and `order` option': { + 'topic': function () { + if (!transport.query) return; + var cb = this.callback; + logger.log('info', 'hello world', {}, function () { + logger.query({ order: 'asc', fields: ['timestamp'] }, cb); + }); + }, + 'should return matching results': function (err, results) { + if (!transport.query) return; + assert.isNull(err); + results = results[transport.name]; + while (!Array.isArray(results)) { + results = results[Object.keys(results).pop()]; + } + assert.equal(Object.keys(results[0]).length, 1); + assert.ok(new Date(results.shift().timestamp) + < new Date(results.pop().timestamp)); + } + }, + 'using the `from` and `until` option': { + 'topic': function () { + if (!transport.query) return; + var cb = this.callback; + var start = Date.now() - (100 * 1000); + var end = Date.now() + (100 * 1000); + logger.query({ from: start, until: end }, cb); + }, + 'should return matching results': function (err, results) { + if (!transport.query) return; + assert.isNull(err); + results = results[transport.name]; + while (!Array.isArray(results)) { + results = results[Object.keys(results).pop()]; + } + assert.ok(results.length >= 1); + } + }, + 'using a bad `from` and `until` option': { + 'topic': function () { + if (!transport.query) return; + var cb = this.callback; + logger.log('info', 'bad from and until', {}, function () { + var now = Date.now() + 1000000; + logger.query({ from: now, until: now }, cb); + }); + }, + 'should return no results': function (err, results) { + if (!transport.query) return; + assert.isNull(err); + results = results[transport.name]; + while (!Array.isArray(results)) { + results = results[Object.keys(results).pop()]; + } + results = [results.filter(function(log) { + return log.message === 'bad from and until'; + }).pop()]; + assert.isUndefined(results[0]); + } + } + } + } + }; + + return out; +}; |