array( 'type' => 'db', 'db' => 'mysql', 'host' => '127.0.0.1', 'port' => 3306, 'dbname' => 'icinga_unittest', 'username' => 'icinga_unittest', 'password' => 'icinga_unittest' ), 'pgsql' => array( 'type' => 'db', 'db' => 'pgsql', 'host' => '127.0.0.1', 'port' => 5432, 'dbname' => 'icinga_unittest', 'username' => 'icinga_unittest', 'password' => 'icinga_unittest' ), ); /** * Setup the default timezone */ public static function setupTimezone() { date_default_timezone_set('UTC'); } /** * Setup test path environment * * @throws RuntimeException */ public static function setupDirectories() { $baseDir = getenv('ICINGAWEB_BASEDIR') ?: realpath(__DIR__ . '/../../../'); if ($baseDir === false) { throw new RuntimeException('Application base dir not found'); } $libDir = getenv('ICINGAWEB_ICINGA_LIB') ?: realpath($baseDir . '/library/Icinga'); if ($libDir === false) { throw new RuntimeException('Icinga library dir not found'); } self::$appDir = $baseDir . '/application'; self::$libDir = $libDir; self::$etcDir = $baseDir . '/etc'; self::$testDir = $baseDir . '/test/php'; self::$shareDir = $baseDir . '/share/icinga2-web'; self::$moduleDir = getenv('ICINGAWEB_MODULES_DIR') ?: $baseDir . '/modules'; } /** * Setup MVC bootstrapping and ensure that the Icinga-Mock gets reinitialized */ public function setUp(): void { parent::setUp(); StaticTranslator::$instance = new NoopTranslator(); $this->setupIcingaMock(); } /** * Setup mock object for the application's bootstrap * * @return Mockery\Mock */ protected function setupIcingaMock() { $requestMock = Mockery::mock('Icinga\Web\Request')->shouldDeferMissing(); $requestMock->shouldReceive('getPathInfo')->andReturn('')->byDefault() ->shouldReceive('getBaseUrl')->andReturn('/')->byDefault() ->shouldReceive('getQuery')->andReturn(array())->byDefault() ->shouldReceive('getParam')->with(Mockery::type('string'), Mockery::type('string')) ->andReturnUsing(function ($name, $default) { return $default; })->byDefault(); $responseMock = Mockery::mock('Icinga\Web\Response')->shouldDeferMissing(); // Can't express this as demeter chains. See: https://github.com/padraic/mockery/issues/59 $bootstrapMock = Mockery::mock('Icinga\Application\ApplicationBootstrap')->shouldDeferMissing(); $libDir = dirname(self::$libDir); $bootstrapMock->shouldReceive('getFrontController')->andReturn($bootstrapMock) ->shouldReceive('getApplicationDir')->andReturn(self::$appDir) ->shouldReceive('getLibraryDir')->andReturnUsing(function ($subdir = null) use ($libDir) { if ($subdir !== null) { $libDir .= '/' . ltrim($subdir, '/'); } return $libDir; }) ->shouldReceive('getRequest')->andReturn($requestMock) ->shouldReceive('getResponse')->andReturn($responseMock); Icinga::setApp($bootstrapMock, true); return $bootstrapMock; } /** * Return the currently active request mock object * * @return Icinga\Web\Request */ public function getRequestMock() { return Icinga::app()->getRequest(); } /** * Return the currently active response mock object * * @return Icinga\Web\Response */ public function getResponseMock() { return Icinga::app()->getFrontController()->getResponse(); } /** * Create Config for database configuration * * @param string $name * * @return ConfigObject * @throws RuntimeException */ protected function createDbConfigFor($name) { if (array_key_exists($name, self::$dbConfiguration)) { $config = new ConfigObject(self::$dbConfiguration[$name]); $host = getenv(sprintf('ICINGAWEB_TEST_%s_HOST', strtoupper($name))); if ($host) { $config['host'] = $host; } $port = getenv(sprintf('ICINGAWEB_TEST_%s_PORT', strtoupper($name))); if ($port) { $config['port'] = $port; } return $config; } throw new RuntimeException('Configuration for database type not available: ' . $name); } /** * Creates an array of Icinga\Data\Db\DbConnection * * @param string $name * * @return array */ protected function createDbConnectionFor($name) { try { $conn = ResourceFactory::createResource($this->createDbConfigFor($name)); } catch (Exception $e) { $conn = $e->getMessage(); } return array( array($conn) ); } /** * PHPUnit provider for mysql * * @return DbConnection */ public function mysqlDb() { return $this->createDbConnectionFor('mysql'); } /** * PHPUnit provider for pgsql * * @return DbConnection */ public function pgsqlDb() { return $this->createDbConnectionFor('pgsql'); } /** * PHPUnit provider for oracle * * @return DbConnection */ public function oracleDb() { return $this->createDbConnectionFor('oracle'); } /** * Executes sql file by using the database connection * * @param DbConnection $resource * @param string $filename * * @throws RuntimeException */ public function loadSql(DbConnection $resource, $filename) { if (!is_file($filename)) { throw new RuntimeException( 'Sql file not found: ' . $filename . ' (test=' . $this->getName() . ')' ); } $sqlData = file_get_contents($filename); if (!$sqlData) { throw new RuntimeException( 'Sql file is empty: ' . $filename . ' (test=' . $this->getName() . ')' ); } $resource->getDbAdapter()->exec($sqlData); } /** * Setup provider for testcase * * @param string|DbConnection|null $resource */ public function setupDbProvider($resource) { if (!$resource instanceof DbConnection) { if (is_string($resource)) { $this->markTestSkipped('Could not initialize provider: ' . $resource); } else { $this->markTestSkipped('Could not initialize provider'); } return; } $adapter = $resource->getDbAdapter(); try { $adapter->getConnection(); } catch (Exception $e) { $this->markTestSkipped('Could not connect to provider: '. $e->getMessage()); } $tables = $adapter->listTables(); foreach ($tables as $table) { $adapter->exec('DROP TABLE ' . $table . ';'); } } /** * Add assertMatchesRegularExpression() method for phpunit >= 8.0 < 9.0 for compatibility with PHP 7.2. * * @TODO Remove once PHP 7.2 support is not needed for testing anymore. */ public static function assertMatchesRegularExpression( string $pattern, string $string, string $message = '' ): void { if (method_exists(parent::class, 'assertMatchesRegularExpression')) { parent::assertMatchesRegularExpression($pattern, $string, $message); } else { static::assertRegExp($pattern, $string, $message); } } } BaseTestCase::setupTimezone(); BaseTestCase::setupDirectories(); }