Skip to content

feat: support upstream health checks in BackendTrafficPolicy#414

Open
AlinsRan wants to merge 8 commits into
masterfrom
feat/backendtrafficpolicy-healthcheck
Open

feat: support upstream health checks in BackendTrafficPolicy#414
AlinsRan wants to merge 8 commits into
masterfrom
feat/backendtrafficpolicy-healthcheck

Conversation

@AlinsRan
Copy link
Copy Markdown
Contributor

@AlinsRan AlinsRan commented May 12, 2026

Summary

Closes #402

  • Add HealthCheck, ActiveHealthCheck, PassiveHealthCheck and related types to api/v1alpha1, independent of the api/v2 types used by ApisixUpstream
  • Add HealthCheck *HealthCheck field to BackendTrafficPolicySpec, enabling Gateway API users to configure active and passive upstream health checks through BackendTrafficPolicy
  • Implement translation from v1alpha1.HealthCheck to ADC UpstreamHealthCheck in attachBackendTrafficPolicyToUpstream
  • Regenerate DeepCopy methods and CRD manifests

Changes

  • api/v1alpha1/backendtrafficpolicy_types.go — new HealthCheck field + 7 new types
  • api/v1alpha1/zz_generated.deepcopy.go — regenerated DeepCopy
  • internal/adc/translator/policies.go — health check translation logic (translateBTPHealthCheck, translateBTPActiveHealthCheck, translateBTPPassiveHealthCheck)
  • internal/adc/translator/httproute_test.go — unit tests for health check translation
  • test/e2e/crds/v1alpha1/backendtrafficpolicy.go — e2e tests for health check lifecycle
  • config/crd/bases/apisix.apache.org_backendtrafficpolicies.yaml — updated CRD schema

Usage Examples

Active health check only

Proactively probe /healthz every second. A node is marked healthy after 2 consecutive 200 responses, unhealthy after 3 consecutive 5xx responses.

apiVersion: apisix.apache.org/v1alpha1
kind: BackendTrafficPolicy
metadata:
  name: my-backend-policy
  namespace: default
spec:
  targetRefs:
  - name: my-service
    kind: Service
    group: ""
  healthCheck:
    active:
      type: http
      httpPath: /healthz
      healthy:
        httpCodes: [200]
        successes: 2
        interval: 1s
      unhealthy:
        httpCodes: [500, 502, 503]
        httpFailures: 3
        interval: 1s

Active and passive health checks

Use active probes for periodic detection, and passive checks to react immediately to failures observed in live traffic.

apiVersion: apisix.apache.org/v1alpha1
kind: BackendTrafficPolicy
metadata:
  name: my-backend-policy
  namespace: default
spec:
  targetRefs:
  - name: my-service
    kind: Service
    group: ""
  healthCheck:
    active:
      type: http
      httpPath: /healthz
      concurrency: 10
      healthy:
        httpCodes: [200]
        successes: 2
        interval: 5s
      unhealthy:
        httpCodes: [500, 502, 503]
        httpFailures: 3
        interval: 2s
    passive:
      type: http
      healthy:
        httpCodes: [200, 201, 204]
        successes: 3
      unhealthy:
        httpCodes: [500, 502, 503]
        httpFailures: 5
        tcpFailures: 2

HTTPS backend with strict TLS

For HTTPS upstream backends, enable strict TLS certificate validation on health check probes.

apiVersion: apisix.apache.org/v1alpha1
kind: BackendTrafficPolicy
metadata:
  name: my-backend-policy
  namespace: default
spec:
  targetRefs:
  - name: my-service
    kind: Service
    group: ""
  scheme: https
  healthCheck:
    active:
      type: https
      httpPath: /health
      strictTLS: true
      healthy:
        httpCodes: [200]
        interval: 10s
      unhealthy:
        httpCodes: [500, 503]
        httpFailures: 2
        interval: 5s

