@@ -18,6 +18,9 @@ import (
1818 gwv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
1919 gwv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
2020
21+ "github.com/stretchr/testify/assert"
22+ "github.com/stretchr/testify/require"
23+
2124 extensionsplug "github.com/kgateway-dev/kgateway/v2/internal/kgateway/extensions2/plugin"
2225 "github.com/kgateway-dev/kgateway/v2/internal/kgateway/ir"
2326 "github.com/kgateway-dev/kgateway/v2/internal/kgateway/utils/krtutil"
@@ -326,6 +329,92 @@ func TestFailInferencePoolWithRefGrantWrongKind(t *testing.T) {
326329 }
327330}
328331
332+ func TestInferencePoolPortOverride (t * testing.T ) {
333+ cases := []struct {
334+ name string
335+ poolNs string
336+ refGrant * gwv1beta1.ReferenceGrant
337+ providedPort gwv1.PortNumber
338+ wantPort int32
339+ expectError bool
340+ }{
341+ {
342+ name : "same‐ns override" ,
343+ poolNs : "" ,
344+ refGrant : nil ,
345+ providedPort : 9001 ,
346+ wantPort : 8080 ,
347+ },
348+ {
349+ name : "cross‐ns override with RefGrant" ,
350+ poolNs : "foo-ns" ,
351+ refGrant : refGrantWithNs ("foo-ns" ),
352+ providedPort : 9999 ,
353+ wantPort : 8080 ,
354+ },
355+ }
356+
357+ for _ , tc := range cases {
358+ t .Run (tc .name , func (t * testing.T ) {
359+ inputs := []any {
360+ infPool (tc .poolNs ),
361+ }
362+ if tc .refGrant != nil {
363+ inputs = append (inputs , tc .refGrant )
364+ }
365+ // Build an HTTPRoute whose HTTPBackendRef.Port is “wrong”
366+ ns := ""
367+ if tc .poolNs != "" {
368+ ns = tc .poolNs
369+ }
370+ route := & gwv1.HTTPRoute {
371+ ObjectMeta : metav1.ObjectMeta {
372+ Name : "httproute" ,
373+ Namespace : "default" ,
374+ },
375+ Spec : gwv1.HTTPRouteSpec {
376+ Rules : []gwv1.HTTPRouteRule {{
377+ BackendRefs : []gwv1.HTTPBackendRef {{
378+ BackendRef : gwv1.BackendRef {
379+ BackendObjectReference : gwv1.BackendObjectReference {
380+ Group : ptr .To (gwv1 .Group (infextv1a2 .GroupVersion .Group )),
381+ Kind : ptr .To (gwv1 .Kind (wellknown .InferencePoolKind )),
382+ Name : gwv1 .ObjectName ("foo" ),
383+ Namespace : ptrToNamespace (ns ),
384+ Port : & tc .providedPort ,
385+ },
386+ },
387+ }},
388+ }},
389+ },
390+ }
391+ inputs = append (inputs , route )
392+
393+ ir := translateRoute (t , inputs )
394+ require .NotNil (t , ir )
395+ b := getBackends (ir )[0 ]
396+ if tc .expectError {
397+ require .Error (t , b .Err )
398+ return
399+ }
400+ require .NoError (t , b .Err )
401+
402+ // Assert the BackendObject IR port number
403+ assert .Equal (t , tc .wantPort , b .BackendObject .Port ,
404+ "expected the pool's TargetPortNumber to override the provided port" )
405+ })
406+ }
407+ }
408+
409+ // Helper to build a Namespace pointer, or nil if empty
410+ func ptrToNamespace (ns string ) * gwv1.Namespace {
411+ if ns == "" {
412+ return nil
413+ }
414+ n := gwv1 .Namespace (ns )
415+ return & n
416+ }
417+
329418func svc (ns string ) * corev1.Service {
330419 if ns == "" {
331420 ns = "default"
@@ -404,6 +493,16 @@ func refGrant() *gwv1beta1.ReferenceGrant {
404493 }
405494}
406495
496+ // Helper that calls refGrant() but with its Namespace set to the given namespace
497+ func refGrantWithNs (ns string ) * gwv1beta1.ReferenceGrant {
498+ rg := refGrant ()
499+ rg .Namespace = ns
500+ for i := range rg .Spec .From {
501+ rg .Spec .From [i ].Namespace = gwv1 .Namespace ("default" )
502+ }
503+ return rg
504+ }
505+
407506func k8sSvcUpstreams (services krt.Collection [* corev1.Service ]) krt.Collection [ir.BackendObjectIR ] {
408507 return krt .NewManyCollection (services , func (kctx krt.HandlerContext , svc * corev1.Service ) []ir.BackendObjectIR {
409508 uss := []ir.BackendObjectIR {}
0 commit comments