Skip to content

feat(conformance): Add EPP conformance test for Gateway routing #961

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

Open
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

zetxqx
Copy link
Contributor

@zetxqx zetxqx commented Jun 11, 2025

This pull request introduces a new conformance test, GatewayFollowingEPPRouting, to validate that a Gateway correctly implements routing logic based on an EPP.

The new test suite ensures that the Gateway honors the EPP's endpoint selection. We used the testing-epp to control the EPP behavior using request header. The two test cases are

  1. request header:[pod1IP, pod2IP, pod3IP]: EPP returns pod1IP, pod2IP, pod3IP, gateway should select the first one pod1IP and send traffic to
  2. request header:[pod3IP, pod2IP, pod1IP] EPP returns ppod3IP, pod2IP, pod1IP, gateway should select the first one pod3IP and send traffic to

Verification

The new conformance test was run against the gke-l7-regional-external-managed GatewayClass and passed successfully.

against gke-l7

Test command

go test -v ./conformance -args -debug \
  -gateway-class gke-l7-regional-external-managed \
  -cleanup-base-resources=false \
  -run-test GatwayFollowingEPPRouting

Test results

=== RUN   TestConformance/HTTPRouteInvalidInferencePoolRef
    conformance.go:68: Skipping HTTPRouteInvalidInferencePoolRef: test explicitly skipped
=== RUN   TestConformance/InferencePoolAccepted
    conformance.go:68: Skipping InferencePoolAccepted: test explicitly skipped
=== RUN   TestConformance/InferencePoolResolvedRefsCondition
    conformance.go:68: Skipping InferencePoolResolvedRefsCondition: test explicitly skipped
--- PASS: TestConformance (53.87s)
    --- PASS: TestConformance/GatewayFollowingEPPRouting (51.41s)
        --- PASS: TestConformance/GatewayFollowingEPPRouting/should_route_traffic_to_a_single_designated_pod (0.08s)
        --- PASS: TestConformance/GatewayFollowingEPPRouting/should_route_traffic_to_two_designated_pods (0.09s)
        --- PASS: TestConformance/GatewayFollowingEPPRouting/should_route_traffic_to_all_available_pods (0.10s)
    --- SKIP: TestConformance/HTTPRouteInvalidInferencePoolRef (0.00s)
    --- SKIP: TestConformance/InferencePoolAccepted (0.00s)
    --- SKIP: TestConformance/InferencePoolResolvedRefsCondition (0.00s)
PASS
ok  	sigs.k8s.io/gateway-api-inference-extension/conformance	54.054s

against istio (FAILED)

The istio implementation may still send traffic to pods not selected by EPP.

go test -v ./conformance -args -debug -gateway-class istio -cleanup-base-resources=false -run-test GatewayFollowingEPPRouting

Test results

error log: gateway_following_epp_routing.go:144: Not all the requests are sent to the expectedPods successfully, err: request was handled by an unexpected pod "infra-backend-deployment-678ff64fb-txms2", Reached pods with request counts: map[infra-backend-deployment-678ff64fb-tnlhd:30 infra-backend-deployment-678ff64fb-txms2:32 infra-backend-deployment-678ff64fb-zjwk2:38]

=== RUN   TestConformance/HTTPRouteInvalidInferencePoolRef
    conformance.go:68: Skipping HTTPRouteInvalidInferencePoolRef: test explicitly skipped
=== RUN   TestConformance/InferencePoolAccepted
    conformance.go:68: Skipping InferencePoolAccepted: test explicitly skipped
=== RUN   TestConformance/InferencePoolResolvedRefsCondition
    conformance.go:68: Skipping InferencePoolResolvedRefsCondition: test explicitly skipped
--- FAIL: TestConformance (139.98s)
    --- FAIL: TestConformance/GatewayFollowingEPPRouting (137.31s)
        --- FAIL: TestConformance/GatewayFollowingEPPRouting/should_route_traffic_to_a_single_designated_pod (0.05s)
        --- FAIL: TestConformance/GatewayFollowingEPPRouting/should_route_traffic_to_two_designated_pods (0.05s)
        --- PASS: TestConformance/GatewayFollowingEPPRouting/should_route_traffic_to_all_available_pods (0.05s)
    --- SKIP: TestConformance/HTTPRouteInvalidInferencePoolRef (0.00s)
    --- SKIP: TestConformance/InferencePoolAccepted (0.00s)
    --- SKIP: TestConformance/InferencePoolResolvedRefsCondition (0.00s)
FAIL
FAIL	sigs.k8s.io/gateway-api-inference-extension/conformance	140.176s
FAIL

