From 2910014ee9aaa3754a2f5eb8a401867c80bc424c Mon Sep 17 00:00:00 2001 From: Kenneth Bingham Date: Fri, 25 Aug 2023 18:44:24 -0400 Subject: [PATCH] test the current branch by building ziti and the quickstart container image and running in compose and running quickstart_test.go --- .github/workflows/test-quickstart.yml | 31 ++++++ quickstart/test/compose-test.zsh | 154 ++++++++++++++++++++++++++ 2 files changed, 185 insertions(+) create mode 100644 .github/workflows/test-quickstart.yml create mode 100755 quickstart/test/compose-test.zsh diff --git a/.github/workflows/test-quickstart.yml b/.github/workflows/test-quickstart.yml new file mode 100644 index 000000000..caff5fddc --- /dev/null +++ b/.github/workflows/test-quickstart.yml @@ -0,0 +1,31 @@ +name: Test Quickstart +on: + workflow_dispatch: + # test quickstart changes after merge + push: + branches: + - release-next + - main + paths: + - 'quickstart/**' + # test quickstart changes before merge + pull_request: + paths: + - 'quickstart/**' + +# cancel older, redundant runs of same workflow on same branch +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }} + cancel-in-progress: true + +jobs: + compose-test: + name: Test Compose Quickstart + runs-on: ubuntu-latest + steps: + - name: Shallow checkout + uses: actions/checkout@v3 + - name: Install zsh + run: sudo apt-get update && sudo apt-get install --yes zsh + - name: Build and run a quickstart container image + run: ./quickstart/test/compose-test.zsh diff --git a/quickstart/test/compose-test.zsh b/quickstart/test/compose-test.zsh new file mode 100755 index 000000000..4fb55ff0d --- /dev/null +++ b/quickstart/test/compose-test.zsh @@ -0,0 +1,154 @@ +#!/usr/bin/env zsh +# +# this script tests the quickstart's ziti-cli-functions.sh, container image creation process, and Compose project by +# gathering files from a particular GitHub repo ref or a filesystem path and running the quickstart's Go test suite +# against the running Compose project +# + +set -euo pipefail + +function down_project() { + # don't destroy volumes or temp dir so we can inspect when running locally + docker compose kill + # rm -rf "${TESTDIR}" + echo "INFO: Stopped Compose project: ${TESTDIR}" +} + +DATESTAMP=$(date +%Y%m%d%H%M%S) +# generate a random password for the controller's admin user to ensure we're testing the expected instance +ZITI_PWD="$(set +o pipefail; LC_ALL=C tr -dc -- -A-Z-a-z-0-9 < /dev/urandom 2>/dev/null | head -c5)" +BASENAME="$(basename "$0")" +DIRNAME="$(dirname "$0")" +if [[ -n "${ZITI_QUICK_DIR:-}" ]]; then + if [[ -d "${ZITI_QUICK_DIR}" ]]; then + ZITI_QUICK_DIR="$(realpath "${ZITI_QUICK_DIR}")" + else + if [[ -d "${DIRNAME}/${ZITI_QUICK_DIR}" ]]; then + ZITI_QUICK_DIR="$(realpath "${DIRNAME}/${ZITI_QUICK_DIR}")" + else + echo "ERROR: ZITI_QUICK_DIR is set but is not a directory: ${ZITI_QUICK_DIR}" >&2 + exit 1 + fi + fi +fi +# avoid re-using directories from previous runs to keep this one-shot (non-idempotent) script simple because we needn't +# consider the state of the test dir +TESTDIR="$(mktemp -d -t "${BASENAME%.*}.${DATESTAMP}.XXX")" + +# if unset, set ZITI_QUICK_DIR to this script's parent dir which is always the quickstart root in the git repo +if [[ -z "${ZITI_QUICK_DIR:-}" ]]; then + ZITI_QUICK_DIR="$(realpath "${DIRNAME}/..")" +fi +# if unset, set ZITI_QUICK_IMAGE_TAG to this run's dirname +if [[ -z "${ZITI_QUICK_IMAGE_TAG:-}" ]]; then + ZITI_QUICK_IMAGE_TAG=$(basename "${TESTDIR}") +fi + +# case "${1:-}" in +# shift +# ;; +# --help|-h) +# echo "Usage: $BASENAME [--local|--help]" +# exit 0 +# ;; +# esac + +cd "${TESTDIR}" +echo "INFO: Testing Compose project $PWD" + +declare -a QUICK_FILES=( + ../go.{mod,sum} + test/{quickstart_test.go,compose.override.yml} + docker/{simplified-docker-compose.yml,.env} +) + # TODO: re-add cert checks files after https://github.com/openziti/ziti/pull/1278 + # test/{quickstart_test.go,compose.override.yml,check-cert-chains.zsh} +# download the quickstart Go test suite files from GitHub unless a local dir is specified +if [[ -n "${ZITI_QUICK_DIR:-}" ]]; then + for FILE in "${QUICK_FILES[@]}"; do + cp "${ZITI_QUICK_DIR}/${FILE}" . + done + if [[ -n "${ZITI_QUICK_IMAGE_TAG:-}" ]]; then + if [[ -x "${ZITI_QUICK_DIR:-}/docker/createLocalImage.sh" ]]; then + ( + cd "${ZITI_QUICK_DIR}/docker" + unset ZITI_VERSION ZITI_OVERRIDE_VERSION # always build the local source + ./createLocalImage.sh --build "${ZITI_QUICK_IMAGE_TAG}" + ) + else + echo "ERROR: ZITI_QUICK_IMAGE_TAG is set but ZITI_QUICK_DIR/docker/createLocalImage.sh is not executable" >&2 + exit 1 + fi + fi +elif [[ -n "${ZITI_QUICK_IMAGE_TAG:-}" ]]; then + echo "ERROR: ZITI_QUICK_IMAGE_TAG is set but ZITI_QUICK_DIR is not set" >&2 + exit 1 +else + echo "ERROR: ZITI_QUICK_IMAGE_TAG is not set, try running with --local" >&2 + exit 1 +fi + +# rename the simplified Compose file to the default Compose project file name +mv ./simplified-docker-compose.yml ./compose.yml + +# learn the expected Go version from the Go mod file so we can pull the correct container image +ZITI_GO_VERSION="$(grep -Po '^go\s+\K\d+\.\d+(\.\d+)?$' ./go.mod)" +# make this var available in the Compose project +sed -Ei "s/^(#\s+)?(ZITI_GO_VERSION)=.*/\2=${ZITI_GO_VERSION}/" ./.env +sed -Ei "s/^(#\s+)?(ZITI_PWD)=.*/\2=${ZITI_PWD}/" ./.env +sed -Ei "s/^(#\s+)?(ZITI_INTERFACE)=.*/\2=${ZITI_INTERFACE:-127.0.0.1}/" ./.env + +# pull images preemptively that we never build locally because pull=never when using a local quickstart image +for IMAGE in \ + "golang:${ZITI_GO_VERSION}-alpine" \ + "openziti/zac:latest" +do + docker pull --quiet "${IMAGE}" &>/dev/null +done + +# any halt after this point should cause the Compose project to be torn down +trap down_project SIGTERM SIGINT EXIT + +# if ZITI_QUICK_IMAGE_TAG is set then run the locally-built image +if [[ -n "${ZITI_QUICK_IMAGE_TAG:-}" ]]; then + sed -Ei "s/^(#\s+)?(ZITI_VERSION)=.*/\2=${ZITI_QUICK_IMAGE_TAG}/" ./.env + docker compose up --detach --pull=never &>/dev/null # no pull because local quickstart image +else + echo "ERROR: ZITI_QUICK_IMAGE_TAG is not set" >&2 + exit 1 +fi + +# copy files that are not present in older quickstart container images to the persistent volume; this allows us to run +# the test suite against them and investigate if the test fails and the container is destroyed +for FILE in \ + "" + # check-cert-chains.zsh + # TODO: re-add cert checks to cp list after https://github.com/openziti/ziti/pull/1278 +do + docker compose cp \ + "./${FILE}" \ + "ziti-controller:/persistent/${FILE}" &>/dev/null +done +# TODO: build these executables into the container image? + +# wait for the controller and router to be ready and run the certificate check script; NOUNSET option is enabled after +# sourcing quickstart functions and env because there are some unset variables in those +docker compose exec ziti-controller \ + bash -eo pipefail -c ' + source "${ZITI_SCRIPTS}/ziti-cli-functions.sh" >/dev/null; + echo "INFO: waiting for controller"; + sleep 3; + source /persistent/ziti.env >/dev/null; + set -u; + _wait_for_controller >/dev/null; + echo "INFO: waiting for public router"; + sleep 3; + source /persistent/ziti.env >/dev/null; + _wait_for_public_router >/dev/null; + ' + # TODO: re-add cert checks to above test suite after https://github.com/openziti/ziti/pull/1278 + # zsh /persistent/check-cert-chains.zsh; +docker compose run quickstart-test + +echo -e "\nINFO: Test completed successfully." +