15
15
16
16
use Cog \DbLocker \Locker \PostgresAdvisoryLocker ;
17
17
use Cog \DbLocker \Locker \PostgresAdvisoryLockScopeEnum ;
18
+ use Cog \DbLocker \Locker \PostgresLockModeEnum ;
18
19
use Cog \DbLocker \LockId \PostgresLockId ;
19
20
use Cog \Test \DbLocker \Integration \AbstractIntegrationTestCase ;
20
21
use LogicException ;
@@ -25,21 +26,69 @@ final class PostgresAdvisoryLockerTest extends AbstractIntegrationTestCase
25
26
private const DB_INT32_VALUE_MIN = -2_147_483_648 ;
26
27
private const DB_INT32_VALUE_MAX = 2_147_483_647 ;
27
28
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
29
50
{
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 {
30
65
$ locker = $ this ->initLocker ();
31
66
$ dbConnection = $ this ->initPostgresPdoConnection ();
32
67
$ postgresLockId = PostgresLockId::fromKeyValue ('test ' );
68
+ $ dbConnection ->beginTransaction ();
33
69
34
70
$ isLockAcquired = $ locker ->acquireLock (
35
71
$ dbConnection ,
36
72
$ postgresLockId ,
37
- PostgresAdvisoryLockScopeEnum::Session,
73
+ scope: PostgresAdvisoryLockScopeEnum::Transaction,
74
+ mode: $ mode ,
38
75
);
39
76
40
77
$ this ->assertTrue ($ isLockAcquired );
41
78
$ 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
+ ];
43
92
}
44
93
45
94
#[DataProvider('provideItCanTryAcquireLockFromIntKeysCornerCasesData ' )]
@@ -52,7 +101,7 @@ public function testItCanTryAcquireLockFromIntKeysCornerCases(): void
52
101
$ isLockAcquired = $ locker ->acquireLock (
53
102
$ dbConnection ,
54
103
$ postgresLockId ,
55
- PostgresAdvisoryLockScopeEnum::Session,
104
+ scope: PostgresAdvisoryLockScopeEnum::Session,
56
105
);
57
106
58
107
$ this ->assertTrue ($ isLockAcquired );
@@ -153,23 +202,82 @@ public function testItCannotAcquireSameLockInTwoConnections(): void
153
202
$ this ->assertPgAdvisoryLockMissingInConnection ($ dbConnection2 , $ postgresLockId );
154
203
}
155
204
156
- public function testItCanReleaseLock (): void
157
- {
205
+ #[DataProvider('provideItCanReleaseLockData ' )]
206
+ public function testItCanReleaseLock (
207
+ PostgresLockModeEnum $ mode ,
208
+ ): void {
158
209
$ locker = $ this ->initLocker ();
159
210
$ dbConnection = $ this ->initPostgresPdoConnection ();
160
211
$ postgresLockId = PostgresLockId::fromKeyValue ('test ' );
161
212
$ locker ->acquireLock (
162
213
$ dbConnection ,
163
214
$ postgresLockId ,
164
- PostgresAdvisoryLockScopeEnum::Session,
215
+ scope: PostgresAdvisoryLockScopeEnum::Session,
216
+ mode: $ mode ,
165
217
);
166
218
167
- $ isLockReleased = $ locker ->releaseLock ($ dbConnection , $ postgresLockId );
219
+ $ isLockReleased = $ locker ->releaseLock (
220
+ $ dbConnection ,
221
+ $ postgresLockId ,
222
+ mode: $ mode ,
223
+ );
168
224
169
225
$ this ->assertTrue ($ isLockReleased );
170
226
$ this ->assertPgAdvisoryLocksCount (0 );
171
227
}
172
228
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
+
173
281
public function testItCanReleaseLockTwiceIfAcquiredTwice (): void
174
282
{
175
283
$ locker = $ this ->initLocker ();
@@ -350,24 +458,6 @@ public function testItCanReleaseAllLocksInConnectionButKeepsOtherLocks(): void
350
458
$ this ->assertPgAdvisoryLockExistsInConnection ($ dbConnection2 , $ postgresLockId4 );
351
459
}
352
460
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
-
371
461
public function testItCannotAcquireLockWithinTransactionNotInTransaction (): void
372
462
{
373
463
$ this ->expectException (LogicException::class);
0 commit comments