diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index c0445470..d7458aca 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -35,6 +35,9 @@ jobs: - name: build run: | VERBOSE=1 make build + - name: unit tests + run: | + VERBOSE=1 make unit-tests - name: lowercase the runner OS name shell: bash run: | diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f31d327b..88ae9e58 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -26,27 +26,22 @@ jobs: build: uses: ./.github/workflows/build.yaml test: + needs: build runs-on: ubuntu-latest env: ARCH: x86_64 steps: - uses: actions/checkout@v3 - - uses: Swatinem/rust-cache@v2 - with: - workspaces: | - "containerd-shim-*-v1 -> target" - - name: "Install Rust Wasm targets" + - uses: actions/download-artifact@v3 + - name: Extract containerd-wasm-shims-v1-linux-${{ env.ARCH }} run: | - make install-rust-targets - - name: "Install dependencies" - run: | - sudo apt-get update - sudo apt-get install protobuf-compiler -y + mkdir -p ./bin + tar -xzf containerd-wasm-shims-v1-linux-${{ env.ARCH }}/containerd-wasm-shims-v1-linux-${{ env.ARCH }}.tar.gz -C ./bin - name: install k3d run: make install-k3d working-directory: ./deployments/k3d - name: run integration tests - run: make test + run: BIN_DIR="./bin" make integration-tests - name: clean up k3d if: always() - run: make test/clean \ No newline at end of file + run: make test/clean diff --git a/Makefile b/Makefile index 8b31649a..e2b2dfd9 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,8 @@ else VERBOSE_FLAG := -vvv endif +BIN_DIR ?= + .PHONY: test test: unit-tests integration-tests @@ -23,14 +25,33 @@ test: unit-tests integration-tests unit-tests: build $(foreach shim,$(SHIMS),cross test --release --manifest-path=containerd-shim-$(shim)-v1/Cargo.toml --target $(TARGET);) +.PHONY: check-bins +check-bins: + ./scripts/check-bins.sh + +./PHONY: move-bins +move-bins: + ./scripts/move-bins.sh $(BIN_DIR) + +./PHONY: up +up: + ./scripts/up.sh + +./PHONY: pod-status-check +pod-status-check: + ./scripts/pod-status-check.sh + +./PHONY: workloads +workloads: + ./scripts/workloads.sh + .PHONY: integration-tests -integration-tests: build - $(PYTHON) tests/setup.py $(TARGET) +integration-tests: install-cross check-bins move-bins up pod-status-check workloads cargo test -- --nocapture .PHONY: tests/clean test/clean: - $(PYTHON) tests/teardown.py + ./scripts/down.sh .PHONY: fmt fmt: diff --git a/scripts/check-bins.sh b/scripts/check-bins.sh new file mode 100755 index 00000000..1d72fcd8 --- /dev/null +++ b/scripts/check-bins.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# Description: +# This script checks for the existence of specific binaries on the system. +# It uses a function called which_binary to accomplish this. +# The script first verifies the existence of the binaries and then prints their paths. + +# Usage: +# ./check-bins.sh + +# Dependencies: +# The script expects the following binaries to be present in the system's PATH: +# k3d, cross, docker, kubectl + +set -euo pipefail + +# Function: which_binary +# Description: +# Finds and prints the path of the specified binary if it exists in the system's PATH. +# If the binary is not found, it prints an error message. +# Parameters: +# $1 - The name of the binary to locate. +which_binary() { + local binary_name="$1" + local binary_path + binary_path=$(command -v "$binary_name") + if [[ -n "$binary_path" ]]; then + echo "$binary_path" + else + echo "Could not find $binary_name" >&2 + exit 1 + fi +} + + +# List of binary names +binaries=("k3d" "cross" "docker" "kubectl") + +for binary in "${binaries[@]}"; do + which_binary "$binary" +done diff --git a/scripts/down.sh b/scripts/down.sh new file mode 100755 index 00000000..21e3d3b8 --- /dev/null +++ b/scripts/down.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -euo pipefail + +cluster_name="test-cluster" + +teardown_test() { + # delete k3d cluster + k3d cluster delete "$cluster_name" + + # delete docker image + docker rmi k3d-shim-test +} + +teardown_test \ No newline at end of file diff --git a/scripts/move-bins.sh b/scripts/move-bins.sh new file mode 100755 index 00000000..2e08a624 --- /dev/null +++ b/scripts/move-bins.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# Containerd Shim Installer Script +# +# This script automates the installation of specific containerd shim versions (slight, spin, wws) +# by checking their existence and copying them to a desired location if not found. +# +# Usage: +# ./move-bins.sh [release_pattern] [target] +# +# Arguments: +# 1. release_pattern (Optional): The pattern used to locate the shim binaries. +# 2. target (Optional): The target architecture used in the release path. +# Default value is `x86_64-unknown-linux-musl`. +# +# Example: +# ./move-bins.sh +# + +set -euo pipefail + +target="${2:-x86_64-unknown-linux-musl}" +release_pattern="${1:-containerd-shim-%s-v1/target/$target/release}" + +dockerfile_path="deployments/k3d" +bin_path="${dockerfile_path}/.tmp/" +cluster_name="test-cluster" +default_shim_path="${bin_path}containerd-shim-" + +declare -A shims=( + [slight]="${default_shim_path}slight-v1" + [spin]="${default_shim_path}spin-v1" + [wws]="${default_shim_path}wws-v1" +) + +mkdir -p "$bin_path" + +for shim_key in "${!shims[@]}"; do + shim_path=${shims[$shim_key]} + release_path=$(printf "$release_pattern" "$shim_key") + + if [ ! -f "$shim_path" ]; then + echo ">>> install containerd-shim-${shim_key}-v1 from $release_path" + cp "$(eval echo $release_path)/containerd-shim-${shim_key}-v1" "${bin_path}containerd-shim-${shim_key}-v1" + fi +done diff --git a/scripts/pod-status-check.sh b/scripts/pod-status-check.sh new file mode 100755 index 00000000..a78a90e4 --- /dev/null +++ b/scripts/pod-status-check.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +set -euo pipefail + +# Get the status of all pods +pod_statuses=$(kubectl get pods --no-headers -o custom-columns=":status.phase") + +# Check if all pods are running fine +all_running=true +for status in $pod_statuses; do + if [ "$status" != "Running" ]; then + all_running=false + break + fi +done + +if $all_running; then + echo "All pods are running fine." +else + echo "Not all pods are running fine. Please check the status." +fi \ No newline at end of file diff --git a/scripts/up.sh b/scripts/up.sh new file mode 100755 index 00000000..a6acbca8 --- /dev/null +++ b/scripts/up.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +set -euo pipefail + +cluster_name="test-cluster" # name of the k3d cluster +dockerfile_path="deployments/k3d" # path to the Dockerfile + +DOCKER_IMAGES=("slight" "spin" "wws") +OUT_DIRS=("test/out_slight" "test/out_spin" "test/out_wws") +IMAGES=("slight-hello-world" "spin-hello-world" "wws-hello-world") + +# build the Docker image for the k3d cluster +docker build -t k3d-shim-test "$dockerfile_path" + +k3d cluster create "$cluster_name" --image k3d-shim-test --api-port 6551 -p '8082:80@loadbalancer' --agents 2 + +kubectl wait --for=condition=ready node --all --timeout=120s + +# Iterate through the Docker images and build them +for i in "${!DOCKER_IMAGES[@]}"; do + docker buildx build -t "${IMAGES[$i]}:latest" "./images/${DOCKER_IMAGES[$i]}" --load + mkdir -p "${OUT_DIRS[$i]}" + docker save -o "${OUT_DIRS[$i]}/img.tar" "${IMAGES[$i]}:latest" + k3d image import "${OUT_DIRS[$i]}/img.tar" -c "$cluster_name" +done + +sleep 5 + +echo ">>> cluster is ready" diff --git a/scripts/workloads.sh b/scripts/workloads.sh new file mode 100755 index 00000000..210b9a0e --- /dev/null +++ b/scripts/workloads.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +set -euo pipefail + +# apply the workloads +echo ">>> apply workloads" +kubectl apply -f tests/workloads + + +# wait for all the pods to be ready +kubectl wait --for=condition=ready --timeout=50s pod --all + +# get and describe all the pods +echo ">>> Pods:" +kubectl get pods -o wide +kubectl describe pods + +# get and describe all the deployments +echo ">>> Deployments:" +kubectl get deployments -o wide +kubectl describe deployments + +# get and describe all the services +echo ">>> Services:" +kubectl get services -o wide +kubectl describe services \ No newline at end of file diff --git a/tests/setup.py b/tests/setup.py deleted file mode 100644 index 0f97d0d9..00000000 --- a/tests/setup.py +++ /dev/null @@ -1,103 +0,0 @@ -import time -import os -import sys - -def which(binary_name): - """Return the path to a binary, or None if it is not found.""" - for path in os.environ["PATH"].split(os.pathsep): - binary_path = os.path.join(path, binary_name) - if os.path.exists(binary_path): - return binary_path - # panic - raise RuntimeError("Could not find %s" % binary_name) - - -def setup_test(target): - # run this as root - which("k3d") - which("cross") - which("docker") - which("kubectl") - - dockerfile_path = "deployments/k3d" - bin_path = "deployments/k3d/.tmp/" - slight_shim_path = "deployments/k3d/.tmp/containerd-shim-slight-v1" - spin_shim_path = "deployments/k3d/.tmp/containerd-shim-spin-v1" - wws_shim_path = "deployments/k3d/.tmp/containerd-shim-wws-v1" - cluster_name = "test-cluster" - - # create bin_path if not exists - if not os.path.exists(bin_path): - os.makedirs(bin_path) - - try: - which(slight_shim_path) - except RuntimeError: - print(">>> install containerd-shim-slight-v1") - os.system(f"cp containerd-shim-slight-v1/target/{target}/release/containerd-shim-slight-v1 {bin_path}/containerd-shim-slight-v1") - - try: - which(spin_shim_path) - except RuntimeError: - print(">>> install containerd-shim-spin-v1") - os.system(f"cp containerd-shim-spin-v1/target/{target}/release/containerd-shim-spin-v1 {bin_path}/containerd-shim-spin-v1") - - try: - which(wws_shim_path) - except RuntimeError: - print(">>> install containerd-shim-wws-v1") - os.system(f"cp containerd-shim-wws-v1/target/{target}/release/containerd-shim-wws-v1 {bin_path}/containerd-shim-wws-v1") - - # build the docker image - os.system(f"docker build -t k3d-shim-test {dockerfile_path}") - - # create the cluster - os.system(f"k3d cluster create {cluster_name} --image k3d-shim-test --api-port 6551 -p '8082:80@loadbalancer' --agents 2") - - # wait for the cluster to be ready - os.system("kubectl wait --for=condition=ready node --all --timeout=120s") - - # build slight and spin images locally - os.system("docker buildx build -t slight-hello-world:latest ./images/slight --load") - os.system("docker buildx build -t spin-hello-world:latest ./images/spin --load") - os.system("docker buildx build -t wws-hello-world:latest ./images/wws --load") - - # create dir if not exists - if not os.path.exists("test/out_slight"): - os.makedirs("test/out_slight") - if not os.path.exists("test/out_spin"): - os.makedirs("test/out_spin") - if not os.path.exists("test/out_wws"): - os.makedirs("test/out_wws") - - # save docker images to tar ball - os.system("docker save -o test/out_slight/img.tar slight-hello-world:latest") - os.system("docker save -o test/out_spin/img.tar spin-hello-world:latest") - os.system("docker save -o test/out_wws/img.tar wws-hello-world:latest") - - # load tar ball to k3d cluster - os.system(f"k3d image import test/out_slight/img.tar -c {cluster_name}") - os.system(f"k3d image import test/out_spin/img.tar -c {cluster_name}") - os.system(f"k3d image import test/out_wws/img.tar -c {cluster_name}") - - # wait for 5 seconds - time.sleep(5) - - print(">>> apply workloads") - os.system("kubectl apply -f tests/workloads") - - # wait for 25 seconds - time.sleep(25) - - os.system("kubectl describe pods") - os.system("kubectl describe deployments") - os.system("kubectl describe services") - - print(">>> cluster is ready") - -if __name__ == '__main__': - if len(sys.argv) < 2: - target = "x86_64-unknown-linux-musl" - else: - target = sys.argv[1] - setup_test(target = target) \ No newline at end of file diff --git a/tests/teardown.py b/tests/teardown.py deleted file mode 100644 index 563c49a7..00000000 --- a/tests/teardown.py +++ /dev/null @@ -1,12 +0,0 @@ -import os - -def teardown_test(): - # delete k3d cluster - os.system("k3d cluster delete test-cluster") - - # delete docker image - os.system("docker rmi k3d-shim-test") - - -if __name__ == '__main__': - teardown_test() \ No newline at end of file