123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487 |
- "use strict";
- var async = require('async')
- , should = require('should')
- , fs = require('fs')
- , path = require('path')
- , zlib = require('zlib')
- , streams = require('readable-stream')
- , RollingFileStream = require('../lib').RollingFileStream;
- function remove(filename, cb) {
- fs.unlink(filename, function(err) { cb(); });
- }
- function create(filename, cb) {
- fs.writeFile(filename, "test file", cb);
- }
- describe('RollingFileStream', function() {
- describe('arguments', function() {
- var stream;
- before(function(done) {
- remove(__dirname + "/test-rolling-file-stream", function() {
- stream = new RollingFileStream(__dirname + "/test-rolling-file-stream", 1024, 5);
- done();
- });
- });
- after(function(done) {
- remove(__dirname + "/test-rolling-file-stream", done);
- });
- it('should take a filename, file size (bytes), no. backups, return Writable', function() {
- stream.should.be.an.instanceOf(streams.Writable);
- stream.filename.should.eql(__dirname + "/test-rolling-file-stream");
- stream.size.should.eql(1024);
- stream.backups.should.eql(5);
- });
- it('should apply default settings to the underlying stream', function() {
- stream.theStream.mode.should.eql(420);
- stream.theStream.flags.should.eql('a');
- //encoding isn't a property on the underlying stream
- //assert.equal(stream.theStream.encoding, 'utf8');
- });
- });
- describe('with stream arguments', function() {
- it('should pass them to the underlying stream', function() {
- var stream = new RollingFileStream(
- __dirname + '/test-rolling-file-stream',
- 1024,
- 5,
- { mode: parseInt('0666', 8) }
- );
- stream.theStream.mode.should.eql(parseInt('0666', 8));
- });
- after(function(done) {
- remove(__dirname + '/test-rolling-file-stream', done);
- });
- });
- describe('without size', function() {
- it('should default to max int size', function() {
- var stream = new RollingFileStream(__dirname + "/test-rolling-file-stream");
- stream.size.should.eql(Number.MAX_SAFE_INTEGER);
- });
- after(function(done) {
- remove(__dirname + "/test-rolling-file-stream", done);
- });
- });
- describe('without number of backups', function() {
- it('should default to 1 backup', function() {
- var stream = new RollingFileStream(__dirname + "/test-rolling-file-stream", 1024);
- stream.backups.should.eql(1);
- });
- after(function(done) {
- remove(__dirname + "/test-rolling-file-stream", done);
- });
- });
- describe('writing less than the file size', function() {
- before(function(done) {
- remove(__dirname + "/test-rolling-file-stream-write-less", function() {
- var stream = new RollingFileStream(
- __dirname + "/test-rolling-file-stream-write-less",
- 100
- );
- stream.write("cheese", "utf8", function() {
- stream.end(done);
- });
- });
- });
- after(function(done) {
- remove(__dirname + "/test-rolling-file-stream-write-less", done);
- });
- it('should write to the file', function(done) {
- fs.readFile(
- __dirname + "/test-rolling-file-stream-write-less", "utf8",
- function(err, contents) {
- contents.should.eql("cheese");
- done(err);
- }
- );
- });
- it('should write one file', function(done) {
- fs.readdir(__dirname, function(err, files) {
- files.filter(
- function(file) { return file.indexOf('test-rolling-file-stream-write-less') > -1; }
- ).should.have.length(1);
- done(err);
- });
- });
- });
- describe('writing more than the file size', function() {
- before(function(done) {
- async.forEach(
- [
- __dirname + "/test-rolling-file-stream-write-more",
- __dirname + "/test-rolling-file-stream-write-more.1"
- ],
- remove,
- function() {
- var stream = new RollingFileStream(
- __dirname + "/test-rolling-file-stream-write-more",
- 45
- );
- async.forEachSeries(
- [0, 1, 2, 3, 4, 5, 6],
- function(i, cb) {
- stream.write(i +".cheese\n", "utf8", cb);
- },
- function() {
- stream.end(done);
- }
- );
- }
- );
- });
- after(function(done) {
- async.forEach(
- [
- __dirname + "/test-rolling-file-stream-write-more",
- __dirname + "/test-rolling-file-stream-write-more.1"
- ],
- remove,
- done
- );
- });
- it('should write two files' , function(done) {
- fs.readdir(__dirname, function(err, files) {
- files.filter(
- function(file) {
- return file.indexOf('test-rolling-file-stream-write-more') > -1;
- }
- ).should.have.length(2);
- done(err);
- });
- });
- it('should write the last two log messages to the first file', function(done) {
- fs.readFile(
- __dirname + "/test-rolling-file-stream-write-more", "utf8",
- function(err, contents) {
- contents.should.eql('5.cheese\n6.cheese\n');
- done(err);
- });
- });
- it('should write the first five log messages to the second file', function(done) {
- fs.readFile(
- __dirname + '/test-rolling-file-stream-write-more.1', "utf8",
- function(err, contents) {
- contents.should.eql('0.cheese\n1.cheese\n2.cheese\n3.cheese\n4.cheese\n');
- done(err);
- }
- );
- });
- });
- describe('with options.compress = true', function() {
- before(function(done) {
- var stream = new RollingFileStream(
- path.join(__dirname, 'compressed-backups.log'),
- 30, //30 bytes max size
- 2, //two backup files to keep
- { compress: true }
- );
- async.forEachSeries(
- [
- "This is the first log message.",
- "This is the second log message.",
- "This is the third log message.",
- "This is the fourth log message."
- ],
- function(i, cb) {
- stream.write(i + "\n", "utf8", cb);
- },
- function() {
- stream.end(done);
- }
- );
- });
- it('should produce three files, with the backups compressed', function(done) {
- fs.readdir(__dirname, function(err, files) {
- var testFiles = files.filter(
- function(f) { return f.indexOf('compressed-backups.log') > -1; }
- ).sort();
- testFiles.length.should.eql(3);
- testFiles.should.eql([
- 'compressed-backups.log',
- 'compressed-backups.log.1.gz',
- 'compressed-backups.log.2.gz',
- ]);
- fs.readFile(path.join(__dirname, testFiles[0]), 'utf8', function(err, contents) {
- contents.should.eql('This is the fourth log message.\n');
- zlib.gunzip(fs.readFileSync(path.join(__dirname, testFiles[1])),
- function(err, contents) {
- contents.toString('utf8').should.eql('This is the third log message.\n');
- zlib.gunzip(fs.readFileSync(path.join(__dirname, testFiles[2])),
- function(err, contents) {
- contents.toString('utf8').should.eql('This is the second log message.\n');
- done(err);
- }
- );
- }
- );
- });
- });
- });
- after(function(done) {
- async.forEach([
- path.join(__dirname, 'compressed-backups.log'),
- path.join(__dirname, 'compressed-backups.log.1.gz'),
- path.join(__dirname, 'compressed-backups.log.2.gz'),
- ], remove, done);
- });
- });
- describe('with options.keepFileExt = true', function() {
- before(function(done) {
- var stream = new RollingFileStream(
- path.join(__dirname, 'extKept-backups.log'),
- 30, //30 bytes max size
- 2, //two backup files to keep
- { keepFileExt: true }
- );
- async.forEachSeries(
- [
- "This is the first log message.",
- "This is the second log message.",
- "This is the third log message.",
- "This is the fourth log message."
- ],
- function(i, cb) {
- stream.write(i + "\n", "utf8", cb);
- },
- function() {
- stream.end(done);
- }
- );
- });
- it('should produce three files, with the file-extension kept', function(done) {
- fs.readdir(__dirname, function(err, files) {
- var testFiles = files.filter(
- function(f) { return f.indexOf('extKept-backups') > -1; }
- ).sort();
- testFiles.length.should.eql(3);
- testFiles.should.eql([
- 'extKept-backups.1.log',
- 'extKept-backups.2.log',
- 'extKept-backups.log',
- ]);
- fs.readFile(path.join(__dirname, testFiles[0]), 'utf8', function(err, contents) {
- contents.should.eql('This is the third log message.\n');
- fs.readFile(path.join(__dirname, testFiles[1]), 'utf8',
- function(err, contents) {
- contents.toString('utf8').should.eql('This is the second log message.\n');
- fs.readFile(path.join(__dirname, testFiles[2]), 'utf8',
- function(err, contents) {
- contents.toString('utf8').should.eql('This is the fourth log message.\n');
- done(err);
- }
- );
- }
- );
- });
- });
- });
- after(function(done) {
- async.forEach([
- path.join(__dirname, 'extKept-backups.log'),
- path.join(__dirname, 'extKept-backups.1.log'),
- path.join(__dirname, 'extKept-backups.2.log'),
- ], remove, done);
- });
- });
- describe('with options.compress = true and keepFileExt = true', function() {
- before(function(done) {
- var stream = new RollingFileStream(
- path.join(__dirname, 'compressed-backups.log'),
- 30, //30 bytes max size
- 2, //two backup files to keep
- { compress: true, keepFileExt: true }
- );
- async.forEachSeries(
- [
- "This is the first log message.",
- "This is the second log message.",
- "This is the third log message.",
- "This is the fourth log message."
- ],
- function(i, cb) {
- stream.write(i + "\n", "utf8", cb);
- },
- function() {
- stream.end(done);
- }
- );
- });
- it('should produce three files, with the backups compressed', function(done) {
- fs.readdir(__dirname, function(err, files) {
- var testFiles = files.filter(
- function(f) { return f.indexOf('compressed-backups') > -1; }
- ).sort();
- testFiles.length.should.eql(3);
- testFiles.should.eql([
- 'compressed-backups.1.log.gz',
- 'compressed-backups.2.log.gz',
- 'compressed-backups.log',
- ]);
- fs.readFile(path.join(__dirname, testFiles[2]), 'utf8', function(err, contents) {
- contents.should.eql('This is the fourth log message.\n');
- zlib.gunzip(fs.readFileSync(path.join(__dirname, testFiles[1])),
- function(err, contents) {
- contents.toString('utf8').should.eql('This is the second log message.\n');
- zlib.gunzip(fs.readFileSync(path.join(__dirname, testFiles[0])),
- function(err, contents) {
- contents.toString('utf8').should.eql('This is the third log message.\n');
- done(err);
- }
- );
- }
- );
- });
- });
- });
- after(function(done) {
- async.forEach([
- path.join(__dirname, 'compressed-backups.log'),
- path.join(__dirname, 'compressed-backups.1.log.gz'),
- path.join(__dirname, 'compressed-backups.2.log.gz'),
- ], remove, done);
- });
- });
- describe('when many files already exist', function() {
- before(function(done) {
- async.forEach(
- [
- __dirname + '/test-rolling-stream-with-existing-files.11',
- __dirname + '/test-rolling-stream-with-existing-files.20',
- __dirname + '/test-rolling-stream-with-existing-files.-1',
- __dirname + '/test-rolling-stream-with-existing-files.1.1',
- __dirname + '/test-rolling-stream-with-existing-files.1'
- ],
- remove,
- function(err) {
- if (err) done(err);
- async.forEach(
- [
- __dirname + '/test-rolling-stream-with-existing-files.11',
- __dirname + '/test-rolling-stream-with-existing-files.20',
- __dirname + '/test-rolling-stream-with-existing-files.-1',
- __dirname + '/test-rolling-stream-with-existing-files.1.1',
- __dirname + '/test-rolling-stream-with-existing-files.1'
- ],
- create,
- function(err) {
- if (err) done(err);
- var stream = new RollingFileStream(
- __dirname + "/test-rolling-stream-with-existing-files",
- 45,
- 5
- );
- async.forEachSeries(
- [0, 1, 2, 3, 4, 5, 6],
- function(i, cb) {
- stream.write(i +".cheese\n", "utf8", cb);
- },
- function() {
- stream.end(done);
- }
- );
- }
- );
- }
- );
- });
- after(function(done) {
- async.forEach([
- __dirname + '/test-rolling-stream-with-existing-files',
- __dirname + '/test-rolling-stream-with-existing-files.0',
- __dirname + '/test-rolling-stream-with-existing-files.1',
- __dirname + '/test-rolling-stream-with-existing-files.2',
- __dirname + '/test-rolling-stream-with-existing-files.3',
- __dirname + '/test-rolling-stream-with-existing-files.4',
- __dirname + '/test-rolling-stream-with-existing-files.5',
- __dirname + '/test-rolling-stream-with-existing-files.11',
- __dirname + '/test-rolling-stream-with-existing-files.20'
- ], remove, done);
- });
- it('should roll the files', function(done) {
- fs.readdir(__dirname, function(err, files) {
- files.should.containEql('test-rolling-stream-with-existing-files');
- files.should.containEql('test-rolling-stream-with-existing-files.1');
- files.should.containEql('test-rolling-stream-with-existing-files.2');
- files.should.containEql('test-rolling-stream-with-existing-files.11');
- files.should.containEql('test-rolling-stream-with-existing-files.20');
- done(err);
- });
- });
- });
- describe('when the directory gets deleted', function() {
- var stream;
- before(function(done) {
- stream = new RollingFileStream(path.join('subdir', 'test-rolling-file-stream'), 5, 5);
- stream.write('initial', 'utf8', done);
- });
- after(function() {
- fs.unlinkSync(path.join('subdir', 'test-rolling-file-stream'));
- fs.rmdirSync('subdir');
- });
- it('handles directory deletion gracefully', function(done) {
- stream.theStream.on('error', done);
- remove(path.join('subdir', 'test-rolling-file-stream'), function() {
- fs.rmdir('subdir', function() {
- stream.write('rollover', 'utf8', function() {
- fs.readFileSync(path.join('subdir', 'test-rolling-file-stream'), 'utf8')
- .should.eql('rollover');
- done();
- });
- });
- });
- });
- });
- });
|