-
Notifications
You must be signed in to change notification settings - Fork 477
critest: test metric descriptors #1931
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
haircommander
wants to merge
4
commits into
kubernetes-sigs:master
Choose a base branch
from
haircommander:metrics-tests
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+192
−2
Open
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
7865637
critest: test metric and metric descriptors
haircommander 7ac79fe
critest: drop cpuLoad metrics from test
haircommander 125e9c3
critest/metrics: generate some disk usage to guarantee io metrics are…
haircommander 01b03eb
crio: update config to enable metrics
haircommander File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -20,16 +20,66 @@ import ( | |||||
| "context" | ||||||
| "os" | ||||||
| "path/filepath" | ||||||
| "strings" | ||||||
| "time" | ||||||
|
|
||||||
| . "github.com/onsi/ginkgo/v2" | ||||||
| . "github.com/onsi/gomega" | ||||||
| "google.golang.org/grpc/codes" | ||||||
| grpcstatus "google.golang.org/grpc/status" | ||||||
| internalapi "k8s.io/cri-api/pkg/apis" | ||||||
| runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" | ||||||
|
|
||||||
| "sigs.k8s.io/cri-tools/pkg/common" | ||||||
| "sigs.k8s.io/cri-tools/pkg/framework" | ||||||
| ) | ||||||
|
|
||||||
| // expectedMetricDescriptorNames contains all expected metric descriptor names | ||||||
| // based on metrics returned by kubelet with CRI-O and cadvisor on the legacy cadvisor stats provider | ||||||
| // on kubernetes 1.35. | ||||||
| var expectedMetricDescriptorNames = []string{ | ||||||
| "container_blkio_device_usage_total", | ||||||
| "container_cpu_system_seconds_total", | ||||||
| "container_cpu_usage_seconds_total", | ||||||
| "container_cpu_user_seconds_total", | ||||||
| "container_file_descriptors", | ||||||
| "container_fs_reads_bytes_total", | ||||||
| "container_fs_reads_total", | ||||||
| "container_fs_usage_bytes", | ||||||
| "container_fs_writes_bytes_total", | ||||||
| "container_fs_writes_total", | ||||||
| "container_last_seen", | ||||||
| "container_memory_cache", | ||||||
| "container_memory_failcnt", | ||||||
| "container_memory_failures_total", | ||||||
| "container_memory_mapped_file", | ||||||
| "container_memory_max_usage_bytes", | ||||||
| "container_memory_rss", | ||||||
| "container_memory_swap", | ||||||
| "container_memory_usage_bytes", | ||||||
| "container_memory_working_set_bytes", | ||||||
| "container_network_receive_bytes_total", | ||||||
| "container_network_receive_errors_total", | ||||||
| "container_network_receive_packets_dropped_total", | ||||||
| "container_network_receive_packets_total", | ||||||
| "container_network_transmit_bytes_total", | ||||||
| "container_network_transmit_errors_total", | ||||||
| "container_network_transmit_packets_dropped_total", | ||||||
| "container_network_transmit_packets_total", | ||||||
| "container_oom_events_total", | ||||||
| "container_processes", | ||||||
| "container_sockets", | ||||||
| "container_spec_cpu_period", | ||||||
| "container_spec_cpu_shares", | ||||||
| "container_spec_memory_limit_bytes", | ||||||
| "container_spec_memory_reservation_limit_bytes", | ||||||
| "container_spec_memory_swap_limit_bytes", | ||||||
| "container_start_time_seconds", | ||||||
| "container_threads", | ||||||
| "container_threads_max", | ||||||
| "container_ulimits_soft", | ||||||
| } | ||||||
|
|
||||||
| var _ = framework.KubeDescribe("PodSandbox", func() { | ||||||
| f := framework.NewDefaultCRIFramework() | ||||||
|
|
||||||
|
|
@@ -80,6 +130,62 @@ var _ = framework.KubeDescribe("PodSandbox", func() { | |||||
| podID = "" // no need to cleanup pod | ||||||
| }) | ||||||
| }) | ||||||
| Context("runtime should support metrics operations", func() { | ||||||
| var podID string | ||||||
| var podConfig *runtimeapi.PodSandboxConfig | ||||||
| BeforeEach(func() { | ||||||
| _, err := rc.ListMetricDescriptors(context.TODO()) | ||||||
| if err != nil { | ||||||
| s, ok := grpcstatus.FromError(err) | ||||||
| Expect(ok && s.Code() == codes.Unimplemented).To(BeTrue(), "Expected CRI metric descriptors call to either be not supported, or not error") | ||||||
| if s.Code() == codes.Unimplemented { | ||||||
| Skip("CRI Metrics endpoints not supported by this runtime version") | ||||||
| } | ||||||
| } | ||||||
| }) | ||||||
|
|
||||||
| AfterEach(func() { | ||||||
| if podID != "" { | ||||||
| By("stop PodSandbox") | ||||||
| Expect(rc.StopPodSandbox(context.TODO(), podID)).NotTo(HaveOccurred()) | ||||||
| By("delete PodSandbox") | ||||||
| Expect(rc.RemovePodSandbox(context.TODO(), podID)).NotTo(HaveOccurred()) | ||||||
| } | ||||||
| }) | ||||||
|
|
||||||
| It("runtime should support returning metrics descriptors [Conformance]", func() { | ||||||
| By("list metric descriptors") | ||||||
| descs := listMetricDescriptors(rc) | ||||||
|
|
||||||
| By("verify expected metric descriptors are present") | ||||||
| testMetricDescriptors(descs) | ||||||
| }) | ||||||
|
|
||||||
| It("runtime should support listing pod sandbox metrics [Conformance]", func() { | ||||||
| By("create pod sandbox") | ||||||
| podID, podConfig = framework.CreatePodSandboxForContainer(rc) | ||||||
|
|
||||||
| By("create container in pod") | ||||||
| ic := f.CRIClient.CRIImageClient | ||||||
| containerID := framework.CreateDefaultContainer(rc, ic, podID, podConfig, "container-for-metrics-") | ||||||
|
|
||||||
| By("start container") | ||||||
| startContainer(rc, containerID) | ||||||
|
|
||||||
| _, _, err := rc.ExecSync( | ||||||
| context.TODO(), containerID, []string{"/bin/sh", "-c", "for i in $(seq 1 10); do echo hi >> /var/lib/mydisktest/inode_test_file_$i; done; sync"}, | ||||||
| time.Duration(defaultExecSyncTimeout)*time.Second, | ||||||
| ) | ||||||
|
|
||||||
| Expect(err).ToNot(HaveOccurred()) | ||||||
|
|
||||||
| By("list pod sandbox metrics") | ||||||
| metrics := listPodSandboxMetrics(rc) | ||||||
|
|
||||||
| By("verify pod metrics are present") | ||||||
| testPodSandboxMetrics(metrics, podID) | ||||||
| }) | ||||||
| }) | ||||||
| }) | ||||||
|
|
||||||
| // podSandboxFound returns whether PodSandbox is found. | ||||||
|
|
@@ -166,6 +272,17 @@ func listPodSandbox(c internalapi.RuntimeService, filter *runtimeapi.PodSandboxF | |||||
| return pods | ||||||
| } | ||||||
|
|
||||||
| // listMetricDescriptors lists MetricDescriptors. | ||||||
| func listMetricDescriptors(c internalapi.RuntimeService) []*runtimeapi.MetricDescriptor { | ||||||
| By("List MetricDescriptors.") | ||||||
|
|
||||||
| descs, err := c.ListMetricDescriptors(context.TODO()) | ||||||
| framework.ExpectNoError(err, "failed to list MetricDescriptors status: %v", err) | ||||||
| framework.Logf("List MetricDescriptors succeed") | ||||||
|
|
||||||
| return descs | ||||||
| } | ||||||
|
|
||||||
| // createLogTempDir creates the log temp directory for podSandbox. | ||||||
| func createLogTempDir(podSandboxName string) (hostPath, podLogPath string) { | ||||||
| hostPath, err := os.MkdirTemp("", "podLogTest") | ||||||
|
|
@@ -196,3 +313,76 @@ func createPodSandboxWithLogDirectory(c internalapi.RuntimeService) (sandboxID s | |||||
|
|
||||||
| return framework.RunPodSandbox(c, podConfig), podConfig, hostPath | ||||||
| } | ||||||
|
|
||||||
| // testMetricDescriptors verifies that all expected metric descriptors are present. | ||||||
| func testMetricDescriptors(descs []*runtimeapi.MetricDescriptor) { | ||||||
| returnedDescriptors := make(map[string]*runtimeapi.MetricDescriptor) | ||||||
| for _, desc := range descs { | ||||||
| returnedDescriptors[desc.GetName()] = desc | ||||||
| Expect(desc.GetHelp()).NotTo(BeEmpty(), "Metric descriptor %q should have help text", desc.GetName()) | ||||||
| Expect(desc.GetLabelKeys()).NotTo(BeEmpty(), "Metric descriptor %q should have label keys", desc.GetName()) | ||||||
| } | ||||||
|
|
||||||
| missingMetrics := []string{} | ||||||
|
|
||||||
| for _, expectedName := range expectedMetricDescriptorNames { | ||||||
| _, found := returnedDescriptors[expectedName] | ||||||
| if !found { | ||||||
| missingMetrics = append(missingMetrics, expectedName) | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| Expect(missingMetrics).To(BeEmpty(), "Expected %s metrics to be present and they were not", strings.Join(missingMetrics, " ")) | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| } | ||||||
|
|
||||||
| // listPodSandboxMetrics lists PodSandboxMetrics. | ||||||
| func listPodSandboxMetrics(c internalapi.RuntimeService) []*runtimeapi.PodSandboxMetrics { | ||||||
| By("List PodSandboxMetrics.") | ||||||
|
|
||||||
| metrics, err := c.ListPodSandboxMetrics(context.TODO()) | ||||||
| framework.ExpectNoError(err, "failed to list PodSandboxMetrics: %v", err) | ||||||
| framework.Logf("List PodSandboxMetrics succeed") | ||||||
|
|
||||||
| return metrics | ||||||
| } | ||||||
|
|
||||||
| // testPodSandboxMetrics verifies that metrics are present for the specified pod. | ||||||
| func testPodSandboxMetrics(allMetrics []*runtimeapi.PodSandboxMetrics, podID string) { | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are still taking in this function. Only the metrics descriptors test are needed right? |
||||||
| var podMetrics *runtimeapi.PodSandboxMetrics | ||||||
|
|
||||||
| for _, m := range allMetrics { | ||||||
| if m.GetPodSandboxId() == podID { | ||||||
| podMetrics = m | ||||||
|
|
||||||
| break | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| Expect(podMetrics).NotTo(BeNil(), "Metrics for pod %q should be present", podID) | ||||||
|
|
||||||
| metricNamesFound := make(map[string]bool) | ||||||
|
|
||||||
| for _, metric := range podMetrics.GetMetrics() { | ||||||
| if !metricNamesFound[metric.GetName()] { | ||||||
| metricNamesFound[metric.GetName()] = true | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| for _, containerMetric := range podMetrics.GetContainerMetrics() { | ||||||
| for _, metric := range containerMetric.GetMetrics() { | ||||||
| if !metricNamesFound[metric.GetName()] { | ||||||
| metricNamesFound[metric.GetName()] = true | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| missingMetrics := []string{} | ||||||
|
|
||||||
| for _, expectedName := range expectedMetricDescriptorNames { | ||||||
| if !metricNamesFound[expectedName] { | ||||||
| missingMetrics = append(missingMetrics, expectedName) | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| Expect(missingMetrics).To(BeEmpty(), "Expected %s metrics to be present and they were not", strings.Join(missingMetrics, " ")) | ||||||
| } | ||||||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few of these metrics are currently not in the implementation in containerd also.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you have a list handy of the ones you aren't yet supporting? is it because you don't plan on it or haven't gotten to it yet
I think for this KEP to go beta each should really support the full set (I say knowing CRI-O is missing some)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From containerd, the below metrics are not reported from metric descriptors
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are now added as part of #12426.
Checking why the CI fails on containerd main.