block: qcow: Port tests to QcowTempDisk

Port tests over to QcowTempDisk and also over to QcowDisk rather than
QcowFile where necessary.

Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Rob Bradford <rbradford@meta.com>
This commit is contained in:
Rob Bradford
2026-06-05 14:56:20 +01:00
parent 31ee5e99e4
commit cfce14edd1
4 changed files with 237 additions and 320 deletions

View File

@@ -205,13 +205,12 @@ fn open_qcow2(
#[cfg(test)]
mod unit_tests {
use std::io::Write;
use std::path::Path;
use vmm_sys_util::tempfile::TempFile;
use super::*;
use crate::qcow::{QcowFile, RawFile};
use crate::formats::qcow;
fn default_options(path: &Path) -> DiskOpenOptions<'_> {
DiskOpenOptions {
@@ -247,12 +246,9 @@ mod unit_tests {
#[test]
fn detect_qcow2_image() {
let tmp = TempFile::new().unwrap();
{
let raw = RawFile::new(tmp.as_file().try_clone().unwrap(), false);
let mut qcow = QcowFile::new(raw, 3, 100 * 1024 * 1024, true).unwrap();
qcow.flush().unwrap();
}
let tmp = qcow::QcowTempDisk::new(100 * 1024 * 1024, None, false, true, false)
.unwrap()
.into_tempfile();
let path = tmp.as_path().to_owned();
let options = default_options(&path);
let opened = open_disk(&options).unwrap();

View File

@@ -18,6 +18,7 @@ use std::os::unix::io::AsRawFd;
use std::sync::Arc;
use std::{fmt, io};
use vm_memory::{Bytes, GuestAddress, GuestMemoryMmap};
#[cfg(test)]
use vmm_sys_util::tempfile::TempFile;
@@ -30,8 +31,9 @@ use self::internal::{MAX_NESTING_DEPTH, RawFile, parse_qcow};
#[cfg(feature = "io_uring")]
use self::worker::async_uring::QcowAsync;
use self::worker::sync::QcowSync;
use crate::async_io::{AsyncIo, BorrowedDiskFd, DiskFileError};
use crate::async_io::{AsyncIo, BorrowedDiskFd, DiskFileError, GuestMemoryTarget};
use crate::disk_file;
use crate::disk_file::AsyncDiskFile;
use crate::error::{BlockError, BlockErrorKind, BlockResult, ErrorOp};
/// Unified DiskFile wrapper for QCOW2 disk images.
@@ -102,6 +104,20 @@ impl QcowDisk {
use_io_uring,
})
}
/// Synchronous write convenience for tests and benchmarks.
pub fn write_all_at(&self, offset: u64, data: &[u8]) {
let mut async_io = self.create_async_io(1).unwrap();
let mem =
Arc::new(GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), data.len())]).unwrap());
mem.write_slice(data, GuestAddress(0)).unwrap();
let range = [(GuestAddress(0), data.len() as u32)];
let target = GuestMemoryTarget::new(Arc::clone(&mem), &range).unwrap();
async_io
.write_from_memory(offset as libc::off_t, target, 0)
.unwrap();
while async_io.next_completed_request().is_some() {}
}
}
/// Writes a fresh qcow2 layout into `file`
@@ -288,9 +304,6 @@ impl disk_file::AsyncDiskFile for QcowDisk {
#[cfg(test)]
mod unit_tests {
use vmm_sys_util::tempfile::TempFile;
use self::internal::{QcowFile, RawFile};
use super::*;
use crate::async_io::AsyncIo;
use crate::disk_file::{AsyncDiskFile, DiskSize, PhysicalSize};
@@ -298,12 +311,10 @@ mod unit_tests {
const TEST_SIZE: u64 = 0x5566_7788;
fn make_qcow_file() -> File {
let temp_file = TempFile::new().unwrap();
{
let raw = RawFile::new(temp_file.as_file().try_clone().unwrap(), false);
QcowFile::new(raw, 3, TEST_SIZE, true).unwrap();
}
temp_file.into_file()
QcowTempDisk::new(TEST_SIZE, None, false, true, false)
.unwrap()
.into_tempfile()
.into_file()
}
#[test]

View File

@@ -523,7 +523,7 @@ impl QcowAsync {
#[cfg(test)]
mod unit_tests {
use std::io::{Seek, SeekFrom, Write};
use std::io::Write;
use std::sync::Arc;
use std::thread;
@@ -534,9 +534,9 @@ mod unit_tests {
use crate::SECTOR_SIZE;
use crate::async_io::{AsyncIoCompletion, AsyncIoOperation, GuestMemoryTarget, OwnedIoBuffer};
use crate::disk_file::AsyncDiskFile;
use crate::formats::qcow::QcowDisk;
use crate::formats::qcow::common::unit_tests::compress_allocated_clusters;
use crate::formats::qcow::internal::{BackingFileConfig, ImageType, QcowFile, RawFile};
use crate::formats::qcow::internal::{BackingFileConfig, ImageType};
use crate::formats::qcow::{QcowDisk, QcowTempDisk};
fn create_disk_with_data(
file_size: u64,
@@ -544,14 +544,15 @@ mod unit_tests {
offset: u64,
sparse: bool,
) -> (TempFile, QcowDisk) {
let temp_file = TempFile::new().unwrap();
{
let raw_file = RawFile::new(temp_file.as_file().try_clone().unwrap(), false);
let mut qcow_file = QcowFile::new(raw_file, 3, file_size, sparse).unwrap();
qcow_file.seek(SeekFrom::Start(offset)).unwrap();
qcow_file.write_all(data).unwrap();
qcow_file.flush().unwrap();
}
let temp_file = if data.is_empty() {
QcowTempDisk::new(file_size, None, false, sparse, true)
.unwrap()
.into_tempfile()
} else {
let tmp_disk = QcowTempDisk::new(file_size, None, false, sparse, true).unwrap();
tmp_disk.disk().write_all_at(offset, data);
tmp_disk.into_tempfile()
};
let disk = QcowDisk::new(
temp_file.as_file().try_clone().unwrap(),
false,
@@ -573,15 +574,13 @@ mod unit_tests {
backing_temp.as_file().sync_all().unwrap();
let backing_path = backing_temp.as_path().to_str().unwrap().to_string();
let overlay_temp = TempFile::new().unwrap();
{
let raw = RawFile::new(overlay_temp.as_file().try_clone().unwrap(), false);
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Raw),
};
QcowFile::new_from_backing(raw, 3, file_size, &backing_config, true).unwrap();
}
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Raw),
};
let overlay_temp = QcowTempDisk::new(file_size, Some(&backing_config), false, true, false)
.unwrap()
.into_tempfile();
let disk = QcowDisk::new(
overlay_temp.as_file().try_clone().unwrap(),
@@ -722,11 +721,9 @@ mod unit_tests {
#[test]
fn test_qcow_async_write_read_roundtrip() {
let file_size = 100 * 1024 * 1024;
let temp_file = TempFile::new().unwrap();
{
let raw_file = RawFile::new(temp_file.as_file().try_clone().unwrap(), false);
QcowFile::new(raw_file, 3, file_size, true).unwrap();
}
let temp_file = QcowTempDisk::new(file_size, None, false, true, false)
.unwrap()
.into_tempfile();
let disk = QcowDisk::new(
temp_file.as_file().try_clone().unwrap(),
false,
@@ -805,11 +802,9 @@ mod unit_tests {
#[test]
fn test_qcow_async_sync_write_from_guest_memory() {
let file_size = 100 * 1024 * 1024;
let temp_file = TempFile::new().unwrap();
{
let raw_file = RawFile::new(temp_file.as_file().try_clone().unwrap(), false);
QcowFile::new(raw_file, 3, file_size, true).unwrap();
}
let temp_file = QcowTempDisk::new(file_size, None, false, true, false)
.unwrap()
.into_tempfile();
let disk = QcowDisk::new(
temp_file.as_file().try_clone().unwrap(),
false,
@@ -843,11 +838,9 @@ mod unit_tests {
#[test]
fn test_qcow_async_batch_mixed_requests() {
let file_size = 100 * 1024 * 1024;
let temp_file = TempFile::new().unwrap();
{
let raw_file = RawFile::new(temp_file.as_file().try_clone().unwrap(), false);
QcowFile::new(raw_file, 3, file_size, true).unwrap();
}
let temp_file = QcowTempDisk::new(file_size, None, false, true, false)
.unwrap()
.into_tempfile();
let disk = QcowDisk::new(
temp_file.as_file().try_clone().unwrap(),
false,
@@ -929,11 +922,9 @@ mod unit_tests {
#[test]
fn test_qcow_async_read_unallocated() {
let file_size = 100 * 1024 * 1024;
let temp_file = TempFile::new().unwrap();
{
let raw_file = RawFile::new(temp_file.as_file().try_clone().unwrap(), false);
QcowFile::new(raw_file, 3, file_size, true).unwrap();
}
let temp_file = QcowTempDisk::new(file_size, None, false, true, false)
.unwrap()
.into_tempfile();
let disk = QcowDisk::new(
temp_file.as_file().try_clone().unwrap(),
false,
@@ -954,11 +945,9 @@ mod unit_tests {
fn test_qcow_async_sub_cluster_write() {
let cluster_size = 65536usize;
let file_size = 100 * 1024 * 1024;
let temp_file = TempFile::new().unwrap();
{
let raw_file = RawFile::new(temp_file.as_file().try_clone().unwrap(), false);
QcowFile::new(raw_file, 3, file_size, true).unwrap();
}
let temp_file = QcowTempDisk::new(file_size, None, false, true, false)
.unwrap()
.into_tempfile();
let disk = QcowDisk::new(
temp_file.as_file().try_clone().unwrap(),
false,
@@ -1049,11 +1038,9 @@ mod unit_tests {
#[test]
fn test_qcow_async_alignment_without_direct_io() {
let file_size = 100 * 1024 * 1024;
let temp_file = TempFile::new().unwrap();
{
let raw_file = RawFile::new(temp_file.as_file().try_clone().unwrap(), false);
QcowFile::new(raw_file, 3, file_size, true).unwrap();
}
let temp_file = QcowTempDisk::new(file_size, None, false, true, false)
.unwrap()
.into_tempfile();
let disk = QcowDisk::new(
temp_file.as_file().try_clone().unwrap(),
false,
@@ -1066,51 +1053,33 @@ mod unit_tests {
assert_eq!(async_io.alignment(), SECTOR_SIZE);
}
/// Returns None if O_DIRECT is not supported (e.g. tmpfs).
fn try_create_direct_io_disk(temp_file: &TempFile, file_size: u64) -> Option<QcowDisk> {
{
let raw_file = RawFile::new(temp_file.as_file().try_clone().unwrap(), false);
QcowFile::new(raw_file, 3, file_size, true).unwrap();
}
QcowDisk::new(
temp_file.as_file().try_clone().unwrap(),
true,
false,
true,
true,
)
.ok()
}
#[test]
fn test_qcow_async_alignment_with_direct_io() {
let temp_file = TempFile::new().unwrap();
let disk = match try_create_direct_io_disk(&temp_file, 100 * 1024 * 1024) {
Some(d) => d,
None => {
let tmp_disk = match QcowTempDisk::new(100 * 1024 * 1024, None, true, true, true) {
Ok(d) => d,
Err(_) => {
eprintln!("skipping: O_DIRECT not supported on this filesystem");
return;
}
};
let async_io = disk.create_async_io(1).unwrap();
let async_io = tmp_disk.disk().create_async_io(1).unwrap();
assert!(async_io.alignment() >= SECTOR_SIZE);
}
#[test]
fn test_qcow_async_sub_sector_read_with_direct_io() {
let temp_file = TempFile::new().unwrap();
let disk = match try_create_direct_io_disk(&temp_file, 100 * 1024 * 1024) {
Some(d) => d,
None => {
let tmp_disk = match QcowTempDisk::new(100 * 1024 * 1024, None, true, true, true) {
Ok(d) => d,
Err(_) => {
eprintln!("skipping: O_DIRECT not supported on this filesystem");
return;
}
};
let pattern = vec![0xAB; 65536];
async_write(&disk, 0, &pattern);
async_write(tmp_disk.disk(), 0, &pattern);
let buf = async_read(&disk, 0, 512);
let buf = async_read(tmp_disk.disk(), 0, 512);
assert!(
buf.iter().all(|&b| b == 0xAB),
"sub-sector O_DIRECT read should return written data"
@@ -1119,19 +1088,18 @@ mod unit_tests {
#[test]
fn test_qcow_async_direct_io_write_read_roundtrip() {
let temp_file = TempFile::new().unwrap();
let disk = match try_create_direct_io_disk(&temp_file, 100 * 1024 * 1024) {
Some(d) => d,
None => {
let tmp_disk = match QcowTempDisk::new(100 * 1024 * 1024, None, true, true, true) {
Ok(d) => d,
Err(_) => {
eprintln!("skipping: O_DIRECT not supported on this filesystem");
return;
}
};
let pattern: Vec<u8> = (0..128 * 1024).map(|i| (i % 251) as u8).collect();
async_write(&disk, 0, &pattern);
async_write(tmp_disk.disk(), 0, &pattern);
let buf = async_read(&disk, 0, pattern.len());
let buf = async_read(tmp_disk.disk(), 0, pattern.len());
assert_eq!(buf, pattern, "O_DIRECT roundtrip should match");
}

View File

@@ -342,6 +342,7 @@ mod unit_tests {
use std::io::{Read, Seek, SeekFrom, Write};
use std::os::fd::RawFd;
use std::path::Path;
use std::sync::Arc;
use std::{env, thread};
use vmm_sys_util::tempdir::TempDir;
@@ -351,11 +352,12 @@ mod unit_tests {
use crate::async_io::{AsyncIoCompletion, OwnedIoBuffer};
use crate::disk_file::{AsyncDiskFile, DiskSize, Resizable};
use crate::error::BlockErrorKind;
use crate::formats::qcow::QcowDisk;
use crate::formats::qcow;
use crate::formats::qcow::common::unit_tests::compress_allocated_clusters;
use crate::formats::qcow::internal::{
BackingFileConfig, Error as QcowError, ImageType, QcowFile, QcowHeader, RawFile,
BackingFileConfig, Error as QcowError, ImageType, QcowHeader, RawFile,
};
use crate::formats::qcow::{QcowDisk, QcowTempDisk};
const TEST_L1_L2_ADDR_MASK: u64 = 0x00ff_ffff_ffff_fe00;
const TEST_HEADER_L1_TABLE_OFFSET: u64 = 40;
@@ -416,14 +418,15 @@ mod unit_tests {
sparse: bool,
direct_io: bool,
) -> (TempFile, QcowDisk) {
let temp_file = TempFile::new().unwrap();
{
let raw_file = RawFile::new(temp_file.as_file().try_clone().unwrap(), false);
let mut qcow_file = QcowFile::new(raw_file, 3, file_size, sparse).unwrap();
qcow_file.seek(SeekFrom::Start(offset)).unwrap();
qcow_file.write_all(data).unwrap();
qcow_file.flush().unwrap();
}
let temp_file = if data.is_empty() {
QcowTempDisk::new(file_size, None, false, sparse, false)
.unwrap()
.into_tempfile()
} else {
let tmp_disk = QcowTempDisk::new(file_size, None, false, sparse, false).unwrap();
tmp_disk.disk().write_all_at(offset, data);
tmp_disk.into_tempfile()
};
let disk = QcowDisk::new(
temp_file.as_file().try_clone().unwrap(),
direct_io,
@@ -446,15 +449,13 @@ mod unit_tests {
backing_temp.as_file().sync_all().unwrap();
let backing_path = backing_temp.as_path().to_str().unwrap().to_string();
let overlay_temp = TempFile::new().unwrap();
{
let raw = RawFile::new(overlay_temp.as_file().try_clone().unwrap(), false);
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Raw),
};
QcowFile::new_from_backing(raw, 3, file_size, &backing_config, true).unwrap();
}
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Raw),
};
let overlay_temp = QcowTempDisk::new(file_size, Some(&backing_config), false, true, false)
.unwrap()
.into_tempfile();
let disk = QcowDisk::new(
overlay_temp.as_file().try_clone().unwrap(),
@@ -644,17 +645,20 @@ mod unit_tests {
let data = vec![0xFF; 64 * 1024];
let (_temp, _) = create_disk_with_data(100 * 1024 * 1024, &[], 0, true, false);
// Write data at multiple offsets via QcowFile first, then punch
// Populate four 64 KiB regions at 128 KiB strides so the subsequent
// punch_hole calls have allocated clusters to operate on.
{
let temp_file = _temp.as_file().try_clone().unwrap();
let raw_file = RawFile::new(temp_file, false);
let mut qcow_file = QcowFile::from(raw_file).unwrap();
let disk = QcowDisk::new(
_temp.as_file().try_clone().unwrap(),
false,
false,
true,
false,
)
.unwrap();
for i in 0..4u64 {
let off = i * 128 * 1024;
qcow_file.seek(SeekFrom::Start(off)).unwrap();
qcow_file.write_all(&data).unwrap();
disk.write_all_at(i * 128 * 1024, &data);
}
qcow_file.flush().unwrap();
}
let disk = QcowDisk::new(
@@ -819,16 +823,13 @@ mod unit_tests {
backing_temp.as_file().sync_all().unwrap();
let backing_path = backing_temp.as_path().to_str().unwrap().to_string();
let overlay_temp = TempFile::new().unwrap();
{
let raw = RawFile::new(overlay_temp.as_file().try_clone().unwrap(), false);
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Raw),
};
let _overlay =
QcowFile::new_from_backing(raw, 3, file_size, &backing_config, true).unwrap();
}
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Raw),
};
let overlay_temp = QcowTempDisk::new(file_size, Some(&backing_config), false, true, false)
.unwrap()
.into_tempfile();
let file = overlay_temp.as_file().try_clone().unwrap();
let disk = QcowDisk::new(file, direct_io, true, true, false).unwrap();
@@ -883,22 +884,18 @@ mod unit_tests {
}
fn create_qcow2_overlay(overlay_path: &Path, backing_path: &str, file_size: u64) {
let raw = RawFile::new(
OpenOptions::new()
.read(true)
.write(true)
.create(true)
.truncate(true)
.open(overlay_path)
.unwrap(),
false,
);
let file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
.truncate(true)
.open(overlay_path)
.unwrap();
let backing_config = BackingFileConfig {
path: backing_path.to_string(),
format: Some(ImageType::Raw),
};
let _overlay =
QcowFile::new_from_backing(raw, 3, file_size, &backing_config, true).unwrap();
qcow::create_image(&file, file_size, Some(&backing_config)).unwrap();
}
fn create_qcow2_overlay_header(overlay_path: &Path, backing_path: &str, file_size: u64) {
@@ -1115,29 +1112,21 @@ mod unit_tests {
}
fn test_backing_file_read_qcow2_backing_impl(direct_io: bool) {
let backing_temp = TempFile::new().unwrap();
let cluster_size = 1u64 << 16;
let file_size = cluster_size * 4;
let pattern: Vec<u8> = (0..file_size as usize).map(|i| (i % 251) as u8).collect();
{
let raw = RawFile::new(backing_temp.as_file().try_clone().unwrap(), false);
let mut qcow = QcowFile::new(raw, 3, file_size, true).unwrap();
qcow.seek(SeekFrom::Start(0)).unwrap();
qcow.write_all(&pattern).unwrap();
qcow.flush().unwrap();
}
let backing = QcowTempDisk::new(file_size, None, false, true, false).unwrap();
backing.disk().write_all_at(0, &pattern);
let backing_temp = backing.into_tempfile();
let backing_path = backing_temp.as_path().to_str().unwrap().to_string();
let overlay_temp = TempFile::new().unwrap();
{
let raw = RawFile::new(overlay_temp.as_file().try_clone().unwrap(), false);
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Qcow2),
};
let _overlay =
QcowFile::new_from_backing(raw, 3, file_size, &backing_config, true).unwrap();
}
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Qcow2),
};
let overlay_temp = QcowTempDisk::new(file_size, Some(&backing_config), false, true, false)
.unwrap()
.into_tempfile();
let file = overlay_temp.as_file().try_clone().unwrap();
let disk = QcowDisk::new(file, direct_io, true, true, false).unwrap();
@@ -1238,29 +1227,21 @@ mod unit_tests {
fn test_multi_queue_concurrent_reads_qcow2_backing_impl(direct_io: bool) {
// Same as above but reads go through a Qcow2Backing,
// exercising concurrent metadata resolution + pread64 in the backing.
let backing_temp = TempFile::new().unwrap();
let cluster_size = 1u64 << 16;
let file_size = cluster_size * 16;
let pattern: Vec<u8> = (0..file_size as usize).map(|i| (i % 251) as u8).collect();
{
let raw = RawFile::new(backing_temp.as_file().try_clone().unwrap(), false);
let mut qcow = QcowFile::new(raw, 3, file_size, true).unwrap();
qcow.seek(SeekFrom::Start(0)).unwrap();
qcow.write_all(&pattern).unwrap();
qcow.flush().unwrap();
}
let backing = QcowTempDisk::new(file_size, None, false, true, false).unwrap();
backing.disk().write_all_at(0, &pattern);
let backing_temp = backing.into_tempfile();
let backing_path = backing_temp.as_path().to_str().unwrap().to_string();
let overlay_temp = TempFile::new().unwrap();
{
let raw = RawFile::new(overlay_temp.as_file().try_clone().unwrap(), false);
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Qcow2),
};
let _overlay =
QcowFile::new_from_backing(raw, 3, file_size, &backing_config, true).unwrap();
}
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Qcow2),
};
let overlay_temp = QcowTempDisk::new(file_size, Some(&backing_config), false, true, false)
.unwrap()
.into_tempfile();
let file = overlay_temp.as_file().try_clone().unwrap();
let disk = Arc::new(QcowDisk::new(file, direct_io, true, true, false).unwrap());
@@ -1313,37 +1294,37 @@ mod unit_tests {
let base_path = base_temp.as_path().to_str().unwrap().to_string();
// Layer 1: qcow2 mid pointing at raw base, write to cluster 0 only
let mid_temp = TempFile::new().unwrap();
let mid_pattern = vec![0xBBu8; cluster_size as usize];
{
let raw = RawFile::new(mid_temp.as_file().try_clone().unwrap(), false);
let backing_config = BackingFileConfig {
let mid = QcowTempDisk::new(
file_size,
Some(&BackingFileConfig {
path: base_path,
format: Some(ImageType::Raw),
};
let mut mid =
QcowFile::new_from_backing(raw, 3, file_size, &backing_config, true).unwrap();
mid.seek(SeekFrom::Start(0)).unwrap();
mid.write_all(&mid_pattern).unwrap();
mid.flush().unwrap();
}
}),
false,
true,
false,
)
.unwrap();
mid.disk().write_all_at(0, &mid_pattern);
let mid_temp = mid.into_tempfile();
let mid_path = mid_temp.as_path().to_str().unwrap().to_string();
// Layer 2: qcow2 overlay pointing at qcow2 mid, write to cluster 1 only
let overlay_temp = TempFile::new().unwrap();
let overlay_pattern = vec![0xCCu8; cluster_size as usize];
{
let raw = RawFile::new(overlay_temp.as_file().try_clone().unwrap(), false);
let backing_config = BackingFileConfig {
let overlay = QcowTempDisk::new(
file_size,
Some(&BackingFileConfig {
path: mid_path,
format: Some(ImageType::Qcow2),
};
let mut overlay =
QcowFile::new_from_backing(raw, 3, file_size, &backing_config, true).unwrap();
overlay.seek(SeekFrom::Start(cluster_size)).unwrap();
overlay.write_all(&overlay_pattern).unwrap();
overlay.flush().unwrap();
}
}),
false,
true,
false,
)
.unwrap();
overlay.disk().write_all_at(cluster_size, &overlay_pattern);
let overlay_temp = overlay.into_tempfile();
let file = overlay_temp.as_file().try_clone().unwrap();
let disk = QcowDisk::new(file, direct_io, true, true, false).unwrap();
@@ -1399,26 +1380,18 @@ mod unit_tests {
let file_size = cluster_size * num_clusters;
let pattern: Vec<u8> = (0..file_size as usize).map(|i| (i % 251) as u8).collect();
let backing_temp = TempFile::new().unwrap();
{
let raw = RawFile::new(backing_temp.as_file().try_clone().unwrap(), false);
let mut qcow = QcowFile::new(raw, 3, file_size, true).unwrap();
qcow.seek(SeekFrom::Start(0)).unwrap();
qcow.write_all(&pattern).unwrap();
qcow.flush().unwrap();
}
let backing = QcowTempDisk::new(file_size, None, false, true, false).unwrap();
backing.disk().write_all_at(0, &pattern);
let backing_temp = backing.into_tempfile();
let backing_path = backing_temp.as_path().to_str().unwrap().to_string();
let overlay_temp = TempFile::new().unwrap();
{
let raw = RawFile::new(overlay_temp.as_file().try_clone().unwrap(), false);
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Qcow2),
};
let _overlay =
QcowFile::new_from_backing(raw, 3, file_size, &backing_config, true).unwrap();
}
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Qcow2),
};
let overlay_temp = QcowTempDisk::new(file_size, Some(&backing_config), false, true, false)
.unwrap()
.into_tempfile();
let file = overlay_temp.as_file().try_clone().unwrap();
let disk = QcowDisk::new(file, direct_io, true, true, false).unwrap();
@@ -1471,26 +1444,21 @@ mod unit_tests {
let backing_size = cluster_size * 2;
let overlay_size = cluster_size * 4; // overlay is larger than backing
let backing_temp = TempFile::new().unwrap();
{
let raw = RawFile::new(backing_temp.as_file().try_clone().unwrap(), false);
let mut qcow = QcowFile::new(raw, 3, backing_size, true).unwrap();
qcow.seek(SeekFrom::Start(0)).unwrap();
qcow.write_all(&vec![0xAA; backing_size as usize]).unwrap();
qcow.flush().unwrap();
}
let backing = QcowTempDisk::new(backing_size, None, false, true, false).unwrap();
backing
.disk()
.write_all_at(0, &vec![0xAA; backing_size as usize]);
let backing_temp = backing.into_tempfile();
let backing_path = backing_temp.as_path().to_str().unwrap().to_string();
let overlay_temp = TempFile::new().unwrap();
{
let raw = RawFile::new(overlay_temp.as_file().try_clone().unwrap(), false);
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Qcow2),
};
let _overlay =
QcowFile::new_from_backing(raw, 3, overlay_size, &backing_config, true).unwrap();
}
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Qcow2),
};
let overlay_temp =
QcowTempDisk::new(overlay_size, Some(&backing_config), false, true, false)
.unwrap()
.into_tempfile();
let file = overlay_temp.as_file().try_clone().unwrap();
let disk = QcowDisk::new(file, direct_io, true, true, false).unwrap();
@@ -1520,27 +1488,20 @@ mod unit_tests {
let backing_size = cluster_size * 2;
let overlay_size = cluster_size * 4;
let backing_temp = TempFile::new().unwrap();
let backing_data = vec![0xBBu8; backing_size as usize];
{
let raw = RawFile::new(backing_temp.as_file().try_clone().unwrap(), false);
let mut qcow = QcowFile::new(raw, 3, backing_size, true).unwrap();
qcow.seek(SeekFrom::Start(0)).unwrap();
qcow.write_all(&backing_data).unwrap();
qcow.flush().unwrap();
}
let backing = QcowTempDisk::new(backing_size, None, false, true, false).unwrap();
backing.disk().write_all_at(0, &backing_data);
let backing_temp = backing.into_tempfile();
let backing_path = backing_temp.as_path().to_str().unwrap().to_string();
let overlay_temp = TempFile::new().unwrap();
{
let raw = RawFile::new(overlay_temp.as_file().try_clone().unwrap(), false);
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Qcow2),
};
let _overlay =
QcowFile::new_from_backing(raw, 3, overlay_size, &backing_config, true).unwrap();
}
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Qcow2),
};
let overlay_temp =
QcowTempDisk::new(overlay_size, Some(&backing_config), false, true, false)
.unwrap()
.into_tempfile();
let file = overlay_temp.as_file().try_clone().unwrap();
let disk = QcowDisk::new(file, direct_io, true, true, false).unwrap();
@@ -1584,16 +1545,14 @@ mod unit_tests {
backing_temp.as_file().sync_all().unwrap();
let backing_path = backing_temp.as_path().to_str().unwrap().to_string();
let overlay_temp = TempFile::new().unwrap();
{
let raw = RawFile::new(overlay_temp.as_file().try_clone().unwrap(), false);
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Raw),
};
let _overlay =
QcowFile::new_from_backing(raw, 3, overlay_size, &backing_config, true).unwrap();
}
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Raw),
};
let overlay_temp =
QcowTempDisk::new(overlay_size, Some(&backing_config), false, true, false)
.unwrap()
.into_tempfile();
let file = overlay_temp.as_file().try_clone().unwrap();
let disk = QcowDisk::new(file, direct_io, true, true, false).unwrap();
@@ -1635,26 +1594,18 @@ mod unit_tests {
let file_size = cluster_size * 4;
let pattern: Vec<u8> = (0..file_size as usize).map(|i| (i % 251) as u8).collect();
let backing_temp = TempFile::new().unwrap();
{
let raw = RawFile::new(backing_temp.as_file().try_clone().unwrap(), false);
let mut qcow = QcowFile::new(raw, 3, file_size, true).unwrap();
qcow.seek(SeekFrom::Start(0)).unwrap();
qcow.write_all(&pattern).unwrap();
qcow.flush().unwrap();
}
let backing = QcowTempDisk::new(file_size, None, false, true, false).unwrap();
backing.disk().write_all_at(0, &pattern);
let backing_temp = backing.into_tempfile();
let backing_path = backing_temp.as_path().to_str().unwrap().to_string();
let overlay_temp = TempFile::new().unwrap();
{
let raw = RawFile::new(overlay_temp.as_file().try_clone().unwrap(), false);
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Qcow2),
};
let _overlay =
QcowFile::new_from_backing(raw, 3, file_size, &backing_config, true).unwrap();
}
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Qcow2),
};
let overlay_temp = QcowTempDisk::new(file_size, Some(&backing_config), false, true, false)
.unwrap()
.into_tempfile();
let file = overlay_temp.as_file().try_clone().unwrap();
let disk = QcowDisk::new(file, direct_io, true, true, false).unwrap();
@@ -1702,16 +1653,13 @@ mod unit_tests {
backing_temp.as_file().sync_all().unwrap();
let backing_path = backing_temp.as_path().to_str().unwrap().to_string();
let overlay_temp = TempFile::new().unwrap();
{
let raw = RawFile::new(overlay_temp.as_file().try_clone().unwrap(), false);
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Raw),
};
let _overlay =
QcowFile::new_from_backing(raw, 3, file_size, &backing_config, true).unwrap();
}
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Raw),
};
let overlay_temp = QcowTempDisk::new(file_size, Some(&backing_config), false, true, false)
.unwrap()
.into_tempfile();
let file = overlay_temp.as_file().try_clone().unwrap();
let disk = QcowDisk::new(file, direct_io, true, true, false).unwrap();
@@ -1812,16 +1760,13 @@ mod unit_tests {
backing_temp.as_file().sync_all().unwrap();
let backing_path = backing_temp.as_path().to_str().unwrap().to_string();
let overlay_temp = TempFile::new().unwrap();
{
let raw = RawFile::new(overlay_temp.as_file().try_clone().unwrap(), false);
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Raw),
};
let _overlay =
QcowFile::new_from_backing(raw, 3, file_size, &backing_config, true).unwrap();
}
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Raw),
};
let overlay_temp = QcowTempDisk::new(file_size, Some(&backing_config), false, true, false)
.unwrap()
.into_tempfile();
let file = overlay_temp.as_file().try_clone().unwrap();
let disk = QcowDisk::new(file, direct_io, true, true, false).unwrap();
@@ -1972,16 +1917,13 @@ mod unit_tests {
backing_temp.as_file().sync_all().unwrap();
let backing_path = backing_temp.as_path().to_str().unwrap().to_string();
let overlay_temp = TempFile::new().unwrap();
{
let raw = RawFile::new(overlay_temp.as_file().try_clone().unwrap(), false);
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Raw),
};
let _overlay =
QcowFile::new_from_backing(raw, 3, file_size, &backing_config, true).unwrap();
}
let backing_config = BackingFileConfig {
path: backing_path,
format: Some(ImageType::Raw),
};
let overlay_temp = QcowTempDisk::new(file_size, Some(&backing_config), false, true, false)
.unwrap()
.into_tempfile();
let file = overlay_temp.as_file().try_clone().unwrap();
let mut disk = QcowDisk::new(file, false, true, true, false).unwrap();