426e9eeabd
Voice Workbench / headless workbench (mocked backends) (push) Has been cancelled
Voice Workbench / real acoustic lane (nightly, provisioned only) (push) Has been cancelled
ci / test (push) Has been cancelled
ci / lint-and-format (push) Has been cancelled
ci / build (push) Has been cancelled
ci / dev-startup (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
Markdown Links / Relative Markdown Links (push) Has been cancelled
Quality (Extended) / Homepage Build (PR smoke) (push) Has been cancelled
Quality (Extended) / Comment-only diff guard (push) Has been cancelled
Quality (Extended) / Format + Type Safety Ratchet (push) Has been cancelled
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Has been cancelled
Quality (Extended) / Develop Gate (lint) (push) Has been cancelled
Chat shell gestures / Chat shell gesture + parity e2e (push) Has been cancelled
Cloud Gateway Discord / Test (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx @biomejs/biome check packages/lifeops-bench/src, benchmark-lint) (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx vitest run --config packages/lifeops-bench/vitest.config.ts --root packages/lifeops-bench --passWithNoTests, benchmark-tests) (push) Has been cancelled
Build Agent Image / build-and-push (push) Has been cancelled
Dev Smoke / bun run dev onboarding chat (push) Has been cancelled
Dev Smoke / Vite HMR dependency-level smoke (push) Has been cancelled
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Has been cancelled
Publish @elizaos/example-code / check_npm (push) Has been cancelled
Publish @elizaos/example-code / publish_npm (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / verify_version (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / publish_npm (push) Has been cancelled
Sandbox Live Smoke / Sandbox live smoke (push) Has been cancelled
Snap Build & Test / Build Snap (amd64) (push) Has been cancelled
Snap Build & Test / Build Snap (arm64) (push) Has been cancelled
Test Packaging / elizaos CLI global-install smoke (node + bun) (push) Has been cancelled
Cloud Gateway Webhook / Test (push) Has been cancelled
Cloud Tests / lint-and-types (push) Has been cancelled
Cloud Tests / unit-tests (push) Has been cancelled
Cloud Tests / integration-tests (push) Has been cancelled
Cloud Tests / e2e-tests (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Apps Worker (Product 2) / Determine environment (push) Has been cancelled
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Has been cancelled
Deploy Eliza Provisioning Worker / Determine environment (push) Has been cancelled
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Has been cancelled
Dev Smoke / Classify changed paths (push) Has been cancelled
supply-chain / sbom (push) Has been cancelled
supply-chain / vulnerability-scan (push) Has been cancelled
Build, Push & Deploy to Phala Cloud / build-and-push (push) Has been cancelled
Test Packaging / Validate Packaging Configs (push) Has been cancelled
Test Packaging / Build & Test PyPI Package (push) Has been cancelled
Test Packaging / PyPI on Python ${{ matrix.python }} (push) Has been cancelled
Test Packaging / Pack & Test JS Tarballs (push) Has been cancelled
UI Fixture E2E / ui-fixture-e2e (push) Has been cancelled
UI Fixture E2E / fixture-e2e (push) Has been cancelled
UI Story Gate / story-gate (push) Has been cancelled
vault-ci / test (macos-latest) (push) Has been cancelled
vault-ci / test (ubuntu-latest) (push) Has been cancelled
vault-ci / test (windows-latest) (push) Has been cancelled
vault-ci / app-core wiring tests (push) Has been cancelled
verify-patches / verify patches/CHECKSUMS.sha256 (push) Has been cancelled
Voice Benchmark Smoke / voice-emotion fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voiceagentbench fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench-quality unit smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench TypeScript unit (no audio) (push) Has been cancelled
Voice Benchmark Smoke / voice bench smoke summary (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd packages/security test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Has been cancelled
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=4 node packages/scripts/run-bash-linux-only.mjs scripts/verify-riscv64-buildpaths.sh node packages/scripts/run… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run typecheck --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/cloud-shared --concurrency=4 bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Has been cancelled
261 lines
8.3 KiB
JavaScript
261 lines
8.3 KiB
JavaScript
/**
|
|
* Exercises the pure batch-orchestration helpers in test-cloud-run.mjs
|
|
* (walkTests, chunkByBudget, formatBatchFiles, writeSyncAll) directly, without
|
|
* driving the side-effecting `main()` (which shells out to `bun test`). Those
|
|
* side effects are covered end-to-end by the `test:cloud` CI lane instead.
|
|
*/
|
|
import { describe, expect, it } from "bun:test";
|
|
import {
|
|
mkdirSync,
|
|
mkdtempSync,
|
|
openSync,
|
|
readSync,
|
|
rmSync,
|
|
writeFileSync,
|
|
} from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
import {
|
|
buildTestEnv,
|
|
chunkByBudget,
|
|
computeTestRoots,
|
|
EXCLUDED_DIRS,
|
|
findMissingRoots,
|
|
formatBatchFiles,
|
|
runBatches,
|
|
walkTests,
|
|
writeSyncAll,
|
|
} from "../test-cloud-run.mjs";
|
|
|
|
describe("walkTests", () => {
|
|
it("finds .test. and .spec. files recursively and skips excluded dirs", () => {
|
|
const root = mkdtempSync(join(tmpdir(), "test-cloud-run-walk-"));
|
|
try {
|
|
writeFileSync(join(root, "a.test.ts"), "");
|
|
writeFileSync(join(root, "b.spec.tsx"), "");
|
|
writeFileSync(join(root, "c.ts"), ""); // not a test file, must be skipped
|
|
mkdirSync(join(root, "nested"));
|
|
writeFileSync(join(root, "nested", "d.test.ts"), "");
|
|
mkdirSync(join(root, "node_modules", "pkg"), { recursive: true });
|
|
writeFileSync(join(root, "node_modules", "pkg", "e.test.ts"), "");
|
|
|
|
const found = walkTests(root, EXCLUDED_DIRS).sort();
|
|
|
|
expect(found).toEqual(
|
|
[
|
|
join(root, "a.test.ts"),
|
|
join(root, "b.spec.tsx"),
|
|
join(root, "nested", "d.test.ts"),
|
|
].sort(),
|
|
);
|
|
} finally {
|
|
rmSync(root, { recursive: true, force: true });
|
|
}
|
|
});
|
|
});
|
|
|
|
describe("chunkByBudget", () => {
|
|
it("closes a batch once the file-count limit is hit", () => {
|
|
const files = ["a", "b", "c", "d", "e"];
|
|
const batches = chunkByBudget(files, 2, 100000);
|
|
expect(batches).toEqual([["a", "b"], ["c", "d"], ["e"]]);
|
|
});
|
|
|
|
it("closes a batch once the char budget is hit", () => {
|
|
// Each entry costs length+1; budget 5 fits "aa"(3) then closes before "bb".
|
|
const files = ["aa", "bb", "cc"];
|
|
const batches = chunkByBudget(files, 80, 5);
|
|
expect(batches).toEqual([["aa"], ["bb"], ["cc"]]);
|
|
});
|
|
|
|
it("returns a single batch when nothing exceeds the budget", () => {
|
|
const files = ["x", "y", "z"];
|
|
const batches = chunkByBudget(files, 80, 100000);
|
|
expect(batches).toEqual([["x", "y", "z"]]);
|
|
});
|
|
|
|
it("returns no batches for an empty file list", () => {
|
|
expect(chunkByBudget([], 80, 100000)).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe("formatBatchFiles", () => {
|
|
it("renders each file as a repo-relative bullet", () => {
|
|
const root = "/repo";
|
|
const batch = ["/repo/packages/a/x.test.ts", "/repo/packages/b/y.spec.ts"];
|
|
expect(formatBatchFiles(batch, root)).toBe(
|
|
" - packages/a/x.test.ts\n - packages/b/y.spec.ts",
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("writeSyncAll", () => {
|
|
it("writes the full payload to the given fd even across multiple internal writes", () => {
|
|
const dir = mkdtempSync(join(tmpdir(), "test-cloud-run-write-"));
|
|
const file = join(dir, "out.txt");
|
|
try {
|
|
const fd = openSync(file, "w");
|
|
const payload = "x".repeat(200_000); // large enough to require several writeSync calls
|
|
writeSyncAll(fd, payload);
|
|
|
|
const buffer = Buffer.alloc(payload.length);
|
|
const readFd = openSync(file, "r");
|
|
let readTotal = 0;
|
|
while (readTotal < buffer.length) {
|
|
const n = readSync(
|
|
readFd,
|
|
buffer,
|
|
readTotal,
|
|
buffer.length - readTotal,
|
|
readTotal,
|
|
);
|
|
if (n === 0) break;
|
|
readTotal += n;
|
|
}
|
|
expect(readTotal).toBe(payload.length);
|
|
expect(buffer.toString("utf8")).toBe(payload);
|
|
} finally {
|
|
rmSync(dir, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
it("is a no-op for empty input", () => {
|
|
const dir = mkdtempSync(join(tmpdir(), "test-cloud-run-write-empty-"));
|
|
const file = join(dir, "out.txt");
|
|
try {
|
|
const fd = openSync(file, "w");
|
|
writeSyncAll(fd, "");
|
|
writeSyncAll(fd, undefined);
|
|
expect(() => writeSyncAll(fd, "")).not.toThrow();
|
|
} finally {
|
|
rmSync(dir, { recursive: true, force: true });
|
|
}
|
|
});
|
|
});
|
|
|
|
describe("buildTestEnv", () => {
|
|
it("pins the unit lane to in-process PGlite and skips the DB/server checks", () => {
|
|
const env = buildTestEnv({
|
|
PATH: "/usr/bin",
|
|
DATABASE_URL: "postgresql://real-db",
|
|
});
|
|
expect(env.PATH).toBe("/usr/bin"); // preserves the base env
|
|
expect(env.DATABASE_URL).toBe("pglite://memory"); // overrides any ambient real DB URL
|
|
expect(env.TEST_DATABASE_URL).toBe("pglite://memory");
|
|
expect(env.SKIP_DB_DEPENDENT).toBe("1");
|
|
expect(env.SKIP_SERVER_CHECK).toBe("true");
|
|
});
|
|
});
|
|
|
|
describe("computeTestRoots", () => {
|
|
it("derives every test root from the repo root", () => {
|
|
const roots = computeTestRoots("/repo");
|
|
expect(roots).toEqual({
|
|
cloudSharedSrc: join("/repo", "packages", "cloud", "shared", "src"),
|
|
cloudApiRoot: join("/repo", "packages", "cloud", "api"),
|
|
cloudScriptsTests: join("/repo", "packages", "scripts", "cloud"),
|
|
cloudRoutingTests: join("/repo", "packages", "cloud", "routing", "src"),
|
|
cloudInfraTests: join("/repo", "packages", "cloud", "infra", "tests"),
|
|
cloudServicesRoot: join("/repo", "packages", "cloud", "services"),
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("findMissingRoots", () => {
|
|
it("reports only the roots the injected existsFn says are absent", () => {
|
|
const roots = { a: "/repo/a", b: "/repo/b", c: "/repo/c" };
|
|
const missing = findMissingRoots(roots, (dir) => dir !== "/repo/b");
|
|
expect(missing).toEqual(["b -> /repo/b"]);
|
|
});
|
|
|
|
it("returns an empty list when every root exists", () => {
|
|
const roots = { a: "/repo/a" };
|
|
expect(findMissingRoots(roots, () => true)).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe("runBatches", () => {
|
|
function collector() {
|
|
const lines = [];
|
|
return { lines, write: (text) => lines.push(text) };
|
|
}
|
|
|
|
it("returns false and keeps going when every batch passes", () => {
|
|
const out = collector();
|
|
const err = collector();
|
|
const calls = [];
|
|
const anyFailed = runBatches([["a.test.ts"], ["b.test.ts"]], {
|
|
spawnBatch: (batch) => {
|
|
calls.push(batch);
|
|
return { status: 0, signal: null, stdout: "ok\n", stderr: "" };
|
|
},
|
|
stagingDir: "/staging",
|
|
env: {},
|
|
repoRoot: "/repo",
|
|
writeOut: out.write,
|
|
writeErr: err.write,
|
|
});
|
|
expect(anyFailed).toBe(false);
|
|
expect(calls).toEqual([["a.test.ts"], ["b.test.ts"]]);
|
|
expect(out.lines.join("")).toContain("batch 1/2");
|
|
expect(out.lines.join("")).toContain("ok\n");
|
|
});
|
|
|
|
it("marks the gate failed and reports the offending files on a real failure", () => {
|
|
const out = collector();
|
|
const err = collector();
|
|
const anyFailed = runBatches([["/repo/packages/x/a.test.ts"]], {
|
|
spawnBatch: () => ({
|
|
status: 1,
|
|
signal: null,
|
|
stdout: "1 fail\n",
|
|
stderr: "(fail) something broke\n",
|
|
}),
|
|
stagingDir: "/staging",
|
|
env: {},
|
|
repoRoot: "/repo",
|
|
writeOut: out.write,
|
|
writeErr: err.write,
|
|
});
|
|
expect(anyFailed).toBe(true);
|
|
expect(err.lines.join("")).toContain("exited non-zero");
|
|
expect(err.lines.join("")).toContain("packages/x/a.test.ts");
|
|
});
|
|
|
|
it("normalizes the known Bun/PGlite status-99 pollution as a pass", () => {
|
|
const out = collector();
|
|
const err = collector();
|
|
const anyFailed = runBatches([["a.test.ts"]], {
|
|
spawnBatch: () => ({
|
|
status: 99,
|
|
signal: null,
|
|
stdout: "Ran 3 tests across 1 file.\n",
|
|
stderr: "",
|
|
}),
|
|
stagingDir: "/staging",
|
|
env: {},
|
|
repoRoot: "/repo",
|
|
writeOut: out.write,
|
|
writeErr: err.write,
|
|
});
|
|
expect(anyFailed).toBe(false);
|
|
expect(err.lines.join("")).toContain("treating as pass");
|
|
});
|
|
|
|
it("stops immediately and reports a spawn error", () => {
|
|
const out = collector();
|
|
const err = collector();
|
|
const anyFailed = runBatches([["a.test.ts"], ["b.test.ts"]], {
|
|
spawnBatch: () => ({ error: new Error("spawn bun ENOENT") }),
|
|
stagingDir: "/staging",
|
|
env: {},
|
|
repoRoot: "/repo",
|
|
writeOut: out.write,
|
|
writeErr: err.write,
|
|
});
|
|
expect(anyFailed).toBe(true);
|
|
expect(err.lines.join("")).toContain("spawn error");
|
|
expect(err.lines.join("")).toContain("ENOENT");
|
|
});
|
|
});
|