Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions related_images.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@
"image": "registry.redhat.io/openshift-lightspeed/lightspeed-operator-bundle@sha256:2ca4638bfc967b0a623c7c6f4170765a38662189653a343b5de5cbd8e26d9595",
"revision": "e8383723a47af947ec49f3d01659d65065c66c86"
}

]
116 changes: 116 additions & 0 deletions test/e2e/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ func (c *Client) WaitForDeploymentRollout(dep *appsv1.Deployment) error {
dep.Status.Replicas, dep.Status.UpdatedReplicas)
}
if dep.Status.UnavailableReplicas != 0 {
c.ShowUnavailablePodsOfDeployment(dep)
return false, fmt.Errorf("got %d unavailable replicas",
dep.Status.UnavailableReplicas)
}
Expand Down Expand Up @@ -199,6 +200,121 @@ func (c *Client) WaitForDeploymentCondition(dep *appsv1.Deployment, condition fu
return nil
}

func (c *Client) ShowUnavailablePodsOfDeployment(dep *appsv1.Deployment) error {
err := c.Get(dep)
if err != nil {
return fmt.Errorf("failed to get deployment %s/%s: %w", dep.GetNamespace(), dep.GetName(), err)
}

selector, err := metav1.LabelSelectorAsSelector(dep.Spec.Selector)
if err != nil {
return fmt.Errorf("failed to parse deployment selector: %w", err)
}

pods := &corev1.PodList{}
err = c.List(pods, client.InNamespace(dep.GetNamespace()), client.MatchingLabelsSelector{
Selector: selector,
})
if err != nil {
return fmt.Errorf("failed to list pods for deployment %s/%s: %w", dep.GetNamespace(), dep.GetName(), err)
}

if len(pods.Items) == 0 {
logf.Log.Info("No pods found for deployment", "deployment", fmt.Sprintf("%s/%s", dep.GetNamespace(), dep.GetName()))
return nil
}

// Find unavailable pods
unavailablePods := []corev1.Pod{}
for _, pod := range pods.Items {
isAvailable := false

// A pod is considered available if it's running and ready
if pod.Status.Phase == corev1.PodRunning && !c.isPodTerminating(&pod) {
for _, condition := range pod.Status.Conditions {
if condition.Type == corev1.PodReady && condition.Status == corev1.ConditionTrue {
isAvailable = true
break
}
}
}

if !isAvailable {
unavailablePods = append(unavailablePods, pod)
}
}

// Log unavailable pods and their status messages
if len(unavailablePods) == 0 {
logf.Log.Info("All pods are available for deployment", "deployment", fmt.Sprintf("%s/%s", dep.GetNamespace(), dep.GetName()))
} else {
logf.Log.Info("Found unavailable pods", "deployment", fmt.Sprintf("%s/%s", dep.GetNamespace(), dep.GetName()), "count", len(unavailablePods))

for _, pod := range unavailablePods {
logf.Log.Info("Unavailable pod details",
"pod", pod.Name,
"phase", pod.Status.Phase,
"reason", pod.Status.Reason,
"message", pod.Status.Message,
)

// Show container statuses
for _, containerStatus := range pod.Status.ContainerStatuses {
logf.Log.Info("Container status",
"pod", pod.Name,
"container", containerStatus.Name,
"ready", containerStatus.Ready,
"restartCount", containerStatus.RestartCount,
)

if containerStatus.State.Waiting != nil {
logf.Log.Info("Container waiting",
"pod", pod.Name,
"container", containerStatus.Name,
"reason", containerStatus.State.Waiting.Reason,
"message", containerStatus.State.Waiting.Message,
)
}

if containerStatus.State.Terminated != nil {
logf.Log.Info("Container terminated",
"pod", pod.Name,
"container", containerStatus.Name,
"reason", containerStatus.State.Terminated.Reason,
"message", containerStatus.State.Terminated.Message,
"exitCode", containerStatus.State.Terminated.ExitCode,
)
}

if containerStatus.LastTerminationState.Terminated != nil {
logf.Log.Info("Container last termination",
"pod", pod.Name,
"container", containerStatus.Name,
"reason", containerStatus.LastTerminationState.Terminated.Reason,
"message", containerStatus.LastTerminationState.Terminated.Message,
"exitCode", containerStatus.LastTerminationState.Terminated.ExitCode,
)
}
}

// Show pod conditions
for _, condition := range pod.Status.Conditions {
if condition.Status != corev1.ConditionTrue {
logf.Log.Info("Pod condition not met",
"pod", pod.Name,
"type", condition.Type,
"status", condition.Status,
"reason", condition.Reason,
"message", condition.Message,
)
}
}
}
}

return nil
}

func (c *Client) WaitForConfigMapContainString(cm *corev1.ConfigMap, key, substr string) error {
var lastErr error
err := wait.PollUntilContextTimeout(c.ctx, DefaultPollInterval, c.conditionCheckTimeout, true, func(ctx context.Context) (bool, error) {
Expand Down