RunProcess.php 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. <?php
  2. namespace Codeception\Extension;
  3. use Codeception\Events;
  4. use Codeception\Exception\ExtensionException;
  5. use Codeception\Extension;
  6. use Symfony\Component\Process\Process;
  7. /**
  8. * Extension to start and stop processes per suite.
  9. * Can be used to start/stop selenium server, chromedriver, phantomjs, mailcatcher, etc.
  10. *
  11. * Can be configured in suite config:
  12. *
  13. * ```yaml
  14. * # acceptance.suite.yml
  15. * extensions:
  16. * enabled:
  17. * - Codeception\Extension\RunProcess:
  18. * - chromedriver
  19. * ```
  20. *
  21. * Multiple parameters can be passed as array:
  22. *
  23. * ```yaml
  24. * # acceptance.suite.yml
  25. *
  26. * extensions:
  27. * enabled:
  28. * - Codeception\Extension\RunProcess:
  29. * - php -S 127.0.0.1:8000 -t tests/data/app
  30. * - java -jar ~/selenium-server.jar
  31. * ```
  32. *
  33. * In the end of a suite all launched processes will be stopped.
  34. *
  35. * To wait for the process to be launched use `sleep` option.
  36. * In this case you need configuration to be specified as object:
  37. *
  38. * ```yaml
  39. * extensions:
  40. * enabled:
  41. * - Codeception\Extension\RunProcess:
  42. * 0: java -jar ~/selenium-server.jar
  43. * 1: mailcatcher
  44. * sleep: 5 # wait 5 seconds for processes to boot
  45. * ```
  46. *
  47. * HINT: you can use different configurations per environment.
  48. */
  49. class RunProcess extends Extension
  50. {
  51. public $config = ['sleep' => 0];
  52. static $events = [
  53. Events::SUITE_BEFORE => 'runProcess',
  54. Events::SUITE_AFTER => 'stopProcess'
  55. ];
  56. protected $processes = [];
  57. public function _initialize()
  58. {
  59. if (!class_exists('Symfony\Component\Process\Process')) {
  60. throw new ExtensionException($this, 'symfony/process package is required');
  61. }
  62. }
  63. public function runProcess()
  64. {
  65. $this->processes = [];
  66. foreach ($this->config as $key => $command) {
  67. if (!$command) {
  68. continue;
  69. }
  70. if (!is_int($key)) {
  71. continue; // configuration options
  72. }
  73. $process = new Process($command, $this->getRootDir(), null, null, null);
  74. $process->start();
  75. $this->processes[] = $process;
  76. $this->output->debug('[RunProcess] Starting '.$command);
  77. }
  78. sleep($this->config['sleep']);
  79. }
  80. public function __destruct()
  81. {
  82. $this->stopProcess();
  83. }
  84. public function stopProcess()
  85. {
  86. foreach (array_reverse($this->processes) as $process) {
  87. /** @var $process Process **/
  88. if (!$process->isRunning()) {
  89. continue;
  90. }
  91. $this->output->debug('[RunProcess] Stopping ' . $process->getCommandLine());
  92. $process->stop();
  93. }
  94. $this->processes = [];
  95. }
  96. }