Skip to content

Commit d7e2cf9

Browse files
Merge pull request #953 from boffin-dmytro/test/bats-tests-for-preflight-and-requirements-phases
test: add BATS tests for preflight and requirements phase scripts
2 parents f9114d3 + 3c813ff commit d7e2cf9

File tree

3 files changed

+548
-0
lines changed

3 files changed

+548
-0
lines changed
Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
#!/usr/bin/env bats
2+
# ============================================================================
3+
# BATS tests for installers/phases/01-preflight.sh
4+
# ============================================================================
5+
# Tests the preflight phase script by sourcing it in a controlled environment
6+
# with mocked commands and filesystem.
7+
8+
load '../bats/bats-support/load'
9+
load '../bats/bats-assert/load'
10+
11+
setup() {
12+
# Stub logging/UI functions
13+
log() { echo "LOG: $1" >> "$BATS_TEST_TMPDIR/install.log"; }
14+
export -f log
15+
warn() { echo "WARN: $1" >> "$BATS_TEST_TMPDIR/install.log"; }
16+
export -f warn
17+
error() { echo "ERROR: $1" >> "$BATS_TEST_TMPDIR/install.log"; exit 1; }
18+
export -f error
19+
ai() { :; }; export -f ai
20+
ai_ok() { echo "OK" >> "$BATS_TEST_TMPDIR/install.log"; }; export -f ai_ok
21+
ai_bad() { :; }; export -f ai_bad
22+
signal() { :; }; export -f signal
23+
show_phase() { :; }; export -f show_phase
24+
show_stranger_boot() { :; }; export -f show_stranger_boot
25+
dream_progress() { :; }; export -f dream_progress
26+
27+
# Set up test environment
28+
export SCRIPT_DIR="$BATS_TEST_TMPDIR/dream-server"
29+
export INSTALL_DIR="$BATS_TEST_TMPDIR/install-target"
30+
export LOG_FILE="$BATS_TEST_TMPDIR/install.log"
31+
export INTERACTIVE=false
32+
export DRY_RUN=false
33+
export PKG_MANAGER="apt"
34+
export VERSION="2.3.0"
35+
36+
mkdir -p "$SCRIPT_DIR"
37+
touch "$LOG_FILE"
38+
39+
# Create minimal os-release
40+
mkdir -p "$BATS_TEST_TMPDIR/etc"
41+
cat > "$BATS_TEST_TMPDIR/etc/os-release" << 'EOF'
42+
PRETTY_NAME="Test Linux 1.0"
43+
ID=ubuntu
44+
EOF
45+
}
46+
47+
teardown() {
48+
rm -rf "$BATS_TEST_TMPDIR/dream-server" "$BATS_TEST_TMPDIR/install-target"
49+
}
50+
51+
# ── Root check ──────────────────────────────────────────────────────────────
52+
53+
@test "preflight: fails when run as root" {
54+
local patched_phase="$BATS_TEST_TMPDIR/01-preflight-root-test.sh"
55+
sed 's/\[\[ \$EUID -eq 0 \]\]/[[ ${TEST_EUID:-$EUID} -eq 0 ]]/' \
56+
"$BATS_TEST_DIRNAME/../../installers/phases/01-preflight.sh" > "$patched_phase"
57+
58+
run bash -c '
59+
export SCRIPT_DIR="'"$SCRIPT_DIR"'"
60+
export INSTALL_DIR="'"$INSTALL_DIR"'"
61+
export LOG_FILE="'"$LOG_FILE"'"
62+
export INTERACTIVE=false
63+
export DRY_RUN=false
64+
export PKG_MANAGER="apt"
65+
export VERSION="2.3.0"
66+
export TEST_EUID=0
67+
68+
log() { :; }
69+
warn() { :; }
70+
error() { echo "ROOT_ERROR"; exit 1; }
71+
ai() { :; }
72+
ai_ok() { :; }
73+
ai_bad() { :; }
74+
signal() { :; }
75+
show_phase() { :; }
76+
show_stranger_boot() { :; }
77+
dream_progress() { :; }
78+
79+
source "'"$patched_phase"'"
80+
'
81+
assert_failure
82+
assert_output --partial "ROOT_ERROR"
83+
}
84+
85+
# ── OS check ────────────────────────────────────────────────────────────────
86+
87+
@test "preflight: fails when /etc/os-release is missing" {
88+
run bash -c '
89+
error() { echo "OS_ERROR"; exit 1; }
90+
if [[ ! -f "/nonexistent/os-release" ]]; then
91+
error "Unsupported OS."
92+
fi
93+
'
94+
assert_failure
95+
assert_output --partial "OS_ERROR"
96+
}
97+
98+
@test "preflight: reads OS info from /etc/os-release" {
99+
# Create a fake os-release and test sourcing
100+
run bash -c '
101+
source "'"$BATS_TEST_TMPDIR/etc/os-release"'"
102+
echo "$PRETTY_NAME"
103+
'
104+
assert_success
105+
assert_output "Test Linux 1.0"
106+
}
107+
108+
# ── Required tools ──────────────────────────────────────────────────────────
109+
110+
@test "preflight: fails when curl is missing" {
111+
# Create a PATH without curl
112+
mkdir -p "$BATS_TEST_TMPDIR/no-curl-bin"
113+
run bash -c '
114+
export PATH="'"$BATS_TEST_TMPDIR/no-curl-bin"'"
115+
PKG_MANAGER="apt"
116+
error() { echo "CURL_ERROR: $1"; exit 1; }
117+
if ! command -v curl &> /dev/null; then
118+
case "$PKG_MANAGER" in
119+
*) error "curl is required but not installed. Install with: sudo apt install curl" ;;
120+
esac
121+
fi
122+
'
123+
assert_failure
124+
assert_output --partial "CURL_ERROR"
125+
}
126+
127+
# ── Source file check ───────────────────────────────────────────────────────
128+
129+
@test "preflight: fails when no compose files exist" {
130+
run bash -c '
131+
SCRIPT_DIR="'"$BATS_TEST_TMPDIR"'"
132+
error() { echo "COMPOSE_ERROR"; exit 1; }
133+
if [[ ! -f "$SCRIPT_DIR/docker-compose.yml" ]] && [[ ! -f "$SCRIPT_DIR/docker-compose.base.yml" ]]; then
134+
error "No compose files found."
135+
fi
136+
'
137+
assert_failure
138+
assert_output --partial "COMPOSE_ERROR"
139+
}
140+
141+
@test "preflight: passes when compose files exist" {
142+
touch "$SCRIPT_DIR/docker-compose.base.yml"
143+
# Create a fake curl in PATH
144+
mkdir -p "$BATS_TEST_TMPDIR/bin"
145+
cat > "$BATS_TEST_TMPDIR/bin/curl" << 'MOCK'
146+
#!/bin/bash
147+
echo "curl 8.0.0"
148+
MOCK
149+
chmod +x "$BATS_TEST_TMPDIR/bin/curl"
150+
export PATH="$BATS_TEST_TMPDIR/bin:$PATH"
151+
152+
# Create fake jq
153+
cat > "$BATS_TEST_TMPDIR/bin/jq" << 'MOCK'
154+
#!/bin/bash
155+
echo "jq-1.7"
156+
MOCK
157+
chmod +x "$BATS_TEST_TMPDIR/bin/jq"
158+
159+
# Source the phase script (it will exit on error, so we capture)
160+
run bash -c '
161+
export SCRIPT_DIR="'"$SCRIPT_DIR"'"
162+
export INSTALL_DIR="'"$INSTALL_DIR"'"
163+
export LOG_FILE="'"$LOG_FILE"'"
164+
export INTERACTIVE=false
165+
export DRY_RUN=false
166+
export PKG_MANAGER="apt"
167+
export VERSION="2.3.0"
168+
169+
log() { :; }
170+
warn() { :; }
171+
error() { echo "PHASE_ERROR: $1"; exit 1; }
172+
ai() { :; }
173+
ai_ok() { :; }
174+
signal() { :; }
175+
show_phase() { :; }
176+
show_stranger_boot() { :; }
177+
dream_progress() { :; }
178+
179+
source "'"$BATS_TEST_DIRNAME/../../installers/phases/01-preflight.sh"'"
180+
echo "PHASE_COMPLETE"
181+
'
182+
assert_success
183+
assert_output --partial "PHASE_COMPLETE"
184+
}
185+
186+
# ── Existing installation detection ─────────────────────────────────────────
187+
188+
@test "preflight: detects existing installation" {
189+
touch "$SCRIPT_DIR/docker-compose.base.yml"
190+
mkdir -p "$INSTALL_DIR"
191+
192+
run bash -c '
193+
export SCRIPT_DIR="'"$SCRIPT_DIR"'"
194+
export INSTALL_DIR="'"$INSTALL_DIR"'"
195+
export LOG_FILE="'"$LOG_FILE"'"
196+
export INTERACTIVE=false
197+
export DRY_RUN=false
198+
export PKG_MANAGER="apt"
199+
export VERSION="2.3.0"
200+
201+
log() { echo "LOG: $1"; }
202+
warn() { :; }
203+
error() { echo "ERROR: $1"; exit 1; }
204+
ai() { :; }
205+
ai_ok() { :; }
206+
signal() { echo "SIGNAL: $1"; }
207+
show_phase() { :; }
208+
show_stranger_boot() { :; }
209+
dream_progress() { :; }
210+
211+
source "'"$BATS_TEST_DIRNAME/../../installers/phases/01-preflight.sh"'"
212+
'
213+
214+
# Should log about existing installation
215+
assert_output --partial "Existing installation"
216+
}
217+
218+
# ── Optional tools warning ──────────────────────────────────────────────────
219+
220+
@test "preflight: warns about missing optional tools" {
221+
touch "$SCRIPT_DIR/docker-compose.base.yml"
222+
mkdir -p "$BATS_TEST_TMPDIR/bin"
223+
224+
# Create curl and jq, then shadow command -v rsync so the warning path is deterministic
225+
cat > "$BATS_TEST_TMPDIR/bin/curl" << 'MOCK'
226+
#!/bin/bash
227+
echo "curl 8.0.0"
228+
MOCK
229+
chmod +x "$BATS_TEST_TMPDIR/bin/curl"
230+
cat > "$BATS_TEST_TMPDIR/bin/jq" << 'MOCK'
231+
#!/bin/bash
232+
echo "jq-1.7"
233+
MOCK
234+
chmod +x "$BATS_TEST_TMPDIR/bin/jq"
235+
export PATH="$BATS_TEST_TMPDIR/bin:$PATH"
236+
237+
run bash -c '
238+
export SCRIPT_DIR="'"$SCRIPT_DIR"'"
239+
export INSTALL_DIR="'"$INSTALL_DIR"'"
240+
export LOG_FILE="'"$LOG_FILE"'"
241+
export INTERACTIVE=false
242+
export DRY_RUN=false
243+
export PKG_MANAGER="apt"
244+
export VERSION="2.3.0"
245+
export PATH="'"$BATS_TEST_TMPDIR/bin:$PATH"'"
246+
247+
log() { :; }
248+
warn() { echo "WARN: $1"; }
249+
error() { echo "ERROR: $1"; exit 1; }
250+
ai() { :; }
251+
ai_ok() { :; }
252+
signal() { :; }
253+
show_phase() { :; }
254+
show_stranger_boot() { :; }
255+
dream_progress() { :; }
256+
command() {
257+
if [[ "$1" == "-v" && "$2" == "rsync" ]]; then
258+
return 1
259+
fi
260+
builtin command "$@"
261+
}
262+
263+
source "'"$BATS_TEST_DIRNAME/../../installers/phases/01-preflight.sh"'"
264+
'
265+
266+
assert_output --partial "rsync"
267+
}

0 commit comments

Comments
 (0)