diff --git a/scripts/lib/channel-contract-test-plan.mjs b/scripts/lib/channel-contract-test-plan.mjs index cab5ca29935..80a45a69178 100644 --- a/scripts/lib/channel-contract-test-plan.mjs +++ b/scripts/lib/channel-contract-test-plan.mjs @@ -14,17 +14,26 @@ function listContractTestFiles(rootDir = "src/channels/plugins/contracts") { const CONTRACT_FILE_WEIGHTS = new Map([ ["channel-import-guardrails.test.ts", 18], - ["directory.registry-backed.contract.test.ts", 12], ["outbound-payload.contract.test.ts", 18], - ["plugin.registry-backed.contract.test.ts", 34], ["plugins-core.catalog.paths.contract.test.ts", 28], ["plugins-core.catalog.entries.contract.test.ts", 16], ["session-binding.registry-backed.contract.test.ts", 16], - ["surfaces-only.registry-backed.contract.test.ts", 36], ]); function resolveContractFileWeight(file) { const name = file.replaceAll("\\", "/").split("/").pop(); + if (name.startsWith("plugin.registry-backed-shard-")) { + return 5; + } + if (name.startsWith("surfaces-only.registry-backed-shard-")) { + return 5; + } + if (name.startsWith("directory.registry-backed-shard-")) { + return 4; + } + if (name.startsWith("threading.registry-backed-shard-")) { + return 4; + } return CONTRACT_FILE_WEIGHTS.get(name) ?? 8; } diff --git a/src/channels/plugins/contracts/directory.registry-backed-shard-a.contract.test.ts b/src/channels/plugins/contracts/directory.registry-backed-shard-a.contract.test.ts new file mode 100644 index 00000000000..18bf28604d0 --- /dev/null +++ b/src/channels/plugins/contracts/directory.registry-backed-shard-a.contract.test.ts @@ -0,0 +1,3 @@ +import { installDirectoryContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installDirectoryContractRegistryShard({ shardIndex: 0, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/directory.registry-backed-shard-b.contract.test.ts b/src/channels/plugins/contracts/directory.registry-backed-shard-b.contract.test.ts new file mode 100644 index 00000000000..575e76d433a --- /dev/null +++ b/src/channels/plugins/contracts/directory.registry-backed-shard-b.contract.test.ts @@ -0,0 +1,3 @@ +import { installDirectoryContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installDirectoryContractRegistryShard({ shardIndex: 1, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/directory.registry-backed-shard-c.contract.test.ts b/src/channels/plugins/contracts/directory.registry-backed-shard-c.contract.test.ts new file mode 100644 index 00000000000..3c715463846 --- /dev/null +++ b/src/channels/plugins/contracts/directory.registry-backed-shard-c.contract.test.ts @@ -0,0 +1,3 @@ +import { installDirectoryContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installDirectoryContractRegistryShard({ shardIndex: 2, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/directory.registry-backed-shard-d.contract.test.ts b/src/channels/plugins/contracts/directory.registry-backed-shard-d.contract.test.ts new file mode 100644 index 00000000000..da83d6e2007 --- /dev/null +++ b/src/channels/plugins/contracts/directory.registry-backed-shard-d.contract.test.ts @@ -0,0 +1,3 @@ +import { installDirectoryContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installDirectoryContractRegistryShard({ shardIndex: 3, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/directory.registry-backed-shard-e.contract.test.ts b/src/channels/plugins/contracts/directory.registry-backed-shard-e.contract.test.ts new file mode 100644 index 00000000000..89c475756b4 --- /dev/null +++ b/src/channels/plugins/contracts/directory.registry-backed-shard-e.contract.test.ts @@ -0,0 +1,3 @@ +import { installDirectoryContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installDirectoryContractRegistryShard({ shardIndex: 4, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/directory.registry-backed-shard-f.contract.test.ts b/src/channels/plugins/contracts/directory.registry-backed-shard-f.contract.test.ts new file mode 100644 index 00000000000..7c1ae4a43bd --- /dev/null +++ b/src/channels/plugins/contracts/directory.registry-backed-shard-f.contract.test.ts @@ -0,0 +1,3 @@ +import { installDirectoryContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installDirectoryContractRegistryShard({ shardIndex: 5, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/directory.registry-backed-shard-g.contract.test.ts b/src/channels/plugins/contracts/directory.registry-backed-shard-g.contract.test.ts new file mode 100644 index 00000000000..eaeb2780d2e --- /dev/null +++ b/src/channels/plugins/contracts/directory.registry-backed-shard-g.contract.test.ts @@ -0,0 +1,3 @@ +import { installDirectoryContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installDirectoryContractRegistryShard({ shardIndex: 6, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/directory.registry-backed-shard-h.contract.test.ts b/src/channels/plugins/contracts/directory.registry-backed-shard-h.contract.test.ts new file mode 100644 index 00000000000..95685ceee1c --- /dev/null +++ b/src/channels/plugins/contracts/directory.registry-backed-shard-h.contract.test.ts @@ -0,0 +1,3 @@ +import { installDirectoryContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installDirectoryContractRegistryShard({ shardIndex: 7, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/directory.registry-backed.contract.test.ts b/src/channels/plugins/contracts/directory.registry-backed.contract.test.ts deleted file mode 100644 index b203dfb1da0..00000000000 --- a/src/channels/plugins/contracts/directory.registry-backed.contract.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { describe } from "vitest"; -import { getDirectoryContractRegistry } from "../../../../test/helpers/channels/surface-contract-registry.js"; -import { installChannelDirectoryContractSuite } from "../../../../test/helpers/channels/threading-directory-contract-suites.js"; - -for (const entry of getDirectoryContractRegistry()) { - describe(`${entry.id} directory contract`, () => { - installChannelDirectoryContractSuite({ - plugin: entry.plugin, - coverage: entry.coverage, - cfg: entry.cfg, - accountId: entry.accountId, - }); - }); -} diff --git a/src/channels/plugins/contracts/plugin.registry-backed-shard-a.contract.test.ts b/src/channels/plugins/contracts/plugin.registry-backed-shard-a.contract.test.ts new file mode 100644 index 00000000000..66798b55eed --- /dev/null +++ b/src/channels/plugins/contracts/plugin.registry-backed-shard-a.contract.test.ts @@ -0,0 +1,3 @@ +import { installPluginContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installPluginContractRegistryShard({ shardIndex: 0, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/plugin.registry-backed-shard-b.contract.test.ts b/src/channels/plugins/contracts/plugin.registry-backed-shard-b.contract.test.ts new file mode 100644 index 00000000000..5869af73677 --- /dev/null +++ b/src/channels/plugins/contracts/plugin.registry-backed-shard-b.contract.test.ts @@ -0,0 +1,3 @@ +import { installPluginContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installPluginContractRegistryShard({ shardIndex: 1, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/plugin.registry-backed-shard-c.contract.test.ts b/src/channels/plugins/contracts/plugin.registry-backed-shard-c.contract.test.ts new file mode 100644 index 00000000000..7db56b0c7c9 --- /dev/null +++ b/src/channels/plugins/contracts/plugin.registry-backed-shard-c.contract.test.ts @@ -0,0 +1,3 @@ +import { installPluginContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installPluginContractRegistryShard({ shardIndex: 2, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/plugin.registry-backed-shard-d.contract.test.ts b/src/channels/plugins/contracts/plugin.registry-backed-shard-d.contract.test.ts new file mode 100644 index 00000000000..ba2466a71ff --- /dev/null +++ b/src/channels/plugins/contracts/plugin.registry-backed-shard-d.contract.test.ts @@ -0,0 +1,3 @@ +import { installPluginContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installPluginContractRegistryShard({ shardIndex: 3, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/plugin.registry-backed-shard-e.contract.test.ts b/src/channels/plugins/contracts/plugin.registry-backed-shard-e.contract.test.ts new file mode 100644 index 00000000000..b1c8efbe8b9 --- /dev/null +++ b/src/channels/plugins/contracts/plugin.registry-backed-shard-e.contract.test.ts @@ -0,0 +1,3 @@ +import { installPluginContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installPluginContractRegistryShard({ shardIndex: 4, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/plugin.registry-backed-shard-f.contract.test.ts b/src/channels/plugins/contracts/plugin.registry-backed-shard-f.contract.test.ts new file mode 100644 index 00000000000..80c26ed8ccf --- /dev/null +++ b/src/channels/plugins/contracts/plugin.registry-backed-shard-f.contract.test.ts @@ -0,0 +1,3 @@ +import { installPluginContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installPluginContractRegistryShard({ shardIndex: 5, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/plugin.registry-backed-shard-g.contract.test.ts b/src/channels/plugins/contracts/plugin.registry-backed-shard-g.contract.test.ts new file mode 100644 index 00000000000..cfd28555252 --- /dev/null +++ b/src/channels/plugins/contracts/plugin.registry-backed-shard-g.contract.test.ts @@ -0,0 +1,3 @@ +import { installPluginContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installPluginContractRegistryShard({ shardIndex: 6, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/plugin.registry-backed-shard-h.contract.test.ts b/src/channels/plugins/contracts/plugin.registry-backed-shard-h.contract.test.ts new file mode 100644 index 00000000000..7ee92b376be --- /dev/null +++ b/src/channels/plugins/contracts/plugin.registry-backed-shard-h.contract.test.ts @@ -0,0 +1,3 @@ +import { installPluginContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installPluginContractRegistryShard({ shardIndex: 7, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/plugin.registry-backed.contract.test.ts b/src/channels/plugins/contracts/plugin.registry-backed.contract.test.ts deleted file mode 100644 index e6602bdabe6..00000000000 --- a/src/channels/plugins/contracts/plugin.registry-backed.contract.test.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { describe } from "vitest"; -import { installChannelPluginContractSuite } from "../../../../test/helpers/channels/registry-contract-suites.js"; -import { getPluginContractRegistry } from "../../../../test/helpers/channels/registry-plugin.js"; - -for (const entry of getPluginContractRegistry()) { - describe(`${entry.id} plugin contract`, () => { - installChannelPluginContractSuite({ - plugin: entry.plugin, - }); - }); -} diff --git a/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-a.contract.test.ts b/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-a.contract.test.ts new file mode 100644 index 00000000000..ca9e1f78d3e --- /dev/null +++ b/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-a.contract.test.ts @@ -0,0 +1,3 @@ +import { installSurfaceContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installSurfaceContractRegistryShard({ shardIndex: 0, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-b.contract.test.ts b/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-b.contract.test.ts new file mode 100644 index 00000000000..d9435795433 --- /dev/null +++ b/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-b.contract.test.ts @@ -0,0 +1,3 @@ +import { installSurfaceContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installSurfaceContractRegistryShard({ shardIndex: 1, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-c.contract.test.ts b/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-c.contract.test.ts new file mode 100644 index 00000000000..bd85f3164b0 --- /dev/null +++ b/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-c.contract.test.ts @@ -0,0 +1,3 @@ +import { installSurfaceContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installSurfaceContractRegistryShard({ shardIndex: 2, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-d.contract.test.ts b/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-d.contract.test.ts new file mode 100644 index 00000000000..c246c3d09d1 --- /dev/null +++ b/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-d.contract.test.ts @@ -0,0 +1,3 @@ +import { installSurfaceContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installSurfaceContractRegistryShard({ shardIndex: 3, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-e.contract.test.ts b/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-e.contract.test.ts new file mode 100644 index 00000000000..66d94dd8c63 --- /dev/null +++ b/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-e.contract.test.ts @@ -0,0 +1,3 @@ +import { installSurfaceContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installSurfaceContractRegistryShard({ shardIndex: 4, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-f.contract.test.ts b/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-f.contract.test.ts new file mode 100644 index 00000000000..b08d8584ad1 --- /dev/null +++ b/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-f.contract.test.ts @@ -0,0 +1,3 @@ +import { installSurfaceContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installSurfaceContractRegistryShard({ shardIndex: 5, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-g.contract.test.ts b/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-g.contract.test.ts new file mode 100644 index 00000000000..1ed4911bac1 --- /dev/null +++ b/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-g.contract.test.ts @@ -0,0 +1,3 @@ +import { installSurfaceContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installSurfaceContractRegistryShard({ shardIndex: 6, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-h.contract.test.ts b/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-h.contract.test.ts new file mode 100644 index 00000000000..6f7b38b42dd --- /dev/null +++ b/src/channels/plugins/contracts/surfaces-only.registry-backed-shard-h.contract.test.ts @@ -0,0 +1,3 @@ +import { installSurfaceContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installSurfaceContractRegistryShard({ shardIndex: 7, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/surfaces-only.registry-backed.contract.test.ts b/src/channels/plugins/contracts/surfaces-only.registry-backed.contract.test.ts deleted file mode 100644 index dc42df3d95b..00000000000 --- a/src/channels/plugins/contracts/surfaces-only.registry-backed.contract.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { describe } from "vitest"; -import { getSurfaceContractRegistry } from "../../../../test/helpers/channels/surface-contract-registry.js"; -import { installChannelSurfaceContractSuite } from "../../../../test/helpers/channels/surface-contract-suite.js"; - -for (const entry of getSurfaceContractRegistry()) { - for (const surface of entry.surfaces) { - describe(`${entry.id} ${surface} surface contract`, () => { - installChannelSurfaceContractSuite({ - plugin: entry.plugin, - surface, - }); - }); - } -} diff --git a/src/channels/plugins/contracts/threading.registry-backed-shard-a.contract.test.ts b/src/channels/plugins/contracts/threading.registry-backed-shard-a.contract.test.ts new file mode 100644 index 00000000000..f1de5ddc67d --- /dev/null +++ b/src/channels/plugins/contracts/threading.registry-backed-shard-a.contract.test.ts @@ -0,0 +1,3 @@ +import { installThreadingContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installThreadingContractRegistryShard({ shardIndex: 0, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/threading.registry-backed-shard-b.contract.test.ts b/src/channels/plugins/contracts/threading.registry-backed-shard-b.contract.test.ts new file mode 100644 index 00000000000..7648c866c8c --- /dev/null +++ b/src/channels/plugins/contracts/threading.registry-backed-shard-b.contract.test.ts @@ -0,0 +1,3 @@ +import { installThreadingContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installThreadingContractRegistryShard({ shardIndex: 1, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/threading.registry-backed-shard-c.contract.test.ts b/src/channels/plugins/contracts/threading.registry-backed-shard-c.contract.test.ts new file mode 100644 index 00000000000..8f63743ade0 --- /dev/null +++ b/src/channels/plugins/contracts/threading.registry-backed-shard-c.contract.test.ts @@ -0,0 +1,3 @@ +import { installThreadingContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installThreadingContractRegistryShard({ shardIndex: 2, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/threading.registry-backed-shard-d.contract.test.ts b/src/channels/plugins/contracts/threading.registry-backed-shard-d.contract.test.ts new file mode 100644 index 00000000000..49307be4df2 --- /dev/null +++ b/src/channels/plugins/contracts/threading.registry-backed-shard-d.contract.test.ts @@ -0,0 +1,3 @@ +import { installThreadingContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installThreadingContractRegistryShard({ shardIndex: 3, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/threading.registry-backed-shard-e.contract.test.ts b/src/channels/plugins/contracts/threading.registry-backed-shard-e.contract.test.ts new file mode 100644 index 00000000000..4fa944a7c9c --- /dev/null +++ b/src/channels/plugins/contracts/threading.registry-backed-shard-e.contract.test.ts @@ -0,0 +1,3 @@ +import { installThreadingContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installThreadingContractRegistryShard({ shardIndex: 4, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/threading.registry-backed-shard-f.contract.test.ts b/src/channels/plugins/contracts/threading.registry-backed-shard-f.contract.test.ts new file mode 100644 index 00000000000..f59b1a0a5fa --- /dev/null +++ b/src/channels/plugins/contracts/threading.registry-backed-shard-f.contract.test.ts @@ -0,0 +1,3 @@ +import { installThreadingContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installThreadingContractRegistryShard({ shardIndex: 5, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/threading.registry-backed-shard-g.contract.test.ts b/src/channels/plugins/contracts/threading.registry-backed-shard-g.contract.test.ts new file mode 100644 index 00000000000..8288ac3fe0b --- /dev/null +++ b/src/channels/plugins/contracts/threading.registry-backed-shard-g.contract.test.ts @@ -0,0 +1,3 @@ +import { installThreadingContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installThreadingContractRegistryShard({ shardIndex: 6, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/threading.registry-backed-shard-h.contract.test.ts b/src/channels/plugins/contracts/threading.registry-backed-shard-h.contract.test.ts new file mode 100644 index 00000000000..e3f14c87085 --- /dev/null +++ b/src/channels/plugins/contracts/threading.registry-backed-shard-h.contract.test.ts @@ -0,0 +1,3 @@ +import { installThreadingContractRegistryShard } from "../../../../test/helpers/channels/registry-backed-contract-shards.js"; + +installThreadingContractRegistryShard({ shardIndex: 7, shardCount: 8 }); diff --git a/src/channels/plugins/contracts/threading.registry-backed.contract.test.ts b/src/channels/plugins/contracts/threading.registry-backed.contract.test.ts deleted file mode 100644 index 8dbf89f3d75..00000000000 --- a/src/channels/plugins/contracts/threading.registry-backed.contract.test.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { describe } from "vitest"; -import { getThreadingContractRegistry } from "../../../../test/helpers/channels/surface-contract-registry.js"; -import { installChannelThreadingContractSuite } from "../../../../test/helpers/channels/threading-directory-contract-suites.js"; - -for (const entry of getThreadingContractRegistry()) { - describe(`${entry.id} threading contract`, () => { - installChannelThreadingContractSuite({ - plugin: entry.plugin, - }); - }); -} diff --git a/test/helpers/channels/registry-backed-contract-shards.ts b/test/helpers/channels/registry-backed-contract-shards.ts new file mode 100644 index 00000000000..29179047702 --- /dev/null +++ b/test/helpers/channels/registry-backed-contract-shards.ts @@ -0,0 +1,92 @@ +import { describe, it } from "vitest"; +import { installChannelPluginContractSuite } from "./registry-contract-suites.js"; +import { getPluginContractRegistryShard } from "./registry-plugin.js"; +import { + getDirectoryContractRegistryShard, + getSurfaceContractRegistryShard, + getThreadingContractRegistryShard, +} from "./surface-contract-registry.js"; +import { installChannelSurfaceContractSuite } from "./surface-contract-suite.js"; +import { + installChannelDirectoryContractSuite, + installChannelThreadingContractSuite, +} from "./threading-directory-contract-suites.js"; + +type ContractShardParams = { + shardIndex: number; + shardCount: number; +}; + +function installEmptyShardSuite(label: string) { + describe(label, () => { + it("has no matching bundled channels", () => { + // Keeps intentionally empty id-based shards visible to Vitest. + }); + }); +} + +export function installSurfaceContractRegistryShard(params: ContractShardParams) { + const entries = getSurfaceContractRegistryShard(params); + if (entries.length === 0) { + installEmptyShardSuite("surface contract registry shard"); + return; + } + for (const entry of entries) { + for (const surface of entry.surfaces) { + describe(`${entry.id} ${surface} surface contract`, () => { + installChannelSurfaceContractSuite({ + plugin: entry.plugin, + surface, + }); + }); + } + } +} + +export function installDirectoryContractRegistryShard(params: ContractShardParams) { + const entries = getDirectoryContractRegistryShard(params); + if (entries.length === 0) { + installEmptyShardSuite("directory contract registry shard"); + return; + } + for (const entry of entries) { + describe(`${entry.id} directory contract`, () => { + installChannelDirectoryContractSuite({ + plugin: entry.plugin, + coverage: entry.coverage, + cfg: entry.cfg, + accountId: entry.accountId, + }); + }); + } +} + +export function installThreadingContractRegistryShard(params: ContractShardParams) { + const entries = getThreadingContractRegistryShard(params); + if (entries.length === 0) { + installEmptyShardSuite("threading contract registry shard"); + return; + } + for (const entry of entries) { + describe(`${entry.id} threading contract`, () => { + installChannelThreadingContractSuite({ + plugin: entry.plugin, + }); + }); + } +} + +export function installPluginContractRegistryShard(params: ContractShardParams) { + const entries = getPluginContractRegistryShard(params); + if (entries.length === 0) { + installEmptyShardSuite("plugin contract registry shard"); + return; + } + for (const entry of entries) { + describe(`${entry.id} plugin contract`, () => { + installChannelPluginContractSuite({ + plugin: entry.plugin, + }); + }); + } +} diff --git a/test/helpers/channels/registry-plugin.ts b/test/helpers/channels/registry-plugin.ts index f4b02e78001..6c6edc7b4b5 100644 --- a/test/helpers/channels/registry-plugin.ts +++ b/test/helpers/channels/registry-plugin.ts @@ -1,4 +1,9 @@ -import { listBundledChannelPlugins } from "../../../src/channels/plugins/bundled.js"; +import { + getBundledChannelPlugin, + listBundledChannelPluginIds, + listBundledChannelPlugins, +} from "../../../src/channels/plugins/bundled.js"; +import type { ChannelId } from "../../../src/channels/plugins/channel-id.types.js"; import { normalizeChannelMeta } from "../../../src/channels/plugins/meta-normalization.js"; import type { ChannelPlugin } from "../../../src/channels/plugins/types.js"; @@ -7,12 +12,35 @@ type PluginContractEntry = { plugin: Pick; }; -export function getPluginContractRegistry(): PluginContractEntry[] { - return listBundledChannelPlugins().map((plugin) => ({ +function toPluginContractEntry(plugin: ChannelPlugin): PluginContractEntry { + return { id: plugin.id, plugin: { ...plugin, meta: normalizeChannelMeta({ id: plugin.id, meta: plugin.meta }), }, - })); + }; +} + +function getBundledChannelPluginIdsForShard(params: { + shardIndex: number; + shardCount: number; +}): readonly ChannelId[] { + return listBundledChannelPluginIds().filter( + (_id, index) => index % params.shardCount === params.shardIndex, + ); +} + +export function getPluginContractRegistry(): PluginContractEntry[] { + return listBundledChannelPlugins().map(toPluginContractEntry); +} + +export function getPluginContractRegistryShard(params: { + shardIndex: number; + shardCount: number; +}): PluginContractEntry[] { + return getBundledChannelPluginIdsForShard(params).flatMap((id) => { + const plugin = getBundledChannelPlugin(id); + return plugin ? [toPluginContractEntry(plugin)] : []; + }); } diff --git a/test/helpers/channels/surface-contract-registry.ts b/test/helpers/channels/surface-contract-registry.ts index b1a00cdb404..a6f8c02e1d4 100644 --- a/test/helpers/channels/surface-contract-registry.ts +++ b/test/helpers/channels/surface-contract-registry.ts @@ -1,7 +1,10 @@ import { + getBundledChannelPlugin, + listBundledChannelPluginIds, listBundledChannelPlugins, setBundledChannelRuntime, } from "../../../src/channels/plugins/bundled.js"; +import type { ChannelId } from "../../../src/channels/plugins/channel-id.types.js"; import type { ChannelPlugin } from "../../../src/channels/plugins/types.js"; import type { OpenClawConfig } from "../../../src/config/config.js"; import { @@ -53,18 +56,52 @@ setBundledChannelRuntime("line", { } as never); let surfaceContractRegistryCache: SurfaceContractEntry[] | undefined; +const surfaceContractEntryCache = new Map(); let threadingContractRegistryCache: ThreadingContractEntry[] | undefined; let directoryContractRegistryCache: DirectoryContractEntry[] | undefined; -export function getSurfaceContractRegistry(): SurfaceContractEntry[] { - surfaceContractRegistryCache ??= listBundledChannelPlugins().map((plugin) => ({ +function toSurfaceContractEntry(plugin: ChannelPlugin): SurfaceContractEntry { + return { id: plugin.id, plugin, surfaces: channelPluginSurfaceKeys.filter((surface) => Boolean(plugin[surface])), - })); + }; +} + +function getBundledChannelPluginIdsForShard(params: { + shardIndex: number; + shardCount: number; +}): readonly ChannelId[] { + return listBundledChannelPluginIds().filter( + (_id, index) => index % params.shardCount === params.shardIndex, + ); +} + +function getSurfaceContractEntry(id: ChannelId): SurfaceContractEntry | undefined { + if (surfaceContractEntryCache.has(id)) { + return surfaceContractEntryCache.get(id) ?? undefined; + } + const plugin = getBundledChannelPlugin(id); + const entry = plugin ? toSurfaceContractEntry(plugin) : null; + surfaceContractEntryCache.set(id, entry); + return entry ?? undefined; +} + +export function getSurfaceContractRegistry(): SurfaceContractEntry[] { + surfaceContractRegistryCache ??= listBundledChannelPlugins().map(toSurfaceContractEntry); return surfaceContractRegistryCache; } +export function getSurfaceContractRegistryShard(params: { + shardIndex: number; + shardCount: number; +}): SurfaceContractEntry[] { + return getBundledChannelPluginIdsForShard(params).flatMap((id) => { + const entry = getSurfaceContractEntry(id); + return entry ? [entry] : []; + }); +} + export function getThreadingContractRegistry(): ThreadingContractEntry[] { threadingContractRegistryCache ??= getSurfaceContractRegistry() .filter((entry) => entry.surfaces.includes("threading")) @@ -75,6 +112,18 @@ export function getThreadingContractRegistry(): ThreadingContractEntry[] { return threadingContractRegistryCache; } +export function getThreadingContractRegistryShard(params: { + shardIndex: number; + shardCount: number; +}): ThreadingContractEntry[] { + return getSurfaceContractRegistryShard(params) + .filter((entry) => entry.surfaces.includes("threading")) + .map((entry) => ({ + id: entry.id, + plugin: entry.plugin, + })); +} + const directoryPresenceOnlyIds = new Set(["whatsapp", "zalouser"]); export function getDirectoryContractRegistry(): DirectoryContractEntry[] { @@ -87,3 +136,16 @@ export function getDirectoryContractRegistry(): DirectoryContractEntry[] { })); return directoryContractRegistryCache; } + +export function getDirectoryContractRegistryShard(params: { + shardIndex: number; + shardCount: number; +}): DirectoryContractEntry[] { + return getSurfaceContractRegistryShard(params) + .filter((entry) => entry.surfaces.includes("directory")) + .map((entry) => ({ + id: entry.id, + plugin: entry.plugin, + coverage: directoryPresenceOnlyIds.has(entry.id) ? "presence" : "lookups", + })); +}