Skip to main content
Glama
lock-manager.test.ts4.12 kB
/** * Agent Synch MCP Server - Lock Manager Tests */ import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { LockManager } from './lock-manager'; import * as fs from 'fs/promises'; import * as path from 'path'; import * as os from 'os'; describe('LockManager', () => { let lockManager: LockManager; let testDir: string; beforeEach(async () => { testDir = path.join(os.tmpdir(), `lock-test-${Date.now()}`); lockManager = new LockManager(testDir, 5000); // 5s timeout await lockManager.initialize(); }); afterEach(async () => { await fs.rm(testDir, { recursive: true, force: true }); }); describe('Basic Locking', () => { it('should acquire lock on unlocked resource', async () => { const acquired = await lockManager.acquireLock('file1', 'agent-a', 'write'); expect(acquired).toBe(true); }); it('should return lock status', async () => { await lockManager.acquireLock('file1', 'agent-a', 'write'); const status = lockManager.getLockStatus('file1'); expect(status).not.toBeNull(); expect(status?.agentId).toBe('agent-a'); }); it('should release lock', async () => { await lockManager.acquireLock('file1', 'agent-a', 'write'); const released = await lockManager.releaseLock('file1', 'agent-a'); expect(released).toBe(true); expect(lockManager.getLockStatus('file1')).toBeNull(); }); it('should not release lock for wrong agent', async () => { await lockManager.acquireLock('file1', 'agent-a', 'write'); const released = await lockManager.releaseLock('file1', 'agent-b'); expect(released).toBe(false); }); }); describe('Queue Behavior', () => { it('should queue second agent request', async () => { await lockManager.acquireLock('file1', 'agent-a', 'write'); // Agent B tries to acquire - should queue const agentBPromise = lockManager.acquireLock('file1', 'agent-b', 'write', 1000); expect(lockManager.getQueueLength('file1')).toBe(1); // Release agent A's lock await lockManager.releaseLock('file1', 'agent-a'); // Agent B should now have the lock const agentBAcquired = await agentBPromise; expect(agentBAcquired).toBe(true); expect(lockManager.getLockStatus('file1')?.agentId).toBe('agent-b'); }); it('should timeout queued request', async () => { await lockManager.acquireLock('file1', 'agent-a', 'write'); // Agent B tries with short timeout const acquired = await lockManager.acquireLock('file1', 'agent-b', 'write', 100); expect(acquired).toBe(false); }); }); describe('Lock Extension', () => { it('should extend lock for same agent', async () => { await lockManager.acquireLock('file1', 'agent-a', 'write', 500); // Wait a bit so the initial 500ms lock is almost expired await new Promise((r) => setTimeout(r, 100)); // Re-acquire (extend) with 5000ms const extended = await lockManager.acquireLock('file1', 'agent-a', 'write', 5000); expect(extended).toBe(true); const extendedLock = lockManager.getLockStatus('file1'); // The new expiry should be at least 4 seconds from now const minExpectedExpiry = Date.now() + 4000; expect(new Date(extendedLock!.expiresAt).getTime()).toBeGreaterThan(minExpectedExpiry); }); }); describe('Multiple Resources', () => { it('should handle locks on different resources independently', async () => { await lockManager.acquireLock('file1', 'agent-a', 'write'); await lockManager.acquireLock('file2', 'agent-b', 'write'); expect(lockManager.getLockStatus('file1')?.agentId).toBe('agent-a'); expect(lockManager.getLockStatus('file2')?.agentId).toBe('agent-b'); }); it('should list all active locks', async () => { await lockManager.acquireLock('file1', 'agent-a', 'write'); await lockManager.acquireLock('file2', 'agent-b', 'read'); const allLocks = lockManager.getAllLocks(); expect(allLocks).toHaveLength(2); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Mnehmos/mnehmos.synch.mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server