pkg/health/controller_test.go
Rama main · réplica de lectura del repositorio original.
package health
import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"testing"
)
// makePodWithStatus constructs a minimal Pod with the container statuses
// summarizeControllerHealth inspects. Phase + ContainerStatuses are the
// only fields the function reads.
func makePodWithStatus(phase corev1.PodPhase, statuses ...corev1.ContainerStatus) *corev1.Pod {
return &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "pod"},
Status: corev1.PodStatus{Phase: phase, ContainerStatuses: statuses},
}
}
// TestSummarizeControllerHealth pins the exact wording of the
// finalizer-owner status string. The output is concatenated into the
// lifecycle Issue's Cause field surfaced to operators, so a copy-paste
// regression that changed "1 pod ready" to "1 pods ready" or "Healthy"
// to "healthy" is part of the user-visible contract — assertions are
// exact-match on purpose.
func TestSummarizeControllerHealth(t *testing.T) {
ready := corev1.ContainerStatus{Ready: true, State: corev1.ContainerState{Running: &corev1.ContainerStateRunning{}}}
notReady := corev1.ContainerStatus{Ready: false}
crashing := corev1.ContainerStatus{Ready: false, State: corev1.ContainerState{Waiting: &corev1.ContainerStateWaiting{Reason: "CrashLoopBackOff"}}}
erroring := corev1.ContainerStatus{Ready: false, State: corev1.ContainerState{Waiting: &corev1.ContainerStateWaiting{Reason: "Error"}}}
tests := []struct {
name string
pods []*corev1.Pod
want string
}{
{
name: "single ready pod uses singular form",
pods: []*corev1.Pod{makePodWithStatus(corev1.PodRunning, ready)},
want: "argocd-application-controller is healthy (1 pod ready)",
},
{
name: "two ready pods uses plural form",
pods: []*corev1.Pod{
makePodWithStatus(corev1.PodRunning, ready),
makePodWithStatus(corev1.PodRunning, ready),
},
want: "argocd-application-controller is healthy (2 pods ready)",
},
{
name: "any crashloop pod dominates aggregate",
pods: []*corev1.Pod{
makePodWithStatus(corev1.PodRunning, ready),
makePodWithStatus(corev1.PodRunning, crashing),
},
want: "argocd-application-controller is CrashLoopBackOff (1/2 pods)",
},
{
name: "Error reason surfaces alongside crashing count",
pods: []*corev1.Pod{makePodWithStatus(corev1.PodRunning, erroring)},
want: "argocd-application-controller is Error (1/1 pods)",
},
{
name: "all pending and zero ready reports pending",
pods: []*corev1.Pod{
makePodWithStatus(corev1.PodPending),
makePodWithStatus(corev1.PodPending),
},
want: "argocd-application-controller is pending start (2/2 pods Pending)",
},
{
name: "partial ready falls back to degraded",
pods: []*corev1.Pod{
makePodWithStatus(corev1.PodRunning, ready),
makePodWithStatus(corev1.PodRunning, notReady),
},
want: "argocd-application-controller is degraded (1/2 pods ready)",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := SummarizeControllerHealth("argocd-application-controller", tt.pods)
if got != tt.want {
t.Fatalf("summarizeControllerHealth =\n got: %q\n want: %q", got, tt.want)
}
})
}
}