From 91c5c99dbe656496a96bc560e5b25e14debe882a Mon Sep 17 00:00:00 2001 From: wan9chi Date: Mon, 12 Oct 2026 15:05:51 +0800 Subject: [PATCH 1/2] test(cache): run the remote cache e2e tests on Windows They were skipped on Windows because the e2e harness couldn't launch `remote-cache-server`, a pnpm command shim. The harness now resolves `.cmd` shims and starts them outside the verbatim temp path. Co-Authored-By: Claude Opus 5.5 --- .../fixtures/remote_cache/snapshots.toml | 16 ++-------------- .../fixtures/remote_cache_backend/snapshots.toml | 6 ------ 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/crates/vt_bin/tests/e2e_snapshots/fixtures/remote_cache/snapshots.toml b/crates/vt_bin/tests/e2e_snapshots/fixtures/remote_cache/snapshots.toml index 0647a836e..36e8c5f5f 100644 --- a/crates/vt_bin/tests/e2e_snapshots/fixtures/remote_cache/snapshots.toml +++ b/crates/vt_bin/tests/e2e_snapshots/fixtures/remote_cache/snapshots.toml @@ -1,12 +1,10 @@ # Cases that use the remote cache backend are ignored because it runs on -# Node.js. Windows is skipped because the PTY launcher cannot execute pnpm -# command shims. Whether an upload to the backend is still running when the -# tasks finish depends on timing, so steps that upload hide the message about +# Node.js. Whether an upload to the backend is still running when the tasks +# finish depends on timing, so steps that upload hide the message about # pending uploads. The cases that test it stall the uploads instead, with # stalled-remote-cache in front of the backend. [[e2e]] name = "read_write" -cfg = "not(windows)" ignore = true steps = [ { argv = [ @@ -39,7 +37,6 @@ steps = [ [[e2e]] name = "read" -cfg = "not(windows)" ignore = true steps = [ { argv = [ @@ -73,7 +70,6 @@ steps = [ [[e2e]] name = "restore" -cfg = "not(windows)" ignore = true steps = [ { argv = [ @@ -145,7 +141,6 @@ steps = [ [[e2e]] name = "local_and_remote_hits" -cfg = "not(windows)" ignore = true steps = [ { argv = [ @@ -188,7 +183,6 @@ steps = [ [[e2e]] name = "fallback" -cfg = "not(windows)" ignore = true steps = [ { argv = [ @@ -228,7 +222,6 @@ steps = [ [[e2e]] name = "corrupt_archive" -cfg = "not(windows)" ignore = true steps = [ { argv = [ @@ -280,7 +273,6 @@ steps = [ [[e2e]] name = "restore_failure" -cfg = "not(windows)" ignore = true steps = [ { argv = [ @@ -349,7 +341,6 @@ steps = [ [[e2e]] name = "pending_uploads" -cfg = "not(windows)" ignore = true steps = [ { argv = [ @@ -562,7 +553,6 @@ steps = [ [[e2e]] name = "ctrl_c_during_upload" -cfg = "not(windows)" ignore = true steps = [ { argv = [ @@ -597,7 +587,6 @@ steps = [ [[e2e]] name = "fast_fail_during_upload" -cfg = "not(windows)" ignore = true steps = [ { argv = [ @@ -622,7 +611,6 @@ steps = [ [[e2e]] name = "hide_pending_uploads" -cfg = "not(windows)" ignore = true steps = [ { argv = [ diff --git a/crates/vt_bin/tests/e2e_snapshots/fixtures/remote_cache_backend/snapshots.toml b/crates/vt_bin/tests/e2e_snapshots/fixtures/remote_cache_backend/snapshots.toml index 7fbf89fcc..2f276a52c 100644 --- a/crates/vt_bin/tests/e2e_snapshots/fixtures/remote_cache_backend/snapshots.toml +++ b/crates/vt_bin/tests/e2e_snapshots/fixtures/remote_cache_backend/snapshots.toml @@ -1,7 +1,5 @@ -# Windows is skipped because the PTY launcher cannot execute pnpm command shims. [[e2e]] name = "entries_and_associations" -cfg = "not(windows)" ignore = true steps = [ [ @@ -96,7 +94,6 @@ steps = [ [[e2e]] name = "blob_replacement" -cfg = "not(windows)" ignore = true steps = [ [ @@ -209,7 +206,6 @@ steps = [ [[e2e]] name = "opaque_binary_data" -cfg = "not(windows)" ignore = true steps = [ [ @@ -264,7 +260,6 @@ steps = [ [[e2e]] name = "invalid_requests" -cfg = "not(windows)" ignore = true steps = [ [ @@ -433,7 +428,6 @@ steps = [ [[e2e]] name = "state_across_invocations" -cfg = "not(windows)" ignore = true steps = [ [ From 81bb81ff4455948c78416e0232844f12b4c800e6 Mon Sep 17 00:00:00 2001 From: wan9chi Date: Mon, 12 Oct 2026 15:16:08 +0800 Subject: [PATCH 2/2] test(cache): spawn the remote cache server's command with cross-spawn On Windows, Node's `spawn` can't run pnpm's `.cmd` shims, so `remote-cache-server cbor-http ...` failed with `spawn cbor-http ENOENT`. cross-spawn runs them with the arguments escaped for `cmd.exe`. `pending_uploads` and `hide_pending_uploads` stay skipped on Windows for another reason: a milestone there is the console title, which ConPTY sends only as the latest title when it next renders, so `uploads-pending` can be replaced by the proxy's `stalled` milestone or not sent at all. Co-Authored-By: Claude Opus 5.5 --- .../fixtures/remote_cache/snapshots.toml | 7 +++++++ packages/tools/package.json | 2 ++ packages/tools/src/remote-cache/cli.ts | 3 ++- pnpm-lock.yaml | 19 +++++++++++++++++++ pnpm-workspace.yaml | 2 ++ 5 files changed, 32 insertions(+), 1 deletion(-) diff --git a/crates/vt_bin/tests/e2e_snapshots/fixtures/remote_cache/snapshots.toml b/crates/vt_bin/tests/e2e_snapshots/fixtures/remote_cache/snapshots.toml index 36e8c5f5f..74f5130f2 100644 --- a/crates/vt_bin/tests/e2e_snapshots/fixtures/remote_cache/snapshots.toml +++ b/crates/vt_bin/tests/e2e_snapshots/fixtures/remote_cache/snapshots.toml @@ -341,6 +341,10 @@ steps = [ [[e2e]] name = "pending_uploads" +# Skipped on Windows, where a milestone is the console title and ConPTY sends +# only the latest one when it next renders: the proxy's `stalled` milestone for +# check's upload can replace `uploads-pending`. +cfg = "not(windows)" ignore = true steps = [ { argv = [ @@ -611,6 +615,9 @@ steps = [ [[e2e]] name = "hide_pending_uploads" +# Skipped on Windows, where a milestone is the console title and ConPTY sends +# it only when it next renders: nothing is printed after `uploads-pending`. +cfg = "not(windows)" ignore = true steps = [ { argv = [ diff --git a/packages/tools/package.json b/packages/tools/package.json index c14f1d66b..851acbfee 100644 --- a/packages/tools/package.json +++ b/packages/tools/package.json @@ -21,6 +21,7 @@ "cbor-edn": "catalog:", "cbor2": "catalog:", "cross-env": "catalog:", + "cross-spawn": "catalog:", "deno": "catalog:", "oxfmt": "catalog:", "oxlint": "catalog:", @@ -33,6 +34,7 @@ "vitest": "catalog:" }, "devDependencies": { + "@types/cross-spawn": "catalog:", "vite-task-tools": "workspace:*" } } diff --git a/packages/tools/src/remote-cache/cli.ts b/packages/tools/src/remote-cache/cli.ts index 82b00339a..c13273059 100755 --- a/packages/tools/src/remote-cache/cli.ts +++ b/packages/tools/src/remote-cache/cli.ts @@ -1,7 +1,7 @@ #!/usr/bin/env node -import { spawn } from 'node:child_process'; import { once } from 'node:events'; import type { AddressInfo } from 'node:net'; +import spawn from 'cross-spawn'; import { createCacheServer } from './server.ts'; const basePath = '/projects/test'; @@ -18,6 +18,7 @@ await once(server, 'listening'); const { port } = server.address() as AddressInfo; // Ctrl-C is left to the command. process.on('SIGINT', () => {}); +// cross-spawn runs pnpm's `.cmd` shims, such as `cbor-http`, on Windows. const child = spawn(command!, args, { stdio: 'inherit', env: { ...process.env, VP_REMOTE_CACHE_URL: `http://127.0.0.1:${port}${basePath}` }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index af708038a..c40154c56 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -21,6 +21,9 @@ catalogs: '@tsconfig/strictest': specifier: ^2.0.8 version: 2.0.8 + '@types/cross-spawn': + specifier: 6.0.6 + version: 6.0.6 '@types/node': specifier: 25.0.3 version: 25.0.3 @@ -39,6 +42,9 @@ catalogs: cross-env: specifier: ^10.1.0 version: 10.1.0 + cross-spawn: + specifier: 7.0.6 + version: 7.0.6 deno: specifier: 2.9.6 version: 2.9.6 @@ -124,6 +130,9 @@ importers: cross-env: specifier: 'catalog:' version: 10.1.0 + cross-spawn: + specifier: 'catalog:' + version: 7.0.6 deno: specifier: 'catalog:' version: 2.9.6 @@ -155,6 +164,9 @@ importers: specifier: 'catalog:' version: 5.0.3(@types/node@25.0.3)(@vitest/browser-playwright@5.0.3)(@vitest/browser-preview@5.0.3)(@vitest/ui@5.0.3)(vite@8.3.2(@types/node@25.0.3)) devDependencies: + '@types/cross-spawn': + specifier: 'catalog:' + version: 6.0.6 vite-task-tools: specifier: workspace:* version: 'link:' @@ -782,6 +794,9 @@ packages: '@types/chai@5.2.3': resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + '@types/cross-spawn@6.0.6': + resolution: {integrity: sha512-fXRhhUkG4H3TQk5dBhQ7m/JDdSNHKwR2BBia62lhwEIq9xGiQKLxd6LymNhn47SjXhsUEPmxi+PKw2OkW4LLjA==} + '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} @@ -1994,6 +2009,10 @@ snapshots: '@types/deep-eql': 4.0.2 assertion-error: 2.0.1 + '@types/cross-spawn@6.0.6': + dependencies: + '@types/node': 25.0.3 + '@types/deep-eql@4.0.2': {} '@types/estree@1.0.9': {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index bbcd7b67c..e5420644c 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -17,6 +17,7 @@ catalog: '@fastify/busboy': 3.2.2 '@openai/codex': 0.160.0 '@tsconfig/strictest': ^2.0.8 + '@types/cross-spawn': 6.0.6 '@types/node': 25.0.3 '@playwright/browser-chromium': 1.63.0 '@vitest/browser-playwright': 5.0.3 @@ -24,6 +25,7 @@ catalog: cbor-edn: 0.2.2 cbor2: 1.12.0 cross-env: ^10.1.0 + cross-spawn: 7.0.6 deno: 2.9.6 husky: ^9.1.7 lint-staged: ^17.0.0