-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Expand file tree
/
Copy pathRunProcess.php
More file actions
143 lines (130 loc) · 3.96 KB
/
Copy pathRunProcess.php
File metadata and controls
143 lines (130 loc) · 3.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
<?php
declare(strict_types=1);
namespace Codeception\Extension;
use BadMethodCallException;
use Codeception\Events;
use Codeception\Exception\ExtensionException;
use Codeception\Extension;
use Symfony\Component\Process\Process;
use function array_reverse;
use function class_exists;
use function is_int;
use function sleep;
/**
* Extension to start and stop processes per suite.
* Can be used to start/stop selenium server, chromedriver, etc.
* Each command is executed only once, at the beginning of the test suite. To execute a command before each test, see [Before/After Attributes](https://codeception.com/docs/AdvancedUsage#BeforeAfter-Attributes).
*
* Can be enabled in suite config:
*
* ```yaml
* # Acceptance.suite.yml
* extensions:
* enabled:
* - Codeception\Extension\RunProcess:
* - chromedriver
* ```
*
* Multiple parameters can be passed as array:
*
* ```yaml
* # Acceptance.suite.yml
* extensions:
* enabled:
* - Codeception\Extension\RunProcess:
* - php -S 127.0.0.1:8000 -t tests/data/app
* - java -jar ~/selenium-server.jar
* ```
*
* In the end of a suite all launched processes will be stopped.
*
* To wait for the process to be launched use the `sleep` option. In this case you need configuration to be specified as object:
*
* ```yaml
* extensions:
* enabled:
* - Codeception\Extension\RunProcess:
* 0: php -S 127.0.0.1:8000 -t tests/data/app
* 1: java -jar ~/selenium-server.jar
* sleep: 5 # wait 5 seconds for the processes to boot
* ```
*
* HINT: You can use different configurations per environment.
*/
class RunProcess extends Extension
{
/**
* @var array<int|string, mixed>
*/
protected array $config = ['sleep' => 0];
/**
* @var array<string, string>
*/
protected static array $events = [
Events::SUITE_BEFORE => 'runProcess',
Events::SUITE_AFTER => 'stopProcess'
];
/**
* @var Process[]
*/
private array $processes = [];
public function _initialize(): void
{
if (!class_exists(Process::class)) {
throw new ExtensionException($this, 'symfony/process package is required');
}
}
public function runProcess(): void
{
$this->processes = [];
foreach ($this->config as $key => $command) {
if (!$command) {
continue;
}
if (!is_int($key)) {
continue; // configuration options
}
$process = Process::fromShellCommandline($command, $this->getRootDir(), null, null, null);
$process->start();
$this->processes[] = $process;
$this->output->debug('[RunProcess] Starting ' . $command);
}
sleep($this->config['sleep']);
}
public function __destruct()
{
$this->stopProcess();
}
public function stopProcess(): void
{
foreach (array_reverse($this->processes) as $process) {
/** @var Process $process */
if (!$process->isRunning()) {
continue;
}
$this->output->debug('[RunProcess] Stopping ' . $process->getCommandLine());
$process->stop();
}
$this->processes = [];
}
/**
* Disable the deserialization of the class to prevent attacker executing
* code by leveraging the __destruct method.
*
* @see https://owasp.org/www-community/vulnerabilities/PHP_Object_Injection
*/
public function __sleep()
{
throw new BadMethodCallException('Cannot serialize ' . self::class);
}
/**
* Disable the deserialization of the class to prevent attacker executing
* code by leveraging the __destruct method.
*
* @see https://owasp.org/www-community/vulnerabilities/PHP_Object_Injection
*/
public function __wakeup()
{
throw new BadMethodCallException('Cannot unserialize ' . self::class);
}
}