Skip to content

Commit 825fea4

Browse files
committed
add bats tests
Change-Id: I203d3c8fbce3a07a13f7d5294793097c61a571f0
1 parent e95a5e6 commit 825fea4

File tree

4 files changed

+158
-48
lines changed

4 files changed

+158
-48
lines changed

.github/workflows/bats.yml

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
name: bats
2+
3+
on:
4+
push:
5+
branches:
6+
- 'main'
7+
tags:
8+
- 'v*'
9+
pull_request:
10+
branches: [ main ]
11+
workflow_dispatch:
12+
13+
env:
14+
GO_VERSION: "1.23"
15+
K8S_VERSION: "v1.32.0"
16+
KIND_VERSION: "v0.27.0"
17+
18+
jobs:
19+
bats_tests:
20+
runs-on: ubuntu-22.04
21+
name: Bats e2e tests
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@v2
25+
- name: Setup Bats and bats libs
26+
id: setup-bats
27+
uses: bats-core/bats-action@3.0.0
28+
- name: Bats tests
29+
shell: bash
30+
env:
31+
BATS_LIB_PATH: ${{ steps.setup-bats.outputs.lib-path }}
32+
TERM: xterm
33+
run: bats -o _artifacts tests/
34+
35+
- name: Upload logs
36+
if: always()
37+
uses: actions/upload-artifact@v4
38+
with:
39+
name: kind-logs-${{ env.JOB_NAME }}-${{ github.run_id }}
40+
path: ./_artifacts
41+
42+
bats_mac_tests:
43+
runs-on: macos-15
44+
name: Bats e2e tests on Mac
45+
steps:
46+
- name: Checkout
47+
uses: actions/checkout@v2
48+
- name: Setup Bats and bats libs
49+
id: setup-bats
50+
uses: bats-core/bats-action@3.0.0
51+
- name: Set up environment (download dependencies)
52+
run: |
53+
# For Intel Macs
54+
[ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/"$KIND_VERSION"/kind-darwin-amd64
55+
# For M1 / ARM Macs
56+
[ $(uname -m) = arm64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/"$KIND_VERSION"/kind-darwin-arm64
57+
chmod +x ./kind
58+
mv ./kind /usr/local/bin/kind
59+
- name: Bats tests
60+
shell: bash
61+
env:
62+
BATS_LIB_PATH: ${{ steps.setup-bats.outputs.lib-path }}
63+
TERM: xterm
64+
run: bats -o _artifacts tests/
65+
66+
- name: Upload logs
67+
if: always()
68+
uses: actions/upload-artifact@v4
69+
with:
70+
name: kind-logs-${{ env.JOB_NAME }}-${{ github.run_id }}
71+
path: ./_artifacts
72+

tests/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Integration tests
2+
3+
4+
1. Install `bats` https://bats-core.readthedocs.io/en/stable/installation.html
5+
6+
2. Install `kind` https://kind.sigs.k8s.io/
7+
8+
3. Run `bats tests/`

tests/setup_suite.bash

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/bin/bash
2+
3+
set -eu
4+
5+
function setup_suite {
6+
export BATS_TEST_TIMEOUT=120
7+
# Define the name of the kind cluster
8+
export CLUSTER_NAME="ccm-kind"
9+
# Build the cloud-provider-kind
10+
cd "$BATS_TEST_DIRNAME"/..
11+
12+
mkdir -p _artifacts
13+
rm -rf _artifacts/*
14+
# create cluster
15+
cat <<EOF | kind create cluster \
16+
--name $CLUSTER_NAME \
17+
-v7 --wait 1m --retain --config=-
18+
kind: Cluster
19+
apiVersion: kind.x-k8s.io/v1alpha4
20+
nodes:
21+
- role: control-plane
22+
- role: worker
23+
- role: worker
24+
EOF
25+
26+
make
27+
nohup bin/cloud-provider-kind -v 2 --enable-log-dumping --logs-dir ./_artifacts > ./_artifacts/ccm-kind.log 2>&1 &
28+
29+
# test depend on external connectivity that can be very flaky
30+
sleep 5
31+
}
32+
33+
function teardown_suite {
34+
kind export logs "$BATS_TEST_DIRNAME"/../_artifacts --name "$CLUSTER_NAME"
35+
kind delete cluster --name "$CLUSTER_NAME"
36+
}

tests/tests.bats

Lines changed: 42 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,69 @@
11
#!/usr/bin/env bats
22

3-
setup_file() {
4-
REPO_ROOT="$( cd "$(dirname "$BATS_TEST_FILENAME")/.." >/dev/null 2>&1 && pwd )"
5-
cd $REPO_ROOT
6-
# install cloud-provider-kind
7-
make
8-
TMP_DIR=$(mktemp -d)
9-
export TMP_DIR
10-
# install `kind` and `kubectl` to tempdir
11-
curl -sLo "${TMP_DIR}/kubectl" "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
12-
chmod +x "${TMP_DIR}/kubectl"
13-
curl -sLo "${TMP_DIR}/kind" https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64
14-
chmod +x "${TMP_DIR}/kind"
15-
16-
PATH="${TMP_DIR}:${PATH}"
17-
export PATH
18-
# create cluster
19-
kind create cluster --name kccm --wait 1m
20-
kind get kubeconfig --name kccm > "${TMP_DIR}/kubeconfig"
21-
kubectl --kubeconfig "${TMP_DIR}/kubeconfig" wait --for=condition=ready pods --namespace=kube-system -l k8s-app=kube-dns --timeout=3m
22-
kubectl --kubeconfig "${TMP_DIR}/kubeconfig" label node kccm-control-plane node.kubernetes.io/exclude-from-external-load-balancers-
23-
# run cloud-provider-kind
24-
nohup bin/cloud-provider-kind > ${TMP_DIR}/kccm-kind.log 2>&1 &
25-
CLOUD_PROVIDER_KIND_PID=$(echo $!)
26-
}
27-
28-
teardown_file() {
29-
kill -9 ${CLOUD_PROVIDER_KIND_PID}
30-
kind delete cluster --name kccm || true
31-
32-
if [[ -n "${TMP_DIR:-}" ]]; then
33-
rm -rf "${TMP_DIR}"
34-
fi
35-
}
36-
373
@test "ExternalTrafficPolicy: Local" {
38-
kubectl --kubeconfig "${TMP_DIR}/kubeconfig" apply -f examples/loadbalancer_etp_local.yaml
39-
kubectl --kubeconfig "${TMP_DIR}/kubeconfig" wait --for=condition=ready pods -l app=MyLocalApp
4+
kubectl apply -f "$BATS_TEST_DIRNAME"/../examples/loadbalancer_etp_local.yaml
5+
kubectl wait --for=condition=ready pods -l app=MyLocalApp
406
for i in {1..5}
417
do
42-
IP=$(kubectl --kubeconfig "${TMP_DIR}/kubeconfig" get services lb-service-local --output jsonpath='{.status.loadBalancer.ingress[0].ip}')
8+
IP=$(kubectl get services lb-service-local --output jsonpath='{.status.loadBalancer.ingress[0].ip}')
439
[[ ! -z "$IP" ]] && break || sleep 1
4410
done
45-
echo $IP
46-
POD=$(kubectl --kubeconfig "${TMP_DIR}/kubeconfig" get pod -l app=MyLocalApp -o jsonpath='{.items[0].metadata.name}')
47-
echo $POD
11+
echo "IP: $IP"
12+
POD=$(kubectl get pod -l app=MyLocalApp -o jsonpath='{.items[0].metadata.name}')
13+
echo "Pod $POD"
4814
for i in {1..5}
4915
do
5016
HOSTNAME=$(curl -s http://${IP}:80/hostname || true)
5117
[[ ! -z "$HOSTNAME" ]] && break || sleep 1
5218
done
53-
echo $HOSTNAME
19+
echo "Hostname via TCP: $HOSTNAME"
5420
[ "$HOSTNAME" = "$POD" ]
5521
}
5622

5723
@test "ExternalTrafficPolicy: Cluster" {
58-
kubectl --kubeconfig "${TMP_DIR}/kubeconfig" apply -f examples/loadbalancer_etp_cluster.yaml
59-
kubectl --kubeconfig "${TMP_DIR}/kubeconfig" wait --for=condition=ready pods -l app=MyClusterApp
24+
kubectl apply -f "$BATS_TEST_DIRNAME"/../examples/loadbalancer_etp_cluster.yaml
25+
kubectl wait --for=condition=ready pods -l app=MyClusterApp
26+
for i in {1..5}
27+
do
28+
IP=$(kubectl get services lb-service-cluster --output jsonpath='{.status.loadBalancer.ingress[0].ip}')
29+
[[ ! -z "$IP" ]] && break || sleep 1
30+
done
31+
echo "IP: $IP"
32+
POD=$(kubectl get pod -l app=MyClusterApp -o jsonpath='{.items[0].metadata.name}')
33+
echo "Pod $POD"
34+
for i in {1..5}
35+
do
36+
HOSTNAME=$(curl -s http://${IP}:80/hostname || true)
37+
[[ ! -z "$HOSTNAME" ]] && break || sleep 1
38+
done
39+
echo "Hostname via TCP: $HOSTNAME"
40+
[ "$HOSTNAME" = "$POD" ]
41+
}
42+
43+
@test "Multiple Protocols: UDP and TCP" {
44+
kubectl apply -f "$BATS_TEST_DIRNAME"/../examples/loadbalancer_etp_cluster.yaml
45+
kubectl wait --for=condition=ready pods -l app=MyClusterApp
6046
for i in {1..5}
6147
do
62-
IP=$(kubectl --kubeconfig "${TMP_DIR}/kubeconfig" get services lb-service-cluster --output jsonpath='{.status.loadBalancer.ingress[0].ip}')
48+
IP=$(kubectl get services lb-service-cluster --output jsonpath='{.status.loadBalancer.ingress[0].ip}')
6349
[[ ! -z "$IP" ]] && break || sleep 1
6450
done
65-
echo $IP
66-
POD=$(kubectl --kubeconfig "${TMP_DIR}/kubeconfig" get pod -l app=MyClusterApp -o jsonpath='{.items[0].metadata.name}')
67-
echo $POD
51+
echo "IP: $IP"
52+
POD=$(kubectl get pod -l app=MyClusterApp -o jsonpath='{.items[0].metadata.name}')
53+
echo "Pod $POD"
6854
for i in {1..5}
6955
do
7056
HOSTNAME=$(curl -s http://${IP}:80/hostname || true)
7157
[[ ! -z "$HOSTNAME" ]] && break || sleep 1
7258
done
73-
echo $HOSTNAME
59+
echo "Hostname via TCP: $HOSTNAME"
60+
[ "$HOSTNAME" = "$POD" ]
61+
62+
for i in {1..5}
63+
do
64+
HOSTNAME=$(echo hostname | timeout 5 nc -u ${IP} 80 || true)
65+
[[ ! -z "$HOSTNAME" ]] && break || sleep 1
66+
done
67+
echo "Hostname via UDP: $HOSTNAME"
7468
[ "$HOSTNAME" = "$POD" ]
7569
}

0 commit comments

Comments
 (0)