Completed
Push — master ( 1a3a48...6e0e69 )
by Alessandro
09:39 queued 07:07
created

Runner::onProcessToBeRetried()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Paraunit\Runner;
6
7
use Paraunit\Filter\Filter;
8
use Paraunit\Lifecycle\EngineEvent;
9
use Paraunit\Lifecycle\ProcessEvent;
10
use Paraunit\Process\ProcessFactoryInterface;
11
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
12
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
13
14
/**
15
 * Class Runner
16
 * @package Paraunit\Runner
17
 */
18
class Runner implements EventSubscriberInterface
19
{
20
    /** @var ProcessFactoryInterface */
21
    private $processFactory;
22
23
    /** @var EventDispatcherInterface */
24
    private $eventDispatcher;
25
26
    /** @var Filter */
27
    private $filter;
28
29
    /** @var PipelineCollection */
30
    private $pipelineCollection;
31
32
    /** @var \SplQueue */
33
    private $queuedProcesses;
34
35
    /** @var int */
36
    private $exitCode;
37
38
    /**
39
     * @param EventDispatcherInterface $eventDispatcher
40
     * @param ProcessFactoryInterface $processFactory
41
     * @param Filter $filter
42
     * @param PipelineCollection $pipelineCollection
43
     */
44 39
    public function __construct(
45
        EventDispatcherInterface $eventDispatcher,
46
        ProcessFactoryInterface $processFactory,
47
        Filter $filter,
48
        PipelineCollection $pipelineCollection
49
    ) {
50 39
        $this->eventDispatcher = $eventDispatcher;
51 39
        $this->processFactory = $processFactory;
52 39
        $this->filter = $filter;
53 39
        $this->pipelineCollection = $pipelineCollection;
54 39
        $this->queuedProcesses = new \SplQueue();
55 39
        $this->exitCode = 0;
56
    }
57
58 64
    public static function getSubscribedEvents(): array
59
    {
60
        return [
61 64
            ProcessEvent::PROCESS_TERMINATED => 'pushToPipeline',
62 64
            ProcessEvent::PROCESS_TO_BE_RETRIED => 'onProcessToBeRetried',
63 64
            ProcessEvent::PROCESS_PARSING_COMPLETED => 'onProcessParsingCompleted',
64
        ];
65
    }
66
67
    /**
68
     * @return int The final exit code: 0 if no failures, 10 otherwise
69
     */
70 21
    public function run(): int
71
    {
72 21
        $this->eventDispatcher->dispatch(EngineEvent::BEFORE_START);
73
74 21
        $this->createProcessQueue();
75
76 21
        $this->eventDispatcher->dispatch(EngineEvent::START);
77
78
        do {
79 21
            $this->pushToPipeline();
80 21
            usleep(100);
81 21
            $this->pipelineCollection->triggerProcessTermination();
82 21
        } while (! $this->pipelineCollection->isEmpty() || ! $this->queuedProcesses->isEmpty());
83
84 21
        $this->eventDispatcher->dispatch(EngineEvent::END);
85
86 21
        return $this->exitCode;
87
    }
88
89
    /**
90
     * @param ProcessEvent $processEvent
91
     */
92 31
    public function onProcessParsingCompleted(ProcessEvent $processEvent)
93
    {
94 31
        if ($processEvent->getProcess()->getExitCode() !== 0) {
95 14
            $this->exitCode = 10;
96
        }
97
    }
98
99
    /**
100
     * @param ProcessEvent $processEvent
101
     */
102 7
    public function onProcessToBeRetried(ProcessEvent $processEvent)
103
    {
104 7
        $this->queuedProcesses->enqueue($processEvent->getProcess());
105
    }
106
107 21
    private function createProcessQueue()
108
    {
109 21
        foreach ($this->filter->filterTestFiles() as $file) {
110 20
            $this->queuedProcesses->enqueue(
111 20
                $this->processFactory->create($file)
112
            );
113
        }
114
    }
115
116 21
    public function pushToPipeline()
117
    {
118 21
        while (! $this->queuedProcesses->isEmpty() && $this->pipelineCollection->hasEmptySlots()) {
119 20
            $this->pipelineCollection->push($this->queuedProcesses->dequeue());
120
        }
121
    }
122
}
123