204 lines
8.0 KiB
JavaScript
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);
|