Completed
Branch feature/0.7.0 (0808a6)
by Ryuichi
85:55 queued 40:54
created

LoggerTest   A

Complexity

Total Complexity 3

Size/Duplication

Total Lines 468
Duplicated Lines 48.29 %

Importance

Changes 0
Metric Value
dl 226
loc 468
rs 10
c 0
b 0
f 0
wmc 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
namespace WebStream\Log\Test;
3
4
require_once dirname(__FILE__) . '/../LoggerUtils.php';
5
require_once dirname(__FILE__) . '/../Logger.php';
6
require_once dirname(__FILE__) . '/../LoggerAdapter.php';
7
require_once dirname(__FILE__) . '/../LoggerConfigurationManager.php';
8
require_once dirname(__FILE__) . '/../LoggerFormatter.php';
9
require_once dirname(__FILE__) . '/../LoggerCache.php';
10
require_once dirname(__FILE__) . '/../Outputter/IOutputter.php';
11
require_once dirname(__FILE__) . '/../Outputter/ILazyWriter.php';
12
require_once dirname(__FILE__) . '/../Outputter/FileOutputter.php';
13
require_once dirname(__FILE__) . '/../Outputter/ConsoleOutputter.php';
14
require_once dirname(__FILE__) . '/../Modules/Cache/Modules/DI/Injector.php';
15
require_once dirname(__FILE__) . '/../Modules/Cache/Driver/CacheDriverFactory.php';
16
require_once dirname(__FILE__) . '/../Modules/Cache/Driver/ICache.php';
17
require_once dirname(__FILE__) . '/../Modules/Cache/Driver/Apcu.php';
18
require_once dirname(__FILE__) . '/../Modules/Container/Container.php';
19
require_once dirname(__FILE__) . '/../Modules/Container/ValueProxy.php';
20
require_once dirname(__FILE__) . '/../Modules/IO/File.php';
21
require_once dirname(__FILE__) . '/../Modules/IO/InputStream.php';
22
require_once dirname(__FILE__) . '/../Modules/IO/OutputStream.php';
23
require_once dirname(__FILE__) . '/../Modules/IO/FileInputStream.php';
24
require_once dirname(__FILE__) . '/../Modules/IO/FileOutputStream.php';
25
require_once dirname(__FILE__) . '/../Modules/IO/Reader/InputStreamReader.php';
26
require_once dirname(__FILE__) . '/../Modules/IO/Reader/FileReader.php';
27
require_once dirname(__FILE__) . '/../Modules/IO/Writer/OutputStreamWriter.php';
28
require_once dirname(__FILE__) . '/../Modules/IO/Writer/FileWriter.php';
29
require_once dirname(__FILE__) . '/../Modules/IO/Writer/SimpleFileWriter.php';
30
require_once dirname(__FILE__) . '/Modules/IOException.php';
31
require_once dirname(__FILE__) . '/Providers/LoggerProvider.php';
32
33
use WebStream\Container\Container;
34
use WebStream\Cache\Driver\CacheDriverFactory;
35
use WebStream\IO\File;
36
use WebStream\IO\Writer\FileWriter;
37
use WebStream\Log\Logger;
38
use WebStream\Log\LoggerAdapter;
39
use WebStream\Log\LoggerConfigurationManager;
40
use WebStream\Log\LoggerCache;
41
use WebStream\Log\Outputter\FileOutputter;
42
use WebStream\Log\Outputter\ConsoleOutputter;
43
use WebStream\Log\Test\Providers\LoggerProvider;
44
45
/**
46
 * LoggerTest
47
 * @author Ryuichi TANAKA.
48
 * @since 2016/01/30
49
 */
