Просмотр исходного кода

Fix scraper test

Signed-off-by: Sean Holcomb <seanholcomb@gmail.com>
Sean Holcomb 4 недель назад
Родитель
Сommit
1a975a857f
1 измененных файлов с 910 добавлено и 5 удалено
  1. 910 5
      modules/collector-source/pkg/scrape/clustercache_test.go

+ 910 - 5
modules/collector-source/pkg/scrape/clustercache_test.go

@@ -422,6 +422,7 @@ func Test_kubernetesScraper_scrapePods(t *testing.T) {
 	}
 	tests := []struct {
 		name     string
+		nsSetup  func(*SyncMap[string, types.UID])
 		scrapes  []scrape
 		expected []metric.Update
 	}{
@@ -653,12 +654,205 @@ func Test_kubernetesScraper_scrapePods(t *testing.T) {
 				},
 			},
 		},
+		{
+			name: "with namespace index",
+			nsSetup: func(nsIndex *SyncMap[string, types.UID]) {
+				nsIndex.Set("namespace1", "ns-uuid1")
+			},
+			scrapes: []scrape{
+				{
+					Pods: []*clustercache.Pod{
+						{
+							Name:      "pod1",
+							Namespace: "namespace1",
+							UID:       "uuid1",
+							Spec: clustercache.PodSpec{
+								NodeName: "node1",
+								Containers: []clustercache.Container{
+									{
+										Name: "container1",
+										Resources: v1.ResourceRequirements{
+											Requests: map[v1.ResourceName]resource.Quantity{
+												v1.ResourceCPU:    resource.MustParse("500m"),
+												v1.ResourceMemory: resource.MustParse("512"),
+											},
+											Limits: map[v1.ResourceName]resource.Quantity{
+												v1.ResourceCPU:    resource.MustParse("1"),
+												v1.ResourceMemory: resource.MustParse("1024"),
+											},
+										},
+									},
+								},
+							},
+							Status: clustercache.PodStatus{
+								ContainerStatuses: []v1.ContainerStatus{
+									{
+										Name: "container1",
+										State: v1.ContainerState{
+											Running: &v1.ContainerStateRunning{},
+										},
+									},
+								},
+							},
+						},
+					},
+					Timestamp: start1,
+				},
+			},
+			expected: []metric.Update{
+				{
+					Name: metric.PodInfo,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.PodLabel:          "pod1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.NodeUIDLabel:      "",
+						source.NamespaceLabel:    "namespace1",
+						source.NodeLabel:         "node1",
+						source.InstanceLabel:     "node1",
+					},
+					Value: 0,
+					AdditionalInfo: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.PodLabel:          "pod1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.NodeUIDLabel:      "",
+						source.NamespaceLabel:    "namespace1",
+						source.NodeLabel:         "node1",
+						source.InstanceLabel:     "node1",
+					},
+				},
+				{
+					Name: metric.KubePodLabels,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.PodLabel:          "pod1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.NodeUIDLabel:      "",
+						source.NamespaceLabel:    "namespace1",
+						source.NodeLabel:         "node1",
+						source.InstanceLabel:     "node1",
+					},
+					Value:          0,
+					AdditionalInfo: map[string]string{},
+				},
+				{
+					Name: metric.KubePodAnnotations,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.PodLabel:          "pod1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.NodeUIDLabel:      "",
+						source.NamespaceLabel:    "namespace1",
+						source.NodeLabel:         "node1",
+						source.InstanceLabel:     "node1",
+					},
+					Value:          0,
+					AdditionalInfo: map[string]string{},
+				},
+				{
+					Name: metric.KubePodContainerStatusRunning,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.PodLabel:          "pod1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.NodeUIDLabel:      "",
+						source.NamespaceLabel:    "namespace1",
+						source.NodeLabel:         "node1",
+						source.InstanceLabel:     "node1",
+						source.ContainerLabel:    "container1",
+					},
+					Value: 0,
+					AdditionalInfo: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.PodLabel:          "pod1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.NodeUIDLabel:      "",
+						source.NamespaceLabel:    "namespace1",
+						source.NodeLabel:         "node1",
+						source.InstanceLabel:     "node1",
+						source.ContainerLabel:    "container1",
+					},
+				},
+				{
+					Name: metric.KubePodContainerResourceRequests,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.PodLabel:          "pod1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.NodeUIDLabel:      "",
+						source.NamespaceLabel:    "namespace1",
+						source.NodeLabel:         "node1",
+						source.InstanceLabel:     "node1",
+						source.ContainerLabel:    "container1",
+						source.ResourceLabel:     "cpu",
+						source.UnitLabel:         "core",
+					},
+					Value:          0.5,
+					AdditionalInfo: nil,
+				},
+				{
+					Name: metric.KubePodContainerResourceRequests,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.PodLabel:          "pod1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.NodeUIDLabel:      "",
+						source.NamespaceLabel:    "namespace1",
+						source.NodeLabel:         "node1",
+						source.InstanceLabel:     "node1",
+						source.ContainerLabel:    "container1",
+						source.ResourceLabel:     "memory",
+						source.UnitLabel:         "byte",
+					},
+					Value:          512,
+					AdditionalInfo: nil,
+				},
+				{
+					Name: metric.KubePodContainerResourceLimits,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.PodLabel:          "pod1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.NodeUIDLabel:      "",
+						source.NamespaceLabel:    "namespace1",
+						source.NodeLabel:         "node1",
+						source.InstanceLabel:     "node1",
+						source.ContainerLabel:    "container1",
+						source.ResourceLabel:     "cpu",
+						source.UnitLabel:         "core",
+					},
+					Value:          1,
+					AdditionalInfo: nil,
+				},
+				{
+					Name: metric.KubePodContainerResourceLimits,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.PodLabel:          "pod1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.NodeUIDLabel:      "",
+						source.NamespaceLabel:    "namespace1",
+						source.NodeLabel:         "node1",
+						source.InstanceLabel:     "node1",
+						source.ContainerLabel:    "container1",
+						source.ResourceLabel:     "memory",
+						source.UnitLabel:         "byte",
+					},
+					Value:          1024,
+					AdditionalInfo: nil,
+				},
+			},
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			ks := &ClusterCacheScraper{}
 			nodeIndex := newSyncMap[string, types.UID](0)
 			nsIndex := newSyncMap[string, types.UID](0)
