name: LockTest class_comment: "# * @author J\xE9r\xE9my Deruss\xE9 " dependencies: - name: TestCase type: class source: PHPUnit\Framework\TestCase - name: AbstractLogger type: class source: Psr\Log\AbstractLogger - name: LoggerInterface type: class source: Psr\Log\LoggerInterface - name: BlockingSharedLockStoreInterface type: class source: Symfony\Component\Lock\BlockingSharedLockStoreInterface - name: BlockingStoreInterface type: class source: Symfony\Component\Lock\BlockingStoreInterface - name: LockConflictedException type: class source: Symfony\Component\Lock\Exception\LockConflictedException - name: LockReleasingException type: class source: Symfony\Component\Lock\Exception\LockReleasingException - name: Key type: class source: Symfony\Component\Lock\Key - name: Lock type: class source: Symfony\Component\Lock\Lock - name: PersistingStoreInterface type: class source: Symfony\Component\Lock\PersistingStoreInterface - name: SharedLockStoreInterface type: class source: Symfony\Component\Lock\SharedLockStoreInterface - name: ExpiringStoreTrait type: class source: Symfony\Component\Lock\Store\ExpiringStoreTrait - name: InMemoryStore type: class source: Symfony\Component\Lock\Store\InMemoryStore - name: ExpiringStoreTrait type: class source: ExpiringStoreTrait - name: ExpiringStoreTrait type: class source: ExpiringStoreTrait properties: [] methods: - name: testExpiration visibility: public parameters: - name: ttls - name: expected comment: "# * @author J\xE9r\xE9my Deruss\xE9 \n# */\n# class\ \ LockTest extends TestCase\n# {\n# public function testAcquireNoBlocking()\n\ # {\n# $key = new Key(__METHOD__);\n# $store = $this->createMock(PersistingStoreInterface::class);\n\ # $lock = new Lock($key, $store);\n# \n# $store\n# ->expects($this->once())\n\ # ->method('save');\n# $store\n# ->method('exists')\n# ->willReturn(true, false);\n\ # \n# $this->assertTrue($lock->acquire(false));\n# }\n# \n# public function testAcquireNoBlockingWithPersistingStoreInterface()\n\ # {\n# $key = new Key(__METHOD__);\n# $store = $this->createMock(PersistingStoreInterface::class);\n\ # $lock = new Lock($key, $store);\n# \n# $store\n# ->expects($this->once())\n\ # ->method('save');\n# $store\n# ->method('exists')\n# ->willReturn(true, false);\n\ # \n# $this->assertTrue($lock->acquire(false));\n# }\n# \n# public function testAcquireBlockingWithPersistingStoreInterface()\n\ # {\n# $key = new Key(__METHOD__);\n# $store = $this->createMock(PersistingStoreInterface::class);\n\ # $lock = new Lock($key, $store);\n# \n# $store\n# ->expects($this->once())\n\ # ->method('save');\n# $store\n# ->method('exists')\n# ->willReturn(true, false);\n\ # \n# $this->assertTrue($lock->acquire(true));\n# }\n# \n# public function testAcquireBlockingRetryWithPersistingStoreInterface()\n\ # {\n# $key = new Key(__METHOD__);\n# $store = $this->createMock(PersistingStoreInterface::class);\n\ # $lock = new Lock($key, $store);\n# \n# $store\n# ->expects($this->any())\n#\ \ ->method('save')\n# ->willReturnCallback(static function () {\n# if (1 === random_int(0,\ \ 1)) {\n# return;\n# }\n# throw new LockConflictedException('boom');\n# });\n\ # $store\n# ->method('exists')\n# ->willReturn(true, false);\n# \n# $this->assertTrue($lock->acquire(true));\n\ # }\n# \n# public function testAcquireReturnsFalse()\n# {\n# $key = new Key(__METHOD__);\n\ # $store = $this->createMock(PersistingStoreInterface::class);\n# $lock = new\ \ Lock($key, $store);\n# \n# $store\n# ->expects($this->once())\n# ->method('save')\n\ # ->willThrowException(new LockConflictedException());\n# $store\n# ->method('exists')\n\ # ->willReturn(true, false);\n# \n# $this->assertFalse($lock->acquire(false));\n\ # }\n# \n# public function testAcquireReturnsFalseStoreInterface()\n# {\n# $key\ \ = new Key(__METHOD__);\n# $store = $this->createMock(PersistingStoreInterface::class);\n\ # $lock = new Lock($key, $store);\n# \n# $store\n# ->expects($this->once())\n\ # ->method('save')\n# ->willThrowException(new LockConflictedException());\n#\ \ $store\n# ->method('exists')\n# ->willReturn(true, false);\n# \n# $this->assertFalse($lock->acquire(false));\n\ # }\n# \n# public function testAcquireBlockingWithBlockingStoreInterface()\n#\ \ {\n# $key = new Key(__METHOD__);\n# $store = $this->createMock(BlockingStoreInterface::class);\n\ # $lock = new Lock($key, $store);\n# \n# $store\n# ->expects($this->never())\n\ # ->method('save');\n# $store\n# ->expects($this->once())\n# ->method('waitAndSave');\n\ # $store\n# ->method('exists')\n# ->willReturn(true, false);\n# \n# $this->assertTrue($lock->acquire(true));\n\ # }\n# \n# public function testAcquireSetsTtl()\n# {\n# $key = new Key(__METHOD__);\n\ # $store = $this->createMock(PersistingStoreInterface::class);\n# $lock = new\ \ Lock($key, $store, 10);\n# \n# $store\n# ->expects($this->once())\n# ->method('save');\n\ # $store\n# ->expects($this->once())\n# ->method('putOffExpiration')\n# ->with($key,\ \ 10);\n# $store\n# ->method('exists')\n# ->willReturn(true, false);\n# \n# $lock->acquire();\n\ # }\n# \n# public function testRefresh()\n# {\n# $key = new Key(__METHOD__);\n\ # $store = $this->createMock(PersistingStoreInterface::class);\n# $lock = new\ \ Lock($key, $store, 10);\n# \n# $store\n# ->expects($this->once())\n# ->method('putOffExpiration')\n\ # ->with($key, 10);\n# $store\n# ->method('exists')\n# ->willReturn(true, false);\n\ # \n# $lock->refresh();\n# }\n# \n# public function testRefreshCustom()\n# {\n\ # $key = new Key(__METHOD__);\n# $store = $this->createMock(PersistingStoreInterface::class);\n\ # $lock = new Lock($key, $store, 10);\n# \n# $store\n# ->expects($this->once())\n\ # ->method('putOffExpiration')\n# ->with($key, 20);\n# $store\n# ->method('exists')\n\ # ->willReturn(true, false);\n# \n# $lock->refresh(20);\n# }\n# \n# public function\ \ testIsAquired()\n# {\n# $key = new Key(__METHOD__);\n# $store = $this->createMock(PersistingStoreInterface::class);\n\ # $lock = new Lock($key, $store, 10);\n# \n# $store\n# ->method('exists')\n# ->with($key)\n\ # ->willReturn(true, false);\n# \n# $this->assertTrue($lock->isAcquired());\n\ # }\n# \n# public function testRelease()\n# {\n# $key = new Key(__METHOD__);\n\ # $store = $this->createMock(PersistingStoreInterface::class);\n# $lock = new\ \ Lock($key, $store, 10);\n# \n# $store\n# ->expects($this->once())\n# ->method('delete')\n\ # ->with($key);\n# \n# $store\n# ->expects($this->once())\n# ->method('exists')\n\ # ->with($key)\n# ->willReturn(false);\n# \n# $lock->release();\n# }\n# \n# public\ \ function testReleaseStoreInterface()\n# {\n# $key = new Key(__METHOD__);\n#\ \ $store = $this->createMock(PersistingStoreInterface::class);\n# $lock = new\ \ Lock($key, $store, 10);\n# \n# $store\n# ->expects($this->once())\n# ->method('delete')\n\ # ->with($key);\n# \n# $store\n# ->expects($this->once())\n# ->method('exists')\n\ # ->with($key)\n# ->willReturn(false);\n# \n# $lock->release();\n# }\n# \n# public\ \ function testReleaseOnDestruction()\n# {\n# $key = new Key(__METHOD__);\n# $store\ \ = $this->createMock(BlockingStoreInterface::class);\n# $lock = new Lock($key,\ \ $store, 10);\n# \n# $store\n# ->method('exists')\n# ->willReturn(true, false);\n\ # \n# $store\n# ->expects($this->once())\n# ->method('delete')\n# ;\n# \n# $lock->acquire(false);\n\ # unset($lock);\n# }\n# \n# public function testNoAutoReleaseWhenNotConfigured()\n\ # {\n# $key = new Key(__METHOD__);\n# $store = $this->createMock(BlockingStoreInterface::class);\n\ # $lock = new Lock($key, $store, 10, false);\n# \n# $store\n# ->method('exists')\n\ # ->willReturn(true, false);\n# \n# $store\n# ->expects($this->never())\n# ->method('delete')\n\ # ;\n# \n# $lock->acquire(false);\n# unset($lock);\n# }\n# \n# public function\ \ testReleaseThrowsExceptionWhenDeletionFail()\n# {\n# $this->expectException(LockReleasingException::class);\n\ # $key = new Key(__METHOD__);\n# $store = $this->createMock(PersistingStoreInterface::class);\n\ # $lock = new Lock($key, $store, 10);\n# \n# $store\n# ->expects($this->once())\n\ # ->method('delete')\n# ->with($key)\n# ->willThrowException(new \\RuntimeException('Boom'));\n\ # \n# $store\n# ->expects($this->never())\n# ->method('exists')\n# ->with($key)\n\ # ->willReturn(true);\n# \n# $lock->release();\n# }\n# \n# public function testReleaseThrowsExceptionIfNotWellDeleted()\n\ # {\n# $this->expectException(LockReleasingException::class);\n# $key = new Key(__METHOD__);\n\ # $store = $this->createMock(PersistingStoreInterface::class);\n# $lock = new\ \ Lock($key, $store, 10);\n# \n# $store\n# ->expects($this->once())\n# ->method('delete')\n\ # ->with($key);\n# \n# $store\n# ->expects($this->once())\n# ->method('exists')\n\ # ->with($key)\n# ->willReturn(true);\n# \n# $lock->release();\n# }\n# \n# public\ \ function testReleaseThrowsAndLog()\n# {\n# $this->expectException(LockReleasingException::class);\n\ # $key = new Key(__METHOD__);\n# $store = $this->createMock(PersistingStoreInterface::class);\n\ # $logger = $this->createMock(LoggerInterface::class);\n# $lock = new Lock($key,\ \ $store, 10, true);\n# $lock->setLogger($logger);\n# \n# $logger->expects($this->atLeastOnce())\n\ # ->method('notice')\n# ->with('Failed to release the \"{resource}\" lock.', ['resource'\ \ => $key]);\n# \n# $store\n# ->expects($this->once())\n# ->method('delete')\n\ # ->with($key);\n# \n# $store\n# ->expects($this->once())\n# ->method('exists')\n\ # ->with($key)\n# ->willReturn(true);\n# \n# $lock->release();\n# }\n# \n# public\ \ function testSuccessReleaseLog()\n# {\n# $key = new Key((string) random_int(100,\ \ 1000));\n# $store = new InMemoryStore();\n# $logger = new class extends AbstractLogger\ \ {\n# private array $logs = [];\n# \n# public function log($level, $message,\ \ array $context = []): void\n# {\n# $this->logs[] = [\n# $level,\n# (string)\ \ $message,\n# $context,\n# ];\n# }\n# \n# public function logs(): array\n# {\n\ # return $this->logs;\n# }\n# };\n# $lock = new Lock($key, $store, 10, true);\n\ # $lock->setLogger($logger);\n# $lock->release();\n# \n# $this->assertSame([['debug',\ \ 'Successfully released the \"{resource}\" lock.', ['resource' => $key]]], $logger->logs());\n\ # }\n# \n# /**\n# * @dataProvider provideExpiredDates" - name: testExpirationStoreInterface visibility: public parameters: - name: ttls - name: expected comment: '# * @dataProvider provideExpiredDates' - name: provideExpiredDates visibility: public parameters: [] comment: null - name: testAcquireReadNoBlockingWithSharedLockStoreInterface visibility: public parameters: [] comment: null - name: testAcquireReadTwiceWithExpiration visibility: public parameters: [] comment: '# * @group time-sensitive' - name: save visibility: public parameters: - name: key comment: null - name: delete visibility: public parameters: - name: key comment: null - name: exists visibility: public parameters: - name: key comment: null - name: putOffExpiration visibility: public parameters: - name: key - name: ttl comment: null - name: testAcquireTwiceWithExpiration visibility: public parameters: [] comment: '# * @group time-sensitive' - name: save visibility: public parameters: - name: key comment: null - name: delete visibility: public parameters: - name: key comment: null - name: exists visibility: public parameters: - name: key comment: null - name: putOffExpiration visibility: public parameters: - name: key - name: ttl comment: null - name: testAcquireReadBlockingWithBlockingSharedLockStoreInterface visibility: public parameters: [] comment: null - name: testAcquireReadBlockingWithSharedLockStoreInterface visibility: public parameters: [] comment: null - name: testAcquireReadBlockingWithBlockingLockStoreInterface visibility: public parameters: [] comment: null - name: testAcquireReadBlockingWithPersistingStoreInterface visibility: public parameters: [] comment: null traits: - PHPUnit\Framework\TestCase - Psr\Log\AbstractLogger - Psr\Log\LoggerInterface - Symfony\Component\Lock\BlockingSharedLockStoreInterface - Symfony\Component\Lock\BlockingStoreInterface - Symfony\Component\Lock\Exception\LockConflictedException - Symfony\Component\Lock\Exception\LockReleasingException - Symfony\Component\Lock\Key - Symfony\Component\Lock\Lock - Symfony\Component\Lock\PersistingStoreInterface - Symfony\Component\Lock\SharedLockStoreInterface - Symfony\Component\Lock\Store\ExpiringStoreTrait - Symfony\Component\Lock\Store\InMemoryStore - ExpiringStoreTrait - ExpiringStoreTrait interfaces: - PersistingStoreInterface - PersistingStoreInterface