From 597cb5c94d936c2b3001950df1a1b66bbd2126be Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Tue, 4 Jul 2023 16:41:22 +0200 Subject: [PATCH] tests: Use a real app for bootstrapping Makes the tests less isolated, but streamlines the autoloading and other stuff in a way that's more maintainable than before. --- icingaweb2.ruleset.xml | 1 + library/Icinga/Application/Cli.php | 2 +- library/Icinga/Application/Test.php | 134 ++++++++++++++++++++++++++++ test/php/bootstrap.php | 121 ++----------------------- 4 files changed, 145 insertions(+), 113 deletions(-) create mode 100644 library/Icinga/Application/Test.php diff --git a/icingaweb2.ruleset.xml b/icingaweb2.ruleset.xml index 537a6be9b..f1bcb8996 100644 --- a/icingaweb2.ruleset.xml +++ b/icingaweb2.ruleset.xml @@ -16,6 +16,7 @@ library/Icinga/Application/Cli.php + library/Icinga/Application/Test.php library/Icinga/Application/StaticWeb.php library/Icinga/Application/EmbeddedWeb.php library/Icinga/Application/functions.php diff --git a/library/Icinga/Application/Cli.php b/library/Icinga/Application/Cli.php index 719bf9279..28109f94f 100644 --- a/library/Icinga/Application/Cli.php +++ b/library/Icinga/Application/Cli.php @@ -200,7 +200,7 @@ class Cli extends ApplicationBootstrap * @throws ProgrammingError * @return void */ - private function assertRunningOnCli() + protected function assertRunningOnCli() { if (Platform::isCli()) { return; diff --git a/library/Icinga/Application/Test.php b/library/Icinga/Application/Test.php new file mode 100644 index 000000000..2a0bb93d1 --- /dev/null +++ b/library/Icinga/Application/Test.php @@ -0,0 +1,134 @@ +request = $request; + } + + public function getRequest(): Request + { + assert(isset($this->request), 'BaseTestCase should have set the request'); + + return $this->request; + } + + public function setResponse(Response $response): void + { + $this->response = $response; + } + + public function getResponse(): Response + { + assert(isset($this->request), 'BaseTestCase should have set the response'); + + return $this->response; + } + + public function getFrontController() + { + return $this; // Callers are expected to only call getRequest or getResponse, hence the app should suffice + } + + protected function bootstrap() + { + $this->assertRunningOnCli(); + $this->setupLogging() + ->setupErrorHandling() + ->loadLibraries() + ->setupComposerAutoload() + ->loadConfig() + ->setupModuleAutoloaders() + ->setupTimezone() + ->prepareInternationalization() + ->setupInternationalization() + ->parseBasicParams() + ->setupLogger() + ->setupModuleManager() + ->setupUserBackendFactory() + ->setupFakeAuthentication(); + } + + public function setupAutoloader() + { + parent::setupAutoloader(); + + if (($icingaLibDir = getenv('ICINGAWEB_ICINGA_LIB')) !== false) { + $this->getLoader()->registerNamespace('Icinga', $icingaLibDir); + } + + // Conflicts with `Tests\Icinga\Module\...\Lib`. But it seems it's not needed anyway... + //$this->getLoader()->registerNamespace('Tests', $this->getBaseDir('test/php/library')); + + return $this; + } + + protected function detectTimezone() + { + return 'UTC'; + } + + private function setupModuleAutoloaders(): self + { + $modulePaths = getenv('ICINGAWEB_MODULE_DIRS'); + + if ($modulePaths) { + $modulePaths = preg_split('/:/', $modulePaths, -1, PREG_SPLIT_NO_EMPTY); + } + + if (! $modulePaths) { + $modulePaths = []; + foreach ($this->getAvailableModulePaths() as $path) { + $candidates = array_flip(scandir($path)); + unset($candidates['.'], $candidates['..']); + foreach ($candidates as $candidate => $_) { + $modulePaths[] = "$path/$candidate"; + } + } + } + + foreach ($modulePaths as $path) { + $module = basename($path); + + $moduleNamespace = 'Icinga\\Module\\' . ucfirst($module); + $moduleLibraryPath = "$path/library/" . ucfirst($module); + + if (is_dir($moduleLibraryPath)) { + $this->getLoader()->registerNamespace($moduleNamespace, $moduleLibraryPath, "$path/application"); + } + + $moduleTestPath = "$path/test/php/Lib"; + if (is_dir($moduleTestPath)) { + $this->getLoader()->registerNamespace('Tests\\' . $moduleNamespace . '\\Lib', $moduleTestPath); + } + } + + return $this; + } + + private function setupComposerAutoload(): self + { + $vendorAutoload = $this->getBaseDir('/vendor/autoload.php'); + if (file_exists($vendorAutoload)) { + require_once $vendorAutoload; + } + + return $this; + } +} diff --git a/test/php/bootstrap.php b/test/php/bootstrap.php index 293682bb9..60174125e 100644 --- a/test/php/bootstrap.php +++ b/test/php/bootstrap.php @@ -1,117 +1,14 @@ registerNamespace('Tests', $testLibraryPath); -$loader->registerNamespace('Icinga', $icingaLibPath); -$loader->registerNamespace('Icinga\\Forms', $applicationPath . '/forms'); - -$libraryPaths = getenv('ICINGAWEB_LIBDIR'); -if ($libraryPaths !== false) { - $libraryPaths = array_filter(array_map( - 'realpath', - explode(':', $libraryPaths) - ), 'is_dir'); -} else { - $libraryPaths = is_dir('/usr/share/icinga-php') - ? ['/usr/share/icinga-php'] - : []; -} - -foreach ($libraryPaths as $externalLibraryPath) { - $libPaths = array_flip(scandir($externalLibraryPath)); - unset($libPaths['.']); - unset($libPaths['..']); - $libPaths = array_keys($libPaths); - foreach ($libPaths as $libPath) { - $libPath = join(DIRECTORY_SEPARATOR, [$externalLibraryPath, $libPath]); - if (is_dir(realpath($libPath))) { - $libAutoLoader = join(DIRECTORY_SEPARATOR, [$libPath, 'vendor', 'autoload.php']); - if (file_exists($libAutoLoader)) { - require_once $libAutoLoader; - } - } - } -} - -$modulePaths = getenv('ICINGAWEB_MODULE_DIRS'); - -if ($modulePaths) { - $modulePaths = preg_split('/:/', $modulePaths, -1, PREG_SPLIT_NO_EMPTY); -} - -if (! $modulePaths) { - $modulePaths = []; - foreach (preg_split('/:/', $modulePath, -1, PREG_SPLIT_NO_EMPTY) as $path) { - $candidates = array_flip(scandir($path)); - unset($candidates['.'], $candidates['..']); - foreach ($candidates as $candidate => $_) { - $modulePaths[] = "$path/$candidate"; - } - } -} - -foreach ($modulePaths as $path) { - $module = basename($path); - - $moduleNamespace = 'Icinga\\Module\\' . ucfirst($module); - $moduleLibraryPath = "$path/library/" . ucfirst($module); - - if (is_dir($moduleLibraryPath)) { - $loader->registerNamespace($moduleNamespace, $moduleLibraryPath); - } - - $moduleTestPath = "$path/test/php/Lib"; - if (is_dir($moduleTestPath)) { - $loader->registerNamespace('Tests\\' . $moduleNamespace . '\\Lib', $moduleTestPath); - } - - $moduleFormPath = "$path/application/forms"; - if (is_dir($moduleFormPath)) { - $loader->registerNamespace($moduleNamespace . '\\Forms', $moduleFormPath); - } -} - -$loader->register(); - -set_include_path( - implode( - PATH_SEPARATOR, - array($libraryPath . '/vendor', get_include_path()) - ) -); - -require_once 'Zend/Loader/Autoloader.php'; -\Zend_Loader_Autoloader::getInstance(); - -Icinga\Application\Config::$configDir = $configPath;