From 9dc0eb55d74f95829dad525fdcca74e479b71b5a Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Wed, 18 Jan 2023 12:24:22 +0300 Subject: [PATCH] Adding test cases for autoscaling/v1 metrics Signed-off-by: Alex Andreev --- .../horizontal-pod-autoscaler.api.test.ts | 465 +++++++++++++++++- .../get-hpa-metrics.injectable.ts | 4 +- 2 files changed, 466 insertions(+), 3 deletions(-) diff --git a/src/common/k8s-api/__tests__/horizontal-pod-autoscaler.api.test.ts b/src/common/k8s-api/__tests__/horizontal-pod-autoscaler.api.test.ts index c21d0d255e..8c2e353818 100644 --- a/src/common/k8s-api/__tests__/horizontal-pod-autoscaler.api.test.ts +++ b/src/common/k8s-api/__tests__/horizontal-pod-autoscaler.api.test.ts @@ -23,6 +23,26 @@ const hpaV2 = { } } +const hpaV1 = { + apiVersion: "autoscaling/v1", + kind: "HorizontalPodAutoscaler", + metadata: { + name: "hpav1", + resourceVersion: "1", + uid: "hpav1", + namespace: "default", + selfLink: "/apis/autoscaling/v1/namespaces/default/horizontalpodautoscalers/hpav1", + }, + spec: { + maxReplicas: 10, + scaleTargetRef: { + kind: "Deployment", + name: "hpav1deployment", + apiVersion: "apps/v1", + } + } +} + describe("getHorizontalPodAutoscalerMetrics", () => { let di: DiContainer; let getMetrics: (hpa: HorizontalPodAutoscaler) => string[]; @@ -320,7 +340,7 @@ describe("getHorizontalPodAutoscalerMetrics", () => { }, target: { type: "AverageValue", - value: "5k" + averageValue: "5k" } } } @@ -346,7 +366,7 @@ describe("getHorizontalPodAutoscalerMetrics", () => { name: "requests-per-second" }, target: { - type: "AverageValue", + type: "Value", value: "5k" } } @@ -577,4 +597,445 @@ describe("getHorizontalPodAutoscalerMetrics", () => { expect(getMetrics(hpa)[0]).toEqual("unknown / 30 (avg)"); }); }); + + describe("HPA v1", () => { + it("should return correct empty metrics", () => { + const hpa = new HorizontalPodAutoscaler(hpaV1); + + expect(getMetrics(hpa)).toHaveLength(0); + }); + + it("should return correct resource metrics", () => { + const hpa = new HorizontalPodAutoscaler({ + ...hpaV1, + spec: { + ...hpaV1.spec, + metrics: [ + { + type: HpaMetricType.Resource, + resource: { + name: "cpu", + targetAverageUtilization: 50 + } + } + ] + } + }); + + expect(getMetrics(hpa)[0]).toEqual("unknown / 50%"); + }); + + it("should return correct resource metrics with current metrics", () => { + const hpa = new HorizontalPodAutoscaler({ + ...hpaV1, + spec: { + ...hpaV1.spec, + metrics: [ + { + type: HpaMetricType.Resource, + resource: { + name: "cpu", + targetAverageUtilization: 50 + } + } + ] + }, + status: { + currentReplicas: 1, + desiredReplicas: 10, + currentMetrics: [ + { + type: HpaMetricType.Resource, + resource: { + name: "cpu", + currentAverageUtilization: 10 + } + } + ], + } + }); + + expect(getMetrics(hpa)[0]).toEqual("10% / 50%"); + }); + + it("should return correct resource metrics with current value", () => { + const hpa = new HorizontalPodAutoscaler({ + ...hpaV1, + spec: { + ...hpaV1.spec, + metrics: [ + { + type: HpaMetricType.Resource, + resource: { + name: "cpu", + targetAverageValue: "100m" + } + } + ] + }, + status: { + currentReplicas: 1, + desiredReplicas: 10, + currentMetrics: [ + { + type: HpaMetricType.Resource, + resource: { + name: "cpu", + currentAverageValue: "500m" + } + } + ], + } + }); + + expect(getMetrics(hpa)[0]).toEqual("500m / 100m"); + }); + + it("should return correct container resource metrics", () => { + const hpa = new HorizontalPodAutoscaler( + { + ...hpaV1, + spec: { + ...hpaV1.spec, + metrics: [ + { + type: HpaMetricType.ContainerResource, + containerResource: { + name: "cpu", + container: "nginx", + targetAverageUtilization: 60 + } + } + ] + } + } + ); + + expect(getMetrics(hpa)[0]).toEqual("unknown / 60%"); + }); + + it("should return correct container resource metrics with current utilization value", () => { + const hpa = new HorizontalPodAutoscaler( + { + ...hpaV1, + spec: { + ...hpaV1.spec, + metrics: [ + { + type: HpaMetricType.ContainerResource, + containerResource: { + name: "cpu", + container: "nginx", + targetAverageUtilization: 60 + } + } + ] + }, + status: { + currentReplicas: 1, + desiredReplicas: 10, + currentMetrics: [ + { + type: HpaMetricType.ContainerResource, + containerResource: { + name: "cpu", + currentAverageUtilization: 10 + } + } + ], + } + } + ); + + expect(getMetrics(hpa)[0]).toEqual("10% / 60%"); + }); + + it("should return correct pod metrics", () => { + const hpa = new HorizontalPodAutoscaler( + { + ...hpaV1, + spec: { + ...hpaV1.spec, + metrics: [ + { + type: HpaMetricType.Pods, + pods: { + metricName: "packets-per-second", + targetAverageValue: "1k" + } + } + ] + } + } + ); + + expect(getMetrics(hpa)[0]).toEqual("unknown / 1k"); + }); + + it("should return correct pod metrics with current values", () => { + const hpa = new HorizontalPodAutoscaler( + { + ...hpaV1, + spec: { + ...hpaV1.spec, + metrics: [ + { + type: HpaMetricType.Pods, + pods: { + metricName: "packets-per-second", + + targetAverageValue: "1k" + } + } + ] + }, + status: { + currentReplicas: 1, + desiredReplicas: 10, + currentMetrics: [ + { + type: HpaMetricType.Pods, + pods: { + metricName: "packets-per-second", + currentAverageValue: "10" + } + } + ], + } + } + ); + + expect(getMetrics(hpa)[0]).toEqual("10 / 1k"); + }); + + it("should return correct object metrics", () => { + const hpa = new HorizontalPodAutoscaler( + { + ...hpaV1, + spec: { + ...hpaV1.spec, + metrics: [ + { + type: HpaMetricType.Object, + object: { + metricName: "packets-per-second", + targetValue: "10k" + } + } + ] + } + } + ); + + expect(getMetrics(hpa)[0]).toEqual("unknown / 10k"); + }); + + it("should return correct object metrics with average value", () => { + const hpa = new HorizontalPodAutoscaler( + { + ...hpaV1, + spec: { + ...hpaV1.spec, + metrics: [ + { + type: HpaMetricType.Object, + object: { + metricName: "packets-per-second", + averageValue: "5k" + } + } + ] + } + } + ); + + expect(getMetrics(hpa)[0]).toEqual("unknown / 5k"); + }); + + it("should return correct object metrics with current value", () => { + const hpa = new HorizontalPodAutoscaler( + { + ...hpaV1, + spec: { + ...hpaV1.spec, + metrics: [ + { + type: HpaMetricType.Object, + object: { + metricName: "packets-per-second", + targetValue: "5k" + } + } + ] + }, + status: { + currentReplicas: 1, + desiredReplicas: 10, + currentMetrics: [ + { + type: HpaMetricType.Object, + object: { + metricName: "packets-per-second", + currentValue: "10k" + } + } + ], + } + } + ); + + expect(getMetrics(hpa)[0]).toEqual("10k / 5k"); + }); + + it("should return correct external metrics with average value", () => { + const hpa = new HorizontalPodAutoscaler( + { + ...hpaV1, + spec: { + ...hpaV1.spec, + metrics: [ + { + type: HpaMetricType.External, + external: { + metricName: "queue_messages_ready", + metricSelector: { matchLabels: {queue: 'worker_tasks'} }, + targetAverageValue: "30" + } + } + ] + } + } + ); + + expect(getMetrics(hpa)[0]).toEqual("unknown / 30"); + }); + + it("should return correct external metrics with value", () => { + const hpa = new HorizontalPodAutoscaler( + { + ...hpaV1, + spec: { + ...hpaV1.spec, + metrics: [ + { + type: HpaMetricType.External, + external: { + metricName: "queue_messages_ready", + metricSelector: { matchLabels: {queue: 'worker_tasks'} }, + targetValue: "30" + } + } + ] + } + } + ); + + expect(getMetrics(hpa)[0]).toEqual("unknown / 30"); + }); + + it("should return correct external metrics with current value", () => { + const hpa = new HorizontalPodAutoscaler( + { + ...hpaV1, + spec: { + ...hpaV1.spec, + metrics: [ + { + type: HpaMetricType.External, + external: { + metricName: "queue_messages_ready", + metricSelector: { matchLabels: {queue: 'worker_tasks'} }, + targetValue: "30" + } + } + ] + }, + status: { + currentReplicas: 1, + desiredReplicas: 10, + currentMetrics: [ + { + type: HpaMetricType.External, + external: { + metricName: "queue_messages_ready", + currentValue: "10" + } + } + ], + } + } + ); + + expect(getMetrics(hpa)[0]).toEqual("10 / 30"); + }); + + it("should return correct external metrics with current average value", () => { + const hpa = new HorizontalPodAutoscaler( + { + ...hpaV1, + spec: { + ...hpaV1.spec, + metrics: [ + { + type: HpaMetricType.External, + external: { + metricName: "queue_messages_ready", + metricSelector: { matchLabels: {queue: 'worker_tasks'} }, + targetAverageValue: "30" + } + } + ] + }, + status: { + currentReplicas: 1, + desiredReplicas: 10, + currentMetrics: [ + { + type: HpaMetricType.External, + external: { + metricName: "queue_messages_ready", + currentAverageValue: "10" + } + } + ], + } + } + ); + + expect(getMetrics(hpa)[0]).toEqual("10 / 30"); + }); + + it("should return unknown current metrics if metric names are different", () => { + const hpa = new HorizontalPodAutoscaler({ + ...hpaV1, + spec: { + ...hpaV1.spec, + metrics: [ + { + type: HpaMetricType.Resource, + resource: { + name: "cpu", + targetAverageUtilization: 50 + } + } + ] + }, + status: { + currentReplicas: 1, + desiredReplicas: 10, + currentMetrics: [ + { + type: HpaMetricType.Resource, + resource: { + name: "memory", + currentAverageUtilization: 10 + } + } + ], + } + }); + + expect(getMetrics(hpa)[0]).toEqual("unknown / 50%"); + }); + }); }); \ No newline at end of file diff --git a/src/renderer/components/+config-autoscalers/get-hpa-metrics.injectable.ts b/src/renderer/components/+config-autoscalers/get-hpa-metrics.injectable.ts index 3111149570..7b075df691 100644 --- a/src/renderer/components/+config-autoscalers/get-hpa-metrics.injectable.ts +++ b/src/renderer/components/+config-autoscalers/get-hpa-metrics.injectable.ts @@ -1,11 +1,13 @@ import { getInjectable } from "@ogre-tools/injectable"; import { HorizontalPodAutoscaler, HorizontalPodAutoscalerMetricSpec, HorizontalPodAutoscalerMetricStatus, HpaMetricType } from "../../../common/k8s-api/endpoints"; +import horizonalPodAutoscalerV1MetricParser from "./hpa-v1-metric-parser.injectable"; import type { HorizontalPodAutoscalerV2MetricParser } from "./hpa-v2-metric-parser"; import horizonalPodAutoscalerV2MetricParser from "./hpa-v2-metric-parser.injectable"; const getHorizontalPodAutoscalerMetrics = getInjectable({ id: "get-horizontal-pod-autoscaler-metrics", instantiate: (di) => (hpa: HorizontalPodAutoscaler) => { + const hpaV1Parser = di.inject(horizonalPodAutoscalerV1MetricParser); const hpaV2Parser = di.inject(horizonalPodAutoscalerV2MetricParser); const metrics = hpa.spec?.metrics ?? []; const currentMetrics = hpa.status?.currentMetrics ?? []; @@ -15,7 +17,7 @@ const getHorizontalPodAutoscalerMetrics = getInjectable({ current.type === metric.type && getMetricName(current) === getMetricName(metric) ); - const parser = hpa.apiVersion.includes("v2") ? hpaV2Parser : hpaV2Parser; + const parser = hpa.apiVersion.includes("v2") ? hpaV2Parser : hpaV1Parser; const values = getMetricValues(parser, currentMetric, metric);