+			if tt.nsSetup != nil {
+				tt.nsSetup(nsIndex)
+			}
 			pvcIndex := newSyncMap[pvcKey, types.UID](0)
 			var scrapeResults []metric.Update
 			for _, s := range tt.scrapes {
@@ -690,6 +884,7 @@ func Test_kubernetesScraper_scrapePVCs(t *testing.T) {
 	}
 	tests := []struct {
 		name     string
+		nsSetup  func(*SyncMap[string, types.UID])
 		scrapes  []scrape
 		expected []metric.Update
 	}{
@@ -755,11 +950,79 @@ func Test_kubernetesScraper_scrapePVCs(t *testing.T) {
 				},
 			},
 		},
+		{
+			name: "with namespace index",
+			nsSetup: func(nsIndex *SyncMap[string, types.UID]) {
+				nsIndex.Set("namespace1", "ns-uuid1")
+			},
+			scrapes: []scrape{
+				{
+					PVCs: []*clustercache.PersistentVolumeClaim{
+						{
+							Name:      "pvc1",
+							Namespace: "namespace1",
+							UID:       "uuid1",
+							Spec: v1.PersistentVolumeClaimSpec{
+								VolumeName:       "vol1",
+								StorageClassName: util.Ptr("storageClass1"),
+								Resources: v1.VolumeResourceRequirements{
+									Requests: v1.ResourceList{
+										v1.ResourceStorage: resource.MustParse("4096"),
+									},
+								},
+							},
+						},
+					},
+					Timestamp: start1,
+				},
+			},
+			expected: []metric.Update{
+				{
+					Name: metric.KubePersistentVolumeClaimInfo,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.PVCLabel:          "pvc1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.NamespaceLabel:    "namespace1",
+						source.VolumeNameLabel:   "vol1",
+						source.PVUIDLabel:        "",
+						source.StorageClassLabel: "storageClass1",
+					},
+					Value: 0,
+					AdditionalInfo: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.PVCLabel:          "pvc1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.NamespaceLabel:    "namespace1",
+						source.VolumeNameLabel:   "vol1",
+						source.PVUIDLabel:        "",
+						source.StorageClassLabel: "storageClass1",
+					},
+				},
+				{
+					Name: metric.KubePersistentVolumeClaimResourceRequestsStorageBytes,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.PVCLabel:          "pvc1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.NamespaceLabel:    "namespace1",
+						source.VolumeNameLabel:   "vol1",
+						source.PVUIDLabel:        "",
+						source.StorageClassLabel: "storageClass1",
+					},
+					Value:          4096,
+					AdditionalInfo: nil,
+				},
+			},
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			ks := &ClusterCacheScraper{}
 			nsIndex := newSyncMap[string, types.UID](0)
