Skip to main content
Glama
rate-limit-standalone-test.js•5.87 kB
/** * Test Rate Limiting Implementation - Standalone */ import { RateLimiter } from '../lib/security/RateLimiter.js'; async function testRateLimiterStandalone() { console.log('šŸ”’ Testing Rate Limiter - Standalone'); console.log('==================================='); // Test 1: Basic functionality console.log('āœ“ Testing instantiation...'); const rateLimiter = new RateLimiter({ maxRequests: 10, windowMs: 5000, burstLimit: 3, burstWindowMs: 500 }); console.log('āœ… RateLimiter instantiated successfully'); // Test 2: Allow normal requests console.log('āœ“ Testing normal request flow...'); let result = await rateLimiter.isAllowed('client1', 'echo', { args: ['hello'] }); console.log('āœ… Normal request allowed:', result.allowed); console.log(' - Remaining requests:', result.remaining); console.log(' - Reset time:', new Date(result.resetTime)); // Test 3: Burst protection console.log('āœ“ Testing burst protection...'); const promises = []; for (let i = 0; i < 5; i++) { promises.push(rateLimiter.isAllowed('burst-client', 'test', {})); } const results = await Promise.all(promises); const allowedCount = results.filter(r => r.allowed).length; const deniedCount = results.filter(r => !r.allowed).length; console.log(`āœ… Burst test: ${allowedCount} allowed, ${deniedCount} denied`); // Test 4: Rate limit enforcement console.log('āœ“ Testing rate limit enforcement...'); const rapidClient = 'rapid-client'; let allowedRequests = 0; let deniedRequests = 0; for (let i = 0; i < 15; i++) { const result = await rateLimiter.isAllowed(rapidClient, 'test', {}); if (result.allowed) { allowedRequests++; } else { deniedRequests++; if (deniedRequests === 1) { console.log(' - First denial reason:', result.reason); console.log(' - Retry after:', result.retryAfter, 'ms'); } } await new Promise(resolve => setTimeout(resolve, 50)); } console.log(`āœ… Rate limit test: ${allowedRequests} allowed, ${deniedRequests} denied`); // Test 5: Suspicious activity detection console.log('āœ“ Testing suspicious activity detection...'); const suspiciousClient = 'suspicious-client'; let suspiciousBlocked = false; for (let i = 0; i < 30; i++) { const result = await rateLimiter.isAllowed(suspiciousClient, 'test', {}); if (!result.allowed && result.reason === 'SUSPICIOUS_ACTIVITY') { console.log('āœ… Suspicious activity detected at request', i + 1); suspiciousBlocked = true; break; } } if (!suspiciousBlocked) { console.log('āš ļø Suspicious activity not detected (might need adjustment)'); } // Test 6: Client isolation console.log('āœ“ Testing client isolation...'); const isolatedResult = await rateLimiter.isAllowed('isolated-client', 'test', {}); console.log('āœ… Isolated client not affected:', isolatedResult.allowed); // Test 7: Statistics console.log('āœ“ Testing statistics...'); const stats = rateLimiter.getStats(); console.log('āœ… Statistics available:'); console.log(' - Active clients:', stats.activeClients); console.log(' - Blocked clients:', stats.blockedClients); console.log(' - Suspicious clients:', stats.suspiciousClients); console.log(' - Rate limit config:', stats.rateLimitConfig); // Test 8: Error handling for invalid inputs console.log('āœ“ Testing error handling...'); try { await rateLimiter.isAllowed(null, 'test', {}); console.log('āš ļø Null client ID should be handled gracefully'); } catch (error) { console.log('āœ… Error handling works for invalid inputs'); } // Test 9: Window reset behavior console.log('āœ“ Testing window reset behavior...'); const resetClient = 'reset-client'; await rateLimiter.isAllowed(resetClient, 'test', {}); console.log(' - Waiting for partial window reset...'); await new Promise(resolve => setTimeout(resolve, 1000)); const afterWaitResult = await rateLimiter.isAllowed(resetClient, 'test', {}); console.log('āœ… Window reset behavior working:', afterWaitResult.allowed); // Cleanup rateLimiter.destroy(); console.log('āœ… RateLimiter cleanup completed'); return true; } async function testRateLimiterConfiguration() { console.log('\nšŸ”§ Testing Rate Limiter Configuration'); console.log('===================================='); // Test different configurations const configs = [ { name: 'Strict', maxRequests: 5, windowMs: 1000, burstLimit: 1 }, { name: 'Moderate', maxRequests: 20, windowMs: 5000, burstLimit: 5 }, { name: 'Lenient', maxRequests: 100, windowMs: 60000, burstLimit: 20 } ]; for (const config of configs) { console.log(`āœ“ Testing ${config.name} configuration...`); const limiter = new RateLimiter(config); let allowed = 0; for (let i = 0; i < config.burstLimit + 2; i++) { const result = await limiter.isAllowed('test', 'cmd', {}); if (result.allowed) allowed++; } console.log(`āœ… ${config.name}: ${allowed} requests allowed of ${config.burstLimit + 2} attempted`); limiter.destroy(); } return true; } async function runAllTests() { try { console.log('šŸš€ Starting Rate Limiter Standalone Tests\n'); await testRateLimiterStandalone(); await testRateLimiterConfiguration(); console.log('\nšŸ“Š Test Summary:'); console.log('āœ… All rate limiter tests passed!'); console.log('šŸŽ‰ Rate limiting implementation is working correctly'); return true; } catch (error) { console.error('āŒ Tests failed:', error); console.error(error.stack); return false; } } // Run tests if called directly if (import.meta.url === `file://${process.argv[1]}`) { runAllTests().then(success => { process.exit(success ? 0 : 1); }); } export { runAllTests };

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/moikas-code/moidvk'

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