Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions ext/ldap/tests/skipifbindfailure.inc
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
<?php
require_once 'connect.inc';
require_once dirname(__DIR__, 3) . '/tests/probe_cache.inc';

if ($skip_on_bind_failure) {
$configuration = [$uri, $user, $passwd, $protocol_version];

$link = ldap_connect($uri);
ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
if (!@ldap_bind($link, $user, $passwd))
die(sprintf("skip Can't bind to LDAP Server - [%d] %s", ldap_errno($link), ldap_error($link)));
$reason = ProbeCache::getFailure('ldap.bind', $configuration, static function () use ($uri, $user, $passwd, $protocol_version): ?string {
$link = ldap_connect($uri);
ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
if (!@ldap_bind($link, $user, $passwd)) {
return sprintf("Can't bind to LDAP Server - [%d] %s", ldap_errno($link), ldap_error($link));
}

ldap_unbind($link);
return null;
});

ldap_unbind($link);
if (is_string($reason)) {
die("skip $reason");
}
}

if (isset($require_vendor)) {
Expand Down
21 changes: 17 additions & 4 deletions ext/mysqli/tests/skipifconnectfailure.inc
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
<?php
require_once 'connect.inc';
$link = @my_mysqli_connect($host, $user, $passwd, $db, $port, $socket);
if (!is_object($link))
die(sprintf("skip Can't connect to MySQL Server - [%d] %s", mysqli_connect_errno(), mysqli_connect_error()));
mysqli_close($link);
require_once dirname(__DIR__, 3) . '/tests/probe_cache.inc';

$configuration = [$host, $port, $user, $passwd, $db, $socket, get_environment_connection_flags()];

$reason = ProbeCache::getFailure('mysqli', $configuration, static function () use ($host, $user, $passwd, $db, $port, $socket): ?string {
$link = @my_mysqli_connect($host, $user, $passwd, $db, $port, $socket);
if (!is_object($link)) {
return sprintf("Can't connect to MySQL Server - [%d] %s", mysqli_connect_errno(), mysqli_connect_error());
}

mysqli_close($link);
return null;
});

if (is_string($reason)) {
die("skip $reason");
}
?>
39 changes: 29 additions & 10 deletions ext/mysqli/tests/test_setup/test_helpers.inc
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

require_once dirname(__DIR__, 4) . '/tests/probe_cache.inc';

function get_default_host(): string {
static $host = null;
if ($host === null) {
Expand Down Expand Up @@ -110,24 +112,41 @@ function default_mysqli_connect(): \mysqli{
function mysqli_check_skip_test(): void {
mysqli_connect_or_skip();
}
function mysqli_connect_or_skip() {
try {
return default_mysqli_connect();
} catch (\mysqli_sql_exception) {
die(sprintf("skip Can't connect to MySQL Server - [%d] %s", mysqli_connect_errno(), mysqli_connect_error()));

function mysqli_connect_or_skip(): mysqli {
$connection = null;
$configuration = [
get_default_host(),
get_default_port(),
get_default_user(),
get_default_password(),
get_default_database(),
get_default_socket(),
get_environment_connection_flags(),
];

$reason = ProbeCache::getFailure('mysqli', $configuration, static function () use (&$connection): ?string {
try {
$connection = default_mysqli_connect();
return null;
} catch (mysqli_sql_exception $e) {
return sprintf("Can't connect to MySQL Server - [%d] %s", mysqli_connect_errno(), mysqli_connect_error());
}
});

if (is_string($reason)) {
die("skip $reason");
}

return $connection;
}
function have_innodb(mysqli $link): bool {
$res = $link->query("SELECT SUPPORT FROM INFORMATION_SCHEMA.ENGINES WHERE ENGINE = 'InnoDB'");
$supported = $res->fetch_column();
return $supported === 'YES' || $supported === 'DEFAULT';
}
function mysqli_check_innodb_support_skip_test(): void {
try {
$link = default_mysqli_connect();
} catch (\mysqli_sql_exception) {
die(sprintf("skip Can't connect to MySQL Server - [%d] %s", mysqli_connect_errno(), mysqli_connect_error()));
}
$link = mysqli_connect_or_skip();
if (! have_innodb($link)) {
die(sprintf("skip Needs InnoDB support"));
}
Expand Down
16 changes: 13 additions & 3 deletions ext/odbc/tests/skipif.inc
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
<?php

include 'config.inc';
require_once dirname(__DIR__, 3) . '/tests/probe_cache.inc';

$conn = @odbc_connect($dsn, $user, $pass);
if (!$conn) {
die('skip could not connect');
$conn = null;
$reason = ProbeCache::getFailure('odbc', [$dsn, $user, $pass], static function () use ($dsn, $user, $pass, &$conn): ?string {
$conn = @odbc_connect($dsn, $user, $pass);
if (!$conn) {
return 'could not connect';
}

return null;
});

if (is_string($reason)) {
die("skip $reason");
}
77 changes: 58 additions & 19 deletions ext/pdo/tests/pdo_test.inc
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?php
# PDO test framework utilities

require_once dirname(__DIR__, 3) . '/tests/probe_cache.inc';

if (getenv('PDOTEST_DSN') === false) {
$common = '';
$append = false;
Expand All @@ -18,41 +20,51 @@ if (getenv('PDOTEST_DSN') === false) {
class PDOTest {
// create an instance of the PDO driver, based on
// the current environment
static function factory($classname = PDO::class, bool $useConnectMethod = false) {
static function factory($classname = PDO::class, bool $useConnectMethod = false, ?array $attributes = null) {
$dsn = getenv('PDOTEST_DSN');
$user = getenv('PDOTEST_USER');
$pass = getenv('PDOTEST_PASS');
$attr = getenv('PDOTEST_ATTR');
if (is_string($attr) && strlen($attr)) {
$attr = unserialize($attr);
} else {
$attr = null;
if ($attributes === null) {
$attributes = self::getAttributes('PDOTEST_ATTR');
if (getenv('TEST_PHP_EVALUATING_SKIPIF') === '1') {
$skipAttributes = self::getAttributes('PDOTEST_SKIP_ATTR');
if ($skipAttributes !== null) {
$attributes = $skipAttributes + ($attributes ?? []);
}
}
}

if ($user === false) $user = NULL;
if ($pass === false) $pass = NULL;

if ($useConnectMethod) {
$db = $classname::connect($dsn, $user, $pass, $attr);
} else {
$db = new $classname($dsn, $user, $pass, $attr);
if (getenv('TEST_PHP_EVALUATING_SKIPIF') !== '1') {
return self::createConnection($classname, $useConnectMethod, $dsn, $user, $pass, $attributes);
}

if (!$db) {
die("Could not create PDO object (DSN=$dsn, user=$user)\n");
$database = null;
$exception = null;
$configuration = [$classname, $useConnectMethod, $dsn, $user, $pass, $attributes];

$reason = ProbeCache::getFailure('pdo', $configuration, static function () use (&$database, &$exception, $classname, $useConnectMethod, $dsn, $user, $pass, $attributes): ?string {
try {
$database = self::createConnection($classname, $useConnectMethod, $dsn, $user, $pass, $attributes);
return null;
} catch (PDOException $e) {
$exception = $e;
return $e->getMessage();
}
});

if (is_string($reason)) {
throw $exception ?? new PDOException($reason);
}
// Ignore errors about non-existent tables
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);

$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
$db->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
return $db;
return $database;
}

static function skip() {
try {
$db = PDOTest::factory();
self::factory();
} catch (PDOException $e) {
die("skip " . $e->getMessage());
}
Expand Down Expand Up @@ -95,6 +107,33 @@ class PDOTest {
default => $db->exec("DROP TABLE IF EXISTS $tableName"),
};
}

private static function createConnection($classname, bool $useConnectMethod, $dsn, $user, $pass, ?array $attributes) {
if ($useConnectMethod) {
$db = $classname::connect($dsn, $user, $pass, $attributes);
} else {
$db = new $classname($dsn, $user, $pass, $attributes);
}

if (!$db) {
die("Could not create PDO object (DSN=$dsn, user=$user)\n");
}
// Ignore errors about non-existent tables
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);

$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
$db->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
return $db;
}

private static function getAttributes(string $environmentVariable): ?array {
$attributes = getenv($environmentVariable);
if (is_string($attributes) && strlen($attributes)) {
return unserialize($attributes);
}
return null;
}
}
/** See https://stackoverflow.com/a/3732466 */
function get_dummy_sql_request(): string
Expand Down
10 changes: 9 additions & 1 deletion ext/pdo_dblib/tests/common.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,19 @@ pdo_dblib
--REDIRECTTEST--
# magic auto-configuration

return [
$config = [
'ENV' => [
'PDOTEST_DSN' => getenv('PDO_DBLIB_TEST_DSN') ?: 'dblib:host=localhost;dbname=test',
'PDOTEST_USER' => getenv('PDO_DBLIB_TEST_USER') ?: 'php',
'PDOTEST_PASS' => getenv('PDO_DBLIB_TEST_PASS') ?: 'password',
],
'TESTS' => __DIR__ . '/ext/pdo/tests',
];

if (getenv('PDO_DBLIB_TEST_DSN') === false) {
$config['ENV']['PDOTEST_SKIP_ATTR'] = serialize([
Pdo\Dblib::ATTR_CONNECTION_TIMEOUT => 1,
]);
}

return $config;
31 changes: 25 additions & 6 deletions ext/pdo_dblib/tests/config.inc
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

require_once dirname(__DIR__, 3) . '/tests/probe_cache.inc';

// bug #72969 reflects a bug with FreeTDS, not with pdo_dblib
// this function will version detect so the relevant tests can XFAILIF
// assume this bug isn't present if not using FreeTDS
Expand Down Expand Up @@ -41,15 +43,32 @@ function setAttributes(PDO $db) {
}

function getDbConnection(string $class = PDO::class, ?array $attributes = null) {
$connectionAttributes = $attributes;
$evaluatingSkipif = getenv('TEST_PHP_EVALUATING_SKIPIF') === '1';
if ($evaluatingSkipif && $connectionAttributes === null && getenv('PDO_DBLIB_TEST_DSN') === false) {
$connectionAttributes = [Pdo\Dblib::ATTR_CONNECTION_TIMEOUT => 1];
}
[$dsn, $user, $pass] = getCredentials();

try {
$db = new $class($dsn, $user, $pass, $attributes);
if ($attributes === null) {
setAttributes($db);
$db = null;
$probe = static function () use (&$db, $class, $dsn, $user, $pass, $attributes, $connectionAttributes): ?string {
try {
$db = new $class($dsn, $user, $pass, $connectionAttributes);
if ($attributes === null) {
setAttributes($db);
}
return null;
} catch (PDOException $e) {
return $e->getMessage();
}
} catch (PDOException $e) {
die('skip ' . $e->getMessage());
};

$reason = $evaluatingSkipif
? ProbeCache::getFailure('pdo', [$class, false, $dsn, $user, $pass, $connectionAttributes], $probe)
: $probe();

if (is_string($reason)) {
die('skip ' . $reason);
}

return $db;
Expand Down
48 changes: 37 additions & 11 deletions ext/pdo_mysql/tests/inc/mysql_pdo_test.inc
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,29 @@ class MySQLPDOTest extends PDOTest {
$attr = is_string($attr) && strlen($attr) ? unserialize($attr) : null;
}

if ($useConnectMethod) {
$db = $classname::connect($dsn, $user, $pass, $attr);
} else {
$db = new $classname($dsn, $user, $pass, $attr);
if (getenv('TEST_PHP_EVALUATING_SKIPIF') !== '1') {
return self::createConnection($classname, $useConnectMethod, $dsn, $user, $pass, $attr);
}

if (!$db) {
die("Could not create PDO object (DSN=$dsn, user=$user)\n");
}
$database = null;
$exception = null;
$configuration = [$classname, $useConnectMethod, $dsn, $user, $pass, $attr];

$reason = ProbeCache::getFailure('pdo', $configuration, static function () use (&$database, &$exception, $classname, $useConnectMethod, $dsn, $user, $pass, $attr): ?string {
try {
$database = self::createConnection($classname, $useConnectMethod, $dsn, $user, $pass, $attr);
return null;
} catch (PDOException $e) {
$exception = $e;
return $e->getMessage();
}
});

$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
$db->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
if (is_string($reason)) {
throw $exception ?? new PDOException($reason);
}

return $db;
return $database;
}

static function factoryWithAttr($attr) {
Expand Down Expand Up @@ -168,7 +177,7 @@ class MySQLPDOTest extends PDOTest {

static function skip() {
try {
$db = self::factory();
self::factory();
} catch (PDOException $e) {
die('skip could not connect');
}
Expand Down Expand Up @@ -212,5 +221,22 @@ class MySQLPDOTest extends PDOTest {
$message = $message ?? 'skip Transactional engine not found';
if (false == self::detect_transactional_mysql_engine($db)) die($message);
}

private static function createConnection($classname, bool $useConnectMethod, $dsn, $user, $pass, $attr) {
if ($useConnectMethod) {
$db = $classname::connect($dsn, $user, $pass, $attr);
} else {
$db = new $classname($dsn, $user, $pass, $attr);
}

if (!$db) {
die("Could not create PDO object (DSN=$dsn, user=$user)\n");
}

$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
$db->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);

return $db;
}
}
?>
Loading
Loading