@@ -2,7 +2,7 @@
|
2 | 2 | import { chmodSync, existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs"; |
3 | 3 | import { tmpdir } from "node:os"; |
4 | 4 | import path from "node:path"; |
5 | | -import { afterEach, describe, expect, it } from "vitest"; |
| 5 | +import { afterEach, describe, expect, it, vi } from "vitest"; |
6 | 6 | import { runWindowsBackgroundPowerShell } from "../../scripts/e2e/parallels/guest-transports.ts"; |
7 | 7 | import { run as hostCommandRun } from "../../scripts/e2e/parallels/host-command.ts"; |
8 | 8 | import { |
@@ -65,6 +65,7 @@ function decodePowerShellFromArgs(args: string[]): string {
|
65 | 65 | } |
66 | 66 | |
67 | 67 | afterEach(() => { |
| 68 | +vi.useRealTimers(); |
68 | 69 | for (const dir of tempDirs.splice(0)) { |
69 | 70 | rmSync(dir, { force: true, recursive: true }); |
70 | 71 | } |
@@ -374,6 +375,41 @@ exit 1
|
374 | 375 | await waitForDead(descendantPid, 2000); |
375 | 376 | }); |
376 | 377 | |
| 378 | +it("clears update stream timers when spawning the guest command fails", async () => { |
| 379 | +vi.useFakeTimers(); |
| 380 | +const smoke = withEnv( |
| 381 | +{ OPENAI_API_KEY: "test-key" }, |
| 382 | +() => |
| 383 | +new NpmUpdateSmoke({ |
| 384 | + ...TEST_AUTH, |
| 385 | +json: false, |
| 386 | +packageSpec: "openclaw@latest", |
| 387 | +platforms: new Set<Platform>(["linux"]), |
| 388 | +provider: "openai", |
| 389 | +updateTarget: "local-main", |
| 390 | +}), |
| 391 | +); |
| 392 | +const runStreamingToJobLog = Reflect.get(smoke, "runStreamingToJobLog") as ( |
| 393 | +command: string, |
| 394 | +args: string[], |
| 395 | +timeoutMs: number, |
| 396 | +ctx: { |
| 397 | +append(chunk: string | Uint8Array): void; |
| 398 | +logPath: string; |
| 399 | +signal: AbortSignal; |
| 400 | +}, |
| 401 | +) => Promise<number>; |
| 402 | + |
| 403 | +await expect( |
| 404 | +runStreamingToJobLog.call(smoke, "openclaw-definitely-missing-command", [], 60 * 60 * 1000, { |
| 405 | +append: () => undefined, |
| 406 | +logPath: "", |
| 407 | +signal: new AbortController().signal, |
| 408 | +}), |
| 409 | +).rejects.toMatchObject({ code: "ENOENT" }); |
| 410 | +expect(vi.getTimerCount()).toBe(0); |
| 411 | +}); |
| 412 | + |
377 | 413 | it("runs Windows updates through a detached done-file runner", () => { |
378 | 414 | const script = readFileSync(SCRIPT_PATH, "utf8"); |
379 | 415 | const transports = readFileSync(GUEST_TRANSPORTS_PATH, "utf8"); |
|