100 lines
2.5 KiB
TypeScript
100 lines
2.5 KiB
TypeScript
import { execSync } from 'node:child_process'
|
|
import { setTimeout as sleep } from 'node:timers/promises'
|
|
import mysql from 'mysql2/promise'
|
|
import Redis from 'ioredis'
|
|
import { loadTestEnv } from './env'
|
|
import { runGlobalTeardown } from './global-teardown'
|
|
|
|
function parseDbUrl(dbUrl: string) {
|
|
const url = new URL(dbUrl)
|
|
return {
|
|
host: url.hostname,
|
|
port: Number(url.port || 3306),
|
|
user: decodeURIComponent(url.username),
|
|
password: decodeURIComponent(url.password),
|
|
database: url.pathname.replace(/^\//, ''),
|
|
}
|
|
}
|
|
|
|
async function waitForMysql(maxAttempts = 180) {
|
|
const db = parseDbUrl(process.env.DATABASE_URL || '')
|
|
|
|
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
try {
|
|
const conn = await mysql.createConnection({
|
|
host: db.host,
|
|
port: db.port,
|
|
user: db.user,
|
|
password: db.password,
|
|
database: db.database,
|
|
connectTimeout: 5_000,
|
|
})
|
|
await conn.query('SELECT 1')
|
|
await conn.end()
|
|
return
|
|
} catch {
|
|
await sleep(1_000)
|
|
}
|
|
}
|
|
|
|
throw new Error('MySQL test service did not become ready in time')
|
|
}
|
|
|
|
async function waitForRedis(maxAttempts = 60) {
|
|
const redis = new Redis({
|
|
host: process.env.REDIS_HOST || '127.0.0.1',
|
|
port: Number(process.env.REDIS_PORT || '6380'),
|
|
maxRetriesPerRequest: 1,
|
|
lazyConnect: true,
|
|
})
|
|
|
|
try {
|
|
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
try {
|
|
if (redis.status !== 'ready') {
|
|
await redis.connect()
|
|
}
|
|
const pong = await redis.ping()
|
|
if (pong === 'PONG') return
|
|
} catch {
|
|
await sleep(1_000)
|
|
}
|
|
}
|
|
} finally {
|
|
redis.disconnect()
|
|
}
|
|
|
|
throw new Error('Redis test service did not become ready in time')
|
|
}
|
|
|
|
export default async function globalSetup() {
|
|
loadTestEnv()
|
|
|
|
const shouldBootstrap = process.env.BILLING_TEST_BOOTSTRAP === '1' || process.env.SYSTEM_TEST_BOOTSTRAP === '1'
|
|
if (!shouldBootstrap) {
|
|
return async () => {}
|
|
}
|
|
|
|
execSync('docker compose -f docker-compose.test.yml down -v --remove-orphans', {
|
|
cwd: process.cwd(),
|
|
stdio: 'inherit',
|
|
})
|
|
|
|
execSync('docker compose -f docker-compose.test.yml up -d --remove-orphans', {
|
|
cwd: process.cwd(),
|
|
stdio: 'inherit',
|
|
})
|
|
|
|
await waitForMysql()
|
|
await waitForRedis()
|
|
|
|
execSync('npx prisma db push --skip-generate --schema prisma/schema.prisma', {
|
|
cwd: process.cwd(),
|
|
stdio: 'inherit',
|
|
})
|
|
|
|
return async () => {
|
|
await runGlobalTeardown()
|
|
}
|
|
}
|