1
0
Files
DiAL/tests/server/checker/engine.test.ts
lanyuanxiaoyao 599d973cbd feat: 增强 expect 规则系统,支持多种 body 校验方法和操作符
- 新增 body 分组校验:contains、regex、json(JSONPath)、css(CSS选择器)、xpath
- 新增操作符系统:equals、contains、match、empty、exists、gte、lte、gt、lt
- 新增 headers 响应头校验
- 引入 cheerio、xpath、@xmldom/xmldom 依赖
- BREAKING: expect.bodyContains 迁移至 expect.body.contains
2026-05-10 00:10:42 +08:00

97 lines
3.1 KiB
TypeScript

import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import { ProbeStore } from "../../../src/server/checker/store";
import { ProbeEngine } from "../../../src/server/checker/engine";
import type { ResolvedTarget } from "../../../src/server/checker/types";
import { mkdir, rm } from "node:fs/promises";
import { join } from "node:path";
import { tmpdir } from "node:os";
describe("ProbeEngine", () => {
let tempDir: string;
let store: ProbeStore;
const target: ResolvedTarget = {
name: "httpbin",
url: "https://httpbin.org/get",
method: "GET",
headers: {},
intervalMs: 60000,
timeoutMs: 10000,
};
beforeAll(async () => {
tempDir = join(tmpdir(), `gc-engine-test-${Date.now()}`);
await mkdir(tempDir, { recursive: true });
store = new ProbeStore(join(tempDir, "test.db"));
store.syncTargets([target]);
});
afterAll(async () => {
store.close();
await rm(tempDir, { recursive: true, force: true });
});
test("groupByInterval 分组逻辑", () => {
const targets: ResolvedTarget[] = [
{ name: "a", url: "http://a.com", method: "GET", headers: {}, intervalMs: 30000, timeoutMs: 10000 },
{ name: "b", url: "http://b.com", method: "GET", headers: {}, intervalMs: 30000, timeoutMs: 10000 },
{ name: "c", url: "http://c.com", method: "GET", headers: {}, intervalMs: 60000, timeoutMs: 10000 },
];
const engine = new ProbeEngine(store, targets);
engine.start();
engine.stop();
// 只要能启动和停止不出错就行
expect(true).toBe(true);
});
test("engine start/stop 不抛错", () => {
const engine = new ProbeEngine(store, [target]);
engine.start();
engine.stop();
expect(true).toBe(true);
});
test("单次拨测写入数据库", async () => {
const engine = new ProbeEngine(store, [target]);
// 手动调用 probeGroup 不启动 timer
const probeGroup = (engine as unknown as { probeGroup: (t: ResolvedTarget[]) => Promise<void> }).probeGroup.bind(
engine,
);
await probeGroup([target]);
const dbTargets = store.getTargets();
const latest = store.getLatestCheck(dbTargets[0]!.id);
expect(latest).not.toBeNull();
expect(latest!.success === 1 || latest!.success === 0).toBe(true);
});
test("单目标失败隔离", async () => {
const badTarget: ResolvedTarget = {
name: "bad-target",
url: "http://127.0.0.1:1/impossible",
method: "GET",
headers: {},
intervalMs: 60000,
timeoutMs: 2000,
};
store.syncTargets([target, badTarget]);
const engine = new ProbeEngine(store, [target, badTarget]);
const probeGroup = (engine as unknown as { probeGroup: (t: ResolvedTarget[]) => Promise<void> }).probeGroup.bind(
engine,
);
await probeGroup([target, badTarget]);
const dbTargets = store.getTargets();
const goodResult = store.getLatestCheck(dbTargets.find((t) => t.name === "httpbin")!.id);
const badResult = store.getLatestCheck(dbTargets.find((t) => t.name === "bad-target")!.id);
expect(goodResult).not.toBeNull();
expect(badResult).not.toBeNull();
expect(badResult!.success).toBe(0);
});
});