Skip to content

Commit 00a2084

Browse files
committed
Improve tests
1 parent 33aa8a1 commit 00a2084

File tree

2 files changed

+135
-39
lines changed

2 files changed

+135
-39
lines changed

test/Integration/AbstractIntegrationTestCase.php

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,13 @@ protected function initPostgresPdoConnection(): PDO
4545
protected function assertPgAdvisoryLockExistsInConnection(
4646
PDO $dbConnection,
4747
PostgresLockId $postgresLockId,
48+
PostgresLockModeEnum $mode = PostgresLockModeEnum::Exclusive,
4849
): void {
49-
$row = $this->findPostgresAdvisoryLockInConnection($dbConnection, $postgresLockId);
50+
$row = $this->findPostgresAdvisoryLockInConnection(
51+
$dbConnection,
52+
$postgresLockId,
53+
$mode,
54+
);
5055

5156
$lockIdString = $postgresLockId->humanReadableValue;
5257

@@ -59,8 +64,13 @@ protected function assertPgAdvisoryLockExistsInConnection(
5964
protected function assertPgAdvisoryLockMissingInConnection(
6065
PDO $dbConnection,
6166
PostgresLockId $postgresLockId,
67+
PostgresLockModeEnum $mode = PostgresLockModeEnum::Exclusive,
6268
): void {
63-
$row = $this->findPostgresAdvisoryLockInConnection($dbConnection, $postgresLockId);
69+
$row = $this->findPostgresAdvisoryLockInConnection(
70+
$dbConnection,
71+
$postgresLockId,
72+
$mode,
73+
);
6474

6575
$lockIdString = $postgresLockId->humanReadableValue;
6676

@@ -86,6 +96,7 @@ protected function assertPgAdvisoryLocksCount(
8696
private function findPostgresAdvisoryLockInConnection(
8797
PDO $dbConnection,
8898
PostgresLockId $postgresLockId,
99+
PostgresLockModeEnum $mode,
89100
): object | null {
90101
// For one-argument advisory locks, Postgres stores the signed 64-bit key as two 32-bit integers:
91102
// classid = high 32 bits, objid = low 32 bits.
@@ -108,7 +119,7 @@ private function findPostgresAdvisoryLockInConnection(
108119
'lock_object_id' => $postgresLockId->objectId,
109120
'lock_object_subid' => 2, // Using two keyed locks
110121
'connection_pid' => $dbConnection->pgsqlGetPid(),
111-
'mode' => PostgresLockModeEnum::Exclusive->value,
122+
'mode' => $mode->value,
112123
],
113124
);
114125

@@ -130,14 +141,9 @@ private function findAllPostgresAdvisoryLocks(): array
130141
SELECT *
131142
FROM pg_locks
132143
WHERE locktype = 'advisory'
133-
AND mode = :mode
134144
SQL,
135145
);
136-
$statement->execute(
137-
[
138-
'mode' => PostgresLockModeEnum::Exclusive->value,
139-
],
140-
);
146+
$statement->execute();
141147

142148
return $statement->fetchAll(PDO::FETCH_OBJ);
143149
}
@@ -146,10 +152,10 @@ private function closeAllPostgresPdoConnections(): void
146152
{
147153
$this->initPostgresPdoConnection()->query(
148154
<<<'SQL'
149-
SELECT PG_TERMINATE_BACKEND(pid)
150-
FROM pg_stat_activity
151-
WHERE pid <> PG_BACKEND_PID()
152-
SQL,
155+
SELECT PG_TERMINATE_BACKEND(pid)
156+
FROM pg_stat_activity
157+
WHERE pid <> PG_BACKEND_PID()
158+
SQL,
153159
);
154160
}
155161
}

test/Integration/Locker/PostgresAdvisoryLockerTest.php

Lines changed: 116 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
use Cog\DbLocker\Locker\PostgresAdvisoryLocker;
1717
use Cog\DbLocker\Locker\PostgresAdvisoryLockScopeEnum;
18+
use Cog\DbLocker\Locker\PostgresLockModeEnum;
1819
use Cog\DbLocker\LockId\PostgresLockId;
1920
use Cog\Test\DbLocker\Integration\AbstractIntegrationTestCase;
2021
use LogicException;
@@ -25,21 +26,69 @@ final class PostgresAdvisoryLockerTest extends AbstractIntegrationTestCase
2526
private const DB_INT32_VALUE_MIN = -2_147_483_648;
2627
private const DB_INT32_VALUE_MAX = 2_147_483_647;
2728

28-
public function testItCanTryAcquireLockWithinSession(): void
29+
#[DataProvider('provideItCanTryAcquireLockWithinSessionData')]
30+
public function testItCanTryAcquireLockWithinSession(
31+
PostgresLockModeEnum $mode,
32+
): void {
33+
$locker = $this->initLocker();
34+
$dbConnection = $this->initPostgresPdoConnection();
35+
$postgresLockId = PostgresLockId::fromKeyValue('test');
36+
37+
$isLockAcquired = $locker->acquireLock(
38+
$dbConnection,
39+
$postgresLockId,
40+
scope: PostgresAdvisoryLockScopeEnum::Session,
41+
mode: $mode,
42+
);
43+
44+
$this->assertTrue($isLockAcquired);
45+
$this->assertPgAdvisoryLocksCount(1);
46+
$this->assertPgAdvisoryLockExistsInConnection($dbConnection, $postgresLockId, $mode);
47+
}
48+
49+
public static function provideItCanTryAcquireLockWithinSessionData(): array
2950
{
51+
return [
52+
'exclusive lock' => [
53+
PostgresLockModeEnum::Exclusive,
54+
],
55+
'share lock' => [
56+
PostgresLockModeEnum::Share,
57+
],
58+
];
59+
}
60+
61+
#[DataProvider('provideItCanTryAcquireLockWithinTransactionData')]
62+
public function testItCanTryAcquireLockWithinTransaction(
63+
PostgresLockModeEnum $mode,
64+
): void {
3065
$locker = $this->initLocker();
3166
$dbConnection = $this->initPostgresPdoConnection();
3267
$postgresLockId = PostgresLockId::fromKeyValue('test');
68+
$dbConnection->beginTransaction();
3369

3470
$isLockAcquired = $locker->acquireLock(
3571
$dbConnection,
3672
$postgresLockId,
37-
PostgresAdvisoryLockScopeEnum::Session,
73+
scope: PostgresAdvisoryLockScopeEnum::Transaction,
74+
mode: $mode,
3875
);
3976

4077
$this->assertTrue($isLockAcquired);
4178
$this->assertPgAdvisoryLocksCount(1);
42-
$this->assertPgAdvisoryLockExistsInConnection($dbConnection, $postgresLockId);
79+
$this->assertPgAdvisoryLockExistsInConnection($dbConnection, $postgresLockId, $mode);
80+
}
81+
82+
public static function provideItCanTryAcquireLockWithinTransactionData(): array
83+
{
84+
return [
85+
'exclusive lock' => [
86+
PostgresLockModeEnum::Exclusive,
87+
],
88+
'share lock' => [
89+
PostgresLockModeEnum::Share,
90+
],
91+
];
4392
}
4493

4594
#[DataProvider('provideItCanTryAcquireLockFromIntKeysCornerCasesData')]
@@ -52,7 +101,7 @@ public function testItCanTryAcquireLockFromIntKeysCornerCases(): void
52101
$isLockAcquired = $locker->acquireLock(
53102
$dbConnection,
54103
$postgresLockId,
55-
PostgresAdvisoryLockScopeEnum::Session,
104+
scope: PostgresAdvisoryLockScopeEnum::Session,
56105
);
57106

58107
$this->assertTrue($isLockAcquired);
@@ -153,23 +202,82 @@ public function testItCannotAcquireSameLockInTwoConnections(): void
153202
$this->assertPgAdvisoryLockMissingInConnection($dbConnection2, $postgresLockId);
154203
}
155204

