From fd1e9464f45179451934d491839e44b72590b1f2 Mon Sep 17 00:00:00 2001 From: Zbynek Roubalik Date: Tue, 19 Jul 2022 12:57:47 +0200 Subject: [PATCH 1/2] Migrate Prometheus e2e test to Go Signed-off-by: Zbynek Roubalik --- .../scalers_go/prometheus/prometheus_test.go | 722 ++++++++++++++++++ 1 file changed, 722 insertions(+) create mode 100644 tests/scalers_go/prometheus/prometheus_test.go diff --git a/tests/scalers_go/prometheus/prometheus_test.go b/tests/scalers_go/prometheus/prometheus_test.go new file mode 100644 index 00000000000..631b8b5cb33 --- /dev/null +++ b/tests/scalers_go/prometheus/prometheus_test.go @@ -0,0 +1,722 @@ +//go:build e2e +// +build e2e + +package prometheus_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 = "prometheus-test" +) + +var ( + testNamespace = fmt.Sprintf("%s-ns", testName) + deploymentName = fmt.Sprintf("%s-deployment", testName) + monitoredAppName = fmt.Sprintf("%s-monitored-app", testName) + publishDeploymentName = fmt.Sprintf("%s-publish", testName) + scaledObjectName = fmt.Sprintf("%s-so", testName) + prometheusServerName = fmt.Sprintf("%s-server", testName) + minReplicaCount = 0 + maxReplicaCount = 2 +) + +type templateData struct { + TestNamespace string + DeploymentName string + MonitoredAppName string + PublishDeploymentName string + ScaledObjectName string + PrometheusServerName string + MinReplicaCount int + MaxReplicaCount int +} + +type templateValues map[string]string + +const ( + deploymentTemplate = `apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: test-app + name: {{.DeploymentName}} + namespace: {{.TestNamespace}} +spec: + replicas: 0 + selector: + matchLabels: + app: test-app + template: + metadata: + labels: + app: test-app + type: keda-testing + spec: + containers: + - name: prom-test-app + image: quay.io/zroubalik/prometheus-app:latest + imagePullPolicy: IfNotPresent + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault +--- +` + + monitoredAppDeploymentTemplate = `apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: {{.MonitoredAppName}} + name: {{.MonitoredAppName}} + namespace: {{.TestNamespace}} +spec: + replicas: 1 + selector: + matchLabels: + app: {{.MonitoredAppName}} + template: + metadata: + labels: + app: {{.MonitoredAppName}} + type: {{.MonitoredAppName}} + spec: + containers: + - name: prom-test-app + image: quay.io/zroubalik/prometheus-app:latest + imagePullPolicy: IfNotPresent + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault +--- +` + + monitoredAppServiceTemplate = `apiVersion: v1 +kind: Service +metadata: + labels: + app: {{.MonitoredAppName}} + name: {{.MonitoredAppName}} + namespace: {{.TestNamespace}} + annotations: + prometheus.io/scrape: "true" +spec: + ports: + - name: http + port: 80 + protocol: TCP + targetPort: 8080 + selector: + type: {{.MonitoredAppName}} +` + + prometheusServerConfigMapTemplate = `apiVersion: v1 +kind: ConfigMap +metadata: + labels: + component: "server" + app: prometheus + release: prometheus + name: {{.PrometheusServerName}} + namespace: {{.TestNamespace}} +data: + alerting_rules.yml: | + {} + + alerts: | + {} + + prometheus.yml: | + global: + evaluation_interval: 1m + scrape_interval: 1m + scrape_timeout: 10s + rule_files: + - /etc/config/recording_rules.yml + - /etc/config/alerting_rules.yml + - /etc/config/rules + - /etc/config/alerts + scrape_configs: + - job_name: prometheus + static_configs: + - targets: + - localhost:9090 + - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + job_name: kubernetes-apiservers + kubernetes_sd_configs: + - role: endpoints + relabel_configs: + - action: keep + regex: default;kubernetes;https + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - __meta_kubernetes_endpoint_port_name + scheme: https + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true + - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + job_name: kubernetes-nodes + kubernetes_sd_configs: + - role: node + relabel_configs: + - action: labelmap + regex: __meta_kubernetes_node_label_(.+) + - replacement: kubernetes.default.svc:443 + target_label: __address__ + - regex: (.+) + replacement: /api/v1/nodes/$1/proxy/metrics + source_labels: + - __meta_kubernetes_node_name + target_label: __metrics_path__ + scheme: https + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true + - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + job_name: kubernetes-nodes-cadvisor + kubernetes_sd_configs: + - role: node + relabel_configs: + - action: labelmap + regex: __meta_kubernetes_node_label_(.+) + - replacement: kubernetes.default.svc:443 + target_label: __address__ + - regex: (.+) + replacement: /api/v1/nodes/$1/proxy/metrics/cadvisor + source_labels: + - __meta_kubernetes_node_name + target_label: __metrics_path__ + scheme: https + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true + - job_name: kubernetes-service-endpoints + kubernetes_sd_configs: + - role: endpoints + relabel_configs: + - action: keep + regex: true + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_scrape + - action: replace + regex: (https?) + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_scheme + target_label: __scheme__ + - action: replace + regex: (.+) + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_path + target_label: __metrics_path__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_annotation_prometheus_io_port + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_service_label_(.+) + - action: replace + source_labels: + - __meta_kubernetes_namespace + target_label: kubernetes_namespace + - action: replace + source_labels: + - __meta_kubernetes_service_name + target_label: kubernetes_name + - action: replace + source_labels: + - __meta_kubernetes_pod_node_name + target_label: kubernetes_node + - job_name: kubernetes-service-endpoints-slow + kubernetes_sd_configs: + - role: endpoints + relabel_configs: + - action: keep + regex: true + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_scrape_slow + - action: replace + regex: (https?) + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_scheme + target_label: __scheme__ + - action: replace + regex: (.+) + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_path + target_label: __metrics_path__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_annotation_prometheus_io_port + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_service_label_(.+) + - action: replace + source_labels: + - __meta_kubernetes_namespace + target_label: kubernetes_namespace + - action: replace + source_labels: + - __meta_kubernetes_service_name + target_label: kubernetes_name + - action: replace + source_labels: + - __meta_kubernetes_pod_node_name + target_label: kubernetes_node + scrape_interval: 5m + scrape_timeout: 30s + - honor_labels: true + job_name: prometheus-pushgateway + kubernetes_sd_configs: + - role: service + relabel_configs: + - action: keep + regex: pushgateway + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_probe + - job_name: kubernetes-services + kubernetes_sd_configs: + - role: service + metrics_path: /probe + params: + module: + - http_2xx + relabel_configs: + - action: keep + regex: true + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_probe + - source_labels: + - __address__ + target_label: __param_target + - replacement: blackbox + target_label: __address__ + - source_labels: + - __param_target + target_label: instance + - action: labelmap + regex: __meta_kubernetes_service_label_(.+) + - source_labels: + - __meta_kubernetes_namespace + target_label: kubernetes_namespace + - source_labels: + - __meta_kubernetes_service_name + target_label: kubernetes_name + - job_name: kubernetes-pods + kubernetes_sd_configs: + - role: pod + relabel_configs: + - action: keep + regex: true + source_labels: + - __meta_kubernetes_pod_annotation_prometheus_io_scrape + - action: replace + regex: (.+) + source_labels: + - __meta_kubernetes_pod_annotation_prometheus_io_path + target_label: __metrics_path__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_pod_annotation_prometheus_io_port + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - action: replace + source_labels: + - __meta_kubernetes_namespace + target_label: kubernetes_namespace + - action: replace + source_labels: + - __meta_kubernetes_pod_name + target_label: kubernetes_pod_name + - job_name: kubernetes-pods-slow + kubernetes_sd_configs: + - role: pod + relabel_configs: + - action: keep + regex: true + source_labels: + - __meta_kubernetes_pod_annotation_prometheus_io_scrape_slow + - action: replace + regex: (.+) + source_labels: + - __meta_kubernetes_pod_annotation_prometheus_io_path + target_label: __metrics_path__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_pod_annotation_prometheus_io_port + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - action: replace + source_labels: + - __meta_kubernetes_namespace + target_label: kubernetes_namespace + - action: replace + source_labels: + - __meta_kubernetes_pod_name + target_label: kubernetes_pod_name + scrape_interval: 5m + scrape_timeout: 30s + + recording_rules.yml: | + {} + + rules: | + {} +` + + prometheusServerServiceAccountTemplate = `apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + component: "server" + app: prometheus + release: prometheus + chart: prometheus-11.1.0 + name: {{.PrometheusServerName}} + namespace: {{.TestNamespace}} + annotations: + {} +` + + prometheusServerClusterRoleTemplate = `apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + component: "server" + app: prometheus + release: prometheus + chart: prometheus-11.1.0 + name: {{.PrometheusServerName}} + namespace: {{.TestNamespace}} +rules: + - apiGroups: + - "" + resources: + - nodes + - nodes/proxy + - nodes/metrics + - services + - endpoints + - pods + - ingresses + - configmaps + verbs: + - get + - list + - watch + - apiGroups: + - "extensions" + resources: + - ingresses/status + - ingresses + verbs: + - get + - list + - watch + - nonResourceURLs: + - "/metrics" + verbs: + - get +` + + prometheusServerClusterRoleBindingTemplate = `apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + component: "server" + app: prometheus + release: prometheus + chart: prometheus-11.1.0 + name: {{.PrometheusServerName}} + namespace: {{.TestNamespace}} +subjects: + - kind: ServiceAccount + name: {{.PrometheusServerName}} + namespace: {{.TestNamespace}} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{.PrometheusServerName}} +` + + prometheusServerServiceTemplate = `apiVersion: v1 +kind: Service +metadata: + labels: + component: "server" + app: prometheus + release: prometheus + chart: prometheus-11.1.0 + name: {{.PrometheusServerName}} + namespace: {{.TestNamespace}} +spec: + ports: + - name: http + port: 80 + protocol: TCP + targetPort: 9090 + selector: + component: "server" + app: prometheus + release: prometheus + sessionAffinity: None + type: "ClusterIP" +` + + prometheusServerDeploymentTemplate = `apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + component: "server" + app: prometheus + release: prometheus + chart: prometheus-11.1.0 + name: {{.PrometheusServerName}} + namespace: {{.TestNamespace}} +spec: + selector: + matchLabels: + component: "server" + app: prometheus + release: prometheus + replicas: 1 + template: + metadata: + labels: + component: "server" + app: prometheus + release: prometheus + chart: prometheus-11.1.0 + spec: + serviceAccountName: {{.PrometheusServerName}} + containers: + - name: prometheus-server-configmap-reload + image: "jimmidyson/configmap-reload:v0.3.0" + imagePullPolicy: "IfNotPresent" + args: + - --volume-dir=/etc/config + - --webhook-url=http://127.0.0.1:9090/-/reload + resources: + {} + + volumeMounts: + - name: config-volume + mountPath: /etc/config + readOnly: true + + - name: prometheus-server + image: "prom/prometheus:v2.16.0" + imagePullPolicy: "IfNotPresent" + args: + - --storage.tsdb.retention.time=15d + - --config.file=/etc/config/prometheus.yml + - --storage.tsdb.path=/data + - --web.console.libraries=/etc/prometheus/console_libraries + - --web.console.templates=/etc/prometheus/consoles + - --web.enable-lifecycle + ports: + - containerPort: 9090 + readinessProbe: + httpGet: + path: /-/ready + port: 9090 + initialDelaySeconds: 30 + timeoutSeconds: 30 + failureThreshold: 3 + successThreshold: 1 + livenessProbe: + httpGet: + path: /-/healthy + port: 9090 + initialDelaySeconds: 30 + timeoutSeconds: 30 + failureThreshold: 3 + successThreshold: 1 + resources: + {} + + volumeMounts: + - name: config-volume + mountPath: /etc/config + - name: storage-volume + mountPath: /data + subPath: "" + securityContext: + fsGroup: 65534 + runAsGroup: 65534 + runAsNonRoot: true + runAsUser: 65534 + + terminationGracePeriodSeconds: 300 + volumes: + - name: config-volume + configMap: + name: {{.PrometheusServerName}} + - name: storage-volume + emptyDir: {} +` + + scaledObjectTemplate = `apiVersion: keda.sh/v1alpha1 +kind: ScaledObject +metadata: + name: {{.ScaledObjectName}} + namespace: {{.TestNamespace}} +spec: + scaleTargetRef: + name: {{.DeploymentName}} + minReplicaCount: {{.MinReplicaCount}} + maxReplicaCount: {{.MaxReplicaCount}} + pollingInterval: 3 + cooldownPeriod: 1 + triggers: + - type: prometheus + metadata: + serverAddress: http://{{.PrometheusServerName}}.{{.TestNamespace}}.svc + metricName: http_requests_total + threshold: '20' + query: sum(rate(http_requests_total{app="{{.MonitoredAppName}}"}[2m])) +` + + generateLoadJobTemplate = `apiVersion: batch/v1 +kind: Job +metadata: + name: generate-requests-job + namespace: {{.TestNamespace}} +spec: + template: + spec: + containers: + - image: quay.io/zroubalik/hey + name: test + command: ["/bin/sh"] + args: ["-c", "for i in $(seq 1 60);do echo $i;/hey -c 5 -n 80 http://{{.MonitoredAppName}}.{{.TestNamespace}}.svc;sleep 1;done"] + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + restartPolicy: Never + activeDeadlineSeconds: 100 + backoffLimit: 2 +` +) + +// TestPrometheusScaler creates deployments - there are two deployments - both using the same image but one deployment +// is directly tied to the KEDA HPA while the other is isolated that can be used for metrics +// even when the KEDA deployment is at zero - the service points to both deployments +func TestPrometheusScaler(t *testing.T) { + // Create kubernetes resources + kc := GetKubernetesClient(t) + data, prometheusServerTemplates := getPrometheusServerTemplateData() + CreateKubernetesResources(t, kc, testNamespace, data, prometheusServerTemplates) + + assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, prometheusServerName, testNamespace, 1, 60, 3), + "replica count should be %d after 3 minutes", minReplicaCount) + + // Create kubernetes resources for testing + data, templates := getTemplateData() + KubectlApplyMultipleWithTemplate(t, data, templates) + assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, monitoredAppName, testNamespace, 1, 60, 3), + "replica count should be %d after 3 minutes", minReplicaCount) + assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, minReplicaCount, 60, 3), + "replica count should be %d after 3 minutes", minReplicaCount) + + testScaleUp(t, kc, data) + testScaleDown(t, kc) + + // cleanup + KubectlDeleteMultipleWithTemplate(t, data, templates) + DeleteKubernetesResources(t, kc, testNamespace, data, prometheusServerTemplates) +} + +func testScaleUp(t *testing.T, kc *kubernetes.Clientset, data templateData) { + t.Log("--- testing scale up ---") + templateTriggerDeployment := templateValues{"generateLoadJobTemplate": generateLoadJobTemplate} + KubectlApplyMultipleWithTemplate(t, data, templateTriggerDeployment) + + assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, maxReplicaCount, 60, 3), + "replica count should be %d after 3 minutes", maxReplicaCount) +} + +func testScaleDown(t *testing.T, kc *kubernetes.Clientset) { + t.Log("--- testing scale down ---") + assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, minReplicaCount, 60, 5), + "replica count should be %d after 5 minutes", minReplicaCount) +} + +func getPrometheusServerTemplateData() (templateData, map[string]string) { + return templateData{ + TestNamespace: testNamespace, + DeploymentName: deploymentName, + PublishDeploymentName: publishDeploymentName, + ScaledObjectName: scaledObjectName, + MonitoredAppName: monitoredAppName, + PrometheusServerName: prometheusServerName, + MinReplicaCount: minReplicaCount, + MaxReplicaCount: maxReplicaCount, + }, templateValues{ + "prometheusServerConfigMapTemplate": prometheusServerConfigMapTemplate, + "prometheusServerServiceAccountTemplate": prometheusServerServiceAccountTemplate, + "prometheusServerClusterRoleTemplate": prometheusServerClusterRoleTemplate, + "prometheusServerClusterRoleBindingTemplate": prometheusServerClusterRoleBindingTemplate, + "prometheusServerServiceTemplate": prometheusServerServiceTemplate, + "prometheusServerDeploymentTemplate": prometheusServerDeploymentTemplate, + } +} + +func getTemplateData() (templateData, map[string]string) { + return templateData{ + TestNamespace: testNamespace, + DeploymentName: deploymentName, + PublishDeploymentName: publishDeploymentName, + ScaledObjectName: scaledObjectName, + MonitoredAppName: monitoredAppName, + PrometheusServerName: prometheusServerName, + MinReplicaCount: minReplicaCount, + MaxReplicaCount: maxReplicaCount, + }, templateValues{ + "deploymentTemplate": deploymentTemplate, + "monitoredAppDeploymentTemplate": monitoredAppDeploymentTemplate, + "monitoredAppServiceTemplate": monitoredAppServiceTemplate, + "scaledObjectTemplate": scaledObjectTemplate, + } +} From 8ab617612614d468e9606b0d6c967d21de21b723 Mon Sep 17 00:00:00 2001 From: Zbynek Roubalik Date: Tue, 19 Jul 2022 12:59:41 +0200 Subject: [PATCH 2/2] remove TS test Signed-off-by: Zbynek Roubalik --- tests/scalers/prometheus.test.ts | 189 ------------------------------- 1 file changed, 189 deletions(-) delete mode 100644 tests/scalers/prometheus.test.ts diff --git a/tests/scalers/prometheus.test.ts b/tests/scalers/prometheus.test.ts deleted file mode 100644 index 1b53fe007c7..00000000000 --- a/tests/scalers/prometheus.test.ts +++ /dev/null @@ -1,189 +0,0 @@ -import * as fs from 'fs' -import * as sh from 'shelljs' -import * as tmp from 'tmp' -import test from 'ava' -import { PrometheusServer } from './prometheus-server-helpers' -import { createNamespace, waitForDeploymentReplicaCount } from './helpers' - -const testNamespace = 'prometheus-test' -const prometheusNamespace = 'prometheus-test-monitoring' -const loadGeneratorJob = tmp.fileSync() - -test.before(async t => { - // install prometheus - PrometheusServer.install(t, prometheusNamespace) - - sh.config.silent = true - // create deployments - there are two deployments - both using the same image but one deployment - // is directly tied to the KEDA HPA while the other is isolated that can be used for metrics - // even when the KEDA deployment is at zero - the service points to both deployments - const tmpFile = tmp.fileSync() - fs.writeFileSync(tmpFile.name, deployYaml.replace('{{PROMETHEUS_NAMESPACE}}', prometheusNamespace)) - createNamespace(testNamespace) - t.is( - 0, - sh.exec(`kubectl apply -f ${tmpFile.name} --namespace ${testNamespace}`).code, - 'creating a deployment should work.' - ) - t.true(await waitForDeploymentReplicaCount(1, 'test-app', testNamespace, 60, 1000), 'test-app replica count should be 1 after 1 minute') - - fs.writeFileSync(loadGeneratorJob.name, generateRequestsYaml.replace('{{NAMESPACE}}', testNamespace)) -}) - -test.serial('Metric type should be "AverageValue"',async t => { - const scaledObjectMetricType = sh.exec( - `kubectl get scaledobject.keda.sh/prometheus-scaledobject --namespace ${testNamespace} -o jsonpath="{.spec.triggers[0].metricType}"` - ).stdout - const hpaMetricType = sh.exec( - `kubectl get hpa.v2beta2.autoscaling/keda-hpa-prometheus-scaledobject --namespace ${testNamespace} -o jsonpath="{.spec.metrics[0].external.target.type}"` - ).stdout - - // when the metric type isn't explicitly set in the ScaledObject, it should default to AverageValue in the HPA - t.is('', scaledObjectMetricType, 'prometheus-scaledobject trigger metric type should be ""') - t.is('AverageValue', hpaMetricType, 'keda-hpa-prometheus-scaledobject metric target type should be "AverageValue"') -}) - -test.serial('Deployment should have 0 replicas on start', async t => { - t.true(await waitForDeploymentReplicaCount(0, 'keda-test-app', testNamespace, 60, 1000), 'keda-test-app replica count should be 0 after 1 minute') -}) - -test.serial(`Deployment should scale to 2 (the max) with HTTP Requests exceeding in the rate`, async t => { - // generate a large number of HTTP requests (using Apache Bench) that will take some time - // so prometheus has some time to scrape it - t.is( - 0, - sh.exec(`kubectl apply -f ${loadGeneratorJob.name} --namespace ${testNamespace}`).code, - 'creating job should work.' - ) - - t.true(await waitForDeploymentReplicaCount(2, 'keda-test-app', testNamespace, 600, 1000), 'keda-test-app replica count should be 2 after 10 minutes') -}) - -test.serial(`Deployment should scale to 0`, async t => { - // Stop the load - t.is( - 0, - sh.exec(`kubectl delete -f ${loadGeneratorJob.name} --namespace ${testNamespace}`).code, - 'deleting job should work.' - ) - - t.true(await waitForDeploymentReplicaCount(0, 'keda-test-app', testNamespace, 300, 1000), 'keda-test-app replica count should be 0 after 5 minutes') - -}) - - -test.after.always.cb('clean up prometheus deployment', t => { - const resources = [ - 'scaledobject.keda.sh/prometheus-scaledobject', - 'deployment.apps/test-app', - 'deployment.apps/keda-test-app', - 'service/test-app', - 'job/generate-requests', - ] - - for (const resource of resources) { - sh.exec(`kubectl delete ${resource} --namespace ${testNamespace}`) - } - sh.exec(`kubectl delete namespace ${testNamespace}`) - - // uninstall prometheus - PrometheusServer.uninstall(prometheusNamespace) - - t.end() -}) - -const deployYaml = `apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: test-app - name: test-app -spec: - replicas: 1 - selector: - matchLabels: - app: test-app - template: - metadata: - labels: - app: test-app - type: keda-testing - spec: - containers: - - name: prom-test-app - image: tbickford/simple-web-app-prometheus:a13ade9 - imagePullPolicy: IfNotPresent ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: keda-test-app - name: keda-test-app -spec: - replicas: 0 - selector: - matchLabels: - app: keda-test-app - template: - metadata: - labels: - app: keda-test-app - type: keda-testing - spec: - containers: - - name: prom-test-app - image: tbickford/simple-web-app-prometheus:a13ade9 - imagePullPolicy: IfNotPresent ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app: test-app - annotations: - prometheus.io/scrape: "true" - name: test-app -spec: - ports: - - name: http - port: 80 - protocol: TCP - targetPort: 8080 - selector: - type: keda-testing ---- -apiVersion: keda.sh/v1alpha1 -kind: ScaledObject -metadata: - name: prometheus-scaledobject -spec: - scaleTargetRef: - name: keda-test-app - minReplicaCount: 0 - maxReplicaCount: 2 - pollingInterval: 5 - cooldownPeriod: 10 - triggers: - - type: prometheus - metadata: - serverAddress: http://prometheus-server.{{PROMETHEUS_NAMESPACE}}.svc - metricName: http_requests_total - threshold: '100' - query: sum(rate(http_requests_total{app="test-app"}[2m]))` - -const generateRequestsYaml = `apiVersion: batch/v1 -kind: Job -metadata: - name: generate-requests -spec: - template: - spec: - containers: - - image: jordi/ab - name: test - command: ["/bin/sh"] - args: ["-c", "for i in $(seq 1 600);do echo $i;ab -c 5 -n 1000 -v 2 http://test-app.{{NAMESPACE}}.svc/;sleep 1;done"] - restartPolicy: Never - activeDeadlineSeconds: 600 - backoffLimit: 5`