From 8c8f14ec742dde360f2e951acb5ab94274928b4a Mon Sep 17 00:00:00 2001 From: Clemens Schwaighofer Date: Thu, 30 Jun 2022 18:15:36 +0900 Subject: [PATCH] Fix logging per run to be setable not only on start Move per run set into method. Add set/get method and add set method override (set new) flag Update phpUnit testing and move providers to test methods --- 4dev/tests/CoreLibsDebugLoggingTest.php | 702 ++++++++++++++---------- www/lib/CoreLibs/Debug/Logging.php | 46 +- 2 files changed, 433 insertions(+), 315 deletions(-) diff --git a/4dev/tests/CoreLibsDebugLoggingTest.php b/4dev/tests/CoreLibsDebugLoggingTest.php index f30a1c9a..21dc3df7 100644 --- a/4dev/tests/CoreLibsDebugLoggingTest.php +++ b/4dev/tests/CoreLibsDebugLoggingTest.php @@ -15,8 +15,6 @@ use PHPUnit\Framework\TestCase; */ final class CoreLibsDebugLoggingTest extends TestCase { - public $log; - /** * test set for options BASIC * @@ -85,6 +83,47 @@ final class CoreLibsDebugLoggingTest extends TestCase ]; } + /** + * init logging class + * + * @dataProvider optionsProvider + * @testdox init test [$_dataName] + * + * @param array|null $options + * @param array $expected + * @param array $override + * @return void + */ + public function testClassInit(?array $options, array $expected, array $override): void + { + if (!empty($override['constant'])) { + foreach ($override['constant'] as $var => $value) { + define($var, $value); + } + } + if ($options === null) { + $log = new \CoreLibs\Debug\Logging(); + } else { + $log = new \CoreLibs\Debug\Logging($options); + } + // check that settings match + $this->assertEquals( + $expected['log_folder'], + $log->getSetting('log_folder') + ); + $this->assertEquals( + $expected['debug_all'], + $log->getSetting('debug_output_all') + ); + $this->assertEquals( + $expected['print_all'], + $log->getSetting('print_output_all') + ); + // print "LOG: " . $log->getSetting('log_folder') . "\n"; + // print "DEBUG: " . $log->getSetting('debug_output_all') . "\n"; + // print "PRINT: " . $log->getSetting('print_output_all') . "\n"; + } + /** * adds log ID settings based on basic options * @@ -173,6 +212,52 @@ final class CoreLibsDebugLoggingTest extends TestCase ]; } + /** + * test the setting and getting of LogId + * + * @covers ::setLogId + * @dataProvider logIdOptionsProvider + * @testdox log id set/get tests [$_dataName] + * + * @param array|null $options + * @param array $expected + * @param array $override + * @return void + */ + public function testLogId(?array $options, array $expected, array $override): void + { + // we need to set with file_id option, globals LOG_FILE_ID, constant LOG_FILE_ID + if (!empty($override['constant'])) { + foreach ($override['constant'] as $var => $value) { + define($var, $value); + } + } + if (!empty($override['globals'])) { + foreach ($override['globals'] as $var => $value) { + $GLOBALS[$var] = $value; + } + } + if ($options === null) { + $log = new \CoreLibs\Debug\Logging(); + } else { + $log = new \CoreLibs\Debug\Logging($options); + } + // check current + $this->assertEquals( + $log->getLogId(), + $expected['log_file_id'] + ); + // we need to override now too + if (!empty($override['values'])) { + // check if we have values, set them post and assert + $log->setLogId($override['values']['log_file_id']); + $this->assertEquals( + $log->getLogId(), + $expected['set_log_file_id'] + ); + } + } + /** * Undocumented function * @@ -180,6 +265,10 @@ final class CoreLibsDebugLoggingTest extends TestCase */ public function logLevelAllProvider(): array { + // 0: type + // 1: flag + // 2: expected set + // 3: expected get return [ 'debug all true' => [ 'debug', @@ -208,6 +297,38 @@ final class CoreLibsDebugLoggingTest extends TestCase ]; } + /** + * check set/get for log level all flag + * + * @dataProvider logLevelAllProvider + * @testdox set/get all log level $type with flag $flag [$_dataName] + * + * @param string $type + * @param bool $flag + * @param bool $expected_set + * @param bool $expected_get + * @return void + */ + public function testSetGetLogLevelAll( + string $type, + bool $flag, + bool $expected_set, + bool $expected_get + ): void { + // neutral start with default + $log = new \CoreLibs\Debug\Logging(); + // set and check + $this->assertEquals( + $log->setLogLevelAll($type, $flag), + $expected_set + ); + // get and check + $this->assertEquals( + $log->getLogLevelAll($type), + $expected_get + ); + } + /** * Undocumented function * @@ -215,6 +336,12 @@ final class CoreLibsDebugLoggingTest extends TestCase */ public function logLevelProvider(): array { + // 0: type + // 1: flag + // 2: debug on (array) + // 3: expected set + // 4: level + // 5: expected get return [ 'set debug on for level A,B,C and check full set' => [ 'debug', @@ -287,6 +414,43 @@ final class CoreLibsDebugLoggingTest extends TestCase ]; } + /** + * checks setting for per log info level + * + * @covers ::setLogLevel + * @dataProvider logLevelProvider + * @testdox set/get log level $type to $flag check with $level [$_dataName] + * + * @param string $type + * @param string $flag + * @param array $debug_on + * @param bool $expected_set + * @param string|null $level + * @param bool|array $expected_get + * @return void + */ + public function testSetGetLogLevel( + string $type, + string $flag, + array $debug_on, + bool $expected_set, + ?string $level, + $expected_get + ): void { + // neutral start with default + $log = new \CoreLibs\Debug\Logging(); + // set + $this->assertEquals( + $log->setLogLevel($type, $flag, $debug_on), + $expected_set + ); + // get, if level is null compare to? + $this->assertEquals( + $log->getLogLevel($type, $flag, $level), + $expected_get + ); + } + /** * Undocumented function * @@ -294,6 +458,10 @@ final class CoreLibsDebugLoggingTest extends TestCase */ public function logPerProvider(): array { + // 0: type + // 1: set + // 2: expected set + // 3: expected get return [ 'level set true' => [ 'level', @@ -328,6 +496,68 @@ final class CoreLibsDebugLoggingTest extends TestCase ]; } + /** + * set and get per log + * for level/class/page/run flags + * + * @covers ::setLogPer + * @dataProvider logPerProvider + * @testdox set/get log per $type with $set [$_dataName] + * + * @param string $type + * @param boolean $set + * @param boolean $expected_set + * @param boolean $expected_get + * @return void + */ + public function testSetGetLogPer( + string $type, + bool $set, + bool $expected_set, + bool $expected_get + ): void { + // neutral start with default + $log = new \CoreLibs\Debug\Logging(); + // set and check + $this->assertEquals( + $log->setLogPer($type, $set), + $expected_set + ); + // get and check + $this->assertEquals( + $log->getLogPer($type), + $expected_get + ); + } + + /** + * set the print log file date part + * + * @covers ::setGetLogPrintFileDate + * @testWith [true, true, true] + * [false, false, false] + * @testdox set/get log file date to $input [$_dataName] + * + * @param boolean $input + * @param boolean $expected_set + * @param boolean $expected_get + * @return void + */ + public function testSetGetLogPrintFileDate(bool $input, bool $expected_set, bool $expected_get): void + { + // neutral start with default + $log = new \CoreLibs\Debug\Logging(); + // set and check + $this->assertEquals( + $log->setGetLogPrintFileDate($input), + $expected_set + ); + $this->assertEquals( + $log->setGetLogPrintFileDate(), + $expected_get + ); + } + /** * Undocumented function * @@ -369,6 +599,95 @@ final class CoreLibsDebugLoggingTest extends TestCase ]; } + /** + * convert array to string with ## pre replace space holders + * + * @covers ::prAr + * @dataProvider prArProvider + * @testdox check prAr array to string conversion [$_dataName] + * + * @param array $input + * @param string $expected + * @return void + */ + public function testPrAr(array $input, string $expected): void + { + $log = new \CoreLibs\Debug\Logging(); + $this->assertEquals( + $log->prAr($input), + $expected + ); + } + + /** + * Undocumented function + * + * @return array + */ + public function prBlProvider(): array + { + // 0: input flag (bool) + // 1: is true + // 2: is flase + // 3: epxected + return [ + 'true bool default' => [ + true, + null, + null, + 'true' + ], + 'false bool default' => [ + false, + null, + null, + 'false' + ], + 'true bool override' => [ + true, + 'ok', + 'not ok', + 'ok' + ], + 'false bool override' => [ + false, + 'ok', + 'not ok', + 'not ok' + ], + ]; + } + + /** + * check bool to string converter + * + * @covers ::prBl + * @dataProvider prBlProvider + * @testdox check prBl $input ($true/$false) is expected $false [$_dataName] + * + * @param bool $input + * @param string|null $true + * @param string|null $false + * @param string $expected + * @return void + */ + public function testPrBl(bool $input, ?string $true, ?string $false, string $expected): void + { + $log = new \CoreLibs\Debug\Logging(); + $return = ''; + if ($true === null && $false === null) { + $return = $log->prBl($input); + } elseif ($true !== null || $false !== null) { + $return = $log->prBl($input, $true ?? '', $false ?? ''); + } + $this->assertEquals( + $expected, + $return + ); + } + + // from here are complex debug tests + /** * Undocumented function * @@ -471,304 +790,6 @@ final class CoreLibsDebugLoggingTest extends TestCase ]; } - /** - * init logging class - * - * @dataProvider optionsProvider - * @testdox init test [$_dataName] - * - * @param array|null $options - * @param array $expected - * @param array $override - * @return void - */ - public function testClassInit(?array $options, array $expected, array $override): void - { - if (!empty($override['constant'])) { - foreach ($override['constant'] as $var => $value) { - define($var, $value); - } - } - if ($options === null) { - $this->log = new \CoreLibs\Debug\Logging(); - } else { - $this->log = new \CoreLibs\Debug\Logging($options); - } - // check that settings match - $this->assertEquals( - $expected['log_folder'], - $this->log->getSetting('log_folder') - ); - $this->assertEquals( - $expected['debug_all'], - $this->log->getSetting('debug_output_all') - ); - $this->assertEquals( - $expected['print_all'], - $this->log->getSetting('print_output_all') - ); - // print "LOG: " . $this->log->getSetting('log_folder') . "\n"; - // print "DEBUG: " . $this->log->getSetting('debug_output_all') . "\n"; - // print "PRINT: " . $this->log->getSetting('print_output_all') . "\n"; - } - - /** - * test the setting and getting of LogId - * - * @covers ::setLogId - * @dataProvider logIdOptionsProvider - * @testdox log id set/get tests [$_dataName] - * - * @param array|null $options - * @param array $expected - * @param array $override - * @return void - */ - public function testLogId(?array $options, array $expected, array $override): void - { - // we need to set with file_id option, globals LOG_FILE_ID, constant LOG_FILE_ID - if (!empty($override['constant'])) { - foreach ($override['constant'] as $var => $value) { - define($var, $value); - } - } - if (!empty($override['globals'])) { - foreach ($override['globals'] as $var => $value) { - $GLOBALS[$var] = $value; - } - } - if ($options === null) { - $this->log = new \CoreLibs\Debug\Logging(); - } else { - $this->log = new \CoreLibs\Debug\Logging($options); - } - // check current - $this->assertEquals( - $this->log->getLogId(), - $expected['log_file_id'] - ); - // we need to override now too - if (!empty($override['values'])) { - // check if we have values, set them post and assert - $this->log->basicSetLogId($override['values']['log_file_id']); - $this->assertEquals( - $this->log->getLogId(), - $expected['set_log_file_id'] - ); - } - } - - /** - * check set/get for log level all flag - * - * @dataProvider logLevelAllProvider - * @testdox set/get all log level $type with flag $flag [$_dataName] - * - * @param string $type - * @param bool $flag - * @param bool $expected_set - * @param bool $expected_get - * @return void - */ - public function testSetGetLogLevelAll( - string $type, - bool $flag, - bool $expected_set, - bool $expected_get - ): void { - // neutral start with default - $this->log = new \CoreLibs\Debug\Logging(); - // set and check - $this->assertEquals( - $this->log->setLogLevelAll($type, $flag), - $expected_set - ); - // get and check - $this->assertEquals( - $this->log->getLogLevelAll($type), - $expected_get - ); - } - - /** - * checks setting for per log info level - * - * @covers ::setLogLevel - * @dataProvider logLevelProvider - * @testdox set/get log level $type to $flag check with $level [$_dataName] - * - * @param string $type - * @param string $flag - * @param array $debug_on - * @param bool $expected_set - * @param string|null $level - * @param bool|array $expected_get - * @return void - */ - public function testSetGetLogLevel( - string $type, - string $flag, - array $debug_on, - bool $expected_set, - ?string $level, - $expected_get - ): void { - // neutral start with default - $this->log = new \CoreLibs\Debug\Logging(); - // set - $this->assertEquals( - $this->log->setLogLevel($type, $flag, $debug_on), - $expected_set - ); - // get, if level is null compare to? - $this->assertEquals( - $this->log->getLogLevel($type, $flag, $level), - $expected_get - ); - } - - /** - * set and get per log - * for level/class/page/run flags - * - * @covers ::setLogPer - * @dataProvider logPerProvider - * @testdox set/get log per $type with $set [$_dataName] - * - * @param string $type - * @param boolean $set - * @param boolean $expected_set - * @param boolean $expected_get - * @return void - */ - public function testSetGetLogPer( - string $type, - bool $set, - bool $expected_set, - bool $expected_get - ): void { - // neutral start with default - $this->log = new \CoreLibs\Debug\Logging(); - // set and check - $this->assertEquals( - $this->log->setLogPer($type, $set), - $expected_set - ); - // get and check - $this->assertEquals( - $this->log->getLogPer($type), - $expected_get - ); - } - - /** - * set the print log file date part - * - * @covers ::setGetLogPrintFileDate - * @testWith [true, true, true] - * [false, false, false] - * @testdox set/get log file date to $input [$_dataName] - * - * @param boolean $input - * @param boolean $expected_set - * @param boolean $expected_get - * @return void - */ - public function testSetGetLogPrintFileDate(bool $input, bool $expected_set, bool $expected_get): void - { - // neutral start with default - $this->log = new \CoreLibs\Debug\Logging(); - // set and check - $this->assertEquals( - $this->log->setGetLogPrintFileDate($input), - $expected_set - ); - $this->assertEquals( - $this->log->setGetLogPrintFileDate(), - $expected_get - ); - } - - /** - * convert array to string with ## pre replace space holders - * - * @covers ::prAr - * @dataProvider prArProvider - * @testdox check prAr array to string conversion [$_dataName] - * - * @param array $input - * @param string $expected - * @return void - */ - public function testPrAr(array $input, string $expected): void - { - $this->log = new \CoreLibs\Debug\Logging(); - $this->assertEquals( - $this->log->prAr($input), - $expected - ); - } - - public function prBlProvider(): array - { - return [ - 'true bool default' => [ - true, - null, - null, - 'true' - ], - 'false bool default' => [ - false, - null, - null, - 'false' - ], - 'true bool override' => [ - true, - 'ok', - 'not ok', - 'ok' - ], - 'false bool override' => [ - false, - 'ok', - 'not ok', - 'not ok' - ], - ]; - } - - /** - * check bool to string converter - * - * @covers ::prBl - * @dataProvider prBlProvider - * @textdox check prBl $input ($true/$false) is expected $false [$_dataName] - * - * @param bool $input - * @param string|null $true - * @param string|null $false - * @param string $expected - * @return void - */ - public function testPrBl(bool $input, ?string $true, ?string $false, string $expected): void - { - $this->log = new \CoreLibs\Debug\Logging(); - $return = ''; - if ($true === null && $false === null) { - $return = $this->log->prBl($input); - } elseif ($true !== null || $false !== null) { - $return = $this->log->prBl($input, $true ?? '', $false ?? ''); - } - $this->assertEquals( - $expected, - $return - ); - } - - // from here are complex debug tests - /** * Test debug flow * @@ -824,11 +845,11 @@ final class CoreLibsDebugLoggingTest extends TestCase // remove any files named /tmp/error_log_TestDebug*.log array_map('unlink', glob($options['log_folder'] . 'error_msg_' . $options['file_id'] . '*.log')); // init logger - $this->log = new \CoreLibs\Debug\Logging($options); + $log = new \CoreLibs\Debug\Logging($options); // * debug (A/B) // NULL check for strip/prefix $this->assertEquals( - $this->log->debug( + $log->debug( $debug_msg['level'], $debug_msg['string'], $debug_msg['strip'], @@ -837,7 +858,7 @@ final class CoreLibsDebugLoggingTest extends TestCase $expected_debug ); // * if print check data in log file - $log_file = $this->log->getLogFileName(); + $log_file = $log->getLogFileName(); if (!empty($options['debug_all']) && !empty($options['print_all'])) { // file name matching $this->assertStringStartsWith( @@ -866,10 +887,10 @@ final class CoreLibsDebugLoggingTest extends TestCase ); } // ** ECHO ON - $log_string = $this->log->printErrorMsg(); + $log_string = $log->printErrorMsg(); // * print if (!empty($options['debug_all']) && !empty($options['echo_all'])) { - // print $this->log->printErrorMsg() . "\n"; + // print $log->printErrorMsg() . "\n"; // echo string must start with $this->assertStringStartsWith( $expected_string_start, @@ -893,6 +914,77 @@ final class CoreLibsDebugLoggingTest extends TestCase ); } } + + // TODO: setLogUniqueId/getLogUniqueId + + /** + * Undocumented function + * + * @return array + */ + public function logUniqueIdProvider(): array + { + return [ + 'option set' => [ + 'option' => true, + 'override' => false, + ], + 'direct set' => [ + 'option' => false, + 'override' => false, + ], + 'override set' => [ + 'option' => false, + 'override' => true, + ], + 'option and override set' => [ + 'option' => false, + 'override' => true, + ], + ]; + } + + /** + * Undocumented function + * + * @covers ::setLogUniqueId + * @covers ::getLogUniqueId + * @dataProvider logUniqueIdProvider + * @testdox per run log id set test: option: $option, override: $override [$_dataName] + * + * @param bool $option + * @param bool $override + * @return void + */ + public function testLogUniqueId(bool $option, bool $override): void + { + if ($option === true) { + $log = new \CoreLibs\Debug\Logging(['per_run' => $option]); + } else { + $log = new \CoreLibs\Debug\Logging(); + $log->setLogUniqueId(); + } + $per_run_id = $log->getLogUniqueId(); + $this->assertMatchesRegularExpression( + "/^\d{4}-\d{2}-\d{2}_\d{6}_U_[a-z0-9]{8}$/", + $per_run_id, + 'assert per log run id 1st' + ); + if ($override === true) { + $log->setLogUniqueId(true); + $per_run_id_2nd = $log->getLogUniqueId(); + $this->assertMatchesRegularExpression( + "/^\d{4}-\d{2}-\d{2}_\d{6}_U_[a-z0-9]{8}$/", + $per_run_id_2nd, + 'assert per log run id 2nd' + ); + $this->assertNotEquals( + $per_run_id, + $per_run_id_2nd, + '1st and 2nd don\'t match' + ); + } + } } // __END__ diff --git a/www/lib/CoreLibs/Debug/Logging.php b/www/lib/CoreLibs/Debug/Logging.php index b033f5f0..f9e70327 100644 --- a/www/lib/CoreLibs/Debug/Logging.php +++ b/www/lib/CoreLibs/Debug/Logging.php @@ -293,15 +293,7 @@ class Logging } // set per run ID if ($this->log_per_run) { - /* if (isset($GLOBALS['LOG_FILE_UNIQUE_ID'])) { - $this->log_file_unique_id = $GLOBALS['LOG_FILE_UNIQUE_ID']; - } */ - if (!$this->log_file_unique_id) { - // $GLOBALS['LOG_FILE_UNIQUE_ID'] = - $this->log_file_unique_id = - date('Y-m-d_His') . '_U_' - . substr(hash('sha1', uniqid((string)mt_rand(), true)), 0, 8); - } + $this->setLogUniqueId(); } } @@ -394,7 +386,10 @@ class Logging // write to file // first check if max file size is is set and file is bigger - if ($this->log_max_filesize > 0 && ((filesize($fn) / 1024) > $this->log_max_filesize)) { + if ( + $this->log_max_filesize > 0 && + ((filesize($fn) / 1024) > $this->log_max_filesize) + ) { // for easy purpose, rename file only to attach timestamp, nur sequence numbering rename($fn, $fn . '.' . date("YmdHis")); } @@ -593,6 +588,10 @@ class Logging return false; } $this->{'log_per_' . $type} = $set; + // if per run set unique id + if ($type == 'run' && $set == true) { + $this->setLogUniqueId(); + } return true; } @@ -610,6 +609,33 @@ class Logging return $this->{'log_per_' . $type}; } + /** + * Sets a unique id based on current date (y/m/d, h:i:s) and a unique id (8 chars) + * if override is set to true it will be newly set, else if already set nothing changes + * + * @param bool $override True to force new set + * @return void + */ + public function setLogUniqueId(bool $override = false): void + { + if (!$this->log_file_unique_id || $override == true) { + $this->log_file_unique_id = + date('Y-m-d_His') . '_U_' + . substr(hash('sha1', uniqid((string)mt_rand(), true)), 0, 8); + } + } + + /** + * Return current set log file unique id, + * empty string for not set + * + * @return string + */ + public function getLogUniqueId(): string + { + return $this->log_file_unique_id; + } + /** * Set or get the log file date extension flag * if null or empty parameter gets current flag