Skip to content

Commit

Permalink
chore: Add pubsub scaler e2e test
Browse files Browse the repository at this point in the history
Fixes kedacore#1528

Signed-off-by: Ram Cohen <ram.cohen@gmail.com>
  • Loading branch information
RamCohen committed Feb 21, 2022
1 parent 52c6a69 commit 460e280
Showing 1 changed file with 235 additions and 0 deletions.
235 changes: 235 additions & 0 deletions tests/scalers/gcp-pubsub.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
import * as crypto from 'crypto'
import * as fs from 'fs'
import * as sh from 'shelljs'
import * as tmp from 'tmp'
import test from 'ava'

const testNamespace = 'gcp-pubsub-test'
const projectId = 'nth-hybrid-341214'
const topicId = `projects/${projectId}/topics/keda-test-topic-` + crypto.randomBytes(6).toString('hex')
const subscriptionName = `keda-test-topic-sub-` + crypto.randomBytes(6).toString('hex')
const subscriptionId = `projects/${projectId}/subscriptions/${subscriptionName}`
const deploymentName = 'dummy-consumer'
const maxReplicaCount = '4'
const gsPrefix = `kubectl exec --namespace ${testNamespace} deploy/gcp-sdk -- `

test.before(t => {
sh.exec(`kubectl create namespace ${testNamespace}`)

// deploy dummy consumer app, scaled object etc.
const tmpFile = tmp.fileSync()
fs.writeFileSync(tmpFile.name, deployYaml.replace("{{GCP_CREDS}}", Buffer.from(serviceAccountJson).toString("base64")))

t.is(
0,
sh.exec(`kubectl apply -f ${tmpFile.name} --namespace ${testNamespace}`).code,
'creating a deployment should work..'
)

})

test.serial('Deployment should have 0 replicas on start', t => {
const replicaCount = sh.exec(
`kubectl get deployment.apps/${deploymentName} --namespace ${testNamespace} -o jsonpath="{.spec.replicas}"`
).stdout
t.is(replicaCount, '0', 'replica count should start out as 0')
})

test.serial('creating the gcp-sdk pod should work..', t => {
let tmpFile = tmp.fileSync()
fs.writeFileSync(tmpFile.name, gcpSdkYaml)
t.is(
0,
sh.exec(`kubectl apply -f ${tmpFile.name} --namespace ${testNamespace}`).code,
'creating the gcp-sdk pod should work..'
)

// wait for the gcp-sdkpod to be ready
let gcpSdkReadyReplicaCount = '0'
for (let i = 0; i < 30; i++) {
gcpSdkReadyReplicaCount = sh.exec(`kubectl get deploy/gcp-sdk -n ${testNamespace} -o jsonpath='{.status.readyReplicas}'`).stdout
if (gcpSdkReadyReplicaCount != '1') {
sh.exec('sleep 2s')
}
}
t.is('1', gcpSdkReadyReplicaCount, 'GCP-SDK pod is not in a ready state')
})

test.serial('initializing the gcp-sdk pod should work..', t => {
// Authenticate to GCP
t.is(
0,
sh.exec(gsPrefix + `gcloud auth activate-service-account --key-file /etc/secret-volume/creds.json`).code,
'Executing remote command on gcp-sdk should work..'
)

// Set project id
sh.exec(gsPrefix + `gcloud config set project ${projectId}`)

// Create topic and subscription
t.is(
0,
sh.exec(gsPrefix + `gcloud pubsub topics create ${topicId}`).code,
'Creating a topic should work..'
)

t.is(0,
sh.exec(gsPrefix + `gcloud pubsub subscriptions create ${subscriptionId} --topic=${topicId}`).code,
'Creating a subscription should work..'
)
})

test.serial(`Publishing to pubsub`, t => {
let replicaCount = '0'

// Publish 30 messages
for (let i = 0; i < 30; i++) {
t.is(
0,
sh.exec(gsPrefix + `gcloud pubsub topics publish ${topicId} --message="AAAAAAAAAA"`).code,
'Publishing a message to pub/sub should work..'
)
}
})

