#!/bin/bash set -euo pipefail PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)" SCRIPT="$PLUGIN_DIR/scripts/da-integration/alt_mysql_native_backup_restore.sh" TMP_DIR="$(mktemp -d)" trap 'rm -rf "$TMP_DIR"' EXIT fail() { echo "FAIL: $*" >&2 exit 1 } # Source only the parsing functions, without triggering main() (the script # guards its own main() call behind a BASH_SOURCE check, see Task 3 Step 1). # shellcheck source=/dev/null source "$SCRIPT" # --- Real example content, copied verbatim from example_backup/psy/backup/psy_it301.conf --- CONF_FILE="$TMP_DIR/psy_it301.conf" cat > "$CONF_FILE" <<'EOF' accesshosts=0=localhost db_collation=DEFAULT_CHARACTER_SET_NAME=utf8mb3&DEFAULT_COLLATION_NAME=utf8mb3_general_ci&SCHEMA_NAME=psy_it301 psy_it301=accesshosts=localhost&alter_priv=Y&alter_routine_priv=Y&create_priv=Y&create_routine_priv=Y&create_tmp_table_priv=Y&create_view_priv=Y&delete_priv=Y&drop_priv=Y&event_priv=Y&execute_priv=Y&index_priv=Y&insert_priv=Y&lock_tables_priv=Y&passwd=%2A8E2A6497279CF1B7F115E213B9904BD32703F4EF&plugin=mysql_native_password&references_priv=Y&select_priv=Y&show_view_priv=Y&trigger_priv=Y&update_priv=Y EOF # url_decode [ "$(url_decode '%2A8E2A6497279CF1B7F115E213B9904BD32703F4EF')" = "*8E2A6497279CF1B7F115E213B9904BD32703F4EF" ] \ || fail "url_decode did not decode %2A correctly" # native_conf_field QS="accesshosts=localhost&select_priv=Y&passwd=%2Aabc&plugin=mysql_native_password" [ "$(native_conf_field "$QS" passwd)" = "%2Aabc" ] || fail "native_conf_field did not extract passwd" [ "$(native_conf_field "$QS" plugin)" = "mysql_native_password" ] || fail "native_conf_field did not extract plugin" [ "$(native_conf_field "$QS" missing_field)" = "" ] || fail "native_conf_field should return empty for a missing field" # native_conf_privilege_list PRIVS="$(native_conf_privilege_list "$QS")" [ "$PRIVS" = "SELECT" ] || fail "expected only SELECT for a single select_priv=Y field, got: $PRIVS" NO_PRIVS="$(native_conf_privilege_list "accesshosts=localhost&plugin=mysql_native_password")" [ "$NO_PRIVS" = "ALL" ] || fail "expected ALL when no *_priv=Y flags are present, got: $NO_PRIVS" # parse_native_db_conf against the real example file parse_native_db_conf "$CONF_FILE" || fail "parse_native_db_conf should succeed on a valid conf file" [ "$NATIVE_DB_CHARSET" = "utf8mb3" ] || fail "expected charset utf8mb3, got: $NATIVE_DB_CHARSET" [ "$NATIVE_DB_COLLATION" = "utf8mb3_general_ci" ] || fail "expected collation utf8mb3_general_ci, got: $NATIVE_DB_COLLATION" [ "${#NATIVE_DB_USER_NAMES[@]}" -eq 1 ] || fail "expected exactly 1 user, got: ${#NATIVE_DB_USER_NAMES[@]}" [ "${NATIVE_DB_USER_NAMES[0]}" = "psy_it301" ] || fail "expected username psy_it301, got: ${NATIVE_DB_USER_NAMES[0]}" [ "${NATIVE_DB_USER_HOST[0]}" = "localhost" ] || fail "expected host localhost, got: ${NATIVE_DB_USER_HOST[0]}" [ "${NATIVE_DB_USER_HASH[0]}" = "*8E2A6497279CF1B7F115E213B9904BD32703F4EF" ] || fail "password hash not decoded correctly, got: ${NATIVE_DB_USER_HASH[0]}" [ "${NATIVE_DB_USER_PLUGIN[0]}" = "mysql_native_password" ] || fail "expected mysql_native_password plugin, got: ${NATIVE_DB_USER_PLUGIN[0]}" echo "${NATIVE_DB_USER_PRIVS[0]}" | grep -q "SELECT" || fail "expected SELECT in privilege list, got: ${NATIVE_DB_USER_PRIVS[0]}" # --- A conf file with two users on the same database --- MULTI_CONF="$TMP_DIR/multi.conf" cat > "$MULTI_CONF" <<'EOF' accesshosts=0=localhost db_collation=DEFAULT_CHARACTER_SET_NAME=utf8mb4&DEFAULT_COLLATION_NAME=utf8mb4_general_ci&SCHEMA_NAME=demo_multi demo_owner=accesshosts=localhost&select_priv=Y&insert_priv=Y&passwd=%2Aaaa&plugin=mysql_native_password demo_reader=accesshosts=localhost&select_priv=Y&passwd=%2Abbb&plugin=mysql_native_password EOF parse_native_db_conf "$MULTI_CONF" || fail "parse_native_db_conf should succeed on a multi-user conf file" [ "${#NATIVE_DB_USER_NAMES[@]}" -eq 2 ] || fail "expected 2 users in a multi-user conf, got: ${#NATIVE_DB_USER_NAMES[@]}" # --- A malformed conf file (no db_collation) must fail closed, not guess --- BAD_CONF="$TMP_DIR/bad.conf" cat > "$BAD_CONF" <<'EOF' accesshosts=0=localhost demo_user=select_priv=Y&passwd=%2Aaaa&plugin=mysql_native_password EOF if parse_native_db_conf "$BAD_CONF" 2>/dev/null; then fail "parse_native_db_conf must fail when db_collation is missing, not guess a default" fi echo "alt_mysql_native_backup_restore_parse_test: OK"