fix(tests): make the platform-specific suites portable and deterministic
Four independent CI failures the first real cross-platform run surfaced: - macOS SIGSEGV: the real-GL unit tests in gl_bridge ran wherever CGL is available, including the headless CI runner. Gate them with the same OAK_GPU_TESTS switch the integration GL tests already use (skip on CI, opt in on a real Mac). - Windows build: examples compile under `cargo test`, and bench_playback used libc::getrusage unconditionally. Keep the Unix CPU accounting behind #[cfg(unix)] and report zero CPU seconds elsewhere. - openKylin arm64: engine_without_a_project_hits_the_guard_paths assumed the library backend was unconfigured while a parallel config test transiently set Storage/Backend=sqlite. Take the shared config lock and pin the key off for the test's duration. - openKylin x64: the prefetch smoke test asserted an exact decode count, but the hand-off LRU holds only DECODE_LRU_CAP (2) frames, so a request can miss the prefetched copy under scheduling pressure and re-run the producer (the eval cache still serves the pixels). Bound the count instead of pinning it; the deterministic sibling test pins read-ahead usage.
This commit is contained in:
@@ -12576,6 +12576,13 @@ mod tests {
|
||||
/// (early return / Err / empty data source) without panicking.
|
||||
#[gpui::test]
|
||||
async fn engine_without_a_project_hits_the_guard_paths(cx: &mut gpui::TestAppContext) {
|
||||
// The library guards below depend on the process-global storage
|
||||
// config: serialize with the config tests (the shared lock) and pin
|
||||
// the backend OFF so a concurrent test's transient "sqlite" cannot
|
||||
// make `library_create_project` succeed mid-assertion.
|
||||
let _guard = crate::oakui::graphops::test_lock();
|
||||
let _backend = ConfigRestore::of(CONFIG_KEY_STORAGE_BACKEND);
|
||||
crate::oakui::real::config_set_string(CONFIG_KEY_STORAGE_BACKEND, "");
|
||||
let engine = cx.update(|cx| cx.new(RealEngine::create));
|
||||
|
||||
// Data sources on an empty engine.
|
||||
|
||||
@@ -801,7 +801,16 @@ mod tests {
|
||||
use crate::render::VideoParams;
|
||||
|
||||
/// GL 不可用时 skip(无 GPU 无头环境);可用时返回 guard。
|
||||
///
|
||||
/// macOS 的真实 CGL 验收与集成 GL 测试同一门禁:CI 无头且用例并行,
|
||||
/// 默认只做可用性探测;设 `OAK_GPU_TESTS=1` 才跑真实 GL 用例
|
||||
/// (`crates/oak-plugin/tests/gl_render_test.rs` 同约定)。
|
||||
fn maybe_gl() -> Option<GlGuard> {
|
||||
#[cfg(target_os = "macos")]
|
||||
if std::env::var_os("OAK_GPU_TESTS").is_none() {
|
||||
println!("SKIP: 真实 GL 桥用例需 OAK_GPU_TESTS(本机 GPU 验收;CI 一律跳过)");
|
||||
return None;
|
||||
}
|
||||
match acquire() {
|
||||
Ok(g) => Some(g),
|
||||
Err(e) => {
|
||||
|
||||
@@ -66,7 +66,10 @@ fn worker_bin() -> PathBuf {
|
||||
PathBuf::from("oak-worker")
|
||||
}
|
||||
|
||||
/// `(user, system)` CPU seconds of this process and its children.
|
||||
/// `(user, system)` CPU seconds of this process and its children (Unix
|
||||
/// `getrusage`; the benchmark's CPU accounting is Unix-only, the rest of
|
||||
/// the harness runs everywhere).
|
||||
#[cfg(unix)]
|
||||
fn cpu_times() -> (f64, f64) {
|
||||
fn rusage(who: i32) -> (f64, f64) {
|
||||
let mut usage: libc::rusage = unsafe { std::mem::zeroed() };
|
||||
@@ -81,6 +84,13 @@ fn cpu_times() -> (f64, f64) {
|
||||
(self_times.0 + children.0, self_times.1 + children.1)
|
||||
}
|
||||
|
||||
/// Windows has no `getrusage`; the harness still builds and runs, it just
|
||||
/// reports zero CPU seconds (`cargo test` compiles examples on every OS).
|
||||
#[cfg(not(unix))]
|
||||
fn cpu_times() -> (f64, f64) {
|
||||
(0.0, 0.0)
|
||||
}
|
||||
|
||||
/// One footage ticket over the whole timeline.
|
||||
fn footage_params(media: &str, time: Rational, width: i32, height: i32) -> VideoTicketParams {
|
||||
VideoTicketParams {
|
||||
|
||||
@@ -913,10 +913,25 @@ fn pipeline_playback_prefetches_ahead_of_the_render() {
|
||||
times.len() as u64,
|
||||
"every playback post queued its footage prefetch"
|
||||
);
|
||||
assert_eq!(
|
||||
// Each distinct frame is produced at least once. The hand-off LRU holds
|
||||
// only `DECODE_LRU_CAP` (2) frames, so under scheduling pressure a
|
||||
// request can miss the prefetched copy and re-run the producer; the
|
||||
// eval-side cache still serves the pixels without touching the media,
|
||||
// but the counter moves. Bound this to one production per command
|
||||
// (prefetch + request) instead of asserting an exact count; the
|
||||
// deterministic `pipeline_prefetch_is_the_frame_the_render_request_uses`
|
||||
// pins that the read-ahead is actually used.
|
||||
assert!(
|
||||
stats.decodes >= times.len() as u64,
|
||||
"each distinct frame is produced at least once ({} < {})",
|
||||
stats.decodes,
|
||||
times.len() as u64,
|
||||
"each distinct frame decodes exactly once (prefetch or rendezvous)"
|
||||
times.len()
|
||||
);
|
||||
assert!(
|
||||
stats.decodes <= 2 * times.len() as u64,
|
||||
"at most one production per prefetch and per request ({} > {})",
|
||||
stats.decodes,
|
||||
2 * times.len()
|
||||
);
|
||||
// Note: `procpool::main_heap_frame_copies` only counts the shm path,
|
||||
// which the thread pipeline never touches, so asserting it here would
|
||||
|
||||
Reference in New Issue
Block a user