-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Expand file tree
/
Copy pathnew_oom.phpt
More file actions
113 lines (99 loc) · 2.83 KB
/
Copy pathnew_oom.phpt
File metadata and controls
113 lines (99 loc) · 2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
--TEST--
Test OOM on new of each instantiable class
--SKIPIF--
<?php
if (getenv("USE_ZEND_ALLOC") === "0") die("skip requires zmm");
if (getenv("SKIP_SLOW_TESTS")) die('skip slow test');
?>
--FILE--
<?php
function getOomProcessCount(): int
{
$processCount = PHP_OS_FAMILY === 'Windows'
? getenv('NUMBER_OF_PROCESSORS')
: shell_exec('getconf _NPROCESSORS_ONLN 2>/dev/null');
if (!is_string($processCount)) {
return 1;
}
$processCount = filter_var(trim($processCount), FILTER_VALIDATE_INT, [
'options' => ['min_range' => 1],
]);
return $processCount === false ? 1 : min($processCount, 4);
}
function startOomTest(string $php, string $file, string $class): ?array
{
$output = tmpfile();
if ($output === false) {
echo "Class $class failed\nUnable to create output file\n";
return null;
}
$process = proc_open(
[$php, '--no-php-ini', $file, $class],
[
0 => ['null'],
1 => $output,
2 => ['redirect', 1],
],
$pipes,
);
if (!is_resource($process)) {
fclose($output);
echo "Class $class failed\nUnable to start process\n";
return null;
}
return [
'class' => $class,
'output' => $output,
'process' => $process,
];
}
function finishOomTest(array $test): bool
{
$status = proc_get_status($test['process']);
if ($status['running']) {
return false;
}
proc_close($test['process']);
rewind($test['output']);
$output = stream_get_contents($test['output']);
fclose($test['output']);
if ($status['signaled']) {
echo "Class {$test['class']} failed\n";
echo "Process terminated by signal {$status['termsig']}\n";
} elseif ($output && preg_match('(^\nFatal error: Allowed memory size of [0-9]+ bytes exhausted[^\r\n]* \(tried to allocate [0-9]+ bytes\) in [^\r\n]+ on line [0-9]+\nStack trace:\n(#[0-9]+ [^\r\n]+\n)+$)', $output) !== 1) {
echo "Class {$test['class']} failed\n";
echo $output, "\n";
}
return true;
}
$file = __DIR__ . '/new_oom.inc';
$php = PHP_BINARY;
$classes = array_filter(
get_declared_classes(),
static fn(string $class): bool => (new ReflectionClass($class))->isInstantiable(),
);
$tests = [];
$processCount = getOomProcessCount();
while ($classes || $tests) {
while ($classes && count($tests) < $processCount) {
$class = array_shift($classes);
$test = startOomTest($php, $file, $class);
if ($test !== null) {
$tests[] = $test;
}
}
$testFinished = false;
foreach ($tests as $index => $test) {
if (finishOomTest($test)) {
unset($tests[$index]);
$testFinished = true;
}
}
if (!$testFinished) {
usleep(1000);
}
}
?>
===DONE===
--EXPECT--
===DONE===