From 6c23a02252d48dfc095fdf49239787d9ca4505bd Mon Sep 17 00:00:00 2001 From: Thomas Gelf Date: Thu, 13 Oct 2016 08:09:51 +0000 Subject: [PATCH] Test: add test suite prototype and command refs #12905 --- application/clicommands/TestCommand.php | 74 ++++++++++++++- library/Director/Test/BaseTestCase.php | 7 +- library/Director/Test/TestProcess.php | 116 +++++++++++++++++++++++ library/Director/Test/TestSuite.php | 68 +++++++++++++ library/Director/Test/TestSuiteLint.php | 56 +++++++++++ library/Director/Test/TestSuiteStyle.php | 67 +++++++++++++ library/Director/Test/TestSuiteUnit.php | 26 +++++ test/bootstrap.php | 9 ++ 8 files changed, 419 insertions(+), 4 deletions(-) create mode 100644 library/Director/Test/TestProcess.php create mode 100644 library/Director/Test/TestSuite.php create mode 100644 library/Director/Test/TestSuiteLint.php create mode 100644 library/Director/Test/TestSuiteStyle.php create mode 100644 library/Director/Test/TestSuiteUnit.php create mode 100644 test/bootstrap.php diff --git a/application/clicommands/TestCommand.php b/application/clicommands/TestCommand.php index 69e44f71..dcb6d170 100644 --- a/application/clicommands/TestCommand.php +++ b/application/clicommands/TestCommand.php @@ -2,7 +2,12 @@ namespace Icinga\Module\Director\Clicommands; +use Icinga\Application\Logger; use Icinga\Cli\Command; +use Icinga\Module\Director\Test\TestSuiteLint; +use Icinga\Module\Director\Test\TestSuiteStyle; +use RecursiveDirectoryIterator; +use RecursiveIteratorIterator; class TestCommand extends Command { @@ -18,6 +23,19 @@ class TestCommand extends Command '--encoding=utf-8' ); + public function lintAction() + { + $test = new TestSuiteLint(); + $test->run(); + if ($test->hasFailures()) { + Logger::error('Lint check failed'); + exit(1); + } else { + Logger::info('Lint check succeeded'); + exit(0); + } + } + /** * Run all unit-test suites * @@ -41,6 +59,7 @@ class TestCommand extends Command */ public function phpAction() { + $basedir = $this->getBaseDir(); $build = $this->params->shift('build'); $include = $this->params->shift('include'); @@ -49,7 +68,9 @@ class TestCommand extends Command $this->fail('PHPUnit not found. Please install PHPUnit to be able to run the unit-test suites.'); } - $options = array(); + $options = array( + '--bootstrap' => $basedir . '/test/bootstrap.php' + ); if ($this->isVerbose) { $options[] = '--verbose --testdox'; } @@ -111,6 +132,47 @@ class TestCommand extends Command */ public function styleAction() { + // passthru( + // 'phpcs -p --standard=PSR2 --extensions=php --encoding=utf-8 -w -s + // --report-checkstyle=/tmp/style/bla library/Director/ application/ + // run.php configuration.php' + // ); + + + $test = new TestSuiteStyle(); + $test->run(); + + return; + // TODO: obsolete: + + if ($test->hasFailures()) { + $this->fail('Lint check failed'); + } else { + Logger::info('Lint check succeeded'); + } + + $out = TestRunner::newTempFile(); + $check = array( + 'library/Director/', + 'application/', + 'configuration.php', + 'run.php', + ); + + $cmd = sprintf( + "phpcs -p --standard=PSR2 --extensions=php --encoding=utf-8 -w -s --report-checkstyle=%s '%s'", + $out, + implode("' '", $check) + ); + + // TODO: Debug only: + `$cmd`; + echo $cmd . "\n"; + echo $out ."\n"; + echo file_get_contents($out); + unlink($out); + exit; + $build = $this->params->shift('build'); $include = (array) $this->params->shift('include', array()); $exclude = (array) $this->params->shift('exclude', array()); @@ -161,6 +223,11 @@ class TestCommand extends Command ); } + protected function getBaseDir() + { + return dirname(dirname(__DIR__)); + } + /** * Setup the directory where to put report files and return its path * @@ -168,8 +235,9 @@ class TestCommand extends Command */ protected function setupAndReturnReportDirectory() { - $path = realpath(__DIR__ . '/../../../..') . '/build/log'; - if (!file_exists($path) && !@mkdir($path, 0755, true)) { + $path = '/tmp/test-devel'; + + if (!is_dir($path) && !@mkdir($path, 0755, true)) { $this->fail("Could not create directory: $path"); } diff --git a/library/Director/Test/BaseTestCase.php b/library/Director/Test/BaseTestCase.php index e17a835a..866598f8 100644 --- a/library/Director/Test/BaseTestCase.php +++ b/library/Director/Test/BaseTestCase.php @@ -2,7 +2,8 @@ namespace Icinga\Module\Director\Test; -use Icinga\Application\Cli; +use Icinga\Application\Icinga; +use Icinga\Application\Cli; // <- remove use Icinga\Application\Config; use Icinga\Exception\ConfigurationError; use Icinga\Module\Director\Db; @@ -72,10 +73,14 @@ class BaseTestCase extends PHPUnit_Framework_TestCase protected function app() { if (self::$app === null) { + // TODO: Replace this.. $testModuleDir = $_SERVER['PWD']; $libDir = dirname(dirname($testModuleDir)) . '/library'; require_once $libDir . '/Icinga/Application/Cli.php'; self::$app = Cli::start(); + + // With this: + // self::$app = Icinga::app(); } return self::$app; diff --git a/library/Director/Test/TestProcess.php b/library/Director/Test/TestProcess.php new file mode 100644 index 00000000..b2399b75 --- /dev/null +++ b/library/Director/Test/TestProcess.php @@ -0,0 +1,116 @@ +command = $command; + $this->identifier = $identifier; + } + + public function getIdentifier() + { + return $this->identifier; + } + + public function expectExitCode($code) + { + $this->expectedExitCode = $code; + return $this; + } + + public function onSuccess($func) + { + $this->onSuccess = $this->makeClosure($func); + return $this; + } + + public function onFailure($func) + { + $this->onSuccess = $this->makeClosure($func); + return $this; + } + + protected function makeClosure($func) + { + if ($func instanceof Closure) { + return $func; + } + + if (is_array($func)) { + return function ($process) use ($func) { + return $func[0]->{$func[1]}($process); + }; + } + } + + public function onFailureThrow($message, $class = 'Exception') + { + return $this->onFailure(function () use ($message, $class) { + throw new $class($message); + }); + } + + public function run() + { + exec($this->command, $this->output, $this->exitCode); + + if ($this->succeeded()) { + $this->triggerSuccess(); + } else { + $this->triggerFailure(); + } + } + + public function succeeded() + { + return $this->exitCode === $this->expectedExitCode; + } + + public function failed() + { + return $this->exitCode !== $this->expectedExitCode; + } + + protected function triggerSuccess() + { + if (($func = $this->onSuccess) !== null) { + $func($this); + } + } + + protected function triggerFailure() + { + if (($func = $this->onFailure) !== null) { + $func($this); + } + } + + public function getExitCode() + { + return $this->exitCode; + } + + public function getOutput() + { + return implode("\n", $this->output) . "\n"; + } +} diff --git a/library/Director/Test/TestSuite.php b/library/Director/Test/TestSuite.php new file mode 100644 index 00000000..131b9741 --- /dev/null +++ b/library/Director/Test/TestSuite.php @@ -0,0 +1,68 @@ +getBaseDir() . '/' . $base; + $dir = new RecursiveDirectoryIterator($basedir); + $iterator = new RecursiveIteratorIterator( + $dir, + RecursiveIteratorIterator::SELF_FIRST + ); + + foreach ($iterator as $file) { + if (! $file->isFile()) { + continue; + } + + if (in_array($file->getExtension(), $extensions)) { + $files[] = $file->getPathname(); + } + } + + return $files; + } + + public function getBaseDir($file = null) + { + if ($this->basedir === null) { + $this->basedir = Icinga::app() + ->getModuleManager() + ->getModule('director') + ->getBaseDir(); + } + + if ($file === null) { + return $this->basedir; + } else { + return $this->basedir . '/' . $file; + } + } +} diff --git a/library/Director/Test/TestSuiteLint.php b/library/Director/Test/TestSuiteLint.php new file mode 100644 index 00000000..41941eb5 --- /dev/null +++ b/library/Director/Test/TestSuiteLint.php @@ -0,0 +1,56 @@ +checked = $this->failed = array(); + + foreach ($this->listFiles() as $file) { + $checked[] = $file; + $cmd = "php -l '$file'"; + $this->result[$file] = $this + ->process($cmd, $file) + ->onFailure(array($this, 'failedCheck')) + ->run(); + } + } + + public function failedCheck($process) + { + Logger::error($process->getOutput()); + $this->failed[] = $process->getIdentifier(); + } + + public function hasFailures() + { + return ! empty($this->failed); + } + + protected function listFiles() + { + $basedir = $this->getBaseDir(); + $files = array( + $basedir . '/run.php', + $basedir . '/configuration.php' + ); + + foreach ($this->filesByExtension('library/Director', 'php') as $file) { + $files[] = $file; + } + + foreach ($this->filesByExtension('application', array('php', 'phtml')) as $file) { + $files[] = $file; + } + + return $files; + } +} diff --git a/library/Director/Test/TestSuiteStyle.php b/library/Director/Test/TestSuiteStyle.php new file mode 100644 index 00000000..f88fbada --- /dev/null +++ b/library/Director/Test/TestSuiteStyle.php @@ -0,0 +1,67 @@ +isVerbose) { + $options[] = '-v'; + } + */ + + /* + $phpcs = exec('which phpcs'); + if (!file_exists($phpcs)) { + $this->fail( + 'PHP_CodeSniffer not found. Please install PHP_CodeSniffer to be able to run code style tests.' + ); + } + */ + + $cmd = sprintf( + "phpcs -p --standard=PSR2 --extensions=php --encoding=utf-8 -w -s --report-checkstyle=%s '%s'", + $out, + implode("' '", $check) + ); + + $proc = $this + ->process($cmd); + + // ->onFailure(array($this, 'failedCheck')) + $proc->run(); + + echo $proc->getOutput(); + + echo file_get_contents($out); + unlink($out); + // /usr/bin/phpcs --standard=PSR2 --extensions=php --encoding=utf-8 application/ + // library/Director/ --report=full + + /* + $options[] = '--log-junit'; + $options[] = $reportPath . '/phpunit_results.xml'; + $options[] = '--coverage-html'; + $options[] = $reportPath . '/php_html_coverage'; + */ + return; + + `$cmd`; + echo $cmd . "\n"; + echo $out ."\n"; + echo file_get_contents($out); + unlink($out); + + } +} diff --git a/library/Director/Test/TestSuiteUnit.php b/library/Director/Test/TestSuiteUnit.php new file mode 100644 index 00000000..8156ebaa --- /dev/null +++ b/library/Director/Test/TestSuiteUnit.php @@ -0,0 +1,26 @@ +testdoxFile = $this->newTempfile(); + } + + public function __destruct() + { + if ($this->testdoxFile && file_exists($this->testdoxFile)) { + unlink($this->testDoxfile); + } + } + + public function getPhpunitCommand() + { + // return phpunit --bootstrap test/bootstrap.php --testdox-text /tmp/testdox.txt . + } +} diff --git a/test/bootstrap.php b/test/bootstrap.php new file mode 100644 index 00000000..be1d364b --- /dev/null +++ b/test/bootstrap.php @@ -0,0 +1,9 @@ +getModuleManager()->loadModule('director'); +