From 4e23b380a9cecdcc7c0ba8a99814c227284aa07c Mon Sep 17 00:00:00 2001 From: Aaron Piotrowski Date: Sun, 7 May 2023 00:05:00 -0500 Subject: [PATCH] Add nested transaction tests --- test/AbstractConnectionTest.php | 82 ++++++++++++++++++++++++++++- test/AbstractLinkTest.php | 76 -------------------------- test/PgSqlConnectionTest.php | 3 +- test/PgSqlNestedTransactionTest.php | 44 ++++++++++++++++ test/PgSqlPoolTest.php | 2 +- test/PqNestedTransactionTest.php | 42 +++++++++++++++ test/PqPoolTest.php | 2 +- 7 files changed, 170 insertions(+), 81 deletions(-) create mode 100644 test/PgSqlNestedTransactionTest.php create mode 100644 test/PqNestedTransactionTest.php diff --git a/test/AbstractConnectionTest.php b/test/AbstractConnectionTest.php index 3ed57bb..3426966 100644 --- a/test/AbstractConnectionTest.php +++ b/test/AbstractConnectionTest.php @@ -2,7 +2,14 @@ namespace Amp\Postgres\Test; +use Amp\Future; +use Amp\Postgres\PostgresListener; +use Amp\Postgres\PostgresNotification; +use Amp\Postgres\QueryExecutionError; use Amp\Sql\ConnectionException; +use Amp\Sql\QueryError; +use Amp\Sql\SqlException; +use Revolt\EventLoop; use function Amp\async; abstract class AbstractConnectionTest extends AbstractLinkTest @@ -24,10 +31,83 @@ public function testConnectionCloseDuringQuery(): void try { $query->await(); self::fail(\sprintf('Expected %s to be thrown', ConnectionException::class)); - } catch (ConnectionException) { + } catch (SqlException) { // Expected } $this->assertLessThan(0.1, \microtime(true) - $start); } + + public function testListen() + { + $channel = "test"; + $listener = $this->link->listen($channel); + + $this->assertInstanceOf(PostgresListener::class, $listener); + $this->assertSame($channel, $listener->getChannel()); + + EventLoop::delay(0.1, function () use ($channel): void { + $this->link->query(\sprintf("NOTIFY %s, '%s'", $channel, '0')); + $this->link->query(\sprintf("NOTIFY %s, '%s'", $channel, '1')); + }); + + $count = 0; + EventLoop::delay(0.2, fn () => $listener->unlisten()); + + /** @var PostgresNotification $notification */ + foreach ($listener as $notification) { + $this->assertSame($notification->getPayload(), (string) $count++); + } + + $this->assertSame(2, $count); + } + + /** + * @depends testListen + */ + public function testNotify() + { + $channel = "test"; + $listener = $this->link->listen($channel); + + EventLoop::delay(0.1, function () use ($channel) { + $this->link->notify($channel, '0'); + $this->link->notify($channel, '1'); + }); + + $count = 0; + EventLoop::delay(0.2, fn () => $listener->unlisten()); + + /** @var PostgresNotification $notification */ + foreach ($listener as $notification) { + $this->assertSame($notification->getPayload(), (string) $count++); + } + + $this->assertSame(2, $count); + } + + /** + * @depends testListen + */ + public function testListenOnSameChannel() + { + $this->expectException(QueryError::class); + $this->expectExceptionMessage('Already listening on channel'); + + $channel = "test"; + Future\await([$this->link->listen($channel), $this->link->listen($channel)]); + } + + public function testQueryAfterErroredQuery() + { + try { + $result = $this->link->query("INSERT INTO test VALUES ('github', 'com', '{1, 2, 3}', true, 4.2)"); + } catch (QueryExecutionError $exception) { + // Expected exception due to duplicate key. + } + + $result = $this->link->query("INSERT INTO test VALUES ('gitlab', 'com', '{1, 2, 3}', true, 4.2)"); + + $this->assertSame(1, $result->getRowCount()); + } } diff --git a/test/AbstractLinkTest.php b/test/AbstractLinkTest.php index 5f09ce8..c894245 100644 --- a/test/AbstractLinkTest.php +++ b/test/AbstractLinkTest.php @@ -7,8 +7,6 @@ use Amp\Postgres\ByteA; use Amp\Postgres\PostgresConnection; use Amp\Postgres\PostgresLink; -use Amp\Postgres\PostgresListener; -use Amp\Postgres\PostgresNotification; use Amp\Postgres\PostgresTransaction; use Amp\Postgres\QueryExecutionError; use Amp\Sql\QueryError; @@ -16,7 +14,6 @@ use Amp\Sql\Statement; use Amp\Sql\TransactionError; use Amp\Sql\TransactionIsolationLevel; -use Revolt\EventLoop; use function Amp\async; abstract class AbstractLinkTest extends AsyncTestCase @@ -575,79 +572,6 @@ public function testTransaction() } } - public function testListen() - { - $channel = "test"; - $listener = $this->link->listen($channel); - - $this->assertInstanceOf(PostgresListener::class, $listener); - $this->assertSame($channel, $listener->getChannel()); - - EventLoop::delay(0.1, function () use ($channel): void { - $this->link->query(\sprintf("NOTIFY %s, '%s'", $channel, '0')); - $this->link->query(\sprintf("NOTIFY %s, '%s'", $channel, '1')); - }); - - $count = 0; - EventLoop::delay(0.2, fn () => $listener->unlisten()); - - /** @var PostgresNotification $notification */ - foreach ($listener as $notification) { - $this->assertSame($notification->getPayload(), (string) $count++); - } - - $this->assertSame(2, $count); - } - - /** - * @depends testListen - */ - public function testNotify() - { - $channel = "test"; - $listener = $this->link->listen($channel); - - EventLoop::delay(0.1, function () use ($channel) { - $this->link->notify($channel, '0'); - $this->link->notify($channel, '1'); - }); - - $count = 0; - EventLoop::delay(0.2, fn () => $listener->unlisten()); - - /** @var PostgresNotification $notification */ - foreach ($listener as $notification) { - $this->assertSame($notification->getPayload(), (string) $count++); - } - - $this->assertSame(2, $count); - } - - /** - * @depends testListen - */ - public function testListenOnSameChannel() - { - $this->expectException(QueryError::class); - $this->expectExceptionMessage('Already listening on channel'); - - $channel = "test"; - Future\await([$this->link->listen($channel), $this->link->listen($channel)]); - } - - public function testQueryAfterErroredQuery() - { - try { - $result = $this->link->query("INSERT INTO test VALUES ('github', 'com', '{1, 2, 3}', true, 4.2)"); - } catch (QueryExecutionError $exception) { - // Expected exception due to duplicate key. - } - - $result = $this->link->query("INSERT INTO test VALUES ('gitlab', 'com', '{1, 2, 3}', true, 4.2)"); - - $this->assertSame(1, $result->getRowCount()); - } - public function provideInsertParameters(): iterable { $data = \str_repeat("\0", 10); diff --git a/test/PgSqlConnectionTest.php b/test/PgSqlConnectionTest.php index 9622be2..61d1657 100644 --- a/test/PgSqlConnectionTest.php +++ b/test/PgSqlConnectionTest.php @@ -13,8 +13,7 @@ */ class PgSqlConnectionTest extends AbstractConnectionTest { - /** @var \PgSql\Connection PostgreSQL connection resource. */ - protected $handle; + protected ?\PgSql\Connection $handle = null; public function createLink(string $connectionString): PostgresLink { diff --git a/test/PgSqlNestedTransactionTest.php b/test/PgSqlNestedTransactionTest.php new file mode 100644 index 0000000..36fda6f --- /dev/null +++ b/test/PgSqlNestedTransactionTest.php @@ -0,0 +1,44 @@ +query(self::DROP_QUERY); + + $connection->query(self::CREATE_QUERY); + + foreach ($this->getParams() as $row) { + $connection->execute(self::INSERT_QUERY, $row); + } + + $this->connection = $connection; + $this->transaction = $connection->beginTransaction(); + + return new PostgresNestableTransaction($this->transaction); + } + + public function tearDown(): void + { + $this->transaction->rollback(); + + parent::tearDown(); + } +} diff --git a/test/PgSqlPoolTest.php b/test/PgSqlPoolTest.php index 6cdd796..91843a5 100644 --- a/test/PgSqlPoolTest.php +++ b/test/PgSqlPoolTest.php @@ -15,7 +15,7 @@ /** * @requires extension pgsql */ -class PgSqlPoolTest extends AbstractLinkTest +class PgSqlPoolTest extends AbstractConnectionTest { const POOL_SIZE = 3; diff --git a/test/PqNestedTransactionTest.php b/test/PqNestedTransactionTest.php new file mode 100644 index 0000000..b9b322f --- /dev/null +++ b/test/PqNestedTransactionTest.php @@ -0,0 +1,42 @@ +query(self::DROP_QUERY); + + $connection->query(self::CREATE_QUERY); + + foreach ($this->getParams() as $row) { + $connection->execute(self::INSERT_QUERY, $row); + } + + $this->transaction = $connection->beginTransaction(); + + return new PostgresNestableTransaction($this->transaction); + } + + public function tearDown(): void + { + //$this->transaction->rollback(); + + parent::tearDown(); + } +} diff --git a/test/PqPoolTest.php b/test/PqPoolTest.php index 459742e..e16d307 100644 --- a/test/PqPoolTest.php +++ b/test/PqPoolTest.php @@ -14,7 +14,7 @@ /** * @requires extension pq */ -class PqPoolTest extends AbstractLinkTest +class PqPoolTest extends AbstractConnectionTest { const POOL_SIZE = 3;