tempDir = sys_get_temp_dir() . '/php_sessions_test_' . uniqid(); mkdir($this->tempDir, 0700, true); $this->clock = new SystemClock(); $this->fileStorage = new FileSessionStorage($this->tempDir, $this->clock); $this->memoryStorage = new InMemorySessionStorage(); $this->sessionId = SessionId::fromString('test-session-' . uniqid()); }); afterEach(function () { // Cleanup if (isset($this->tempDir) && is_dir($this->tempDir)) { array_map('unlink', glob($this->tempDir . '/*')); rmdir($this->tempDir); } }); it('acquires and releases lock for file storage', function () { $acquired = $this->fileStorage->acquireLock($this->sessionId, 1); expect($acquired)->toBeTrue(); // Should be able to release $this->fileStorage->releaseLock($this->sessionId); // Should be able to acquire again $acquired2 = $this->fileStorage->acquireLock($this->sessionId, 1); expect($acquired2)->toBeTrue(); $this->fileStorage->releaseLock($this->sessionId); }); it('prevents concurrent locks for file storage', function () { // Acquire lock in first "process" $acquired1 = $this->fileStorage->acquireLock($this->sessionId, 1); expect($acquired1)->toBeTrue(); // Try to acquire same lock in second "process" (should fail or timeout) $acquired2 = $this->fileStorage->acquireLock($this->sessionId, 1); // In single-threaded test, second acquisition might succeed // But in real scenario with concurrent processes, it would fail // This test verifies the locking mechanism exists $this->fileStorage->releaseLock($this->sessionId); }); it('acquires and releases lock for memory storage', function () { $acquired = $this->memoryStorage->acquireLock($this->sessionId, 1); expect($acquired)->toBeTrue(); // Should be able to release $this->memoryStorage->releaseLock($this->sessionId); // Should be able to acquire again $acquired2 = $this->memoryStorage->acquireLock($this->sessionId, 1); expect($acquired2)->toBeTrue(); $this->memoryStorage->releaseLock($this->sessionId); }); it('prevents concurrent locks for memory storage', function () { // Acquire lock $acquired1 = $this->memoryStorage->acquireLock($this->sessionId, 1); expect($acquired1)->toBeTrue(); // Try to acquire same lock (should fail) $acquired2 = $this->memoryStorage->acquireLock($this->sessionId, 1); expect($acquired2)->toBeFalse(); // Release and try again $this->memoryStorage->releaseLock($this->sessionId); $acquired3 = $this->memoryStorage->acquireLock($this->sessionId, 1); expect($acquired3)->toBeTrue(); $this->memoryStorage->releaseLock($this->sessionId); }); it('handles lock timeout correctly', function () { // Acquire lock $acquired1 = $this->memoryStorage->acquireLock($this->sessionId, 1); expect($acquired1)->toBeTrue(); // Try to acquire with very short timeout (should fail) $acquired2 = $this->memoryStorage->acquireLock($this->sessionId, 0); expect($acquired2)->toBeFalse(); $this->memoryStorage->releaseLock($this->sessionId); });