183 lines
No EOL
7.2 KiB
JavaScript
183 lines
No EOL
7.2 KiB
JavaScript
/**
|
|
* Integration Test Setup
|
|
*
|
|
* Sets up test containers and real database instances for integration testing.
|
|
* This file is executed before integration tests run.
|
|
*/
|
|
import { GenericContainer } from 'testcontainers';
|
|
import { MongoMemoryServer } from 'mongodb-memory-server';
|
|
let questdbContainer;
|
|
let postgresContainer;
|
|
let mongoContainer;
|
|
let mongoMemoryServer;
|
|
/**
|
|
* Global setup for integration tests
|
|
* Starts real database containers for testing
|
|
*/
|
|
beforeAll(async () => {
|
|
console.log('🚀 Starting integration test containers...');
|
|
try {
|
|
// Start QuestDB container
|
|
console.log('📊 Starting QuestDB container...');
|
|
questdbContainer = await new GenericContainer('questdb/questdb:7.3.10')
|
|
.withExposedPorts(9000, 8812, 9009)
|
|
.withEnvironment({
|
|
'QDB_TELEMETRY_ENABLED': 'false',
|
|
'QDB_LOG_LEVEL': 'ERROR'
|
|
})
|
|
.withStartupTimeout(60000)
|
|
.start();
|
|
// Start PostgreSQL container
|
|
console.log('🐘 Starting PostgreSQL container...');
|
|
postgresContainer = await new GenericContainer('postgres:15-alpine')
|
|
.withExposedPorts(5432)
|
|
.withEnvironment({
|
|
'POSTGRES_DB': 'trading_bot_test',
|
|
'POSTGRES_USER': 'trading_admin',
|
|
'POSTGRES_PASSWORD': 'trading_pass_test'
|
|
})
|
|
.withStartupTimeout(60000)
|
|
.start();
|
|
// Start MongoDB container
|
|
console.log('🍃 Starting MongoDB container...');
|
|
mongoContainer = await new GenericContainer('mongo:7-jammy')
|
|
.withExposedPorts(27017)
|
|
.withEnvironment({
|
|
'MONGO_INITDB_ROOT_USERNAME': 'trading_admin',
|
|
'MONGO_INITDB_ROOT_PASSWORD': 'trading_mongo_test',
|
|
'MONGO_INITDB_DATABASE': 'trading_bot_test'
|
|
})
|
|
.withStartupTimeout(60000)
|
|
.start();
|
|
// Update environment variables for tests
|
|
process.env.QUESTDB_HOST = questdbContainer.getHost();
|
|
process.env.QUESTDB_HTTP_PORT = questdbContainer.getMappedPort(9000).toString();
|
|
process.env.QUESTDB_PG_PORT = questdbContainer.getMappedPort(8812).toString();
|
|
process.env.QUESTDB_INFLUX_PORT = questdbContainer.getMappedPort(9009).toString();
|
|
process.env.POSTGRES_HOST = postgresContainer.getHost();
|
|
process.env.POSTGRES_PORT = postgresContainer.getMappedPort(5432).toString();
|
|
process.env.MONGODB_HOST = mongoContainer.getHost();
|
|
process.env.MONGODB_PORT = mongoContainer.getMappedPort(27017).toString();
|
|
console.log('✅ All containers started successfully!');
|
|
console.log(`📊 QuestDB: http://${process.env.QUESTDB_HOST}:${process.env.QUESTDB_HTTP_PORT}`);
|
|
console.log(`🐘 PostgreSQL: ${process.env.POSTGRES_HOST}:${process.env.POSTGRES_PORT}`);
|
|
console.log(`🍃 MongoDB: ${process.env.MONGODB_HOST}:${process.env.MONGODB_PORT}`);
|
|
}
|
|
catch (error) {
|
|
console.error('❌ Failed to start test containers:', error);
|
|
// Try to use MongoDB Memory Server as fallback
|
|
console.log('🔄 Falling back to MongoDB Memory Server...');
|
|
try {
|
|
mongoMemoryServer = await MongoMemoryServer.create({
|
|
instance: {
|
|
dbName: 'trading_bot_test'
|
|
}
|
|
});
|
|
const mongoUri = mongoMemoryServer.getUri();
|
|
const mongoUrl = new URL(mongoUri);
|
|
process.env.MONGODB_HOST = mongoUrl.hostname;
|
|
process.env.MONGODB_PORT = mongoUrl.port;
|
|
process.env.MONGODB_URI = mongoUri;
|
|
console.log('✅ MongoDB Memory Server started as fallback');
|
|
}
|
|
catch (fallbackError) {
|
|
console.error('❌ Failed to start MongoDB Memory Server:', fallbackError);
|
|
throw fallbackError;
|
|
}
|
|
// For other databases, use localhost defaults if containers fail
|
|
if (!questdbContainer) {
|
|
console.log('⚠️ Using localhost QuestDB (ensure it\'s running)');
|
|
process.env.QUESTDB_HOST = 'localhost';
|
|
process.env.QUESTDB_HTTP_PORT = '9000';
|
|
process.env.QUESTDB_PG_PORT = '8812';
|
|
process.env.QUESTDB_INFLUX_PORT = '9009';
|
|
}
|
|
if (!postgresContainer) {
|
|
console.log('⚠️ Using localhost PostgreSQL (ensure it\'s running)');
|
|
process.env.POSTGRES_HOST = 'localhost';
|
|
process.env.POSTGRES_PORT = '5432';
|
|
}
|
|
}
|
|
}, 120000); // 2 minutes timeout for container startup
|
|
/**
|
|
* Global cleanup for integration tests
|
|
* Stops all test containers
|
|
*/
|
|
afterAll(async () => {
|
|
console.log('🧹 Cleaning up integration test containers...');
|
|
const cleanup = async (container, name) => {
|
|
if (container) {
|
|
try {
|
|
await container.stop();
|
|
console.log(`✅ ${name} container stopped`);
|
|
}
|
|
catch (error) {
|
|
console.warn(`⚠️ Failed to stop ${name} container:`, error);
|
|
}
|
|
}
|
|
};
|
|
await Promise.all([
|
|
cleanup(questdbContainer, 'QuestDB'),
|
|
cleanup(postgresContainer, 'PostgreSQL'),
|
|
cleanup(mongoContainer, 'MongoDB')
|
|
]);
|
|
if (mongoMemoryServer) {
|
|
try {
|
|
await mongoMemoryServer.stop();
|
|
console.log('✅ MongoDB Memory Server stopped');
|
|
}
|
|
catch (error) {
|
|
console.warn('⚠️ Failed to stop MongoDB Memory Server:', error);
|
|
}
|
|
}
|
|
console.log('🎉 Integration test cleanup complete!');
|
|
}, 30000);
|
|
/**
|
|
* Wait for database services to be ready
|
|
*/
|
|
export const waitForServices = async (timeout = 30000) => {
|
|
const start = Date.now();
|
|
while (Date.now() - start < timeout) {
|
|
try {
|
|
// Check if QuestDB HTTP interface is ready
|
|
const questdbUrl = `http://${process.env.QUESTDB_HOST}:${process.env.QUESTDB_HTTP_PORT}/status`;
|
|
const response = await fetch(questdbUrl);
|
|
if (response.ok) {
|
|
console.log('✅ QuestDB is ready');
|
|
return;
|
|
}
|
|
}
|
|
catch (error) {
|
|
// Service not ready yet, continue waiting
|
|
}
|
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
}
|
|
throw new Error('Services did not become ready within timeout');
|
|
};
|
|
/**
|
|
* Test utilities for integration tests
|
|
*/
|
|
export const integrationTestHelpers = {
|
|
/**
|
|
* Get QuestDB HTTP URL
|
|
*/
|
|
getQuestDBUrl: () => `http://${process.env.QUESTDB_HOST}:${process.env.QUESTDB_HTTP_PORT}`,
|
|
/**
|
|
* Get PostgreSQL connection string
|
|
*/
|
|
getPostgresUrl: () => `postgresql://${process.env.POSTGRES_USER}:${process.env.POSTGRES_PASSWORD}@${process.env.POSTGRES_HOST}:${process.env.POSTGRES_PORT}/${process.env.POSTGRES_DB}`,
|
|
/**
|
|
* Get MongoDB connection string
|
|
*/
|
|
getMongoUrl: () => {
|
|
if (process.env.MONGODB_URI) {
|
|
return process.env.MONGODB_URI;
|
|
}
|
|
return `mongodb://${process.env.MONGODB_USERNAME}:${process.env.MONGODB_PASSWORD}@${process.env.MONGODB_HOST}:${process.env.MONGODB_PORT}/${process.env.MONGODB_DATABASE}`;
|
|
},
|
|
/**
|
|
* Wait for services to be ready
|
|
*/
|
|
waitForServices
|
|
};
|
|
//# sourceMappingURL=setup.js.map
|