Test: add test suite prototype and command

refs #12905
This commit is contained in:
Thomas Gelf 2016-10-13 08:09:51 +00:00
parent 468a2719a7
commit 6c23a02252
8 changed files with 419 additions and 4 deletions

View File

@ -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");
}

View File

@ -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;

View File

@ -0,0 +1,116 @@
<?php
namespace Icinga\Module\Director\Test;
use Closure;
class TestProcess
{
protected $command;
protected $identifier;
protected $exitCode;
protected $output;
protected $onSuccess;
protected $onFailure;
protected $expectedExitCode = 0;
public function __construct($command, $identifier = null)
{
$this->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";
}
}

View File

@ -0,0 +1,68 @@
<?php
namespace Icinga\Module\Director\Test;
use Icinga\Application\Icinga;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
abstract class TestSuite
{
private $basedir;
abstract public function run();
public static function newTempfile()
{
return tempnam(sys_get_temp_dir(), 'DirectorTest-');
}
public function process($command, $identifier = null)
{
return new TestProcess($command, $identifier);
}
protected function filesByExtension($base, $extensions)
{
$files = array();
if (! is_array($extensions)) {
$extensions = array($extensions);
}
$basedir = $this->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;
}
}
}

View File

@ -0,0 +1,56 @@
<?php
namespace Icinga\Module\Director\Test;
use Icinga\Application\Logger;
class TestSuiteLint extends TestSuite
{
protected $checked;
protected $failed;
public function run()
{
$this->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;
}
}

View File

@ -0,0 +1,67 @@
<?php
namespace Icinga\Module\Director\Test;
class TestSuiteStyle extends TestSuite
{
public function run()
{
$out = static::newTempFile();
$check = array(
'library/Director/',
'application/',
'configuration.php',
'run.php',
);
/*
$options = array();
if ($this->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);
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace Icinga\Module\Director\Test;
abstract class TestSuiteUnit
{
public function run()
{
}
public function __construct()
{
$this->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 .
}
}

9
test/bootstrap.php Normal file
View File

@ -0,0 +1,9 @@
<?php
use Icinga\Application\Cli;
// TODO: fix paths
require_once '/usr/local/icingaweb2/library/Icinga/Application/Cli.php';
require_once dirname(__DIR__) . '/library/Director/Test/BaseTestCase.php';
Cli::start('/usr/local/icingaweb2')->getModuleManager()->loadModule('director');