Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix metric name passed to external scaler in GetMetrics call. #2890

Merged
merged 7 commits into from
Apr 8, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@
- **AWS DynamoDB:** Setup AWS DynamoDB test account ([#2803](https://github.com/kedacore/keda/issues/2803))
- **AWS Kinesis Stream:** Adding e2e test ([#1526](https://github.com/kedacore/keda/issues/1526))
- **AWS SQS Queue:** Adding e2e test ([#1527](https://github.com/kedacore/keda/issues/1527))
- **External Scaler:** Adding e2e test. ([#2697](https://github.com/kedacore/keda/issues/2697))
- **External Scaler:** Fix issue with internal KEDA core prefix being passed to external scaler. ([#2640](https://github.com/kedacore/keda/issues/2640))
- **GCP Pubsub Scaler:** Adding e2e test ([#1528](https://github.com/kedacore/keda/issues/1528))
- **Hashicorp Vault Secret Provider:** Adding e2e test ([#2842](https://github.com/kedacore/keda/issues/2842))
- **Memory Scaler:** Adding e2e test ([#2220](https://github.com/kedacore/keda/issues/2220))
Expand Down
2 changes: 2 additions & 0 deletions pkg/scalers/external_scaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ func (s *externalScaler) GetMetrics(ctx context.Context, metricName string, metr
}
defer done()

// Remove the sX- prefix as the external scaler shouldn't have to know about it
metricName = strings.SplitN(metricName, "-", 2)[1]
v-shenoy marked this conversation as resolved.
Show resolved Hide resolved
request := &pb.GetMetricsRequest{
MetricName: metricName,
ScaledObjectRef: &s.scaledObjectRef,
Expand Down
192 changes: 192 additions & 0 deletions tests/scalers/external-scaler.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import * as sh from "shelljs"
import test from "ava"
import { createNamespace, createYamlFile, waitForDeploymentReplicaCount } from "./helpers"

const testName = "test-external-scaler"
const testNamespace = `${testName}-ns`
const scalerName = `${testName}-scaler`
const serviceName = `${testName}-service`
const deploymentName = `${testName}-deployment`
const scaledObjectName = `${testName}-scaled-object`

const idleReplicaCount = 0
const minReplicaCount = 1
const maxReplicaCount = 2
const threshold = 10

test.before(async t => {
sh.config.silent = true

// Create Kubernetes Namespace
createNamespace(testNamespace)

// Create external scaler deployment
t.is(
sh.exec(`kubectl apply -f ${createYamlFile(scalerYaml)} -n ${testNamespace}`).code,
0,
"Createing a external scaler deployment should work"
)

// Create service
t.is(
sh.exec(`kubectl apply -f ${createYamlFile(serviceYaml)} -n ${testNamespace}`).code,
0,
"Createing a service should work"
)

// Create deployment
t.is(
sh.exec(`kubectl apply -f ${createYamlFile(deploymentYaml)} -n ${testNamespace}`).code,
0,
"Createing a deployment should work"
)

// Create scaled object
t.is(
sh.exec(`kubectl apply -f ${createYamlFile(scaledObjectYaml.replace("{{VALUE}}", "0"))} -n ${testNamespace}`).code,
0,
"Creating a scaled object should work"
)

t.true(await waitForDeploymentReplicaCount(idleReplicaCount, deploymentName, testNamespace, 60, 1000),
`Replica count should be ${idleReplicaCount} after 1 minute`)
})

test.serial("Deployment should scale up to minReplicaCount", async t => {
// Modify scaled object's metricValue to induce scaling
t.is(
sh.exec(`kubectl apply -f ${createYamlFile(scaledObjectYaml.replace("{{VALUE}}", `${threshold}`))} -n ${testNamespace}`).code,
0,
"Modifying scaled object should work"
)

t.true(await waitForDeploymentReplicaCount(minReplicaCount, deploymentName, testNamespace, 60, 1000),
`Replica count should be ${minReplicaCount} after 1 minute`)
})

test.serial("Deployment should scale up to maxReplicaCount", async t => {
// Modify scaled object's metricValue to induce scaling
t.is(
sh.exec(`kubectl apply -f ${createYamlFile(scaledObjectYaml.replace("{{VALUE}}", `${threshold * 2}`))} -n ${testNamespace}`).code,
0,
"Modifying scaled object should work"
)

t.true(await waitForDeploymentReplicaCount(maxReplicaCount, deploymentName, testNamespace, 60, 1000),
`Replica count should be ${maxReplicaCount} after 1 minute`)
})

test.serial("Deployment should scale back down to idleReplicaCount", async t => {
// Modify scaled object's metricValue to induce scaling
t.is(
sh.exec(`kubectl apply -f ${createYamlFile(scaledObjectYaml.replace("{{VALUE}}", "0"))} -n ${testNamespace}`).code,
0,
"Modifying scaled object should work"
)

t.true(await waitForDeploymentReplicaCount(idleReplicaCount, deploymentName, testNamespace, 60, 1000),
`Replica count should be ${idleReplicaCount} after 1 minute`)
})

test.after.always("Clean up E2E K8s objects", async t => {
const resources = [
`scaledobject.keda.sh/${scaledObjectName}`,
`deployments.apps/${deploymentName}`,
`service/${serviceName}`,
`deployments.apps/${scalerName}`,
]

for (const resource of resources) {
sh.exec(`kubectl delete ${resource} -n ${testNamespace}`)
}

sh.exec(`kubectl delete ns ${testNamespace}`)
})

// YAML Definitions for Kubernetes resources
// External Scaler Deployment
const scalerYaml =
`
apiVersion: apps/v1
kind: Deployment
metadata:
name: ${scalerName}
namespace: ${testNamespace}
spec:
replicas: 1
selector:
matchLabels:
app: ${scalerName}
template:
metadata:
labels:
app: ${scalerName}
spec:
containers:
- name: scaler
image: ghcr.io/kedacore/tests-external-scaler-e2e:latest
imagePullPolicy: Always
ports:
- containerPort: 6000
`

const serviceYaml =
`
apiVersion: v1
kind: Service
metadata:
name: ${serviceName}
namespace: ${testNamespace}
spec:
ports:
- port: 6000
targetPort: 6000
selector:
app: ${scalerName}
`

// Deployment
const deploymentYaml =
`apiVersion: apps/v1
kind: Deployment
metadata:
name: ${deploymentName}
namespace: ${testNamespace}
spec:
replicas: 0
selector:
matchLabels:
app: ${deploymentName}
template:
metadata:
labels:
app: ${deploymentName}
spec:
containers:
- name: nginx
image: nginx:1.16.1
`

// Scaled Object
const scaledObjectYaml =
`
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: ${scaledObjectName}
namespace: ${testNamespace}
spec:
scaleTargetRef:
name: ${deploymentName}
pollingInterval: 5
cooldownPeriod: 10
idleReplicaCount: ${idleReplicaCount}
minReplicaCount: ${minReplicaCount}
maxReplicaCount: ${maxReplicaCount}
triggers:
- type: external
metadata:
scalerAddress: ${serviceName}.${testNamespace}:6000
metricThreshold: "${threshold}"
metricValue: "{{VALUE}}"
`
6 changes: 6 additions & 0 deletions tests/scalers/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ export async function createNamespace(namespace: string) {
sh.exec(`kubectl apply -f ${namespaceFile.name}`)
}

export function createYamlFile(yaml: string) {
const tmpFile = tmp.fileSync()
fs.writeFileSync(tmpFile.name, yaml)
return tmpFile.name
}

const namespaceTemplate = `apiVersion: v1
kind: Namespace
metadata:
Expand Down