Key example


    /** * @see AbstractStoreTestCase::getStore() */
    abstract protected function getStore(): PersistingStoreInterface;

    public function testSharedLockReadFirst()
    {
        $store = $this->getStore();

        $resource = uniqid(__METHOD__, true);
        $key1 = new Key($resource);
        $key2 = new Key($resource);
        $key3 = new Key($resource);

        $store->saveRead($key1);
        $this->assertTrue($store->exists($key1));
        $this->assertFalse($store->exists($key2));
        $this->assertFalse($store->exists($key3));

        // assert we can store multiple keys in read mode         $store->saveRead($key2);
        $this->assertTrue($store->exists($key1));
        
public function __construct(
        private PersistingStoreInterface $store,
    ) {
    }

    /** * @param float|null $ttlInSecond Maximum expected semaphore duration in seconds * @param bool $autoRelease Whether to automatically release the semaphore or not when the semaphore instance is destroyed */
    public function createSemaphore(string $resource, int $limit, int $weight = 1, ?float $ttlInSecond = 300.0, bool $autoRelease = true): SemaphoreInterface
    {
        return $this->createSemaphoreFromKey(new Key($resource$limit$weight)$ttlInSecond$autoRelease);
    }

    /** * @param float|null $ttlInSecond Maximum expected semaphore duration in seconds * @param bool $autoRelease Whether to automatically release the semaphore or not when the semaphore instance is destroyed */
    public function createSemaphoreFromKey(Key $key, ?float $ttlInSecond = 300.0, bool $autoRelease = true): SemaphoreInterface
    {
        $semaphore = new Semaphore($key$this->store, $ttlInSecond$autoRelease);
        if ($this->logger) {
            $semaphore->setLogger($this->logger);
        }
/** * @requires extension pdo_sqlite * * @dataProvider getInvalidDrivers */
    public function testInvalidDriver($connOrDsn)
    {
        $this->expectException(InvalidArgumentException::class);
        $this->expectExceptionMessage('The adapter "Symfony\Component\Lock\Store\DoctrineDbalPostgreSqlStore" does not support');

        $store = new DoctrineDbalPostgreSqlStore($connOrDsn);
        $store->exists(new Key('foo'));
    }

    public static function getInvalidDrivers()
    {
        yield ['sqlite:///tmp/foo.db'];
        yield [self::getDbalConnection('sqlite:///tmp/foo.db')];
    }

    public function testSaveAfterConflict()
    {
        $store1 = $this->getStore();
        
/** * @author Jérémy Derussé <jeremy@derusse.com> */
abstract class AbstractStoreTestCase extends TestCase
{
    abstract protected function getStore(): PersistingStoreInterface;

    public function testSave()
    {
        $store = $this->getStore();

        $key = new Key(uniqid(__METHOD__, true));

        $this->assertFalse($store->exists($key));
        $store->save($key);
        $this->assertTrue($store->exists($key));
        $store->delete($key);
        $this->assertFalse($store->exists($key));
    }

    public function testSaveWithDifferentResources()
    {
        $store = $this->getStore();

        

    public function testBlockingLocks()
    {
        // Amount of microseconds we should wait without slowing things down too much         $clockDelay = 50000;

        $key = new Key(uniqid(__METHOD__, true));
        $parentPID = posix_getpid();

        // Block SIGHUP signal         pcntl_sigprocmask(\SIG_BLOCK, [\SIGHUP]);

        if ($childPID = pcntl_fork()) {
            // Wait the start of the child             pcntl_sigwaitinfo([\SIGHUP]$info);

            $store = $this->getStore();
            try {
                
use Symfony\Component\Semaphore\PersistingStoreInterface;
use Symfony\Component\Semaphore\Semaphore;

/** * @author Jérémy Derussé <jeremy@derusse.com> * @author Grégoire Pineau <lyrixx@lyrixx.info> */
class SemaphoreTest extends TestCase
{
    public function testAcquireReturnsTrue()
    {
        $key = new Key('key', 1);
        $store = $this->createMock(PersistingStoreInterface::class);
        $semaphore = new Semaphore($key$store);

        $store
            ->expects($this->once())
            ->method('save')
            ->with($key, 300.0)
        ;

        $this->assertTrue($semaphore->acquire());
        $this->assertGreaterThanOrEqual(299.0, $key->getRemainingLifetime());
    }
$cache->get('cache', fn () => [$now, 0], \INF);

        $this->assertTrue($checkpoint->acquire($startedAt = $now->modify('1 min')));
        $this->assertEquals($now$checkpoint->time());
        $this->assertEquals(0, $checkpoint->index());
        $this->assertEquals([$now, 0, $startedAt]$cache->get('cache', fn () => []));
    }

    public function testWithLockInitStateOnFirstAcquiring()
    {
        $lock = new Lock(new Key('lock')new InMemoryStore());
        $checkpoint = new Checkpoint('dummy', $lock);
        $now = new \DateTimeImmutable('2020-02-20 20:20:20Z');

        $this->assertTrue($checkpoint->acquire($now));
        $this->assertEquals($now$checkpoint->time());
        $this->assertEquals($now$checkpoint->from());
        $this->assertEquals(-1, $checkpoint->index());
        $this->assertTrue($lock->isAcquired());
    }

    public function testWithLockLoadStateOnAcquiring()
    {
use PHPUnit\Framework\TestCase;
use Symfony\Component\Lock\Exception\UnserializableKeyException;
use Symfony\Component\Lock\Key;

/** * @author Jérémy Derussé <jeremy@derusse.com> */
class KeyTest extends TestCase
{
    public function testSerialize()
    {
        $key = new Key(__METHOD__);
        $key->reduceLifetime(1);
        $key->setState('foo', 'bar');

        $copy = unserialize(serialize($key));
        $this->assertSame($key->getState('foo')$copy->getState('foo'));
        $this->assertEqualsWithDelta($key->getRemainingLifetime()$copy->getRemainingLifetime(), 0.001);
    }

    public function testUnserialize()
    {
        $key = new Key(__METHOD__);
        

        $this->strategy = $this->createMock(StrategyInterface::class);
        $this->store1 = $this->createMock(BlockingStoreInterface::class);
        $this->store2 = $this->createMock(BlockingStoreInterface::class);

        $this->store = new CombinedStore([$this->store1, $this->store2]$this->strategy);
    }

    public function testSaveThrowsExceptionOnFailure()
    {
        $this->expectException(LockConflictedException::class);
        $key = new Key(uniqid(__METHOD__, true));

        $this->store1
            ->expects($this->once())
            ->method('save')
            ->with($key)
            ->willThrowException(new LockConflictedException());
        $this->store2
            ->expects($this->once())
            ->method('save')
            ->with($key)
            ->willThrowException(new LockConflictedException());

        
trait UnserializableTestTrait
{
    /** * @see AbstractStoreTestCase::getStore() */
    abstract protected function getStore(): PersistingStoreInterface;

    public function testUnserializableKey()
    {
        $store = $this->getStore();

        $key = new Key(uniqid(__METHOD__, true));

        $store->save($key);
        $this->assertTrue($store->exists($key));

        $this->expectException(UnserializableKeyException::class);
        serialize($key);
    }
}

abstract class AbstractStoreTestCase extends TestCase
{
    abstract protected function getStore(): PersistingStoreInterface;

    public function testSaveExistAndDelete()
    {
        $store = $this->getStore();

        $key = new Key(__METHOD__, 1);

        $this->assertFalse($store->exists($key));
        $store->save($key, 10);
        $this->assertTrue($store->exists($key));
        $store->delete($key);
        $this->assertFalse($store->exists($key));
    }

    public function testSaveWithDifferentResources()
    {
        $store = $this->getStore();

        
abstract protected function getRedisConnection(): \Redis|Relay|\RedisArray|\RedisCluster|\Predis\ClientInterface;

    public function getStore(): PersistingStoreInterface
    {
        return new RedisStore($this->getRedisConnection());
    }

    public function testBackwardCompatibility()
    {
        $resource = uniqid(__METHOD__, true);
        $key1 = new Key($resource);
        $key2 = new Key($resource);

        $oldStore = new Symfony51Store($this->getRedisConnection());
        $newStore = $this->getStore();

        $oldStore->save($key1);
        $this->assertTrue($oldStore->exists($key1));

        $this->expectException(LockConflictedException::class);
        $newStore->save($key2);
    }
}
->method('save')
            ->with($this->callback(function D$key) use (&$keys) {
                $keys[] = $key;

                return true;
            }));

        $logger = $this->createMock(LoggerInterface::class);
        $factory = new LockFactory($store);
        $factory->setLogger($logger);

        $key = new Key('foo');
        $lock1 = $factory->createLockFromKey($key);
        $lock2 = $factory->createLockFromKey($key);

        // assert lock1 and lock2 share the same state         $lock1->acquire();
        $lock2->acquire();

        $this->assertSame($keys[0]$keys[1]);
    }
}
/** * Creates a lock for the given resource. * * @param string $resource The resource to lock * @param float|null $ttl Maximum expected lock duration in seconds * @param bool $autoRelease Whether to automatically release the lock or not when the lock instance is destroyed * * @return SharedLockInterface */
    public function createLock(string $resource, ?float $ttl = 300.0, bool $autoRelease = true): LockInterface
    {
        return $this->createLockFromKey(new Key($resource)$ttl$autoRelease);
    }

    /** * Creates a lock from the given key. * * @param Key $key The key containing the lock's state * @param float|null $ttl Maximum expected lock duration in seconds * @param bool $autoRelease Whether to automatically release the lock or not when the lock instance is destroyed * * @return SharedLockInterface */
    
use UnserializableTestTrait;

    protected function getStore(): PersistingStoreInterface
    {
        return new SemaphoreStore();
    }

    public function testResourceRemoval()
    {
        $initialCount = $this->getOpenedSemaphores();
        $store = new SemaphoreStore();
        $key = new Key(uniqid(__METHOD__, true));
        $store->waitAndSave($key);

        $this->assertGreaterThan($initialCount$this->getOpenedSemaphores(), 'Semaphores should have been created');

        $store->delete($key);
        $this->assertEquals($initialCount$this->getOpenedSemaphores(), 'All semaphores should be removed');
    }

    private function getOpenedSemaphores()
    {
        if ('Darwin' === \PHP_OS) {
            
Home | Imprint | This part of the site doesn't use cookies.