156-
public function testItCanReleaseLock(): void
157-
{
205+
#[DataProvider('provideItCanReleaseLockData')]
206+
public function testItCanReleaseLock(
207+
PostgresLockModeEnum $mode,
208+
): void {
158209
$locker = $this->initLocker();
159210
$dbConnection = $this->initPostgresPdoConnection();
160211
$postgresLockId = PostgresLockId::fromKeyValue('test');
161212
$locker->acquireLock(
162213
$dbConnection,
163214
$postgresLockId,
164-
PostgresAdvisoryLockScopeEnum::Session,
215+
scope: PostgresAdvisoryLockScopeEnum::Session,
216+
mode: $mode,
165217
);
166218

167-
$isLockReleased = $locker->releaseLock($dbConnection, $postgresLockId);
219+
$isLockReleased = $locker->releaseLock(
220+
$dbConnection,
221+
$postgresLockId,
222+
mode: $mode,
223+
);
168224

169225
$this->assertTrue($isLockReleased);
170226
$this->assertPgAdvisoryLocksCount(0);
171227
}
172228

229+
public static function provideItCanReleaseLockData(): array
230+
{
231+
return [
232+
'exclusive lock' => [
233+
PostgresLockModeEnum::Exclusive,
234+
],
235+
'share lock' => [
236+
PostgresLockModeEnum::Share,
237+
],
238+
];
239+
}
240+
241+
#[DataProvider('provideItCanNotReleaseLockOfDifferentModesData')]
242+
public function testItCanNotReleaseLockOfDifferentModes(
243+
PostgresLockModeEnum $acquireMode,
244+
PostgresLockModeEnum $releaseMode,
245+
): void {
246+
$locker = $this->initLocker();
247+
$dbConnection = $this->initPostgresPdoConnection();
248+
$postgresLockId = PostgresLockId::fromKeyValue('test');
249+
$locker->acquireLock(
250+
$dbConnection,
251+
$postgresLockId,
252+
scope: PostgresAdvisoryLockScopeEnum::Session,
253+
mode: $acquireMode,
254+
);
255+
256+
$isLockReleased = $locker->releaseLock(
257+
$dbConnection,
258+
$postgresLockId,
259+
mode: $releaseMode,
260+
);
261+
262+
$this->assertFalse($isLockReleased);
263+
$this->assertPgAdvisoryLocksCount(1);
264+
$this->assertPgAdvisoryLockExistsInConnection($dbConnection, $postgresLockId, $acquireMode);
265+
}
266+
267+
public static function provideItCanNotReleaseLockOfDifferentModesData(): array
268+
{
269+
return [
270+
'release exclusive lock as share' => [
271+
'acquireMode' => PostgresLockModeEnum::Exclusive,
272+
'releaseMode' => PostgresLockModeEnum::Share,
273+
],
274+
'release share lock as exclusive' => [
275+
'acquireMode' => PostgresLockModeEnum::Share,
276+
'releaseMode' => PostgresLockModeEnum::Exclusive,
277+
],
278+
];
279+
}
280+
173281
public function testItCanReleaseLockTwiceIfAcquiredTwice(): void
174282
{
175283
$locker = $this->initLocker();
@@ -350,24 +458,6 @@ public function testItCanReleaseAllLocksInConnectionButKeepsOtherLocks(): void
350458
$this->assertPgAdvisoryLockExistsInConnection($dbConnection2, $postgresLockId4);
351459
}
352460

353-
public function testItCanTryAcquireLockWithinTransaction(): void
354-
{
355-
$locker = $this->initLocker();
356-
$dbConnection = $this->initPostgresPdoConnection();
357-
$postgresLockId = PostgresLockId::fromKeyValue('test');
358-
$dbConnection->beginTransaction();
359-
360-
$isLockAcquired = $locker->acquireLock(
361-
$dbConnection,
362-
$postgresLockId,
363-
PostgresAdvisoryLockScopeEnum::Session,
364-
);
365-
366-
$this->assertTrue($isLockAcquired);
367-
$this->assertPgAdvisoryLocksCount(1);
368-
$this->assertPgAdvisoryLockExistsInConnection($dbConnection, $postgresLockId);
369-
}
370-
371461
public function testItCannotAcquireLockWithinTransactionNotInTransaction(): void
372462
{
373463
$this->expectException(LogicException::class);

0 commit comments

Comments
 (0)