|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Paraunit\Parser; |
|
4
|
|
|
|
|
5
|
|
|
use Paraunit\Process\ProcessWithResultsInterface; |
|
6
|
|
|
use Paraunit\Process\RetryAwareInterface; |
|
7
|
|
|
use Paraunit\TestResult\Interfaces\TestResultContainerInterface; |
|
8
|
|
|
use Paraunit\TestResult\MuteTestResult; |
|
9
|
|
|
use Paraunit\TestResult\TestResultFormat; |
|
10
|
|
|
|
|
11
|
|
|
/** |
|
12
|
|
|
* Class RetryParser |
|
13
|
|
|
* @package Paraunit\Parser |
|
14
|
|
|
*/ |
|
15
|
|
|
class RetryParser implements JSONParserChainElementInterface |
|
16
|
|
|
{ |
|
17
|
|
|
/** @var TestResultFormat */ |
|
18
|
|
|
private $testResultFormat; |
|
19
|
|
|
|
|
20
|
|
|
/** @var int */ |
|
21
|
|
|
private $maxRetryCount; |
|
22
|
|
|
|
|
23
|
|
|
/** @var string */ |
|
24
|
|
|
private $regexPattern; |
|
25
|
|
|
|
|
26
|
|
|
/** |
|
27
|
|
|
* RetryParser constructor. |
|
28
|
|
|
* @param TestResultFormat $testResultFormat |
|
29
|
|
|
* @param int $maxRetryCount |
|
30
|
|
|
*/ |
|
31
|
35 |
|
public function __construct(TestResultFormat $testResultFormat, $maxRetryCount = 3) |
|
32
|
|
|
{ |
|
33
|
35 |
|
$this->testResultFormat = $testResultFormat; |
|
34
|
35 |
|
$this->maxRetryCount = $maxRetryCount; |
|
35
|
|
|
|
|
36
|
|
|
$patterns = array( |
|
37
|
35 |
|
'The EntityManager is closed', |
|
38
|
|
|
// MySQL |
|
39
|
35 |
|
'Deadlock found', |
|
40
|
35 |
|
'Lock wait timeout exceeded', |
|
41
|
|
|
// SQLite |
|
42
|
35 |
|
'General error: 5 database is locked', |
|
43
|
35 |
|
); |
|
44
|
|
|
|
|
45
|
35 |
|
$this->regexPattern = $this->buildRegexPattern($patterns); |
|
46
|
35 |
|
} |
|
47
|
|
|
|
|
48
|
32 |
|
public function handleLogItem(ProcessWithResultsInterface $process, \stdClass $logItem) |
|
49
|
|
|
{ |
|
50
|
32 |
|
if ($this->isRetriable($process) && $this->isToBeRetried($logItem)) { |
|
51
|
|
|
/** @var RetryAwareInterface | TestResultContainerInterface $process */ |
|
52
|
7 |
|
$process->markAsToBeRetried(); |
|
53
|
|
|
|
|
54
|
7 |
|
return new MuteTestResult($this->testResultFormat); |
|
|
|
|
|
|
55
|
|
|
} |
|
56
|
|
|
|
|
57
|
28 |
|
return null; |
|
58
|
|
|
} |
|
59
|
|
|
|
|
60
|
|
|
/** |
|
61
|
|
|
* @param TestResultContainerInterface $process |
|
62
|
|
|
* @return bool |
|
63
|
|
|
*/ |
|
64
|
32 |
|
private function isRetriable(TestResultContainerInterface $process) |
|
65
|
|
|
{ |
|
66
|
32 |
|
return $process instanceof RetryAwareInterface && $process->getRetryCount() < $this->maxRetryCount; |
|
67
|
|
|
} |
|
68
|
|
|
|
|
69
|
|
|
/** |
|
70
|
|
|
* @param \stdClass $log |
|
71
|
|
|
* @return bool |
|
72
|
|
|
*/ |
|
73
|
31 |
|
private function isToBeRetried(\stdClass $log) |
|
74
|
|
|
{ |
|
75
|
31 |
|
return property_exists($log, 'status') && $log->status == 'error' && preg_match($this->regexPattern, $log->message); |
|
76
|
|
|
} |
|
77
|
|
|
|
|
78
|
|
|
/** |
|
79
|
|
|
* @param array | string[] $patterns |
|
80
|
|
|
* @return string |
|
81
|
|
|
*/ |
|
82
|
35 |
|
private function buildRegexPattern(array $patterns) |
|
83
|
|
|
{ |
|
84
|
35 |
|
$regex = implode('|', $patterns); |
|
85
|
|
|
|
|
86
|
35 |
|
return '/' . $regex . '/'; |
|
87
|
|
|
} |
|
88
|
|
|
} |
|
89
|
|
|
|
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignorePhpDoc annotation to the duplicate definition and it will be ignored.