stock-bot/apps/stock/data-ingestion/test/test-advanced-rate-limit.ts
2025-07-06 18:53:02 -04:00

100 lines
No EOL
3.5 KiB
TypeScript
Executable file
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bun
import { getLogger } from '@stock-bot/logger';
const logger = getLogger('test-advanced-rate-limit');
async function testAdvancedRateLimits() {
logger.info('Testing advanced rate limit features...');
const baseUrl = 'http://localhost:3001/api';
logger.info('\n📋 Rate Limit Configuration:');
logger.info('Handler limits: 100pts/sec, 10k pts/hour, 100k pts/day');
logger.info('fetch-daily-prices: 1 point per call');
logger.info('fetch-fundamentals: 10 points per call');
logger.info('fetch-news: 50 points per call (custom limits: 10pts/min, 100pts/hour)');
// First test: test-burst operation
logger.info('\n🚀 Testing burst operation with mixed costs...');
const burstResponse = await fetch(`${baseUrl}/handlers/eod/operations/test-burst`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
operationsToTest: ['fetch-daily-prices', 'fetch-fundamentals', 'fetch-news'],
burstSize: 30
})
});
const burstResult = await burstResponse.json();
logger.info('Burst test result:', burstResult);
// Wait for jobs to process
logger.info('\n⏳ Waiting 10 seconds for jobs to process...');
await new Promise(resolve => setTimeout(resolve, 10000));
// Test individual operations with different costs
logger.info('\n📊 Testing individual operations:');
// Test cheap operation (1 point)
logger.info('\n1⃣ Testing fetch-daily-prices (1 point each)...');
for (let i = 0; i < 5; i++) {
const response = await fetch(`${baseUrl}/handlers/eod/operations/fetch-daily-prices`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ test: true, index: i })
});
logger.info(`Request ${i + 1}: ${response.status} ${response.statusText}`);
}
// Test medium cost operation (10 points)
logger.info('\n🔟 Testing fetch-fundamentals (10 points each)...');
for (let i = 0; i < 3; i++) {
const response = await fetch(`${baseUrl}/handlers/eod/operations/fetch-fundamentals`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ test: true, index: i })
});
logger.info(`Request ${i + 1}: ${response.status} ${response.statusText}`);
}
// Test expensive operation (50 points)
logger.info('\n💰 Testing fetch-news (50 points each, custom limits)...');
for (let i = 0; i < 2; i++) {
const response = await fetch(`${baseUrl}/handlers/eod/operations/fetch-news`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ test: true, index: i })
});
logger.info(`Request ${i + 1}: ${response.status} ${response.statusText}`);
}
logger.info('\n✅ Test completed!');
logger.info('Check the data-ingestion service logs to see rate limiting in action.');
}
// Health check before running tests
async function checkService() {
try {
const response = await fetch('http://localhost:3001/health');
if (!response.ok) {
throw new Error('Service not healthy');
}
return true;
} catch (error) {
logger.error('Data ingestion service not running. Start it with: bun run dev');
return false;
}
}
async function main() {
if (await checkService()) {
await testAdvancedRateLimits();
}
}
main().catch(error => {
logger.error('Test failed:', error);
process.exit(1);
});