Skip to content

Commit d881c39

Browse files
boffin-dmytroLightheartdevs
authored andcommitted
test: add BATS tests for preflight and requirements phase scripts
1 parent 1843ebd commit d881c39

File tree

2 files changed

+510
-0
lines changed

2 files changed

+510
-0
lines changed
Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
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+
# Simulate root by setting EUID=0
55+
# We can't actually run as root in tests, so we test the logic directly
56+
run bash -c '
57+
error() { echo "ROOT_ERROR"; exit 1; }
58+
EUID=0
59+
if [[ $EUID -eq 0 ]]; then
60+
error "Do not run as root."
61+
fi
62+
echo "passed"
63+
'
64+
assert_failure
65+
assert_output --partial "ROOT_ERROR"
66+
}
67+
68+
# ── OS check ────────────────────────────────────────────────────────────────
69+
70+
@test "preflight: fails when /etc/os-release is missing" {
71+
run bash -c '
72+
error() { echo "OS_ERROR"; exit 1; }
73+
if [[ ! -f "/nonexistent/os-release" ]]; then
74+
error "Unsupported OS."
75+
fi
76+
'
77+
assert_failure
78+
assert_output --partial "OS_ERROR"
79+
}
80+
81+
@test "preflight: reads OS info from /etc/os-release" {
82+
# Create a fake os-release and test sourcing
83+
run bash -c '
84+
source "'"$BATS_TEST_TMPDIR/etc/os-release"'"
85+
echo "$PRETTY_NAME"
86+
'
87+
assert_success
88+
assert_output "Test Linux 1.0"
89+
}
90+
91+
# ── Required tools ──────────────────────────────────────────────────────────
92+
93+
@test "preflight: fails when curl is missing" {
94+
# Create a PATH without curl
95+
mkdir -p "$BATS_TEST_TMPDIR/no-curl-bin"
96+
run bash -c '
97+
export PATH="'"$BATS_TEST_TMPDIR/no-curl-bin"'"
98+
PKG_MANAGER="apt"
99+
error() { echo "CURL_ERROR: $1"; exit 1; }
100+
if ! command -v curl &> /dev/null; then
101+
case "$PKG_MANAGER" in
102+
*) error "curl is required but not installed. Install with: sudo apt install curl" ;;
103+
esac
104+
fi
105+
'
106+
assert_failure
107+
assert_output --partial "CURL_ERROR"
108+
}
109+
110+
# ── Source file check ───────────────────────────────────────────────────────
111+
112+
@test "preflight: fails when no compose files exist" {
113+
run bash -c '
114+
SCRIPT_DIR="'"$BATS_TEST_TMPDIR"'"
115+
error() { echo "COMPOSE_ERROR"; exit 1; }
116+
if [[ ! -f "$SCRIPT_DIR/docker-compose.yml" ]] && [[ ! -f "$SCRIPT_DIR/docker-compose.base.yml" ]]; then
117+
error "No compose files found."
118+
fi
119+
'
120+
assert_failure
121+
assert_output --partial "COMPOSE_ERROR"
122+
}
123+
124+
@test "preflight: passes when compose files exist" {
125+
touch "$SCRIPT_DIR/docker-compose.base.yml"
126+
# Create a fake curl in PATH
127+
mkdir -p "$BATS_TEST_TMPDIR/bin"
128+
cat > "$BATS_TEST_TMPDIR/bin/curl" << 'MOCK'
129+
#!/bin/bash
130+
echo "curl 8.0.0"
131+
MOCK
132+
chmod +x "$BATS_TEST_TMPDIR/bin/curl"
133+
export PATH="$BATS_TEST_TMPDIR/bin:$PATH"
134+
135+
# Create fake jq
136+
cat > "$BATS_TEST_TMPDIR/bin/jq" << 'MOCK'
137+
#!/bin/bash
138+
echo "jq-1.7"
139+
MOCK
140+
chmod +x "$BATS_TEST_TMPDIR/bin/jq"
141+
142+
# Source the phase script (it will exit on error, so we capture)
143+
run bash -c '
144+
export SCRIPT_DIR="'"$SCRIPT_DIR"'"
145+
export INSTALL_DIR="'"$INSTALL_DIR"'"
146+
export LOG_FILE="'"$LOG_FILE"'"
147+
export INTERACTIVE=false
148+
export DRY_RUN=false
149+
export PKG_MANAGER="apt"
150+
export VERSION="2.3.0"
151+
152+
log() { :; }
153+
warn() { :; }
154+
error() { echo "PHASE_ERROR: $1"; exit 1; }
155+
ai() { :; }
156+
ai_ok() { :; }
157+
signal() { :; }
158+
show_phase() { :; }
159+
show_stranger_boot() { :; }
160+
dream_progress() { :; }
161+
162+
source "'"$BATS_TEST_DIRNAME/../../installers/phases/01-preflight.sh"'"
163+
echo "PHASE_COMPLETE"
164+
'
165+
assert_success
166+
assert_output --partial "PHASE_COMPLETE"
167+
}
168+
169+
# ── Existing installation detection ─────────────────────────────────────────
170+
171+
@test "preflight: detects existing installation" {
172+
touch "$SCRIPT_DIR/docker-compose.base.yml"
173+
mkdir -p "$INSTALL_DIR"
174+
175+
run bash -c '
176+
export SCRIPT_DIR="'"$SCRIPT_DIR"'"
177+
export INSTALL_DIR="'"$INSTALL_DIR"'"
178+
export LOG_FILE="'"$LOG_FILE"'"
179+
export INTERACTIVE=false
180+
export DRY_RUN=false
181+
export PKG_MANAGER="apt"
182+
export VERSION="2.3.0"
183+
184+
log() { echo "LOG: $1"; }
185+
warn() { :; }
186+
error() { echo "ERROR: $1"; exit 1; }
187+
ai() { :; }
188+
ai_ok() { :; }
189+
signal() { echo "SIGNAL: $1"; }
190+
show_phase() { :; }
191+
show_stranger_boot() { :; }
192+
dream_progress() { :; }
193+
194+
source "'"$BATS_TEST_DIRNAME/../../installers/phases/01-preflight.sh"'"
195+
'
196+
197+
# Should log about existing installation
198+
assert_output --partial "Existing installation"
199+
}
200+
201+
# ── Optional tools warning ──────────────────────────────────────────────────
202+
203+
@test "preflight: warns about missing optional tools" {
204+
touch "$SCRIPT_DIR/docker-compose.base.yml"
205+
mkdir -p "$BATS_TEST_TMPDIR/bin"
206+
207+
# Create curl and jq but NOT rsync
208+
cat > "$BATS_TEST_TMPDIR/bin/curl" << 'MOCK'
209+
#!/bin/bash
210+
echo "curl 8.0.0"
211+
MOCK
212+
chmod +x "$BATS_TEST_TMPDIR/bin/curl"
213+
cat > "$BATS_TEST_TMPDIR/bin/jq" << 'MOCK'
214+
#!/bin/bash
215+
echo "jq-1.7"
216+
MOCK
217+
chmod +x "$BATS_TEST_TMPDIR/bin/jq"
218+
export PATH="$BATS_TEST_TMPDIR/bin:$PATH"
219+
220+
run bash -c '
221+
export SCRIPT_DIR="'"$SCRIPT_DIR"'"
222+
export INSTALL_DIR="'"$INSTALL_DIR"'"
223+
export LOG_FILE="'"$LOG_FILE"'"
224+
export INTERACTIVE=false
225+
export DRY_RUN=false
226+
export PKG_MANAGER="apt"
227+
export VERSION="2.3.0"
228+
229+
log() { :; }
230+
warn() { echo "WARN: $1"; }
231+
error() { echo "ERROR: $1"; exit 1; }
232+
ai() { :; }
233+
ai_ok() { :; }
234+
signal() { :; }
235+
show_phase() { :; }
236+
show_stranger_boot() { :; }
237+
dream_progress() { :; }
238+
239+
source "'"$BATS_TEST_DIRNAME/../../installers/phases/01-preflight.sh"'"
240+
'
241+
242+
assert_output --partial "rsync"
243+
}

0 commit comments

Comments
 (0)