furtka/tests/test_drives.py

118 lines
3.2 KiB
Python
Raw Permalink Normal View History

from drives import (
get_drive_type_label,
get_drive_type_score,
get_size_score,
feat: webinstaller writes archinstall config + execs install, styled Wires the live-ISO wizard from "shows three screens" to "actually invokes archinstall on the chosen disk", plus first-pass styling so it stops looking like raw <h1>/<form>. Webinstaller flow: - S1 form gains username/password/password2/language with server-side validation (hostname/username regex, ≥8 char password, match check). - /install/run writes user_configuration.json + user_credentials.json (creds 0600) to FURTKA_STATE_DIR (default /tmp/furtka), then execs `archinstall --config … --creds … --silent` as a backgrounded subprocess. - /install/log renders the subprocess output via meta-refresh polling. - FURTKA_DRY_RUN=1 short-circuits the exec for testing. - archinstall flag names verified against `archinstall --help` in an archlinux container before committing. Drive list: - drives.py now filters via `lsblk … -o NAME,SIZE,TYPE` keeping TYPE=disk, so the live ISO's own squashfs (loop) and CD-ROM (rom) stop appearing as install targets. Boot menu: - iso/build.sh sed-rebrands "Arch Linux install medium" → "Furtka Live Installer" across grub/, syslinux/, and efiboot/loader/ entries. Verified zero leftovers against the current releng profile. Styling: - static/style.css adopts the website's design tokens (palette, typography, gate-mark accent), with light + dark via prefers-color-scheme. - New base.html with header (gate SVG + FURTKA·INSTALLER wordmark + step indicator) and footer; all install templates extend it. - Drive picker uses radio cards with score chip; overview uses a summary table and a destructive "wipe drive" button. Tests: 17 pass (4 new in test_app.py covering validation + config builders, 2 new in test_drives.py covering the lsblk filter). Ruff clean. README roadmap updated to mark these done and explicitly defer the 26.0-alpha release until archinstall actually completes end-to-end on a VM. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 10:54:49 +02:00
parse_lsblk_output,
parse_size_gb,
score_device,
)
def test_parse_size_gb_terabytes():
assert parse_size_gb("1T") == 1024.0
def test_parse_size_gb_gigabytes():
assert parse_size_gb("500G") == 500.0
def test_parse_size_gb_megabytes():
assert parse_size_gb("2048M") == 2.0
def test_parse_size_gb_european_comma_decimal():
assert parse_size_gb("1,5T") == 1.5 * 1024
def test_parse_size_gb_empty_returns_none():
assert parse_size_gb("") is None
def test_parse_size_gb_unknown_unit_returns_none():
assert parse_size_gb("500K") is None
def test_drive_type_score_nvme():
assert get_drive_type_score("/dev/nvme0n1") == 15
def test_drive_type_score_ssd():
assert get_drive_type_score("/dev/ssd0") == 10
def test_drive_type_score_hdd_fallback():
assert get_drive_type_score("/dev/sda") == 5
def test_size_score_bands():
assert get_size_score(None) == 5
assert get_size_score(64) == 5
assert get_size_score(256) == 7
assert get_size_score(1024) == 10
def test_score_device_sums_type_and_size(monkeypatch):
import drives
monkeypatch.setattr(drives, "get_drive_health", lambda _: 10)
assert score_device("/dev/nvme0n1", 1024) == 15 + 10 + 10
assert score_device("/dev/sda", 64) == 5 + 10 + 5
feat: webinstaller writes archinstall config + execs install, styled Wires the live-ISO wizard from "shows three screens" to "actually invokes archinstall on the chosen disk", plus first-pass styling so it stops looking like raw <h1>/<form>. Webinstaller flow: - S1 form gains username/password/password2/language with server-side validation (hostname/username regex, ≥8 char password, match check). - /install/run writes user_configuration.json + user_credentials.json (creds 0600) to FURTKA_STATE_DIR (default /tmp/furtka), then execs `archinstall --config … --creds … --silent` as a backgrounded subprocess. - /install/log renders the subprocess output via meta-refresh polling. - FURTKA_DRY_RUN=1 short-circuits the exec for testing. - archinstall flag names verified against `archinstall --help` in an archlinux container before committing. Drive list: - drives.py now filters via `lsblk … -o NAME,SIZE,TYPE` keeping TYPE=disk, so the live ISO's own squashfs (loop) and CD-ROM (rom) stop appearing as install targets. Boot menu: - iso/build.sh sed-rebrands "Arch Linux install medium" → "Furtka Live Installer" across grub/, syslinux/, and efiboot/loader/ entries. Verified zero leftovers against the current releng profile. Styling: - static/style.css adopts the website's design tokens (palette, typography, gate-mark accent), with light + dark via prefers-color-scheme. - New base.html with header (gate SVG + FURTKA·INSTALLER wordmark + step indicator) and footer; all install templates extend it. - Drive picker uses radio cards with score chip; overview uses a summary table and a destructive "wipe drive" button. Tests: 17 pass (4 new in test_app.py covering validation + config builders, 2 new in test_drives.py covering the lsblk filter). Ruff clean. README roadmap updated to mark these done and explicitly defer the 26.0-alpha release until archinstall actually completes end-to-end on a VM. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 10:54:49 +02:00
def test_parse_lsblk_drops_loop_and_rom(monkeypatch):
import drives
monkeypatch.setattr(drives, "_smart_status", lambda _: "passed")
output = "loop0 2.5G loop\nsr0 1024M rom\nsda 500G disk\nnvme0n1 1T disk\n"
feat: webinstaller writes archinstall config + execs install, styled Wires the live-ISO wizard from "shows three screens" to "actually invokes archinstall on the chosen disk", plus first-pass styling so it stops looking like raw <h1>/<form>. Webinstaller flow: - S1 form gains username/password/password2/language with server-side validation (hostname/username regex, ≥8 char password, match check). - /install/run writes user_configuration.json + user_credentials.json (creds 0600) to FURTKA_STATE_DIR (default /tmp/furtka), then execs `archinstall --config … --creds … --silent` as a backgrounded subprocess. - /install/log renders the subprocess output via meta-refresh polling. - FURTKA_DRY_RUN=1 short-circuits the exec for testing. - archinstall flag names verified against `archinstall --help` in an archlinux container before committing. Drive list: - drives.py now filters via `lsblk … -o NAME,SIZE,TYPE` keeping TYPE=disk, so the live ISO's own squashfs (loop) and CD-ROM (rom) stop appearing as install targets. Boot menu: - iso/build.sh sed-rebrands "Arch Linux install medium" → "Furtka Live Installer" across grub/, syslinux/, and efiboot/loader/ entries. Verified zero leftovers against the current releng profile. Styling: - static/style.css adopts the website's design tokens (palette, typography, gate-mark accent), with light + dark via prefers-color-scheme. - New base.html with header (gate SVG + FURTKA·INSTALLER wordmark + step indicator) and footer; all install templates extend it. - Drive picker uses radio cards with score chip; overview uses a summary table and a destructive "wipe drive" button. Tests: 17 pass (4 new in test_app.py covering validation + config builders, 2 new in test_drives.py covering the lsblk filter). Ruff clean. README roadmap updated to mark these done and explicitly defer the 26.0-alpha release until archinstall actually completes end-to-end on a VM. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 10:54:49 +02:00
devices = parse_lsblk_output(output)
names = [d["name"] for d in devices]
assert names == ["/dev/nvme0n1", "/dev/sda"]
def test_parse_lsblk_attaches_human_labels(monkeypatch):
import drives
monkeypatch.setattr(drives, "_smart_status", lambda _: "passed")
output = "nvme0n1 1T disk\n"
[dev] = parse_lsblk_output(output)
assert dev["type_label"] == "NVMe"
assert dev["health_label"] == "Healthy"
def test_parse_lsblk_surfaces_smart_warning(monkeypatch):
import drives
monkeypatch.setattr(drives, "_smart_status", lambda _: "failed")
[dev] = parse_lsblk_output("sda 500G disk\n")
assert dev["health_label"] == "SMART warning"
def test_drive_type_label_nvme_ssd_hdd():
assert get_drive_type_label("/dev/nvme0n1") == "NVMe"
assert get_drive_type_label("/dev/ssd0") == "SSD"
assert get_drive_type_label("/dev/sda") == "HDD"
feat: webinstaller writes archinstall config + execs install, styled Wires the live-ISO wizard from "shows three screens" to "actually invokes archinstall on the chosen disk", plus first-pass styling so it stops looking like raw <h1>/<form>. Webinstaller flow: - S1 form gains username/password/password2/language with server-side validation (hostname/username regex, ≥8 char password, match check). - /install/run writes user_configuration.json + user_credentials.json (creds 0600) to FURTKA_STATE_DIR (default /tmp/furtka), then execs `archinstall --config … --creds … --silent` as a backgrounded subprocess. - /install/log renders the subprocess output via meta-refresh polling. - FURTKA_DRY_RUN=1 short-circuits the exec for testing. - archinstall flag names verified against `archinstall --help` in an archlinux container before committing. Drive list: - drives.py now filters via `lsblk … -o NAME,SIZE,TYPE` keeping TYPE=disk, so the live ISO's own squashfs (loop) and CD-ROM (rom) stop appearing as install targets. Boot menu: - iso/build.sh sed-rebrands "Arch Linux install medium" → "Furtka Live Installer" across grub/, syslinux/, and efiboot/loader/ entries. Verified zero leftovers against the current releng profile. Styling: - static/style.css adopts the website's design tokens (palette, typography, gate-mark accent), with light + dark via prefers-color-scheme. - New base.html with header (gate SVG + FURTKA·INSTALLER wordmark + step indicator) and footer; all install templates extend it. - Drive picker uses radio cards with score chip; overview uses a summary table and a destructive "wipe drive" button. Tests: 17 pass (4 new in test_app.py covering validation + config builders, 2 new in test_drives.py covering the lsblk filter). Ruff clean. README roadmap updated to mark these done and explicitly defer the 26.0-alpha release until archinstall actually completes end-to-end on a VM. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 10:54:49 +02:00
def test_parse_lsblk_handles_empty_output():
assert parse_lsblk_output("") == []
def test_parse_lsblk_drops_boot_usb(monkeypatch):
import drives
monkeypatch.setattr(drives, "_smart_status", lambda _: "passed")
output = "sda 500G disk\nsdb 16G disk\nnvme0n1 1T disk\n"
devices = parse_lsblk_output(output, boot_disk="sdb")
names = [d["name"] for d in devices]
assert "/dev/sdb" not in names
assert names == ["/dev/nvme0n1", "/dev/sda"]
def test_parse_lsblk_no_boot_disk_keeps_all(monkeypatch):
import drives
monkeypatch.setattr(drives, "_smart_status", lambda _: "passed")
output = "sda 500G disk\nsdb 16G disk\n"
names = [d["name"] for d in parse_lsblk_output(output, boot_disk=None)]
assert set(names) == {"/dev/sda", "/dev/sdb"}