Skip to content

Commit 4e23b38

Browse files
committed
Add nested transaction tests
1 parent ce9106a commit 4e23b38

7 files changed

+170
-81
lines changed

test/AbstractConnectionTest.php

+81-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@
22

33
namespace Amp\Postgres\Test;
44

5+
use Amp\Future;
6+
use Amp\Postgres\PostgresListener;
7+
use Amp\Postgres\PostgresNotification;
8+
use Amp\Postgres\QueryExecutionError;
59
use Amp\Sql\ConnectionException;
10+
use Amp\Sql\QueryError;
11+
use Amp\Sql\SqlException;
12+
use Revolt\EventLoop;
613
use function Amp\async;
714

815
abstract class AbstractConnectionTest extends AbstractLinkTest
@@ -24,10 +31,83 @@ public function testConnectionCloseDuringQuery(): void
2431
try {
2532
$query->await();
2633
self::fail(\sprintf('Expected %s to be thrown', ConnectionException::class));
27-
} catch (ConnectionException) {
34+
} catch (SqlException) {
2835
// Expected
2936
}
3037

3138
$this->assertLessThan(0.1, \microtime(true) - $start);
3239
}
40+
41+
public function testListen()
42+
{
43+
$channel = "test";
44+
$listener = $this->link->listen($channel);
45+
46+
$this->assertInstanceOf(PostgresListener::class, $listener);
47+
$this->assertSame($channel, $listener->getChannel());
48+
49+
EventLoop::delay(0.1, function () use ($channel): void {
50+
$this->link->query(\sprintf("NOTIFY %s, '%s'", $channel, '0'));
51+
$this->link->query(\sprintf("NOTIFY %s, '%s'", $channel, '1'));
52+
});
53+
54+
$count = 0;
55+
EventLoop::delay(0.2, fn () => $listener->unlisten());
56+
57+
/** @var PostgresNotification $notification */
58+
foreach ($listener as $notification) {
59+
$this->assertSame($notification->getPayload(), (string) $count++);
60+
}
61+
62+
$this->assertSame(2, $count);
63+
}
64+
65+
/**
66+
* @depends testListen
67+
*/
68+
public function testNotify()
69+
{
70+
$channel = "test";
71+
$listener = $this->link->listen($channel);
72+
73+
EventLoop::delay(0.1, function () use ($channel) {
74+
$this->link->notify($channel, '0');
75+
$this->link->notify($channel, '1');
76+
});
77+
78+
$count = 0;
79+
EventLoop::delay(0.2, fn () => $listener->unlisten());
80+
81+
/** @var PostgresNotification $notification */
82+
foreach ($listener as $notification) {
83+
$this->assertSame($notification->getPayload(), (string) $count++);
84+
}
85+
86+
$this->assertSame(2, $count);
87+
}
88+
89+
/**
90+
* @depends testListen
91+
*/
92+
public function testListenOnSameChannel()
93+
{
94+
$this->expectException(QueryError::class);
95+
$this->expectExceptionMessage('Already listening on channel');
96+
97+
$channel = "test";
98+
Future\await([$this->link->listen($channel), $this->link->listen($channel)]);
99+
}
100+
101+
public function testQueryAfterErroredQuery()
102+
{
103+
try {
104+
$result = $this->link->query("INSERT INTO test VALUES ('github', 'com', '{1, 2, 3}', true, 4.2)");
105+
} catch (QueryExecutionError $exception) {
106+
// Expected exception due to duplicate key.
107+
}
108+
109+
$result = $this->link->query("INSERT INTO test VALUES ('gitlab', 'com', '{1, 2, 3}', true, 4.2)");
110+
111+
$this->assertSame(1, $result->getRowCount());
112+
}
33113
}

test/AbstractLinkTest.php

-76
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,13 @@
77
use Amp\Postgres\ByteA;
88
use Amp\Postgres\PostgresConnection;
99
use Amp\Postgres\PostgresLink;
10-
use Amp\Postgres\PostgresListener;
11-
use Amp\Postgres\PostgresNotification;
1210
use Amp\Postgres\PostgresTransaction;
1311
use Amp\Postgres\QueryExecutionError;
1412
use Amp\Sql\QueryError;
1513
use Amp\Sql\Result;
1614
use Amp\Sql\Statement;
1715
use Amp\Sql\TransactionError;
1816
use Amp\Sql\TransactionIsolationLevel;
19-
use Revolt\EventLoop;
2017
use function Amp\async;
2118

2219
abstract class AbstractLinkTest extends AsyncTestCase
@@ -575,79 +572,6 @@ public function testTransaction()
575572
}
576573
}
577574

