test: server 测试共用建库与假引擎,sse-pg 归入串行组

- 新增 apps/server/test/support/{pg,engine}.ts:测试库地址、可用性探测、schema 咨询锁、
  建 schema + 加锁迁移 + 删除、可选去重的假引擎;6 份 harness 改用它(acquisition-organize 与
  file-manager 原先迁移不加锁,并行下有冲突隐患,一并修正)
- sse-pg 起子进程,并行下子进程启动超时,归入 serial
- 修正 b61335e 挪动 / 改名测试后遗留的 import 排序与格式(当时 lint 检查经管道被吞掉退出码)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-10-02 17:40:43 +08:00
1 parent 7cc3742d31
commit c9e8120fc6
25 files changed
+254 -328

No files matched your search

@@ -1,8 +1,8 @@
import { MOCK_CAMOFOX_IDENTITY } from "@umt/testkit";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { egressProxy } from "../../src/modules/browser/service.ts";
import { sourcesIdentityModule } from "../../src/modules/sources-identity/index.ts";
import { readBrowserUserAgent } from "../../src/modules/sources-identity/service/user-agent.ts";
import { egressProxy } from "../../src/modules/browser/service.ts";
import { type BrowserHarness, createBrowserHarness, type Loose, ORIGIN, pgAvailable } from "./harness.ts";
// BR-4:打开会话前按站点下发出口(站点开代理 = 与 HTTP 同一代理,否则直连);浏览器固定身份写进 browser_provider.identity,
@@ -1,6 +1,6 @@
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import type { ServerContext } from "../../src/modules/types.ts";
import { BrowserService, BrowserServiceError, ENV_PROVIDER_NAME } from "../../src/modules/browser/service.ts";
import type { ServerContext } from "../../src/modules/types.ts";
import { ACCESS_KEY, type BrowserHarness, createBrowserHarness, type Loose, pgAvailable } from "./harness.ts";
// BR-1:浏览器服务登记 —— 环境变量(BROWSER_PROVIDER_URL / BROWSER_ACCESS_KEY / BROWSER_ENABLED → camofox-env)
+9 -23
View File
@@ -2,7 +2,7 @@ import { mkdtemp, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import type { CapabilityRegistry, InvokeContext } from "@umt/agent";
import { type DB, type Kysely, migrateToLatest, sql } from "@umt/db";
import type { DB, Kysely } from "@umt/db";
import {
buildFakeTorrent,
createMockCamofox,
@@ -10,22 +10,20 @@ import {
type MockCamofox,
type MockCamofoxSite,
} from "@umt/testkit";
import { Kysely as K, PostgresDialect } from "kysely";
import pg from "pg";
import { withSchemaLock } from "../auth-settings/harness.ts";
import { DEV_KEY, memoryLogger, memoryStore } from "../helpers.ts";
import { fakeEngine, fakeSecrets, PG_URL, plainSettings } from "../sources-identity/harness.ts";
import { createOutboxPort } from "../../src/context.ts";
import { createApp } from "../../src/http/app.ts";
import { EventBus } from "../../src/http/sse.ts";
import { createAcquisitionOrganizeModule } from "../../src/modules/acquisition-organize/index.ts";
import { createCapabilityRegistry } from "../../src/modules/agent/capability-registry.ts";
import { createAgentModule } from "../../src/modules/agent/index.ts";
import { createSourcesIdentityModule } from "../../src/modules/sources-identity/index.ts";
import type { ServerContext } from "../../src/modules/types.ts";
import { registerBrowserCapabilities } from "../../src/modules/browser/capabilities.ts";
import { createBrowserModule } from "../../src/modules/browser/index.ts";
import type { BrowserModuleOptions } from "../../src/modules/browser/service.ts";
import { createSourcesIdentityModule } from "../../src/modules/sources-identity/index.ts";
import type { ServerContext } from "../../src/modules/types.ts";
import { DEV_KEY, memoryLogger, memoryStore } from "../helpers.ts";
import { fakeEngine, fakeSecrets, plainSettings } from "../sources-identity/harness.ts";
import { createTestSchema, uniqueSchema } from "../support/pg.ts";
// C1-E 浏览器模块测试装配:独立 PG schema + 真实迁移 + 交互式 mock camofox(观众风格站点)+ 真实能力注册中心。
@@ -94,18 +92,8 @@ export async function createBrowserHarness(
},
});
const stagingDir = await mkdtemp(join(tmpdir(), "umt-browser-"));
const schema = `c1e_${name}_${process.pid.toString(36)}${Math.random().toString(36).slice(2, 7)}`;
const admin = new K<unknown>({
dialect: new PostgresDialect({ pool: new pg.Pool({ connectionString: PG_URL, max: 1 }) }),
});
await sql.raw(`create schema ${schema}`).execute(admin);
await import("@umt/db");
const db = new K<DB>({
dialect: new PostgresDialect({
pool: new pg.Pool({ connectionString: PG_URL, max: 8, options: `-c search_path=${schema},public` }),
}),
}) as unknown as Kysely<DB>;
await withSchemaLock(() => migrateToLatest(db, { migrationTableSchema: schema }));
const ts = await createTestSchema(uniqueSchema(`c1e_${name}`), { max: 8 });
const db = ts.db as unknown as Kysely<DB>;
const { logger } = memoryLogger();
const secrets = fakeSecrets(() => db);
@@ -230,9 +218,7 @@ export async function createBrowserHarness(
await db.insertInto("automation_grant").values({ action, granted_by: "test" }).execute();
},
async close() {
await db.destroy();
await withSchemaLock(() => sql.raw(`drop schema if exists ${schema} cascade`).execute(admin));
await admin.destroy();
await ts.drop();
await mock.close();
await rm(stagingDir, { recursive: true, force: true });
},