Skip to content

Commit 5265773

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

File tree

5 files changed

+155
-49
lines changed

5 files changed

+155
-49
lines changed

.github/workflows/bats.yml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
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+
brew install kind
54+
brew install docker
55+
colima start
56+
- name: Bats tests
57+
shell: bash
58+
env:
59+
BATS_LIB_PATH: ${{ steps.setup-bats.outputs.lib-path }}
60+
TERM: xterm
61+
run: bats -o _artifacts tests/
62+
63+
- name: Upload logs
64+
if: always()
65+
uses: actions/upload-artifact@v4
66+
with:
67+
name: kind-logs-${{ env.JOB_NAME }}-${{ github.run_id }}
68+
path: ./_artifacts
69+

.github/workflows/k8s.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
id: go
3333

3434
- name: Check out code
35-
uses: actions/checkout@v2
35+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
3636

3737
- name: Enable ipv4 and ipv6 forwarding
3838
run: |

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

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
6026
for i in {1..5}
6127
do
62-
IP=$(kubectl --kubeconfig "${TMP_DIR}/kubeconfig" get services lb-service-cluster --output jsonpath='{.status.loadBalancer.ingress[0].ip}')
28+
IP=$(kubectl get services lb-service-cluster --output jsonpath='{.status.loadBalancer.ingress[0].ip}')
6329
[[ ! -z "$IP" ]] && break || sleep 1
6430
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
31+
echo "IP: $IP"
32+
POD=$(kubectl get pod -l app=MyClusterApp -o jsonpath='{.items[0].metadata.name}')
33+
echo "Pod $POD"
6834
for i in {1..5}
6935
do
7036
HOSTNAME=$(curl -s http://${IP}:80/hostname || true)
7137
[[ ! -z "$HOSTNAME" ]] && break || sleep 1
7238
done
73-
echo $HOSTNAME
39+
echo "Hostname via TCP: $HOSTNAME"
7440
[ "$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
46+
for i in {1..5}
47+
do
48+
IP=$(kubectl get services lb-service-cluster --output jsonpath='{.status.loadBalancer.ingress[0].ip}')
49+
[[ ! -z "$IP" ]] && break || sleep 1
50+
done
51+
echo "IP: $IP"
52+
POD=$(kubectl get pod -l app=MyClusterApp -o jsonpath='{.items[0].metadata.name}')
53+
echo "Pod $POD"
54+
for i in {1..5}
55+
do
56+
HOSTNAME=$(curl -s http://${IP}:80/hostname || true)
57+
[[ ! -z "$HOSTNAME" ]] && break || sleep 1
58+
done
59+
echo "Hostname via TCP: $HOSTNAME"
60+
[ "$HOSTNAME" = "$POD" ]
61+
62+
for i in {1..5}
63+
do
64+
HOSTNAME=$(echo hostname | nc -u -w 3 ${IP} 80 || true)
65+
[[ ! -z "$HOSTNAME" ]] && break || sleep 1
66+
done
67+
echo "Hostname via UDP: $HOSTNAME"
68+
[[ ! -z "$HOSTNAME" ]] && [ "$HOSTNAME" = "$POD" ]
7569
}

0 commit comments

Comments
 (0)