mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
block: qcow: Add unit tests for qcow refcount positional access
Cover refcount block round trip for the byte aligned and sub byte paths, and add_cluster_end appending an aligned cluster and staying within the maximum offset bound. Assisted-by: Claude:Opus-4.8 Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
@@ -395,12 +395,17 @@ mod unit_tests {
|
|||||||
const FILE_LEN: u64 = 0x40000; // 256 KiB filler so all offsets are valid
|
const FILE_LEN: u64 = 0x40000; // 256 KiB filler so all offsets are valid
|
||||||
|
|
||||||
fn make_qcow_raw() -> (TempFile, QcowRawFile) {
|
fn make_qcow_raw() -> (TempFile, QcowRawFile) {
|
||||||
|
make_qcow_raw_bits(16)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_qcow_raw_bits(refcount_bits: u64) -> (TempFile, QcowRawFile) {
|
||||||
let temp_file = TempFile::new().unwrap();
|
let temp_file = TempFile::new().unwrap();
|
||||||
temp_file.as_file().set_len(FILE_LEN).unwrap();
|
temp_file.as_file().set_len(FILE_LEN).unwrap();
|
||||||
|
|
||||||
let file = temp_file.as_file().try_clone().unwrap();
|
let file = temp_file.as_file().try_clone().unwrap();
|
||||||
let raw = AlignedFile::new(file, false);
|
let raw = AlignedFile::new(file, false);
|
||||||
let qcow_raw = QcowRawFile::from(raw, CLUSTER_SIZE, 16).expect("QcowRawFile::from");
|
let qcow_raw =
|
||||||
|
QcowRawFile::from(raw, CLUSTER_SIZE, refcount_bits).expect("QcowRawFile::from");
|
||||||
(temp_file, qcow_raw)
|
(temp_file, qcow_raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -509,4 +514,55 @@ mod unit_tests {
|
|||||||
verify.read_exact(&mut buf).unwrap();
|
verify.read_exact(&mut buf).unwrap();
|
||||||
assert!(buf.iter().all(|&b| b == 0));
|
assert!(buf.iter().all(|&b| b == 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn refcount_block_round_trips() {
|
||||||
|
let (_temp_file, mut qcow) = make_qcow_raw_bits(16);
|
||||||
|
let count = qcow.refcount_block_entries as usize;
|
||||||
|
let table: Vec<u64> = (0..count).map(|i| (i % 251) as u64).collect();
|
||||||
|
|
||||||
|
qcow.write_refcount_block(TARGET_OFFSET, &table)
|
||||||
|
.expect("write_refcount_block");
|
||||||
|
let read_back = qcow
|
||||||
|
.read_refcount_block(TARGET_OFFSET)
|
||||||
|
.expect("read_refcount_block");
|
||||||
|
|
||||||
|
assert_eq!(read_back, table);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn refcount_block_subbyte_round_trips() {
|
||||||
|
let (_temp_file, mut qcow) = make_qcow_raw_bits(4);
|
||||||
|
let count = qcow.refcount_block_entries as usize;
|
||||||
|
let table: Vec<u64> = (0..count).map(|i| (i % 16) as u64).collect();
|
||||||
|
|
||||||
|
qcow.write_refcount_block(TARGET_OFFSET, &table)
|
||||||
|
.expect("write_refcount_block");
|
||||||
|
let read_back = qcow
|
||||||
|
.read_refcount_block(TARGET_OFFSET)
|
||||||
|
.expect("read_refcount_block");
|
||||||
|
|
||||||
|
assert_eq!(read_back, table);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_cluster_end_appends_aligned_cluster() {
|
||||||
|
let (_temp_file, mut qcow) = make_qcow_raw();
|
||||||
|
let before = qcow.physical_size().unwrap();
|
||||||
|
|
||||||
|
let addr = qcow
|
||||||
|
.add_cluster_end(u64::MAX)
|
||||||
|
.expect("add_cluster_end")
|
||||||
|
.expect("a cluster was allocated");
|
||||||
|
|
||||||
|
assert_eq!(addr % CLUSTER_SIZE, 0);
|
||||||
|
assert!(addr >= before);
|
||||||
|
assert_eq!(qcow.physical_size().unwrap(), addr + CLUSTER_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_cluster_end_respects_max_offset() {
|
||||||
|
let (_temp_file, mut qcow) = make_qcow_raw();
|
||||||
|
assert!(qcow.add_cluster_end(0).unwrap().is_none());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user