add changes
This commit is contained in:
203
backend/test-performance.js
Normal file
203
backend/test-performance.js
Normal file
@@ -0,0 +1,203 @@
|
||||
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);
|
||||
Reference in New Issue
Block a user