blob: 46f023672e0640509057730870dadbdd86a41a8e (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
|
#!/usr/bin/env bats
# Unit tests for installer/lib/config.sh
setup() {
# shellcheck disable=SC1091
source "${BATS_TEST_DIRNAME}/../../installer/lib/common.sh"
# shellcheck disable=SC1091
source "${BATS_TEST_DIRNAME}/../../installer/lib/config.sh"
}
@test "parse_args stores --config-file path" {
parse_args --config-file /tmp/foo.conf
[ "$CONFIG_FILE" = "/tmp/foo.conf" ]
}
@test "parse_args rejects --config-file with no argument" {
run parse_args --config-file
[ "$status" -eq 1 ]
[[ "$output" == *"requires a path"* ]]
}
@test "parse_args rejects --config-file when value looks like a flag" {
run parse_args --config-file --help
[ "$status" -eq 1 ]
[[ "$output" == *"requires a path"* ]]
}
@test "parse_args --color enables color vars" {
[ -z "$RED" ]
parse_args --color
[ -n "$RED" ]
}
@test "parse_args --help shows usage and exits 0" {
run parse_args --help
[ "$status" -eq 0 ]
[[ "$output" == *"Usage:"* ]]
[[ "$output" == *"--config-file"* ]]
}
@test "parse_args rejects unknown option" {
run parse_args --not-a-real-flag
[ "$status" -eq 1 ]
[[ "$output" == *"Unknown option"* ]]
}
@test "load_config errors on missing file" {
run load_config /nonexistent/path/archangel.conf
[ "$status" -eq 1 ]
[[ "$output" == *"Config file not found"* ]]
}
@test "load_config parses a minimal config and sets UNATTENDED" {
local tmp
tmp=$(mktemp)
cat >"$tmp" <<'EOF'
HOSTNAME=testhost
TIMEZONE=UTC
DISKS=/dev/sda,/dev/sdb
ROOT_PASSWORD=secret
EOF
load_config "$tmp"
[ "$HOSTNAME" = "testhost" ]
[ "$TIMEZONE" = "UTC" ]
[ "$ROOT_PASSWORD" = "secret" ]
[ "${SELECTED_DISKS[0]}" = "/dev/sda" ]
[ "${SELECTED_DISKS[1]}" = "/dev/sdb" ]
[ "$UNATTENDED" = "true" ]
rm -f "$tmp"
}
@test "load_config parses a single-disk config into 1-element array" {
local tmp
tmp=$(mktemp)
echo "DISKS=/dev/nvme0n1" >"$tmp"
load_config "$tmp"
[ "${#SELECTED_DISKS[@]}" -eq 1 ]
[ "${SELECTED_DISKS[0]}" = "/dev/nvme0n1" ]
rm -f "$tmp"
}
@test "validate_config fails and lists every missing required field" {
HOSTNAME=""
TIMEZONE=""
SELECTED_DISKS=()
ROOT_PASSWORD=""
run validate_config
[ "$status" -eq 1 ]
[[ "$output" == *"HOSTNAME not set"* ]]
[[ "$output" == *"TIMEZONE not set"* ]]
[[ "$output" == *"No disks selected"* ]]
[[ "$output" == *"ROOT_PASSWORD not set"* ]]
[[ "$output" == *"4 error"* ]]
}
@test "validate_config rejects an invalid timezone" {
HOSTNAME="h"
TIMEZONE="Not/A_Real_Zone_xyz"
SELECTED_DISKS=()
ROOT_PASSWORD="x"
run validate_config
[ "$status" -eq 1 ]
[[ "$output" == *"Invalid timezone"* ]]
}
@test "check_config is a no-op when CONFIG_FILE is unset" {
CONFIG_FILE=""
run check_config
[ "$status" -eq 0 ]
[ -z "$output" ]
}
@test "check_config loads the config file when CONFIG_FILE is set" {
local tmp
tmp=$(mktemp)
cat >"$tmp" <<'EOF'
HOSTNAME=fromcheckconfig
TIMEZONE=UTC
EOF
CONFIG_FILE="$tmp"
check_config
[ "$HOSTNAME" = "fromcheckconfig" ]
[ "$TIMEZONE" = "UTC" ]
[ "$UNATTENDED" = "true" ]
rm -f "$tmp"
}
@test "validate_config flags an existing-but-not-block path in SELECTED_DISKS" {
HOSTNAME=h
TIMEZONE=UTC
ROOT_PASSWORD=x
SELECTED_DISKS=(/dev/null)
run validate_config
[ "$status" -eq 1 ]
[[ "$output" == *"Disk not found: /dev/null"* ]]
}
@test "validate_config flags a missing path in SELECTED_DISKS" {
HOSTNAME=h
TIMEZONE=UTC
ROOT_PASSWORD=x
SELECTED_DISKS=(/nonexistent/disk-xyz-42)
run validate_config
[ "$status" -eq 1 ]
[[ "$output" == *"Disk not found"* ]]
}
@test "parse_args accepts --color and --config-file together (color first)" {
parse_args --color --config-file /tmp/foo.conf
[ "$CONFIG_FILE" = "/tmp/foo.conf" ]
[ -n "$RED" ]
}
@test "parse_args accepts --config-file and --color together (config first)" {
parse_args --config-file /tmp/foo.conf --color
[ "$CONFIG_FILE" = "/tmp/foo.conf" ]
[ -n "$RED" ]
}
#############################
# Default values sourced from config.sh
#############################
# config.sh is the single source of truth for installer defaults. The
# monolith no longer re-applies them in gather_input. These tests pin
# the values so a regression that drops a default surfaces here, not
# halfway through an unattended install.
@test "config.sh sets defaults for FILESYSTEM, LOCALE, KEYMAP, ENABLE_SSH, NO_ENCRYPT" {
[ "$FILESYSTEM" = "zfs" ]
[ "$LOCALE" = "en_US.UTF-8" ]
[ "$KEYMAP" = "us" ]
[ "$ENABLE_SSH" = "yes" ]
[ "$NO_ENCRYPT" = "no" ]
}
#############################
# validate_filesystem
#############################
# Called from main() between check_config and gather_input. Catches a
# typo in FILESYSTEM= from a config file before the install starts.
@test "validate_filesystem accepts zfs" {
FILESYSTEM=zfs
run validate_filesystem
[ "$status" -eq 0 ]
}
@test "validate_filesystem accepts btrfs" {
FILESYSTEM=btrfs
run validate_filesystem
[ "$status" -eq 0 ]
}
@test "validate_filesystem rejects an unknown filesystem" {
FILESYSTEM=ext4
run validate_filesystem
[ "$status" -eq 1 ]
[[ "$output" == *"Invalid FILESYSTEM"* ]]
[[ "$output" == *"ext4"* ]]
}
@test "validate_filesystem rejects an empty FILESYSTEM" {
FILESYSTEM=""
run validate_filesystem
[ "$status" -eq 1 ]
[[ "$output" == *"Invalid FILESYSTEM"* ]]
}
|