Skip to main content
Glama
test-cache-configurations.js•15.9 kB
#!/usr/bin/env node /** * Comprehensive Cache Configuration Testing * Tests both single-site and multi-site caching scenarios */ import { performance } from "perf_hooks"; import { MCPWordPressServer } from "../dist/index.js"; import * as fs from "fs"; import * as path from "path"; /** * Test Results Tracker */ class TestResults { constructor() { this.tests = []; this.passed = 0; this.failed = 0; } addTest(name, status, details = "") { this.tests.push({ name, status, details, timestamp: new Date() }); if (status === "PASS") this.passed++; if (status === "FAIL") this.failed++; const icon = status === "PASS" ? "✅" : status === "FAIL" ? "❌" : "⏳"; console.log(`${icon} ${name}${details ? ` - ${details}` : ""}`); } summary() { console.log("\n📊 Test Summary"); console.log("================"); console.log(`Total Tests: ${this.tests.length}`); console.log(`Passed: ${this.passed}`); console.log(`Failed: ${this.failed}`); console.log(`Success Rate: ${Math.round((this.passed / this.tests.length) * 100)}%`); } } /** * Configuration Helper */ class ConfigHelper { static backupConfig() { const configPath = "mcp-wordpress.config.json"; const backupPath = "mcp-wordpress.config.json.backup"; if (fs.existsSync(configPath)) { fs.copyFileSync(configPath, backupPath); return true; } return false; } static restoreConfig() { const configPath = "mcp-wordpress.config.json"; const backupPath = "mcp-wordpress.config.json.backup"; if (fs.existsSync(backupPath)) { fs.copyFileSync(backupPath, configPath); fs.unlinkSync(backupPath); return true; } return false; } static createSingleSiteConfig() { // Remove multi-site config to force single-site mode const configPath = "mcp-wordpress.config.json"; if (fs.existsSync(configPath)) { fs.unlinkSync(configPath); } } static createMultiSiteConfig() { const config = { sites: [ { id: "test-site-1", name: "Test Site 1", config: { WORDPRESS_SITE_URL: process.env.WORDPRESS_SITE_URL || "https://example1.com", WORDPRESS_USERNAME: process.env.WORDPRESS_USERNAME || "test1", WORDPRESS_APP_PASSWORD: process.env.WORDPRESS_APP_PASSWORD || "test-pass-1", }, }, { id: "test-site-2", name: "Test Site 2", config: { WORDPRESS_SITE_URL: process.env.WORDPRESS_SITE_URL_2 || "https://example2.com", WORDPRESS_USERNAME: process.env.WORDPRESS_USERNAME_2 || "test2", WORDPRESS_APP_PASSWORD: process.env.WORDPRESS_APP_PASSWORD_2 || "test-pass-2", }, }, ], }; fs.writeFileSync("mcp-wordpress.config.json", JSON.stringify(config, null, 2)); } } /** * Cache Tester */ class CacheTester { constructor(results) { this.results = results; } async testCacheInfrastructure() { console.log("\n🔧 Testing Cache Infrastructure"); console.log("==============================="); try { const { CacheManager, HttpCacheWrapper, CacheInvalidation } = await import("../dist/cache/index.js"); // Test CacheManager const cacheManager = new CacheManager({ maxSize: 10, defaultTTL: 1000, enableLRU: true, enableStats: true, }); // Basic operations cacheManager.set("test-key", { data: "test" }); const result = cacheManager.get("test-key"); if (result && result.data === "test") { this.results.addTest("CacheManager basic operations", "PASS"); } else { this.results.addTest("CacheManager basic operations", "FAIL", "Failed to retrieve cached data"); return false; } // Key generation const key1 = cacheManager.generateKey("site1", "posts", { per_page: 10 }); const key2 = cacheManager.generateKey("site1", "posts", { per_page: 10 }); const key3 = cacheManager.generateKey("site2", "posts", { per_page: 10 }); if (key1 === key2 && key1 !== key3) { this.results.addTest("Cache key generation consistency", "PASS"); } else { this.results.addTest("Cache key generation consistency", "FAIL", "Keys not consistent"); return false; } // Site isolation cacheManager.set(key1, { site: "site1" }); cacheManager.set(key3, { site: "site2" }); const cleared = cacheManager.clearSite("site1"); const site1Data = cacheManager.get(key1); const site2Data = cacheManager.get(key3); if (!site1Data && site2Data && site2Data.site === "site2") { this.results.addTest("Site-specific cache isolation", "PASS"); } else { this.results.addTest("Site-specific cache isolation", "FAIL", "Site isolation failed"); return false; } // HttpCacheWrapper const httpCache = new HttpCacheWrapper(cacheManager, "test-site"); const mockRequest = async () => ({ data: { id: 1, title: "Test" }, status: 200, headers: {}, }); const response1 = await httpCache.request(mockRequest, { method: "GET", url: "https://example.com/wp-json/wp/v2/posts", headers: {}, params: {}, }); if (response1.data.id === 1) { this.results.addTest("HttpCacheWrapper basic functionality", "PASS"); } else { this.results.addTest("HttpCacheWrapper basic functionality", "FAIL"); return false; } return true; } catch (error) { this.results.addTest("Cache infrastructure", "FAIL", error.message); return false; } } async testSingleSiteConfiguration() { console.log("\n🏠 Testing Single-Site Configuration"); console.log("===================================="); try { // Backup existing config ConfigHelper.backupConfig(); // Create single-site setup ConfigHelper.createSingleSiteConfig(); // Test server initialization const server = new MCPWordPressServer(); this.results.addTest("Single-site server initialization", "PASS"); // Test cache tools exist const { CacheTools } = await import("../dist/tools/index.js"); const cacheTools = new CacheTools(new Map([["default", {}]])); const tools = cacheTools.getTools(); if (tools.length === 4) { this.results.addTest("Single-site cache tools registration", "PASS", `${tools.length} tools available`); } else { this.results.addTest("Single-site cache tools registration", "FAIL", `Expected 4 tools, got ${tools.length}`); } // Test cache with default site const hasCredentials = process.env.WORDPRESS_SITE_URL && process.env.WORDPRESS_USERNAME && process.env.WORDPRESS_APP_PASSWORD; if (hasCredentials) { // Test actual cache operations await this.testLiveCacheOperations("default"); } else { this.results.addTest("Single-site live testing", "SKIP", "No WordPress credentials provided"); } } catch (error) { this.results.addTest("Single-site configuration", "FAIL", error.message); } finally { // Restore config ConfigHelper.restoreConfig(); } } async testMultiSiteConfiguration() { console.log("\n🏢 Testing Multi-Site Configuration"); console.log("==================================="); try { // Backup existing config ConfigHelper.backupConfig(); // Create multi-site setup ConfigHelper.createMultiSiteConfig(); // Test server initialization const server = new MCPWordPressServer(); this.results.addTest("Multi-site server initialization", "PASS"); // Test site isolation await this.testMultiSiteCacheIsolation(); // Test cross-site operations await this.testCrossSiteOperations(); } catch (error) { this.results.addTest("Multi-site configuration", "FAIL", error.message); } finally { // Restore config ConfigHelper.restoreConfig(); } } async testMultiSiteCacheIsolation() { try { const { CacheManager } = await import("../dist/cache/index.js"); const cacheManager = new CacheManager({ maxSize: 100, defaultTTL: 10000, enableLRU: true, enableStats: true, }); // Test site isolation const site1Key = cacheManager.generateKey("test-site-1", "posts", {}); const site2Key = cacheManager.generateKey("test-site-2", "posts", {}); cacheManager.set(site1Key, { site: "site1", data: "site1-data" }); cacheManager.set(site2Key, { site: "site2", data: "site2-data" }); // Clear site1 only const cleared = cacheManager.clearSite("test-site-1"); const site1Data = cacheManager.get(site1Key); const site2Data = cacheManager.get(site2Key); if (!site1Data && site2Data && site2Data.site === "site2") { this.results.addTest( "Multi-site cache isolation", "PASS", `Cleared ${cleared} entries for site1, site2 unaffected`, ); } else { this.results.addTest("Multi-site cache isolation", "FAIL", "Cache isolation failed between sites"); } } catch (error) { this.results.addTest("Multi-site cache isolation", "FAIL", error.message); } } async testCrossSiteOperations() { try { const { CacheManager } = await import("../dist/cache/index.js"); const cacheManager = new CacheManager({ maxSize: 100, defaultTTL: 10000, enableLRU: true, enableStats: true, }); // Simulate different sites with same endpoint const sites = ["test-site-1", "test-site-2"]; const endpoints = ["posts", "categories", "users"]; // Populate cache for all sites and endpoints for (const site of sites) { for (const endpoint of endpoints) { const key = cacheManager.generateKey(site, endpoint, {}); cacheManager.set(key, { site, endpoint, data: `${site}-${endpoint}` }); } } // Test pattern clearing across sites const postsPattern = /posts/; const clearedPosts = cacheManager.clearPattern(postsPattern); // Verify only posts were cleared, other endpoints remain let remainingEntries = 0; let clearedPostsCount = 0; for (const site of sites) { for (const endpoint of endpoints) { const key = cacheManager.generateKey(site, endpoint, {}); const data = cacheManager.get(key); if (endpoint === "posts") { if (!data) clearedPostsCount++; } else { if (data) remainingEntries++; } } } if (clearedPostsCount === 2 && remainingEntries === 4) { this.results.addTest( "Cross-site pattern clearing", "PASS", `Cleared posts from all sites, preserved other data`, ); } else { this.results.addTest( "Cross-site pattern clearing", "FAIL", `Expected to clear 2 posts, preserve 4 others. Cleared: ${clearedPostsCount}, Remaining: ${remainingEntries}`, ); } } catch (error) { this.results.addTest("Cross-site operations", "FAIL", error.message); } } async testLiveCacheOperations(siteId) { // This would test with actual WordPress if credentials are available this.results.addTest(`Live cache operations for ${siteId}`, "SKIP", "Requires live WordPress testing"); } async testCacheInvalidation() { console.log("\n🗑️ Testing Cache Invalidation"); console.log("=============================="); try { const { CacheManager, HttpCacheWrapper, CacheInvalidation } = await import("../dist/cache/index.js"); const cacheManager = new CacheManager({ maxSize: 100, defaultTTL: 10000, enableLRU: true, enableStats: true, }); const httpCache = new HttpCacheWrapper(cacheManager, "test-site"); const invalidation = new CacheInvalidation(httpCache); // Pre-populate cache httpCache.warm("posts", [{ id: 1 }, { id: 2 }]); httpCache.warm("posts/1", { id: 1, title: "Test Post" }); httpCache.warm("categories", [{ id: 1, name: "Test Category" }]); const statsBefore = cacheManager.getStats(); // Trigger invalidation event await invalidation.trigger({ type: "update", resource: "posts", id: 1, siteId: "test-site", timestamp: Date.now(), }); const statsAfter = cacheManager.getStats(); if (statsAfter.totalSize < statsBefore.totalSize) { this.results.addTest( "Cache invalidation triggers", "PASS", `Entries reduced from ${statsBefore.totalSize} to ${statsAfter.totalSize}`, ); } else { this.results.addTest("Cache invalidation triggers", "FAIL", "No cache entries were invalidated"); } } catch (error) { this.results.addTest("Cache invalidation", "FAIL", error.message); } } async testCachePerformance() { console.log("\n⚡ Testing Cache Performance"); console.log("============================"); try { const { CacheManager } = await import("../dist/cache/index.js"); const cacheManager = new CacheManager({ maxSize: 1000, defaultTTL: 10000, enableLRU: true, enableStats: true, }); // Performance test: Set operations const setStart = performance.now(); for (let i = 0; i < 1000; i++) { cacheManager.set(`perf-test-${i}`, { id: i, data: `test-data-${i}` }); } const setEnd = performance.now(); const setTime = setEnd - setStart; // Performance test: Get operations const getStart = performance.now(); let hits = 0; for (let i = 0; i < 1000; i++) { const result = cacheManager.get(`perf-test-${i}`); if (result) hits++; } const getEnd = performance.now(); const getTime = getEnd - getStart; const stats = cacheManager.getStats(); this.results.addTest( "Cache performance - 1000 sets", "PASS", `${setTime.toFixed(2)}ms (${(setTime / 1000).toFixed(3)}ms per op)`, ); this.results.addTest( "Cache performance - 1000 gets", "PASS", `${getTime.toFixed(2)}ms (${(getTime / 1000).toFixed(3)}ms per op)`, ); this.results.addTest( "Cache hit rate", hits === 1000 ? "PASS" : "FAIL", `${hits}/1000 hits (${stats.hitRate * 100}%)`, ); } catch (error) { this.results.addTest("Cache performance", "FAIL", error.message); } } } /** * Main test runner */ async function runAllTests() { console.log("🧪 MCP WordPress Cache Configuration Tests"); console.log("=========================================="); const results = new TestResults(); const tester = new CacheTester(results); try { // Infrastructure tests await tester.testCacheInfrastructure(); // Configuration tests await tester.testSingleSiteConfiguration(); await tester.testMultiSiteConfiguration(); // Invalidation tests await tester.testCacheInvalidation(); // Performance tests await tester.testCachePerformance(); // Summary results.summary(); if (results.failed === 0) { console.log("\n🎉 All tests passed! Cache system is ready for production."); } else { console.log(`\n⚠️ ${results.failed} test(s) failed. Please review and fix issues.`); process.exit(1); } } catch (error) { console.error("❌ Test suite failed:", error); process.exit(1); } } if (import.meta.url === `file://${process.argv[1]}`) { runAllTests(); }

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/docdyhr/mcp-wordpress'

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