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