run-tests: use the EXTENSIONS section for skipping

Currently, most skip checks are just for making sure an extension is
available. Even with recent addition of skip caching, this makes tests
needlessly slow:
* Checks for the same extension in its tests can have small differences
  impacting cacheability.
* Even identical skip checks in two tests can still be executed twice if
  they're run by different workers.

To remedy this, I'm repurposing the existing --EXTENSIONS-- section of
.phpt files to specify wjich extensions are required for current test to
run. Current behavior:
1) If the extension is already visible to PHP, all is good
2) If it isn't, assume it's present as a shared module and attempt to add
   it via a command line parameter
3) If that works, all is good
4) If it doesn't, PHP fails with a cryptic error message trying to
   execute the test itself

After this commit:
1) and 2) are kept unchanged
3) Check if shared extension file from 2) is actually present
4) Skip the test if it isn't

Other benefits include clear skip reasons (vs. sometimes none in many
current skip checks) and moving test information from code to metadata,
opening more opportunities for search and analysis.

Since --EXTENSIONS-- is barely ever used, this change poses no risk of
hidden failures.

As a demonstration of the new approach, this commit migrates one
extension to it. If merged, I will migrate other extensions in
subsequent PRs.

Closes GH-6787.
This commit is contained in:
Max Semenik 2021-03-18 14:53:14 +03:00 committed by Nikita Popov
parent a3e1082e0a
commit 6c9a05667b
28 changed files with 74 additions and 71 deletions

View file

@ -1,9 +1,7 @@
--TEST--
Bug #78114 (segfault when calling sodium_* functions from eval)
--SKIPIF--
<?php
if (!extension_loaded('sodium')) die('skip sodium extension not available');
?>
--EXTENSIONS--
sodium
--FILE--
<?php
try {

View file

@ -1,8 +1,9 @@
--TEST--
Bug #78516 (password_hash(): Memory cost is not in allowed range)
--EXTENSIONS--
sodium
--SKIPIF--
<?php
if (!extension_loaded('sodium')) die('skip sodium extension not available');
if (!defined('PASSWORD_ARGON2ID')) die('skip PASSWORD_ARGON2ID not available');
?>
--FILE--

View file

@ -1,8 +1,9 @@
--TEST--
Check for libsodium AEAD
--EXTENSIONS--
sodium
--SKIPIF--
<?php
if (!extension_loaded("sodium")) print "skip extension not loaded";
if (!defined('SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES')) print "skip libsodium without AESGCM";
?>
--FILE--

View file

@ -1,7 +1,7 @@
--TEST--
Check for libsodium auth
--SKIPIF--
<?php if (!extension_loaded("sodium")) print "skip"; ?>
--EXTENSIONS--
sodium
--FILE--
<?php
$msg = random_bytes(1000);

View file

@ -1,7 +1,7 @@
--TEST--
Check for libsodium box
--SKIPIF--
<?php if (!extension_loaded("sodium")) print "skip"; ?>
--EXTENSIONS--
sodium
--FILE--
<?php
$keypair = sodium_crypto_box_keypair();

View file

@ -1,7 +1,7 @@
--TEST--
Check for libsodium generichash
--SKIPIF--
<?php if (!extension_loaded("sodium")) print "skip"; ?>
--EXTENSIONS--
sodium
--FILE--
<?php
$q = sodium_crypto_generichash('msg');

View file

@ -1,7 +1,7 @@
--TEST--
Check for libsodium bin2hex
--SKIPIF--
<?php if (!extension_loaded("sodium")) print "skip"; ?>
--EXTENSIONS--
sodium
--FILE--
<?php
$bin = random_bytes(random_int(1, 1000));

View file

@ -1,7 +1,7 @@
--TEST--
Check for libsodium KDF
--SKIPIF--
<?php if (!extension_loaded("sodium")) print "skip"; ?>
--EXTENSIONS--
sodium
--FILE--
<?php
$key = sodium_crypto_kdf_keygen();

View file

@ -1,7 +1,7 @@
--TEST--
Check for libsodium-based key exchange
--SKIPIF--
<?php if (!extension_loaded("sodium")) print "skip"; ?>
--EXTENSIONS--
sodium
--FILE--
<?php
$client_seed = sodium_hex2bin('0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef');

View file

@ -1,7 +1,7 @@
--TEST--
Check for libsodium scalarmult
--SKIPIF--
<?php if (!extension_loaded("sodium")) print "skip"; ?>
--EXTENSIONS--
sodium
--FILE--
<?php
$n = sodium_hex2bin("5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb");

View file

@ -1,7 +1,7 @@
--TEST--
Check for libsodium secretbox
--SKIPIF--
<?php if (!extension_loaded("sodium")) print "skip"; ?>
--EXTENSIONS--
sodium
--FILE--
<?php
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);

View file

@ -1,8 +1,9 @@
--TEST--
Check for libsodium secretstream
--EXTENSIONS--
sodium
--SKIPIF--
<?php
if (!extension_loaded("sodium")) print "skip extension not loaded";
if (!defined('SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES')) print "skip libsodium without secretbytes";
?>
--FILE--

View file

@ -1,7 +1,7 @@
--TEST--
Check for libsodium shorthash
--SKIPIF--
<?php if (!extension_loaded("sodium")) print "skip"; ?>
--EXTENSIONS--
sodium
--FILE--
<?php
$m1 = 'message';

View file

@ -1,7 +1,7 @@
--TEST--
Check for libsodium ed25519 signatures
--SKIPIF--
<?php if (!extension_loaded("sodium")) print "skip"; ?>
--EXTENSIONS--
sodium
--FILE--
<?php
$keypair = sodium_crypto_sign_keypair();

View file

