/backup/util/loggers/tests/logger_test.php
PHP | 392 lines | 262 code | 41 blank | 89 comment | 6 complexity | 54bd44f6bdc6b137c077f7192cdc5139 MD5 | raw file
- <?php
- // This file is part of Moodle - http://moodle.org/
- //
- // Moodle is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // Moodle is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
- /**
- * @package core_backup
- * @category phpunit
- * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
- defined('MOODLE_INTERNAL') || die();
- // Include all the needed stuff
- global $CFG;
- require_once($CFG->dirroot . '/backup/util/interfaces/checksumable.class.php');
- require_once($CFG->dirroot . '/backup/backup.class.php');
- require_once($CFG->dirroot . '/backup/util/loggers/base_logger.class.php');
- require_once($CFG->dirroot . '/backup/util/loggers/error_log_logger.class.php');
- require_once($CFG->dirroot . '/backup/util/loggers/output_text_logger.class.php');
- require_once($CFG->dirroot . '/backup/util/loggers/output_indented_logger.class.php');
- require_once($CFG->dirroot . '/backup/util/loggers/database_logger.class.php');
- require_once($CFG->dirroot . '/backup/util/loggers/file_logger.class.php');
- /**
- * logger tests (all)
- */
- class backup_logger_testcase extends basic_testcase {
- /**
- * test base_logger class
- */
- function test_base_logger() {
- // Test logger with simple action (message * level)
- $lo = new mock_base_logger1(backup::LOG_ERROR);
- $msg = 13;
- $this->assertEquals($lo->process($msg, backup::LOG_ERROR), $msg * backup::LOG_ERROR);
- // With lowest level must return true
- $lo = new mock_base_logger1(backup::LOG_ERROR);
- $msg = 13;
- $this->assertTrue($lo->process($msg, backup::LOG_DEBUG));
- // Chain 2 loggers, we must get as result the result of the inner one
- $lo1 = new mock_base_logger1(backup::LOG_ERROR);
- $lo2 = new mock_base_logger2(backup::LOG_ERROR);
- $lo1->set_next($lo2);
- $msg = 13;
- $this->assertEquals($lo1->process($msg, backup::LOG_ERROR), $msg + backup::LOG_ERROR);
- // Try circular reference
- $lo1 = new mock_base_logger1(backup::LOG_ERROR);
- try {
- $lo1->set_next($lo1); //self
- $this->assertTrue(false, 'base_logger_exception expected');
- } catch (exception $e) {
- $this->assertTrue($e instanceof base_logger_exception);
- $this->assertEquals($e->errorcode, 'logger_circular_reference');
- $this->assertTrue($e->a instanceof stdclass);
- $this->assertEquals($e->a->main, get_class($lo1));
- $this->assertEquals($e->a->alreadyinchain, get_class($lo1));
- }
- $lo1 = new mock_base_logger1(backup::LOG_ERROR);
- $lo2 = new mock_base_logger2(backup::LOG_ERROR);
- $lo3 = new mock_base_logger3(backup::LOG_ERROR);
- $lo1->set_next($lo2);
- $lo2->set_next($lo3);
- try {
- $lo3->set_next($lo1);
- $this->assertTrue(false, 'base_logger_exception expected');
- } catch (exception $e) {
- $this->assertTrue($e instanceof base_logger_exception);
- $this->assertEquals($e->errorcode, 'logger_circular_reference');
- $this->assertTrue($e->a instanceof stdclass);
- $this->assertEquals($e->a->main, get_class($lo1));
- $this->assertEquals($e->a->alreadyinchain, get_class($lo3));
- }
- // Test stopper logger
- $lo1 = new mock_base_logger1(backup::LOG_ERROR);
- $lo2 = new mock_base_logger2(backup::LOG_ERROR);
- $lo3 = new mock_base_logger3(backup::LOG_ERROR);
- $lo1->set_next($lo2);
- $lo2->set_next($lo3);
- $this->assertFalse($lo1->process('test', backup::LOG_ERROR));
- // Test checksum correct
- $lo1 = new mock_base_logger1(backup::LOG_ERROR);
- $lo1->is_checksum_correct(get_class($lo1) . '-' . backup::LOG_ERROR);
- // Test get_levelstr()
- $lo1 = new mock_base_logger1(backup::LOG_ERROR);
- $this->assertEquals($lo1->get_levelstr(backup::LOG_NONE), 'undefined');
- $this->assertEquals($lo1->get_levelstr(backup::LOG_ERROR), 'error');
- $this->assertEquals($lo1->get_levelstr(backup::LOG_WARNING), 'warn');
- $this->assertEquals($lo1->get_levelstr(backup::LOG_INFO), 'info');
- $this->assertEquals($lo1->get_levelstr(backup::LOG_DEBUG), 'debug');
- }
- /**
- * test error_log_logger class
- */
- function test_error_log_logger() {
- // Not much really to test, just instantiate and execute, should return true
- $lo = new error_log_logger(backup::LOG_ERROR);
- $this->assertTrue($lo instanceof error_log_logger);
- $message = 'This log exists because you have run Moodle unit tests: Ignore it';
- $result = $lo->process($message, backup::LOG_ERROR);
- $this->assertTrue($result);
- }
- /**
- * test output_text_logger class
- */
- function test_output_text_logger() {
- // Instantiate without date nor level output
- $lo = new output_text_logger(backup::LOG_ERROR);
- $this->assertTrue($lo instanceof output_text_logger);
- $message = 'testing output_text_logger';
- ob_start(); // Capture output
- $result = $lo->process($message, backup::LOG_ERROR);
- $contents = ob_get_contents();
- ob_end_clean(); // End capture and discard
- $this->assertTrue($result);
- $this->assertTrue(strpos($contents, $message) !== false);
- // Instantiate with date and level output
- $lo = new output_text_logger(backup::LOG_ERROR, true, true);
- $this->assertTrue($lo instanceof output_text_logger);
- $message = 'testing output_text_logger';
- ob_start(); // Capture output
- $result = $lo->process($message, backup::LOG_ERROR);
- $contents = ob_get_contents();
- ob_end_clean(); // End capture and discard
- $this->assertTrue($result);
- $this->assertTrue(strpos($contents,'[') === 0);
- $this->assertTrue(strpos($contents,'[error]') !== false);
- $this->assertTrue(strpos($contents, $message) !== false);
- $this->assertTrue(substr_count($contents , '] ') >= 2);
- }
- /**
- * test output_indented_logger class
- */
- function test_output_indented_logger() {
- // Instantiate without date nor level output
- $options = array('depth' => 2);
- $lo = new output_indented_logger(backup::LOG_ERROR);
- $this->assertTrue($lo instanceof output_indented_logger);
- $message = 'testing output_indented_logger';
- ob_start(); // Capture output
- $result = $lo->process($message, backup::LOG_ERROR, $options);
- $contents = ob_get_contents();
- ob_end_clean(); // End capture and discard
- $this->assertTrue($result);
- if (defined('STDOUT')) {
- $check = ' ';
- } else {
- $check = ' ';
- }
- $this->assertTrue(strpos($contents, str_repeat($check, $options['depth']) . $message) !== false);
- // Instantiate with date and level output
- $options = array('depth' => 3);
- $lo = new output_indented_logger(backup::LOG_ERROR, true, true);
- $this->assertTrue($lo instanceof output_indented_logger);
- $message = 'testing output_indented_logger';
- ob_start(); // Capture output
- $result = $lo->process($message, backup::LOG_ERROR, $options);
- $contents = ob_get_contents();
- ob_end_clean(); // End capture and discard
- $this->assertTrue($result);
- $this->assertTrue(strpos($contents,'[') === 0);
- $this->assertTrue(strpos($contents,'[error]') !== false);
- $this->assertTrue(strpos($contents, $message) !== false);
- $this->assertTrue(substr_count($contents , '] ') >= 2);
- if (defined('STDOUT')) {
- $check = ' ';
- } else {
- $check = ' ';
- }
- $this->assertTrue(strpos($contents, str_repeat($check, $options['depth']) . $message) !== false);
- }
- /**
- * test database_logger class
- */
- function test_database_logger() {
- // Instantiate with date and level output (and with specs from the global moodle "log" table so checks will pass
- $now = time();
- $datecol = 'time';
- $levelcol = 'action';
- $messagecol = 'info';
- $logtable = 'log';
- $columns = array('url' => 'http://127.0.0.1');
- $loglevel = backup::LOG_ERROR;
- $lo = new mock_database_logger(backup::LOG_ERROR, $datecol, $levelcol, $messagecol, $logtable, $columns);
- $this->assertTrue($lo instanceof database_logger);
- $message = 'testing database_logger';
- $result = $lo->process($message, $loglevel);
- // Check everything is ready to be inserted to DB
- $this->assertEquals($result['table'], $logtable);
- $this->assertTrue($result['columns'][$datecol] >= $now);
- $this->assertEquals($result['columns'][$levelcol], $loglevel);
- $this->assertEquals($result['columns'][$messagecol], $message);
- $this->assertEquals($result['columns']['url'], $columns['url']);
- }
- /**
- * test file_logger class
- */
- function test_file_logger() {
- global $CFG;
- $file = $CFG->tempdir . '/test/test_file_logger.txt';
- // Remove the test dir and any content
- @remove_dir(dirname($file));
- // Recreate test dir
- if (!check_dir_exists(dirname($file), true, true)) {
- throw new moodle_exception('error_creating_temp_dir', 'error', dirname($file));
- }
- // Instantiate with date and level output, and also use the depth option
- $options = array('depth' => 3);
- $lo1 = new file_logger(backup::LOG_ERROR, true, true, $file);
- $this->assertTrue($lo1 instanceof file_logger);
- $message1 = 'testing file_logger';
- $result = $lo1->process($message1, backup::LOG_ERROR, $options);
- $this->assertTrue($result);
- // Another file_logger is going towrite there too without closing
- $options = array();
- $lo2 = new file_logger(backup::LOG_WARNING, true, true, $file);
- $this->assertTrue($lo2 instanceof file_logger);
- $message2 = 'testing file_logger2';
- $result = $lo2->process($message2, backup::LOG_WARNING, $options);
- $this->assertTrue($result);
- // Destruct loggers
- $lo1 = null;
- $lo2 = null;
- // Load file results to analyze them
- $fcontents = file_get_contents($file);
- $acontents = explode(PHP_EOL, $fcontents); // Split by line
- $this->assertTrue(strpos($acontents[0], $message1) !== false);
- $this->assertTrue(strpos($acontents[0], '[error]') !== false);
- $this->assertTrue(strpos($acontents[0], ' ') !== false);
- $this->assertTrue(substr_count($acontents[0] , '] ') >= 2);
- $this->assertTrue(strpos($acontents[1], $message2) !== false);
- $this->assertTrue(strpos($acontents[1], '[warn]') !== false);
- $this->assertTrue(strpos($acontents[1], ' ') === false);
- $this->assertTrue(substr_count($acontents[1] , '] ') >= 2);
- unlink($file); // delete file
- // Try one html file
- check_dir_exists($CFG->tempdir . '/test');
- $file = $CFG->tempdir . '/test/test_file_logger.html';
- $options = array('depth' => 1);
- $lo = new file_logger(backup::LOG_ERROR, true, true, $file);
- $this->assertTrue($lo instanceof file_logger);
- $this->assertTrue(file_exists($file));
- $message = 'testing file_logger';
- $result = $lo->process($message, backup::LOG_ERROR, $options);
- // Get file contents and inspect them
- $fcontents = file_get_contents($file);
- $this->assertTrue($result);
- $this->assertTrue(strpos($fcontents, $message) !== false);
- $this->assertTrue(strpos($fcontents, '[error]') !== false);
- $this->assertTrue(strpos($fcontents, ' ') !== false);
- $this->assertTrue(substr_count($fcontents , '] ') >= 2);
- $lo->__destruct(); // closes file handle
- unlink($file); // delete file
- // Instantiate, write something, force deletion, try to write again
- check_dir_exists($CFG->tempdir . '/test');
- $file = $CFG->tempdir . '/test/test_file_logger.html';
- $lo = new mock_file_logger(backup::LOG_ERROR, true, true, $file);
- $this->assertTrue(file_exists($file));
- $message = 'testing file_logger';
- $result = $lo->process($message, backup::LOG_ERROR);
- fclose($lo->get_fhandle()); // close file
- try {
- $result = @$lo->process($message, backup::LOG_ERROR); // Try to write again
- $this->assertTrue(false, 'base_logger_exception expected');
- } catch (exception $e) {
- $this->assertTrue($e instanceof base_logger_exception);
- $this->assertEquals($e->errorcode, 'error_writing_file');
- }
- // Instantiate without file
- try {
- $lo = new file_logger(backup::LOG_WARNING, true, true, '');
- $this->assertTrue(false, 'base_logger_exception expected');
- } catch (exception $e) {
- $this->assertTrue($e instanceof base_logger_exception);
- $this->assertEquals($e->errorcode, 'missing_fullpath_parameter');
- }
- // Instantiate in (near) impossible path
- $file = $CFG->tempdir . '/test_azby/test_file_logger.txt';
- try {
- $lo = new file_logger(backup::LOG_WARNING, true, true, $file);
- $this->assertTrue(false, 'base_logger_exception expected');
- } catch (exception $e) {
- $this->assertTrue($e instanceof base_logger_exception);
- $this->assertEquals($e->errorcode, 'file_not_writable');
- $this->assertEquals($e->a, $file);
- }
- // Instantiate one file logger with level = backup::LOG_NONE
- $file = $CFG->tempdir . '/test/test_file_logger.txt';
- $lo = new file_logger(backup::LOG_NONE, true, true, $file);
- $this->assertTrue($lo instanceof file_logger);
- $this->assertFalse(file_exists($file));
- // Remove the test dir and any content
- @remove_dir(dirname($file));
- }
- }
- /**
- * helper extended base_logger class that implements some methods for testing
- * Simply return the product of message and level
- */
- class mock_base_logger1 extends base_logger {
- protected function action($message, $level, $options = null) {
- return $message * $level; // Simply return that, for testing
- }
- public function get_levelstr($level) {
- return parent::get_levelstr($level);
- }
- }
- /**
- * helper extended base_logger class that implements some methods for testing
- * Simply return the sum of message and level
- */
- class mock_base_logger2 extends base_logger {
- protected function action($message, $level, $options = null) {
- return $message + $level; // Simply return that, for testing
- }
- }
- /**
- * helper extended base_logger class that implements some methods for testing
- * Simply return 8
- */
- class mock_base_logger3 extends base_logger {
- protected function action($message, $level, $options = null) {
- return false; // Simply return false, for testing stopper
- }
- }
- /**
- * helper extended database_logger class that implements some methods for testing
- * Returns the complete info that normally will be used by insert record calls
- */
- class mock_database_logger extends database_logger {
- protected function insert_log_record($table, $columns) {
- return array('table' => $table, 'columns' => $columns);
- }
- }
- /**
- * helper extended file_logger class that implements some methods for testing
- * Returns the, usually protected, handle
- */
- class mock_file_logger extends file_logger {
- function get_fhandle() {
- return $this->fhandle;
- }
- }