diff --git a/tests/php-unit-tests/module_integration.xml.dist b/tests/php-unit-tests/module_integration.xml.dist
index 8c18521e6..ad7ff7a99 100644
--- a/tests/php-unit-tests/module_integration.xml.dist
+++ b/tests/php-unit-tests/module_integration.xml.dist
@@ -19,10 +19,6 @@
printerClass="\Sempro\PHPUnitPrettyPrinter\PrettyPrinterForPhpUnit9"
>
-
-
-
-
diff --git a/tests/php-unit-tests/phpunit.xml.dist b/tests/php-unit-tests/phpunit.xml.dist
index 5bab63d01..59c451488 100644
--- a/tests/php-unit-tests/phpunit.xml.dist
+++ b/tests/php-unit-tests/phpunit.xml.dist
@@ -19,10 +19,6 @@
printerClass="\Sempro\PHPUnitPrettyPrinter\PrettyPrinterForPhpUnit9"
>
-
-
-
-
diff --git a/tests/php-unit-tests/postbuild_integration.xml.dist b/tests/php-unit-tests/postbuild_integration.xml.dist
index 95315e322..6f422e804 100644
--- a/tests/php-unit-tests/postbuild_integration.xml.dist
+++ b/tests/php-unit-tests/postbuild_integration.xml.dist
@@ -19,10 +19,6 @@
printerClass="\Sempro\PHPUnitPrettyPrinter\PrettyPrinterForPhpUnit9"
>
-
-
-
-
diff --git a/tests/php-unit-tests/src/BaseTestCase/ItopCustomDatamodelTestCase.php b/tests/php-unit-tests/src/BaseTestCase/ItopCustomDatamodelTestCase.php
index 87d3f734f..6be47bd7f 100644
--- a/tests/php-unit-tests/src/BaseTestCase/ItopCustomDatamodelTestCase.php
+++ b/tests/php-unit-tests/src/BaseTestCase/ItopCustomDatamodelTestCase.php
@@ -7,7 +7,6 @@
namespace Combodo\iTop\Test\UnitTest;
use CMDBSource;
-use Combodo\iTop\Test\UnitTest\Hook\TestsRunStartHook;
use Combodo\iTop\Test\UnitTest\Service\UnitTestRunTimeEnvironment;
use Config;
use Exception;
@@ -30,9 +29,9 @@ use utils;
abstract class ItopCustomDatamodelTestCase extends ItopDataTestCase
{
/**
- * @var bool[]
- */
- protected static $aReadyCustomEnvironments = [];
+ * @var UnitTestRunTimeEnvironment
+ */
+ protected $oEnvironment = null;
/**
* @inheritDoc
@@ -50,11 +49,19 @@ abstract class ItopCustomDatamodelTestCase extends ItopDataTestCase
$this->setRunClassInSeparateProcess(true);
}
- /**
+ /**
* @return string Abs path to the XML delta to use for the tests of that class
*/
abstract public function GetDatamodelDeltaAbsPath(): string;
+ protected function setUp(): void
+ {
+ static::LoadRequiredItopFiles();
+ $this->oEnvironment = new UnitTestRunTimeEnvironment('production', $this->GetTestEnvironment());
+
+ parent::setUp();
+ }
+
/**
* @inheritDoc
*/
@@ -92,40 +99,16 @@ abstract class ItopCustomDatamodelTestCase extends ItopDataTestCase
}
/**
- * Mark {@see \Combodo\iTop\Test\UnitTest\ItopDataTestCase::GetTestEnvironment()} as ready (compiled)
- *
- * @return void
- */
- private function MarkEnvironmentReady(): void
- {
- if (false === $this->IsEnvironmentReady()) {
- touch(static::GetTestEnvironmentFolderAbsPath());
- }
- }
-
- /**
- * @return bool True if the {@see \Combodo\iTop\Test\UnitTest\ItopDataTestCase::GetTestEnvironment()} is ready (compiled, but not started)
- *
- * @details Having the environment ready means that it has been compiled for this global tests run, not that it is a relic from a previous global tests run
+ * @return bool True if the {@see \Combodo\iTop\Test\UnitTest\ItopDataTestCase::GetTestEnvironment()} is ready (compiled, up-to-date, but not necessarily started)
*/
final protected function IsEnvironmentReady(): bool
{
- // As these test cases run in separate processes, the best way we found to let know a process if its environment was already prepared for **this run** was to compare the modification times of:
- // - its own env- folder
- // - a file generated at the beginning of the global test run {@see \Combodo\iTop\Test\UnitTest\Hook\TestsRunStartHook}
- $sRunStartedFilePath = TestsRunStartHook::GetRunStartedFileAbsPath();
- $sEnvFolderPath = static::GetTestEnvironmentFolderAbsPath();
-
clearstatcache();
- if (false === file_exists($sRunStartedFilePath) || false === file_exists($sEnvFolderPath)) {
+ if (false === file_exists($this->GetTestEnvironmentFolderAbsPath())) {
return false;
}
-
- $iRunStartedFileModificationTime = filemtime($sRunStartedFilePath);
- $iEnvFolderModificationTime = filemtime($sEnvFolderPath);
-
- return $iEnvFolderModificationTime >= $iRunStartedFileModificationTime;
- }
+ return $this->oEnvironment->IsUpToDate();
+ }
/**
* @inheritDoc
@@ -140,6 +123,12 @@ abstract class ItopCustomDatamodelTestCase extends ItopDataTestCase
// Note: To improve performances, we compile all XML deltas from test cases derived from this class and make a single environment where everything will be ran at once.
// This requires XML deltas to be compatible, but it is a known and accepted trade-off. See PR #457
if (false === $this->IsEnvironmentReady()) {
+
+ $this->debug("Preparing custom environment '$sTestEnv' with the following datamodel files:");
+ foreach ($this->oEnvironment->GetCustomDatamodelFiles() as $sCustomDatamodelFile) {
+ $this->debug(" - $sCustomDatamodelFile");
+ }
+
//----------------------------------------------------
// Clear any previous "$sTestEnv" environment
//----------------------------------------------------
@@ -152,14 +141,6 @@ abstract class ItopCustomDatamodelTestCase extends ItopDataTestCase
SetupUtils::tidydir($sConfFolder);
}
- // - Datamodel delta files
- // - Cache folder
- // - Compiled folder
- // We don't need to clean them as they are already by the compilation
-
- // - Drop database
- // We don't do that now, it will be done before re-creating the DB, once the metamodel is started
-
//----------------------------------------------------
// Prepare "$sTestEnv" environment
//----------------------------------------------------
@@ -178,7 +159,7 @@ abstract class ItopCustomDatamodelTestCase extends ItopDataTestCase
$oTestConfig->Set('db_name', $oTestConfig->Get('db_name').'_'.$sTestEnvSanitizedForDBName);
// - Compile env. based on the existing 'production' env.
- $oEnvironment = new UnitTestRunTimeEnvironment($sTestEnv);
+ $oEnvironment = new UnitTestRunTimeEnvironment($sSourceEnv, $sTestEnv);
$oEnvironment->WriteConfigFileSafe($oTestConfig);
$oEnvironment->CompileFrom($sSourceEnv);
@@ -192,8 +173,7 @@ abstract class ItopCustomDatamodelTestCase extends ItopDataTestCase
// N°7446 For some reason we need to create the DB schema before starting the MM, then only we can create the tables.
MetaModel::DBCreate();
- $this->MarkEnvironmentReady();
- $this->debug('Preparation of custom environment "'.$sTestEnv.'" done.');
+ $this->debug("Custom environment '$sTestEnv' is ready!");
}
parent::PrepareEnvironment();
diff --git a/tests/php-unit-tests/src/BaseTestCase/ItopTestCase.php b/tests/php-unit-tests/src/BaseTestCase/ItopTestCase.php
index 9d96bc8b4..9bb5b51d2 100644
--- a/tests/php-unit-tests/src/BaseTestCase/ItopTestCase.php
+++ b/tests/php-unit-tests/src/BaseTestCase/ItopTestCase.php
@@ -50,7 +50,7 @@ abstract class ItopTestCase extends TestCase
static::$DEBUG_UNIT_TEST = getenv('DEBUG_UNIT_TEST');
- require_once static::GetAppRoot() . 'approot.inc.php';
+ require_once __DIR__.'/../../../../approot.inc.php';
if ((static::DISABLE_DEPRECATEDCALLSLOG_ERRORHANDLER)
&& (false === defined(ITOP_PHPUNIT_RUNNING_CONSTANT_NAME))) {
@@ -78,6 +78,7 @@ abstract class ItopTestCase extends TestCase
}
}
+
/**
* @param array $args
* @param string $sExportFileName relative to log folder
@@ -93,43 +94,41 @@ abstract class ItopTestCase extends TestCase
* @return string
* @throws \ReflectionException
*/
- public static function ExportFunctionParameterValues(array $args, string $sExportFileName, array $aExcludedParams = []): string
- {
+ public static function ExportFunctionParameterValues(array $args, string $sExportFileName, array $aExcludedParams = []): string
+ {
// get sclass et function dans la callstrack
- // in the callstack get the call function name
- $aCallStack = debug_backtrace();
- $sCallFunction = $aCallStack[1]['function'];
- // in the casll stack get the call class name
- $sCallClass = $aCallStack[1]['class'];
- $reflectionFunc = new ReflectionMethod($sCallClass, $sCallFunction);
- $parameters = $reflectionFunc->getParameters();
+ // in the callstack get the call function name
+ $aCallStack = debug_backtrace();
+ $sCallFunction = $aCallStack[1]['function'];
+ // in the casll stack get the call class name
+ $sCallClass = $aCallStack[1]['class'];
+ $reflectionFunc = new ReflectionMethod($sCallClass, $sCallFunction);
+ $parameters = $reflectionFunc->getParameters();
- $aParamValues = [];
- foreach ($parameters as $index => $param) {
- $aParamValues[$param->getName()] = $args[$index] ?? null;
- }
+ $aParamValues = [];
+ foreach ($parameters as $index => $param) {
+ $aParamValues[$param->getName()] = $args[$index] ?? null;
+ }
- $paramValues = $aParamValues;
- foreach ($aExcludedParams as $sExcludedParam) {
- unset($paramValues[$sExcludedParam]);
- }
+ $paramValues = $aParamValues;
+ foreach ($aExcludedParams as $sExcludedParam) {
+ unset($paramValues[$sExcludedParam]);
+ }
- // extract oPage from the array in parameters and make a foreach on exlucded parameters
- foreach ($aExcludedParams as $sExcludedParam) {
- unset($paramValues[$sExcludedParam]);
- }
+ // extract oPage from the array in parameters and make a foreach on exlucded parameters
+ foreach ($aExcludedParams as $sExcludedParam) {
+ unset($paramValues[$sExcludedParam]);
+ }
- $var_export = var_export($paramValues, true);
- file_put_contents(APPROOT.'/log/' .$sExportFileName, $var_export);
+ $var_export = var_export($paramValues, true);
+ file_put_contents(APPROOT.'/log/' .$sExportFileName, $var_export);
return $var_export;
- }
+ }
- protected function setUp(): void {
+ protected function setUp(): void {
parent::setUp();
- $this->debug("\n----------\n---------- ".$this->getName()."\n----------\n");
-
$this->LoadRequiredItopFiles();
$this->LoadRequiredTestFiles();
}
@@ -178,8 +177,9 @@ abstract class ItopTestCase extends TestCase
*/
protected function LoadRequiredItopFiles(): void
{
- // Empty until we actually need to require some files in the class
- }
+ // At least make sure that the autoloader will be loaded, and that the APPROOT constant is defined
+ require_once __DIR__.'/../../../../approot.inc.php';
+ }
/**
* Overload this method to require necessary files through {@see \Combodo\iTop\Test\UnitTest\ItopTestCase::RequireOnceUnitTestFile()}
diff --git a/tests/php-unit-tests/src/Hook/TestsRunStartHook.php b/tests/php-unit-tests/src/Hook/TestsRunStartHook.php
deleted file mode 100644
index 7d2f6c212..000000000
--- a/tests/php-unit-tests/src/Hook/TestsRunStartHook.php
+++ /dev/null
@@ -1,63 +0,0 @@
-
- * @package Combodo\iTop\Test\UnitTest\Hook
- * @since N°6097 2.7.10 3.0.4 3.1.1
- */
-class TestsRunStartHook implements BeforeFirstTestHook, AfterLastTestHook
-{
- /**
- * Use the modification time on this file to check whereas it is newer than the requirements in a test case
- *
- * @return string Abs. path to a file generated when the global tests run starts.
- */
- public static function GetRunStartedFileAbsPath(): string
- {
- // Note: This can't be put in the cache- folder as we have multiple running across the test cases
- // We also don't want to put it in the unit tests folder as it is not supposed to be writable
- return APPROOT.'data/.php-unit-tests-run-started';
- }
-
- /**
- * @inheritDoc
- */
- public function executeBeforeFirstTest(): void
- {
- // Create / change modification timestamp of file marking the beginning of the tests run
- touch(static::GetRunStartedFileAbsPath());
- }
-
- /**
- * @inheritDoc
- */
- public function executeAfterLastTest(): void
- {
- // Cleanup of file marking the beginning of the tests run
- if (file_exists(static::GetRunStartedFileAbsPath())) {
- unlink(static::GetRunStartedFileAbsPath());
- }
- }
-
-
-}
\ No newline at end of file
diff --git a/tests/php-unit-tests/src/Service/UnitTestRunTimeEnvironment.php b/tests/php-unit-tests/src/Service/UnitTestRunTimeEnvironment.php
index 0c76e727f..7de18f928 100644
--- a/tests/php-unit-tests/src/Service/UnitTestRunTimeEnvironment.php
+++ b/tests/php-unit-tests/src/Service/UnitTestRunTimeEnvironment.php
@@ -11,6 +11,8 @@ use Combodo\iTop\Test\UnitTest\ItopCustomDatamodelTestCase;
use IssueLog;
use LogChannels;
use MFCoreModule;
+use RecursiveDirectoryIterator;
+use RecursiveIteratorIterator;
use ReflectionClass;
use RunTimeEnvironment;
use utils;
@@ -27,111 +29,140 @@ use utils;
class UnitTestRunTimeEnvironment extends RunTimeEnvironment
{
/**
+ * @var string[]
+ */
+ protected $aCustomDatamodelFiles = null;
+
+ /**
+ * @var string
+ */
+ protected $sSourceEnv;
+
+ public function __construct($sSourceEnv, $sTargetEnv)
+ {
+ parent::__construct($sTargetEnv);
+ $this->sSourceEnv = $sSourceEnv;
+ }
+
+ public function GetEnvironment(): string
+ {
+ return $this->sFinalEnv;
+ }
+
+ public function IsUpToDate()
+ {
+ clearstatcache();
+ $fLastCompilationTime = filemtime(APPROOT.'env-'.$this->sFinalEnv);
+ $aModifiedFiles = [];
+ $this->FindFilesModifiedAfter($fLastCompilationTime, APPROOT.'datamodels/2.x', $aModifiedFiles);
+ $this->FindFilesModifiedAfter($fLastCompilationTime, APPROOT.'extensions', $aModifiedFiles);
+ $this->FindFilesModifiedAfter($fLastCompilationTime, APPROOT.'data/production-modules', $aModifiedFiles);
+ foreach ($this->GetCustomDatamodelFiles() as $sCustomDatamodelFile) {
+ if (filemtime($sCustomDatamodelFile) > $fLastCompilationTime) {
+ $aModifiedFiles[] = $sCustomDatamodelFile;
+ }
+ }
+ if (count($aModifiedFiles) > 0) {
+ echo "The following files have been modified after the last compilation:\n";
+ foreach ($aModifiedFiles as $sFile) {
+ echo " - $sFile\n";
+ }
+ }
+ return (count($aModifiedFiles) === 0);
+ }
+
+ /**
* @inheritDoc
*/
protected function GetMFModulesToCompile($sSourceEnv, $sSourceDir)
{
$aRet = parent::GetMFModulesToCompile($sSourceEnv, $sSourceDir);
- /** @var string[] $aDeltaFiles Referential of loaded deltas. Mostly to avoid duplicates. */
- $aDeltaFiles = [];
- $aRelatedClasses = $this->GetClassesExtending(
- ItopCustomDatamodelTestCase::class,
- array(
- '[\\\\/]tests[\\\\/]php-unit-tests[\\\\/]vendor[\\\\/]',
- '[\\\\/]tests[\\\\/]php-unit-tests[\\\\/]unitary-tests[\\\\/]datamodels[\\\\/]2.x[\\\\/]authent-local',
- ));
- //Combodo\iTop\Test\UnitTest\Application\ApplicationExtensionTest
- //Combodo\iTop\Test\UnitTest\Application\ApplicationExtensionTest
- foreach ($aRelatedClasses as $sClass) {
- $oReflectionClass = new ReflectionClass($sClass);
- $oReflectionMethod = $oReflectionClass->getMethod('GetDatamodelDeltaAbsPath');
-
- // Filter on classes with an actual XML delta (eg. not \Combodo\iTop\Test\UnitTest\ItopCustomDatamodelTestCase and maybe some other deriving from a class with a delta)
- if ($oReflectionMethod->isAbstract()) {
- continue;
- }
-
- /** @var \Combodo\iTop\Test\UnitTest\ItopCustomDatamodelTestCase $oTestClassInstance */
- $oTestClassInstance = new $sClass();
-
- // Check test class is for desired environment
- if ($oTestClassInstance->GetTestEnvironment() !== $this->sFinalEnv) {
- continue;
- }
-
- // Check XML delta actually exists
- $sDeltaFile = $oTestClassInstance->GetDatamodelDeltaAbsPath();
- if (false === is_file($sDeltaFile)) {
- $this->fail("Could not prepare '$this->sFinalEnv' as the XML delta file '$sDeltaFile' (used in $sClass) does not seem to exist");
- }
-
- // Avoid duplicates
- if (in_array($sDeltaFile, $aDeltaFiles)) {
- continue;
- }
-
- // Prepare fake module name for delta
- $sDeltaName = preg_replace('/[^\d\w]/', '', $sDeltaFile);
- // Note: We can't use \MFDeltaModule as we can't specify the ID which leads to only 1 delta being applied... In the future we might introduce a new MFXXXModule, but in the meantime it feels alright (GLA / RQU)
- $oDelta = new MFCoreModule($sDeltaName, $sDeltaName, $sDeltaFile);
-
- IssueLog::Debug('XML delta found for unit tests', static::class, [
- 'Unit test class' => $sClass,
- 'Delta file path' => $sDeltaFile,
- ]);
-
- $aDeltaFiles[] = $sDeltaFile;
- $aRet[$sDeltaName] = $oDelta;
+ foreach ($this->GetCustomDatamodelFiles() as $sDeltaFile) {
+ $sDeltaId = preg_replace('/[^\d\w]/', '', $sDeltaFile);
+ $sDeltaName = basename($sDeltaFile);
+ $sDeltaDir = dirname($sDeltaFile);
+ $oDelta = new MFCoreModule($sDeltaName, "$sDeltaDir/$sDeltaName", $sDeltaFile);
+ $aRet[$sDeltaId] = $oDelta;
}
-
return $aRet;
}
- protected function GetClassesExtending (string $sExtendedClass, array $aExcludedPath = []) : array {
- $aMatchingClasses = [];
-
- $aAutoloadClassMaps =[__DIR__."/../../vendor/composer/autoload_classmap.php"];
-
- $aClassMap = [];
- $aAutoloaderErrors = [];
- foreach ($aAutoloadClassMaps as $sAutoloadFile) {
- $aTmpClassMap = include $sAutoloadFile;
- /** @noinspection SlowArrayOperationsInLoopInspection we are getting an associative array so the documented workarounds cannot be used */
- $aClassMap = array_merge($aClassMap, $aTmpClassMap);
+ public function GetCustomDatamodelFiles()
+ {
+ if (!is_null($this->aCustomDatamodelFiles)) {
+ return $this->aCustomDatamodelFiles;
}
- foreach ($aClassMap as $sPHPClass => $sPHPFile) {
- $bSkipped = false;
- if (utils::IsNotNullOrEmptyString($sPHPFile)) {
- $sPHPFile = utils::LocalPath($sPHPFile);
- if ($sPHPFile !== false) {
- $sPHPFile = '/'.$sPHPFile; // for regex
- foreach ($aExcludedPath as $sExcludedPath) {
- // Note: We use '#' as delimiters as usual '/' is often used in paths.
- if ($sExcludedPath !== '' && preg_match('#'.$sExcludedPath.'#', $sPHPFile) === 1) {
- $bSkipped = true;
- break;
- }
- }
- } else {
- $bSkipped = true; // file not found
- }
- }
+ $this->aCustomDatamodelFiles = [];
- if (!$bSkipped) {
- try {
- $oRefClass = new ReflectionClass($sPHPClass);
- if ($oRefClass->isSubclassOf($sExtendedClass) &&
- !$oRefClass->isInterface() && !$oRefClass->isAbstract() && !$oRefClass->isTrait()) {
- $aMatchingClasses[] = $sPHPClass;
- }
+ // Search for the PHP files implementing the method GetDatamodelDeltaAbsPath
+ // and extract the delta file path from the method
+ foreach(['unitary-tests', 'integration-tests'] as $sTestDir) {
+ // Iterate on all PHP files in subdirectories
+ // Note: grep is not available on Windows, so we will use the PHP Reflection API
+ foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator(__DIR__."/../../$sTestDir")) as $oFile) {
+ if ($oFile->isDir()){
+ continue;
}
- catch (Exception $e) {
+ if (pathinfo($oFile->getFilename(), PATHINFO_EXTENSION) !== 'php') {
+ continue;
+ }
+ $sFile = $oFile->getPathname();
+ $sContent = file_get_contents($sFile);
+ if (strpos($sContent, 'GetDatamodelDeltaAbsPath') === false) {
+ continue;
+ }
+ $sClass = '';
+ $aMatches = [];
+ if (preg_match('/namespace\s+([^;]+);/', $sContent, $aMatches)) {
+ $sNamespace = $aMatches[1];
+ $sClass = $sNamespace.'\\'.basename($sFile, '.php');
+ }
+ if (preg_match('/\s+class\s+([^ ]+)\s+/', $sContent, $aMatches)) {
+ $sClass = $sNamespace.'\\'.$aMatches[1];
+ }
+ if ($sClass === '') {
+ continue;
+ }
+ require_once $sFile;
+ $oReflectionClass = new ReflectionClass($sClass);
+ if ($oReflectionClass->isAbstract()) {
+ continue;
+ }
+ // Check if the class extends ItopCustomDatamodelTestCase
+ if (!$oReflectionClass->isSubclassOf(ItopCustomDatamodelTestCase::class)) {
+ continue;
+ }
+ /** @var \Combodo\iTop\Test\UnitTest\ItopCustomDatamodelTestCase $oTestClassInstance */
+ $oTestClassInstance = new $sClass();
+ if ($oTestClassInstance->GetTestEnvironment() !== $this->sFinalEnv) {
+ continue;
+ }
+ $sDeltaFile = $oTestClassInstance->GetDatamodelDeltaAbsPath();
+ if (!is_file($sDeltaFile)) {
+ throw new \Exception("Unknown delta file: $sDeltaFile, from test class '$sClass'");
+ }
+ if (!in_array($sDeltaFile, $this->aCustomDatamodelFiles)) {
+ $this->aCustomDatamodelFiles[] = $sDeltaFile;
}
}
}
- return $aMatchingClasses;
+
+ return $this->aCustomDatamodelFiles;
}
-
+ private function FindFilesModifiedAfter(float $fReferenceTimestamp, string $sPathToScan, array &$aModifiedFiles)
+ {
+ if (!is_dir($sPathToScan)) {
+ return;
+ }
+ foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($sPathToScan)) as $oFile) {
+ if ($oFile->isDir()) {
+ continue;
+ }
+ if (filemtime($oFile->getPathname()) > $fReferenceTimestamp) {
+ $aModifiedFiles[] = $oFile->getPathname();
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/tests/php-unit-tests/unitary-tests/setup/unattended-install/InstallationFileServiceTest.php b/tests/php-unit-tests/unitary-tests/setup/unattended-install/InstallationFileServiceTest.php
index 080af0cfc..8e0cba695 100644
--- a/tests/php-unit-tests/unitary-tests/setup/unattended-install/InstallationFileServiceTest.php
+++ b/tests/php-unit-tests/unitary-tests/setup/unattended-install/InstallationFileServiceTest.php
@@ -289,8 +289,8 @@ class InstallationFileServiceTest extends ItopTestCase {
private function GetMockListOfFoundModules() : array {
$sJsonContent = file_get_contents(realpath(__DIR__ . '/resources/AnalyzeInstallation.json'));
- $sJsonContent = str_replace('ROOTDIR_TOREPLACE', APPROOT, $sJsonContent);
- return json_decode($sJsonContent, true);
+ $sJsonContent = str_replace('ROOTDIR_TOREPLACE', addslashes(APPROOT), $sJsonContent);
+ return json_decode($sJsonContent, true);
}
/**
diff --git a/tests/php-unit-tests/unitary-tests/setup/unattended-install/UnattendedInstallTest.php b/tests/php-unit-tests/unitary-tests/setup/unattended-install/UnattendedInstallTest.php
index cde7af01a..77116c351 100644
--- a/tests/php-unit-tests/unitary-tests/setup/unattended-install/UnattendedInstallTest.php
+++ b/tests/php-unit-tests/unitary-tests/setup/unattended-install/UnattendedInstallTest.php
@@ -69,6 +69,12 @@ class UnattendedInstallTest extends ItopDataTestCase
$sOutput = implode('\n', $aOutput);
var_dump($sOutput);
$this->assertStringContainsString("Missing mandatory argument `--param-file`", $sOutput);
- $this->assertEquals(255, $iCode);
+ if (DIRECTORY_SEPARATOR === '\\') {
+ // Windows
+ $this->assertEquals(-1, $iCode);
+ } else {
+ // Linux
+ $this->assertEquals(255, $iCode);
+ }
}
}