const axios = require('axios'); const BASE_URL = 'http://localhost:3000/api'; // Test configuration const ITERATIONS = 10; // Colors for terminal output const colors = { reset: '\x1b[0m', green: '\x1b[32m', yellow: '\x1b[33m', blue: '\x1b[34m', cyan: '\x1b[36m', magenta: '\x1b[35m' }; const log = (message, color = 'reset') => { console.log(`${colors[color]}${message}${colors.reset}`); }; /** * Measure endpoint performance */ const measureEndpoint = async (name, url, options = {}) => { const times = []; for (let i = 0; i < ITERATIONS; i++) { const startTime = Date.now(); try { await axios.get(url, options); const endTime = Date.now(); times.push(endTime - startTime); } catch (error) { // Some endpoints may return errors (401, etc.) but we still measure time const endTime = Date.now(); times.push(endTime - startTime); } } const avg = times.reduce((a, b) => a + b, 0) / times.length; const min = Math.min(...times); const max = Math.max(...times); return { name, avg, min, max, times }; }; /** * Run performance benchmarks */ async function runBenchmarks() { log('\n═══════════════════════════════════════════════════════', 'cyan'); log(' Performance Benchmark Test Suite', 'cyan'); log('═══════════════════════════════════════════════════════', 'cyan'); log(`\n📊 Running ${ITERATIONS} iterations per endpoint...\n`, 'blue'); const results = []; try { // Test 1: Categories list (should be cached after first request) log('Testing: GET /categories', 'yellow'); const categoriesResult = await measureEndpoint( 'Categories List', `${BASE_URL}/categories` ); results.push(categoriesResult); log(` Average: ${categoriesResult.avg.toFixed(2)}ms`, 'green'); // Test 2: Health check (simple query) log('\nTesting: GET /health', 'yellow'); const healthResult = await measureEndpoint( 'Health Check', 'http://localhost:3000/health' ); results.push(healthResult); log(` Average: ${healthResult.avg.toFixed(2)}ms`, 'green'); // Test 3: API docs JSON (file serving) log('\nTesting: GET /api-docs.json', 'yellow'); const docsResult = await measureEndpoint( 'API Documentation', 'http://localhost:3000/api-docs.json' ); results.push(docsResult); log(` Average: ${docsResult.avg.toFixed(2)}ms`, 'green'); // Test 4: Guest session creation (database write) log('\nTesting: POST /guest/start-session', 'yellow'); const guestTimes = []; for (let i = 0; i < ITERATIONS; i++) { const startTime = Date.now(); try { await axios.post(`${BASE_URL}/guest/start-session`); const endTime = Date.now(); guestTimes.push(endTime - startTime); } catch (error) { // Rate limited, still measure const endTime = Date.now(); guestTimes.push(endTime - startTime); } // Small delay to avoid rate limiting await new Promise(resolve => setTimeout(resolve, 100)); } const guestAvg = guestTimes.reduce((a, b) => a + b, 0) / guestTimes.length; results.push({ name: 'Guest Session Creation', avg: guestAvg, min: Math.min(...guestTimes), max: Math.max(...guestTimes), times: guestTimes }); log(` Average: ${guestAvg.toFixed(2)}ms`, 'green'); // Summary log('\n═══════════════════════════════════════════════════════', 'cyan'); log(' Performance Summary', 'cyan'); log('═══════════════════════════════════════════════════════', 'cyan'); results.sort((a, b) => a.avg - b.avg); results.forEach((result, index) => { const emoji = index === 0 ? '🏆' : index === 1 ? '🥈' : index === 2 ? '🥉' : '📊'; log(`\n${emoji} ${result.name}:`, 'blue'); log(` Average: ${result.avg.toFixed(2)}ms`, 'green'); log(` Min: ${result.min}ms`, 'cyan'); log(` Max: ${result.max}ms`, 'cyan'); // Performance rating if (result.avg < 50) { log(' Rating: ⚡ Excellent', 'green'); } else if (result.avg < 100) { log(' Rating: ✓ Good', 'green'); } else if (result.avg < 200) { log(' Rating: ⚠ Fair', 'yellow'); } else { log(' Rating: ⚠️ Needs Optimization', 'yellow'); } }); // Cache effectiveness test log('\n═══════════════════════════════════════════════════════', 'cyan'); log(' Cache Effectiveness Test', 'cyan'); log('═══════════════════════════════════════════════════════', 'cyan'); log('\n🔄 Testing cache hit vs miss for categories...', 'blue'); // Clear cache by making a write operation (if applicable) // First request (cache miss) const cacheMissStart = Date.now(); await axios.get(`${BASE_URL}/categories`); const cacheMissTime = Date.now() - cacheMissStart; // Second request (cache hit) const cacheHitStart = Date.now(); await axios.get(`${BASE_URL}/categories`); const cacheHitTime = Date.now() - cacheHitStart; log(`\n First Request (cache miss): ${cacheMissTime}ms`, 'yellow'); log(` Second Request (cache hit): ${cacheHitTime}ms`, 'green'); if (cacheHitTime < cacheMissTime) { const improvement = ((1 - cacheHitTime / cacheMissTime) * 100).toFixed(1); log(` Cache Improvement: ${improvement}% faster 🚀`, 'green'); } // Overall statistics log('\n═══════════════════════════════════════════════════════', 'cyan'); log(' Overall Statistics', 'cyan'); log('═══════════════════════════════════════════════════════', 'cyan'); const overallAvg = results.reduce((sum, r) => sum + r.avg, 0) / results.length; const fastest = results[0]; const slowest = results[results.length - 1]; log(`\n Total Endpoints Tested: ${results.length}`, 'blue'); log(` Total Requests Made: ${results.length * ITERATIONS}`, 'blue'); log(` Overall Average: ${overallAvg.toFixed(2)}ms`, 'magenta'); log(` Fastest Endpoint: ${fastest.name} (${fastest.avg.toFixed(2)}ms)`, 'green'); log(` Slowest Endpoint: ${slowest.name} (${slowest.avg.toFixed(2)}ms)`, 'yellow'); if (overallAvg < 100) { log('\n 🎉 Overall Performance: EXCELLENT', 'green'); } else if (overallAvg < 200) { log('\n ✓ Overall Performance: GOOD', 'green'); } else { log('\n ⚠️ Overall Performance: NEEDS IMPROVEMENT', 'yellow'); } log('\n═══════════════════════════════════════════════════════', 'cyan'); log(' Benchmark complete! Performance data collected.', 'cyan'); log('═══════════════════════════════════════════════════════\n', 'cyan'); } catch (error) { log(`\n❌ Benchmark error: ${error.message}`, 'yellow'); console.error(error); } } // Run benchmarks console.log('\nStarting performance benchmarks in 2 seconds...'); console.log('Make sure the server is running on http://localhost:3000\n'); setTimeout(runBenchmarks, 2000);