Test Plan

  • Unit tests: TestAttachBackendTrafficPolicyHealthCheck covers nil, active-only, passive+active, and strictTLS=false cases
  • E2e tests: active-only, active+passive, and policy deletion (health check removed) scenarios
  • go build ./... passes
  • go test ./... (unit tests) passes

Summary by CodeRabbit

  • New Features

    • Add upstream backend health checks: active probes and passive traffic-based monitoring with configurable thresholds, intervals, HTTP codes and failure counters
  • Documentation

    • API reference updated to document health-check configuration for BackendTrafficPolicy
  • Tests

    • New unit and end-to-end tests validating health-check behavior and removal on policy deletion

Review Change Stack

Copilot AI review requested due to automatic review settings May 12, 2026 00:55
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ae8bedf1-08e5-44f1-b140-f7716b25c7ac

📥 Commits

Reviewing files that changed from the base of the PR and between 84c72fd and ead701c.

📒 Files selected for processing (1)
  • test/e2e/crds/v1alpha1/backendtrafficpolicy.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/e2e/crds/v1alpha1/backendtrafficpolicy.go

📝 Walkthrough

Walkthrough

This PR extends BackendTrafficPolicy with upstream health check capabilities by adding API types (active/passive checks and thresholds), updating the CRD schema, generating deepcopy methods, translating policy fields into ADC upstream checks, adding unit and e2e tests, and updating docs.

Changes

Upstream Health Check Support for BackendTrafficPolicy

Layer / File(s) Summary
API Type Definitions
api/v1alpha1/backendtrafficpolicy_types.go
BackendTrafficPolicySpec gains optional HealthCheck field. New types define active/passive health check configurations with probe settings (type, timeout, concurrency, host, port, path, headers, TLS), and threshold structures for healthy/unhealthy state transitions (intervals, success/failure counts, HTTP codes, TCP failures, timeouts).
CRD Schema Validation
config/crd/bases/apisix.apache.org_backendtrafficpolicies.yaml
spec.healthCheck schema added with active (required) and passive (optional) objects. Active probe defines concurrency, host/port/path, request headers, strict TLS, timeout, and type. Both modes specify healthy/unhealthy thresholds with HTTP codes, success/failure counters, TCP failures, and timeouts.
Generated Deep Copy Methods
api/v1alpha1/zz_generated.deepcopy.go
DeepCopyInto and DeepCopy methods generated for HealthCheck, ActiveHealthCheck, PassiveHealthCheck, and threshold types. BackendTrafficPolicySpec updated to deep-copy the new HealthCheck pointer field with proper nested struct and slice handling.
Health Check Translator
internal/adc/translator/policies.go
attachBackendTrafficPolicyToUpstream populates upstream.Checks when health check is configured. Helper functions translateBTPHealthCheck, translateBTPActiveHealthCheck, and translateBTPPassiveHealthCheck map policy config to adctypes.UpstreamHealthCheck, defaulting check type to "http" and converting durations, headers, and TLS behavior.
Unit Tests
internal/adc/translator/httproute_test.go
New TestAttachBackendTrafficPolicyHealthCheck validates health check attachment with test cases for nil checks, full active configuration with strict TLS and headers, strictTLS=false override, and combined active+passive checks; asserts upstream.Checks population matches expected structures.
E2E Tests
test/e2e/crds/v1alpha1/backendtrafficpolicy.go
Adds shared gateway setup helper and health-check e2e tests that apply policies, send traffic to register upstreams, assert dataplane upstream health-check configuration, and verify removal after policy deletion.

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • Baoyuantop
🚥 Pre-merge checks | ✅ 5 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
E2e Test Quality Review ⚠️ Warning Test coverage gaps: Missing boundary case test for interval clamping (< 1s), no invalid input testing, no error handling verification in unit tests. Add unit test for interval < 1s clamping. Add E2E tests for policy updates, invalid values, error paths, and interaction with other BackendTrafficPolicy fields.
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the primary change: adding upstream health check support to BackendTrafficPolicy, which aligns perfectly with the changeset.
Linked Issues check ✅ Passed The PR successfully implements all coding requirements from issue #402: adds health check API types, translation logic for active/passive checks, deepcopy methods, CRD schema updates, and comprehensive test coverage.
Out of Scope Changes check ✅ Passed All changes are directly scoped to health check support in BackendTrafficPolicy: new API types, translation logic, generated deepcopy methods, CRD schema, tests, and documentation updates are all aligned with the stated objectives.
Security Check ✅ Passed All 7 security categories reviewed. No vulnerabilities: no sensitive logs, DB ops, auth bypass, resource access issues, TLS errors, resource conflicts, or unresolved secrets.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/backendtrafficpolicy-healthcheck

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

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds upstream health check configuration support to BackendTrafficPolicy (v1alpha1) so Gateway API users can configure APISIX active/passive upstream health checks through policy attachment during translation to ADC upstreams.

