Rev 1 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
<?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/>./*** Logger tests (all).* @package core_backup* @category test* @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/namespace core_backup;use backup;use base_logger;use base_logger_exception;use database_logger;use error_log_logger;use file_logger;use output_indented_logger;use output_text_logger;defined('MOODLE_INTERNAL') || die();// Include all the needed stuffglobal $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).** @package core_backup* @category test* @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/class logger_test extends \basic_testcase {/*** test base_logger class*/function test_base_logger(): void {// 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);$msg = 13;$this->assertFalse($lo1->process($msg, 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 destroy.$lo1 = new mock_base_logger1(backup::LOG_ERROR);$lo2 = new mock_base_logger2(backup::LOG_ERROR);$lo1->set_next($lo2);$this->assertInstanceOf('base_logger', $lo1->get_next());$this->assertNull($lo2->get_next());$lo1->destroy();$this->assertNull($lo1->get_next());$this->assertNull($lo2->get_next());}/*** test error_log_logger class*/function test_error_log_logger(): void {// 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(): void {// 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(): void {// 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(): void {// 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(): void {global $CFG;$file = $CFG->tempdir . '/test/test_file_logger.txt';// Remove the test dir and any content@remove_dir(dirname($file));// Recreate test dirif (!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);// Destroy loggers.$lo1->destroy();$lo2->destroy();// 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 filecheck_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);$lo->close(); // Closes logger.// 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);unlink($file); // delete file// Instantiate, write something, force deletion, try to write againcheck_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);$lo->close();$this->assertNull($lo->get_fhandle());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 filetry {$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));$lo->close();// 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;}}