N°5538 Make PHPUnit test fail if transaction opened but not closed

This commit is contained in:
Pierre Goiffon
2022-09-21 11:59:59 +02:00
parent 7ac4bc95bb
commit 88d743b1cc
8 changed files with 89 additions and 27 deletions

View File

@@ -113,10 +113,18 @@ class MySQLNoTransactionException extends MySQLException
}
/**
* @since 2.7.8 3.0.3 3.1.0 N°5538
*/
class MySQLTransactionNotClosedException extends MySQLException
{
}
/**
* CMDBSource
* database access wrapper
* database access wrapper
*
* @package iTopORM
*/

View File

@@ -119,12 +119,13 @@ class ItopDataTestCase extends ItopTestCase
$this->debug("Removing $sClass::$iKey");
$oObject->DBDelete();
}
catch (Exception $e)
{
catch (Exception $e) {
$this->debug("Error when removing created objects : $sClass::$iKey. Exception message: ".$e->getMessage());
}
}
}
parent::tearDown();
}
/**

View File

@@ -25,6 +25,8 @@ namespace Combodo\iTop\Test\UnitTest;
* Time: 11:21
*/
use CMDBSource;
use MySQLTransactionNotClosedException;
use PHPUnit\Framework\TestCase;
use SetupUtils;
@@ -47,15 +49,26 @@ class ItopTestCase extends TestCase
@include_once '../../../../../../../../approot.inc.php';
}
/**
* @throws \MySQLTransactionNotClosedException see N°5538
* @since 2.7.8 3.0.3 3.1.0 N°5538
*/
protected function tearDown(): void
{
parent::tearDown();
if (CMDBSource::IsInsideTransaction()) {
// Nested transactions were opened but not finished !
throw new MySQLTransactionNotClosedException('Some DB transactions were opened but not closed ! Fix the code by adding ROLLBACK or COMMIT statements !', []);
}
}
protected function debug($sMsg)
{
if (DEBUG_UNIT_TEST)
{
if (is_string($sMsg))
{
echo "$sMsg\n";
}
else {
{
if (DEBUG_UNIT_TEST) {
if (is_string($sMsg)) {
echo "$sMsg\n";
} else {
/** @noinspection ForgottenDebugOutputInspection */
print_r($sMsg);
}

View File

@@ -10,6 +10,7 @@ use CMDBSource;
use Combodo\iTop\Test\UnitTest\ItopTestCase;
use Exception;
use MetaModel;
use MySQLTransactionNotClosedException;
/**
* @runTestsInSeparateProcesses
@@ -230,22 +231,56 @@ class TransactionsTest extends ItopTestCase
public function DBUpdateProvider()
{
return [
"Normal case" => ['iFailAt' => -1, 'bIsModified' => false],
"ticket_request" => ['iFailAt' => 1, 'bIsModified' => true],
"Normal case" => ['iFailAt' => -1, 'bIsModified' => false],
"ticket_request" => ['iFailAt' => 1, 'bIsModified' => true],
"lnkcontacttoticket" => ['iFailAt' => 2, 'bIsModified' => true],
"History 1" => ['iFailAt' => 3, 'bIsModified' => true],
"History 2" => ['iFailAt' => 4, 'bIsModified' => true],
"History 3" => ['iFailAt' => 5, 'bIsModified' => true],
"History 4" => ['iFailAt' => 6, 'bIsModified' => true],
"History 5" => ['iFailAt' => 7, 'bIsModified' => true],
"History 6" => ['iFailAt' => 8, 'bIsModified' => true],
"History 7" => ['iFailAt' => 9, 'bIsModified' => true],
"History 8" => ['iFailAt' => 10, 'bIsModified' => true],
"History 9" => ['iFailAt' => 11, 'bIsModified' => true],
"History 10" => ['iFailAt' => 12, 'bIsModified' => true],
"History 11" => ['iFailAt' => 13, 'bIsModified' => true],
"History 12" => ['iFailAt' => 14, 'bIsModified' => true],
"History 13" => ['iFailAt' => 15, 'bIsModified' => true],
"History 1" => ['iFailAt' => 3, 'bIsModified' => true],
"History 2" => ['iFailAt' => 4, 'bIsModified' => true],
"History 3" => ['iFailAt' => 5, 'bIsModified' => true],
"History 4" => ['iFailAt' => 6, 'bIsModified' => true],
"History 5" => ['iFailAt' => 7, 'bIsModified' => true],
"History 6" => ['iFailAt' => 8, 'bIsModified' => true],
"History 7" => ['iFailAt' => 9, 'bIsModified' => true],
"History 8" => ['iFailAt' => 10, 'bIsModified' => true],
"History 9" => ['iFailAt' => 11, 'bIsModified' => true],
"History 10" => ['iFailAt' => 12, 'bIsModified' => true],
"History 11" => ['iFailAt' => 13, 'bIsModified' => true],
"History 12" => ['iFailAt' => 14, 'bIsModified' => true],
"History 13" => ['iFailAt' => 15, 'bIsModified' => true],
];
}
/**
* @return void
* @doesNotPerformAssertions
*/
public function testTransactionOpenedThenClosed()
{
CMDBSource::Query('START TRANSACTION;');
CMDBSource::Query('COMMIT;');
}
/**
* This will throw an exception in the tearDown method.
* This cannot be detected nor by `@expectedException` nor `expectException` method, so we have a specific tearDown impl
*
* @return void
* @doesNotPerformAssertions
*/
public function testTransactionOpenedNotClosed()
{
CMDBSource::Query('START TRANSACTION;');
}
protected function tearDown(): void
{
try {
parent::tearDown();
}
catch (MySQLTransactionNotClosedException $e) {
if ($this->getName() === 'testTransactionOpenedNotClosed') {
$this->debug('Executing the testTransactionOpenNoClose method throws a '.MySQLTransactionNotClosedException::class.' exception in tearDown');
}
}
}
}

View File

@@ -50,6 +50,7 @@ class apcEmulationTest extends ItopTestCase
public function tearDown(): void
{
apc_clear_cache();
parent::tearDown();
}
public function testBasic()

View File

@@ -116,6 +116,8 @@ PHP;
}
rmdir(APPROOT."env-$this->sEnvName".DIRECTORY_SEPARATOR."dictionaries");
rmdir(APPROOT."env-$this->sEnvName");
parent::tearDown();
}
public function InitLangIfNeeded_NoApcProvider(){

View File

@@ -81,6 +81,8 @@ PHP;
}
rmdir(APPROOT."env-$this->sEnvName".DIRECTORY_SEPARATOR."dictionaries");
rmdir(APPROOT."env-$this->sEnvName");
parent::tearDown();
}
/**

View File

@@ -33,7 +33,7 @@ class iTopConfigParserTest extends ItopTestCase
public function tearDown(): void
{
parent::tearDown(); // TODO: Change the autogenerated stub
parent::tearDown();
if ($this->conf_exists) {
rename($this->tmpSavePath, $this->sConfigPath);
}