Skip to content

Commit

Permalink
add e2e tests
Browse files Browse the repository at this point in the history
Signed-off-by: Sanskar Jaiswal <jaiswalsanskar078@gmail.com>
  • Loading branch information
aryan9600 committed Mar 23, 2022
1 parent 38099b9 commit e756d83
Show file tree
Hide file tree
Showing 2 changed files with 393 additions and 0 deletions.
199 changes: 199 additions & 0 deletions tests/scalers/pause-at-n.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
import * as async from 'async'
import * as fs from 'fs'
import * as azure from 'azure-storage'
import * as sh from 'shelljs'
import * as tmp from 'tmp'
import test from 'ava'
import {createNamespace, waitForDeploymentReplicaCount} from "./helpers";

const deploymentFile = tmp.fileSync()
const scaledObjectFile = tmp.fileSync()
const scaledObjectFileWithAnnotation = tmp.fileSync()
const pauseCount = 5

const testNamespace = 'pause-at-n-test'
const queueName = 'paused-replicas-queue-name'
const connectionString = process.env['AZURE_STORAGE_CONNECTION_STRING']

test.before(async t => {
if (!connectionString) {
t.fail('AZURE_STORAGE_CONNECTION_STRING environment variable is required for queue tests')
}

const createQueueAsync = () => new Promise((resolve, _) => {
const queueSvc = azure.createQueueService(connectionString)
queueSvc.messageEncoder = new azure.QueueMessageEncoder.TextBase64QueueMessageEncoder()
queueSvc.createQueueIfNotExists(queueName, _ => {
resolve(undefined);
})
})
await createQueueAsync()

sh.config.silent = true
const base64ConStr = Buffer.from(connectionString).toString('base64')
const tmpFile = tmp.fileSync()
fs.writeFileSync(tmpFile.name, deployYaml.replace('{{CONNECTION_STRING_BASE64}}', base64ConStr))
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-deployment', testNamespace, 60, 1000), 'replica count should be 1 after 1 minute')
})

test.serial(`Creating ScaledObject should work`, async t => {
fs.writeFileSync(scaledObjectFile.name, scaledObjectYaml)
t.is(
0,
sh.exec(`kubectl apply -f ${scaledObjectFile.name} --namespace ${testNamespace}`).code,
'Updating ScaledObject should work.'
)
})

test.serial(
'Deployment should scale to 2 - to minReplicaCount',
async t => {
t.true(await waitForDeploymentReplicaCount(1, 'test-deployment', testNamespace, 60, 2000), 'replica count should be 0 after 3 minutes')
}
)

test.serial.cb(
'Deployment should scale up with messages on storage',
t => {
const queueSvc = azure.createQueueService(connectionString)
queueSvc.messageEncoder = new azure.QueueMessageEncoder.TextBase64QueueMessageEncoder()
async.mapLimit(
Array(2000).keys(),
20,
(n, cb) => queueSvc.createMessage(queueName, `test ${n}`, cb),
async () => {
// Scaling out when messages available
t.true(await waitForDeploymentReplicaCount(3, 'test-deployment', testNamespace, 60, 2000), 'replica count should be 3 after 1 minute')
queueSvc.clearMessages(queueName, _ => {})
}
)
}
)

