mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
block: qcow: Test async batch mixed requests
Add a QcowAsync unit test that submits a batch of interleaved write and read requests via submit_batch_requests. Verifies that all completions arrive with the correct user_data and that the read back data matches the written data. Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
committed by
Rob Bradford
parent
093922ff24
commit
34a9f7246d
@@ -582,6 +582,7 @@ mod unit_tests {
|
||||
use super::*;
|
||||
use crate::disk_file::AsyncDiskFile;
|
||||
use crate::qcow::{QcowFile, RawFile};
|
||||
use crate::{BatchRequest, RequestType};
|
||||
|
||||
fn create_disk_with_data(
|
||||
file_size: u64,
|
||||
@@ -742,4 +743,100 @@ mod unit_tests {
|
||||
"second half should come from cluster 1"
|
||||
);
|
||||
}
|
||||
|
||||
#[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 disk = QcowDiskAsync::new(temp_file.as_file().try_clone().unwrap(), false, false, true)
|
||||
.unwrap();
|
||||
|
||||
let mut async_io = disk.new_async_io(8).unwrap();
|
||||
|
||||
// Prepare write data for two regions.
|
||||
let write_a = vec![0xAA; 4096];
|
||||
let write_b = vec![0xBB; 4096];
|
||||
let offset_a: u64 = 0;
|
||||
let offset_b: u64 = 65536;
|
||||
|
||||
let iov_a = libc::iovec {
|
||||
iov_base: write_a.as_ptr() as *mut libc::c_void,
|
||||
iov_len: write_a.len(),
|
||||
};
|
||||
let iov_b = libc::iovec {
|
||||
iov_base: write_b.as_ptr() as *mut libc::c_void,
|
||||
iov_len: write_b.len(),
|
||||
};
|
||||
|
||||
let batch = vec![
|
||||
BatchRequest {
|
||||
offset: offset_a as libc::off_t,
|
||||
iovecs: smallvec::smallvec![iov_a],
|
||||
user_data: 10,
|
||||
request_type: RequestType::Out,
|
||||
},
|
||||
BatchRequest {
|
||||
offset: offset_b as libc::off_t,
|
||||
iovecs: smallvec::smallvec![iov_b],
|
||||
user_data: 20,
|
||||
request_type: RequestType::Out,
|
||||
},
|
||||
];
|
||||
|
||||
async_io.submit_batch_requests(&batch).unwrap();
|
||||
|
||||
let mut completions = [
|
||||
wait_for_completion(async_io.as_mut()),
|
||||
wait_for_completion(async_io.as_mut()),
|
||||
];
|
||||
completions.sort_by_key(|c| c.0);
|
||||
assert_eq!(completions[0], (10, 4096));
|
||||
assert_eq!(completions[1], (20, 4096));
|
||||
drop(async_io);
|
||||
|
||||
// Batch read both regions back.
|
||||
let mut read_a = vec![0u8; 4096];
|
||||
let mut read_b = vec![0u8; 4096];
|
||||
let riov_a = libc::iovec {
|
||||
iov_base: read_a.as_mut_ptr() as *mut libc::c_void,
|
||||
iov_len: read_a.len(),
|
||||
};
|
||||
let riov_b = libc::iovec {
|
||||
iov_base: read_b.as_mut_ptr() as *mut libc::c_void,
|
||||
iov_len: read_b.len(),
|
||||
};
|
||||
|
||||
let mut async_io = disk.new_async_io(8).unwrap();
|
||||
let read_batch = vec![
|
||||
BatchRequest {
|
||||
offset: offset_a as libc::off_t,
|
||||
iovecs: smallvec::smallvec![riov_a],
|
||||
user_data: 30,
|
||||
request_type: RequestType::In,
|
||||
},
|
||||
BatchRequest {
|
||||
offset: offset_b as libc::off_t,
|
||||
iovecs: smallvec::smallvec![riov_b],
|
||||
user_data: 40,
|
||||
request_type: RequestType::In,
|
||||
},
|
||||
];
|
||||
|
||||
async_io.submit_batch_requests(&read_batch).unwrap();
|
||||
|
||||
let mut completions = [
|
||||
wait_for_completion(async_io.as_mut()),
|
||||
wait_for_completion(async_io.as_mut()),
|
||||
];
|
||||
completions.sort_by_key(|c| c.0);
|
||||
assert_eq!(completions[0], (30, 4096));
|
||||
assert_eq!(completions[1], (40, 4096));
|
||||
|
||||
assert_eq!(read_a, write_a, "batch read A should match written data");
|
||||
assert_eq!(read_b, write_b, "batch read B should match written data");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user