Skip to content

test(e2e): pin the proxy health endpoints under admin-off#802

Merged
moonming merged 2 commits into
mainfrom
feat/readyz-off-admin
Jul 22, 2026
Merged

test(e2e): pin the proxy health endpoints under admin-off#802
moonming merged 2 commits into
mainfrom
feat/readyz-off-admin

Conversation

@moonming

@moonming moonming commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

What

Pin the proxy listener's health endpoints under admin-off — the health surface that survives the Admin API's removal. Two e2e legs added to admin-disabled-e2e (etcd + file source): wait for /readyz to report ready, then assert /livez → 200 ok and /readyz?verbose lists [+]shutdown ok + [+]config ok, all with no admin listener bound.

Why — a premise correction

The Admin-API-removal roadmap listed "/readyz relocation + deployment-probe repointing" as a prerequisite, on the premise that /readyz existed only on the admin listener. Investigation shows the premise is wrong:

  • The proxy listener already serves both /livez and /readyz (aisix-proxy build_router), via the same shared health::livez_response/readyz_response the admin handlers call.
  • The proxy /readyz carries the full readiness semantics: its config-freshness block is wired from the same supervisor.watch_status() the admin handler reads (etcd and managed modes), and an always-fresh probe in file mode (no watch to go stale) — crates/aisix-server/src/main.rs wires with_config_apply_age in every mode.
  • A sweep of every deployment artifact — this repo's Dockerfile (no HEALTHCHECK), docker/entrypoint.sh, CI docker smoke (already probes the proxy /livez), and the control-plane repo's entire deploy/ tree — found no health probe pointing at the admin listener. There is nothing to relocate and nothing to repoint.

So the only real gap was a regression pin: nothing asserted that the surviving health surface works with the admin listener off. This PR adds that pin, so the eventual admin-listener removal PR cannot silently regress /livez//readyz on the proxy.

The operational readiness story after removal is unchanged and now fully covered: proxy /livez (liveness) + proxy /readyz (readiness incl. config freshness/drain) + metrics listener /status/ready (config-only readiness) — the latter already pinned by status-config-e2e.

Verification

admin-disabled-e2e 9/9 green (7 existing + 2 new health legs); the new legs do their own readiness wait so they hold under test filtering. npx tsc --noEmit clean on the changed file; health-minimal (held-back admin health surface) untouched and green.

Follow-up (not this PR)

The repo README still leads with "configure through the admin API on :3001" and points at the rewritten docs quickstart — stale against the deprecation story; belongs with the coexistence-release communication pass. Docs-side, the proxy /livez//readyz could be listed on the ports/proxy-api reference pages as the surviving health surface.

Summary by CodeRabbit

  • Tests
    • Expanded end-to-end coverage for proxy health checks when the Admin listener is disabled.
    • Verified readiness and liveness endpoints across both etcd-backed and file-based configurations.
    • Confirmed readiness details report successful shutdown and configuration checks, while liveness returns the expected healthy response.

The Admin API removal roadmap listed '/readyz relocation' as a
prerequisite, on the premise that /readyz only existed on the admin
listener. The premise is wrong: the proxy listener already serves both
/livez and /readyz (aisix-proxy build_router), through the same shared
health functions, with the config-freshness block wired from the same
supervisor watch_status the admin handler uses (etcd/managed), and an
always-fresh probe in file mode. A sweep of every deployment artifact
(this repo's Dockerfile/CI/docker, and the control-plane repo's deploy
tree) found no health probe pointing at the admin listener — so nothing
needs relocating or repointing.

What was missing is a regression pin: nothing asserted the surviving
health surface works with the admin listener off. Extend the
admin-disabled e2e with a health leg in both source modes (etcd + file):
wait for /readyz to report ready, then assert /livez 200 'ok' and
/readyz?verbose lists '[+]shutdown ok' and '[+]config ok' — so the
eventual admin-listener removal cannot regress /livez//readyz on the
proxy.
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@moonming, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 45 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 64512be1-30e7-41f1-a9b9-706bfc9a4577

📥 Commits

Reviewing files that changed from the base of the PR and between 876cc56 and 06acf84.

📒 Files selected for processing (2)
  • crates/aisix-proxy/src/lib.rs
  • tests/e2e/src/cases/admin-disabled-e2e.test.ts
📝 Walkthrough

Walkthrough

Adds end-to-end coverage for proxy health endpoints when the Admin listener is disabled, covering both etcd and file configuration sources.

Changes

Admin-disabled health checks

