RotatingFileHandlerTest.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. <?php
  2. /*
  3. * This file is part of the Monolog package.
  4. *
  5. * (c) Jordi Boggiano <j.boggiano@seld.be>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Monolog\Handler;
  11. use InvalidArgumentException;
  12. use Monolog\TestCase;
  13. /**
  14. * @covers Monolog\Handler\RotatingFileHandler
  15. */
  16. class RotatingFileHandlerTest extends TestCase
  17. {
  18. public function setUp()
  19. {
  20. $dir = __DIR__.'/Fixtures';
  21. chmod($dir, 0777);
  22. if (!is_writable($dir)) {
  23. $this->markTestSkipped($dir.' must be writable to test the RotatingFileHandler.');
  24. }
  25. }
  26. public function testRotationCreatesNewFile()
  27. {
  28. touch(__DIR__.'/Fixtures/foo-'.date('Y-m-d', time() - 86400).'.rot');
  29. $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot');
  30. $handler->setFormatter($this->getIdentityFormatter());
  31. $handler->handle($this->getRecord());
  32. $log = __DIR__.'/Fixtures/foo-'.date('Y-m-d').'.rot';
  33. $this->assertTrue(file_exists($log));
  34. $this->assertEquals('test', file_get_contents($log));
  35. }
  36. /**
  37. * @dataProvider rotationTests
  38. */
  39. public function testRotation($createFile, $dateFormat, $timeCallback)
  40. {
  41. touch($old1 = __DIR__.'/Fixtures/foo-'.date($dateFormat, $timeCallback(-1)).'.rot');
  42. touch($old2 = __DIR__.'/Fixtures/foo-'.date($dateFormat, $timeCallback(-2)).'.rot');
  43. touch($old3 = __DIR__.'/Fixtures/foo-'.date($dateFormat, $timeCallback(-3)).'.rot');
  44. touch($old4 = __DIR__.'/Fixtures/foo-'.date($dateFormat, $timeCallback(-4)).'.rot');
  45. $log = __DIR__.'/Fixtures/foo-'.date($dateFormat).'.rot';
  46. if ($createFile) {
  47. touch($log);
  48. }
  49. $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot', 2);
  50. $handler->setFormatter($this->getIdentityFormatter());
  51. $handler->setFilenameFormat('{filename}-{date}', $dateFormat);
  52. $handler->handle($this->getRecord());
  53. $handler->close();
  54. $this->assertTrue(file_exists($log));
  55. $this->assertTrue(file_exists($old1));
  56. $this->assertEquals($createFile, file_exists($old2));
  57. $this->assertEquals($createFile, file_exists($old3));
  58. $this->assertEquals($createFile, file_exists($old4));
  59. $this->assertEquals('test', file_get_contents($log));
  60. }
  61. public function rotationTests()
  62. {
  63. $now = time();
  64. $dayCallback = function($ago) use ($now) {
  65. return $now + 86400 * $ago;
  66. };
  67. $monthCallback = function($ago) {
  68. return gmmktime(0, 0, 0, date('n') + $ago, date('d'), date('Y'));
  69. };
  70. $yearCallback = function($ago) {
  71. return gmmktime(0, 0, 0, date('n'), date('d'), date('Y') + $ago);
  72. };
  73. return array(
  74. 'Rotation is triggered when the file of the current day is not present'
  75. => array(true, RotatingFileHandler::FILE_PER_DAY, $dayCallback),
  76. 'Rotation is not triggered when the file of the current day is already present'
  77. => array(false, RotatingFileHandler::FILE_PER_DAY, $dayCallback),
  78. 'Rotation is triggered when the file of the current month is not present'
  79. => array(true, RotatingFileHandler::FILE_PER_MONTH, $monthCallback),
  80. 'Rotation is not triggered when the file of the current month is already present'
  81. => array(false, RotatingFileHandler::FILE_PER_MONTH, $monthCallback),
  82. 'Rotation is triggered when the file of the current year is not present'
  83. => array(true, RotatingFileHandler::FILE_PER_YEAR, $yearCallback),
  84. 'Rotation is not triggered when the file of the current year is already present'
  85. => array(false, RotatingFileHandler::FILE_PER_YEAR, $yearCallback),
  86. );
  87. }
  88. /**
  89. * @dataProvider dateFormatProvider
  90. */
  91. public function testAllowOnlyFixedDefinedDateFormats($dateFormat, $valid)
  92. {
  93. $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot', 2);
  94. if (!$valid) {
  95. $this->setExpectedExceptionRegExp(InvalidArgumentException::class, '~^Invalid date format~');
  96. }
  97. $handler->setFilenameFormat('{filename}-{date}', $dateFormat);
  98. }
  99. public function dateFormatProvider()
  100. {
  101. return array(
  102. array(RotatingFileHandler::FILE_PER_DAY, true),
  103. array(RotatingFileHandler::FILE_PER_MONTH, true),
  104. array(RotatingFileHandler::FILE_PER_YEAR, true),
  105. array('m-d-Y', false),
  106. array('Y-m-d-h-i', false)
  107. );
  108. }
  109. /**
  110. * @dataProvider filenameFormatProvider
  111. */
  112. public function testDisallowFilenameFormatsWithoutDate($filenameFormat, $valid)
  113. {
  114. $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot', 2);
  115. if (!$valid) {
  116. $this->setExpectedExceptionRegExp(InvalidArgumentException::class, '~^Invalid filename format~');
  117. }
  118. $handler->setFilenameFormat($filenameFormat, RotatingFileHandler::FILE_PER_DAY);
  119. }
  120. public function filenameFormatProvider()
  121. {
  122. return array(
  123. array('{filename}', false),
  124. array('{filename}-{date}', true),
  125. array('{date}', true),
  126. array('foobar-{date}', true),
  127. array('foo-{date}-bar', true),
  128. array('{date}-foobar', true),
  129. array('foobar', false),
  130. );
  131. }
  132. public function testReuseCurrentFile()
  133. {
  134. $log = __DIR__.'/Fixtures/foo-'.date('Y-m-d').'.rot';
  135. file_put_contents($log, "foo");
  136. $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot');
  137. $handler->setFormatter($this->getIdentityFormatter());
  138. $handler->handle($this->getRecord());
  139. $this->assertEquals('footest', file_get_contents($log));
  140. }
  141. public function tearDown()
  142. {
  143. foreach (glob(__DIR__.'/Fixtures/*.rot') as $file) {
  144. unlink($file);
  145. }
  146. }
  147. }