Proyectos de Subversion Moodle

Rev

Ir a la última revisión | | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
/**
18
 * Logger tests (all).
19
 * @package    core_backup
20
 * @category   test
21
 * @copyright  2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
namespace core_backup;
26
 
27
use backup;
28
use base_logger;
29
use base_logger_exception;
30
use database_logger;
31
use error_log_logger;
32
use file_logger;
33
use output_indented_logger;
34
use output_text_logger;
35
 
36
defined('MOODLE_INTERNAL') || die();
37
 
38
// Include all the needed stuff
39
global $CFG;
40
require_once($CFG->dirroot . '/backup/util/interfaces/checksumable.class.php');
41
require_once($CFG->dirroot . '/backup/backup.class.php');
42
require_once($CFG->dirroot . '/backup/util/loggers/base_logger.class.php');
43
require_once($CFG->dirroot . '/backup/util/loggers/error_log_logger.class.php');
44
require_once($CFG->dirroot . '/backup/util/loggers/output_text_logger.class.php');
45
require_once($CFG->dirroot . '/backup/util/loggers/output_indented_logger.class.php');
46
require_once($CFG->dirroot . '/backup/util/loggers/database_logger.class.php');
47
require_once($CFG->dirroot . '/backup/util/loggers/file_logger.class.php');
48
 
49
 
50
/**
51
 * Logger tests (all).
52
 *
53
 * @package    core_backup
54
 * @category   test
55
 * @copyright  2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
56
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
57
 */
