Skip to content

Commit

Permalink
Add tests for kubectl plugin (#445)
Browse files Browse the repository at this point in the history
* Add tests for kubectl-rabbitmq

See #440

* Test rabbitmq plugin in GitHub actions

See #440

* Rebase onto origin/main

Fix failing tests due to changes in #447
  • Loading branch information
ansd committed Nov 6, 2020
1 parent dda2be1 commit db113e5
Show file tree
Hide file tree
Showing 3 changed files with 239 additions and 58 deletions.
23 changes: 23 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,26 @@ jobs:
kind create cluster --image kindest/node:"$K8S_VERSION"
DOCKER_REGISTRY_SERVER=local-server OPERATOR_IMAGE=local-operator make deploy-kind
make system-tests
kubectl_tests:
name: kubectl rabbitmq tests
runs-on: ubuntu-latest
steps:
- name: Install Bats
run: |
git clone https://github.com/bats-core/bats-core.git "$HOME"/bats-core
cd "$HOME"/bats-core
sudo ./install.sh /usr/local
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: kubectl rabbitmq tests
env:
K8S_VERSION: v1.19.1
run: |
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
make install-tools
kind create cluster --image kindest/node:"$K8S_VERSION"
DOCKER_REGISTRY_SERVER=local-server OPERATOR_IMAGE=local-operator make deploy-kind
PATH=$PATH:$(pwd)/bin
kubectl-rabbitmq.bats
128 changes: 70 additions & 58 deletions bin/kubectl-rabbitmq
Original file line number Diff line number Diff line change
Expand Up @@ -16,60 +16,66 @@ password=""
service=""

usage() {
echo "USAGE:"
echo " Install RabbitMQ Cluster Operator (optionally provide image to use a relocated image or a specific version)"
echo " kubectl rabbitmq install-cluster-operator [IMAGE]"
echo
echo " Open Management UI for an instance"
echo " kubectl rabbitmq manage INSTANCE"
echo
echo " Print default-user secrets for an instance"
echo " kubectl rabbitmq secrets INSTANCE"
echo
echo " List all RabbitMQ clusters"
echo " kubectl rabbitmq list"
echo
echo " Delete a RabbitMQ cluster (or multiple clusters)"
echo " kubectl rabbitmq delete INSTANCE ..."
echo
echo " Create a RabbitMQ custom resource - INSTANCE name required, all other flags optional"
echo " kubectl rabbitmq create INSTANCE --replicas 1 --service ClusterIP --image rabbitmq:3.8.9-management --image-pull-secret mysecret"
echo " --tls-secret secret-name --storage-class mystorageclass"
echo
echo " Get a RabbitMQ custom resource and dependant objects"
echo " kubectl rabbitmq get INSTANCE"
echo
echo " Set log level to 'debug' on all nodes"
echo " kubectl rabbitmq debug INSTANCE"
echo
echo " Run 'rabbitmq-diagnostics observer' on a specific INSTANCE NODE"
echo " kubectl rabbitmq observe INSTANCE 0"
echo
echo " Enable all feature flags on an INSTANCE"
echo " kubectl rabbitmq enable-all-feature-flags INSTANCE"
echo
echo " Run perf-test against an instance - you can pass as many perf test parameters as you want"
echo " kubectl rabbitmq perf-test INSTANCE --rate 100"
echo
echo "If you want to monitor perf-test, create the following ServiceMonitor"
echo " apiVersion: monitoring.coreos.com/v1"
echo " kind: ServiceMonitor"
echo " metadata:"
echo " name: kubectl-perf-test"
echo " spec:"
echo " endpoints:"
echo " - interval: 15s"
echo " targetPort: 8080"
echo " selector:"
echo " matchLabels:"
echo " app: perf-test"
usage=$(cat <<-END
USAGE:
Install (latest released) RabbitMQ Cluster Operator
kubectl rabbitmq install-cluster-operator
Create a RabbitMQ custom resource - INSTANCE name required, all other flags optional
kubectl rabbitmq create INSTANCE --replicas 1 --service ClusterIP --image rabbitmq:3.8.9-management --image-pull-secret mysecret
--tls-secret secret-name --storage-class mystorageclass
Get a RabbitMQ custom resource and dependant objects
kubectl rabbitmq get INSTANCE
List all RabbitMQ clusters
kubectl rabbitmq list
Delete a RabbitMQ cluster (or multiple clusters)
kubectl rabbitmq delete INSTANCE ...
Print default-user secrets for an instance
kubectl rabbitmq secrets INSTANCE
Open Management UI for an instance
kubectl rabbitmq manage INSTANCE
Set log level to 'debug' on all nodes
kubectl rabbitmq debug INSTANCE
Run 'rabbitmq-diagnostics observer' on a specific INSTANCE NODE
kubectl rabbitmq observe INSTANCE 0
Enable all feature flags on an INSTANCE
kubectl rabbitmq enable-all-feature-flags INSTANCE
Run perf-test against an instance - you can pass as many perf test parameters as you want
kubectl rabbitmq perf-test INSTANCE --rate 100
If you want to monitor perf-test, create the following ServiceMonitor:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: kubectl-perf-test
spec:
endpoints:
- interval: 15s
targetPort: 8080
selector:
matchLabels:
app: perf-test
Print this help
kubectl rabbitmq help
END
)
echo "$usage"
}

get_instance_details() {
instance=${1}
username=$(kubectl get secret "${instance}-rabbitmq-default-user" -o jsonpath="{.data.username}" | base64 --decode)
password=$(kubectl get secret "${instance}-rabbitmq-default-user" -o jsonpath="{.data.password}" | base64 --decode)
service=${instance}-rabbitmq-client
username=$(kubectl get secret "${instance}-default-user" -o jsonpath="{.data.username}" | base64 --decode)
password=$(kubectl get secret "${instance}-default-user" -o jsonpath="{.data.password}" | base64 --decode)
service="$instance"
}

perf_test() {
Expand Down Expand Up @@ -119,7 +125,6 @@ create() {
fi

while [[ "$#" -ne 0 ]]; do
#statements
case "$1" in
"--replicas")
shift 1
Expand Down Expand Up @@ -161,9 +166,8 @@ create() {
shift 1
;;
*)
# Unrecognised or unsupported option
echo "Option '$1' not recongnised"
shift 1
exit 1
;;
esac
done
Expand All @@ -177,7 +181,7 @@ delete() {
}

observe() {
kubectl exec -it "${1}-rabbitmq-server-${2}" -- rabbitmq-diagnostics observer
kubectl exec -it "${1}-server-${2}" -- rabbitmq-diagnostics observer
}

get() {
Expand All @@ -192,7 +196,7 @@ debug() {
}

enable_all_feature_flags() {
kubectl exec "${1}-rabbitmq-server-0" -- bash -c "rabbitmqctl list_feature_flags | grep disabled | cut -f 1 | xargs -r -L1 rabbitmqctl enable_feature_flag"
kubectl exec "${1}-server-0" -- bash -c "rabbitmqctl list_feature_flags | grep disabled | cut -f 1 | xargs -r -L1 rabbitmqctl enable_feature_flag"
}

secrets() {
Expand Down Expand Up @@ -286,13 +290,21 @@ main() {
;;
"install-cluster-operator")
shift 1
if [[ "$#" -gt 1 ]]; then
if [[ "$#" -gt 0 ]]; then
usage
exit 1
fi
install_cluster_operator "${1:-}"
install_cluster_operator
;;
"help")
usage
;;
"--help")
usage
;;
"-h")
usage
;;

*)
usage
exit 1
Expand Down
146 changes: 146 additions & 0 deletions bin/kubectl-rabbitmq.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#!/usr/bin/env bats

