healthcheck: split delete and login passes
This commit is contained in:
@@ -26,18 +26,29 @@ if ! id "${RUN_AS_USER}" >/dev/null 2>&1; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
LOGIN="smkhc$(date +%s)"
|
DELETE_LOGIN="smkdel$(date +%s)"
|
||||||
PASSWORD="$(openssl rand -hex 6)"
|
DELETE_PASSWORD="$(openssl rand -hex 6)"
|
||||||
SOCIAL_ID="$(date +%s%N | tail -c 14)"
|
DELETE_SOCIAL_ID="$(date +%s%N | tail -c 14)"
|
||||||
EMAIL="${LOGIN}@example.invalid"
|
DELETE_EMAIL="${DELETE_LOGIN}@example.invalid"
|
||||||
CHARACTER_NAME="c${LOGIN}"
|
DELETE_CHARACTER_NAME="c${DELETE_LOGIN}"
|
||||||
ACCOUNT_ID=""
|
DELETE_PRIVATE_CODE="${DELETE_SOCIAL_ID: -7}"
|
||||||
|
DELETE_ACCOUNT_ID=""
|
||||||
|
|
||||||
cleanup() {
|
FULL_LOGIN="smkfull$(date +%s)"
|
||||||
if [[ -n "${ACCOUNT_ID}" ]]; then
|
FULL_PASSWORD="$(openssl rand -hex 6)"
|
||||||
|
FULL_SOCIAL_ID="$(date +%s%N | tail -c 14)"
|
||||||
|
FULL_EMAIL="${FULL_LOGIN}@example.invalid"
|
||||||
|
FULL_CHARACTER_NAME="c${FULL_LOGIN}"
|
||||||
|
FULL_ACCOUNT_ID=""
|
||||||
|
|
||||||
|
cleanup_account() {
|
||||||
|
local account_id="$1"
|
||||||
|
local login="$2"
|
||||||
|
|
||||||
|
if [[ -n "${account_id}" ]]; then
|
||||||
mysql player >/dev/null 2>&1 <<SQL || true
|
mysql player >/dev/null 2>&1 <<SQL || true
|
||||||
CREATE TEMPORARY TABLE smoke_pids AS
|
CREATE TEMPORARY TABLE smoke_pids AS
|
||||||
SELECT id FROM player WHERE account_id = ${ACCOUNT_ID};
|
SELECT id FROM player WHERE account_id = ${account_id};
|
||||||
|
|
||||||
DELETE FROM item
|
DELETE FROM item
|
||||||
WHERE owner_id IN (SELECT id FROM smoke_pids);
|
WHERE owner_id IN (SELECT id FROM smoke_pids);
|
||||||
@@ -58,18 +69,21 @@ SQL
|
|||||||
mysql player >/dev/null 2>&1 <<SQL || true
|
mysql player >/dev/null 2>&1 <<SQL || true
|
||||||
DELETE FROM player_index
|
DELETE FROM player_index
|
||||||
WHERE id IN (
|
WHERE id IN (
|
||||||
SELECT id FROM account.account WHERE login='${LOGIN}'
|
SELECT id FROM account.account WHERE login='${login}'
|
||||||
);
|
);
|
||||||
SQL
|
SQL
|
||||||
|
|
||||||
mysql account >/dev/null 2>&1 <<SQL || true
|
mysql account >/dev/null 2>&1 <<SQL || true
|
||||||
DELETE FROM account WHERE login='${LOGIN}';
|
DELETE FROM account WHERE login='${login}';
|
||||||
SQL
|
SQL
|
||||||
}
|
}
|
||||||
|
|
||||||
trap cleanup EXIT
|
create_account() {
|
||||||
|
local login="$1"
|
||||||
|
local password="$2"
|
||||||
|
local social_id="$3"
|
||||||
|
local email="$4"
|
||||||
|
|
||||||
ACCOUNT_ID="$(
|
|
||||||
mysql -N account <<SQL
|
mysql -N account <<SQL
|
||||||
INSERT INTO account (
|
INSERT INTO account (
|
||||||
login,
|
login,
|
||||||
@@ -97,10 +111,10 @@ INSERT INTO account (
|
|||||||
channel_company,
|
channel_company,
|
||||||
last_play
|
last_play
|
||||||
) VALUES (
|
) VALUES (
|
||||||
'${LOGIN}',
|
'${login}',
|
||||||
PASSWORD('${PASSWORD}'),
|
PASSWORD('${password}'),
|
||||||
'${SOCIAL_ID}',
|
'${social_id}',
|
||||||
'${EMAIL}',
|
'${email}',
|
||||||
NOW(),
|
NOW(),
|
||||||
0,
|
0,
|
||||||
'OK',
|
'OK',
|
||||||
@@ -124,18 +138,43 @@ INSERT INTO account (
|
|||||||
);
|
);
|
||||||
SELECT LAST_INSERT_ID();
|
SELECT LAST_INSERT_ID();
|
||||||
SQL
|
SQL
|
||||||
)"
|
}
|
||||||
|
|
||||||
mysql player >/dev/null <<SQL
|
create_player_index() {
|
||||||
|
local account_id="$1"
|
||||||
|
|
||||||
|
mysql player >/dev/null <<SQL
|
||||||
INSERT INTO player_index (id, pid1, pid2, pid3, pid4, empire)
|
INSERT INTO player_index (id, pid1, pid2, pid3, pid4, empire)
|
||||||
VALUES (${ACCOUNT_ID}, 0, 0, 0, 0, 1);
|
VALUES (${account_id}, 0, 0, 0, 0, 1);
|
||||||
SQL
|
SQL
|
||||||
|
}
|
||||||
|
|
||||||
echo "Running login healthcheck for temporary account ${LOGIN}"
|
cleanup() {
|
||||||
sudo -iu "${RUN_AS_USER}" env METIN_LOGIN_SMOKE_PASSWORD="${PASSWORD}" \
|
cleanup_account "${DELETE_ACCOUNT_ID}" "${DELETE_LOGIN}"
|
||||||
"${SMOKE_BIN}" "${SERVER_HOST}" "${AUTH_PORT}" "${CHANNEL_PORT}" "${LOGIN}" \
|
cleanup_account "${FULL_ACCOUNT_ID}" "${FULL_LOGIN}"
|
||||||
|
}
|
||||||
|
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
DELETE_ACCOUNT_ID="$(create_account "${DELETE_LOGIN}" "${DELETE_PASSWORD}" "${DELETE_SOCIAL_ID}" "${DELETE_EMAIL}")"
|
||||||
|
create_player_index "${DELETE_ACCOUNT_ID}"
|
||||||
|
|
||||||
|
FULL_ACCOUNT_ID="$(create_account "${FULL_LOGIN}" "${FULL_PASSWORD}" "${FULL_SOCIAL_ID}" "${FULL_EMAIL}")"
|
||||||
|
create_player_index "${FULL_ACCOUNT_ID}"
|
||||||
|
|
||||||
|
echo "Running create/delete healthcheck for temporary account ${DELETE_LOGIN}"
|
||||||
|
sudo -iu "${RUN_AS_USER}" env METIN_LOGIN_SMOKE_PASSWORD="${DELETE_PASSWORD}" \
|
||||||
|
"${SMOKE_BIN}" "${SERVER_HOST}" "${AUTH_PORT}" "${CHANNEL_PORT}" "${DELETE_LOGIN}" \
|
||||||
--password-env=METIN_LOGIN_SMOKE_PASSWORD \
|
--password-env=METIN_LOGIN_SMOKE_PASSWORD \
|
||||||
--create-character-name="${CHARACTER_NAME}" \
|
--create-character-name="${DELETE_CHARACTER_NAME}" \
|
||||||
|
--delete-private-code="${DELETE_PRIVATE_CODE}" \
|
||||||
|
--client-version="${CLIENT_VERSION}"
|
||||||
|
|
||||||
|
echo "Running full login healthcheck for temporary account ${FULL_LOGIN}"
|
||||||
|
sudo -iu "${RUN_AS_USER}" env METIN_LOGIN_SMOKE_PASSWORD="${FULL_PASSWORD}" \
|
||||||
|
"${SMOKE_BIN}" "${SERVER_HOST}" "${AUTH_PORT}" "${CHANNEL_PORT}" "${FULL_LOGIN}" \
|
||||||
|
--password-env=METIN_LOGIN_SMOKE_PASSWORD \
|
||||||
|
--create-character-name="${FULL_CHARACTER_NAME}" \
|
||||||
--client-version="${CLIENT_VERSION}" \
|
--client-version="${CLIENT_VERSION}" \
|
||||||
--mall-password="${MALL_PASSWORD}"
|
--mall-password="${MALL_PASSWORD}"
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,12 @@ Installed on the VPS:
|
|||||||
|
|
||||||
## What The Headless Healthcheck Verifies
|
## What The Headless Healthcheck Verifies
|
||||||
|
|
||||||
The check performs the real two-step Metin login flow without a GUI client and then exercises the in-game mall open path:
|
The installed wrapper now performs two headless passes against the live server:
|
||||||
|
|
||||||
|
1. a select-screen create/delete pass
|
||||||
|
2. a full auth + channel + `ENTERGAME` + mall pass
|
||||||
|
|
||||||
|
Together they perform the real two-step Metin login flow without a GUI client and cover both character lifecycle and in-game mall open behavior:
|
||||||
|
|
||||||
1. Connect to the auth socket.
|
1. Connect to the auth socket.
|
||||||
2. Complete the secure handshake.
|
2. Complete the secure handshake.
|
||||||
@@ -30,11 +35,14 @@ The check performs the real two-step Metin login flow without a GUI client and t
|
|||||||
7. Send `LOGIN2` with `login` + `login_key`.
|
7. Send `LOGIN2` with `login` + `login_key`.
|
||||||
8. Verify `EMPIRE`.
|
8. Verify `EMPIRE`.
|
||||||
9. Verify `LOGIN_SUCCESS4`.
|
9. Verify `LOGIN_SUCCESS4`.
|
||||||
10. Select a character slot.
|
10. Create a temporary character on an empty account.
|
||||||
11. Send `ENTERGAME`.
|
11. Delete that temporary character on the select screen using the account private code path.
|
||||||
12. Verify `MAIN_CHARACTER`, `PHASE_GAME`, `TIME`, and `CHANNEL`.
|
12. Create a fresh temporary character again.
|
||||||
13. Send `/mall_password 000000` through the encrypted chat path.
|
13. Select a character slot.
|
||||||
14. Verify `MALL_OPEN`.
|
14. Send `ENTERGAME`.
|
||||||
|
15. Verify `MAIN_CHARACTER`, `PHASE_GAME`, `TIME`, and `CHANNEL`.
|
||||||
|
16. Send `/mall_password 000000` through the encrypted chat path.
|
||||||
|
17. Verify `MALL_OPEN`.
|
||||||
|
|
||||||
This is an end-to-end gameplay-path verification, not just a TCP port check.
|
This is an end-to-end gameplay-path verification, not just a TCP port check.
|
||||||
|
|
||||||
@@ -42,12 +50,12 @@ This is an end-to-end gameplay-path verification, not just a TCP port check.
|
|||||||
|
|
||||||
`metin-login-healthcheck.sh` does the following:
|
`metin-login-healthcheck.sh` does the following:
|
||||||
|
|
||||||
- creates a temporary account in MariaDB
|
- creates two temporary accounts in MariaDB
|
||||||
- lets `metin_login_smoke` create a temporary character when the account is empty
|
- runs `metin_login_smoke` once in create/delete mode on the select screen
|
||||||
- runs `metin_login_smoke`
|
- runs `metin_login_smoke` again for the full auth + channel + `ENTERGAME` flow
|
||||||
- verifies a successful auth + channel + `ENTERGAME` flow
|
- uses separate temporary accounts because the server enforces a per-account character-create cooldown
|
||||||
- verifies that the shared safebox/mall DB load bootstrap can open the mall with the default empty password
|
- verifies that the shared safebox/mall DB load bootstrap can open the mall with the default empty password
|
||||||
- deletes the temporary account and temporary character rows on exit
|
- deletes both temporary accounts and any temporary character rows on exit
|
||||||
- passes the configured client version expected by the server
|
- passes the configured client version expected by the server
|
||||||
|
|
||||||
It is intended for manual admin use on the VPS.
|
It is intended for manual admin use on the VPS.
|
||||||
@@ -96,6 +104,8 @@ Useful direct flags:
|
|||||||
treats an auth failure such as `NOID` or `WRONGPWD` as a successful negative test
|
treats an auth failure such as `NOID` or `WRONGPWD` as a successful negative test
|
||||||
- `--expect-channel-failure=STATUS`
|
- `--expect-channel-failure=STATUS`
|
||||||
treats a channel failure as a successful negative test
|
treats a channel failure as a successful negative test
|
||||||
|
- `--delete-private-code=CODE`
|
||||||
|
creates or reuses a character slot, sends `CHARACTER_DELETE`, and verifies `PLAYER_DELETE_SUCCESS`
|
||||||
- `--mall-password=PASSWORD`
|
- `--mall-password=PASSWORD`
|
||||||
after `ENTERGAME`, opens the in-game mall via encrypted chat command and verifies `MALL_OPEN`
|
after `ENTERGAME`, opens the in-game mall via encrypted chat command and verifies `MALL_OPEN`
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user