-
Notifications
You must be signed in to change notification settings - Fork 1
fix: should not return when service type is ExternalName #203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Signed-off-by: ashing <[email protected]>
There was a problem hiding this 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 addresses a bug where ExternalName services caused the reconciler to exit early, preventing additional backendRefs from being processed, and adds an end-to-end test to verify load balancing across ExternalName services.
- Changed the reconciler to
continue
instead ofreturn
when encounteringServiceTypeExternalName
- Added an E2E test that spins up ExternalName services, a BackendTrafficPolicy, and an HTTPRoute, then validates round-robin behavior
- Defined a
servicesSpec
block in tests to create two ExternalName services and associated HTTPRoute
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
File | Description |
---|---|
test/e2e/gatewayapi/httproute.go | New E2E test for HTTPRoute load balancing with ExternalName types |
internal/controller/httproute_controller.go | Replace return with continue when handling ExternalName services |
Comments suppressed due to low confidence (1)
internal/controller/httproute_controller.go:504
- Add a unit test for
processHTTPRouteBackendRefs
covering theServiceTypeExternalName
path to ensure these services get added totctx.Services
without exiting the loop.
continue
time.Sleep(5 * time.Second) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of a fixed time.Sleep
, use a polling loop or Gomega's Eventually
to wait for the HTTPRoute to become ready. This reduces flakiness and can shorten test run time.
time.Sleep(5 * time.Second) | |
Eventually(func() bool { | |
resp, err := s.NewAPISIXClient().GET("/headers").Expect().Raw() | |
if err != nil { | |
return false | |
} | |
return resp.StatusCode == http.StatusOK | |
}, 30*time.Second, 1*time.Second).Should(BeTrue(), "HTTPRoute should become ready") |
Copilot uses AI. Check for mistakes.
for i := 0; i < totalRequests; i++ { | ||
resp := s.NewAPISIXClient().GET("/headers").Expect().Status(http.StatusOK) | ||
|
||
// Parse JSON response to get the Host header | ||
var responseBody map[string]any | ||
resp.JSON().Decode(&responseBody) | ||
|
||
if headers, ok := responseBody["headers"].(map[string]any); ok { | ||
var host string | ||
if host, ok = headers["Host"].(string); !ok { | ||
host, ok = headers["host"].(string) | ||
} | ||
if ok && host != "" { | ||
upstreamHosts[host]++ | ||
} | ||
Expect(ok).To(BeTrue(), "Host header should be present") | ||
Expect(host).Should(Or(Equal("httpbin.org"), Equal("mock.api7.ai"))) | ||
} | ||
time.Sleep(100 * time.Millisecond) // Small delay between requests | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Avoid fixed delays inside the request loop. If pacing is needed, consider using parallel requests with a timeout or parameterizing the delay to speed up the suite.
for i := 0; i < totalRequests; i++ { | |
resp := s.NewAPISIXClient().GET("/headers").Expect().Status(http.StatusOK) | |
// Parse JSON response to get the Host header | |
var responseBody map[string]any | |
resp.JSON().Decode(&responseBody) | |
if headers, ok := responseBody["headers"].(map[string]any); ok { | |
var host string | |
if host, ok = headers["Host"].(string); !ok { | |
host, ok = headers["host"].(string) | |
} | |
if ok && host != "" { | |
upstreamHosts[host]++ | |
} | |
Expect(ok).To(BeTrue(), "Host header should be present") | |
Expect(host).Should(Or(Equal("httpbin.org"), Equal("mock.api7.ai"))) | |
} | |
time.Sleep(100 * time.Millisecond) // Small delay between requests | |
} | |
var wg sync.WaitGroup | |
var mu sync.Mutex | |
for i := 0; i < totalRequests; i++ { | |
wg.Add(1) | |
go func() { | |
defer wg.Done() | |
resp := s.NewAPISIXClient().GET("/headers").Expect().Status(http.StatusOK) | |
// Parse JSON response to get the Host header | |
var responseBody map[string]any | |
resp.JSON().Decode(&responseBody) | |
if headers, ok := responseBody["headers"].(map[string]any); ok { | |
var host string | |
if host, ok = headers["Host"].(string); !ok { | |
host, ok = headers["host"].(string) | |
} | |
if ok && host != "" { | |
mu.Lock() | |
upstreamHosts[host]++ | |
mu.Unlock() | |
} | |
Expect(ok).To(BeTrue(), "Host header should be present") | |
Expect(host).Should(Or(Equal("httpbin.org"), Equal("mock.api7.ai"))) | |
} | |
}() | |
} | |
wg.Wait() |
Copilot uses AI. Check for mistakes.
conformance test report - apisix-standalone modeapiVersion: gateway.networking.k8s.io/v1
date: "2025-07-16T12:04:16Z"
gatewayAPIChannel: standard
gatewayAPIVersion: v1.2.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:
- HTTPRouteCrossNamespace
result: failure
skippedTests:
- HTTPRouteHTTPSListener
statistics:
Failed: 1
Passed: 31
Skipped: 1
name: GATEWAY-HTTP
summary: Core tests failed with 1 test failures. |
conformance test report - apisix modeapiVersion: gateway.networking.k8s.io/v1
date: "2025-07-16T12:04:34Z"
gatewayAPIChannel: standard
gatewayAPIVersion: v1.2.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:
- HTTPRouteCrossNamespace
result: failure
skippedTests:
- HTTPRouteHTTPSListener
statistics:
Failed: 1
Passed: 31
Skipped: 1
name: GATEWAY-HTTP
summary: Core tests failed with 1 test failures. |
conformance test reportapiVersion: gateway.networking.k8s.io/v1
date: "2025-07-16T10:19:06Z"
gatewayAPIChannel: standard
gatewayAPIVersion: v1.2.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: partial
skippedTests:
- HTTPRouteHTTPSListener
statistics:
Failed: 0
Passed: 32
Skipped: 1
name: GATEWAY-HTTP
summary: Core tests partially succeeded with 1 test skips. |
Type of change:
What this PR does / why we need it:
ref: apache/apisix-ingress-controller#2468
Pre-submission checklist: