package k8s import ( "context" "testing" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" ) func TestGetClusterStatus_Nodes(t *testing.T) { cs := fake.NewSimpleClientset( &corev1.Node{ ObjectMeta: metav1.ObjectMeta{Name: "node-1"}, Status: corev1.NodeStatus{ Conditions: []corev1.NodeCondition{ {Type: corev1.NodeReady, Status: corev1.ConditionTrue}, }, Capacity: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("8"), corev1.ResourceMemory: resource.MustParse("32Gi"), }, Allocatable: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("7800m"), corev1.ResourceMemory: resource.MustParse("30Gi"), }, }, }, &corev1.Node{ ObjectMeta: metav1.ObjectMeta{Name: "node-2"}, Status: corev1.NodeStatus{ Conditions: []corev1.NodeCondition{ {Type: corev1.NodeReady, Status: corev1.ConditionFalse}, }, Capacity: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("4"), corev1.ResourceMemory: resource.MustParse("16Gi"), }, Allocatable: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("3800m"), corev1.ResourceMemory: resource.MustParse("14Gi"), }, }, }, ) client := NewClientWithClientset(cs, nil, Config{}) status, err := client.GetClusterStatus(context.Background()) if err != nil { t.Fatalf("unexpected error: %v", err) } if len(status.Nodes) != 2 { t.Fatalf("expected 2 nodes, got %d", len(status.Nodes)) } n1 := status.Nodes[0] if n1.Name != "node-1" { t.Fatalf("expected node-1, got %s", n1.Name) } if n1.Status != "Ready" { t.Fatalf("expected Ready, got %s", n1.Status) } if n1.CPUCapacity != "8" { t.Fatalf("expected CPU capacity 8, got %s", n1.CPUCapacity) } n2 := status.Nodes[1] if n2.Status != "NotReady" { t.Fatalf("expected NotReady, got %s", n2.Status) } // Check totals: 8 + 4 = 12 CPU, 7800m + 3800m = 11600m allocatable if status.Total.CPUCapacity != "12" { t.Fatalf("expected total CPU capacity 12, got %s", status.Total.CPUCapacity) } } func TestGetClusterStatus_EmptyCluster(t *testing.T) { cs := fake.NewSimpleClientset() client := NewClientWithClientset(cs, nil, Config{}) status, err := client.GetClusterStatus(context.Background()) if err != nil { t.Fatalf("unexpected error: %v", err) } if len(status.Nodes) != 0 { t.Fatalf("expected 0 nodes, got %d", len(status.Nodes)) } } func TestGetClusterStatus_NodeWithNoReadyCondition(t *testing.T) { cs := fake.NewSimpleClientset( &corev1.Node{ ObjectMeta: metav1.ObjectMeta{Name: "node-unknown"}, Status: corev1.NodeStatus{ Conditions: []corev1.NodeCondition{ {Type: corev1.NodeMemoryPressure, Status: corev1.ConditionFalse}, }, Capacity: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("4"), corev1.ResourceMemory: resource.MustParse("8Gi"), }, Allocatable: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("4"), corev1.ResourceMemory: resource.MustParse("8Gi"), }, }, }, ) client := NewClientWithClientset(cs, nil, Config{}) status, err := client.GetClusterStatus(context.Background()) if err != nil { t.Fatalf("unexpected error: %v", err) } if status.Nodes[0].Status != "Unknown" { t.Fatalf("expected Unknown, got %s", status.Nodes[0].Status) } } func TestGetCacheStats_AllBound(t *testing.T) { cs := fake.NewSimpleClientset( &corev1.PersistentVolumeClaim{ ObjectMeta: metav1.ObjectMeta{Name: "verdaccio-storage", Namespace: "dev-infra"}, Status: corev1.PersistentVolumeClaimStatus{ Phase: corev1.ClaimBound, Capacity: corev1.ResourceList{corev1.ResourceStorage: resource.MustParse("10Gi")}, }, }, &corev1.PersistentVolumeClaim{ ObjectMeta: metav1.ObjectMeta{Name: "athens-storage", Namespace: "dev-infra"}, Status: corev1.PersistentVolumeClaimStatus{ Phase: corev1.ClaimBound, Capacity: corev1.ResourceList{corev1.ResourceStorage: resource.MustParse("10Gi")}, }, }, &corev1.PersistentVolumeClaim{ ObjectMeta: metav1.ObjectMeta{Name: "cargo-proxy-cache", Namespace: "dev-infra"}, Status: corev1.PersistentVolumeClaimStatus{ Phase: corev1.ClaimBound, Capacity: corev1.ResourceList{corev1.ResourceStorage: resource.MustParse("10Gi")}, }, }, ) client := NewClientWithClientset(cs, nil, Config{}) stats, err := client.GetCacheStats(context.Background()) if err != nil { t.Fatalf("unexpected error: %v", err) } if len(stats) != 3 { t.Fatalf("expected 3 cache stats, got %d", len(stats)) } for _, s := range stats { if s.Status != "Bound" { t.Fatalf("expected Bound for %s, got %s", s.Name, s.Status) } if s.Capacity != "10Gi" { t.Fatalf("expected 10Gi capacity for %s, got %s", s.Name, s.Capacity) } } } func TestGetCacheStats_MissingPVC(t *testing.T) { // Only verdaccio exists cs := fake.NewSimpleClientset( &corev1.PersistentVolumeClaim{ ObjectMeta: metav1.ObjectMeta{Name: "verdaccio-storage", Namespace: "dev-infra"}, Status: corev1.PersistentVolumeClaimStatus{ Phase: corev1.ClaimBound, Capacity: corev1.ResourceList{corev1.ResourceStorage: resource.MustParse("10Gi")}, }, }, ) client := NewClientWithClientset(cs, nil, Config{}) stats, err := client.GetCacheStats(context.Background()) if err != nil { t.Fatalf("unexpected error: %v", err) } if len(stats) != 3 { t.Fatalf("expected 3 entries, got %d", len(stats)) } for _, s := range stats { switch s.Name { case "verdaccio": if s.Status != "Bound" { t.Fatalf("expected Bound for verdaccio, got %s", s.Status) } case "athens", "cargo-proxy": if s.Status != "NotFound" { t.Fatalf("expected NotFound for %s, got %s", s.Name, s.Status) } } } } func TestGetCacheStats_EmptyCluster(t *testing.T) { cs := fake.NewSimpleClientset() client := NewClientWithClientset(cs, nil, Config{}) stats, err := client.GetCacheStats(context.Background()) if err != nil { t.Fatalf("unexpected error: %v", err) } if len(stats) != 3 { t.Fatalf("expected 3 entries, got %d", len(stats)) } for _, s := range stats { if s.Status != "NotFound" { t.Fatalf("expected NotFound for %s, got %s", s.Name, s.Status) } } }