+			if tt.nsSetup != nil {
+				tt.nsSetup(nsIndex)
+			}
 			pvIndex := newSyncMap[string, types.UID](0)
 			var scrapeResults []metric.Update
 			for _, s := range tt.scrapes {
@@ -973,6 +1236,7 @@ func Test_kubernetesScraper_scrapeStatefulSets(t *testing.T) {
 	}
 	tests := []struct {
 		name     string
+		nsSetup  func(*SyncMap[string, types.UID])
 		scrapes  []scrape
 		expected []metric.Update
 	}{
@@ -1053,11 +1317,86 @@ func Test_kubernetesScraper_scrapeStatefulSets(t *testing.T) {
 				},
 			},
 		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			ks := &ClusterCacheScraper{}
-			nsIndex := newSyncMap[string, types.UID](0)
+		{
+			// statefulSetInfo map is shared; NamespaceLabel is added before MatchLabels,
+			// so all 4 metrics reflect the final state including namespace_uid.
+			name: "with namespace index",
+			nsSetup: func(nsIndex *SyncMap[string, types.UID]) {
+				nsIndex.Set("namespace1", "ns-uuid1")
+			},
+			scrapes: []scrape{
+				{
+					StatefulSets: []*clustercache.StatefulSet{
+						{
+							Name:         "statefulSet1",
+							Namespace:    "namespace1",
+							UID:          "uuid1",
+							SpecSelector: &metav1.LabelSelector{},
+						},
+					},
+					Timestamp: start1,
+				},
+			},
+			expected: []metric.Update{
+				{
+					Name: metric.StatefulSetInfo,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.StatefulSetLabel:  "statefulSet1",
+						source.NamespaceLabel:    "namespace1",
+					},
+					Value: 0,
+					AdditionalInfo: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.StatefulSetLabel:  "statefulSet1",
+						source.NamespaceLabel:    "namespace1",
+					},
+				},
+				{
+					Name: metric.StatefulSetLabels,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.StatefulSetLabel:  "statefulSet1",
+						source.NamespaceLabel:    "namespace1",
+					},
+					Value:          0,
+					AdditionalInfo: map[string]string{},
+				},
+				{
+					Name: metric.StatefulSetAnnotations,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.StatefulSetLabel:  "statefulSet1",
+						source.NamespaceLabel:    "namespace1",
+					},
+					Value:          0,
+					AdditionalInfo: map[string]string{},
+				},
+				{
+					Name: metric.StatefulSetMatchLabels,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.StatefulSetLabel:  "statefulSet1",
+						source.NamespaceLabel:    "namespace1",
+					},
+					Value:          0,
+					AdditionalInfo: map[string]string{},
+				},
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			ks := &ClusterCacheScraper{}
+			nsIndex := newSyncMap[string, types.UID](0)
+			if tt.nsSetup != nil {
+				tt.nsSetup(nsIndex)
+			}
 			var scrapeResults []metric.Update
 			for _, s := range tt.scrapes {
 				res := ks.scrapeStatefulSets(s.StatefulSets, nsIndex)
@@ -1088,6 +1427,7 @@ func Test_kubernetesScraper_scrapeReplicaSets(t *testing.T) {
 	}
 	tests := []struct {
 		name     string
+		nsSetup  func(*SyncMap[string, types.UID])
 		scrapes  []scrape
 		expected []metric.Update
 	}{
@@ -1216,11 +1556,80 @@ func Test_kubernetesScraper_scrapeReplicaSets(t *testing.T) {
 				},
 			},
 		},