Changes:

  • Introduces HealthCheck (active/passive) types and a HealthCheck field on BackendTrafficPolicySpec (v1alpha1).
  • Adds translation logic to map v1alpha1.HealthCheck into ADC UpstreamHealthCheck when attaching BackendTrafficPolicy to an upstream.
  • Adds unit coverage for health check translation and updates generated DeepCopy + CRD schema.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
internal/adc/translator/policies.go Adds BTP → ADC upstream health check translation and attaches it to upstreams.
internal/adc/translator/httproute_test.go Adds unit tests for BTP health check translation (active/passive + strictTLS).
api/v1alpha1/backendtrafficpolicy_types.go Adds new v1alpha1 health check API types and spec.healthCheck.
api/v1alpha1/zz_generated.deepcopy.go Regenerates DeepCopy methods for the new v1alpha1 types.
config/crd/bases/apisix.apache.org_backendtrafficpolicies.yaml Updates CRD OpenAPI schema for the new healthCheck fields.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/adc/translator/policies.go
Comment thread api/v1alpha1/backendtrafficpolicy_types.go
Comment thread config/crd/bases/apisix.apache.org_backendtrafficpolicies.yaml
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

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 `@api/v1alpha1/backendtrafficpolicy_types.go`:
- Line 265: The struct field Timeouts in backendtrafficpolicy_types.go has a
mismatched JSON tag (json:"timeout,omitempty"); change the tag to
json:"timeouts,omitempty" so the field and serialized name align (i.e., keep the
field name Timeouts and update its tag), then run code generation to update CRD
manifests and deepcopy code (make generate).
🪄 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: 23738847-ed1e-4850-8bbe-9e4f44fa97ac

📥 Commits

Reviewing files that changed from the base of the PR and between 0283a04 and 8550ca0.

📒 Files selected for processing (5)
  • api/v1alpha1/backendtrafficpolicy_types.go
  • api/v1alpha1/zz_generated.deepcopy.go
  • config/crd/bases/apisix.apache.org_backendtrafficpolicies.yaml
  • internal/adc/translator/httproute_test.go
  • internal/adc/translator/policies.go

Comment thread api/v1alpha1/backendtrafficpolicy_types.go Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
test/e2e/crds/v1alpha1/backendtrafficpolicy.go (1)

66-76: ⚡ Quick win

Replace fixed sleeps with condition-based waiting.

The hard-coded time.Sleep calls make these e2e specs slow and flaky under variable reconciliation timing. Prefer polling assertions with bounded timeout/interval until the expected state is observed.

Also applies to: 235-236, 271-272, 310-311, 327-327

