Skip to content

Commit 9a8e78c

Browse files
committed
cs
1 parent 3cc5b46 commit 9a8e78c

File tree

2 files changed

+79
-50
lines changed

2 files changed

+79
-50
lines changed

src/Framework/TestRunner.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
*/
1010
namespace PHPUnit\Framework;
1111

12-
use PHPUnit\TestRunner\TestResult\PassedTests;
13-
use PHPUnit\Util\PHP\PcntlFork;
1412
use const PHP_EOL;
1513
use function assert;
1614
use function class_exists;
@@ -35,6 +33,7 @@
3533
use PHPUnit\TextUI\Configuration\Registry as ConfigurationRegistry;
3634
use PHPUnit\Util\GlobalState;
3735
use PHPUnit\Util\PHP\AbstractPhpProcess;
36+
use PHPUnit\Util\PHP\PcntlFork;
3837
use ReflectionClass;
3938
use SebastianBergmann\CodeCoverage\Exception as OriginalCodeCoverageException;
4039
use SebastianBergmann\CodeCoverage\InvalidArgumentException;
@@ -255,8 +254,9 @@ public function runInSeparateProcess(TestCase $test, bool $runEntireClass, bool
255254
if (PcntlFork::isPcntlForkAvailable()) {
256255
// forking the parent process is a more lightweight way to run a test in isolation.
257256
// it requires the pcntl extension though.
258-
$fork = new PcntlFork();
257+
$fork = new PcntlFork;
259258
$fork->runTest($test);
259+
260260
return;
261261
}
262262

src/Util/PHP/PcntlFork.php

+76-47
Original file line numberDiff line numberDiff line change
@@ -9,35 +9,62 @@
99
*/
1010
namespace PHPUnit\Util\PHP;
1111

12+
use function array_key_exists;
13+
use function array_values;
14+
use function function_exists;
15+
use function hrtime;
16+
use function ini_get;
17+
use function is_array;
18+
use function pack;
19+
use function pcntl_fork;
20+
use function serialize;
21+
use function socket_close;
22+
use function socket_create_pair;
23+
use function socket_last_error;
24+
use function socket_read;
25+
use function socket_strerror;
26+
use function socket_write;
27+
use function str_contains;
28+
use function strlen;
29+
use function strtoupper;
30+
use function substr;
31+
use function unpack;
32+
use function unserialize;
33+
use Exception;
1234
use PHPUnit\Event\Facade;
35+
use PHPUnit\Event\Telemetry\HRTime;
1336
use PHPUnit\Framework\TestCase;
1437
use PHPUnit\Runner\CodeCoverage;
1538
use PHPUnit\TestRunner\TestResult\PassedTests;
39+
use RuntimeException;
1640

17-
final class PcntlFork {
41+
final class PcntlFork
42+
{
1843
// IPC inspired from https://github.com/barracudanetworks/forkdaemon-php
1944
private const SOCKET_HEADER_SIZE = 4;
2045

21-
static public function isPcntlForkAvailable(): bool {
46+
public static function isPcntlForkAvailable(): bool
47+
{
2248
$disabledFunctions = ini_get('disable_functions');
2349

2450
return
25-
function_exists('pcntl_fork')
26-
&& !str_contains($disabledFunctions, 'pcntl')
27-
&& function_exists('socket_create_pair')
28-
&& !str_contains($disabledFunctions, 'socket')
29-
;
51+
function_exists('pcntl_fork') &&
52+
!str_contains($disabledFunctions, 'pcntl') &&
53+
function_exists('socket_create_pair') &&
54+
!str_contains($disabledFunctions, 'socket');
3055
}
3156

3257
public function runTest(TestCase $test): void
3358
{
34-
list($socket_child, $socket_parent) = $this->ipcInit();
59+
[$socket_child, $socket_parent] = $this->ipcInit();
3560

3661
$pid = pcntl_fork();
3762

38-
if ($pid === -1 ) {
39-
throw new \Exception('could not fork');
40-
} else if ($pid) {
63+
if ($pid === -1) {
64+
throw new Exception('could not fork');
65+
}
66+
67+
if ($pid) {
4168
// we are the parent
4269

4370
socket_close($socket_parent);
@@ -47,6 +74,7 @@ public function runTest(TestCase $test): void
4774

4875
$stderr = '';
4976
$stdout = '';
77+
5078
if (is_array($result) && array_key_exists('error', $result)) {
5179
$stderr = $result['error'];
5280
} else {
@@ -61,19 +89,21 @@ public function runTest(TestCase $test): void
6189

6290
socket_close($socket_child);
6391

64-
$offset = hrtime();
92+
$offset = hrtime();
6593
$dispatcher = Facade::instance()->initForIsolation(
66-
\PHPUnit\Event\Telemetry\HRTime::fromSecondsAndNanoseconds(
94+
HRTime::fromSecondsAndNanoseconds(
6795
$offset[0],
68-
$offset[1]
69-
)
96+
$offset[1],
97+
),
7098
);
7199

72100
$test->setInIsolation(true);
101+
73102
try {
74103
$test->run();
75104
} catch (Throwable $e) {
76105
$this->socketSend($socket_parent, ['error' => $e->getMessage()]);
106+
77107
exit();
78108
}
79109

@@ -84,12 +114,13 @@ public function runTest(TestCase $test): void
84114
'numAssertions' => $test->numberOfAssertionsPerformed(),
85115
'output' => !$test->expectsOutput() ? $test->output() : '',
86116
'events' => $dispatcher->flush(),
87-
'passedTests' => PassedTests::instance()
88-
]
117+
'passedTests' => PassedTests::instance(),
118+
],
89119
);
90120

91121
// send result into parent
92122
$this->socketSend($socket_parent, $result);
123+
93124
exit();
94125
}
95126
}
@@ -100,10 +131,10 @@ private function ipcInit(): array
100131
$domain = strtoupper(substr(PHP_OS, 0, 3)) == 'WIN' ? AF_INET : AF_UNIX;
101132

102133
// create a socket pair for IPC
103-
$sockets = array();
104-
if (socket_create_pair($domain, SOCK_STREAM, 0, $sockets) === false)
105-
{
106-
throw new \RuntimeException('socket_create_pair failed: ' . socket_strerror(socket_last_error()));
134+
$sockets = [];
135+
136+
if (socket_create_pair($domain, SOCK_STREAM, 0, $sockets) === false) {
137+
throw new RuntimeException('socket_create_pair failed: ' . socket_strerror(socket_last_error()));
107138
}
108139

109140
return $sockets;
@@ -116,32 +147,30 @@ private function socketReceive($socket): mixed
116147
{
117148
// initially read to the length of the header size, then
118149
// expand to read more
119-
$bytes_total = self::SOCKET_HEADER_SIZE;
120-
$bytes_read = 0;
121-
$have_header = false;
150+
$bytes_total = self::SOCKET_HEADER_SIZE;
151+
$bytes_read = 0;
152+
$have_header = false;
122153
$socket_message = '';
123-
while ($bytes_read < $bytes_total)
124-
{
154+
155+
while ($bytes_read < $bytes_total) {
125156
$read = @socket_read($socket, $bytes_total - $bytes_read);
126-
if ($read === false)
127-
{
128-
throw new \RuntimeException('socket_receive error: ' . socket_strerror(socket_last_error()));
157+
158+
if ($read === false) {
159+
throw new RuntimeException('socket_receive error: ' . socket_strerror(socket_last_error()));
129160
}
130161

131162
// blank socket_read means done
132-
if ($read == '')
133-
{
163+
if ($read == '') {
134164
break;
135165
}
136166

137167
$bytes_read += strlen($read);
138168
$socket_message .= $read;
139169

140-
if (!$have_header && $bytes_read >= self::SOCKET_HEADER_SIZE)
141-
{
142-
$have_header = true;
143-
list($bytes_total) = array_values(unpack('N', $socket_message));
144-
$bytes_read = 0;
170+
if (!$have_header && $bytes_read >= self::SOCKET_HEADER_SIZE) {
171+
$have_header = true;
172+
[$bytes_total] = array_values(unpack('N', $socket_message));
173+
$bytes_read = 0;
145174
$socket_message = '';
146175
}
147176
}
@@ -151,25 +180,25 @@ private function socketReceive($socket): mixed
151180

152181
/**
153182
* @param resource $socket
154-
* @param mixed $message
183+
* @param mixed $message
155184
*/
156185
private function socketSend($socket, $message): void
157186
{
158187
$serialized_message = @serialize($message);
159-
if ($serialized_message == false)
160-
{
161-
throw new \RuntimeException('socket_send failed to serialize message');
188+
189+
if ($serialized_message == false) {
190+
throw new RuntimeException('socket_send failed to serialize message');
162191
}
163192

164-
$header = pack('N', strlen($serialized_message));
165-
$data = $header . $serialized_message;
193+
$header = pack('N', strlen($serialized_message));
194+
$data = $header . $serialized_message;
166195
$bytes_left = strlen($data);
167-
while ($bytes_left > 0)
168-
{
196+
197+
while ($bytes_left > 0) {
169198
$bytes_sent = @socket_write($socket, $data);
170-
if ($bytes_sent === false)
171-
{
172-
throw new \RuntimeException('socket_send failed to write to socket');
199+
200+
if ($bytes_sent === false) {
201+
throw new RuntimeException('socket_send failed to write to socket');
173202
}
174203

175204
$bytes_left -= $bytes_sent;

0 commit comments

Comments
 (0)