50
class LoggerTest extends \PHPUnit_Framework_TestCase
51
{
52
    use LoggerProvider;
53
54
    private function getLogger(string $configPath)
55
    {
56
        $manager = new LoggerConfigurationManager($configPath);
57
        $manager->load();
58
        Logger::init($manager->getConfig());
59
        $instance = Logger::getInstance();
60
        $instance->setOutputter([new FileOutputter("/tmp/webstream.logtest.log"), new ConsoleOutputter()]);
61
62
        return new LoggerAdapter($instance);
63
    }
64
65
    private function getLotateLogger(string $configPath)
66
    {
67
        $manager = new LoggerConfigurationManager($configPath);
68
        $manager->load();
69
        Logger::init($manager->getConfig());
70
        $instance = Logger::getInstance();
71
        $instance->setOutputter([new FileOutputter("/tmp/webstream.logtest.log")]);
72
73
        return new LoggerAdapter($instance);
74
    }
75
76
    private function assertLog($level, $msg, $logLine)
77
    {
78
        if (preg_match('/^\[\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}\..{3}\]\[(.+?)\]\[(.+?)]\s(.*)$/', $logLine, $matches)) {
79
            $target = ["webstream.logtest", $level, $msg];
80
            $result = [trim($matches[1]), trim($matches[2]), $matches[3]];
81
            $this->assertEquals($target, $result);
82
        } else {
83
            $this->assertTrue(false);
84
        }
85
    }
86
87
    /**
88
     * 正常系
89
     * LoggerAdapter経由でログが書き込めること
90
     * @test
91
     * @dataProvider loggerAdapterProvider
92
     */
93
    public function okLoggerAdapter($level)
94
    {
95
        $msg = "log message";
96
        $configPath = dirname(__FILE__) . "/Fixtures/log.test1.${level}.ini";
97
        $logger = $this->getLogger($configPath);
98
99
        ob_start();
100
        $logger->{$level}($msg);
101
        $actual = ob_get_clean();
102
103
        $this->assertLog(strtoupper($level), $msg, $actual);
104
    }
105
106
    /**
107
     * 正常系
108
     * LoggerAdapter経由でログが書き込めること、プレースホルダーで値を埋め込めること
109
     * @test
110
     * @dataProvider loggerAdapterWithPlaceholderProvider
111
     */
112
    public function okLoggerAdapterWithPlaceholder($level, $msg1, $msg2, array $placeholder)
113
    {
114
        $msg = "log message";
115
        $configPath = dirname(__FILE__) . "/Fixtures/log.test1.${level}.ini";
116
        $logger = $this->getLogger($configPath);
117
118
        ob_start();
119
        $logger->{$level}($msg2, $placeholder);
120
        $actual = ob_get_clean();
121
122
        $this->assertLog(strtoupper($level), $msg1, $actual);
123
    }
124
125
    /**
126
     * 正常系
127
     * ログレベルが「debug」のとき、
128
     * 「debug」「info」「notice」「warn」「warning」「error」「critical」「alert」「emergency」「fatal」レベルのログが書き出せること
129
     * @test
130
     * @dataProvider logLevelDebugProvider
131
     */
132
    public function okWriteDebug($level, $isWrite)
133
    {
134
        $execLevel = "debug";
135
        $msg = "log message";
136
        $configPath = dirname(__FILE__) . "/Fixtures/log.test2.${execLevel}.ini";
137
        $logger = $this->getLogger($configPath);
138
139
        ob_start();
140
        $logger->{$level}($msg);
141
        $actual = ob_get_clean();
142
143
        $this->assertEquals($isWrite, trim($actual) === $msg);
144
    }
145
146
    /**
147
     * 正常系
148
     * ログレベルが「info」のとき、
149
     * 「info」「notice」「warn」「warning」「error」「critical」「alert」「emergency」「fatal」レベルのログが書き出せること
150
     * @test
151
     * @dataProvider logLevelInfoProvider
152
     */
153
    public function okWriteInfo($level, $isWrite)
154
    {
155
        $execLevel = "info";
156
        $msg = "log message";
157
        $configPath = dirname(__FILE__) . "/Fixtures/log.test2.${execLevel}.ini";
158
        $logger = $this->getLogger($configPath);
159
160
        ob_start();
161
        $logger->{$level}($msg);
162
        $actual = ob_get_clean();
163
164
        $this->assertEquals($isWrite, trim($actual) === $msg);
165
    }
166
167
    /**
168
     * 正常系
169
     * ログレベルが「notice」のとき、
170
     * 「notice」「warn」「warning」「error」「critical」「alert」「emergency」「fatal」レベルのログが書き出せること
171
     * @test
172
     * @dataProvider logLevelNoticeProvider
173
     */
174
    public function okWriteNotice($level, $isWrite)
175
    {
176
        $execLevel = "notice";
177
        $msg = "log message";
178
        $configPath = dirname(__FILE__) . "/Fixtures/log.test2.${execLevel}.ini";
179
        $logger = $this->getLogger($configPath);
180
181
        ob_start();
182
        $logger->{$level}($msg);
183
        $actual = ob_get_clean();
184
185
        $this->assertEquals($isWrite, trim($actual) === $msg);
186
    }
187
188
    /**
189
     * 正常系
190
     * ログレベルが「warn」のとき、
191
     * 「warn」「warning」「error」「critical」「alert」「emergency」「fatal」レベルのログが書き出せること
192
     * @test
193
     * @dataProvider logLevelWarnProvider
194
     */
195
    public function okWriteWarn($level, $isWrite)
196
    {
197
        $execLevel = "warn";
198
        $msg = "log message";
199
        $configPath = dirname(__FILE__) . "/Fixtures/log.test2.${execLevel}.ini";
200
        $logger = $this->getLogger($configPath);
201
202
        ob_start();
203
        $logger->{$level}($msg);
204
        $actual = ob_get_clean();
205
206
        $this->assertEquals($isWrite, trim($actual) === $msg);
207
    }
208
209
    /**
210
     * 正常系
211
     * ログレベルが「warning」のとき、
212
     * 「warn」「warning」「error」「critical」「alert」「emergency」「fatal」レベルのログが書き出せること
213
     * @test
214
     * @dataProvider logLevelWarningProvider
215
     */
216
    public function okWriteWarning($level, $isWrite)
217
    {
218
        $execLevel = "warning";
219
        $msg = "log message";
220
        $configPath = dirname(__FILE__) . "/Fixtures/log.test2.${execLevel}.ini";
221
        $logger = $this->getLogger($configPath);
222
223
        ob_start();
224
        $logger->{$level}($msg);
225
        $actual = ob_get_clean();
226
227
        $this->assertEquals($isWrite, trim($actual) === $msg);
228
    }
229
230
    /**
231
     * 正常系
232
     * ログレベルが「error」のとき、
233
     * 「error」「critical」「alert」「emergency」「fatal」レベルのログが書き出せること
234
     * @test
235
     * @dataProvider logLevelErrorProvider
236
     */
237
    public function okWriteError($level, $isWrite)
238
    {
239
        $execLevel = "error";
240
        $msg = "log message";
241
        $configPath = dirname(__FILE__) . "/Fixtures/log.test2.${execLevel}.ini";
242
        $logger = $this->getLogger($configPath);
243
244
        ob_start();
245
        $logger->{$level}($msg);
246
        $actual = ob_get_clean();
247
248
        $this->assertEquals($isWrite, trim($actual) === $msg);
249
    }
250
251
    /**
252
     * 正常系
253
     * ログレベルが「critical」のとき、
254
     * 「critical」「alert」「emergency」「fatal」レベルのログが書き出せること
255
     * @test
256
     * @dataProvider logLevelCriticalProvider
257
     */
258
    public function okWriteCritical($level, $isWrite)
259
    {
260
        $execLevel = "critical";
261
        $msg = "log message";
262
        $configPath = dirname(__FILE__) . "/Fixtures/log.test2.${execLevel}.ini";
263
        $logger = $this->getLogger($configPath);
264
265
        ob_start();
266
        $logger->{$level}($msg);
267
        $actual = ob_get_clean();
268
269
        $this->assertEquals($isWrite, trim($actual) === $msg);
270
    }
271
272
    /**
273
     * 正常系
274
     * ログレベルが「alert」のとき、
275
     * 「alert」「emergency」「fatal」レベルのログが書き出せること
276
     * @test
277
     * @dataProvider logLevelAlertProvider
278
     */
279
    public function okWriteAlert($level, $isWrite)
280
    {
281
        $execLevel = "alert";
282
        $msg = "log message";
283
        $configPath = dirname(__FILE__) . "/Fixtures/log.test2.${execLevel}.ini";
284
        $logger = $this->getLogger($configPath);
285
286
        ob_start();
287
        $logger->{$level}($msg);
288
        $actual = ob_get_clean();
289
290
        $this->assertEquals($isWrite, trim($actual) === $msg);
291
    }
292
293
    /**
294
     * 正常系
295
     * ログレベルが「emergency」のとき、
296
     * 「emergency」「fatal」レベルのログが書き出せること
297
     * @test
298
     * @dataProvider logLevelEmergencyProvider
299
     */
300
    public function okWriteEmergency($level, $isWrite)
301
    {
302
        $execLevel = "emergency";
303
        $msg = "log message";
304
        $configPath = dirname(__FILE__) . "/Fixtures/log.test2.${execLevel}.ini";
305
        $logger = $this->getLogger($configPath);
306
307
        ob_start();
308
        $logger->{$level}($msg);
309
        $actual = ob_get_clean();
310
311
        $this->assertEquals($isWrite, trim($actual) === $msg);
312
    }
313
314
    /**
315
     * 正常系
316
     * ログレベルが「fatal」のとき、
317
     * 「fatal」レベルのログが書き出せること
318
     * @test
319
     * @dataProvider logLevelFatalProvider
320
     */
321
    public function okWriteFatal($level, $isWrite)
322
    {
323
        $execLevel = "fatal";
324
        $msg = "log message";
325
        $configPath = dirname(__FILE__) . "/Fixtures/log.test2.${execLevel}.ini";
326
        $logger = $this->getLogger($configPath);
327
328
        ob_start();
329
        $logger->{$level}($msg);
330
        $actual = ob_get_clean();
331
332
        $this->assertEquals($isWrite, trim($actual) === $msg);
333
    }
334
335
    /**
336
     * 正常系
337
     * 指定されたフォーマットでログ出力されること
338
     * @test
339
     * @dataProvider loggerFormatterProvider
340
     */
341
    public function okLoggerFormatter($configPath, $msg, $formattedMessage)
342
    {
343
        $configPath = dirname(__FILE__) . "/Fixtures/${configPath}";
344
        $logger = $this->getLogger($configPath);
345
346
        ob_start();
347
        $logger->debug($msg);
348
        $actual = ob_get_clean();
349
350
        $this->assertEquals(trim($actual), $formattedMessage);
351
    }
352
353
    /**
354
     * 正常系
355
     * DateTimeフォーマットでログ出力されること
356
     * @test
357
     * @dataProvider loggerFormatterDateTimeProvider
358
     */
359
    public function okLoggerDateTimeFormatter($configPath, $dateTimeRegexp, $message, $messageWithSpace)
360
    {
361
        $configPath = dirname(__FILE__) . "/Fixtures/${configPath}";
362
        $logger = $this->getLogger($configPath);
363
364
        ob_start();
365
        $logger->debug($message);
366
        $actual = ob_get_clean();
367
368
        preg_match($dateTimeRegexp, $actual, $matches);
369
        $this->assertEquals(trim($actual), $matches[1] . $messageWithSpace);
370
    }
371
372
    /**
373
     * 正常系
374
     * ログの書き出しタイミングを制御できること
375
     * @test
376
     * @dataProvider writeTimingProvider
377
     */
378
    public function okLoggerWriteTiming($isLazy, $msg1, $msg2, $msg3, $result)
379
    {
380
        $configPath = dirname(__FILE__) . "/Fixtures/log.test5.ini";
381
        $logger = $this->getLogger($configPath);
382
        $manager = new LoggerConfigurationManager($configPath);
383
        $manager->load();
384
        Logger::init($manager->getConfig());
385
        $instance = Logger::getInstance();
386
387
        $outputter = new ConsoleOutputter();
388
        if ($isLazy) {
389
            $outputter->enableLazyWrite();
390
        } else {
391
            $outputter->enableDirectWrite();
392
        }
393
        $instance->setOutputter([$outputter]);
394
395
        $logger = new LoggerAdapter($instance);
396
        ob_start();
397
        $logger->debug($msg1);
398
        echo $msg2 . PHP_EOL;
399
        $logger->debug($msg3);
400
        if ($isLazy) {
401
            $logger->enableDirectWrite(); // バッファをクリアする
402
        }
403
        $actual = ob_get_clean();
404
405
        $this->assertEquals($actual, $result);
406
    }
407
408
    /**
409
     * 正常系
410
     * ローテート設定が
411
     * 日単位かつログファイル作成日24時間以内の場合、
412
     * 週単位かつログファイル作成日が1週間以内の場合、
413
     * 月単位かつログファイル作成日が1ヶ月以内の場合、
414
     * 年単位かつログファイル作成日が1年以内の場合、
415
     * ログローテートは実行されないこと
416
     * @test
417
     * @dataProvider unRotateByCycleProvider
418
     */
419
    public function okUnRotateByCycle($configPath, $hour)
420
    {
421
        $message = "hoge";
422
        $configPath = dirname(__FILE__) . "/Fixtures/${configPath}";
423
        $logger = $this->getLotateLogger($configPath);
424
425
        // 現在時刻より$hour時間前のUnixTimeを取得
426
        $now = intval(preg_replace('/^.*\s/', '', microtime()));
427
        $createdAt = $now - 3600 * $hour;
428
        $createdAtDate = date("YmdHis", $createdAt);
429
        $nowDate = date("YmdHis", $now);
430
431
        $writer = new FileWriter("/tmp/webstream.logtest.status");
432
        $writer->write($createdAt);
433
        $writer->flush();
434
        $writer->close();
435
        $logger->info($message);
436
437
        $this->assertFileNotExists("/tmp/webstream.logtest.${createdAtDate}-${nowDate}.log");
438
    }
439
440
    /**
441
     * 正常系
442
     * ローテート設定が
443
     * 日単位かつログファイル作成日が24時間以上の場合、
444
     * 週単位かつログファイル作成日が1週間以上の場合、
445
     * 月単位かつログファイル作成日が1ヶ月以上の場合、
446
     * 年単位かつログファイル作成日が1年以上の場合、
447
     * ログローテートが実行されること
448
     * @test
449
     * @dataProvider rotateByCycleProvider
450
     */
451
    public function okRotateByCycle($configPath, $hour)
452
    {
453
        $message = "hoge";
454
        $configPath = dirname(__FILE__) . "/Fixtures/${configPath}";
455
        $logger = $this->getLotateLogger($configPath);
456
457
        // 現在時刻より$hour時間前のUnixTimeを取得
458
        $now = intval(preg_replace('/^.*\s/', '', microtime()));
459
        $createdAt = $now - 3600 * $hour;
460
        $createdAtDate = date("YmdHis", $createdAt);
461
        $nowDate = date("YmdHis", $now);
462
463
        $writer = new FileWriter("/tmp/webstream.logtest.status");
464
        $writer->write($createdAt);
465
        $writer->flush();
466
        $writer->close();
467
        $logger->info($message);
468
469
        $this->assertFileExists("/tmp/webstream.logtest.${createdAtDate}-${nowDate}.log");
470
    }
471
472
    /**
473
     * 正常系
474
     * ログキャッシュできること
475
     * @test
476
     */
477
    public function okLoggerCache()
478
    {
479
        $config = new Container(false);
480
        $config->classPrefix = "logger_cache";
481
        $config->cacheDir = "/tmp";
482
        $factory = new CacheDriverFactory();
483
        $driver = $factory->create("WebStream\Cache\Driver\Apcu", $config);
484
        $logger = new class() { function __call($name, $args) {} };
485
        $driver->inject('logger', $logger);
486
        $driver->clear();
487
488
        $cache = new LoggerCache($driver);
489
        $cache->add("a");
490
        $cache->add("b");
491
        $this->assertEquals(2, $cache->length());
492
        $this->assertEquals(implode("", $cache->get()), "ab");
493
    }
494
495
    /**
496
     * 正常系
497
     * ログファイルが見つからない場合、新規作成できること
498
     * @test
499
     */
500
    public function okLoggerNewLogFile()
501
    {
502
        $file = new File("/tmp/webstream.logtest.new.log");
503
        $file->delete();
504
505
        $configPath = dirname(__FILE__) . "/Fixtures/log.test7.ini";
506
        $manager = new LoggerConfigurationManager($configPath);
507
        $manager->load();
508
        Logger::init($manager->getConfig());
509
        $instance = Logger::getInstance();
510
        $instance->setOutputter([new FileOutputter($file->getFilePath())]);
511
512
        $logger = new LoggerAdapter($instance);
513
        $logger->debug("hoge");
514
515
        $this->assertFileExists($file->getFilePath());
516
    }
517
}
518