mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-20 17:18:51 +02:00
Merge remote-tracking branch 'origin/support/3.0' into support/3.1
This commit is contained in:
@@ -627,18 +627,24 @@ class CMDBSource
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Exception $e
|
||||
* @param Exception $e
|
||||
* @param bool $bForQuery to get the proper DB connection
|
||||
* @param bool $bCheckMysqliErrno if false won't try to check for mysqli::errno value
|
||||
*
|
||||
* @since 2.7.1
|
||||
* @since 3.0.0 N°4325 add new optional parameter to use the correct DB connection
|
||||
* @since 3.0.4 3.1.1 3.2.0 N°6643 new bCheckMysqliErrno parameter as a workaround for mysqli::errno cannot be mocked
|
||||
*/
|
||||
private static function LogDeadLock(Exception $e, $bForQuery = false)
|
||||
private static function LogDeadLock(Exception $e, $bForQuery = false, $bCheckMysqliErrno = true)
|
||||
{
|
||||
// checks MySQL error code
|
||||
$iMySqlErrorNo = DbConnectionWrapper::GetDbConnection($bForQuery)->errno;
|
||||
if (!in_array($iMySqlErrorNo, array(self::MYSQL_ERRNO_WAIT_TIMEOUT, self::MYSQL_ERRNO_DEADLOCK))) {
|
||||
return;
|
||||
if ($bCheckMysqliErrno) {
|
||||
$iMySqlErrorNo = DbConnectionWrapper::GetDbConnection($bForQuery)->errno;
|
||||
if (!in_array($iMySqlErrorNo, array(self::MYSQL_ERRNO_WAIT_TIMEOUT, self::MYSQL_ERRNO_DEADLOCK))) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
$iMySqlErrorNo = "N/A";
|
||||
}
|
||||
|
||||
// Get error info
|
||||
@@ -665,7 +671,10 @@ class CMDBSource
|
||||
);
|
||||
DeadLockLog::Info($sMessage, $iMySqlErrorNo, $aLogContext);
|
||||
|
||||
IssueLog::Error($sMessage, LogChannels::DEADLOCK, $e->getMessage());
|
||||
IssueLog::Error($sMessage, LogChannels::DEADLOCK, [
|
||||
'exception.class' => get_class($e),
|
||||
'exception.message' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,6 +6,9 @@ namespace Combodo\iTop\Test\UnitTest\Core;
|
||||
use CMDBSource;
|
||||
use Combodo\iTop\Core\DbConnectionWrapper;
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use Exception;
|
||||
use IssueLog;
|
||||
use LogChannels;
|
||||
use utils;
|
||||
|
||||
/**
|
||||
@@ -137,4 +140,49 @@ class CMDBSourceTest extends ItopTestCase
|
||||
$bIsTlsCnx = $this->InvokeNonPublicStaticMethod(CMDBSource::class, 'IsOpenedDbConnectionUsingTls', [$oMysqli]);
|
||||
$this->assertFalse($bIsTlsCnx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.7.10 3.0.4 3.1.1 3.2.0 N°6643 Checks writing in IssueLog is really done
|
||||
*/
|
||||
public function testLogDeadLock(): void
|
||||
{
|
||||
$sExceptionMessage = 'Test exception for deadlock';
|
||||
$oDeadlockException = new Exception($sExceptionMessage);
|
||||
|
||||
// \CMDBSource::LogDeadLock uses mysqli::errno and mysqli::query()
|
||||
// I didn't achieve mocking the errno property by either of the following means :
|
||||
// - PHPUnit mock => property is read only error
|
||||
// - DbConnectionWrapper::SetDbConnectionMockForQuery with a custom mysqli children
|
||||
// - override of errno property with an assignment (public $errno = ...;) => property is read only error
|
||||
// - override of __get() for the errno property => no error but no change
|
||||
// Solution for errno was to add a new parameter to disable errno read :/
|
||||
/** @noinspection PhpDeprecationInspection */
|
||||
$oMockMysqli = $this->getMockBuilder('mysqli')
|
||||
->setMethods(['query'])
|
||||
->getMock();
|
||||
$oMockMysqli->expects($this->any())
|
||||
->method('query')
|
||||
->willReturnCallback(function () {
|
||||
return false;
|
||||
});
|
||||
DbConnectionWrapper::SetDbConnectionMockForQuery($oMockMysqli);
|
||||
|
||||
$sTestErrorLogPath = APPROOT . 'log/error.phpunit.log';
|
||||
IssueLog::Enable($sTestErrorLogPath);
|
||||
try {
|
||||
$this->InvokeNonPublicStaticMethod(CMDBSource::class, 'LogDeadLock', [$oDeadlockException, true, false]);
|
||||
$sLastErrorLogLine = $this->GetErrorLogLastLines($sTestErrorLogPath, 10); // we are getting multiple lines as the context log introduced multiple lines per log
|
||||
$this->assertStringContainsString(LogChannels::DEADLOCK, $sLastErrorLogLine);
|
||||
$this->assertStringContainsString($sExceptionMessage, $sLastErrorLogLine);
|
||||
} finally {
|
||||
if (file_exists($sTestErrorLogPath)) {
|
||||
unlink($sTestErrorLogPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function GetErrorLogLastLines(string $sErrorLogPath, int $iLineNumbers = 1): string
|
||||
{
|
||||
return trim(implode("", array_slice(file($sErrorLogPath), -$iLineNumbers)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user