UNPKG

@simonecoelhosfo/optimizely-mcp-server

Version:

Optimizely MCP Server for AI assistants with integrated CLI tools

216 lines (214 loc) 9 kB
/** * Test script for cache integration with actual data * Creates test data and verifies caching behavior */ import { IntelligentQueryEngine } from './IntelligentQueryEngine.js'; import { OptimizelyAdapter } from './adapters/OptimizelyAdapter.js'; import { getLogger } from '../../logging/Logger.js'; import Database from 'better-sqlite3'; const logger = getLogger(); async function setupTestData(db) { console.info('Setting up test data...'); // Create tables db.exec(` CREATE TABLE IF NOT EXISTS flags ( id TEXT PRIMARY KEY, key TEXT NOT NULL, name TEXT, description TEXT, enabled INTEGER DEFAULT 1, archived INTEGER DEFAULT 0, project_id TEXT, environments TEXT, created TEXT, last_modified TEXT ); CREATE TABLE IF NOT EXISTS experiments ( id TEXT PRIMARY KEY, key TEXT NOT NULL, name TEXT, description TEXT, status TEXT, project_id TEXT, campaign_id TEXT, created TEXT, last_modified TEXT ); CREATE TABLE IF NOT EXISTS audiences ( id TEXT PRIMARY KEY, key TEXT, name TEXT NOT NULL, description TEXT, conditions TEXT, project_id TEXT, archived INTEGER DEFAULT 0, created TEXT, last_modified TEXT ); `); // Insert test flags const insertFlag = db.prepare(` INSERT INTO flags (id, key, name, description, enabled, project_id, environments, created, last_modified) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) `); for (let i = 1; i <= 20; i++) { insertFlag.run(`flag_${i}`, `test_flag_${i}`, `Test Flag ${i}`, `Description for test flag ${i}`, i % 3 !== 0 ? 1 : 0, // Every 3rd flag is disabled 'test_project', JSON.stringify({ production: { enabled: true }, staging: { enabled: false } }), new Date().toISOString(), new Date().toISOString()); } // Insert test experiments const insertExp = db.prepare(` INSERT INTO experiments (id, key, name, description, status, project_id, created, last_modified) VALUES (?, ?, ?, ?, ?, ?, ?, ?) `); const statuses = ['running', 'paused', 'completed']; for (let i = 1; i <= 15; i++) { insertExp.run(`exp_${i}`, `test_experiment_${i}`, `Test Experiment ${i}`, `Description for experiment ${i}`, statuses[i % 3], 'test_project', new Date().toISOString(), new Date().toISOString()); } // Insert test audiences const insertAud = db.prepare(` INSERT INTO audiences (id, name, description, conditions, project_id, created, last_modified) VALUES (?, ?, ?, ?, ?, ?, ?) `); for (let i = 1; i <= 10; i++) { insertAud.run(`aud_${i}`, `Test Audience ${i}`, `Description for audience ${i}`, JSON.stringify({ type: 'custom_attribute', name: `attr_${i}`, value: `value_${i}` }), 'test_project', new Date().toISOString(), new Date().toISOString()); } console.info('Test data created successfully'); } async function runCacheTest() { console.info('Starting cache integration test with data'); try { // Initialize in-memory database const db = new Database(':memory:'); // Setup test data await setupTestData(db); // Create engine with cache enabled const engine = new IntelligentQueryEngine({ cache: { enabled: true, warmupOnStart: false, statsInterval: 5000, // 5 seconds for testing defaultTTL: 30000, // 30 seconds for testing } }); // Register Optimizely adapter const adapter = new OptimizelyAdapter({ database: db }); engine.registerAdapter(adapter); // Test queries const testQueries = [ { name: 'List enabled flags', query: { find: 'flags', select: ['key', 'name', 'enabled'], where: [{ field: 'enabled', operator: '=', value: 1 }], limit: 10, } }, { name: 'Count experiments by status', query: { find: 'experiments', select: ['status'], groupBy: ['status'], aggregations: [{ field: 'id', function: 'COUNT', alias: 'count' }], } }, { name: 'Get audience details', query: { find: 'audiences', select: ['id', 'name', 'conditions'], limit: 5, } }, { name: 'Complex flag query', query: { find: 'flags', select: ['key', 'name', 'description', 'environments'], where: [ { field: 'enabled', operator: '=', value: 1 }, { field: 'archived', operator: '=', value: 0 } ], orderBy: [{ field: 'name', direction: 'ASC' }], limit: 20, } } ]; console.info('=== Running Cache Performance Tests ===\n'); const results = []; // Run each query multiple times for (const test of testQueries) { console.info(`\nTesting: ${test.name}`); console.info('─'.repeat(50)); const timings = []; const cacheHits = []; // Run 5 times to see cache behavior for (let run = 1; run <= 5; run++) { const start = Date.now(); const result = await engine.query(test.query); const elapsed = Date.now() - start; timings.push(elapsed); cacheHits.push(result.metadata.cached || false); console.info(` Run ${run}: ${elapsed}ms ${result.metadata.cached ? 'CACHED' : 'NOT CACHED'} - ${result.data.length} rows`); } // Calculate statistics const avgTime = timings.reduce((a, b) => a + b, 0) / timings.length; const cacheHitRate = cacheHits.filter(h => h).length / cacheHits.length * 100; const speedup = timings[0] > 0 ? ((timings[0] - timings[timings.length - 1]) / timings[0] * 100).toFixed(1) : 0; console.info(`\n 📈 Stats:`); console.info(` Average time: ${avgTime.toFixed(1)}ms`); console.info(` Cache hit rate: ${cacheHitRate.toFixed(0)}%`); console.info(` Speed improvement: ${speedup}%`); results.push({ query: test.name, avgTime, cacheHitRate, speedup }); } // Test cache invalidation console.info('\n\n=== Testing Cache Invalidation ==='); console.info('─'.repeat(50)); const beforeInvalidation = await engine.query(testQueries[0].query); console.info(`Before invalidation: ${beforeInvalidation.metadata.cached ? 'CACHED' : 'NOT CACHED'}`); const invalidated = await engine.invalidateCache('flags'); console.info(`Invalidated ${invalidated} cache entries for flags`); const afterInvalidation = await engine.query(testQueries[0].query); console.info(`After invalidation: ${afterInvalidation.metadata.cached ? 'CACHED' : 'NOT CACHED'}`); // Get final statistics console.info('\n\n=== Cache Statistics ==='); console.info('─'.repeat(50)); const cacheMetrics = engine.getCacheMetrics(); console.info(`Hit Rate: ${(cacheMetrics.hitRate * 100).toFixed(1)}%`); console.info(`Total Entries: ${cacheMetrics.entries}`); console.info(`Cache Size: ${(cacheMetrics.sizeBytes / 1024).toFixed(1)} KB`); console.info(`\nRecommended TTLs:`); Object.entries(cacheMetrics.recommendedTTLs).forEach(([scenario, ttl]) => { console.info(` ${scenario}: ${ttl / 1000}s`); }); // Summary console.info('\n\n=== Performance Summary ==='); console.info('─'.repeat(50)); results.forEach(r => { console.info(`${r.query}:`); console.info(` ⚡ Avg: ${r.avgTime.toFixed(1)}ms | Cache: ${r.cacheHitRate}% | Speedup: ${r.speedup}%`); }); // Wait a bit to see stats reporting console.info('\n\nWaiting 6 seconds to see periodic stats reporting...'); await new Promise(resolve => setTimeout(resolve, 6000)); // Shutdown await engine.shutdown(); console.info('\nCache integration test completed successfully!'); } catch (error) { console.error('Test failed: ' + String(error)); throw error; } } // Run the test runCacheTest().catch(error => { console.error('Fatal error: ' + String(error)); process.exit(1); }); //# sourceMappingURL=test-cache-with-data.js.map