🤖 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 `@test/e2e/crds/v1alpha1/backendtrafficpolicy.go` around lines 66 - 76, Replace
the fixed time.Sleep calls after resource creation with condition-based polling:
after calling s.CreateResourceFromString(...) for the GatewayClass (using
s.GetGatewayClassYaml()) and for the Gateway (using s.GetGatewayYaml()), remove
the time.Sleep(5 * time.Second) and instead wait until the created resource
reaches the expected reconciliation state using a polling assertion (e.g.,
Eventually/Wait with a bounded timeout/interval) that checks the resource
readiness/observed status via the test harness helper (or implement a small
s.WaitForResourceCondition/Get and assert the expected condition); apply the
same replacement for the other occurrences noted (around lines 235-236, 271-272,
310-311, 327) so tests poll for the actual ready state instead of sleeping.
🤖 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 `@test/e2e/crds/v1alpha1/backendtrafficpolicy.go`:
- Around line 241-247: The loop picks the first upstream with Checks != nil
(using ups and target of type adctypes.Upstream) which may be for a different
backend; change the selection to find the upstream that belongs to the
deterministic backend (e.g. match the upstream identity to
"httpbin-service-e2e-test" by checking the upstream’s owner/target/service name
field) and only set/assert against that matching upstream (target). Apply the
same scoped match (instead of the any-upstream check) in the other two test
locations mentioned so each assertion operates on the upstream that actually
belongs to the intended backend.

---

Nitpick comments:
In `@test/e2e/crds/v1alpha1/backendtrafficpolicy.go`:
- Around line 66-76: Replace the fixed time.Sleep calls after resource creation
with condition-based polling: after calling s.CreateResourceFromString(...) for
the GatewayClass (using s.GetGatewayClassYaml()) and for the Gateway (using
s.GetGatewayYaml()), remove the time.Sleep(5 * time.Second) and instead wait
until the created resource reaches the expected reconciliation state using a
polling assertion (e.g., Eventually/Wait with a bounded timeout/interval) that
checks the resource readiness/observed status via the test harness helper (or
implement a small s.WaitForResourceCondition/Get and assert the expected
condition); apply the same replacement for the other occurrences noted (around
lines 235-236, 271-272, 310-311, 327) so tests poll for the actual ready state
instead of sleeping.
🪄 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: 629a0dc7-9c53-4fd7-be46-500a27672a13

📥 Commits

Reviewing files that changed from the base of the PR and between 8550ca0 and 752ff61.

📒 Files selected for processing (1)
  • test/e2e/crds/v1alpha1/backendtrafficpolicy.go

Comment thread test/e2e/crds/v1alpha1/backendtrafficpolicy.go
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 12, 2026

conformance test report - apisix mode

apiVersion: gateway.networking.k8s.io/v1
date: "2026-05-12T21:45:44Z"
gatewayAPIChannel: experimental
gatewayAPIVersion: v1.3.0
implementation:
  contact: null
  organization: APISIX
  project: apisix-ingress-controller
  url: https://github.com/apache/apisix-ingress-controller.git
  version: v2.0.0
kind: ConformanceReport
mode: default
profiles:
- core:
    result: success
    statistics:
      Failed: 0
      Passed: 12
      Skipped: 0
  name: GATEWAY-GRPC
  summary: Core tests succeeded.
- core:
    failedTests:
    - HTTPRouteInvalidBackendRefUnknownKind
    result: failure
    skippedTests:
    - HTTPRouteHTTPSListener
    statistics:
      Failed: 1
      Passed: 31
      Skipped: 1
  extended:
    result: partial
    skippedTests:
    - HTTPRouteRedirectPortAndScheme
    statistics:
      Failed: 0
      Passed: 11
      Skipped: 1
    supportedFeatures:
    - GatewayAddressEmpty
    - GatewayPort8080
    - HTTPRouteBackendProtocolWebSocket
    - HTTPRouteDestinationPortMatching
    - HTTPRouteHostRewrite
    - HTTPRouteMethodMatching
    - HTTPRoutePathRewrite
    - HTTPRoutePortRedirect
    - HTTPRouteQueryParamMatching
    - HTTPRouteRequestMirror
    - HTTPRouteResponseHeaderModification
    - HTTPRouteSchemeRedirect
    unsupportedFeatures:
    - GatewayHTTPListenerIsolation
    - GatewayInfrastructurePropagation
    - GatewayStaticAddresses
    - HTTPRouteBackendProtocolH2C
    - HTTPRouteBackendRequestHeaderModification
    - HTTPRouteBackendTimeout
    - HTTPRouteParentRefPort
    - HTTPRoutePathRedirect
    - HTTPRouteRequestMultipleMirrors
    - HTTPRouteRequestPercentageMirror
    - HTTPRouteRequestTimeout
  name: GATEWAY-HTTP
  summary: Core tests failed with 1 test failures. Extended tests partially succeeded
    with 1 test skips.
