1515
1616use Cog \DbLocker \Locker \PostgresAdvisoryLocker ;
1717use Cog \DbLocker \Locker \PostgresAdvisoryLockScopeEnum ;
18+ use Cog \DbLocker \Locker \PostgresLockModeEnum ;
1819use Cog \DbLocker \LockId \PostgresLockId ;
1920use Cog \Test \DbLocker \Integration \AbstractIntegrationTestCase ;
2021use 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