@ -1,7 +1,7 @@
--TEST--
Check for libsodium stream
--SKIPIF--
<?php if (!extension_loaded("sodium")) print "skip"; ?>
--EXTENSIONS--
sodium
--FILE--
<?php
$nonce = random_bytes(SODIUM_CRYPTO_STREAM_NONCEBYTES);

View file

@ -1,7 +1,7 @@
--TEST--
SodiumException backtraces do not contain function arguments
--SKIPIF--
<?php if (!extension_loaded("sodium")) print "skip"; ?>
--EXTENSIONS--
sodium
--FILE--
<?php

View file

@ -1,7 +1,7 @@
--TEST--
increment and add edge cases
--SKIPIF--
<?php if (!extension_loaded("sodium")) print "skip"; ?>
--EXTENSIONS--
sodium
--FILE--
<?php

View file

@ -1,7 +1,7 @@
--TEST--
Check for sodium presence
--SKIPIF--
<?php if (!extension_loaded("sodium")) print "skip"; ?>
--EXTENSIONS--
sodium
--FILE--
<?php
echo "sodium extension is available";

View file

@ -1,7 +1,9 @@
--TEST--
Check for libsodium argon2i
--EXTENSIONS--
sodium
--SKIPIF--
<?php if (!extension_loaded("sodium")) print "skip";
<?php
if (!defined('SODIUM_CRYPTO_PWHASH_SALTBYTES')) print "skip libsodium without argon2i"; ?>
--FILE--
<?php

View file

@ -1,7 +1,9 @@
--TEST--
Check for libsodium scrypt
--EXTENSIONS--
sodium
--SKIPIF--
<?php if (!extension_loaded("sodium")) print "skip";
<?php
if (!defined('SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES')) print "skip libsodium without scrypt"; ?>
--FILE--
<?php

View file

@ -1,7 +1,7 @@
--TEST--
TypeErrors will not contain param values in backtrace
--SKIPIF--
<?php if (!extension_loaded("sodium")) die("skip ext/sodium required"); ?>
--EXTENSIONS--
sodium
--FILE--
<?php
declare(strict_types=1);

View file

@ -1,7 +1,7 @@
--TEST--
Check for libsodium utils
--SKIPIF--
<?php if (!extension_loaded("sodium")) print "skip"; ?>
--EXTENSIONS--
sodium
--FILE--
<?php
$a = 'test';

View file

@ -1,7 +1,7 @@
--TEST--
Check for libsodium version
--SKIPIF--
<?php if (!extension_loaded("sodium")) print "skip"; ?>
--EXTENSIONS--
sodium
--FILE--
<?php
echo strlen(SODIUM_LIBRARY_VERSION) >= 5;

View file

@ -2057,15 +2057,26 @@ TEST $file
$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_prefix = IS_WINDOWS ? "php_" : "";
$missing = [];
foreach ($extensions as $req_ext) {
if (!in_array($req_ext, $loaded)) {
if ($req_ext == 'opcache') {
$ini_settings['zend_extension'][] = $ext_dir . DIRECTORY_SEPARATOR . $ext_prefix . $req_ext . '.' . PHP_SHLIB_SUFFIX;
$ext_file = $ext_dir . DIRECTORY_SEPARATOR . $ext_prefix . $req_ext . '.' . PHP_SHLIB_SUFFIX;
$ini_settings['zend_extension'][] = $ext_file;
} else {
$ini_settings['extension'][] = $ext_dir . DIRECTORY_SEPARATOR . $ext_prefix . $req_ext . '.' . PHP_SHLIB_SUFFIX;
$ext_file = $ext_dir . DIRECTORY_SEPARATOR . $ext_prefix . $req_ext . '.' . PHP_SHLIB_SUFFIX;
$ini_settings['extension'][] = $ext_file;
}
if (!is_readable($ext_file)) {
$missing[] = $req_ext;
}
}
}
if ($missing) {
$message = 'Required extension' . (count($missing) > 1 ? 's' : '')
. ' missing: ' . implode(', ', $missing);
return skip_test($tested, $tested_file, $shortname, $message);
}
}
// additional ini overwrites

View file

@ -1,10 +0,0 @@
--TEST--
phpt EXTENSIONS directive with static module
--EXTENSIONS--
SPL
--FILE--
<?php
var_dump(extension_loaded('spl'));
?>
--EXPECT--
bool(true)

View file

@ -1,13 +0,0 @@
--TEST--
phpt EXTENSIONS directive with nonexistent shared module
--INI--
error_log=
display_startup_errors=1
display_errors=1
--EXTENSIONS--
nonexistentsharedmodule
--FILE--
<?php
?>
--EXPECTF--
Warning: PHP Startup: Unable to load dynamic library '%snonexistentsharedmodule.%s' %A

View file

@ -1,5 +1,7 @@
--TEST--
phpt EXTENSIONS directive with shared module
phpt EXTENSIONS directive - shared module
--EXTENSIONS--
openssl
--SKIPIF--
<?php
$php = getenv('TEST_PHP_EXECUTABLE');
@ -8,8 +10,7 @@ if (false !== stripos(`$php -n -m`, 'openssl')) {
}
$ext_module = ini_get('extension_dir') . DIRECTORY_SEPARATOR . (substr(PHP_OS, 0, 3) === "WIN" ? "php_openssl." : "openssl.") . PHP_SHLIB_SUFFIX;
if( !file_exists($ext_module) ) die('skip openssl shared extension not found');
--EXTENSIONS--
openssl
--FILE--
<?php
var_dump(extension_loaded('openssl'));

View file

@ -0,0 +1,9 @@
--TEST--
phpt EXTENSIONS directive - static extension is present
--EXTENSIONS--
standard
--FILE--
<?php
var_dump(extension_loaded('standard'));
--EXPECT--
bool(true)