Skip to content

Commit

Permalink
Migrate unit and integration tests to new testing library
Browse files Browse the repository at this point in the history
  • Loading branch information
thekid committed Nov 19, 2023
1 parent 34c8407 commit b76569b
Show file tree
Hide file tree
Showing 60 changed files with 278 additions and 452 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ jobs:
echo "vendor/autoload.php" > composer.pth
- name: Run test suite
run: sh xp-run xp.unittest.TestRunner src/test/php
run: sh xp-run xp.test.Runner -r Dots src/test/php

- name: SQLite integration test suite
env:
SQLITE_DSN: sqlite://./unittest.db
run: sh xp-run xp.unittest.TestRunner src/it/php
run: sh xp-run xp.test.Runner -r Dots src/it/php
2 changes: 1 addition & 1 deletion ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ RDBMS support for the XP Framework: MySQL, Sybase, MSSQL, PostgreSQL, SQLite3, I
* Fixed handling of MySQL error code 1927 ("Connection was killed")
(@thekid)
* Overhauled test suite:
. Migrated tests to baseless
. Migrated tests to new testing library, see xp-framework/rfc#344
. Split unit and integration tests
. Added PHP 8.3 and PHP 8.4 to the test matrix
. Fixed integration tests to no longer reuse connections
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"php" : ">=7.0.0"
},
"require-dev" : {
"xp-framework/unittest": "^11.0 | ^10.0 | ^9.0 | ^8.0 | ^7.05"
"xp-framework/test": "^1.0"
},
"autoload" : {
"files" : ["src/main/php/autoload.php"]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,47 +1,43 @@
<?php namespace rdbms\unittest\integration;

use lang\{Runtime, Throwable};
use rdbms\DriverManager;
use unittest\Assert;
use unittest\{PrerequisitesNotMetError, Test, TestCase};
use lang\Runtime;
use rdbms\{DriverManager, SQLStatementFailedException};
use test\verify\Condition;
use test\{Assert, Before, After, Test};

/**
* Abstract deadlock test
*
*/
#[Condition('self::testDsnSet()')]
abstract class AbstractDeadlockTest {
protected static $DRIVER= null;
private $dsn;
private $close= [];

/** @return string */
protected abstract function driverName();
/** Verifies [NAME]_DSN */
public static function testDsnSet() {
return getenv(strtoupper(static::$DRIVER).'_DSN');
}

/** Initialize DSN */
public function __construct() {
$this->dsn= self::testDsnSet();
}

/**
* Retrieve database connection object
*
* @param bool connect default TRUE
* @return rdbms.DBConnection
* @param bool $connect default TRUE
* @return rdbms.DBConnection
*/
protected function db($connect= true) {
with ($db= DriverManager::getConnection($this->dsn)); {
if ($connect) $db->connect();
return $db;
}
$conn= DriverManager::getConnection($this->dsn);
$connect && $conn->connect();
return $conn;
}

/** @return void */
#[Before]
public function setUp() {
$env= strtoupper($this->driverName()).'_DSN';
if (!($this->dsn= getenv($env))) {
throw new PrerequisitesNotMetError('No credentials for '.nameof($this).', use '.$env.' to set');
}

try {
$this->dropTables();
$this->createTables();
} catch (Throwable $e) {
throw new PrerequisitesNotMetError($e->getMessage(), $e);
}
$this->dropTables();
$this->createTables();
}

/** @return void */
Expand Down Expand Up @@ -76,11 +72,11 @@ protected function dropTables() {

try {
$db->query('drop table table_a');
} catch (\rdbms\SQLStatementFailedException $ignored) {}
} catch (SQLStatementFailedException $ignored) {}

try {
$db->query('drop table table_b');
} catch (\rdbms\SQLStatementFailedException $ignored) {}
} catch (SQLStatementFailedException $ignored) {}

$db->close();
}
Expand All @@ -91,29 +87,29 @@ protected function dropTables() {
* @return lang.Process
*/
protected function newProcess() {
with ($rt= Runtime::getInstance()); {
$proc= $rt->newInstance(
$rt->startupOptions(),
'class',
'rdbms.unittest.integration.SQLRunner',
[$this->dsn]
);
Assert::equals('! Started', $proc->out->readLine());
return $proc;
}
$rt= Runtime::getInstance();
$proc= $rt->newInstance(
$rt->startupOptions(),
'class',
'rdbms.unittest.integration.SQLRunner',
[$this->dsn]
);
Assert::equals('! Started', $proc->out->readLine());
return $proc;
}

#[Test]
public function provokeDeadlock() {
$a= $this->newProcess();
$b= $this->newProcess();
$result= [];

$a->in->write("update table_a set pk= pk+1\n");
$b->in->write("update table_b set pk= pk+1\n");

// Reads "+ OK", on each process
$a->out->readLine();
$b->out->readLine();
$result[]= $a->out->readLine();
$result[]= $b->out->readLine();

// Now, process a hangs, waiting for lock to table_b
$a->in->write("update table_b set pk= pk+1\n");
Expand All @@ -125,17 +121,15 @@ public function provokeDeadlock() {
$a->in->close();
$b->in->close();

$result= [
$a->out->readLine(),
$b->out->readLine()
];
$result[]= $a->out->readLine();
$result[]= $b->out->readLine();
sort($result);

// Cleanup
$a->close(); $b->close();

// Assert one process succeeds, the other catches a deadlock exception
// We can't tell which one will do what, though.
Assert::equals(['+ OK', '- rdbms.SQLDeadlockException'], $result);
Assert::equals(['+ OK', '+ OK', '+ OK', '- rdbms.SQLDeadlockException'], $result);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php namespace rdbms\unittest\integration;

use rdbms\SQLStatementFailedException;
use unittest\{Assert, Before, Expect, Ignore, Test};
use test\{Assert, Before, Expect, Ignore, Test};
use util\Date;

/**
Expand All @@ -12,6 +12,7 @@
* @ext mssql
*/
class MsSQLIntegrationTest extends RdbmsIntegrationTest {
protected static $DRIVER= 'mssql';

/**
* Before class method: set minimun server severity;
Expand All @@ -29,9 +30,6 @@ public function setMinimumServerSeverity() {

/** @return string */
protected function tableName() { return '#unittest'; }

/** @return string */
protected function driverName() { return 'mssql'; }

/**
* Create autoincrement table
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,5 @@
<?php namespace rdbms\unittest\integration;

use unittest\Assert;
/**
* Deadlock test on mysql
*
*/
class MySQLDeadlockTest extends AbstractDeadlockTest {

/** @return string */
protected function driverName() { return 'mysql'; }

/** @return void */
#[After]
public function tearDown() {
parent::tearDown();

// Suppress "mysql_connect(): The mysql extension is deprecated [...]"
foreach (\xp::$errors as $file => $errors) {
if (strstr($file, 'MySQLConnection')) {
unset(\xp::$errors[$file]);
}
}
}
protected static $DRIVER= 'mysql';
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
<?php namespace rdbms\unittest\integration;

use rdbms\{SQLConnectionClosedException, SQLException, Transaction};
use unittest\Assert;
use unittest\{Ignore, Test};
use test\Assert;
use test\{Ignore, Test};

class MySQLIntegrationTest extends RdbmsIntegrationTest {

/** @return string */
protected function driverName() { return 'mysql'; }
protected static $DRIVER= 'mysql';

/**
* Create autoincrement table
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
<?php namespace rdbms\unittest\integration;

use unittest\Assert;
/**
* Deadlock test on PostgreSQL
*
*/
class PostgreSQLDeadlockTest extends AbstractDeadlockTest {

/** @return string */
protected function driverName() { return 'pgsql'; }
protected static $DRIVER= 'pgsql';
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
<?php namespace rdbms\unittest\integration;

use rdbms\SQLException;
use unittest\{Assert, Ignore, Test};
use test\{Assert, Ignore, Test};

class PostgreSQLIntegrationTest extends RdbmsIntegrationTest {

/** @return string */
protected function driverName() { return 'pgsql'; }

protected static $DRIVER= 'pgsql';

/**
* Create autoincrement table
*
Expand Down Expand Up @@ -212,7 +210,7 @@ public function selectSmallintOne() { }
#[Test, Ignore('Cast to smallint not supported by PostgreSQL')]
public function selectSmallintZero() { }

#[Test]
#[Test]
public function reconnects_when_server_disconnects() {
$conn= $this->db();
$before= $conn->query('select pg_backend_pid() as id')->next('id');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
<?php namespace rdbms\unittest\integration;

use lang\{MethodNotImplementedException, Throwable};
use lang\{MethodNotImplementedException, Throwable, IllegalArgumentException};
use rdbms\{DBEvent, DSN, DriverManager, ResultSet, SQLConnectException, SQLException, SQLStateException, SQLStatementFailedException};
use unittest\{Assert, Before, Expect, PrerequisitesNotMetError, Test};
use test\verify\Condition;
use test\{Assert, Before, Expect, Test};
use util\{Bytes, Date, Observer};

/**
* Base class for all RDBMS integration tests
*/
#[Condition('self::testDsnSet()')]
abstract class RdbmsIntegrationTest {
protected static $DRIVER= null;

private $dsn;
private $close= [];

#[Before]
public function verify() {
$env= strtoupper($this->driverName()).'_DSN';
if (!($this->dsn= getenv($env))) {
throw new PrerequisitesNotMetError('No credentials for '.nameof($this).', use '.$env.' to set');
}
/** Verifies [NAME]_DSN */
public static function testDsnSet() {
return getenv(strtoupper(static::$DRIVER).'_DSN');
}

/** Initialize DSN */
public function __construct() {
$this->dsn= self::testDsnSet();
}

#[After]
Expand All @@ -34,13 +37,6 @@ public function disconnect() {
*/
protected function tableName() { return 'unittest'; }

/**
* Retrieve driver name
*
* @return string
*/
abstract protected function driverName();

/**
* Retrieve database connection object
*
Expand Down
8 changes: 4 additions & 4 deletions src/it/php/rdbms/unittest/integration/SQLRunner.class.php
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<?php namespace rdbms\unittest\integration;

use rdbms\DriverManager;
use rdbms\{DriverManager, SQLException, Transaction};
use util\cmd\Console;

/**
* SQL Runner used inside deadlock tests
*
* @see xp://net.xp_framework.unittest.rdbms.integration.AbstractDeadlockTest
* @see net.xp_framework.unittest.rdbms.integration.AbstractDeadlockTest
*/
class SQLRunner {

Expand All @@ -19,7 +19,7 @@ public static function main(array $args) {
$db= DriverManager::getConnection($args[0]);
try {
$db->connect();
$tran= $db->begin(new \rdbms\Transaction('process'));
$tran= $db->begin(new Transaction('process'));

Console::$out->writeLine('! Started');
while ($sql= Console::$in->readLine()) {
Expand All @@ -28,7 +28,7 @@ public static function main(array $args) {
}

$tran->commit();
} catch (\rdbms\SQLException $e) {
} catch (SQLException $e) {
Console::$out->writeLine('- ', nameof($e));
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
<?php namespace rdbms\unittest\integration;

use rdbms\ResultSet;
use unittest\{Assert, Ignore, Test};
use test\{Assert, Ignore, Test};
use util\Date;

/**
* SQLite integration test
*
* @ext sqlite
*/
class SQLiteIntegrationTest extends RdbmsIntegrationTest {

/** @return string */
protected function driverName() { return 'sqlite'; }
protected static $DRIVER= 'sqlite';

/**
* Create autoincrement table
Expand Down
Loading

0 comments on commit b76569b

Please sign in to comment.