- core:
    result: partial
    skippedTests:
    - TLSRouteSimpleSameNamespace
    statistics:
      Failed: 0
      Passed: 10
      Skipped: 1
  name: GATEWAY-TLS
  summary: Core tests partially succeeded with 1 test skips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 12, 2026

conformance test report - apisix-standalone mode

apiVersion: gateway.networking.k8s.io/v1
date: "2026-05-12T21:46:40Z"
gatewayAPIChannel: experimental
gatewayAPIVersion: v1.3.0
implementation:
  contact: null
  organization: APISIX
  project: apisix-ingress-controller
  url: https://github.com/apache/apisix-ingress-controller.git
  version: v2.0.0
kind: ConformanceReport
mode: default
profiles:
- core:
    result: success
    statistics:
      Failed: 0
      Passed: 12
      Skipped: 0
  name: GATEWAY-GRPC
  summary: Core tests succeeded.
- core:
    failedTests:
    - HTTPRouteMatchingAcrossRoutes
    result: failure
    skippedTests:
    - HTTPRouteHTTPSListener
    statistics:
      Failed: 1
      Passed: 31
      Skipped: 1
  extended:
    result: partial
    skippedTests:
    - HTTPRouteRedirectPortAndScheme
    statistics:
      Failed: 0
      Passed: 11
      Skipped: 1
    supportedFeatures:
    - GatewayAddressEmpty
    - GatewayPort8080
    - HTTPRouteBackendProtocolWebSocket
    - HTTPRouteDestinationPortMatching
    - HTTPRouteHostRewrite
    - HTTPRouteMethodMatching
    - HTTPRoutePathRewrite
    - HTTPRoutePortRedirect
    - HTTPRouteQueryParamMatching
    - HTTPRouteRequestMirror
    - HTTPRouteResponseHeaderModification
    - HTTPRouteSchemeRedirect
    unsupportedFeatures:
    - GatewayHTTPListenerIsolation
    - GatewayInfrastructurePropagation
    - GatewayStaticAddresses
    - HTTPRouteBackendProtocolH2C
    - HTTPRouteBackendRequestHeaderModification
    - HTTPRouteBackendTimeout
    - HTTPRouteParentRefPort
    - HTTPRoutePathRedirect
    - HTTPRouteRequestMultipleMirrors
    - HTTPRouteRequestPercentageMirror
    - HTTPRouteRequestTimeout
  name: GATEWAY-HTTP
  summary: Core tests failed with 1 test failures. Extended tests partially succeeded
    with 1 test skips.
- core:
    result: partial
    skippedTests:
    - TLSRouteSimpleSameNamespace
    statistics:
      Failed: 0
      Passed: 10
      Skipped: 1
  name: GATEWAY-TLS
  summary: Core tests partially succeeded with 1 test skips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 12, 2026

conformance test report

apiVersion: gateway.networking.k8s.io/v1
date: "2026-05-12T22:06:17Z"
gatewayAPIChannel: experimental
gatewayAPIVersion: v1.3.0
implementation:
  contact: null
  organization: APISIX
  project: apisix-ingress-controller
  url: https://github.com/apache/apisix-ingress-controller.git
  version: v2.0.0
