aboutsummaryrefslogtreecommitdiff
path: root/tests/unit
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-04-12 23:58:01 -0400
committerCraig Jennings <c@cjennings.net>2026-04-12 23:58:01 -0400
commit19f4624749228fcbe385d1edf1d2542c036440ff (patch)
tree961e815d2226178345f5ec7ec7cb82f23da34379 /tests/unit
parent863ceeac8fdb10258a58d35bcee6874097fffc88 (diff)
downloadarchangel-19f4624749228fcbe385d1edf1d2542c036440ff.tar.gz
archangel-19f4624749228fcbe385d1edf1d2542c036440ff.zip
refactor: extract pure RAID logic to lib/raid.sh with bats coverage
Peel the testable pieces of get_raid_level() out of the 1600-line installer monolith into installer/lib/raid.sh: - raid_valid_levels_for_count(count) — replaces the inline option-list builder in get_raid_level() - raid_is_valid(level, count) — useful for unattended-config validation - raid_usable_bytes(level, count, smallest, total) — usable-space math - raid_fault_tolerance(level, count) — max tolerable disk failures archangel now sources lib/raid.sh and uses raid_valid_levels_for_count for the fzf option list. Fzf preview subshell still inlines its own usable-bytes arithmetic (calling exported lib functions across preview subshells is fragile; left for a later pass). 30 bats tests in tests/unit/test_raid.bats cover the full enumeration table, every valid/invalid level-vs-count combo from 2 to 5 disks, mixed-size mirror, and unknown-level error paths. make test: 53/53.
Diffstat (limited to 'tests/unit')
-rw-r--r--tests/unit/test_raid.bats199
1 files changed, 199 insertions, 0 deletions
diff --git a/tests/unit/test_raid.bats b/tests/unit/test_raid.bats
new file mode 100644
index 0000000..4e2f842
--- /dev/null
+++ b/tests/unit/test_raid.bats
@@ -0,0 +1,199 @@
+#!/usr/bin/env bats
+# Unit tests for installer/lib/raid.sh
+
+setup() {
+ # shellcheck disable=SC1091
+ source "${BATS_TEST_DIRNAME}/../../installer/lib/raid.sh"
+}
+
+#############################
+# raid_valid_levels_for_count
+#############################
+
+@test "raid_valid_levels_for_count: 0 disks → empty output" {
+ run raid_valid_levels_for_count 0
+ [ "$status" -eq 0 ]
+ [ -z "$output" ]
+}
+
+@test "raid_valid_levels_for_count: 1 disk → empty output" {
+ run raid_valid_levels_for_count 1
+ [ "$status" -eq 0 ]
+ [ -z "$output" ]
+}
+
+@test "raid_valid_levels_for_count: 2 disks → mirror + stripe" {
+ run raid_valid_levels_for_count 2
+ [ "$status" -eq 0 ]
+ [ "$output" = "mirror
+stripe" ]
+}
+
+@test "raid_valid_levels_for_count: 3 disks → + raidz1" {
+ run raid_valid_levels_for_count 3
+ [ "$status" -eq 0 ]
+ [ "$output" = "mirror
+stripe
+raidz1" ]
+}
+
+@test "raid_valid_levels_for_count: 4 disks → + raidz2" {
+ run raid_valid_levels_for_count 4
+ [ "$status" -eq 0 ]
+ [ "$output" = "mirror
+stripe
+raidz1
+raidz2" ]
+}
+
+@test "raid_valid_levels_for_count: 5 disks → + raidz3" {
+ run raid_valid_levels_for_count 5
+ [ "$status" -eq 0 ]
+ [ "$output" = "mirror
+stripe
+raidz1
+raidz2
+raidz3" ]
+}
+
+@test "raid_valid_levels_for_count: 8 disks → same as 5 (no new levels)" {
+ levels_5=$(raid_valid_levels_for_count 5)
+ levels_8=$(raid_valid_levels_for_count 8)
+ [ "$levels_5" = "$levels_8" ]
+}
+
+#############################
+# raid_is_valid
+#############################
+
+@test "raid_is_valid: empty level + 1 disk = valid (no RAID)" {
+ run raid_is_valid "" 1
+ [ "$status" -eq 0 ]
+}
+
+@test "raid_is_valid: any level + 1 disk = invalid" {
+ run raid_is_valid mirror 1
+ [ "$status" -eq 1 ]
+}
+
+@test "raid_is_valid: mirror + 2 disks = valid" {
+ run raid_is_valid mirror 2
+ [ "$status" -eq 0 ]
+}
+
+@test "raid_is_valid: stripe + 2 disks = valid" {
+ run raid_is_valid stripe 2
+ [ "$status" -eq 0 ]
+}
+
+@test "raid_is_valid: raidz1 + 2 disks = invalid (need 3)" {
+ run raid_is_valid raidz1 2
+ [ "$status" -eq 1 ]
+}
+
+@test "raid_is_valid: raidz1 + 3 disks = valid" {
+ run raid_is_valid raidz1 3
+ [ "$status" -eq 0 ]
+}
+
+@test "raid_is_valid: raidz2 + 3 disks = invalid (need 4)" {
+ run raid_is_valid raidz2 3
+ [ "$status" -eq 1 ]
+}
+
+@test "raid_is_valid: raidz2 + 4 disks = valid" {
+ run raid_is_valid raidz2 4
+ [ "$status" -eq 0 ]
+}
+
+@test "raid_is_valid: raidz3 + 4 disks = invalid (need 5)" {
+ run raid_is_valid raidz3 4
+ [ "$status" -eq 1 ]
+}
+
+@test "raid_is_valid: raidz3 + 5 disks = valid" {
+ run raid_is_valid raidz3 5
+ [ "$status" -eq 0 ]
+}
+
+@test "raid_is_valid: unknown level = invalid" {
+ run raid_is_valid raidz99 5
+ [ "$status" -eq 1 ]
+}
+
+#############################
+# raid_usable_bytes
+#############################
+
+@test "raid_usable_bytes: mirror returns smallest disk's bytes" {
+ run raid_usable_bytes mirror 3 100 300
+ [ "$status" -eq 0 ]
+ [ "$output" = "100" ]
+}
+
+@test "raid_usable_bytes: stripe returns total bytes" {
+ run raid_usable_bytes stripe 3 100 300
+ [ "$status" -eq 0 ]
+ [ "$output" = "300" ]
+}
+
+@test "raid_usable_bytes: raidz1 = (n-1) * smallest" {
+ run raid_usable_bytes raidz1 3 100 300
+ [ "$status" -eq 0 ]
+ [ "$output" = "200" ]
+}
+
+@test "raid_usable_bytes: raidz2 = (n-2) * smallest" {
+ run raid_usable_bytes raidz2 4 100 400
+ [ "$status" -eq 0 ]
+ [ "$output" = "200" ]
+}
+
+@test "raid_usable_bytes: raidz3 = (n-3) * smallest" {
+ run raid_usable_bytes raidz3 5 100 500
+ [ "$status" -eq 0 ]
+ [ "$output" = "200" ]
+}
+
+@test "raid_usable_bytes: mixed-size mirror honors smallest (not average)" {
+ run raid_usable_bytes mirror 3 80 300
+ [ "$status" -eq 0 ]
+ [ "$output" = "80" ]
+}
+
+@test "raid_usable_bytes: unknown level returns status 1" {
+ run raid_usable_bytes bogus 3 100 300
+ [ "$status" -eq 1 ]
+ [ -z "$output" ]
+}
+
+#############################
+# raid_fault_tolerance
+#############################
+
+@test "raid_fault_tolerance: mirror of 3 = can lose 2" {
+ run raid_fault_tolerance mirror 3
+ [ "$output" = "2" ]
+}
+
+@test "raid_fault_tolerance: mirror of 5 = can lose 4" {
+ run raid_fault_tolerance mirror 5
+ [ "$output" = "4" ]
+}
+
+@test "raid_fault_tolerance: stripe = 0" {
+ run raid_fault_tolerance stripe 4
+ [ "$output" = "0" ]
+}
+
+@test "raid_fault_tolerance: raidz1/2/3 = 1/2/3 regardless of disk count" {
+ [ "$(raid_fault_tolerance raidz1 3)" = "1" ]
+ [ "$(raid_fault_tolerance raidz1 8)" = "1" ]
+ [ "$(raid_fault_tolerance raidz2 4)" = "2" ]
+ [ "$(raid_fault_tolerance raidz3 5)" = "3" ]
+}
+
+@test "raid_fault_tolerance: unknown level returns status 1" {
+ run raid_fault_tolerance bogus 3
+ [ "$status" -eq 1 ]
+}