+		{
+			name: "with namespace index",
+			nsSetup: func(nsIndex *SyncMap[string, types.UID]) {
+				nsIndex.Set("namespace1", "ns-uuid1")
+			},
+			scrapes: []scrape{
+				{
+					ReplicaSets: []*clustercache.ReplicaSet{
+						{
+							Name:            "replicaSet1",
+							Namespace:       "namespace1",
+							UID:             "uuid1",
+							OwnerReferences: []metav1.OwnerReference{},
+						},
+					},
+					Timestamp: start1,
+				},
+			},
+			expected: []metric.Update{
+				{
+					Name: metric.ReplicaSetInfo,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.ReplicaSetLabel:   "replicaSet1",
+					},
+					Value: 0,
+					AdditionalInfo: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.ReplicaSetLabel:   "replicaSet1",
+					},
+				},
+				{
+					Name: metric.ReplicaSetLabels,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.ReplicaSetLabel:   "replicaSet1",
+					},
+					Value:          0,
+					AdditionalInfo: map[string]string{},
+				},
+				{
+					Name: metric.ReplicaSetAnnotations,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.ReplicaSetLabel:   "replicaSet1",
+					},
+					Value:          0,
+					AdditionalInfo: map[string]string{},
+				},
+				{
+					Name: metric.KubeReplicasetOwner,
+					Labels: map[string]string{
+						source.ReplicaSetLabel: "replicaSet1",
+						source.NamespaceLabel:  "namespace1",
+						source.UIDLabel:        "uuid1",
+						source.OwnerNameLabel:  source.NoneLabelValue,
+						source.OwnerKindLabel:  source.NoneLabelValue,
+					},
+					Value: 0,
+				},
+			},
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			ks := &ClusterCacheScraper{}
 			nsIndex := newSyncMap[string, types.UID](0)
+			if tt.nsSetup != nil {
+				tt.nsSetup(nsIndex)
+			}
 			var scrapeResults []metric.Update
 			for _, s := range tt.scrapes {
 				res := ks.scrapeReplicaSets(s.ReplicaSets, nsIndex)
@@ -1250,6 +1659,7 @@ func Test_kubernetesScraper_scrapeResourceQuotas(t *testing.T) {
 	}
 	tests := []struct {
 		name     string
+		nsSetup  func(*SyncMap[string, types.UID])
 		scrapes  []scrape
 		expected []metric.Update
 	}{
@@ -1396,12 +1806,66 @@ func Test_kubernetesScraper_scrapeResourceQuotas(t *testing.T) {
 				},
 			},
 		},
