Merge branch 'feature/9412-uninstallationchoices' into feature/uninstallation

This commit is contained in:
odain
2026-05-06 13:30:12 +02:00
18 changed files with 219 additions and 46 deletions

View File

@@ -22,6 +22,7 @@ use Dict;
use Exception;
use IssueLog;
use MetaModel;
use SetupUtils;
use utils;
class DataFeatureRemovalController extends Controller
@@ -97,6 +98,50 @@ class DataFeatureRemovalController extends Controller
$this->aCountClassesToCleanup = $aGetRemovedClasses;
}
public function OperationAnalysisResult(): void
{
$aParams = [];
if (SetupUtils::IsSessionSetupTokenValid()) {
//from setup wizard/mtp
SetupUtils::EraseSetupToken();
} else {
//from same module
$this->ValidateTransactionId();
}
$sSourceEnv = MetaModel::GetEnvironment();
$oSetupAudit = new SetupAudit($sSourceEnv);
$aGetRemovedClasses = array_keys($oSetupAudit->RunDataAudit());
IssueLog::Debug(__METHOD__, null, ['aGetRemovedClasses' => $aGetRemovedClasses]);
$oDataCleanupService = new DataCleanupService();
$aDeletionPlanSummaryEntities = $oDataCleanupService->GetCleanupSummary($aGetRemovedClasses);
$aColumns = ['Class', 'DeleteCount' , 'UpdateCount', 'IssueCount'];
$aRows = [];
$iQueryCount = 0;
$bHasIssues = false;
foreach ($aDeletionPlanSummaryEntities as $oDeletionPlanSummaryEntity) {
$aRows[] = [
$oDeletionPlanSummaryEntity->sClass,
$oDeletionPlanSummaryEntity->iDeleteCount,
$oDeletionPlanSummaryEntity->iUpdateCount,
$oDeletionPlanSummaryEntity->iIssueCount,
];
$bHasIssues |= ($oDeletionPlanSummaryEntity->iIssueCount !== 0);
$iQueryCount += $oDeletionPlanSummaryEntity->iDeleteCount;
$iQueryCount += $oDeletionPlanSummaryEntity->iUpdateCount;
}
$aParams['sTransactionId'] = utils::GetNewTransactionId();
$aParams['aDeletionPlanSummary'] = $this->GetTableData('Extensions', $aColumns, $aRows);
$aParams['aClasses'] = $aGetRemovedClasses;
$aParams['iQueryCount'] = $iQueryCount;
$aParams['bDeletionPossible'] = !$bHasIssues;
$this->DisplayPage($aParams);
}
public function OperationDeletionPlan(): void
{
$aParams = [];

View File

@@ -0,0 +1,29 @@
{# @copyright Copyright (C) 2010-2026 Combodo SARL #}
{# @license http://opensource.org/licenses/AGPL-3.0 #}
{% UIPanel ForInformation { sTitle:'DataFeatureRemoval:DeletionPlan:Title'|dict_s, sSubTitle: 'DataFeatureRemoval:DeletionPlan:SubTitle'|dict_format(iQueryCount) } %}
{% UIDataTable ForForm { sRef:'aDeletionPlanSummary', aColumns:aDeletionPlanSummary.Columns, aData:aDeletionPlanSummary.Data} %}{% EndUIDataTable %}
{% EndUIPanel %}
{% if bDeletionPossible %}
{% UIForm Standard {} %}
{% UIInput ForHidden { sName:'transaction_id', sValue:sTransactionId} %}
{% UIInput ForHidden { sName:'operation', sValue:'DoDeletion'} %}
{% for sKey, sClass in aClasses %}
{% UIInput ForHidden { sName:"classes[" ~ sKey ~ "]", sValue:sClass } %}
{% endfor %}
{% UIToolbar ForButton {} %}
{% UIButton ForPrimaryAction {sLabel:'UI:Button:DoDeletion'|dict_s, sName:'btn_deletion', sId:'btn_deletion', bIsSubmit:true} %}
{% EndUIToolbar %}
{% EndUIForm %}
{% else %}
{{ 'DataFeatureRemoval:DeletionPlan:Error:Issues'|dict_s }}
{% endif %}
{% UIForm Standard {} %}
{% UIInput ForHidden { sName:'transaction_id', sValue:sTransactionId} %}
{% UIInput ForHidden { sName:'operation', sValue:'Main'} %}
{% UIToolbar ForButton {} %}
{% UIButton ForPrimaryAction {sLabel:'UI:Button:BackToMain'|dict_s, sName:'btn_back', sId:'btn_back', bIsSubmit:true} %}
{% EndUIToolbar %}
{% EndUIForm %}

View File

@@ -36,19 +36,6 @@ class ModelReflectionSerializer
{
IssueLog::Info(__METHOD__, null, ['env' => $sEnv]);
$sCurrentEnvt = MetaModel::GetEnvironment();
if ($sCurrentEnvt === $sEnv) {
$aClasses = MetaModel::GetClasses();
if (count($aClasses) === 0) {
//MetaModel not started yet
$sConfFile = utils::GetConfigFilePath($sEnv);
MetaModel::Startup($sConfFile, false /* $bModelOnly */, false /* $bAllowCache */, false /* $bTraceSourceFiles */, $sEnv);
$aClasses = MetaModel::GetClasses();
}
return $aClasses;
}
$sPHPExec = trim(utils::GetConfig()->Get('php_path'));
$sOutput = "";
$iRes = 0;

View File

@@ -16,6 +16,7 @@ use PhpParser\Node\Stmt\ElseIf_;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\If_;
use PhpParser\ParserFactory;
use SetupLog;
require_once __DIR__.'/ModuleFileReaderException.php';
require_once APPROOT.'sources/PhpParser/Evaluation/PhpExpressionEvaluator.php';
@@ -143,6 +144,7 @@ class ModuleFileReader
}
// Replace the main function call by an assignment to a variable, as an array...
$sModuleFileContents = str_replace(['SetupWebPage::AddModule', 'ModuleDiscovery::AddModule'], '$aModuleInfo = array', $sModuleFileContents);
SetupLog::Debug(__METHOD__, null, ['module_file' => $sModuleFilePath]);
eval($sModuleFileContents); // Assigns $aModuleInfo
if (count($aModuleInfo) === 0) {

View File

@@ -1126,7 +1126,9 @@ class RunTimeEnvironment
}
if (is_null($aSelectedModules) || in_array($sModuleId, $aSelectedModules)) {
$aArgs = [MetaModel::GetConfig(), $aModule['installed_version'], $aModule['available_version']];
$oConfig = MetaModel::GetConfig();
$oConfig->Set('access_mode', ACCESS_FULL);
$aArgs = [$oConfig, $aModule['installed_version'], $aModule['available_version']];
RunTimeEnvironment::CallInstallerHandler($aModule, $sHandlerName, $aArgs);
}
}
@@ -1193,6 +1195,9 @@ class RunTimeEnvironment
*/
public function LoadData($aAvailableModules, $bSampleData, $aSelectedModules = null)
{
$oConfig = MetaModel::GetConfig();
$oConfig->Set('access_mode', ACCESS_FULL);
$oDataLoader = new XMLDataLoader();
CMDBObject::SetCurrentChangeFromParams("Initialization from XML files for the selected modules ");
@@ -1537,6 +1542,15 @@ class RunTimeEnvironment
$oBackup->CreateCompressedBackup($sTargetFile, $sSourceConfigFile);
}
/**
* @param \Config $oConfig
* @return void
*/
public function EnterMaintenanceMode(Config $oConfig)
{
SetupUtils::EnterMaintenanceMode($oConfig);
}
public function EnterReadOnlyMode(Config $oConfig)
{
if ($this->GetFinalEnv() != 'production') {
@@ -1550,6 +1564,13 @@ class RunTimeEnvironment
SetupUtils::EnterReadOnlyMode($oConfig);
}
public function ExitMaintenanceMode(): void
{
if (SetupUtils::IsInMaintenanceMode()){
SetupUtils::ExitMaintenanceMode();
}
}
public function ExitReadOnlyMode()
{
if ($this->GetFinalEnv() != 'production') {

View File

@@ -89,6 +89,7 @@ class ApplicationInstallSequencer extends StepSequencer
return $this->ComputeNextStep($sStep);
case 'migrate-before':
$this->oRunTimeEnvironment->EnterMaintenanceMode($this->GetConfig());
if (array_key_exists($sStep, $this->oParams->Get('optional_steps', []))) {
$this->oRunTimeEnvironment->MigrateDataBeforeUpdateStructure($this->oParams->Get('mode'), $this->GetConfig());
}
@@ -139,6 +140,7 @@ class ApplicationInstallSequencer extends StepSequencer
case 'commit':
$this->oRunTimeEnvironment->Commit();
$this->oRunTimeEnvironment->ExitReadOnlyMode();
$this->oRunTimeEnvironment->ExitMaintenanceMode();
return $this->GetNextStep('', 'Completed', 100);
default:

View File

@@ -94,6 +94,10 @@ class DataAuditSequencer extends StepSequencer
protected function IsDataAuditRequired(): bool
{
if (! array_key_exists('setup-audit', $this->oParams->Get('optional_steps', []))) {
return false;
}
if ('install' === $this->oParams->Get('mode')) {
return false;
}

View File

@@ -159,6 +159,11 @@ abstract class StepSequencer
file_put_contents(APPROOT.'log/'.$sFileName.'.xml', $sSafeXml);
}
/**
* @return \Config
* @throws \ConfigException
* @throws \CoreException
*/
protected function GetConfig()
{
if (! is_null($this->oTestConfig)) {

View File

@@ -82,7 +82,7 @@ if (! is_null($sInstallationXmlPath) && is_file($sInstallationXmlPath)) {
$aComputedExtensions = $oInstallationFileService->GetAfterComputationSelectedExtensions();
if (! $bInstallationChoicesProvided) {
$sMsg = "Computed installation choices";
echo "$sMsg:\n".implode(',', $aComputedExtensions)."\n\n";
echo "$sMsg:\n".implode(",\n", $aComputedExtensions)."\n\n";
SetupLog::Info($sMsg, null, $aComputedExtensions);
$oParams->Set('selected_extensions', $aComputedExtensions);
}
@@ -97,8 +97,8 @@ if (! is_null($sInstallationXmlPath) && is_file($sInstallationXmlPath)) {
$sMsg = "Modules to install listed in $sXmlSetupBaseName (selected_modules section)";
}
sort($aSelectedModules);
echo "$sMsg:\n".implode(',', $aSelectedModules)."\n\n";
//sort($aSelectedModules);
echo "$sMsg:\n".implode(",\n", $aSelectedModules)."\n\n";
SetupLog::Info($sMsg, null, $aSelectedModules);
// Configuration file

View File

@@ -1,11 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<installation>
<mode>install</mode>
<preinstall>
</preinstall>
<optional_steps>
<log-parameters>1</log-parameters>
<migrate-before>1</migrate-before>
<migrate-after>1</migrate-after>
</optional_steps>
<source_dir>datamodels/2.x/</source_dir>
<datamodel_version>2.7.0</datamodel_version>
<previous_configuration_file>/var/www/html/iTop/conf/production/config-itop.php</previous_configuration_file>
<datamodel_version>3.3.0</datamodel_version>
<extensions_dir>extensions</extensions_dir>
<target_env>production</target_env>
<workspace_dir></workspace_dir>
@@ -38,4 +40,5 @@
</selected_modules>
<selected_extensions type="array">
</selected_extensions>
<use_symbolic_links>off</use_symbolic_links>
</installation>

View File

@@ -1,11 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<installation>
<mode>install</mode>
<preinstall>
</preinstall>
<optional_steps>
<log-parameters>1</log-parameters>
<migrate-before>1</migrate-before>
<migrate-after>1</migrate-after>
</optional_steps>
<source_dir>datamodels/2.x/</source_dir>
<datamodel_version>2.7.0</datamodel_version>
<previous_configuration_file>/var/www/html/iTop/conf/production/config-itop.php</previous_configuration_file>
<datamodel_version>3.3.0</datamodel_version>
<extensions_dir>extensions</extensions_dir>
<target_env>production</target_env>
<workspace_dir></workspace_dir>
@@ -50,4 +52,5 @@
<item>itop-config-mgmt-core</item>
<item>itop-kown-error-mgmt</item>
</selected_extensions>
<use_symbolic_links>off</use_symbolic_links>
</installation>

View File

@@ -1,11 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<installation>
<mode>upgrade</mode>
<preinstall>
</preinstall>
<optional_steps>
<log-parameters>1</log-parameters>
<migrate-before>1</migrate-before>
<migrate-after>1</migrate-after>
</optional_steps>
<source_dir>datamodels/2.x/</source_dir>
<datamodel_version>2.7.0</datamodel_version>
<previous_configuration_file>/var/www/html/iTop/conf/production/config-itop.php</previous_configuration_file>
<datamodel_version>3.3.0</datamodel_version>
<extensions_dir>extensions</extensions_dir>
<target_env>production</target_env>
<workspace_dir></workspace_dir>
@@ -50,4 +52,5 @@
<item>itop-config-mgmt-core</item>
<item>itop-kown-error-mgmt</item>
</selected_extensions>
<use_symbolic_links>off</use_symbolic_links>
</installation>

View File

@@ -1,11 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<installation>
<mode>upgrade</mode>
<preinstall>
</preinstall>
<optional_steps>
<log-parameters>1</log-parameters>
<migrate-before>1</migrate-before>
<migrate-after>1</migrate-after>
</optional_steps>
<source_dir>datamodels/2.x/</source_dir>
<datamodel_version>2.7.0</datamodel_version>
<previous_configuration_file>/var/www/html/iTop/conf/production/config-itop.php</previous_configuration_file>
<datamodel_version>3.3.0</datamodel_version>
<extensions_dir>extensions</extensions_dir>
<target_env>production</target_env>
<workspace_dir></workspace_dir>
@@ -38,4 +40,5 @@
</selected_modules>
<selected_extensions type="array">
</selected_extensions>
</installation>
<use_symbolic_links>off</use_symbolic_links>
</installation>

View File

@@ -66,6 +66,7 @@ abstract class AbstractWizStepInstall extends WizardStep
'log-parameters' => true,
'migrate-before' => true,
'migrate-after' => true,
'setup-audit' => true,
// 'backup' => see below
],
'source_dir' => str_replace(APPROOT, '', $sSourceDir),

View File

@@ -18,6 +18,7 @@
* You should have received a copy of the GNU Affero General Public License
*/
use Combodo\iTop\Application\Helper\Session;
use Combodo\iTop\Application\WebPage\WebPage;
require_once(APPROOT.'setup/sequencers/DataAuditSequencer.php');
@@ -112,11 +113,12 @@ JS);
<input type="hidden" name="aExtensions[$sSafeExtCode][enable]" value="on"/>
INPUT;
}
$sUID = Session::Get('setup_token');
$oPage->add(
<<<HTML
<form id="data-feature-removal" class="ibo-setup--wizard ibo-is-hidden" method="post" action="$sApplicationUrl">
<input type="hidden" name="operation" value="Analyze"/>
<input type="hidden" name="operation" value="AnalysisResult"/>
<input type="hidden" name="setup_token" value="$sUID"/>
$aHiddenRemovedExtensionInputs
</form>
HTML

View File

@@ -509,6 +509,7 @@ EOF
$sDisplayChoices .= '<li>'.$aChoice['title'].'</li>';
if (isset($aChoice['modules'])) {
if (count($aChoice['modules']) === 0 && (!isset($aChoice['missing']) || $aChoice['missing'] === false)) {
SetupLog::Error(__METHOD__, null, ['choice' => $aChoice]);
throw new Exception('Extension '.$aChoice['extension_code'].' does not have any module associated');
}
foreach ($aChoice['modules'] as $sModuleId) {

View File

@@ -62,6 +62,7 @@ class ApplicationInstallerSequencerTest extends ItopTestCase
'optional_steps' => [
'migrate-before' => true,
],
'bCallEnterMaintenanceMode' => true,
],
];
}
@@ -69,12 +70,12 @@ class ApplicationInstallerSequencerTest extends ItopTestCase
/**
* @dataProvider FirstStepProvider
*/
public function testFirstStep($sNextStep, $sNextLabel, $iPercent, $aOptionalSteps)
public function testFirstStep($sNextStep, $sNextLabel, $iPercent, $aOptionalSteps, bool $bCallEnterMaintenanceMode = false, bool $bCallExitMaintenanceMode = false)
{
$aAdditionalParams = [
'optional_steps' => $aOptionalSteps,
];
$this->GivenApplicationInstallSequencer($aAdditionalParams);
$this->GivenApplicationInstallSequencer($aAdditionalParams, $bCallEnterMaintenanceMode, $bCallExitMaintenanceMode);
$aRes = $this->oSequencer->ExecuteStep();
$aExpected = [
@@ -160,7 +161,7 @@ class ApplicationInstallerSequencerTest extends ItopTestCase
'migrate-before' => true,
],
];
$this->GivenApplicationInstallSequencer($aAdditionalParams);
$this->GivenApplicationInstallSequencer($aAdditionalParams, bCallEnterMaintenanceMode: true);
$this->oRunTimeEnvironment->expects($this->once())->method('MigrateDataBeforeUpdateStructure')
->with('install', $this->oConfig);
@@ -320,7 +321,7 @@ class ApplicationInstallerSequencerTest extends ItopTestCase
public function testCommit()
{
$this->GivenApplicationInstallSequencer();
$this->GivenApplicationInstallSequencer(bCallExitMaintenanceMode: true);
$this->oRunTimeEnvironment->expects($this->once())->method('Commit');
$this->oRunTimeEnvironment->expects($this->once())->method('ExitReadOnlyMode');
@@ -484,13 +485,18 @@ class ApplicationInstallerSequencerTest extends ItopTestCase
$this->assertEquals(['', 100], $this->oSequencer->GetStepAfterWithPercent('commit'));
}
private function GivenRunTimeEnvironment(bool $bStepComputationOnly = false): void
private function GivenRunTimeEnvironment(bool $bStepComputationOnly = false, bool $bCallEnterMaintenanceMode = false, bool $bCallExitMaintenanceMode = false): void
{
$this->oRunTimeEnvironment = $this->createMock(RunTimeEnvironment::class);
if (! $bStepComputationOnly) {
$this->oRunTimeEnvironment->expects($this->once())->method('EnterReadOnlyMode')
->with($this->oConfig);
}
$this->oRunTimeEnvironment->expects($this->exactly($bCallEnterMaintenanceMode ? 1 : 0))->method('EnterMaintenanceMode')
->with($this->oConfig);
$this->oRunTimeEnvironment->expects($this->exactly($bCallExitMaintenanceMode ? 1 : 0))->method('ExitMaintenanceMode');
}
private function GivenConfig(): void
@@ -498,10 +504,10 @@ class ApplicationInstallerSequencerTest extends ItopTestCase
$this->oConfig = $this->createMock(Config::class);
}
private function GivenApplicationInstallSequencer(array $aAdditionalParams = [], bool $bStepComputationOnly = false): void
private function GivenApplicationInstallSequencer(array $aAdditionalParams = [], bool $bStepComputationOnly = false, bool $bCallEnterMaintenanceMode = false, bool $bCallExitMaintenanceMode = false): void
{
$this->GivenConfig();
$this->GivenRunTimeEnvironment($bStepComputationOnly);
$this->GivenRunTimeEnvironment($bStepComputationOnly, $bCallEnterMaintenanceMode, $bCallExitMaintenanceMode);
$this->oSequencer = new ApplicationInstallSequencer($this->GivenParams($aAdditionalParams), $this->oRunTimeEnvironment);
$this->SetNonPublicProperty($this->oSequencer, 'oTestConfig', $this->oConfig);
}

View File

@@ -8,6 +8,8 @@ use PHPParameters;
class DataAuditSequencerTest extends ItopTestCase
{
private $oConfig;
protected function setUp(): void
{
static::LoadRequiredItopFiles();
@@ -85,6 +87,7 @@ class DataAuditSequencerTest extends ItopTestCase
$aAdditionalParams = [
'mode' => 'update',
'optional_steps' => ['setup-audit' => true ],
];
$oSequencer = new DataAuditSequencer($this->GivenParams($aAdditionalParams), $oRunTimeEnvironment);
@@ -99,6 +102,30 @@ class DataAuditSequencerTest extends ItopTestCase
$this->assertEquals($aExpected, $aRes);
}
public function testCompileWithAuditDisabledViaOptionalSteps()
{
$oRunTimeEnvironment = $this->createMock(\RunTimeEnvironment::class);
$oRunTimeEnvironment->expects($this->never())->method('GetApplicationVersion');
$oRunTimeEnvironment->expects($this->once())->method('DoCompile');
$oRunTimeEnvironment->expects($this->never())->method('GetFinalEnv')
->willReturn('production');
$aAdditionalParams = [
'mode' => 'update',
];
$oSequencer = new DataAuditSequencer($this->GivenParams($aAdditionalParams), $oRunTimeEnvironment);
$aRes = $oSequencer->ExecuteStep('compile');
$aExpected = [
'status' => 1,
'message' => '',
'next-step' => 'complete',
'next-step-label' => 'Check Completed',
'percentage-completed' => 100,
];
$this->assertEquals($aExpected, $aRes);
}
public function testCompileNoAuditInFreshInstall()
{
$oRunTimeEnvironment = $this->createMock(\RunTimeEnvironment::class);
@@ -127,6 +154,7 @@ class DataAuditSequencerTest extends ItopTestCase
$aAdditionalParams = [
'mode' => 'update',
'optional_steps' => ['setup-audit' => true ],
];
$oSequencer = new DataAuditSequencer($this->GivenParams($aAdditionalParams), $oRunTimeEnvironment);
@@ -171,6 +199,7 @@ class DataAuditSequencerTest extends ItopTestCase
$aAdditionalParams = [
'mode' => 'update',
'optional_steps' => ['setup-audit' => true ],
];
$oSequencer = new DataAuditSequencer($this->GivenParams($aAdditionalParams), $oRunTimeEnvironment);
@@ -196,6 +225,7 @@ class DataAuditSequencerTest extends ItopTestCase
$aAdditionalParams = [
'mode' => 'update',
'optional_steps' => ['setup-audit' => true ],
];
$oSequencer = new DataAuditSequencer($this->GivenParams($aAdditionalParams), $oRunTimeEnvironment);
$aRes = $oSequencer->ExecuteStep('setup-audit');
@@ -272,7 +302,11 @@ class DataAuditSequencerTest extends ItopTestCase
->willReturn(['product_version' => ITOP_VERSION_FULL."_alpha"]);
$oRunTimeEnvironment->expects($this->never())->method("GetFinalEnv");
$oSequencer = new DataAuditSequencer($this->GivenParams(['mode' => 'upgrade']), $oRunTimeEnvironment);
$aAdditionalParams = [
'mode' => 'upgrade',
'optional_steps' => ['setup-audit' => true ],
];
$oSequencer = new DataAuditSequencer($this->GivenParams($aAdditionalParams), $oRunTimeEnvironment);
self::assertFalse($this->InvokeNonPublicMethod(DataAuditSequencer::class, "IsDataAuditRequired", $oSequencer));
}
@@ -283,7 +317,25 @@ class DataAuditSequencerTest extends ItopTestCase
->willReturn(['product_version' => ITOP_VERSION_FULL]);
$oRunTimeEnvironment->expects($this->once())->method("GetFinalEnv")->willReturn("production-gabuzomeu");
$oSequencer = new DataAuditSequencer($this->GivenParams(['mode' => 'upgrade']), $oRunTimeEnvironment);
$aAdditionalParams = [
'mode' => 'upgrade',
'optional_steps' => ['setup-audit' => true ],
];
$oSequencer = new DataAuditSequencer($this->GivenParams($aAdditionalParams), $oRunTimeEnvironment);
self::assertFalse($this->InvokeNonPublicMethod(DataAuditSequencer::class, "IsDataAuditRequired", $oSequencer));
}
public function testIsDataAuditRequired_NoAuditTriggeredBecauseDisabled()
{
$oRunTimeEnvironment = $this->createMock(\RunTimeEnvironment::class);
$oRunTimeEnvironment->expects($this->never())->method('GetApplicationVersion')
->willReturn(['product_version' => ITOP_VERSION_FULL]);
$oRunTimeEnvironment->expects($this->never())->method("GetFinalEnv")->willReturn("production");
$aAdditionalParams = [
'mode' => 'upgrade',
];
$oSequencer = new DataAuditSequencer($this->GivenParams($aAdditionalParams), $oRunTimeEnvironment);
self::assertFalse($this->InvokeNonPublicMethod(DataAuditSequencer::class, "IsDataAuditRequired", $oSequencer));
}
@@ -294,7 +346,11 @@ class DataAuditSequencerTest extends ItopTestCase
->willReturn(['product_version' => ITOP_VERSION_FULL]);
$oRunTimeEnvironment->expects($this->once())->method("GetFinalEnv")->willReturn("production");
$oSequencer = new DataAuditSequencer($this->GivenParams(['mode' => 'upgrade']), $oRunTimeEnvironment);
$aAdditionalParams = [
'mode' => 'upgrade',
'optional_steps' => ['setup-audit' => true ],
];
$oSequencer = new DataAuditSequencer($this->GivenParams($aAdditionalParams), $oRunTimeEnvironment);
self::assertTrue($this->InvokeNonPublicMethod(DataAuditSequencer::class, "IsDataAuditRequired", $oSequencer));
}
}