Layer / File(s) Summary
Proxy health endpoint assertions
tests/e2e/src/cases/admin-disabled-e2e.test.ts
Tests /readyz, /livez, and /readyz?verbose responses after configuration propagation in etcd and file modes.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • api7/aisix#800: Updates the harness and readiness behavior used by these Admin-disabled health endpoint tests.
🚥 Pre-merge checks | ✅ 6
✅ Passed checks (6 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the change set by describing proxy health endpoint coverage when the admin listener is disabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
E2e Test Quality Review ✅ Passed The new tests are true E2E, cover both etcd and file modes, use real services, and the assertions are clear and relevant to the admin-off goal.
Security Check ✅ Passed Only e2e health tests changed; no sensitive logging, secret storage, auth bypass, ownership, TLS, isolation, or secret-resolution issues found.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/readyz-off-admin

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@moonming

Copy link
Copy Markdown
Collaborator Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.


Your plan includes PR reviews subject to rate limits. More reviews will be available in 59 minutes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/e2e/src/cases/admin-disabled-e2e.test.ts`:
- Around line 148-151: Update the guard around the application setup result so
only !etcdReachable calls ctx.skip() and returns; when etcd is reachable but app
is absent, fail explicitly instead of skipping. Preserve the existing behavior
for successful app setup.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bdd39b96-7ef7-4440-bc89-ee442d81fef5

📥 Commits

Reviewing files that changed from the base of the PR and between 5a4ca3c and 876cc56.

📒 Files selected for processing (1)
  • tests/e2e/src/cases/admin-disabled-e2e.test.ts

Comment on lines +148 to +151
if (!etcdReachable || !app) {
ctx.skip();
return;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Do not skip an application setup failure.

!app currently turns any setup/provisioning failure into a skipped test even when etcd is reachable. Skip only for unavailable etcd; fail explicitly when app is absent.

Proposed fix
-    if (!etcdReachable || !app) {
+    if (!etcdReachable) {
       ctx.skip();
       return;
     }
+    if (!app) throw new Error("setup failed");

Based on learnings, only unreachable etcd should cause a skip; setup failures must surface.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!etcdReachable || !app) {
ctx.skip();
return;
}
if (!etcdReachable) {
ctx.skip();
return;
}
if (!app) throw new Error("setup failed");
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/e2e/src/cases/admin-disabled-e2e.test.ts` around lines 148 - 151,
Update the guard around the application setup result so only !etcdReachable
calls ctx.skip() and returns; when etcd is reachable but app is absent, fail
explicitly instead of skipping. Preserve the existing behavior for successful
app setup.

Source: Learnings

Audit MEDIUM on the health pin: dropping the with_config_apply_age
wiring would leave readyz reporting '[+]config ok' unconditionally —
byte-identical to wired-and-fresh, silently downgrading readiness to
shutdown-only. Pin the plumbing at the router level: a wired probe
returning None must 503 with '[-]config failed: not ready'. The wiring
itself cannot be e2e'd leak-proof (the pre-first-apply 503 window is
milliseconds); the structural fix — a fail-closed default — is filed as
#803. Also correct the etcd health leg's comment: readyz reports ready
after the initial load applies (an empty prefix counts), not only after
the seed lands.
@moonming

Copy link
Copy Markdown
Collaborator Author

Independent cold audit: PASS — all four premise-correction claims verified against source and empirically (the auditor re-ran the sweeps, including the AISIX-Cloud helm chart the PR body's sweep description didn't mention: CP-only components, no DP probe — conclusion unchanged and now repo-wide).

MEDIUM — the pin couldn't catch the config-freshness gate becoming unwired (field-None[+]config ok unconditionally, byte-identical to wired-and-fresh; the likely trigger is the admin-removal PR reworking the adjacent main.rs region). Addressed in 06acf84: a router-level unit test (readyz_503s_when_the_config_probe_reports_no_apply_yet) pins the plumbing — a wired probe reporting no-apply-yet must 503 with [-]config failed: not ready. The main.rs wiring itself cannot be e2e'd leak-proof (the pre-first-apply 503 window is milliseconds, and an unreachable etcd fails boot instead of serving 503); /status/ready on the metrics listener independently covers config readiness (status-config-e2e). The structural fix — a fail-closed default for ProxyState.config_apply_age so a dropped wiring turns readyz permanently 503 instead of permanently 200 — is filed as #803 (audit LOW, pre-existing design).

LOW — comment overstated: the etcd health leg's comment now says readyz reports ready after the initial load applies (an empty prefix counts), matching the supervisor's record-apply-on-first-cycle behavior.

Housekeeping per audit: branch is 1 commit behind main (release-notes CI only — no path overlap, no semantic conflict); CodeRabbit shows a rate-limit false-green with zero comments to triage. Verification at the new head: aisix-proxy readyz tests 4/4 (incl. the new pin), clippy clean, admin-disabled-e2e 9/9.

@moonming
moonming merged commit dc7a435 into main Jul 22, 2026
12 checks passed
@moonming
moonming deleted the feat/readyz-off-admin branch July 22, 2026 05:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant