From eaa0119d7965fdad31b7dc81a64479772643e935 Mon Sep 17 00:00:00 2001 From: Kamil Kasperski Date: Fri, 17 Nov 2023 17:02:18 +0100 Subject: [PATCH] Initial smoke-test framework for docker testimages /kind feature /area ci Added small framework that allows to define small test script that allows doing some work around the Docker context. I've added small tests around basic functionalities and binary presence. Script results outputs are collected to the ARTIFACTS directory and if any error occurs, the build loop is interrupted, returning non-zero exit code. The functionality docu is provided for anyone who wants to add another smoke test for new or existing image. --- images/README.md | 19 +++++++++++++++ images/build-images.sh | 12 ++++++++-- images/buildpack/go/test.sh | 20 ++++++++++++++++ images/e2e-dind-k3d/test.sh | 42 ++++++++++++++++++++++++++++++++++ images/e2e-dind-nodejs/test.sh | 40 ++++++++++++++++++++++++++++++++ 5 files changed, 131 insertions(+), 2 deletions(-) create mode 100755 images/buildpack/go/test.sh create mode 100755 images/e2e-dind-k3d/test.sh create mode 100755 images/e2e-dind-nodejs/test.sh diff --git a/images/README.md b/images/README.md index 27ade93c9ae0..7cfd7071ef75 100644 --- a/images/README.md +++ b/images/README.md @@ -10,3 +10,22 @@ To add additional applications into the images, open a PR with changes. Follow t * Always build from a source to ensure compiler vulnerabilities do not affect the resulting binary * Link the binary to a specific version so that it's easier to update when necessary * Build binaries in a separate stage, then copy the resulting binary into the final image to ensure images are small and contain the least number of layers + +## Writing image tests + +to write simple smoke tests with your image, add an **executable** file called `test.sh`. +The scripts should contain all steps that perform basic or advanced test operations against the image. You are allowed to use all binaries available in [E2E DinD K3d image](./e2e-dind-k3d) to test built image. +Test script **must** exit with non-zero number, if any of the steps failed. + +By default, current context of a test script will always be Docker build context. Image name is passed as a variable `IMG`. + +### Example + +The example below showcases the example definition of test.sh script. +```shell +#!/usr/bin/env bash +set -e +echo "$IMG" +docker run --rm $IMG -- some-command +test $? -eq 0 || exit 1 +``` \ No newline at end of file diff --git a/images/build-images.sh b/images/build-images.sh index 214ac66ca2fc..49995041f0cb 100755 --- a/images/build-images.sh +++ b/images/build-images.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -e - +ARTIFACTS="${ARTIFACTS:-/tmp}" # WORKAROUND #TODO (@Ressetkk): Use bundled image with docker-credential-gcr and docker if [[ $CI == "true" ]]; then @@ -20,12 +20,20 @@ toPush=() for v in $(find . -type d -exec test -e '{}'/Dockerfile \; -print | cut -c3-) ; do name=$(echo "$v" | sed "s/\//-/g") echo "building $name..." + IMG="local/$v" docker buildx build \ --load \ - -t "local/$v" \ + -t "$IMG" \ -t "$REGISTRY/$name:latest" \ -t "$REGISTRY/$name:$TAG" \ "./$v" + + if [ -x "./$v/test.sh" ]; then + pushd "./$v" + echo "Run $v/test.sh" + IMG=$IMG ./test.sh &> "$ARTIFACTS/$name-test.log" && echo "OK!" || exit 1 + popd + fi toPush+=("$REGISTRY/$name") done diff --git a/images/buildpack/go/test.sh b/images/buildpack/go/test.sh new file mode 100755 index 000000000000..bb57fd30c5ee --- /dev/null +++ b/images/buildpack/go/test.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -e +podman run --arch=amd64 --rm "$IMG" bash -c ' +set -e +go version +ko version +kubebuilder version +kustomize version +jobguard -help + +cat< /tmp/main.go +package main +import "fmt" +func main() { +fmt.Println("Hello World!") +} +EOF +go run /tmp/main.go +' \ No newline at end of file diff --git a/images/e2e-dind-k3d/test.sh b/images/e2e-dind-k3d/test.sh new file mode 100755 index 000000000000..c62b8e9975cc --- /dev/null +++ b/images/e2e-dind-k3d/test.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +set -e + +echo ">>> Basic checks" +docker run --rm --privileged \ + "$IMG" bash -c ' + set -e + helm version + jobguard -h + env + ' +echo "DinD checks" +docker run --rm --privileged \ + -e DOCKER_IN_DOCKER_ENABLED=true \ + "$IMG" bash -c ' + set -e + cat $ARTIFACTS/docker-info.log + docker run --rm alpine:latest uname -a + ' + +echo ">>> K3D test" +docker run --rm --privileged \ + -e DOCKER_IN_DOCKER_ENABLED=true \ + -e K3D_ENABLED=true \ + -e PROVISION_REGISTRY=true \ + "$IMG" bash -c ' + k3d version + k3d cluster get + docker ps + kubectl cluster-info + kubectl run nginx --image=nginx:latest + ' + +docker run --rm --privileged \ + "$IMG" bash -c ' + kind version + kind create cluster + docker ps + kubectl cluster-info + kubectl run nginx --image=nginx:latest + ' \ No newline at end of file diff --git a/images/e2e-dind-nodejs/test.sh b/images/e2e-dind-nodejs/test.sh new file mode 100755 index 000000000000..41a8d1094975 --- /dev/null +++ b/images/e2e-dind-nodejs/test.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +set -e + +echo ">>> Basic checks" +docker run --rm --privileged \ + "$IMG" bash -c ' + set -e + helm version + jobguard -h + env + ' +echo "DinD checks" +docker run --rm --privileged \ + -e DOCKER_IN_DOCKER_ENABLED=true \ + "$IMG" bash -c ' + set -e + cat $ARTIFACTS/docker-info.log + docker run --rm alpine:latest uname -a + ' + +echo ">>> K3D test" +docker run --rm --privileged \ + -e DOCKER_IN_DOCKER_ENABLED=true \ + -e K3D_ENABLED=true \ + -e PROVISION_REGISTRY=true \ + "$IMG" bash -c ' + k3d version + k3d cluster get + docker ps + kubectl cluster-info + kubectl run nginx --image=nginx:latest + ' +echo ">>> NodeJS test" +docker run --rm --privileged \ + "$IMG" bash -c ' + node --version + npm --version + yarn version + ' \ No newline at end of file