diff --git a/block/src/formats/vhdx/internal/mod.rs b/block/src/formats/vhdx/internal/mod.rs index 3baa7ef0b..c8f5a2fd1 100644 --- a/block/src/formats/vhdx/internal/mod.rs +++ b/block/src/formats/vhdx/internal/mod.rs @@ -239,34 +239,16 @@ impl AsRawFd for Vhdx { #[cfg(test)] mod tests { use std::fs; - use std::process::Command; - - use vmm_sys_util::tempfile::TempFile; use super::*; - - /// Generate a small dynamic VHDX with `qemu-img`. Returns `None` (and the - /// test is skipped) when `qemu-img` is unavailable, e.g. in minimal CI. - fn dynamic_vhdx(size_mib: u64) -> Option { - let tf = TempFile::new().unwrap(); - let path = tf.as_path(); - let status = Command::new("qemu-img") - .args(["create", "-f", "vhdx", "-o", "subformat=dynamic"]) - .arg(path) - .arg(format!("{size_mib}M")) - .status(); - match status { - Ok(s) if s.success() => Some(tf), - _ => None, - } - } + use crate::formats::vhdx::test_util::create_dynamic_vhdx; /// An unaligned sector write under a forced O_DIRECT alignment must go /// through `AlignedFile`'s read-modify-write bounce (the data block and the /// BAT update both land at unaligned host offsets) and read back intact. #[test] fn unaligned_write_is_rmw() { - let Some(tf) = dynamic_vhdx(16) else { + let Some(tf) = create_dynamic_vhdx(16) else { eprintln!("skipping unaligned_write_is_rmw: qemu-img unavailable"); return; }; @@ -299,7 +281,7 @@ mod tests { #[test] fn header_update_survives_reopen() { - let Some(tf) = dynamic_vhdx(16) else { + let Some(tf) = create_dynamic_vhdx(16) else { eprintln!("skipping header_update_survives_reopen: qemu-img unavailable"); return; }; diff --git a/block/src/formats/vhdx/mod.rs b/block/src/formats/vhdx/mod.rs index 295413357..139401029 100644 --- a/block/src/formats/vhdx/mod.rs +++ b/block/src/formats/vhdx/mod.rs @@ -10,6 +10,8 @@ //! images. pub mod internal; +#[cfg(test)] +pub(crate) mod test_util; pub(crate) mod worker; use std::fs::File; diff --git a/block/src/formats/vhdx/test_util.rs b/block/src/formats/vhdx/test_util.rs new file mode 100644 index 000000000..2b5ddd05e --- /dev/null +++ b/block/src/formats/vhdx/test_util.rs @@ -0,0 +1,25 @@ +// Copyright 2026 The Cloud Hypervisor Authors. All rights reserved. +// +// SPDX-License-Identifier: Apache-2.0 + +//! Shared test helpers for VHDX image tests. + +use std::process::Command; + +use vmm_sys_util::tempfile::TempFile; + +/// Generate a small dynamic VHDX with `qemu-img`. Returns `None` (and the +/// test is skipped) when `qemu-img` is unavailable, e.g. in minimal CI. +pub(crate) fn create_dynamic_vhdx(size_mib: u64) -> Option { + let tf = TempFile::new().unwrap(); + let path = tf.as_path(); + let status = Command::new("qemu-img") + .args(["create", "-f", "vhdx", "-o", "subformat=dynamic"]) + .arg(path) + .arg(format!("{size_mib}M")) + .status(); + match status { + Ok(s) if s.success() => Some(tf), + _ => None, + } +}