diff options
Diffstat (limited to 'library/Icinga/Test')
-rw-r--r-- | library/Icinga/Test/BaseTestCase.php | 313 | ||||
-rw-r--r-- | library/Icinga/Test/ClassLoader.php | 113 | ||||
-rw-r--r-- | library/Icinga/Test/DbTest.php | 47 |
3 files changed, 473 insertions, 0 deletions
diff --git a/library/Icinga/Test/BaseTestCase.php b/library/Icinga/Test/BaseTestCase.php new file mode 100644 index 0000000..1283013 --- /dev/null +++ b/library/Icinga/Test/BaseTestCase.php @@ -0,0 +1,313 @@ +<?php +/* Icinga Web 2 | (c) 2013 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Test { + + use Exception; + use Icinga\Util\Csp; + use Icinga\Web\Request; + use Icinga\Web\Response; + use Icinga\Web\Session; + use ipl\I18n\NoopTranslator; + use ipl\I18n\StaticTranslator; + use RuntimeException; + use Mockery; + use Icinga\Application\Icinga; + use Icinga\Data\ConfigObject; + use Icinga\Data\ResourceFactory; + use Icinga\Data\Db\DbConnection; + use Tests\Icinga\Lib\FakeSession; + + /** + * Class BaseTestCase + */ + abstract class BaseTestCase extends Mockery\Adapter\Phpunit\MockeryTestCase implements DbTest + { + /** + * Path to application/ + * + * @var string + * @deprecated Use Icinga::app()->getApplicationDir() instead + */ + public static $appDir; + + /** + * Path to library/Icinga + * + * @var string + * @deprecated Use Icinga::app()->getLibraryDir('Icinga') instead + */ + public static $libDir; + + /** + * Path to etc/ + * + * @var string + * @deprecated Use Icinga::app()->getBaseDir('etc') instead + */ + public static $etcDir; + + /** + * Path to test/php/ + * + * @var string + * @deprecated Use Icinga::app()->getBaseDir('test/php') instead + */ + public static $testDir; + + /** + * Path to share/icinga2-web + * + * @var string + * @deprecated Unused + */ + public static $shareDir; + + /** + * Path to modules/ + * + * @var string + * @deprecated Use Icinga::app()->getModuleManager()->getModuleDirs() instead + */ + public static $moduleDir; + + /** + * Resource configuration for different database types + * + * @var array + */ + protected static $dbConfiguration = array( + 'mysql' => 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' + ), + ); + + /** @var Request */ + private $requestMock; + + /** @var Response */ + private $responseMock; + + /** + * Setup MVC bootstrapping and ensure that the Icinga-Mock gets reinitialized + */ + public function setUp(): void + { + parent::setUp(); + $this->setupRequestMock(); + $this->setupResponseMock(); + Session::create(new FakeSession()); + Csp::createNonce(); + + StaticTranslator::$instance = new NoopTranslator(); + } + + private function setupRequestMock() + { + $this->requestMock = Mockery::mock('Icinga\Web\Request')->shouldDeferMissing(); + $this->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(); + + Icinga::app()->setRequest($this->requestMock); + } + + private function setupResponseMock() + { + $this->responseMock = Mockery::mock('Icinga\Web\Response')->shouldDeferMissing(); + Icinga::app()->setResponse($this->responseMock); + } + + /** + * Return the currently active request mock object + * + * @return Request + */ + public function getRequestMock() + { + return $this->requestMock; + } + + /** + * Return the currently active response mock object + * + * @return Response + */ + public function getResponseMock() + { + return $this->responseMock; + } + + /** + * 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); + } + } + } +} diff --git a/library/Icinga/Test/ClassLoader.php b/library/Icinga/Test/ClassLoader.php new file mode 100644 index 0000000..af90a7e --- /dev/null +++ b/library/Icinga/Test/ClassLoader.php @@ -0,0 +1,113 @@ +<?php +/* Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Test; + +/** + * PSR-4 class loader + */ +class ClassLoader +{ + /** + * Namespace separator + */ + const NAMESPACE_SEPARATOR = '\\'; + + /** + * Namespaces + * + * @var array + */ + private $namespaces = array(); + + /** + * Register a base directory for a namespace prefix + * + * @param string $namespace + * @param string $directory + * + * @return $this + */ + public function registerNamespace($namespace, $directory) + { + $this->namespaces[$namespace] = $directory; + + return $this; + } + + /** + * Test whether a namespace exists + * + * @param string $namespace + * + * @return bool + */ + public function hasNamespace($namespace) + { + return array_key_exists($namespace, $this->namespaces); + } + + /** + * Get the source file of the given class or interface + * + * @param string $class Name of the class or interface + * + * @return string|null + */ + public function getSourceFile($class) + { + foreach ($this->namespaces as $namespace => $dir) { + if ($class === strstr($class, $namespace)) { + $classPath = str_replace( + self::NAMESPACE_SEPARATOR, + DIRECTORY_SEPARATOR, + substr($class, strlen($namespace)) + ) . '.php'; + if (file_exists($file = $dir . $classPath)) { + return $file; + } + } + } + return null; + } + + /** + * Load the given class or interface + * + * @param string $class Name of the class or interface + * + * @return bool Whether the class or interface has been loaded + */ + public function loadClass($class) + { + if ($file = $this->getSourceFile($class)) { + require $file; + return true; + } + return false; + } + + /** + * Register {@link loadClass()} as an autoloader + */ + public function register() + { + spl_autoload_register(array($this, 'loadClass')); + } + + /** + * Unregister {@link loadClass()} as an autoloader + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Unregister this as an autoloader + */ + public function __destruct() + { + $this->unregister(); + } +} diff --git a/library/Icinga/Test/DbTest.php b/library/Icinga/Test/DbTest.php new file mode 100644 index 0000000..d1b1ff0 --- /dev/null +++ b/library/Icinga/Test/DbTest.php @@ -0,0 +1,47 @@ +<?php +/* Icinga Web 2 | (c) 2013 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Test; + +use Icinga\Data\Db\DbConnection; + +interface DbTest +{ + /** + * PHPUnit provider for mysql + * + * @return DbConnection + */ + public function mysqlDb(); + + /** + * PHPUnit provider for pgsql + * + * @return DbConnection + */ + public function pgsqlDb(); + + /** + * PHPUnit provider for oracle + * + * @return DbConnection + */ + public function oracleDb(); + + /** + * Executes sql file on PDO object + * + * @param DbConnection $resource + * @param string $filename + * + * @return boolean Operational success flag + */ + public function loadSql(DbConnection $resource, $filename); + + /** + * Setup provider for testcase + * + * @param string|DbConnection|null $resource + */ + public function setupDbProvider($resource); +} |