fix(test): Docker 集成测试在无 daemon 环境优雅跳过而非失败
Some checks failed
CI / check (push) Has been cancelled
CI / build (push) Has been cancelled

docker.rs 的 4 个 test_run_in_container_* 此前直接 unwrap Docker 客户端,
在没有 Docker daemon 的环境(如 CI、纯服务端交叉编译检查)会 panic 失败,
拖累整套 cargo test 的退出码——即便这些测试本就无法在那里运行。

加 require_docker() 守卫:socket 缺失(DOCKER_CLIENT == None)或 daemon
无响应(轻量 version() 探测)时返回 None,测试 eprintln + 提前 return。

选动态探测而非 #[ignore]:#[ignore] 会在所有环境一律跳过、需
cargo test --ignored 显式触发;探测守卫让测试在有 Docker 时自动运行,
在无 Docker 的 CI 上静默放行,且在 --nocapture 下可见跳过原因。

验证:cargo test --bin yggdrasil 从 535 passed / 4 failed → 539 passed / 0 failed。
This commit is contained in:
xfy 2026-07-16 13:22:49 +08:00
parent fa8b1d9968
commit debe7dabe3

View File

@ -696,9 +696,27 @@ mod tests {
assert_eq!(host_config.memory_swap, Some(512 * 1024 * 1024));
}
/// 探测 Docker daemon 是否可用socket 缺失(`DOCKER_CLIENT == None`)或
/// daemon 无响应时返回 `None`。集成测试用它做动态守卫——daemon 在则跑,
/// 不在则显式跳过eprintln + 提前 return而非 panic 失败。
///
/// 这比 `#[ignore]` 更合适:`#[ignore]` 会在所有环境(含有 Docker 的开发机)
/// 一律跳过、且需 `cargo test --ignored` 显式触发;探测守卫让这些测试在
/// 有 Docker 时自动运行、在无 Docker 的 CI 上静默放行。
async fn require_docker() -> Option<&'static Docker> {
let docker = DOCKER_CLIENT.as_ref()?;
// socket 在但 daemon 挂了的情况靠这一步轻量只读调用兜住。
docker.version().await.ok()?;
Some(docker)
}
#[tokio::test]
#[serial_test::serial]
async fn test_run_in_container_success() {
if require_docker().await.is_none() {
eprintln!("skip: Docker daemon 不可用(未安装或未运行)");
return;
}
let limits = ResourceLimits {
cpu_cores: 1.0,
memory_mb: 128,
@ -725,6 +743,10 @@ mod tests {
#[tokio::test]
#[serial_test::serial]
async fn test_run_in_container_output_truncation() {
if require_docker().await.is_none() {
eprintln!("skip: Docker daemon 不可用(未安装或未运行)");
return;
}
let limits = ResourceLimits {
cpu_cores: 1.0,
memory_mb: 128,
@ -751,6 +773,10 @@ mod tests {
#[tokio::test]
#[serial_test::serial]
async fn test_run_in_container_timeout() {
if require_docker().await.is_none() {
eprintln!("skip: Docker daemon 不可用(未安装或未运行)");
return;
}
let limits = ResourceLimits {
cpu_cores: 1.0,
memory_mb: 128,
@ -774,7 +800,13 @@ mod tests {
#[serial_test::serial]
async fn test_run_in_container_cancellation() {
use bollard::query_parameters::ListContainersOptions;
let docker = get_docker().expect("test requires a running Docker daemon");
let docker = match require_docker().await {
Some(d) => d,
None => {
eprintln!("skip: Docker daemon 不可用(未安装或未运行)");
return;
}
};
let before = docker
.list_containers(Some(ListContainersOptions {