Files
alt-mysql/tests/native_mariadb_port_takeover_e2e_test.sh
T

204 lines
5.8 KiB
Bash

#!/bin/bash
set -euo pipefail
PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)"
SCRIPT="$PLUGIN_DIR/scripts/setup/native_mariadb_port_takeover.sh"
TMP_DIR="$(mktemp -d)"
trap 'rm -rf "$TMP_DIR"' EXIT
fail() {
echo "FAIL: $*" >&2
exit 1
}
setup_fixture() {
local dir="$1"
mkdir -p "$dir/bin" "$dir/my.cnf.d"
cat > "$dir/my.cnf" <<'EOF'
[client]
port=3306
[mysqld]
datadir=/var/lib/mysql
port=3306
socket=/var/lib/mysql/mysql.sock
EOF
cat > "$dir/mysql.conf" <<'EOF'
user=da_admin
passwd=secret
port=3306
socket=/var/lib/mysql/mysql.sock
host=
EOF
cat > "$dir/options.conf" <<'EOF'
mysql_inst=mariadb
mariadb=10.6
EOF
cat > "$dir/os-release" <<'EOF'
ID="almalinux"
VERSION_ID="9.4"
EOF
}
# run_takeover DIR
# Runs the script under test against the fixture already prepared at DIR
# (by a prior call to setup_fixture, possibly customized further by the
# scenario since) - writes stdout+stderr to "$DIR/run.out". Does NOT touch
# the fixture itself, so scenario-specific customizations made after
# setup_fixture (e.g. editing mysql.conf, swapping os-release) are preserved.
run_takeover() {
local dir="$1"
env \
NATIVE_TAKEOVER_LOG="$dir/takeover.log" \
NATIVE_MY_CNF="$dir/my.cnf" \
NATIVE_MY_CNF_D="$dir/my.cnf.d" \
NATIVE_MYSQL_CONF="$dir/mysql.conf" \
CUSTOMBUILD_OPTIONS_CONF="$dir/options.conf" \
OS_RELEASE_FILE="$dir/os-release" \
NEW_NATIVE_PORT="3307" \
DA_CLI_BIN="$dir/bin/da" \
PATH="$dir/bin:$PATH" \
bash "$SCRIPT" > "$dir/run.out" 2>&1
}
# --- Fake command stubs shared by scenarios; each scenario builds its own copies ---
write_common_stubs() {
local dir="$1"
local mode="${2:-happy}"
cat > "$dir/bin/da" <<EOF
#!/bin/bash
echo "\$*" >> "$dir/da_calls.log"
exit 0
EOF
chmod 755 "$dir/bin/da"
cat > "$dir/bin/mysql" <<EOF
#!/bin/bash
CURRENT_PORT_FILE="$dir/current_port"
requested_port=""
for arg in "\$@"; do
case "\$arg" in
--port=*) requested_port="\${arg#--port=}" ;;
esac
done
if [ "\$requested_port" = "\$(cat "\$CURRENT_PORT_FILE" 2>/dev/null || echo 3306)" ]; then
exit 0
fi
exit 1
EOF
chmod 755 "$dir/bin/mysql"
echo "3306" > "$dir/current_port"
cat > "$dir/bin/systemctl" <<EOF
#!/bin/bash
# mysql_service_name() (mysql_common.sh) probes "mysqld", then "mariadb", then
# "mysql" via 'systemctl list-unit-files <name>.service' and picks the first
# that succeeds - only mariadb.service "exists" here, matching a real
# AlmaLinux+MariaDB box where mysqld.service does not exist.
if [ "\$1" = "list-unit-files" ]; then
case "\$2" in
mariadb.service) exit 0 ;;
*) exit 1 ;;
esac
fi
echo "systemctl \$*" >> "$dir/systemctl_calls.log"
if [ "\$1" = "restart" ] && [ "\$2" = "mariadb" ] && [ "$mode" = "restart-fail" ]; then
exit 1
fi
if [ "\$1" = "restart" ] && [ "\$2" = "mariadb" ]; then
echo "3307" > "$dir/current_port"
fi
if [ "\$1" = "restart" ] && [ "\$2" = "directadmin" ] && [ "$mode" = "da-restart-fail" ]; then
exit 1
fi
exit 0
EOF
chmod 755 "$dir/bin/systemctl"
cat > "$dir/bin/ss" <<EOF
#!/bin/bash
current="\$(cat "$dir/current_port" 2>/dev/null || echo 3306)"
for arg in "\$@"; do
case "\$arg" in
*":\$current"*) echo header; echo occupied; exit 0 ;;
esac
done
exit 0
EOF
chmod 755 "$dir/bin/ss"
}
# --- Scenario 1: happy path ---
DIR="$TMP_DIR/happy"
setup_fixture "$DIR"
write_common_stubs "$DIR" happy
run_takeover "$DIR"
STATUS=$?
[ "$STATUS" -eq 0 ] || fail "happy path should exit 0, got $STATUS: $(cat "$DIR/run.out")"
grep -Fxq "port=3307" "$DIR/mysql.conf" || fail "happy path should leave mysql.conf on port 3307"
grep -Fq "build set mysql_inst no" "$DIR/da_calls.log" || fail "happy path should call da build set mysql_inst no"
grep -Fq "restart mariadb" "$DIR/systemctl_calls.log" || fail "happy path should restart mariadb"
grep -Fq "restart directadmin" "$DIR/systemctl_calls.log" || fail "happy path should restart directadmin"
# --- Scenario 2: already migrated (idempotent no-op) ---
DIR="$TMP_DIR/already"
setup_fixture "$DIR"
write_common_stubs "$DIR" happy
sed -i.orig 's/^port=3306$/port=3307/' "$DIR/mysql.conf"
run_takeover "$DIR"
STATUS=$?
[ "$STATUS" -eq 0 ] || fail "already-migrated case should exit 0, got $STATUS"
grep -Fq "build set" "$DIR/da_calls.log" 2>/dev/null && fail "already-migrated case should not touch CustomBuild settings"
# --- Scenario 3: OS guard rejection ---
DIR="$TMP_DIR/badose"
setup_fixture "$DIR"
write_common_stubs "$DIR" happy
cat > "$DIR/os-release" <<'EOF'
ID="cloudlinux"
VERSION_ID="8.9"
EOF
set +e
run_takeover "$DIR"
STATUS=$?
set -e
[ "$STATUS" -ne 0 ] || fail "CloudLinux should be refused, not exit 0"
grep -Fq "build set" "$DIR/da_calls.log" 2>/dev/null && fail "OS-guard rejection must not touch CustomBuild settings"
# --- Scenario 4: rollback when native restart fails ---
DIR="$TMP_DIR/restartfail"
setup_fixture "$DIR"
write_common_stubs "$DIR" restart-fail
set +e
run_takeover "$DIR"
STATUS=$?
set -e
[ "$STATUS" -ne 0 ] || fail "a failed native restart should not exit 0"
grep -Fxq "port=3306" "$DIR/mysql.conf" \
|| fail "mysql.conf should be rolled back to port 3306 after a failed native restart"
grep -Fq "build set mysql_inst mariadb" "$DIR/da_calls.log" \
|| fail "mysql_inst should be restored to mariadb after a failed native restart"
# --- Scenario 5: rollback when DirectAdmin restart fails ---
DIR="$TMP_DIR/darestartfail"
setup_fixture "$DIR"
write_common_stubs "$DIR" da-restart-fail
set +e
run_takeover "$DIR"
STATUS=$?
set -e
[ "$STATUS" -ne 0 ] || fail "a failed directadmin restart should not exit 0"
grep -Fxq "port=3306" "$DIR/mysql.conf" \
|| fail "mysql.conf should be rolled back to port 3306 after a failed directadmin restart"
grep -Fq "build set mysql_inst mariadb" "$DIR/da_calls.log" \
|| fail "mysql_inst should be restored to mariadb after a failed directadmin restart"
echo "native_mariadb_port_takeover_e2e_test: OK"