See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 39 and 401]
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 = ' '; 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 = ' '; 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, ' ') !== 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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body