diff --git a/server/apis/v1/handler.go b/server/apis/v1/handler.go index 9e588daed8..651b5a3f46 100644 --- a/server/apis/v1/handler.go +++ b/server/apis/v1/handler.go @@ -1598,24 +1598,24 @@ func (h *handler) getPodDetails(pod corev1.Pod) (PodDetails, error) { memQuantity := container.Usage.Memory() details, ok := containerDetails[containerName] if !ok { - details = ContainerDetails{Name: container.Name} // Initialize if not found + details = ContainerDetails{Name: container.Name} } if cpuQuantity != nil { - details.TotalCPU = strconv.FormatInt(cpuQuantity.MilliValue(), 10) + "m" + details.TotalCPU = cpuToMillicores(cpuQuantity.String()) totalCPU.Add(*cpuQuantity) } if memQuantity != nil { - details.TotalMemory = strconv.FormatInt(memQuantity.Value()/(1024*1024), 10) + "Mi" + details.TotalMemory = fmt.Sprintf("%.2fMi", float64(memQuantity.Value())/(1024*1024)) totalMemory.Add(*memQuantity) } containerDetails[containerName] = details } if totalCPU != nil { - podDetails.TotalCPU = strconv.FormatInt(totalCPU.MilliValue(), 10) + "m" + podDetails.TotalCPU = cpuToMillicores(totalCPU.String()) } if totalMemory != nil { - podDetails.TotalMemory = strconv.FormatInt(totalMemory.Value()/(1024*1024), 10) + "Mi" + podDetails.TotalMemory = fmt.Sprintf("%.2fMi", float64(totalMemory.Value())/(1024*1024)) } } return podDetails, nil @@ -1684,3 +1684,24 @@ func (h *handler) getContainerStatus(state corev1.ContainerState) string { return "Unknown" } } + +func cpuToMillicores(quantityStr string) string { + var value float64 + var format string + + // Parse the quantity string + if _, err := fmt.Sscanf(quantityStr, "%f%s", &value, &format); err != nil { + fmt.Println("Error parsing cpu quantity string:", err) + return "0m" + } + + // Adjust value based on the format suffix + switch { + case strings.HasSuffix(format, "n"): + value /= 1e6 + case !strings.HasSuffix(format, "m"): + fmt.Println("Error parsing quantity string: invalid format") + return "0m" + } + return fmt.Sprintf("%.2fm", value) +} diff --git a/server/apis/v1/handler_test.go b/server/apis/v1/handler_test.go index aeae24d8a0..d6e7ff7844 100644 --- a/server/apis/v1/handler_test.go +++ b/server/apis/v1/handler_test.go @@ -464,8 +464,8 @@ func TestHandler_GetMonoVertexPodsInfo(t *testing.T) { if len(podInfos) > 0 { assert.Equal(t, "test-pod-1", podInfos[0].Name) assert.Equal(t, string(corev1.PodRunning), podInfos[0].Status) - assert.Equal(t, "150m", podInfos[0].TotalCPU) - assert.Equal(t, "150Mi", podInfos[0].TotalMemory) + assert.Equal(t, "150.00m", podInfos[0].TotalCPU) + assert.Equal(t, "150.00Mi", podInfos[0].TotalMemory) } } }) @@ -662,8 +662,8 @@ func TestHandler_GetVertexPodsInfo(t *testing.T) { assert.Len(t, podInfos, 1) assert.Equal(t, "test-pod-1", podInfos[0].Name) assert.Equal(t, string(corev1.PodRunning), podInfos[0].Status) - assert.Equal(t, "150m", podInfos[0].TotalCPU) - assert.Equal(t, "150Mi", podInfos[0].TotalMemory) + assert.Equal(t, "150.00m", podInfos[0].TotalCPU) + assert.Equal(t, "150.00Mi", podInfos[0].TotalMemory) } }) } @@ -764,8 +764,8 @@ func TestHandler_GetPodDetails(t *testing.T) { Status: "Running", Message: "", Reason: "", - TotalCPU: "250m", - TotalMemory: "500Mi", + TotalCPU: "250.00m", + TotalMemory: "500.00Mi", ContainerDetailsMap: map[string]ContainerDetails{ "container-1": { Name: "container-1", @@ -777,8 +777,8 @@ func TestHandler_GetPodDetails(t *testing.T) { RequestedMemory: "200Mi", LimitCPU: "200m", LimitMemory: "400Mi", - TotalCPU: "100m", - TotalMemory: "200Mi", + TotalCPU: "100.00m", + TotalMemory: "200.00Mi", LastTerminationReason: "", LastTerminationMessage: "", WaitingReason: "", @@ -794,8 +794,8 @@ func TestHandler_GetPodDetails(t *testing.T) { RequestedMemory: "300Mi", LimitCPU: "300m", LimitMemory: "600Mi", - TotalCPU: "150m", - TotalMemory: "300Mi", + TotalCPU: "150.00m", + TotalMemory: "300.00Mi", LastTerminationReason: "", LastTerminationMessage: "", LastStartedAt: "", @@ -1028,3 +1028,26 @@ func TestHandler_GetContainerStatus(t *testing.T) { }) } } + +func TestHandler_cpuToMillicores(t *testing.T) { + testCases := []struct { + input string + expected string + }{ + {"2953072n", "2.95m"}, + {"500m", "500.00m"}, + {"10000n", "0.01m"}, + {"0n", "0.00m"}, + {"100000000g", "0m"}, + {"invalid input", "0m"}, // Error case + } + + for _, tc := range testCases { + t.Run(fmt.Sprintf("Input: %s", tc.input), func(t *testing.T) { + result := cpuToMillicores(tc.input) + if result != tc.expected { + t.Errorf("Expected: %s, Got: %s", tc.expected, result) + } + }) + } +} diff --git a/ui/src/components/pages/Pipeline/partials/Graph/partials/NodeInfo/partials/Pods/index.tsx b/ui/src/components/pages/Pipeline/partials/Graph/partials/NodeInfo/partials/Pods/index.tsx index 91baaeed84..4041dd9df7 100644 --- a/ui/src/components/pages/Pipeline/partials/Graph/partials/NodeInfo/partials/Pods/index.tsx +++ b/ui/src/components/pages/Pipeline/partials/Graph/partials/NodeInfo/partials/Pods/index.tsx @@ -30,6 +30,7 @@ import { PodsProps, } from "../../../../../../../../../types/declarations/pods"; +// TODO: calculate podsDetails from pods-info API export function Pods(props: PodsProps) { const { host } = useContext(AppContext); const { namespaceId, pipelineId, vertexId, type } = props; diff --git a/ui/src/components/pages/Pipeline/partials/Graph/partials/NodeInfo/partials/Pods/partials/PodDetails/partials/ContainerInfo/index.tsx b/ui/src/components/pages/Pipeline/partials/Graph/partials/NodeInfo/partials/Pods/partials/PodDetails/partials/ContainerInfo/index.tsx index 5a225b0dca..22134c5e79 100644 --- a/ui/src/components/pages/Pipeline/partials/Graph/partials/NodeInfo/partials/Pods/partials/PodDetails/partials/ContainerInfo/index.tsx +++ b/ui/src/components/pages/Pipeline/partials/Graph/partials/NodeInfo/partials/Pods/partials/PodDetails/partials/ContainerInfo/index.tsx @@ -4,7 +4,7 @@ import { getPodContainerUsePercentages } from "../../../../../../../../../../../ import { PodInfoProps } from "../../../../../../../../../../../../../types/declarations/pods"; import "./style.css"; - +// TODO: calculate cpu/mem percent from containerInfoProps/calculateCPUPercent/calculateMemoryPercent export function ContainerInfo({ pod, podDetails, diff --git a/ui/src/utils/fetcherHooks/podsViewFetch.ts b/ui/src/utils/fetcherHooks/podsViewFetch.ts index e893381cf6..3c7bf46e59 100644 --- a/ui/src/utils/fetcherHooks/podsViewFetch.ts +++ b/ui/src/utils/fetcherHooks/podsViewFetch.ts @@ -14,6 +14,8 @@ import { PodDetail, } from "../../types/declarations/pods"; + +// TODO: calculate podsDetails from pods-info API export const usePodsViewFetch = ( namespaceId: string | undefined, pipelineId: string | undefined,