From c64dd5ce0687358c216e4aae03689d598161861a Mon Sep 17 00:00:00 2001 From: Mike Solar Date: Thu, 24 Sep 2026 15:06:08 +0800 Subject: [PATCH] fix(ci): give the Windows tests vcpkg's DLLs; skip root-only perm checks - Windows: the first test executable died with STATUS_DLL_NOT_FOUND (0xc0000135) because vcpkg's x64-windows DLLs (ffmpeg and its codecs) were not on PATH; add vcpkg_installed/x64-windows/bin in the configure step. - openKylin: failure_paths_report_cleanly asserts that a read-only library write fails, but the container runs as root, which bypasses the file permission bits (CAP_DAC_OVERRIDE) and the write succeeds; skip that sub-check when euid is 0 (read from /proc/self/status on Linux) and note it in the log. --- .github/workflows/ci.yml | 4 +++ crates/oak-storage/tests/database_test.rs | 33 +++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index afb158553..b3a38c51e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -340,6 +340,10 @@ jobs: "FFMPEG_DIR=$prefix" >> $env:GITHUB_ENV "PKG_CONFIG_PATH=$prefix\lib\pkgconfig" >> $env:GITHUB_ENV "$prefix\tools\pkgconf" >> $env:GITHUB_PATH + # The test binaries link vcpkg's dynamic DLLs (ffmpeg and its + # codecs): without this the runner reports STATUS_DLL_NOT_FOUND + # when the first test executable starts. + "$prefix\bin" >> $env:GITHUB_PATH # Bundled OCIO: ocio-sys' vendored sources build with the MSVC # toolchain (what they need — the MSYS2 package was the # workaround, not the preference), so no OCIO_INSTALL_DIR and diff --git a/crates/oak-storage/tests/database_test.rs b/crates/oak-storage/tests/database_test.rs index 1a6e8a31c..a80ef23b7 100644 --- a/crates/oak-storage/tests/database_test.rs +++ b/crates/oak-storage/tests/database_test.rs @@ -1090,6 +1090,28 @@ fn invalid_uri_matrix() { ); } +/// Linux CI containers run as root, which bypasses the file permission bits +/// (`CAP_DAC_OVERRIDE`), so the read-only failure paths cannot be exercised +/// there. +#[cfg(target_os = "linux")] +fn running_as_root() -> bool { + std::fs::read_to_string("/proc/self/status") + .ok() + .and_then(|status| { + status + .lines() + .find(|line| line.starts_with("Uid:")) + .and_then(|line| line.split_whitespace().nth(1).map(str::to_string)) + }) + .map(|uid| uid == "0") + .unwrap_or(false) +} + +#[cfg(not(target_os = "linux"))] +fn running_as_root() -> bool { + false +} + /// Write failures surface as errors, not panics or silent corruption: /// (a) read-only database files, (b) an out-of-range undo target, and /// (c) concurrent writers on one file. @@ -1120,8 +1142,15 @@ fn failure_paths_report_cleanly() { std::fs::set_permissions(f, p).unwrap(); } let fresh = DatabaseBackend::new(); - let err = save_project(&fresh, &project, &uri).err().unwrap(); - assert_eq!(err.code(), OAKSTORAGE_E_IO, "read-only library write must fail"); + let result = save_project(&fresh, &project, &uri); + if running_as_root() { + // The openKylin CI container runs as root: the read-only bits do not + // stop the write, so the failure cannot be asserted here. + println!("SKIP: read-only library write check needs an unprivileged user"); + } else { + let err = result.err().expect("read-only library write must fail"); + assert_eq!(err.code(), OAKSTORAGE_E_IO, "read-only library write must fail"); + } for (f, p) in targets.iter().zip(saved) { std::fs::set_permissions(f, p).unwrap(); }