@@ -53,15 +53,32 @@ var _ = g.Describe("[sig-network-edge][Feature:Router][apigroup:route.openshift.
5353 ctx := context .Background ()
5454 oc := exutil .NewCLIWithPodSecurityLevel ("router-dcm-ingress" , api .LevelPrivileged ).AsAdmin ()
5555 kubeClient := oc .AdminKubeClient ()
56+ routeClient := oc .AdminRouteClient ()
5657
5758 // variables updated on every new test
5859 var (
5960 execPod execPodRef
6061 controller types.NamespacedName
62+ routerPod types.NamespacedName
6163 routeSelectorSet labels.Set
6264 )
6365
6466 g .AfterEach (func () {
67+ if g .CurrentSpecReport ().Failed () {
68+ routes , _ := routeClient .RouteV1 ().Routes (oc .Namespace ()).List (ctx , metav1.ListOptions {})
69+ if routes != nil {
70+ outputIngress (routes .Items ... )
71+ }
72+ endpoints , _ := kubeClient .CoreV1 ().Endpoints (oc .Namespace ()).List (ctx , metav1.ListOptions {})
73+ if endpoints != nil {
74+ outputEndpoints (endpoints .Items ... )
75+ }
76+ epsList , _ := kubeClient .DiscoveryV1 ().EndpointSlices (oc .Namespace ()).List (ctx , metav1.ListOptions {})
77+ if epsList != nil {
78+ outputEndpointSlice (epsList .Items ... )
79+ }
80+ exutil .DumpPodLogsStartingWithInNamespace (routerPod .Name , routerPod .Namespace , oc )
81+ }
6582 if controller .Name != "" {
6683 err := oc .AdminOperatorClient ().OperatorV1 ().IngressControllers (controller .Namespace ).Delete (ctx , controller .Name , * metav1 .NewDeleteOptions (1 ))
6784 o .Expect (err ).NotTo (o .HaveOccurred ())
@@ -73,7 +90,7 @@ var _ = g.Describe("[sig-network-edge][Feature:Router][apigroup:route.openshift.
7390 nsOperator := "openshift-ingress-operator"
7491 controllerName := names .SimpleNameGenerator .GenerateName ("e2e-dcm-" )
7592
76- // ... and its router is created on router's namespace
93+ // ... and its router and service are created in router's namespace
7794 nsRouter := "openshift-ingress"
7895 svcName := "router-internal-" + controllerName
7996
@@ -134,12 +151,15 @@ var _ = g.Describe("[sig-network-edge][Feature:Router][apigroup:route.openshift.
134151 if utilnet .IsIPv6String (pods .Items [0 ].Status .PodIP ) {
135152 loopback = "::1"
136153 }
154+
155+ routerPod = types.NamespacedName {
156+ Namespace : pods .Items [0 ].Namespace ,
157+ Name : pods .Items [0 ].Name ,
158+ }
159+
137160 execPod = execPodRef {
138- NamespacedName : types.NamespacedName {
139- Namespace : pods .Items [0 ].Namespace ,
140- Name : pods .Items [0 ].Name ,
141- },
142- ipAddress : loopback ,
161+ NamespacedName : routerPod ,
162+ ipAddress : loopback ,
143163 }
144164 })
145165
@@ -471,6 +491,7 @@ var _ = g.Describe("[sig-network-edge][Feature:Router][apigroup:route.openshift.
471491
472492 // ... k8s recreates it and we wait it to be fully functional
473493 err = builder .waitDeployment (replicas , dcmIngressTimeout )
494+ builder .printDeploymentState (ctx )
474495 o .Expect (err ).NotTo (o .HaveOccurred ())
475496 }
476497
@@ -682,7 +703,7 @@ func execPodReadURL(execPod execPodRef, host string, secure bool, abspath string
682703 port = 443
683704 }
684705 uri := fmt .Sprintf ("%s://%s:%d%s" , proto , host , port , abspath )
685- cmd := fmt .Sprintf ("curl -ksS -m 5 -w '\n %%{http_code}' --resolve %s:%d:%s %q" , host , port , execPod .ipAddress , uri )
706+ cmd := fmt .Sprintf ("curl -ksS --max-time %d -w '\n %%{http_code}' --resolve %s:%d:%s %q" , fastTimeoutSeconds , host , port , execPod .ipAddress , uri )
686707 output , err = e2eoutput .RunHostCmd (execPod .Namespace , execPod .Name , cmd )
687708
688709 // Checking for curl's "(52) empty response from server", this means a FIN or RST from the server side.
@@ -778,7 +799,12 @@ func (r *routeStackBuilder) createDeploymentStack(ctx context.Context, routetype
778799 if err = r .waitDeployment (replicas , timeout ); err != nil {
779800 return nil , err
780801 }
781- return r .exposeDeployment (ctx )
802+ backendServers , err = r .exposeDeployment (ctx )
803+ if err != nil {
804+ return nil , err
805+ }
806+ r .printDeploymentState (ctx )
807+ return backendServers , nil
782808}
783809
784810// scaleDeployment scales-in/out the common deployment to the specified replicas. It waits for all the pods to be created and returns their names.
@@ -796,6 +822,7 @@ func (r *routeStackBuilder) scaleDeployment(ctx context.Context, replicas int, t
796822 }
797823 return len (backendServers ) == replicas , nil
798824 })
825+ r .printDeploymentState (ctx )
799826 return backendServers , err
800827}
801828
@@ -824,7 +851,14 @@ func (r *routeStackBuilder) createDetachedService(ctx context.Context) (serviceN
824851 }
825852
826853 // we also need the deprecated Endpoints API, since router still uses it depending on the ROUTER_WATCH_ENDPOINTS envvar
827- epCurrent , err := r .kubeClient .CoreV1 ().Endpoints (svcCurrent .Namespace ).Get (ctx , svcCurrent .Name , metav1.GetOptions {})
854+ var epCurrent * corev1.Endpoints
855+ err = wait .PollUntilContextTimeout (ctx , time .Second , fastTimeoutSeconds * time .Second , false , func (ctx context.Context ) (done bool , err error ) {
856+ epCurrent , err = r .kubeClient .CoreV1 ().Endpoints (svcCurrent .Namespace ).Get (ctx , svcCurrent .Name , metav1.GetOptions {})
857+ if err != nil {
858+ framework .Logf ("error fetching Endpoints: %s" , err .Error ())
859+ }
860+ return err == nil , nil
861+ })
828862 if err != nil {
829863 return "" , err
830864 }
@@ -841,7 +875,7 @@ func (r *routeStackBuilder) createDetachedService(ctx context.Context) (serviceN
841875 }
842876
843877 // EndpointSlice use to be created as soon as the Endpoints resource is created. Lets wait for it, and create ourselves in case it is missing
844- err = wait .PollUntilContextTimeout (ctx , time .Second , 5 * time .Second , false , func (ctx context.Context ) (done bool , err error ) {
878+ err = wait .PollUntilContextTimeout (ctx , time .Second , fastTimeoutSeconds * time .Second , false , func (ctx context.Context ) (done bool , err error ) {
845879 _ , err = r .fetchEndpointSlice (ctx , serviceName )
846880 if err != nil {
847881 framework .Logf ("error fetching EndpointSlice: %s" , err .Error ())
@@ -910,7 +944,7 @@ func (r *routeStackBuilder) scaleInEndpoints(ctx context.Context, detachedServic
910944 if err != nil {
911945 return err
912946 }
913- // deleting addresses, from all subnets , whose IP address is not found in the patched `eps`
947+ // deleting addresses, from all subsets , whose IP address is not found in the patched `eps`
914948 for i := range ep .Subsets {
915949 ss := & ep .Subsets [i ]
916950 ss .Addresses = slices .DeleteFunc (ss .Addresses , func (addr corev1.EndpointAddress ) bool {
@@ -953,6 +987,25 @@ func (r *routeStackBuilder) exposeDeployment(ctx context.Context) (backendServer
953987 return r .fetchServiceReplicas (ctx )
954988}
955989
990+ // printDeploymentState outputs the pod names, status, and their IP addresses. Best effort, it outputs the error instead in case it happens.
991+ // It requires that `exposeDeployment()` was already called.
992+ func (r * routeStackBuilder ) printDeploymentState (ctx context.Context ) {
993+ pods , err := r .fetchPods (ctx )
994+ if err != nil {
995+ framework .Logf ("deployment state: error reading deployment pods: %v" , err )
996+ return
997+ }
998+ var podDescription []string
999+ for _ , pod := range pods {
1000+ var podIPs []string
1001+ for _ , ip := range pod .Status .PodIPs {
1002+ podIPs = append (podIPs , ip .IP )
1003+ }
1004+ podDescription = append (podDescription , fmt .Sprintf ("%s/%s/%s" , pod .Name , pod .Status .Phase , strings .Join (podIPs , "," )))
1005+ }
1006+ framework .Logf ("deployment state: replicas=%d pods=%s" , len (pods ), strings .Join (podDescription , " // " ))
1007+ }
1008+
9561009// fetchEndpointSlice fetches the EndpointSlice of the provided service name. It currently supports only one EndpointSlice instance for simplicity.
9571010func (r * routeStackBuilder ) fetchEndpointSlice (ctx context.Context , serviceName string ) (* discoveryv1.EndpointSlice , error ) {
9581011 listOpts := metav1.ListOptions {LabelSelector : discoveryv1 .LabelServiceName + "=" + serviceName }
@@ -967,8 +1020,8 @@ func (r *routeStackBuilder) fetchEndpointSlice(ctx context.Context, serviceName
9671020 return & epsList .Items [0 ], nil
9681021}
9691022
970- // fetchServiceReplicas fetches the pod names from the exposed common deployment. It requires that `exposeDeployment()` was already called.
971- func (r * routeStackBuilder ) fetchServiceReplicas (ctx context.Context ) ([]string , error ) {
1023+ // fetchPods fetches the pods from the exposed common deployment. It requires that `exposeDeployment()` was already called.
1024+ func (r * routeStackBuilder ) fetchPods (ctx context.Context ) ([]corev1. Pod , error ) {
9721025 svc , err := r .kubeClient .CoreV1 ().Services (r .namespace ).Get (ctx , r .resourceName , metav1.GetOptions {})
9731026 if err != nil {
9741027 return nil , err
@@ -978,9 +1031,18 @@ func (r *routeStackBuilder) fetchServiceReplicas(ctx context.Context) ([]string,
9781031 if err != nil {
9791032 return nil , err
9801033 }
981- backendServers := make ([]string , len (pods .Items ))
982- for i := range pods .Items {
983- backendServers [i ] = pods .Items [i ].Name
1034+ return pods .Items , nil
1035+ }
1036+
1037+ // fetchServiceReplicas fetches the pod names from the exposed common deployment. It requires that `exposeDeployment()` was already called.
1038+ func (r * routeStackBuilder ) fetchServiceReplicas (ctx context.Context ) ([]string , error ) {
1039+ pods , err := r .fetchPods (ctx )
1040+ if err != nil {
1041+ return nil , err
1042+ }
1043+ backendServers := make ([]string , len (pods ))
1044+ for i := range pods {
1045+ backendServers [i ] = pods [i ].Name
9841046 }
9851047 return backendServers , nil
9861048}
0 commit comments