github.com/cilium/cilium@v1.16.2/operator/pkg/model/ingestion/gateway_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package ingestion
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  	corev1 "k8s.io/api/core/v1"
    11  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    12  	gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
    13  	gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
    14  	mcsapiv1alpha1 "sigs.k8s.io/mcs-api/pkg/apis/v1alpha1"
    15  	mcsapicontrollers "sigs.k8s.io/mcs-api/pkg/controllers"
    16  
    17  	"github.com/cilium/cilium/operator/pkg/model"
    18  )
    19  
    20  func GroupPtr(name string) *gatewayv1.Group {
    21  	group := gatewayv1.Group(name)
    22  	return &group
    23  }
    24  
    25  func KindPtr(name string) *gatewayv1.Kind {
    26  	kind := gatewayv1.Kind(name)
    27  	return &kind
    28  }
    29  
    30  var basicHTTP = Input{
    31  	GatewayClass: gatewayv1.GatewayClass{},
    32  	Gateway: gatewayv1.Gateway{
    33  		TypeMeta: metav1.TypeMeta{
    34  			Kind:       "Gateway",
    35  			APIVersion: "gateway.networking.k8s.io/v1",
    36  		},
    37  		ObjectMeta: metav1.ObjectMeta{
    38  			Name:      "my-gateway",
    39  			Namespace: "default",
    40  		},
    41  		Spec: gatewayv1.GatewaySpec{
    42  			Listeners: []gatewayv1.Listener{
    43  				{
    44  					Name:     "prod-web-gw",
    45  					Port:     80,
    46  					Protocol: "HTTP",
    47  				},
    48  			},
    49  			Infrastructure: &gatewayv1.GatewayInfrastructure{
    50  				Labels: map[gatewayv1.AnnotationKey]gatewayv1.AnnotationValue{
    51  					"internal-loadbalancer-label": "true",
    52  				},
    53  				Annotations: map[gatewayv1.AnnotationKey]gatewayv1.AnnotationValue{
    54  					"internal-loadbalancer-annotation": "true",
    55  				},
    56  			},
    57  		},
    58  	},
    59  	HTTPRoutes: []gatewayv1.HTTPRoute{
    60  		{
    61  			ObjectMeta: metav1.ObjectMeta{
    62  				Name:      "http-app-1",
    63  				Namespace: "default",
    64  			},
    65  			Spec: gatewayv1.HTTPRouteSpec{
    66  				CommonRouteSpec: gatewayv1.CommonRouteSpec{
    67  					ParentRefs: []gatewayv1.ParentReference{
    68  						{
    69  							Name: "my-gateway",
    70  						},
    71  					},
    72  				},
    73  				Rules: []gatewayv1.HTTPRouteRule{
    74  					{
    75  						Matches: []gatewayv1.HTTPRouteMatch{
    76  							{
    77  								Path: &gatewayv1.HTTPPathMatch{
    78  									Type:  model.AddressOf[gatewayv1.PathMatchType]("PathPrefix"),
    79  									Value: model.AddressOf("/bar"),
    80  								},
    81  							},
    82  						},
    83  						BackendRefs: []gatewayv1.HTTPBackendRef{
    84  							{
    85  								BackendRef: gatewayv1.BackendRef{
    86  									BackendObjectReference: gatewayv1.BackendObjectReference{
    87  										Name: "my-service",
    88  										Port: model.AddressOf[gatewayv1.PortNumber](8080),
    89  									},
    90  								},
    91  							},
    92  							{
    93  								BackendRef: gatewayv1.BackendRef{
    94  									BackendObjectReference: gatewayv1.BackendObjectReference{
    95  										Group: GroupPtr(mcsapiv1alpha1.GroupName),
    96  										Kind:  KindPtr("ServiceImport"),
    97  										Name:  "my-service",
    98  										Port:  model.AddressOf[gatewayv1.PortNumber](8080),
    99  									},
   100  								},
   101  							},
   102  						},
   103  					},
   104  				},
   105  			},
   106  		},
   107  	},
   108  	Services: []corev1.Service{
   109  		{
   110  			ObjectMeta: metav1.ObjectMeta{
   111  				Name:      "my-service",
   112  				Namespace: "default",
   113  			},
   114  		},
   115  	},
   116  	ServiceImports: []mcsapiv1alpha1.ServiceImport{
   117  		{
   118  			ObjectMeta: metav1.ObjectMeta{
   119  				Name:      "my-service",
   120  				Namespace: "default",
   121  				Annotations: map[string]string{
   122  					mcsapicontrollers.DerivedServiceAnnotation: "my-service",
   123  				},
   124  			},
   125  		},
   126  	},
   127  }
   128  
   129  var basicHTTPListeners = []model.HTTPListener{
   130  	{
   131  		Name: "prod-web-gw",
   132  		Sources: []model.FullyQualifiedResource{
   133  			{
   134  				Name:      "my-gateway",
   135  				Namespace: "default",
   136  				Group:     "gateway.networking.k8s.io",
   137  				Version:   "v1",
   138  				Kind:      "Gateway",
   139  			},
   140  		},
   141  		Address:  "",
   142  		Port:     80,
   143  		Hostname: "*",
   144  		Routes: []model.HTTPRoute{
   145  			{
   146  				PathMatch: model.StringMatch{
   147  					Prefix: "/bar",
   148  				},
   149  				Backends: []model.Backend{
   150  					{
   151  						Name:      "my-service",
   152  						Namespace: "default",
   153  						Port: &model.BackendPort{
   154  							Port: 8080,
   155  						},
   156  					},
   157  					{
   158  						Name:      "my-service",
   159  						Namespace: "default",
   160  						Port: &model.BackendPort{
   161  							Port: 8080,
   162  						},
   163  					},
   164  				},
   165  			},
   166  		},
   167  		Infrastructure: &model.Infrastructure{
   168  			Labels: map[string]string{
   169  				"internal-loadbalancer-label": "true",
   170  			},
   171  			Annotations: map[string]string{
   172  				"internal-loadbalancer-annotation": "true",
   173  			},
   174  		},
   175  	},
   176  }
   177  
   178  var basicTLS = Input{
   179  	GatewayClass: gatewayv1.GatewayClass{},
   180  	Gateway: gatewayv1.Gateway{
   181  		TypeMeta: metav1.TypeMeta{
   182  			Kind:       "Gateway",
   183  			APIVersion: "gateway.networking.k8s.io/v1",
   184  		},
   185  		ObjectMeta: metav1.ObjectMeta{
   186  			Name:      "my-gateway",
   187  			Namespace: "default",
   188  		},
   189  		Spec: gatewayv1.GatewaySpec{
   190  			Listeners: []gatewayv1.Listener{
   191  				{
   192  					Name:     "prod-web-gw",
   193  					Port:     443,
   194  					Protocol: "TLS",
   195  				},
   196  			},
   197  		},
   198  	},
   199  	TLSRoutes: []gatewayv1alpha2.TLSRoute{
   200  		{
   201  			ObjectMeta: metav1.ObjectMeta{
   202  				Name:      "tls-app-1",
   203  				Namespace: "default",
   204  			},
   205  			Spec: gatewayv1alpha2.TLSRouteSpec{
   206  				CommonRouteSpec: gatewayv1.CommonRouteSpec{
   207  					ParentRefs: []gatewayv1.ParentReference{
   208  						{
   209  							Name: "my-gateway",
   210  						},
   211  					},
   212  				},
   213  				Hostnames: []gatewayv1alpha2.Hostname{
   214  					"example.com",
   215  				},
   216  				Rules: []gatewayv1alpha2.TLSRouteRule{
   217  					{
   218  						BackendRefs: []gatewayv1.BackendRef{
   219  							{
   220  								BackendObjectReference: gatewayv1alpha2.BackendObjectReference{
   221  									Name: "my-service",
   222  									Port: model.AddressOf[gatewayv1.PortNumber](443),
   223  								},
   224  							},
   225  							{
   226  								BackendObjectReference: gatewayv1.BackendObjectReference{
   227  									Group: GroupPtr(mcsapiv1alpha1.GroupName),
   228  									Kind:  KindPtr("ServiceImport"),
   229  									Name:  "my-service",
   230  									Port:  model.AddressOf[gatewayv1.PortNumber](443),
   231  								},
   232  							},
   233  						},
   234  					},
   235  				},
   236  			},
   237  		},
   238  	},
   239  	Services: []corev1.Service{
   240  		{
   241  			ObjectMeta: metav1.ObjectMeta{
   242  				Name:      "my-service",
   243  				Namespace: "default",
   244  			},
   245  		},
   246  	},
   247  	ServiceImports: []mcsapiv1alpha1.ServiceImport{
   248  		{
   249  			ObjectMeta: metav1.ObjectMeta{
   250  				Name:      "my-service",
   251  				Namespace: "default",
   252  				Annotations: map[string]string{
   253  					mcsapicontrollers.DerivedServiceAnnotation: "my-service",
   254  				},
   255  			},
   256  		},
   257  	},
   258  }
   259  
   260  var simpleSameNamespaceTLSListeners = []model.TLSPassthroughListener{
   261  	{
   262  		Name: "https",
   263  		Sources: []model.FullyQualifiedResource{
   264  			{
   265  				Name:      "gateway-tlsroute",
   266  				Namespace: "gateway-conformance-infra",
   267  				Group:     "gateway.networking.k8s.io",
   268  				Version:   "v1",
   269  				Kind:      "Gateway",
   270  			},
   271  		},
   272  		Address:  "",
   273  		Port:     443,
   274  		Hostname: "*",
   275  		Routes: []model.TLSPassthroughRoute{
   276  			{
   277  				Hostnames: []string{
   278  					"abc.example.com",
   279  				},
   280  				Backends: []model.Backend{
   281  					{
   282  						Name:      "tls-backend",
   283  						Namespace: "gateway-conformance-infra",
   284  						Port: &model.BackendPort{
   285  							Port: 443,
   286  						},
   287  					},
   288  				},
   289  			},
   290  		},
   291  	},
   292  }
   293  
   294  var basicTLSListeners = []model.TLSPassthroughListener{
   295  	{
   296  		Name: "prod-web-gw",
   297  		Sources: []model.FullyQualifiedResource{
   298  			{
   299  				Name:      "my-gateway",
   300  				Namespace: "default",
   301  				Group:     "gateway.networking.k8s.io",
   302  				Version:   "v1",
   303  				Kind:      "Gateway",
   304  			},
   305  		},
   306  		Address:  "",
   307  		Port:     443,
   308  		Hostname: "*",
   309  		Routes: []model.TLSPassthroughRoute{
   310  			{
   311  				Hostnames: []string{
   312  					"example.com",
   313  				},
   314  				Backends: []model.Backend{
   315  					{
   316  						Name:      "my-service",
   317  						Namespace: "default",
   318  						Port: &model.BackendPort{
   319  							Port: 443,
   320  						},
   321  					},
   322  					{
   323  						Name:      "my-service",
   324  						Namespace: "default",
   325  						Port: &model.BackendPort{
   326  							Port: 443,
   327  						},
   328  					},
   329  				},
   330  			},
   331  		},
   332  	},
   333  }
   334  
   335  var simpleSameNamespaceTLS = Input{
   336  	GatewayClass: gatewayv1.GatewayClass{},
   337  	Gateway:      sameNamespaceTLSGateway,
   338  	TLSRoutes: []gatewayv1alpha2.TLSRoute{
   339  		sameNamespaceTLSRoute,
   340  	},
   341  	Services: allServices,
   342  }
   343  
   344  var crossNamespaceHTTPInput = Input{
   345  	GatewayClass: gatewayv1.GatewayClass{},
   346  	Gateway:      backendNamespaceGateway,
   347  	HTTPRoutes: []gatewayv1.HTTPRoute{
   348  		crossNamespaceHTTPRoute,
   349  	},
   350  	Services: allServices,
   351  }
   352  
   353  var crossNamespaceHTTPListeners = []model.HTTPListener{
   354  	{
   355  		Name: "http",
   356  		Sources: []model.FullyQualifiedResource{
   357  			{
   358  				Name:      "backend-namespaces",
   359  				Namespace: "gateway-conformance-infra",
   360  			},
   361  		},
   362  		Port:     80,
   363  		Hostname: "*",
   364  		Routes: []model.HTTPRoute{
   365  			{
   366  				Backends: []model.Backend{
   367  					{
   368  						Name:      "web-backend",
   369  						Namespace: "gateway-conformance-web-backend",
   370  						Port: &model.BackendPort{
   371  							Port: 8080,
   372  						},
   373  					},
   374  				},
   375  			},
   376  		},
   377  	},
   378  }
   379  
   380  var exactPathMatchingHTTPInput = Input{
   381  	GatewayClass: gatewayv1.GatewayClass{},
   382  	Gateway:      sameNamespaceGateway,
   383  	HTTPRoutes: []gatewayv1.HTTPRoute{
   384  		exactPathMatchingHTTPRoute,
   385  	},
   386  	Services: allServices,
   387  }
   388  
   389  var exactPathMatchingHTTPListeners = []model.HTTPListener{
   390  	{
   391  		Name: "http",
   392  		Sources: []model.FullyQualifiedResource{
   393  			{
   394  				Name:      "same-namespace",
   395  				Namespace: "gateway-conformance-infra",
   396  			},
   397  		},
   398  		Port:     80,
   399  		Hostname: "*",
   400  		Routes: []model.HTTPRoute{
   401  			{
   402  				PathMatch: model.StringMatch{Exact: "/one"},
   403  				Backends: []model.Backend{
   404  					{
   405  						Name:      "infra-backend-v1",
   406  						Namespace: "gateway-conformance-infra",
   407  						Port: &model.BackendPort{
   408  							Port: 8080,
   409  						},
   410  					},
   411  				},
   412  			},
   413  			{
   414  				PathMatch: model.StringMatch{Exact: "/two"},
   415  				Backends: []model.Backend{
   416  					{
   417  						Name:      "infra-backend-v2",
   418  						Namespace: "gateway-conformance-infra",
   419  						Port: &model.BackendPort{
   420  							Port: 8080,
   421  						},
   422  					},
   423  				},
   424  			},
   425  		},
   426  	},
   427  }
   428  
   429  var headerMatchingHTTPInput = Input{
   430  	GatewayClass: gatewayv1.GatewayClass{},
   431  	Gateway:      sameNamespaceGateway,
   432  	HTTPRoutes: []gatewayv1.HTTPRoute{
   433  		headerMatchingHTTPRoute,
   434  	},
   435  	Services: allServices,
   436  }
   437  
   438  var headerMatchingHTTPListeners = []model.HTTPListener{
   439  	{
   440  		Name: "http",
   441  		Sources: []model.FullyQualifiedResource{
   442  			{
   443  				Name:      "same-namespace",
   444  				Namespace: "gateway-conformance-infra",
   445  			},
   446  		},
   447  		Port:     80,
   448  		Hostname: "*",
   449  		Routes: []model.HTTPRoute{
   450  			{
   451  				HeadersMatch: []model.KeyValueMatch{
   452  					{
   453  						Key:   "version",
   454  						Match: model.StringMatch{Exact: "one"},
   455  					},
   456  				},
   457  				Backends: []model.Backend{
   458  					{
   459  						Name:      "infra-backend-v1",
   460  						Namespace: "gateway-conformance-infra",
   461  						Port: &model.BackendPort{
   462  							Port: 8080,
   463  						},
   464  					},
   465  				},
   466  			},
   467  			{
   468  				HeadersMatch: []model.KeyValueMatch{
   469  					{
   470  						Key:   "version",
   471  						Match: model.StringMatch{Exact: "two"},
   472  					},
   473  				},
   474  				Backends: []model.Backend{
   475  					{
   476  						Name:      "infra-backend-v2",
   477  						Namespace: "gateway-conformance-infra",
   478  						Port: &model.BackendPort{
   479  							Port: 8080,
   480  						},
   481  					},
   482  				},
   483  			},
   484  			{
   485  				HeadersMatch: []model.KeyValueMatch{
   486  					{
   487  						Key:   "version",
   488  						Match: model.StringMatch{Exact: "two"},
   489  					},
   490  					{
   491  						Key:   "color",
   492  						Match: model.StringMatch{Exact: "orange"},
   493  					},
   494  				},
   495  				Backends: []model.Backend{
   496  					{
   497  						Name:      "infra-backend-v1",
   498  						Namespace: "gateway-conformance-infra",
   499  						Port: &model.BackendPort{
   500  							Port: 8080,
   501  						},
   502  					},
   503  				},
   504  			},
   505  			{
   506  				HeadersMatch: []model.KeyValueMatch{
   507  					{
   508  						Key:   "color",
   509  						Match: model.StringMatch{Prefix: "", Exact: "blue", Regex: ""},
   510  					},
   511  				},
   512  				Backends: []model.Backend{
   513  					{
   514  						Name:      "infra-backend-v1",
   515  						Namespace: "gateway-conformance-infra",
   516  						Port: &model.BackendPort{
   517  							Port: 8080,
   518  						},
   519  					},
   520  				},
   521  			},
   522  			{
   523  				HeadersMatch: []model.KeyValueMatch{
   524  					{
   525  						Key:   "color",
   526  						Match: model.StringMatch{Exact: "blue"},
   527  					},
   528  				},
   529  				Backends: []model.Backend{
   530  					{
   531  						Name:      "infra-backend-v1",
   532  						Namespace: "gateway-conformance-infra",
   533  						Port: &model.BackendPort{
   534  							Port: 8080,
   535  						},
   536  					},
   537  				},
   538  			},
   539  			{
   540  				HeadersMatch: []model.KeyValueMatch{
   541  					{
   542  						Key:   "color",
   543  						Match: model.StringMatch{Exact: "red"},
   544  					},
   545  				},
   546  				Backends: []model.Backend{
   547  					{
   548  						Name:      "infra-backend-v2",
   549  						Namespace: "gateway-conformance-infra",
   550  						Port: &model.BackendPort{
   551  							Port: 8080,
   552  						},
   553  					},
   554  				},
   555  			},
   556  			{
   557  				HeadersMatch: []model.KeyValueMatch{
   558  					{
   559  						Key:   "color",
   560  						Match: model.StringMatch{Exact: "yellow"},
   561  					},
   562  				},
   563  				Backends: []model.Backend{
   564  					{
   565  						Name:      "infra-backend-v2",
   566  						Namespace: "gateway-conformance-infra", Port: &model.BackendPort{
   567  							Port: 8080,
   568  						},
   569  					},
   570  				},
   571  			},
   572  		},
   573  	},
   574  }
   575  
   576  var hostnameIntersectionHTTPInput = Input{
   577  	GatewayClass: gatewayv1.GatewayClass{},
   578  	Gateway:      *hostnameIntersectionGateway,
   579  	HTTPRoutes:   hostnameIntersectionHTTPRoutes,
   580  	Services:     allServices,
   581  }
   582  
   583  var hostnameIntersectionHTTPListeners = []model.HTTPListener{
   584  	{
   585  		Name:     "listener-1",
   586  		Sources:  []model.FullyQualifiedResource{{Name: "httproute-hostname-intersection", Namespace: "gateway-conformance-infra"}},
   587  		Port:     80,
   588  		Hostname: "very.specific.com",
   589  		Routes: []model.HTTPRoute{
   590  			{
   591  				Hostnames: []string{"very.specific.com"},
   592  				PathMatch: model.StringMatch{Prefix: "/s1"},
   593  				Backends: []model.Backend{
   594  					{
   595  						Name:      "infra-backend-v1",
   596  						Namespace: "gateway-conformance-infra",
   597  						Port: &model.BackendPort{
   598  							Port: 8080,
   599  						},
   600  					},
   601  				},
   602  			},
   603  			{
   604  				Hostnames: []string{"very.specific.com"},
   605  				PathMatch: model.StringMatch{Prefix: "/s3"},
   606  				Backends: []model.Backend{
   607  					{
   608  						Name:      "infra-backend-v3",
   609  						Namespace: "gateway-conformance-infra",
   610  						Port: &model.BackendPort{
   611  							Port: 8080,
   612  						},
   613  					},
   614  				},
   615  			},
   616  		},
   617  	},
   618  	{
   619  		Name: "listener-2",
   620  		Sources: []model.FullyQualifiedResource{
   621  			{
   622  				Name:      "httproute-hostname-intersection",
   623  				Namespace: "gateway-conformance-infra",
   624  			},
   625  		},
   626  		Port:     80,
   627  		Hostname: "*.wildcard.io",
   628  		Routes: []model.HTTPRoute{
   629  			{
   630  				Hostnames: []string{"bar.wildcard.io", "foo.bar.wildcard.io", "foo.wildcard.io"},
   631  				PathMatch: model.StringMatch{Prefix: "/s2"},
   632  				Backends: []model.Backend{
   633  					{
   634  						Name:      "infra-backend-v2",
   635  						Namespace: "gateway-conformance-infra",
   636  						Port: &model.BackendPort{
   637  							Port: 8080,
   638  						},
   639  					},
   640  				},
   641  			},
   642  		},
   643  	},
   644  	{
   645  		Name: "listener-3",
   646  		Sources: []model.FullyQualifiedResource{
   647  			{
   648  				Name:      "httproute-hostname-intersection",
   649  				Namespace: "gateway-conformance-infra",
   650  			},
   651  		},
   652  		Port:     80,
   653  		Hostname: "*.anotherwildcard.io",
   654  		Routes: []model.HTTPRoute{
   655  			{
   656  				Hostnames: []string{"*.anotherwildcard.io"},
   657  				PathMatch: model.StringMatch{Prefix: "/s4"},
   658  				Backends: []model.Backend{
   659  					{
   660  						Name:      "infra-backend-v1",
   661  						Namespace: "gateway-conformance-infra",
   662  						Port: &model.BackendPort{
   663  							Port: 8080,
   664  						},
   665  					},
   666  				},
   667  			},
   668  		},
   669  	},
   670  }
   671  
   672  var listenerHostnameMatchingHTTPInput = Input{
   673  	GatewayClass: gatewayv1.GatewayClass{},
   674  	Gateway:      *listenerHostnameMatchingGateway,
   675  	HTTPRoutes:   listenerHostnameMatchingHTTPRoutes,
   676  	Services:     allServices,
   677  }
   678  
   679  var listenerHostnameMatchingHTTPListeners = []model.HTTPListener{
   680  	{
   681  		Name: "listener-1",
   682  		Sources: []model.FullyQualifiedResource{
   683  			{
   684  				Name:      "httproute-listener-hostname-matching",
   685  				Namespace: "gateway-conformance-infra",
   686  			},
   687  		},
   688  		Port:     80,
   689  		Hostname: "bar.com",
   690  		Routes: []model.HTTPRoute{
   691  			{
   692  				Hostnames: []string{"bar.com"},
   693  				Backends: []model.Backend{
   694  					{
   695  						Name:      "infra-backend-v1",
   696  						Namespace: "gateway-conformance-infra",
   697  						Port: &model.BackendPort{
   698  							Port: 8080,
   699  						},
   700  					},
   701  				},
   702  			},
   703  		},
   704  	},
   705  	{
   706  		Name: "listener-2",
   707  		Sources: []model.FullyQualifiedResource{
   708  			{
   709  				Name:      "httproute-listener-hostname-matching",
   710  				Namespace: "gateway-conformance-infra",
   711  			},
   712  		},
   713  		Port:     80,
   714  		Hostname: "foo.bar.com",
   715  		Routes: []model.HTTPRoute{
   716  			{
   717  				Hostnames: []string{"foo.bar.com"},
   718  				Backends: []model.Backend{
   719  					{
   720  						Name:      "infra-backend-v2",
   721  						Namespace: "gateway-conformance-infra",
   722  						Port: &model.BackendPort{
   723  							Port: 8080,
   724  						},
   725  					},
   726  				},
   727  			},
   728  		},
   729  	},
   730  	{
   731  		Name: "listener-3",
   732  		Sources: []model.FullyQualifiedResource{
   733  			{
   734  				Name:      "httproute-listener-hostname-matching",
   735  				Namespace: "gateway-conformance-infra",
   736  			},
   737  		},
   738  		Port:     80,
   739  		Hostname: "*.bar.com",
   740  		Routes: []model.HTTPRoute{
   741  			{
   742  				Hostnames: []string{"*.bar.com"},
   743  				Backends: []model.Backend{
   744  					{
   745  						Name:      "infra-backend-v3",
   746  						Namespace: "gateway-conformance-infra",
   747  						Port: &model.BackendPort{
   748  							Port: 8080,
   749  						},
   750  					},
   751  				},
   752  			},
   753  		},
   754  	},
   755  	{
   756  		Name: "listener-4",
   757  		Sources: []model.FullyQualifiedResource{
   758  			{
   759  				Name:      "httproute-listener-hostname-matching",
   760  				Namespace: "gateway-conformance-infra",
   761  			},
   762  		},
   763  		Port:     80,
   764  		Hostname: "*.foo.com",
   765  		Routes: []model.HTTPRoute{
   766  			{
   767  				Hostnames: []string{"*.foo.com"},
   768  				Backends: []model.Backend{
   769  					{
   770  						Name:      "infra-backend-v3",
   771  						Namespace: "gateway-conformance-infra",
   772  						Port: &model.BackendPort{
   773  							Port: 8080,
   774  						},
   775  					},
   776  				},
   777  			},
   778  		},
   779  	},
   780  }
   781  
   782  var matchingAcrossHTTPInput = Input{
   783  	GatewayClass: gatewayv1.GatewayClass{},
   784  	Gateway:      sameNamespaceGateway,
   785  	HTTPRoutes:   matchingAcrossHTTPRoutes,
   786  	Services:     allServices,
   787  }
   788  
   789  var matchingAcrossHTTPListeners = []model.HTTPListener{
   790  	{
   791  		Name: "http",
   792  		Sources: []model.FullyQualifiedResource{
   793  			{
   794  				Name:      "same-namespace",
   795  				Namespace: "gateway-conformance-infra",
   796  			},
   797  		},
   798  		Port:     80,
   799  		Hostname: "*",
   800  		Routes: []model.HTTPRoute{
   801  			{
   802  				Hostnames: []string{"example.com", "example.net"},
   803  				PathMatch: model.StringMatch{Exact: "/"},
   804  				HeadersMatch: []model.KeyValueMatch{
   805  					{
   806  						Key:   "version",
   807  						Match: model.StringMatch{Exact: "one"},
   808  					},
   809  				},
   810  				Backends: []model.Backend{
   811  					{
   812  						Name:      "infra-backend-v1",
   813  						Namespace: "gateway-conformance-infra",
   814  						Port: &model.BackendPort{
   815  							Port: 8080,
   816  						},
   817  					},
   818  				},
   819  			},
   820  			{
   821  				Hostnames:    []string{"example.com"},
   822  				PathMatch:    model.StringMatch{Exact: "/v2"},
   823  				HeadersMatch: []model.KeyValueMatch{{Key: "version", Match: model.StringMatch{Exact: "two"}}},
   824  				Backends: []model.Backend{
   825  					{
   826  						Name:      "infra-backend-v2",
   827  						Namespace: "gateway-conformance-infra",
   828  						Port: &model.BackendPort{
   829  							Port: 8080,
   830  						},
   831  					},
   832  				},
   833  			},
   834  		},
   835  	},
   836  }
   837  
   838  var matchingHTTPInput = Input{
   839  	GatewayClass: gatewayv1.GatewayClass{},
   840  	Gateway:      sameNamespaceGateway,
   841  	HTTPRoutes:   matchingHTTPRoutes,
   842  	Services:     allServices,
   843  }
   844  
   845  var matchingHTTPListeners = []model.HTTPListener{
   846  	{
   847  		Name: "http",
   848  		Sources: []model.FullyQualifiedResource{
   849  			{
   850  				Name:      "same-namespace",
   851  				Namespace: "gateway-conformance-infra",
   852  			},
   853  		},
   854  		Port: 80, Hostname: "*",
   855  		Routes: []model.HTTPRoute{
   856  			{
   857  				PathMatch: model.StringMatch{Exact: "/"},
   858  				HeadersMatch: []model.KeyValueMatch{
   859  					{
   860  						Key:   "version",
   861  						Match: model.StringMatch{Exact: "one"},
   862  					},
   863  				},
   864  				Backends: []model.Backend{
   865  					{
   866  						Name:      "infra-backend-v1",
   867  						Namespace: "gateway-conformance-infra",
   868  						Port: &model.BackendPort{
   869  							Port: 8080,
   870  						},
   871  					},
   872  				},
   873  			},
   874  			{
   875  				PathMatch: model.StringMatch{Exact: "/v2"},
   876  				HeadersMatch: []model.KeyValueMatch{
   877  					{
   878  						Key:   "version",
   879  						Match: model.StringMatch{Exact: "two"},
   880  					},
   881  				},
   882  				Backends: []model.Backend{
   883  					{
   884  						Name:      "infra-backend-v2",
   885  						Namespace: "gateway-conformance-infra",
   886  						Port: &model.BackendPort{
   887  							Port: 8080,
   888  						},
   889  					},
   890  				},
   891  			},
   892  		},
   893  	},
   894  }
   895  
   896  var queryParamMatchingHTTPInput = Input{
   897  	GatewayClass: gatewayv1.GatewayClass{},
   898  	Gateway:      sameNamespaceGateway,
   899  	HTTPRoutes:   queryParamMatchingHTTPRoutes,
   900  	Services:     allServices,
   901  }
   902  
   903  var queryParamMatchingHTTPListeners = []model.HTTPListener{
   904  	{
   905  		Name: "http",
   906  		Sources: []model.FullyQualifiedResource{
   907  			{
   908  				Name:      "same-namespace",
   909  				Namespace: "gateway-conformance-infra",
   910  			},
   911  		},
   912  		Port:     80,
   913  		Hostname: "*",
   914  		Routes: []model.HTTPRoute{
   915  			{
   916  				QueryParamsMatch: []model.KeyValueMatch{
   917  					{
   918  						Key:   "animal",
   919  						Match: model.StringMatch{Exact: "whale"},
   920  					},
   921  				},
   922  				Backends: []model.Backend{
   923  					{
   924  						Name:      "infra-backend-v1",
   925  						Namespace: "gateway-conformance-infra",
   926  						Port: &model.BackendPort{
   927  							Port: 8080,
   928  						},
   929  					},
   930  				},
   931  			},
   932  			{
   933  				QueryParamsMatch: []model.KeyValueMatch{
   934  					{
   935  						Key:   "animal",
   936  						Match: model.StringMatch{Exact: "dolphin"},
   937  					},
   938  				},
   939  				Backends: []model.Backend{
   940  					{
   941  						Name:      "infra-backend-v2",
   942  						Namespace: "gateway-conformance-infra",
   943  						Port: &model.BackendPort{
   944  							Port: 8080,
   945  						},
   946  					},
   947  				},
   948  			},
   949  			{
   950  				QueryParamsMatch: []model.KeyValueMatch{
   951  					{
   952  						Key:   "animal",
   953  						Match: model.StringMatch{Exact: "dolphin"},
   954  					},
   955  					{
   956  						Key:   "color",
   957  						Match: model.StringMatch{Exact: "blue"},
   958  					},
   959  				},
   960  				Backends: []model.Backend{
   961  					{
   962  						Name:      "infra-backend-v3",
   963  						Namespace: "gateway-conformance-infra",
   964  						Port: &model.BackendPort{
   965  							Port: 8080,
   966  						},
   967  					},
   968  				},
   969  			},
   970  			{
   971  				QueryParamsMatch: []model.KeyValueMatch{
   972  					{
   973  						Key:   "ANIMAL",
   974  						Match: model.StringMatch{Exact: "Whale"},
   975  					},
   976  				},
   977  				Backends: []model.Backend{
   978  					{
   979  						Name:      "infra-backend-v3",
   980  						Namespace: "gateway-conformance-infra",
   981  						Port: &model.BackendPort{
   982  							Port: 8080,
   983  						},
   984  					},
   985  				},
   986  			},
   987  		},
   988  	},
   989  }
   990  
   991  var requestHeaderModifierHTTPInput = Input{
   992  	GatewayClass: gatewayv1.GatewayClass{},
   993  	Gateway:      sameNamespaceGateway,
   994  	HTTPRoutes:   requestHeaderModifierHTTPRoutes,
   995  	Services:     allServices,
   996  }
   997  
   998  var backendRefsRequestHeaderModifierHTTPInput = Input{
   999  	GatewayClass: gatewayv1.GatewayClass{},
  1000  	Gateway:      sameNamespaceGateway,
  1001  	HTTPRoutes:   backendRefsRequestHeaderModifierHTTPRoutes,
  1002  	Services:     allServices,
  1003  }
  1004  
  1005  var requestHeaderModifierHTTPListeners = []model.HTTPListener{
  1006  	{
  1007  		Name: "http",
  1008  		Sources: []model.FullyQualifiedResource{
  1009  			{
  1010  				Name:      "same-namespace",
  1011  				Namespace: "gateway-conformance-infra",
  1012  			},
  1013  		},
  1014  		Port: 80, Hostname: "*",
  1015  		Routes: []model.HTTPRoute{
  1016  			{
  1017  				PathMatch: model.StringMatch{Exact: "/set"},
  1018  				Backends: []model.Backend{
  1019  					{
  1020  						Name:      "infra-backend-v1",
  1021  						Namespace: "gateway-conformance-infra",
  1022  						Port: &model.BackendPort{
  1023  							Port: 8080,
  1024  						},
  1025  					},
  1026  				},
  1027  				RequestHeaderFilter: &model.HTTPHeaderFilter{
  1028  					HeadersToSet: []model.Header{
  1029  						{
  1030  							Name:  "X-Header-Set",
  1031  							Value: "set-overwrites-values",
  1032  						},
  1033  					},
  1034  				},
  1035  			},
  1036  			{
  1037  				PathMatch: model.StringMatch{Exact: "/add"},
  1038  				Backends: []model.Backend{
  1039  					{
  1040  						Name:      "infra-backend-v1",
  1041  						Namespace: "gateway-conformance-infra",
  1042  						Port: &model.BackendPort{
  1043  							Port: 8080,
  1044  						},
  1045  					},
  1046  				},
  1047  				RequestHeaderFilter: &model.HTTPHeaderFilter{
  1048  					HeadersToAdd: []model.Header{
  1049  						{
  1050  							Name:  "X-Header-Add",
  1051  							Value: "add-appends-values",
  1052  						},
  1053  					},
  1054  				},
  1055  			},
  1056  			{
  1057  				PathMatch: model.StringMatch{Exact: "/remove"},
  1058  				Backends: []model.Backend{
  1059  					{
  1060  						Name:      "infra-backend-v1",
  1061  						Namespace: "gateway-conformance-infra",
  1062  						Port: &model.BackendPort{
  1063  							Port: 8080,
  1064  						},
  1065  					},
  1066  				},
  1067  				RequestHeaderFilter: &model.HTTPHeaderFilter{
  1068  					HeadersToRemove: []string{"X-Header-Remove"},
  1069  				},
  1070  			},
  1071  			{
  1072  				PathMatch: model.StringMatch{Exact: "/multiple"},
  1073  				Backends: []model.Backend{
  1074  					{
  1075  						Name:      "infra-backend-v1",
  1076  						Namespace: "gateway-conformance-infra",
  1077  						Port: &model.BackendPort{
  1078  							Port: 8080,
  1079  						},
  1080  					},
  1081  				},
  1082  				RequestHeaderFilter: &model.HTTPHeaderFilter{
  1083  					HeadersToAdd: []model.Header{
  1084  						{
  1085  							Name:  "X-Header-Add-1",
  1086  							Value: "header-add-1",
  1087  						},
  1088  						{
  1089  							Name:  "X-Header-Add-2",
  1090  							Value: "header-add-2",
  1091  						},
  1092  						{
  1093  							Name:  "X-Header-Add-3",
  1094  							Value: "header-add-3",
  1095  						},
  1096  					},
  1097  					HeadersToSet: []model.Header{
  1098  						{
  1099  							Name:  "X-Header-Set-1",
  1100  							Value: "header-set-1",
  1101  						},
  1102  						{
  1103  							Name:  "X-Header-Set-2",
  1104  							Value: "header-set-2",
  1105  						},
  1106  					},
  1107  					HeadersToRemove: []string{
  1108  						"X-Header-Remove-1",
  1109  						"X-Header-Remove-2",
  1110  					},
  1111  				},
  1112  			},
  1113  			{
  1114  				PathMatch: model.StringMatch{Exact: "/case-insensitivity"},
  1115  				Backends: []model.Backend{
  1116  					{
  1117  						Name:      "infra-backend-v1",
  1118  						Namespace: "gateway-conformance-infra",
  1119  						Port: &model.BackendPort{
  1120  							Port: 8080,
  1121  						},
  1122  					},
  1123  				},
  1124  				RequestHeaderFilter: &model.HTTPHeaderFilter{
  1125  					HeadersToAdd: []model.Header{
  1126  						{
  1127  							Name:  "X-Header-Add",
  1128  							Value: "header-add",
  1129  						},
  1130  					},
  1131  					HeadersToSet: []model.Header{
  1132  						{
  1133  							Name:  "X-Header-Set",
  1134  							Value: "header-set",
  1135  						},
  1136  					},
  1137  					HeadersToRemove: []string{
  1138  						"X-Header-Remove",
  1139  					},
  1140  				},
  1141  			},
  1142  		},
  1143  	},
  1144  }
  1145  
  1146  var backendRefsRequestHeaderModifierHTTPListeners = []model.HTTPListener{
  1147  	{
  1148  		Name: "http",
  1149  		Sources: []model.FullyQualifiedResource{
  1150  			{
  1151  				Name:      "same-namespace",
  1152  				Namespace: "gateway-conformance-infra",
  1153  			},
  1154  		},
  1155  		Port: 80, Hostname: "*",
  1156  		Routes: []model.HTTPRoute{
  1157  			{
  1158  				PathMatch: model.StringMatch{Exact: "/set"},
  1159  				Backends: []model.Backend{
  1160  					{
  1161  						Name:      "infra-backend-v1",
  1162  						Namespace: "gateway-conformance-infra",
  1163  						Port: &model.BackendPort{
  1164  							Port: 8080,
  1165  						},
  1166  					},
  1167  				},
  1168  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  1169  					{
  1170  						Name: "gateway-conformance-infra:infra-backend-v1:8080",
  1171  						RequestHeaderFilter: &model.HTTPHeaderFilter{
  1172  							HeadersToSet: []model.Header{
  1173  								{
  1174  									Name:  "X-Header-Set",
  1175  									Value: "set-overwrites-values",
  1176  								},
  1177  							},
  1178  						},
  1179  					},
  1180  				},
  1181  			},
  1182  			{
  1183  				PathMatch: model.StringMatch{Exact: "/add"},
  1184  				Backends: []model.Backend{
  1185  					{
  1186  						Name:      "infra-backend-v1",
  1187  						Namespace: "gateway-conformance-infra",
  1188  						Port: &model.BackendPort{
  1189  							Port: 8080,
  1190  						},
  1191  					},
  1192  				},
  1193  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  1194  					{
  1195  						Name: "gateway-conformance-infra:infra-backend-v1:8080",
  1196  						RequestHeaderFilter: &model.HTTPHeaderFilter{
  1197  							HeadersToAdd: []model.Header{
  1198  								{
  1199  									Name:  "X-Header-Add",
  1200  									Value: "add-appends-values",
  1201  								},
  1202  							},
  1203  						},
  1204  					},
  1205  				},
  1206  			},
  1207  			{
  1208  				PathMatch: model.StringMatch{Exact: "/remove"},
  1209  				Backends: []model.Backend{
  1210  					{
  1211  						Name:      "infra-backend-v1",
  1212  						Namespace: "gateway-conformance-infra",
  1213  						Port: &model.BackendPort{
  1214  							Port: 8080,
  1215  						},
  1216  					},
  1217  				},
  1218  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  1219  					{
  1220  						Name: "gateway-conformance-infra:infra-backend-v1:8080",
  1221  						RequestHeaderFilter: &model.HTTPHeaderFilter{
  1222  							HeadersToRemove: []string{"X-Header-Remove"},
  1223  						},
  1224  					},
  1225  				},
  1226  			},
  1227  			{
  1228  				PathMatch: model.StringMatch{Exact: "/multiple-backends"},
  1229  				Backends: []model.Backend{
  1230  					{
  1231  						Name:      "infra-backend-v1",
  1232  						Namespace: "gateway-conformance-infra",
  1233  						Port: &model.BackendPort{
  1234  							Port: 8080,
  1235  						},
  1236  					},
  1237  					{
  1238  						Name:      "infra-backend-v2",
  1239  						Namespace: "gateway-conformance-infra",
  1240  						Port: &model.BackendPort{
  1241  							Port: 8080,
  1242  						},
  1243  					},
  1244  				},
  1245  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  1246  					{
  1247  						Name: "gateway-conformance-infra:infra-backend-v1:8080",
  1248  						RequestHeaderFilter: &model.HTTPHeaderFilter{
  1249  							HeadersToAdd: []model.Header{
  1250  								{
  1251  									Name:  "X-Header-Add-1",
  1252  									Value: "header-add-1",
  1253  								},
  1254  								{
  1255  									Name:  "X-Header-Add-2",
  1256  									Value: "header-add-2",
  1257  								},
  1258  							},
  1259  						},
  1260  					},
  1261  					{
  1262  						Name: "gateway-conformance-infra:infra-backend-v2:8080",
  1263  						RequestHeaderFilter: &model.HTTPHeaderFilter{
  1264  							HeadersToAdd: []model.Header{
  1265  								{
  1266  									Name:  "X-Header-Add-3",
  1267  									Value: "header-add-3",
  1268  								},
  1269  							},
  1270  						},
  1271  					},
  1272  				},
  1273  			},
  1274  			{
  1275  				PathMatch: model.StringMatch{Exact: "/multiple-backends-with-some-not"},
  1276  				Backends: []model.Backend{
  1277  					{
  1278  						Name:      "infra-backend-v1",
  1279  						Namespace: "gateway-conformance-infra",
  1280  						Port: &model.BackendPort{
  1281  							Port: 8080,
  1282  						},
  1283  					},
  1284  					{
  1285  						Name:      "infra-backend-v2",
  1286  						Namespace: "gateway-conformance-infra",
  1287  						Port: &model.BackendPort{
  1288  							Port: 8080,
  1289  						},
  1290  					},
  1291  				},
  1292  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  1293  					{
  1294  						Name: "gateway-conformance-infra:infra-backend-v2:8080",
  1295  						RequestHeaderFilter: &model.HTTPHeaderFilter{
  1296  							HeadersToAdd: []model.Header{
  1297  								{
  1298  									Name:  "X-Header-Add",
  1299  									Value: "header-add",
  1300  								},
  1301  							},
  1302  							HeadersToSet: []model.Header{
  1303  								{
  1304  									Name:  "X-Header-Set",
  1305  									Value: "header-set",
  1306  								},
  1307  							},
  1308  							HeadersToRemove: []string{
  1309  								"X-Header-Remove",
  1310  							},
  1311  						},
  1312  					},
  1313  				},
  1314  			},
  1315  		},
  1316  	},
  1317  }
  1318  
  1319  var simpleSameNamespaceHTTPInput = Input{
  1320  	GatewayClass: gatewayv1.GatewayClass{},
  1321  	Gateway:      sameNamespaceGateway,
  1322  	HTTPRoutes:   simpleSameNamespaceHTTPRoutes,
  1323  	Services:     allServices,
  1324  }
  1325  
  1326  var simpleSameNamespaceHTTPListeners = []model.HTTPListener{
  1327  	{
  1328  		Name: "http",
  1329  		Sources: []model.FullyQualifiedResource{
  1330  			{
  1331  				Name:      "same-namespace",
  1332  				Namespace: "gateway-conformance-infra",
  1333  			},
  1334  		},
  1335  		Port:     80,
  1336  		Hostname: "*",
  1337  		Routes: []model.HTTPRoute{
  1338  			{
  1339  				Backends: []model.Backend{
  1340  					{
  1341  						Name:      "infra-backend-v1",
  1342  						Namespace: "gateway-conformance-infra",
  1343  						Port: &model.BackendPort{
  1344  							Port: 8080,
  1345  						},
  1346  					},
  1347  				},
  1348  			},
  1349  		},
  1350  	},
  1351  }
  1352  
  1353  var methodMatchingHTTPInput = Input{
  1354  	GatewayClass: gatewayv1.GatewayClass{},
  1355  	Gateway:      sameNamespaceGateway,
  1356  	HTTPRoutes:   methodMatchingHTTPRoutes,
  1357  	Services:     allServices,
  1358  }
  1359  
  1360  var methodMatchingHTTPListeners = []model.HTTPListener{
  1361  	{
  1362  		Name: "http",
  1363  		Sources: []model.FullyQualifiedResource{
  1364  			{
  1365  				Name:      "same-namespace",
  1366  				Namespace: "gateway-conformance-infra",
  1367  			},
  1368  		},
  1369  		Port:     80,
  1370  		Hostname: "*",
  1371  		Routes: []model.HTTPRoute{
  1372  			{
  1373  				Method: model.AddressOf("POST"),
  1374  				Backends: []model.Backend{
  1375  					{
  1376  						Name:      "infra-backend-v1",
  1377  						Namespace: "gateway-conformance-infra",
  1378  						Port: &model.BackendPort{
  1379  							Port: 8080,
  1380  						},
  1381  					},
  1382  				},
  1383  			},
  1384  			{
  1385  				Method: model.AddressOf("GET"),
  1386  				Backends: []model.Backend{
  1387  					{
  1388  						Name:      "infra-backend-v2",
  1389  						Namespace: "gateway-conformance-infra",
  1390  						Port: &model.BackendPort{
  1391  							Port: 8080,
  1392  						},
  1393  					},
  1394  				},
  1395  			},
  1396  		},
  1397  	},
  1398  }
  1399  
  1400  var requestRedirectHTTPInput = Input{
  1401  	GatewayClass: gatewayv1.GatewayClass{},
  1402  	Gateway:      sameNamespaceGateway,
  1403  	HTTPRoutes:   requestRedirectHTTPRoutes,
  1404  	Services:     allServices,
  1405  }
  1406  
  1407  var requestRedirectHTTPListeners = []model.HTTPListener{
  1408  	{
  1409  		Name: "http",
  1410  		Sources: []model.FullyQualifiedResource{
  1411  			{
  1412  				Name:      "same-namespace",
  1413  				Namespace: "gateway-conformance-infra",
  1414  			},
  1415  		},
  1416  		Port:     80,
  1417  		Hostname: "*",
  1418  		Routes: []model.HTTPRoute{
  1419  			{
  1420  				PathMatch: model.StringMatch{Prefix: "/hostname-redirect"},
  1421  				Backends: []model.Backend{
  1422  					{
  1423  						Name:      "infra-backend-v1",
  1424  						Namespace: "gateway-conformance-infra",
  1425  						Port: &model.BackendPort{
  1426  							Port: 8080,
  1427  						},
  1428  					},
  1429  				},
  1430  				RequestRedirect: &model.HTTPRequestRedirectFilter{
  1431  					Hostname: model.AddressOf("example.com"),
  1432  					Port:     model.AddressOf(int32(80)),
  1433  				},
  1434  			},
  1435  			{
  1436  				PathMatch: model.StringMatch{Prefix: "/status-code-301"},
  1437  				Backends:  []model.Backend{},
  1438  				DirectResponse: &model.DirectResponse{
  1439  					StatusCode: 500,
  1440  				},
  1441  				RequestRedirect: &model.HTTPRequestRedirectFilter{
  1442  					StatusCode: model.AddressOf(301),
  1443  					Port:       model.AddressOf(int32(80)),
  1444  				},
  1445  			},
  1446  			{
  1447  				PathMatch: model.StringMatch{Prefix: "/host-and-status"},
  1448  				Backends: []model.Backend{
  1449  					{
  1450  						Name:      "infra-backend-v1",
  1451  						Namespace: "gateway-conformance-infra",
  1452  						Port: &model.BackendPort{
  1453  							Port: 8080,
  1454  						},
  1455  					},
  1456  				},
  1457  				RequestRedirect: &model.HTTPRequestRedirectFilter{
  1458  					Hostname:   model.AddressOf("example.com"),
  1459  					StatusCode: model.AddressOf(301),
  1460  					Port:       model.AddressOf(int32(80)),
  1461  				},
  1462  			},
  1463  		},
  1464  	},
  1465  }
  1466  
  1467  var responseHeaderModifierHTTPInput = Input{
  1468  	GatewayClass: gatewayv1.GatewayClass{},
  1469  	Gateway:      sameNamespaceGateway,
  1470  	HTTPRoutes:   responseHeaderModifierHTTPRoutes,
  1471  	Services:     allServices,
  1472  }
  1473  
  1474  var responseHeaderModifierHTTPListeners = []model.HTTPListener{
  1475  	{
  1476  		Name: "http",
  1477  		Sources: []model.FullyQualifiedResource{
  1478  			{
  1479  				Name:      "same-namespace",
  1480  				Namespace: "gateway-conformance-infra",
  1481  			},
  1482  		},
  1483  		Port: 80, Hostname: "*",
  1484  		Routes: []model.HTTPRoute{
  1485  			{
  1486  				PathMatch: model.StringMatch{Prefix: "/set"},
  1487  				Backends: []model.Backend{
  1488  					{
  1489  						Name:      "infra-backend-v1",
  1490  						Namespace: "gateway-conformance-infra",
  1491  						Port: &model.BackendPort{
  1492  							Port: 8080,
  1493  						},
  1494  					},
  1495  				},
  1496  				ResponseHeaderModifier: &model.HTTPHeaderFilter{
  1497  					HeadersToSet: []model.Header{
  1498  						{
  1499  							Name:  "X-Header-Set",
  1500  							Value: "set-overwrites-values",
  1501  						},
  1502  					},
  1503  				},
  1504  			},
  1505  			{
  1506  				PathMatch: model.StringMatch{Prefix: "/add"},
  1507  				Backends: []model.Backend{
  1508  					{
  1509  						Name:      "infra-backend-v1",
  1510  						Namespace: "gateway-conformance-infra",
  1511  						Port: &model.BackendPort{
  1512  							Port: 8080,
  1513  						},
  1514  					},
  1515  				},
  1516  				ResponseHeaderModifier: &model.HTTPHeaderFilter{
  1517  					HeadersToAdd: []model.Header{
  1518  						{
  1519  							Name:  "X-Header-Add",
  1520  							Value: "add-appends-values",
  1521  						},
  1522  					},
  1523  				},
  1524  			},
  1525  			{
  1526  				PathMatch: model.StringMatch{Prefix: "/remove"},
  1527  				Backends: []model.Backend{
  1528  					{
  1529  						Name:      "infra-backend-v1",
  1530  						Namespace: "gateway-conformance-infra",
  1531  						Port: &model.BackendPort{
  1532  							Port: 8080,
  1533  						},
  1534  					},
  1535  				},
  1536  				ResponseHeaderModifier: &model.HTTPHeaderFilter{
  1537  					HeadersToRemove: []string{"X-Header-Remove"},
  1538  				},
  1539  			},
  1540  			{
  1541  				PathMatch: model.StringMatch{Prefix: "/multiple"},
  1542  				Backends: []model.Backend{
  1543  					{
  1544  						Name:      "infra-backend-v1",
  1545  						Namespace: "gateway-conformance-infra",
  1546  						Port: &model.BackendPort{
  1547  							Port: 8080,
  1548  						},
  1549  					},
  1550  				},
  1551  				ResponseHeaderModifier: &model.HTTPHeaderFilter{
  1552  					HeadersToAdd: []model.Header{
  1553  						{
  1554  							Name:  "X-Header-Add-1",
  1555  							Value: "header-add-1",
  1556  						},
  1557  						{
  1558  							Name:  "X-Header-Add-2",
  1559  							Value: "header-add-2",
  1560  						},
  1561  						{
  1562  							Name:  "X-Header-Add-3",
  1563  							Value: "header-add-3",
  1564  						},
  1565  					},
  1566  					HeadersToSet: []model.Header{
  1567  						{
  1568  							Name:  "X-Header-Set-1",
  1569  							Value: "header-set-1",
  1570  						},
  1571  						{
  1572  							Name:  "X-Header-Set-2",
  1573  							Value: "header-set-2",
  1574  						},
  1575  					},
  1576  					HeadersToRemove: []string{
  1577  						"X-Header-Remove-1",
  1578  						"X-Header-Remove-2",
  1579  					},
  1580  				},
  1581  			},
  1582  			{
  1583  				PathMatch: model.StringMatch{Prefix: "/case-insensitivity"},
  1584  				Backends: []model.Backend{
  1585  					{
  1586  						Name:      "infra-backend-v1",
  1587  						Namespace: "gateway-conformance-infra",
  1588  						Port: &model.BackendPort{
  1589  							Port: 8080,
  1590  						},
  1591  					},
  1592  				},
  1593  				ResponseHeaderModifier: &model.HTTPHeaderFilter{
  1594  					HeadersToAdd: []model.Header{
  1595  						{
  1596  							Name:  "X-Header-Add",
  1597  							Value: "header-add",
  1598  						},
  1599  						{
  1600  							Name:  "x-lowercase-add",
  1601  							Value: "lowercase-add",
  1602  						},
  1603  						{
  1604  							Name:  "x-Mixedcase-ADD-1",
  1605  							Value: "mixedcase-add-1",
  1606  						},
  1607  						{
  1608  							Name:  "X-mixeDcase-add-2",
  1609  							Value: "mixedcase-add-2",
  1610  						},
  1611  						{
  1612  							Name:  "X-UPPERCASE-ADD",
  1613  							Value: "uppercase-add",
  1614  						},
  1615  					},
  1616  					HeadersToSet: []model.Header{
  1617  						{
  1618  							Name:  "X-Header-Set",
  1619  							Value: "header-set",
  1620  						},
  1621  					},
  1622  					HeadersToRemove: []string{
  1623  						"X-Header-Remove",
  1624  					},
  1625  				},
  1626  			},
  1627  		},
  1628  	},
  1629  }
  1630  
  1631  var backendRefsResponseHeaderModifierHTTPInput = Input{
  1632  	GatewayClass: gatewayv1.GatewayClass{},
  1633  	Gateway:      sameNamespaceGateway,
  1634  	HTTPRoutes:   backendRefsResponseHeaderModifierHTTPRoutes,
  1635  	Services:     allServices,
  1636  }
  1637  
  1638  var backendRefsResponseHeaderModifierHTTPListeners = []model.HTTPListener{
  1639  	{
  1640  		Name: "http",
  1641  		Sources: []model.FullyQualifiedResource{
  1642  			{
  1643  				Name:      "same-namespace",
  1644  				Namespace: "gateway-conformance-infra",
  1645  			},
  1646  		},
  1647  		Port: 80, Hostname: "*",
  1648  		Routes: []model.HTTPRoute{
  1649  			{
  1650  				PathMatch: model.StringMatch{Prefix: "/set"},
  1651  				Backends: []model.Backend{
  1652  					{
  1653  						Name:      "infra-backend-v1",
  1654  						Namespace: "gateway-conformance-infra",
  1655  						Port: &model.BackendPort{
  1656  							Port: 8080,
  1657  						},
  1658  					},
  1659  				},
  1660  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  1661  					{
  1662  						Name: "gateway-conformance-infra:infra-backend-v1:8080",
  1663  						ResponseHeaderModifier: &model.HTTPHeaderFilter{
  1664  							HeadersToSet: []model.Header{
  1665  								{
  1666  									Name:  "X-Header-Set",
  1667  									Value: "set-overwrites-values",
  1668  								},
  1669  							},
  1670  						},
  1671  					},
  1672  				},
  1673  			},
  1674  			{
  1675  				PathMatch: model.StringMatch{Prefix: "/add"},
  1676  				Backends: []model.Backend{
  1677  					{
  1678  						Name:      "infra-backend-v1",
  1679  						Namespace: "gateway-conformance-infra",
  1680  						Port: &model.BackendPort{
  1681  							Port: 8080,
  1682  						},
  1683  					},
  1684  				},
  1685  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  1686  					{
  1687  						Name: "gateway-conformance-infra:infra-backend-v1:8080",
  1688  						ResponseHeaderModifier: &model.HTTPHeaderFilter{
  1689  							HeadersToAdd: []model.Header{
  1690  								{
  1691  									Name:  "X-Header-Add",
  1692  									Value: "add-appends-values",
  1693  								},
  1694  							},
  1695  						},
  1696  					},
  1697  				},
  1698  			},
  1699  			{
  1700  				PathMatch: model.StringMatch{Prefix: "/remove"},
  1701  				Backends: []model.Backend{
  1702  					{
  1703  						Name:      "infra-backend-v1",
  1704  						Namespace: "gateway-conformance-infra",
  1705  						Port: &model.BackendPort{
  1706  							Port: 8080,
  1707  						},
  1708  					},
  1709  				},
  1710  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  1711  					{
  1712  						Name: "gateway-conformance-infra:infra-backend-v1:8080",
  1713  						ResponseHeaderModifier: &model.HTTPHeaderFilter{
  1714  							HeadersToRemove: []string{"X-Header-Remove"},
  1715  						},
  1716  					},
  1717  				},
  1718  			},
  1719  			{
  1720  				PathMatch: model.StringMatch{Prefix: "/multiple"},
  1721  				Backends: []model.Backend{
  1722  					{
  1723  						Name:      "infra-backend-v1",
  1724  						Namespace: "gateway-conformance-infra",
  1725  						Port: &model.BackendPort{
  1726  							Port: 8080,
  1727  						},
  1728  					},
  1729  				},
  1730  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  1731  					{
  1732  						Name: "gateway-conformance-infra:infra-backend-v1:8080",
  1733  						ResponseHeaderModifier: &model.HTTPHeaderFilter{
  1734  							HeadersToAdd: []model.Header{
  1735  								{
  1736  									Name:  "X-Header-Add-1",
  1737  									Value: "header-add-1",
  1738  								},
  1739  								{
  1740  									Name:  "X-Header-Add-2",
  1741  									Value: "header-add-2",
  1742  								},
  1743  								{
  1744  									Name:  "X-Header-Add-3",
  1745  									Value: "header-add-3",
  1746  								},
  1747  							},
  1748  							HeadersToSet: []model.Header{
  1749  								{
  1750  									Name:  "X-Header-Set-1",
  1751  									Value: "header-set-1",
  1752  								},
  1753  								{
  1754  									Name:  "X-Header-Set-2",
  1755  									Value: "header-set-2",
  1756  								},
  1757  							},
  1758  							HeadersToRemove: []string{
  1759  								"X-Header-Remove-1",
  1760  								"X-Header-Remove-2",
  1761  							},
  1762  						},
  1763  					},
  1764  				},
  1765  			},
  1766  			{
  1767  				PathMatch: model.StringMatch{Prefix: "/multiple-backends"},
  1768  				Backends: []model.Backend{
  1769  					{
  1770  						Name:      "infra-backend-v1",
  1771  						Namespace: "gateway-conformance-infra",
  1772  						Port: &model.BackendPort{
  1773  							Port: 8080,
  1774  						},
  1775  					},
  1776  					{
  1777  						Name:      "infra-backend-v2",
  1778  						Namespace: "gateway-conformance-infra",
  1779  						Port: &model.BackendPort{
  1780  							Port: 8080,
  1781  						},
  1782  					},
  1783  					{
  1784  						Name:      "infra-backend-v3",
  1785  						Namespace: "gateway-conformance-infra",
  1786  						Port: &model.BackendPort{
  1787  							Port: 8080,
  1788  						},
  1789  					},
  1790  				},
  1791  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  1792  					{
  1793  						Name: "gateway-conformance-infra:infra-backend-v1:8080",
  1794  						ResponseHeaderModifier: &model.HTTPHeaderFilter{
  1795  							HeadersToAdd: []model.Header{
  1796  								{
  1797  									Name:  "X-Header-Add-1",
  1798  									Value: "header-add-1",
  1799  								},
  1800  							},
  1801  							HeadersToSet: []model.Header{
  1802  								{
  1803  									Name:  "X-Header-Set-1",
  1804  									Value: "header-set-1",
  1805  								},
  1806  							},
  1807  							HeadersToRemove: []string{
  1808  								"X-Header-Remove-1",
  1809  							},
  1810  						},
  1811  					},
  1812  					{
  1813  						Name: "gateway-conformance-infra:infra-backend-v2:8080",
  1814  						ResponseHeaderModifier: &model.HTTPHeaderFilter{
  1815  							HeadersToAdd: []model.Header{
  1816  								{
  1817  									Name:  "X-Header-Add-2",
  1818  									Value: "header-add-2",
  1819  								},
  1820  							},
  1821  							HeadersToSet: []model.Header{
  1822  								{
  1823  									Name:  "X-Header-Set-2",
  1824  									Value: "header-set-2",
  1825  								},
  1826  							},
  1827  							HeadersToRemove: []string{
  1828  								"X-Header-Remove-2",
  1829  							},
  1830  						},
  1831  					},
  1832  					{
  1833  						Name: "gateway-conformance-infra:infra-backend-v3:8080",
  1834  						ResponseHeaderModifier: &model.HTTPHeaderFilter{
  1835  							HeadersToAdd: []model.Header{
  1836  								{
  1837  									Name:  "X-Header-Add-3",
  1838  									Value: "header-add-3",
  1839  								},
  1840  							},
  1841  							HeadersToSet: []model.Header{
  1842  								{
  1843  									Name:  "X-Header-Set-3",
  1844  									Value: "header-set-3",
  1845  								},
  1846  							},
  1847  							HeadersToRemove: []string{
  1848  								"X-Header-Remove-3",
  1849  							},
  1850  						},
  1851  					},
  1852  				},
  1853  			},
  1854  			{
  1855  				PathMatch: model.StringMatch{Prefix: "/case-insensitivity"},
  1856  				Backends: []model.Backend{
  1857  					{
  1858  						Name:      "infra-backend-v1",
  1859  						Namespace: "gateway-conformance-infra",
  1860  						Port: &model.BackendPort{
  1861  							Port: 8080,
  1862  						},
  1863  					},
  1864  				},
  1865  				BackendHTTPFilters: []*model.BackendHTTPFilter{
  1866  					{
  1867  						Name: "gateway-conformance-infra:infra-backend-v1:8080",
  1868  						ResponseHeaderModifier: &model.HTTPHeaderFilter{
  1869  							HeadersToAdd: []model.Header{
  1870  								{
  1871  									Name:  "X-Header-Add",
  1872  									Value: "header-add",
  1873  								},
  1874  								{
  1875  									Name:  "x-lowercase-add",
  1876  									Value: "lowercase-add",
  1877  								},
  1878  								{
  1879  									Name:  "x-Mixedcase-ADD-1",
  1880  									Value: "mixedcase-add-1",
  1881  								},
  1882  								{
  1883  									Name:  "X-mixeDcase-add-2",
  1884  									Value: "mixedcase-add-2",
  1885  								},
  1886  								{
  1887  									Name:  "X-UPPERCASE-ADD",
  1888  									Value: "uppercase-add",
  1889  								},
  1890  							},
  1891  							HeadersToSet: []model.Header{
  1892  								{
  1893  									Name:  "X-Header-Set",
  1894  									Value: "header-set",
  1895  								},
  1896  							},
  1897  							HeadersToRemove: []string{
  1898  								"X-Header-Remove",
  1899  							},
  1900  						},
  1901  					},
  1902  				},
  1903  			},
  1904  		},
  1905  	},
  1906  }
  1907  
  1908  var rewriteHostHTTPInput = Input{
  1909  	GatewayClass: gatewayv1.GatewayClass{},
  1910  	Gateway:      sameNamespaceGateway,
  1911  	HTTPRoutes:   rewriteHostHTTPRoutes,
  1912  	Services:     allServices,
  1913  }
  1914  
  1915  var rewriteHostHTTPListeners = []model.HTTPListener{
  1916  	{
  1917  		Name: "http",
  1918  		Sources: []model.FullyQualifiedResource{
  1919  			{
  1920  				Name:      "same-namespace",
  1921  				Namespace: "gateway-conformance-infra",
  1922  			},
  1923  		},
  1924  		Port:     80,
  1925  		Hostname: "*",
  1926  		Routes: []model.HTTPRoute{
  1927  			{
  1928  				Hostnames: []string{"rewrite.example"},
  1929  				PathMatch: model.StringMatch{Prefix: "/one"},
  1930  				Backends: []model.Backend{
  1931  					{
  1932  						Name:      "infra-backend-v1",
  1933  						Namespace: "gateway-conformance-infra",
  1934  						Port: &model.BackendPort{
  1935  							Port: 8080,
  1936  						},
  1937  					},
  1938  				},
  1939  				Rewrite: &model.HTTPURLRewriteFilter{
  1940  					HostName: model.AddressOf("one.example.org"),
  1941  				},
  1942  			},
  1943  			{
  1944  				Hostnames: []string{"rewrite.example"},
  1945  				Backends: []model.Backend{
  1946  					{
  1947  						Name:      "infra-backend-v2",
  1948  						Namespace: "gateway-conformance-infra",
  1949  						Port: &model.BackendPort{
  1950  							Port: 8080,
  1951  						},
  1952  					},
  1953  				},
  1954  				Rewrite: &model.HTTPURLRewriteFilter{
  1955  					HostName: model.AddressOf("example.org"),
  1956  				},
  1957  			},
  1958  		},
  1959  	},
  1960  }
  1961  
  1962  var rewritePathHTTPInput = Input{
  1963  	GatewayClass: gatewayv1.GatewayClass{},
  1964  	Gateway:      sameNamespaceGateway,
  1965  	HTTPRoutes:   rewritePathHTTPRoutes,
  1966  	Services:     allServices,
  1967  }
  1968  
  1969  var rewritePathHTTPListeners = []model.HTTPListener{
  1970  	{
  1971  		Name: "http",
  1972  		Sources: []model.FullyQualifiedResource{
  1973  			{
  1974  				Name:      "same-namespace",
  1975  				Namespace: "gateway-conformance-infra",
  1976  			},
  1977  		},
  1978  		Port:     80,
  1979  		Hostname: "*",
  1980  		Routes: []model.HTTPRoute{
  1981  			{
  1982  				PathMatch: model.StringMatch{Prefix: "/prefix/one"},
  1983  				Backends: []model.Backend{
  1984  					{
  1985  						Name:      "infra-backend-v1",
  1986  						Namespace: "gateway-conformance-infra",
  1987  						Port: &model.BackendPort{
  1988  							Port: 8080,
  1989  						},
  1990  					},
  1991  				},
  1992  				Rewrite: &model.HTTPURLRewriteFilter{
  1993  					Path: &model.StringMatch{
  1994  						Prefix: "/one",
  1995  					},
  1996  				},
  1997  			},
  1998  			{
  1999  				PathMatch: model.StringMatch{Prefix: "/full/one"},
  2000  				Backends: []model.Backend{
  2001  					{
  2002  						Name:      "infra-backend-v1",
  2003  						Namespace: "gateway-conformance-infra",
  2004  						Port: &model.BackendPort{
  2005  							Port: 8080,
  2006  						},
  2007  					},
  2008  				},
  2009  				Rewrite: &model.HTTPURLRewriteFilter{
  2010  					Path: &model.StringMatch{
  2011  						Exact: "/one",
  2012  					},
  2013  				},
  2014  			},
  2015  			{
  2016  				PathMatch: model.StringMatch{Prefix: "/full/rewrite-path-and-modify-headers"},
  2017  				Backends: []model.Backend{
  2018  					{
  2019  						Name:      "infra-backend-v1",
  2020  						Namespace: "gateway-conformance-infra",
  2021  						Port: &model.BackendPort{
  2022  							Port: 8080,
  2023  						},
  2024  					},
  2025  				},
  2026  				Rewrite: &model.HTTPURLRewriteFilter{
  2027  					Path: &model.StringMatch{
  2028  						Exact: "/test",
  2029  					},
  2030  				},
  2031  				RequestHeaderFilter: &model.HTTPHeaderFilter{
  2032  					HeadersToAdd: []model.Header{
  2033  						{
  2034  							Name:  "X-Header-Add",
  2035  							Value: "header-val-1",
  2036  						},
  2037  						{
  2038  							Name:  "X-Header-Add-Append",
  2039  							Value: "header-val-2",
  2040  						},
  2041  					},
  2042  					HeadersToSet: []model.Header{
  2043  						{
  2044  							Name:  "X-Header-Set",
  2045  							Value: "set-overwrites-values",
  2046  						},
  2047  					},
  2048  					HeadersToRemove: []string{"X-Header-Remove"},
  2049  				},
  2050  			},
  2051  			{
  2052  				PathMatch: model.StringMatch{Prefix: "/prefix/rewrite-path-and-modify-headers"},
  2053  				Backends: []model.Backend{
  2054  					{
  2055  						Name:      "infra-backend-v1",
  2056  						Namespace: "gateway-conformance-infra",
  2057  						Port: &model.BackendPort{
  2058  							Port: 8080,
  2059  						},
  2060  					},
  2061  				},
  2062  				Rewrite: &model.HTTPURLRewriteFilter{
  2063  					Path: &model.StringMatch{
  2064  						Prefix: "/prefix",
  2065  					},
  2066  				},
  2067  				RequestHeaderFilter: &model.HTTPHeaderFilter{
  2068  					HeadersToAdd: []model.Header{
  2069  						{
  2070  							Name:  "X-Header-Add",
  2071  							Value: "header-val-1",
  2072  						},
  2073  						{
  2074  							Name:  "X-Header-Add-Append",
  2075  							Value: "header-val-2",
  2076  						},
  2077  					},
  2078  					HeadersToSet: []model.Header{
  2079  						{
  2080  							Name:  "X-Header-Set",
  2081  							Value: "set-overwrites-values",
  2082  						},
  2083  					},
  2084  					HeadersToRemove: []string{"X-Header-Remove"},
  2085  				},
  2086  			},
  2087  		},
  2088  	},
  2089  }
  2090  
  2091  var mirrorHTTPInput = Input{
  2092  	GatewayClass: gatewayv1.GatewayClass{},
  2093  	Gateway:      sameNamespaceGateway,
  2094  	HTTPRoutes:   mirrorPathHTTPRoutes,
  2095  	Services:     allServices,
  2096  }
  2097  
  2098  var mirrorHTTPListeners = []model.HTTPListener{
  2099  	{
  2100  		Name: "http",
  2101  		Sources: []model.FullyQualifiedResource{
  2102  			{
  2103  				Name:      "same-namespace",
  2104  				Namespace: "gateway-conformance-infra",
  2105  			},
  2106  		},
  2107  		Port:     80,
  2108  		Hostname: "*",
  2109  		Routes: []model.HTTPRoute{
  2110  			{
  2111  				PathMatch: model.StringMatch{Prefix: "/mirror"},
  2112  				Backends: []model.Backend{
  2113  					{
  2114  						Name:      "infra-backend-v1",
  2115  						Namespace: "gateway-conformance-infra",
  2116  						Port: &model.BackendPort{
  2117  							Port: 8080,
  2118  						},
  2119  					},
  2120  				},
  2121  				RequestMirrors: []*model.HTTPRequestMirror{
  2122  					{
  2123  						Backend: &model.Backend{
  2124  							Name:      "infra-backend-v2",
  2125  							Namespace: "gateway-conformance-infra",
  2126  							Port: &model.BackendPort{
  2127  								Port: 8080,
  2128  							},
  2129  						},
  2130  					},
  2131  				},
  2132  			},
  2133  		},
  2134  	},
  2135  }
  2136  
  2137  var (
  2138  	basicGRPC = Input{
  2139  		GatewayClass: gatewayv1.GatewayClass{},
  2140  		Gateway: gatewayv1.Gateway{
  2141  			TypeMeta: metav1.TypeMeta{
  2142  				Kind:       "Gateway",
  2143  				APIVersion: "gateway.networking.k8s.io/v1beta1",
  2144  			},
  2145  			ObjectMeta: metav1.ObjectMeta{
  2146  				Name:      "my-gateway",
  2147  				Namespace: "default",
  2148  			},
  2149  			Spec: gatewayv1.GatewaySpec{
  2150  				Listeners: []gatewayv1.Listener{
  2151  					{
  2152  						Name:     "prod-web-gw",
  2153  						Port:     80,
  2154  						Protocol: gatewayv1.HTTPProtocolType,
  2155  					},
  2156  				},
  2157  			},
  2158  		},
  2159  		GRPCRoutes: []gatewayv1.GRPCRoute{
  2160  			{
  2161  				ObjectMeta: metav1.ObjectMeta{
  2162  					Name:      "grpc-route",
  2163  					Namespace: "default",
  2164  				},
  2165  				Spec: gatewayv1.GRPCRouteSpec{
  2166  					CommonRouteSpec: gatewayv1.CommonRouteSpec{
  2167  						ParentRefs: []gatewayv1.ParentReference{
  2168  							{
  2169  								Name: "my-gateway",
  2170  							},
  2171  						},
  2172  					},
  2173  					Hostnames: []gatewayv1.Hostname{
  2174  						"example.com",
  2175  					},
  2176  					Rules: []gatewayv1.GRPCRouteRule{
  2177  						{
  2178  							Matches: []gatewayv1.GRPCRouteMatch{
  2179  								{
  2180  									Method: &gatewayv1.GRPCMethodMatch{
  2181  										Type:    model.AddressOf[gatewayv1.GRPCMethodMatchType](gatewayv1.GRPCMethodMatchExact),
  2182  										Service: model.AddressOf("service.Echo"),
  2183  										Method:  model.AddressOf("Ping"),
  2184  									},
  2185  								},
  2186  							},
  2187  							BackendRefs: []gatewayv1.GRPCBackendRef{
  2188  								{
  2189  									BackendRef: gatewayv1.BackendRef{
  2190  										BackendObjectReference: gatewayv1.BackendObjectReference{
  2191  											Name: "grp-service",
  2192  											Port: model.AddressOf[gatewayv1.PortNumber](8080),
  2193  										},
  2194  									},
  2195  								},
  2196  							},
  2197  						},
  2198  					},
  2199  				},
  2200  			},
  2201  		},
  2202  		Services: []corev1.Service{
  2203  			{
  2204  				ObjectMeta: metav1.ObjectMeta{
  2205  					Name:      "grp-service",
  2206  					Namespace: "default",
  2207  				},
  2208  			},
  2209  		},
  2210  	}
  2211  
  2212  	basicGRPCListeners = []model.HTTPListener{
  2213  		{
  2214  			Name: "prod-web-gw",
  2215  			Sources: []model.FullyQualifiedResource{
  2216  				{
  2217  					Name:      "my-gateway",
  2218  					Namespace: "default",
  2219  					Group:     "gateway.networking.k8s.io",
  2220  					Version:   "v1beta1",
  2221  					Kind:      "Gateway",
  2222  				},
  2223  			},
  2224  			Address:  "",
  2225  			Port:     80,
  2226  			Hostname: "*",
  2227  			Routes: []model.HTTPRoute{
  2228  				{
  2229  					Hostnames: []string{"example.com"},
  2230  					PathMatch: model.StringMatch{
  2231  						Exact: "/service.Echo/Ping",
  2232  					},
  2233  					Backends: []model.Backend{
  2234  						{
  2235  							Name:      "grp-service",
  2236  							Namespace: "default",
  2237  							Port: &model.BackendPort{
  2238  								Port: 8080,
  2239  							},
  2240  						},
  2241  					},
  2242  					IsGRPC: true,
  2243  				},
  2244  			},
  2245  		},
  2246  	}
  2247  )
  2248  
  2249  func TestHTTPGatewayAPI(t *testing.T) {
  2250  	tests := map[string]struct {
  2251  		input Input
  2252  		want  []model.HTTPListener
  2253  	}{
  2254  		"basic http": {
  2255  			input: basicHTTP,
  2256  			want:  basicHTTPListeners,
  2257  		},
  2258  		"Conformance/HTTPRouteSimpleSameNamespace": {
  2259  			input: simpleSameNamespaceHTTPInput,
  2260  			want:  simpleSameNamespaceHTTPListeners,
  2261  		},
  2262  		"Conformance/HTTPRouteCrossNamespace": {
  2263  			input: crossNamespaceHTTPInput,
  2264  			want:  crossNamespaceHTTPListeners,
  2265  		},
  2266  		"Conformance/HTTPExactPathMatching": {
  2267  			input: exactPathMatchingHTTPInput,
  2268  			want:  exactPathMatchingHTTPListeners,
  2269  		},
  2270  		"Conformance/HTTPRouteHeaderMatching": {
  2271  			input: headerMatchingHTTPInput,
  2272  			want:  headerMatchingHTTPListeners,
  2273  		},
  2274  		"Conformance/HTTPRouteHostnameIntersection": {
  2275  			input: hostnameIntersectionHTTPInput,
  2276  			want:  hostnameIntersectionHTTPListeners,
  2277  		},
  2278  		"Conformance/HTTPRouteListenerHostnameMatching": {
  2279  			input: listenerHostnameMatchingHTTPInput,
  2280  			want:  listenerHostnameMatchingHTTPListeners,
  2281  		},
  2282  		"Conformance/HTTPRouteMatchingAcrossRoutes": {
  2283  			input: matchingAcrossHTTPInput,
  2284  			want:  matchingAcrossHTTPListeners,
  2285  		},
  2286  		"Conformance/HTTPRouteMatching": {
  2287  			input: matchingHTTPInput,
  2288  			want:  matchingHTTPListeners,
  2289  		},
  2290  		"Conformance/HTTPRouteMethodMatching": {
  2291  			input: methodMatchingHTTPInput,
  2292  			want:  methodMatchingHTTPListeners,
  2293  		},
  2294  		"Conformance/HTTPRouteQueryParamMatching": {
  2295  			input: queryParamMatchingHTTPInput,
  2296  			want:  queryParamMatchingHTTPListeners,
  2297  		},
  2298  		"Conformance/HTTPRouteRequestHeaderModifier": {
  2299  			input: requestHeaderModifierHTTPInput,
  2300  			want:  requestHeaderModifierHTTPListeners,
  2301  		},
  2302  		"Conformance/HTTPRouteBackendRefsRequestHeaderModifier": {
  2303  			input: backendRefsRequestHeaderModifierHTTPInput,
  2304  			want:  backendRefsRequestHeaderModifierHTTPListeners,
  2305  		},
  2306  		"Conformance/HTTPRouteRequestRedirect": {
  2307  			input: requestRedirectHTTPInput,
  2308  			want:  requestRedirectHTTPListeners,
  2309  		},
  2310  		"Conformance/HTTPRouteResponseHeaderModifier": {
  2311  			input: responseHeaderModifierHTTPInput,
  2312  			want:  responseHeaderModifierHTTPListeners,
  2313  		},
  2314  		"Conformance/HTTPRouteBackendRefsResponseHeaderModifier": {
  2315  			input: backendRefsResponseHeaderModifierHTTPInput,
  2316  			want:  backendRefsResponseHeaderModifierHTTPListeners,
  2317  		},
  2318  		"Conformance/HTTPRouteRewriteHost": {
  2319  			input: rewriteHostHTTPInput,
  2320  			want:  rewriteHostHTTPListeners,
  2321  		},
  2322  		"Conformance/HTTPRouteRewritePath": {
  2323  			input: rewritePathHTTPInput,
  2324  			want:  rewritePathHTTPListeners,
  2325  		},
  2326  		"Conformance/HTTPRouteRequestMirror": {
  2327  			input: mirrorHTTPInput,
  2328  			want:  mirrorHTTPListeners,
  2329  		},
  2330  	}
  2331  
  2332  	for name, tc := range tests {
  2333  		t.Run(name, func(t *testing.T) {
  2334  			listeners, _ := GatewayAPI(tc.input)
  2335  			assert.Equal(t, tc.want, listeners, "Listeners did not match")
  2336  		})
  2337  	}
  2338  }
  2339  
  2340  func TestTLSGatewayAPI(t *testing.T) {
  2341  	tests := map[string]struct {
  2342  		input Input
  2343  		want  []model.TLSPassthroughListener
  2344  	}{
  2345  		"basic http": {
  2346  			input: basicTLS,
  2347  			want:  basicTLSListeners,
  2348  		},
  2349  		"Conformance/TLSRouteSimpleSameNamespace": {
  2350  			input: simpleSameNamespaceTLS,
  2351  			want:  simpleSameNamespaceTLSListeners,
  2352  		},
  2353  	}
  2354  
  2355  	for name, tc := range tests {
  2356  		t.Run(name, func(t *testing.T) {
  2357  			_, listeners := GatewayAPI(tc.input)
  2358  			assert.Equal(t, tc.want, listeners, "Listeners did not match")
  2359  		})
  2360  	}
  2361  }
  2362  
  2363  func TestGRPCGatewayAPI(t *testing.T) {
  2364  	tests := map[string]struct {
  2365  		input Input
  2366  		want  []model.HTTPListener
  2367  	}{
  2368  		"basic grpc": {
  2369  			input: basicGRPC,
  2370  			want:  basicGRPCListeners,
  2371  		},
  2372  	}
  2373  
  2374  	for name, tc := range tests {
  2375  		t.Run(name, func(t *testing.T) {
  2376  			listeners, _ := GatewayAPI(tc.input)
  2377  			assert.Equal(t, tc.want, listeners, "Listeners did not match")
  2378  		})
  2379  	}
  2380  }