Skip to content

Commit 301cecb

Browse files
committed
Fix TearDownProcess can be started
1 parent b6357f1 commit 301cecb

File tree

13 files changed

+158
-57
lines changed

13 files changed

+158
-57
lines changed

config/ci/phpstan.neon

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ parameters:
1010
- '#Method Steevanb\\ParallelProcess\\Tests\\Console\\Output\\TestOutput::write\(\) has parameter \$messages with no value type specified in iterable type iterable.#'
1111
# I can't remove this phpstan error because of the bad typehint of Symfony
1212
- '#Method Steevanb\\ParallelProcess\\Tests\\Console\\Output\\TestOutput::writeln\(\) has parameter \$messages with no value type specified in iterable type iterable.#'
13+
# To be compatible with Symfony Console 6.3, who require int|false as return type insteand of void for olver versions
14+
-
15+
message: '#Return type \(void\) of method Steevanb\\ParallelProcess\\Console\\Application\\ParallelProcessesApplication::handleSignal\(\) should be compatible with return type \(int\|false\) of method Symfony\\Component\\Console\\Command\\SignalableCommandInterface::handleSignal\(\)#'
16+
reportUnmatched: false
1317
includes:
1418
- ../../vendor/steevanb/php-typed-array/bridge/Phpstan/rules.neon
1519
- /composer/common/vendor/phpstan/phpstan-deprecation-rules/rules.neon