test.serial(`Updsating ScaledObject (with annotation) should work`, async t => {
fs.writeFileSync(scaledObjectFileWithAnnotation.name, scaledObjectYamlWithAnnotation.
replace('{{PAUSED_REPLICA_COUNT}}', pauseCount.toString())
t.is(
0,
sh.exec(`kubectl apply -f ${scaledObjectFileWithAnnotation.name} --namespace ${testNamespace}`).code,
'Updating ScaledObject should work.'
)
})

test.serial(
'Deployment should scale to 5 - to pausedReplicaCount',
async t => {
t.true(await waitForDeploymentReplicaCount(5, 'test-deployment', testNamespace, 60, 1000), 'replica count should be 0 after 1 minute')
}
)

test.serial(`Updating ScaledObject (delete annotation) should work`, async t => {
fs.writeFileSync(scaledObjectFile.name, scaledObjectYaml)
t.is(
0,
sh.exec(`kubectl apply -f ${scaledObjectFile.name} --namespace ${testNamespace}`).code,
'Updating ScaledObject should work.'
)
})

test.serial(
'Deployment should scale scale down',
async t => {
t.true(await waitForDeploymentReplicaCount(4, 'test-deployment', testNamespace, 60, 1000), 'replica count should scale dwon after 1 minute')
}
)

test.after.always.cb('clean up workload test related deployments', t => {
const resources = [
'deployment.apps/test-deployment',
'scaledobject.keda.sh/pause-scaledobject',
'secret/test-secrets',
]
for (const resource of resources) {
sh.exec(`kubectl delete ${resource} --namespace ${testNamespace}`)
}
sh.exec(`kubectl delete namespace ${testNamespace}`)
t.end()
})

const deployYaml = `apiVersion: v1
kind: Secret
metadata:
name: test-secrets
labels:
data:
AzureWebJobsStorage: {{CONNECTION_STRING_BASE64}}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deployment
labels:
app: test-deployment
spec:
replicas: 1
selector:
matchLabels:
app: test-deployment
template:
metadata:
name:
namespace:
labels:
app: test-deployment
spec:
containers:
- name: test-deployment
image: docker.io/kedacore/tests-azure-queue:824031e
resources:
ports:
env:
- name: FUNCTIONS_WORKER_RUNTIME
value: node
- name: AzureWebJobsStorage
valueFrom:
secretKeyRef:
name: test-secrets
key: AzureWebJobsStorage`

const scaledObjectYaml = `apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: pause-scaledobject
spec:
scaleTargetRef:
name: test-deployment
pollingInterval: 5
minReplicaCount: 2
maxReplicaCount: 4
cooldownPeriod: 10
triggers:
- type: azure-queue
metadata:
queueName: ${queueName}
connectionFromEnv: AzureWebJobsStorage`

const scaledObjectYamlWithAnnotation = `apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: pause-scaledobject
annotations:
autoscaling.keda.sh/paused-replicas: "{{PAUSED_REPLICA_COUNT}}"
spec:
scaleTargetRef:
name: test-deployment
pollingInterval: 5
minReplicaCount: 2
maxReplicaCount: 4
cooldownPeriod: 10
triggers:
- type: azure-queue
metadata:
queueName: ${queueName}
connectionFromEnv: AzureWebJobsStorage`
194 changes: 194 additions & 0 deletions tests/scalers/pause.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
import * as async from 'async'
import * as fs from 'fs'
import * as azure from 'azure-storage'
import * as sh from 'shelljs'
import * as tmp from 'tmp'
import test from 'ava'
import {createNamespace, waitForDeploymentReplicaCount} from "./helpers";

const testNamespace = 'pause-test'
const deploymentFile = tmp.fileSync()
const scaledObjectFile = tmp.fileSync()
const scaledObjectFileWithAnnotation = tmp.fileSync()
const zeroPauseCount = 0
const onePauseCount = 1

const queueName = 'paused-replicas-queue-name'
const connectionString = process.env['AZURE_STORAGE_CONNECTION_STRING']

test.before(async t => {
if (!connectionString) {
t.fail('AZURE_STORAGE_CONNECTION_STRING environment variable is required for queue tests')
}

const createQueueAsync = () => new Promise((resolve, _) => {
const queueSvc = azure.createQueueService(connectionString)
queueSvc.messageEncoder = new azure.QueueMessageEncoder.TextBase64QueueMessageEncoder()
queueSvc.createQueueIfNotExists(queueName, _ => {
resolve(undefined);
})
})
await createQueueAsync()

sh.config.silent = true
const base64ConStr = Buffer.from(connectionString).toString('base64')
const tmpFile = tmp.fileSync()
fs.writeFileSync(tmpFile.name, deployYaml.replace('{{CONNECTION_STRING_BASE64}}', base64ConStr))
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-deployment', testNamespace, 60, 1000), 'replica count should be 1 after 1 minute')
})

test.serial(`Creating ScaledObject should work`, async t => {
fs.writeFileSync(scaledObjectFileWithAnnotation.name, scaledObjectYamlWithAnnotation.
replace('{{PAUSED_REPLICA_COUNT}}', zeroPauseCount.toString()))
t.is(
0,
sh.exec(`kubectl apply -f ${scaledObjectFileWithAnnotation.name} --namespace ${testNamespace}`).code,
'creating new ScaledObject should work.'
)
})

test.serial(
'Deployment should scale to 0 - to pausedReplicaCount',
async t => {
t.true(await waitForDeploymentReplicaCount(0, 'test-deployment', testNamespace, 60, 1000), 'replica count should be 0 after 1 minute')
}
)

test.serial(`Updsating ScaledObject (without annotation) should work`, async t => {
fs.writeFileSync(scaledObjectFile.name, scaledObjectYaml)
t.is(
0,
sh.exec(`kubectl apply -f ${scaledObjectFile.name} --namespace ${testNamespace}`).code,
'Updating ScaledObject should work.'
)
})

test.serial.cb(
'Deployment should scale from pausedReplicaCount (0) to minReplicaCount (2) with messages on storage',
t => {
const queueSvc = azure.createQueueService(connectionString)
queueSvc.messageEncoder = new azure.QueueMessageEncoder.TextBase64QueueMessageEncoder()
async.mapLimit(
Array(1000).keys(),
20,
(n, cb) => queueSvc.createMessage(queueName, `test ${n}`, cb),
async () => {
// Scaling out when messages available
t.true(await waitForDeploymentReplicaCount(2, 'test-deployment', testNamespace, 60, 1000), 'replica count should be 3 after 1 minute')
queueSvc.clearMessages(queueName, _ => {})
}
)
}
)

test.serial(`Updsating ScaledObject (with 1 paused replica) should work`, async t => {
fs.writeFileSync(scaledObjectFileWithAnnotation.name, scaledObjectYamlWithAnnotation.
replace('{{PAUSED_REPLICA_COUNT}}', onePauseCount.toString()))
t.is(
0,
sh.exec(`kubectl apply -f ${scaledObjectFileWithAnnotation.name} --namespace ${testNamespace}`).code,
'Updating ScaledObject should work.'
)
})

test.serial(
'Deployment should scale to 1 - to pausedReplicaCount',
async t => {
t.true(await waitForDeploymentReplicaCount(1, 'test-deployment', testNamespace, 60, 1000), 'replica count should be 0 after 1 minute')
}
)

test.after.always.cb('clean up workload test related deployments', t => {
const resources = [
'deployment.apps/test-deployment',
'scaledobject.keda.sh/pause-scaledobject',
'secret/test-secrets',
]
for (const resource of resources) {
sh.exec(`kubectl delete ${resource} --namespace ${testNamespace}`)
}
sh.exec(`kubectl delete namespace ${testNamespace}`)
t.end()
})

const deployYaml = `apiVersion: v1
kind: Secret
metadata:
name: test-secrets
labels:
data:
AzureWebJobsStorage: {{CONNECTION_STRING_BASE64}}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deployment
labels:
app: test-deployment
spec:
replicas: 1
selector:
matchLabels:
app: test-deployment
template:
metadata:
name:
namespace:
labels:
app: test-deployment
spec:
containers:
- name: test-deployment
image: docker.io/kedacore/tests-azure-queue:824031e
resources:
ports:
env:
- name: FUNCTIONS_WORKER_RUNTIME
value: node
- name: AzureWebJobsStorage
valueFrom:
secretKeyRef:
name: test-secrets
key: AzureWebJobsStorage`

const scaledObjectYaml = `apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: pause-scaledobject
spec:
scaleTargetRef:
name: test-deployment
pollingInterval: 5
minReplicaCount: 2
maxReplicaCount: 4
cooldownPeriod: 10
triggers:
- type: azure-queue
metadata:
queueName: ${queueName}
connectionFromEnv: AzureWebJobsStorage`

const scaledObjectYamlWithAnnotation = `apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: pause-scaledobject
annotations:
autoscaling.keda.sh/paused-replicas: "{{PAUSED_REPLICA_COUNT}}"
spec:
scaleTargetRef:
name: test-deployment
pollingInterval: 5
minReplicaCount: 2
maxReplicaCount: 4
cooldownPeriod: 10
triggers:
- type: azure-queue
metadata:
queueName: ${queueName}
connectionFromEnv: AzureWebJobsStorage`

0 comments on commit e756d83

Please sign in to comment.