From 37aae22ef09b88c85cf93fc4a47457c17ac22604 Mon Sep 17 00:00:00 2001 From: Kevin Marilleau Date: Wed, 13 Jan 2021 02:41:36 +0100 Subject: [PATCH 1/6] add shunit tests --- .github/workflows/test.yml | 9 ++++ Makefile | 11 +++++ hack/init.sh | 7 ++++ hack/make-rules/install-unit-test-deps.sh | 8 ++++ hack/make-rules/unit-test.sh | 28 +++++++++++++ hack/make-rules/verify.sh | 8 ++++ hack/shunit2.sh | 50 +++++++++++++++++++++++ 7 files changed, 121 insertions(+) create mode 100644 Makefile create mode 100644 hack/init.sh create mode 100755 hack/make-rules/install-unit-test-deps.sh create mode 100755 hack/make-rules/unit-test.sh create mode 100644 hack/make-rules/verify.sh create mode 100644 hack/shunit2.sh diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 203534cb..9182ee3a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -71,6 +71,15 @@ jobs: name: docker-gen.tar path: docker-gen.tar + unit-tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install Required Dependencies + run: make install-unit-test-deps + - name: Run Unit Tests + run: make unit-test + docker-specs-tests: needs: companion-build runs-on: ubuntu-latest diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..775588bc --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +install: install-unit-test-deps + +install-unit-test-deps: + ./hack/make-rules/install-unit-test-deps.sh + +unit-test: + ./hack/make-rules/unit-test.sh + +.PHONY: verify +verify: ## Verify that dev dependencies are installed and correctly configured + ./hack/make-rules/verify.sh \ No newline at end of file diff --git a/hack/init.sh b/hack/init.sh new file mode 100644 index 00000000..1659339d --- /dev/null +++ b/hack/init.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +# shellcheck disable=SC2034 # Variables sourced in other scripts. + +PROJECT_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) + +THIRD_PARTY=$PROJECT_ROOT/third_party diff --git a/hack/make-rules/install-unit-test-deps.sh b/hack/make-rules/install-unit-test-deps.sh new file mode 100755 index 00000000..137e619c --- /dev/null +++ b/hack/make-rules/install-unit-test-deps.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +PROJECT_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd) + +# shellcheck disable=SC1090 # Sourced files +source "$PROJECT_ROOT/hack/shunit2.sh" + +shunit2::install diff --git a/hack/make-rules/unit-test.sh b/hack/make-rules/unit-test.sh new file mode 100755 index 00000000..83c6fdf4 --- /dev/null +++ b/hack/make-rules/unit-test.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +# shellcheck disable=SC2034 # Variables sourced in other scripts. + +set -e +shopt -s globstar + +PROJECT_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd) + +UNIT_TEST_DIR=$PROJECT_ROOT/test/unit + +source_all_files_recursively_from() { + local directory=$1 + for file in "$directory"/**/*.sh; do + # shellcheck disable=SC1090 # Sourced files + source "$file" + done +} + +# shellcheck disable=SC1090 # Sourced files +source "$PROJECT_ROOT/hack/shunit2.sh" + +suite() { + source_all_files_recursively_from "$UNIT_TEST_DIR" +} + +# shellcheck disable=SC1090 # Sourced files +. "$SHUNIT2_BIN" diff --git a/hack/make-rules/verify.sh b/hack/make-rules/verify.sh new file mode 100644 index 00000000..df7fc75c --- /dev/null +++ b/hack/make-rules/verify.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +PROJECT_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd) + +# shellcheck disable=SC1090 # Sourced files +source "$PROJECT_ROOT/hack/shunit2.sh" + +shunit2::validate diff --git a/hack/shunit2.sh b/hack/shunit2.sh new file mode 100644 index 00000000..64cbf71d --- /dev/null +++ b/hack/shunit2.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash + +# shellcheck disable=SC2034 # Variables sourced in other scripts. + +PROJECT_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) + +# shellcheck disable=SC1090 # Sourced files +source "$PROJECT_ROOT/hack/init.sh" + +SHUNIT2_VERSION=v2.1.8 +SHUNIT2_REPO_URL=https://github.com/kward/shunit2 +SHUNIT2_DIR=$THIRD_PARTY/shunit2 +SHUNIT2_BIN=$SHUNIT2_DIR/shunit2 + +shunit2::validate() { + # Validate shUnit2 is installed + if [[ ! -d $SHUNIT2_DIR ]]; then + echo "shUnit2 is not installed." + return 1 + fi + + # Validate installed version + local expected_release=$SHUNIT2_VERSION + local current_release + + current_release=$(cd "$SHUNIT2_DIR" && git describe --tags) + if [[ "$current_release" != "$expected_release" ]]; then + echo "shUnit2 version $expected_release required, the current version" \ + "installed is $current_release." + return 1 + fi +} + +shunit2::install() { + if shunit2::validate; then + echo "shUnit2 ${SHUNIT2_VERSION} already installed." + return 1 + else + shunit2::cleanup + + git clone --branch "$SHUNIT2_VERSION" "$SHUNIT2_REPO_URL" "$SHUNIT2_DIR" + chmod +x "$SHUNIT2_BIN" + fi +} + +shunit2::cleanup() { + if [[ -d "$SHUNIT2_DIR" ]]; then + rm -rf "$SHUNIT2_DIR" + fi +} From 36305a0233828b1a99995f56f6b09189180239a6 Mon Sep 17 00:00:00 2001 From: Kevin Marilleau Date: Wed, 13 Jan 2021 13:28:01 +0100 Subject: [PATCH 2/6] rename integration tests folder --- .gitignore | 6 +++--- .../acme_accounts/expected-std-out.txt | 0 test/{tests => integration}/acme_accounts/run.sh | 0 .../certs_san/expected-std-out.txt | 0 test/{tests => integration}/certs_san/run.sh | 0 .../certs_single/expected-std-out.txt | 0 test/{tests => integration}/certs_single/run.sh | 0 .../certs_single_domain/expected-std-out.txt | 0 .../certs_single_domain/run.sh | 0 .../certs_standalone/expected-std-out.txt | 0 test/{tests => integration}/certs_standalone/run.sh | 6 +++--- .../container_restart/expected-std-out.txt | 0 test/{tests => integration}/container_restart/run.sh | 6 +++--- .../default_cert/expected-std-out.txt | 0 test/{tests => integration}/default_cert/run.sh | 0 test/{tests => integration}/docker_api/run.sh | 4 ++-- .../force_renew/expected-std-out.txt | 0 test/{tests => integration}/force_renew/run.sh | 0 .../location_config/expected-std-out.txt | 0 test/{tests => integration}/location_config/run.sh | 2 +- .../ocsp_must_staple/expected-std-out.txt | 0 test/{tests => integration}/ocsp_must_staple/run.sh | 0 .../permissions_custom/expected-std-out.txt | 0 .../{tests => integration}/permissions_custom/run.sh | 0 .../permissions_default/expected-std-out.txt | 0 .../permissions_default/run.sh | 0 .../private_keys/expected-std-out.txt | 0 test/{tests => integration}/private_keys/run.sh | 0 .../symlinks/expected-std-out.txt | 0 test/{tests => integration}/symlinks/run.sh | 0 test/{tests => integration}/test-functions.sh | 0 .../unit_tests/expected-std-out.txt | 0 test/run.sh | 12 ++++++------ 33 files changed, 18 insertions(+), 18 deletions(-) rename test/{tests => integration}/acme_accounts/expected-std-out.txt (100%) rename test/{tests => integration}/acme_accounts/run.sh (100%) rename test/{tests => integration}/certs_san/expected-std-out.txt (100%) rename test/{tests => integration}/certs_san/run.sh (100%) rename test/{tests => integration}/certs_single/expected-std-out.txt (100%) rename test/{tests => integration}/certs_single/run.sh (100%) rename test/{tests => integration}/certs_single_domain/expected-std-out.txt (100%) rename test/{tests => integration}/certs_single_domain/run.sh (100%) rename test/{tests => integration}/certs_standalone/expected-std-out.txt (100%) rename test/{tests => integration}/certs_standalone/run.sh (92%) rename test/{tests => integration}/container_restart/expected-std-out.txt (100%) rename test/{tests => integration}/container_restart/run.sh (85%) rename test/{tests => integration}/default_cert/expected-std-out.txt (100%) rename test/{tests => integration}/default_cert/run.sh (100%) rename test/{tests => integration}/docker_api/run.sh (98%) rename test/{tests => integration}/force_renew/expected-std-out.txt (100%) rename test/{tests => integration}/force_renew/run.sh (100%) rename test/{tests => integration}/location_config/expected-std-out.txt (100%) rename test/{tests => integration}/location_config/run.sh (99%) rename test/{tests => integration}/ocsp_must_staple/expected-std-out.txt (100%) rename test/{tests => integration}/ocsp_must_staple/run.sh (100%) rename test/{tests => integration}/permissions_custom/expected-std-out.txt (100%) rename test/{tests => integration}/permissions_custom/run.sh (100%) rename test/{tests => integration}/permissions_default/expected-std-out.txt (100%) rename test/{tests => integration}/permissions_default/run.sh (100%) rename test/{tests => integration}/private_keys/expected-std-out.txt (100%) rename test/{tests => integration}/private_keys/run.sh (100%) rename test/{tests => integration}/symlinks/expected-std-out.txt (100%) rename test/{tests => integration}/symlinks/run.sh (100%) rename test/{tests => integration}/test-functions.sh (100%) rename test/{tests => integration}/unit_tests/expected-std-out.txt (100%) diff --git a/.gitignore b/.gitignore index 08ef5882..d0e86463 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,6 @@ vhost.d/ go/ nginx.tmpl test/local_test_env.sh -test/tests/docker_api/expected-std-out.txt -test/tests/container_restart/docker_event_out.txt -test/tests/certs_standalone/letsencrypt_user_data +test/integration/docker_api/expected-std-out.txt +test/integration/container_restart/docker_event_out.txt +test/integration/certs_standalone/letsencrypt_user_data diff --git a/test/tests/acme_accounts/expected-std-out.txt b/test/integration/acme_accounts/expected-std-out.txt similarity index 100% rename from test/tests/acme_accounts/expected-std-out.txt rename to test/integration/acme_accounts/expected-std-out.txt diff --git a/test/tests/acme_accounts/run.sh b/test/integration/acme_accounts/run.sh similarity index 100% rename from test/tests/acme_accounts/run.sh rename to test/integration/acme_accounts/run.sh diff --git a/test/tests/certs_san/expected-std-out.txt b/test/integration/certs_san/expected-std-out.txt similarity index 100% rename from test/tests/certs_san/expected-std-out.txt rename to test/integration/certs_san/expected-std-out.txt diff --git a/test/tests/certs_san/run.sh b/test/integration/certs_san/run.sh similarity index 100% rename from test/tests/certs_san/run.sh rename to test/integration/certs_san/run.sh diff --git a/test/tests/certs_single/expected-std-out.txt b/test/integration/certs_single/expected-std-out.txt similarity index 100% rename from test/tests/certs_single/expected-std-out.txt rename to test/integration/certs_single/expected-std-out.txt diff --git a/test/tests/certs_single/run.sh b/test/integration/certs_single/run.sh similarity index 100% rename from test/tests/certs_single/run.sh rename to test/integration/certs_single/run.sh diff --git a/test/tests/certs_single_domain/expected-std-out.txt b/test/integration/certs_single_domain/expected-std-out.txt similarity index 100% rename from test/tests/certs_single_domain/expected-std-out.txt rename to test/integration/certs_single_domain/expected-std-out.txt diff --git a/test/tests/certs_single_domain/run.sh b/test/integration/certs_single_domain/run.sh similarity index 100% rename from test/tests/certs_single_domain/run.sh rename to test/integration/certs_single_domain/run.sh diff --git a/test/tests/certs_standalone/expected-std-out.txt b/test/integration/certs_standalone/expected-std-out.txt similarity index 100% rename from test/tests/certs_standalone/expected-std-out.txt rename to test/integration/certs_standalone/expected-std-out.txt diff --git a/test/tests/certs_standalone/run.sh b/test/integration/certs_standalone/run.sh similarity index 92% rename from test/tests/certs_standalone/run.sh rename to test/integration/certs_standalone/run.sh index 20e5855b..345621b5 100755 --- a/test/tests/certs_standalone/run.sh +++ b/test/integration/certs_standalone/run.sh @@ -36,7 +36,7 @@ function cleanup { trap cleanup EXIT # Create letsencrypt_user_data with a single domain cert -cat > "${GITHUB_WORKSPACE}/test/tests/certs_standalone/letsencrypt_user_data" < "${GITHUB_WORKSPACE}/test/integration/certs_standalone/letsencrypt_user_data" < "${GITHUB_WORKSPACE}/test/tests/certs_standalone/letsencrypt_user_data" < "${GITHUB_WORKSPACE}/test/integration/certs_standalone/letsencrypt_user_data" < "${GITHUB_WORKSPACE}/test/tests/container_restart/docker_event_out.txt" & + --format 'Container {{.Actor.Attributes.name}} restarted' > "${GITHUB_WORKSPACE}/test/integration/container_restart/docker_event_out.txt" & docker_events_pid=$! # Cleanup function with EXIT trap @@ -23,7 +23,7 @@ function cleanup { # Kill the Docker events listener kill $docker_events_pid && wait $docker_events_pid 2>/dev/null # Remove temporary files - rm -f "${GITHUB_WORKSPACE}/test/tests/container_restart/docker_event_out.txt" + rm -f "${GITHUB_WORKSPACE}/test/integration/container_restart/docker_event_out.txt" # Remove any remaining Nginx container(s) silently. for domain in "${domains[@]}"; do docker rm --force "$domain" &> /dev/null @@ -42,7 +42,7 @@ for domain in "${domains[@]}"; do # Check if container restarted timeout="$(date +%s)" timeout="$((timeout + 60))" - until grep "$domain" "${GITHUB_WORKSPACE}"/test/tests/container_restart/docker_event_out.txt; do + until grep "$domain" "${GITHUB_WORKSPACE}"/test/integration/container_restart/docker_event_out.txt; do if [[ "$(date +%s)" -gt "$timeout" ]]; then echo "Container $domain didn't restart in under one minute." break diff --git a/test/tests/default_cert/expected-std-out.txt b/test/integration/default_cert/expected-std-out.txt similarity index 100% rename from test/tests/default_cert/expected-std-out.txt rename to test/integration/default_cert/expected-std-out.txt diff --git a/test/tests/default_cert/run.sh b/test/integration/default_cert/run.sh similarity index 100% rename from test/tests/default_cert/run.sh rename to test/integration/default_cert/run.sh diff --git a/test/tests/docker_api/run.sh b/test/integration/docker_api/run.sh similarity index 98% rename from test/tests/docker_api/run.sh rename to test/integration/docker_api/run.sh index 84acf098..209e767d 100755 --- a/test/tests/docker_api/run.sh +++ b/test/integration/docker_api/run.sh @@ -78,7 +78,7 @@ case $SETUP in "$1" \ bash -c "$commands" 2>&1 - cat > "${GITHUB_WORKSPACE}/test/tests/docker_api/expected-std-out.txt" < "${GITHUB_WORKSPACE}/test/integration/docker_api/expected-std-out.txt" <&1 - cat > "${GITHUB_WORKSPACE}/test/tests/docker_api/expected-std-out.txt" < "${GITHUB_WORKSPACE}/test/integration/docker_api/expected-std-out.txt" < "$location_file" # Create le1.wtf configuration file, *.le3.wtf and test.* from inside the nginx container diff --git a/test/tests/ocsp_must_staple/expected-std-out.txt b/test/integration/ocsp_must_staple/expected-std-out.txt similarity index 100% rename from test/tests/ocsp_must_staple/expected-std-out.txt rename to test/integration/ocsp_must_staple/expected-std-out.txt diff --git a/test/tests/ocsp_must_staple/run.sh b/test/integration/ocsp_must_staple/run.sh similarity index 100% rename from test/tests/ocsp_must_staple/run.sh rename to test/integration/ocsp_must_staple/run.sh diff --git a/test/tests/permissions_custom/expected-std-out.txt b/test/integration/permissions_custom/expected-std-out.txt similarity index 100% rename from test/tests/permissions_custom/expected-std-out.txt rename to test/integration/permissions_custom/expected-std-out.txt diff --git a/test/tests/permissions_custom/run.sh b/test/integration/permissions_custom/run.sh similarity index 100% rename from test/tests/permissions_custom/run.sh rename to test/integration/permissions_custom/run.sh diff --git a/test/tests/permissions_default/expected-std-out.txt b/test/integration/permissions_default/expected-std-out.txt similarity index 100% rename from test/tests/permissions_default/expected-std-out.txt rename to test/integration/permissions_default/expected-std-out.txt diff --git a/test/tests/permissions_default/run.sh b/test/integration/permissions_default/run.sh similarity index 100% rename from test/tests/permissions_default/run.sh rename to test/integration/permissions_default/run.sh diff --git a/test/tests/private_keys/expected-std-out.txt b/test/integration/private_keys/expected-std-out.txt similarity index 100% rename from test/tests/private_keys/expected-std-out.txt rename to test/integration/private_keys/expected-std-out.txt diff --git a/test/tests/private_keys/run.sh b/test/integration/private_keys/run.sh similarity index 100% rename from test/tests/private_keys/run.sh rename to test/integration/private_keys/run.sh diff --git a/test/tests/symlinks/expected-std-out.txt b/test/integration/symlinks/expected-std-out.txt similarity index 100% rename from test/tests/symlinks/expected-std-out.txt rename to test/integration/symlinks/expected-std-out.txt diff --git a/test/tests/symlinks/run.sh b/test/integration/symlinks/run.sh similarity index 100% rename from test/tests/symlinks/run.sh rename to test/integration/symlinks/run.sh diff --git a/test/tests/test-functions.sh b/test/integration/test-functions.sh similarity index 100% rename from test/tests/test-functions.sh rename to test/integration/test-functions.sh diff --git a/test/tests/unit_tests/expected-std-out.txt b/test/integration/unit_tests/expected-std-out.txt similarity index 100% rename from test/tests/unit_tests/expected-std-out.txt rename to test/integration/unit_tests/expected-std-out.txt diff --git a/test/run.sh b/test/run.sh index 7c9abb8c..1ea0a031 100755 --- a/test/run.sh +++ b/test/run.sh @@ -208,8 +208,8 @@ if [[ -z $GITHUB_ACTIONS ]] && [[ -f "$dir/local_test_env.sh" ]]; then source "$dir/local_test_env.sh" fi -# shellcheck source=./tests/test-functions.sh -source "$dir/tests/test-functions.sh" +# shellcheck source=./integration/test-functions.sh +source "$dir/integration/test-functions.sh" ## End of additional code usage() { @@ -296,12 +296,12 @@ for conf in "${configs[@]}"; do for testName in ${globalTests[@]} ${imageTests[@]}; do [ "${testPaths[$testName]}" ] && continue - if [ -d "$confDir/tests/$testName" ]; then + if [ -d "$confDir/integration/$testName" ]; then # Test directory found relative to the conf file - testPaths[$testName]="$confDir/tests/$testName" - elif [ -d "$dir/tests/$testName" ]; then + testPaths[$testName]="$confDir/integration/$testName" + elif [ -d "$dir/integration/$testName" ]; then # Test directory found in the main tests/ directory - testPaths[$testName]="$dir/tests/$testName" + testPaths[$testName]="$dir/integration/$testName" fi done done From dd39e081d48e625bb57847b6d974af0c4191d214 Mon Sep 17 00:00:00 2001 From: Kevin Marilleau Date: Wed, 13 Jan 2021 13:28:07 +0100 Subject: [PATCH 3/6] add example unit test file --- test/unit/test-template.sh | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 test/unit/test-template.sh diff --git a/test/unit/test-template.sh b/test/unit/test-template.sh new file mode 100644 index 00000000..084a6dba --- /dev/null +++ b/test/unit/test-template.sh @@ -0,0 +1,8 @@ +#! /bin/sh + +testEquality() +{ + assertEquals 1 1 +} + +suite_addTest testEquality From e41d85a7d50ea6c33c0caa06b7bf3a81a5fa61fd Mon Sep 17 00:00:00 2001 From: Kevin Marilleau Date: Sun, 24 Jan 2021 17:22:44 +0100 Subject: [PATCH 4/6] add Makefile autodoc and help command as default --- Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 775588bc..0416071a 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,9 @@ -install: install-unit-test-deps +.DEFAULT_GOAL := help + +help: ## Show help +# Source: https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + install-unit-test-deps: ./hack/make-rules/install-unit-test-deps.sh From dbb3ed2ecb084ea0280fc140b3d1d2177f0de8fe Mon Sep 17 00:00:00 2001 From: Kevin Marilleau Date: Sun, 24 Jan 2021 17:23:27 +0100 Subject: [PATCH 5/6] Add Makefile documentation --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0416071a..caa869dc 100644 --- a/Makefile +++ b/Makefile @@ -4,11 +4,12 @@ help: ## Show help # Source: https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' +install: install-unit-test-deps ## Install all dev dependencies install-unit-test-deps: ./hack/make-rules/install-unit-test-deps.sh -unit-test: +unit-test: ## Run all tests ./hack/make-rules/unit-test.sh .PHONY: verify From a081802d140b5444b6ff6aff3fe9a964f5137eb1 Mon Sep 17 00:00:00 2001 From: Kevin Marilleau Date: Sun, 24 Jan 2021 17:25:44 +0100 Subject: [PATCH 6/6] ensure targets in Makefile aren't associated with files --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index caa869dc..80bb0a83 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,18 @@ .DEFAULT_GOAL := help +.PHONY: help help: ## Show help # Source: https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' +.PHONY: install install: install-unit-test-deps ## Install all dev dependencies +.PHONY: install-unit-test-deps install-unit-test-deps: ./hack/make-rules/install-unit-test-deps.sh +.PHONY: unit-test unit-test: ## Run all tests ./hack/make-rules/unit-test.sh