test: reroute telegram fetch network policy suite

This commit is contained in:
Peter Steinberger 2026-04-03 11:17:54 +01:00
parent c0a8d07fce
commit a5eb8e08ad
No known key found for this signature in database
9 changed files with 92 additions and 23 deletions

View File

@ -1,6 +1,6 @@
import fs from "node:fs";
import path from "node:path";
import { channelTestPrefixes } from "../../vitest.channel-paths.mjs";
import { channelTestPrefixes, isChannelSurfaceTestFile } from "../../vitest.channel-paths.mjs";
import {
isBoundaryTestFile,
isBundledPluginDependentUnitTestFile,
@ -127,7 +127,7 @@ export function loadTestCatalog() {
surface = "live";
} else if (normalizedFile.endsWith(".e2e.test.ts")) {
surface = "e2e";
} else if (channelTestPrefixes.some((prefix) => normalizedFile.startsWith(prefix))) {
} else if (isChannelSurfaceTestFile(normalizedFile)) {
surface = "channels";
} else if (normalizedFile.startsWith(BUNDLED_PLUGIN_PATH_PREFIX)) {
surface = "extensions";

View File

@ -8,10 +8,6 @@
"deltaKb": 1111491,
"sources": ["openclaw-test-memory-trace:unit-heavy-2"]
},
"src/media/fetch.telegram-network.test.ts": {
"deltaKb": 1101005,
"sources": ["openclaw-test-memory-trace:unit-heavy-1"]
},
"src/cron/isolated-agent/run.skill-filter.test.ts": {
"deltaKb": 1069548,
"sources": ["openclaw-test-memory-trace:unit-run.skill-filter-memory-isolated"]

View File

@ -1,6 +1,6 @@
{
"config": "vitest.extensions.config.ts",
"generatedAt": "2026-03-31T06:24:09.128Z",
"generatedAt": "2026-04-03T10:15:21.663Z",
"defaultDurationMs": 1000,
"files": {
"extensions/bluebubbles/src/monitor.webhook-auth.test.ts": {
@ -1046,6 +1046,10 @@
"extensions/mattermost/src/mattermost/probe.test.ts": {
"durationMs": 2.155517578125,
"testCount": 5
},
"extensions/telegram/src/fetch.network-policy.test.ts": {
"durationMs": 3260,
"testCount": 5
}
}
}

View File

@ -3,10 +3,6 @@
"generatedAt": "2026-03-23T05:11:36.071Z",
"defaultDurationMs": 250,
"files": {
"src/media/fetch.telegram-network.test.ts": {
"durationMs": 6483.10009765625,
"testCount": 5
},
"src/cron/service.issue-regressions.test.ts": {
"durationMs": 4524.16552734375,
"testCount": 39

View File

@ -447,6 +447,18 @@ describe("scripts/test-parallel lane planning", () => {
expect(output).not.toContain("vitest.unit.config.ts");
});
it("routes telegram fetch network policy through the extensions config", () => {
const output = runPlannerPlan([
"--explain",
bundledPluginFile("telegram", "src/fetch.network-policy.test.ts"),
]);
expect(output).toContain("surface=extensions");
expect(output).toContain("reasons=extensions-surface");
expect(output).toContain("vitest.extensions.config.ts");
expect(output).not.toContain("vitest.channels.config.ts");
});
it("prints the planner-backed CI manifest as JSON", () => {
const output = runPlannerPlan(["--ci-manifest"], {
GITHUB_EVENT_NAME: "pull_request",

View File

@ -97,6 +97,21 @@ describe("scoped vitest configs", () => {
expect(defaultExtensionsConfig.test?.include).toEqual(["**/*.test.ts"]);
});
it("keeps telegram fetch network policy in extensions while excluding other telegram channel suites", () => {
const extensionExcludes = defaultExtensionsConfig.test?.exclude ?? [];
expect(
extensionExcludes.some((pattern) => path.matchesGlob("telegram/src/fetch.test.ts", pattern)),
).toBe(true);
expect(
extensionExcludes.some((pattern) =>
path.matchesGlob("telegram/src/fetch.network-policy.test.ts", pattern),
),
).toBe(false);
expect(defaultChannelsConfig.test?.exclude).toContain(
bundledPluginFile("telegram", "src/fetch.network-policy.test.ts"),
);
});
it("normalizes gateway include patterns relative to the scoped dir", () => {
expect(defaultGatewayConfig.test?.dir).toBe("src/gateway");
expect(defaultGatewayConfig.test?.include).toEqual(["**/*.test.ts"]);

View File

@ -1,4 +1,17 @@
import { bundledPluginRoot } from "./scripts/lib/bundled-plugin-paths.mjs";
import path from "node:path";
import {
BUNDLED_PLUGIN_PATH_PREFIX,
bundledPluginFile,
bundledPluginRoot,
} from "./scripts/lib/bundled-plugin-paths.mjs";
const normalizeRepoPath = (value) => value.split(path.sep).join("/");
export const extensionRoutedChannelTestFiles = [
bundledPluginFile("telegram", "src/fetch.network-policy.test.ts"),
];
const extensionRoutedChannelTestFileSet = new Set(extensionRoutedChannelTestFiles);
export const channelTestRoots = [
bundledPluginRoot("telegram"),
@ -14,3 +27,40 @@ export const channelTestRoots = [
export const channelTestPrefixes = channelTestRoots.map((root) => `${root}/`);
export const channelTestInclude = channelTestRoots.map((root) => `${root}/**/*.test.ts`);
export const channelTestExclude = channelTestRoots.map((root) => `${root}/**`);
const extensionChannelRootOverrideBasenames = new Map();
for (const file of extensionRoutedChannelTestFiles) {
if (!file.startsWith(BUNDLED_PLUGIN_PATH_PREFIX)) {
continue;
}
const relativeFile = file.slice(BUNDLED_PLUGIN_PATH_PREFIX.length);
const separator = relativeFile.indexOf("/");
if (separator === -1) {
continue;
}
const root = relativeFile.slice(0, separator);
const baseName = path.basename(relativeFile, ".test.ts");
const current = extensionChannelRootOverrideBasenames.get(root) ?? [];
current.push(baseName);
extensionChannelRootOverrideBasenames.set(root, current);
}
export const extensionExcludedChannelTestGlobs = channelTestRoots
.filter((root) => root.startsWith(BUNDLED_PLUGIN_PATH_PREFIX))
.map((root) => root.slice(BUNDLED_PLUGIN_PATH_PREFIX.length))
.map((relativeRoot) => {
const allowedBasenames = extensionChannelRootOverrideBasenames.get(relativeRoot) ?? [];
if (allowedBasenames.length === 0) {
return `${relativeRoot}/**`;
}
const alternation = allowedBasenames.join("|");
return `${relativeRoot}/**/!(${alternation}).test.ts`;
});
export function isChannelSurfaceTestFile(filePath) {
const normalizedFile = normalizeRepoPath(filePath);
return (
channelTestPrefixes.some((prefix) => normalizedFile.startsWith(prefix)) &&
!extensionRoutedChannelTestFileSet.has(normalizedFile)
);
}

View File

@ -1,4 +1,4 @@
import { channelTestInclude } from "./vitest.channel-paths.mjs";
import { channelTestInclude, extensionRoutedChannelTestFiles } from "./vitest.channel-paths.mjs";
import { loadPatternListFromEnv } from "./vitest.pattern-file.ts";
import { createScopedVitestConfig } from "./vitest.scoped-config.ts";
@ -11,7 +11,7 @@ export function loadIncludePatternsFromEnv(
export function createChannelsVitestConfig(env?: Record<string, string | undefined>) {
return createScopedVitestConfig(loadIncludePatternsFromEnv(env) ?? channelTestInclude, {
env,
exclude: ["src/gateway/**"],
exclude: ["src/gateway/**", ...extensionRoutedChannelTestFiles],
passWithNoTests: true,
});
}

View File

@ -1,8 +1,5 @@
import {
BUNDLED_PLUGIN_PATH_PREFIX,
BUNDLED_PLUGIN_TEST_GLOB,
} from "./scripts/lib/bundled-plugin-paths.mjs";
import { channelTestExclude } from "./vitest.channel-paths.mjs";
import { BUNDLED_PLUGIN_TEST_GLOB } from "./scripts/lib/bundled-plugin-paths.mjs";
import { extensionExcludedChannelTestGlobs } from "./vitest.channel-paths.mjs";
import { loadPatternListFromEnv } from "./vitest.pattern-file.ts";
import { createScopedVitestConfig } from "./vitest.scoped-config.ts";
@ -19,10 +16,9 @@ export function createExtensionsVitestConfig(
dir: "extensions",
env,
passWithNoTests: true,
// Channel implementations live under the bundled plugin tree but are tested by
// vitest.channels.config.ts (pnpm test:channels) which provides
// the heavier mock scaffolding they need.
exclude: channelTestExclude.filter((pattern) => pattern.startsWith(BUNDLED_PLUGIN_PATH_PREFIX)),
// Most channel implementations stay on the channel surface, but a few
// transport-only suites live better in the general extensions lane.
exclude: extensionExcludedChannelTestGlobs,
});
}