From 751cb668140bbce8016e90311b1643042aa5143e Mon Sep 17 00:00:00 2001 From: Zbynek Roubalik Date: Thu, 14 Jul 2022 20:17:00 +0200 Subject: [PATCH] Migrate Graphite e2e tests to Go (#3369) --- tests/scalers/graphite.test.ts | 155 ----------- .../graphite/graphite_test.go} | 257 +++++++++++++++--- 2 files changed, 223 insertions(+), 189 deletions(-) delete mode 100644 tests/scalers/graphite.test.ts rename tests/{scalers/graphite-deployment.yaml => scalers_go/graphite/graphite_test.go} (58%) diff --git a/tests/scalers/graphite.test.ts b/tests/scalers/graphite.test.ts deleted file mode 100644 index eccd53f4850..00000000000 --- a/tests/scalers/graphite.test.ts +++ /dev/null @@ -1,155 +0,0 @@ -import * as fs from 'fs' -import * as sh from 'shelljs' -import * as tmp from 'tmp' -import test from 'ava' -import {createNamespace, waitForDeploymentReplicaCount, waitForRollout} from "./helpers"; - -const graphiteNamespace = 'graphite' -const graphiteDeploymentFile = 'scalers/graphite-deployment.yaml' - -test.before(t => { - // install graphite - createNamespace(graphiteNamespace) - t.is(0, - sh.exec(`kubectl apply --namespace ${graphiteNamespace} -f ${graphiteDeploymentFile}`).code, - 'creating a Graphite deployment should work.' - ) - // wait for graphite to load - t.is(0, waitForRollout('statefulset', "graphite", graphiteNamespace)) - - sh.config.silent = true - const tmpFile = tmp.fileSync() - fs.writeFileSync(tmpFile.name, deployYaml.replace('{{GRAPHITE_NAMESPACE}}', graphiteNamespace)) - t.is( - 0, - sh.exec(`kubectl apply -f ${tmpFile.name} --namespace ${graphiteNamespace}`).code, - 'creating graphite scaling test deployment should work.' - ) - for (let i = 0; i < 10; i++) { - const readyReplicaCount = sh.exec(`kubectl get deployment php-apache-graphite --namespace ${graphiteNamespace} -o jsonpath="{.status.readyReplicas}`).stdout - if (readyReplicaCount != '1') { - sh.exec('sleep 2s') - } - } -}) - -test.serial('Deployment should have 0 replica on start', t => { - const replicaCount = sh.exec( - `kubectl get deployment php-apache-graphite --namespace ${graphiteNamespace} -o jsonpath="{.spec.replicas}"` - ).stdout - t.is(replicaCount, '0', 'replica count should start out as 0') -}) - -test.serial(`Deployment should scale to 5 (the max) with HTTP Requests exceeding in the rate then back to 0`, async t => { - const tmpFile = tmp.fileSync() - t.log(tmpFile.name) - - fs.writeFileSync(tmpFile.name, generateRequestsYaml.replace('{{GRAPHITE_NAMESPACE}}', graphiteNamespace)) - t.is( - 0, - sh.exec(`kubectl apply -f ${tmpFile.name} --namespace ${graphiteNamespace}`).code, - 'creating job should work.' - ) - - // keda based deployment should start scaling up with http requests issued - t.true(await waitForDeploymentReplicaCount(5, "php-apache-graphite", graphiteNamespace, 180, 1000), 'Replica count should be maxed at 5') - - fs.writeFileSync(tmpFile.name, generateNoRequestsYaml.replace('{{GRAPHITE_NAMESPACE}}', graphiteNamespace)) - t.is( - 0, - sh.exec(`kubectl apply -f ${tmpFile.name} --namespace ${graphiteNamespace}`).code, - 'creating job should work.' - ) - - t.true(await waitForDeploymentReplicaCount(0, "php-apache-graphite", graphiteNamespace, 300, 1000), 'Replica count should be 0 after 5 minutes') -}) - -test.after.always.cb('clean up graphite deployment', t => { - const resources = [ - 'scaledobject.keda.sh/graphite-scaledobject', - 'deployment.apps/php-apache-graphite', - 'job/generate-graphite-metrics', - ] - - for (const resource of resources) { - sh.exec(`kubectl delete ${resource} --namespace ${graphiteNamespace}`) - } - - // uninstall graphite - sh.exec(`kubectl delete --namespace ${graphiteNamespace} -f ${graphiteDeploymentFile}`) - sh.exec(`kubectl delete namespace ${graphiteNamespace}`) - - t.end() -}) - -const deployYaml = `apiVersion: apps/v1 -kind: Deployment -metadata: - name: php-apache-graphite -spec: - selector: - matchLabels: - run: php-apache-graphite - replicas: 0 - template: - metadata: - labels: - run: php-apache-graphite - spec: - containers: - - name: php-apache-graphite - image: k8s.gcr.io/hpa-example - ports: - - containerPort: 80 ---- -apiVersion: keda.sh/v1alpha1 -kind: ScaledObject -metadata: - name: graphite-scaledobject -spec: - scaleTargetRef: - name: php-apache-graphite - minReplicaCount: 0 - maxReplicaCount: 5 - pollingInterval: 5 - cooldownPeriod: 10 - triggers: - - type: graphite - metadata: - serverAddress: http://graphite.{{GRAPHITE_NAMESPACE}}.svc:8080 - metricName: https_metric - threshold: '100' - query: "https_metric" - queryTime: '-10Seconds'` - -const generateRequestsYaml = `apiVersion: batch/v1 -kind: Job -metadata: - name: generate-load-graphite-metrics -spec: - template: - spec: - containers: - - image: busybox - name: generate-graphite-metrics - command: ["/bin/sh"] - args: ["-c", "for i in $(seq 1 60);do echo $i; echo \\"https_metric 1000 $(date +%s)\\" | nc graphite.{{GRAPHITE_NAMESPACE}}.svc 2003; echo 'data sent :)'; sleep 1; done"] - restartPolicy: Never - activeDeadlineSeconds: 120 - backoffLimit: 2` - -const generateNoRequestsYaml = `apiVersion: batch/v1 -kind: Job -metadata: - name: generate-empty-load-graphite-metrics -spec: - template: - spec: - containers: - - image: busybox - name: generate-graphite-metrics - command: ["/bin/sh"] - args: ["-c", "for i in $(seq 1 60);do echo $i; echo \\"https_metric 0 $(date +%s)\\" | nc graphite.{{GRAPHITE_NAMESPACE}}.svc 2003; echo 'data sent :)'; sleep 1; done"] - restartPolicy: Never - activeDeadlineSeconds: 120 - backoffLimit: 2` diff --git a/tests/scalers/graphite-deployment.yaml b/tests/scalers_go/graphite/graphite_test.go similarity index 58% rename from tests/scalers/graphite-deployment.yaml rename to tests/scalers_go/graphite/graphite_test.go index d0de94ea9d1..c138c6d3222 100644 --- a/tests/scalers/graphite-deployment.yaml +++ b/tests/scalers_go/graphite/graphite_test.go @@ -1,9 +1,75 @@ ---- -# Source: graphite/templates/configmap-statsd.yaml +//go:build e2e +// +build e2e + +package graphite_test + +import ( + "fmt" + "testing" + + "github.com/joho/godotenv" + "github.com/stretchr/testify/assert" + "k8s.io/client-go/kubernetes" + + . "github.com/kedacore/keda/v2/tests/helper" +) + +// Load environment variables from .env file +var _ = godotenv.Load("../../.env") + +const ( + testName = "graphite-test" +) + +var ( + testNamespace = fmt.Sprintf("%s-ns", testName) + deploymentName = fmt.Sprintf("%s-deployment", testName) + scaledObjectName = fmt.Sprintf("%s-so", testName) + minReplicaCount = 0 + maxReplicaCount = 5 +) + +type templateData struct { + TestNamespace string + DeploymentName string + ScaledObjectName string + SecretName string + MinReplicaCount int + MaxReplicaCount int +} + +type templateValues map[string]string + +const ( + deploymentTemplate = `apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{.DeploymentName}} + namespace: {{.TestNamespace}} +spec: + selector: + matchLabels: + run: {{.DeploymentName}} + replicas: 0 + template: + metadata: + labels: + run: {{.DeploymentName}} + spec: + containers: + - name: php-apache-graphite + image: k8s.gcr.io/hpa-example + ports: + - containerPort: 80 +` + + // Source: graphite/templates/configmap-statsd.yaml + graphiteStatsdConfigMapTemplate = ` apiVersion: v1 kind: ConfigMap metadata: name: graphite-statsd-configmap + namespace: {{.TestNamespace}} labels: app.kubernetes.io/name: graphite helm.sh/chart: graphite-0.7.2 @@ -34,12 +100,15 @@ data: "port": 8125 }] } ---- -# Source: graphite/templates/configmap.yaml +` + + // Source: graphite/templates/configmap.yaml + graphiteConfigMapTemplate = ` apiVersion: v1 kind: ConfigMap metadata: name: graphite-configmap + namespace: {{.TestNamespace}} labels: app: graphite chart: graphite-0.7.2 @@ -233,13 +302,14 @@ data: [default_1min_for_1day] pattern = .* retentions = 10s:6h,1m:6d,10m:1800d +` ---- -# Source: graphite/templates/service.yaml -apiVersion: v1 + // Source: graphite/templates/service.yaml + graphiteServiceTemplate = `apiVersion: v1 kind: Service metadata: name: graphite + namespace: {{.TestNamespace}} labels: app.kubernetes.io/name: graphite helm.sh/chart: graphite-0.7.2 @@ -248,39 +318,41 @@ metadata: spec: type: ClusterIP ports: - - name: graphite-pickle - port: 2004 - protocol: TCP - - name: graphite-plain - port: 2003 - protocol: TCP - - name: graphite-udp - port: 2003 - protocol: UDP - - name: graphite-gui - port: 8080 - protocol: TCP - - name: aggregate-plain - port: 2023 - protocol: TCP - - name: aggregate-pickl - port: 2024 - protocol: TCP - - name: statsd - port: 8125 - protocol: UDP - - name: statsd-admin - port: 8126 - protocol: TCP + - name: graphite-pickle + port: 2004 + protocol: TCP + - name: graphite-plain + port: 2003 + protocol: TCP + - name: graphite-udp + port: 2003 + protocol: UDP + - name: graphite-gui + port: 8080 + protocol: TCP + - name: aggregate-plain + port: 2023 + protocol: TCP + - name: aggregate-pickl + port: 2024 + protocol: TCP + - name: statsd + port: 8125 + protocol: UDP + - name: statsd-admin + port: 8126 + protocol: TCP selector: app.kubernetes.io/name: graphite app.kubernetes.io/instance: RELEASE-NAME ---- -# Source: graphite/templates/statefulset.yaml -apiVersion: apps/v1 +` + + // Source: graphite/templates/statefulset.yaml + graphiteStatefulSetTemplate = `apiVersion: apps/v1 kind: StatefulSet metadata: name: graphite + namespace: {{.TestNamespace}} labels: app.kubernetes.io/name: graphite helm.sh/chart: graphite-0.7.2 @@ -357,3 +429,120 @@ spec: name: graphite-statsd-configmap - name: graphite-pvc emptyDir: {} +` + + scaledObjectTemplate = `apiVersion: keda.sh/v1alpha1 +kind: ScaledObject +metadata: + name: {{.ScaledObjectName}} + namespace: {{.TestNamespace}} +spec: + scaleTargetRef: + name: {{.DeploymentName}} + minReplicaCount: {{.MinReplicaCount}} + maxReplicaCount: {{.MaxReplicaCount}} + pollingInterval: 5 + cooldownPeriod: 10 + triggers: + - type: graphite + metadata: + serverAddress: http://graphite.{{.TestNamespace}}.svc:8080 + metricName: https_metric + threshold: '100' + query: "https_metric" + queryTime: '-10Seconds' +` + + requestsJobTemplate = `apiVersion: batch/v1 +kind: Job +metadata: + name: generate-load-graphite-metrics + namespace: {{.TestNamespace}} +spec: + template: + spec: + containers: + - image: busybox + name: generate-graphite-metrics + command: ["/bin/sh"] + args: + - -c + - for i in $(seq 1 60);do echo $i; echo "https_metric 1000 $(date +%s)" | nc graphite.{{.TestNamespace}}.svc 2003; echo 'data sent :)'; sleep 1; done + restartPolicy: Never + activeDeadlineSeconds: 120 + backoffLimit: 2 +` + + emptyRequestsJobTemplate = `apiVersion: batch/v1 +kind: Job +metadata: + name: generate-empty-load-graphite-metrics + namespace: {{.TestNamespace}} +spec: + template: + spec: + containers: + - image: busybox + name: generate-graphite-metrics + command: ["/bin/sh"] + args: + - -c + - for i in $(seq 1 60);do echo $i; echo "https_metric 0 $(date +%s)" | nc graphite.{{.TestNamespace}}.svc 2003; echo 'data sent :)'; sleep 1; done + restartPolicy: Never + activeDeadlineSeconds: 120 + backoffLimit: 2 +` +) + +func TestGraphiteScaler(t *testing.T) { + // Create kubernetes resources + kc := GetKubernetesClient(t) + data, templates := getTemplateData() + CreateKubernetesResources(t, kc, testNamespace, data, templates) + + assert.True(t, WaitForStatefulsetReplicaReadyCount(t, kc, "graphite", testNamespace, 1, 60, 3), + "replica count should be %s after 3 minute", minReplicaCount) + assert.True(t, WaitForDeploymentReplicaCount(t, kc, deploymentName, testNamespace, minReplicaCount, 60, 3), + "replica count should be %s after 3 minute", minReplicaCount) + + testScaleUp(t, kc, data) + testScaleDown(t, kc, data) + + // cleanup + DeleteKubernetesResources(t, kc, testNamespace, data, templates) +} + +func testScaleUp(t *testing.T, kc *kubernetes.Clientset, data templateData) { + t.Log("--- testing scale up ---") + templateTriggerJob := templateValues{"requestsJobTemplate": requestsJobTemplate} + KubectlApplyMultipleWithTemplate(t, data, templateTriggerJob) + + assert.True(t, WaitForDeploymentReplicaCount(t, kc, deploymentName, testNamespace, maxReplicaCount, 60, 3), + "replica count should be %s after 3 minutes", maxReplicaCount) +} + +func testScaleDown(t *testing.T, kc *kubernetes.Clientset, data templateData) { + t.Log("--- testing scale down ---") + templateTriggerJob := templateValues{"emptyRequestsJobTemplate": emptyRequestsJobTemplate} + KubectlApplyMultipleWithTemplate(t, data, templateTriggerJob) + + assert.True(t, WaitForDeploymentReplicaCount(t, kc, deploymentName, testNamespace, minReplicaCount, 60, 3), + "replica count should be %s after 3 minutes", minReplicaCount) +} + +func getTemplateData() (templateData, map[string]string) { + return templateData{ + TestNamespace: testNamespace, + DeploymentName: deploymentName, + ScaledObjectName: scaledObjectName, + MinReplicaCount: minReplicaCount, + MaxReplicaCount: maxReplicaCount, + }, templateValues{ + "graphiteStatsdConfigMapTemplate": graphiteStatsdConfigMapTemplate, + "graphiteConfigMapTemplate": graphiteConfigMapTemplate, + "graphiteServiceTemplate": graphiteServiceTemplate, + "graphiteStatefulSetTemplate": graphiteStatefulSetTemplate, + "deploymentTemplate": deploymentTemplate, + "scaledObjectTemplate": scaledObjectTemplate, + } +}