eventually() {
assertion="$1"
timeout_in_seconds="$2"

for _ in $(seq 0 "$timeout_in_seconds")
do
if eval "$assertion" ; then
return 0
fi
sleep 1
done

echo assertion timed out: "$assertion"
return 1
}

@test "install-cluster-operator with too many args fails" {
run kubectl rabbitmq install-cluster-operator too-many-args

[ "$status" -eq 1 ]
[ "${lines[0]}" = "USAGE:" ]
}

@test "create creates RabbitMQ cluster" {
kubectl rabbitmq create bats-default \
--unlimited # otherwise scheduling the pod fails on kind in GitHub actions because of insufficient CPU

eventually '[[ $(kubectl get rabbitmqcluster bats-default -o json | jq -r '"'"'.status.conditions | .[] | select(.type=="AllReplicasReady").status'"'"') == "True" ]]' 600
}

@test "create with invalid flag does not create RabbitMQ cluster" {
run kubectl rabbitmq create bats-invalid \
--replicas 3 \
--invalid "flag"

[ "$status" -eq 1 ]
[[ "${lines[0]}" == "Option '--invalid' not recongnised" ]]
}

@test "create with flags creates RabbitMQ cluster configured accordingly" {
replicas=3
image="rabbitmq:3.8.8"
service="NodePort"
storage_class="my-storage-class"

kubectl rabbitmq create bats-configured \
--replicas "$replicas" \
--image "$image" \
--service "$service" \
--storage-class "$storage_class"

sleep 10 # let the RabbitMQ controller create the K8s objects

sts_spec=$(kubectl get statefulset bats-configured-server -o jsonpath='{.spec}')
[[ $(jq -r '.replicas' <<< "$sts_spec") -eq "$replicas" ]]
[[ $(jq -r '.template.spec.containers | .[0].image' <<< "$sts_spec") == "$image" ]]

[[ $(kubectl get service bats-configured -o jsonpath='{.spec.type}') == "$service" ]]
[[ $(kubectl get pvc persistence-bats-configured-server-0 -o jsonpath='{.spec.storageClassName}') == "$storage_class" ]]
}