58
class logger_test extends \basic_testcase {
59
 
60
    /**
61
     * test base_logger class
62
     */
63
    function test_base_logger() {
64
        // Test logger with simple action (message * level)
65
        $lo = new mock_base_logger1(backup::LOG_ERROR);
66
        $msg = 13;
67
        $this->assertEquals($lo->process($msg, backup::LOG_ERROR), $msg * backup::LOG_ERROR);
68
        // With lowest level must return true
69
        $lo = new mock_base_logger1(backup::LOG_ERROR);
70
        $msg = 13;
71
        $this->assertTrue($lo->process($msg, backup::LOG_DEBUG));
72
 
73
        // Chain 2 loggers, we must get as result the result of the inner one
74
        $lo1 = new mock_base_logger1(backup::LOG_ERROR);
75
        $lo2 = new mock_base_logger2(backup::LOG_ERROR);
76
        $lo1->set_next($lo2);
77
        $msg = 13;
78
        $this->assertEquals($lo1->process($msg, backup::LOG_ERROR), $msg + backup::LOG_ERROR);
79
 
80
        // Try circular reference
81
        $lo1 = new mock_base_logger1(backup::LOG_ERROR);
82
        try {
83
            $lo1->set_next($lo1); //self
84
            $this->assertTrue(false, 'base_logger_exception expected');
85
        } catch (\Exception $e) {
86
            $this->assertTrue($e instanceof base_logger_exception);
87
            $this->assertEquals($e->errorcode, 'logger_circular_reference');
88
            $this->assertTrue($e->a instanceof \stdClass);
89
            $this->assertEquals($e->a->main, get_class($lo1));
90
            $this->assertEquals($e->a->alreadyinchain, get_class($lo1));
91
        }
92
 
93
        $lo1 = new mock_base_logger1(backup::LOG_ERROR);
94
        $lo2 = new mock_base_logger2(backup::LOG_ERROR);
95
        $lo3 = new mock_base_logger3(backup::LOG_ERROR);
96
        $lo1->set_next($lo2);
97
        $lo2->set_next($lo3);
98
        try {
99
            $lo3->set_next($lo1);
100
            $this->assertTrue(false, 'base_logger_exception expected');
101
        } catch (\Exception $e) {
102
            $this->assertTrue($e instanceof base_logger_exception);
103
            $this->assertEquals($e->errorcode, 'logger_circular_reference');
104
            $this->assertTrue($e->a instanceof \stdClass);
105
            $this->assertEquals($e->a->main, get_class($lo1));
106
            $this->assertEquals($e->a->alreadyinchain, get_class($lo3));
107
        }
108
 
109
        // Test stopper logger
110
        $lo1 = new mock_base_logger1(backup::LOG_ERROR);
111
        $lo2 = new mock_base_logger2(backup::LOG_ERROR);
112
        $lo3 = new mock_base_logger3(backup::LOG_ERROR);
113
        $lo1->set_next($lo2);
114
        $lo2->set_next($lo3);
115
        $msg = 13;
116
        $this->assertFalse($lo1->process($msg, backup::LOG_ERROR));
117
 
118
        // Test checksum correct
119
        $lo1 = new mock_base_logger1(backup::LOG_ERROR);
120
        $lo1->is_checksum_correct(get_class($lo1) . '-' . backup::LOG_ERROR);
121
 
122
        // Test get_levelstr()
123
        $lo1 = new mock_base_logger1(backup::LOG_ERROR);
124
        $this->assertEquals($lo1->get_levelstr(backup::LOG_NONE), 'undefined');
125
        $this->assertEquals($lo1->get_levelstr(backup::LOG_ERROR), 'error');
126
        $this->assertEquals($lo1->get_levelstr(backup::LOG_WARNING), 'warn');
127
        $this->assertEquals($lo1->get_levelstr(backup::LOG_INFO), 'info');
128
        $this->assertEquals($lo1->get_levelstr(backup::LOG_DEBUG), 'debug');
129
 
130
        // Test destroy.
131
        $lo1 = new mock_base_logger1(backup::LOG_ERROR);
132
        $lo2 = new mock_base_logger2(backup::LOG_ERROR);
133
        $lo1->set_next($lo2);
134
        $this->assertInstanceOf('base_logger', $lo1->get_next());
135
        $this->assertNull($lo2->get_next());
136
        $lo1->destroy();
137
        $this->assertNull($lo1->get_next());
138
        $this->assertNull($lo2->get_next());
139
    }
140
 
141
    /**
142
     * test error_log_logger class
143
     */
144
    function test_error_log_logger() {
145
        // Not much really to test, just instantiate and execute, should return true
146
        $lo = new error_log_logger(backup::LOG_ERROR);
147
        $this->assertTrue($lo instanceof error_log_logger);
148
        $message = 'This log exists because you have run Moodle unit tests: Ignore it';
149
        $result = $lo->process($message, backup::LOG_ERROR);
150
        $this->assertTrue($result);
151
    }
152
 
153
    /**
154
     * test output_text_logger class
155
     */
156
    function test_output_text_logger() {
157
        // Instantiate without date nor level output
158
        $lo = new output_text_logger(backup::LOG_ERROR);
159
        $this->assertTrue($lo instanceof output_text_logger);
160
        $message = 'testing output_text_logger';
161
        ob_start(); // Capture output
162
        $result = $lo->process($message, backup::LOG_ERROR);
163
        $contents = ob_get_contents();
164
        ob_end_clean(); // End capture and discard
165
        $this->assertTrue($result);
166
        $this->assertTrue(strpos($contents, $message) !== false);
167
 
168
        // Instantiate with date and level output
169
        $lo = new output_text_logger(backup::LOG_ERROR, true, true);
170
        $this->assertTrue($lo instanceof output_text_logger);
171
        $message = 'testing output_text_logger';
172
        ob_start(); // Capture output
173
        $result = $lo->process($message, backup::LOG_ERROR);
174
        $contents = ob_get_contents();
175
        ob_end_clean(); // End capture and discard
176
        $this->assertTrue($result);
177
        $this->assertTrue(strpos($contents,'[') === 0);
178
        $this->assertTrue(strpos($contents,'[error]') !== false);
179
        $this->assertTrue(strpos($contents, $message) !== false);
180
        $this->assertTrue(substr_count($contents , '] ') >= 2);
181
    }
182
 
183
    /**
184
     * test output_indented_logger class
185
     */
186
    function test_output_indented_logger() {
187
        // Instantiate without date nor level output
188
        $options = array('depth' => 2);
189
        $lo = new output_indented_logger(backup::LOG_ERROR);
190
        $this->assertTrue($lo instanceof output_indented_logger);
191
        $message = 'testing output_indented_logger';
192
        ob_start(); // Capture output
193
        $result = $lo->process($message, backup::LOG_ERROR, $options);
194
        $contents = ob_get_contents();
195
        ob_end_clean(); // End capture and discard
196
        $this->assertTrue($result);
197
        if (defined('STDOUT')) {
198
            $check = '  ';
199
        } else {
200
            $check = '&nbsp;&nbsp;';
201
        }
202
        $this->assertTrue(strpos($contents, str_repeat($check, $options['depth']) . $message) !== false);
203
 
204
        // Instantiate with date and level output
205
        $options = array('depth' => 3);
206
        $lo = new output_indented_logger(backup::LOG_ERROR, true, true);
207
        $this->assertTrue($lo instanceof output_indented_logger);
208
        $message = 'testing output_indented_logger';
209
        ob_start(); // Capture output
210
        $result = $lo->process($message, backup::LOG_ERROR, $options);
211
        $contents = ob_get_contents();
212
        ob_end_clean(); // End capture and discard
213
        $this->assertTrue($result);
214
        $this->assertTrue(strpos($contents,'[') === 0);
215
        $this->assertTrue(strpos($contents,'[error]') !== false);
216
        $this->assertTrue(strpos($contents, $message) !== false);
217
        $this->assertTrue(substr_count($contents , '] ') >= 2);
218
        if (defined('STDOUT')) {
219
            $check = '  ';
220
        } else {
221
            $check = '&nbsp;&nbsp;';
222
        }
223
        $this->assertTrue(strpos($contents, str_repeat($check, $options['depth']) . $message) !== false);
224
    }
225
 
226
    /**
227
     * test database_logger class
228
     */
229
    function test_database_logger() {
230
        // Instantiate with date and level output (and with specs from the global moodle "log" table so checks will pass
231
        $now = time();
232
        $datecol = 'time';
233
        $levelcol = 'action';
234
        $messagecol = 'info';
235
        $logtable = 'log';
236
        $columns = array('url' => 'http://127.0.0.1');
237
        $loglevel = backup::LOG_ERROR;
238
        $lo = new mock_database_logger(backup::LOG_ERROR, $datecol, $levelcol, $messagecol, $logtable, $columns);
239
        $this->assertTrue($lo instanceof database_logger);
240
        $message = 'testing database_logger';
241
        $result = $lo->process($message, $loglevel);
242
        // Check everything is ready to be inserted to DB
243
        $this->assertEquals($result['table'], $logtable);
244
        $this->assertTrue($result['columns'][$datecol] >= $now);
245
        $this->assertEquals($result['columns'][$levelcol], $loglevel);
246
        $this->assertEquals($result['columns'][$messagecol], $message);
247
        $this->assertEquals($result['columns']['url'], $columns['url']);
248
    }
249
 
250
    /**
251
     * test file_logger class
252
     */
253
    function test_file_logger() {
254
        global $CFG;
255
 
256
        $file = $CFG->tempdir . '/test/test_file_logger.txt';
257
        // Remove the test dir and any content
258
        @remove_dir(dirname($file));
259
        // Recreate test dir
260
        if (!check_dir_exists(dirname($file), true, true)) {
261
            throw new \moodle_exception('error_creating_temp_dir', 'error', dirname($file));
262
        }
263
 
264
        // Instantiate with date and level output, and also use the depth option
265
        $options = array('depth' => 3);
266
        $lo1 = new file_logger(backup::LOG_ERROR, true, true, $file);
267
        $this->assertTrue($lo1 instanceof file_logger);
268
        $message1 = 'testing file_logger';
269
        $result = $lo1->process($message1, backup::LOG_ERROR, $options);
270
        $this->assertTrue($result);
271
 
272
        // Another file_logger is going towrite there too without closing
273
        $options = array();
274
        $lo2 = new file_logger(backup::LOG_WARNING, true, true, $file);
275
        $this->assertTrue($lo2 instanceof file_logger);
276
        $message2 = 'testing file_logger2';
277
        $result = $lo2->process($message2, backup::LOG_WARNING, $options);
278
        $this->assertTrue($result);
279
 
280
        // Destroy loggers.
281
        $lo1->destroy();
282
        $lo2->destroy();
283
 
284
        // Load file results to analyze them
285
        $fcontents = file_get_contents($file);
286
        $acontents = explode(PHP_EOL, $fcontents); // Split by line
287
        $this->assertTrue(strpos($acontents[0], $message1) !== false);
288
        $this->assertTrue(strpos($acontents[0], '[error]') !== false);
289
        $this->assertTrue(strpos($acontents[0], '      ') !== false);
290
        $this->assertTrue(substr_count($acontents[0] , '] ') >= 2);
291
        $this->assertTrue(strpos($acontents[1], $message2) !== false);
292
        $this->assertTrue(strpos($acontents[1], '[warn]') !== false);
293
        $this->assertTrue(strpos($acontents[1], '      ') === false);
294
        $this->assertTrue(substr_count($acontents[1] , '] ') >= 2);
295
        unlink($file); // delete file
296
 
297
        // Try one html file
298
        check_dir_exists($CFG->tempdir . '/test');
299
        $file = $CFG->tempdir . '/test/test_file_logger.html';
300
        $options = array('depth' => 1);
301
        $lo = new file_logger(backup::LOG_ERROR, true, true, $file);
302
        $this->assertTrue($lo instanceof file_logger);
303
        $this->assertTrue(file_exists($file));
304
        $message = 'testing file_logger';
305
        $result = $lo->process($message, backup::LOG_ERROR, $options);
306
        $lo->close(); // Closes logger.
307
        // Get file contents and inspect them
308
        $fcontents = file_get_contents($file);
309
        $this->assertTrue($result);
310
        $this->assertTrue(strpos($fcontents, $message) !== false);
311
        $this->assertTrue(strpos($fcontents, '[error]') !== false);
312
        $this->assertTrue(strpos($fcontents, '&nbsp;&nbsp;') !== false);
313
        $this->assertTrue(substr_count($fcontents , '] ') >= 2);
314
        unlink($file); // delete file
315
 
316
        // Instantiate, write something, force deletion, try to write again
317
        check_dir_exists($CFG->tempdir . '/test');
318
        $file = $CFG->tempdir . '/test/test_file_logger.html';
319
        $lo = new mock_file_logger(backup::LOG_ERROR, true, true, $file);
320
        $this->assertTrue(file_exists($file));
321
        $message = 'testing file_logger';
322
        $result = $lo->process($message, backup::LOG_ERROR);
323
        $lo->close();
324
        $this->assertNull($lo->get_fhandle());
325
        try {
326
            $result = @$lo->process($message, backup::LOG_ERROR); // Try to write again
327
            $this->assertTrue(false, 'base_logger_exception expected');
328
        } catch (\Exception $e) {
329
            $this->assertTrue($e instanceof base_logger_exception);
330
            $this->assertEquals($e->errorcode, 'error_writing_file');
331
        }
332
 
333
        // Instantiate without file
334
        try {
335
            $lo = new file_logger(backup::LOG_WARNING, true, true, '');
336
            $this->assertTrue(false, 'base_logger_exception expected');
337
        } catch (\Exception $e) {
338
            $this->assertTrue($e instanceof base_logger_exception);
339
            $this->assertEquals($e->errorcode, 'missing_fullpath_parameter');
340
        }
341
 
342
        // Instantiate in (near) impossible path
343
        $file =  $CFG->tempdir . '/test_azby/test_file_logger.txt';
344
        try {
345
            $lo = new file_logger(backup::LOG_WARNING, true, true, $file);
346
            $this->assertTrue(false, 'base_logger_exception expected');
347
        } catch (\Exception $e) {
348
            $this->assertTrue($e instanceof base_logger_exception);
349
            $this->assertEquals($e->errorcode, 'file_not_writable');
350
            $this->assertEquals($e->a, $file);
351
        }
352
 
353
        // Instantiate one file logger with level = backup::LOG_NONE
354
        $file =  $CFG->tempdir . '/test/test_file_logger.txt';
355
        $lo = new file_logger(backup::LOG_NONE, true, true, $file);
356
        $this->assertTrue($lo instanceof file_logger);
357
        $this->assertFalse(file_exists($file));
358
        $lo->close();
359
 
360
        // Remove the test dir and any content
361
        @remove_dir(dirname($file));
362
    }
363
}
364
 
365
 
366
/**
367
 * helper extended base_logger class that implements some methods for testing
368
 * Simply return the product of message and level
369
 */
370
class mock_base_logger1 extends base_logger {
371
 
372
    protected function action($message, $level, $options = null) {
373
        return $message * $level; // Simply return that, for testing
374
    }
375
    public function get_levelstr($level) {
376
        return parent::get_levelstr($level);
377
    }
378
}
379
 
380
/**
381
 * helper extended base_logger class that implements some methods for testing
382
 * Simply return the sum of message and level
383
 */
384
class mock_base_logger2 extends base_logger {
385
 
386
    protected function action($message, $level, $options = null) {
387
        return $message + $level; // Simply return that, for testing
388
    }
389
}
390
 
391
/**
392
 * helper extended base_logger class that implements some methods for testing
393
 * Simply return 8
394
 */
395
class mock_base_logger3 extends base_logger {
396
 
397
    protected function action($message, $level, $options = null) {
398
        return false; // Simply return false, for testing stopper
399
    }
400
}
401
 
402
/**
403
 * helper extended database_logger class that implements some methods for testing
404
 * Returns the complete info that normally will be used by insert record calls
405
 */
406
class mock_database_logger extends database_logger {
407
 
408
    protected function insert_log_record($table, $columns) {
409
        return array('table' => $table, 'columns' => $columns);
410
    }
411
}
412
 
413
/**
414
 * helper extended file_logger class that implements some methods for testing
415
 * Returns the, usually protected, handle
416
 */
417
class mock_file_logger extends file_logger {
418
 
419
    function get_fhandle() {
420
        return $this->fhandle;
421
    }
422
}