@@ -1832,6 +1832,11 @@ function run_test(string $php, $file, array $env): string
18321832 /** @var JUnit */
18331833 global $ junit ;
18341834
1835+ static $ skipCache ;
1836+ if (!$ skipCache ) {
1837+ $ skipCache = new SkipCache ($ cfg ['keep ' ]['skip ' ]);
1838+ }
1839+
18351840 $ temp_filenames = null ;
18361841 $ org_file = $ file ;
18371842
@@ -2155,9 +2160,8 @@ function run_test(string $php, $file, array $env): string
21552160 $ ext_params = [];
21562161 settings2array ($ ini_overwrites , $ ext_params );
21572162 $ ext_params = settings2params ($ ext_params );
2158- $ ext_dir = `$ php $ pass_options $ extra_options $ ext_params $ no_file_cache -d display_errors=0 -r "echo ini_get('extension_dir');" `;
21592163 $ extensions = preg_split ("/[ \n\r]+/ " , trim ($ section_text ['EXTENSIONS ' ]));
2160- $ loaded = explode ( " , " , ` $ php $ pass_options $ extra_options $ ext_params $ no_file_cache -d display_errors=0 -r "echo implode(',', get_loaded_extensions());" ` );
2164+ [ $ ext_dir , $ loaded] = $ skipCache -> getExtensions ( " $ php $ pass_options $ extra_options $ ext_params $ no_file_cache" );
21612165 $ ext_prefix = IS_WINDOWS ? "php_ " : "" ;
21622166 foreach ($ extensions as $ req_ext ) {
21632167 if (!in_array ($ req_ext , $ loaded )) {
@@ -2217,7 +2221,6 @@ function run_test(string $php, $file, array $env): string
22172221 if (array_key_exists ('SKIPIF ' , $ section_text )) {
22182222 if (trim ($ section_text ['SKIPIF ' ])) {
22192223 show_file_block ('skip ' , $ section_text ['SKIPIF ' ]);
2220- save_text ($ test_skipif , $ section_text ['SKIPIF ' ], $ temp_skipif );
22212224 $ extra = !IS_WINDOWS ?
22222225 "unset REQUEST_METHOD; unset QUERY_STRING; unset PATH_TRANSLATED; unset SCRIPT_FILENAME; unset REQUEST_METHOD; " : "" ;
22232226
@@ -2229,8 +2232,9 @@ function run_test(string $php, $file, array $env): string
22292232 $ junit ->startTimer ($ shortname );
22302233
22312234 $ startTime = microtime (true );
2232- $ 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 );
2233- $ output = trim ($ output );
2235+ $ commandLine = "$ extra $ php $ pass_options $ extra_options -q $ orig_ini_settings $ no_file_cache -d display_errors=1 -d display_startup_errors=0 " ;
2236+ $ output = $ skipCache ->checkSkip ($ commandLine , $ section_text ['SKIPIF ' ], $ test_skipif , $ temp_skipif , $ env );
2237+
22342238 $ time = microtime (true ) - $ startTime ;
22352239
22362240 $ junit ->stopTimer ($ shortname );
@@ -2245,21 +2249,13 @@ function run_test(string $php, $file, array $env): string
22452249 ];
22462250 }
22472251
2248- if (!$ cfg ['keep ' ]['skip ' ]) {
2249- @unlink ($ test_skipif );
2250- }
2251-
22522252 if (!strncasecmp ('skip ' , $ output , 4 )) {
22532253 if (preg_match ('/^skip\s*(.+)/i ' , $ output , $ m )) {
22542254 show_result ('SKIP ' , $ tested , $ tested_file , "reason: $ m [1 ]" , $ temp_filenames );
22552255 } else {
22562256 show_result ('SKIP ' , $ tested , $ tested_file , '' , $ temp_filenames );
22572257 }
22582258
2259- if (!$ cfg ['keep ' ]['skip ' ]) {
2260- @unlink ($ test_skipif );
2261- }
2262-
22632259 $ message = !empty ($ m [1 ]) ? $ m [1 ] : '' ;
22642260 $ junit ->markTestAs ('SKIP ' , $ shortname , $ tested , null , $ message );
22652261 return 'SKIPPED ' ;
@@ -3716,6 +3712,79 @@ 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+ // Extension tests frequently use something like <?php require 'skipif.inc';
3735+ // for skip checks. This forces us to cache per directory to avoid pollution.
3736+ $ dir = dirname ($ checkFile );
3737+ $ key = "$ php => $ dir " ;
3738+
3739+ if (isset ($ this ->skips [$ key ][$ code ])) {
3740+ $ this ->hits ++;
3741+ if ($ this ->keepFile ) {
3742+ save_text ($ checkFile , $ code , $ tempFile );
3743+ }
3744+ return $ this ->skips [$ key ][$ code ];
3745+ }
3746+
3747+ save_text ($ checkFile , $ code , $ tempFile );
3748+ $ result = trim (system_with_timeout ("$ php \"$ checkFile \"" , $ env ));
3749+ $ this ->skips [$ key ][$ code ] = $ result ;
3750+ $ this ->misses ++;
3751+
3752+ if (!$ this ->keepFile ) {
3753+ @unlink ($ checkFile );
3754+ }
3755+
3756+ return $ result ;
3757+ }
3758+
3759+ public function getExtensions (string $ php ): array
3760+ {
3761+ if (isset ($ this ->extensions [$ php ])) {
3762+ $ this ->extHits ++;
3763+ return $ this ->extensions [$ php ];
3764+ }
3765+
3766+ $ extDir = `$ php -d display_errors=0 -r "echo ini_get('extension_dir');" `;
3767+ $ extensions = explode (", " , `$ php -d display_errors=0 -r "echo implode(',', get_loaded_extensions());" `);
3768+
3769+ $ result = [$ extDir , $ extensions ];
3770+ $ this ->extensions [$ php ] = $ result ;
3771+ $ this ->extMisses ++;
3772+
3773+ return $ result ;
3774+ }
3775+
3776+ // public function __destruct()
3777+ // {
3778+ // echo "Skips: {$this->hits} hits, {$this->misses} misses.\n";
3779+ // echo "Extensions: {$this->extHits} hits, {$this->extMisses} misses.\n";
3780+ // echo "Cache distribution:\n";
3781+ //
3782+ // foreach ($this->skips as $php => $cache) {
3783+ // echo "$php: " . count($cache) . "\n";
3784+ // }
3785+ // }
3786+ }
3787+
37193788class RuntestsValgrind
37203789{
37213790 protected $ version = '' ;
0 commit comments