Skip to content

Commit f1ab79f

Browse files
committed
Merge remote-tracking branch 'upstream/main' into inf_pool_tests_11
2 parents daeb8e6 + 191e710 commit f1ab79f

File tree

25 files changed

+868
-201
lines changed

25 files changed

+868
-201
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ test-integration: ## Run integration tests.
137137
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test ./test/integration/epp/... -race -coverprofile cover.out
138138

139139
.PHONY: test-e2e
140-
test-e2e: ## Run end-to-end tests against an existing Kubernetes cluster. When using default configuration, the tests need at least 3 available GPUs.
140+
test-e2e: ## Run end-to-end tests against an existing Kubernetes cluster.
141141
MANIFEST_PATH=$(PROJECT_DIR)/$(E2E_MANIFEST_PATH) ./hack/run-e2es.sh
142142

143143
.PHONY: lint

api/v1alpha2/inferencepool_types.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,18 @@ type EndpointPickerConfig struct {
8080

8181
// Extension specifies how to configure an extension that runs the endpoint picker.
8282
type Extension struct {
83-
// Reference is a reference to a service extension.
83+
// Reference is a reference to a service extension. When ExtensionReference is invalid,
84+
// a 5XX status code MUST be returned for the request that would have otherwise been routed
85+
// to the invalid backend.
8486
ExtensionReference `json:",inline"`
8587

8688
// ExtensionConnection configures the connection between the gateway and the extension.
8789
ExtensionConnection `json:",inline"`
8890
}
8991

90-
// ExtensionReference is a reference to the extension deployment.
92+
// ExtensionReference is a reference to the extension deployment. When ExtensionReference is invalid,
93+
// a 5XX status code MUST be returned for the request that would have otherwise been routed to the
94+
// invalid backend.
9195
type ExtensionReference struct {
9296
// Group is the group of the referent.
9397
// The default value is "", representing the Core API group.

cmd/epp/main.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ package main
1919
import (
2020
"os"
2121

22+
ctrl "sigs.k8s.io/controller-runtime"
23+
2224
"sigs.k8s.io/gateway-api-inference-extension/cmd/epp/runner"
2325
)
2426

2527
func main() {
26-
if err := runner.NewRunner().Run(); err != nil {
28+
if err := runner.NewRunner().Run(ctrl.SetupSignalHandler()); err != nil {
2729
os.Exit(1)
2830
}
2931
}

cmd/epp/runner/runner.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package runner
1818

1919
import (
20+
"context"
2021
"flag"
2122
"fmt"
2223

@@ -92,7 +93,8 @@ var (
9293
logVerbosity = flag.Int("v", logging.DEFAULT, "number for the log level verbosity")
9394
secureServing = flag.Bool(
9495
"secureServing", runserver.DefaultSecureServing, "Enables secure serving. Defaults to true.")
95-
certPath = flag.String(
96+
healthChecking = flag.Bool("healthChecking", runserver.DefaultHealthChecking, "Enables health checking")
97+
certPath = flag.String(
9698
"certPath", "", "The path to the certificate for secure serving. The certificate and private key files "+
9799
"are assumed to be named tls.crt and tls.key, respectively. If not set, and secureServing is enabled, "+
98100
"then a self-signed certificate is used.")
@@ -139,7 +141,7 @@ func (r *Runner) WithSchedulerConfig(schedulerConfig *scheduling.SchedulerConfig
139141
return r
140142
}
141143

142-
func (r *Runner) Run() error {
144+
func (r *Runner) Run(ctx context.Context) error {
143145
opts := zap.Options{
144146
Development: true,
145147
}
@@ -182,7 +184,7 @@ func (r *Runner) Run() error {
182184
}
183185
verifyMetricMapping(*mapping, setupLog)
184186
pmf := backendmetrics.NewPodMetricsFactory(&backendmetrics.PodMetricsClientImpl{MetricMapping: mapping}, *refreshMetricsInterval)
185-
ctx := ctrl.SetupSignalHandler()
187+
186188
datastore := datastore.NewDatastore(ctx, pmf)
187189

188190
// --- Setup Metrics Server ---
@@ -228,6 +230,7 @@ func (r *Runner) Run() error {
228230
PoolNamespacedName: poolNamespacedName,
229231
Datastore: datastore,
230232
SecureServing: *secureServing,
233+
HealthChecking: *healthChecking,
231234
CertPath: *certPath,
232235
RefreshPrometheusMetricsInterval: *refreshPrometheusMetricsInterval,
233236
Director: director,
@@ -318,7 +321,7 @@ func loadPrefixCacheConfig() prefix.Config {
318321
return prefix.Config{
319322
HashBlockSize: envutil.GetEnvInt("PREFIX_CACHE_HASH_BLOCK_SIZE", prefix.DefaultHashBlockSize, baseLogger),
320323
MaxPrefixBlocksToMatch: envutil.GetEnvInt("PREFIX_CACHE_MAX_PREFIX_BLOCKS", prefix.DefaultMaxPrefixBlocks, baseLogger),
321-
LRUIndexerCapacity: envutil.GetEnvInt("PREFIX_CACHE_LRU_CAPACITY", prefix.DefaultLRUIndexerCapacity, baseLogger),
324+
LRUCapacityPerServer: envutil.GetEnvInt("PREFIX_CACHE_LRU_CAPACITY_PER_SERVER", prefix.DefaultLRUCapacityPerServer, baseLogger),
322325
}
323326
}
324327

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package basic
18+
19+
import (
20+
"net/http"
21+
"testing"
22+
23+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24+
"k8s.io/apimachinery/pkg/types"
25+
"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
26+
"sigs.k8s.io/gateway-api/conformance/utils/suite"
27+
"sigs.k8s.io/gateway-api/pkg/features"
28+
29+
"sigs.k8s.io/gateway-api-inference-extension/conformance/tests"
30+
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
31+
conformancehttp "sigs.k8s.io/gateway-api/conformance/utils/http"
32+
)
33+
34+
func init() {
35+
tests.ConformanceTests = append(tests.ConformanceTests, InferencePoolInvalidEPPService)
36+
}
37+
38+
var InferencePoolInvalidEPPService = suite.ConformanceTest{
39+
ShortName: "InferencePoolInvalidEPPService",
40+
Description: "An HTTPRoute that references an InferencePool with a non-existent EPP service should have a ResolvedRefs condition with a status of False and a reason of BackendNotFound.",
41+
Manifests: []string{"tests/basic/inferencepool_invalid_epp_service.yaml"},
42+
Features: []features.FeatureName{
43+
features.SupportGateway,
44+
features.SupportHTTPRoute,
45+
features.FeatureName("SupportInferencePool"),
46+
},
47+
Test: func(t *testing.T, s *suite.ConformanceTestSuite) {
48+
const (
49+
routePath = "/invalid-epp-test"
50+
infraNamespace = "gateway-conformance-infra"
51+
appNamespace = "gateway-conformance-app-backend"
52+
)
53+
54+
routeNN := types.NamespacedName{Name: "httproute-for-invalid-epp-pool", Namespace: appNamespace}
55+
gwNN := types.NamespacedName{Name: "conformance-gateway", Namespace: infraNamespace}
56+
57+
gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, s.Client, s.TimeoutConfig, s.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
58+
59+
t.Run("HTTPRoute has a ResolvedRefs Condition with status False and Reason BackendNotFound", func(t *testing.T) {
60+
resolvedRefsCond := metav1.Condition{
61+
Type: string(gatewayv1.RouteConditionResolvedRefs),
62+
Status: metav1.ConditionFalse,
63+
Reason: string(gatewayv1.RouteReasonBackendNotFound),
64+
}
65+
kubernetes.HTTPRouteMustHaveCondition(t, s.Client, s.TimeoutConfig, routeNN, gwNN, resolvedRefsCond)
66+
})
67+
68+
t.Run("Request to a route with an invalid backend reference receives a 500 response", func(t *testing.T) {
69+
conformancehttp.MakeRequestAndExpectEventuallyConsistentResponse(t, s.RoundTripper, s.TimeoutConfig, gwAddr, conformancehttp.ExpectedResponse{
70+
Request: conformancehttp.Request{
71+
Path: routePath,
72+
},
73+
Response: conformancehttp.Response{
74+
StatusCode: http.StatusInternalServerError,
75+
},
76+
})
77+
})
78+
},
79+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
apiVersion: inference.networking.x-k8s.io/v1alpha2
2+
kind: InferencePool
3+
metadata:
4+
name: pool-with-invalid-epp
5+
namespace: gateway-conformance-app-backend
6+
spec:
7+
selector:
8+
app: "inference-model-1"
9+
targetPortNumber: 3000
10+
extensionRef:
11+
name: non-existent-epp-svc
12+
---
13+
apiVersion: gateway.networking.k8s.io/v1
14+
kind: HTTPRoute
15+
metadata:
16+
name: httproute-for-invalid-epp-pool
17+
namespace: gateway-conformance-app-backend
18+
spec:
19+
parentRefs:
20+
- name: conformance-gateway
21+
namespace: gateway-conformance-infra
22+
rules:
23+
- backendRefs:
24+
- name: pool-with-invalid-epp
25+
kind: InferencePool
26+
group: inference.networking.x-k8s.io
27+
port: 80
28+
matches:
29+
- path:
30+
type: PathPrefix
31+
value: /invalid-epp-test

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ require (
99
github.com/go-logr/logr v1.4.3
1010
github.com/google/go-cmp v0.7.0
1111
github.com/google/uuid v1.6.0
12+
github.com/hashicorp/golang-lru/v2 v2.0.7
1213
github.com/onsi/ginkgo/v2 v2.23.4
1314
github.com/onsi/gomega v1.37.0
1415
github.com/prometheus/client_golang v1.22.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5T
9595
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
9696
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE=
9797
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI=
98+
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
99+
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
98100
github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4=
99101
github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
100102
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=

0 commit comments

Comments
 (0)