Skip to content

Commit

Permalink
Add nested transaction tests
Browse files Browse the repository at this point in the history
  • Loading branch information
trowski committed May 7, 2023
1 parent ce9106a commit 4e23b38
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 81 deletions.
82 changes: 81 additions & 1 deletion test/AbstractConnectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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());
}
}
76 changes: 0 additions & 76 deletions test/AbstractLinkTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,13 @@
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;
use Amp\Sql\Result;
use Amp\Sql\Statement;
use Amp\Sql\TransactionError;
use Amp\Sql\TransactionIsolationLevel;
use Revolt\EventLoop;
use function Amp\async;

abstract class AbstractLinkTest extends AsyncTestCase
Expand Down Expand Up @@ -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);
Expand Down
3 changes: 1 addition & 2 deletions test/PgSqlConnectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
44 changes: 44 additions & 0 deletions test/PgSqlNestedTransactionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php declare(strict_types=1);

namespace Amp\Postgres\Test;

use Amp\Postgres\PgSqlConnection;
use Amp\Postgres\PostgresConfig;
use Amp\Postgres\PostgresLink;
use Amp\Postgres\PostgresNestableTransaction;
use Amp\Postgres\PostgresTransaction;

/**
* @requires extension pgsql
*/
class PgSqlNestedTransactionTest extends AbstractLinkTest
{
protected PgSqlConnection $connection;
protected PostgresTransaction $transaction;

public function createLink(string $connectionString): PostgresLink
{
$connectionConfig = PostgresConfig::fromString($connectionString);
$connection = PgSqlConnection::connect($connectionConfig);

$connection->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();
}
}
2 changes: 1 addition & 1 deletion test/PgSqlPoolTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
/**
* @requires extension pgsql
*/
class PgSqlPoolTest extends AbstractLinkTest
class PgSqlPoolTest extends AbstractConnectionTest
{
const POOL_SIZE = 3;

Expand Down
42 changes: 42 additions & 0 deletions test/PqNestedTransactionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php declare(strict_types=1);

namespace Amp\Postgres\Test;

use Amp\Postgres\PostgresConfig;
use Amp\Postgres\PostgresLink;
use Amp\Postgres\PostgresNestableTransaction;
use Amp\Postgres\PostgresTransaction;
use Amp\Postgres\PqConnection;

/**
* @requires extension pgsql
*/
class PqNestedTransactionTest extends AbstractLinkTest
{
protected PostgresTransaction $transaction;

public function createLink(string $connectionString): PostgresLink
{
$connectionConfig = PostgresConfig::fromString($connectionString);
$connection = PqConnection::connect($connectionConfig);

$connection->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();
}
}
2 changes: 1 addition & 1 deletion test/PqPoolTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
/**
* @requires extension pq
*/
class PqPoolTest extends AbstractLinkTest
class PqPoolTest extends AbstractConnectionTest
{
const POOL_SIZE = 3;

Expand Down

0 comments on commit 4e23b38

Please sign in to comment.