#!/usr/bin/env node
/**
* Comprehensive Regression Test for Multi-Tenant MCP Server
* Tests all functionality through the new HTTP multi-tenant architecture
*/
const { spawn } = require('child_process');
const http = require('http');
// Test configuration
const SERVER_URL = 'http://localhost:3000';
const TEST_ACCOUNTS = {
saola: {
username: 'david+saola@umbrellacost.com',
password: 'Dsamsung1!'
},
allcloud: {
username: 'david+allcloud@umbrellacost.com',
password: 'Dsamsung1!'
}
};
// Utility functions
function makeHttpRequest(options, data = null) {
return new Promise((resolve, reject) => {
const req = http.request(options, (res) => {
let responseData = '';
res.on('data', chunk => responseData += chunk);
res.on('end', () => {
try {
const parsed = JSON.parse(responseData);
resolve({ statusCode: res.statusCode, data: parsed });
} catch (e) {
resolve({ statusCode: res.statusCode, data: responseData });
}
});
});
req.on('error', reject);
if (data) req.write(JSON.stringify(data));
req.end();
});
}
async function authenticateUser(username, password) {
console.log(`🔐 Authenticating ${username}...`);
const options = {
hostname: 'localhost',
port: 3000,
path: '/auth',
method: 'POST',
headers: { 'Content-Type': 'application/json' }
};
try {
const response = await makeHttpRequest(options, { username, password });
if (response.data.success) {
console.log(`✅ Authentication successful for ${username}`);
return response.data.sessionToken;
} else {
console.log(`❌ Authentication failed for ${username}: ${response.data.error}`);
return null;
}
} catch (error) {
console.log(`❌ Authentication error for ${username}: ${error.message}`);
return null;
}
}
async function testMCPRequest(sessionToken, method, params = {}) {
const options = {
hostname: 'localhost',
port: 3000,
path: '/mcp',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Session-Token': sessionToken
}
};
const request = {
jsonrpc: '2.0',
id: Date.now(),
method,
params
};
try {
const response = await makeHttpRequest(options, request);
return response;
} catch (error) {
return { error: error.message };
}
}
async function testDirectMCPConnection(username, password) {
console.log(`\\n🔌 Testing direct MCP connection for ${username}...`);
return new Promise((resolve, reject) => {
const encodedUsername = encodeURIComponent(username);
const encodedPassword = encodeURIComponent(password);
const url = `http://localhost:3000/sse?username=${encodedUsername}&password=${encodedPassword}`;
const mcpProcess = spawn('npx', ['mcp-remote', url], {
stdio: ['pipe', 'pipe', 'pipe']
});
let output = '';
let connected = false;
const timeout = setTimeout(() => {
if (!connected) {
mcpProcess.kill();
resolve({ success: false, error: 'Connection timeout' });
}
}, 10000);
mcpProcess.stdout.on('data', (data) => {
output += data.toString();
if (output.includes('Connected to remote server') || output.includes('Proxy established')) {
connected = true;
clearTimeout(timeout);
// Test a simple initialize request
const initRequest = {
jsonrpc: '2.0',
id: 1,
method: 'initialize',
params: {
protocolVersion: '2024-11-05',
capabilities: {},
clientInfo: { name: 'regression-test', version: '1.0.0' }
}
};
mcpProcess.stdin.write(JSON.stringify(initRequest) + '\\n');
setTimeout(() => {
mcpProcess.kill();
resolve({ success: true, output });
}, 2000);
}
});
mcpProcess.stderr.on('data', (data) => {
console.log(`MCP Error: ${data}`);
});
mcpProcess.on('error', (error) => {
clearTimeout(timeout);
resolve({ success: false, error: error.message });
});
});
}
async function runComprehensiveRegressionTest() {
console.log('🔬 MULTI-TENANT MCP SERVER COMPREHENSIVE REGRESSION TEST');
console.log('=' .repeat(80));
console.log('Testing ALL functionality through new HTTP multi-tenant architecture');
console.log('1. Multi-tenant authentication');
console.log('2. Session isolation');
console.log('3. Direct MCP-remote connection');
console.log('4. API functionality through sessions');
console.log('5. Concurrent user support');
console.log('');
let serverProcess;
const testResults = [];
try {
// Start the multi-tenant server
console.log('🚀 Starting multi-tenant MCP server...');
serverProcess = spawn('node', ['http-server-multitenant.cjs'], {
stdio: ['ignore', 'pipe', 'pipe']
});
// Wait for server to start
await new Promise(resolve => setTimeout(resolve, 3000));
console.log('✅ Server started');
// Test 1: Authentication for both accounts
console.log('\\n🧪 TEST 1: MULTI-TENANT AUTHENTICATION');
console.log('=' .repeat(60));
const saolaToken = await authenticateUser(TEST_ACCOUNTS.saola.username, TEST_ACCOUNTS.saola.password);
const allcloudToken = await authenticateUser(TEST_ACCOUNTS.allcloud.username, TEST_ACCOUNTS.allcloud.password);
testResults.push({
name: 'Saola Authentication',
passed: !!saolaToken,
details: saolaToken ? 'Session created' : 'Failed to authenticate'
});
testResults.push({
name: 'AllCloud Authentication',
passed: !!allcloudToken,
details: allcloudToken ? 'Session created' : 'Failed to authenticate'
});
if (!saolaToken || !allcloudToken) {
console.log('❌ Authentication failed, skipping remaining tests');
return testResults;
}
// Test 2: Session isolation - test tools/list for each account
console.log('\\n🧪 TEST 2: SESSION ISOLATION');
console.log('=' .repeat(60));
console.log('Testing tools/list for Saola account...');
const saolaTools = await testMCPRequest(saolaToken, 'tools/list');
console.log('Testing tools/list for AllCloud account...');
const allcloudTools = await testMCPRequest(allcloudToken, 'tools/list');
testResults.push({
name: 'Saola Tools List',
passed: saolaTools.statusCode === 200 && saolaTools.data.result,
details: saolaTools.data.result ? `${saolaTools.data.result.tools?.length || 0} tools found` : 'Failed'
});
testResults.push({
name: 'AllCloud Tools List',
passed: allcloudTools.statusCode === 200 && allcloudTools.data.result,
details: allcloudTools.data.result ? `${allcloudTools.data.result.tools?.length || 0} tools found` : 'Failed'
});
// Test 3: Direct MCP connection via mcp-remote
console.log('\\n🧪 TEST 3: DIRECT MCP CONNECTION');
console.log('=' .repeat(60));
const saolaConnection = await testDirectMCPConnection(TEST_ACCOUNTS.saola.username, TEST_ACCOUNTS.saola.password);
const allcloudConnection = await testDirectMCPConnection(TEST_ACCOUNTS.allcloud.username, TEST_ACCOUNTS.allcloud.password);
testResults.push({
name: 'Saola Direct Connection',
passed: saolaConnection.success,
details: saolaConnection.success ? 'mcp-remote connected successfully' : saolaConnection.error
});
testResults.push({
name: 'AllCloud Direct Connection',
passed: allcloudConnection.success,
details: allcloudConnection.success ? 'mcp-remote connected successfully' : allcloudConnection.error
});
// Test 4: API functionality through sessions
console.log('\\n🧪 TEST 4: API FUNCTIONALITY');
console.log('=' .repeat(60));
// Test health endpoint
console.log('Testing server health...');
const healthResponse = await makeHttpRequest({
hostname: 'localhost',
port: 3000,
path: '/health',
method: 'GET'
});
testResults.push({
name: 'Server Health',
passed: healthResponse.statusCode === 200,
details: healthResponse.data.activeSessions ? `${healthResponse.data.activeSessions} active sessions` : 'No session data'
});
// Test API call through MCP
if (saolaToken) {
console.log('Testing API call through Saola session...');
const apiTest = await testMCPRequest(saolaToken, 'tools/call', {
name: 'list_endpoints'
});
testResults.push({
name: 'Saola API Call',
passed: apiTest.statusCode === 200 && !apiTest.data.error,
details: apiTest.data.result ? 'API endpoints listed successfully' : 'Failed to call API'
});
}
} catch (error) {
console.error('❌ Test execution error:', error);
testResults.push({
name: 'Test Execution',
passed: false,
details: error.message
});
} finally {
// Cleanup
if (serverProcess) {
console.log('\\n🧹 Cleaning up server process...');
serverProcess.kill();
}
}
// Print results
console.log('\\n' + '=' .repeat(80));
console.log('🏁 REGRESSION TEST RESULTS');
console.log('=' .repeat(80));
let passed = 0;
let failed = 0;
testResults.forEach(result => {
const status = result.passed ? '✅ PASS' : '❌ FAIL';
console.log(`${status} ${result.name}: ${result.details}`);
if (result.passed) passed++; else failed++;
});
console.log('\\n' + '=' .repeat(80));
console.log(`📊 SUMMARY: ${passed} passed, ${failed} failed`);
console.log(`🎯 Success Rate: ${Math.round((passed / testResults.length) * 100)}%`);
if (failed === 0) {
console.log('\\n🎉 ALL TESTS PASSED! Multi-tenant MCP server is working correctly.');
} else {
console.log('\\n⚠️ Some tests failed. Review the results above.');
}
return testResults;
}
// Run the test
if (require.main === module) {
runComprehensiveRegressionTest()
.then(() => process.exit(0))
.catch(error => {
console.error('❌ Test runner failed:', error);
process.exit(1);
});
}
module.exports = { runComprehensiveRegressionTest };