@aiassesstech/mighty-mark 0.3.29 → 0.3.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/checks/backup-orchestrator.d.ts +33 -0
- package/dist/checks/backup-orchestrator.d.ts.map +1 -0
- package/dist/checks/backup-orchestrator.js +260 -0
- package/dist/checks/backup-orchestrator.js.map +1 -0
- package/dist/checks/check-runner.d.ts +7 -0
- package/dist/checks/check-runner.d.ts.map +1 -1
- package/dist/checks/check-runner.js +22 -2
- package/dist/checks/check-runner.js.map +1 -1
- package/dist/checks/data-integrity.d.ts +8 -1
- package/dist/checks/data-integrity.d.ts.map +1 -1
- package/dist/checks/data-integrity.js +99 -1
- package/dist/checks/data-integrity.js.map +1 -1
- package/package.json +3 -1
- package/src/watchdog/fleet-backup/config.sh +74 -0
- package/src/watchdog/fleet-backup/fleet-backup.sh +363 -0
- package/src/watchdog/fleet-backup/fleet-restore.sh +437 -0
- package/src/watchdog/fleet-backup/test/test-backup.sh +395 -0
- package/src/watchdog/fleet-backup/test/test-restore.sh +302 -0
- package/src/watchdog/install.sh +112 -4
- package/src/watchdog/morning-check.sh +6 -0
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ═══════════════════════════════════════════════════════════════════
|
|
3
|
+
# nole-fleet-backup — Backup Script Test Suite
|
|
4
|
+
#
|
|
5
|
+
# Tests fleet-backup.sh in a sandboxed environment using temp dirs.
|
|
6
|
+
# No real VPS data is touched. No real GitHub push occurs.
|
|
7
|
+
#
|
|
8
|
+
# Usage:
|
|
9
|
+
# ./test/test-backup.sh # run all tests
|
|
10
|
+
# ./test/test-backup.sh -v # verbose mode
|
|
11
|
+
#
|
|
12
|
+
# Exit code: 0 if all tests pass, 1 if any test fails.
|
|
13
|
+
# ═══════════════════════════════════════════════════════════════════
|
|
14
|
+
|
|
15
|
+
set -euo pipefail
|
|
16
|
+
|
|
17
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
18
|
+
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
19
|
+
VERBOSE="${1:-}"
|
|
20
|
+
|
|
21
|
+
PASS_COUNT=0
|
|
22
|
+
FAIL_COUNT=0
|
|
23
|
+
SKIP_COUNT=0
|
|
24
|
+
|
|
25
|
+
# Colors
|
|
26
|
+
RED='\033[0;31m'
|
|
27
|
+
GREEN='\033[0;32m'
|
|
28
|
+
YELLOW='\033[1;33m'
|
|
29
|
+
NC='\033[0m'
|
|
30
|
+
|
|
31
|
+
pass() { PASS_COUNT=$((PASS_COUNT + 1)); echo -e " ${GREEN}PASS${NC}: $1"; }
|
|
32
|
+
fail() { FAIL_COUNT=$((FAIL_COUNT + 1)); echo -e " ${RED}FAIL${NC}: $1"; echo -e " $2"; }
|
|
33
|
+
skip() { SKIP_COUNT=$((SKIP_COUNT + 1)); echo -e " ${YELLOW}SKIP${NC}: $1 — $2"; }
|
|
34
|
+
|
|
35
|
+
# ─── Test Sandbox Setup ──────────────────────────────────────────
|
|
36
|
+
|
|
37
|
+
SANDBOX=""
|
|
38
|
+
setup_sandbox() {
|
|
39
|
+
SANDBOX=$(mktemp -d "/tmp/fleet-backup-test-XXXXXX")
|
|
40
|
+
mkdir -p "$SANDBOX"/{openclaw/extensions/grillo/agent,openclaw/extensions/jessie/agent}
|
|
41
|
+
mkdir -p "$SANDBOX"/{openclaw/extensions/noah/agent,openclaw/extensions/nole/agent}
|
|
42
|
+
mkdir -p "$SANDBOX"/{openclaw/extensions/mark/agent,openclaw/extensions/sam/agent}
|
|
43
|
+
mkdir -p "$SANDBOX"/{openclaw/agents/grillo/memory,openclaw/agents/jessie/memory}
|
|
44
|
+
mkdir -p "$SANDBOX"/{openclaw/agents/noah/memory,openclaw/agents/nole/memory}
|
|
45
|
+
mkdir -p "$SANDBOX"/{openclaw/agents/mark/memory,openclaw/agents/sam/memory}
|
|
46
|
+
mkdir -p "$SANDBOX"/{openclaw/agents/grillo/sessions,openclaw/agents/jessie/sessions}
|
|
47
|
+
mkdir -p "$SANDBOX"/{openclaw/memory,openclaw/grillo-data,openclaw/workspace}
|
|
48
|
+
mkdir -p "$SANDBOX"/{openclaw/.noah-data,openclaw/nole-data}
|
|
49
|
+
mkdir -p "$SANDBOX"/{openclaw/.fleet-data,openclaw/.sam-artifacts}
|
|
50
|
+
mkdir -p "$SANDBOX"/{clawdbot,clawd,mighty-mark-opt}
|
|
51
|
+
mkdir -p "$SANDBOX"/{jessie-data,mark-data}
|
|
52
|
+
mkdir -p "$SANDBOX"/{backup-dir/backups,backup-dir/logs}
|
|
53
|
+
|
|
54
|
+
echo "# Grillo SOUL" > "$SANDBOX/openclaw/extensions/grillo/agent/SOUL.md"
|
|
55
|
+
echo "# Grillo Memory" > "$SANDBOX/openclaw/agents/grillo/memory/context.md"
|
|
56
|
+
echo '{"model":"claude"}' > "$SANDBOX/openclaw/agents/grillo/memory/state.json"
|
|
57
|
+
echo "session data" > "$SANDBOX/openclaw/agents/grillo/sessions/001.jsonl"
|
|
58
|
+
echo '{"agents":[]}' > "$SANDBOX/openclaw/grillo-data/chain.json"
|
|
59
|
+
echo '{"apiKey":"sk-secret-key-123","model":"claude"}' > "$SANDBOX/openclaw/openclaw.json"
|
|
60
|
+
echo '{"apiKey":"sk-another-key","provider":"anthropic"}' > "$SANDBOX/clawdbot/openclaw.json"
|
|
61
|
+
echo '{"name":"grillo"}' > "$SANDBOX/openclaw/extensions/grillo/package.json"
|
|
62
|
+
echo "watchdog script" > "$SANDBOX/mighty-mark-opt/watchdog.sh"
|
|
63
|
+
echo "SECRET=value" > "$SANDBOX/mighty-mark-opt/.env"
|
|
64
|
+
|
|
65
|
+
# Create test config
|
|
66
|
+
cat > "$SANDBOX/config.sh" << 'CFGEOF'
|
|
67
|
+
BACKUP_DIR="__SANDBOX__/backup-dir/backups"
|
|
68
|
+
RETENTION_DAYS=35
|
|
69
|
+
LOG_FILE="__SANDBOX__/backup-dir/logs/backup.log"
|
|
70
|
+
MANIFEST_FILE="__SANDBOX__/backup-dir/latest-manifest.json"
|
|
71
|
+
OPENCLAW_HOME="__SANDBOX__/openclaw"
|
|
72
|
+
CLAWDBOT_HOME="__SANDBOX__/clawdbot"
|
|
73
|
+
CLAWD_WORKSPACE="__SANDBOX__/clawd"
|
|
74
|
+
MIGHTY_MARK_OPT="__SANDBOX__/mighty-mark-opt"
|
|
75
|
+
NOLE_CREDS="__SANDBOX__/nole"
|
|
76
|
+
FULL_BACKUP_DAY="0"
|
|
77
|
+
SYSTEMD_UNITS=()
|
|
78
|
+
CRON_FILES=()
|
|
79
|
+
LOGROTATE_FILES=()
|
|
80
|
+
EXCLUDE_PATTERNS=()
|
|
81
|
+
SANITIZE_OPENCLAW_JSON=true
|
|
82
|
+
PUSH_TO_GITHUB=false
|
|
83
|
+
GITHUB_REPO_DIR=""
|
|
84
|
+
GITHUB_SSH_HOST=""
|
|
85
|
+
GITHUB_BACKUP_BRANCH="backups"
|
|
86
|
+
GITHUB_MAX_FILE_SIZE=$((95 * 1024 * 1024))
|
|
87
|
+
CFGEOF
|
|
88
|
+
sed -i.bak "s|__SANDBOX__|${SANDBOX}|g" "$SANDBOX/config.sh" 2>/dev/null || \
|
|
89
|
+
sed -i '' "s|__SANDBOX__|${SANDBOX}|g" "$SANDBOX/config.sh"
|
|
90
|
+
rm -f "$SANDBOX/config.sh.bak"
|
|
91
|
+
|
|
92
|
+
cp "$PROJECT_DIR/fleet-backup.sh" "$SANDBOX/fleet-backup.sh"
|
|
93
|
+
chmod +x "$SANDBOX/fleet-backup.sh"
|
|
94
|
+
|
|
95
|
+
# Override config loading: point to sandbox config
|
|
96
|
+
# fleet-backup.sh looks for config.local.sh in SCRIPT_DIR, which we set to $SANDBOX
|
|
97
|
+
cat > "$SANDBOX/config.local.sh" << LOCALEOF
|
|
98
|
+
source "$SANDBOX/config.sh"
|
|
99
|
+
LOCALEOF
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
teardown_sandbox() {
|
|
103
|
+
[[ -n "$SANDBOX" ]] && rm -rf "$SANDBOX"
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
run_backup() {
|
|
107
|
+
local args="${1:-}"
|
|
108
|
+
cd "$SANDBOX"
|
|
109
|
+
# fleet-backup.sh resolves SCRIPT_DIR from BASH_SOURCE[0], so we
|
|
110
|
+
# can't override it via env. Instead we put config.local.sh next to the script.
|
|
111
|
+
bash "$SANDBOX/fleet-backup.sh" $args 2>&1
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
# ─── Tests ────────────────────────────────────────────────────────
|
|
115
|
+
|
|
116
|
+
echo "═══════════════════════════════════════════════════════"
|
|
117
|
+
echo " nole-fleet-backup — Backup Test Suite"
|
|
118
|
+
echo "═══════════════════════════════════════════════════════"
|
|
119
|
+
echo ""
|
|
120
|
+
|
|
121
|
+
# --- Test 1: Light backup creates archive ---
|
|
122
|
+
echo "▸ Light backup"
|
|
123
|
+
setup_sandbox
|
|
124
|
+
output=$(FULL_BACKUP_DAY=9 run_backup "--light")
|
|
125
|
+
archive=$(find "$SANDBOX/backup-dir/backups" -name 'fleet-light-*.tar.gz' 2>/dev/null | head -1)
|
|
126
|
+
if [[ -n "$archive" && -f "$archive" ]]; then
|
|
127
|
+
pass "Light backup creates archive"
|
|
128
|
+
else
|
|
129
|
+
fail "Light backup creates archive" "No archive found in $SANDBOX/backup-dir/backups"
|
|
130
|
+
fi
|
|
131
|
+
|
|
132
|
+
if echo "$output" | grep -q "Starting light backup"; then
|
|
133
|
+
pass "Light backup reports correct tier"
|
|
134
|
+
else
|
|
135
|
+
fail "Light backup reports correct tier" "Output: $output"
|
|
136
|
+
fi
|
|
137
|
+
teardown_sandbox
|
|
138
|
+
|
|
139
|
+
# --- Test 2: Full backup creates archive ---
|
|
140
|
+
echo "▸ Full backup"
|
|
141
|
+
setup_sandbox
|
|
142
|
+
output=$(run_backup "--full")
|
|
143
|
+
archive=$(find "$SANDBOX/backup-dir/backups" -name 'fleet-full-*.tar.gz' 2>/dev/null | head -1)
|
|
144
|
+
if [[ -n "$archive" && -f "$archive" ]]; then
|
|
145
|
+
pass "Full backup creates archive"
|
|
146
|
+
else
|
|
147
|
+
fail "Full backup creates archive" "No archive found"
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
if echo "$output" | grep -q "Starting full backup"; then
|
|
151
|
+
pass "Full backup reports correct tier"
|
|
152
|
+
else
|
|
153
|
+
fail "Full backup reports correct tier" "Output: $output"
|
|
154
|
+
fi
|
|
155
|
+
teardown_sandbox
|
|
156
|
+
|
|
157
|
+
# --- Test 3: Full backup is larger than light ---
|
|
158
|
+
echo "▸ Size comparison"
|
|
159
|
+
setup_sandbox
|
|
160
|
+
run_backup "--light" > /dev/null 2>&1
|
|
161
|
+
light_archive=$(find "$SANDBOX/backup-dir/backups" -name 'fleet-light-*.tar.gz' | head -1)
|
|
162
|
+
light_size=$(stat -c%s "$light_archive" 2>/dev/null || stat -f%z "$light_archive" 2>/dev/null)
|
|
163
|
+
|
|
164
|
+
run_backup "--full" > /dev/null 2>&1
|
|
165
|
+
full_archive=$(find "$SANDBOX/backup-dir/backups" -name 'fleet-full-*.tar.gz' | head -1)
|
|
166
|
+
full_size=$(stat -c%s "$full_archive" 2>/dev/null || stat -f%z "$full_archive" 2>/dev/null)
|
|
167
|
+
|
|
168
|
+
if [[ "$full_size" -gt "$light_size" ]]; then
|
|
169
|
+
pass "Full backup is larger than light ($full_size > $light_size bytes)"
|
|
170
|
+
else
|
|
171
|
+
fail "Full backup should be larger than light" "full=$full_size light=$light_size"
|
|
172
|
+
fi
|
|
173
|
+
teardown_sandbox
|
|
174
|
+
|
|
175
|
+
# --- Test 4: Manifest is written with correct fields ---
|
|
176
|
+
echo "▸ Manifest"
|
|
177
|
+
setup_sandbox
|
|
178
|
+
run_backup "--light" > /dev/null 2>&1
|
|
179
|
+
manifest="$SANDBOX/backup-dir/latest-manifest.json"
|
|
180
|
+
if [[ -f "$manifest" ]]; then
|
|
181
|
+
pass "Manifest file created"
|
|
182
|
+
else
|
|
183
|
+
fail "Manifest file created" "Not found at $manifest"
|
|
184
|
+
teardown_sandbox
|
|
185
|
+
# skip remaining manifest tests
|
|
186
|
+
echo ""
|
|
187
|
+
echo "═══════════════════════════════════════════════════════"
|
|
188
|
+
echo " Results: ${PASS_COUNT} passed, ${FAIL_COUNT} failed, ${SKIP_COUNT} skipped"
|
|
189
|
+
echo "═══════════════════════════════════════════════════════"
|
|
190
|
+
exit 1
|
|
191
|
+
fi
|
|
192
|
+
|
|
193
|
+
for field in date timestamp tier archive size_bytes checksum extensions agents memory_files retention_days; do
|
|
194
|
+
if grep -q "\"$field\"" "$manifest"; then
|
|
195
|
+
pass "Manifest contains field: $field"
|
|
196
|
+
else
|
|
197
|
+
fail "Manifest contains field: $field" "Missing from $manifest"
|
|
198
|
+
fi
|
|
199
|
+
done
|
|
200
|
+
|
|
201
|
+
tier_value=$(grep -o '"tier": *"[^"]*"' "$manifest" | sed 's/.*"tier": *"//;s/"//')
|
|
202
|
+
if [[ "$tier_value" == "light" ]]; then
|
|
203
|
+
pass "Manifest tier is 'light'"
|
|
204
|
+
else
|
|
205
|
+
fail "Manifest tier is 'light'" "Got: $tier_value"
|
|
206
|
+
fi
|
|
207
|
+
teardown_sandbox
|
|
208
|
+
|
|
209
|
+
# --- Test 5: Full manifest has tier=full ---
|
|
210
|
+
echo "▸ Full manifest tier"
|
|
211
|
+
setup_sandbox
|
|
212
|
+
run_backup "--full" > /dev/null 2>&1
|
|
213
|
+
manifest="$SANDBOX/backup-dir/latest-manifest.json"
|
|
214
|
+
tier_value=$(grep -o '"tier": *"[^"]*"' "$manifest" | sed 's/.*"tier": *"//;s/"//')
|
|
215
|
+
if [[ "$tier_value" == "full" ]]; then
|
|
216
|
+
pass "Full backup manifest has tier=full"
|
|
217
|
+
else
|
|
218
|
+
fail "Full backup manifest has tier=full" "Got: $tier_value"
|
|
219
|
+
fi
|
|
220
|
+
teardown_sandbox
|
|
221
|
+
|
|
222
|
+
# --- Test 6: API keys are redacted ---
|
|
223
|
+
echo "▸ Secret redaction"
|
|
224
|
+
setup_sandbox
|
|
225
|
+
run_backup "--light" > /dev/null 2>&1
|
|
226
|
+
archive=$(find "$SANDBOX/backup-dir/backups" -name 'fleet-light-*.tar.gz' | head -1)
|
|
227
|
+
extract_dir=$(mktemp -d)
|
|
228
|
+
tar -xzf "$archive" -C "$extract_dir" 2>/dev/null
|
|
229
|
+
|
|
230
|
+
if grep -r "sk-secret-key-123" "$extract_dir" 2>/dev/null; then
|
|
231
|
+
fail "API keys are redacted from backup" "Found sk-secret-key-123 in archive"
|
|
232
|
+
else
|
|
233
|
+
pass "API keys are redacted from backup"
|
|
234
|
+
fi
|
|
235
|
+
|
|
236
|
+
if grep -r "REDACTED_FOR_BACKUP" "$extract_dir" 2>/dev/null >/dev/null; then
|
|
237
|
+
pass "Redaction placeholder present"
|
|
238
|
+
else
|
|
239
|
+
fail "Redaction placeholder present" "REDACTED_FOR_BACKUP not found"
|
|
240
|
+
fi
|
|
241
|
+
|
|
242
|
+
rm -rf "$extract_dir"
|
|
243
|
+
teardown_sandbox
|
|
244
|
+
|
|
245
|
+
# --- Test 7: .env files are excluded ---
|
|
246
|
+
echo "▸ Secret exclusion"
|
|
247
|
+
setup_sandbox
|
|
248
|
+
run_backup "--full" > /dev/null 2>&1
|
|
249
|
+
archive=$(find "$SANDBOX/backup-dir/backups" -name 'fleet-full-*.tar.gz' | head -1)
|
|
250
|
+
|
|
251
|
+
if tar -tzf "$archive" | grep -q "\.env"; then
|
|
252
|
+
fail ".env files excluded from backup" "Found .env in archive listing"
|
|
253
|
+
else
|
|
254
|
+
pass ".env files excluded from backup"
|
|
255
|
+
fi
|
|
256
|
+
teardown_sandbox
|
|
257
|
+
|
|
258
|
+
# --- Test 8: Light backup excludes heavy data ---
|
|
259
|
+
echo "▸ Light backup exclusions"
|
|
260
|
+
setup_sandbox
|
|
261
|
+
run_backup "--light" > /dev/null 2>&1
|
|
262
|
+
archive=$(find "$SANDBOX/backup-dir/backups" -name 'fleet-light-*.tar.gz' | head -1)
|
|
263
|
+
listing=$(tar -tzf "$archive")
|
|
264
|
+
|
|
265
|
+
if echo "$listing" | grep -q "sessions/"; then
|
|
266
|
+
fail "Light backup excludes sessions" "Found sessions/ in archive"
|
|
267
|
+
else
|
|
268
|
+
pass "Light backup excludes sessions"
|
|
269
|
+
fi
|
|
270
|
+
|
|
271
|
+
if echo "$listing" | grep -q "grillo-data/"; then
|
|
272
|
+
fail "Light backup excludes data stores" "Found grillo-data/ in archive"
|
|
273
|
+
else
|
|
274
|
+
pass "Light backup excludes data stores"
|
|
275
|
+
fi
|
|
276
|
+
teardown_sandbox
|
|
277
|
+
|
|
278
|
+
# --- Test 9: Full backup includes heavy data ---
|
|
279
|
+
echo "▸ Full backup inclusions"
|
|
280
|
+
setup_sandbox
|
|
281
|
+
run_backup "--full" > /dev/null 2>&1
|
|
282
|
+
archive=$(find "$SANDBOX/backup-dir/backups" -name 'fleet-full-*.tar.gz' | head -1)
|
|
283
|
+
listing=$(tar -tzf "$archive")
|
|
284
|
+
|
|
285
|
+
if echo "$listing" | grep -q "sessions/"; then
|
|
286
|
+
pass "Full backup includes sessions"
|
|
287
|
+
else
|
|
288
|
+
fail "Full backup includes sessions" "sessions/ not in archive"
|
|
289
|
+
fi
|
|
290
|
+
|
|
291
|
+
if echo "$listing" | grep -q "grillo-data/"; then
|
|
292
|
+
pass "Full backup includes data stores"
|
|
293
|
+
else
|
|
294
|
+
fail "Full backup includes data stores" "grillo-data/ not in archive"
|
|
295
|
+
fi
|
|
296
|
+
teardown_sandbox
|
|
297
|
+
|
|
298
|
+
# --- Test 10: Light backup includes .md memory files ---
|
|
299
|
+
echo "▸ Light backup .md inclusion"
|
|
300
|
+
setup_sandbox
|
|
301
|
+
run_backup "--light" > /dev/null 2>&1
|
|
302
|
+
archive=$(find "$SANDBOX/backup-dir/backups" -name 'fleet-light-*.tar.gz' | head -1)
|
|
303
|
+
listing=$(tar -tzf "$archive")
|
|
304
|
+
|
|
305
|
+
if echo "$listing" | grep -q "context.md"; then
|
|
306
|
+
pass "Light backup includes memory .md files"
|
|
307
|
+
else
|
|
308
|
+
fail "Light backup includes memory .md files" "context.md not in archive"
|
|
309
|
+
fi
|
|
310
|
+
teardown_sandbox
|
|
311
|
+
|
|
312
|
+
# --- Test 11: Checksum is valid ---
|
|
313
|
+
echo "▸ Checksum validation"
|
|
314
|
+
setup_sandbox
|
|
315
|
+
run_backup "--light" > /dev/null 2>&1
|
|
316
|
+
archive=$(find "$SANDBOX/backup-dir/backups" -name 'fleet-light-*.tar.gz' | head -1)
|
|
317
|
+
manifest="$SANDBOX/backup-dir/latest-manifest.json"
|
|
318
|
+
|
|
319
|
+
manifest_checksum=$(grep -o '"checksum": *"[^"]*"' "$manifest" | sed 's/.*sha256://;s/"//')
|
|
320
|
+
actual_checksum=$(sha256sum "$archive" 2>/dev/null | awk '{print $1}' || shasum -a 256 "$archive" | awk '{print $1}')
|
|
321
|
+
|
|
322
|
+
if [[ "$manifest_checksum" == "$actual_checksum" ]]; then
|
|
323
|
+
pass "Checksum matches archive"
|
|
324
|
+
else
|
|
325
|
+
fail "Checksum matches archive" "manifest=$manifest_checksum actual=$actual_checksum"
|
|
326
|
+
fi
|
|
327
|
+
teardown_sandbox
|
|
328
|
+
|
|
329
|
+
# --- Test 12: --help exits 0 ---
|
|
330
|
+
echo "▸ Help flag"
|
|
331
|
+
setup_sandbox
|
|
332
|
+
if run_backup "--help" > /dev/null 2>&1; then
|
|
333
|
+
pass "--help exits 0"
|
|
334
|
+
else
|
|
335
|
+
fail "--help exits 0" "Non-zero exit code"
|
|
336
|
+
fi
|
|
337
|
+
teardown_sandbox
|
|
338
|
+
|
|
339
|
+
# --- Test 13: Multiple backups on same day get unique names ---
|
|
340
|
+
echo "▸ Unique archive names"
|
|
341
|
+
setup_sandbox
|
|
342
|
+
run_backup "--light" > /dev/null 2>&1
|
|
343
|
+
sleep 1
|
|
344
|
+
run_backup "--light" > /dev/null 2>&1
|
|
345
|
+
count=$(find "$SANDBOX/backup-dir/backups" -name 'fleet-light-*.tar.gz' | wc -l | tr -d ' ')
|
|
346
|
+
if [[ "$count" -ge 2 ]]; then
|
|
347
|
+
pass "Multiple same-day backups get unique names ($count archives)"
|
|
348
|
+
else
|
|
349
|
+
fail "Multiple same-day backups get unique names" "Only $count archive(s) found"
|
|
350
|
+
fi
|
|
351
|
+
teardown_sandbox
|
|
352
|
+
|
|
353
|
+
# --- Test 14: Extension and agent counts are correct ---
|
|
354
|
+
echo "▸ Content counts"
|
|
355
|
+
setup_sandbox
|
|
356
|
+
run_backup "--full" > /dev/null 2>&1
|
|
357
|
+
manifest="$SANDBOX/backup-dir/latest-manifest.json"
|
|
358
|
+
ext_count=$(grep -o '"extensions": *[0-9]*' "$manifest" | grep -o '[0-9]*$')
|
|
359
|
+
agent_count=$(grep -o '"agents": *[0-9]*' "$manifest" | grep -o '[0-9]*$')
|
|
360
|
+
|
|
361
|
+
if [[ "$ext_count" -eq 6 ]]; then
|
|
362
|
+
pass "Extension count is 6"
|
|
363
|
+
else
|
|
364
|
+
fail "Extension count is 6" "Got: $ext_count"
|
|
365
|
+
fi
|
|
366
|
+
|
|
367
|
+
if [[ "$agent_count" -eq 6 ]]; then
|
|
368
|
+
pass "Agent count is 6"
|
|
369
|
+
else
|
|
370
|
+
fail "Agent count is 6" "Got: $agent_count"
|
|
371
|
+
fi
|
|
372
|
+
teardown_sandbox
|
|
373
|
+
|
|
374
|
+
# --- Test 15: GitHub push disabled doesn't error ---
|
|
375
|
+
echo "▸ GitHub push disabled"
|
|
376
|
+
setup_sandbox
|
|
377
|
+
output=$(run_backup "--light" 2>&1)
|
|
378
|
+
if echo "$output" | grep -q "Pushing backup to GitHub"; then
|
|
379
|
+
fail "GitHub push skipped when PUSH_TO_GITHUB=false" "Push was attempted"
|
|
380
|
+
else
|
|
381
|
+
pass "GitHub push skipped when PUSH_TO_GITHUB=false"
|
|
382
|
+
fi
|
|
383
|
+
teardown_sandbox
|
|
384
|
+
|
|
385
|
+
# ─── Summary ──────────────────────────────────────────────────────
|
|
386
|
+
|
|
387
|
+
echo ""
|
|
388
|
+
echo "═══════════════════════════════════════════════════════"
|
|
389
|
+
TOTAL=$((PASS_COUNT + FAIL_COUNT + SKIP_COUNT))
|
|
390
|
+
echo -e " Results: ${GREEN}${PASS_COUNT} passed${NC}, ${RED}${FAIL_COUNT} failed${NC}, ${YELLOW}${SKIP_COUNT} skipped${NC} (${TOTAL} total)"
|
|
391
|
+
echo "═══════════════════════════════════════════════════════"
|
|
392
|
+
|
|
393
|
+
if [[ "$FAIL_COUNT" -gt 0 ]]; then
|
|
394
|
+
exit 1
|
|
395
|
+
fi
|