fix(personal): bound DNS fallback and smoke redirects

This commit is contained in:
2026-07-12 17:00:20 +08:00
parent fed32939e6
commit c8a0de82b7
5 changed files with 333 additions and 254 deletions
+51 -16
View File
@@ -20,6 +20,8 @@ PDF_TITLE="$TITLE-pdf"
URL_TITLE="$TITLE-url"
PDF_QUERY="Personal PDF verification evidence"
PUBLIC_URL="${AIHR_PERSONAL_SMOKE_PUBLIC_URL:-https://example.com/}"
PUBLIC_EXPECTED_URL="${AIHR_PERSONAL_SMOKE_EXPECTED_PUBLIC_URL:-}"
[[ -n "${AIHR_PERSONAL_SMOKE_PUBLIC_URL:-}" ]] || PUBLIC_EXPECTED_URL="https://example.com/"
PUBLIC_QUERY="${AIHR_PERSONAL_SMOKE_PUBLIC_QUERY:-Example Domain}"
TMP_ROOT="$(mktemp -d "${TMPDIR:-/tmp}/wygj-personal-smoke.XXXXXX")"
chmod 700 "$TMP_ROOT"
@@ -96,9 +98,6 @@ cleanup_once() {
USER_B="$(mysql "select user_id from sys_user where phonenumber='$PHONE_B' and remark='移动端短信自动注册' order by user_id desc limit 1" | head -1)"
fi
discover_run_items
if [[ "$USER_A" =~ ^[0-9]+$ && ! "$SESSION_ID" =~ ^[0-9]+$ ]]; then
SESSION_ID="$(mysql "select s.id from aihr_personal_chat_session s join aihr_personal_chat_message m on m.session_id=s.id and m.owner_user_id=s.owner_user_id where s.tenant_id='000000' and s.owner_user_id=$USER_A and m.content like '%$RUN_ID%' order by s.id desc limit 1" | head -1)"
fi
local index item_id oss_id object_key
for index in "${!ITEM_IDS[@]}"; do
item_id="${ITEM_IDS[$index]}"
@@ -119,10 +118,11 @@ cleanup_once() {
delete from aihr_personal_cleanup_job where tenant_id='000000' and owner_user_id=$USER_A and item_id=$item_id;
delete from aihr_personal_item where tenant_id='000000' and owner_user_id=$USER_A and id=$item_id and title like '$TITLE-%';" >/dev/null 2>&1 || true
done
if [[ "$SESSION_ID" =~ ^[0-9]+$ && "$USER_A" =~ ^[0-9]+$ ]]; then
mysql "delete from aihr_personal_chat_message where tenant_id='000000' and owner_user_id=$USER_A and session_id=$SESSION_ID;
delete from aihr_personal_chat_session where tenant_id='000000' and owner_user_id=$USER_A and id=$SESSION_ID;" >/dev/null 2>&1 || true
fi
for owner in "$USER_A" "$USER_B"; do
[[ "$owner" =~ ^[0-9]+$ ]] || continue
mysql "delete from aihr_personal_chat_message where tenant_id='000000' and owner_user_id=$owner;
delete from aihr_personal_chat_session where tenant_id='000000' and owner_user_id=$owner;" >/dev/null 2>&1 || true
done
for owner in "$USER_A" "$USER_B"; do
[[ "$owner" =~ ^[0-9]+$ ]] || continue
mysql "delete from aihr_personal_space where tenant_id='000000' and owner_user_id=$owner and not exists
@@ -145,7 +145,37 @@ cleanup_once() {
done < <(redis-cli -h 127.0.0.1 -p 16379 -a ruoyi123 --scan --pattern "*resource/sms/code:$phone*" 2>/dev/null)
done
}
on_exit() { local code=$?; trap - EXIT INT TERM; cleanup_once; exit "$code"; }
assert_identity_cleanup() {
local owner session_count message_count
for owner in "$USER_A" "$USER_B"; do
[[ "$owner" =~ ^[0-9]+$ ]] || continue
session_count="$(mysql "select count(*) from aihr_personal_chat_session where tenant_id='000000' and owner_user_id=$owner")"
message_count="$(mysql "select count(*) from aihr_personal_chat_message where tenant_id='000000' and owner_user_id=$owner")"
[[ "$session_count" == 0 && "$message_count" == 0 ]] || {
echo "FAIL: personal chat residue owner=$owner sessions=$session_count messages=$message_count" >&2
return 1
}
done
[[ "$(mysql "select count(*) from sys_user where phonenumber in ('$PHONE_A','$PHONE_B')")" == 0 ]] || {
echo "FAIL: smoke users were not removed" >&2
return 1
}
}
on_exit() {
local code=$?
trap - EXIT INT TERM
cleanup_once
if [[ "$code" != 0 && "${AIHR_SMOKE_CLEANUP_DRY_RUN:-0}" != 1 ]]; then
if assert_identity_cleanup; then
echo "PASS: failure-window owner session and user cleanup"
else
code=1
fi
fi
exit "$code"
}
on_int() { trap - EXIT INT TERM; cleanup_once; exit 130; }
on_term() { trap - EXIT INT TERM; cleanup_once; exit 143; }
trap on_exit EXIT
@@ -253,6 +283,8 @@ assert_single_item_ask() {
expect_success "A $label single-item answer"
response_session="$(jq -er '.data.sessionId | tostring' <<<"$HTTP_BODY")"
[[ "$response_session" =~ ^[0-9]+$ ]] || fail "A $label answer did not persist session"
[[ "${AIHR_SMOKE_FAIL_AFTER_SESSION_CREATED:-0}" != 1 ]] \
|| fail "injected failure after backend session creation"
if [[ "$SESSION_ID" =~ ^[0-9]+$ ]]; then
expect_code "$response_session" "$SESSION_ID" "A $label answer session continuity"
else
@@ -326,14 +358,12 @@ case "$PUBLIC_URL" in
http://localhost*|https://localhost*|http://127.*|https://127.*|http://\[*|https://\[*|http://169.254.*|https://169.254.*)
fail "AIHR_PERSONAL_SMOKE_PUBLIC_URL must be a public URL, not localhost/private metadata"
;;
http://*|https://*) ;;
http://*|https://*)
[[ "$PUBLIC_URL" =~ ^https?://[^/?#]+([/?#].*)?$ ]] \
|| fail "AIHR_PERSONAL_SMOKE_PUBLIC_URL has no valid HTTP(S) authority"
;;
*) fail "AIHR_PERSONAL_SMOKE_PUBLIC_URL must use http or https" ;;
esac
PUBLIC_EFFECTIVE_URL="$(curl --fail --location --silent --show-error --max-time 20 \
--output /dev/null --write-out '%{url_effective}' "$PUBLIC_URL")" \
|| fail "public URL unreachable: $PUBLIC_URL"
[[ "$PUBLIC_EFFECTIVE_URL" == http://* || "$PUBLIC_EFFECTIVE_URL" == https://* ]] \
|| fail "public URL did not resolve to HTTP(S): $PUBLIC_URL"
request GET /auth/tenant/list
expect_success "backend health"
docker ps --format '{{.Names}}' | grep -qx "$DB_CONTAINER" || fail "database container not running: $DB_CONTAINER"
@@ -375,7 +405,9 @@ append_item_metadata "$PDF_ITEM_ID" "$PDF_TITLE"
request POST /api/aihr/personal-assistant/items/url "$TOKEN_A" "$CLIENT_A" \
"$(jq -cn --arg url "$PUBLIC_URL" --arg title "$URL_TITLE" '{url:$url,title:$title}')"
expect_success "A create public URL item"
if [[ "$HTTP_STATUS" != 200 || "$(jq -r '.code // empty' <<<"$HTTP_BODY")" != 200 ]]; then
fail "public URL capture failed HTTP=$HTTP_STATUS code=$(jq -r '.code // empty' <<<"$HTTP_BODY") msg=$(jq -r '.msg // empty' <<<"$HTTP_BODY")"
fi
URL_ITEM_ID="$(jq -er '.data.itemId | tostring' <<<"$HTTP_BODY")"
append_item_metadata "$URL_ITEM_ID" "$URL_TITLE"
expect_code "${#ITEM_IDS[@]}" 3 "three personal items captured"
@@ -387,7 +419,9 @@ expect_code "$(jq -r '.data.sourceType' <<<"$HTTP_BODY")" FILE "A PDF source typ
expect_code "$(jq -r '.data.mimeType' <<<"$HTTP_BODY")" application/pdf "A PDF mime type"
wait_ready "$URL_ITEM_ID" "A public URL item"
expect_code "$(jq -r '.data.sourceType' <<<"$HTTP_BODY")" URL "A URL source type"
expect_code "$(jq -r '.data.originalUrl' <<<"$HTTP_BODY")" "$PUBLIC_EFFECTIVE_URL" "A URL originalUrl"
URL_ORIGINAL="$(jq -r '.data.originalUrl // empty' <<<"$HTTP_BODY")"
[[ "$URL_ORIGINAL" == http://* || "$URL_ORIGINAL" == https://* ]] || fail "A URL originalUrl is not HTTP(S)"
[[ -z "$PUBLIC_EXPECTED_URL" ]] || expect_code "$URL_ORIGINAL" "$PUBLIC_EXPECTED_URL" "A URL originalUrl"
for index in "${!OSS_URLS[@]}"; do
assert_anonymous_private "${OSS_URLS[$index]}" "personal object ${ITEM_IDS[$index]}"
@@ -434,6 +468,7 @@ expect_code "$cleanup_done" 3 "three cleanup jobs completed"
assert_business_cleanup
cleanup_once
assert_identity_cleanup
expect_code "$(mysql "select count(*) from aihr_personal_item where tenant_id='000000' and owner_user_id=$USER_A and title like '$TITLE-%'")" 0 "run items residual"
expect_code "$(mysql "select count(*) from aihr_personal_fragment where tenant_id='000000' and owner_user_id=$USER_A and item_id in ($TEXT_ITEM_ID,$PDF_ITEM_ID,$URL_ITEM_ID)")" 0 "run fragments residual"
expect_code "$(mysql "select count(*) from aihr_personal_cleanup_job where tenant_id='000000' and owner_user_id=$USER_A and item_id in ($TEXT_ITEM_ID,$PDF_ITEM_ID,$URL_ITEM_ID)")" 0 "run cleanup jobs residual"