kind: ConformanceReport
mode: default
profiles:
- core:
    failedTests:
    - GatewayModifyListeners
    result: failure
    skippedTests:
    - HTTPRouteHTTPSListener
    statistics:
      Failed: 1
      Passed: 31
      Skipped: 1
  extended:
    failedTests:
    - HTTPRouteBackendProtocolWebSocket
    result: failure
    skippedTests:
    - HTTPRouteRedirectPortAndScheme
    statistics:
      Failed: 1
      Passed: 10
      Skipped: 1
    supportedFeatures:
    - GatewayAddressEmpty
    - GatewayPort8080
    - HTTPRouteBackendProtocolWebSocket
    - HTTPRouteDestinationPortMatching
    - HTTPRouteHostRewrite
    - HTTPRouteMethodMatching
    - HTTPRoutePathRewrite
    - HTTPRoutePortRedirect
    - HTTPRouteQueryParamMatching
    - HTTPRouteRequestMirror
    - HTTPRouteResponseHeaderModification
    - HTTPRouteSchemeRedirect
    unsupportedFeatures:
    - GatewayHTTPListenerIsolation
    - GatewayInfrastructurePropagation
    - GatewayStaticAddresses
    - HTTPRouteBackendProtocolH2C
    - HTTPRouteBackendRequestHeaderModification
    - HTTPRouteBackendTimeout
    - HTTPRouteParentRefPort
    - HTTPRoutePathRedirect
    - HTTPRouteRequestMultipleMirrors
    - HTTPRouteRequestPercentageMirror
    - HTTPRouteRequestTimeout
  name: GATEWAY-HTTP
  summary: Core tests failed with 1 test failures. Extended tests failed with 1 test
    failures.
- core:
    failedTests:
    - GatewayModifyListeners
    - TLSRouteSimpleSameNamespace
    result: failure
    statistics:
      Failed: 2
      Passed: 9
      Skipped: 0
  name: GATEWAY-TLS
  summary: Core tests failed with 2 test failures.
- core:
    failedTests:
    - GRPCExactMethodMatching
    - GRPCRouteHeaderMatching
    - GRPCRouteListenerHostnameMatching
    - GatewayModifyListeners
    result: failure
    statistics:
      Failed: 4
      Passed: 8
      Skipped: 0
  name: GATEWAY-GRPC
  summary: Core tests failed with 4 test failures.

AlinsRan and others added 2 commits May 13, 2026 04:48
- Fix Timeouts field JSON tag: timeout -> timeouts to match ADC type
- Enforce minimum 1s interval in translateBTPActiveHealthCheck to prevent
  sub-second values from truncating to 0 (matching v2/apisixupstream behavior)
