#!/bin/bash set -euo pipefail PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)" SCRIPT="$PLUGIN_DIR/scripts/da-integration/alt_mysql_restore_payload.sh" TMP_DIR="$(mktemp -d)" trap 'rm -rf "$TMP_DIR"' EXIT fail() { echo "FAIL: $*" >&2 exit 1 } sha256_of() { if command -v sha256sum >/dev/null 2>&1; then sha256sum "$1" | awk '{print $1}' else shasum -a 256 "$1" | awk '{print $1}' fi } # --- Fake alt-mariadb client binaries + credentials, isolated from the real system --- # The stub tracks a simple "existing databases" state file so CREATE/DROP # DATABASE during the test actually affects what a later existence check sees. mkdir -p "$TMP_DIR/mariadb/bin" cat > "$TMP_DIR/mariadb/bin/mariadb" <<'STUB' #!/bin/bash STATE_FILE="${FAKE_DB_STATE_FILE:?FAKE_DB_STATE_FILE must be set}" sql="" mode="" for arg in "$@"; do case "$arg" in -e) mode="sql" ;; -Nse) mode="sql" ;; --database=*|--user=*|--socket=*|--host=*|--port=*|--protocol=*) ;; *) if [ "$mode" = "sql" ]; then sql="$arg" mode="" fi ;; esac done if [ -n "$sql" ]; then case "$sql" in *"SELECT 1 FROM information_schema.SCHEMATA"*) name="$(printf '%s' "$sql" | sed -n "s/.*SCHEMA_NAME='\([^']*\)'.*/\1/p")" grep -qx "$name" "$STATE_FILE" 2>/dev/null && echo 1 ;; *"DROP DATABASE"*) name="$(printf '%s' "$sql" | sed -n 's/.*DATABASE[^`]*`\([A-Za-z0-9_]*\)`.*/\1/p')" if [ -n "$name" ]; then grep -vx "$name" "$STATE_FILE" > "$STATE_FILE.tmp" 2>/dev/null || true mv -f "$STATE_FILE.tmp" "$STATE_FILE" fi ;; *"CREATE DATABASE"*) name="$(printf '%s' "$sql" | sed -n 's/.*DATABASE[^`]*`\([A-Za-z0-9_]*\)`.*/\1/p')" [ -n "$name" ] && echo "$name" >> "$STATE_FILE" ;; esac exit 0 fi # No -e/-Nse: reading an import from stdin cat >/dev/null if [ "${FAKE_MYSQL_IMPORT_FAIL:-0}" = "1" ]; then echo "fake mariadb: simulated import failure" >&2 exit 1 fi exit 0 STUB chmod 755 "$TMP_DIR/mariadb/bin/mariadb" cat > "$TMP_DIR/mariadb/bin/mariadb-dump" <<'STUB' #!/bin/bash echo "-- fake rollback dump" echo "SELECT 1;" exit 0 STUB chmod 755 "$TMP_DIR/mariadb/bin/mariadb-dump" cat > "$TMP_DIR/alt-mysql.conf" < "$TMP_DIR/settings.conf" < "$payload_dir/databases/${db_name}.sql" gzip -9 -f "$payload_dir/databases/${db_name}.sql" printf '%s\n' '-- users' | gzip -9 > "$payload_dir/grants/users.sql.gz" printf '%s\n' '-- grants' | gzip -9 > "$payload_dir/grants/grants.sql.gz" local sha sha="$(sha256_of "$payload_dir/databases/${db_name}.sql.gz")" cat > "$payload_dir/manifest.json" < "$db_state" DA_ALT_MYSQL_SETTINGS_FILE="$TMP_DIR/settings.conf" \ DA_ALT_MYSQL_RESTORE_LOG="$TMP_DIR/restore.log" \ FAKE_DB_STATE_FILE="$db_state" \ bash "$SCRIPT" "$@" } # --- Scenario 1: checksum mismatch must be rejected before any restore happens --- PAYLOAD1="$TMP_DIR/payload1" build_payload "$PAYLOAD1" "demo_app" echo 'CORRUPTED CONTENT' > "$PAYLOAD1/databases/demo_app.sql.gz" OUTPUT1="$(run_restore --user demo --payload "$PAYLOAD1" --overwrite allow 2>&1)" && fail "checksum mismatch must cause a non-zero exit, output: $OUTPUT1" echo "$OUTPUT1" | grep -qi "checksum mismatch" \ || fail "expected a checksum mismatch error, got: $OUTPUT1" [ ! -f "$TMP_DIR/restore.log" ] || ! grep -qi "restoring user definitions" "$TMP_DIR/restore.log" \ || fail "restore must not proceed past checksum verification on mismatch" # --- Scenario 2: overwrite=deny must refuse to touch an existing database --- PAYLOAD2="$TMP_DIR/payload2" build_payload "$PAYLOAD2" "demo_existing" OUTPUT2="$(FAKE_EXISTING_DBS="demo_existing" run_restore --user demo --payload "$PAYLOAD2" --overwrite deny 2>&1)" && fail "overwrite=deny must reject an existing database, output: $OUTPUT2" echo "$OUTPUT2" | grep -qi "overwrite is denied" \ || fail "expected an overwrite-denied error, got: $OUTPUT2" # --- Scenario 3: happy path - valid checksum, no conflict, overwrite=allow --- PAYLOAD3="$TMP_DIR/payload3" build_payload "$PAYLOAD3" "demo_new" run_restore --user demo --payload "$PAYLOAD3" --overwrite allow >/dev/null 2>&1 \ || fail "a valid payload with no conflicts and overwrite=allow should succeed" grep -qi "restore payload completed" "$TMP_DIR/restore.log" \ || fail "expected the restore to log completion" echo "alt_mysql_restore_payload_test: OK"