|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 00003 // This file is part of Moodle - http://moodle.org/ 00004 // 00005 // Moodle is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // Moodle is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00017 00025 // Prevent direct access to this file 00026 if (!defined('MOODLE_INTERNAL')) { 00027 die('Direct access to this script is forbidden.'); 00028 } 00029 00030 // Include all the needed stuff 00031 require_once($CFG->dirroot . '/backup/util/interfaces/checksumable.class.php'); 00032 require_once($CFG->dirroot . '/backup/backup.class.php'); 00033 require_once($CFG->dirroot . '/backup/util/loggers/base_logger.class.php'); 00034 require_once($CFG->dirroot . '/backup/util/loggers/error_log_logger.class.php'); 00035 require_once($CFG->dirroot . '/backup/util/loggers/output_text_logger.class.php'); 00036 require_once($CFG->dirroot . '/backup/util/loggers/output_indented_logger.class.php'); 00037 require_once($CFG->dirroot . '/backup/util/loggers/database_logger.class.php'); 00038 require_once($CFG->dirroot . '/backup/util/loggers/file_logger.class.php'); 00039 00040 /* 00041 * logger tests (all) 00042 */ 00043 class logger_test extends UnitTestCase { 00044 00045 public static $includecoverage = array('backup/util/loggers'); 00046 public static $excludecoverage = array('backup/util/loggers/simpletest'); 00047 00048 /* 00049 * test base_logger class 00050 */ 00051 function test_base_logger() { 00052 // Test logger with simple action (message * level) 00053 $lo = new mock_base_logger1(backup::LOG_ERROR); 00054 $msg = 13; 00055 $this->assertEqual($lo->process($msg, backup::LOG_ERROR), $msg * backup::LOG_ERROR); 00056 // With lowest level must resturn true 00057 $lo = new mock_base_logger1(backup::LOG_ERROR); 00058 $msg = 13; 00059 $this->assertTrue($lo->process($msg, backup::LOG_DEBUG)); 00060 00061 // Chain 2 loggers, we must get as result the result of the ineer one 00062 $lo1 = new mock_base_logger1(backup::LOG_ERROR); 00063 $lo2 = new mock_base_logger2(backup::LOG_ERROR); 00064 $lo1->set_next($lo2); 00065 $msg = 13; 00066 $this->assertEqual($lo1->process($msg, backup::LOG_ERROR), $msg + backup::LOG_ERROR); 00067 00068 // Try circular reference 00069 $lo1 = new mock_base_logger1(backup::LOG_ERROR); 00070 try { 00071 $lo1->set_next($lo1); //self 00072 $this->assertTrue(false, 'base_logger_exception expected'); 00073 } catch (exception $e) { 00074 $this->assertTrue($e instanceof base_logger_exception); 00075 $this->assertEqual($e->errorcode, 'logger_circular_reference'); 00076 $this->assertTrue($e->a instanceof stdclass); 00077 $this->assertEqual($e->a->main, get_class($lo1)); 00078 $this->assertEqual($e->a->alreadyinchain, get_class($lo1)); 00079 } 00080 00081 $lo1 = new mock_base_logger1(backup::LOG_ERROR); 00082 $lo2 = new mock_base_logger2(backup::LOG_ERROR); 00083 $lo3 = new mock_base_logger3(backup::LOG_ERROR); 00084 $lo1->set_next($lo2); 00085 $lo2->set_next($lo3); 00086 try { 00087 $lo3->set_next($lo1); 00088 $this->assertTrue(false, 'base_logger_exception expected'); 00089 } catch (exception $e) { 00090 $this->assertTrue($e instanceof base_logger_exception); 00091 $this->assertEqual($e->errorcode, 'logger_circular_reference'); 00092 $this->assertTrue($e->a instanceof stdclass); 00093 $this->assertEqual($e->a->main, get_class($lo1)); 00094 $this->assertEqual($e->a->alreadyinchain, get_class($lo3)); 00095 } 00096 00097 // Test stopper logger 00098 $lo1 = new mock_base_logger1(backup::LOG_ERROR); 00099 $lo2 = new mock_base_logger2(backup::LOG_ERROR); 00100 $lo3 = new mock_base_logger3(backup::LOG_ERROR); 00101 $lo1->set_next($lo2); 00102 $lo2->set_next($lo3); 00103 $this->assertFalse($lo1->process('test', backup::LOG_ERROR)); 00104 00105 // Test checksum correct 00106 $lo1 = new mock_base_logger1(backup::LOG_ERROR); 00107 $lo1->is_checksum_correct(get_class($lo1) . '-' . backup::LOG_ERROR); 00108 00109 // Test get_levelstr() 00110 $lo1 = new mock_base_logger1(backup::LOG_ERROR); 00111 $this->assertEqual($lo1->get_levelstr(backup::LOG_NONE), 'undefined'); 00112 $this->assertEqual($lo1->get_levelstr(backup::LOG_ERROR), 'error'); 00113 $this->assertEqual($lo1->get_levelstr(backup::LOG_WARNING), 'warn'); 00114 $this->assertEqual($lo1->get_levelstr(backup::LOG_INFO), 'info'); 00115 $this->assertEqual($lo1->get_levelstr(backup::LOG_DEBUG), 'debug'); 00116 } 00117 00118 /* 00119 * test error_log_logger class 00120 */ 00121 function test_error_log_logger() { 00122 // Not much really to test, just intantiate and execute, should return true 00123 $lo = new error_log_logger(backup::LOG_ERROR); 00124 $this->assertTrue($lo instanceof error_log_logger); 00125 $message = 'This log exists because you have run Moodle unit tests: Ignore it'; 00126 $result = $lo->process($message, backup::LOG_ERROR); 00127 $this->assertTrue($result); 00128 } 00129 00130 /* 00131 * test output_text_logger class 00132 */ 00133 function test_output_text_logger() { 00134 // Instantiate without date nor level output 00135 $lo = new output_text_logger(backup::LOG_ERROR); 00136 $this->assertTrue($lo instanceof output_text_logger); 00137 $message = 'testing output_text_logger'; 00138 ob_start(); // Capture output 00139 $result = $lo->process($message, backup::LOG_ERROR); 00140 $contents = ob_get_contents(); 00141 ob_end_clean(); // End capture and discard 00142 $this->assertTrue($result); 00143 $this->assertTrue(strpos($contents, $message) !== false); 00144 00145 // Instantiate with date and level output 00146 $lo = new output_text_logger(backup::LOG_ERROR, true, true); 00147 $this->assertTrue($lo instanceof output_text_logger); 00148 $message = 'testing output_text_logger'; 00149 ob_start(); // Capture output 00150 $result = $lo->process($message, backup::LOG_ERROR); 00151 $contents = ob_get_contents(); 00152 ob_end_clean(); // End capture and discard 00153 $this->assertTrue($result); 00154 $this->assertTrue(strpos($contents,'[') === 0); 00155 $this->assertTrue(strpos($contents,'[error]') !== false); 00156 $this->assertTrue(strpos($contents, $message) !== false); 00157 $this->assertTrue(substr_count($contents , '] ') >= 2); 00158 } 00159 00160 /* 00161 * test output_indented_logger class 00162 */ 00163 function test_output_indented_logger() { 00164 // Instantiate without date nor level output 00165 $options = array('depth' => 2); 00166 $lo = new output_indented_logger(backup::LOG_ERROR); 00167 $this->assertTrue($lo instanceof output_indented_logger); 00168 $message = 'testing output_indented_logger'; 00169 ob_start(); // Capture output 00170 $result = $lo->process($message, backup::LOG_ERROR, $options); 00171 $contents = ob_get_contents(); 00172 ob_end_clean(); // End capture and discard 00173 $this->assertTrue($result); 00174 if (defined('STDOUT')) { 00175 $check = ' '; 00176 } else { 00177 $check = ' '; 00178 } 00179 $this->assertTrue(strpos($contents, str_repeat($check, $options['depth']) . $message) !== false); 00180 00181 // Instantiate with date and level output 00182 $options = array('depth' => 3); 00183 $lo = new output_indented_logger(backup::LOG_ERROR, true, true); 00184 $this->assertTrue($lo instanceof output_indented_logger); 00185 $message = 'testing output_indented_logger'; 00186 ob_start(); // Capture output 00187 $result = $lo->process($message, backup::LOG_ERROR, $options); 00188 $contents = ob_get_contents(); 00189 ob_end_clean(); // End capture and discard 00190 $this->assertTrue($result); 00191 $this->assertTrue(strpos($contents,'[') === 0); 00192 $this->assertTrue(strpos($contents,'[error]') !== false); 00193 $this->assertTrue(strpos($contents, $message) !== false); 00194 $this->assertTrue(substr_count($contents , '] ') >= 2); 00195 if (defined('STDOUT')) { 00196 $check = ' '; 00197 } else { 00198 $check = ' '; 00199 } 00200 $this->assertTrue(strpos($contents, str_repeat($check, $options['depth']) . $message) !== false); 00201 } 00202 00203 /* 00204 * test database_logger class 00205 */ 00206 function test_database_logger() { 00207 // Instantiate with date and level output (and with specs from the global moodle "log" table so checks will pass 00208 $now = time(); 00209 $datecol = 'time'; 00210 $levelcol = 'action'; 00211 $messagecol = 'info'; 00212 $logtable = 'log'; 00213 $columns = array('url' => 'http://127.0.0.1'); 00214 $loglevel = backup::LOG_ERROR; 00215 $lo = new mock_database_logger(backup::LOG_ERROR, $datecol, $levelcol, $messagecol, $logtable, $columns); 00216 $this->assertTrue($lo instanceof database_logger); 00217 $message = 'testing database_logger'; 00218 $result = $lo->process($message, $loglevel); 00219 // Check everything is ready to be inserted to DB 00220 $this->assertEqual($result['table'], $logtable); 00221 $this->assertTrue($result['columns'][$datecol] >= $now); 00222 $this->assertEqual($result['columns'][$levelcol], $loglevel); 00223 $this->assertEqual($result['columns'][$messagecol], $message); 00224 $this->assertEqual($result['columns']['url'], $columns['url']); 00225 } 00226 00227 /* 00228 * test file_logger class 00229 */ 00230 function test_file_logger() { 00231 global $CFG; 00232 00233 $file = $CFG->tempdir . '/test/test_file_logger.txt'; 00234 // Remove the test dir and any content 00235 @remove_dir(dirname($file)); 00236 // Recreate test dir 00237 if (!check_dir_exists(dirname($file), true, true)) { 00238 throw new moodle_exception('error_creating_temp_dir', 'error', dirname($file)); 00239 } 00240 00241 // Instantiate with date and level output, and also use the depth option 00242 $options = array('depth' => 3); 00243 $lo1 = new file_logger(backup::LOG_ERROR, true, true, $file); 00244 $this->assertTrue($lo1 instanceof file_logger); 00245 $message1 = 'testing file_logger'; 00246 $result = $lo1->process($message1, backup::LOG_ERROR, $options); 00247 $this->assertTrue($result); 00248 00249 // Another file_logger is going towrite there too without closing 00250 $options = array(); 00251 $lo2 = new file_logger(backup::LOG_WARNING, true, true, $file); 00252 $this->assertTrue($lo2 instanceof file_logger); 00253 $message2 = 'testing file_logger2'; 00254 $result = $lo2->process($message2, backup::LOG_WARNING, $options); 00255 $this->assertTrue($result); 00256 00257 // Destruct loggers 00258 $lo1 = null; 00259 $lo2 = null; 00260 00261 // Load file results to analyze them 00262 $fcontents = file_get_contents($file); 00263 $acontents = explode(PHP_EOL, $fcontents); // Split by line 00264 $this->assertTrue(strpos($acontents[0], $message1) !== false); 00265 $this->assertTrue(strpos($acontents[0], '[error]') !== false); 00266 $this->assertTrue(strpos($acontents[0], ' ') !== false); 00267 $this->assertTrue(substr_count($acontents[0] , '] ') >= 2); 00268 $this->assertTrue(strpos($acontents[1], $message2) !== false); 00269 $this->assertTrue(strpos($acontents[1], '[warn]') !== false); 00270 $this->assertTrue(strpos($acontents[1], ' ') === false); 00271 $this->assertTrue(substr_count($acontents[1] , '] ') >= 2); 00272 unlink($file); // delete file 00273 00274 // Try one html file 00275 $file = $CFG->tempdir . '/test/test_file_logger.html'; 00276 $options = array('depth' => 1); 00277 $lo = new file_logger(backup::LOG_ERROR, true, true, $file); 00278 $this->assertTrue($lo instanceof file_logger); 00279 $this->assertTrue(file_exists($file)); 00280 $message = 'testing file_logger'; 00281 $result = $lo->process($message, backup::LOG_ERROR, $options); 00282 // Get file contents and inspect them 00283 $fcontents = file_get_contents($file); 00284 $this->assertTrue($result); 00285 $this->assertTrue(strpos($fcontents, $message) !== false); 00286 $this->assertTrue(strpos($fcontents, '[error]') !== false); 00287 $this->assertTrue(strpos($fcontents, ' ') !== false); 00288 $this->assertTrue(substr_count($fcontents , '] ') >= 2); 00289 unlink($file); // delete file 00290 00291 // Instantiate, write something, force deletion, try to write again 00292 $file = $CFG->tempdir . '/test/test_file_logger.html'; 00293 $lo = new mock_file_logger(backup::LOG_ERROR, true, true, $file); 00294 $this->assertTrue(file_exists($file)); 00295 $message = 'testing file_logger'; 00296 $result = $lo->process($message, backup::LOG_ERROR); 00297 fclose($lo->get_fhandle()); // close file 00298 try { 00299 $result = @$lo->process($message, backup::LOG_ERROR); // Try to write again 00300 $this->assertTrue(false, 'base_logger_exception expected'); 00301 } catch (exception $e) { 00302 $this->assertTrue($e instanceof base_logger_exception); 00303 $this->assertEqual($e->errorcode, 'error_writing_file'); 00304 } 00305 00306 // Instantiate without file 00307 try { 00308 $lo = new file_logger(backup::LOG_WARNING, true, true, ''); 00309 $this->assertTrue(false, 'base_logger_exception expected'); 00310 } catch (exception $e) { 00311 $this->assertTrue($e instanceof base_logger_exception); 00312 $this->assertEqual($e->errorcode, 'missing_fullpath_parameter'); 00313 } 00314 00315 // Instantiate in (near) impossible path 00316 $file = $CFG->tempdir . '/test_azby/test_file_logger.txt'; 00317 try { 00318 $lo = new file_logger(backup::LOG_WARNING, true, true, $file); 00319 $this->assertTrue(false, 'base_logger_exception expected'); 00320 } catch (exception $e) { 00321 $this->assertTrue($e instanceof base_logger_exception); 00322 $this->assertEqual($e->errorcode, 'file_not_writable'); 00323 $this->assertEqual($e->a, $file); 00324 } 00325 00326 // Instatiate one file logger with level = backup::LOG_NONE 00327 $file = $CFG->tempdir . '/test/test_file_logger.txt'; 00328 $lo = new file_logger(backup::LOG_NONE, true, true, $file); 00329 $this->assertTrue($lo instanceof file_logger); 00330 $this->assertFalse(file_exists($file)); 00331 00332 // Remove the test dir and any content 00333 @remove_dir(dirname($file)); 00334 } 00335 } 00336 00337 /* 00338 * helper extended base_logger class that implements some methods for testing 00339 * Simply return the product of message and level 00340 */ 00341 class mock_base_logger1 extends base_logger { 00342 00343 protected function action($message, $level, $options = null) { 00344 return $message * $level; // Simply return that, for testing 00345 } 00346 public function get_levelstr($level) { 00347 return parent::get_levelstr($level); 00348 } 00349 } 00350 00351 /* 00352 * helper extended base_logger class that implements some methods for testing 00353 * Simply return the sum of message and level 00354 */ 00355 class mock_base_logger2 extends base_logger { 00356 00357 protected function action($message, $level, $options = null) { 00358 return $message + $level; // Simply return that, for testing 00359 } 00360 } 00361 00362 /* 00363 * helper extended base_logger class that implements some methods for testing 00364 * Simply return 8 00365 */ 00366 class mock_base_logger3 extends base_logger { 00367 00368 protected function action($message, $level, $options = null) { 00369 return false; // Simply return false, for testing stopper 00370 } 00371 } 00372 00373 /* 00374 * helper extended database_logger class that implements some methods for testing 00375 * Returns the complete info that normally will be used by insert record calls 00376 */ 00377 class mock_database_logger extends database_logger { 00378 00379 protected function insert_log_record($table, $columns) { 00380 return array('table' => $table, 'columns' => $columns); 00381 } 00382 } 00383 00384 /* 00385 * helper extended file_logger class that implements some methods for testing 00386 * Returns the, usually protected, fhandle 00387 */ 00388 class mock_file_logger extends file_logger { 00389 00390 function get_fhandle() { 00391 return $this->fhandle; 00392 } 00393 }