@@ -3,12 +3,13 @@ package routeutils
33import (
44 "context"
55 "fmt"
6+ "testing"
7+
68 "github.com/go-logr/logr"
79 "github.com/stretchr/testify/assert"
810 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
911 "k8s.io/apimachinery/pkg/types"
1012 gwv1 "sigs.k8s.io/gateway-api/apis/v1"
11- "testing"
1213)
1314
1415type mockListenerAttachmentHelper struct {
@@ -299,6 +300,99 @@ func Test_mapGatewayAndRoutes(t *testing.T) {
299300 name : "no output" ,
300301 expected : make (map [int ][]preLoadRouteDescriptor ),
301302 },
303+ {
304+ name : "route attaches to multiple listeners on same port - verify deduplication" ,
305+ gw : gwv1.Gateway {
306+ ObjectMeta : metav1.ObjectMeta {
307+ Name : "gw1" ,
308+ Namespace : "ns-gw" ,
309+ },
310+ Spec : gwv1.GatewaySpec {
311+ Listeners : []gwv1.Listener {
312+ {
313+ Name : "listener1-port80" ,
314+ Port : gwv1 .PortNumber (80 ),
315+ },
316+ {
317+ Name : "listener2-port80" ,
318+ Port : gwv1 .PortNumber (80 ),
319+ },
320+ },
321+ },
322+ },
323+ routes : []preLoadRouteDescriptor {route1 },
324+ listenerAttachmentMap : map [string ]bool {
325+ "listener1-port80-80-route1-ns1" : true ,
326+ "listener2-port80-80-route1-ns1" : true ,
327+ },
328+ routeListenerMap : map [string ]bool {
329+ "listener1-port80-80-route1-ns1" : true ,
330+ "listener2-port80-80-route1-ns1" : true ,
331+ },
332+ routeGatewayMap : map [string ]bool {
333+ makeRouteGatewayMapKey (gateway , route1 ): true ,
334+ },
335+ expected : map [int ][]preLoadRouteDescriptor {
336+ 80 : {route1 }, // Only one route1, not duplicated
337+ },
338+ },
339+ {
340+ name : "different route kinds with same name attach to same listener" ,
341+ gw : gwv1.Gateway {
342+ ObjectMeta : metav1.ObjectMeta {
343+ Name : "gw1" ,
344+ Namespace : "ns-gw" ,
345+ },
346+ Spec : gwv1.GatewaySpec {
347+ Listeners : []gwv1.Listener {
348+ {
349+ Name : "https-listener" ,
350+ Port : gwv1 .PortNumber (443 ),
351+ Protocol : gwv1 .HTTPSProtocolType ,
352+ },
353+ },
354+ },
355+ },
356+ routes : []preLoadRouteDescriptor {
357+ convertHTTPRoute (gwv1.HTTPRoute {
358+ ObjectMeta : metav1.ObjectMeta {
359+ Name : "my-route" ,
360+ Namespace : "default" ,
361+ },
362+ }),
363+ convertGRPCRoute (gwv1.GRPCRoute {
364+ ObjectMeta : metav1.ObjectMeta {
365+ Name : "my-route" ,
366+ Namespace : "default" ,
367+ },
368+ }),
369+ },
370+ listenerAttachmentMap : map [string ]bool {
371+ "https-listener-443-my-route-default" : true ,
372+ },
373+ routeListenerMap : map [string ]bool {
374+ "https-listener-443-my-route-default" : true ,
375+ },
376+ routeGatewayMap : map [string ]bool {
377+ "gw1-ns-gw-my-route-default" : true ,
378+ },
379+ expected : map [int ][]preLoadRouteDescriptor {
380+ 443 : {
381+ convertHTTPRoute (gwv1.HTTPRoute {
382+ ObjectMeta : metav1.ObjectMeta {
383+ Name : "my-route" ,
384+ Namespace : "default" ,
385+ },
386+ }),
387+ convertGRPCRoute (gwv1.GRPCRoute {
388+ ObjectMeta : metav1.ObjectMeta {
389+ Name : "my-route" ,
390+ Namespace : "default" ,
391+ },
392+ }),
393+ },
394+ },
395+ },
302396 }
303397
304398 for _ , tc := range testCases {
@@ -313,7 +407,7 @@ func Test_mapGatewayAndRoutes(t *testing.T) {
313407 },
314408 logger : logr .Discard (),
315409 }
316- result , _ , statusUpdates , err := mapper .mapGatewayAndRoutes (context .Background (), tc .gw , tc .routes )
410+ result , compatibleHostnames , statusUpdates , err := mapper .mapGatewayAndRoutes (context .Background (), tc .gw , tc .routes )
317411
318412 if tc .expectErr {
319413 assert .Error (t , err )
@@ -322,6 +416,7 @@ func Test_mapGatewayAndRoutes(t *testing.T) {
322416
323417 assert .NoError (t , err )
324418 assert .Equal (t , len (tc .expected ), len (result ))
419+ assert .NotNil (t , compatibleHostnames )
325420
326421 assert .Equal (t , 0 , len (statusUpdates ))
327422
0 commit comments