1<?php
2/**
3 * CakeLogTest file
4 *
5 * CakePHP(tm) Tests <https://book.cakephp.org/2.0/en/development/testing.html>
6 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
7 *
8 * Licensed under The MIT License
9 * For full copyright and license information, please see the LICENSE.txt
10 * Redistributions of files must retain the above copyright notice
11 *
12 * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
13 * @link          https://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
14 * @package       Cake.Test.Case.Log
15 * @since         CakePHP(tm) v 1.2.0.5432
16 * @license       https://opensource.org/licenses/mit-license.php MIT License
17 */
18
19App::uses('CakeLog', 'Log');
20App::uses('FileLog', 'Log/Engine');
21
22/**
23 * CakeLogTest class
24 *
25 * @package       Cake.Test.Case.Log
26 */
27class CakeLogTest extends CakeTestCase {
28
29/**
30 * Start test callback, clears all streams enabled.
31 *
32 * @return void
33 */
34	public function setUp() {
35		parent::setUp();
36		$streams = CakeLog::configured();
37		foreach ($streams as $stream) {
38			CakeLog::drop($stream);
39		}
40	}
41
42/**
43 * test importing loggers from app/libs and plugins.
44 *
45 * @return void
46 */
47	public function testImportingLoggers() {
48		App::build(array(
49			'Lib' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Lib' . DS),
50			'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
51		), App::RESET);
52		CakePlugin::load('TestPlugin');
53
54		$result = CakeLog::config('libtest', array(
55			'engine' => 'TestAppLog'
56		));
57		$this->assertTrue($result);
58		$this->assertEquals(CakeLog::configured(), array('libtest'));
59
60		$result = CakeLog::config('plugintest', array(
61			'engine' => 'TestPlugin.TestPluginLog'
62		));
63		$this->assertTrue($result);
64		$this->assertEquals(CakeLog::configured(), array('libtest', 'plugintest'));
65
66		CakeLog::write(LOG_INFO, 'TestPluginLog is not a BaseLog descendant');
67
68		App::build();
69		CakePlugin::unload();
70	}
71
72/**
73 * test all the errors from failed logger imports
74 *
75 * @expectedException CakeLogException
76 * @return void
77 */
78	public function testImportingLoggerFailure() {
79		CakeLog::config('fail', array());
80	}
81
82/**
83 * test config() with valid key name
84 *
85 * @return void
86 */
87	public function testValidKeyName() {
88		CakeLog::config('valid', array('engine' => 'File'));
89		$stream = CakeLog::stream('valid');
90		$this->assertInstanceOf('FileLog', $stream);
91		CakeLog::drop('valid');
92	}
93
94/**
95 * test config() with valid key name including the deprecated Log suffix
96 *
97 * @return void
98 */
99	public function testValidKeyNameLogSuffix() {
100		CakeLog::config('valid', array('engine' => 'FileLog'));
101		$stream = CakeLog::stream('valid');
102		$this->assertInstanceOf('FileLog', $stream);
103		CakeLog::drop('valid');
104	}
105
106/**
107 * test config() with invalid key name
108 *
109 * @expectedException CakeLogException
110 * @return void
111 */
112	public function testInvalidKeyName() {
113		CakeLog::config('1nv', array('engine' => 'File'));
114	}
115
116/**
117 * test that loggers have to implement the correct interface.
118 *
119 * @expectedException CakeLogException
120 * @return void
121 */
122	public function testNotImplementingInterface() {
123		CakeLog::config('fail', array('engine' => 'stdClass'));
124	}
125
126/**
127 * Test that CakeLog does not auto create logs when no streams are there to listen.
128 *
129 * @return void
130 */
131	public function testNoStreamListenting() {
132		if (file_exists(LOGS . 'error.log')) {
133			unlink(LOGS . 'error.log');
134		}
135		$res = CakeLog::write(LOG_WARNING, 'Test warning');
136		$this->assertFalse($res);
137		$this->assertFalse(file_exists(LOGS . 'error.log'));
138
139		$result = CakeLog::configured();
140		$this->assertEquals(array(), $result);
141	}
142
143/**
144 * test configuring log streams
145 *
146 * @return void
147 */
148	public function testConfig() {
149		CakeLog::config('file', array(
150			'engine' => 'File',
151			'path' => LOGS
152		));
153		$result = CakeLog::configured();
154		$this->assertEquals(array('file'), $result);
155
156		if (file_exists(LOGS . 'error.log')) {
157			unlink(LOGS . 'error.log');
158		}
159		CakeLog::write(LOG_WARNING, 'Test warning');
160		$this->assertTrue(file_exists(LOGS . 'error.log'));
161
162		$result = file_get_contents(LOGS . 'error.log');
163		$this->assertRegExp('/^2[0-9]{3}-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+ Warning: Test warning/', $result);
164		unlink(LOGS . 'error.log');
165	}
166
167/**
168 * explicit tests for drop()
169 *
170 * @return void
171 */
172	public function testDrop() {
173		CakeLog::config('file', array(
174			'engine' => 'File',
175			'path' => LOGS
176		));
177		$result = CakeLog::configured();
178		$this->assertEquals(array('file'), $result);
179
180		CakeLog::drop('file');
181		$result = CakeLog::configured();
182		$this->assertSame(array(), $result);
183	}
184
185/**
186 * testLogFileWriting method
187 *
188 * @return void
189 */
190	public function testLogFileWriting() {
191		CakeLog::config('file', array(
192			'engine' => 'File',
193			'path' => LOGS
194		));
195		if (file_exists(LOGS . 'error.log')) {
196			unlink(LOGS . 'error.log');
197		}
198		$result = CakeLog::write(LOG_WARNING, 'Test warning');
199		$this->assertTrue($result);
200		$this->assertTrue(file_exists(LOGS . 'error.log'));
201		unlink(LOGS . 'error.log');
202
203		CakeLog::write(LOG_WARNING, 'Test warning 1');
204		CakeLog::write(LOG_WARNING, 'Test warning 2');
205		$result = file_get_contents(LOGS . 'error.log');
206		$this->assertRegExp('/^2[0-9]{3}-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+ Warning: Test warning 1/', $result);
207		$this->assertRegExp('/2[0-9]{3}-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+ Warning: Test warning 2$/', $result);
208		unlink(LOGS . 'error.log');
209	}
210
211/**
212 * test selective logging by level/type
213 *
214 * @return void
215 */
216	public function testSelectiveLoggingByLevel() {
217		if (file_exists(LOGS . 'spam.log')) {
218			unlink(LOGS . 'spam.log');
219		}
220		if (file_exists(LOGS . 'eggs.log')) {
221			unlink(LOGS . 'eggs.log');
222		}
223		CakeLog::config('spam', array(
224			'engine' => 'File',
225			'types' => 'debug',
226			'file' => 'spam',
227		));
228		CakeLog::config('eggs', array(
229			'engine' => 'File',
230			'types' => array('eggs', 'debug', 'error', 'warning'),
231			'file' => 'eggs',
232		));
233
234		$testMessage = 'selective logging';
235		CakeLog::write(LOG_WARNING, $testMessage);
236
237		$this->assertTrue(file_exists(LOGS . 'eggs.log'));
238		$this->assertFalse(file_exists(LOGS . 'spam.log'));
239
240		CakeLog::write(LOG_DEBUG, $testMessage);
241		$this->assertTrue(file_exists(LOGS . 'spam.log'));
242
243		$contents = file_get_contents(LOGS . 'spam.log');
244		$this->assertContains('Debug: ' . $testMessage, $contents);
245		$contents = file_get_contents(LOGS . 'eggs.log');
246		$this->assertContains('Debug: ' . $testMessage, $contents);
247
248		if (file_exists(LOGS . 'spam.log')) {
249			unlink(LOGS . 'spam.log');
250		}
251		if (file_exists(LOGS . 'eggs.log')) {
252			unlink(LOGS . 'eggs.log');
253		}
254	}
255
256/**
257 * test enable
258 *
259 * @expectedException CakeLogException
260 * @return void
261 */
262	public function testStreamEnable() {
263		CakeLog::config('spam', array(
264			'engine' => 'File',
265			'file' => 'spam',
266			));
267		$this->assertTrue(CakeLog::enabled('spam'));
268		CakeLog::drop('spam');
269		CakeLog::enable('bogus_stream');
270	}
271
272/**
273 * test disable
274 *
275 * @expectedException CakeLogException
276 * @return void
277 */
278	public function testStreamDisable() {
279		CakeLog::config('spam', array(
280			'engine' => 'File',
281			'file' => 'spam',
282			));
283		$this->assertTrue(CakeLog::enabled('spam'));
284		CakeLog::disable('spam');
285		$this->assertFalse(CakeLog::enabled('spam'));
286		CakeLog::drop('spam');
287		CakeLog::enable('bogus_stream');
288	}
289
290/**
291 * test enabled() invalid stream
292 *
293 * @expectedException CakeLogException
294 * @return void
295 */
296	public function testStreamEnabledInvalid() {
297		CakeLog::enabled('bogus_stream');
298	}
299
300/**
301 * test disable invalid stream
302 *
303 * @expectedException CakeLogException
304 * @return void
305 */
306	public function testStreamDisableInvalid() {
307		CakeLog::disable('bogus_stream');
308	}
309
310/**
311 * resets log config
312 *
313 * @return void
314 */
315	protected function _resetLogConfig() {
316		CakeLog::config('debug', array(
317			'engine' => 'File',
318			'types' => array('notice', 'info', 'debug'),
319			'file' => 'debug',
320		));
321		CakeLog::config('error', array(
322			'engine' => 'File',
323			'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
324			'file' => 'error',
325		));
326	}
327
328/**
329 * delete logs
330 *
331 * @return void
332 */
333	protected function _deleteLogs() {
334		if (file_exists(LOGS . 'shops.log')) {
335			unlink(LOGS . 'shops.log');
336		}
337		if (file_exists(LOGS . 'error.log')) {
338			unlink(LOGS . 'error.log');
339		}
340		if (file_exists(LOGS . 'debug.log')) {
341			unlink(LOGS . 'debug.log');
342		}
343		if (file_exists(LOGS . 'bogus.log')) {
344			unlink(LOGS . 'bogus.log');
345		}
346		if (file_exists(LOGS . 'spam.log')) {
347			unlink(LOGS . 'spam.log');
348		}
349		if (file_exists(LOGS . 'eggs.log')) {
350			unlink(LOGS . 'eggs.log');
351		}
352	}
353
354/**
355 * test backward compatible scoped logging
356 *
357 * @return void
358 */
359	public function testScopedLoggingBC() {
360		$this->_resetLogConfig();
361
362		CakeLog::config('shops', array(
363			'engine' => 'File',
364			'types' => array('info', 'notice', 'warning'),
365			'scopes' => array('transactions', 'orders'),
366			'file' => 'shops',
367		));
368		$this->_deleteLogs();
369
370		CakeLog::write('info', 'info message');
371		$this->assertFalse(file_exists(LOGS . 'error.log'));
372		$this->assertTrue(file_exists(LOGS . 'debug.log'));
373
374		$this->_deleteLogs();
375
376		CakeLog::write('transactions', 'transaction message');
377		$this->assertTrue(file_exists(LOGS . 'shops.log'));
378		$this->assertFalse(file_exists(LOGS . 'transactions.log'));
379		$this->assertFalse(file_exists(LOGS . 'error.log'));
380		$this->assertFalse(file_exists(LOGS . 'debug.log'));
381
382		$this->_deleteLogs();
383
384		CakeLog::write('error', 'error message');
385		$this->assertTrue(file_exists(LOGS . 'error.log'));
386		$this->assertFalse(file_exists(LOGS . 'debug.log'));
387		$this->assertFalse(file_exists(LOGS . 'shops.log'));
388
389		$this->_deleteLogs();
390
391		CakeLog::write('orders', 'order message');
392		$this->assertFalse(file_exists(LOGS . 'error.log'));
393		$this->assertFalse(file_exists(LOGS . 'debug.log'));
394		$this->assertFalse(file_exists(LOGS . 'orders.log'));
395		$this->assertTrue(file_exists(LOGS . 'shops.log'));
396
397		$this->_deleteLogs();
398
399		CakeLog::write('warning', 'warning message');
400		$this->assertTrue(file_exists(LOGS . 'error.log'));
401		$this->assertFalse(file_exists(LOGS . 'debug.log'));
402
403		$this->_deleteLogs();
404
405		CakeLog::drop('shops');
406	}
407
408/**
409 * Test that scopes are exclusive and don't bleed.
410 *
411 * @return void
412 */
413	public function testScopedLoggingExclusive() {
414		$this->_deleteLogs();
415
416		CakeLog::config('shops', array(
417			'engine' => 'File',
418			'types' => array('info', 'notice', 'warning'),
419			'scopes' => array('transactions', 'orders'),
420			'file' => 'shops.log',
421		));
422		CakeLog::config('eggs', array(
423			'engine' => 'File',
424			'types' => array('info', 'notice', 'warning'),
425			'scopes' => array('eggs'),
426			'file' => 'eggs.log',
427		));
428
429		CakeLog::write('info', 'transactions message', 'transactions');
430		$this->assertFalse(file_exists(LOGS . 'eggs.log'));
431		$this->assertTrue(file_exists(LOGS . 'shops.log'));
432
433		$this->_deleteLogs();
434
435		CakeLog::write('info', 'eggs message', 'eggs');
436		$this->assertTrue(file_exists(LOGS . 'eggs.log'));
437		$this->assertFalse(file_exists(LOGS . 'shops.log'));
438	}
439
440/**
441 * test scoped logging
442 *
443 * @return void
444 */
445	public function testScopedLogging() {
446		$this->_resetLogConfig();
447		$this->_deleteLogs();
448
449		CakeLog::config('string-scope', array(
450			'engine' => 'File',
451			'types' => array('info', 'notice', 'warning'),
452			'scopes' => 'string-scope',
453			'file' => 'string-scope.log'
454		));
455		CakeLog::write('info', 'info message', 'string-scope');
456		$this->assertTrue(file_exists(LOGS . 'string-scope.log'));
457
458		CakeLog::drop('string-scope');
459
460		CakeLog::config('shops', array(
461			'engine' => 'File',
462			'types' => array('info', 'notice', 'warning'),
463			'scopes' => array('transactions', 'orders'),
464			'file' => 'shops.log',
465		));
466
467		CakeLog::write('info', 'info message', 'transactions');
468		$this->assertFalse(file_exists(LOGS . 'error.log'));
469		$this->assertTrue(file_exists(LOGS . 'shops.log'));
470		$this->assertTrue(file_exists(LOGS . 'debug.log'));
471
472		$this->_deleteLogs();
473
474		CakeLog::write('transactions', 'transaction message', 'orders');
475		$this->assertTrue(file_exists(LOGS . 'shops.log'));
476		$this->assertFalse(file_exists(LOGS . 'transactions.log'));
477		$this->assertFalse(file_exists(LOGS . 'error.log'));
478		$this->assertFalse(file_exists(LOGS . 'debug.log'));
479
480		$this->_deleteLogs();
481
482		CakeLog::write('error', 'error message', 'orders');
483		$this->assertTrue(file_exists(LOGS . 'error.log'));
484		$this->assertFalse(file_exists(LOGS . 'debug.log'));
485		$this->assertFalse(file_exists(LOGS . 'shops.log'));
486
487		$this->_deleteLogs();
488
489		CakeLog::write('orders', 'order message', 'transactions');
490		$this->assertFalse(file_exists(LOGS . 'error.log'));
491		$this->assertFalse(file_exists(LOGS . 'debug.log'));
492		$this->assertFalse(file_exists(LOGS . 'orders.log'));
493		$this->assertTrue(file_exists(LOGS . 'shops.log'));
494
495		$this->_deleteLogs();
496
497		CakeLog::write('warning', 'warning message', 'orders');
498		$this->assertTrue(file_exists(LOGS . 'error.log'));
499		$this->assertTrue(file_exists(LOGS . 'shops.log'));
500		$this->assertFalse(file_exists(LOGS . 'debug.log'));
501
502		$this->_deleteLogs();
503
504		CakeLog::drop('shops');
505	}
506
507/**
508 * test bogus type and scope
509 *
510 * @return void
511 */
512	public function testBogusTypeAndScope() {
513		$this->_resetLogConfig();
514		$this->_deleteLogs();
515
516		CakeLog::config('file', array(
517			'engine' => 'File',
518			'path' => LOGS
519		));
520
521		CakeLog::write('bogus', 'bogus message');
522		$this->assertTrue(file_exists(LOGS . 'bogus.log'));
523		$this->assertFalse(file_exists(LOGS . 'error.log'));
524		$this->assertFalse(file_exists(LOGS . 'debug.log'));
525		$this->_deleteLogs();
526
527		CakeLog::write('bogus', 'bogus message', 'bogus');
528		$this->assertTrue(file_exists(LOGS . 'bogus.log'));
529		$this->assertFalse(file_exists(LOGS . 'error.log'));
530		$this->assertFalse(file_exists(LOGS . 'debug.log'));
531		$this->_deleteLogs();
532
533		CakeLog::write('error', 'bogus message', 'bogus');
534		$this->assertFalse(file_exists(LOGS . 'bogus.log'));
535		$this->assertTrue(file_exists(LOGS . 'error.log'));
536		$this->assertFalse(file_exists(LOGS . 'debug.log'));
537		$this->_deleteLogs();
538	}
539
540/**
541 * test scoped logging with convenience methods
542 *
543 * @return void
544 */
545	public function testConvenienceScopedLogging() {
546		if (file_exists(LOGS . 'shops.log')) {
547			unlink(LOGS . 'shops.log');
548		}
549		if (file_exists(LOGS . 'error.log')) {
550			unlink(LOGS . 'error.log');
551		}
552		if (file_exists(LOGS . 'debug.log')) {
553			unlink(LOGS . 'debug.log');
554		}
555
556		$this->_resetLogConfig();
557		CakeLog::config('shops', array(
558			'engine' => 'File',
559			'types' => array('info', 'debug', 'notice', 'warning'),
560			'scopes' => array('transactions', 'orders'),
561			'file' => 'shops',
562		));
563
564		CakeLog::info('info message', 'transactions');
565		$this->assertFalse(file_exists(LOGS . 'error.log'));
566		$this->assertTrue(file_exists(LOGS . 'shops.log'));
567		$this->assertTrue(file_exists(LOGS . 'debug.log'));
568
569		$this->_deleteLogs();
570
571		CakeLog::error('error message', 'orders');
572		$this->assertTrue(file_exists(LOGS . 'error.log'));
573		$this->assertFalse(file_exists(LOGS . 'debug.log'));
574		$this->assertFalse(file_exists(LOGS . 'shops.log'));
575
576		$this->_deleteLogs();
577
578		CakeLog::warning('warning message', 'orders');
579		$this->assertTrue(file_exists(LOGS . 'error.log'));
580		$this->assertTrue(file_exists(LOGS . 'shops.log'));
581		$this->assertFalse(file_exists(LOGS . 'debug.log'));
582
583		$this->_deleteLogs();
584
585		CakeLog::drop('shops');
586	}
587
588/**
589 * test convenience methods
590 *
591 * @return void
592 */
593	public function testConvenienceMethods() {
594		$this->_deleteLogs();
595
596		CakeLog::config('debug', array(
597			'engine' => 'File',
598			'types' => array('notice', 'info', 'debug'),
599			'file' => 'debug',
600		));
601		CakeLog::config('error', array(
602			'engine' => 'File',
603			'types' => array('emergency', 'alert', 'critical', 'error', 'warning'),
604			'file' => 'error',
605		));
606
607		$testMessage = 'emergency message';
608		CakeLog::emergency($testMessage);
609		$contents = file_get_contents(LOGS . 'error.log');
610		$this->assertRegExp('/(Emergency|Critical): ' . $testMessage . '/', $contents);
611		$this->assertFalse(file_exists(LOGS . 'debug.log'));
612		$this->_deleteLogs();
613
614		$testMessage = 'alert message';
615		CakeLog::alert($testMessage);
616		$contents = file_get_contents(LOGS . 'error.log');
617		$this->assertRegExp('/(Alert|Critical): ' . $testMessage . '/', $contents);
618		$this->assertFalse(file_exists(LOGS . 'debug.log'));
619		$this->_deleteLogs();
620
621		$testMessage = 'critical message';
622		CakeLog::critical($testMessage);
623		$contents = file_get_contents(LOGS . 'error.log');
624		$this->assertContains('Critical: ' . $testMessage, $contents);
625		$this->assertFalse(file_exists(LOGS . 'debug.log'));
626		$this->_deleteLogs();
627
628		$testMessage = 'error message';
629		CakeLog::error($testMessage);
630		$contents = file_get_contents(LOGS . 'error.log');
631		$this->assertContains('Error: ' . $testMessage, $contents);
632		$this->assertFalse(file_exists(LOGS . 'debug.log'));
633		$this->_deleteLogs();
634
635		$testMessage = 'warning message';
636		CakeLog::warning($testMessage);
637		$contents = file_get_contents(LOGS . 'error.log');
638		$this->assertContains('Warning: ' . $testMessage, $contents);
639		$this->assertFalse(file_exists(LOGS . 'debug.log'));
640		$this->_deleteLogs();
641
642		$testMessage = 'notice message';
643		CakeLog::notice($testMessage);
644		$contents = file_get_contents(LOGS . 'debug.log');
645		$this->assertRegExp('/(Notice|Debug): ' . $testMessage . '/', $contents);
646		$this->assertFalse(file_exists(LOGS . 'error.log'));
647		$this->_deleteLogs();
648
649		$testMessage = 'info message';
650		CakeLog::info($testMessage);
651		$contents = file_get_contents(LOGS . 'debug.log');
652		$this->assertRegExp('/(Info|Debug): ' . $testMessage . '/', $contents);
653		$this->assertFalse(file_exists(LOGS . 'error.log'));
654		$this->_deleteLogs();
655
656		$testMessage = 'debug message';
657		CakeLog::debug($testMessage);
658		$contents = file_get_contents(LOGS . 'debug.log');
659		$this->assertContains('Debug: ' . $testMessage, $contents);
660		$this->assertFalse(file_exists(LOGS . 'error.log'));
661		$this->_deleteLogs();
662	}
663
664/**
665 * test levels customization
666 *
667 * @return void
668 */
669	public function testLevelCustomization() {
670		$this->skipIf(DIRECTORY_SEPARATOR === '\\', 'Log level tests not supported on Windows.');
671
672		$levels = CakeLog::defaultLevels();
673		$this->assertNotEmpty($levels);
674		$result = array_keys($levels);
675		$this->assertEquals(array(0, 1, 2, 3, 4, 5, 6, 7), $result);
676
677		$levels = CakeLog::levels(array('foo', 'bar'));
678		CakeLog::defaultLevels();
679		$this->assertEquals('foo', $levels[8]);
680		$this->assertEquals('bar', $levels[9]);
681
682		$levels = CakeLog::levels(array(11 => 'spam', 'bar' => 'eggs'));
683		CakeLog::defaultLevels();
684		$this->assertEquals('spam', $levels[8]);
685		$this->assertEquals('eggs', $levels[9]);
686
687		$levels = CakeLog::levels(array(11 => 'spam', 'bar' => 'eggs'), false);
688		CakeLog::defaultLevels();
689		$this->assertEquals(array('spam', 'eggs'), $levels);
690
691		$levels = CakeLog::levels(array('ham', 9 => 'spam', '12' => 'fam'), false);
692		CakeLog::defaultLevels();
693		$this->assertEquals(array('ham', 'spam', 'fam'), $levels);
694	}
695
696/**
697 * Test writing log files with custom levels
698 *
699 * @return void
700 */
701	public function testCustomLevelWrites() {
702		$this->_deleteLogs();
703		$this->_resetLogConfig();
704
705		CakeLog::levels(array('spam', 'eggs'));
706
707		$testMessage = 'error message';
708		CakeLog::write('error', $testMessage);
709		CakeLog::defaultLevels();
710		$this->assertTrue(file_exists(LOGS . 'error.log'));
711		$contents = file_get_contents(LOGS . 'error.log');
712		$this->assertContains('Error: ' . $testMessage, $contents);
713
714		CakeLog::config('spam', array(
715			'engine' => 'File',
716			'file' => 'spam.log',
717			'types' => 'spam',
718			));
719		CakeLog::config('eggs', array(
720			'engine' => 'File',
721			'file' => 'eggs.log',
722			'types' => array('spam', 'eggs'),
723			));
724
725		$testMessage = 'spam message';
726		CakeLog::write('spam', $testMessage);
727		CakeLog::defaultLevels();
728		$this->assertTrue(file_exists(LOGS . 'spam.log'));
729		$this->assertTrue(file_exists(LOGS . 'eggs.log'));
730		$contents = file_get_contents(LOGS . 'spam.log');
731		$this->assertContains('Spam: ' . $testMessage, $contents);
732
733		$testMessage = 'egg message';
734		CakeLog::write('eggs', $testMessage);
735		CakeLog::defaultLevels();
736		$contents = file_get_contents(LOGS . 'spam.log');
737		$this->assertNotContains('Eggs: ' . $testMessage, $contents);
738		$contents = file_get_contents(LOGS . 'eggs.log');
739		$this->assertContains('Eggs: ' . $testMessage, $contents);
740
741		CakeLog::drop('spam');
742		CakeLog::drop('eggs');
743
744		$this->_deleteLogs();
745	}
746
747}
748