- Scope e2e upstream assertions to httpbin-service-e2e-test by name
- Regenerate CRD manifests and API reference docs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 12, 2026 20:48
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

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 `@test/e2e/crds/v1alpha1/backendtrafficpolicy.go`:
- Around line 331-337: The test currently loops over ups returned by
s.DefaultDataplaneResource().Upstream().List and asserts checks are nil only for
matching names, but if no upstream matches the assertion is never executed; add
a sentinel (e.g., found or matchCount) initialized before the loop, set it
true/increment when strings.Contains(u.Name, "httpbin-service-e2e-test") and
still run Expect(u.Checks).To(BeNil()) inside that branch, then after the loop
add Expect(found).To(BeTrue(), "expected at least one upstream matching
'httpbin-service-e2e-test' to validate deletion") so the test fails when the
target upstream is missing.
🪄 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: 203c29f9-428b-4867-b084-cba98b03feb6

📥 Commits

Reviewing files that changed from the base of the PR and between 752ff61 and 84c72fd.

📒 Files selected for processing (5)
  • api/v1alpha1/backendtrafficpolicy_types.go
  • config/crd/bases/apisix.apache.org_backendtrafficpolicies.yaml
  • docs/en/latest/reference/api-reference.md
  • internal/adc/translator/policies.go
  • test/e2e/crds/v1alpha1/backendtrafficpolicy.go
✅ Files skipped from review due to trivial changes (1)
  • docs/en/latest/reference/api-reference.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • internal/adc/translator/policies.go
  • config/crd/bases/apisix.apache.org_backendtrafficpolicies.yaml

Comment on lines +331 to +337
ups, err = s.DefaultDataplaneResource().Upstream().List(context.Background())
Expect(err).ToNot(HaveOccurred())
for _, u := range ups {
if strings.Contains(u.Name, "httpbin-service-e2e-test") {
Expect(u.Checks).To(BeNil(), "upstream should not have health check after policy deletion")
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Ensure the deletion assertion fails when target upstream is missing.

Right now, if no upstream name matches, the loop body never runs and the test can pass without validating post-delete state.

Proposed fix
 			ups, err = s.DefaultDataplaneResource().Upstream().List(context.Background())
 			Expect(err).ToNot(HaveOccurred())
+			foundTarget := false
 			for _, u := range ups {
 				if strings.Contains(u.Name, "httpbin-service-e2e-test") {
+					foundTarget = true
 					Expect(u.Checks).To(BeNil(), "upstream should not have health check after policy deletion")
 				}
 			}
+			Expect(foundTarget).To(BeTrue(), "target upstream should exist after policy deletion")
📝 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
ups, err = s.DefaultDataplaneResource().Upstream().List(context.Background())
Expect(err).ToNot(HaveOccurred())
for _, u := range ups {
if strings.Contains(u.Name, "httpbin-service-e2e-test") {
Expect(u.Checks).To(BeNil(), "upstream should not have health check after policy deletion")
}
}
ups, err = s.DefaultDataplaneResource().Upstream().List(context.Background())
Expect(err).ToNot(HaveOccurred())
foundTarget := false
for _, u := range ups {
if strings.Contains(u.Name, "httpbin-service-e2e-test") {
foundTarget = true
Expect(u.Checks).To(BeNil(), "upstream should not have health check after policy deletion")
}
}
Expect(foundTarget).To(BeTrue(), "target upstream should exist after policy deletion")
🤖 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 `@test/e2e/crds/v1alpha1/backendtrafficpolicy.go` around lines 331 - 337, The
test currently loops over ups returned by
s.DefaultDataplaneResource().Upstream().List and asserts checks are nil only for
matching names, but if no upstream matches the assertion is never executed; add
a sentinel (e.g., found or matchCount) initialized before the loop, set it
true/increment when strings.Contains(u.Name, "httpbin-service-e2e-test") and
still run Expect(u.Checks).To(BeNil()) inside that branch, then after the loop
add Expect(found).To(BeTrue(), "expected at least one upstream matching
'httpbin-service-e2e-test' to validate deletion") so the test fails when the
target upstream is missing.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 7 changed files in this pull request and generated 3 comments.

Files not reviewed (1)
  • api/v1alpha1/zz_generated.deepcopy.go: Language not supported
Comments suppressed due to low confidence (1)

api/v1alpha1/backendtrafficpolicy_types.go:216

  • The interval fields accept any Duration, but translation rounds down to whole seconds and coerces anything < 1s up to 1s. Consider adding CRD validation to constrain intervals to whole seconds and enforce the documented minimum (1s) to avoid surprising truncation/coercion (apply to both healthy and unhealthy intervals).
	// Interval defines the time between health check probes.
	// Minimum is 1s.
	Interval metav1.Duration `json:"interval,omitempty" yaml:"interval,omitempty"`

Comment on lines 28 to +31
"github.com/apache/apisix-ingress-controller/api/v1alpha1"
)

const _minHealthCheckInterval = time.Second
// +optional
Type string `json:"type,omitempty" yaml:"type,omitempty"`

// Timeout sets health check timeout.
Comment on lines +121 to +125
interval := config.Healthy.Interval.Duration
if interval < _minHealthCheckInterval {
interval = _minHealthCheckInterval
}
active.Healthy = adctypes.UpstreamActiveHealthCheckHealthy{
Upstream Name is cleared when embedded in a service object
(httproute translator sets Name="" for single-backend upstreams).
Filtering by name always fails; rely on Checks field instead.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

enhancement: support upstream health checks in BackendTrafficPolicy

2 participants