mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-25 10:37:11 -06:00
* CI: dev profile keeps line tables for workspace crates and no debug info for dependencies * Control server tests: persistent_requests_and_slow_replies_outlive_the_idle_read_timeout no longer races the idle timeout Each request (and the closing half-shutdown) reaches the socket before the worker reads, so on a slow machine only the reply waits outlast the 100 ms idle timeout, as the test intends. The idle test sends its input the same way, and the no-frames test allows 5 s instead of 2 s to give up. * CI: one integration-test binary per crate Each crate's tests/*.rs become modules of tests/it/main.rs (51 test files into 13 binaries, plus 6 that stay their own). Inner #![cfg] attributes move to the mod lines. Files that change state for the whole process keep a binary of their own: codecs jxl_tail_heap and raw sr2_heap (dhat global allocator), gpu shutdown, shutdown_first and memory, ui-egui shutdown. Docs, comments and the GPU probe name the new paths and targets (--test it <module>::); the CI report names an it binary's skips after the crate. * CI: tests under nextest, doctests apart, one wasm check xtask ci runs the tests with cargo nextest run --lib --bins --tests when cargo-nextest is installed, else cargo test with the same targets and a one-line notice; doctests run after them with cargo test --workspace --doc. The heif and hardware GPU steps use the same runner. Examples stay out of the test build (clippy --all-targets still checks them). Concurrent tests under nextest follow the RUST_TEST_THREADS cap (NEXTEST_TEST_THREADS). The wasm check is one cargo check --keep-going over the same crates, and clippy runs with --keep-going. * CI: tests run under cargo test by default, nextest with LIGHTCRAFT_NEXTEST=1 (per-process scene cache)
87 lines
3.7 KiB
Rust
87 lines
3.7 KiB
Rust
//! What GPU this machine offers the develop pipeline, as one JSON line: the capability probe of
|
|
//! `cargo xtask ci`, which is std + serde_json and has no wgpu of its own. Ignored in normal runs;
|
|
//! xtask runs it after the workspace tests, so it costs no extra build:
|
|
//! `cargo test --workspace --test it -- --ignored --exact gpu_probe::gpu_probe --nocapture`.
|
|
//!
|
|
//! - `LIGHTCRAFT_GPU_PROBE` unset: the compute device the pipeline picks (`available()`,
|
|
//! `adapter_name()`, `unavailable_reason()`), the backends it may use and the backends this build
|
|
//! contains.
|
|
//! - `LIGHTCRAFT_GPU_PROBE=<backend>` (`vulkan`, `metal`, `dx12`, `gl`): every adapter that
|
|
//! backend lists, software ones (lavapipe, llvmpipe, WARP) included. One backend per process, so
|
|
//! a driver that crashes while it is enumerated (issue #136) costs only its own line.
|
|
//!
|
|
//! Only reports: which adapters the pipeline accepts is `ctx.rs`'s policy.
|
|
|
|
use lightcraft_gpu::backend::{self, Backends};
|
|
|
|
const NAMES: [(&str, Backends); 4] = [("vulkan", Backends::VULKAN), ("metal", Backends::METAL), ("dx12", Backends::DX12), ("gl", Backends::GL)];
|
|
|
|
#[test]
|
|
#[ignore = "the capability probe of `cargo xtask ci`"]
|
|
fn gpu_probe() {
|
|
let line = match std::env::var("LIGHTCRAFT_GPU_PROBE").ok().filter(|b| !b.is_empty()) {
|
|
None => pipeline(),
|
|
Some(name) => adapters(&name),
|
|
};
|
|
// its own line, prefixed: libtest may have printed `test gpu_probe ... ` on this one
|
|
println!("\ngpu_probe: {line}");
|
|
}
|
|
|
|
fn names(set: Backends) -> String {
|
|
let list: Vec<String> = NAMES.iter().filter(|(_, b)| set.contains(*b)).map(|(n, _)| json_str(n)).collect();
|
|
format!("[{}]", list.join(","))
|
|
}
|
|
|
|
fn pipeline() -> String {
|
|
let available = lightcraft_gpu::available();
|
|
let opt = |s: Option<String>| s.map_or_else(|| "null".to_owned(), |s| json_str(&s));
|
|
let compiled = wgpu::Instance::enabled_backend_features();
|
|
format!(
|
|
"{{\"pipeline\":{{\"available\":{available},\"adapter\":{},\"reason\":{},\"backends\":{},\"compiled\":{}}}}}",
|
|
opt(lightcraft_gpu::adapter_name()),
|
|
opt(lightcraft_gpu::unavailable_reason()),
|
|
names(backend::compute_backends().unwrap_or(Backends::empty()) & compiled),
|
|
names(compiled),
|
|
)
|
|
}
|
|
|
|
fn adapters(name: &str) -> String {
|
|
let (_, set) = NAMES.iter().find(|(n, _)| *n == name).unwrap_or_else(|| panic!("unknown backend `{name}` (vulkan, metal, dx12, gl)"));
|
|
let mut desc = wgpu::InstanceDescriptor::new_without_display_handle();
|
|
desc.backends = *set;
|
|
desc.backend_options = backend::backend_options();
|
|
desc.flags = backend::instance_flags_from_env(desc.flags);
|
|
let instance = wgpu::Instance::new(desc);
|
|
let adapters: Vec<String> = pollster::block_on(instance.enumerate_adapters(*set))
|
|
.iter()
|
|
.map(|a| {
|
|
let i = a.get_info();
|
|
format!(
|
|
"{{\"name\":{},\"type\":{},\"vendor\":\"0x{:04x}\",\"device\":\"0x{:04x}\",\"driver\":{},\"driver_info\":{}}}",
|
|
json_str(&i.name),
|
|
json_str(&format!("{:?}", i.device_type)),
|
|
i.vendor,
|
|
i.device,
|
|
json_str(&i.driver),
|
|
json_str(&i.driver_info),
|
|
)
|
|
})
|
|
.collect();
|
|
format!("{{\"backend\":{},\"adapters\":[{}]}}", json_str(name), adapters.join(","))
|
|
}
|
|
|
|
/// A JSON string literal.
|
|
fn json_str(s: &str) -> String {
|
|
let mut out = String::from("\"");
|
|
for c in s.chars() {
|
|
match c {
|
|
'"' => out.push_str("\\\""),
|
|
'\\' => out.push_str("\\\\"),
|
|
c if u32::from(c) < 0x20 => out.push_str(&format!("\\u{:04x}", u32::from(c))),
|
|
c => out.push(c),
|
|
}
|
|
}
|
|
out.push('"');
|
|
out
|
|
}
|