Passed
Pull Request — master (#48)
by
unknown
20:54
created

Phiremock::getOutputCallable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
nc 1
nop 0
1
<?php
2
/**
3
 * This file is part of phiremock-codeception-extension.
4
 *
5
 * phiremock-codeception-extension is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU Lesser General Public License as published by
7
 * the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * phiremock-codeception-extension is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with phiremock-codeception-extension.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18
19
namespace Codeception\Extension;
20
21
use Codeception\Event\SuiteEvent;
22
use Codeception\Exception\ConfigurationException;
23
use Codeception\Extension as CodeceptionExtension;
24
use Codeception\Suite;
25
use Mcustiel\Phiremock\Client\Connection\Host;
0 ignored issues
show
Bug introduced by
The type Mcustiel\Phiremock\Client\Connection\Host was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
26
use Mcustiel\Phiremock\Client\Connection\Port;
0 ignored issues
show
Bug introduced by
The type Mcustiel\Phiremock\Client\Connection\Port was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
27
use Mcustiel\Phiremock\Client\Connection\Scheme;
0 ignored issues
show
Bug introduced by
The type Mcustiel\Phiremock\Client\Connection\Scheme was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
28
use Mcustiel\Phiremock\Client\Factory;
0 ignored issues
show
Bug introduced by
The type Mcustiel\Phiremock\Client\Factory was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
29
use Mcustiel\Phiremock\Codeception\Extension\Config;
30
use Mcustiel\Phiremock\Codeception\Extension\PhiremockProcessManager;
31
32
class Phiremock extends CodeceptionExtension
33
{
34
    /** @var array */
35
    public static $events = [
36
        'suite.before' => 'startProcess',
37
        'suite.after'  => 'stopProcess',
38
    ];
39
40
    /** @var array */
41
    protected $config = Config::DEFAULT_CONFIG;
42
43
    /** @var PhiremockProcessManager */
44
    private $process;
45
46
    /** @var Config */
47
    private $extensionConfig;
48
49
    /**  @throws ConfigurationException */
50
    public function __construct(
51
        array $config,
52
        array $options,
53
        PhiremockProcessManager $process = null
54
    ) {
55
        $this->setDefaultLogsPath();
56
        parent::__construct($config, $options);
57
        $this->extensionConfig = new Config($this->config, $this->getOutputCallable());
58
        $this->initProcess($process);
59
    }
60
61
    public function startProcess(SuiteEvent $event): void
62
    {
63
        $this->writeln('Starting default phiremock instance...');
64
        $suite = $event->getSuite();
65
        if ($this->mustRunForSuite($suite, $this->extensionConfig->getSuites())) {
66
            $this->process->start($this->extensionConfig);
67
        }
68
        foreach ($this->extensionConfig->getExtraInstances() as $configInstance) {
69
            if ($this->mustRunForSuite($suite, $configInstance->getSuites())) {
70
                $this->writeln('Starting extra phiremock instance...');
71
                $this->process->start($configInstance);
72
            }
73
        }
74
        $this->executeDelay();
75
        $this->waitUntilReady();
76
    }
77
78
    public function stopProcess(): void
79
    {
80
        $this->writeln('Stopping phiremock...');
81
        $this->process->stop();
82
    }
83
84
    public function getOutputCallable(): callable
85
    {
86
        return function (string $message) {
87
            $this->writeln($message);
88
        };
89
    }
90
91
    private function mustRunForSuite(Suite $suite, array $allowedSuites): bool
92
    {
93
        return empty($allowedSuites) || in_array($suite->getBaseName(), $allowedSuites, true);
94
    }
95
96
    private function executeDelay(): void
97
    {
98
        $delay = $this->extensionConfig->getDelay();
99
        if ($delay > 0) {
100
            sleep($delay);
101
        }
102
    }
103
104
    private function initProcess(?PhiremockProcessManager $process): void
105
    {
106
        $this->process = $process ?? new PhiremockProcessManager($this->getOutputCallable());
107
    }
108
109
    /** @throws ConfigurationException */
110
    private function setDefaultLogsPath(): void
111
    {
112
        if (!isset($this->config['logs_path'])) {
113
            $this->config['logs_path'] = Config::getDefaultLogsPath();
114
        }
115
    }
116
117
    private function waitUntilReady(): void
118
    {
119
        if (!$this->extensionConfig->isWaitUntilReady()) {
120
            return;
121
        }
122
123
        $this->writeln('Waiting until Phiremock is ready...');
124
        $client = Factory::createDefault()
125
            ->createPhiremockClient(
126
                new Host($this->extensionConfig->getInterface()),
127
                new Port($this->extensionConfig->getPort()),
128
                $this->extensionConfig->isSecure() ? Scheme::createHttps() : Scheme::createHttp()
129
            );
130
131
        $start = \microtime(true);
132
133
        while (true) {
134
            try {
135
                $client->reset();
136
                break;
137
            } catch (\Throwable $e) {
138
                \sleep(1);
139
            }
140
141
            $elapsed = (int) (\microtime(true) - $start);
142
143
            if ($elapsed > $this->extensionConfig->getWaitUntilReadyTimeout()) {
144
                throw new \RuntimeException(
145
                    \sprintf('Phiremock failed to start within %d seconds', $this->extensionConfig->getWaitUntilReadyTimeout())
146
                );
147
            }
148
        }
149
150
        $this->writeln('Phiremock is ready!');
151
    }
152
}
153