#[macro_export]
macro_rules! generate_filesystem_tests {
[ $($fs_name:literal),* ] => {
$( gen_fs_test!($fs_name, $fs_name, "session_offset", 0); )*
};
}
#[macro_export]
macro_rules! generate_partition_table_tests {
[ $($pt_name:literal),* ] => {
$( gen_pt_test!($pt_name); )*
};
}
#[macro_export]
macro_rules! gen_fs_test {
( $fs_name:literal, $image_file_name:literal, $hint_name:literal, $hint_value:expr ) => {
paste::paste! {
#[test]
fn [< probe_file_system_ $fs_name:lower >]() {
use std::io::Read;
INIT.call_once(|| {
env_logger::init();
rsblkid::debug::init_default_debug();
});
let base_dir: &'static str = env!("CARGO_MANIFEST_DIR");
let mut blkid_dir = std::path::PathBuf::new();
blkid_dir.push(base_dir);
blkid_dir.push("third-party/vendor/util-linux/blkid/");
let mut compressed_image_file_path = blkid_dir.clone();
let fragment = concat!("images/filesystems/", $image_file_name, ".img.xz");
compressed_image_file_path.push(fragment);
let compressed_image_file = std::fs::File::open(compressed_image_file_path).unwrap();
let mut decompressed = xz2::read::XzDecoder::new(compressed_image_file);
let mut temp_image_file = tempfile::NamedTempFile::new().unwrap();
std::io::copy(&mut decompressed, &mut temp_image_file).unwrap();
let image = temp_image_file.into_file();
let mut probe = rsblkid::probe::Probe::builder()
.scan_file(image)
.scan_device_superblocks(true)
.collect_fs_properties(vec![
rsblkid::probe::FsProperty::Label,
rsblkid::probe::FsProperty::SecondType,
rsblkid::probe::FsProperty::Type,
rsblkid::probe::FsProperty::Usage,
rsblkid::probe::FsProperty::Uuid,
rsblkid::probe::FsProperty::Version,
rsblkid::probe::FsProperty::FsInfo,
])
.build()
.unwrap();
let io_hint = rsblkid::probe::IoHint::from(($hint_name, $hint_value));
probe.set_hint(&io_hint).unwrap();
probe.find_device_properties();
let kv = probe.iter_device_properties().collect::<Vec<_>>();
let mut kv_str = kv
.iter()
.map(|kv| kv.to_udev_format())
.collect::<Result<Vec<_>, _>>()
.unwrap();
kv_str.sort();
let mut output = kv_str.join("\n");
output.push('\n');
let mut expected_file = blkid_dir.clone();
let fragment = concat!("expected/filesystems/", "low-probe-", $fs_name);
expected_file.push(fragment);
let mut f = std::fs::File::open(expected_file).unwrap();
let mut expected = String::new();
f.read_to_string(&mut expected).unwrap();
pretty_assertions::assert_eq!(output, expected, "comparing scanned device properties to expected values");
}
}
};
}
#[macro_export]
macro_rules! gen_pt_test {
[ $pt_name:literal ] => {
paste::paste! {
#[test]
fn [< probe_partition_table_ $pt_name:lower >]() {
use std::io::Read;
INIT.call_once(|| {
env_logger::init();
rsblkid::debug::init_default_debug();
});
let base_dir: &'static str = env!("CARGO_MANIFEST_DIR");
let mut blkid_dir = std::path::PathBuf::new();
blkid_dir.push(base_dir);
blkid_dir.push("third-party/vendor/util-linux/blkid/");
let mut compressed_image_file_path = blkid_dir.clone();
let fragment = concat!("images/partition_tables/", $pt_name, ".img.xz");
compressed_image_file_path.push(fragment);
let compressed_image_file = std::fs::File::open(&compressed_image_file_path).unwrap();
let mut decompressed = xz2::read::XzDecoder::new(compressed_image_file);
let mut temp_image_file = tempfile::NamedTempFile::new().unwrap();
std::io::copy(&mut decompressed, &mut temp_image_file).unwrap();
let image = temp_image_file.into_file();
let mut probe = rsblkid::probe::Probe::builder()
.scan_file(image)
.scan_device_superblocks(false)
.scan_device_partitions(true)
.build()
.unwrap();
probe.find_device_properties();
let partitions_iter = probe.iter_partitions();
let err_msg = format!("PartitionIter::partition_table {:?} does not contain any known partition table", compressed_image_file_path);
let partition_table = partitions_iter
.partition_table()
.expect(&err_msg);
let size = probe.scanned_device_segment_size();
let sector_size = probe.device_logical_sector_size();
let pt = partition_table.partition_table_type().unwrap();
let offset = partition_table.location_in_bytes().unwrap();
let partition_table_id = partition_table.id();
let id = if let Some(ref id) = partition_table_id { id.to_string() } else { "(null)".to_string() } ;
let mut output = String::new();
let header = format!("size: {size}, sector size: {sector_size}, PT: {pt}, offset: {offset}, id={id}\n---\n");
let rows = partitions_iter.map(|partition| {
let number = partition.number();
let start = partition.location_in_sectors();
let size = partition.size_in_sectors();
let part_type = partition.partition_type();
let parent_table = partition.partition_table().unwrap();
let parent_table_id = parent_table.id();
let mut row = format!("#{}: {:>10} {:>10} 0x{:x}", number, start, size, part_type);
if parent_table_id != partition_table_id {
let parent_table_type = parent_table.partition_table_type().unwrap();
let table_type = format!(" ({})", parent_table_type);
row.push_str(&table_type);
}
if let Some(name) = partition.name() {
let name = format!(" name='{}'", name);
row.push_str(&name);
}
if let Some(uuid) = partition.uuid() {
let uuid = format!(" uuid='{}'", uuid);
row.push_str(&uuid);
}
if let Some(type_str) = partition.partition_type_string() {
let type_str = format!(" type='{}'", type_str);
row.push_str(&type_str);
}
row
}).collect::<Vec<_>>().join("\n");
output.push_str(&header);
output.push_str(&rows);
output.push('\n');
let mut expected_file = blkid_dir.clone();
let fragment = concat!("expected/partition_tables/lowprobe-pt-", $pt_name);
expected_file.push(fragment);
let mut f = std::fs::File::open(expected_file).unwrap();
let mut expected = String::new();
f.read_to_string(&mut expected).unwrap();
pretty_assertions::assert_eq!(output, expected);
}
}
};
}