package agent import "testing" // lookupFixed returns a lookupUID func that maps pod names to UIDs. // An empty UID in the map means "pod found but no UID" (legacy entry). // A missing key means "pod not found on this node". func lookupFixed(m map[string]string) func(ns, name string) (string, bool) { return func(_, name string) (string, bool) { uid, found := m[name] return uid, found } } func TestOrphanedCommitted_PodAbsent(t *testing.T) { allocs := []Allocation{{ ContainerID: "c1", Namespace: "ns", PodName: "gitea-0", OwnerUID: "uid-old", State: StateCommitted, IP6: "2001:db8::1", }} // Pod not on this node at all. got := orphanedCommitted(allocs, lookupFixed(map[string]string{})) if len(got) != 1 || got[0].ContainerID != "c1" { t.Fatalf("expected 1 orphan, got %v", got) } } func TestOrphanedCommitted_UIDMismatch(t *testing.T) { // Pod name re-used: informer has a newer pod with a different UID. allocs := []Allocation{{ ContainerID: "c1", Namespace: "ns", PodName: "gitea-0", OwnerUID: "uid-old", State: StateCommitted, IP6: "2001:db8::1", }} got := orphanedCommitted(allocs, lookupFixed(map[string]string{ "gitea-0": "uid-new", })) if len(got) != 1 || got[0].ContainerID != "c1" { t.Fatalf("expected 1 orphan on UID mismatch, got %v", got) } } func TestOrphanedCommitted_LivePod(t *testing.T) { // Matching UID — pod is live; must not be reported as orphan. allocs := []Allocation{{ ContainerID: "c1", Namespace: "ns", PodName: "gitea-0", OwnerUID: "uid-live", State: StateCommitted, IP6: "2001:db8::1", }} got := orphanedCommitted(allocs, lookupFixed(map[string]string{ "gitea-0": "uid-live", })) if len(got) != 0 { t.Fatalf("live pod must not be orphaned, got %v", got) } } func TestOrphanedCommitted_PendingSkipped(t *testing.T) { // Pending entries are excluded (handled by separate startup GC). allocs := []Allocation{{ ContainerID: "c1", Namespace: "ns", PodName: "pod-a", OwnerUID: "uid-x", State: StatePending, IP6: "2001:db8::1", }} got := orphanedCommitted(allocs, lookupFixed(map[string]string{})) if len(got) != 0 { t.Fatalf("pending must be skipped, got %v", got) } } func TestOrphanedCommitted_EmptyOwnerUID_PodFound(t *testing.T) { // Legacy allocation with empty OwnerUID: if the pod is found, do NOT // treat it as orphaned (can't verify ownership without UID). allocs := []Allocation{{ ContainerID: "c1", Namespace: "ns", PodName: "gitea-0", OwnerUID: "", State: StateCommitted, IP6: "2001:db8::1", }} got := orphanedCommitted(allocs, lookupFixed(map[string]string{ "gitea-0": "uid-any", })) if len(got) != 0 { t.Fatalf("empty OwnerUID with found pod must not be orphaned, got %v", got) } } func TestOrphanedCommitted_EmptyOwnerUID_PodAbsent(t *testing.T) { // Legacy allocation with empty OwnerUID: if the pod is absent, it IS // orphaned (pod is gone from this node regardless of UID). allocs := []Allocation{{ ContainerID: "c1", Namespace: "ns", PodName: "gitea-0", OwnerUID: "", State: StateCommitted, IP6: "2001:db8::1", }} got := orphanedCommitted(allocs, lookupFixed(map[string]string{})) if len(got) != 1 { t.Fatalf("empty OwnerUID with absent pod must be orphaned, got %v", got) } } func TestOrphanedCommitted_Mixed(t *testing.T) { // Three committed allocations: one live, one absent, one UID-mismatched. allocs := []Allocation{ {ContainerID: "live", Namespace: "ns", PodName: "pod-live", OwnerUID: "uid-live", State: StateCommitted}, {ContainerID: "absent", Namespace: "ns", PodName: "pod-absent", OwnerUID: "uid-gone", State: StateCommitted}, {ContainerID: "replaced", Namespace: "ns", PodName: "pod-replaced", OwnerUID: "uid-old", State: StateCommitted}, } got := orphanedCommitted(allocs, lookupFixed(map[string]string{ "pod-live": "uid-live", "pod-replaced": "uid-new", })) if len(got) != 2 { t.Fatalf("expected 2 orphans, got %d: %v", len(got), got) } seen := map[string]bool{} for _, a := range got { seen[a.ContainerID] = true } if !seen["absent"] || !seen["replaced"] { t.Fatalf("wrong orphan set: %v", got) } }