Skip to main content
Glama
demo-endpoint-test.cjs18.1 kB
#!/usr/bin/env node /** * Demo Endpoint Test Script * Demonstrates the comprehensive testing framework with mock data * Shows the structure and capabilities without requiring real credentials */ const fs = require('fs'); const path = require('path'); // Mock test results to demonstrate the comprehensive testing capabilities const MOCK_TEST_RESULTS = [ // SAOLA (Direct Customer) Results { account: 'SAOLA', customer: 'Direct', endpoint: '/invoices/caui', category: 'Cost Analysis', variation: 'Basic unblended costs', tool: 'api__invoices_caui', method: 'GET', success: true, hasData: true, duration: 1250, responseSize: 15240, statusCode: 200, errorMessage: null, timestamp: new Date().toISOString(), sampleData: '{"data":[{"date":"2024-01","cost":1250.45,"service":"EC2"}...]}' }, { account: 'SAOLA', customer: 'Direct', endpoint: '/budgets/v2/i/', category: 'Budget Management', variation: 'AWS budgets only', tool: 'api__budgets_v2_i_', method: 'GET', success: true, hasData: true, duration: 890, responseSize: 8530, statusCode: 200, errorMessage: null, timestamp: new Date().toISOString(), sampleData: '{"data":[{"budgetName":"Monthly AWS Budget","budgetAmount":5000}...]}' }, { account: 'SAOLA', customer: 'Direct', endpoint: '/recommendationsNew/heatmap/summary', category: 'Recommendations', variation: 'All recommendations summary', tool: 'api__recommendationsNew_heatmap_summary', method: 'POST', success: true, hasData: true, duration: 2100, responseSize: 12800, statusCode: 200, errorMessage: null, timestamp: new Date().toISOString(), sampleData: '{"potentialAnnualSavings":25000,"actualAnnualSavings":5000}...' }, // AllCloud (MSP) - Bank Leumi Results { account: 'AllCloud', customer: 'Bank Leumi', endpoint: '/invoices/caui', category: 'Cost Analysis', variation: 'Service breakdown - amortized', tool: 'api__invoices_caui', method: 'GET', success: true, hasData: true, duration: 1850, responseSize: 28400, statusCode: 200, errorMessage: null, timestamp: new Date().toISOString(), sampleData: '{"data":[{"service":"EC2","cost":45000,"date":"2024-01"}...]}' }, { account: 'AllCloud', customer: 'Bank Leumi', endpoint: '/recommendationsNew/heatmap/summary', category: 'Recommendations', variation: 'All recommendations summary', tool: 'api__recommendationsNew_heatmap_summary', method: 'POST', success: true, hasData: true, duration: 3200, responseSize: 18600, statusCode: 200, errorMessage: null, timestamp: new Date().toISOString(), sampleData: '{"potentialAnnualSavings":120000,"actualAnnualSavings":15000}...' }, // AllCloud (MSP) - Bank Hapoalim Results { account: 'AllCloud', customer: 'Bank Hapoalim', endpoint: '/invoices/caui', category: 'Cost Analysis', variation: 'EC2 costs only', tool: 'api__invoices_caui', method: 'GET', success: true, hasData: true, duration: 1100, responseSize: 9240, statusCode: 200, errorMessage: null, timestamp: new Date().toISOString(), sampleData: '{"data":[{"service":"EC2","region":"us-east-1","cost":8500}...]}' }, { account: 'AllCloud', customer: 'Bank Hapoalim', endpoint: '/recommendationsNew/heatmap/summary', category: 'Recommendations', variation: 'All recommendations summary', tool: 'api__recommendationsNew_heatmap_summary', method: 'POST', success: true, hasData: true, duration: 2800, responseSize: 14200, statusCode: 200, errorMessage: null, timestamp: new Date().toISOString(), sampleData: '{"potentialAnnualSavings":85000,"actualAnnualSavings":12000}...' }, // Some failed tests to show error handling { account: 'SAOLA', customer: 'Direct', endpoint: '/kubernetes', category: 'Kubernetes', variation: 'All Kubernetes costs', tool: 'api__kubernetes', method: 'GET', success: false, hasData: false, duration: 1500, responseSize: 156, statusCode: 404, errorMessage: 'No Kubernetes clusters found for this account', timestamp: new Date().toISOString(), sampleData: null }, { account: 'AllCloud', customer: 'Bank Leumi', endpoint: '/anomaly-detection', category: 'Anomaly Detection', variation: 'Recent anomalies', tool: 'api__anomaly_detection', method: 'GET', success: false, hasData: false, duration: 800, responseSize: 203, statusCode: 403, errorMessage: 'Insufficient permissions for anomaly detection data', timestamp: new Date().toISOString(), sampleData: null } ]; class DemoTester { constructor() { this.results = MOCK_TEST_RESULTS; this.startTime = Date.now() - 45000; // Simulate 45 second test run } log(message, level = 'info') { const timestamp = new Date().toISOString().split('.')[0]; const levelEmoji = { info: '📋', success: '✅', error: '❌', warning: '⚠️', test: '🧪' }[level] || '📋'; console.log(`${timestamp} ${levelEmoji} ${message}`); } demonstrateComprehensiveTesting() { this.log('🚀 COMPREHENSIVE ENDPOINT TESTING DEMONSTRATION', 'info'); this.log('This demo shows what the full test would produce with real credentials\n', 'info'); const totalTests = this.results.length; const successfulTests = this.results.filter(r => r.success).length; const failedTests = this.results.filter(r => !r.success).length; const testsWithData = this.results.filter(r => r.hasData).length; const totalDuration = Date.now() - this.startTime; // Overall Summary this.log('📊 TEST EXECUTION SUMMARY:', 'info'); this.log(`Total Tests Run: ${totalTests}`, 'info'); this.log(`Successful: ${successfulTests} (${((successfulTests/totalTests)*100).toFixed(1)}%)`, 'success'); this.log(`Failed: ${failedTests} (${((failedTests/totalTests)*100).toFixed(1)}%)`, 'error'); this.log(`With Data: ${testsWithData} (${((testsWithData/totalTests)*100).toFixed(1)}%)`, 'info'); this.log(`Total Duration: ${(totalDuration/1000).toFixed(1)}s`, 'info'); // Account Breakdown this.log('\n🏢 ACCOUNT PERFORMANCE:', 'info'); const accounts = [...new Set(this.results.map(r => r.account))]; accounts.forEach(account => { const accountTests = this.results.filter(r => r.account === account); const accountSuccess = accountTests.filter(r => r.success).length; const accountWithData = accountTests.filter(r => r.hasData).length; const avgDuration = accountTests.reduce((sum, r) => sum + r.duration, 0) / accountTests.length; const totalDataSize = accountTests.reduce((sum, r) => sum + r.responseSize, 0); this.log(`${account}:`, 'info'); this.log(` Tests: ${accountTests.length}`, 'info'); this.log(` Success Rate: ${accountSuccess}/${accountTests.length} (${((accountSuccess/accountTests.length)*100).toFixed(1)}%)`, 'info'); this.log(` Data Rate: ${accountWithData}/${accountTests.length} (${((accountWithData/accountTests.length)*100).toFixed(1)}%)`, 'info'); this.log(` Avg Response Time: ${Math.round(avgDuration)}ms`, 'info'); this.log(` Total Data Retrieved: ${(totalDataSize/1024).toFixed(1)}KB`, 'info'); }); // Category Analysis this.log('\n📂 ENDPOINT CATEGORY ANALYSIS:', 'info'); const categories = [...new Set(this.results.map(r => r.category))]; categories.forEach(category => { const categoryTests = this.results.filter(r => r.category === category); const categorySuccess = categoryTests.filter(r => r.success).length; const categoryWithData = categoryTests.filter(r => r.hasData).length; this.log(`${category}: ${categorySuccess}/${categoryTests.length} working (${categoryWithData} with data)`, 'info'); }); // Successful Endpoints this.log('\n✅ WORKING ENDPOINTS (with data):', 'success'); const workingEndpoints = this.results.filter(r => r.success && r.hasData); workingEndpoints.forEach(result => { const customerInfo = result.customer !== 'Direct' ? ` (${result.customer})` : ''; this.log(` ${result.endpoint} - ${result.variation}${customerInfo} - ${result.duration}ms`, 'info'); }); // Failed Endpoints if (failedTests > 0) { this.log('\n❌ FAILED ENDPOINTS:', 'error'); const failedEndpoints = this.results.filter(r => !r.success); failedEndpoints.forEach(result => { const customerInfo = result.customer !== 'Direct' ? ` (${result.customer})` : ''; this.log(` ${result.endpoint}${customerInfo} - ${result.statusCode}: ${result.errorMessage}`, 'warning'); }); } // MSP Customer Comparison this.log('\n🏦 MSP CUSTOMER COMPARISON:', 'info'); const mspResults = this.results.filter(r => r.customer !== 'Direct'); const customerGroups = {}; mspResults.forEach(result => { if (!customerGroups[result.customer]) { customerGroups[result.customer] = []; } customerGroups[result.customer].push(result); }); Object.entries(customerGroups).forEach(([customer, tests]) => { const successful = tests.filter(t => t.success).length; const withData = tests.filter(t => t.hasData).length; const totalSavings = this.extractSavingsFromResults(tests); this.log(`${customer}:`, 'info'); this.log(` Endpoint Tests: ${successful}/${tests.length} successful`, 'info'); this.log(` Data Available: ${withData}/${tests.length} endpoints`, 'info'); if (totalSavings > 0) { this.log(` Potential Annual Savings: $${totalSavings.toLocaleString()}`, 'info'); } }); // Performance Metrics this.log('\n⚡ PERFORMANCE METRICS:', 'info'); const durations = this.results.map(r => r.duration); const avgDuration = durations.reduce((sum, d) => sum + d, 0) / durations.length; const maxDuration = Math.max(...durations); const minDuration = Math.min(...durations); this.log(`Average Response Time: ${Math.round(avgDuration)}ms`, 'info'); this.log(`Fastest Response: ${minDuration}ms`, 'info'); this.log(`Slowest Response: ${maxDuration}ms`, 'info'); // Data Volume Analysis const totalDataRetrieved = this.results.reduce((sum, r) => sum + r.responseSize, 0); this.log(`Total Data Retrieved: ${(totalDataRetrieved/1024/1024).toFixed(2)}MB`, 'info'); this.generateDemoReports(); } extractSavingsFromResults(tests) { // Extract potential savings from sample data (mock) let totalSavings = 0; tests.forEach(test => { if (test.sampleData && test.sampleData.includes('potentialAnnualSavings')) { const match = test.sampleData.match(/"potentialAnnualSavings":(\d+)/); if (match) { totalSavings += parseInt(match[1]); } } }); return totalSavings; } generateDemoReports() { this.log('\n📋 GENERATING COMPREHENSIVE REPORTS:', 'info'); // Summary Report const summaryReport = { testRun: { startTime: new Date(this.startTime).toISOString(), endTime: new Date().toISOString(), duration: Date.now() - this.startTime, totalTests: this.results.length, successfulTests: this.results.filter(r => r.success).length, failedTests: this.results.filter(r => !r.success).length, testsWithData: this.results.filter(r => r.hasData).length }, endpointCoverage: this.calculateEndpointCoverage(), accountPerformance: this.calculateAccountPerformance(), categoryAnalysis: this.calculateCategoryAnalysis(), performanceMetrics: this.calculatePerformanceMetrics(), errorAnalysis: this.calculateErrorAnalysis() }; const summaryPath = path.join(__dirname, `demo-test-summary-${Date.now()}.json`); fs.writeFileSync(summaryPath, JSON.stringify(summaryReport, null, 2)); this.log(`Summary Report: ${summaryPath}`, 'success'); // Detailed Results const detailedPath = path.join(__dirname, `demo-test-results-${Date.now()}.json`); fs.writeFileSync(detailedPath, JSON.stringify(this.results, null, 2)); this.log(`Detailed Results: ${detailedPath}`, 'success'); // CSV Export const csvHeaders = [ 'Account', 'Customer', 'Endpoint', 'Category', 'Variation', 'Method', 'Success', 'HasData', 'StatusCode', 'Duration(ms)', 'ResponseSize(bytes)', 'ErrorMessage', 'Timestamp' ]; const csvRows = this.results.map(r => [ r.account, r.customer, r.endpoint, r.category, r.variation, r.method, r.success, r.hasData, r.statusCode, r.duration, r.responseSize, r.errorMessage || '', r.timestamp ]); const csvContent = [csvHeaders.join(','), ...csvRows.map(row => row.map(cell => `"${cell}"`).join(',') )].join('\n'); const csvPath = path.join(__dirname, `demo-test-results-${Date.now()}.csv`); fs.writeFileSync(csvPath, csvContent); this.log(`CSV Export: ${csvPath}`, 'success'); this.log('\n📊 WHAT THE REAL TEST PROVIDES:', 'info'); this.log('• Comprehensive endpoint coverage across all API categories', 'info'); this.log('• Multi-account testing (Direct customers vs MSP customers)', 'info'); this.log('• Parameter variation testing for each endpoint', 'info'); this.log('• Performance metrics and response time analysis', 'info'); this.log('• Data availability and content verification', 'info'); this.log('• Error detection and categorization', 'info'); this.log('• Customer-specific testing for MSP accounts', 'info'); this.log('• Detailed reporting in multiple formats (JSON, CSV)', 'info'); this.log('• Automated test execution without human intervention', 'info'); this.log('\n🎯 TO RUN THE FULL TEST:', 'warning'); this.log('1. Set environment variables:', 'info'); this.log(' export SAOLA_PASSWORD="your_saola_password"', 'info'); this.log(' export ALLCLOUD_PASSWORD="your_allcloud_password"', 'info'); this.log('2. Run the comprehensive test:', 'info'); this.log(' node scripts/debug/direct-api-comprehensive-test.cjs', 'info'); this.log(' # OR', 'info'); this.log(' node scripts/debug/mcp-endpoint-test.cjs', 'info'); } calculateEndpointCoverage() { const uniqueEndpoints = [...new Set(this.results.map(r => r.endpoint))]; const successfulEndpoints = [...new Set(this.results.filter(r => r.success).map(r => r.endpoint))]; return { totalEndpointsTested: uniqueEndpoints.length, successfulEndpoints: successfulEndpoints.length, coverageRate: ((successfulEndpoints.length / uniqueEndpoints.length) * 100).toFixed(1) }; } calculateAccountPerformance() { const accounts = [...new Set(this.results.map(r => r.account))]; const performance = {}; accounts.forEach(account => { const accountTests = this.results.filter(r => r.account === account); performance[account] = { totalTests: accountTests.length, successful: accountTests.filter(r => r.success).length, withData: accountTests.filter(r => r.hasData).length, avgDuration: Math.round(accountTests.reduce((sum, r) => sum + r.duration, 0) / accountTests.length), totalDataSize: accountTests.reduce((sum, r) => sum + r.responseSize, 0) }; }); return performance; } calculateCategoryAnalysis() { const categories = [...new Set(this.results.map(r => r.category))]; const analysis = {}; categories.forEach(category => { const categoryTests = this.results.filter(r => r.category === category); analysis[category] = { totalTests: categoryTests.length, successful: categoryTests.filter(r => r.success).length, withData: categoryTests.filter(r => r.hasData).length, avgDuration: Math.round(categoryTests.reduce((sum, r) => sum + r.duration, 0) / categoryTests.length) }; }); return analysis; } calculatePerformanceMetrics() { const durations = this.results.map(r => r.duration); const responseSizes = this.results.map(r => r.responseSize); return { responseTime: { average: Math.round(durations.reduce((sum, d) => sum + d, 0) / durations.length), min: Math.min(...durations), max: Math.max(...durations) }, dataTransfer: { totalBytes: responseSizes.reduce((sum, s) => sum + s, 0), averageBytes: Math.round(responseSizes.reduce((sum, s) => sum + s, 0) / responseSizes.length), maxResponseSize: Math.max(...responseSizes) } }; } calculateErrorAnalysis() { const errors = this.results.filter(r => !r.success); const errorsByStatus = {}; const errorsByEndpoint = {}; errors.forEach(error => { errorsByStatus[error.statusCode] = (errorsByStatus[error.statusCode] || 0) + 1; errorsByEndpoint[error.endpoint] = (errorsByEndpoint[error.endpoint] || 0) + 1; }); return { totalErrors: errors.length, errorsByStatusCode: errorsByStatus, errorsByEndpoint: errorsByEndpoint, commonErrors: errors.slice(0, 5).map(e => ({ endpoint: e.endpoint, statusCode: e.statusCode, message: e.errorMessage })) }; } } // Main execution function main() { console.log('🧪 Comprehensive Endpoint Testing Framework Demo'); console.log('================================================\n'); const demo = new DemoTester(); demo.demonstrateComprehensiveTesting(); console.log('\n🎉 Demo completed! This shows what the full automated test provides.'); console.log('The actual test will run all endpoints with real authentication and data.'); } if (require.main === module) { main(); } module.exports = { DemoTester };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/daviddraiumbrella/invoice-monitoring'

If you have feedback or need assistance with the MCP directory API, please join our Discord server