@test "list lists all RabbitMQ clusters" {
run kubectl rabbitmq list

[ "$status" -eq 0 ]
[[ "${lines[0]}" =~ ^NAME ]]
[[ "${lines[1]}" =~ ^bats-configured ]]
[[ "${lines[2]}" =~ ^bats-default ]]
}

@test "get gets child resources" {
run kubectl rabbitmq get bats-default

[ "$status" -eq 0 ]
[[ "$output" == *"statefulset.apps/bats-default-server"* ]]
[[ "$output" == *"pod/bats-default-server-0"* ]]
[[ "$output" == *"service/bats-default-nodes"* ]]
[[ "$output" == *"service/bats-default"* ]]
[[ "$output" == *"configmap/bats-default-server-conf"* ]]
[[ "$output" == *"configmap/bats-default-plugins-conf"* ]]
[[ "$output" == *"secret/bats-default-default-user"* ]]
[[ "$output" == *"secret/bats-default-erlang-cookie"* ]]
}

@test "secrets prints secrets of default-user" {
run kubectl rabbitmq secrets bats-default

[ "$status" -eq 0 ]
# 24 bytes base64 encoded makes 32 characters
username_regex='^username: .{32}$'
password_regex='^password: .{32}$'
[[ "${lines[0]}" =~ $username_regex ]]
[[ "${lines[1]}" =~ $password_regex ]]
}

@test "enable-all-feature-flags enables all feature flags" {
kubectl rabbitmq enable-all-feature-flags bats-default

states=$(kubectl exec bats-default-server-0 -- rabbitmqctl list_feature_flags --silent state --formatter=json)
[[ $(jq 'map(select(.state=="disabled")) | length' <<< "$states") -eq 0 ]]
}

@test "perf-test runs perf-test" {
kubectl rabbitmq perf-test bats-default --rate 1

eventually "kubectl exec bats-default-server-0 -- rabbitmqctl list_connections client_properties | grep perf-test " 600

kubectl delete pod -l "app=perf-test,run=perf-test"
kubectl delete svc -l "app=perf-test,run=perf-test"
}

@test "debug sets log level to debug" {
kubectl rabbitmq debug bats-default

# '[debug] <pid> Lager installed handler' is logged even without enabling debug logging
eventually "kubectl logs bats-default-server-0 | grep -v ' \[debug\] .* Lager installed handler ' | grep ' \[debug\] '" 30
}

@test "delete deletes RabbitMQ cluster" {
kubectl rabbitmq delete bats-configured bats-default

[[ $(kubectl get rabbitmqclusters -o jsonpath='{.items}' | jq length) -eq 0 ]]
}

@test "help prints help" {
run kubectl rabbitmq help

[ "$status" -eq 0 ]
[ "${lines[0]}" = "USAGE:" ]
}

@test "--help prints help" {
run kubectl rabbitmq --help

[ "$status" -eq 0 ]
[ "${lines[0]}" = "USAGE:" ]
}

@test "-h prints help" {
run kubectl rabbitmq -h

[ "$status" -eq 0 ]
[ "${lines[0]}" = "USAGE:" ]
}

0 comments on commit db113e5

Please sign in to comment.