Skip to content

Commit 3cb8630

Browse files
committed
critest: test metric descriptors
Signed-off-by: Peter Hunt <[email protected]>
1 parent e68cdf6 commit 3cb8630

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed

pkg/validate/pod.go

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,67 @@ import (
2020
"context"
2121
"os"
2222
"path/filepath"
23+
"strings"
2324

2425
. "github.com/onsi/ginkgo/v2"
2526
. "github.com/onsi/gomega"
27+
"google.golang.org/grpc/codes"
28+
grpcstatus "google.golang.org/grpc/status"
2629
internalapi "k8s.io/cri-api/pkg/apis"
2730
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
2831

2932
"sigs.k8s.io/cri-tools/pkg/common"
3033
"sigs.k8s.io/cri-tools/pkg/framework"
3134
)
3235

36+
// expectedMetricDescriptorNames contains all expected metric descriptor names
37+
// based on metrics returned by kubelet with CRI-O and cadvisor on the legacy cadvisor stats provider
38+
// on kubernetes 1.35.
39+
var expectedMetricDescriptorNames = []string{
40+
"container_blkio_device_usage_total",
41+
"container_cpu_load_average_10s",
42+
"container_cpu_system_seconds_total",
43+
"container_cpu_usage_seconds_total",
44+
"container_cpu_user_seconds_total",
45+
"container_file_descriptors",
46+
"container_fs_reads_bytes_total",
47+
"container_fs_reads_total",
48+
"container_fs_usage_bytes",
49+
"container_fs_writes_bytes_total",
50+
"container_fs_writes_total",
51+
"container_last_seen",
52+
"container_memory_cache",
53+
"container_memory_failcnt",
54+
"container_memory_failures_total",
55+
"container_memory_mapped_file",
56+
"container_memory_max_usage_bytes",
57+
"container_memory_rss",
58+
"container_memory_swap",
59+
"container_memory_usage_bytes",
60+
"container_memory_working_set_bytes",
61+
"container_network_receive_bytes_total",
62+
"container_network_receive_errors_total",
63+
"container_network_receive_packets_dropped_total",
64+
"container_network_receive_packets_total",
65+
"container_network_transmit_bytes_total",
66+
"container_network_transmit_errors_total",
67+
"container_network_transmit_packets_dropped_total",
68+
"container_network_transmit_packets_total",
69+
"container_oom_events_total",
70+
"container_processes",
71+
"container_sockets",
72+
"container_spec_cpu_period",
73+
"container_spec_cpu_shares",
74+
"container_spec_memory_limit_bytes",
75+
"container_spec_memory_reservation_limit_bytes",
76+
"container_spec_memory_swap_limit_bytes",
77+
"container_start_time_seconds",
78+
"container_tasks_state",
79+
"container_threads",
80+
"container_threads_max",
81+
"container_ulimits_soft",
82+
}
83+
3384
var _ = framework.KubeDescribe("PodSandbox", func() {
3485
f := framework.NewDefaultCRIFramework()
3586

@@ -80,6 +131,36 @@ var _ = framework.KubeDescribe("PodSandbox", func() {
80131
podID = "" // no need to cleanup pod
81132
})
82133
})
134+
Context("runtime should support metrics operations", func() {
135+
var podID string
136+
BeforeEach(func() {
137+
_, err := rc.ListMetricDescriptors(context.TODO())
138+
if err != nil {
139+
s, ok := grpcstatus.FromError(err)
140+
Expect(ok && s.Code() == codes.Unimplemented).To(BeTrue(), "Expected CRI metric descriptors call to either be not supported, or not error")
141+
if s.Code() == codes.Unimplemented {
142+
Skip("CRI Metrics endpoints not supported by this runtime version")
143+
}
144+
}
145+
})
146+
147+
AfterEach(func() {
148+
if podID != "" {
149+
By("stop PodSandbox")
150+
Expect(rc.StopPodSandbox(context.TODO(), podID)).NotTo(HaveOccurred())
151+
By("delete PodSandbox")
152+
Expect(rc.RemovePodSandbox(context.TODO(), podID)).NotTo(HaveOccurred())
153+
}
154+
})
155+
156+
It("runtime should support returning metrics descriptors [Conformance]", func() {
157+
By("list metric descriptors")
158+
descs := listMetricDescriptors(rc)
159+
160+
By("verify expected metric descriptors are present")
161+
testMetricDescriptors(descs)
162+
})
163+
})
83164
})
84165

85166
// podSandboxFound returns whether PodSandbox is found.
@@ -166,6 +247,17 @@ func listPodSandbox(c internalapi.RuntimeService, filter *runtimeapi.PodSandboxF
166247
return pods
167248
}
168249

250+
// listMetricDescriptors lists MetricDescriptors.
251+
func listMetricDescriptors(c internalapi.RuntimeService) []*runtimeapi.MetricDescriptor {
252+
By("List MetricDescriptors.")
253+
254+
descs, err := c.ListMetricDescriptors(context.TODO())
255+
framework.ExpectNoError(err, "failed to list MetricDescriptors status: %v", err)
256+
framework.Logf("List MetricDescriptors succeed")
257+
258+
return descs
259+
}
260+
169261
// createLogTempDir creates the log temp directory for podSandbox.
170262
func createLogTempDir(podSandboxName string) (hostPath, podLogPath string) {
171263
hostPath, err := os.MkdirTemp("", "podLogTest")
@@ -196,3 +288,24 @@ func createPodSandboxWithLogDirectory(c internalapi.RuntimeService) (sandboxID s
196288

197289
return framework.RunPodSandbox(c, podConfig), podConfig, hostPath
198290
}
291+
292+
// testMetricDescriptors verifies that all expected metric descriptors are present.
293+
func testMetricDescriptors(descs []*runtimeapi.MetricDescriptor) {
294+
returnedDescriptors := make(map[string]*runtimeapi.MetricDescriptor)
295+
for _, desc := range descs {
296+
returnedDescriptors[desc.GetName()] = desc
297+
Expect(desc.GetHelp()).NotTo(BeEmpty(), "Metric descriptor %q should have help text", desc.GetName())
298+
Expect(desc.GetLabelKeys()).NotTo(BeEmpty(), "Metric descriptor %q should have label keys", desc.GetName())
299+
}
300+
301+
missingMetrics := []string{}
302+
303+
for _, expectedName := range expectedMetricDescriptorNames {
304+
_, found := returnedDescriptors[expectedName]
305+
if !found {
306+
missingMetrics = append(missingMetrics, expectedName)
307+
}
308+
}
309+
310+
Expect(missingMetrics).To(BeEmpty(), "Expected %s metrics to be present and they were not", strings.Join(missingMetrics, " "))
311+
}

0 commit comments

Comments
 (0)