test: add unit tests for partition step planning & validation

This commit is contained in:
Erkan IŞIK
2026-08-19 13:19:39 +03:00
parent 80e3559d0d
commit fb905d9714
+185
View File
@@ -1650,3 +1650,188 @@ fn format_number_thousands(n: u64) -> String {
}
result
}
#[cfg(test)]
mod tests {
use super::*;
use crate::installer::{LogicalVolume, PartitionTableType};
fn disk(name: &str, size_gb: u64) -> DiskInfo {
DiskInfo {
name: name.to_string(),
vendor: "ATA".to_string(),
model: "VBOX HARDDISK".to_string(),
drive_type: "HDD".to_string(),
size_gb,
size_bytes: size_gb * 1_073_741_824,
}
}
fn part(device: &str, size_mb: u64, fstype: FsType, mountpoint: &str) -> CustomPartition {
CustomPartition {
device: device.to_string(),
size_mb,
fstype,
mountpoint: mountpoint.to_string(),
encrypt: false,
luks_password: String::new(),
luks_name: String::new(),
skip_format: false,
}
}
fn step(uefi: bool) -> PartitionStep {
PartitionStep {
scanned: true,
is_uefi: uefi,
manual: ManualState::default(),
show_luks_password: false,
selected_disk_size_mb: None,
}
}
// ── make_plan ────────────────────────────────────────────
#[test]
fn plan_rejects_small_disk() {
let d = disk("/dev/sdb", 9);
assert!(make_plan(&d, true).is_none());
assert!(make_plan(&d, false).is_none());
}
#[test]
fn plan_uefi_large_disk() {
let d = disk("/dev/sda", 100);
let plan = make_plan(&d, true).expect("100GB disk için plan oluşmalı");
assert_eq!(plan.disk, "/dev/sda");
assert_eq!(plan.table_type, PartitionTableType::Gpt);
assert!(plan.efi_mb > 0, "UEFI planında EFI bölümü olmalı");
// EFI + swap + root, overhead payı düşülmüş disk boyutunu aşmamalı
assert!(plan.efi_mb + plan.swap_mb + plan.root_mb <= 100 * 1024);
}
#[test]
fn plan_bios_large_disk() {
let d = disk("/dev/sda", 100);
let plan = make_plan(&d, false).expect("100GB disk için plan oluşmalı");
assert_eq!(plan.table_type, PartitionTableType::Mbr);
assert_eq!(plan.efi_mb, 0, "BIOS modunda EFI bölümü olmamalı");
}
// ── validate_manual ───────────────────────────────────────
#[test]
fn manual_empty_plan_fails() {
assert!(validate_manual(&[], &[], true).is_some());
assert!(validate_manual(&[], &[], false).is_some());
}
#[test]
fn manual_root_only_ok_on_bios() {
let parts = vec![part("/dev/sda1", 20_000, FsType::Ext4, "/")];
assert!(validate_manual(&parts, &[], false).is_none());
}
#[test]
fn manual_uefi_requires_efi_part() {
let parts = vec![part("/dev/sda1", 20_000, FsType::Ext4, "/")];
assert!(
validate_manual(&parts, &[], true).is_some(),
"UEFI modunda EFI bölümü zorunlu"
);
let with_efi = vec![
part("/dev/sda1", 300, FsType::Fat32, "/boot/efi"),
part("/dev/sda2", 20_000, FsType::Ext4, "/"),
];
assert!(validate_manual(&with_efi, &[], true).is_none());
}
#[test]
fn manual_root_can_come_from_lv() {
let parts = vec![part("/dev/sda1", 20_000, FsType::Lvm, "")];
let lvs = vec![LogicalVolume {
name: "root".to_string(),
vg_name: "vg0".to_string(),
size_mb: 10_000,
fstype: FsType::Ext4,
mountpoint: "/".to_string(),
}];
assert!(validate_manual(&parts, &lvs, false).is_none());
}
// ── InstallerStep arayüzü ─────────────────────────────────
#[test]
fn auto_mode_complete_only_with_plan() {
let st = step(true);
let mut state = crate::installer::GlobalState::default();
state.erase_disk = true;
assert!(!st.is_complete(&state), "plan yokken tamamlanmamalı");
state.partition_plan = make_plan(&disk("/dev/sda", 100), true);
assert!(st.is_complete(&state), "plan varken tamamlanmalı");
}
#[test]
fn manual_mode_complete_with_valid_partitions() {
let st = step(true);
let mut state = crate::installer::GlobalState::default();
state.erase_disk = false;
assert!(!st.is_complete(&state), "bölüm yokken tamamlanmamalı");
// Kök var ama EFI yok → tamamlanmamalı
state.custom_partitions.push(part("/dev/sda1", 20_000, FsType::Ext4, "/"));
assert!(!st.is_complete(&state), "eksik EFI bölümü ile tamamlanmamalı");
// Geçerli düzen → tamamlanmalı
state.custom_partitions.push(part("/dev/sda1", 300, FsType::Fat32, "/boot/efi"));
assert!(st.is_complete(&state), "geçerli düzen ile tamamlanmalı");
}
// ── format_number_thousands ───────────────────────────────
#[test]
fn formats_thousands() {
assert_eq!(format_number_thousands(0), "0");
assert_eq!(format_number_thousands(999), "999");
assert_eq!(format_number_thousands(1000), "1.000");
assert_eq!(format_number_thousands(7000000), "7.000.000");
}
// ── detect_drive_type ─────────────────────────────────────
#[test]
fn drive_type_by_name() {
assert_eq!(detect_drive_type("nvme0n1"), "NVMe SSD");
assert_eq!(detect_drive_type("mmcblk0"), "MMC/SD");
assert_eq!(detect_drive_type("nonexistent99"), "HDD");
}
// ── lsblk / sysfs okumaları (canlı sistem) ────────────────
#[test]
fn read_existing_partitions_never_panics() {
// Var olmayan disk → boş liste, çökmemeli
assert!(read_existing_partitions("/dev/does-not-exist").is_empty());
// Var olan disklerde dönen bölümler /dev/ ön ekli olmalı
for d in list_block_devices().iter().take(1) {
for p in read_existing_partitions(&d.name) {
assert!(p.device.starts_with("/dev/"));
}
}
}
#[test]
fn list_block_devices_scrubs_loop_ram() {
for d in list_block_devices() {
let base = d.name.trim_start_matches("/dev/");
assert!(!base.starts_with("loop"));
assert!(!base.starts_with("ram"));
assert!(!base.starts_with("sr"));
assert!(!base.starts_with("zram"));
}
}
}