forked from pisilinux-rs/yali-rs
fix(partition): "Kalan Alan" tanımı alanı boş alandan düşmüyordu
Kullanıcı raporu: "boş alanı gösterdi ve o kısmı yeni bölümden ntfs olarak formatlamasını seçtim ama eklenen bölümün 19.8 gb demesine rağmen bunu boş alandan düşmedi." ## Kök neden `size_mb == 0` bir tanım **"Kalan Alan"** demektir: kurulumda diskin o an kalanının TAMAMINI alır. Bu yüzden sabit boyutlu tanımlarla toplanırken katılmaz (`size_mb` zaten 0). Ama ne tablo ne de kapasite kontrolü bunu biliyordu. Sonuç: 20 GB'lik disk 39 GB kullanıyor gibi görünüyordu — bölüm satırı kalanın tamamını (19.8 GB) gösteriyor, alttaki "Boş Alan" satırı da aynı 19.8 GB'yi gösteriyordu. ## Düzeltme `has_symbolic_remaining(parts, disk)` tek kaynak olarak eklendi (`!delete && size_mb == 0 && orig_device.is_empty()`) ve dört yere bağlandı: - **tablo** (`build_table_rows`): sembolik varsa boş alan satırı çizilmez — o alan o tanıma ait - **çubuk** (`manual_dual_bars`): sembolik varsa serbest segment eklenmez. Zaten doğruydu ama kuralın AYRI kopyası vardı; artık aynı fonksiyona bakıyor, tablo ile çubuk ayrışamaz - **kapasite** (`manual_capacity_error`): sembolik varsa `fixed_mb >= cap_mb` reddedilir ## Kapanan açık madde AGENTS.md'de şu yazıyordu: "`manual_capacity_error` sembolik (`size_mb == 0`) tanımları hesaba katmıyor → `fixed == cap` geçiyor, kurulumda 'yeterli boş alan yok' ile düşüyor." Disk sabit tanımlarla tam doluysa ve bir de "Kalan Alan" tanımı varsa o tanıma 0 byte kalıyordu. Artık `>=` ile reddediliyor. Ayrıca **aynı diskte iki "Kalan Alan" tanımı** reddediliyor: ikisi de kalanın tamamını alır, ikincisine hiç yer kalmaz. Bu da kuruluma başlayıp orada düşmeye yol açan bir durumdu. ## Not `orig_device` dolu (taranmış) 0 boyutlu bölüm sembolik SAYILMAZ: sıfır boyut "kalanın tamamı" anlamına gelmez. Testle sabitlendi. ## Testler (113 → 122) Yeni `symbolic_capacity_tests` (5) + `free_space_tests`'e 4 test: - sembolik tanım boş alan satırını yutar (kullanıcı senaryosu) - sembolik bölümün kendi satırı kalanın tamamını gösterir - sembolik tanım silinince boş alan satırı geri gelir - 0 boyutlu fiziksel bölüm sembolik sayılmaz - dolu disk + sembolik tanım reddedilir - yer olan sembolik tanım geçerli - aynı diskte iki sembolik reddedilir - her diskte birer tane geçerli - sabit tanımlarla tam dolu disk (semboliksiz) yine geçerli Testlerden biri ilk yazımda yanlış beklenti koydu (sembolik silinince 20480 bekliyordum, doğrusu 19980 — sda1'in 500 MB'ı hâlâ kullanımda). Beklenti düzeltildi. cargo check --all-targets : 0 hata, 0 uyarı cargo test : 122/122 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -298,6 +298,31 @@ ikincil (veri) diskler içindir: boş diske bölüm eklemek için alanı
|
|||||||
elle doldurmak zorunda kalmamak. Silinmek işaretli tanımlar
|
elle doldurmak zorunda kalmamak. Silinmek işaretli tanımlar
|
||||||
sayılmaz.
|
sayılmaz.
|
||||||
|
|
||||||
|
### ⭐ "Kalan Alan" (sembolik) tanımlar — `size_mb == 0`
|
||||||
|
|
||||||
|
`CustomPartition::size_mb == 0` **"Kalan Alan"** demektir: kurulumda
|
||||||
|
diskin o an kalan boşluğunun **tamamını** alır. Bu yüzden sabit
|
||||||
|
boyutlu tanımlarla birlikte hesaplanırken **sabit toplama katılmaz**.
|
||||||
|
|
||||||
|
Kullanıcı raporu: *"eklenen bölümün 19.8 gb demesine rağmen bunu
|
||||||
|
boş alandan düşmedi"* — 20 GB'lik disk 39 GB kullanıyor gibi görünüyordu,
|
||||||
|
çünkü hem bölüm satırı hem boş alan satırı kalanın tamamını gösteriyordu.
|
||||||
|
|
||||||
|
| Yer | Kural |
|
||||||
|
|---|---|
|
||||||
|
| `has_symbolic_remaining(parts, disk)` | **TEK KAYNAK.** `!delete && size_mb == 0 && orig_device.is_empty()` |
|
||||||
|
| tablo (`build_table_rows`) | sembolik varsa boş alan satırı **çizilmez** — o alan o tanıma ait |
|
||||||
|
| çubuk (`manual_dual_bars`) | sembolik varsa serbest segment **eklenmez** |
|
||||||
|
| `manual_capacity_error` | sembolik varsa `fixed_mb >= cap_mb` reddedilir |
|
||||||
|
|
||||||
|
Son satır, AGENTS.md'de açık madde olarak duran hatayı kapatır:
|
||||||
|
`fixed == cap` geçiyordu, kurulumda "yeterli boş alan yok" ile düşülüyordu.
|
||||||
|
Ayrıca **aynı diskte iki "Kalan Alan" tanımı** reddedilir — ikisi de
|
||||||
|
kalanın tamamını alır, ikincisine hiç yer kalmaz.
|
||||||
|
|
||||||
|
`orig_device` dolu (taranmış) 0 boyutlu bölüm sembolik **DEĞİLDİR**:
|
||||||
|
sıfır boyut "kalanın tamamı" anlamına gelmez.
|
||||||
|
|
||||||
### `selected_disk` hâlâ 3 yerde kullanılıyor
|
### `selected_disk` hâlâ 3 yerde kullanılıyor
|
||||||
1. Tablo hangi diski gösteriyor + `manual_dual_bars`
|
1. Tablo hangi diski gösteriyor + `manual_dual_bars`
|
||||||
2. Diyaloğun varsayılan hedefi
|
2. Diyaloğun varsayılan hedefi
|
||||||
@@ -457,11 +482,11 @@ nedeni yorumla sabitlendi. Log bile "MiB" derken argüman "MB" gönderiyordu.
|
|||||||
|
|
||||||
```
|
```
|
||||||
cargo check --all-targets : 0 hata, 0 uyarı
|
cargo check --all-targets : 0 hata, 0 uyarı
|
||||||
cargo test : 113/113 (test modülü sayısı arttıkça güncel tut)
|
cargo test : 122/122 (test modülü sayısı arttıkça güncel tut)
|
||||||
cargo clippy : ~77 uyarı, tamamı stil (collapsed_if, replace zinciri)
|
cargo clippy : ~77 uyarı, tamamı stil (collapsed_if, replace zinciri)
|
||||||
```
|
```
|
||||||
|
|
||||||
Bu oturumda 1 → 113 test. Test modülü olmayan dosyalar (`users.rs`,
|
Bu oturumda 1 → 122 test. Test modülü olmayan dosyalar (`users.rs`,
|
||||||
`location.rs`, `rescue.rs`, `funct.rs`, `autoinstall/mod.rs`, `main.rs`)
|
`location.rs`, `rescue.rs`, `funct.rs`, `autoinstall/mod.rs`, `main.rs`)
|
||||||
içine modüller eklendi. Çoklu test modülü paylaşılan yardımcıları
|
içine modüller eklendi. Çoklu test modülü paylaşılan yardımcıları
|
||||||
`steps/partition.rs::testutil` altındadır (`disk()`, `part()`).
|
`steps/partition.rs::testutil` altındadır (`disk()`, `part()`).
|
||||||
@@ -507,9 +532,8 @@ senaryoları dene:
|
|||||||
job `pvcreate` çalıştırmaya çalışabilir)
|
job `pvcreate` çalıştırmaya çalışabilir)
|
||||||
- [ ] BIOS `device.map` `/dev` **alfabetik** sıraya göre yazılıyor;
|
- [ ] BIOS `device.map` `/dev` **alfabetik** sıraya göre yazılıyor;
|
||||||
firmware sırası ile aynı olmayabilir → çoklu diskte BIOS boot kırılgan
|
firmware sırası ile aynı olmayabilir → çoklu diskte BIOS boot kırılgan
|
||||||
- [ ] `manual_capacity_error` sembolik (`size_mb == 0`) tanımları
|
- [ ] ~~`manual_capacity_error` sembolik tanımları hesaba katmıyor~~ —
|
||||||
hesaba katmıyor → `fixed == cap` geçiyor, kurulumda "yeterli boş
|
KAPANDI (bkz. "Kalan Alan" bölümü; `has_symbolic_remaining`)
|
||||||
alan yok" ile düşüyor
|
|
||||||
|
|
||||||
### Orta öncelik
|
### Orta öncelik
|
||||||
- [ ] `available_disks` `< 4 GB` diski tamamen gizliyor (ComboBox'ta yok,
|
- [ ] `available_disks` `< 4 GB` diski tamamen gizliyor (ComboBox'ta yok,
|
||||||
@@ -557,7 +581,7 @@ senaryoları dene:
|
|||||||
|---|---|
|
|---|---|
|
||||||
| `src/jobs/partition.rs` | `plan_disk_layout`, `PhysicalExtent`, `PlannedCreate`, `disk_total_mb`, `read_physical_extents`, `device_map`; `disk_free_regions_mb` silindi |
|
| `src/jobs/partition.rs` | `plan_disk_layout`, `PhysicalExtent`, `PlannedCreate`, `disk_total_mb`, `read_physical_extents`, `device_map`; `disk_free_regions_mb` silindi |
|
||||||
| `src/jobs/cleanup.rs` | **YENİ** — `EmergencyCleanupJob` |
|
| `src/jobs/cleanup.rs` | **YENİ** — `EmergencyCleanupJob` |
|
||||||
| `src/steps/partition.rs` | **tek diske odaklı tablo + disk şeridi** (diyalogda disk seçicisi yok), **seçime göre görünen butonlar** (`selected_free`), diske filtreli LVM, `validate_manual_on`, `mountpoint_required`, `suggest_mountpoint`, `build_table_rows`; `multidisk_tests`, `table_scope_tests`, `free_space_tests`, `selection_tests`, `edit_flow_tests`, `edit_disk_tests`, `testutil` |
|
| `src/steps/partition.rs` | **tek diske odaklı tablo + disk şeridi** (diyalogda disk seçicisi yok), **seçime göre görünen butonlar** (`selected_free`), diske filtreli LVM, `validate_manual_on`, `manual_capacity_error`, `mountpoint_required`, `suggest_mountpoint`, `has_symbolic_remaining`, `build_table_rows`; `multidisk_tests`, `table_scope_tests`, `free_space_tests`, `symbolic_capacity_tests`, `selection_tests`, `edit_flow_tests`, `edit_disk_tests`, `testutil` |
|
||||||
| `src/jobs/users.rs` | `set_password_via_chpasswd` (stdin pipe) |
|
| `src/jobs/users.rs` | `set_password_via_chpasswd` (stdin pipe) |
|
||||||
| `src/jobs/bootloader.rs` | `CRYPTROOT_NAME`, `luks_backing_device`, `mounted_root_device` |
|
| `src/jobs/bootloader.rs` | `CRYPTROOT_NAME`, `luks_backing_device`, `mounted_root_device` |
|
||||||
| `src/jobs/finish.rs` | `RunComarJob` geri geldi; `ldconfig`/`update-environment`/depo fatal |
|
| `src/jobs/finish.rs` | `RunComarJob` geri geldi; `ldconfig`/`update-environment`/depo fatal |
|
||||||
|
|||||||
+223
-4
@@ -534,6 +534,22 @@ fn suggest_mountpoint(parts: &[CustomPartition], is_uefi: bool) -> &'static str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Diskte "Kalan Alan" (sembolik, `size_mb == 0`) bir tanım var mı?
|
||||||
|
///
|
||||||
|
/// Böyle bir tanım, diskte kalan alanın **tamamını** kendine alır.
|
||||||
|
/// Bu yüzden o diskte ayrı bir "Boş Alan" satırı çizilmez: tablo
|
||||||
|
/// satırı zaten kalanın tamamını kendi boyut sütununda gösteriyor,
|
||||||
|
/// ikinci bir satır aynı alanı iki kez sayar ve kullanıcı diskin
|
||||||
|
/// iki katı büyük olduğunu sanır.
|
||||||
|
///
|
||||||
|
/// `manual_dual_bars` (kapasite çubuğu) da aynı kuralı uygular;
|
||||||
|
/// ikisi de bu fonksiyona bakmalı ki tablo ile çubuk ayrışmasın.
|
||||||
|
fn has_symbolic_remaining(parts: &[CustomPartition], disk: &str) -> bool {
|
||||||
|
parts.iter().any(|p| {
|
||||||
|
p.disk == disk && !p.delete && p.size_mb == 0 && p.orig_device.is_empty()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Bölümleme tablosunda görünen bir satır.
|
/// Bölümleme tablosunda görünen bir satır.
|
||||||
///
|
///
|
||||||
/// Görünen her bölüm satırı `GlobalState.custom_partitions` içindeki
|
/// Görünen her bölüm satırı `GlobalState.custom_partitions` içindeki
|
||||||
@@ -583,6 +599,8 @@ fn build_table_rows<'a>(
|
|||||||
.map(|p| p.size_mb)
|
.map(|p| p.size_mb)
|
||||||
.sum();
|
.sum();
|
||||||
let free_total_mb = disk_mb.saturating_sub(used_total);
|
let free_total_mb = disk_mb.saturating_sub(used_total);
|
||||||
|
// "Kalan Alan" tanımı kalanın tamamını alır → boş alan satırı çizilmez.
|
||||||
|
let has_symbolic = has_symbolic_remaining(parts, active_disk);
|
||||||
|
|
||||||
let mut fs_first: Option<usize> = None;
|
let mut fs_first: Option<usize> = None;
|
||||||
// Boş alan satırı disk başına TEK'tir (GParted tarzı: silinenler
|
// Boş alan satırı disk başına TEK'tir (GParted tarzı: silinenler
|
||||||
@@ -620,7 +638,7 @@ fn build_table_rows<'a>(
|
|||||||
first_idx: Some(first),
|
first_idx: Some(first),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if free_total_mb > 0 && !free_row_shown {
|
} else if free_total_mb > 0 && !free_row_shown && !has_symbolic {
|
||||||
// Disk SONUNDAKİ boş alan — diskte tanım olsun ya da olmasın.
|
// Disk SONUNDAKİ boş alan — diskte tanım olsun ya da olmasın.
|
||||||
//
|
//
|
||||||
// REGRESYON: koşul `all(|p| p.disk != active_disk)` idi, yani
|
// REGRESYON: koşul `all(|p| p.disk != active_disk)` idi, yani
|
||||||
@@ -628,6 +646,14 @@ fn build_table_rows<'a>(
|
|||||||
// Diskte tanım var ama hiçbiri silinmek işaretli değilse
|
// Diskte tanım var ama hiçbiri silinmek işaretli değilse
|
||||||
// (`sda1` + 15 GB boş) satır hiç basılmıyordu.
|
// (`sda1` + 15 GB boş) satır hiç basılmıyordu.
|
||||||
//
|
//
|
||||||
|
// `has_symbolic` kuralı: "Kalan Alan" tanımı varsa boş alan o
|
||||||
|
// tanıma aittir. REGRESYON 2: sembolik tanım (`size_mb == 0`)
|
||||||
|
// hiçbir hesaba katılmadığı için hem bölüm satırı hem boş alan
|
||||||
|
// satırı kalanın tamamını gösteriyordu — 20 GB'lik disk
|
||||||
|
// 39 GB kullanıyormuş gibi görünüyordu. Kullanıcı raporu:
|
||||||
|
// "eklenen bölümün 19.8 gb demesine rağmen bunu boş alandan
|
||||||
|
// düşmedi".
|
||||||
|
//
|
||||||
// `first_idx: None` burada "seçilemez" DEĞİL demektir; yalnızca
|
// `first_idx: None` burada "seçilemez" DEĞİL demektir; yalnızca
|
||||||
// temsil ettiği silinmiş bir tanım yoktur. Tıklanabilirdir
|
// temsil ettiği silinmiş bir tanım yoktur. Tıklanabilirdir
|
||||||
// (`global_idx == None` dalı `selected_free` tutar ve
|
// (`global_idx == None` dalı `selected_free` tutar ve
|
||||||
@@ -695,8 +721,34 @@ fn manual_capacity_error(parts: &[CustomPartition], disks: &[DiskInfo]) -> Optio
|
|||||||
None => continue,
|
None => continue,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Aynı diskte iki "Kalan Alan" tanımı çelişkidir: ikisi de
|
||||||
|
// kalanın tamamını alır, ikincisine hiç yer kalmaz.
|
||||||
|
let symbolic: Vec<&CustomPartition> = defs.iter()
|
||||||
|
.copied()
|
||||||
|
.filter(|p| p.size_mb == 0 && p.orig_device.is_empty())
|
||||||
|
.collect();
|
||||||
|
if symbolic.len() > 1 {
|
||||||
|
return Some(format!(
|
||||||
|
"{}: {} adet \"Kalan Alan\" tanımı var; her biri diskin kalanının tamamını alır, birden fazlası olamaz",
|
||||||
|
d, symbolic.len()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sembolik tanımın `size_mb` = 0 olduğu için sabit toplama
|
||||||
|
// KATILMAZ. Önceden yalnızca `fixed_mb > cap_mb` kontrolü
|
||||||
|
// vardı; disk tamamen sabit tanımlarla doluysa ve bir de
|
||||||
|
// "Kalan Alan" tanımı varsa `fixed_mb == cap_mb` geçiyordu ve
|
||||||
|
// kurulumda "yeterli boş alan yok" hatasıyla düşülüyordu.
|
||||||
|
//
|
||||||
|
// Sembolik varken boşluk SIRAYA BAĞLI: `fixed_mb == cap_mb`
|
||||||
|
// demek o tanıma 0 byte kalacağı demektir → `>=` ile reddedilir.
|
||||||
let fixed_mb: u64 = defs.iter().map(|p| p.size_mb).sum();
|
let fixed_mb: u64 = defs.iter().map(|p| p.size_mb).sum();
|
||||||
if fixed_mb > cap_mb {
|
let over_capacity = if symbolic.is_empty() {
|
||||||
|
fixed_mb > cap_mb
|
||||||
|
} else {
|
||||||
|
fixed_mb >= cap_mb
|
||||||
|
};
|
||||||
|
if over_capacity {
|
||||||
return Some(format!(
|
return Some(format!(
|
||||||
"{}: sabit tanımlar ({:.1} GB) disk boyutunu ({:.1} GB) aşıyor",
|
"{}: sabit tanımlar ({:.1} GB) disk boyutunu ({:.1} GB) aşıyor",
|
||||||
d, fixed_mb as f64 / 1024.0, cap_mb as f64 / 1024.0
|
d, fixed_mb as f64 / 1024.0, cap_mb as f64 / 1024.0
|
||||||
@@ -2521,8 +2573,10 @@ fn manual_dual_bars(ui: &mut egui::Ui, state: &GlobalState, disk: &str) {
|
|||||||
(label, if p.size_mb == 0 { 0 } else { p.size_mb }, color)
|
(label, if p.size_mb == 0 { 0 } else { p.size_mb }, color)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
// Sembolik ("kalan") tanım varsa kalan boşluğun tamamını o alır
|
// Sembolik ("kalan") tanım varsa kalan boşluğun tamamını o alır.
|
||||||
let has_symbolic = defs.iter().any(|p| !p.delete && p.size_mb == 0 && p.orig_device.is_empty());
|
// Tablo ile çubuk AYRIŞMAMASI için aynı kural ortak yardımcıdan
|
||||||
|
// gelir — önceden burada ayrı bir kopya vardı.
|
||||||
|
let has_symbolic = has_symbolic_remaining(&state.custom_partitions, disk);
|
||||||
let fixed_new: u64 = new_segs.iter().map(|s| s.1).sum();
|
let fixed_new: u64 = new_segs.iter().map(|s| s.1).sum();
|
||||||
let free_mb = disk_mb.saturating_sub(fixed_new);
|
let free_mb = disk_mb.saturating_sub(fixed_new);
|
||||||
|
|
||||||
@@ -3554,6 +3608,171 @@ mod free_space_tests {
|
|||||||
let parts = vec![part("/dev/sda1", 500, FsType::Ntfs, "")];
|
let parts = vec![part("/dev/sda1", 500, FsType::Ntfs, "")];
|
||||||
assert!(build_table_rows(&parts, "", 20_480).is_empty());
|
assert!(build_table_rows(&parts, "", 20_480).is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── "Kalan Alan" (sembolik) tanımlar ───────────────────────
|
||||||
|
|
||||||
|
/// Kullanıcı raporu: "eklenen bölümün 19.8 gb demesine rağmen
|
||||||
|
/// bunu boş alandan düşmedi".
|
||||||
|
///
|
||||||
|
/// REGRESYON: sembolik tanımın `size_mb` = 0 olduğu için
|
||||||
|
/// `used_total`'a katkısı yok; hem bölüm satırı hem boş alan
|
||||||
|
/// satırı kalanın tamamını gösteriyordu.
|
||||||
|
#[test]
|
||||||
|
fn symbolic_remaining_absorbs_the_free_space_row() {
|
||||||
|
let mut rest = part("/dev/sda2", 0, FsType::Ntfs, "/data");
|
||||||
|
rest.orig_device = String::new(); // sembolik = yeni tanım
|
||||||
|
let parts = vec![part("/dev/sda1", 500, FsType::Ntfs, ""), rest];
|
||||||
|
let rows = build_table_rows(&parts, "/dev/sda", 20_480);
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
free_mb_of(&rows).is_empty(),
|
||||||
|
"sembolik tanım kalanı alıyor, ayrı boş alan satırı olmamalı: {:?}",
|
||||||
|
free_mb_of(&rows)
|
||||||
|
);
|
||||||
|
assert_eq!(rows.len(), 2, "sda1 + sembolik bölüm olmalı");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sembolik tanımın kendi satırı kalanın tamamını GÖSTERİR —
|
||||||
|
/// kullanıcı alanın nereye gittiğini görebilmeli.
|
||||||
|
#[test]
|
||||||
|
fn symbolic_partition_row_shows_the_full_remainder() {
|
||||||
|
let mut rest = part("/dev/sda2", 0, FsType::Ntfs, "/data");
|
||||||
|
rest.orig_device = String::new();
|
||||||
|
let parts = vec![part("/dev/sda1", 500, FsType::Ntfs, ""), rest];
|
||||||
|
let rows = build_table_rows(&parts, "/dev/sda", 20_480);
|
||||||
|
|
||||||
|
let symbolic = rows.iter().find_map(|r| match r {
|
||||||
|
TableRow::Part(_, p) if p.size_mb == 0 => Some(p.device.as_str()),
|
||||||
|
_ => None,
|
||||||
|
});
|
||||||
|
assert_eq!(symbolic, Some("/dev/sda2"), "sembolik bölüm satırı görünmeli");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sembolik tanım silinmek işaretliyse boş alan satırı GERİ GELİR —
|
||||||
|
/// artık o alanı kimse almıyor. (sda1 hâlâ 500 MB kullandığı için
|
||||||
|
/// serbest alan 19980 MB, 20480 değil.)
|
||||||
|
#[test]
|
||||||
|
fn deleting_the_symbolic_definition_frees_the_row_again() {
|
||||||
|
let mut rest = part("/dev/sda2", 0, FsType::Ntfs, "/data");
|
||||||
|
rest.orig_device = String::new();
|
||||||
|
rest.delete = true;
|
||||||
|
let parts = vec![part("/dev/sda1", 500, FsType::Ntfs, ""), rest];
|
||||||
|
let rows = build_table_rows(&parts, "/dev/sda", 20_480);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
free_mb_of(&rows),
|
||||||
|
vec![20_480 - 500],
|
||||||
|
"sembolik tanım silinince kalan boş alan satırı geri gelmeli"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `size_mb == 0` OLAN FİZİKSEL bölüm sembolik sayılmaz — 0 boyutlu
|
||||||
|
/// taranmış bölüm "kalanın tamamı" demek değildir. (Yine de fiziksel
|
||||||
|
/// bölümler `skip_format` geldiği için ayrı konu.)
|
||||||
|
#[test]
|
||||||
|
fn zero_sized_physical_partition_is_not_symbolic() {
|
||||||
|
let physical = part("/dev/sda1", 0, FsType::Ext4, ""); // orig_device DOLU
|
||||||
|
let parts = vec![physical];
|
||||||
|
assert!(
|
||||||
|
!super::has_symbolic_remaining(&parts, "/dev/sda"),
|
||||||
|
"orig_device dolu bölüm sembolik sayılmamalı"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ⭐ Sembolik ("Kalan Alan") tanımların KAPASİTE doğrulaması
|
||||||
|
///
|
||||||
|
/// Bu, AGENTS.md'de açık madde olarak duruyordu:
|
||||||
|
/// "`manual_capacity_error` sembolik (`size_mb == 0`) tanımları
|
||||||
|
/// hesaba katmıyor → `fixed == cap` geçiyor, kurulumda 'yeterli boş
|
||||||
|
/// alan yok' ile düşüyor".
|
||||||
|
#[cfg(test)]
|
||||||
|
mod symbolic_capacity_tests {
|
||||||
|
use super::manual_capacity_error;
|
||||||
|
use super::testutil::{disk, part};
|
||||||
|
use crate::installer::FsType;
|
||||||
|
|
||||||
|
fn symbolic(device: &str, fstype: FsType, mountpoint: &str) -> crate::installer::CustomPartition {
|
||||||
|
let mut p = part(device, 0, fstype, mountpoint);
|
||||||
|
p.orig_device = String::new();
|
||||||
|
p
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Disk sabit tanımlarla TAM doluysa ve bir de "Kalan Alan" tanımı
|
||||||
|
/// varsa, o tanıma 0 byte kalır. Kuruluma başlamadan reddedilmeli.
|
||||||
|
#[test]
|
||||||
|
fn full_disk_with_a_symbolic_definition_is_rejected() {
|
||||||
|
let disks = vec![disk("/dev/sda", 20)];
|
||||||
|
let parts = vec![
|
||||||
|
part("/dev/sda1", 20_480, FsType::Ext4, "/"),
|
||||||
|
symbolic("/dev/sda2", FsType::Ext4, "/data"),
|
||||||
|
];
|
||||||
|
let err = manual_capacity_error(&parts, &disks);
|
||||||
|
assert!(
|
||||||
|
err.is_some(),
|
||||||
|
"dolu disk + Kalan Alan tanımı reddedilmeli: {:?}",
|
||||||
|
err
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// REGRESYON: burada sabit toplam 500 MB, kapasite 20 GB — bol yer
|
||||||
|
/// var, geçerli olmalı. `>=` kontrolü yanlışlıkla burada da
|
||||||
|
/// reddetmemeli.
|
||||||
|
#[test]
|
||||||
|
fn symbolic_with_headroom_is_accepted() {
|
||||||
|
let disks = vec![disk("/dev/sda", 20)];
|
||||||
|
let parts = vec![
|
||||||
|
part("/dev/sda1", 500, FsType::Ntfs, ""),
|
||||||
|
symbolic("/dev/sda2", FsType::Ntfs, "/data"),
|
||||||
|
];
|
||||||
|
assert_eq!(
|
||||||
|
manual_capacity_error(&parts, &disks),
|
||||||
|
None,
|
||||||
|
"yer olan sembolik tanım geçerli olmalı"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Aynı diskte iki "Kalan Alan" tanımı çelişkidir: ikisi de kalanın
|
||||||
|
/// tamamını alır, ikincisine hiç yer kalmaz.
|
||||||
|
#[test]
|
||||||
|
fn two_symbolic_definitions_on_one_disk_are_rejected() {
|
||||||
|
let disks = vec![disk("/dev/sda", 20)];
|
||||||
|
let parts = vec![
|
||||||
|
symbolic("/dev/sda1", FsType::Ext4, "/"),
|
||||||
|
symbolic("/dev/sda2", FsType::Ext4, "/data"),
|
||||||
|
];
|
||||||
|
let err = manual_capacity_error(&parts, &disks);
|
||||||
|
assert!(err.is_some(), "iki Kalan Alan tanımı reddedilmeli: {:?}", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Farklı disklerde birer tane olabilir — /home sdb'de, / sda'da.
|
||||||
|
#[test]
|
||||||
|
fn one_symbolic_per_disk_is_accepted() {
|
||||||
|
let disks = vec![disk("/dev/sda", 20), disk("/dev/sdb", 500)];
|
||||||
|
let parts = vec![
|
||||||
|
part("/dev/sda1", 500, FsType::Ntfs, ""),
|
||||||
|
symbolic("/dev/sda2", FsType::Ext4, "/"),
|
||||||
|
symbolic("/dev/sdb1", FsType::Ext4, "/home"),
|
||||||
|
];
|
||||||
|
assert_eq!(
|
||||||
|
manual_capacity_error(&parts, &disks),
|
||||||
|
None,
|
||||||
|
"her diskte bir tane sembolik tanım geçerli olmalı"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sembolik olmayan, sabit boyutlu tanımlar için davranış DEĞİŞMEDİ:
|
||||||
|
/// tam dolu olmak yine geçerli.
|
||||||
|
#[test]
|
||||||
|
fn exactly_full_disk_without_symbolic_is_accepted() {
|
||||||
|
let disks = vec![disk("/dev/sda", 20)];
|
||||||
|
let parts = vec![part("/dev/sda1", 20_480, FsType::Ext4, "/")];
|
||||||
|
assert_eq!(
|
||||||
|
manual_capacity_error(&parts, &disks),
|
||||||
|
None,
|
||||||
|
"sabit tanımlarla tam dolu disk geçerli olmalı"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
Reference in New Issue
Block a user