Skip to content

Commit 59b5b1d

Browse files
committed
wire annotations
1 parent 50def38 commit 59b5b1d

7 files changed

+151
-5
lines changed

src/Framework/Attributes/RunClassInSeparateProcess.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
{
2222
private ?bool $forkIfPossible;
2323

24-
public function __construct(bool $forkIfPossible = null)
24+
public function __construct(?bool $forkIfPossible = null)
2525
{
2626
$this->forkIfPossible = $forkIfPossible;
2727
}

src/Framework/TestBuilder.php

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
use PHPUnit\Metadata\ExcludeStaticPropertyFromBackup;
2020
use PHPUnit\Metadata\Parser\Registry as MetadataRegistry;
2121
use PHPUnit\Metadata\PreserveGlobalState;
22+
use PHPUnit\Metadata\RunClassInSeparateProcess;
23+
use PHPUnit\Metadata\RunInSeparateProcess;
24+
use PHPUnit\Metadata\RunTestsInSeparateProcesses;
2225
use PHPUnit\TextUI\Configuration\Registry as ConfigurationRegistry;
2326
use ReflectionClass;
2427

@@ -51,6 +54,7 @@ public function build(ReflectionClass $theClass, string $methodName, array $grou
5154
$this->shouldTestMethodBeRunInSeparateProcess($className, $methodName),
5255
$this->shouldGlobalStateBePreserved($className, $methodName),
5356
$this->shouldAllTestMethodsOfTestClassBeRunInSingleSeparateProcess($className),
57+
$this->shouldForkIfPossible($className, $methodName),
5458
$this->backupSettings($className, $methodName),
5559
$groups,
5660
);
@@ -64,6 +68,7 @@ public function build(ReflectionClass $theClass, string $methodName, array $grou
6468
$this->shouldTestMethodBeRunInSeparateProcess($className, $methodName),
6569
$this->shouldGlobalStateBePreserved($className, $methodName),
6670
$this->shouldAllTestMethodsOfTestClassBeRunInSingleSeparateProcess($className),
71+
$this->shouldForkIfPossible($className, $methodName),
6772
$this->backupSettings($className, $methodName),
6873
);
6974

@@ -76,7 +81,7 @@ public function build(ReflectionClass $theClass, string $methodName, array $grou
7681
* @psalm-param array{backupGlobals: ?bool, backupGlobalsExcludeList: list<string>, backupStaticProperties: ?bool, backupStaticPropertiesExcludeList: array<string,list<string>>} $backupSettings
7782
* @psalm-param list<non-empty-string> $groups
7883
*/
79-
private function buildDataProviderTestSuite(string $methodName, string $className, array $data, bool $runTestInSeparateProcess, ?bool $preserveGlobalState, bool $runClassInSeparateProcess, array $backupSettings, array $groups): DataProviderTestSuite
84+
private function buildDataProviderTestSuite(string $methodName, string $className, array $data, bool $runTestInSeparateProcess, ?bool $preserveGlobalState, bool $runClassInSeparateProcess, bool $forkIfPossible, array $backupSettings, array $groups): DataProviderTestSuite
8085
{
8186
$dataProviderTestSuite = DataProviderTestSuite::empty(
8287
$className . '::' . $methodName,
@@ -98,6 +103,7 @@ private function buildDataProviderTestSuite(string $methodName, string $classNam
98103
$runTestInSeparateProcess,
99104
$preserveGlobalState,
100105
$runClassInSeparateProcess,
106+
$forkIfPossible,
101107
$backupSettings,
102108
);
103109

@@ -110,7 +116,7 @@ private function buildDataProviderTestSuite(string $methodName, string $classNam
110116
/**
111117
* @psalm-param array{backupGlobals: ?bool, backupGlobalsExcludeList: list<string>, backupStaticProperties: ?bool, backupStaticPropertiesExcludeList: array<string,list<string>>} $backupSettings
112118
*/
113-
private function configureTestCase(TestCase $test, bool $runTestInSeparateProcess, ?bool $preserveGlobalState, bool $runClassInSeparateProcess, array $backupSettings): void
119+
private function configureTestCase(TestCase $test, bool $runTestInSeparateProcess, ?bool $preserveGlobalState, bool $runClassInSeparateProcess, bool $forkIfPossible, array $backupSettings): void
114120
{
115121
if ($runTestInSeparateProcess) {
116122
$test->setRunTestInSeparateProcess(true);
@@ -120,6 +126,10 @@ private function configureTestCase(TestCase $test, bool $runTestInSeparateProces
120126
$test->setRunClassInSeparateProcess(true);
121127
}
122128

129+
if ($forkIfPossible) {
130+
$test->setForkIfPossible(true);
131+
}
132+
123133
if ($preserveGlobalState !== null) {
124134
$test->setPreserveGlobalState($preserveGlobalState);
125135
}
@@ -272,4 +282,53 @@ private function shouldAllTestMethodsOfTestClassBeRunInSingleSeparateProcess(str
272282
{
273283
return MetadataRegistry::parser()->forClass($className)->isRunClassInSeparateProcess()->isNotEmpty();
274284
}
285+
286+
/**
287+
* @psalm-param class-string $className
288+
* @psalm-param non-empty-string $methodName
289+
*/
290+
private function shouldForkIfPossible(string $className, string $methodName): bool
291+
{
292+
$metadataForMethod = MetadataRegistry::parser()->forMethod($className, $methodName);
293+
294+
if ($metadataForMethod->isRunInSeparateProcess()->isNotEmpty()) {
295+
$metadata = $metadataForMethod->isRunInSeparateProcess()->asArray()[0];
296+
297+
assert($metadata instanceof RunInSeparateProcess);
298+
299+
$forkIfPossible = $metadata->forkIfPossible();
300+
301+
if ($forkIfPossible !== null) {
302+
return $forkIfPossible;
303+
}
304+
}
305+
306+
$metadataForClass = MetadataRegistry::parser()->forClass($className);
307+
308+
if ($metadataForClass->isRunTestsInSeparateProcesses()->isNotEmpty()) {
309+
$metadata = $metadataForClass->isRunTestsInSeparateProcesses()->asArray()[0];
310+
311+
assert($metadata instanceof RunTestsInSeparateProcesses);
312+
313+
$forkIfPossible = $metadata->forkIfPossible();
314+
315+
if ($forkIfPossible !== null) {
316+
return $forkIfPossible;
317+
}
318+
}
319+
320+
if ($metadataForClass->isRunClassInSeparateProcess()->isNotEmpty()) {
321+
$metadata = $metadataForClass->isRunClassInSeparateProcess()->asArray()[0];
322+
323+
assert($metadata instanceof RunClassInSeparateProcess);
324+
325+
$forkIfPossible = $metadata->forkIfPossible();
326+
327+
if ($forkIfPossible !== null) {
328+
return $forkIfPossible;
329+
}
330+
}
331+
332+
return false;
333+
}
275334
}

src/Framework/TestCase.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ abstract class TestCase extends Assert implements Reorderable, SelfDescribing, T
142142
*/
143143
private ?array $backupGlobalExceptionHandlers = null;
144144
private ?bool $runClassInSeparateProcess = null;
145+
private ?bool $forkIfPossible = null;
145146
private ?bool $runTestInSeparateProcess = null;
146147
private bool $preserveGlobalState = false;
147148
private bool $inIsolation = false;
@@ -340,6 +341,7 @@ final public function run(): void
340341
$this,
341342
$this->runClassInSeparateProcess && !$this->runTestInSeparateProcess,
342343
$this->preserveGlobalState,
344+
$this->forkIfPossible === true,
343345
);
344346
}
345347
}
@@ -709,6 +711,14 @@ final public function setRunClassInSeparateProcess(bool $runClassInSeparateProce
709711
$this->runClassInSeparateProcess = $runClassInSeparateProcess;
710712
}
711713

714+
/**
715+
* @internal This method is not covered by the backward compatibility promise for PHPUnit
716+
*/
717+
final public function setForkIfPossible(bool $forkIfPossible): void
718+
{
719+
$this->forkIfPossible = $forkIfPossible;
720+
}
721+
712722
/**
713723
* @internal This method is not covered by the backward compatibility promise for PHPUnit
714724
*/

src/Framework/TestRunner.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,9 +249,9 @@ public function run(TestCase $test): void
249249
* @throws ProcessIsolationException
250250
* @throws StaticAnalysisCacheNotConfiguredException
251251
*/
252-
public function runInSeparateProcess(TestCase $test, bool $runEntireClass, bool $preserveGlobalState): void
252+
public function runInSeparateProcess(TestCase $test, bool $runEntireClass, bool $preserveGlobalState, bool $forkIfPossible): void
253253
{
254-
if (PcntlFork::isPcntlForkAvailable()) {
254+
if ($forkIfPossible && PcntlFork::isPcntlForkAvailable()) {
255255
// forking the parent process is a more lightweight way to run a test in isolation.
256256
// it requires the pcntl extension though.
257257
$fork = new PcntlFork;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* This file is part of PHPUnit.
4+
*
5+
* (c) Sebastian Bergmann <[email protected]>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
namespace PHPUnit\TestFixture\Metadata\Attribute;
11+
12+
use PHPUnit\Framework\Attributes\RunClassInSeparateProcess;
13+
use PHPUnit\Framework\Attributes\RunInSeparateProcess;
14+
use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
15+
use PHPUnit\Framework\TestCase;
16+
17+
#[RunClassInSeparateProcess(true)]
18+
#[RunTestsInSeparateProcesses]
19+
final class ProcessIsolationForkedTest extends TestCase
20+
{
21+
#[RunInSeparateProcess]
22+
public function testOne(): void
23+
{
24+
}
25+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* This file is part of PHPUnit.
4+
*
5+
* (c) Sebastian Bergmann <[email protected]>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
namespace PHPUnit\TestFixture\TestBuilder;
11+
12+
use PHPUnit\Framework\Attributes\BackupGlobals;
13+
use PHPUnit\Framework\Attributes\BackupStaticProperties;
14+
use PHPUnit\Framework\Attributes\RunClassInSeparateProcess;
15+
use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
16+
use PHPUnit\Framework\TestCase;
17+
18+
#[BackupGlobals(true)]
19+
#[BackupStaticProperties(true)]
20+
#[RunClassInSeparateProcess]
21+
#[RunTestsInSeparateProcesses(true)]
22+
final class TestWithClassLevelIsolationAttributesForked extends TestCase
23+
{
24+
public function testOne(): void
25+
{
26+
}
27+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* This file is part of PHPUnit.
4+
*
5+
* (c) Sebastian Bergmann <[email protected]>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
namespace PHPUnit\TestFixture\TestBuilder;
11+
12+
use PHPUnit\Framework\Attributes\BackupGlobals;
13+
use PHPUnit\Framework\Attributes\BackupStaticProperties;
14+
use PHPUnit\Framework\Attributes\RunInSeparateProcess;
15+
use PHPUnit\Framework\TestCase;
16+
17+
final class TestWithMethodLevelIsolationAttributes extends TestCase
18+
{
19+
#[BackupGlobals(true)]
20+
#[BackupStaticProperties(true)]
21+
#[RunInSeparateProcess(true)]
22+
public function testOne(): void
23+
{
24+
}
25+
}

0 commit comments

Comments
 (0)