From 29d527af562f0a3b739ed72c6a1fd92432bbac90 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Tue, 29 Sep 2026 00:32:16 -0700 Subject: [PATCH 1/4] perf(test): one integration-test binary each for core, cli, packages, library-select 14 top-level tests/*.rs files become modules of tests/it/main.rs in their crates (FastLED/fbuild#1577, zackees/ci.yml RUST-005). Test counts are unchanged (the one gap in fbuild-core is a #[cfg(windows)] test). Dylint allowlists, boundary ledgers and --test references follow the move. Workspace test binaries 47 -> 37. Local cargo test --no-run for the four crates after a clean, alternating runs: 18.3-20.2s vs 20.9-21.4s before. --- ci/platform_boundary_ledger.tsv | 4 ++-- ci/platform_boundary_research.tsv | 4 ++-- crates/fbuild-cli/tests/it/README.md | 7 +++++++ crates/fbuild-cli/tests/{ => it}/ci_command.rs | 0 .../fbuild-cli/tests/{ => it}/daemon_crash_recovery.rs | 0 crates/fbuild-cli/tests/{ => it}/lib_select.rs | 0 crates/fbuild-cli/tests/it/main.rs | 8 ++++++++ crates/fbuild-cli/tests/{ => it}/test_emu_exit_code.rs | 0 crates/fbuild-core/tests/it/README.md | 7 +++++++ crates/fbuild-core/tests/{ => it}/cpu_profiling.rs | 0 crates/fbuild-core/tests/{ => it}/dep_identity.rs | 0 crates/fbuild-core/tests/it/main.rs | 10 ++++++++++ .../tests/{ => it}/platformio_avr_resolution.rs | 0 .../tests/{ => it}/platformio_ch32v_resolution.rs | 0 .../tests/{ => it}/platformio_esp8266_resolution.rs | 0 .../tests/{ => it}/platformio_package_resolution.rs | 0 crates/fbuild-library-select/tests/it/README.md | 7 +++++++ crates/fbuild-library-select/tests/it/main.rs | 6 ++++++ .../fbuild-library-select/tests/{ => it}/perf_tdd.rs | 0 .../tests/{ => it}/teensy41_ldf_diag.rs | 2 +- crates/fbuild-packages/tests/it/README.md | 7 +++++++ .../tests/{ => it}/disk_cache_schema_migration.rs | 0 crates/fbuild-packages/tests/{ => it}/lnk_e2e.rs | 0 crates/fbuild-packages/tests/it/main.rs | 6 ++++++ dylints/ban_raw_path_prefix_compare/src/lib.rs | 2 +- dylints/ban_raw_subprocess/src/lib.rs | 2 +- dylints/ban_std_pathbuf/src/allowlist.txt | 6 +++--- dylints/enforce_platform_boundary/src/baseline.txt | 4 ++-- 28 files changed, 70 insertions(+), 12 deletions(-) create mode 100644 crates/fbuild-cli/tests/it/README.md rename crates/fbuild-cli/tests/{ => it}/ci_command.rs (100%) rename crates/fbuild-cli/tests/{ => it}/daemon_crash_recovery.rs (100%) rename crates/fbuild-cli/tests/{ => it}/lib_select.rs (100%) create mode 100644 crates/fbuild-cli/tests/it/main.rs rename crates/fbuild-cli/tests/{ => it}/test_emu_exit_code.rs (100%) create mode 100644 crates/fbuild-core/tests/it/README.md rename crates/fbuild-core/tests/{ => it}/cpu_profiling.rs (100%) rename crates/fbuild-core/tests/{ => it}/dep_identity.rs (100%) create mode 100644 crates/fbuild-core/tests/it/main.rs rename crates/fbuild-core/tests/{ => it}/platformio_avr_resolution.rs (100%) rename crates/fbuild-core/tests/{ => it}/platformio_ch32v_resolution.rs (100%) rename crates/fbuild-core/tests/{ => it}/platformio_esp8266_resolution.rs (100%) rename crates/fbuild-core/tests/{ => it}/platformio_package_resolution.rs (100%) create mode 100644 crates/fbuild-library-select/tests/it/README.md create mode 100644 crates/fbuild-library-select/tests/it/main.rs rename crates/fbuild-library-select/tests/{ => it}/perf_tdd.rs (100%) rename crates/fbuild-library-select/tests/{ => it}/teensy41_ldf_diag.rs (98%) create mode 100644 crates/fbuild-packages/tests/it/README.md rename crates/fbuild-packages/tests/{ => it}/disk_cache_schema_migration.rs (100%) rename crates/fbuild-packages/tests/{ => it}/lnk_e2e.rs (100%) create mode 100644 crates/fbuild-packages/tests/it/main.rs diff --git a/ci/platform_boundary_ledger.tsv b/ci/platform_boundary_ledger.tsv index f47962701..d69b2cc3a 100644 --- a/ci/platform_boundary_ledger.tsv +++ b/ci/platform_boundary_ledger.tsv @@ -1,6 +1,6 @@ path kind normalized ordinal capability classification -crates/fbuild-core/tests/platformio_package_resolution.rs attr_cfg #[cfg(windows)] 0 host host_mechanic -crates/fbuild-core/tests/platformio_package_resolution.rs attr_cfg #[cfg(windows)] 1 host host_mechanic +crates/fbuild-core/tests/it/platformio_package_resolution.rs attr_cfg #[cfg(windows)] 0 host host_mechanic +crates/fbuild-core/tests/it/platformio_package_resolution.rs attr_cfg #[cfg(windows)] 1 host host_mechanic crates/fbuild-daemon/Cargo.toml native_dependency libc 0 process host_mechanic crates/fbuild-daemon/src/handlers/emulator/tests_npm_cache.rs attr_cfg #[cfg(windows)] 0 host_executable host_artifact_policy crates/fbuild-daemon/src/handlers/emulator/tests_process.rs attr_cfg #[cfg(not(windows))] 0 host_executable host_artifact_policy diff --git a/ci/platform_boundary_research.tsv b/ci/platform_boundary_research.tsv index 801f40bfd..e9828c4d3 100644 --- a/ci/platform_boundary_research.tsv +++ b/ci/platform_boundary_research.tsv @@ -71,8 +71,8 @@ crates/fbuild-core/src/platform/windows/usb_pnp.rs 32 native_path windows_sys:: crates/fbuild-core/src/platform/windows/usb_pnp.rs 35 native_path windows_sys:: process host_mechanic crates/fbuild-core/src/platform/windows/usb_pnp.rs 39 native_path windows_sys:: process host_mechanic crates/fbuild-core/src/platform/windows/usb_pnp.rs 40 native_path windows_sys:: process host_mechanic -crates/fbuild-core/tests/platformio_package_resolution.rs 5 attr_cfg #[cfg(windows)] host host_mechanic -crates/fbuild-core/tests/platformio_package_resolution.rs 107 attr_cfg #[cfg(windows)] host host_mechanic +crates/fbuild-core/tests/it/platformio_package_resolution.rs 5 attr_cfg #[cfg(windows)] host host_mechanic +crates/fbuild-core/tests/it/platformio_package_resolution.rs 107 attr_cfg #[cfg(windows)] host host_mechanic crates/fbuild-daemon/Cargo.toml 68 native_dependency libc process host_mechanic crates/fbuild-daemon/src/handlers/emulator/tests_npm_cache.rs 146 attr_cfg #[cfg(windows)] host_executable host_artifact_policy crates/fbuild-daemon/src/handlers/emulator/tests_process.rs 9 attr_cfg #[cfg(windows)] host_executable host_artifact_policy diff --git a/crates/fbuild-cli/tests/it/README.md b/crates/fbuild-cli/tests/it/README.md new file mode 100644 index 000000000..45624633f --- /dev/null +++ b/crates/fbuild-cli/tests/it/README.md @@ -0,0 +1,7 @@ +# fbuild-cli integration tests + +All integration tests for `fbuild-cli` compile into this single `it` binary; each +`*.rs` here is a module listed in `main.rs`. Add new integration tests +as a module here, not as a new top-level `tests/*.rs` file: every top-level +file is a separate binary that re-links the crate's whole dependency graph +(zackees/ci.yml RUST-005). diff --git a/crates/fbuild-cli/tests/ci_command.rs b/crates/fbuild-cli/tests/it/ci_command.rs similarity index 100% rename from crates/fbuild-cli/tests/ci_command.rs rename to crates/fbuild-cli/tests/it/ci_command.rs diff --git a/crates/fbuild-cli/tests/daemon_crash_recovery.rs b/crates/fbuild-cli/tests/it/daemon_crash_recovery.rs similarity index 100% rename from crates/fbuild-cli/tests/daemon_crash_recovery.rs rename to crates/fbuild-cli/tests/it/daemon_crash_recovery.rs diff --git a/crates/fbuild-cli/tests/lib_select.rs b/crates/fbuild-cli/tests/it/lib_select.rs similarity index 100% rename from crates/fbuild-cli/tests/lib_select.rs rename to crates/fbuild-cli/tests/it/lib_select.rs diff --git a/crates/fbuild-cli/tests/it/main.rs b/crates/fbuild-cli/tests/it/main.rs new file mode 100644 index 000000000..511f5598e --- /dev/null +++ b/crates/fbuild-cli/tests/it/main.rs @@ -0,0 +1,8 @@ +//! One integration-test binary for this crate (zackees/ci.yml RUST-005): +//! each top-level `tests/*.rs` file links the crate's whole dependency +//! graph separately, so these modules share one link instead. + +mod ci_command; +mod daemon_crash_recovery; +mod lib_select; +mod test_emu_exit_code; diff --git a/crates/fbuild-cli/tests/test_emu_exit_code.rs b/crates/fbuild-cli/tests/it/test_emu_exit_code.rs similarity index 100% rename from crates/fbuild-cli/tests/test_emu_exit_code.rs rename to crates/fbuild-cli/tests/it/test_emu_exit_code.rs diff --git a/crates/fbuild-core/tests/it/README.md b/crates/fbuild-core/tests/it/README.md new file mode 100644 index 000000000..b9c7ba122 --- /dev/null +++ b/crates/fbuild-core/tests/it/README.md @@ -0,0 +1,7 @@ +# fbuild-core integration tests + +All integration tests for `fbuild-core` compile into this single `it` binary; each +`*.rs` here is a module listed in `main.rs`. Add new integration tests +as a module here, not as a new top-level `tests/*.rs` file: every top-level +file is a separate binary that re-links the crate's whole dependency graph +(zackees/ci.yml RUST-005). diff --git a/crates/fbuild-core/tests/cpu_profiling.rs b/crates/fbuild-core/tests/it/cpu_profiling.rs similarity index 100% rename from crates/fbuild-core/tests/cpu_profiling.rs rename to crates/fbuild-core/tests/it/cpu_profiling.rs diff --git a/crates/fbuild-core/tests/dep_identity.rs b/crates/fbuild-core/tests/it/dep_identity.rs similarity index 100% rename from crates/fbuild-core/tests/dep_identity.rs rename to crates/fbuild-core/tests/it/dep_identity.rs diff --git a/crates/fbuild-core/tests/it/main.rs b/crates/fbuild-core/tests/it/main.rs new file mode 100644 index 000000000..80ded676f --- /dev/null +++ b/crates/fbuild-core/tests/it/main.rs @@ -0,0 +1,10 @@ +//! One integration-test binary for this crate (zackees/ci.yml RUST-005): +//! each top-level `tests/*.rs` file links the crate's whole dependency +//! graph separately, so these modules share one link instead. + +mod cpu_profiling; +mod dep_identity; +mod platformio_avr_resolution; +mod platformio_ch32v_resolution; +mod platformio_esp8266_resolution; +mod platformio_package_resolution; diff --git a/crates/fbuild-core/tests/platformio_avr_resolution.rs b/crates/fbuild-core/tests/it/platformio_avr_resolution.rs similarity index 100% rename from crates/fbuild-core/tests/platformio_avr_resolution.rs rename to crates/fbuild-core/tests/it/platformio_avr_resolution.rs diff --git a/crates/fbuild-core/tests/platformio_ch32v_resolution.rs b/crates/fbuild-core/tests/it/platformio_ch32v_resolution.rs similarity index 100% rename from crates/fbuild-core/tests/platformio_ch32v_resolution.rs rename to crates/fbuild-core/tests/it/platformio_ch32v_resolution.rs diff --git a/crates/fbuild-core/tests/platformio_esp8266_resolution.rs b/crates/fbuild-core/tests/it/platformio_esp8266_resolution.rs similarity index 100% rename from crates/fbuild-core/tests/platformio_esp8266_resolution.rs rename to crates/fbuild-core/tests/it/platformio_esp8266_resolution.rs diff --git a/crates/fbuild-core/tests/platformio_package_resolution.rs b/crates/fbuild-core/tests/it/platformio_package_resolution.rs similarity index 100% rename from crates/fbuild-core/tests/platformio_package_resolution.rs rename to crates/fbuild-core/tests/it/platformio_package_resolution.rs diff --git a/crates/fbuild-library-select/tests/it/README.md b/crates/fbuild-library-select/tests/it/README.md new file mode 100644 index 000000000..35bf6bbef --- /dev/null +++ b/crates/fbuild-library-select/tests/it/README.md @@ -0,0 +1,7 @@ +# fbuild-library-select integration tests + +All integration tests for `fbuild-library-select` compile into this single `it` binary; each +`*.rs` here is a module listed in `main.rs`. Add new integration tests +as a module here, not as a new top-level `tests/*.rs` file: every top-level +file is a separate binary that re-links the crate's whole dependency graph +(zackees/ci.yml RUST-005). diff --git a/crates/fbuild-library-select/tests/it/main.rs b/crates/fbuild-library-select/tests/it/main.rs new file mode 100644 index 000000000..c85f34b3c --- /dev/null +++ b/crates/fbuild-library-select/tests/it/main.rs @@ -0,0 +1,6 @@ +//! One integration-test binary for this crate (zackees/ci.yml RUST-005): +//! each top-level `tests/*.rs` file links the crate's whole dependency +//! graph separately, so these modules share one link instead. + +mod perf_tdd; +mod teensy41_ldf_diag; diff --git a/crates/fbuild-library-select/tests/perf_tdd.rs b/crates/fbuild-library-select/tests/it/perf_tdd.rs similarity index 100% rename from crates/fbuild-library-select/tests/perf_tdd.rs rename to crates/fbuild-library-select/tests/it/perf_tdd.rs diff --git a/crates/fbuild-library-select/tests/teensy41_ldf_diag.rs b/crates/fbuild-library-select/tests/it/teensy41_ldf_diag.rs similarity index 98% rename from crates/fbuild-library-select/tests/teensy41_ldf_diag.rs rename to crates/fbuild-library-select/tests/it/teensy41_ldf_diag.rs index 738ac5d49..584836520 100644 --- a/crates/fbuild-library-select/tests/teensy41_ldf_diag.rs +++ b/crates/fbuild-library-select/tests/it/teensy41_ldf_diag.rs @@ -6,7 +6,7 @@ //! only runs on explicit demand: //! //! soldr cargo test -p fbuild-library-select \ -//! --test teensy41_ldf_diag -- --ignored --nocapture +//! --test it teensy41_ldf_diag:: -- --ignored --nocapture //! //! Requires: //! * Cached Teensyduino framework at: diff --git a/crates/fbuild-packages/tests/it/README.md b/crates/fbuild-packages/tests/it/README.md new file mode 100644 index 000000000..0a26c1b17 --- /dev/null +++ b/crates/fbuild-packages/tests/it/README.md @@ -0,0 +1,7 @@ +# fbuild-packages integration tests + +All integration tests for `fbuild-packages` compile into this single `it` binary; each +`*.rs` here is a module listed in `main.rs`. Add new integration tests +as a module here, not as a new top-level `tests/*.rs` file: every top-level +file is a separate binary that re-links the crate's whole dependency graph +(zackees/ci.yml RUST-005). diff --git a/crates/fbuild-packages/tests/disk_cache_schema_migration.rs b/crates/fbuild-packages/tests/it/disk_cache_schema_migration.rs similarity index 100% rename from crates/fbuild-packages/tests/disk_cache_schema_migration.rs rename to crates/fbuild-packages/tests/it/disk_cache_schema_migration.rs diff --git a/crates/fbuild-packages/tests/lnk_e2e.rs b/crates/fbuild-packages/tests/it/lnk_e2e.rs similarity index 100% rename from crates/fbuild-packages/tests/lnk_e2e.rs rename to crates/fbuild-packages/tests/it/lnk_e2e.rs diff --git a/crates/fbuild-packages/tests/it/main.rs b/crates/fbuild-packages/tests/it/main.rs new file mode 100644 index 000000000..b275293fa --- /dev/null +++ b/crates/fbuild-packages/tests/it/main.rs @@ -0,0 +1,6 @@ +//! One integration-test binary for this crate (zackees/ci.yml RUST-005): +//! each top-level `tests/*.rs` file links the crate's whole dependency +//! graph separately, so these modules share one link instead. + +mod disk_cache_schema_migration; +mod lnk_e2e; diff --git a/dylints/ban_raw_path_prefix_compare/src/lib.rs b/dylints/ban_raw_path_prefix_compare/src/lib.rs index 95657d61f..ec8738aa5 100644 --- a/dylints/ban_raw_path_prefix_compare/src/lib.rs +++ b/dylints/ban_raw_path_prefix_compare/src/lib.rs @@ -222,7 +222,7 @@ mod tests { #[test] fn in_production_scope_rejects_non_src() { assert!(!in_production_scope( - "crates/fbuild-cli/tests/lib_select.rs" + "crates/fbuild-cli/tests/it/lib_select.rs" )); assert!(!in_production_scope( "dylints/ban_raw_path_prefix_compare/src/lib.rs" diff --git a/dylints/ban_raw_subprocess/src/lib.rs b/dylints/ban_raw_subprocess/src/lib.rs index 67acc4093..c6d0dc35c 100644 --- a/dylints/ban_raw_subprocess/src/lib.rs +++ b/dylints/ban_raw_subprocess/src/lib.rs @@ -245,7 +245,7 @@ mod tests { #[test] fn in_production_scope_rejects_non_src() { assert!(!in_production_scope( - "crates/fbuild-cli/tests/lib_select.rs" + "crates/fbuild-cli/tests/it/lib_select.rs" )); assert!(!in_production_scope("crates/fbuild-build/examples/demo.rs")); assert!(!in_production_scope( diff --git a/dylints/ban_std_pathbuf/src/allowlist.txt b/dylints/ban_std_pathbuf/src/allowlist.txt index 5be64224f..b0bba370b 100644 --- a/dylints/ban_std_pathbuf/src/allowlist.txt +++ b/dylints/ban_std_pathbuf/src/allowlist.txt @@ -159,7 +159,7 @@ crates/fbuild-library-select/src/lib.rs # (FastLED/fbuild#1371). A file move must not silently drop the # exception the moved code already had. crates/fbuild-library-select/src/lib_tests.rs -crates/fbuild-library-select/tests/teensy41_ldf_diag.rs +crates/fbuild-library-select/tests/it/teensy41_ldf_diag.rs crates/fbuild-packages-fetch/src/cache.rs crates/fbuild-packages-fetch/src/disk_cache/gc.rs crates/fbuild-packages-fetch/src/disk_cache/index/mod.rs @@ -218,8 +218,8 @@ crates/fbuild-toolchain/src/toolchain/riscv.rs crates/fbuild-toolchain/src/toolchain/rp2040_picotool.rs crates/fbuild-toolchain/src/toolchain/rp2040_pqt.rs crates/fbuild-toolchain/src/toolchain/teensy_arm.rs -crates/fbuild-packages/tests/disk_cache_schema_migration.rs -crates/fbuild-packages/tests/lnk_e2e.rs +crates/fbuild-packages/tests/it/disk_cache_schema_migration.rs +crates/fbuild-packages/tests/it/lnk_e2e.rs crates/fbuild-paths/src/lib.rs crates/fbuild-paths/src/running_process.rs crates/fbuild-python/src/daemon.rs diff --git a/dylints/enforce_platform_boundary/src/baseline.txt b/dylints/enforce_platform_boundary/src/baseline.txt index b10d9c6d4..a3083a999 100644 --- a/dylints/enforce_platform_boundary/src/baseline.txt +++ b/dylints/enforce_platform_boundary/src/baseline.txt @@ -1,6 +1,6 @@ # pathkindnormalizedordinal -crates/fbuild-core/tests/platformio_package_resolution.rs attr_cfg windows 0 -crates/fbuild-core/tests/platformio_package_resolution.rs attr_cfg windows 1 +crates/fbuild-core/tests/it/platformio_package_resolution.rs attr_cfg windows 0 +crates/fbuild-core/tests/it/platformio_package_resolution.rs attr_cfg windows 1 crates/fbuild-daemon/src/handlers/emulator/tests_npm_cache.rs attr_cfg windows 0 crates/fbuild-daemon/src/handlers/emulator/tests_process.rs attr_cfg windows 0 crates/fbuild-daemon/src/handlers/emulator/tests_process.rs attr_cfg windows 1 From a0f56ee49f21af23096a7805f1a4830cb2348a60 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Tue, 29 Sep 2026 22:10:37 -0700 Subject: [PATCH 2/4] perf(test): finish #1577 -- 8 integration-test binaries workspace-wide Categories (ci/check_test_layout.py is the list): fbuild-build/tests/it build fbuild-build/tests/env_isolated tests that mutate FBUILD_*/ZCCACHE_* env, all behind one ENV_LOCK: avr_build, eh_frame_strip_esp32, include-farm parity, build-engine dev_daemon_namespace_isolation fbuild-daemon/tests/it daemon fbuild-cli/tests/it cli fbuild-core/tests/it config_resolution fbuild-packages/tests/it packages (+ toolchain qemu_linux_runtime) fbuild-library-select/tests/it library_select fbuild-python/tests/python_facades python (+ pyo3_policy) - test = false on harnesses that ran 0 tests: fbuild-packages lib, enrich_boards, containment_harness, bench-fastled-examples. - fbuild_build_engine::zccache::daemon_endpoint() so the namespace test can move without a second zccache pin. - ci/check_test_layout.py (crate-gate.yml): fails on a new top-level tests/*.rs, an unknown category dir, [[test]] targets, or a #[test] inside a test = false target. - select_boards: test-only paths (crates/*/tests/**, *_tests.rs, ci/test_*.py) never select platform boards. - Workflows, Dylint allowlist/baseline and run instructions follow the move. Workspace test binaries 47 -> 29 (8 integration + unit-test harnesses). Test counts unchanged: 3588 passed, 91 ignored. Closes #1577. --- .github/workflows/acceptance-205.yml | 11 ++- .github/workflows/crate-gate.yml | 5 + .github/workflows/qemu-linux-runtime.yml | 2 +- bench/fastled-examples/Cargo.toml | 2 + ci/check_test_layout.py | 99 +++++++++++++++++++ ci/select_boards.py | 14 +++ ci/test_check_test_layout.py | 75 ++++++++++++++ ci/test_select_boards.py | 19 ++++ .../fbuild-build-engine/src/include_farm.rs | 2 +- crates/fbuild-build-engine/src/zccache.rs | 7 ++ crates/fbuild-build-engine/tests/README.md | 12 --- .../fbuild-build/tests/env_isolated/README.md | 9 ++ .../tests/{ => env_isolated}/avr_build.rs | 7 +- .../dev_daemon_namespace_isolation.rs | 21 ++-- .../eh_frame_strip_esp32.rs | 3 +- .../esp32_include_farm_parity.rs | 9 +- .../fbuild-build/tests/env_isolated/main.rs | 14 +++ .../tests/it/clangd_check_parity.rs | 4 +- .../tests/it/compile_many_two_stage.rs | 2 +- crates/fbuild-build/tests/it/main.rs | 1 - crates/fbuild-config/Cargo.toml | 2 + crates/fbuild-daemon/Cargo.toml | 6 ++ crates/fbuild-packages/Cargo.toml | 6 ++ crates/fbuild-packages/tests/it/main.rs | 1 + .../tests/it}/qemu_linux_runtime.rs | 0 .../fbuild-paths/src/dev_daemon_namespace.rs | 2 +- crates/fbuild-python/Cargo.toml | 2 +- crates/fbuild-python/tests/README.md | 6 +- .../main.rs} | 3 +- .../tests/{ => python_facades}/pyo3_policy.rs | 0 crates/fbuild-toolchain/tests/README.md | 18 ---- dylints/ban_std_pathbuf/src/allowlist.txt | 2 +- .../src/baseline.txt | 2 +- 33 files changed, 305 insertions(+), 63 deletions(-) create mode 100644 ci/check_test_layout.py create mode 100644 ci/test_check_test_layout.py delete mode 100644 crates/fbuild-build-engine/tests/README.md create mode 100644 crates/fbuild-build/tests/env_isolated/README.md rename crates/fbuild-build/tests/{ => env_isolated}/avr_build.rs (98%) rename crates/{fbuild-build-engine/tests => fbuild-build/tests/env_isolated}/dev_daemon_namespace_isolation.rs (78%) rename crates/fbuild-build/tests/{ => env_isolated}/eh_frame_strip_esp32.rs (98%) rename crates/fbuild-build/tests/{it => env_isolated}/esp32_include_farm_parity.rs (96%) create mode 100644 crates/fbuild-build/tests/env_isolated/main.rs rename crates/{fbuild-toolchain/tests => fbuild-packages/tests/it}/qemu_linux_runtime.rs (100%) rename crates/fbuild-python/tests/{python_facades.rs => python_facades/main.rs} (99%) rename crates/fbuild-python/tests/{ => python_facades}/pyo3_policy.rs (100%) delete mode 100644 crates/fbuild-toolchain/tests/README.md diff --git a/.github/workflows/acceptance-205.yml b/.github/workflows/acceptance-205.yml index 56fb4a1cf..07a784315 100644 --- a/.github/workflows/acceptance-205.yml +++ b/.github/workflows/acceptance-205.yml @@ -51,30 +51,39 @@ jobs: test_fn: teensy41_cold_library_selection_meets_205_ac6 # FastLED/fbuild#1588: GCC resolves the same headers with and without the include farm. - gate: esp32dev include-farm parity + test_target: env_isolated test_bin: esp32_include_farm_parity test_fn: farm_parity_esp32dev - gate: esp32s2 include-farm parity + test_target: env_isolated test_bin: esp32_include_farm_parity test_fn: farm_parity_esp32s2 - gate: esp32s3 include-farm parity + test_target: env_isolated test_bin: esp32_include_farm_parity test_fn: farm_parity_esp32s3 - gate: esp32c2 include-farm parity + test_target: env_isolated test_bin: esp32_include_farm_parity test_fn: farm_parity_esp32c2 - gate: esp32c3 include-farm parity + test_target: env_isolated test_bin: esp32_include_farm_parity test_fn: farm_parity_esp32c3 - gate: esp32c5 include-farm parity + test_target: env_isolated test_bin: esp32_include_farm_parity test_fn: farm_parity_esp32c5 - gate: esp32c6 include-farm parity + test_target: env_isolated test_bin: esp32_include_farm_parity test_fn: farm_parity_esp32c6 - gate: esp32h2 include-farm parity + test_target: env_isolated test_bin: esp32_include_farm_parity test_fn: farm_parity_esp32h2 - gate: esp32p4 include-farm parity + test_target: env_isolated test_bin: esp32_include_farm_parity test_fn: farm_parity_esp32p4 steps: @@ -101,4 +110,4 @@ jobs: - name: Run ${{ matrix.gate }} acceptance gate run: | - soldr cargo test -p fbuild-build --test it -- --ignored --exact ${{ matrix.test_bin }}::${{ matrix.test_fn }} --nocapture --test-threads=1 + soldr cargo test -p fbuild-build --test ${{ matrix.test_target || 'it' }} -- --ignored --exact ${{ matrix.test_bin }}::${{ matrix.test_fn }} --nocapture --test-threads=1 diff --git a/.github/workflows/crate-gate.yml b/.github/workflows/crate-gate.yml index 92c6b708a..ca69f2e05 100644 --- a/.github/workflows/crate-gate.yml +++ b/.github/workflows/crate-gate.yml @@ -39,3 +39,8 @@ jobs: # which requires `soldr` (absent in this job) and fails the gate for an # unrelated reason. The script declares its own inline metadata. run: uv run --script ci/check_workspace_crates.py + + - name: Check integration tests stay in their 8 category binaries + # FastLED/fbuild#1577: a new top-level crates/*/tests/*.rs is a new + # test binary that re-links the whole dependency graph. + run: uv run --script ci/check_test_layout.py diff --git a/.github/workflows/qemu-linux-runtime.yml b/.github/workflows/qemu-linux-runtime.yml index e88db1f74..f45d9a4eb 100644 --- a/.github/workflows/qemu-linux-runtime.yml +++ b/.github/workflows/qemu-linux-runtime.yml @@ -72,5 +72,5 @@ jobs: - name: QEMU runtime provisioning test run: | - soldr cargo test -p fbuild-toolchain --test qemu_linux_runtime -- \ + soldr cargo test -p fbuild-packages --test it -- qemu_linux_runtime:: \ --ignored --nocapture diff --git a/bench/fastled-examples/Cargo.toml b/bench/fastled-examples/Cargo.toml index 599e92e8b..4fab3c934 100644 --- a/bench/fastled-examples/Cargo.toml +++ b/bench/fastled-examples/Cargo.toml @@ -10,6 +10,8 @@ publish = false [[bin]] name = "bench-fastled-examples" path = "src/main.rs" +# No #[test] in this bin; skip its empty harness (FastLED/fbuild#1577). +test = false [[bin]] name = "bench-build-comparison" diff --git a/ci/check_test_layout.py b/ci/check_test_layout.py new file mode 100644 index 000000000..3e6d83204 --- /dev/null +++ b/ci/check_test_layout.py @@ -0,0 +1,99 @@ +#!/usr/bin/env -S uv run --script +# /// script +# requires-python = ">=3.10" +# /// +"""Linter: keep the workspace at no more than 8 integration-test binaries. + +Every top-level `crates//tests/*.rs` file, and every +`tests//main.rs`, is a separate test binary. Each one links its crate's +whole dependency graph again, and before FastLED/fbuild#1577 that linking took +most of CI's `Test` step. The workspace now has a fixed set of category +binaries (soldr's layout, zackees/ci.yml RUST-005). A new integration test goes +into one of them as a module, never into a new top-level file or directory. + +Adding a category is a deliberate act: add it to `CATEGORIES` below with a +one-line reason, and keep the total at no more than `MAX_CATEGORIES`. + +Usage: + uv run --script ci/check_test_layout.py +""" + +from __future__ import annotations + +import re +import sys +from pathlib import Path + +MAX_CATEGORIES = 8 + +# (crate dir, tests/ subdir) -> what belongs there. +CATEGORIES: dict[tuple[str, str], str] = { + ("fbuild-build", "it"): "build: real and synthetic build pipelines", + ("fbuild-build", "env_isolated"): "tests that mutate FBUILD_*/ZCCACHE_* env vars, behind ENV_LOCK", + ("fbuild-daemon", "it"): "daemon: HTTP/WS server and managers", + ("fbuild-cli", "it"): "cli: command-line front end", + ("fbuild-core", "it"): "config_resolution: PlatformIO resolution and core types", + ("fbuild-packages", "it"): "packages: caches, lnk, toolchain provisioning", + ("fbuild-library-select", "it"): "library_select: LDF and library selection", + ("fbuild-python", "python_facades"): "python: needs libpython at link time", +} + +REPO = Path(__file__).resolve().parent.parent + + +def violations(repo: Path = REPO) -> list[str]: + problems: list[str] = [] + if len(CATEGORIES) > MAX_CATEGORIES: + problems.append(f"{len(CATEGORIES)} categories declared; the limit is {MAX_CATEGORIES}") + for tests in sorted((repo / "crates").glob("*/tests")): + crate = tests.parent.name + for entry in sorted(tests.iterdir()): + rel = entry.relative_to(repo).as_posix() + if entry.is_file() and entry.suffix == ".rs": + problems.append(f"{rel}: top-level test file is its own binary; add it as a module of a category in ci/check_test_layout.py") + elif entry.is_dir() and (entry / "main.rs").exists() and (crate, entry.name) not in CATEGORIES: + problems.append(f"{rel}/main.rs: unknown test category; use an existing one") + manifests = sorted((repo / "crates").glob("*/Cargo.toml")) + sorted((repo / "bench").glob("*/Cargo.toml")) + for manifest in manifests: + text = manifest.read_text(encoding="utf-8") + rel = manifest.relative_to(repo).as_posix() + if re.search(r"^\[\[test\]\]", text, re.MULTILINE): + problems.append(f"{rel}: [[test]] targets bypass the category layout") + for source in test_disabled_sources(manifest, text): + if TEST_ATTR.search(source.read_text(encoding="utf-8")): + problems.append( + f"{source.relative_to(repo).as_posix()}: has #[test] but its target sets `test = false` in {rel}, so it never runs" + ) + return problems + + +TEST_ATTR = re.compile(r"#\[(tokio::)?test\b") + + +def test_disabled_sources(manifest: Path, text: str) -> list[Path]: + """Source files of `[lib]`/`[[bin]]` targets that set `test = false`.""" + crate = manifest.parent + sources: list[Path] = [] + for header, body in re.findall(r"^(\[lib\]|\[\[bin\]\])\n((?:(?!\[).*\n?)*)", text, re.MULTILINE): + if not re.search(r"^test\s*=\s*false", body, re.MULTILINE): + continue + path = re.search(r'^path\s*=\s*"([^"]+)"', body, re.MULTILINE) + entry = crate / (path.group(1) if path else ("src/lib.rs" if header == "[lib]" else "src/main.rs")) + # A lib's unit tests can live anywhere under src/; a bin's in its file. + sources.extend(sorted(entry.parent.rglob("*.rs")) if header == "[lib]" else [entry]) + return [s for s in sources if s.is_file()] + + +def main() -> int: + problems = violations() + for problem in problems: + print(f"error: {problem}", file=sys.stderr) + if problems: + print(f"\n{len(problems)} test-layout violation(s); see FastLED/fbuild#1577", file=sys.stderr) + return 1 + print(f"ok: {len(CATEGORIES)} integration-test categories, no stray test binaries") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/ci/select_boards.py b/ci/select_boards.py index 181c48176..311444280 100644 --- a/ci/select_boards.py +++ b/ci/select_boards.py @@ -53,10 +53,24 @@ def path_matches(pattern: str, path: str) -> bool: return _compile(pattern).match(path) is not None +# Test-only paths never select boards (FastLED/fbuild#1577): the Linux test +# job runs them, and a test refactor must not fan out to every platform. +TEST_ONLY_PATTERNS = ( + "crates/*/tests/**", + "crates/**/*_tests.rs", + "ci/test_*.py", +) + + +def is_test_only(path: str) -> bool: + return any(path_matches(p, path) for p in TEST_ONLY_PATTERNS) + + def select_workflows(boards, families, common_paths, changed): """Workflows to run for `changed` files; `None` means the diff is unknown.""" if changed is None: return sorted(b["workflow"] for b in boards) + changed = [f for f in changed if not is_test_only(f)] selected = [] for board in boards: patterns = render_paths_for_board(board, families, common_paths) diff --git a/ci/test_check_test_layout.py b/ci/test_check_test_layout.py new file mode 100644 index 000000000..a471e920d --- /dev/null +++ b/ci/test_check_test_layout.py @@ -0,0 +1,75 @@ +"""Tests for ci/check_test_layout.py (FastLED/fbuild#1577).""" +from __future__ import annotations + +import sys +import tempfile +import unittest +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parent)) + +from check_test_layout import CATEGORIES, MAX_CATEGORIES, violations # noqa: E402 + + +def make(root: Path, rel: str, body: str = "") -> None: + path = root / rel + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(body, encoding="utf-8") + + +class LayoutTests(unittest.TestCase): + def test_repository_is_clean(self): + self.assertEqual([], violations()) + + def test_at_most_eight_categories(self): + self.assertLessEqual(len(CATEGORIES), MAX_CATEGORIES) + self.assertEqual(8, MAX_CATEGORIES) + + def test_top_level_test_file_is_rejected(self): + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + make(root, "crates/fbuild-core/tests/it/main.rs") + make(root, "crates/fbuild-core/tests/new_thing.rs") + problems = violations(root) + self.assertEqual(1, len(problems)) + self.assertIn("new_thing.rs", problems[0]) + + def test_unknown_category_dir_is_rejected(self): + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + make(root, "crates/fbuild-core/tests/extra/main.rs") + self.assertIn("unknown test category", violations(root)[0]) + + def test_explicit_test_target_is_rejected(self): + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + make(root, "crates/fbuild-core/Cargo.toml", '[package]\nname = "x"\n\n[[test]]\nname = "y"\n') + self.assertIn("[[test]]", violations(root)[0]) + + def test_helper_dirs_without_main_are_allowed(self): + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + make(root, "crates/fbuild-core/tests/it/main.rs") + make(root, "crates/fbuild-core/tests/fixtures/data.json") + self.assertEqual([], violations(root)) + + def test_test_false_target_with_tests_is_rejected(self): + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + make(root, "crates/fbuild-x/Cargo.toml", '[package]\nname = "x"\n\n[lib]\ntest = false\n\n[dependencies]\n') + make(root, "crates/fbuild-x/src/lib.rs", "mod a;\n") + make(root, "crates/fbuild-x/src/a.rs", "#[test]\nfn t() {}\n") + problems = violations(root) + self.assertEqual(1, len(problems)) + self.assertIn("never runs", problems[0]) + + def test_test_false_target_without_tests_is_fine(self): + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + make(root, "crates/fbuild-x/Cargo.toml", '[package]\nname = "x"\n\n[[bin]]\nname = "b"\npath = "src/bin/b.rs"\ntest = false\n') + make(root, "crates/fbuild-x/src/bin/b.rs", "fn main() {}\n") + self.assertEqual([], violations(root)) + + +if __name__ == "__main__": + unittest.main() diff --git a/ci/test_select_boards.py b/ci/test_select_boards.py index 4233696e2..b3297fbba 100644 --- a/ci/test_select_boards.py +++ b/ci/test_select_boards.py @@ -62,6 +62,25 @@ def test_shared_code_selects_core_boards_only(self): def test_own_workflow_file_selects_board(self): self.assertEqual(["build-esp32c3.yml"], select([".github/workflows/build-esp32c3.yml"])) + def test_test_only_changes_select_nothing(self): + # FastLED/fbuild#1577: moving or editing tests must not fan out to + # platform builds; the Linux test job already runs them. + self.assertEqual( + [], + select([ + "crates/fbuild-core/tests/it/main.rs", + "crates/fbuild-build/tests/env_isolated/avr_build.rs", + "crates/fbuild-build-mcu/src/avr/orchestrator_tests.rs", + "ci/test_select_boards.py", + ]), + ) + + def test_test_change_alongside_source_still_selects(self): + self.assertEqual( + ["build-attiny85.yml", "build-uno.yml"], + select(["crates/fbuild-core/tests/it/main.rs", "crates/fbuild-build-mcu/src/avr/mod.rs"]), + ) + def test_unknown_diff_selects_everything(self): self.assertEqual(sorted(b["workflow"] for b in BOARDS), select(None)) diff --git a/crates/fbuild-build-engine/src/include_farm.rs b/crates/fbuild-build-engine/src/include_farm.rs index c1bc477aa..8684a2a3f 100644 --- a/crates/fbuild-build-engine/src/include_farm.rs +++ b/crates/fbuild-build-engine/src/include_farm.rs @@ -22,7 +22,7 @@ //! Callers skip farms on Windows, where symlinks usually need elevated rights, //! and when `FBUILD_INCLUDE_FARM=0`. The text-level checks above cannot see //! macro includes; the real-SDK parity test in -//! `fbuild-build/tests/it/esp32_include_farm_parity.rs` compares GCC's own +//! `fbuild-build/tests/env_isolated/esp32_include_farm_parity.rs` compares GCC's own //! depfiles with and without the farm (FastLED/fbuild#1588). use std::collections::{BTreeMap, HashMap}; diff --git a/crates/fbuild-build-engine/src/zccache.rs b/crates/fbuild-build-engine/src/zccache.rs index 0aef3bb0a..ed6717233 100644 --- a/crates/fbuild-build-engine/src/zccache.rs +++ b/crates/fbuild-build-engine/src/zccache.rs @@ -86,3 +86,10 @@ pub fn mark_fingerprint_success(watch: &FingerprintWatch) -> Result<()> { )) }) } + +/// The compile daemon's IPC endpoint for the current environment, including +/// the `ZCCACHE_DAEMON_NAMESPACE` stamp (FastLED/fbuild#1285). Two checkouts +/// with different stamps must get different endpoints. +pub fn daemon_endpoint() -> String { + ::zccache::ipc::default_endpoint() +} diff --git a/crates/fbuild-build-engine/tests/README.md b/crates/fbuild-build-engine/tests/README.md deleted file mode 100644 index 59510eeb2..000000000 --- a/crates/fbuild-build-engine/tests/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# `fbuild-build-engine` integration tests - -Tests that need a separate final executable, or that exercise a contract -spanning this crate and one of its external dependencies. - -- **`dev_daemon_namespace_isolation.rs`** — proves the dev daemon-identity - stamp `fbuild-paths` exports actually changes the zccache IPC endpoint - (FastLED/fbuild#1285). It lives here because this is the crate that depends - on both sides: `fbuild-paths` produces the stamp but cannot see zccache, and - zccache consumes it but is a pinned external dependency. A repin that - dropped endpoint namespacing would otherwise pass every other test in the - tree while quietly restoring the `displace-stale` daemon war. diff --git a/crates/fbuild-build/tests/env_isolated/README.md b/crates/fbuild-build/tests/env_isolated/README.md new file mode 100644 index 000000000..b9834868a --- /dev/null +++ b/crates/fbuild-build/tests/env_isolated/README.md @@ -0,0 +1,9 @@ +# env_isolated integration tests + +One test binary (FastLED/fbuild#1577) for `fbuild-build` integration tests +that mutate process-wide environment variables (`FBUILD_*`, +`ZCCACHE_DAEMON_NAMESPACE`). Every test takes `ENV_LOCK` from `main.rs` for +its whole body. Add env-mutating tests here as a module; everything else goes +in `../it`. + +Run one test: `soldr cargo test -p fbuild-build --test env_isolated -- --ignored --exact :: --nocapture` diff --git a/crates/fbuild-build/tests/avr_build.rs b/crates/fbuild-build/tests/env_isolated/avr_build.rs similarity index 98% rename from crates/fbuild-build/tests/avr_build.rs rename to crates/fbuild-build/tests/env_isolated/avr_build.rs index 475eb0814..b069924fa 100644 --- a/crates/fbuild-build/tests/avr_build.rs +++ b/crates/fbuild-build/tests/env_isolated/avr_build.rs @@ -3,7 +3,7 @@ //! Downloads avr-gcc + Arduino core (cached after first run), compiles a //! minimal blink sketch, and validates the output firmware.hex. //! -//! Run with: `soldr cargo test -p fbuild-build --test avr_build -- --ignored` +//! Run with: `soldr cargo test -p fbuild-build --test env_isolated -- --ignored avr_build::` //! //! ## Timeout cap (FastLED/fbuild#806, MEDIUM) //! @@ -71,6 +71,7 @@ async fn install_test_compile_backend() { /// Verify stem/hash cache path format produces readable, unique paths. #[test] fn cache_paths_stem_hash() { + let _env = crate::ENV_LOCK.blocking_lock(); use fbuild_packages::cache::{hash_url, url_stem}; // Toolchain: stem from base URL @@ -107,6 +108,7 @@ fn cache_paths_stem_hash() { #[tokio::test(flavor = "multi_thread", worker_threads = 4)] #[ignore = "downloads AVR toolchain + Arduino-AVR core; requires ~/dev/fbuild/tests/uno_minimal"] async fn build_uno_minimal() { + let _env = crate::ENV_LOCK.lock().await; let project_dir = home_dir().join("dev/fbuild/tests/uno_minimal"); if !project_dir.exists() { @@ -212,6 +214,7 @@ async fn build_uno_minimal() { #[tokio::test(flavor = "multi_thread", worker_threads = 4)] #[ignore = "downloads AVR toolchain; requires Python fbuild reference output at ~/dev/fbuild/tests/uno_minimal"] async fn compare_with_python_output() { + let _env = crate::ENV_LOCK.lock().await; let project_dir = home_dir().join("dev/fbuild/tests/uno_minimal"); let python_hex = project_dir.join(format!( @@ -298,6 +301,7 @@ async fn compare_with_python_output() { #[tokio::test(flavor = "multi_thread", worker_threads = 4)] #[ignore = "downloads AVR toolchain + Arduino-AVR core"] async fn build_self_contained_blink() { + let _env = crate::ENV_LOCK.lock().await; install_test_compile_backend().await; let tmp = tempfile::TempDir::new().unwrap(); let project_dir = tmp.path(); @@ -511,6 +515,7 @@ impl Drop for EnvVarGuard { #[tokio::test(flavor = "multi_thread", worker_threads = 4)] #[ignore = "downloads AVR toolchain + Arduino-AVR core; exercises tar-extract cache path"] async fn cache_survives_tar_extract_uno() { + let _env = crate::ENV_LOCK.lock().await; install_test_compile_backend().await; let tmp_a = tempfile::TempDir::new().unwrap(); let proj_a = tmp_a.path().join("proj"); diff --git a/crates/fbuild-build-engine/tests/dev_daemon_namespace_isolation.rs b/crates/fbuild-build/tests/env_isolated/dev_daemon_namespace_isolation.rs similarity index 78% rename from crates/fbuild-build-engine/tests/dev_daemon_namespace_isolation.rs rename to crates/fbuild-build/tests/env_isolated/dev_daemon_namespace_isolation.rs index 449d573b1..86a50a381 100644 --- a/crates/fbuild-build-engine/tests/dev_daemon_namespace_isolation.rs +++ b/crates/fbuild-build/tests/env_isolated/dev_daemon_namespace_isolation.rs @@ -11,31 +11,32 @@ //! export was inert until fbuild repinned zccache. It is not; it has been //! live since the stamp landed. //! -//! This test is the place that can tell. It lives in `fbuild-build-engine` -//! because that is the crate depending on both sides. A zccache repin that +//! This test is the place that can tell. It reaches zccache through +//! `fbuild_build_engine::zccache::daemon_endpoint`, the crate depending on +//! both sides. A zccache repin that //! silently dropped endpoint namespacing would take the `displace-stale` war //! from zackees/soldr#2352 with it, and nothing else in the tree would //! notice. use fbuild_paths::dev_daemon_namespace::ZCCACHE_DAEMON_NAMESPACE_ENV; -/// One test, not three: the variable is process-global, so parallel cases -/// would race each other's `set_var`. +/// One test, not three: the variable is process-global. #[test] fn the_exported_stamp_changes_the_zccache_daemon_endpoint() { - // SAFETY: this test binary contains one test, so no peer thread can - // observe the process-wide environment change. + let _env = crate::ENV_LOCK.blocking_lock(); + // SAFETY: every test in this binary holds crate::ENV_LOCK, so no peer + // test observes the process-wide environment change. unsafe { std::env::remove_var(ZCCACHE_DAEMON_NAMESPACE_ENV) }; - let bare = zccache::ipc::default_endpoint(); + let bare = fbuild_build_engine::zccache::daemon_endpoint(); unsafe { std::env::set_var(ZCCACHE_DAEMON_NAMESPACE_ENV, "2.5.0-aaaaaaaaaaaaaaaa") }; - let first = zccache::ipc::default_endpoint(); + let first = fbuild_build_engine::zccache::daemon_endpoint(); unsafe { std::env::set_var(ZCCACHE_DAEMON_NAMESPACE_ENV, "2.5.0-bbbbbbbbbbbbbbbb") }; - let second = zccache::ipc::default_endpoint(); + let second = fbuild_build_engine::zccache::daemon_endpoint(); unsafe { std::env::remove_var(ZCCACHE_DAEMON_NAMESPACE_ENV) }; - let bare_again = zccache::ipc::default_endpoint(); + let bare_again = fbuild_build_engine::zccache::daemon_endpoint(); // The property that matters: two checkouts with different stamps do not // meet on one pipe. Without this, each displaces the other as diff --git a/crates/fbuild-build/tests/eh_frame_strip_esp32.rs b/crates/fbuild-build/tests/env_isolated/eh_frame_strip_esp32.rs similarity index 98% rename from crates/fbuild-build/tests/eh_frame_strip_esp32.rs rename to crates/fbuild-build/tests/env_isolated/eh_frame_strip_esp32.rs index f595fef37..185b10cf4 100644 --- a/crates/fbuild-build/tests/eh_frame_strip_esp32.rs +++ b/crates/fbuild-build/tests/env_isolated/eh_frame_strip_esp32.rs @@ -6,7 +6,7 @@ //! of MB on first run) and is not headless-CI-friendly. Run with: //! //! ``` -//! soldr cargo test -p fbuild-build --test eh_frame_strip_esp32 -- --ignored +//! soldr cargo test -p fbuild-build --test env_isolated -- --ignored eh_frame_strip_esp32:: //! ``` //! //! The orchestrator invocation pattern mirrors @@ -114,6 +114,7 @@ void loop() { #[tokio::test(flavor = "multi_thread", worker_threads = 4)] #[ignore = "downloads ESP32 toolchain (~hundreds of MB)"] async fn eh_frame_strip_drops_firmware_at_least_150kb() { + let _env = crate::ENV_LOCK.lock().await; install_test_compile_backend().await; // Use two separate tempdirs so .fbuild/build/... paths don't collide. let preserve_tmp = tempfile::TempDir::new().unwrap(); diff --git a/crates/fbuild-build/tests/it/esp32_include_farm_parity.rs b/crates/fbuild-build/tests/env_isolated/esp32_include_farm_parity.rs similarity index 96% rename from crates/fbuild-build/tests/it/esp32_include_farm_parity.rs rename to crates/fbuild-build/tests/env_isolated/esp32_include_farm_parity.rs index fc34c4bcc..1e7eff5b2 100644 --- a/crates/fbuild-build/tests/it/esp32_include_farm_parity.rs +++ b/crates/fbuild-build/tests/env_isolated/esp32_include_farm_parity.rs @@ -8,7 +8,7 @@ //! header files. //! //! Run one variant with: -//! `soldr cargo test -p fbuild-build --test it -- --ignored --exact +//! `soldr cargo test -p fbuild-build --test env_isolated -- --ignored --exact //! esp32_include_farm_parity::farm_parity_esp32dev --nocapture --test-threads=1` use std::collections::{BTreeMap, BTreeSet}; @@ -21,9 +21,6 @@ use fbuild_core::path::NormalizedPath; const REAL_BUILD_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(900); -/// `FBUILD_INCLUDE_FARM` is process-wide; serialize the builds that flip it. -static FARM_ENV: tokio::sync::Mutex<()> = tokio::sync::Mutex::const_new(()); - async fn install_test_compile_backend() { static INSTALL: tokio::sync::OnceCell<()> = tokio::sync::OnceCell::const_new(); INSTALL @@ -83,7 +80,7 @@ async fn build(project_dir: &Path, env_name: &str, farm: bool) -> NormalizedPath bloat_analysis: false, caller_path: None, }; - // Process-wide; FARM_ENV keeps the other parity tests out meanwhile. + // Process-wide; the caller holds crate::ENV_LOCK. std::env::set_var("FBUILD_INCLUDE_FARM", if farm { "1" } else { "0" }); let result = tokio::time::timeout( REAL_BUILD_TIMEOUT, @@ -192,7 +189,7 @@ fn mentions_farm(build_dir: &Path) -> bool { async fn assert_farm_parity(fixture: &str, env_name: &str) { install_test_compile_backend().await; - let _guard = FARM_ENV.lock().await; + let _env = crate::ENV_LOCK.lock().await; let fixtures = Path::new(env!("CARGO_MANIFEST_DIR")).join("../../tests/platform"); let tmp = tempfile::TempDir::new().unwrap(); let project_dir = tmp.path().join(fixture); diff --git a/crates/fbuild-build/tests/env_isolated/main.rs b/crates/fbuild-build/tests/env_isolated/main.rs new file mode 100644 index 000000000..0db0953df --- /dev/null +++ b/crates/fbuild-build/tests/env_isolated/main.rs @@ -0,0 +1,14 @@ +//! Integration tests that change process-wide `FBUILD_*` / `ZCCACHE_*` +//! environment variables (FastLED/fbuild#1577 category `env_isolated`). +//! +//! They live apart from `tests/it` so an env change can never leak into an +//! unrelated test, and every test here holds [`ENV_LOCK`] for its whole body +//! so they cannot race each other either. + +mod avr_build; +mod dev_daemon_namespace_isolation; +mod eh_frame_strip_esp32; +mod esp32_include_farm_parity; + +/// Held by every test in this binary for its whole body. +pub(crate) static ENV_LOCK: tokio::sync::Mutex<()> = tokio::sync::Mutex::const_new(()); diff --git a/crates/fbuild-build/tests/it/clangd_check_parity.rs b/crates/fbuild-build/tests/it/clangd_check_parity.rs index 44df073b7..f17c968d8 100644 --- a/crates/fbuild-build/tests/it/clangd_check_parity.rs +++ b/crates/fbuild-build/tests/it/clangd_check_parity.rs @@ -36,7 +36,7 @@ use fbuild_core::BuildProfile; /// indexing). Generous — cold AVR toolchain/core downloads can take a few /// minutes; a warm cache (the common case once #1194-era CI has run once) /// finishes in seconds. Mirrors the pattern in -/// `crates/fbuild-build/tests/avr_build.rs` (FastLED/fbuild#806). +/// `crates/fbuild-build/tests/env_isolated/avr_build.rs` (FastLED/fbuild#806). const HARNESS_TIMEOUT: Duration = Duration::from_secs(600); /// Diagnostic substrings that are known-benign and must never fail the @@ -126,7 +126,7 @@ fn unexpected_error_diagnostics(output: &str) -> Vec<&str> { } /// Generate the IDE-flavored `compile_commands.json` for `tests/platform/uno` -/// via the same in-process orchestrator path `avr_build.rs` uses (no daemon, +/// via the same in-process orchestrator path `env_isolated/avr_build.rs` uses (no daemon, /// no CLI subprocess — `compiledb_only: true` skips actual compilation and /// linking, so this is the "lighter path" mentioned in FastLED/fbuild#1076: /// generate the DB without paying for a full AVR link). diff --git a/crates/fbuild-build/tests/it/compile_many_two_stage.rs b/crates/fbuild-build/tests/it/compile_many_two_stage.rs index 5ec686337..bc0c1db06 100644 --- a/crates/fbuild-build/tests/it/compile_many_two_stage.rs +++ b/crates/fbuild-build/tests/it/compile_many_two_stage.rs @@ -4,7 +4,7 @@ //! These tests inject a mock [`SketchBuilder`] so we exercise the //! orchestration layer (stage counts, parallelism, output-path //! uniqueness, input ordering) without dragging in a real toolchain. -//! Real-toolchain coverage lives in `avr_build.rs` etc. and is +//! Real-toolchain coverage lives in `../env_isolated/avr_build.rs` etc. and is //! `#[ignore]`-gated to keep `uv run test` fast. use std::collections::HashSet; diff --git a/crates/fbuild-build/tests/it/main.rs b/crates/fbuild-build/tests/it/main.rs index 9eb201b18..1d5cea594 100644 --- a/crates/fbuild-build/tests/it/main.rs +++ b/crates/fbuild-build/tests/it/main.rs @@ -7,7 +7,6 @@ mod clangd_check_parity; mod compile_many_stage2_perf; mod compile_many_two_stage; mod esp32_build; -mod esp32_include_farm_parity; mod esp32s3_size_parity; mod flag_escaping_lint; mod lite_scons_acceptance; diff --git a/crates/fbuild-config/Cargo.toml b/crates/fbuild-config/Cargo.toml index dbe69caf9..e36580a25 100644 --- a/crates/fbuild-config/Cargo.toml +++ b/crates/fbuild-config/Cargo.toml @@ -12,6 +12,8 @@ publish = false [[bin]] name = "enrich_boards" path = "src/bin/enrich_boards.rs" +# No #[test] in the tool; skip its empty harness (FastLED/fbuild#1577). +test = false [dependencies] fbuild-core = { path = "../fbuild-core" } diff --git a/crates/fbuild-daemon/Cargo.toml b/crates/fbuild-daemon/Cargo.toml index aeec687ef..c1a7d5cb6 100644 --- a/crates/fbuild-daemon/Cargo.toml +++ b/crates/fbuild-daemon/Cargo.toml @@ -13,6 +13,12 @@ publish = false name = "fbuild-daemon" path = "src/main.rs" +[[bin]] +name = "containment_harness" +path = "src/bin/containment_harness.rs" +# No #[test] in the harness; skip its empty test binary (FastLED/fbuild#1577). +test = false + [lib] name = "fbuild_daemon" path = "src/lib.rs" diff --git a/crates/fbuild-packages/Cargo.toml b/crates/fbuild-packages/Cargo.toml index cbadfc151..2e446b86b 100644 --- a/crates/fbuild-packages/Cargo.toml +++ b/crates/fbuild-packages/Cargo.toml @@ -9,6 +9,12 @@ license.workspace = true # this member exists purely for internal compile parallelism. FastLED/fbuild#1008. publish = false +# The lib has no unit tests (its tests live in tests/it), so don't build and +# link an empty harness. FastLED/fbuild#1577; ci/check_test_layout.py fails if +# a #[test] is added to src/ while this is set. +[lib] +test = false + [dependencies] # FastLED/fbuild#1008 Phase B — this crate is now a thin facade re-exporting # the fetch primitives + the parallel library / toolchain crates. diff --git a/crates/fbuild-packages/tests/it/main.rs b/crates/fbuild-packages/tests/it/main.rs index b275293fa..12084a109 100644 --- a/crates/fbuild-packages/tests/it/main.rs +++ b/crates/fbuild-packages/tests/it/main.rs @@ -4,3 +4,4 @@ mod disk_cache_schema_migration; mod lnk_e2e; +mod qemu_linux_runtime; diff --git a/crates/fbuild-toolchain/tests/qemu_linux_runtime.rs b/crates/fbuild-packages/tests/it/qemu_linux_runtime.rs similarity index 100% rename from crates/fbuild-toolchain/tests/qemu_linux_runtime.rs rename to crates/fbuild-packages/tests/it/qemu_linux_runtime.rs diff --git a/crates/fbuild-paths/src/dev_daemon_namespace.rs b/crates/fbuild-paths/src/dev_daemon_namespace.rs index de89d95ad..2b14af26d 100644 --- a/crates/fbuild-paths/src/dev_daemon_namespace.rs +++ b/crates/fbuild-paths/src/dev_daemon_namespace.rs @@ -15,7 +15,7 @@ //! This module previously claimed the export was "inert until fbuild repins //! a zccache release containing it". That was wrong: endpoint namespacing is //! already present at the pinned rev, and the isolation has worked since the -//! stamp landed. `crates/fbuild-build-engine/tests/ +//! stamp landed. `crates/fbuild-build/tests/env_isolated/ //! dev_daemon_namespace_isolation.rs` pins the contract so a future repin //! cannot drop it silently. What remains zccache-side (zccache#1362) is //! zccache *deriving its own* stamp when nothing exported one — which fbuild diff --git a/crates/fbuild-python/Cargo.toml b/crates/fbuild-python/Cargo.toml index fa1b6cf92..1ad2d526d 100644 --- a/crates/fbuild-python/Cargo.toml +++ b/crates/fbuild-python/Cargo.toml @@ -44,7 +44,7 @@ tracing = { workspace = true } [dev-dependencies] tempfile = { workspace = true } tracing-subscriber = { workspace = true } -# Only pulled in for the `tests/python_facades.rs` integration binary, which +# Only pulled in for the `tests/python_facades/` integration binary, which # embeds CPython to exercise the Python-visible facades under real GIL and # asyncio behavior (FastLED/fbuild#1485 §5.2). Cargo's per-target feature # resolution keeps this out of the normal `cdylib`/`rlib` build. diff --git a/crates/fbuild-python/tests/README.md b/crates/fbuild-python/tests/README.md index dfbbac8a4..434b15fab 100644 --- a/crates/fbuild-python/tests/README.md +++ b/crates/fbuild-python/tests/README.md @@ -2,8 +2,10 @@ Repository-level contract tests for the `fbuild-python` PyO3 extension. -- `pyo3_policy.rs` keeps the PyO3 dependency family and cross-build workflow policy in sync. -- `python_facades.rs` — embedded-CPython integration tests for `SerialMonitor` / +One test binary, `python_facades/` (FastLED/fbuild#1577): + +- `python_facades/pyo3_policy.rs` keeps the PyO3 dependency family and cross-build workflow policy in sync (runs in the normal test sweep). +- `python_facades/main.rs`, `cases.rs`, `extended.rs` — embedded-CPython integration tests for `SerialMonitor` / `AsyncSerialMonitor` (FastLED/fbuild#1485 §5.2, "AT-P" tests). Needs `libpython` at link and run time (the `pyo3` `auto-initialize` dev-dependency feature), so every test is `#[ignore]`d and run separately diff --git a/crates/fbuild-python/tests/python_facades.rs b/crates/fbuild-python/tests/python_facades/main.rs similarity index 99% rename from crates/fbuild-python/tests/python_facades.rs rename to crates/fbuild-python/tests/python_facades/main.rs index 568d77cda..c2a9d3f4a 100644 --- a/crates/fbuild-python/tests/python_facades.rs +++ b/crates/fbuild-python/tests/python_facades/main.rs @@ -387,10 +387,9 @@ fn run_snippet(py: pyo3::Python<'_>, code: &str) { }); } -#[path = "python_facades/cases.rs"] mod cases; -#[path = "python_facades/extended.rs"] mod extended; +mod pyo3_policy; /// FastLED/fbuild#1487: the test binary must load the `libpython` belonging to /// the interpreter it embeds, found through its own RUNPATH rather than a diff --git a/crates/fbuild-python/tests/pyo3_policy.rs b/crates/fbuild-python/tests/python_facades/pyo3_policy.rs similarity index 100% rename from crates/fbuild-python/tests/pyo3_policy.rs rename to crates/fbuild-python/tests/python_facades/pyo3_policy.rs diff --git a/crates/fbuild-toolchain/tests/README.md b/crates/fbuild-toolchain/tests/README.md deleted file mode 100644 index 0afada345..000000000 --- a/crates/fbuild-toolchain/tests/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# fbuild-toolchain integration tests - -Tests that exercise toolchain resolution against the real network and the real -package cache, rather than in-process fixtures. - -- **`qemu_linux_runtime.rs`** — Linux-only. Proves fbuild can start Espressif - QEMU on a host that carries none of libslirp / libSDL2 / libpixman, by - provisioning its own runtime-library bundle. `#[ignore]`d by default because - it downloads QEMU (~15 MB) and, when needed, the bundle (~5 MB). Run in CI by - `.github/workflows/qemu-linux-runtime.yml` on a stock `ubuntu-latest` runner - with **no** apt preinstall step — that missing preinstall is the point of the - test. - -Run locally on Linux: - -```bash -soldr cargo test -p fbuild-toolchain --test qemu_linux_runtime -- --ignored --nocapture -``` diff --git a/dylints/ban_std_pathbuf/src/allowlist.txt b/dylints/ban_std_pathbuf/src/allowlist.txt index b0bba370b..459e2bd37 100644 --- a/dylints/ban_std_pathbuf/src/allowlist.txt +++ b/dylints/ban_std_pathbuf/src/allowlist.txt @@ -91,7 +91,7 @@ crates/fbuild-build-arm/src/teensy/teensy_compiler.rs crates/fbuild-build-arm/src/teensy/teensy_linker.rs crates/fbuild-build-engine/src/zccache.rs crates/fbuild-build-engine/src/zccache_embedded.rs -crates/fbuild-build/tests/avr_build.rs +crates/fbuild-build/tests/env_isolated/avr_build.rs crates/fbuild-build/tests/it/cache_survives_tar_extract.rs crates/fbuild-build/tests/it/compile_many_stage2_perf.rs crates/fbuild-build/tests/it/compile_many_two_stage.rs diff --git a/dylints/enforce_platform_boundary/src/baseline.txt b/dylints/enforce_platform_boundary/src/baseline.txt index a3083a999..28d83d2a5 100644 --- a/dylints/enforce_platform_boundary/src/baseline.txt +++ b/dylints/enforce_platform_boundary/src/baseline.txt @@ -41,4 +41,4 @@ crates/fbuild-toolchain/src/toolchain/esp_qemu.rs attr_cfg windows 5 crates/fbuild-toolchain/src/toolchain/esp_qemu_runtime.rs attr_cfg target_os 0 crates/fbuild-toolchain/src/toolchain/esp_qemu_runtime.rs attr_cfg target_os 1 crates/fbuild-toolchain/src/toolchain/esp_qemu_runtime.rs attr_cfg target_os 2 -crates/fbuild-toolchain/tests/qemu_linux_runtime.rs attr_cfg target_os 0 +crates/fbuild-packages/tests/it/qemu_linux_runtime.rs attr_cfg target_os 0 From b333ef12c26c40e9486f97b72e998dbeca62558b Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Tue, 29 Sep 2026 22:28:38 -0700 Subject: [PATCH 3/4] chore(platform-boundary): follow the moved test files in ledger, baseline, inventory --- ci/platform_boundary_ledger.tsv | 4 ++-- ci/platform_boundary_research.tsv | 6 +++--- dylints/enforce_platform_boundary/src/baseline.txt | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ci/platform_boundary_ledger.tsv b/ci/platform_boundary_ledger.tsv index d69b2cc3a..e59f0ec5c 100644 --- a/ci/platform_boundary_ledger.tsv +++ b/ci/platform_boundary_ledger.tsv @@ -24,6 +24,7 @@ crates/fbuild-daemon/src/handlers/websockets_tests.rs native_path libc:: 6 proce crates/fbuild-daemon/src/handlers/websockets_tests.rs native_path libc:: 7 process host_mechanic crates/fbuild-daemon/src/handlers/websockets_tests.rs native_path libc:: 8 process host_mechanic crates/fbuild-daemon/src/handlers/websockets_tests.rs native_path libc:: 9 process host_mechanic +crates/fbuild-packages/tests/it/qemu_linux_runtime.rs attr_cfg #![cfg(target_os=)] 0 host host_mechanic crates/fbuild-paths/src/dev_daemon_namespace.rs native_path std::env::current_exe 0 host_executable host_mechanic crates/fbuild-paths/src/executable_hash.rs attr_cfg #[cfg(all(test,unix))] 0 host host_mechanic crates/fbuild-paths/src/executable_hash.rs attr_cfg #[cfg(not(unix))] 0 host host_mechanic @@ -32,7 +33,7 @@ crates/fbuild-paths/src/executable_hash.rs attr_cfg #[cfg(unix)] 1 host host_mec crates/fbuild-paths/src/executable_hash.rs attr_cfg #[cfg(unix)] 2 host host_mechanic crates/fbuild-paths/src/executable_hash.rs attr_cfg #[cfg(unix)] 3 host host_mechanic crates/fbuild-paths/src/executable_hash.rs attr_cfg #[cfg(unix)] 4 host host_mechanic -crates/fbuild-python/tests/python_facades.rs native_path std::env::current_exe 0 host_executable host_mechanic +crates/fbuild-python/tests/python_facades/main.rs native_path std::env::current_exe 0 host_executable host_mechanic crates/fbuild-toolchain/src/toolchain/esp_qemu.rs attr_cfg #[cfg(not(windows))] 0 host_executable host_mechanic crates/fbuild-toolchain/src/toolchain/esp_qemu.rs attr_cfg #[cfg(not(windows))] 1 host_executable host_mechanic crates/fbuild-toolchain/src/toolchain/esp_qemu.rs attr_cfg #[cfg(windows)] 0 host_executable host_mechanic @@ -42,4 +43,3 @@ crates/fbuild-toolchain/src/toolchain/esp_qemu.rs attr_cfg #[cfg(windows)] 3 hos crates/fbuild-toolchain/src/toolchain/esp_qemu_runtime.rs attr_cfg #[cfg(not(target_os=))] 0 host_executable host_artifact_policy crates/fbuild-toolchain/src/toolchain/esp_qemu_runtime.rs attr_cfg #[cfg(target_os=)] 0 host_executable host_artifact_policy crates/fbuild-toolchain/src/toolchain/esp_qemu_runtime.rs attr_cfg #[cfg_attr(not(target_os=),allow(dead_code))] 0 host_executable host_artifact_policy -crates/fbuild-toolchain/tests/qemu_linux_runtime.rs attr_cfg #![cfg(target_os=)] 0 host_executable host_artifact_policy diff --git a/ci/platform_boundary_research.tsv b/ci/platform_boundary_research.tsv index e9828c4d3..2463c3189 100644 --- a/ci/platform_boundary_research.tsv +++ b/ci/platform_boundary_research.tsv @@ -73,7 +73,7 @@ crates/fbuild-core/src/platform/windows/usb_pnp.rs 39 native_path windows_sys:: crates/fbuild-core/src/platform/windows/usb_pnp.rs 40 native_path windows_sys:: process host_mechanic crates/fbuild-core/tests/it/platformio_package_resolution.rs 5 attr_cfg #[cfg(windows)] host host_mechanic crates/fbuild-core/tests/it/platformio_package_resolution.rs 107 attr_cfg #[cfg(windows)] host host_mechanic -crates/fbuild-daemon/Cargo.toml 68 native_dependency libc process host_mechanic +crates/fbuild-daemon/Cargo.toml 74 native_dependency libc process host_mechanic crates/fbuild-daemon/src/handlers/emulator/tests_npm_cache.rs 146 attr_cfg #[cfg(windows)] host_executable host_artifact_policy crates/fbuild-daemon/src/handlers/emulator/tests_process.rs 9 attr_cfg #[cfg(windows)] host_executable host_artifact_policy crates/fbuild-daemon/src/handlers/emulator/tests_process.rs 21 attr_cfg #[cfg(not(windows))] host_executable host_artifact_policy @@ -96,6 +96,7 @@ crates/fbuild-daemon/src/handlers/websockets_tests.rs 340 native_path libc:: pro crates/fbuild-daemon/src/handlers/websockets_tests.rs 342 native_path libc:: process host_mechanic crates/fbuild-daemon/src/handlers/websockets_tests.rs 345 native_path libc:: process host_mechanic crates/fbuild-daemon/src/handlers/websockets_tests.rs 348 native_path libc:: process host_mechanic +crates/fbuild-packages/tests/it/qemu_linux_runtime.rs 18 attr_cfg #![cfg(target_os=)] host host_mechanic crates/fbuild-paths/src/dev_daemon_namespace.rs 91 native_path std::env::current_exe host_executable host_mechanic crates/fbuild-paths/src/executable_hash.rs 6 attr_cfg #[cfg(unix)] host host_mechanic crates/fbuild-paths/src/executable_hash.rs 9 attr_cfg #[cfg(unix)] host host_mechanic @@ -104,7 +105,7 @@ crates/fbuild-paths/src/executable_hash.rs 66 attr_cfg #[cfg(not(unix))] host ho crates/fbuild-paths/src/executable_hash.rs 71 attr_cfg #[cfg(unix)] host host_mechanic crates/fbuild-paths/src/executable_hash.rs 76 attr_cfg #[cfg(unix)] host host_mechanic crates/fbuild-paths/src/executable_hash.rs 85 attr_cfg #[cfg(all(test,unix))] host host_mechanic -crates/fbuild-python/tests/python_facades.rs 317 native_path std::env::current_exe host_executable host_mechanic +crates/fbuild-python/tests/python_facades/main.rs 317 native_path std::env::current_exe host_executable host_mechanic crates/fbuild-toolchain/src/toolchain/esp_qemu.rs 528 attr_cfg #[cfg(windows)] host_executable host_mechanic crates/fbuild-toolchain/src/toolchain/esp_qemu.rs 534 attr_cfg #[cfg(windows)] host_executable host_mechanic crates/fbuild-toolchain/src/toolchain/esp_qemu.rs 565 attr_cfg #[cfg(not(windows))] host_executable host_mechanic @@ -114,4 +115,3 @@ crates/fbuild-toolchain/src/toolchain/esp_qemu.rs 755 attr_cfg #[cfg(windows)] h crates/fbuild-toolchain/src/toolchain/esp_qemu_runtime.rs 253 attr_cfg #[cfg_attr(not(target_os=),allow(dead_code))] host_executable host_artifact_policy crates/fbuild-toolchain/src/toolchain/esp_qemu_runtime.rs 295 attr_cfg #[cfg(not(target_os=))] host_executable host_artifact_policy crates/fbuild-toolchain/src/toolchain/esp_qemu_runtime.rs 301 attr_cfg #[cfg(target_os=)] host_executable host_artifact_policy -crates/fbuild-toolchain/tests/qemu_linux_runtime.rs 18 attr_cfg #![cfg(target_os=)] host_executable host_artifact_policy diff --git a/dylints/enforce_platform_boundary/src/baseline.txt b/dylints/enforce_platform_boundary/src/baseline.txt index 28d83d2a5..38e408194 100644 --- a/dylints/enforce_platform_boundary/src/baseline.txt +++ b/dylints/enforce_platform_boundary/src/baseline.txt @@ -23,6 +23,7 @@ crates/fbuild-daemon/src/handlers/websockets_tests.rs native_import libc 6 crates/fbuild-daemon/src/handlers/websockets_tests.rs native_import libc 7 crates/fbuild-daemon/src/handlers/websockets_tests.rs native_import libc 8 crates/fbuild-daemon/src/handlers/websockets_tests.rs native_import libc 9 +crates/fbuild-packages/tests/it/qemu_linux_runtime.rs attr_cfg target_os 0 crates/fbuild-paths/src/dev_daemon_namespace.rs native_import std::env::current_exe 0 crates/fbuild-paths/src/executable_hash.rs attr_cfg unix 0 crates/fbuild-paths/src/executable_hash.rs attr_cfg unix 1 @@ -31,7 +32,7 @@ crates/fbuild-paths/src/executable_hash.rs attr_cfg unix 3 crates/fbuild-paths/src/executable_hash.rs attr_cfg unix 4 crates/fbuild-paths/src/executable_hash.rs attr_cfg unix 5 crates/fbuild-paths/src/executable_hash.rs attr_cfg unix 6 -crates/fbuild-python/tests/python_facades.rs native_import std::env::current_exe 0 +crates/fbuild-python/tests/python_facades/main.rs native_import std::env::current_exe 0 crates/fbuild-toolchain/src/toolchain/esp_qemu.rs attr_cfg windows 0 crates/fbuild-toolchain/src/toolchain/esp_qemu.rs attr_cfg windows 1 crates/fbuild-toolchain/src/toolchain/esp_qemu.rs attr_cfg windows 2 @@ -41,4 +42,3 @@ crates/fbuild-toolchain/src/toolchain/esp_qemu.rs attr_cfg windows 5 crates/fbuild-toolchain/src/toolchain/esp_qemu_runtime.rs attr_cfg target_os 0 crates/fbuild-toolchain/src/toolchain/esp_qemu_runtime.rs attr_cfg target_os 1 crates/fbuild-toolchain/src/toolchain/esp_qemu_runtime.rs attr_cfg target_os 2 -crates/fbuild-packages/tests/it/qemu_linux_runtime.rs attr_cfg target_os 0 From fc4b6cd1291501465e875175385d5cf38cbc35bd Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Tue, 29 Sep 2026 22:31:01 -0700 Subject: [PATCH 4/4] ci(check-ubuntu): give the check and python-facade jobs their own build-cache store setup-soldr keys the zccache build cache on toolchain + job suffix + Cargo.lock. With no suffix these jobs shared one key with ~10 other workflows; the first small job to save it froze a 165 MB entry (an exact hit never re-saves), so every run of the PR gate restored it and recompiled ~240 crates (28-32% hit rate, ~380 s of the Test step). --- .github/workflows/check-ubuntu.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/check-ubuntu.yml b/.github/workflows/check-ubuntu.yml index 9d0577797..c1ba342eb 100644 --- a/.github/workflows/check-ubuntu.yml +++ b/.github/workflows/check-ubuntu.yml @@ -44,6 +44,11 @@ jobs: id: setup-soldr uses: zackees/setup-soldr@67ed4018aca013f8388050ac9bc264244f9b742c with: + # Own build-cache store (setup-soldr#237): with no suffix this job + # shared one Cargo.lock-keyed entry with ~10 other workflows, and + # the first small job to save it (165 MB) froze it -- an exact hit + # never re-saves -- so every run recompiled ~240 crates. + cache-key-suffix: check-ubuntu cache: true build-cache: true target-cache: true @@ -103,6 +108,7 @@ jobs: - name: Setup soldr uses: zackees/setup-soldr@67ed4018aca013f8388050ac9bc264244f9b742c with: + cache-key-suffix: python-facades cache: true build-cache: true target-cache: true