Skip to content

Commit 043c31b

Browse files
committed
run-tests: add skip cache
Currently every --SKIPIF-- section in every test file results in 1 extra execution of PHP, every --EXTENSIONS-- section - in 2 executions. This is quite wasteful, as skip checking code is extremely repetitive and extensions are fixed for every binary/ini/command parameters combination. This patch adds caching to all such checks. On my machine, the gains are quite noticeable: 36s instead of 43s with -j16, 253s instead of 302s without concurrency. Cache stats are 3420 hits, 1066 misses in the latter case. In the future, tests could be adjusted to have more uniform skip checks to improve performance even more.
1 parent f068954 commit 043c31b

File tree

1 file changed

+74
-13
lines changed

1 file changed

+74
-13
lines changed

run-tests.php

Lines changed: 74 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1833,6 +1833,11 @@ function run_test(string $php, $file, array $env): string
18331833
/** @var JUnit */
18341834
global $junit;
18351835

1836+
static $skipCache;
1837+
if (!$skipCache) {
1838+
$skipCache = new SkipCache($cfg['keep']['skip']);
1839+
}
1840+
18361841
$temp_filenames = null;
18371842
$org_file = $file;
18381843

@@ -2156,9 +2161,8 @@ function run_test(string $php, $file, array $env): string
21562161
$ext_params = [];
21572162
settings2array($ini_overwrites, $ext_params);
21582163
$ext_params = settings2params($ext_params);
2159-
$ext_dir = `$php $pass_options $extra_options $ext_params $no_file_cache -d display_errors=0 -r "echo ini_get('extension_dir');"`;
21602164
$extensions = preg_split("/[\n\r]+/", trim($section_text['EXTENSIONS']));
2161-
$loaded = explode(",", `$php $pass_options $extra_options $ext_params $no_file_cache -d display_errors=0 -r "echo implode(',', get_loaded_extensions());"`);
2165+
[$ext_dir, $loaded] = $skipCache->getExtensions("$php $pass_options $extra_options $ext_params $no_file_cache");
21622166
$ext_prefix = IS_WINDOWS ? "php_" : "";
21632167
foreach ($extensions as $req_ext) {
21642168
if (!in_array($req_ext, $loaded)) {
@@ -2218,7 +2222,6 @@ function run_test(string $php, $file, array $env): string
22182222
if (array_key_exists('SKIPIF', $section_text)) {
22192223
if (trim($section_text['SKIPIF'])) {
22202224
show_file_block('skip', $section_text['SKIPIF']);
2221-
save_text($test_skipif, $section_text['SKIPIF'], $temp_skipif);
22222225
$extra = !IS_WINDOWS ?
22232226
"unset REQUEST_METHOD; unset QUERY_STRING; unset PATH_TRANSLATED; unset SCRIPT_FILENAME; unset REQUEST_METHOD;" : "";
22242227

@@ -2230,8 +2233,9 @@ function run_test(string $php, $file, array $env): string
22302233
$junit->startTimer($shortname);
22312234

22322235
$startTime = microtime(true);
2233-
$output = system_with_timeout("$extra $php $pass_options $extra_options -q $orig_ini_settings $no_file_cache -d display_errors=1 -d display_startup_errors=0 \"$test_skipif\"", $env);
2234-
$output = trim($output);
2236+
$commandLine = "$extra $php $pass_options $extra_options -q $orig_ini_settings $no_file_cache -d display_errors=1 -d display_startup_errors=0";
2237+
$output = $skipCache->checkSkip($commandLine, $section_text['SKIPIF'], $test_skipif, $temp_skipif, $env);
2238+
22352239
$time = microtime(true) - $startTime;
22362240

22372241
$junit->stopTimer($shortname);
@@ -2246,21 +2250,13 @@ function run_test(string $php, $file, array $env): string
22462250
];
22472251
}
22482252

2249-
if (!$cfg['keep']['skip']) {
2250-
@unlink($test_skipif);
2251-
}
2252-
22532253
if (!strncasecmp('skip', $output, 4)) {
22542254
if (preg_match('/^skip\s*(.+)/i', $output, $m)) {
22552255
show_result('SKIP', $tested, $tested_file, "reason: $m[1]", $temp_filenames);
22562256
} else {
22572257
show_result('SKIP', $tested, $tested_file, '', $temp_filenames);
22582258
}
22592259

2260-
if (!$cfg['keep']['skip']) {
2261-
@unlink($test_skipif);
2262-
}
2263-
22642260
$message = !empty($m[1]) ? $m[1] : '';
22652261
$junit->markTestAs('SKIP', $shortname, $tested, null, $message);
22662262
return 'SKIPPED';
@@ -3716,6 +3712,71 @@ private function mergeSuites(array &$dest, array $source): void
37163712
}
37173713
}
37183714

3715+
class SkipCache
3716+
{
3717+
private bool $keepFile;
3718+
3719+
private array $skips = [];
3720+
private array $extensions = [];
3721+
3722+
private int $hits = 0;
3723+
private int $misses = 0;
3724+
private int $extHits = 0;
3725+
private int $extMisses = 0;
3726+
3727+
public function __construct(bool $keepFile)
3728+
{
3729+
$this->keepFile = $keepFile;
3730+
}
3731+
3732+
public function checkSkip(string $php, string $code, string $checkFile, string $tempFile, array $env): string
3733+
{
3734+
if (isset($this->skips[$php][$code])) {
3735+
$this->hits++;
3736+
return $this->skips[$php][$code];
3737+
}
3738+
3739+
save_text($checkFile, $code, $tempFile);
3740+
$result = trim(system_with_timeout("$php \"$checkFile\"", $env));
3741+
$this->skips[$php][$code] = $result;
3742+
$this->misses++;
3743+
3744+
if (!$this->keepFile) {
3745+
@unlink($checkFile);
3746+
}
3747+
3748+
return $result;
3749+
}
3750+
3751+
public function getExtensions(string $php): array
3752+
{
3753+
if (isset($this->extensions[$php])) {
3754+
$this->extHits++;
3755+
return $this->extensions[$php];
3756+
}
3757+
3758+
$extDir = `$php -d display_errors=0 -r "echo ini_get('extension_dir');"`;
3759+
$extensions = explode(",", `$php -d display_errors=0 -r "echo implode(',', get_loaded_extensions());"`);
3760+
3761+
$result = [$extDir, $extensions];
3762+
$this->extensions[$php] = $result;
3763+
$this->extMisses++;
3764+
3765+
return $result;
3766+
}
3767+
3768+
// public function __destruct()
3769+
// {
3770+
// echo "Skips: {$this->hits} hits, {$this->misses} misses.\n";
3771+
// echo "Extensions: {$this->extHits} hits, {$this->extMisses} misses.\n";
3772+
// echo "Cache distribution:\n";
3773+
//
3774+
// foreach ($this->skips as $php => $cache) {
3775+
// echo "$php: " . count($cache) . "\n";
3776+
// }
3777+
// }
3778+
}
3779+
37193780
class RuntestsValgrind
37203781
{
37213782
protected $version = '';

0 commit comments

Comments
 (0)