/**
* Test ContainerPool functionality
*/
import { ContainerPool } from './core/ContainerPool.js';
import { PythonRuntime } from './runtimes/PythonRuntime.js';
import type { PoolConfig } from './types/index.js';
async function testContainerPool() {
console.log('๐งช Testing ContainerPool...\n');
console.log('=' .repeat(60));
let pool: ContainerPool | null = null;
try {
// 1. Initialize pool
console.log('\n1๏ธโฃ Initializing pool with pre-warming...');
const startTime = Date.now();
const config: PoolConfig = {
minIdle: 2,
maxActive: 10,
warmupLanguages: ['python', 'javascript'],
evictionPolicy: 'LRU',
healthCheckInterval: 30000,
containerMemory: '256m',
containerCpus: '0.5',
};
pool = ContainerPool.getInstance(config);
await pool.initialize();
const initTime = Date.now() - startTime;
console.log(` โ
Pool initialized in ${initTime}ms`);
// Check stats
let stats = pool.getStats();
console.log(` โ
Pool size: ${stats.total} containers`);
console.log(` โ
By language: Python=${stats.byLanguage.python || 0}, JavaScript=${stats.byLanguage.javascript || 0}`);
// 2. Test pool hit (warm container)
console.log('\n2๏ธโฃ Testing pool hit (warm container)...');
const hitStartTime = Date.now();
const container1 = await pool.acquire('python');
const hitTime = Date.now() - hitStartTime;
console.log(` โ
Acquired container in ${hitTime}ms (should be <200ms)`);
console.log(` โ
Container ID: ${container1.id.substring(0, 12)}`);
// Execute code to verify it works
const runtime = new PythonRuntime();
const result = await runtime.execute('print("Pool hit test!")', {
container: container1,
timeout: 5000,
env: {},
});
console.log(` โ
Execution successful: ${result.stdout.trim()}`);
// Release back to pool
await pool.release(container1, 'python');
console.log(` โ
Container released back to pool`);
// 3. Test pool stats after release
console.log('\n3๏ธโฃ Testing pool stats...');
stats = pool.getStats();
console.log(` โ
Total containers: ${stats.total}`);
console.log(` โ
Available: ${stats.available}`);
console.log(` โ
In use: ${stats.inUse}`);
console.log(` โ
Healthy: ${stats.healthy}`);
console.log(` โ
Unhealthy: ${stats.unhealthy}`);
// 4. Test pool miss (new language)
console.log('\n4๏ธโฃ Testing pool miss (new language)...');
const missStartTime = Date.now();
const container2 = await pool.acquire('go');
const missTime = Date.now() - missStartTime;
console.log(` โ
Acquired Go container in ${missTime}ms (pool miss)`);
console.log(` โ
Container ID: ${container2.id.substring(0, 12)}`);
// Release
await pool.release(container2, 'go');
console.log(` โ
Go container released to pool`);
// 5. Test acquiring same container again (should be faster)
console.log('\n5๏ธโฃ Testing second acquisition (should be faster)...');
const secondHitStartTime = Date.now();
const container3 = await pool.acquire('python');
const secondHitTime = Date.now() - secondHitStartTime;
console.log(` โ
Acquired Python container in ${secondHitTime}ms`);
console.log(` โก Speedup: ${hitTime}ms โ ${secondHitTime}ms`);
// Don't release yet - test multiple in use
// 6. Test acquiring multiple containers
console.log('\n6๏ธโฃ Testing multiple acquisitions...');
const container4 = await pool.acquire('python');
const container5 = await pool.acquire('javascript');
console.log(` โ
Acquired 3 containers total`);
console.log(` โ
Container 3: ${container3.id.substring(0, 12)}`);
console.log(` โ
Container 4: ${container4.id.substring(0, 12)}`);
console.log(` โ
Container 5: ${container5.id.substring(0, 12)}`);
// Release all
await pool.release(container3, 'python');
await pool.release(container4, 'python');
await pool.release(container5, 'javascript');
console.log(` โ
All containers released`);
// 7. Final stats
console.log('\n7๏ธโฃ Final pool statistics...');
stats = pool.getStats();
console.log(` ๐ Total: ${stats.total}`);
console.log(` ๐ Python: ${stats.byLanguage.python || 0}`);
console.log(` ๐ JavaScript: ${stats.byLanguage.javascript || 0}`);
console.log(` ๐ Go: ${stats.byLanguage.go || 0}`);
console.log(` ๐ Healthy: ${stats.healthy}/${stats.total}`);
// 8. Test LRU eviction by filling pool beyond maxActive
console.log('\n8๏ธโฃ Testing LRU eviction (filling pool)...');
console.log(` Current pool size: ${stats.total}, Max: ${config.maxActive}`);
// This test is optional since it would take a while
console.log(` โญ๏ธ Skipping eviction test (would need ${config.maxActive + 1} containers)`);
console.log('\n' + '='.repeat(60));
console.log('\n๐ All ContainerPool tests passed!\n');
} catch (error: any) {
console.error('\nโ Test failed:', error.message);
if (error.stack) {
console.error(error.stack);
}
process.exit(1);
} finally {
// Cleanup
if (pool) {
console.log('๐งน Draining pool...');
await pool.drain();
console.log(' โ
Pool drained\n');
}
}
}
testContainerPool();