test: 测试按行为命名、server 测试统一到 test/、PG 测试分组并行

- server 的 src/modules/*/__tests__ 挪到 test/<模块>/;e2e 去掉 eN- 前缀,
  w5a2 / v2 / search2 / *-dh1 / *-md1 / *-md2、web 的 agui3 / search2、domain 的 id2 / id3 改为按行为命名
- vitest 分三组:unit、pg(真实 PG + 假引擎,文件并行,最多 6 个)、serial(真实引擎 / worker / e2e,串行);
  pg 组用例超时放宽到 60s(迁移类用例并行时排队等 schema 锁)。server 测试 615s → 约 350s
- CLAUDE.md 补测试约定;待办补 harness 去重与 continuous-series 偶发超时(疑似 Slot 评估竞争)
- ADR-004 补充:维持 Deno,记录实际只用到 --allow-run 白名单

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-10-02 16:54:04 +08:00
1 parent b343dddbf6
commit b61335eaf6
75 files changed
+159 -115

No files matched your search

@@ -1,10 +1,10 @@
import { sql } from "@umt/db";
import { createMockQb, createTempTree, type MockQb, makeTorrent, type TempTree } from "@umt/testkit";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { createSchedulesModule } from "../../schedules/index.ts";
import { evaluateAcquisition } from "../services/acquisition.ts";
import { submitDownload, syncDownloads } from "../services/downloads.ts";
import { executeRecord, planImport } from "../services/organize.ts";
import { createSchedulesModule } from "../../src/modules/schedules/index.ts";
import { evaluateAcquisition } from "../../src/modules/acquisition-organize/services/acquisition.ts";
import { submitDownload, syncDownloads } from "../../src/modules/acquisition-organize/services/downloads.ts";
import { executeRecord, planImport } from "../../src/modules/acquisition-organize/services/organize.ts";
import {
createHarness,
fakeDisk,
@@ -2,11 +2,11 @@ import { OpenAPIHono } from "@hono/zod-openapi";
import type { TmdbClient } from "@umt/adapters";
import { DEFAULT_CLASSIFICATION_YAML } from "@umt/domain";
import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from "vitest";
import type { AuthEnv } from "../../../http/auth.ts";
import { createSettingsReader } from "../../auth-settings/provided.ts";
import { registerSettingsRoutes } from "../../auth-settings/settings-routes.ts";
import { SourcesRuntime } from "../../sources-identity/runtime.ts";
import { classifyEntity } from "../services/classification.ts";
import type { AuthEnv } from "../../src/http/auth.ts";
import { createSettingsReader } from "../../src/modules/auth-settings/provided.ts";
import { registerSettingsRoutes } from "../../src/modules/auth-settings/settings-routes.ts";
import { SourcesRuntime } from "../../src/modules/sources-identity/runtime.ts";
import { classifyEntity } from "../../src/modules/acquisition-organize/services/classification.ts";
import { createHarness, type Harness, pgAvailable, seedEntity } from "./harness.ts";
const hasPg = await pgAvailable();
@@ -294,7 +294,7 @@ describe.skipIf(!hasPg)("DL-3 下载计划并入下载面板(真实 PG)", () =>
});
it("审批被拒 / 过期:草案跟着结束,不再算进行中", async () => {
const { closeDraftPlan } = await import("../../agent/interaction.ts");
const { closeDraftPlan } = await import("../../src/modules/agent/interaction.ts");
await closeDraftPlan(h.db, { plan_type: "acquisition_plan", plan_id: ids.draft }, "rejected");
await closeDraftPlan(h.db, { plan_type: "acquisition_plan", plan_id: ids.agentDraft }, "expired");
// 不是草案的不动
@@ -1,6 +1,6 @@
import { createMockQb, type MockQb } from "@umt/testkit";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { syncDownloads } from "../services/downloads.ts";
import { syncDownloads } from "../../src/modules/acquisition-organize/services/downloads.ts";
import { createHarness, type Harness, pgAvailable, seedEntity } from "./harness.ts";
// DL-2 下载面板:进行中 / 已完成分组与计数、每个种子的实时速度 / 剩余时间 / 连接数、下载器总速度、
@@ -2,8 +2,8 @@ import type { TaskRunView } from "@umt/tasks";
import { createTempTree, type TempTree } from "@umt/testkit";
import { sql } from "kysely";
import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from "vitest";
import { enqueueSweep, enqueueTracked } from "../services/common.ts";
import { type QueueScrapeInput, queueScrape, runScrapeRecord } from "../services/scrape.ts";
import { enqueueSweep, enqueueTracked } from "../../src/modules/acquisition-organize/services/common.ts";
import { type QueueScrapeInput, queueScrape, runScrapeRecord } from "../../src/modules/acquisition-organize/services/scrape.ts";
import { createHarness, type Harness, pgAvailable, seedBase, seedEntity } from "./harness.ts";
const hasPg = await pgAvailable();
@@ -7,17 +7,17 @@ import { type DB, migrateToLatest } from "@umt/db";
import type { TaskEngine } from "@umt/tasks";
import { Kysely, PostgresDialect, sql } from "kysely";
import pg from "pg";
import { ConfigSchema } from "../../../config.ts";
import { createOutboxPort } from "../../../context.ts";
import { createApp } from "../../../http/app.ts";
import { hashApiKey } from "../../../http/auth.ts";
import { EventBus } from "../../../http/sse.ts";
import { createLogger } from "../../../logger.ts";
import { createCapabilityRegistry } from "../../agent/capability-registry.ts";
import { createSourcesIdentityModule } from "../../sources-identity/index.ts";
import type { ServerContext } from "../../types.ts";
import { type AoOverrides, createAcquisitionOrganizeModule } from "../index.ts";
import type { AoDeps } from "../services/common.ts";
import { ConfigSchema } from "../../src/config.ts";
import { createOutboxPort } from "../../src/context.ts";
import { createApp } from "../../src/http/app.ts";
import { hashApiKey } from "../../src/http/auth.ts";
import { EventBus } from "../../src/http/sse.ts";
import { createLogger } from "../../src/logger.ts";
import { createCapabilityRegistry } from "../../src/modules/agent/capability-registry.ts";
import { createSourcesIdentityModule } from "../../src/modules/sources-identity/index.ts";
import type { ServerContext } from "../../src/modules/types.ts";
import { type AoOverrides, createAcquisitionOrganizeModule } from "../../src/modules/acquisition-organize/index.ts";
import type { AoDeps } from "../../src/modules/acquisition-organize/services/common.ts";
// 真实 PG(独立 schema)+ mock qB + 临时目录 的测试装配;引擎用记录入队的假实现,测试直接驱动服务函数。
@@ -1,7 +1,7 @@
import type { DB } from "@umt/db";
import type { Kysely } from "kysely";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { backfillVersionSpecs } from "../services/version-backfill.ts";
import { backfillVersionSpecs } from "../../src/modules/acquisition-organize/services/version-backfill.ts";
import { createHarness, type Harness, pgAvailable, seedEntity, seedRelease, seedSlot } from "./harness.ts";
// LIBV-1:入库版本 API(每集多个版本、季汇总、单目标比对)与规格回填(dry-run / apply)。
@@ -1,9 +1,9 @@
import { ManualAcquisitionRequest } from "@umt/contracts";
import { createMockQb, createTempTree, makeTorrent } from "@umt/testkit";
import { describe, expect, it } from "vitest";
import { evaluateAcquisition } from "../services/acquisition.ts";
import { submitDownload } from "../services/downloads.ts";
import { planManualAcquisition } from "../services/manual-acquisition.ts";
import { evaluateAcquisition } from "../../src/modules/acquisition-organize/services/acquisition.ts";
import { submitDownload } from "../../src/modules/acquisition-organize/services/downloads.ts";
import { planManualAcquisition } from "../../src/modules/acquisition-organize/services/manual-acquisition.ts";
import { createHarness, fakeDisk, pgAvailable, seedBase, seedEntity, seedRelease, seedSlot } from "./harness.ts";
const hasPg = await pgAvailable();
@@ -2,7 +2,7 @@ import { createHash } from "node:crypto";
import { DEFAULT_NAMING_TEMPLATES } from "@umt/contracts";
import { LEGACY_V1_NAMING, MP_DEFAULT_NAMING, namingCanonicalJson } from "@umt/domain";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { ensureNamingVersion, namingByVersion } from "../services/naming.ts";
import { ensureNamingVersion, namingByVersion } from "../../src/modules/acquisition-organize/services/naming.ts";
import { createHarness, type Harness, pgAvailable, seedBase, seedEntity } from "./harness.ts";
// W9-C 命名模板:变量表、预览(样本/错误/路径绑定)、三级模板读写与保存前校验、模板版本登记。
@@ -4,7 +4,7 @@ import { readdir, readFile, rm, utimes, writeFile } from "node:fs/promises";
import { dirname, join } from "node:path";
import { createTempTree, type TempTree } from "@umt/testkit";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { executeRecord, type FrozenPlan, planImport } from "../services/organize.ts";
import { executeRecord, type FrozenPlan, planImport } from "../../src/modules/acquisition-organize/services/organize.ts";
import { createHarness, type Harness, pgAvailable, seedBase, seedEntity } from "./harness.ts";
// W4-E4 执行侧:replace_with_verify 接线(写临时→校验→原子替换,旧文件进回收目录)、写前清 partial、
@@ -4,8 +4,8 @@ import { join } from "node:path";
import { sql } from "@umt/db";
import { createMockQb, createTempTree, type MockQb, makeTorrent, type TempTree } from "@umt/testkit";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { evaluateAcquisition } from "../services/acquisition.ts";
import { submitDownload, syncDownloads } from "../services/downloads.ts";
import { evaluateAcquisition } from "../../src/modules/acquisition-organize/services/acquisition.ts";
import { submitDownload, syncDownloads } from "../../src/modules/acquisition-organize/services/downloads.ts";
import {
createHarness,
EXEC_KEY,
@@ -12,9 +12,9 @@ import {
type TempTree,
} from "@umt/testkit";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { evaluateAcquisition } from "../services/acquisition.ts";
import { submitDownload, syncDownloads } from "../services/downloads.ts";
import { executeRecord, type FrozenPlan, planImport } from "../services/organize.ts";
import { evaluateAcquisition } from "../../src/modules/acquisition-organize/services/acquisition.ts";
import { submitDownload, syncDownloads } from "../../src/modules/acquisition-organize/services/downloads.ts";
import { executeRecord, type FrozenPlan, planImport } from "../../src/modules/acquisition-organize/services/organize.ts";
import {
createHarness,
EXEC_KEY,
@@ -4,9 +4,9 @@ import type { TmdbClient } from "@umt/adapters";
import { DEFAULT_SETTINGS, type OrganizeSourceConfig } from "@umt/contracts";
import { createMockQb, createTempTree, type MockQb, type TempTree } from "@umt/testkit";
import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from "vitest";
import { SourcesRuntime } from "../../sources-identity/runtime.ts";
import { syncDownloads } from "../services/downloads.ts";
import { executeRecord, planImport } from "../services/organize.ts";
import { SourcesRuntime } from "../../src/modules/sources-identity/runtime.ts";
import { syncDownloads } from "../../src/modules/acquisition-organize/services/downloads.ts";
import { executeRecord, planImport } from "../../src/modules/acquisition-organize/services/organize.ts";
import { createHarness, type Harness, pgAvailable, seedBase, seedEntity } from "./harness.ts";
const hasPg = await pgAvailable();
@@ -5,7 +5,7 @@ import { dirname } from "node:path";
import { DEFAULT_SETTINGS } from "@umt/contracts";
import { createMockQb, createTempTree, type MockQb, type TempTree } from "@umt/testkit";
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
import { executeRecord, planImport } from "../services/organize.ts";
import { executeRecord, planImport } from "../../src/modules/acquisition-organize/services/organize.ts";
import { createHarness, type Harness, pgAvailable, seedBase, seedEntity } from "./harness.ts";
const hasPg = await pgAvailable();
@@ -1,7 +1,7 @@
import { makeTorrent } from "@umt/testkit";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { createAcquisitionOrganizeModule } from "../index.ts";
import { evaluateAcquisition } from "../services/acquisition.ts";
import { createAcquisitionOrganizeModule } from "../../src/modules/acquisition-organize/index.ts";
import { evaluateAcquisition } from "../../src/modules/acquisition-organize/services/acquisition.ts";
import { createHarness, fakeDisk, type Harness, pgAvailable, seedBase, seedEntity, seedRelease } from "./harness.ts";
// 规则 API:订阅/Slot/策略版本(发布=持续授权、回滚)/偏好标签抑制;新作品收录走已发布策略;outbox 路由。
@@ -2,8 +2,8 @@ import { chmod, readdir, readFile, stat, writeFile } from "node:fs/promises";
import { join, relative } from "node:path";
import { createTempTree, type TempTree } from "@umt/testkit";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { executeRecord, planImport } from "../services/organize.ts";
import { entityScrapeLocations, runScrapeRecord, SCRAPE_TASK, scrapeEntity } from "../services/scrape.ts";
import { executeRecord, planImport } from "../../src/modules/acquisition-organize/services/organize.ts";
import { entityScrapeLocations, runScrapeRecord, SCRAPE_TASK, scrapeEntity } from "../../src/modules/acquisition-organize/services/scrape.ts";
import { createHarness, type Harness, pgAvailable, seedBase, seedEntity } from "./harness.ts";
// 刮削(SCR-1 / SCR-2):入库成功后自动对作品目录排 scrapeMedia → 写 NFO 与图片(临时库根);只补缺失 / 全部覆盖;
@@ -1,10 +1,10 @@
import { createQbClient } from "@umt/adapters";
import { createMockQb, createTempTree, type MockQb, makeTorrent, type TempTree } from "@umt/testkit";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { evaluateAcquisition } from "../services/acquisition.ts";
import { submitDownload, syncDownloads } from "../services/downloads.ts";
import { executeRecord, planImport } from "../services/organize.ts";
import { applyEpisodeTotal, subscriptionProgress, sweepDueSlots } from "../services/subscriptions.ts";
import { evaluateAcquisition } from "../../src/modules/acquisition-organize/services/acquisition.ts";
import { submitDownload, syncDownloads } from "../../src/modules/acquisition-organize/services/downloads.ts";
import { executeRecord, planImport } from "../../src/modules/acquisition-organize/services/organize.ts";
import { applyEpisodeTotal, subscriptionProgress, sweepDueSlots } from "../../src/modules/acquisition-organize/services/subscriptions.ts";
import { createHarness, fakeDisk, type Harness, pgAvailable, seedBase, seedEntity, seedRelease } from "./harness.ts";
// W5-C 订阅增强集成:Slot×单元多在途 + 忙时延后重评 + 移除释放;季包按缺集选文件(mock qB files/filePrio);
@@ -2,10 +2,10 @@ import { existsSync, readdirSync, statSync } from "node:fs";
import { join } from "node:path";
import { createMockQb, createTempTree, type MockQb, type TempTree } from "@umt/testkit";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { addAliasIfAbsent } from "../../sources-identity/service/entities.ts";
import { syncDownloads } from "../services/downloads.ts";
import { executeRecord, planImport } from "../services/organize.ts";
import { organizeDecisionHook, pickMainVideo, takeoverParsed } from "../services/takeover.ts";
import { addAliasIfAbsent } from "../../src/modules/sources-identity/service/entities.ts";
import { syncDownloads } from "../../src/modules/acquisition-organize/services/downloads.ts";
import { executeRecord, planImport } from "../../src/modules/acquisition-organize/services/organize.ts";
import { organizeDecisionHook, pickMainVideo, takeoverParsed } from "../../src/modules/acquisition-organize/services/takeover.ts";
import { createHarness, type Harness, pgAvailable, seedBase, seedEntity } from "./harness.ts";
// QB-1:接管任务(用户手动加进 qB、贴管理标签,没有站点资源)完成后按 种子名 + 主视频文件名 识别 → 直接整理;
@@ -4,10 +4,10 @@ import { join } from "node:path";
import { sql } from "@umt/db";
import { createMockQb, createTempTree, type MockQb, makeTorrent, type TempTree } from "@umt/testkit";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { evaluateAcquisition } from "../services/acquisition.ts";
import { cleanupDownloadCache, submitDownload, syncDownloads } from "../services/downloads.ts";
import { executeRecord, planImport } from "../services/organize.ts";
import { reconcileLibrary } from "../services/reconcile.ts";
import { evaluateAcquisition } from "../../src/modules/acquisition-organize/services/acquisition.ts";
import { cleanupDownloadCache, submitDownload, syncDownloads } from "../../src/modules/acquisition-organize/services/downloads.ts";
import { executeRecord, planImport } from "../../src/modules/acquisition-organize/services/organize.ts";
import { reconcileLibrary } from "../../src/modules/acquisition-organize/services/reconcile.ts";
import {
createHarness,
fakeDisk,
@@ -3,8 +3,8 @@ import { readdir, readFile } from "node:fs/promises";
import { join } from "node:path";
import { MOCK_ROW_H, MOCK_ROW_Y0, MOCK_VIEWPORT } from "@umt/testkit";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { registerBrowserCapabilities } from "../capabilities.ts";
import { createBrowserModule } from "../index.ts";
import { registerBrowserCapabilities } from "../../src/modules/browser/capabilities.ts";
import { createBrowserModule } from "../../src/modules/browser/index.ts";
import {
ACCESS_KEY,
type BrowserHarness,
@@ -206,7 +206,7 @@ describe.skipIf(!up)("浏览器 HTTP 端点", () => {
it("服务重启:按数据库恢复会话,旧引用失效;上游回收的标签页标 lost 并自动重开", async () => {
// 新模块实例 = 进程重启(适配器内存为空)
const fresh = createBrowserModule({ stagingDir: h.stagingDir });
const reg = (await import("../../agent/capability-registry.ts")).createCapabilityRegistry({
const reg = (await import("../../src/modules/agent/capability-registry.ts")).createCapabilityRegistry({
logger: h.ctx.logger,
db: h.db,
settings: h.ctx.settings,
@@ -1,8 +1,8 @@
import { siteCloudflareState } from "@umt/contracts";
import { MOCK_CAMOFOX_IDENTITY, type MockCamofoxSite } from "@umt/testkit";
import { afterAll, beforeAll, beforeEach, describe, expect, it } from "vitest";
import { browserServiceFor } from "../index.ts";
import { type BrowserService, registerChallengeVision } from "../service.ts";
import { browserServiceFor } from "../../src/modules/browser/index.ts";
import { type BrowserService, registerChallengeVision } from "../../src/modules/browser/service.ts";
import { type BrowserHarness, createBrowserHarness, type Loose, ORIGIN, pgAvailable } from "./harness.ts";
// CF-2 浏览器一侧(对 testkit mock camofox 的 Cloudflare 模式):
@@ -1,5 +1,5 @@
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { readAccountCookie } from "../../sources-identity/service/credentials.ts";
import { readAccountCookie } from "../../src/modules/sources-identity/service/credentials.ts";
import { type BrowserHarness, createBrowserHarness, type Loose, ORIGIN, pgAvailable } from "./harness.ts";
// BR-2 凭据统一(对 testkit mock camofox + mock NexusPHP 登录态判定):
@@ -1,8 +1,8 @@
import { MOCK_CAMOFOX_IDENTITY } from "@umt/testkit";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { sourcesIdentityModule } from "../../sources-identity/index.ts";
import { readBrowserUserAgent } from "../../sources-identity/service/user-agent.ts";
import { egressProxy } from "../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 { browserServiceFor } from "../index.ts";
import { BrowserKeepalive } from "../keepalive.ts";
import { browserServiceFor } from "../../src/modules/browser/index.ts";
import { BrowserKeepalive } from "../../src/modules/browser/keepalive.ts";
import { type BrowserHarness, createBrowserHarness, type Loose, ORIGIN, pgAvailable } from "./harness.ts";
// AG-4 浏览器会话保活(对 testkit mock camofox):桌面连接 / 人工接管 / 智能体会话正在用的会话定期做一次
@@ -1,6 +1,6 @@
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import type { ServerContext } from "../../types.ts";
import { BrowserService, BrowserServiceError, ENV_PROVIDER_NAME } from "../service.ts";
import type { ServerContext } from "../../src/modules/types.ts";
import { BrowserService, BrowserServiceError, ENV_PROVIDER_NAME } from "../../src/modules/browser/service.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)
@@ -1,6 +1,6 @@
import { getSiteDefinition } from "@umt/adapters";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { resourceIdFromUrl } from "../resource.ts";
import { resourceIdFromUrl } from "../../src/modules/browser/resource.ts";
import { type BrowserHarness, createBrowserHarness, ORIGIN, pgAvailable, READ_KEY } from "./harness.ts";
const def = getSiteDefinition("audiences")!;
@@ -12,24 +12,24 @@ import {
} from "@umt/testkit";
import { Kysely as K, PostgresDialect } from "kysely";
import pg from "pg";
import { withSchemaLock } from "../../../../test/auth-settings/harness.ts";
import { DEV_KEY, memoryLogger, memoryStore } from "../../../../test/helpers.ts";
import { fakeEngine, fakeSecrets, PG_URL, plainSettings } from "../../../../test/sources-identity/harness.ts";
import { createOutboxPort } from "../../../context.ts";
import { createApp } from "../../../http/app.ts";
import { EventBus } from "../../../http/sse.ts";
import { createAcquisitionOrganizeModule } from "../../acquisition-organize/index.ts";
import { createCapabilityRegistry } from "../../agent/capability-registry.ts";
import { createAgentModule } from "../../agent/index.ts";
import { createSourcesIdentityModule } from "../../sources-identity/index.ts";
import type { ServerContext } from "../../types.ts";
import { registerBrowserCapabilities } from "../capabilities.ts";
import { createBrowserModule } from "../index.ts";
import type { BrowserModuleOptions } from "../service.ts";
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";
// C1-E 浏览器模块测试装配:独立 PG schema + 真实迁移 + 交互式 mock camofox(观众风格站点)+ 真实能力注册中心。
export { pgAvailable } from "../../../../test/sources-identity/harness.ts";
export { pgAvailable } from "../sources-identity/harness.ts";
export const ORIGIN = "https://audiences.example";
export const PASSWORD = "brw-s3cret-login-pw";
@@ -1,7 +1,7 @@
import { OpenAPIHono } from "@hono/zod-openapi";
import { describe, expect, it } from "vitest";
import type { AuthEnv, Principal, SessionVar } from "../../../http/auth.ts";
import { ApiException, errorBody } from "../../../http/errors.ts";
import type { AuthEnv, Principal, SessionVar } from "../../src/http/auth.ts";
import { ApiException, errorBody } from "../../src/http/errors.ts";
import {
basicAuth,
type DesktopDeps,
@@ -10,7 +10,7 @@ import {
desktopUpstream,
registerDesktopRoutes,
sameOrigin,
} from "../desktop.ts";
} from "../../src/modules/desktop/desktop.ts";
// 桌面模式反代:口令派生与容器 init 脚本一致、角色 → 口令注入、只接受控制台会话、响应头与路径约束。
@@ -14,7 +14,7 @@ import { createE2E, type E2E, pgAvailable, runEvents, runRow, waitFor } from "./
// 运行(凭证只经环境变量传入,不写进代码与报告):
// UMT_EVAL_REAL=1 UMT_EVAL_API_KEY=… UMT_EVAL_PROVIDER=opencode-go UMT_EVAL_MODEL=deepseek-v4.1-flash \
// UMT_EVAL_LEGACY_PROMPT=/tmp/legacy-system-prompt.ts UMT_EVAL_CASES=health,acquire,why UMT_EVAL_OUT=/tmp/eval.json \
// DATABASE_URL=… deno run -A npm:vitest run test/e2e/e16-agent-prompt-eval.real.test.ts
// DATABASE_URL=… deno run -A npm:vitest run test/e2e/agent-prompt-eval.real.test.ts
// UMT_EVAL_LEGACY_PROMPT 用 `git show main:packages/agent/src/system-prompt.ts > /tmp/legacy-system-prompt.ts` 生成;
// UMT_EVAL_PROMPTS=legacy,layered 控制跑哪几组(缺省两组都跑)。
@@ -9,7 +9,7 @@ import { createE2E, type E2E, pgAvailable, runEvents, runRow, waitFor } from "./
// - fake 模型按"合格模型"的路线调用能力:断言调用顺序、只读调用都成功、需要批准的被拒绝(不向用户要 ID:
// download.inspect 的 ID 来自 download.list);
// - 汇报格式约束:合格汇报(只用工具结果里的数据写)通过 lintReport(无 UUID / 原始字节 / 内部字段,≤8 行,结论先行)。
// 真实模型的前后对比见 e16-agent-prompt-eval.real.test.ts 与 docs/design/agent-prompt-eval.md。
// 真实模型的前后对比见 agent-prompt-eval.real.test.ts 与 docs/design/agent-prompt-eval.md。
const hasPg = await pgAvailable();
File renamed without changes.
+1 -1
View File
@@ -20,7 +20,7 @@ import { createApp } from "../../src/http/app.ts";
import { deriveCsrfToken, hashApiKey, hashSessionToken } from "../../src/http/auth.ts";
import { EventBus } from "../../src/http/sse.ts";
import { createLogger } from "../../src/logger.ts";
import { fakeEngine } from "../../src/modules/acquisition-organize/__tests__/harness.ts";
import { fakeEngine } from "../acquisition-organize/harness.ts";
import { executeRecord, type FrozenPlan } from "../../src/modules/acquisition-organize/services/organize.ts";
import { runScrapeRecord } from "../../src/modules/acquisition-organize/services/scrape.ts";
import { createCapabilityRegistry } from "../../src/modules/agent/capability-registry.ts";
@@ -4,7 +4,7 @@ import {
type Harness,
pgAvailable,
seedEntity,
} from "../../src/modules/acquisition-organize/__tests__/harness.ts";
} from "../acquisition-organize/harness.ts";
import { MEDIA_SERVER_LIMITS } from "../../src/modules/acquisition-organize/routes/library.ts";
// C1-D:GET /inventory/media-servers 按实例并行(allSettled)+ 实例内并发上限 + 整实例超时;部分失败 partial=true。
+1 -1
View File
@@ -9,7 +9,7 @@ import {
seedEntity,
seedRelease,
seedSlot,
} from "../../src/modules/acquisition-organize/__tests__/harness.ts";
} from "../acquisition-organize/harness.ts";
import { evaluateAcquisition } from "../../src/modules/acquisition-organize/services/acquisition.ts";
// W9-D 规则组:关键字表、规则串解析/序列化、CRUD + 修订、抑制记录、试算、默认链、评估接入、旧端点别名。
@@ -10,7 +10,7 @@ import {
seedBase,
seedEntity,
seedRelease,
} from "../../src/modules/acquisition-organize/__tests__/harness.ts";
} from "../acquisition-organize/harness.ts";
import {
evaluateAcquisition,
subscriptionSavePath,
@@ -10,7 +10,7 @@ import {
seedBase,
seedEntity,
seedRelease,
} from "../../src/modules/acquisition-organize/__tests__/harness.ts";
} from "../acquisition-organize/harness.ts";
import { evaluateAcquisition } from "../../src/modules/acquisition-organize/services/acquisition.ts";
// W9-E 订阅重做后端:总览分组/排序/计数、覆盖矩阵(单集/季包/多版本/在途/临时单元/电影版本)、
+35 -9
View File
@@ -1,11 +1,12 @@
import { defineConfig } from "vitest/config";
// 两组测试:
// unit —— 纯内存、无 PG,文件并行;
// pg —— 真实 PG 的集成/e2e(每文件独立业务 schema + 引擎 schema,真实 worker/后台循环),文件级串行,
// 并排在 unit 之后(groupOrder)。并发全量跑时多个 e2e 的 worker/轮询/迁移互相抢 CPU 与连接,
// 会把"入库→状态推进"这类时序拉长到超时,也会放大竞态;串行让每个文件拿到稳定的时序预算。
// 新测试文件缺省归入 pg(串行,安全);确认不碰 PG 的才加进 UNIT。
// 三组测试,按 groupOrder 依次跑:
// unit —— 纯内存、无 PG,文件并行;
// pg —— 真实 PG、假引擎(每文件独立 schema),文件并行;
// serial —— 起真实引擎 / worker / 后台循环 / 子进程的集成与 e2e,文件级串行。并发跑时 worker、轮询、迁移
// 互相抢 CPU 与连接,会把"入库→状态推进"这类时序拉长到超时,串行让每个文件拿到稳定的时序预算。
// 新测试缺省进 pg;起真实 worker / 引擎的加进 SERIAL;确认不碰 PG 的加进 UNIT。
// 并行文件数受开发库连接数约束(max_connections 100,每个 harness 连接池 5–10):MAX_WORKERS 别随手调大。
const UNIT = [
"test/api-registry.test.ts",
"test/organize-in-place-verify.test.ts",
@@ -22,23 +23,48 @@ const UNIT = [
"test/static.test.ts",
];
const SERIAL = [
"test/e2e/**/*.test.ts",
"test/auth-settings/admin-api.test.ts",
"test/auth-settings/engine-retry.test.ts",
"test/system/**/*.test.ts",
"test/search/search.test.ts",
"test/search/two-stage-search.test.ts",
"test/worker-lanes.test.ts",
"test/preflight.test.ts",
"test/bootstrap.test.ts",
];
const MAX_WORKERS = 6;
export default defineConfig({
test: {
// 建/删 schema 在一把咨询锁上排队(withSchemaLock),迁移 + 引擎 schema 在负载下可能超过缺省 10s
hookTimeout: 120_000,
teardownTimeout: 60_000,
maxWorkers: MAX_WORKERS,
projects: [
{ extends: true, test: { name: "unit", include: UNIT } },
{
extends: true,
test: {
name: "pg",
include: ["test/**/*.test.ts", "src/**/*.test.ts"],
exclude: UNIT,
fileParallelism: false,
include: ["test/**/*.test.ts"],
exclude: [...UNIT, ...SERIAL],
// 迁移类用例在用例体里建 schema + 迁移,并行时排队等同一把锁,缺省 5s 不够
testTimeout: 60_000,
sequence: { groupOrder: 1 },
},
},
{
extends: true,
test: {
name: "serial",
include: SERIAL,
fileParallelism: false,
sequence: { groupOrder: 2 },
},
},
],
},
});