From f5712a90b2b3bf98d784228456f89de2fcabfefc Mon Sep 17 00:00:00 2001 From: admin-valentin Date: Fri, 31 Jul 2026 15:18:36 +0000 Subject: [PATCH] =?UTF-8?q?feat(tst-016):=20backup/restore=20test=20script?= =?UTF-8?q?=20=E2=80=94=20Zerobyte=20integrity=20verify?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/test-backup-restore.sh | 115 +++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 scripts/test-backup-restore.sh diff --git a/scripts/test-backup-restore.sh b/scripts/test-backup-restore.sh new file mode 100644 index 0000000..a15b989 --- /dev/null +++ b/scripts/test-backup-restore.sh @@ -0,0 +1,115 @@ +#!/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