Reworked the DaemonCommand.
* Accepts options for PID and log file. * Uses posix_kill whenever available. * Checks that the daemon actually started or stopped. * Try to terminate then kill the daemon. * Uses the logger or output instead of "echo". Added a ProcessControl interface and implementations. Closed #908
This commit is contained in:
parent
8fc4c51d54
commit
7de9023810
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
|
@ -10,28 +11,48 @@
|
|||
namespace PHPCI\Command;
|
||||
|
||||
use Monolog\Logger;
|
||||
use PHPCI\ProcessControl\Factory;
|
||||
use PHPCI\ProcessControl\ProcessControlInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Daemon that loops and call the run-command.
|
||||
* @author Gabriel Baker <gabriel.baker@autonomicpilot.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Console
|
||||
*/
|
||||
* Daemon that loops and call the run-command.
|
||||
* @author Gabriel Baker <gabriel.baker@autonomicpilot.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Console
|
||||
*/
|
||||
class DaemonCommand extends Command
|
||||
{
|
||||
|
||||
/**
|
||||
* @var \Monolog\Logger
|
||||
* @var Logger
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
public function __construct(Logger $logger, $name = null)
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $pidFilePath;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $logFilePath;
|
||||
|
||||
/**
|
||||
* @var ProcessControlInterface
|
||||
*/
|
||||
protected $processControl;
|
||||
|
||||
public function __construct(Logger $logger, ProcessControlInterface $processControl = null, $name = null)
|
||||
{
|
||||
parent::__construct($name);
|
||||
$this->logger = $logger;
|
||||
$this->processControl = $processControl ?: Factory::getInstance();
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
|
@ -40,17 +61,30 @@ class DaemonCommand extends Command
|
|||
->setName('phpci:daemon')
|
||||
->setDescription('Initiates the daemon to run commands.')
|
||||
->addArgument(
|
||||
'state',
|
||||
InputArgument::REQUIRED,
|
||||
'start|stop|status'
|
||||
);
|
||||
'state', InputArgument::REQUIRED, 'start|stop|status'
|
||||
)
|
||||
->addOption(
|
||||
'pid-file', 'p', InputOption::VALUE_REQUIRED,
|
||||
'Path of the PID file',
|
||||
implode(DIRECTORY_SEPARATOR,
|
||||
array(PHPCI_DIR, 'daemon', 'daemon.pid'))
|
||||
)
|
||||
->addOption(
|
||||
'log-file', 'l', InputOption::VALUE_REQUIRED,
|
||||
'Path of the log file',
|
||||
implode(DIRECTORY_SEPARATOR,
|
||||
array(PHPCI_DIR, 'daemon', 'daemon.log'))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loops through running.
|
||||
*/
|
||||
* Loops through running.
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$this->pidFilePath = $input->getOption('pid-file');
|
||||
$this->logFilePath = $input->getOption('log-file');
|
||||
|
||||
$state = $input->getArgument('state');
|
||||
|
||||
switch ($state) {
|
||||
|
@ -61,64 +95,108 @@ class DaemonCommand extends Command
|
|||
$this->stopDaemon();
|
||||
break;
|
||||
case 'status':
|
||||
$this->statusDaemon();
|
||||
$this->statusDaemon($output);
|
||||
break;
|
||||
default:
|
||||
echo "Not a valid choice, please use start stop or status";
|
||||
$this->output->writeln("<error>Not a valid choice, please use start, stop or status</error>");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected function startDaemon()
|
||||
{
|
||||
|
||||
if (file_exists(PHPCI_DIR.'/daemon/daemon.pid')) {
|
||||
echo "Already started\n";
|
||||
$this->logger->warning("Daemon already started");
|
||||
$pid = $this->getRunningPid();
|
||||
if ($pid) {
|
||||
$this->logger->notice("Daemon already started", array('pid' => $pid));
|
||||
return "alreadystarted";
|
||||
}
|
||||
|
||||
$logfile = PHPCI_DIR."/daemon/daemon.log";
|
||||
$this->logger->info("Trying to start the daemon");
|
||||
|
||||
$cmd = "nohup %s/daemonise phpci:daemonise > %s 2>&1 &";
|
||||
$command = sprintf($cmd, PHPCI_DIR, $logfile);
|
||||
$this->logger->info("Daemon started");
|
||||
exec($command);
|
||||
$command = sprintf($cmd, PHPCI_DIR, $this->logFilePath);
|
||||
$output = $exitCode = null;
|
||||
exec($command, $output, $exitCode);
|
||||
|
||||
if ($exitCode !== 0) {
|
||||
$this->logger->error(sprintf("daemonise exited with status %d", $exitCode));
|
||||
return "notstarted";
|
||||
}
|
||||
|
||||
for ($i = 0; !($pid = $this->getRunningPid()) && $i < 5; $i++) {
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
if (!$pid) {
|
||||
$this->logger->error("Could not start the daemon");
|
||||
return "notstarted";
|
||||
}
|
||||
|
||||
$this->logger->notice("Daemon started", array('pid' => $pid));
|
||||
return "started";
|
||||
}
|
||||
|
||||
protected function stopDaemon()
|
||||
{
|
||||
|
||||
if (!file_exists(PHPCI_DIR.'/daemon/daemon.pid')) {
|
||||
echo "Not started\n";
|
||||
$this->logger->warning("Can't stop daemon as not started");
|
||||
$pid = $this->getRunningPid();
|
||||
if (!$pid) {
|
||||
$this->logger->notice("Cannot stop the daemon as it is not started");
|
||||
return "notstarted";
|
||||
}
|
||||
|
||||
$cmd = "kill $(cat %s/daemon/daemon.pid)";
|
||||
$command = sprintf($cmd, PHPCI_DIR);
|
||||
exec($command);
|
||||
$this->logger->info("Daemon stopped");
|
||||
unlink(PHPCI_DIR.'/daemon/daemon.pid');
|
||||
}
|
||||
$this->logger->info("Trying to terminate the daemon", array('pid' => $pid));
|
||||
$this->processControl->kill($pid);
|
||||
|
||||
protected function statusDaemon()
|
||||
{
|
||||
|
||||
if (!file_exists(PHPCI_DIR.'/daemon/daemon.pid')) {
|
||||
echo "Not running\n";
|
||||
return "notrunning";
|
||||
for ($i = 0; ($pid = $this->getRunningPid()) && $i < 5; $i++) {
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
$pid = trim(file_get_contents(PHPCI_DIR.'/daemon/daemon.pid'));
|
||||
$pidcheck = sprintf("/proc/%s", $pid);
|
||||
if (is_dir($pidcheck)) {
|
||||
echo "Running\n";
|
||||
if ($pid) {
|
||||
$this->logger->warning("The daemon is resiting, trying to kill it", array('pid' => $pid));
|
||||
$this->processControl->kill($pid, true);
|
||||
|
||||
for ($i = 0; ($pid = $this->getRunningPid()) && $i < 5; $i++) {
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$pid) {
|
||||
$this->logger->notice("Daemon stopped");
|
||||
return "stopped";
|
||||
}
|
||||
|
||||
$this->logger->error("Could not stop the daemon");
|
||||
}
|
||||
|
||||
protected function statusDaemon(OutputInterface $output)
|
||||
{
|
||||
$pid = $this->getRunningPid();
|
||||
if ($pid) {
|
||||
$output->writeln(sprintf('The daemon is running, PID: %d', $pid));
|
||||
return "running";
|
||||
}
|
||||
|
||||
unlink(PHPCI_DIR.'/daemon/daemon.pid');
|
||||
echo "Not running\n";
|
||||
$output->writeln('The daemon is not running');
|
||||
return "notrunning";
|
||||
}
|
||||
|
||||
/** Check if there is a running daemon
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
protected function getRunningPid()
|
||||
{
|
||||
if (!file_exists($this->pidFilePath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$pid = intval(trim(file_get_contents($this->pidFilePath)));
|
||||
|
||||
if($this->processControl->isRunning($pid, true)) {
|
||||
return $pid;
|
||||
}
|
||||
|
||||
// Not found, remove the stale PID file
|
||||
unlink($this->pidFilePath);
|
||||
}
|
||||
}
|
||||
|
|
63
PHPCI/ProcessControl/Factory.php
Normal file
63
PHPCI/ProcessControl/Factory.php
Normal file
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 2015, Block 8 Limited.
|
||||
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||
* @link https://www.phptesting.org/
|
||||
*/
|
||||
|
||||
namespace PHPCI\ProcessControl;
|
||||
|
||||
/**
|
||||
* Construct an appropriate ProcessControl instance.
|
||||
*
|
||||
* @author Adirelle <adirelle@gmail.com>
|
||||
*/
|
||||
class Factory
|
||||
{
|
||||
/**
|
||||
* ProcessControl singleton.
|
||||
*
|
||||
* @var ProcessControlInterface
|
||||
*/
|
||||
protected static $instance = null;
|
||||
|
||||
/**
|
||||
* Returns the ProcessControl singleton.
|
||||
*
|
||||
* @return ProcessControlInterface
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (static::$instance === null) {
|
||||
static::$instance = static::createProcessControl();
|
||||
}
|
||||
return static::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ProcessControl depending on available extensions and the underlying OS.
|
||||
*
|
||||
* Check PosixProcessControl, WindowsProcessControl and UnixProcessControl, in that order.
|
||||
*
|
||||
* @return ProcessControlInterface
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function createProcessControl()
|
||||
{
|
||||
switch(true) {
|
||||
case PosixProcessControl::isAvailable():
|
||||
return new PosixProcessControl();
|
||||
|
||||
case WindowsProcessControl::isAvailable():
|
||||
return new WindowsProcessControl();
|
||||
|
||||
case UnixProcessControl::isAvailable():
|
||||
return new UnixProcessControl();
|
||||
}
|
||||
|
||||
throw new \Exception("No ProcessControl implementation available.");
|
||||
}
|
||||
}
|
52
PHPCI/ProcessControl/PosixProcessControl.php
Normal file
52
PHPCI/ProcessControl/PosixProcessControl.php
Normal file
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 2015, Block 8 Limited.
|
||||
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||
* @link https://www.phptesting.org/
|
||||
*/
|
||||
|
||||
namespace PHPCI\ProcessControl;
|
||||
|
||||
/**
|
||||
* Control process using the POSIX extension.
|
||||
*
|
||||
* @author Adirelle <adirelle@gmail.com>
|
||||
*/
|
||||
class PosixProcessControl implements ProcessControlInterface
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @param int $pid
|
||||
* @return bool
|
||||
*/
|
||||
public function isRunning($pid)
|
||||
{
|
||||
// Signal "0" is not sent to the process, but posix_kill checks the process anyway;
|
||||
return posix_kill($pid, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a TERMINATE or KILL signal to the process using posix_kill.
|
||||
*
|
||||
* @param int $pid
|
||||
* @param bool $forcefully Whetehr to send TERMINATE (false) or KILL (true).
|
||||
*/
|
||||
public function kill($pid, $forcefully = false)
|
||||
{
|
||||
posix_kill($pid, $forcefully ? 9 : 15);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this posix_kill is available.
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function isAvailable()
|
||||
{
|
||||
return function_exists('posix_kill');
|
||||
}
|
||||
}
|
33
PHPCI/ProcessControl/ProcessControlInterface.php
Normal file
33
PHPCI/ProcessControl/ProcessControlInterface.php
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 2015, Block 8 Limited.
|
||||
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||
* @link https://www.phptesting.org/
|
||||
*/
|
||||
|
||||
namespace PHPCI\ProcessControl;
|
||||
|
||||
/**
|
||||
* A stateless service to check and kill system processes.
|
||||
*
|
||||
* @author Adirelle <adirelle@gmail.com>
|
||||
*/
|
||||
interface ProcessControlInterface
|
||||
{
|
||||
/** Checks if a process exists.
|
||||
*
|
||||
* @param int $pid The process identifier.
|
||||
*
|
||||
* @return boolean true is the process is running, else false.
|
||||
*/
|
||||
public function isRunning($pid);
|
||||
|
||||
/** Terminate a running process.
|
||||
*
|
||||
* @param int $pid The process identifier.
|
||||
* @param bool $forcefully Whether to gently (false) or forcefully (true) terminate the process.
|
||||
*/
|
||||
public function kill($pid, $forcefully = false);
|
||||
}
|
54
PHPCI/ProcessControl/UnixProcessControl.php
Normal file
54
PHPCI/ProcessControl/UnixProcessControl.php
Normal file
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 2015, Block 8 Limited.
|
||||
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||
* @link https://www.phptesting.org/
|
||||
*/
|
||||
|
||||
namespace PHPCI\ProcessControl;
|
||||
|
||||
/**
|
||||
* Control processes using the "ps" and "kill" commands.
|
||||
*
|
||||
* @author Adirelle <adirelle@gmail.com>
|
||||
*/
|
||||
class UnixProcessControl implements ProcessControlInterface
|
||||
{
|
||||
/**
|
||||
* Check process using the "ps" command.
|
||||
*
|
||||
* @param int $pid
|
||||
* @return boolean
|
||||
*/
|
||||
public function isRunning($pid)
|
||||
{
|
||||
$output = $exitCode = null;
|
||||
exec(sprintf("ps %d", $pid), $output, $exitCode);
|
||||
return $exitCode === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a signal using the "kill" command.
|
||||
*
|
||||
* @param int $pid
|
||||
* @param bool $forcefully
|
||||
*/
|
||||
public function kill($pid, $forcefully = false)
|
||||
{
|
||||
exec(sprintf("kill -%d %d", $forcefully ? 9 : 15, $pid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the commands "ps" and "kill" are available.
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function isAvailable()
|
||||
{
|
||||
return DIRECTORY_SEPARATOR === '/' && exec("which ps") && exec("which kill");
|
||||
}
|
||||
}
|
54
PHPCI/ProcessControl/WindowsProcessControl.php
Normal file
54
PHPCI/ProcessControl/WindowsProcessControl.php
Normal file
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 2015, Block 8 Limited.
|
||||
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||
* @link https://www.phptesting.org/
|
||||
*/
|
||||
|
||||
namespace PHPCI\ProcessControl;
|
||||
|
||||
/**
|
||||
* Control processes using the "tasklist" and "taskkill" commands.
|
||||
*
|
||||
* @author Adirelle <adirelle@gmail.com>
|
||||
*/
|
||||
class WindowsProcessControl implements ProcessControlInterface
|
||||
{
|
||||
/**
|
||||
* Check if the process is running using the "tasklist" command.
|
||||
*
|
||||
* @param type $pid
|
||||
* @return bool
|
||||
*/
|
||||
public function isRunning($pid)
|
||||
{
|
||||
$lastLine = exec(sprintf('tasklist /fi "PID eq %d" /nh /fo csv 2>nul:', $pid));
|
||||
$record = str_getcsv($lastLine);
|
||||
return isset($record[1]) && intval($record[1]) === $pid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminate the process using the "taskkill" command.
|
||||
*
|
||||
* @param type $pid
|
||||
* @param bool $forcefully
|
||||
*/
|
||||
public function kill($pid, $forcefully = false)
|
||||
{
|
||||
exec(sprintf("taskkill /t /pid %d %s 2>nul:", $pid, $forcefully ? '/f' : ''));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the commands "tasklist" and "taskkill" are available.
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function isAvailable()
|
||||
{
|
||||
return DIRECTORY_SEPARATOR === '\\' && exec("where tasklist") && exec("where taskkill");
|
||||
}
|
||||
}
|
17
Tests/PHPCI/ProcessControl/PosixProcessControlTest.php
Normal file
17
Tests/PHPCI/ProcessControl/PosixProcessControlTest.php
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
namespace Tests\PHPCI\ProcessControl;
|
||||
|
||||
use PHPCI\ProcessControl\PosixProcessControl;
|
||||
|
||||
class PosixProcessControlTest extends UnixProcessControlTest
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
$this->object = new PosixProcessControl();
|
||||
}
|
||||
|
||||
public function testIsAvailable()
|
||||
{
|
||||
$this->assertEquals(function_exists('posix_kill'), PosixProcessControl::isAvailable());
|
||||
}
|
||||
}
|
126
Tests/PHPCI/ProcessControl/ProcessControlTest.php
Normal file
126
Tests/PHPCI/ProcessControl/ProcessControlTest.php
Normal file
|
@ -0,0 +1,126 @@
|
|||
<?php
|
||||
namespace Tests\PHPCI\ProcessControl;
|
||||
|
||||
/**
|
||||
* Some helpers to
|
||||
*/
|
||||
abstract class ProcessControlTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var type
|
||||
*/
|
||||
protected $process;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $pipes;
|
||||
|
||||
/**
|
||||
* @var \PHPCI\ProcessControl\ProcessControlInterface
|
||||
*/
|
||||
protected $object;
|
||||
|
||||
/** Starts a process.
|
||||
*
|
||||
* @return int The PID of the process.
|
||||
*/
|
||||
protected function startProcess()
|
||||
{
|
||||
$desc = array(array("pipe", "r"), array("pipe", "w"), array("pipe", "w"));
|
||||
$this->pipes = array();
|
||||
|
||||
$this->process = proc_open($this->getTestCommand(), $desc, $this->pipes);
|
||||
usleep(500);
|
||||
|
||||
$this->assertTrue(is_resource($this->process));
|
||||
$this->assertTrue($this->isRunning());
|
||||
|
||||
$status = proc_get_status($this->process);
|
||||
return $status['pid'];
|
||||
}
|
||||
|
||||
/** End the running process.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function endProcess()
|
||||
{
|
||||
if (!is_resource($this->process)) {
|
||||
return;
|
||||
}
|
||||
array_map('fclose', $this->pipes);
|
||||
$exitCode = proc_close($this->process);
|
||||
$this->assertFalse($this->isRunning());
|
||||
$this->process = null;
|
||||
return $exitCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function isRunning()
|
||||
{
|
||||
if (!is_resource($this->process)) {
|
||||
return false;
|
||||
}
|
||||
$status = proc_get_status($this->process);
|
||||
return $status['running'];
|
||||
}
|
||||
|
||||
public function testIsRunning()
|
||||
{
|
||||
if (!$this->object->isAvailable()) {
|
||||
$this->markTestSkipped();
|
||||
}
|
||||
|
||||
$pid = $this->startProcess();
|
||||
|
||||
$this->assertTrue($this->object->isRunning($pid));
|
||||
|
||||
fwrite($this->pipes[0], PHP_EOL);
|
||||
|
||||
$exitCode = $this->endProcess();
|
||||
|
||||
$this->assertEquals(0, $exitCode);
|
||||
$this->assertFalse($this->object->isRunning($pid));
|
||||
}
|
||||
|
||||
public function testSoftKill()
|
||||
{
|
||||
if (!$this->object->isAvailable()) {
|
||||
$this->markTestSkipped();
|
||||
}
|
||||
|
||||
$pid = $this->startProcess();
|
||||
|
||||
$this->object->kill($pid);
|
||||
usleep(500);
|
||||
|
||||
$this->assertFalse($this->isRunning());
|
||||
}
|
||||
|
||||
public function testForcefullyKill()
|
||||
{
|
||||
if (!$this->object->isAvailable()) {
|
||||
$this->markTestSkipped();
|
||||
}
|
||||
|
||||
$pid = $this->startProcess();
|
||||
|
||||
$this->object->kill($pid, true);
|
||||
usleep(500);
|
||||
|
||||
$this->assertFalse($this->isRunning());
|
||||
}
|
||||
|
||||
abstract public function testIsAvailable();
|
||||
|
||||
abstract public function getTestCommand();
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
$this->endProcess();
|
||||
}
|
||||
}
|
22
Tests/PHPCI/ProcessControl/UnixProcessControlTest.php
Normal file
22
Tests/PHPCI/ProcessControl/UnixProcessControlTest.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
namespace Tests\PHPCI\ProcessControl;
|
||||
|
||||
use PHPCI\ProcessControl\UnixProcessControl;
|
||||
|
||||
class UnixProcessControlTest extends ProcessControlTest
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
$this->object = new UnixProcessControl();
|
||||
}
|
||||
|
||||
public function getTestCommand()
|
||||
{
|
||||
return "read SOMETHING";
|
||||
}
|
||||
|
||||
public function testIsAvailable()
|
||||
{
|
||||
$this->assertEquals(DIRECTORY_SEPARATOR === '/', UnixProcessControl::isAvailable());
|
||||
}
|
||||
}
|
22
Tests/PHPCI/ProcessControl/WindowsProcessControlTest.php
Normal file
22
Tests/PHPCI/ProcessControl/WindowsProcessControlTest.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
namespace Tests\PHPCI\ProcessControl;
|
||||
|
||||
use PHPCI\ProcessControl\WindowsProcessControl;
|
||||
|
||||
class WindowsProcessControlTest extends ProcessControlTest
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
$this->object = new WindowsProcessControl;
|
||||
}
|
||||
|
||||
public function getTestCommand()
|
||||
{
|
||||
return "pause";
|
||||
}
|
||||
|
||||
public function testIsAvailable()
|
||||
{
|
||||
$this->assertEquals(DIRECTORY_SEPARATOR === '\\', WindowsProcessControl::isAvailable());
|
||||
}
|
||||
}
|
|
@ -28,6 +28,12 @@
|
|||
}
|
||||
},
|
||||
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Tests\\PHPCI\\": "Tests/PHPCI/"
|
||||
}
|
||||
},
|
||||
|
||||
"require": {
|
||||
"php": ">=5.3.8",
|
||||
"ext-pdo": "*",
|
||||
|
|
Loading…
Reference in a new issue