File size: 2,514 Bytes
c7d34c1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#!/usr/bin/env node
import { spawnSync } from 'node:child_process';
import { setTimeout as delay } from 'node:timers/promises';

const testFiles = ['src/lib/agent-state-postgres.test.ts', 'src/app/api/agent/agent-routes.test.ts'];
const POSTGRES_READY_ATTEMPTS = 30;
const POSTGRES_READY_INTERVAL_MS = 1000;

function run(command, args, options = {}) {
  const result = spawnSync(command, args, {
    stdio: options.capture ? ['ignore', 'pipe', 'pipe'] : options.silent ? 'ignore' : 'inherit',
    encoding: 'utf8',
    env: options.env || process.env
  });
  if (options.capture) {
    return result;
  }
  if (result.status !== 0) {
    process.exit(result.status || 1);
  }
  return result;
}

function runTests(databaseUrl) {
  run('node', ['--test', '--import', 'tsx', ...testFiles], {
    env: {
      ...process.env,
      NODE_ENV: 'test',
      AGENT_POSTGRES_TEST_DATABASE_URL: databaseUrl
    }
  });
}

async function waitForPostgres(containerName) {
  for (let attempt = 0; attempt < POSTGRES_READY_ATTEMPTS; attempt += 1) {
    const result = spawnSync('docker', ['exec', containerName, 'pg_isready', '-U', 'agent_test', '-d', 'agent_test'], {
      stdio: 'ignore'
    });
    if (result.status === 0) return;
    await delay(POSTGRES_READY_INTERVAL_MS);
  }
  throw new Error('临时 PostgreSQL 容器未就绪');
}

function readMappedPort(containerName) {
  const result = run('docker', ['port', containerName, '5432/tcp'], { capture: true });
  if (result.status !== 0) {
    throw new Error(result.stderr || '读取 PostgreSQL 映射端口失败');
  }
  const line = result.stdout.trim().split('\n')[0] || '';
  const match = line.match(/:(\d+)$/);
  if (!match) {
    throw new Error(`docker port 输出不符合预期:${line}`);
  }
  return match[1];
}

if (process.env.AGENT_POSTGRES_TEST_DATABASE_URL) {
  runTests(process.env.AGENT_POSTGRES_TEST_DATABASE_URL);
  process.exit(0);
}

const containerName = `gpt-image-agent-test-pg-${Date.now()}`;

try {
  run('docker', [
    'run',
    '-d',
    '--name',
    containerName,
    '-e',
    'POSTGRES_DB=agent_test',
    '-e',
    'POSTGRES_USER=agent_test',
    '-e',
    'POSTGRES_PASSWORD=agent_test',
    '-p',
    '127.0.0.1::5432',
    'postgres:16-alpine'
  ], { silent: true });
  await waitForPostgres(containerName);
  const port = readMappedPort(containerName);
  runTests(`postgres://agent_test:agent_test@127.0.0.1:${port}/agent_test`);
} finally {
  spawnSync('docker', ['rm', '-f', containerName], { stdio: 'ignore' });
}