src/Console/Application/ParallelProcessesApplication.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,6 @@ protected function runProcessesInParallel(InputInterface $input, OutputInterface
196196

197197
protected function configureBootstrapProcesses(): static
198198
{
199-
$standardProcesses = $this->getStandardProcesses();
200-
201199
$bootstrapProcesses = new ProcessInterfaceArray();
202200
foreach ($this->getProcesses()->toArray() as $process) {
203201
if ($process instanceof BootstrapProcessInterface) {
@@ -206,6 +204,7 @@ protected function configureBootstrapProcesses(): static
206204
}
207205
$bootstrapProcesses->setReadOnly();
208206

207+
$standardProcesses = $this->getStandardProcesses();
209208
foreach ($bootstrapProcesses->toArray() as $bootstrapProcess) {
210209
foreach ($standardProcesses->toArray() as $standardProcess) {
211210
$standardProcess->getStartCondition()->addProcessSuccessful($bootstrapProcess);
@@ -217,8 +216,6 @@ protected function configureBootstrapProcesses(): static
217216

218217
protected function configureTearDownProcesses(): static
219218
{
220-
$standardProcesses = $this->getStandardProcesses();
221-
222219
$tearDownProcesses = new ProcessInterfaceArray();
223220
foreach ($this->getProcesses()->toArray() as $process) {
224221
if ($process instanceof TearDownProcessInterface) {
@@ -227,6 +224,7 @@ protected function configureTearDownProcesses(): static
227224
}
228225
$tearDownProcesses->setReadOnly();
229226

227+
$standardProcesses = $this->getStandardProcesses();
230228
foreach ($tearDownProcesses->toArray() as $tearDownProcess) {
231229
foreach ($standardProcesses->toArray() as $standardProcess) {
232230
$tearDownProcess->getStartCondition()->addProcessTerminated($standardProcess);

src/Process/Process.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public function __construct(
5050
parent::__construct($command, $cwd, $env, $input, $timeout);
5151

5252
$this->setName(basename($command[0]));
53-
$this->startCondition = new StartCondition();
53+
$this->startCondition = new StartCondition($this);
5454
}
5555

5656
public function setName(string $name): static

src/Process/StartCondition.php

Lines changed: 56 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class StartCondition
1212

1313
protected ProcessInterfaceArray $processesFailed;
1414

15-
public function __construct()
15+
public function __construct(protected readonly ProcessInterface $process)
1616
{
1717
$this->processesTerminated = (new ProcessInterfaceArray())->setReadOnly();
1818
$this->processesSuccessful = (new ProcessInterfaceArray())->setReadOnly();
@@ -23,7 +23,7 @@ public function addProcessTerminated(Process $process): static
2323
{
2424
$this->processesTerminated->setReadOnly(false);
2525
$this->processesTerminated[] = $process;
26-
$this->processesTerminated->setReadOnly(true);
26+
$this->processesTerminated->setReadOnly();
2727

2828
return $this;
2929
}
@@ -37,7 +37,7 @@ public function addProcessSuccessful(Process $process): static
3737
{
3838
$this->processesSuccessful->setReadOnly(false);
3939
$this->processesSuccessful[] = $process;
40-
$this->processesSuccessful->setReadOnly(true);
40+
$this->processesSuccessful->setReadOnly();
4141

4242
return $this;
4343
}
@@ -51,7 +51,7 @@ public function addProcessFailed(Process $process): static
5151
{
5252
$this->processesFailed->setReadOnly(false);
5353
$this->processesFailed[] = $process;
54-
$this->processesFailed->setReadOnly(true);
54+
$this->processesFailed->setReadOnly();
5555

5656
return $this;
5757
}
@@ -70,6 +70,46 @@ public function hasConditions(): bool
7070
}
7171

7272
public function canBeStarted(): bool
73+
{
74+
if ($this->process instanceof TearDownProcess) {
75+
$return = $this->tearDownProcessCanBeStarted();
76+
} else {
77+
$return = $this->standardProcessCanBeStarted();
78+
}
79+
80+
return $return;
81+
}
82+
83+
public function isCanceled(): bool
84+
{
85+
$return = false;
86+
87+
foreach ($this->getProcessesSuccessful()->toArray() as $successfulProcess) {
88+
if (
89+
($successfulProcess->isTerminated() && $successfulProcess->isSuccessful() === false)
90+
|| $successfulProcess->isCanceled()
91+
) {
92+
$return = true;
93+
break;
94+
}
95+
}
96+
97+
if ($return === false) {
98+
foreach ($this->getProcessesFailed()->toArray() as $failedProcess) {
99+
if (
100+
($failedProcess->isTerminated() && $failedProcess->isSuccessful())
101+
|| $failedProcess->isCanceled()
102+
) {
103+
$return = true;
104+
break;
105+
}
106+
}
107+
}
108+
109+
return $return;
110+
}
111+
112+
protected function standardProcessCanBeStarted(): bool
73113
{
74114
$return = true;
75115

@@ -101,32 +141,24 @@ public function canBeStarted(): bool
101141
return $return;
102142
}
103143

104-
public function isCanceled(): bool
144+
protected function tearDownProcessCanBeStarted(): bool
105145
{
106-
$return = false;
146+
$processes = new ProcessInterfaceArray(
147+
array_merge(
148+
$this->getProcessesSuccessful()->toArray(),
149+
$this->getProcessesTerminated()->toArray(),
150+
$this->getProcessesFailed()->toArray(),
151+
)
152+
);
107153

108-
foreach ($this->getProcessesSuccessful()->toArray() as $successfulProcess) {
109-
if (
110-
($successfulProcess->isTerminated() && $successfulProcess->isSuccessful() === false)
111-
|| $successfulProcess->isCanceled()
112-
) {
113-
$return = true;
154+
$return = true;
155+
foreach ($processes->toArray() as $process) {
156+
if ($process->isTerminated() === false && $process->isCanceled() === false) {
157+
$return = false;
114158
break;
115159
}
116160
}
117161

118-
if ($return === false) {
119-
foreach ($this->getProcessesFailed()->toArray() as $failedProcess) {
120-
if (
121-
($failedProcess->isTerminated() && $failedProcess->isSuccessful())
122-
|| $failedProcess->isCanceled()
123-
) {
124-
$return = true;
125-
break;
126-
}
127-
}
128-
}
129-
130162
return $return;
131163
}
132164
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Steevanb\ParallelProcess\Tests\Console\Application\ParallelProcessesApplication;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use Steevanb\ParallelProcess\{
9+
Console\Application\ParallelProcessesApplication,
10+
Process\Process,
11+
Process\TearDownProcess
12+
};
13+
use Symfony\Component\Console\{
14+
Input\ArrayInput,
15+
Output\NullOutput
16+
};
17+
18+
/** @coversNothing */
19+
final class AllUseCasesTest extends TestCase
20+
{
21+
public function testAllUseCases(): void
22+
{
23+
$rootDir = dirname(__DIR__, 4);
24+
25+
$process1 = new Process(['pwd'], $rootDir);
26+
27+
$process2 = new Process(['commandNotFound'], $rootDir);
28+
$process2->getStartCondition()->addProcessSuccessful($process1);
29+
30+
$process3 = new Process(['pwd'], $rootDir);
31+
$process3->getStartCondition()->addProcessSuccessful($process2);
32+
33+
$process4 = new Process(['pwd'], $rootDir);
34+
$process4->getStartCondition()->addProcessSuccessful($process3);
35+
36+
$tearDownProcess = new TearDownProcess(['pwd']);
37+
38+
$exitCode = (new ParallelProcessesApplication())
39+
->setRefreshInterval(100)
40+
->setAutoExit(false)
41+
->addProcess($process1)
42+
->addProcess($process2)
43+
->addProcess($process3)
44+
->addProcess($process4)
45+
->addProcess($tearDownProcess)
46+
->run(new ArrayInput([]), new NullOutput());
47+
48+
static::assertSame(1, $exitCode);
49+
50+
static::assertTrue($process1->isTerminated());
51+
static::assertTrue($process1->isSuccessful());
52+
53+
static::assertTrue($process2->isTerminated());
54+
static::assertFalse($process2->isSuccessful());
55+
56+
static::assertFalse($process3->isStarted());
57+
58+
static::assertFalse($process4->isStarted());
59+
60+
static::assertTrue($tearDownProcess->isTerminated());
61+
static::assertTrue($tearDownProcess->isSuccessful());
62+
}
63+
}

tests/Process/StartCondition/CanBeStartedTest.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ final class CanBeStartedTest extends TestCase
2424

2525
public function testCanBeStarted(): void
2626
{
27-
$startCondition = new StartCondition();
27+
$startCondition = new StartCondition($this->createLsProcess());
2828

2929
static::assertTrue($startCondition->canBeStarted());
3030
}
3131

3232
public function testHaveOneNotTerminated(): void
3333
{
34-
$startCondition = new StartCondition();
34+
$startCondition = new StartCondition($this->createLsProcess());
3535
$process = $this->createLsProcess();
3636
$startCondition->addProcessTerminated($process);
3737

@@ -41,7 +41,7 @@ public function testHaveOneNotTerminated(): void
4141

4242
public function testHaveOneTerminated(): void
4343
{
44-
$startCondition = new StartCondition();
44+
$startCondition = new StartCondition($this->createLsProcess());
4545
$process = $this->createLsProcess();
4646
$process->run();
4747
$startCondition->addProcessTerminated($process);
@@ -52,7 +52,7 @@ public function testHaveOneTerminated(): void
5252

5353
public function testHaveOneNotSuccessful(): void
5454
{
55-
$startCondition = new StartCondition();
55+
$startCondition = new StartCondition($this->createLsProcess());
5656
$process = $this->createLsProcess();
5757
$startCondition->addProcessSuccessful($process);
5858

@@ -62,7 +62,7 @@ public function testHaveOneNotSuccessful(): void
6262

6363
public function testHaveOneSuccessful(): void
6464
{
65-
$startCondition = new StartCondition();
65+
$startCondition = new StartCondition($this->createLsProcess());
6666
$process = $this->createLsProcess();
6767
$process->mustRun();
6868
$startCondition->addProcessSuccessful($process);
@@ -74,7 +74,7 @@ public function testHaveOneSuccessful(): void
7474

7575
public function testHaveOneNotFailed(): void
7676
{
77-
$startCondition = new StartCondition();
77+
$startCondition = new StartCondition($this->createLsProcess());
7878
$process = new Process(['unknown-command']);
7979
$startCondition->addProcessFailed($process);
8080

@@ -84,7 +84,7 @@ public function testHaveOneNotFailed(): void
8484

8585
public function testHaveOneFailed(): void
8686
{
87-
$startCondition = new StartCondition();
87+
$startCondition = new StartCondition($this->createLsProcess());
8888
$process = new Process(['unknown-command']);
8989
$process->run();
9090
$startCondition->addProcessFailed($process);

tests/Process/StartCondition/ConstructTest.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,19 @@
55
namespace Steevanb\ParallelProcess\Tests\Process\StartCondition;
66

77
use PHPUnit\Framework\TestCase;
8-
use Steevanb\ParallelProcess\Process\StartCondition;
8+
use Steevanb\ParallelProcess\{
9+
Process\StartCondition,
10+
Tests\CreateLsProcessTrait
11+
};
912

1013
/** @covers \Steevanb\ParallelProcess\Process\StartCondition::__construct */
1114
final class ConstructTest extends TestCase
1215
{
16+
use CreateLsProcessTrait;
17+
1318
public function testDefaultValues(): void
1419
{
15-
$startCondition = new StartCondition();
20+
$startCondition = new StartCondition($this->createLsProcess());
1621

1722
static::assertCount(0, $startCondition->getProcessesTerminated());
1823
static::assertTrue($startCondition->getProcessesTerminated()->isReadOnly());

tests/Process/StartCondition/HasConditionsTest.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ final class HasConditionsTest extends TestCase
2020

2121
public function testDontHave(): void
2222
{
23-
$startCondition = new StartCondition();
23+
$startCondition = new StartCondition($this->createLsProcess());
2424

2525
static::assertFalse($startCondition->hasConditions());
2626
}
2727

2828
public function testHaveOneTerminated(): void
2929
{
30-
$startCondition = new StartCondition();
30+
$startCondition = new StartCondition($this->createLsProcess());
3131
$process = $this->createLsProcess();
3232
$startCondition->addProcessTerminated($process);
3333

@@ -36,7 +36,7 @@ public function testHaveOneTerminated(): void
3636

3737
public function testHaveTwoTerminated(): void
3838
{
39-
$startCondition = new StartCondition();
39+
$startCondition = new StartCondition($this->createLsProcess());
4040
$process = $this->createLsProcess();
4141
$startCondition->addProcessTerminated($process);
4242
$startCondition->addProcessTerminated($process);
@@ -46,7 +46,7 @@ public function testHaveTwoTerminated(): void
4646

4747
public function testHaveOneSuccessful(): void
4848
{
49-
$startCondition = new StartCondition();
49+
$startCondition = new StartCondition($this->createLsProcess());
5050
$process = $this->createLsProcess();
5151
$startCondition->addProcessSuccessful($process);
5252

@@ -55,7 +55,7 @@ public function testHaveOneSuccessful(): void
5555

5656
public function testHaveTwoSuccessful(): void
5757
{
58-
$startCondition = new StartCondition();
58+
$startCondition = new StartCondition($this->createLsProcess());
5959
$process = $this->createLsProcess();
6060
$startCondition->addProcessSuccessful($process);
6161
$startCondition->addProcessSuccessful($process);
@@ -65,7 +65,7 @@ public function testHaveTwoSuccessful(): void
6565

6666
public function testHaveOneFailed(): void
6767
{
68-
$startCondition = new StartCondition();
68+
$startCondition = new StartCondition($this->createLsProcess());
6969
$process = $this->createLsProcess();
7070
$startCondition->addProcessFailed($process);
7171

@@ -74,7 +74,7 @@ public function testHaveOneFailed(): void
7474

7575
public function testHaveTwoFailed(): void
7676
{
77-
$startCondition = new StartCondition();
77+
$startCondition = new StartCondition($this->createLsProcess());
7878
$process = $this->createLsProcess();
7979
$startCondition->addProcessFailed($process);
8080
$startCondition->addProcessFailed($process);

0 commit comments

Comments
 (0)