578-
public function testListen()
579-
{
580-
$channel = "test";
581-
$listener = $this->link->listen($channel);
582-
583-
$this->assertInstanceOf(PostgresListener::class, $listener);
584-
$this->assertSame($channel, $listener->getChannel());
585-
586-
EventLoop::delay(0.1, function () use ($channel): void {
587-
$this->link->query(\sprintf("NOTIFY %s, '%s'", $channel, '0'));
588-
$this->link->query(\sprintf("NOTIFY %s, '%s'", $channel, '1'));
589-
});
590-
591-
$count = 0;
592-
EventLoop::delay(0.2, fn () => $listener->unlisten());
593-
594-
/** @var PostgresNotification $notification */
595-
foreach ($listener as $notification) {
596-
$this->assertSame($notification->getPayload(), (string) $count++);
597-
}
598-
599-
$this->assertSame(2, $count);
600-
}
601-
602-
/**
603-
* @depends testListen
604-
*/
605-
public function testNotify()
606-
{
607-
$channel = "test";
608-
$listener = $this->link->listen($channel);
609-
610-
EventLoop::delay(0.1, function () use ($channel) {
611-
$this->link->notify($channel, '0');
612-
$this->link->notify($channel, '1');
613-
});
614-
615-
$count = 0;
616-
EventLoop::delay(0.2, fn () => $listener->unlisten());
617-
618-
/** @var PostgresNotification $notification */
619-
foreach ($listener as $notification) {
620-
$this->assertSame($notification->getPayload(), (string) $count++);
621-
}
622-
623-
$this->assertSame(2, $count);
624-
}
625-
626-
/**
627-
* @depends testListen
628-
*/
629-
public function testListenOnSameChannel()
630-
{
631-
$this->expectException(QueryError::class);
632-
$this->expectExceptionMessage('Already listening on channel');
633-
634-
$channel = "test";
635-
Future\await([$this->link->listen($channel), $this->link->listen($channel)]);
636-
}
637-
638-
public function testQueryAfterErroredQuery()
639-
{
640-
try {
641-
$result = $this->link->query("INSERT INTO test VALUES ('github', 'com', '{1, 2, 3}', true, 4.2)");
642-
} catch (QueryExecutionError $exception) {
643-
// Expected exception due to duplicate key.
644-
}
645-
646-
$result = $this->link->query("INSERT INTO test VALUES ('gitlab', 'com', '{1, 2, 3}', true, 4.2)");
647-
648-
$this->assertSame(1, $result->getRowCount());
649-
}
650-
651575
public function provideInsertParameters(): iterable
652576
{
653577
$data = \str_repeat("\0", 10);

test/PgSqlConnectionTest.php

+1-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313
*/
1414
class PgSqlConnectionTest extends AbstractConnectionTest
1515
{
16-
/** @var \PgSql\Connection PostgreSQL connection resource. */
17-
protected $handle;
16+
protected ?\PgSql\Connection $handle = null;
1817

1918
public function createLink(string $connectionString): PostgresLink
2019
{

test/PgSqlNestedTransactionTest.php

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Amp\Postgres\Test;
4+
5+
use Amp\Postgres\PgSqlConnection;
6+
use Amp\Postgres\PostgresConfig;
7+
use Amp\Postgres\PostgresLink;
8+
use Amp\Postgres\PostgresNestableTransaction;
9+
use Amp\Postgres\PostgresTransaction;
10+
11+
/**
12+
* @requires extension pgsql
13+
*/
14+
class PgSqlNestedTransactionTest extends AbstractLinkTest
15+
{
16+
protected PgSqlConnection $connection;
17+
protected PostgresTransaction $transaction;
18+
19+
public function createLink(string $connectionString): PostgresLink
20+
{
21+
$connectionConfig = PostgresConfig::fromString($connectionString);
22+
$connection = PgSqlConnection::connect($connectionConfig);
23+
24+
$connection->query(self::DROP_QUERY);
25+
26+
$connection->query(self::CREATE_QUERY);
27+
28+
foreach ($this->getParams() as $row) {
29+
$connection->execute(self::INSERT_QUERY, $row);
30+
}
31+
32+
$this->connection = $connection;
33+
$this->transaction = $connection->beginTransaction();
34+
35+
return new PostgresNestableTransaction($this->transaction);
36+
}
37+
38+
public function tearDown(): void
39+
{
40+
$this->transaction->rollback();
41+
42+
parent::tearDown();
43+
}
44+
}

test/PgSqlPoolTest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
/**
1616
* @requires extension pgsql
1717
*/
18-
class PgSqlPoolTest extends AbstractLinkTest
18+
class PgSqlPoolTest extends AbstractConnectionTest
1919
{
2020
const POOL_SIZE = 3;
2121

test/PqNestedTransactionTest.php

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Amp\Postgres\Test;
4+
5+
use Amp\Postgres\PostgresConfig;
6+
use Amp\Postgres\PostgresLink;
7+
use Amp\Postgres\PostgresNestableTransaction;
8+
use Amp\Postgres\PostgresTransaction;
9+
use Amp\Postgres\PqConnection;
10+
11+
/**
12+
* @requires extension pgsql
13+
*/
14+
class PqNestedTransactionTest extends AbstractLinkTest
15+
{
16+
protected PostgresTransaction $transaction;
17+
18+
public function createLink(string $connectionString): PostgresLink
19+
{
20+
$connectionConfig = PostgresConfig::fromString($connectionString);
21+
$connection = PqConnection::connect($connectionConfig);
22+
23+
$connection->query(self::DROP_QUERY);
24+
25+
$connection->query(self::CREATE_QUERY);
26+
27+
foreach ($this->getParams() as $row) {
28+
$connection->execute(self::INSERT_QUERY, $row);
29+
}
30+
31+
$this->transaction = $connection->beginTransaction();
32+
33+
return new PostgresNestableTransaction($this->transaction);
34+
}
35+
36+
public function tearDown(): void
37+
{
38+
//$this->transaction->rollback();
39+
40+
parent::tearDown();
41+
}
42+
}

test/PqPoolTest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
/**
1515
* @requires extension pq
1616
*/
17-
class PqPoolTest extends AbstractLinkTest
17+
class PqPoolTest extends AbstractConnectionTest
1818
{
1919
const POOL_SIZE = 3;
2020

0 commit comments

Comments
 (0)