mirror of
https://github.com/php/php-src.git
synced 2025-08-16 14:08:47 +02:00
run-tests.php: class for test file loading
This moves a bunch of code outside of run_tests(), making it a bit more manageable. Additionally, accessors provide better readability than isset() and friends. This is a minimal patch that moves the code but does not refactor much. For the sake of reviewing experience, it does not involve further refactoring which could include: * Removing setSection() * Fixing up the mess with hasSection() vs. sectionNotEmpty(), only one of which is really needed. * Moving more repetitive code into the new class. All of this will be done with later commits. Closes GH-6678.
This commit is contained in:
parent
77ebf81492
commit
9140c9038a
1 changed files with 350 additions and 256 deletions
606
run-tests.php
606
run-tests.php
|
@ -1862,141 +1862,36 @@ TEST $file
|
||||||
";
|
";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the sections of the test file.
|
|
||||||
$section_text = ['TEST' => ''];
|
|
||||||
|
|
||||||
$fp = fopen($file, "rb") or error("Cannot open test file: $file");
|
|
||||||
|
|
||||||
$bork_info = null;
|
|
||||||
|
|
||||||
if (!feof($fp)) {
|
|
||||||
$line = fgets($fp);
|
|
||||||
|
|
||||||
if ($line === false) {
|
|
||||||
$bork_info = "cannot read test";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$bork_info = "empty test [$file]";
|
|
||||||
}
|
|
||||||
if ($bork_info === null && strncmp('--TEST--', $line, 8)) {
|
|
||||||
$bork_info = "tests must start with --TEST-- [$file]";
|
|
||||||
}
|
|
||||||
|
|
||||||
$section = 'TEST';
|
|
||||||
$secfile = false;
|
|
||||||
$secdone = false;
|
|
||||||
|
|
||||||
while (!feof($fp)) {
|
|
||||||
$line = fgets($fp);
|
|
||||||
|
|
||||||
if ($line === false) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match the beginning of a section.
|
|
||||||
if (preg_match('/^--([_A-Z]+)--/', $line, $r)) {
|
|
||||||
$section = (string) $r[1];
|
|
||||||
|
|
||||||
if (isset($section_text[$section]) && $section_text[$section]) {
|
|
||||||
$bork_info = "duplicated $section section";
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for unknown sections
|
|
||||||
if (!in_array($section, [
|
|
||||||
'EXPECT', 'EXPECTF', 'EXPECTREGEX', 'EXPECTREGEX_EXTERNAL', 'EXPECT_EXTERNAL', 'EXPECTF_EXTERNAL', 'EXPECTHEADERS',
|
|
||||||
'POST', 'POST_RAW', 'GZIP_POST', 'DEFLATE_POST', 'PUT', 'GET', 'COOKIE', 'ARGS',
|
|
||||||
'FILE', 'FILEEOF', 'FILE_EXTERNAL', 'REDIRECTTEST',
|
|
||||||
'CAPTURE_STDIO', 'STDIN', 'CGI', 'PHPDBG',
|
|
||||||
'INI', 'ENV', 'EXTENSIONS',
|
|
||||||
'SKIPIF', 'XFAIL', 'XLEAK', 'CLEAN',
|
|
||||||
'CREDITS', 'DESCRIPTION', 'CONFLICTS', 'WHITESPACE_SENSITIVE',
|
|
||||||
])) {
|
|
||||||
$bork_info = 'Unknown section "' . $section . '"';
|
|
||||||
}
|
|
||||||
|
|
||||||
$section_text[$section] = '';
|
|
||||||
$secfile = $section == 'FILE' || $section == 'FILEEOF' || $section == 'FILE_EXTERNAL';
|
|
||||||
$secdone = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add to the section text.
|
|
||||||
if (!$secdone) {
|
|
||||||
$section_text[$section] .= $line;
|
|
||||||
}
|
|
||||||
|
|
||||||
// End of actual test?
|
|
||||||
if ($secfile && preg_match('/^===DONE===\s*$/', $line)) {
|
|
||||||
$secdone = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$shortname = str_replace(TEST_PHP_SRCDIR . '/', '', $file);
|
$shortname = str_replace(TEST_PHP_SRCDIR . '/', '', $file);
|
||||||
$tested_file = $shortname;
|
$tested_file = $shortname;
|
||||||
$tested = trim($section_text['TEST']);
|
|
||||||
|
|
||||||
// the redirect section allows a set of tests to be reused outside of
|
try {
|
||||||
// a given test dir
|
$test = new TestFile($file, (bool)$IN_REDIRECT);
|
||||||
if ($bork_info === null) {
|
} catch (BorkageException $ex) {
|
||||||
if (isset($section_text['REDIRECTTEST'])) {
|
show_result("BORK", $ex->getMessage(), $tested_file);
|
||||||
if ($IN_REDIRECT) {
|
|
||||||
$bork_info = "Can't redirect a test from within a redirected test";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!isset($section_text['PHPDBG']) && isset($section_text['FILE']) + isset($section_text['FILEEOF']) + isset($section_text['FILE_EXTERNAL']) != 1) {
|
|
||||||
$bork_info = "missing section --FILE--";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($section_text['FILEEOF'])) {
|
|
||||||
$section_text['FILE'] = preg_replace("/[\r\n]+$/", '', $section_text['FILEEOF']);
|
|
||||||
unset($section_text['FILEEOF']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($num_repeats > 1 && isset($section_text['FILE_EXTERNAL'])) {
|
|
||||||
return skip_test($tested, $tested_file, $shortname, 'Test with FILE_EXTERNAL might not be repeatable');
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (['FILE', 'EXPECT', 'EXPECTF', 'EXPECTREGEX'] as $prefix) {
|
|
||||||
$key = $prefix . '_EXTERNAL';
|
|
||||||
|
|
||||||
if (isset($section_text[$key])) {
|
|
||||||
// don't allow tests to retrieve files from anywhere but this subdirectory
|
|
||||||
$section_text[$key] = dirname($file) . '/' . trim(str_replace('..', '', $section_text[$key]));
|
|
||||||
|
|
||||||
if (file_exists($section_text[$key])) {
|
|
||||||
$section_text[$prefix] = file_get_contents($section_text[$key]);
|
|
||||||
unset($section_text[$key]);
|
|
||||||
} else {
|
|
||||||
$bork_info = "could not load --" . $key . "-- " . dirname($file) . '/' . trim($section_text[$key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((isset($section_text['EXPECT']) + isset($section_text['EXPECTF']) + isset($section_text['EXPECTREGEX'])) != 1) {
|
|
||||||
$bork_info = "missing section --EXPECT--, --EXPECTF-- or --EXPECTREGEX--";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose($fp);
|
|
||||||
|
|
||||||
if ($bork_info !== null) {
|
|
||||||
show_result("BORK", $bork_info, $tested_file);
|
|
||||||
$PHP_FAILED_TESTS['BORKED'][] = [
|
$PHP_FAILED_TESTS['BORKED'][] = [
|
||||||
'name' => $file,
|
'name' => $file,
|
||||||
'test_name' => '',
|
'test_name' => '',
|
||||||
'output' => '',
|
'output' => '',
|
||||||
'diff' => '',
|
'diff' => '',
|
||||||
'info' => "$bork_info [$file]",
|
'info' => "{$ex->getMessage()} [$file]",
|
||||||
];
|
];
|
||||||
|
|
||||||
$junit->markTestAs('BORK', $shortname, $tested_file, 0, $bork_info);
|
$junit->markTestAs('BORK', $shortname, $tested_file, 0, $ex->getMessage());
|
||||||
return 'BORKED';
|
return 'BORKED';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($section_text['CAPTURE_STDIO'])) {
|
$tested = $test->getName();
|
||||||
$captureStdIn = stripos($section_text['CAPTURE_STDIO'], 'STDIN') !== false;
|
|
||||||
$captureStdOut = stripos($section_text['CAPTURE_STDIO'], 'STDOUT') !== false;
|
if ($num_repeats > 1 && $test->hasSection('FILE_EXTERNAL')) {
|
||||||
$captureStdErr = stripos($section_text['CAPTURE_STDIO'], 'STDERR') !== false;
|
return skip_test($tested, $tested_file, $shortname, 'Test with FILE_EXTERNAL might not be repeatable');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($test->hasSection('CAPTURE_STDIO')) {
|
||||||
|
$capture = $test->getSection('CAPTURE_STDIO');
|
||||||
|
$captureStdIn = stripos($capture, 'STDIN') !== false;
|
||||||
|
$captureStdOut = stripos($capture, 'STDOUT') !== false;
|
||||||
|
$captureStdErr = stripos($capture, 'STDERR') !== false;
|
||||||
} else {
|
} else {
|
||||||
$captureStdIn = true;
|
$captureStdIn = true;
|
||||||
$captureStdOut = true;
|
$captureStdOut = true;
|
||||||
|
@ -2009,7 +1904,7 @@ TEST $file
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For GET/POST/PUT tests, check if cgi sapi is available and if it is, use it. */
|
/* For GET/POST/PUT tests, check if cgi sapi is available and if it is, use it. */
|
||||||
if (array_key_exists('CGI', $section_text) || !empty($section_text['GET']) || !empty($section_text['POST']) || !empty($section_text['GZIP_POST']) || !empty($section_text['DEFLATE_POST']) || !empty($section_text['POST_RAW']) || !empty($section_text['PUT']) || !empty($section_text['COOKIE']) || !empty($section_text['EXPECTHEADERS'])) {
|
if ($test->isCGI()) {
|
||||||
if (!$php_cgi) {
|
if (!$php_cgi) {
|
||||||
return skip_test($tested, $tested_file, $shortname, 'CGI not available');
|
return skip_test($tested, $tested_file, $shortname, 'CGI not available');
|
||||||
}
|
}
|
||||||
|
@ -2022,11 +1917,7 @@ TEST $file
|
||||||
|
|
||||||
/* For phpdbg tests, check if phpdbg sapi is available and if it is, use it. */
|
/* For phpdbg tests, check if phpdbg sapi is available and if it is, use it. */
|
||||||
$extra_options = '';
|
$extra_options = '';
|
||||||
if (array_key_exists('PHPDBG', $section_text)) {
|
if ($test->hasSection('PHPDBG')) {
|
||||||
if (!isset($section_text['STDIN'])) {
|
|
||||||
$section_text['STDIN'] = $section_text['PHPDBG'] . "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($phpdbg)) {
|
if (isset($phpdbg)) {
|
||||||
$php = $phpdbg . ' -qIb';
|
$php = $phpdbg . ' -qIb';
|
||||||
|
|
||||||
|
@ -2042,13 +1933,13 @@ TEST $file
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($num_repeats > 1) {
|
if ($num_repeats > 1) {
|
||||||
if (array_key_exists('CLEAN', $section_text)) {
|
if ($test->hasSection('CLEAN')) {
|
||||||
return skip_test($tested, $tested_file, $shortname, 'Test with CLEAN might not be repeatable');
|
return skip_test($tested, $tested_file, $shortname, 'Test with CLEAN might not be repeatable');
|
||||||
}
|
}
|
||||||
if (array_key_exists('STDIN', $section_text)) {
|
if ($test->hasSection('STDIN')) {
|
||||||
return skip_test($tested, $tested_file, $shortname, 'Test with STDIN might not be repeatable');
|
return skip_test($tested, $tested_file, $shortname, 'Test with STDIN might not be repeatable');
|
||||||
}
|
}
|
||||||
if (array_key_exists('CAPTURE_STDIO', $section_text)) {
|
if ($test->hasSection('CAPTURE_STDIO')) {
|
||||||
return skip_test($tested, $tested_file, $shortname, 'Test with CAPTURE_STDIO might not be repeatable');
|
return skip_test($tested, $tested_file, $shortname, 'Test with CAPTURE_STDIO might not be repeatable');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2095,8 +1986,8 @@ TEST $file
|
||||||
mkdir(dirname($copy_file), 0777, true) or error("Cannot create output directory - " . dirname($copy_file));
|
mkdir(dirname($copy_file), 0777, true) or error("Cannot create output directory - " . dirname($copy_file));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($section_text['FILE'])) {
|
if ($test->hasSection('FILE')) {
|
||||||
save_text($copy_file, $section_text['FILE']);
|
save_text($copy_file, $test->getSection('FILE'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$temp_filenames = [
|
$temp_filenames = [
|
||||||
|
@ -2114,7 +2005,7 @@ TEST $file
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_array($IN_REDIRECT)) {
|
if (is_array($IN_REDIRECT)) {
|
||||||
$tested = $IN_REDIRECT['prefix'] . ' ' . trim($section_text['TEST']);
|
$tested = $IN_REDIRECT['prefix'] . ' ' . $tested;
|
||||||
$tested_file = $tmp_relative_file;
|
$tested_file = $tmp_relative_file;
|
||||||
$shortname = str_replace(TEST_PHP_SRCDIR . '/', '', $tested_file);
|
$shortname = str_replace(TEST_PHP_SRCDIR . '/', '', $tested_file);
|
||||||
}
|
}
|
||||||
|
@ -2145,8 +2036,8 @@ TEST $file
|
||||||
$env['CONTENT_LENGTH'] = '';
|
$env['CONTENT_LENGTH'] = '';
|
||||||
$env['TZ'] = '';
|
$env['TZ'] = '';
|
||||||
|
|
||||||
if (!empty($section_text['ENV'])) {
|
if ($test->sectionNotEmpty('ENV')) {
|
||||||
foreach (explode("\n", trim($section_text['ENV'])) as $e) {
|
foreach (explode("\n", $test->getSection('ENV')) as $e) {
|
||||||
$e = explode('=', trim($e), 2);
|
$e = explode('=', trim($e), 2);
|
||||||
|
|
||||||
if (!empty($e[0]) && isset($e[1])) {
|
if (!empty($e[0]) && isset($e[1])) {
|
||||||
|
@ -2159,11 +2050,11 @@ TEST $file
|
||||||
$ini_settings = $workerID ? ['opcache.cache_id' => "worker$workerID"] : [];
|
$ini_settings = $workerID ? ['opcache.cache_id' => "worker$workerID"] : [];
|
||||||
|
|
||||||
// Additional required extensions
|
// Additional required extensions
|
||||||
if (array_key_exists('EXTENSIONS', $section_text)) {
|
if ($test->hasSection('EXTENSIONS')) {
|
||||||
$ext_params = [];
|
$ext_params = [];
|
||||||
settings2array($ini_overwrites, $ext_params);
|
settings2array($ini_overwrites, $ext_params);
|
||||||
$ext_params = settings2params($ext_params);
|
$ext_params = settings2params($ext_params);
|
||||||
$extensions = preg_split("/[\n\r]+/", trim($section_text['EXTENSIONS']));
|
$extensions = preg_split("/[\n\r]+/", trim($test->getSection('EXTENSIONS')));
|
||||||
[$ext_dir, $loaded] = $skipCache->getExtensions("$php $pass_options $extra_options $ext_params $no_file_cache");
|
[$ext_dir, $loaded] = $skipCache->getExtensions("$php $pass_options $extra_options $ext_params $no_file_cache");
|
||||||
$ext_prefix = IS_WINDOWS ? "php_" : "";
|
$ext_prefix = IS_WINDOWS ? "php_" : "";
|
||||||
foreach ($extensions as $req_ext) {
|
foreach ($extensions as $req_ext) {
|
||||||
|
@ -2201,12 +2092,12 @@ TEST $file
|
||||||
|
|
||||||
// Any special ini settings
|
// Any special ini settings
|
||||||
// these may overwrite the test defaults...
|
// these may overwrite the test defaults...
|
||||||
if (array_key_exists('INI', $section_text)) {
|
if ($test->hasSection('INI')) {
|
||||||
$section_text['INI'] = str_replace('{PWD}', dirname($file), $section_text['INI']);
|
$ini = str_replace('{PWD}', dirname($file), $test->getSection('INI'));
|
||||||
$section_text['INI'] = str_replace('{TMP}', sys_get_temp_dir(), $section_text['INI']);
|
$ini = str_replace('{TMP}', sys_get_temp_dir(), $ini);
|
||||||
$replacement = IS_WINDOWS ? '"' . PHP_BINARY . ' -r \"while ($in = fgets(STDIN)) echo $in;\" > $1"' : 'tee $1 >/dev/null';
|
$replacement = IS_WINDOWS ? '"' . PHP_BINARY . ' -r \"while ($in = fgets(STDIN)) echo $in;\" > $1"' : 'tee $1 >/dev/null';
|
||||||
$section_text['INI'] = preg_replace('/{MAIL:(\S+)}/', $replacement, $section_text['INI']);
|
$ini = preg_replace('/{MAIL:(\S+)}/', $replacement, $ini);
|
||||||
settings2array(preg_split("/[\n\r]+/", $section_text['INI']), $ini_settings);
|
settings2array(preg_split("/[\n\r]+/", $ini), $ini_settings);
|
||||||
|
|
||||||
if ($num_repeats > 1 && isset($ini_settings['opcache.opt_debug_level'])) {
|
if ($num_repeats > 1 && isset($ini_settings['opcache.opt_debug_level'])) {
|
||||||
return skip_test($tested, $tested_file, $shortname, 'opt_debug_level tests are not repeatable');
|
return skip_test($tested, $tested_file, $shortname, 'opt_debug_level tests are not repeatable');
|
||||||
|
@ -2221,89 +2112,89 @@ TEST $file
|
||||||
$info = '';
|
$info = '';
|
||||||
$warn = false;
|
$warn = false;
|
||||||
|
|
||||||
if (array_key_exists('SKIPIF', $section_text)) {
|
if ($test->sectionNotEmpty('SKIPIF')) {
|
||||||
if (trim($section_text['SKIPIF'])) {
|
show_file_block('skip', $test->getSection('SKIPIF'));
|
||||||
show_file_block('skip', $section_text['SKIPIF']);
|
$extra = !IS_WINDOWS ?
|
||||||
$extra = !IS_WINDOWS ?
|
"unset REQUEST_METHOD; unset QUERY_STRING; unset PATH_TRANSLATED; unset SCRIPT_FILENAME; unset REQUEST_METHOD;" : "";
|
||||||
"unset REQUEST_METHOD; unset QUERY_STRING; unset PATH_TRANSLATED; unset SCRIPT_FILENAME; unset REQUEST_METHOD;" : "";
|
|
||||||
|
|
||||||
if ($valgrind) {
|
if ($valgrind) {
|
||||||
$env['USE_ZEND_ALLOC'] = '0';
|
$env['USE_ZEND_ALLOC'] = '0';
|
||||||
$env['ZEND_DONT_UNLOAD_MODULES'] = 1;
|
$env['ZEND_DONT_UNLOAD_MODULES'] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$junit->startTimer($shortname);
|
||||||
|
|
||||||
|
$startTime = microtime(true);
|
||||||
|
$commandLine = "$extra $php $pass_options $extra_options -q $orig_ini_settings $no_file_cache -d display_errors=1 -d display_startup_errors=0";
|
||||||
|
$output = $skipCache->checkSkip($commandLine, $test->getSection('SKIPIF'), $test_skipif, $temp_skipif, $env);
|
||||||
|
|
||||||
|
$time = microtime(true) - $startTime;
|
||||||
|
$junit->stopTimer($shortname);
|
||||||
|
|
||||||
|
if ($time > $slow_min_ms / 1000) {
|
||||||
|
$PHP_FAILED_TESTS['SLOW'][] = [
|
||||||
|
'name' => $file,
|
||||||
|
'test_name' => 'SKIPIF of ' . $tested . " [$tested_file]",
|
||||||
|
'output' => '',
|
||||||
|
'diff' => '',
|
||||||
|
'info' => $time,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$cfg['keep']['skip']) {
|
||||||
|
@unlink($test_skipif);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strncasecmp('skip', $output, 4)) {
|
||||||
|
if (preg_match('/^skip\s*(.+)/i', $output, $m)) {
|
||||||
|
show_result('SKIP', $tested, $tested_file, "reason: $m[1]", $temp_filenames);
|
||||||
|
} else {
|
||||||
|
show_result('SKIP', $tested, $tested_file, '', $temp_filenames);
|
||||||
}
|
}
|
||||||
|
|
||||||
$junit->startTimer($shortname);
|
$message = !empty($m[1]) ? $m[1] : '';
|
||||||
|
$junit->markTestAs('SKIP', $shortname, $tested, null, $message);
|
||||||
|
return 'SKIPPED';
|
||||||
|
}
|
||||||
|
|
||||||
$startTime = microtime(true);
|
|
||||||
$commandLine = "$extra $php $pass_options $extra_options -q $orig_ini_settings $no_file_cache -d display_errors=1 -d display_startup_errors=0";
|
|
||||||
$output = $skipCache->checkSkip($commandLine, $section_text['SKIPIF'], $test_skipif, $temp_skipif, $env);
|
|
||||||
|
|
||||||
$time = microtime(true) - $startTime;
|
if (!strncasecmp('info', $output, 4) && preg_match('/^info\s*(.+)/i', $output, $m)) {
|
||||||
|
$info = " (info: $m[1])";
|
||||||
|
} elseif (!strncasecmp('warn', $output, 4) && preg_match('/^warn\s+(.+)/i', $output, $m)) {
|
||||||
|
$warn = true; /* only if there is a reason */
|
||||||
|
$info = " (warn: $m[1])";
|
||||||
|
} elseif (!strncasecmp('xfail', $output, 5)) {
|
||||||
|
// Pretend we have an XFAIL section
|
||||||
|
$test->setSection('XFAIL', ltrim(substr($output, 5)));
|
||||||
|
} elseif ($output !== '') {
|
||||||
|
show_result("BORK", $output, $tested_file, 'reason: invalid output from SKIPIF', $temp_filenames);
|
||||||
|
$PHP_FAILED_TESTS['BORKED'][] = [
|
||||||
|
'name' => $file,
|
||||||
|
'test_name' => '',
|
||||||
|
'output' => '',
|
||||||
|
'diff' => '',
|
||||||
|
'info' => "$output [$file]",
|
||||||
|
];
|
||||||
|
|
||||||
$junit->stopTimer($shortname);
|
$junit->markTestAs('BORK', $shortname, $tested, null, $output);
|
||||||
|
return 'BORKED';
|
||||||
if ($time > $slow_min_ms / 1000) {
|
|
||||||
$PHP_FAILED_TESTS['SLOW'][] = [
|
|
||||||
'name' => $file,
|
|
||||||
'test_name' => 'SKIPIF of ' . $tested . " [$tested_file]",
|
|
||||||
'output' => '',
|
|
||||||
'diff' => '',
|
|
||||||
'info' => $time,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strncasecmp('skip', $output, 4)) {
|
|
||||||
if (preg_match('/^skip\s*(.+)/i', $output, $m)) {
|
|
||||||
show_result('SKIP', $tested, $tested_file, "reason: $m[1]", $temp_filenames);
|
|
||||||
} else {
|
|
||||||
show_result('SKIP', $tested, $tested_file, '', $temp_filenames);
|
|
||||||
}
|
|
||||||
|
|
||||||
$message = !empty($m[1]) ? $m[1] : '';
|
|
||||||
$junit->markTestAs('SKIP', $shortname, $tested, null, $message);
|
|
||||||
return 'SKIPPED';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strncasecmp('info', $output, 4) && preg_match('/^info\s*(.+)/i', $output, $m)) {
|
|
||||||
$info = " (info: $m[1])";
|
|
||||||
} elseif (!strncasecmp('warn', $output, 4) && preg_match('/^warn\s+(.+)/i', $output, $m)) {
|
|
||||||
$warn = true; /* only if there is a reason */
|
|
||||||
$info = " (warn: $m[1])";
|
|
||||||
} elseif (!strncasecmp('xfail', $output, 5)) {
|
|
||||||
// Pretend we have an XFAIL section
|
|
||||||
$section_text['XFAIL'] = ltrim(substr($output, 5));
|
|
||||||
} elseif ($output !== '') {
|
|
||||||
show_result("BORK", $output, $tested_file, 'reason: invalid output from SKIPIF', $temp_filenames);
|
|
||||||
$PHP_FAILED_TESTS['BORKED'][] = [
|
|
||||||
'name' => $file,
|
|
||||||
'test_name' => '',
|
|
||||||
'output' => '',
|
|
||||||
'diff' => '',
|
|
||||||
'info' => "$output [$file]",
|
|
||||||
];
|
|
||||||
|
|
||||||
$junit->markTestAs('BORK', $shortname, $tested, null, $output);
|
|
||||||
return 'BORKED';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!extension_loaded("zlib")
|
if (!extension_loaded("zlib") && $test->hasAnySections("GZIP_POST", "DEFLATE_POST")) {
|
||||||
&& (array_key_exists("GZIP_POST", $section_text)
|
|
||||||
|| array_key_exists("DEFLATE_POST", $section_text))) {
|
|
||||||
$message = "ext/zlib required";
|
$message = "ext/zlib required";
|
||||||
show_result('SKIP', $tested, $tested_file, "reason: $message", $temp_filenames);
|
show_result('SKIP', $tested, $tested_file, "reason: $message", $temp_filenames);
|
||||||
$junit->markTestAs('SKIP', $shortname, $tested, null, $message);
|
$junit->markTestAs('SKIP', $shortname, $tested, null, $message);
|
||||||
return 'SKIPPED';
|
return 'SKIPPED';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($section_text['REDIRECTTEST'])) {
|
if ($test->hasSection('REDIRECTTEST')) {
|
||||||
$test_files = [];
|
$test_files = [];
|
||||||
|
|
||||||
$IN_REDIRECT = eval($section_text['REDIRECTTEST']);
|
$IN_REDIRECT = eval($test->getSection('REDIRECTTEST'));
|
||||||
$IN_REDIRECT['via'] = "via [$shortname]\n\t";
|
$IN_REDIRECT['via'] = "via [$shortname]\n\t";
|
||||||
$IN_REDIRECT['dir'] = realpath(dirname($file));
|
$IN_REDIRECT['dir'] = realpath(dirname($file));
|
||||||
$IN_REDIRECT['prefix'] = trim($section_text['TEST']);
|
$IN_REDIRECT['prefix'] = $tested;
|
||||||
|
|
||||||
if (!empty($IN_REDIRECT['TESTS'])) {
|
if (!empty($IN_REDIRECT['TESTS'])) {
|
||||||
if (is_array($org_file)) {
|
if (is_array($org_file)) {
|
||||||
|
@ -2348,7 +2239,7 @@ TEST $file
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_array($org_file) || isset($section_text['REDIRECTTEST'])) {
|
if (is_array($org_file) || $test->hasSection('REDIRECTTEST')) {
|
||||||
if (is_array($org_file)) {
|
if (is_array($org_file)) {
|
||||||
$file = $org_file[0];
|
$file = $org_file[0];
|
||||||
}
|
}
|
||||||
|
@ -2369,15 +2260,15 @@ TEST $file
|
||||||
}
|
}
|
||||||
|
|
||||||
// We've satisfied the preconditions - run the test!
|
// We've satisfied the preconditions - run the test!
|
||||||
if (isset($section_text['FILE'])) {
|
if ($test->hasSection('FILE')) {
|
||||||
show_file_block('php', $section_text['FILE'], 'TEST');
|
show_file_block('php', $test->getSection('FILE'), 'TEST');
|
||||||
save_text($test_file, $section_text['FILE'], $temp_file);
|
save_text($test_file, $test->getSection('FILE'), $temp_file);
|
||||||
} else {
|
} else {
|
||||||
$test_file = $temp_file = "";
|
$test_file = $temp_file = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('GET', $section_text)) {
|
if ($test->hasSection('GET')) {
|
||||||
$query_string = trim($section_text['GET']);
|
$query_string = trim($test->getSection('GET'));
|
||||||
} else {
|
} else {
|
||||||
$query_string = '';
|
$query_string = '';
|
||||||
}
|
}
|
||||||
|
@ -2393,13 +2284,13 @@ TEST $file
|
||||||
$env['SCRIPT_FILENAME'] = $test_file;
|
$env['SCRIPT_FILENAME'] = $test_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('COOKIE', $section_text)) {
|
if ($test->hasSection('COOKIE')) {
|
||||||
$env['HTTP_COOKIE'] = trim($section_text['COOKIE']);
|
$env['HTTP_COOKIE'] = trim($test->getSection('COOKIE'));
|
||||||
} else {
|
} else {
|
||||||
$env['HTTP_COOKIE'] = '';
|
$env['HTTP_COOKIE'] = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$args = isset($section_text['ARGS']) ? ' -- ' . $section_text['ARGS'] : '';
|
$args = $test->hasSection('ARGS') ? ' -- ' . $test->getSection('ARGS') : '';
|
||||||
|
|
||||||
if ($preload && !empty($test_file)) {
|
if ($preload && !empty($test_file)) {
|
||||||
save_text($preload_filename, "<?php opcache_compile_file('$test_file');");
|
save_text($preload_filename, "<?php opcache_compile_file('$test_file');");
|
||||||
|
@ -2409,8 +2300,8 @@ TEST $file
|
||||||
$pass_options .= " -d opcache.preload=" . $preload_filename;
|
$pass_options .= " -d opcache.preload=" . $preload_filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('POST_RAW', $section_text) && !empty($section_text['POST_RAW'])) {
|
if ($test->sectionNotEmpty('POST_RAW')) {
|
||||||
$post = trim($section_text['POST_RAW']);
|
$post = trim($test->getSection('POST_RAW'));
|
||||||
$raw_lines = explode("\n", $post);
|
$raw_lines = explode("\n", $post);
|
||||||
|
|
||||||
$request = '';
|
$request = '';
|
||||||
|
@ -2440,8 +2331,8 @@ TEST $file
|
||||||
|
|
||||||
save_text($tmp_post, $request);
|
save_text($tmp_post, $request);
|
||||||
$cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
|
$cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
|
||||||
} elseif (array_key_exists('PUT', $section_text) && !empty($section_text['PUT'])) {
|
} elseif ($test->sectionNotEmpty('PUT')) {
|
||||||
$post = trim($section_text['PUT']);
|
$post = trim($test->getSection('PUT'));
|
||||||
$raw_lines = explode("\n", $post);
|
$raw_lines = explode("\n", $post);
|
||||||
|
|
||||||
$request = '';
|
$request = '';
|
||||||
|
@ -2471,8 +2362,8 @@ TEST $file
|
||||||
|
|
||||||
save_text($tmp_post, $request);
|
save_text($tmp_post, $request);
|
||||||
$cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
|
$cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
|
||||||
} elseif (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) {
|
} elseif ($test->sectionNotEmpty('POST')) {
|
||||||
$post = trim($section_text['POST']);
|
$post = trim($test->getSection('POST'));
|
||||||
$content_length = strlen($post);
|
$content_length = strlen($post);
|
||||||
save_text($tmp_post, $post);
|
save_text($tmp_post, $post);
|
||||||
|
|
||||||
|
@ -2486,8 +2377,8 @@ TEST $file
|
||||||
}
|
}
|
||||||
|
|
||||||
$cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
|
$cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
|
||||||
} elseif (array_key_exists('GZIP_POST', $section_text) && !empty($section_text['GZIP_POST'])) {
|
} elseif ($test->sectionNotEmpty('GZIP_POST')) {
|
||||||
$post = trim($section_text['GZIP_POST']);
|
$post = trim($test->getSection('GZIP_POST'));
|
||||||
$post = gzencode($post, 9, FORCE_GZIP);
|
$post = gzencode($post, 9, FORCE_GZIP);
|
||||||
$env['HTTP_CONTENT_ENCODING'] = 'gzip';
|
$env['HTTP_CONTENT_ENCODING'] = 'gzip';
|
||||||
|
|
||||||
|
@ -2499,8 +2390,8 @@ TEST $file
|
||||||
$env['CONTENT_LENGTH'] = $content_length;
|
$env['CONTENT_LENGTH'] = $content_length;
|
||||||
|
|
||||||
$cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
|
$cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
|
||||||
} elseif (array_key_exists('DEFLATE_POST', $section_text) && !empty($section_text['DEFLATE_POST'])) {
|
} elseif ($test->sectionNotEmpty('DEFLATE_POST')) {
|
||||||
$post = trim($section_text['DEFLATE_POST']);
|
$post = trim($test->getSection('DEFLATE_POST'));
|
||||||
$post = gzcompress($post, 9);
|
$post = gzcompress($post, 9);
|
||||||
$env['HTTP_CONTENT_ENCODING'] = 'deflate';
|
$env['HTTP_CONTENT_ENCODING'] = 'deflate';
|
||||||
save_text($tmp_post, $post);
|
save_text($tmp_post, $post);
|
||||||
|
@ -2546,7 +2437,8 @@ COMMAND $cmd
|
||||||
$hrtime = hrtime();
|
$hrtime = hrtime();
|
||||||
$startTime = $hrtime[0] * 1000000000 + $hrtime[1];
|
$startTime = $hrtime[0] * 1000000000 + $hrtime[1];
|
||||||
|
|
||||||
$out = system_with_timeout($cmd, $env, $section_text['STDIN'] ?? null, $captureStdIn, $captureStdOut, $captureStdErr);
|
$stdin = $test->hasSection('STDIN') ? $test->getSection('STDIN') : null;
|
||||||
|
$out = system_with_timeout($cmd, $env, $stdin, $captureStdIn, $captureStdOut, $captureStdErr);
|
||||||
|
|
||||||
$junit->stopTimer($shortname);
|
$junit->stopTimer($shortname);
|
||||||
$hrtime = hrtime();
|
$hrtime = hrtime();
|
||||||
|
@ -2561,20 +2453,18 @@ COMMAND $cmd
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('CLEAN', $section_text) && (!$no_clean || $cfg['keep']['clean'])) {
|
if ($test->sectionNotEmpty('CLEAN') && (!$no_clean || $cfg['keep']['clean'])) {
|
||||||
if (trim($section_text['CLEAN'])) {
|
show_file_block('clean', $test->getSection('CLEAN'));
|
||||||
show_file_block('clean', $section_text['CLEAN']);
|
save_text($test_clean, trim($test->getSection('CLEAN')), $temp_clean);
|
||||||
save_text($test_clean, trim($section_text['CLEAN']), $temp_clean);
|
|
||||||
|
|
||||||
if (!$no_clean) {
|
if (!$no_clean) {
|
||||||
$extra = !IS_WINDOWS ?
|
$extra = !IS_WINDOWS ?
|
||||||
"unset REQUEST_METHOD; unset QUERY_STRING; unset PATH_TRANSLATED; unset SCRIPT_FILENAME; unset REQUEST_METHOD;" : "";
|
"unset REQUEST_METHOD; unset QUERY_STRING; unset PATH_TRANSLATED; unset SCRIPT_FILENAME; unset REQUEST_METHOD;" : "";
|
||||||
system_with_timeout("$extra $php $pass_options $extra_options -q $orig_ini_settings $no_file_cache \"$test_clean\"", $env);
|
system_with_timeout("$extra $php $pass_options $extra_options -q $orig_ini_settings $no_file_cache \"$test_clean\"", $env);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$cfg['keep']['clean']) {
|
if (!$cfg['keep']['clean']) {
|
||||||
@unlink($test_clean);
|
@unlink($test_clean);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2630,10 +2520,10 @@ COMMAND $cmd
|
||||||
|
|
||||||
$failed_headers = false;
|
$failed_headers = false;
|
||||||
|
|
||||||
if (isset($section_text['EXPECTHEADERS'])) {
|
if ($test->hasSection('EXPECTHEADERS')) {
|
||||||
$want = [];
|
$want = [];
|
||||||
$wanted_headers = [];
|
$wanted_headers = [];
|
||||||
$lines = preg_split("/[\n\r]+/", $section_text['EXPECTHEADERS']);
|
$lines = preg_split("/[\n\r]+/", $test->getSection('EXPECTHEADERS'));
|
||||||
|
|
||||||
foreach ($lines as $line) {
|
foreach ($lines as $line) {
|
||||||
if (strpos($line, ':') !== false) {
|
if (strpos($line, ':') !== false) {
|
||||||
|
@ -2667,17 +2557,17 @@ COMMAND $cmd
|
||||||
$output = trim(preg_replace("/\n?Warning: Can't preload [^\n]*\n?/", "", $output));
|
$output = trim(preg_replace("/\n?Warning: Can't preload [^\n]*\n?/", "", $output));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($section_text['EXPECTF']) || isset($section_text['EXPECTREGEX'])) {
|
if ($test->hasAnySections('EXPECTF', 'EXPECTREGEX')) {
|
||||||
if (isset($section_text['EXPECTF'])) {
|
if ($test->hasSection('EXPECTF')) {
|
||||||
$wanted = trim($section_text['EXPECTF']);
|
$wanted = trim($test->getSection('EXPECTF'));
|
||||||
} else {
|
} else {
|
||||||
$wanted = trim($section_text['EXPECTREGEX']);
|
$wanted = trim($test->getSection('EXPECTREGEX'));
|
||||||
}
|
}
|
||||||
|
|
||||||
show_file_block('exp', $wanted);
|
show_file_block('exp', $wanted);
|
||||||
$wanted_re = preg_replace('/\r\n/', "\n", $wanted);
|
$wanted_re = preg_replace('/\r\n/', "\n", $wanted);
|
||||||
|
|
||||||
if (isset($section_text['EXPECTF'])) {
|
if ($test->hasSection('EXPECTF')) {
|
||||||
// do preg_quote, but miss out any %r delimited sections
|
// do preg_quote, but miss out any %r delimited sections
|
||||||
$temp = "";
|
$temp = "";
|
||||||
$r = "%r";
|
$r = "%r";
|
||||||
|
@ -2729,10 +2619,10 @@ COMMAND $cmd
|
||||||
@unlink($tmp_post);
|
@unlink($tmp_post);
|
||||||
|
|
||||||
if (!$leaked && !$failed_headers) {
|
if (!$leaked && !$failed_headers) {
|
||||||
if (isset($section_text['XFAIL'])) {
|
if ($test->hasSection('XFAIL')) {
|
||||||
$warn = true;
|
$warn = true;
|
||||||
$info = " (warn: XFAIL section but test passes)";
|
$info = " (warn: XFAIL section but test passes)";
|
||||||
} elseif (isset($section_text['XLEAK'])) {
|
} elseif ($test->hasSection('XLEAK')) {
|
||||||
$warn = true;
|
$warn = true;
|
||||||
$info = " (warn: XLEAK section but test passes)";
|
$info = " (warn: XLEAK section but test passes)";
|
||||||
} else {
|
} else {
|
||||||
|
@ -2743,7 +2633,7 @@ COMMAND $cmd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$wanted = trim($section_text['EXPECT']);
|
$wanted = trim($test->getSection('EXPECT'));
|
||||||
$wanted = preg_replace('/\r\n/', "\n", $wanted);
|
$wanted = preg_replace('/\r\n/', "\n", $wanted);
|
||||||
show_file_block('exp', $wanted);
|
show_file_block('exp', $wanted);
|
||||||
|
|
||||||
|
@ -2757,10 +2647,10 @@ COMMAND $cmd
|
||||||
@unlink($tmp_post);
|
@unlink($tmp_post);
|
||||||
|
|
||||||
if (!$leaked && !$failed_headers) {
|
if (!$leaked && !$failed_headers) {
|
||||||
if (isset($section_text['XFAIL'])) {
|
if ($test->hasSection('XFAIL')) {
|
||||||
$warn = true;
|
$warn = true;
|
||||||
$info = " (warn: XFAIL section but test passes)";
|
$info = " (warn: XFAIL section but test passes)";
|
||||||
} elseif (isset($section_text['XLEAK'])) {
|
} elseif ($test->hasSection('XLEAK')) {
|
||||||
$warn = true;
|
$warn = true;
|
||||||
$info = " (warn: XLEAK section but test passes)";
|
$info = " (warn: XLEAK section but test passes)";
|
||||||
} else {
|
} else {
|
||||||
|
@ -2786,7 +2676,7 @@ COMMAND $cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($leaked) {
|
if ($leaked) {
|
||||||
$restype[] = isset($section_text['XLEAK']) ?
|
$restype[] = $test->hasSection('XLEAK') ?
|
||||||
'XLEAK' : 'LEAK';
|
'XLEAK' : 'LEAK';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2795,12 +2685,12 @@ COMMAND $cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$passed) {
|
if (!$passed) {
|
||||||
if (isset($section_text['XFAIL'])) {
|
if ($test->hasSection('XFAIL')) {
|
||||||
$restype[] = 'XFAIL';
|
$restype[] = 'XFAIL';
|
||||||
$info = ' XFAIL REASON: ' . rtrim($section_text['XFAIL']);
|
$info = ' XFAIL REASON: ' . rtrim($test->getSection('XFAIL'));
|
||||||
} elseif (isset($section_text['XLEAK'])) {
|
} elseif ($test->hasSection('XLEAK')) {
|
||||||
$restype[] = 'XLEAK';
|
$restype[] = 'XLEAK';
|
||||||
$info = ' XLEAK REASON: ' . rtrim($section_text['XLEAK']);
|
$info = ' XLEAK REASON: ' . rtrim($test->getSection('XLEAK'));
|
||||||
} else {
|
} else {
|
||||||
$restype[] = 'FAIL';
|
$restype[] = 'FAIL';
|
||||||
}
|
}
|
||||||
|
@ -3431,6 +3321,10 @@ function show_result(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class BorkageException extends Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
class JUnit
|
class JUnit
|
||||||
{
|
{
|
||||||
private bool $enabled = true;
|
private bool $enabled = true;
|
||||||
|
@ -3843,6 +3737,206 @@ class RuntestsValgrind
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TestFile
|
||||||
|
{
|
||||||
|
private string $fileName;
|
||||||
|
|
||||||
|
private array $sections = ['TEST' => ''];
|
||||||
|
|
||||||
|
private const ALLOWED_SECTIONS = [
|
||||||
|
'EXPECT', 'EXPECTF', 'EXPECTREGEX', 'EXPECTREGEX_EXTERNAL', 'EXPECT_EXTERNAL', 'EXPECTF_EXTERNAL', 'EXPECTHEADERS',
|
||||||
|
'POST', 'POST_RAW', 'GZIP_POST', 'DEFLATE_POST', 'PUT', 'GET', 'COOKIE', 'ARGS',
|
||||||
|
'FILE', 'FILEEOF', 'FILE_EXTERNAL', 'REDIRECTTEST',
|
||||||
|
'CAPTURE_STDIO', 'STDIN', 'CGI', 'PHPDBG',
|
||||||
|
'INI', 'ENV', 'EXTENSIONS',
|
||||||
|
'SKIPIF', 'XFAIL', 'XLEAK', 'CLEAN',
|
||||||
|
'CREDITS', 'DESCRIPTION', 'CONFLICTS', 'WHITESPACE_SENSITIVE',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function __construct(string $fileName, bool $inRedirect)
|
||||||
|
{
|
||||||
|
$this->fileName = $fileName;
|
||||||
|
|
||||||
|
$this->readFile();
|
||||||
|
$this->validateAndProcess($inRedirect);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasSection(string $name): bool
|
||||||
|
{
|
||||||
|
return isset($this->sections[$name]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasAllSections(string ...$names): bool
|
||||||
|
{
|
||||||
|
foreach ($names as $section) {
|
||||||
|
if (!isset($this->sections[$section])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasAnySections(string ...$names): bool
|
||||||
|
{
|
||||||
|
foreach ($names as $section) {
|
||||||
|
if (isset($this->sections[$section])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sectionNotEmpty(string $name): bool
|
||||||
|
{
|
||||||
|
return !empty($this->sections[$name]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSection(string $name): string
|
||||||
|
{
|
||||||
|
if (!isset($this->sections[$name])) {
|
||||||
|
throw new Exception("Section $name not found");
|
||||||
|
}
|
||||||
|
return $this->sections[$name];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(): string
|
||||||
|
{
|
||||||
|
return trim($this->getSection('TEST'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isCGI(): bool
|
||||||
|
{
|
||||||
|
return $this->sectionNotEmpty('CGI')
|
||||||
|
|| $this->sectionNotEmpty('GET')
|
||||||
|
|| $this->sectionNotEmpty('POST')
|
||||||
|
|| $this->sectionNotEmpty('GZIP_POST')
|
||||||
|
|| $this->sectionNotEmpty('DEFLATE_POST')
|
||||||
|
|| $this->sectionNotEmpty('POST_RAW')
|
||||||
|
|| $this->sectionNotEmpty('PUT')
|
||||||
|
|| $this->sectionNotEmpty('COOKIE')
|
||||||
|
|| $this->sectionNotEmpty('EXPECTHEADERS');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO Refactor to make it not needed
|
||||||
|
*/
|
||||||
|
public function setSection(string $name, string $value): void
|
||||||
|
{
|
||||||
|
$this->sections[$name] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the sections of the test file
|
||||||
|
*/
|
||||||
|
private function readFile(): void
|
||||||
|
{
|
||||||
|
$fp = fopen($this->fileName, "rb") or error("Cannot open test file: {$this->fileName}");
|
||||||
|
|
||||||
|
if (!feof($fp)) {
|
||||||
|
$line = fgets($fp);
|
||||||
|
|
||||||
|
if ($line === false) {
|
||||||
|
throw new BorkageException("cannot read test");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new BorkageException("empty test [{$this->fileName}]");
|
||||||
|
}
|
||||||
|
if (strncmp('--TEST--', $line, 8)) {
|
||||||
|
throw new BorkageException("tests must start with --TEST-- [{$this->fileName}]");
|
||||||
|
}
|
||||||
|
|
||||||
|
$section = 'TEST';
|
||||||
|
$secfile = false;
|
||||||
|
$secdone = false;
|
||||||
|
|
||||||
|
while (!feof($fp)) {
|
||||||
|
$line = fgets($fp);
|
||||||
|
|
||||||
|
if ($line === false) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match the beginning of a section.
|
||||||
|
if (preg_match('/^--([_A-Z]+)--/', $line, $r)) {
|
||||||
|
$section = (string) $r[1];
|
||||||
|
|
||||||
|
if (isset($this->sections[$section]) && $this->sections[$section]) {
|
||||||
|
throw new BorkageException("duplicated $section section");
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for unknown sections
|
||||||
|
if (!in_array($section, self::ALLOWED_SECTIONS)) {
|
||||||
|
throw new BorkageException('Unknown section "' . $section . '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->sections[$section] = '';
|
||||||
|
$secfile = $section == 'FILE' || $section == 'FILEEOF' || $section == 'FILE_EXTERNAL';
|
||||||
|
$secdone = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add to the section text.
|
||||||
|
if (!$secdone) {
|
||||||
|
$this->sections[$section] .= $line;
|
||||||
|
}
|
||||||
|
|
||||||
|
// End of actual test?
|
||||||
|
if ($secfile && preg_match('/^===DONE===\s*$/', $line)) {
|
||||||
|
$secdone = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose($fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function validateAndProcess(bool $inRedirect): void
|
||||||
|
{
|
||||||
|
// the redirect section allows a set of tests to be reused outside of
|
||||||
|
// a given test dir
|
||||||
|
if ($this->hasSection('REDIRECTTEST')) {
|
||||||
|
if ($inRedirect) {
|
||||||
|
throw new BorkageException("Can't redirect a test from within a redirected test");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!$this->hasSection('PHPDBG') && $this->hasSection('FILE') + $this->hasSection('FILEEOF') + $this->hasSection('FILE_EXTERNAL') != 1) {
|
||||||
|
throw new BorkageException("missing section --FILE--");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->hasSection('FILEEOF')) {
|
||||||
|
$this->sections['FILE'] = preg_replace("/[\r\n]+$/", '', $this->sections['FILEEOF']);
|
||||||
|
unset($this->sections['FILEEOF']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (['FILE', 'EXPECT', 'EXPECTF', 'EXPECTREGEX'] as $prefix) {
|
||||||
|
// For grepping: FILE_EXTERNAL, EXPECT_EXTERNAL, EXPECTF_EXTERNAL, EXPECTREGEX_EXTERNAL
|
||||||
|
$key = $prefix . '_EXTERNAL';
|
||||||
|
|
||||||
|
if ($this->hasSection($key)) {
|
||||||
|
// don't allow tests to retrieve files from anywhere but this subdirectory
|
||||||
|
$dir = dirname($this->fileName);
|
||||||
|
$fileName = $dir . '/' . trim(str_replace('..', '', $this->getSection($key)));
|
||||||
|
|
||||||
|
if (file_exists($fileName)) {
|
||||||
|
$this->sections[$prefix] = file_get_contents($fileName);
|
||||||
|
} else {
|
||||||
|
throw new BorkageException("could not load --" . $key . "-- " . $dir . '/' . trim($fileName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($this->hasSection('EXPECT') + $this->hasSection('EXPECTF') + $this->hasSection('EXPECTREGEX')) != 1) {
|
||||||
|
throw new BorkageException("missing section --EXPECT--, --EXPECTF-- or --EXPECTREGEX--");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->hasSection('PHPDBG') && !$this->hasSection('STDIN')) {
|
||||||
|
$this->sections['STDIN'] = $this->sections['PHPDBG'] . "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function init_output_buffers(): void
|
function init_output_buffers(): void
|
||||||
{
|
{
|
||||||
// Delete as much output buffers as possible.
|
// Delete as much output buffers as possible.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue