123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- <?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;
- }
- }
|