Files
Tasks/backend/test-performance.js
2025-11-12 23:06:27 +02:00

204 lines
8.0 KiB
JavaScript

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);