source: trip-planner-front/node_modules/streamroller/test/RollingFileWriteStream-test.js@ 6fe77af

Last change on this file since 6fe77af was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 39.6 KB
Line 
1require("should");
2
3const path = require("path");
4const zlib = require("zlib");
5const stream = require("stream");
6const fs = require("fs-extra");
7const proxyquire = require("proxyquire").noPreserveCache();
8
9let fakeNow = new Date(2012, 8, 12, 10, 37, 11);
10const mockNow = () => fakeNow;
11const RollingFileWriteStream = proxyquire("../lib/RollingFileWriteStream", {
12 "./now": mockNow
13});
14let fakedFsDate = fakeNow;
15const mockFs = require("fs-extra");
16const oldStatSync = mockFs.statSync;
17mockFs.statSync = fd => {
18 const result = oldStatSync(fd);
19 result.mtime = fakedFsDate;
20 return result;
21};
22
23function generateTestFile(fileName) {
24 const dirName = path.join(
25 __dirname,
26 "tmp_" + Math.floor(Math.random() * new Date())
27 );
28 fileName = fileName || "ignored.log";
29 const fileNameObj = path.parse(fileName);
30 return {
31 dir: dirName,
32 base: fileNameObj.base,
33 name: fileNameObj.name,
34 ext: fileNameObj.ext,
35 path: path.join(dirName, fileName)
36 };
37}
38
39function resetTime() {
40 fakeNow = new Date(2012, 8, 12, 10, 37, 11);
41 fakedFsDate = fakeNow;
42}
43
44describe("RollingFileWriteStream", () => {
45 beforeEach(() => {
46 resetTime();
47 });
48
49 after(() => {
50 fs.readdirSync(__dirname)
51 .filter(f => f.startsWith("tmp_"))
52 .forEach(f => fs.removeSync(path.join(__dirname, f)));
53 });
54
55 describe("with no arguments", () => {
56 it("should throw an error", () => {
57 (() => new RollingFileWriteStream()).should.throw(
58 /(the )?"?path"? (argument )?must be (a|of type) string\. received (type )?undefined/i
59 );
60 });
61 });
62
63 describe("with invalid options", () => {
64 after(done => {
65 fs.remove("filename", done);
66 });
67
68 it("should complain about a negative maxSize", () => {
69 (() => {
70 new RollingFileWriteStream("filename", { maxSize: -3 });
71 }).should.throw("options.maxSize (-3) should be > 0");
72 (() => {
73 new RollingFileWriteStream("filename", { maxSize: 0 });
74 }).should.throw("options.maxSize (0) should be > 0");
75 });
76
77 it("should complain about a negative numToKeep", () => {
78 (() => {
79 new RollingFileWriteStream("filename", { numToKeep: -3 });
80 }).should.throw("options.numToKeep (-3) should be > 0");
81 (() => {
82 new RollingFileWriteStream("filename", { numToKeep: 0 });
83 }).should.throw("options.numToKeep (0) should be > 0");
84 });
85 });
86
87 describe("with default arguments", () => {
88 const fileObj = generateTestFile();
89 let s;
90
91 before(() => {
92 s = new RollingFileWriteStream(fileObj.path);
93 });
94
95 after(() => {
96 s.end(() => fs.removeSync(fileObj.dir));
97 });
98
99 it("should take a filename and options, return Writable", () => {
100 s.should.be.an.instanceOf(stream.Writable);
101 s.currentFileStream.path.should.eql(fileObj.path);
102 s.currentFileStream.mode.should.eql(420);
103 s.currentFileStream.flags.should.eql("a");
104 });
105
106 it("should apply default options", () => {
107 s.options.maxSize.should.eql(Number.MAX_SAFE_INTEGER);
108 s.options.encoding.should.eql("utf8");
109 s.options.mode.should.eql(420);
110 s.options.flags.should.eql("a");
111 s.options.compress.should.eql(false);
112 s.options.keepFileExt.should.eql(false);
113 });
114 });
115
116 describe("with 5 maxSize, rotating daily", () => {
117 const fileObj = generateTestFile("noExtension");
118 let s;
119
120 before(async () => {
121 fakeNow = new Date(2012, 8, 12, 10, 37, 11);
122 s = new RollingFileWriteStream(fileObj.path, {
123 pattern: "yyyy-MM-dd",
124 maxSize: 5
125 });
126 const flows = Array.from(Array(38).keys()).map(i => () => {
127 fakeNow = new Date(2012, 8, 12 + parseInt(i / 5, 10), 10, 37, 11);
128 return new Promise(resolve => {
129 s.write(i.toString(), "utf8", () => resolve());
130 });
131 });
132 for (let i = 0; i < flows.length; i += 1) {
133 await flows[i]();
134 }
135 });
136
137 after(done => {
138 s.end(() => {
139 fs.removeSync(fileObj.dir);
140 done();
141 });
142 });
143
144 it("should rotate using filename with no extension", () => {
145 const files = fs.readdirSync(fileObj.dir);
146 const expectedFileList = [
147 fileObj.base, //353637
148 fileObj.base + ".2012-09-12.1", // 01234
149 fileObj.base + ".2012-09-13.1", // 56789
150 fileObj.base + ".2012-09-14.2", // 101112
151 fileObj.base + ".2012-09-14.1", // 1314
152 fileObj.base + ".2012-09-15.2", // 151617
153 fileObj.base + ".2012-09-15.1", // 1819
154 fileObj.base + ".2012-09-16.2", // 202122
155 fileObj.base + ".2012-09-16.1", // 2324
156 fileObj.base + ".2012-09-17.2", // 252627
157 fileObj.base + ".2012-09-17.1", // 2829
158 fileObj.base + ".2012-09-18.2", // 303132
159 fileObj.base + ".2012-09-18.1" // 3334
160 ];
161 files.should.containDeep(expectedFileList);
162 files.length.should.equal(expectedFileList.length);
163 fs.readFileSync(path.format(fileObj))
164 .toString()
165 .should.equal("353637");
166 fs.readFileSync(
167 path.format(
168 Object.assign({}, fileObj, {
169 base: fileObj.base + ".2012-09-12.1"
170 })
171 )
172 )
173 .toString()
174 .should.equal("01234");
175 fs.readFileSync(
176 path.format(
177 Object.assign({}, fileObj, {
178 base: fileObj.base + ".2012-09-13.1"
179 })
180 )
181 )
182 .toString()
183 .should.equal("56789");
184 fs.readFileSync(
185 path.format(
186 Object.assign({}, fileObj, {
187 base: fileObj.base + ".2012-09-14.2"
188 })
189 )
190 )
191 .toString()
192 .should.equal("101112");
193 fs.readFileSync(
194 path.format(
195 Object.assign({}, fileObj, {
196 base: fileObj.base + ".2012-09-14.1"
197 })
198 )
199 )
200 .toString()
201 .should.equal("1314");
202 fs.readFileSync(
203 path.format(
204 Object.assign({}, fileObj, {
205 base: fileObj.base + ".2012-09-15.2"
206 })
207 )
208 )
209 .toString()
210 .should.equal("151617");
211 fs.readFileSync(
212 path.format(
213 Object.assign({}, fileObj, {
214 base: fileObj.base + ".2012-09-15.1"
215 })
216 )
217 )
218 .toString()
219 .should.equal("1819");
220 fs.readFileSync(
221 path.format(
222 Object.assign({}, fileObj, {
223 base: fileObj.base + ".2012-09-16.2"
224 })
225 )
226 )
227 .toString()
228 .should.equal("202122");
229 fs.readFileSync(
230 path.format(
231 Object.assign({}, fileObj, {
232 base: fileObj.base + ".2012-09-16.1"
233 })
234 )
235 )
236 .toString()
237 .should.equal("2324");
238 fs.readFileSync(
239 path.format(
240 Object.assign({}, fileObj, {
241 base: fileObj.base + ".2012-09-17.2"
242 })
243 )
244 )
245 .toString()
246 .should.equal("252627");
247 fs.readFileSync(
248 path.format(
249 Object.assign({}, fileObj, {
250 base: fileObj.base + ".2012-09-17.1"
251 })
252 )
253 )
254 .toString()
255 .should.equal("2829");
256 fs.readFileSync(
257 path.format(
258 Object.assign({}, fileObj, {
259 base: fileObj.base + ".2012-09-18.2"
260 })
261 )
262 )
263 .toString()
264 .should.equal("303132");
265 fs.readFileSync(
266 path.format(
267 Object.assign({}, fileObj, {
268 base: fileObj.base + ".2012-09-18.1"
269 })
270 )
271 )
272 .toString()
273 .should.equal("3334");
274 });
275 });
276
277 describe("with default arguments and recreated in the same day", () => {
278 const fileObj = generateTestFile();
279 let s;
280
281 before(async () => {
282 const flows = Array.from(Array(3).keys()).map(() => () => {
283 s = new RollingFileWriteStream(fileObj.path);
284 return new Promise(resolve => {
285 s.end("abc", "utf8", () => resolve());
286 });
287 });
288 for (let i = 0; i < flows.length; i += 1) {
289 await flows[i]();
290 }
291 });
292
293 after(() => {
294 fs.removeSync(fileObj.dir);
295 });
296
297 it("should have only 1 file", () => {
298 const files = fs.readdirSync(fileObj.dir);
299 const expectedFileList = [fileObj.base];
300 files.should.containDeep(expectedFileList);
301 files.length.should.equal(expectedFileList.length);
302 fs.readFileSync(
303 path.format(
304 Object.assign({}, fileObj, {
305 base: fileObj.base
306 })
307 )
308 )
309 .toString()
310 .should.equal("abcabcabc");
311 });
312 });
313
314 describe("with 5 maxSize, using filename with extension", () => {
315 const fileObj = generateTestFile("withExtension.log");
316 let s;
317
318 before(async () => {
319 fakeNow = new Date(2012, 8, 12, 10, 37, 11);
320 s = new RollingFileWriteStream(fileObj.path, {
321 pattern: "yyyy-MM-dd",
322 maxSize: 5
323 });
324 const flows = Array.from(Array(38).keys()).map(i => () => {
325 fakeNow = new Date(2012, 8, 12 + parseInt(i / 10, 10), 10, 37, 11);
326 return new Promise(resolve => {
327 s.write(i.toString(), "utf8", () => resolve());
328 });
329 });
330 for (let i = 0; i < flows.length; i += 1) {
331 await flows[i]();
332 }
333 });
334
335 after(done => {
336 s.end(() => {
337 fs.removeSync(fileObj.dir);
338 done();
339 })
340 });
341
342 it("should rotate files within the day, and when the day changes", () => {
343 const files = fs.readdirSync(fileObj.dir);
344 const expectedFileList = [
345 fileObj.base, //3637
346 fileObj.base + ".2012-09-12.2", //01234
347 fileObj.base + ".2012-09-12.1", //56789
348 fileObj.base + ".2012-09-13.4", //101112
349 fileObj.base + ".2012-09-13.3", //131415
350 fileObj.base + ".2012-09-13.2", //161718
351 fileObj.base + ".2012-09-13.1", //19
352 fileObj.base + ".2012-09-14.4", //202122
353 fileObj.base + ".2012-09-14.3", //232425
354 fileObj.base + ".2012-09-14.2", //262728
355 fileObj.base + ".2012-09-14.1", //29
356 fileObj.base + ".2012-09-15.2", //303132
357 fileObj.base + ".2012-09-15.1" //333435
358 ];
359 files.should.containDeep(expectedFileList);
360 files.length.should.equal(expectedFileList.length);
361 fs.readFileSync(path.format(fileObj))
362 .toString()
363 .should.equal("3637");
364 fs.readFileSync(
365 path.format(
366 Object.assign({}, fileObj, {
367 base: fileObj.base + ".2012-09-12.2"
368 })
369 )
370 )
371 .toString()
372 .should.equal("01234");
373 fs.readFileSync(
374 path.format(
375 Object.assign({}, fileObj, {
376 base: fileObj.base + ".2012-09-12.1"
377 })
378 )
379 )
380 .toString()
381 .should.equal("56789");
382 fs.readFileSync(
383 path.format(
384 Object.assign({}, fileObj, {
385 base: fileObj.base + ".2012-09-13.4"
386 })
387 )
388 )
389 .toString()
390 .should.equal("101112");
391 fs.readFileSync(
392 path.format(
393 Object.assign({}, fileObj, {
394 base: fileObj.base + ".2012-09-13.3"
395 })
396 )
397 )
398 .toString()
399 .should.equal("131415");
400 fs.readFileSync(
401 path.format(
402 Object.assign({}, fileObj, {
403 base: fileObj.base + ".2012-09-13.2"
404 })
405 )
406 )
407 .toString()
408 .should.equal("161718");
409 fs.readFileSync(
410 path.format(
411 Object.assign({}, fileObj, {
412 base: fileObj.base + ".2012-09-13.1"
413 })
414 )
415 )
416 .toString()
417 .should.equal("19");
418 fs.readFileSync(
419 path.format(
420 Object.assign({}, fileObj, {
421 base: fileObj.base + ".2012-09-14.4"
422 })
423 )
424 )
425 .toString()
426 .should.equal("202122");
427 fs.readFileSync(
428 path.format(
429 Object.assign({}, fileObj, {
430 base: fileObj.base + ".2012-09-14.3"
431 })
432 )
433 )
434 .toString()
435 .should.equal("232425");
436 fs.readFileSync(
437 path.format(
438 Object.assign({}, fileObj, {
439 base: fileObj.base + ".2012-09-14.2"
440 })
441 )
442 )
443 .toString()
444 .should.equal("262728");
445 fs.readFileSync(
446 path.format(
447 Object.assign({}, fileObj, {
448 base: fileObj.base + ".2012-09-14.1"
449 })
450 )
451 )
452 .toString()
453 .should.equal("29");
454 fs.readFileSync(
455 path.format(
456 Object.assign({}, fileObj, {
457 base: fileObj.base + ".2012-09-15.2"
458 })
459 )
460 )
461 .toString()
462 .should.equal("303132");
463 fs.readFileSync(
464 path.format(
465 Object.assign({}, fileObj, {
466 base: fileObj.base + ".2012-09-15.1"
467 })
468 )
469 )
470 .toString()
471 .should.equal("333435");
472 });
473 });
474
475 describe("with 5 maxSize and 3 files limit", () => {
476 const fileObj = generateTestFile();
477 let s;
478
479 before(async () => {
480 fakeNow = new Date(2012, 8, 12, 10, 37, 11);
481 s = new RollingFileWriteStream(fileObj.path, {
482 maxSize: 5,
483 numToKeep: 3
484 });
485 const flows = Array.from(Array(38).keys()).map(i => () => {
486 fakeNow = new Date(2012, 8, 12 + parseInt(i / 5), 10, 37, 11);
487 return new Promise(resolve => {
488 s.write(i.toString(), "utf8", () => resolve());
489 });
490 });
491 for (let i = 0; i < flows.length; i += 1) {
492 await flows[i]();
493 }
494 });
495
496 after(done => {
497 s.end(() => {
498 fs.removeSync(fileObj.dir);
499 done();
500 });
501 });
502
503 it("should rotate with at most 3 backup files not including the hot one", () => {
504 const files = fs.readdirSync(fileObj.dir);
505 const expectedFileList = [
506 fileObj.base,
507 fileObj.base + ".1",
508 fileObj.base + ".2",
509 fileObj.base + ".3"
510 ];
511 files.should.containDeep(expectedFileList);
512 files.length.should.equal(expectedFileList.length);
513 fs.readFileSync(path.format(fileObj))
514 .toString()
515 .should.equal("37");
516 fs.readFileSync(
517 path.format(
518 Object.assign({}, fileObj, {
519 base: fileObj.base + ".1"
520 })
521 )
522 )
523 .toString()
524 .should.equal("343536");
525 fs.readFileSync(
526 path.format(
527 Object.assign({}, fileObj, {
528 base: fileObj.base + ".2"
529 })
530 )
531 )
532 .toString()
533 .should.equal("313233");
534 fs.readFileSync(
535 path.format(
536 Object.assign({}, fileObj, {
537 base: fileObj.base + ".3"
538 })
539 )
540 )
541 .toString()
542 .should.equal("282930");
543 });
544 });
545
546 describe("with 5 maxSize and 3 files limit, rotating daily", () => {
547 const fileObj = generateTestFile();
548 let s;
549
550 before(async () => {
551 fakeNow = new Date(2012, 8, 12, 10, 37, 11);
552 s = new RollingFileWriteStream(fileObj.path, {
553 maxSize: 5,
554 pattern: "yyyy-MM-dd",
555 numToKeep: 3
556 });
557 const flows = Array.from(Array(38).keys()).map(i => () => {
558 fakeNow = new Date(2012, 8, 12 + parseInt(i / 10), 10, 37, 11);
559 return new Promise(resolve => {
560 s.write(i.toString(), "utf8", () => resolve());
561 });
562 });
563 for (let i = 0; i < flows.length; i += 1) {
564 await flows[i]();
565 }
566 });
567
568 after(done => {
569 s.end(() => {
570 fs.removeSync(fileObj.dir);
571 done();
572 });
573 });
574
575 it("should rotate with at most 3 backup files not including the hot one", () => {
576 const files = fs.readdirSync(fileObj.dir);
577 const expectedFileList = [
578 fileObj.base, //3637
579 fileObj.base + ".2012-09-14.1", //29
580 fileObj.base + ".2012-09-15.2", //303132
581 fileObj.base + ".2012-09-15.1" //333435
582 ];
583 files.should.containDeep(expectedFileList);
584 files.length.should.equal(expectedFileList.length);
585 fs.readFileSync(path.format(fileObj))
586 .toString()
587 .should.equal("3637");
588 fs.readFileSync(
589 path.format(
590 Object.assign({}, fileObj, {
591 base: fileObj.base + ".2012-09-15.1"
592 })
593 )
594 )
595 .toString()
596 .should.equal("333435");
597 fs.readFileSync(
598 path.format(
599 Object.assign({}, fileObj, {
600 base: fileObj.base + ".2012-09-15.2"
601 })
602 )
603 )
604 .toString()
605 .should.equal("303132");
606 fs.readFileSync(
607 path.format(
608 Object.assign({}, fileObj, {
609 base: fileObj.base + ".2012-09-14.1"
610 })
611 )
612 )
613 .toString()
614 .should.equal("29");
615 });
616 });
617
618 describe("with date pattern dd-MM-yyyy", () => {
619 const fileObj = generateTestFile();
620 let s;
621
622 before(async () => {
623 fakeNow = new Date(2012, 8, 12, 10, 37, 11);
624 s = new RollingFileWriteStream(fileObj.path, {
625 maxSize: 5,
626 pattern: "dd-MM-yyyy"
627 });
628 const flows = Array.from(Array(8).keys()).map(i => () => {
629 fakeNow = new Date(2012, 8, 12 + parseInt(i / 5, 10), 10, 37, 11);
630 return new Promise(resolve => {
631 s.write(i.toString(), "utf8", () => resolve());
632 });
633 });
634 for (let i = 0; i < flows.length; i += 1) {
635 await flows[i]();
636 }
637 });
638
639 after(done => {
640 s.end(() => {
641 fs.remove(fileObj.dir, done);
642 });
643 });
644
645 it("should rotate with date pattern dd-MM-yyyy in the file name", () => {
646 const files = fs.readdirSync(fileObj.dir);
647 const expectedFileList = [fileObj.base, fileObj.base + ".12-09-2012.1"];
648 files.should.containDeep(expectedFileList);
649 files.length.should.equal(expectedFileList.length);
650 fs.readFileSync(path.format(fileObj))
651 .toString()
652 .should.equal("567");
653 fs.readFileSync(
654 path.format(
655 Object.assign({}, fileObj, {
656 base: fileObj.base + ".12-09-2012.1"
657 })
658 )
659 )
660 .toString()
661 .should.equal("01234");
662 });
663 });
664
665 describe("with compress true", () => {
666 const fileObj = generateTestFile();
667 let s;
668
669 before(async () => {
670 fakeNow = new Date(2012, 8, 12, 10, 37, 11);
671 s = new RollingFileWriteStream(fileObj.path, {
672 maxSize: 5,
673 pattern: "yyyy-MM-dd",
674 compress: true
675 });
676 const flows = Array.from(Array(8).keys()).map(i => () => {
677 fakeNow = new Date(2012, 8, 12 + parseInt(i / 5, 10), 10, 37, 11);
678 return new Promise(resolve => {
679 s.write(i.toString(), "utf8", () => resolve());
680 });
681 });
682 for (let i = 0; i < flows.length; i += 1) {
683 await flows[i]();
684 }
685 });
686
687 after(done => {
688 s.end(() => {
689 fs.removeSync(fileObj.dir);
690 done();
691 });
692 });
693
694 it("should rotate with gunzip", () => {
695 const files = fs.readdirSync(fileObj.dir);
696 const expectedFileList = [
697 fileObj.base,
698 fileObj.base + ".2012-09-12.1.gz"
699 ];
700 files.should.containDeep(expectedFileList);
701 files.length.should.equal(expectedFileList.length);
702
703 fs.readFileSync(path.format(fileObj))
704 .toString()
705 .should.equal("567");
706 const content = fs.readFileSync(
707 path.format(
708 Object.assign({}, fileObj, {
709 base: fileObj.base + ".2012-09-12.1.gz"
710 })
711 )
712 );
713 zlib
714 .gunzipSync(content)
715 .toString()
716 .should.equal("01234");
717 });
718 });
719
720 describe("with keepFileExt", () => {
721 const fileObj = generateTestFile("keepFileExt.log");
722 let s;
723
724 before(async () => {
725 fakeNow = new Date(2012, 8, 12, 10, 37, 11);
726 s = new RollingFileWriteStream(fileObj.path, {
727 pattern: "yyyy-MM-dd",
728 maxSize: 5,
729 keepFileExt: true
730 });
731 const flows = Array.from(Array(8).keys()).map(i => () => {
732 fakeNow = new Date(2012, 8, 12 + parseInt(i / 5, 10), 10, 37, 11);
733 return new Promise(resolve => {
734 s.write(i.toString(), "utf8", () => resolve());
735 });
736 });
737 for (let i = 0; i < flows.length; i += 1) {
738 await flows[i]();
739 }
740 });
741
742 after(done => {
743 s.end(() => {
744 fs.removeSync(fileObj.dir);
745 done();
746 });
747 });
748
749 it("should rotate with the same extension", () => {
750 const files = fs.readdirSync(fileObj.dir);
751 const expectedFileList = [
752 fileObj.base,
753 fileObj.name + ".2012-09-12.1.log"
754 ];
755 files.should.containDeep(expectedFileList);
756 files.length.should.equal(expectedFileList.length);
757
758 fs.readFileSync(path.format(fileObj))
759 .toString()
760 .should.equal("567");
761 fs.readFileSync(
762 path.format({
763 dir: fileObj.dir,
764 base: fileObj.name + ".2012-09-12.1" + fileObj.ext
765 })
766 )
767 .toString()
768 .should.equal("01234");
769 });
770 });
771
772 describe("with keepFileExt and compress", () => {
773 const fileObj = generateTestFile("keepFileExt.log");
774 let s;
775
776 before(async () => {
777 fakeNow = new Date(2012, 8, 12, 10, 37, 11);
778 s = new RollingFileWriteStream(fileObj.path, {
779 maxSize: 5,
780 pattern: "yyyy-MM-dd",
781 keepFileExt: true,
782 compress: true
783 });
784 const flows = Array.from(Array(8).keys()).map(i => () => {
785 fakeNow = new Date(2012, 8, 12 + parseInt(i / 5, 10), 10, 37, 11);
786 return new Promise(resolve => {
787 s.write(i.toString(), "utf8", () => resolve());
788 });
789 });
790 for (let i = 0; i < flows.length; i += 1) {
791 await flows[i]();
792 }
793 });
794
795 after(done => {
796 s.end(() => {
797 fs.removeSync(fileObj.dir);
798 done();
799 });
800 });
801
802 it("should rotate with the same extension", () => {
803 const files = fs.readdirSync(fileObj.dir);
804 const expectedFileList = [
805 fileObj.base,
806 fileObj.name + ".2012-09-12.1.log.gz"
807 ];
808 files.should.containDeep(expectedFileList);
809 files.length.should.equal(expectedFileList.length);
810
811 fs.readFileSync(path.format(fileObj))
812 .toString()
813 .should.equal("567");
814 const content = fs.readFileSync(
815 path.format(
816 Object.assign({}, fileObj, {
817 base: fileObj.name + ".2012-09-12.1.log.gz"
818 })
819 )
820 );
821 zlib
822 .gunzipSync(content)
823 .toString()
824 .should.equal("01234");
825 });
826 });
827
828 describe("with alwaysIncludePattern and keepFileExt", () => {
829 const fileObj = generateTestFile("keepFileExt.log");
830 let s;
831
832 before(async () => {
833 fakeNow = new Date(2012, 8, 12, 10, 37, 11);
834 s = new RollingFileWriteStream(fileObj.path, {
835 maxSize: 5,
836 pattern: "yyyy-MM-dd",
837 keepFileExt: true,
838 alwaysIncludePattern: true
839 });
840 const flows = Array.from(Array(8).keys()).map(i => () => {
841 fakeNow = new Date(2012, 8, 12 + parseInt(i / 5, 10), 10, 37, 11);
842 return new Promise(resolve => {
843 s.write(i.toString(), "utf8", () => resolve());
844 });
845 });
846 for (let i = 0; i < flows.length; i += 1) {
847 await flows[i]();
848 }
849 });
850
851 after(done => {
852 s.end(() => {
853 fs.removeSync(fileObj.dir);
854 done();
855 });
856 });
857
858 it("should rotate with the same extension and keep date in the filename", () => {
859 const files = fs.readdirSync(fileObj.dir);
860 const expectedFileList = [
861 fileObj.name + ".2012-09-12.1.log",
862 fileObj.name + ".2012-09-13.log"
863 ];
864 files.should.containDeep(expectedFileList);
865 files.length.should.equal(expectedFileList.length);
866 fs.readFileSync(
867 path.format(
868 Object.assign({}, fileObj, {
869 base: fileObj.name + ".2012-09-13.log"
870 })
871 )
872 )
873 .toString()
874 .should.equal("567");
875 fs.readFileSync(
876 path.format(
877 Object.assign({}, fileObj, {
878 base: fileObj.name + ".2012-09-12.1.log"
879 })
880 )
881 )
882 .toString()
883 .should.equal("01234");
884 });
885 });
886
887 describe("with 5 maxSize, compress, keepFileExt and alwaysIncludePattern", () => {
888 const fileObj = generateTestFile("keepFileExt.log");
889 let s;
890
891 before(async () => {
892 fakeNow = new Date(2012, 8, 12, 10, 37, 11);
893 s = new RollingFileWriteStream(fileObj.path, {
894 maxSize: 5,
895 compress: true,
896 keepFileExt: true,
897 alwaysIncludePattern: true,
898 pattern: "yyyy-MM-dd"
899 });
900 const flows = Array.from(Array(38).keys()).map(i => () => {
901 fakeNow = new Date(2012, 8, 12 + parseInt(i / 5, 10), 10, 37, 11);
902 return new Promise(resolve => {
903 s.write(i.toString(), "utf8", () => resolve());
904 });
905 });
906 for (let i = 0; i < flows.length; i += 1) {
907 await flows[i]();
908 }
909 });
910
911 after(done => {
912 s.end(() => {
913 fs.removeSync(fileObj.dir);
914 done();
915 });
916 });
917
918 it("should rotate every day", () => {
919 const files = fs.readdirSync(fileObj.dir);
920 const expectedFileList = [
921 fileObj.name + ".2012-09-12.1.log.gz", //01234
922 fileObj.name + ".2012-09-13.1.log.gz", //56789
923 fileObj.name + ".2012-09-14.2.log.gz", //101112
924 fileObj.name + ".2012-09-14.1.log.gz", //1314
925 fileObj.name + ".2012-09-15.2.log.gz", //151617
926 fileObj.name + ".2012-09-15.1.log.gz", //1819
927 fileObj.name + ".2012-09-16.2.log.gz", //202122
928 fileObj.name + ".2012-09-16.1.log.gz", //2324
929 fileObj.name + ".2012-09-17.2.log.gz", //252627
930 fileObj.name + ".2012-09-17.1.log.gz", //2829
931 fileObj.name + ".2012-09-18.2.log.gz", //303132
932 fileObj.name + ".2012-09-18.1.log.gz", //3334
933 fileObj.name + ".2012-09-19.log" //353637
934 ];
935 files.should.containDeep(expectedFileList);
936 files.length.should.equal(expectedFileList.length);
937 fs.readFileSync(
938 path.format(
939 Object.assign({}, fileObj, {
940 base: fileObj.name + ".2012-09-19.log"
941 })
942 )
943 )
944 .toString()
945 .should.equal("353637");
946 zlib
947 .gunzipSync(
948 fs.readFileSync(
949 path.format(
950 Object.assign({}, fileObj, {
951 base: fileObj.name + ".2012-09-18.1.log.gz"
952 })
953 )
954 )
955 )
956 .toString()
957 .should.equal("3334");
958 zlib
959 .gunzipSync(
960 fs.readFileSync(
961 path.format(
962 Object.assign({}, fileObj, {
963 base: fileObj.name + ".2012-09-18.2.log.gz"
964 })
965 )
966 )
967 )
968 .toString()
969 .should.equal("303132");
970 zlib
971 .gunzipSync(
972 fs.readFileSync(
973 path.format(
974 Object.assign({}, fileObj, {
975 base: fileObj.name + ".2012-09-17.1.log.gz"
976 })
977 )
978 )
979 )
980 .toString()
981 .should.equal("2829");
982 zlib
983 .gunzipSync(
984 fs.readFileSync(
985 path.format(
986 Object.assign({}, fileObj, {
987 base: fileObj.name + ".2012-09-17.2.log.gz"
988 })
989 )
990 )
991 )
992 .toString()
993 .should.equal("252627");
994 zlib
995 .gunzipSync(
996 fs.readFileSync(
997 path.format(
998 Object.assign({}, fileObj, {
999 base: fileObj.name + ".2012-09-16.1.log.gz"
1000 })
1001 )
1002 )
1003 )
1004 .toString()
1005 .should.equal("2324");
1006 zlib
1007 .gunzipSync(
1008 fs.readFileSync(
1009 path.format(
1010 Object.assign({}, fileObj, {
1011 base: fileObj.name + ".2012-09-16.2.log.gz"
1012 })
1013 )
1014 )
1015 )
1016 .toString()
1017 .should.equal("202122");
1018 zlib
1019 .gunzipSync(
1020 fs.readFileSync(
1021 path.format(
1022 Object.assign({}, fileObj, {
1023 base: fileObj.name + ".2012-09-15.1.log.gz"
1024 })
1025 )
1026 )
1027 )
1028 .toString()
1029 .should.equal("1819");
1030 zlib
1031 .gunzipSync(
1032 fs.readFileSync(
1033 path.format(
1034 Object.assign({}, fileObj, {
1035 base: fileObj.name + ".2012-09-15.2.log.gz"
1036 })
1037 )
1038 )
1039 )
1040 .toString()
1041 .should.equal("151617");
1042 zlib
1043 .gunzipSync(
1044 fs.readFileSync(
1045 path.format(
1046 Object.assign({}, fileObj, {
1047 base: fileObj.name + ".2012-09-14.1.log.gz"
1048 })
1049 )
1050 )
1051 )
1052 .toString()
1053 .should.equal("1314");
1054 zlib
1055 .gunzipSync(
1056 fs.readFileSync(
1057 path.format(
1058 Object.assign({}, fileObj, {
1059 base: fileObj.name + ".2012-09-14.2.log.gz"
1060 })
1061 )
1062 )
1063 )
1064 .toString()
1065 .should.equal("101112");
1066 zlib
1067 .gunzipSync(
1068 fs.readFileSync(
1069 path.format(
1070 Object.assign({}, fileObj, {
1071 base: fileObj.name + ".2012-09-13.1.log.gz"
1072 })
1073 )
1074 )
1075 )
1076 .toString()
1077 .should.equal("56789");
1078 zlib
1079 .gunzipSync(
1080 fs.readFileSync(
1081 path.format(
1082 Object.assign({}, fileObj, {
1083 base: fileObj.name + ".2012-09-12.1.log.gz"
1084 })
1085 )
1086 )
1087 )
1088 .toString()
1089 .should.equal("01234");
1090 });
1091 });
1092
1093 describe("when old files exist", () => {
1094 const fileObj = generateTestFile();
1095 let s;
1096
1097 before(done => {
1098 fakeNow = new Date(2012, 8, 12, 10, 37, 11);
1099 fs.ensureFileSync(fileObj.path);
1100 fs.writeFileSync(fileObj.path, "exist");
1101 s = new RollingFileWriteStream(fileObj.path);
1102 s.write("now", "utf8", done);
1103 });
1104
1105 after(done => {
1106 s.end(() => {
1107 fs.removeSync(fileObj.dir);
1108 done();
1109 });
1110 });
1111
1112 it("should use write in the old file if not reach the maxSize limit", () => {
1113 const files = fs.readdirSync(fileObj.dir);
1114 const expectedFileList = [fileObj.base];
1115 files.should.containDeep(expectedFileList);
1116 files.length.should.equal(expectedFileList.length);
1117
1118 fs.readFileSync(path.format(fileObj))
1119 .toString()
1120 .should.equal("existnow");
1121 });
1122 });
1123
1124 describe("when old files exist with contents", () => {
1125 const fileObj = generateTestFile();
1126 let s;
1127
1128 before(done => {
1129 fakeNow = new Date(2012, 8, 12, 10, 37, 11);
1130 fs.ensureFileSync(fileObj.path);
1131 fs.writeFileSync(fileObj.path, "This is exactly 30 bytes long\n");
1132 s = new RollingFileWriteStream(fileObj.path, { maxSize: 35 });
1133 s.write("one\n", "utf8"); //34
1134 s.write("two\n", "utf8"); //38 - file should be rotated next time
1135 s.write("three\n", "utf8", done); // this should be in a new file.
1136 });
1137
1138 after(done => {
1139 s.end(() => {
1140 fs.removeSync(fileObj.dir);
1141 done();
1142 });
1143 });
1144
1145 it("should respect the existing file size", () => {
1146 const files = fs.readdirSync(fileObj.dir);
1147 const expectedFileList = [fileObj.base, fileObj.base + ".1"];
1148 files.should.containDeep(expectedFileList);
1149 files.length.should.equal(expectedFileList.length);
1150
1151 fs.readFileSync(path.format(fileObj))
1152 .toString()
1153 .should.equal("three\n");
1154 fs.readFileSync(path.join(fileObj.dir, fileObj.base + ".1"))
1155 .toString()
1156 .should.equal("This is exactly 30 bytes long\none\ntwo\n");
1157 });
1158 });
1159
1160 describe("when old files exist with contents and the flag is a+", () => {
1161 const fileObj = generateTestFile();
1162 let s;
1163
1164 before(done => {
1165 fakeNow = new Date(2012, 8, 12, 10, 37, 11);
1166 fs.ensureFileSync(fileObj.path);
1167 fs.writeFileSync(fileObj.path, "This is exactly 30 bytes long\n");
1168 s = new RollingFileWriteStream(fileObj.path, {
1169 maxSize: 35,
1170 flags: "a+"
1171 });
1172 s.write("one\n", "utf8"); //34
1173 s.write("two\n", "utf8"); //38 - file should be rotated next time
1174 s.write("three\n", "utf8", done); // this should be in a new file.
1175 });
1176
1177 after(done => {
1178 s.end(() => {
1179 fs.removeSync(fileObj.dir);
1180 done();
1181 });
1182 });
1183
1184 it("should respect the existing file size", () => {
1185 const files = fs.readdirSync(fileObj.dir);
1186 const expectedFileList = [fileObj.base, fileObj.base + ".1"];
1187 files.should.containDeep(expectedFileList);
1188 files.length.should.equal(expectedFileList.length);
1189
1190 fs.readFileSync(path.format(fileObj))
1191 .toString()
1192 .should.equal("three\n");
1193 fs.readFileSync(path.join(fileObj.dir, fileObj.base + ".1"))
1194 .toString()
1195 .should.equal("This is exactly 30 bytes long\none\ntwo\n");
1196 });
1197 });
1198
1199 describe("when old files exist with indices", () => {
1200 const fileObj = generateTestFile();
1201 let s;
1202
1203 before(done => {
1204 fs.ensureFileSync(fileObj.path);
1205 fs.writeFileSync(
1206 fileObj.path,
1207 "This was the base file and it should be more than 30 bytes\n"
1208 ); // base
1209 fs.writeFileSync(fileObj.path + ".1", "This was the first old file\n"); // base.1
1210 s = new RollingFileWriteStream(fileObj.path, {
1211 maxSize: 30,
1212 numToKeep: 5
1213 });
1214 s.write("This is exactly 30 bytes long\n", "utf8"); // base.1 -> base.2, base -> base.1
1215 s.write("This is exactly 30 bytes long\n", "utf8"); // base.2 -> base.3, base.1 -> base.2, base -> base.1
1216 s.write("three\n", "utf8", done); // base.3 -> base.4, base.2 -> base.3, base.1 -> base.2, base -> base.1
1217 });
1218
1219 after(done => {
1220 s.end(() => {
1221 fs.removeSync(fileObj.dir);
1222 done();
1223 });
1224 });
1225
1226 it("should rotate the old file indices", () => {
1227 const files = fs.readdirSync(fileObj.dir);
1228 const expectedFileList = [
1229 fileObj.base,
1230 fileObj.base + ".1",
1231 fileObj.base + ".2",
1232 fileObj.base + ".3",
1233 fileObj.base + ".4"
1234 ];
1235 files.should.containDeep(expectedFileList);
1236 files.length.should.equal(expectedFileList.length);
1237
1238 fs.readFileSync(path.format(fileObj))
1239 .toString()
1240 .should.equal("three\n");
1241 fs.readFileSync(path.join(fileObj.dir, fileObj.base + ".1"))
1242 .toString()
1243 .should.equal("This is exactly 30 bytes long\n");
1244 fs.readFileSync(path.join(fileObj.dir, fileObj.base + ".2"))
1245 .toString()
1246 .should.equal("This is exactly 30 bytes long\n");
1247 fs.readFileSync(path.join(fileObj.dir, fileObj.base + ".3"))
1248 .toString()
1249 .should.equal(
1250 "This was the base file and it should be more than 30 bytes\n"
1251 );
1252 fs.readFileSync(path.join(fileObj.dir, fileObj.base + ".4"))
1253 .toString()
1254 .should.equal("This was the first old file\n");
1255 });
1256 });
1257
1258 describe("when old files exist with contents and rolling by date", () => {
1259 const fileObj = generateTestFile();
1260 let s;
1261
1262 before(done => {
1263 fakeNow = new Date(2012, 8, 12, 10, 37, 11);
1264 fs.ensureFileSync(fileObj.path);
1265 fs.writeFileSync(fileObj.path, "This was created Sept 12, 2012.\n");
1266 fakeNow = new Date(2012, 8, 13, 10, 53, 12);
1267 s = new RollingFileWriteStream(fileObj.path, { pattern: "yyyy-MM-dd" });
1268 s.write("It is now Sept 13, 2012.\n", "utf8", done); // this should be in a new file.
1269 });
1270
1271 after(done => {
1272 s.end(() => {
1273 fs.removeSync(fileObj.dir);
1274 done();
1275 });
1276 });
1277
1278 it("should respect the existing file date", () => {
1279 const files = fs.readdirSync(fileObj.dir);
1280 const expectedFileList = [fileObj.base, fileObj.base + ".2012-09-12"];
1281 files.should.containDeep(expectedFileList);
1282 files.length.should.equal(expectedFileList.length);
1283
1284 fs.readFileSync(path.format(fileObj))
1285 .toString()
1286 .should.equal("It is now Sept 13, 2012.\n");
1287 fs.readFileSync(path.join(fileObj.dir, fileObj.base + ".2012-09-12"))
1288 .toString()
1289 .should.equal("This was created Sept 12, 2012.\n");
1290 });
1291 });
1292
1293 describe("when old files exist with contents and stream created with overwrite flag", () => {
1294 const fileObj = generateTestFile();
1295 let s;
1296
1297 before(done => {
1298 fakeNow = new Date(2012, 8, 12, 10, 37, 11);
1299 fs.ensureFileSync(fileObj.path);
1300 fs.writeFileSync(fileObj.path, "This is exactly 30 bytes long\n");
1301 s = new RollingFileWriteStream(fileObj.path, { maxSize: 35, flags: "w" });
1302 s.write("there should only be this\n", "utf8", done);
1303 });
1304
1305 after(done => {
1306 s.end(() => {
1307 fs.removeSync(fileObj.dir);
1308 done();
1309 });
1310 });
1311
1312 it("should ignore the existing file size", () => {
1313 const files = fs.readdirSync(fileObj.dir);
1314 const expectedFileList = [fileObj.base];
1315 files.should.containDeep(expectedFileList);
1316 files.length.should.equal(expectedFileList.length);
1317
1318 s.state.currentSize.should.equal(26);
1319
1320 fs.readFileSync(path.format(fileObj))
1321 .toString()
1322 .should.equal("there should only be this\n");
1323 });
1324 });
1325
1326 describe("when dir does not exist", () => {
1327 const fileObj = generateTestFile();
1328 let s;
1329
1330 before(done => {
1331 fs.removeSync(fileObj.dir);
1332 fakeNow = new Date(2012, 8, 12, 10, 37, 11);
1333 s = new RollingFileWriteStream(fileObj.path);
1334 s.write("test", "utf8", done);
1335 });
1336
1337 after(done => {
1338 s.end(() => {
1339 fs.removeSync(fileObj.dir);
1340 done();
1341 });
1342 });
1343
1344 it("should create the dir", () => {
1345 const files = fs.readdirSync(fileObj.dir);
1346 const expectedFileList = [fileObj.base];
1347 files.should.containDeep(expectedFileList);
1348 files.length.should.equal(expectedFileList.length);
1349
1350 fs.readFileSync(path.format(fileObj))
1351 .toString()
1352 .should.equal("test");
1353 });
1354 });
1355
1356 describe("when given just a base filename with no dir", () => {
1357 let s;
1358 before(done => {
1359 s = new RollingFileWriteStream("test.log");
1360 s.write("this should not cause any problems", "utf8", done);
1361 });
1362
1363 after(done => {
1364 s.end(() => {
1365 fs.removeSync("test.log");
1366 done();
1367 });
1368 });
1369
1370 it("should use process.cwd() as the dir", () => {
1371 const files = fs.readdirSync(process.cwd());
1372 files.should.containDeep(["test.log"]);
1373
1374 fs.readFileSync(path.join(process.cwd(), "test.log"))
1375 .toString()
1376 .should.equal("this should not cause any problems");
1377 });
1378 });
1379
1380 describe("with no callback to write", () => {
1381 let s;
1382 before(done => {
1383 s = new RollingFileWriteStream("no-callback.log");
1384 s.write("this is all very nice", "utf8", done);
1385 });
1386
1387 after(done => {
1388 fs.remove("no-callback.log", done);
1389 });
1390
1391 it("should not complain", done => {
1392 s.write("I am not bothered if this succeeds or not");
1393 s.end(done);
1394 });
1395 });
1396
1397 describe("events", () => {
1398 let s;
1399 before(done => {
1400 s = new RollingFileWriteStream("test-events.log");
1401 s.write("this should not cause any problems", "utf8", done);
1402 });
1403
1404 after(done => {
1405 s.end(() => {
1406 fs.removeSync("test-events.log");
1407 done();
1408 });
1409 });
1410
1411 it("should emit the error event of the underlying stream", done => {
1412 s.on("error", e => {
1413 e.message.should.equal("oh no");
1414 done();
1415 });
1416 s.currentFileStream.emit("error", new Error("oh no"));
1417 });
1418 });
1419
1420 describe("when deleting old files and there is an error", () => {
1421 before(done => {
1422 fs.ensureDir('/tmp/delete-test/logfile.log.2', done);
1423 });
1424
1425 it("should not let errors bubble up", done => {
1426 const s = new RollingFileWriteStream("/tmp/delete-test/logfile.log", {
1427 maxSize: 10,
1428 numToKeep: 1
1429 });
1430
1431 s.write("length is 10", "utf8", () => {
1432 // if there's an error during deletion, then done never gets called
1433 s.write("length is 10", "utf8", done);
1434 });
1435 });
1436
1437 after(done => {
1438 fs.remove('/tmp/delete-test', done);
1439 })
1440 });
1441});
Note: See TracBrowser for help on using the repository browser.