253 lines
13 KiB
YAML
253 lines
13 KiB
YAML
|
name: LockTest
|
||
|
class_comment: "# * @author J\xE9r\xE9my Deruss\xE9 <jeremy@derusse.com>"
|
||
|
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 <jeremy@derusse.com>\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
|