test.serial(`Deployment should scale to ${maxReplicaCount} (the max) then back to 0`, t => {
let replicaCount = '0'

// Wait for the number of replicas to be scaled up to maxReplicaCount
for (let i = 0; i < 150 && replicaCount != maxReplicaCount; i++) {
replicaCount = sh.exec(
`kubectl get deployment.apps/${deploymentName} --namespace ${testNamespace} -o jsonpath="{.spec.replicas}"`
).stdout
if (replicaCount != maxReplicaCount) {
sh.exec('sleep 2s')
}
}

t.is(maxReplicaCount, replicaCount, `Replica count should be ${maxReplicaCount} after 120 seconds but is ${replicaCount}`)

// Purge all messages
sh.exec(gsPrefix + `gcloud pubsub subscriptions seek ${subscriptionId} --time=-p1s`)

// Wait for the number of replicas to be scaled down to 0
for (let i = 0; i < 30 && replicaCount !== '0'; i++) {
replicaCount = sh.exec(
`kubectl get deployment.apps/${deploymentName} --namespace ${testNamespace} -o jsonpath="{.spec.replicas}"`
).stdout
if (replicaCount != '0') {
sh.exec('sleep 10s')
}
}

t.is('0', replicaCount, 'Replica count should be 0 after 3 minutes')
})

test.after.always.cb('clean up', t => {
// Delete the subscription and topic
sh.exec(gsPrefix + `gcloud pubsub subscriptions delete ${subscriptionId}`)
sh.exec(gsPrefix + `gcloud pubsub topics delete ${topicId}`)

sh.exec(`kubectl delete deployment.apps/${deploymentName} --namespace ${testNamespace}`)
sh.exec(`kubectl delete namespace ${testNamespace}`)

t.end()
})


const deployYaml = `apiVersion: apps/v1
kind: Deployment
metadata:
name: ${deploymentName}
namespace: ${testNamespace}
labels:
app: ${deploymentName}
spec:
replicas: 0
selector:
matchLabels:
app: ${deploymentName}
template:
metadata:
labels:
app: ${deploymentName}
spec:
containers:
- name: ${deploymentName}-processor
image: google/cloud-sdk:slim
# Consume a message
command: [ "/bin/bash", "-c", "--" ]
args: [ "gcloud auth activate-service-account --key-file /etc/secret-volume/creds.json && gcloud pubsub subscriptions pull ${subscriptionId} --auto-ack" ]
env:
- name: GOOGLE_APPLICATION_CREDENTIALS_JSON
valueFrom:
secretKeyRef:
name: pubsub-secrets
key: creds.json
volumeMounts:
- name: secret-volume
mountPath: /etc/secret-volume
volumes:
- name: secret-volume
secret:
secretName: pubsub-secrets
---
apiVersion: v1
kind: Secret
metadata:
name: pubsub-secrets
type: Opaque
data:
creds.json: {{GCP_CREDS}}
---
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: test-scaledobject
spec:
scaleTargetRef:
name: ${deploymentName}
pollingInterval: 5
maxReplicaCount: ${maxReplicaCount}
cooldownPeriod: 10
triggers:
- type: gcp-pubsub
metadata:
subscriptionName: ${subscriptionName}
mode: SubscriptionSize
value: "5"
credentialsFromEnv: GOOGLE_APPLICATION_CREDENTIALS_JSON
`

const gcpSdkYaml = `apiVersion: apps/v1
kind: Deployment
metadata:
name: gcp-sdk
namespace: ${testNamespace}
labels:
app: gcp-sdk
spec:
replicas: 1
selector:
matchLabels:
app: gcp-sdk
template:
metadata:
labels:
app: gcp-sdk
spec:
containers:
- name: gcp-sdk-container
image: google/cloud-sdk:slim
# Just spin & wait forever
command: [ "/bin/bash", "-c", "--" ]
args: [ "while true; do sleep 30; done;" ]
volumeMounts:
- name: secret-volume
mountPath: /etc/secret-volume
volumes:
- name: secret-volume
secret:
secretName: pubsub-secrets
`

const serviceAccountJson = `{
}` // Json key with \n converted to \\n

0 comments on commit 460e280

Please sign in to comment.