@@ -18,13 +18,17 @@ package ingress
1818
1919import (
2020 "context"
21+ "errors"
2122 "fmt"
2223 "testing"
2324 "time"
2425
2526 corev1 "k8s.io/api/core/v1"
27+ apierrs "k8s.io/apimachinery/pkg/api/errors"
2628 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29+ "k8s.io/apimachinery/pkg/labels"
2730 "k8s.io/apimachinery/pkg/runtime"
31+ "k8s.io/apimachinery/pkg/runtime/schema"
2832 "k8s.io/apimachinery/pkg/types"
2933 clientgotesting "k8s.io/client-go/testing"
3034 "k8s.io/utils/ptr"
@@ -47,6 +51,7 @@ import (
4751
4852 gatewayapi "sigs.k8s.io/gateway-api/apis/v1"
4953 gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
54+ gatewaylisters "sigs.k8s.io/gateway-api/pkg/client/listers/apis/v1"
5055
5156 . "knative.dev/net-gateway-api/pkg/reconciler/testing"
5257 . "knative.dev/pkg/reconciler/testing"
@@ -196,6 +201,103 @@ func TestReconcile(t *testing.T) {
196201 httpRoute (t , ing (withBasicSpec , withGatewayAPIclass ), httpRouteReady ),
197202 }, servicesAndEndpoints ... ),
198203 // no extra update
204+ }, {
205+ Name : "prune stale HTTPRoute when rule removed" ,
206+ Key : "ns/name" ,
207+ Objects : append ([]runtime.Object {
208+ ing (withBasicSpec , withGatewayAPIclass , withFinalizer , makeItReady ),
209+ httpRoute (t , ing (withBasicSpec , withGatewayAPIclass ), httpRouteReady ),
210+ HTTPRoute {
211+ Name : "stale.example.com" ,
212+ Namespace : "ns" ,
213+ Hostname : "stale.example.com" ,
214+ }.Build (),
215+ }, servicesAndEndpoints ... ),
216+ WantDeletes : []clientgotesting.DeleteActionImpl {
217+ clientgotesting .NewDeleteAction (
218+ schema.GroupVersionResource {
219+ Group : "gateway.networking.k8s.io" ,
220+ Version : "v1" ,
221+ Resource : "httproutes" ,
222+ },
223+ "ns" ,
224+ "stale.example.com" ,
225+ ),
226+ },
227+ }, {
228+ Name : "prune skips non-owned HTTPRoute" ,
229+ Key : "ns/name" ,
230+ Objects : append (func () []runtime.Object {
231+ route := HTTPRoute {
232+ Name : "stale.example.com" ,
233+ Namespace : "ns" ,
234+ Hostname : "stale.example.com" ,
235+ }.Build ()
236+ // Remove owner so it is not controlled by this Ingress
237+ route .OwnerReferences = nil
238+ return []runtime.Object {
239+ ing (withBasicSpec , withGatewayAPIclass , withFinalizer , makeItReady ),
240+ httpRoute (t , ing (withBasicSpec , withGatewayAPIclass ), httpRouteReady ),
241+ route ,
242+ }
243+ }(), servicesAndEndpoints ... ),
244+ // No deletes expected
245+ WantDeletes : []clientgotesting.DeleteActionImpl {},
246+ }, {
247+ Name : "prune list error bubbles up" ,
248+ Key : "ns/name" ,
249+ Ctx : withHTTPRouteListError (),
250+ Objects : append ([]runtime.Object {
251+ ing (withBasicSpec , withGatewayAPIclass , withFinalizer , makeItReady ),
252+ }, servicesAndEndpoints ... ),
253+ WantCreates : []runtime.Object {
254+ httpRoute (t , ing (withBasicSpec , withGatewayAPIclass )),
255+ },
256+ WantStatusUpdates : []clientgotesting.UpdateActionImpl {{
257+ Object : ing (withBasicSpec , withGatewayAPIclass , withFinalizer , makeItReady , func (i * v1alpha1.Ingress ) {
258+ i .Status .MarkIngressNotReady ("ReconcileIngressFailed" , "Ingress reconciliation failed" )
259+ }),
260+ }},
261+ WantEvents : []string {
262+ Eventf (corev1 .EventTypeNormal , "Created" , "Created HTTPRoute \" example.com\" " ),
263+ Eventf (corev1 .EventTypeWarning , "InternalError" , `failed to list HTTPRoutes: forced list error` ),
264+ },
265+ WantErr : true ,
266+ }, {
267+ Name : "prune delete NotFound tolerated" ,
268+ Key : "ns/name" ,
269+ WithReactors : []clientgotesting.ReactionFunc {
270+ func (a clientgotesting.Action ) (bool , runtime.Object , error ) {
271+ if a .GetVerb () == "delete" && a .GetResource ().Resource == "httproutes" {
272+ name := a .(clientgotesting.DeleteActionImpl ).Name
273+ return true , nil , apierrs .NewNotFound (
274+ schema.GroupResource {Group : "gateway.networking.k8s.io" , Resource : "httproutes" },
275+ name ,
276+ )
277+ }
278+ return false , nil , nil
279+ },
280+ },
281+ Objects : append ([]runtime.Object {
282+ ing (withBasicSpec , withGatewayAPIclass , withFinalizer , makeItReady ),
283+ httpRoute (t , ing (withBasicSpec , withGatewayAPIclass ), httpRouteReady ),
284+ HTTPRoute {
285+ Name : "stale.example.com" ,
286+ Namespace : "ns" ,
287+ Hostname : "stale.example.com" ,
288+ }.Build (),
289+ }, servicesAndEndpoints ... ),
290+ WantDeletes : []clientgotesting.DeleteActionImpl {
291+ clientgotesting .NewDeleteAction (
292+ schema.GroupVersionResource {
293+ Group : "gateway.networking.k8s.io" ,
294+ Version : "v1" ,
295+ Resource : "httproutes" ,
296+ },
297+ "ns" ,
298+ "stale.example.com" ,
299+ ),
300+ },
199301 }}
200302
201303 table .Test (t , MakeFactory (func (ctx context.Context , listers * Listers , cmw configmap.Watcher ) controller.Reconciler {
@@ -214,6 +316,11 @@ func TestReconcile(t *testing.T) {
214316 },
215317 }
216318
319+ // Force HTTPRoute List error when test context requests it.
320+ if ctx .Value (httpRouteListErrorKey {}) == true {
321+ r .httprouteLister = errorWrapHTTPRouteLister {inner : listers .GetHTTPRouteLister ()}
322+ }
323+
217324 ingr := ingressreconciler .NewReconciler (ctx , logging .FromContext (ctx ), fakeingressclient .Get (ctx ),
218325 listers .GetIngressLister (), controller .GetEventRecorder (ctx ), r , gatewayAPIIngressClassName ,
219326 controller.Options {
@@ -226,6 +333,38 @@ func TestReconcile(t *testing.T) {
226333 }))
227334}
228335
336+ // --- helpers for forcing lister errors in specific tests ---
337+
338+ type httpRouteListErrorKey struct {}
339+
340+ func withHTTPRouteListError () context.Context {
341+ return context .WithValue (context .Background (), httpRouteListErrorKey {}, true )
342+ }
343+
344+ type errorWrapHTTPRouteNamespaceLister struct {
345+ inner gatewaylisters.HTTPRouteNamespaceLister
346+ }
347+
348+ func (e errorWrapHTTPRouteNamespaceLister ) List (selector labels.Selector ) ([]* gatewayapi.HTTPRoute , error ) {
349+ return nil , errors .New ("forced list error" )
350+ }
351+
352+ func (e errorWrapHTTPRouteNamespaceLister ) Get (name string ) (* gatewayapi.HTTPRoute , error ) {
353+ return e .inner .Get (name )
354+ }
355+
356+ type errorWrapHTTPRouteLister struct {
357+ inner gatewaylisters.HTTPRouteLister
358+ }
359+
360+ func (e errorWrapHTTPRouteLister ) List (selector labels.Selector ) ([]* gatewayapi.HTTPRoute , error ) {
361+ return e .inner .List (selector )
362+ }
363+
364+ func (e errorWrapHTTPRouteLister ) HTTPRoutes (namespace string ) gatewaylisters.HTTPRouteNamespaceLister {
365+ return errorWrapHTTPRouteNamespaceLister {inner : e .inner .HTTPRoutes (namespace )}
366+ }
367+
229368func TestReconcileTLS (t * testing.T ) {
230369 // The gateway API annoyingly has a number of
231370 secretName := "name-WE-STICK-A-LONG-UID-HERE"
0 commit comments