304a102fa6e836e996c11d59eeb2833920818fa7
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Log / Writer / FileWriterTest.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Core\Tests\Unit\Log\Writer;
4
5 /*
6 * This file is part of the TYPO3 CMS project.
7 *
8 * It is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, either version 2
10 * of the License, or any later version.
11 *
12 * For the full copyright and license information, please read the
13 * LICENSE.txt file that was distributed with this source code.
14 *
15 * The TYPO3 project - inspiring people to share!
16 */
17
18 use org\bovigo\vfs\vfsStream;
19 use org\bovigo\vfs\vfsStreamWrapper;
20 use TYPO3\CMS\Core\Log\Logger;
21 use TYPO3\CMS\Core\Log\LogManager;
22 use TYPO3\CMS\Core\Log\LogRecord;
23 use TYPO3\CMS\Core\Log\Writer\FileWriter;
24 use TYPO3\CMS\Core\Utility\GeneralUtility;
25 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
26
27 /**
28 * Test case
29 */
30 class FileWriterTest extends UnitTestCase
31 {
32 /**
33 * @var string
34 */
35 protected $logFileDirectory = 'Log';
36
37 /**
38 * @var string
39 */
40 protected $logFileName = 'test.log';
41
42 protected function setUpVfsStream(): void
43 {
44 vfsStream::setup('LogRoot');
45 }
46
47 /**
48 * Creates a test logger
49 *
50 * @param string $name
51 * @internal param string $component Component key
52 * @return Logger
53 */
54 protected function createLogger($name = ''): Logger
55 {
56 if (empty($name)) {
57 $name = $this->getUniqueId('test.core.log.');
58 }
59 GeneralUtility::makeInstance(LogManager::class)->registerLogger($name);
60 /** @var Logger $logger */
61 $logger = GeneralUtility::makeInstance(LogManager::class)->getLogger($name);
62 return $logger;
63 }
64
65 /**
66 * Creates a file writer
67 *
68 * @param string $prependName
69 * @return FileWriter
70 */
71 protected function createWriter($prependName = ''): FileWriter
72 {
73 /** @var FileWriter $writer */
74 $writer = GeneralUtility::makeInstance(FileWriter::class, [
75 'logFile' => $this->getDefaultFileName($prependName)
76 ]);
77 return $writer;
78 }
79
80 protected function getDefaultFileName($prependName = ''): string
81 {
82 return 'vfs://LogRoot/' . $this->logFileDirectory . '/' . $prependName . $this->logFileName;
83 }
84
85 /**
86 * @test
87 */
88 public function setLogFileSetsLogFile(): void
89 {
90 $this->setUpVfsStream();
91 vfsStream::newFile($this->logFileName)->at(vfsStreamWrapper::getRoot());
92 $writer = GeneralUtility::makeInstance(FileWriter::class);
93 $writer->setLogFile($this->getDefaultFileName());
94 $this->assertAttributeEquals($this->getDefaultFileName(), 'logFile', $writer);
95 }
96
97 /**
98 * @test
99 */
100 public function setLogFileAcceptsAbsolutePath(): void
101 {
102 $writer = GeneralUtility::makeInstance(FileWriter::class);
103 $tempFile = rtrim(sys_get_temp_dir(), '/\\') . '/typo3.log';
104 $writer->setLogFile($tempFile);
105 $this->assertAttributeEquals($tempFile, 'logFile', $writer);
106 }
107
108 /**
109 * @test
110 */
111 public function createsLogFileDirectory(): void
112 {
113 $this->setUpVfsStream();
114 $this->createWriter();
115 $this->assertTrue(vfsStreamWrapper::getRoot()->hasChild($this->logFileDirectory));
116 }
117
118 /**
119 * @test
120 */
121 public function createsLogFile(): void
122 {
123 $this->setUpVfsStream();
124 $this->createWriter();
125 $this->assertTrue(vfsStreamWrapper::getRoot()->getChild($this->logFileDirectory)->hasChild($this->logFileName));
126 }
127
128 /**
129 * @return array
130 */
131 public function logsToFileDataProvider(): array
132 {
133 $simpleRecord = GeneralUtility::makeInstance(LogRecord::class, $this->getUniqueId('test.core.log.fileWriter.simpleRecord.'), \TYPO3\CMS\Core\Log\LogLevel::INFO, 'test record');
134 $recordWithData = GeneralUtility::makeInstance(LogRecord::class, $this->getUniqueId('test.core.log.fileWriter.recordWithData.'), \TYPO3\CMS\Core\Log\LogLevel::ALERT, 'test record with data', ['foo' => ['bar' => 'baz']]);
135 return [
136 'simple record' => [$simpleRecord, trim((string)$simpleRecord)],
137 'record with data' => [$recordWithData, trim((string)$recordWithData)]
138 ];
139 }
140
141 /**
142 * @test
143 * @param LogRecord $record Record Test Data
144 * @param string $expectedResult Needle
145 * @dataProvider logsToFileDataProvider
146 */
147 public function logsToFile(LogRecord $record, $expectedResult): void
148 {
149 $this->setUpVfsStream();
150 $this->createWriter()->writeLog($record);
151 $logFileContents = trim(file_get_contents($this->getDefaultFileName()));
152 $this->assertEquals($expectedResult, $logFileContents);
153 }
154
155 /**
156 * @test
157 * @param LogRecord $record Record Test Data
158 * @param string $expectedResult Needle
159 * @dataProvider logsToFileDataProvider
160 */
161 public function differentWritersLogToDifferentFiles(LogRecord $record, $expectedResult): void
162 {
163 $this->setUpVfsStream();
164 $firstWriter = $this->createWriter();
165 $secondWriter = $this->createWriter('second-');
166
167 $firstWriter->writeLog($record);
168 $secondWriter->writeLog($record);
169
170 $firstLogFileContents = trim(file_get_contents($this->getDefaultFileName()));
171 $secondLogFileContents = trim(file_get_contents($this->getDefaultFileName('second-')));
172
173 $this->assertEquals($expectedResult, $firstLogFileContents);
174 $this->assertEquals($expectedResult, $secondLogFileContents);
175 }
176
177 /**
178 * @test
179 */
180 public function aSecondLogWriterToTheSameFileDoesNotOpenTheFileTwice()
181 {
182 $this->setUpVfsStream();
183
184 $firstWriter = $this->getMockBuilder(FileWriter::class)
185 ->setMethods(['dummy'])
186 ->getMock();
187 $secondWriter = $this->getMockBuilder(FileWriter::class)
188 ->setMethods(['createLogFile'])
189 ->getMock();
190
191 $secondWriter->expects($this->never())->method('createLogFile');
192
193 $logFilePrefix = $this->getUniqueId('unique');
194 $firstWriter->setLogFile($this->getDefaultFileName($logFilePrefix));
195 $secondWriter->setLogFile($this->getDefaultFileName($logFilePrefix));
196 }
197
198 /**
199 * @test
200 */
201 public function fileHandleIsNotClosedIfSecondFileWriterIsStillUsingSameFile()
202 {
203 $this->setUpVfsStream();
204
205 $firstWriter = $this->getMockBuilder(FileWriter::class)
206 ->setMethods(['closeLogFile'])
207 ->getMock();
208 $secondWriter = $this->getMockBuilder(FileWriter::class)
209 ->setMethods(['closeLogFile'])
210 ->getMock();
211
212 $firstWriter->expects($this->never())->method('closeLogFile');
213 $secondWriter->expects($this->once())->method('closeLogFile');
214
215 $logFilePrefix = $this->getUniqueId('unique');
216 $firstWriter->setLogFile($this->getDefaultFileName($logFilePrefix));
217 $secondWriter->setLogFile($this->getDefaultFileName($logFilePrefix));
218 $firstWriter->__destruct();
219 $secondWriter->__destruct();
220 }
221 }