Codex/windows bazel rust test coverage no rs#16528
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 52f2c86975
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| + lld_link = rctx.which("lld-link.exe") | ||
| + if lld_link == None: | ||
| + fail("lld-link.exe not found on PATH") |
There was a problem hiding this comment.
Remove hard dependency on host lld-link.exe
_rustc_repository_impl now requires rctx.which("lld-link.exe") to succeed and explicitly fail(...)s otherwise. That introduces a non-hermetic host-tool dependency for Windows toolchain repository setup: any Bazel run in an environment where lld-link.exe is not already on PATH will fail during external repo fetch, before normal analysis/build can proceed.
Useful? React with 👍 / 👎.
3220176 to
cdaed53
Compare
In #16528, I am trying to get tests running under Bazel on Windows, but currently I see: ``` thread 'suite::user_shell_cmd::user_shell_command_does_not_set_network_sandbox_env_var' (10220) panicked at core/tests\suite\user_shell_cmd.rs:358:5: assertion failed: `(left == right)` Diff < left / right > : <1 >0 ``` This PR updates the `assert_eq!()` to provide more information to help diagnose the failure. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/16606). * #16608 * __->__ #16606
0077532 to
7bc5bb7
Compare
## Why We were seeing failures in the following tests as part of trying to get all the tests running under Bazel on Windows in CI (#16528): ``` suite::shell_command::unicode_output::with_login suite::shell_command::unicode_output::without_login ``` Certainly `PATHEXT` should have been included in the extra `CORE_VARS` list, so we fix that up here, but also take things a step further for now by forcibly ensuring it is set on Windows in the return value of `create_env()`. Once we get the Windows Bazel build working reliably (i.e., after #16528 is merged), we should come back to this and confirm we can remove the special case in `create_env()`. ## What - Split core env inheritance into `COMMON_CORE_VARS` plus platform-specific allowlists for Windows and Unix in [`exec_env.rs`](https://github.com/openai/codex/blob/1b55c88fbf585b32cd553cb9d02ec817f2ad6ebc/codex-rs/core/src/exec_env.rs#L45-L81). - Preserve `PATHEXT`, `USERNAME`, and `USERPROFILE` on Windows, and `HOME` / locale vars on Unix. - Backfill a default `PATHEXT` in `create_env()` on Windows if the parent env does not provide one, so child process launch still works in stripped-down Bazel environments. - Extend the Windows exec-env test to assert mixed-case `PathExt` survives case-insensitive core filtering, and document why the shell-command Unicode test goes through a child process. ## Verification - `cargo test -p codex-core exec_env::tests`
1d2d0b6 to
10361c6
Compare
## Why Extracted from [#16528](#16528) so the Windows Bazel app-server test failures can be reviewed independently from the rest of that PR. This PR targets: - `suite::v2::thread_shell_command::thread_shell_command_runs_as_standalone_turn_and_persists_history` - `suite::v2::thread_start::thread_start_with_elevated_sandbox_trusts_project_and_followup_loads_project_config` - `suite::v2::thread_start::thread_start_with_nested_git_cwd_trusts_repo_root` There were two Windows-specific assumptions baked into those tests and the underlying trust lookup: - project trust keys were persisted and looked up using raw path strings, but Bazel's Windows test environment can surface canonicalized paths with `\\?\` / UNC prefixes or normalized symlink/junction targets, so follow-up `thread/start` requests no longer matched the project entry that had just been written - `item/commandExecution/outputDelta` assertions compared exact trailing line endings even though shell output chunk boundaries and CRLF handling can differ on Windows, and Bazel made that timing-sensitive mismatch visible There was also one behavior bug separate from the assertion cleanup: `thread/start` decided whether to persist trust from the final resolved sandbox policy, but on Windows an explicit `workspace-write` request may be downgraded to `read-only`. That incorrectly skipped writing trust even though the request had asked to elevate the project, so the new logic also keys off the requested sandbox mode. ## What - Canonicalize project trust keys when persisting/loading `[projects]` entries, while still accepting legacy raw keys for existing configs. - Persist project trust when `thread/start` explicitly requests `workspace-write` or `danger-full-access`, even if the resolved policy is later downgraded on Windows. - Make the Windows app-server tests compare persisted trust paths and command output deltas in a path/newline-normalized way. ## Verification - Existing app-server v2 tests cover the three failing Windows Bazel cases above.
2a9aa12 to
1e365c9
Compare
Why this PR exists
This PR is trying to fix a coverage gap in the Windows Bazel Rust test lane.
Before this change, the Windows
bazel test //...job was nominally part of PR CI, but a non-trivial set of//codex-rs/...Rust test targets did not actually contribute test signal on Windows. In particular, targets such as//codex-rs/core:core-unit-tests,//codex-rs/core:core-all-test, and//codex-rs/login:login-unit-testswere incompatible during Bazel analysis on the Windows gnullvm platform, so they never reached test execution there. That is why the Cargo-powered Windows CI job could surface Windows-only failures that the Bazel-powered job did not report: Cargo was executing those tests, while Bazel was silently dropping them from the runnable target set.The main goal of this PR is to make the Windows Bazel test lane execute those Rust test targets instead of skipping them during analysis, while still preserving
windows-gnullvmas the target configuration for the code under test. In other words: use an MSVC host/exec toolchain where Bazel helper binaries and build scripts need it, but continue compiling the actual crate targets with the Windows gnullvm cfgs that our current Bazel matrix is supposed to exercise.Important scope note
This branch intentionally removes the non-resource-loading
.rstest and production-code changes from the earliercodex/windows-bazel-rust-test-coveragebranch. The only Rust source changes kept here are runfiles/resource-loading fixes in TUI tests:codex-rs/tui/src/chatwidget/tests.rscodex-rs/tui/tests/manager_dependency_regression.rsThat is deliberate. Since the corresponding tests already pass under Cargo, this PR is meant to test whether Bazel infrastructure/toolchain fixes alone are enough to get a healthy Windows Bazel test signal, without changing test behavior for Windows timing, shell output, or SQLite file-locking.
How this PR changes the Windows Bazel setup
1. Split Windows host/exec and target concerns in the Bazel test lane
The core change is that the Windows Bazel test job now opts into an MSVC host platform for Bazel execution-time tools, but only for
bazel test, not for the Bazel clippy build.Files:
.github/workflows/bazel.yml.github/scripts/run-bazel-ci.shMODULE.bazelWhat changed:
run-bazel-ci.shnow accepts--windows-msvc-host-platform.--host_platform=//:local_windows_msvcunless the caller already provided an explicit--host_platform.bazel.ymlpasses that wrapper flag only for the Windowsbazel test //...job.run-bazel-ci.shalso now forwardsCODEX_JS_REPL_NODE_PATHon Windows and normalizes thenodeexecutable path withcygpath -w, so tests that need Node resolve the runner's Node installation correctly under the Windows Bazel test environment.Why this helps:
msvcandgnullvm.2. Teach the repo's Bazel Rust macro about Windows link flags and integration-test knobs
Files:
defs.bzlcodex-rs/core/BUILD.bazelcodex-rs/otel/BUILD.bazelcodex-rs/tui/BUILD.bazelWhat changed:
WINDOWS_RUSTC_LINK_FLAGS, which now handles both Windows ABIs:-C link-arg=-Wl,--stack,8388608-C link-arg=/STACK:8388608,-C link-arg=/NODEFAULTLIB:libucrt.lib, and-C link-arg=ucrt.librust_binary, unit-test binaries, and integration-test binaries.codex_rust_crate(...)with:integration_test_argsintegration_test_timeout//codex-rs/core:core-all-testas a long-running integration test//codex-rs/otel:otel-all-testwith--test-threads=1src/**/*.rstocodex-rs/tuitest runfiles, because one regression test scans source files at runtime and Bazel does not expose source-tree directories unless they are declared as data.Why this helps:
3. Patch
rules_rs/rules_rustso Windows MSVC exec-side Rust and build scripts are actually usableFiles:
MODULE.bazelpatches/rules_rs_windows_exec_linker.patchpatches/rules_rust_windows_bootstrap_process_wrapper_linker.patchpatches/rules_rust_windows_build_script_runner_paths.patchpatches/rules_rust_windows_exec_msvc_build_script_env.patchpatches/rules_rust_windows_msvc_direct_link_args.patchpatches/rules_rust_windows_process_wrapper_skip_temp_outputs.patchpatches/BUILD.bazelWhat these patches do:
rules_rs_windows_exec_linker.patchrust-lldfilegroup for Windows Rust toolchain repos, symlinked tolld-link.exefromPATH.rules_rust_windows_bootstrap_process_wrapper_linker.patchclang++./NOLOGO//LIBPATH://OUT:arguments but Bazel still invokesclang++.exe.rules_rust_windows_build_script_runner_paths.patchRUSTC,OUT_DIR, and the build-script working directory to avoid path-length and quoting issues in third-party build scripts.RULES_RUST_BAZEL_BUILD_SCRIPT_RUNNER=1to build scripts so crate-local patches can detect "this is running under Bazel's build-script runner".rules_rust_windows_exec_msvc_build_script_env.patchCC,CXX,LD,CFLAGS, andCXXFLAGSwhen that would send GNU-flavored tool paths/flags into MSVC-oriented Cargo build scripts.--sysroot, MinGW include/library paths, stack-protector, and_FORTIFY_SOURCEflags on the MSVC exec path.clang.exesetup.rules_rust_windows_msvc_direct_link_args.patch-L...and--sysroot=...thatlld-link.exedoes not understand..libnative artifacts as explicit-Clink-arg=<path>entries when needed..libartifacts on the Windows direct-driver path.rules_rust_windows_process_wrapper_skip_temp_outputs.patch*.tmp*and*.rcgu.ofiles from process-wrapper dependency search-path consolidation, so unstable compiler outputs do not get treated as real link search-path inputs.Why this helps:
clang++with MSVC-style arguments.4. Patch third-party crate build scripts that were not robust under Bazel's Windows MSVC build-script path
Files:
MODULE.bazelpatches/aws-lc-sys_windows_msvc_prebuilt_nasm.patchpatches/ring_windows_msvc_include_dirs.patchpatches/zstd-sys_windows_msvc_include_dirs.patchWhat changed:
aws-lc-sysRULES_RUST_BAZEL_BUILD_SCRIPT_RUNNERor abazel-outmanifest-dir path.clang-clfor Bazel Windows MSVC builds when no explicitCC/CXXis set.nasmis not available directly in the runner environment.CARGO_MANIFEST_DIRin the Bazel Windows MSVC case, because that path may point into Bazel output/runfiles state where preserving the given path is more reliable than forcing a local filesystem canonicalization.ringOUT_DIRand uses that as the generated-source root.zstd-syscompress,decompress, and feature-gated dictionary/legacy/seekable sources.-fvisibility=hiddenon MSVC targets, where that GCC/Clang-style flag is not the right mechanism.Why this helps:
rules_rustplumbing started running build scripts on the Windows MSVC exec path, some third-party crates still failed for crate-local reasons: wrong compiler choice, missing include directories, build-script assumptions about manifest paths, or Unix-only C compiler flags.5. Keep the only
.rstest changes to Bazel/Cargo runfiles parityFiles:
codex-rs/tui/src/chatwidget/tests.rscodex-rs/tui/tests/manager_dependency_regression.rsWhat changed:
find_resource!for a directory runfile likesrc/chatwidget/snapshotsorsrc, these tests now resolve one known file runfile first and then walk to its parent directory.Why this helps:
What we tried before landing on this shape, and why those attempts did not work
Attempt 1: Force
--host_platform=//:local_windows_msvcfor all Windows Bazel jobsThis did make the previously incompatible test targets show up during analysis, but it also pushed the Bazel clippy job and some unrelated build actions onto the MSVC exec path.
Why that was bad:
tree-sitterandlibsqlite3-sys.What this PR does instead:
bazel.ymluses it only for the Windowsbazel testlane.Attempt 2: Broaden the
rules_rustlinker override to all Windows Rust actionsThis fixed the MSVC test-lane failure where normal
rust_testtargets were linked throughclang++with MSVC-style arguments, but it broke the default gnullvm path.Why that was bad:
@@rules_rs++rules_rust+rules_rust//util/process_wrapper:process_wrapperon the gnullvm exec platform started linking withlld-link.exeand then failed to resolve MinGW-style libraries such as-lkernel32,-luser32, and-lmingw32.What this PR does instead:
Attempt 3: Keep everything on pure Windows gnullvm and patch the V8 / Python incompatibility chain instead
This would have preserved a single Windows ABI everywhere, but it is a much larger project than this PR.
Why that was not the practical first step:
third_party/v8is already special-cased on Windows gnullvm becauserusty_v8only publishes Windows prebuilts under MSVC names.What this PR does instead:
Attempt 4: Validate compatibility with
bazel test --nobuild ...This turned out to be a misleading local validation command.
Why:
bazel test --nobuild ...can successfully analyze targets and then still exit 1 with "Couldn't start the build. Unable to run tests" because there are no runnable test actions after--nobuild.Better local check:
Which patches probably deserve upstream follow-up
My rough take is that the
rules_rs/rules_rustpatches are the highest-value upstream candidates, because they are fixing generic Windows host/exec + MSVC direct-linker behavior rather than Codex-specific test logic.Strong upstream candidates:
patches/rules_rs_windows_exec_linker.patchpatches/rules_rust_windows_bootstrap_process_wrapper_linker.patchpatches/rules_rust_windows_build_script_runner_paths.patchpatches/rules_rust_windows_exec_msvc_build_script_env.patchpatches/rules_rust_windows_msvc_direct_link_args.patchpatches/rules_rust_windows_process_wrapper_skip_temp_outputs.patchWhy these seem upstreamable:
Potentially upstreamable crate patches, but likely with more care:
patches/zstd-sys_windows_msvc_include_dirs.patchpatches/ring_windows_msvc_include_dirs.patchpatches/aws-lc-sys_windows_msvc_prebuilt_nasm.patchNotes on those:
zstd-sysandringinclude-path fixes look fairly generic for MSVC/Bazel build-script environments and may be straightforward to propose upstream after we confirm CI stability.aws-lc-syspatch is useful, but it includes a Bazel-specific environment probe and CI-specific compiler fallback behavior. That probably needs a cleaner upstream-facing shape before sending it out, so upstream maintainers are not forced to adopt Codex's exact CI assumptions.Probably not worth upstreaming as-is:
defs.bzl,codex-rs/*/BUILD.bazel, and.github/scripts/run-bazel-ci.share mostly Codex-specific policy and CI wiring, not generic rules changes.Validation notes for reviewers
On this branch, I ran the following local checks after dropping the non-resource-loading Rust edits:
One local caveat:
just argument-comment-lintstill fails on this Windows machine for an unrelated Bazel toolchain-resolution issue in//codex-rs/exec:exec-all-test, so I used the direct prebuilt linter forcodex-tuias the local fallback.Expected reviewer takeaway
If this PR goes green, the important conclusion is that the Windows Bazel test coverage gap was primarily a Bazel host/exec toolchain problem, not a need to make the Rust tests themselves Windows-specific. That would be a strong signal that the deleted non-resource-loading Rust test edits from the earlier branch should stay out, and that future work should focus on upstreaming the generic
rules_rs/rules_rustWindows fixes and reducing the crate-local patch surface.