+		{
+			name: "with namespace index",
+			nsSetup: func(nsIndex *SyncMap[string, types.UID]) {
+				nsIndex.Set("namespace1", "ns-uuid1")
+			},
+			scrapes: []scrape{
+				{
+					ResourceQuotas: []*clustercache.ResourceQuota{
+						{
+							Name:      "resourceQuota1",
+							Namespace: "namespace1",
+							UID:       "uuid1",
+							Spec: v1.ResourceQuotaSpec{
+								Hard: v1.ResourceList{
+									v1.ResourceRequestsCPU: resource.MustParse("1"),
+								},
+							},
+						},
+					},
+					Timestamp: start1,
+				},
+			},
+			expected: []metric.Update{
+				{
+					Name: metric.ResourceQuotaInfo,
+					Labels: map[string]string{
+						source.UIDLabel:           "uuid1",
+						source.NamespaceUIDLabel:  "ns-uuid1",
+						source.ResourceQuotaLabel: "resourceQuota1",
+					},
+					Value: 0,
+					AdditionalInfo: map[string]string{
+						source.UIDLabel:           "uuid1",
+						source.NamespaceUIDLabel:  "ns-uuid1",
+						source.ResourceQuotaLabel: "resourceQuota1",
+					},
+				},
+				{
+					Name: metric.KubeResourceQuotaSpecResourceRequests,
+					Labels: map[string]string{
+						source.UIDLabel:           "uuid1",
+						source.NamespaceUIDLabel:  "ns-uuid1",
+						source.ResourceQuotaLabel: "resourceQuota1",
+						source.ResourceLabel:      "cpu",
+						source.UnitLabel:          "core",
+					},
+					Value:          1,
+					AdditionalInfo: nil,
+				},
+			},
+		},
 	}
 
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			ks := &ClusterCacheScraper{}
 			nsIndex := newSyncMap[string, types.UID](0)
+			if tt.nsSetup != nil {
+				tt.nsSetup(nsIndex)
+			}
 			var scrapeResults []metric.Update
 			for _, s := range tt.scrapes {
 				res := ks.scrapeResourceQuotas(s.ResourceQuotas, nsIndex)
@@ -1421,3 +1885,444 @@ func Test_kubernetesScraper_scrapeResourceQuotas(t *testing.T) {
 		})
 	}
 }
