115 lines
3.7 KiB
Bash
115 lines
3.7 KiB
Bash
#!/usr/bin/env bash
|
|
# TST-016: Backup Restore Test — CC-047
|
|
# Verifies Zerobyte backup integrity for CEO-OS on supersrv.
|
|
# Usage: bash scripts/test-backup-restore.sh
|
|
# Exit codes: 0=PASS, 1=FAIL, 2=WARN
|
|
|
|
set -euo pipefail
|
|
|
|
ZEROBYTE_DB="${ZEROBYTE_DB:-/var/lib/zerobyte/data/zerobyte.db}"
|
|
MAX_AGE_HOURS="${MAX_AGE_HOURS:-26}" # warn if newest backup older than 26h
|
|
PASS=0; WARN=0; FAIL=0
|
|
|
|
log() { echo "[$(date -u +%H:%M:%S)] $*"; }
|
|
pass() { log "PASS: $*"; ((PASS++)) || true; }
|
|
warn() { log "WARN: $*"; ((WARN++)) || true; }
|
|
fail() { log "FAIL: $*"; ((FAIL++)) || true; }
|
|
|
|
log "=== TST-016: Backup/Restore Test ==="
|
|
log "Zerobyte DB: $ZEROBYTE_DB"
|
|
log "Max age: ${MAX_AGE_HOURS}h"
|
|
|
|
# 1. Zerobyte DB exists
|
|
if [[ -f "$ZEROBYTE_DB" ]]; then
|
|
pass "Zerobyte SQLite DB exists at $ZEROBYTE_DB"
|
|
else
|
|
fail "Zerobyte SQLite DB NOT found at $ZEROBYTE_DB"
|
|
log "RESULT: FAIL ($FAIL failures, $WARN warnings, $PASS passed)"
|
|
exit 1
|
|
fi
|
|
|
|
# 2. DB is readable
|
|
if sqlite3 "$ZEROBYTE_DB" "SELECT 1" &>/dev/null; then
|
|
pass "Zerobyte DB is readable"
|
|
else
|
|
fail "Zerobyte DB is not readable"
|
|
exit 1
|
|
fi
|
|
|
|
# 3. Check tables
|
|
TABLES=$(sqlite3 "$ZEROBYTE_DB" "SELECT name FROM sqlite_master WHERE type='table'" 2>/dev/null | tr '\n' ',')
|
|
log "Tables: $TABLES"
|
|
if [[ "$TABLES" == *"backups"* ]]; then
|
|
pass "backups table exists"
|
|
else
|
|
warn "backups table not found — schema may differ"
|
|
fi
|
|
|
|
# 4. Check recent backups
|
|
BACKUP_COUNT=$(sqlite3 "$ZEROBYTE_DB" "SELECT COUNT(*) FROM backups" 2>/dev/null || echo "0")
|
|
log "Total backup records: $BACKUP_COUNT"
|
|
|
|
if [[ "$BACKUP_COUNT" -gt 0 ]]; then
|
|
pass "Backup records found: $BACKUP_COUNT"
|
|
|
|
# Check newest backup age
|
|
NEWEST=$(sqlite3 "$ZEROBYTE_DB" "SELECT MAX(created_at) FROM backups" 2>/dev/null || echo "")
|
|
if [[ -n "$NEWEST" ]]; then
|
|
NEWEST_EPOCH=$(date -d "$NEWEST" +%s 2>/dev/null || date -j -f "%Y-%m-%d %H:%M:%S" "$NEWEST" +%s 2>/dev/null || echo "0")
|
|
NOW_EPOCH=$(date +%s)
|
|
AGE_HOURS=$(( (NOW_EPOCH - NEWEST_EPOCH) / 3600 ))
|
|
log "Newest backup: $NEWEST (${AGE_HOURS}h ago)"
|
|
|
|
if [[ "$AGE_HOURS" -lt "$MAX_AGE_HOURS" ]]; then
|
|
pass "Newest backup is ${AGE_HOURS}h old (within ${MAX_AGE_HOURS}h threshold)"
|
|
else
|
|
fail "Newest backup is ${AGE_HOURS}h old — exceeds ${MAX_AGE_HOURS}h threshold"
|
|
fi
|
|
fi
|
|
|
|
# Check failed backups
|
|
FAILED=$(sqlite3 "$ZEROBYTE_DB" "SELECT COUNT(*) FROM backups WHERE status='failed'" 2>/dev/null || echo "0")
|
|
if [[ "$FAILED" -gt 0 ]]; then
|
|
warn "$FAILED backup(s) with status=failed"
|
|
else
|
|
pass "No failed backups found"
|
|
fi
|
|
|
|
# List last 4 backups
|
|
log "Last 4 backups:"
|
|
sqlite3 "$ZEROBYTE_DB" "SELECT id, name, status, created_at FROM backups ORDER BY created_at DESC LIMIT 4" 2>/dev/null | while IFS='|' read -r id name status ts; do
|
|
log " [$status] $name @ $ts"
|
|
done
|
|
else
|
|
warn "No backup records in Zerobyte DB — first run or schema mismatch"
|
|
fi
|
|
|
|
# 5. Zerobyte agent process running
|
|
if pgrep -f zerobyte &>/dev/null; then
|
|
pass "Zerobyte agent process is running"
|
|
else
|
|
fail "Zerobyte agent process NOT running"
|
|
fi
|
|
|
|
# 6. Zerobyte port 4096 responding
|
|
if curl -s --max-time 3 http://localhost:4096/ &>/dev/null; then
|
|
pass "Zerobyte HTTP service responding on port 4096"
|
|
else
|
|
warn "Zerobyte HTTP port 4096 not responding (may require auth)"
|
|
fi
|
|
|
|
# ── Summary ─────────────────────────────────────────────────────────────────
|
|
log ""
|
|
log "=== TST-016 RESULT ==="
|
|
log "PASS: $PASS | WARN: $WARN | FAIL: $FAIL"
|
|
|
|
if [[ "$FAIL" -gt 0 ]]; then
|
|
log "STATUS: FAIL"
|
|
exit 1
|
|
elif [[ "$WARN" -gt 0 ]]; then
|
|
log "STATUS: WARN"
|
|
exit 2
|
|
else
|
|
log "STATUS: PASS"
|
|
exit 0
|
|
fi
|