TODO(all done now)

  1. (Done) Currently the Mock EPP can only accept one endpoint from the request header, I need to add multi-endpoints support to test the case when EPP return multiple endpoints. Extending feat(Conformance): Add a header based filter to make a controllable epp behavior determined by request header. #922
  2. (Done) Need to refactor the test utils. The library our conformance test is depending on need some modification. Currently the library can only make request w/o body. I try to make some minimum change to make this PR.
  3. (Done) Need to figure out a poll and check way to make sure the whole stack is ready to server request.

Copy link

netlify bot commented Jun 11, 2025

Deploy Preview for gateway-api-inference-extension ready!

Name Link
🔨 Latest commit be9c779
🔍 Latest deploy log https://app.netlify.com/projects/gateway-api-inference-extension/deploys/6852d53b6e6ca700088914d8
😎 Deploy Preview https://deploy-preview-961--gateway-api-inference-extension.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Jun 11, 2025
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: zetxqx
Once this PR has been reviewed and has the lgtm label, please assign sergeykanzhelev for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot requested review from ahg-g and danehans June 11, 2025 03:58
@k8s-ci-robot k8s-ci-robot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Jun 11, 2025
@k8s-ci-robot
Copy link
Contributor

Hi @zetxqx. Thanks for your PR.

I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@k8s-ci-robot k8s-ci-robot added the size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label Jun 11, 2025
Copy link
Member

@robscott robscott left a comment

Choose a reason for hiding this comment

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

Thanks @zetxqx!

@zetxqx zetxqx requested a review from robscott June 11, 2025 22:54
@zetxqx zetxqx mentioned this pull request Jun 12, 2025
12 tasks
Copy link
Member

@robscott robscott left a comment

Choose a reason for hiding this comment

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

Thanks for all the work on this @zetxqx!

@robscott
Copy link
Member

/ok-to-test

@k8s-ci-robot k8s-ci-robot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Jun 13, 2025
@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Jun 13, 2025
@zetxqx
Copy link
Contributor Author

zetxqx commented Jun 13, 2025

/retest

@zetxqx zetxqx requested a review from robscott June 13, 2025 23:33
Copy link
Member

@robscott robscott left a comment

Choose a reason for hiding this comment

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

Thanks @zetxqx! This is looking pretty close

Comment on lines 51 to 62
# --- Backend Service ---
# Service for the infra-backend-deployment.
apiVersion: inference.networking.x-k8s.io/v1alpha2
kind: InferenceModel
metadata:
name: conformance-fake-model-server
namespace: gateway-conformance-app-backend
spec:
modelName: conformance-fake-model
criticality: Critical # Mark it as critical to bypass the saturation check since the model server is fake and don't have such metrics.
poolRef:
name: normal-gateway-pool
Copy link
Member

Choose a reason for hiding this comment

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

This isn't a Service + I don't think we need it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Rename the comment.

"I don't think we need it"
I think we still need the InferenceModel to direct the traffic to the correct POD hosting the model.

Copy link
Member

Choose a reason for hiding this comment

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

I didn't think we're testing EPP behavior? Instead I thought that every request would tell EPP which Pod IP(s) to return, and then our test would validate EPP behavior.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right about the test's intent. The need for the InferenceModel is an implementation detail of the testingEPP.

Even though we control the final endpoint list with request headers, the testingEPP still requires the InferenceModel resource to:

  1. Discover the initial list of all possible pods from the referenced InferencePoo. The requestHeadBased filter(testingEPP used) then selects from this list.
  2. Identify the modelName it is serving

So, while the test logic focuses on the gateway's reaction to the EPP's output, the testingEPP itself still needs the InferenceModel to know the universe of possible backends and the model being served

Copy link
Member

Choose a reason for hiding this comment

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

Can we modify EPP so it doesn't need InferenceModel when running in this context?

cc @ahg-g @kfswain

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's a little hard and needs more refactoring because currently the Pod lists is from the datastore(https://github.com/kubernetes-sigs/gateway-api-inference-extension/blob/main/pkg/epp/scheduling/scheduler.go#L108). And it's getting updated from some reconciler logic I believe. Hence there is not a easy way we can pass in a input parameters to EPP as what we did for custom filter.

Also, currently the EPP request control flow tries to find a inferenceModel(https://github.com/kubernetes-sigs/gateway-api-inference-extension/blob/main/pkg/epp/requestcontrol/director.go#L94-L97), so w/o inferenceModel the EPP will always return error.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, we can do that. @zetxqx will you cut an issue and assign it to me? Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks both,

@k8s-ci-robot k8s-ci-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jun 16, 2025
@zetxqx zetxqx requested a review from robscott June 16, 2025 07:04
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants