Skip to main content
Glama
global-test-manager.cjs•9.89 kB
#!/usr/bin/env node /** * Global Test Manager - Singleton system that can be called from any tool * Ensures only one test runs globally and benefits all tool calls */ const fs = require('fs'); const path = require('path'); const { spawn } = require('child_process'); const GLOBAL_STATUS_FILE = path.join(__dirname, 'global-test-status.json'); const LOCK_FILE = path.join(__dirname, 'global-test.lock'); class GlobalTestManager { // Check if any test is running globally static isTestRunning() { try { // Check lock file first (fast check) if (!fs.existsSync(LOCK_FILE)) { return { isRunning: false }; } // Check status file for details if (!fs.existsSync(GLOBAL_STATUS_FILE)) { return { isRunning: false, hasLock: true }; } const status = JSON.parse(fs.readFileSync(GLOBAL_STATUS_FILE, 'utf8')); // Verify process is still alive if (status.isRunning && status.pid) { const ageMinutes = (Date.now() - new Date(status.lastUpdate)) / (1000 * 60); // If status is older than 10 minutes, assume dead if (ageMinutes > 10) { return { isRunning: false, reason: 'Status too old' }; } return { isRunning: true, pid: status.pid, startedAt: status.startedAt, message: status.message, progress: status.progress, testType: status.testType, benefits: status.benefits || [] }; } return { isRunning: false }; } catch (error) { console.error('āŒ Failed to check global test status:', error.message); return { isRunning: false, reason: error.message }; } } // Start global test (anywhere in system) static async startGlobalTest(testType = 'complete', callerTool = 'unknown') { const currentStatus = this.isTestRunning(); if (currentStatus.isRunning) { // Add benefit for this caller this.addBenefit(callerTool, currentStatus); return { success: true, alreadyRunning: true, message: `Test already running (PID: ${currentStatus.pid}) - ${callerTool} benefiting from active test`, status: currentStatus, callerTool: callerTool, testType: testType }; } try { // Create lock file fs.writeFileSync(LOCK_FILE, JSON.stringify({ locked: true, timestamp: new Date().toISOString(), initiator: callerTool })); let testScript; if (testType === 'dummy') { testScript = 'dummy-test-runner.cjs'; } else if (testType === 'simple') { testScript = 'simple-test-runner.cjs'; } else { // Default to complete system test testScript = '../../../test-complete-system.cjs'; } const testPath = path.join(__dirname, testScript); console.log(`šŸŒ Starting global test: ${testScript} (requested by: ${callerTool})`); // Start test as detached background process const testProcess = spawn('node', [testPath], { detached: true, stdio: ['ignore', 'pipe', 'pipe'], env: { ...process.env, NODE_ENV: 'production', GLOBAL_TEST_CALLER: callerTool, GLOBAL_TEST_TYPE: testType } }); testProcess.unref(); // Give it time to initialize await new Promise(resolve => setTimeout(resolve, 2000)); // Create global status const newStatus = { isRunning: true, pid: testProcess.pid, startedAt: new Date().toISOString(), lastUpdate: new Date().toISOString(), message: `${testType} test started by ${callerTool}`, progress: 0, testType: testType, initiator: callerTool, benefits: [ { tool: callerTool, timestamp: new Date().toISOString(), action: 'initiated', benefit: 'Started global test' } ] }; fs.writeFileSync(GLOBAL_STATUS_FILE, JSON.stringify(newStatus, null, 2)); return { success: true, alreadyRunning: false, message: `Global ${testType} test started successfully (PID: ${testProcess.pid})`, status: newStatus, callerTool: callerTool, testType: testType }; } catch (error) { // Clean up lock on error try { fs.unlinkSync(LOCK_FILE); } catch (e) {} console.error('āŒ Failed to start global test:', error.message); return { success: false, message: `Failed to start global test: ${error.message}`, callerTool: callerTool }; } } // Add benefit record for caller static addBenefit(callerTool, currentStatus) { try { if (!fs.existsSync(GLOBAL_STATUS_FILE)) return; const status = JSON.parse(fs.readFileSync(GLOBAL_STATUS_FILE, 'utf8')); if (!status.benefits) status.benefits = []; status.benefits.push({ tool: callerTool, timestamp: new Date().toISOString(), action: 'benefited', benefit: `Tool ${callerTool} used existing test (PID: ${currentStatus.pid})` }); status.lastUpdate = new Date().toISOString(); fs.writeFileSync(GLOBAL_STATUS_FILE, JSON.stringify(status, null, 2)); console.log(`šŸ’” ${callerTool} is benefiting from active test (PID: ${currentStatus.pid})`); } catch (error) { console.error('āŒ Failed to add benefit:', error.message); } } // Stop global test static async stopGlobalTest() { const currentStatus = this.isTestRunning(); if (!currentStatus.isRunning) { return { success: true, alreadyStopped: true, message: 'No global test is currently running' }; } try { const pid = currentStatus.pid; console.log(`šŸ›‘ Stopping global test (PID: ${pid})`); // Graceful stop process.kill(pid, 'SIGTERM'); await new Promise(resolve => setTimeout(resolve, 3000)); // Force stop if needed const statusAfter = this.isTestRunning(); if (statusAfter.isRunning) { console.log(`⚔ Force killing global test (PID: ${pid})`); process.kill(pid, 'SIGKILL'); await new Promise(resolve => setTimeout(resolve, 1000)); } // Clean up files try { fs.unlinkSync(GLOBAL_STATUS_FILE); fs.unlinkSync(LOCK_FILE); } catch (error) { console.warn('āš ļø Could not clean up files:', error.message); } return { success: true, message: `Global test stopped successfully (was PID: ${pid})` }; } catch (error) { console.error('āŒ Failed to stop global test:', error.message); return { success: false, message: `Failed to stop global test: ${error.message}` }; } } // Get global status static getGlobalStatus() { const status = this.isTestRunning(); return { isRunning: status.isRunning, pid: status.pid || null, startedAt: status.startedAt || null, lastUpdate: status.lastUpdate || null, message: status.message || null, progress: status.progress || null, testType: status.testType || null, initiator: status.initiator || null, benefits: status.benefits || [], lockFile: fs.existsSync(LOCK_FILE), statusFile: fs.existsSync(GLOBAL_STATUS_FILE) }; } // Tool interface - can be called from anywhere static async ensureTestForTool(toolName, testType = 'complete') { console.log(`šŸ”§ Tool "${toolName}" requesting test access...`); const result = await this.startGlobalTest(testType, toolName); if (result.success) { console.log(`āœ… Tool "${toolName}" has test access:`); console.log(` Test Type: ${result.testType}`); console.log(` Status: ${result.alreadyRunning ? 'Benefiting from existing' : 'Started new'}`); console.log(` PID: ${result.status.pid}`); // Log benefits for tracking if (result.status.benefits) { console.log(` Total Benefits: ${result.status.benefits.length}`); } } return result; } } // Export for use by any tool module.exports = { GlobalTestManager }; // CLI interface for direct use if (require.main === module) { const args = process.argv.slice(2); const command = args[0]; const toolName = args[1] || 'cli'; const testType = args[2] || 'complete'; switch (command) { case 'start': GlobalTestManager.ensureTestForTool(toolName, testType).then(result => { console.log(JSON.stringify(result, null, 2)); }); break; case 'stop': GlobalTestManager.stopGlobalTest().then(result => { console.log(JSON.stringify(result, null, 2)); }); break; case 'status': const status = GlobalTestManager.getGlobalStatus(); console.log(JSON.stringify(status, null, 2)); break; default: console.log(` Global Test Manager - Universal Singleton Test System Usage: node global-test-manager.cjs <command> [toolName] [testType] Commands: start [toolName] [testType] Start test (toolName benefits from existing if running) stop Stop any running test status Show global test status Test Types: complete Full system test (test-complete-system.cjs) simple Simple database test (simple-test-runner.cjs) dummy Dummy test for validation (dummy-test-runner.cjs) Examples: node global-test-manager.cjs start my-tool complete node global-test-manager.cjs status node global-test-manager.cjs stop `); } }

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/pythondev-pro/egw_writings_mcp_server'

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