| require("should"); |
| |
| const fs = require("fs-extra"), |
| path = require("path"), |
| zlib = require("zlib"), |
| proxyquire = require("proxyquire").noPreserveCache(), |
| util = require("util"), |
| streams = require("stream"); |
| |
| let fakeNow = new Date(2012, 8, 12, 10, 37, 11); |
| const mockNow = () => fakeNow; |
| const RollingFileWriteStream = proxyquire("../lib/RollingFileWriteStream", { |
| "./now": mockNow |
| }); |
| const DateRollingFileStream = proxyquire("../lib/DateRollingFileStream", { |
| "./RollingFileWriteStream": RollingFileWriteStream |
| }); |
| |
| const gunzip = util.promisify(zlib.gunzip); |
| const gzip = util.promisify(zlib.gzip); |
| const remove = filename => fs.unlink(filename).catch(() => {}); |
| const close = async (stream) => new Promise( |
| (resolve, reject) => stream.end(e => e ? reject(e) : resolve()) |
| ); |
| |
| describe("DateRollingFileStream", function() { |
| describe("arguments", function() { |
| let stream; |
| |
| before(function() { |
| stream = new DateRollingFileStream( |
| path.join(__dirname, "test-date-rolling-file-stream-1"), |
| "yyyy-MM-dd.hh" |
| ); |
| }); |
| |
| after(async function() { |
| await close(stream); |
| await remove(path.join(__dirname, "test-date-rolling-file-stream-1")); |
| }); |
| |
| it("should take a filename and a pattern and return a WritableStream", function() { |
| stream.filename.should.eql( |
| path.join(__dirname, "test-date-rolling-file-stream-1") |
| ); |
| stream.options.pattern.should.eql("yyyy-MM-dd.hh"); |
| stream.should.be.instanceOf(streams.Writable); |
| }); |
| |
| it("with default settings for the underlying stream", function() { |
| stream.currentFileStream.mode.should.eql(420); |
| stream.currentFileStream.flags.should.eql("a"); |
| }); |
| }); |
| |
| describe("default arguments", function() { |
| var stream; |
| |
| before(function() { |
| stream = new DateRollingFileStream( |
| path.join(__dirname, "test-date-rolling-file-stream-2") |
| ); |
| }); |
| |
| after(async function() { |
| await close(stream); |
| await remove(path.join(__dirname, "test-date-rolling-file-stream-2")); |
| }); |
| |
| it("should have pattern of .yyyy-MM-dd", function() { |
| stream.options.pattern.should.eql("yyyy-MM-dd"); |
| }); |
| }); |
| |
| describe("with stream arguments", function() { |
| var stream; |
| |
| before(function() { |
| stream = new DateRollingFileStream( |
| path.join(__dirname, "test-date-rolling-file-stream-3"), |
| "yyyy-MM-dd", |
| { mode: parseInt("0666", 8) } |
| ); |
| }); |
| |
| after(async function() { |
| await close(stream); |
| await remove(path.join(__dirname, "test-date-rolling-file-stream-3")); |
| }); |
| |
| it("should pass them to the underlying stream", function() { |
| stream.theStream.mode.should.eql(parseInt("0666", 8)); |
| }); |
| }); |
| |
| describe("with stream arguments but no pattern", function() { |
| var stream; |
| |
| before(function() { |
| stream = new DateRollingFileStream( |
| path.join(__dirname, "test-date-rolling-file-stream-4"), |
| { mode: parseInt("0666", 8) } |
| ); |
| }); |
| |
| after(async function() { |
| await close(stream); |
| await remove(path.join(__dirname, "test-date-rolling-file-stream-4")); |
| }); |
| |
| it("should pass them to the underlying stream", function() { |
| stream.theStream.mode.should.eql(parseInt("0666", 8)); |
| }); |
| |
| it("should use default pattern", function() { |
| stream.options.pattern.should.eql("yyyy-MM-dd"); |
| }); |
| }); |
| |
| describe("with a pattern of .yyyy-MM-dd", function() { |
| var stream; |
| |
| before(function(done) { |
| stream = new DateRollingFileStream( |
| path.join(__dirname, "test-date-rolling-file-stream-5"), |
| ".yyyy-MM-dd", |
| null |
| ); |
| stream.write("First message\n", "utf8", done); |
| }); |
| |
| after(async function() { |
| await close(stream); |
| await remove(path.join(__dirname, "test-date-rolling-file-stream-5")); |
| }); |
| |
| it("should create a file with the base name", async function() { |
| const contents = await fs.readFile( |
| path.join(__dirname, "test-date-rolling-file-stream-5"), |
| "utf8" |
| ); |
| contents.should.eql("First message\n"); |
| }); |
| |
| describe("when the day changes", function() { |
| before(function(done) { |
| fakeNow = new Date(2012, 8, 13, 0, 10, 12); |
| stream.write("Second message\n", "utf8", done); |
| }); |
| |
| after(async function() { |
| await remove( |
| path.join(__dirname, "test-date-rolling-file-stream-5.2012-09-12") |
| ); |
| }); |
| |
| describe("the number of files", function() { |
| it("should be two", async function() { |
| const files = await fs.readdir(__dirname); |
| files |
| .filter( |
| file => file.indexOf("test-date-rolling-file-stream-5") > -1 |
| ) |
| .should.have.length(2); |
| }); |
| }); |
| |
| describe("the file without a date", function() { |
| it("should contain the second message", async function() { |
| const contents = await fs.readFile( |
| path.join(__dirname, "test-date-rolling-file-stream-5"), |
| "utf8" |
| ); |
| contents.should.eql("Second message\n"); |
| }); |
| }); |
| |
| describe("the file with the date", function() { |
| it("should contain the first message", async function() { |
| const contents = await fs.readFile( |
| path.join(__dirname, "test-date-rolling-file-stream-5.2012-09-12"), |
| "utf8" |
| ); |
| contents.should.eql("First message\n"); |
| }); |
| }); |
| }); |
| }); |
| |
| describe("with alwaysIncludePattern", function() { |
| var stream; |
| |
| before(async function() { |
| fakeNow = new Date(2012, 8, 12, 11, 10, 12); |
| await remove( |
| path.join( |
| __dirname, |
| "test-date-rolling-file-stream-pattern.2012-09-12-11.log" |
| ) |
| ); |
| stream = new DateRollingFileStream( |
| path.join(__dirname, "test-date-rolling-file-stream-pattern"), |
| ".yyyy-MM-dd-hh.log", |
| { alwaysIncludePattern: true } |
| ); |
| |
| await new Promise(resolve => { |
| setTimeout(function() { |
| stream.write("First message\n", "utf8", () => resolve()); |
| }, 50); |
| }); |
| }); |
| |
| after(async function() { |
| await close(stream); |
| await remove( |
| path.join( |
| __dirname, |
| "test-date-rolling-file-stream-pattern.2012-09-12-11.log" |
| ) |
| ); |
| }); |
| |
| it("should create a file with the pattern set", async function() { |
| const contents = await fs.readFile( |
| path.join( |
| __dirname, |
| "test-date-rolling-file-stream-pattern.2012-09-12-11.log" |
| ), |
| "utf8" |
| ); |
| contents.should.eql("First message\n"); |
| }); |
| |
| describe("when the day changes", function() { |
| before(function(done) { |
| fakeNow = new Date(2012, 8, 12, 12, 10, 12); |
| stream.write("Second message\n", "utf8", done); |
| }); |
| |
| after(async function() { |
| await remove( |
| path.join( |
| __dirname, |
| "test-date-rolling-file-stream-pattern.2012-09-12-12.log" |
| ) |
| ); |
| }); |
| |
| describe("the number of files", function() { |
| it("should be two", async function() { |
| const files = await fs.readdir(__dirname); |
| files |
| .filter( |
| file => file.indexOf("test-date-rolling-file-stream-pattern") > -1 |
| ) |
| .should.have.length(2); |
| }); |
| }); |
| |
| describe("the file with the later date", function() { |
| it("should contain the second message", async function() { |
| const contents = await fs.readFile( |
| path.join( |
| __dirname, |
| "test-date-rolling-file-stream-pattern.2012-09-12-12.log" |
| ), |
| "utf8" |
| ); |
| contents.should.eql("Second message\n"); |
| }); |
| }); |
| |
| describe("the file with the date", function() { |
| it("should contain the first message", async function() { |
| const contents = await fs.readFile( |
| path.join( |
| __dirname, |
| "test-date-rolling-file-stream-pattern.2012-09-12-11.log" |
| ), |
| "utf8" |
| ); |
| contents.should.eql("First message\n"); |
| }); |
| }); |
| }); |
| }); |
| |
| describe("with a pattern that evaluates to digits", function() { |
| let stream; |
| before(done => { |
| fakeNow = new Date(2012, 8, 12, 0, 10, 12); |
| stream = new DateRollingFileStream( |
| path.join(__dirname, "digits.log"), |
| ".yyyyMMdd" |
| ); |
| stream.write("First message\n", "utf8", done); |
| }); |
| |
| describe("when the day changes", function() { |
| before(function(done) { |
| fakeNow = new Date(2012, 8, 13, 0, 10, 12); |
| stream.write("Second message\n", "utf8", done); |
| }); |
| |
| it("should be two files (it should not get confused by indexes)", async function() { |
| const files = await fs.readdir(__dirname); |
| var logFiles = files.filter(file => file.indexOf("digits.log") > -1); |
| logFiles.should.have.length(2); |
| |
| const contents = await fs.readFile( |
| path.join(__dirname, "digits.log.20120912"), |
| "utf8" |
| ); |
| contents.should.eql("First message\n"); |
| const c = await fs.readFile(path.join(__dirname, "digits.log"), "utf8"); |
| c.should.eql("Second message\n"); |
| }); |
| }); |
| |
| after(async function() { |
| await close(stream); |
| await remove(path.join(__dirname, "digits.log")); |
| await remove(path.join(__dirname, "digits.log.20120912")); |
| }); |
| }); |
| |
| describe("with compress option", function() { |
| var stream; |
| |
| before(function(done) { |
| fakeNow = new Date(2012, 8, 12, 0, 10, 12); |
| stream = new DateRollingFileStream( |
| path.join(__dirname, "compressed.log"), |
| ".yyyy-MM-dd", |
| { compress: true } |
| ); |
| stream.write("First message\n", "utf8", done); |
| }); |
| |
| describe("when the day changes", function() { |
| before(function(done) { |
| fakeNow = new Date(2012, 8, 13, 0, 10, 12); |
| stream.write("Second message\n", "utf8", done); |
| }); |
| |
| it("should be two files, one compressed", async function() { |
| const files = await fs.readdir(__dirname); |
| var logFiles = files.filter( |
| file => file.indexOf("compressed.log") > -1 |
| ); |
| logFiles.should.have.length(2); |
| |
| const gzipped = await fs.readFile( |
| path.join(__dirname, "compressed.log.2012-09-12.gz") |
| ); |
| const contents = await gunzip(gzipped); |
| contents.toString("utf8").should.eql("First message\n"); |
| |
| (await fs.readFile( |
| path.join(__dirname, "compressed.log"), |
| "utf8" |
| )).should.eql("Second message\n"); |
| }); |
| }); |
| |
| after(async function() { |
| await close(stream); |
| await remove(path.join(__dirname, "compressed.log")); |
| await remove(path.join(__dirname, "compressed.log.2012-09-12.gz")); |
| }); |
| }); |
| |
| describe("with keepFileExt option", function() { |
| var stream; |
| |
| before(function(done) { |
| fakeNow = new Date(2012, 8, 12, 0, 10, 12); |
| stream = new DateRollingFileStream( |
| path.join(__dirname, "keepFileExt.log"), |
| ".yyyy-MM-dd", |
| { keepFileExt: true } |
| ); |
| stream.write("First message\n", "utf8", done); |
| }); |
| |
| describe("when the day changes", function() { |
| before(function(done) { |
| fakeNow = new Date(2012, 8, 13, 0, 10, 12); |
| stream.write("Second message\n", "utf8", done); |
| }); |
| |
| it("should be two files", async function() { |
| const files = await fs.readdir(__dirname); |
| var logFiles = files.filter(file => file.indexOf("keepFileExt") > -1); |
| logFiles.should.have.length(2); |
| |
| (await fs.readFile( |
| path.join(__dirname, "keepFileExt.2012-09-12.log"), |
| "utf8" |
| )).should.eql("First message\n"); |
| (await fs.readFile( |
| path.join(__dirname, "keepFileExt.log"), |
| "utf8" |
| )).should.eql("Second message\n"); |
| }); |
| }); |
| |
| after(async function() { |
| await close(stream); |
| await remove(path.join(__dirname, "keepFileExt.log")); |
| await remove(path.join(__dirname, "keepFileExt.2012-09-12.log")); |
| }); |
| }); |
| |
| describe("with compress option and keepFileExt option", function() { |
| var stream; |
| |
| before(function(done) { |
| fakeNow = new Date(2012, 8, 12, 0, 10, 12); |
| stream = new DateRollingFileStream( |
| path.join(__dirname, "compressedAndKeepExt.log"), |
| ".yyyy-MM-dd", |
| { compress: true, keepFileExt: true } |
| ); |
| stream.write("First message\n", "utf8", done); |
| }); |
| |
| describe("when the day changes", function() { |
| before(function(done) { |
| fakeNow = new Date(2012, 8, 13, 0, 10, 12); |
| stream.write("Second message\n", "utf8", done); |
| }); |
| |
| it("should be two files, one compressed", async function() { |
| const files = await fs.readdir(__dirname); |
| var logFiles = files.filter( |
| file => file.indexOf("compressedAndKeepExt") > -1 |
| ); |
| logFiles.should.have.length(2); |
| |
| const gzipped = await fs.readFile( |
| path.join(__dirname, "compressedAndKeepExt.2012-09-12.log.gz") |
| ); |
| const contents = await gunzip(gzipped); |
| contents.toString("utf8").should.eql("First message\n"); |
| (await fs.readFile( |
| path.join(__dirname, "compressedAndKeepExt.log"), |
| "utf8" |
| )).should.eql("Second message\n"); |
| }); |
| }); |
| |
| after(async function() { |
| await close(stream); |
| await remove(path.join(__dirname, "compressedAndKeepExt.log")); |
| await remove( |
| path.join(__dirname, "compressedAndKeepExt.2012-09-12.log.gz") |
| ); |
| }); |
| }); |
| |
| describe("with daysToKeep option", function() { |
| let stream; |
| var daysToKeep = 4; |
| var numOriginalLogs = 10; |
| |
| before(async function() { |
| for (let i = 0; i < numOriginalLogs; i += 1) { |
| await fs.writeFile( |
| path.join(__dirname, `daysToKeep.log.2012-09-${20-i}`), |
| `Message on day ${i}\n`, |
| { encoding: "utf-8" } |
| ); |
| } |
| stream = new DateRollingFileStream( |
| path.join(__dirname, "daysToKeep.log"), |
| ".yyyy-MM-dd", |
| { |
| alwaysIncludePattern: true, |
| daysToKeep: daysToKeep |
| } |
| ); |
| }); |
| |
| describe("when the day changes", function() { |
| before(function(done) { |
| fakeNow = new Date(2012, 8, 21, 0, 10, 12); |
| stream.write("Second message\n", "utf8", done); |
| }); |
| |
| it("should be daysToKeep + 1 files left from numOriginalLogs", async function() { |
| const files = await fs.readdir(__dirname); |
| var logFiles = files.filter( |
| file => file.indexOf("daysToKeep.log") > -1 |
| ); |
| logFiles.should.have.length(daysToKeep + 1); |
| }); |
| }); |
| |
| after(async function() { |
| await close(stream); |
| const files = await fs.readdir(__dirname); |
| const logFiles = files |
| .filter(file => file.indexOf("daysToKeep.log") > -1) |
| .map(f => remove(path.join(__dirname, f))); |
| await Promise.all(logFiles); |
| }); |
| }); |
| |
| describe("with daysToKeep and compress options", function() { |
| let stream; |
| const daysToKeep = 4; |
| const numOriginalLogs = 10; |
| |
| before(async function() { |
| for (let i = numOriginalLogs; i >= 0; i -= 1) { |
| fakeNow = new Date(2012, 8, 20 - i, 0, 10, 12); |
| const contents = await gzip(`Message on day ${i}\n`); |
| await fs.writeFile( |
| path.join(__dirname, `compressedDaysToKeep.log.2012-09-${20-i}.gz`), |
| contents |
| ); |
| } |
| stream = new DateRollingFileStream( |
| path.join(__dirname, "compressedDaysToKeep.log"), |
| ".yyyy-MM-dd", |
| { |
| alwaysIncludePattern: true, |
| compress: true, |
| daysToKeep: daysToKeep |
| } |
| ); |
| }); |
| |
| describe("when the day changes", function() { |
| before(function(done) { |
| fakeNow = new Date(2012, 8, 21, 0, 10, 12); |
| stream.write("New file message\n", "utf8", done); |
| }); |
| |
| it("should be 4 files left from original 3", async function() { |
| const files = await fs.readdir(__dirname); |
| var logFiles = files.filter( |
| file => file.indexOf("compressedDaysToKeep.log") > -1 |
| ); |
| logFiles.should.have.length(daysToKeep + 1); |
| }); |
| }); |
| |
| after(async function() { |
| await close(stream); |
| const files = await fs.readdir(__dirname); |
| const logFiles = files |
| .filter(file => file.indexOf("compressedDaysToKeep.log") > -1) |
| .map(f => remove(path.join(__dirname, f))); |
| await Promise.all(logFiles); |
| }); |
| }); |
| }); |