WIP - prepare cron cleanup + first tests

This commit is contained in:
odain
2026-03-13 11:04:33 +01:00
parent 963da15510
commit 04380802b6
2 changed files with 74 additions and 4 deletions

View File

@@ -89,7 +89,9 @@ class DeletionPlanService
} }
/** /**
* @since 3.3.0
* @param array $aClasses * @param array $aClasses
* @param int $iUnixTimeLimit : max execution time in seconds since Epoch before stopping deletion. by default: no limit (ie remove all without stop)
* *
* @return array<\Combodo\iTop\DataFeatureRemoval\Entity\DeletionPlanSummaryEntity> * @return array<\Combodo\iTop\DataFeatureRemoval\Entity\DeletionPlanSummaryEntity>
* @throws \Combodo\iTop\DataFeatureRemoval\Helper\DataFeatureRemovalException * @throws \Combodo\iTop\DataFeatureRemoval\Helper\DataFeatureRemovalException
@@ -97,7 +99,7 @@ class DeletionPlanService
* @throws \CoreUnexpectedValue * @throws \CoreUnexpectedValue
* @throws \MySQLException * @throws \MySQLException
*/ */
public function ExecuteDeletionPlan(array $aClasses): array public function ExecuteDeletionPlan(array $aClasses, int $iUnixTimeLimit = 0): array
{ {
$oDeletionPlan = $this->GetDeletionPlan($aClasses); $oDeletionPlan = $this->GetDeletionPlan($aClasses);
@@ -110,6 +112,11 @@ class DeletionPlanService
$oDeletionPlanSummaryEntity = $aSummary[$sClass] ?? new DeletionPlanSummaryEntity($sClass); $oDeletionPlanSummaryEntity = $aSummary[$sClass] ?? new DeletionPlanSummaryEntity($sClass);
foreach ($aToUpdate as $aData) { foreach ($aToUpdate as $aData) {
if ($this->IsTimeLimitExceeded($iUnixTimeLimit)) {
$aSummary[$sClass] = $oDeletionPlanSummaryEntity;
return $aSummary;
}
$oToUpdate = $aData['to_reset']; $oToUpdate = $aData['to_reset'];
/** @var \DBObject $oToUpdate */ /** @var \DBObject $oToUpdate */
foreach ($aData['attributes'] as $sRemoteExtKey => $aRemoteAttDef) { foreach ($aData['attributes'] as $sRemoteExtKey => $aRemoteAttDef) {
@@ -126,6 +133,11 @@ class DeletionPlanService
$oDeletionPlanSummaryEntity = $aSummary[$sClass] ?? new DeletionPlanSummaryEntity($sClass); $oDeletionPlanSummaryEntity = $aSummary[$sClass] ?? new DeletionPlanSummaryEntity($sClass);
foreach ($aDeletes as $sId => $aDelete) { foreach ($aDeletes as $sId => $aDelete) {
if ($this->IsTimeLimitExceeded($iUnixTimeLimit)) {
$aSummary[$sClass] = $oDeletionPlanSummaryEntity;
return $aSummary;
}
try { try {
CMDBSource::Query('START TRANSACTION'); CMDBSource::Query('START TRANSACTION');
// Delete any existing change tracking about the current object // Delete any existing change tracking about the current object
@@ -144,7 +156,7 @@ class DeletionPlanService
CMDBSource::Query('COMMIT'); CMDBSource::Query('COMMIT');
} catch (\Exception $e) { } catch (\Exception $e) {
\IssueLog::Exception(__METHOD__.': Cleanup failed', $e); \IssueLog::Exception(__METHOD__.": Cleanup failed", $e);
CMDBSource::Query('ROLLBACK'); CMDBSource::Query('ROLLBACK');
throw $e; throw $e;
} }
@@ -179,4 +191,13 @@ class DeletionPlanService
return $oDeletionPlan; return $oDeletionPlan;
} }
public function IsTimeLimitExceeded(int $iUnixTimeLimit): bool
{
if ($iUnixTimeLimit === 0) {
return false;
}
return (time() <= $iUnixTimeLimit);
}
} }

View File

@@ -10,7 +10,7 @@ namespace Combodo\iTop\Test\UnitTest\Module\DataFeatureRemoval\Service;
use Combodo\iTop\DataFeatureRemoval\Entity\DeletionPlanSummaryEntity; use Combodo\iTop\DataFeatureRemoval\Entity\DeletionPlanSummaryEntity;
use Combodo\iTop\DataFeatureRemoval\Helper\DataFeatureRemovalException; use Combodo\iTop\DataFeatureRemoval\Helper\DataFeatureRemovalException;
use Combodo\iTop\DataFeatureRemoval\Service\DeletionPlanService; use Combodo\iTop\DataFeatureRemoval\Service\DeletionPlanService;
use Combodo\iTop\Test\UnitTest\ItopDataTestCase; use Combodo\iTop\Test\UnitTest\ItopCustomDatamodelTestCase;
use DeletionPlan; use DeletionPlan;
/** /**
@@ -32,7 +32,7 @@ use DeletionPlan;
* @see DeletionPlanSummaryEntity * @see DeletionPlanSummaryEntity
* @see ItopDataTestCase * @see ItopDataTestCase
*/ */
class DeletionPlanServiceTest extends ItopDataTestCase class DeletionPlanServiceTest extends ItopCustomDatamodelTestCase
{ {
protected function setUp(): void protected function setUp(): void
{ {
@@ -274,4 +274,53 @@ class DeletionPlanServiceTest extends ItopDataTestCase
$oMockService->ExecuteDeletionPlan(['SomeClass']); $oMockService->ExecuteDeletionPlan(['SomeClass']);
} }
public function testExecuteDeletionPlan_DeleteAllWithoutLimit()
{
$iDFRToRemoveLeaf = $this->GivenObjectInDB('DFRToRemoveLeaf', ['name' => 'ga']);
$this->GivenObjectInDB('DFRToUpdate', ['name' => 'bu', 'dfrtoremove_id' => $iDFRToRemoveLeaf]);
$iDFRRemovedCollateral = $this->GivenObjectInDB('DFRRemovedCollateral', ['name' => 'zo', 'dfrtoremove_id' => $iDFRToRemoveLeaf]);
$this->GivenObjectInDB('DFRRemovedCollateralCascade', ['name' => 'meu', 'dfrremovedcollateral_id' => $iDFRRemovedCollateral]);
$aClasses = [ 'DFRToRemoveLeaf' ];
$aRes = DeletionPlanService::GetInstance()->ExecuteDeletionPlan($aClasses);
$aExpected = [
['DFRToUpdate', 1, 0 ],
['DFRToRemoveLeaf', 0, 1 ],
['DFRRemovedCollateral', 0, 1 ],
['DFRRemovedCollateralCascade', 0, 1 ],
];
$this->AssertSummaryEquals($aExpected, $aRes, 'DeleteAllWithoutLimit');
}
private function AssertSummaryEquals(array $expected, $actual, $sMessage = '')
{
$aExpected = [];
foreach ($expected as $line) {
$sClass = $line[0];
$iUpdate = $line[1];
$iDelete = $line[2];
$oDeletionPlanSummaryEntity = new DeletionPlanSummaryEntity($sClass);
$oDeletionPlanSummaryEntity->iUpdateCount = $iUpdate;
$oDeletionPlanSummaryEntity->iDeleteCount = $iDelete;
$aExpected[$sClass] = $oDeletionPlanSummaryEntity;
}
$this->assertEquals($aExpected, $actual, $sMessage);
}
public function testExecuteDeletionPlan_StopInUpdates()
{
self::markTestSkipped();
}
public function testExecuteDeletionPlan_StopInDeletes()
{
self::markTestSkipped();
}
public function GetDatamodelDeltaAbsPath(): string
{
return __DIR__.'/deletionplan_delta.xml';
}
} }