+
+func Test_kubernetesScraper_scrapeDaemonSets(t *testing.T) {
+	start1, _ := time.Parse(time.RFC3339, Start1Str)
+
+	type scrape struct {
+		DaemonSets []*clustercache.DaemonSet
+		Timestamp  time.Time
+	}
+	tests := []struct {
+		name     string
+		nsSetup  func(*SyncMap[string, types.UID])
+		scrapes  []scrape
+		expected []metric.Update
+	}{
+		{
+			name: "simple",
+			scrapes: []scrape{
+				{
+					DaemonSets: []*clustercache.DaemonSet{
+						{
+							Name:      "daemonSet1",
+							Namespace: "namespace1",
+							UID:       "uuid1",
+						},
+					},
+					Timestamp: start1,
+				},
+			},
+			expected: []metric.Update{
+				{
+					Name: metric.DaemonSetInfo,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "",
+						source.DaemonSetLabel:    "daemonSet1",
+					},
+					Value: 0,
+					AdditionalInfo: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "",
+						source.DaemonSetLabel:    "daemonSet1",
+					},
+				},
+				{
+					Name: metric.DaemonSetLabels,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "",
+						source.DaemonSetLabel:    "daemonSet1",
+					},
+					Value:          0,
+					AdditionalInfo: map[string]string{},
+				},
+				{
+					Name: metric.DaemonSetAnnotations,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "",
+						source.DaemonSetLabel:    "daemonSet1",
+					},
+					Value:          0,
+					AdditionalInfo: map[string]string{},
+				},
+			},
+		},
+		{
+			name: "with namespace index",
+			nsSetup: func(nsIndex *SyncMap[string, types.UID]) {
+				nsIndex.Set("namespace1", "ns-uuid1")
+			},
+			scrapes: []scrape{
+				{
+					DaemonSets: []*clustercache.DaemonSet{
+						{
+							Name:      "daemonSet1",
+							Namespace: "namespace1",
+							UID:       "uuid1",
+						},
+					},
+					Timestamp: start1,
+				},
+			},
+			expected: []metric.Update{
+				{
+					Name: metric.DaemonSetInfo,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.DaemonSetLabel:    "daemonSet1",
+					},
+					Value: 0,
+					AdditionalInfo: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.DaemonSetLabel:    "daemonSet1",
+					},
+				},
+				{
+					Name: metric.DaemonSetLabels,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.DaemonSetLabel:    "daemonSet1",
+					},
+					Value:          0,
+					AdditionalInfo: map[string]string{},
+				},
+				{
+					Name: metric.DaemonSetAnnotations,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.DaemonSetLabel:    "daemonSet1",
+					},
+					Value:          0,
+					AdditionalInfo: map[string]string{},
+				},
+			},
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			ks := &ClusterCacheScraper{}
+			nsIndex := newSyncMap[string, types.UID](0)
+			if tt.nsSetup != nil {
+				tt.nsSetup(nsIndex)
+			}
+			var scrapeResults []metric.Update
+			for _, s := range tt.scrapes {
+				res := ks.scrapeDaemonSets(s.DaemonSets, nsIndex)
+				scrapeResults = append(scrapeResults, res...)
+			}
+
+			if len(scrapeResults) != len(tt.expected) {
+				t.Errorf("Expected result length of %d, got %d", len(tt.expected), len(scrapeResults))
+			}
+
+			for i, expected := range tt.expected {
+				got := scrapeResults[i]
+				if !reflect.DeepEqual(expected, got) {
+					t.Errorf("Result did not match expected at index %d: got %v, want %v", i, got, expected)
+				}
+			}
+		})
+	}
+}
+
+func Test_kubernetesScraper_scrapeJobs(t *testing.T) {
+	start1, _ := time.Parse(time.RFC3339, Start1Str)
+
+	type scrape struct {
+		Jobs      []*clustercache.Job
+		Timestamp time.Time
+	}
+	tests := []struct {
+		name     string
+		nsSetup  func(*SyncMap[string, types.UID])
+		scrapes  []scrape
+		expected []metric.Update
+	}{
+		{
+			name: "simple",
+			scrapes: []scrape{
+				{
+					Jobs: []*clustercache.Job{
+						{
+							Name:      "job1",
+							Namespace: "namespace1",
+							UID:       "uuid1",
+						},
+					},
+					Timestamp: start1,
+				},
+			},
+			expected: []metric.Update{
+				{
+					Name: metric.JobInfo,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "",
+						source.JobLabel:          "job1",
+					},
+					Value: 0,
+					AdditionalInfo: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "",
+						source.JobLabel:          "job1",
+					},
+				},
+				{
+					Name: metric.JobLabels,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "",
+						source.JobLabel:          "job1",
+					},
+					Value:          0,
+					AdditionalInfo: map[string]string{},
+				},
+				{
+					Name: metric.JobAnnotations,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "",
+						source.JobLabel:          "job1",
+					},
+					Value:          0,
+					AdditionalInfo: map[string]string{},
+				},
+			},
+		},
+		{
+			name: "with namespace index",
+			nsSetup: func(nsIndex *SyncMap[string, types.UID]) {
+				nsIndex.Set("namespace1", "ns-uuid1")
+			},
+			scrapes: []scrape{
+				{
+					Jobs: []*clustercache.Job{
+						{
+							Name:      "job1",
+							Namespace: "namespace1",
+							UID:       "uuid1",
+						},
+					},
+					Timestamp: start1,
+				},
+			},
+			expected: []metric.Update{
+				{
+					Name: metric.JobInfo,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.JobLabel:          "job1",
+					},
+					Value: 0,
+					AdditionalInfo: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.JobLabel:          "job1",
+					},
+				},
+				{
+					Name: metric.JobLabels,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.JobLabel:          "job1",
+					},
+					Value:          0,
+					AdditionalInfo: map[string]string{},
+				},
+				{
+					Name: metric.JobAnnotations,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.JobLabel:          "job1",
+					},
+					Value:          0,
+					AdditionalInfo: map[string]string{},
+				},
+			},
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			ks := &ClusterCacheScraper{}
+			nsIndex := newSyncMap[string, types.UID](0)
+			if tt.nsSetup != nil {
+				tt.nsSetup(nsIndex)
+			}
+			var scrapeResults []metric.Update
+			for _, s := range tt.scrapes {
+				res := ks.scrapeJobs(s.Jobs, nsIndex)
+				scrapeResults = append(scrapeResults, res...)
+			}
+
+			if len(scrapeResults) != len(tt.expected) {
+				t.Errorf("Expected result length of %d, got %d", len(tt.expected), len(scrapeResults))
+			}
+
+			for i, expected := range tt.expected {
+				got := scrapeResults[i]
+				if !reflect.DeepEqual(expected, got) {
+					t.Errorf("Result did not match expected at index %d: got %v, want %v", i, got, expected)
+				}
+			}
+		})
+	}
+}
+
+func Test_kubernetesScraper_scrapeCronJobs(t *testing.T) {
+	start1, _ := time.Parse(time.RFC3339, Start1Str)
+
+	type scrape struct {
+		CronJobs  []*clustercache.CronJob
+		Timestamp time.Time
+	}
+	tests := []struct {
+		name     string
+		nsSetup  func(*SyncMap[string, types.UID])
+		scrapes  []scrape
+		expected []metric.Update
+	}{
+		{
+			name: "simple",
+			scrapes: []scrape{
+				{
+					CronJobs: []*clustercache.CronJob{
+						{
+							Name:      "cronJob1",
+							Namespace: "namespace1",
+							UID:       "uuid1",
+						},
+					},
+					Timestamp: start1,
+				},
+			},
+			expected: []metric.Update{
+				{
+					Name: metric.CronJobInfo,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "",
+						source.CronJobLabel:      "cronJob1",
+					},
+					Value: 0,
+					AdditionalInfo: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "",
+						source.CronJobLabel:      "cronJob1",
+					},
+				},
+				{
+					Name: metric.CronJobLabels,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "",
+						source.CronJobLabel:      "cronJob1",
+					},
+					Value:          0,
+					AdditionalInfo: map[string]string{},
+				},
+				{
+					Name: metric.CronJobAnnotations,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "",
+						source.CronJobLabel:      "cronJob1",
+					},
+					Value:          0,
+					AdditionalInfo: map[string]string{},
+				},
+			},
+		},
+		{
+			name: "with namespace index",
+			nsSetup: func(nsIndex *SyncMap[string, types.UID]) {
+				nsIndex.Set("namespace1", "ns-uuid1")
+			},
+			scrapes: []scrape{
+				{
+					CronJobs: []*clustercache.CronJob{
+						{
+							Name:      "cronJob1",
+							Namespace: "namespace1",
+							UID:       "uuid1",
+						},
+					},
+					Timestamp: start1,
+				},
+			},
+			expected: []metric.Update{
+				{
+					Name: metric.CronJobInfo,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.CronJobLabel:      "cronJob1",
+					},
+					Value: 0,
+					AdditionalInfo: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.CronJobLabel:      "cronJob1",
+					},
+				},
+				{
+					Name: metric.CronJobLabels,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.CronJobLabel:      "cronJob1",
+					},
+					Value:          0,
+					AdditionalInfo: map[string]string{},
+				},
+				{
+					Name: metric.CronJobAnnotations,
+					Labels: map[string]string{
+						source.UIDLabel:          "uuid1",
+						source.NamespaceUIDLabel: "ns-uuid1",
+						source.CronJobLabel:      "cronJob1",
+					},
+					Value:          0,
+					AdditionalInfo: map[string]string{},
+				},
+			},
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			ks := &ClusterCacheScraper{}
+			nsIndex := newSyncMap[string, types.UID](0)
+			if tt.nsSetup != nil {
+				tt.nsSetup(nsIndex)
+			}
+			var scrapeResults []metric.Update
+			for _, s := range tt.scrapes {
+				res := ks.scrapeCronJobs(s.CronJobs, nsIndex)
+				scrapeResults = append(scrapeResults, res...)
+			}
+
+			if len(scrapeResults) != len(tt.expected) {
+				t.Errorf("Expected result length of %d, got %d", len(tt.expected), len(scrapeResults))
+			}
+
+			for i, expected := range tt.expected {
+				got := scrapeResults[i]
+				if !reflect.DeepEqual(expected, got) {
+					t.Errorf("Result did not match expected at index %d: got %v, want %v", i, got, expected)
+				}
+			}
+		})
+	}
+}