Skip to content

Commit 41473f2

Browse files
committed
remove tests for kai-resource-isolator metrics
Signed-off-by: dttung2905 <ttdao.2015@accountancy.smu.edu.sg>
1 parent 91021da commit 41473f2

2 files changed

Lines changed: 2 additions & 173 deletions

File tree

hack/setup-e2e-cluster.sh

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,11 @@ while [[ $# -gt 0 ]]; do
8585
esac
8686
done
8787

88-
# Extra helm --set flags for HAMi/hamicore. Kind e2e has no nvidia RuntimeClass, so clear
89-
# the defaults that would otherwise reject GPU-fraction pods at admission.
88+
# Extra helm --set flags for HAMi/hamicore when --test-hami is set.
9089
HAMI_HELM_SETS=()
9190
if [ "$TEST_HAMI" = "true" ]; then
9291
HAMI_HELM_SETS+=(
9392
--set "binder.plugins.hamicore.enabled=true"
94-
--set "binder.resourceReservation.runtimeClassName="
95-
--set "admission.gpuFractionRuntimeClassName="
9693
)
9794
fi
9895

test/e2e/suites/integrations/third_party/hamicore/hamicore_test.go

Lines changed: 1 addition & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,17 @@ SPDX-License-Identifier: Apache-2.0
55
package hamicore
66

77
import (
8-
"bytes"
98
"context"
109
"encoding/json"
1110
"fmt"
1211
"strconv"
1312
"strings"
14-
"time"
1513

1614
. "github.com/onsi/ginkgo/v2"
1715
. "github.com/onsi/gomega"
18-
dto "github.com/prometheus/client_model/go"
19-
"github.com/prometheus/common/expfmt"
20-
"github.com/prometheus/common/model"
2116
v1 "k8s.io/api/core/v1"
2217
"k8s.io/apimachinery/pkg/api/resource"
2318
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24-
"k8s.io/client-go/kubernetes"
2519
"k8s.io/utils/ptr"
2620

2721
kaiv1binder "github.com/kai-scheduler/KAI-scheduler/pkg/apis/kai/v1/binder"
@@ -38,51 +32,13 @@ import (
3832

3933
const (
4034
kaiResourceIsolatorWebhookName = "kai-resource-isolator-mutating"
41-
kaiResourceIsolatorNamespace = "kai-resource-isolator"
42-
kaiVGPUMonitorDaemonSetName = "kai-resource-isolator-monitor"
43-
kaiVGPUMonitorLabel = "app.kubernetes.io/component=kai-vgpu-monitor"
44-
kaiVGPUMonitorMetricsPort = "9394"
4535
binderDeploymentName = "binder"
4636
binderDeploymentNamespace = "kai-scheduler"
4737
binderPluginsFlag = "--plugins"
4838
cudaImage = "nvidia/cuda:12.6.0-base-ubuntu22.04"
49-
// devel image is needed so the metrics workload can nvcc a tiny cudaMalloc hold binary.
50-
cudaDevelImage = "nvidia/cuda:12.6.0-devel-ubuntu22.04"
51-
gpuMemoryRequestMiB = 2000
52-
cudaAllocHoldMiB = 64
53-
vgpuMetricsTimeout = 60 * time.Second
54-
vgpuMetricsInterval = 5 * time.Second
55-
hamiVGPUMemoryUsed = "hami_vgpu_memory_used_bytes"
39+
gpuMemoryRequestMiB = 2000
5640
)
5741

58-
// Compiles and runs a small CUDA alloc that holds memory so kai-vgpu-monitor can
59-
// scrape hami_vgpu_memory_used_bytes > 0. Kept as a container entrypoint (not
60-
// ExecInPod) so the allocation outlives the ready wait.
61-
const cudaAllocHoldScript = `set -euo pipefail
62-
cat >/tmp/hold.cu <<'EOF'
63-
#include <cuda_runtime.h>
64-
#include <stdio.h>
65-
#include <unistd.h>
66-
int main(void) {
67-
void *p = NULL;
68-
size_t bytes = (size_t)64 * 1024 * 1024;
69-
cudaError_t err = cudaMalloc(&p, bytes);
70-
if (err != cudaSuccess) {
71-
fprintf(stderr, "cudaMalloc failed: %s\n", cudaGetErrorString(err));
72-
return 1;
73-
}
74-
printf("allocated %zu bytes at %p\n", bytes, p);
75-
fflush(stdout);
76-
for (;;) {
77-
sleep(3600);
78-
}
79-
return 0;
80-
}
81-
EOF
82-
nvcc -O0 -o /tmp/hold /tmp/hold.cu
83-
exec /tmp/hold
84-
`
85-
8642
var _ = Describe("HAMi-core resource isolation", Ordered, func() {
8743
var testCtx *testcontext.TestContext
8844

@@ -235,45 +191,6 @@ var _ = Describe("HAMi-core resource isolation", Ordered, func() {
235191
"nvidia-smi visible memory (%d MiB) should match CUDA_DEVICE_MEMORY_LIMIT (%d MiB)",
236192
visibleMemMiB, limitMiB)
237193
})
238-
239-
It("gpu-memory: kai-vgpu-monitor reports hami_vgpu_memory_used_bytes > 0",
240-
Label(labels.ReservationPod), func(ctx context.Context) {
241-
if !isKaiVGPUMonitorInstalled(ctx, testCtx.KubeClientset) {
242-
Skip(fmt.Sprintf(
243-
"kai-vgpu-monitor DaemonSet %q not found in namespace %q; "+
244-
"install via hack/hami/deploy_isolator.sh (--test-hami)",
245-
kaiVGPUMonitorDaemonSetName, kaiResourceIsolatorNamespace,
246-
))
247-
}
248-
249-
pod := rd.CreatePodObject(testCtx.Queues[0], v1.ResourceRequirements{})
250-
pod.Annotations[constants.GpuMemory] = strconv.Itoa(gpuMemoryRequestMiB)
251-
pod.Spec.Containers[0].Image = cudaDevelImage
252-
pod.Spec.Containers[0].Command = []string{"bash", "-c"}
253-
pod.Spec.Containers[0].Args = []string{cudaAllocHoldScript}
254-
255-
_, err := rd.CreatePod(ctx, testCtx.KubeClientset, pod)
256-
Expect(err).NotTo(HaveOccurred())
257-
wait.ForPodReady(ctx, testCtx.ControllerClient, pod)
258-
259-
pod, err = rd.GetPod(ctx, testCtx.KubeClientset, pod.Namespace, pod.Name)
260-
Expect(err).NotTo(HaveOccurred())
261-
Expect(pod.Spec.NodeName).NotTo(BeEmpty(), "pod should be scheduled to a node")
262-
containerName := pod.Spec.Containers[0].Name
263-
264-
By("waiting for kai-vgpu-monitor to expose hami_vgpu_memory_used_bytes for the workload")
265-
Eventually(func(g Gomega) {
266-
used, scrapeErr := scrapeHamiVGPUMemoryUsedBytes(
267-
ctx, testCtx.KubeClientset, pod.Spec.NodeName, pod.Namespace, pod.Name, containerName,
268-
)
269-
g.Expect(scrapeErr).NotTo(HaveOccurred())
270-
GinkgoLogr.Info("hami_vgpu_memory_used_bytes",
271-
"namespace", pod.Namespace, "pod", pod.Name, "container", containerName, "bytes", used)
272-
g.Expect(used).To(BeNumerically(">", 0),
273-
"expected hami_vgpu_memory_used_bytes > 0 for %s/%s container %s (held ~%d MiB)",
274-
pod.Namespace, pod.Name, containerName, cudaAllocHoldMiB)
275-
}, vgpuMetricsTimeout, vgpuMetricsInterval).Should(Succeed())
276-
})
277194
})
278195

279196
func printNvidiaSmi(ctx context.Context, testCtx *testcontext.TestContext, pod *v1.Pod) {
@@ -345,88 +262,3 @@ func hamiCoreEnabledInPluginsJSON(raw string) bool {
345262
}
346263
return ptr.Deref(cfg.Enabled, false)
347264
}
348-
349-
func isKaiVGPUMonitorInstalled(ctx context.Context, client kubernetes.Interface) bool {
350-
_, err := client.AppsV1().DaemonSets(kaiResourceIsolatorNamespace).
351-
Get(ctx, kaiVGPUMonitorDaemonSetName, metav1.GetOptions{})
352-
return err == nil
353-
}
354-
355-
func scrapeHamiVGPUMemoryUsedBytes(
356-
ctx context.Context,
357-
client kubernetes.Interface,
358-
nodeName, namespace, podName, containerName string,
359-
) (float64, error) {
360-
monitorPod, err := findMonitorPodOnNode(ctx, client, nodeName)
361-
if err != nil {
362-
return 0, err
363-
}
364-
365-
raw, err := client.CoreV1().Pods(monitorPod.Namespace).
366-
ProxyGet("http", monitorPod.Name, kaiVGPUMonitorMetricsPort, "/metrics", nil).
367-
DoRaw(ctx)
368-
if err != nil {
369-
return 0, fmt.Errorf("proxy GET /metrics from monitor pod %s/%s: %w",
370-
monitorPod.Namespace, monitorPod.Name, err)
371-
}
372-
373-
parser := expfmt.NewTextParser(model.UTF8Validation)
374-
families, err := parser.TextToMetricFamilies(bytes.NewReader(raw))
375-
if err != nil {
376-
return 0, fmt.Errorf("parse prometheus metrics: %w", err)
377-
}
378-
379-
family, ok := families[hamiVGPUMemoryUsed]
380-
if !ok {
381-
return 0, fmt.Errorf("metric %s not present in monitor scrape", hamiVGPUMemoryUsed)
382-
}
383-
384-
want := map[string]string{
385-
"namespace": namespace,
386-
"pod": podName,
387-
"container": containerName,
388-
}
389-
for _, metric := range family.GetMetric() {
390-
if !metricHasLabels(metric, want) {
391-
continue
392-
}
393-
if metric.GetGauge() == nil {
394-
return 0, fmt.Errorf("metric %s for %v is not a gauge", hamiVGPUMemoryUsed, want)
395-
}
396-
return metric.GetGauge().GetValue(), nil
397-
}
398-
return 0, fmt.Errorf("metric %s with labels %v not found", hamiVGPUMemoryUsed, want)
399-
}
400-
401-
func findMonitorPodOnNode(ctx context.Context, client kubernetes.Interface, nodeName string) (*v1.Pod, error) {
402-
pods, err := client.CoreV1().Pods(kaiResourceIsolatorNamespace).List(ctx, metav1.ListOptions{
403-
LabelSelector: kaiVGPUMonitorLabel,
404-
FieldSelector: "spec.nodeName=" + nodeName,
405-
})
406-
if err != nil {
407-
return nil, fmt.Errorf("list kai-vgpu-monitor pods on node %s: %w", nodeName, err)
408-
}
409-
for i := range pods.Items {
410-
pod := &pods.Items[i]
411-
if rd.IsPodReady(pod) {
412-
return pod, nil
413-
}
414-
}
415-
if len(pods.Items) == 0 {
416-
return nil, fmt.Errorf("no kai-vgpu-monitor pods scheduled on node %s", nodeName)
417-
}
418-
return nil, fmt.Errorf("kai-vgpu-monitor pod(s) on node %s are not Ready", nodeName)
419-
}
420-
421-
func metricHasLabels(metric *dto.Metric, want map[string]string) bool {
422-
got := make(map[string]string, len(metric.GetLabel()))
423-
for _, label := range metric.GetLabel() {
424-
got[label.GetName()] = label.GetValue()
425-
}
426-
for k, v := range want {
427-
if got[k] != v {
428-
return false
429-
}
430-
}
431-
return true
432-
}

0 commit comments

Comments
 (0)