Skip to content

Commit b76569b

Browse files
committed
Migrate unit and integration tests to new testing library
See xp-framework/rfc#344
1 parent 34c8407 commit b76569b

File tree

60 files changed

+278
-452
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+278
-452
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ jobs:
5454
echo "vendor/autoload.php" > composer.pth
5555
5656
- name: Run test suite
57-
run: sh xp-run xp.unittest.TestRunner src/test/php
57+
run: sh xp-run xp.test.Runner -r Dots src/test/php
5858

5959
- name: SQLite integration test suite
6060
env:
6161
SQLITE_DSN: sqlite://./unittest.db
62-
run: sh xp-run xp.unittest.TestRunner src/it/php
62+
run: sh xp-run xp.test.Runner -r Dots src/it/php

ChangeLog.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ RDBMS support for the XP Framework: MySQL, Sybase, MSSQL, PostgreSQL, SQLite3, I
1212
* Fixed handling of MySQL error code 1927 ("Connection was killed")
1313
(@thekid)
1414
* Overhauled test suite:
15-
. Migrated tests to baseless
15+
. Migrated tests to new testing library, see xp-framework/rfc#344
1616
. Split unit and integration tests
1717
. Added PHP 8.3 and PHP 8.4 to the test matrix
1818
. Fixed integration tests to no longer reuse connections

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"php" : ">=7.0.0"
1414
},
1515
"require-dev" : {
16-
"xp-framework/unittest": "^11.0 | ^10.0 | ^9.0 | ^8.0 | ^7.05"
16+
"xp-framework/test": "^1.0"
1717
},
1818
"autoload" : {
1919
"files" : ["src/main/php/autoload.php"]
Lines changed: 40 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,43 @@
11
<?php namespace rdbms\unittest\integration;
22

3-
use lang\{Runtime, Throwable};
4-
use rdbms\DriverManager;
5-
use unittest\Assert;
6-
use unittest\{PrerequisitesNotMetError, Test, TestCase};
3+
use lang\Runtime;
4+
use rdbms\{DriverManager, SQLStatementFailedException};
5+
use test\verify\Condition;
6+
use test\{Assert, Before, After, Test};
77

8-
/**
9-
* Abstract deadlock test
10-
*
11-
*/
8+
#[Condition('self::testDsnSet()')]
129
abstract class AbstractDeadlockTest {
10+
protected static $DRIVER= null;
1311
private $dsn;
12+
private $close= [];
1413

15-
/** @return string */
16-
protected abstract function driverName();
14+
/** Verifies [NAME]_DSN */
15+
public static function testDsnSet() {
16+
return getenv(strtoupper(static::$DRIVER).'_DSN');
17+
}
18+
19+
/** Initialize DSN */
20+
public function __construct() {
21+
$this->dsn= self::testDsnSet();
22+
}
1723

1824
/**
1925
* Retrieve database connection object
2026
*
21-
* @param bool connect default TRUE
22-
* @return rdbms.DBConnection
27+
* @param bool $connect default TRUE
28+
* @return rdbms.DBConnection
2329
*/
2430
protected function db($connect= true) {
25-
with ($db= DriverManager::getConnection($this->dsn)); {
26-
if ($connect) $db->connect();
27-
return $db;
28-
}
31+
$conn= DriverManager::getConnection($this->dsn);
32+
$connect && $conn->connect();
33+
return $conn;
2934
}
3035

3136
/** @return void */
3237
#[Before]
3338
public function setUp() {
34-
$env= strtoupper($this->driverName()).'_DSN';
35-
if (!($this->dsn= getenv($env))) {
36-
throw new PrerequisitesNotMetError('No credentials for '.nameof($this).', use '.$env.' to set');
37-
}
38-
39-
try {
40-
$this->dropTables();
41-
$this->createTables();
42-
} catch (Throwable $e) {
43-
throw new PrerequisitesNotMetError($e->getMessage(), $e);
44-
}
39+
$this->dropTables();
40+
$this->createTables();
4541
}
4642

4743
/** @return void */
@@ -76,11 +72,11 @@ protected function dropTables() {
7672

7773
try {
7874
$db->query('drop table table_a');
79-
} catch (\rdbms\SQLStatementFailedException $ignored) {}
75+
} catch (SQLStatementFailedException $ignored) {}
8076

8177
try {
8278
$db->query('drop table table_b');
83-
} catch (\rdbms\SQLStatementFailedException $ignored) {}
79+
} catch (SQLStatementFailedException $ignored) {}
8480

8581
$db->close();
8682
}
@@ -91,29 +87,29 @@ protected function dropTables() {
9187
* @return lang.Process
9288
*/
9389
protected function newProcess() {
94-
with ($rt= Runtime::getInstance()); {
95-
$proc= $rt->newInstance(
96-
$rt->startupOptions(),
97-
'class',
98-
'rdbms.unittest.integration.SQLRunner',
99-
[$this->dsn]
100-
);
101-
Assert::equals('! Started', $proc->out->readLine());
102-
return $proc;
103-
}
90+
$rt= Runtime::getInstance();
91+
$proc= $rt->newInstance(
92+
$rt->startupOptions(),
93+
'class',
94+
'rdbms.unittest.integration.SQLRunner',
95+
[$this->dsn]
96+
);
97+
Assert::equals('! Started', $proc->out->readLine());
98+
return $proc;
10499
}
105100

106101
#[Test]
107102
public function provokeDeadlock() {
108103
$a= $this->newProcess();
109104
$b= $this->newProcess();
105+
$result= [];
110106

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

114110
// Reads "+ OK", on each process
115-
$a->out->readLine();
116-
$b->out->readLine();
111+
$result[]= $a->out->readLine();
112+
$result[]= $b->out->readLine();
117113

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

128-
$result= [
129-
$a->out->readLine(),
130-
$b->out->readLine()
131-
];
124+
$result[]= $a->out->readLine();
125+
$result[]= $b->out->readLine();
132126
sort($result);
133127

134128
// Cleanup
135129
$a->close(); $b->close();
136130

137131
// Assert one process succeeds, the other catches a deadlock exception
138132
// We can't tell which one will do what, though.
139-
Assert::equals(['+ OK', '- rdbms.SQLDeadlockException'], $result);
133+
Assert::equals(['+ OK', '+ OK', '+ OK', '- rdbms.SQLDeadlockException'], $result);
140134
}
141135
}

src/it/php/rdbms/unittest/integration/MsSQLIntegrationTest.class.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php namespace rdbms\unittest\integration;
22

33
use rdbms\SQLStatementFailedException;
4-
use unittest\{Assert, Before, Expect, Ignore, Test};
4+
use test\{Assert, Before, Expect, Ignore, Test};
55
use util\Date;
66

77
/**
@@ -12,6 +12,7 @@
1212
* @ext mssql
1313
*/
1414
class MsSQLIntegrationTest extends RdbmsIntegrationTest {
15+
protected static $DRIVER= 'mssql';
1516

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

3031
/** @return string */
3132
protected function tableName() { return '#unittest'; }
32-
33-
/** @return string */
34-
protected function driverName() { return 'mssql'; }
3533

3634
/**
3735
* Create autoincrement table
Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,5 @@
11
<?php namespace rdbms\unittest\integration;
22

3-
use unittest\Assert;
4-
/**
5-
* Deadlock test on mysql
6-
*
7-
*/
83
class MySQLDeadlockTest extends AbstractDeadlockTest {
9-
10-
/** @return string */
11-
protected function driverName() { return 'mysql'; }
12-
13-
/** @return void */
14-
#[After]
15-
public function tearDown() {
16-
parent::tearDown();
17-
18-
// Suppress "mysql_connect(): The mysql extension is deprecated [...]"
19-
foreach (\xp::$errors as $file => $errors) {
20-
if (strstr($file, 'MySQLConnection')) {
21-
unset(\xp::$errors[$file]);
22-
}
23-
}
24-
}
4+
protected static $DRIVER= 'mysql';
255
}

src/it/php/rdbms/unittest/integration/MySQLIntegrationTest.class.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
<?php namespace rdbms\unittest\integration;
22

33
use rdbms\{SQLConnectionClosedException, SQLException, Transaction};
4-
use unittest\Assert;
5-
use unittest\{Ignore, Test};
4+
use test\Assert;
5+
use test\{Ignore, Test};
66

77
class MySQLIntegrationTest extends RdbmsIntegrationTest {
8-
9-
/** @return string */
10-
protected function driverName() { return 'mysql'; }
8+
protected static $DRIVER= 'mysql';
119

1210
/**
1311
* Create autoincrement table
Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
11
<?php namespace rdbms\unittest\integration;
22

3-
use unittest\Assert;
4-
/**
5-
* Deadlock test on PostgreSQL
6-
*
7-
*/
83
class PostgreSQLDeadlockTest extends AbstractDeadlockTest {
9-
10-
/** @return string */
11-
protected function driverName() { return 'pgsql'; }
4+
protected static $DRIVER= 'pgsql';
125
}

src/it/php/rdbms/unittest/integration/PostgreSQLIntegrationTest.class.php

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
<?php namespace rdbms\unittest\integration;
22

33
use rdbms\SQLException;
4-
use unittest\{Assert, Ignore, Test};
4+
use test\{Assert, Ignore, Test};
55

66
class PostgreSQLIntegrationTest extends RdbmsIntegrationTest {
7-
8-
/** @return string */
9-
protected function driverName() { return 'pgsql'; }
10-
7+
protected static $DRIVER= 'pgsql';
8+
119
/**
1210
* Create autoincrement table
1311
*
@@ -212,7 +210,7 @@ public function selectSmallintOne() { }
212210
#[Test, Ignore('Cast to smallint not supported by PostgreSQL')]
213211
public function selectSmallintZero() { }
214212

215-
#[Test]
213+
#[Test]
216214
public function reconnects_when_server_disconnects() {
217215
$conn= $this->db();
218216
$before= $conn->query('select pg_backend_pid() as id')->next('id');

src/it/php/rdbms/unittest/integration/RdbmsIntegrationTest.class.php

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,26 @@
11
<?php namespace rdbms\unittest\integration;
22

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

8-
/**
9-
* Base class for all RDBMS integration tests
10-
*/
9+
#[Condition('self::testDsnSet()')]
1110
abstract class RdbmsIntegrationTest {
11+
protected static $DRIVER= null;
12+
1213
private $dsn;
1314
private $close= [];
1415

15-
#[Before]
16-
public function verify() {
17-
$env= strtoupper($this->driverName()).'_DSN';
18-
if (!($this->dsn= getenv($env))) {
19-
throw new PrerequisitesNotMetError('No credentials for '.nameof($this).', use '.$env.' to set');
20-
}
16+
/** Verifies [NAME]_DSN */
17+
public static function testDsnSet() {
18+
return getenv(strtoupper(static::$DRIVER).'_DSN');
19+
}
20+
21+
/** Initialize DSN */
22+
public function __construct() {
23+
$this->dsn= self::testDsnSet();
2124
}
2225

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

37-
/**
38-
* Retrieve driver name
39-
*
40-
* @return string
41-
*/
42-
abstract protected function driverName();
43-
4440
/**
4541
* Retrieve database connection object
4642
*

0 commit comments

Comments
 (0)