Passed
Push — v7 ( ecaaea...ac44be )
by Georges
01:41
created

TestHelper::runSubProcess()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 1
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 *
4
 * This file is part of phpFastCache.
5
 *
6
 * @license MIT License (MIT)
7
 *
8
 * For full copyright and license information, please see the docs/CREDITS.txt file.
9
 *
10
 * @author Khoa Bui (khoaofgod)  <[email protected]> http://www.phpfastcache.com
11
 * @author Georges.L (Geolim4)  <[email protected]>
12
 *
13
 */
14
declare(strict_types=1);
15
16
namespace Phpfastcache\Helper;
17
18
use Phpfastcache\Api;
19
use Phpfastcache\Exceptions\PhpfastcacheDriverCheckException;
20
21
/**
22
 * Class TestHelper
23
 * @package phpFastCache\Helper
24
 */
25
class TestHelper
26
{
27
    /**
28
     * @var int
29
     */
30
    protected $exitCode = 0;
31
32
    /**
33
     * @var int
34
     */
35
    protected $timestamp;
36
37
    /**
38
     * TestHelper constructor.
39
     * @param $testName
40
     */
41
    public function __construct($testName)
42
    {
43
        $this->timestamp = microtime(true);
44
        $this->printText('[PhpFastCache CORE v' . Api::getPhpFastCacheVersion() . Api::getPhpFastCacheGitHeadHash() . ']', true);
45
        $this->printText('[PhpFastCache API v' . Api::getVersion() . ']', true);
46
        $this->printText('[PHP v' . PHP_VERSION . ']', true);
47
        $this->printText("[Begin Test: '{$testName}']");
48
        $this->printText('---');
49
50
        /**
51
         * Catch all uncaught exception
52
         * to our own exception handler
53
         */
54
        set_exception_handler([$this, 'exceptionHandler']);
55
        set_error_handler([$this, 'errorHandler']);
56
    }
57
58
    /**
59
     * @return int
60
     */
61
    public function getExitCode(): int
62
    {
63
        return $this->exitCode;
64
    }
65
66
    /**
67
     * @return $this
68
     */
69
    public function resetExitCode(): self
70
    {
71
        $this->exitCode = 0;
72
73
        return $this;
74
    }
75
76
    /**
77
     * @param string $string
78
     * @return $this
79
     */
80
    public function printSkipText($string): self
81
    {
82
        $this->printText("[SKIP] {$string}");
83
84
        return $this;
85
    }
86
87
    /**
88
     * @param string $string
89
     * @return $this
90
     */
91
    public function printPassText($string): self
92
    {
93
        $this->printText("[PASS] {$string}");
94
95
        return $this;
96
    }
97
98
    /**
99
     * @param string printFailText
0 ignored issues
show
Bug introduced by
The type Phpfastcache\Helper\printFailText 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...
100
     * @return $this
101
     */
102
    public function printInfoText($string): self
103
    {
104
        $this->printText("[INFO] {$string}");
105
106
        return $this;
107
    }
108
109
    /**
110
     * @param string $string
111
     * @return $this
112
     */
113
    public function printDebugText($string): self
114
    {
115
        $this->printText("[DEBUG] {$string}");
116
117
        return $this;
118
    }
119
120
    /**
121
     * @param string $string
122
     * @return $this
123
     */
124
    public function printNoteText($string): self
125
    {
126
        $this->printText("[NOTE] {$string}");
127
128
        return $this;
129
    }
130
131
    /**
132
     * @param string $string
133
     * @return $this
134
     */
135
    public function printFailText($string): self
136
    {
137
        $this->printText("[FAIL] {$string}");
138
        $this->exitCode = 1;
139
140
        return $this;
141
    }
142
143
    /**
144
     * @param int $count
145
     * @return $this
146
     */
147
    public function printNewLine($count = 1): self
148
    {
149
        for ($i = 0; $i < $count; $i++) {
150
            print PHP_EOL;
151
        }
152
153
        return $this;
154
    }
155
156
    /**
157
     * @param $string
158
     * @param bool $strtoupper
159
     * @return $this
160
     */
161
    public function printText($string, $strtoupper = false): self
162
    {
163
        if (!$strtoupper) {
164
            print \trim($string) . PHP_EOL;
165
        } else {
166
            print strtoupper(\trim($string) . PHP_EOL);
167
        }
168
169
        return $this;
170
    }
171
172
    /**
173
     * @param string $cmd
174
     */
175
    public function runAsyncProcess($cmd)
176
    {
177
        if (\substr(php_uname(), 0, 7) === 'Windows') {
178
            pclose(popen('start /B ' . $cmd, 'r'));
0 ignored issues
show
Bug introduced by
It seems like popen('start /B ' . $cmd, 'r') can also be of type false; however, parameter $handle of pclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

178
            pclose(/** @scrutinizer ignore-type */ popen('start /B ' . $cmd, 'r'));
Loading history...
179
        } else {
180
            exec($cmd . ' > /dev/null &');
181
        }
182
    }
183
184
    /**
185
     * @param string $file
186
     * @param string $ext
187
     */
188
    public function runSubProcess($file, $ext = '.php')
189
    {
190
        $this->runAsyncProcess(($this->isHHVM() ? 'hhvm ' : 'php ') . getcwd() . DIRECTORY_SEPARATOR . 'subprocess' . DIRECTORY_SEPARATOR . $file . '.subprocess' . $ext);
191
    }
192
193
    /**
194
     * @return void
195
     */
196
    public function terminateTest()
197
    {
198
        $execTime = round(microtime(true) - $this->timestamp, 3);
199
200
        $this->printText('Test finished in ' . $execTime . 's');
201
        exit($this->exitCode);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
202
    }
203
204
    /**
205
     * @return bool
206
     */
207
    public function isHHVM(): bool
208
    {
209
        return \defined('HHVM_VERSION');
210
    }
211
212
    /**
213
     * @param $obj
214
     * @param $prop
215
     * @return mixed
216
     * @throws \ReflectionException
217
     */
218
    public function accessInaccessibleMember($obj, $prop)
219
    {
220
        $reflection = new \ReflectionClass($obj);
221
        $property = $reflection->getProperty($prop);
222
        $property->setAccessible(true);
223
        return $property->getValue($obj);
224
    }
225
226
    /**
227
     * @param \Throwable $exception
228
     */
229
    public function exceptionHandler(\Throwable $exception)
230
    {
231
        if ($exception instanceof PhpfastcacheDriverCheckException) {
232
            $this->printSkipText('A driver could not be initialized due to missing requirement: ' . $exception->getMessage());
233
        } else {
234
            $this->printFailText(\sprintf(
235
              'Uncaught exception "%s" in "%s" line %d with message: "%s"',
236
              \get_class($exception),
237
              $exception->getFile(),
238
              $exception->getLine(),
239
              $exception->getMessage()
240
            ));
241
        }
242
        $this->terminateTest();
243
    }
244
245
    /**
246
     * @param int $errno
247
     * @param string $errstr
248
     * @param string $errfile
249
     * @param int $errline
250
     */
251
    public function errorHandler(int $errno, string $errstr, string $errfile, int $errline)
252
    {
253
        $errorType = '';
254
255
        switch ($errno) {
256
            case E_PARSE:
257
            case E_ERROR:
258
            case E_CORE_ERROR:
259
            case E_COMPILE_ERROR:
260
            case E_USER_ERROR:
261
                $errorType = '[FATAL ERROR]';
262
                break;
263
            case E_WARNING:
264
            case E_USER_WARNING:
265
            case E_COMPILE_WARNING:
266
            case E_RECOVERABLE_ERROR:
267
                $errorType = '[WARNING]';
268
                break;
269
            case E_NOTICE:
270
            case E_USER_NOTICE:
271
                $errorType = '[NOTICE]';
272
                break;
273
            case E_STRICT:
274
                $errorType = '[STRICT]';
275
                break;
276
            case E_DEPRECATED:
277
            case E_USER_DEPRECATED:
278
                $errorType = '[DEPRECATED]';
279
                break;
280
            default :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a DEFAULT statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in the default statement.

switch ($expr) {
    default : //wrong
        doSomething();
        break;
}

switch ($expr) {
    default: //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
281
                break;
282
        }
283
284
        if ($errorType === '[FATAL ERROR]') {
285
            $this->printFailText(\sprintf(
286
              "A critical error has been caught: \"%s\" in %s line %d",
287
              "$errorType $errstr",
288
              $errfile,
289
              $errline
290
            ));
291
        } else {
292
            $this->printDebugText(\sprintf(
293
              "A non-critical error has been caught: \"%s\" in %s line %d",
294
              "$errorType $errstr",
295
              $errfile,
296
              $errline
297
            ));
298
        }
299
    }
300
}