BiFace_Server_Lite/vendor/codeception/base/ext/RunBefore.php
2020-03-27 10:13:51 +07:00

146 lines
3.7 KiB
PHP

<?php
namespace Codeception\Extension;
use Codeception\Events;
use Codeception\Exception\ExtensionException;
use Codeception\Extension;
use Symfony\Component\Process\Process;
/**
* Extension for execution of some processes before running tests.
*
* Processes can be independent and dependent.
* Independent processes run independently of each other.
* Dependent processes run sequentially one by one.
*
* Can be configured in suite config:
*
* ```yaml
* # acceptance.suite.yml
* extensions:
* enabled:
* - Codeception\Extension\RunBefore:
* - independent_process_1
* -
* - dependent_process_1_1
* - dependent_process_1_2
* - independent_process_2
* -
* - dependent_process_2_1
* - dependent_process_2_2
* ```
*
* HINT: you can use different configurations per environment.
*/
class RunBefore extends Extension
{
protected $config = [];
protected static $events = [
Events::SUITE_BEFORE => 'runBefore'
];
/** @var array[] */
private $processes = [];
public function _initialize()
{
if (!class_exists('Symfony\Component\Process\Process')) {
throw new ExtensionException($this, 'symfony/process package is required');
}
}
public function runBefore()
{
$this->runProcesses();
$this->processMonitoring();
}
private function runProcesses()
{
foreach ($this->config as $item) {
if (is_array($item)) {
$currentCommand = array_shift($item);
$followingCommands = $item;
} else {
$currentCommand = $item;
$followingCommands = [];
}
$process = $this->runProcess($currentCommand);
$this->addProcessToMonitoring($process, $followingCommands);
}
}
/**
* @param string $command
* @return Process
*/
private function runProcess($command)
{
$this->output->debug('[RunBefore] Starting ' . $command);
$process = new Process($command, $this->getRootDir());
$process->start();
return $process;
}
/**
* @param string[] $followingCommands
*/
private function addProcessToMonitoring(Process $process, array $followingCommands)
{
$this->processes[] = [
'instance' => $process,
'following' => $followingCommands
];
}
/**
* @param int $index
*/
private function removeProcessFromMonitoring($index)
{
unset($this->processes[$index]);
}
private function processMonitoring()
{
while (count($this->processes) !== 0) {
$this->checkProcesses();
sleep(1);
}
}
private function checkProcesses()
{
foreach ($this->processes as $index => $process) {
if (!$this->isRunning($process['instance'])) {
$this->output->debug('[RunBefore] Completing ' . $process['instance']->getCommandLine());
$this->runFollowingCommand($process['following']);
$this->removeProcessFromMonitoring($index);
}
}
}
/**
* @param string[] $followingCommands
*/
private function runFollowingCommand(array $followingCommands)
{
if (count($followingCommands) > 0) {
$process = $this->runProcess(array_shift($followingCommands));
$this->addProcessToMonitoring($process, $followingCommands);
}
}
private function isRunning(Process $process)
{
if ($process->isRunning()) {
return true;
}
return false;
}
}