diff --git a/.github/workflows/pull-requests.yaml b/.github/workflows/pull-requests.yaml index a4dc1a4b..06b4f3d3 100644 --- a/.github/workflows/pull-requests.yaml +++ b/.github/workflows/pull-requests.yaml @@ -33,6 +33,9 @@ jobs: fetch-depth: 0 fetch-tags: true + - name: Run unit tests + run: make unit-tests + - name: Set up Docker config run: | if [ -d ~/.docker ]; then diff --git a/Makefile b/Makefile index bb5eb40e..2038ff9f 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: manifests repos assets +.PHONY: manifests repos assets unit-tests helm-unit-tests build-deps: @command -V find docker skopeo jq gh helm > /dev/null @@ -46,6 +46,11 @@ test: make -C packages/core/testing apply make -C packages/core/testing test +unit-tests: helm-unit-tests + +helm-unit-tests: + hack/helm-unit-tests.sh + prepare-env: make -C packages/core/testing apply make -C packages/core/testing prepare-cluster diff --git a/hack/helm-unit-tests.sh b/hack/helm-unit-tests.sh new file mode 100755 index 00000000..d97042a2 --- /dev/null +++ b/hack/helm-unit-tests.sh @@ -0,0 +1,59 @@ +#!/bin/sh +set -eu + +# Script to run unit tests for all Helm charts. +# It iterates through directories in packages/apps, packages/extra, +# packages/system, and packages/library and runs the 'test' Makefile +# target if it exists. + +FAILED_DIRS_FILE="$(mktemp)" +trap 'rm -f "$FAILED_DIRS_FILE"' EXIT + +tests_found=0 + +check_and_run_test() { + dir="$1" + makefile="$dir/Makefile" + + if [ ! -f "$makefile" ]; then + return 0 + fi + + if make -C "$dir" -n test >/dev/null 2>&1; then + echo "Running tests in $dir" + tests_found=$((tests_found + 1)) + if ! make -C "$dir" test; then + printf '%s\n' "$dir" >> "$FAILED_DIRS_FILE" + return 1 + fi + fi + + return 0 +} + +for package_dir in packages/apps packages/extra packages/system packages/library; do + if [ ! -d "$package_dir" ]; then + echo "Warning: Directory $package_dir does not exist, skipping..." >&2 + continue + fi + + for dir in "$package_dir"/*; do + [ -d "$dir" ] || continue + check_and_run_test "$dir" || true + done +done + +if [ "$tests_found" -eq 0 ]; then + echo "No directories with 'test' Makefile targets found." + exit 0 +fi + +if [ -s "$FAILED_DIRS_FILE" ]; then + echo "ERROR: Tests failed in the following directories:" >&2 + while IFS= read -r dir; do + echo " - $dir" >&2 + done < "$FAILED_DIRS_FILE" + exit 1 +fi + +echo "All Helm unit tests passed." \ No newline at end of file diff --git a/packages/library/cozy-lib/Makefile b/packages/library/cozy-lib/Makefile index a4cf622b..362bf32c 100644 --- a/packages/library/cozy-lib/Makefile +++ b/packages/library/cozy-lib/Makefile @@ -4,3 +4,5 @@ include ../../../scripts/package.mk generate: cozyvalues-gen -v values.yaml -s values.schema.json -r README.md +test: + $(MAKE) -C ../../tests/cozy-lib-tests/ test diff --git a/packages/tests/cozy-lib-tests/.helmignore b/packages/tests/cozy-lib-tests/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/packages/tests/cozy-lib-tests/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/packages/tests/cozy-lib-tests/Chart.yaml b/packages/tests/cozy-lib-tests/Chart.yaml new file mode 100644 index 00000000..e18a84bf --- /dev/null +++ b/packages/tests/cozy-lib-tests/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: quota +description: Testing chart for cozy-lib + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/packages/tests/cozy-lib-tests/Makefile b/packages/tests/cozy-lib-tests/Makefile new file mode 100644 index 00000000..dec17a5f --- /dev/null +++ b/packages/tests/cozy-lib-tests/Makefile @@ -0,0 +1,2 @@ +test: + helm unittest . diff --git a/packages/tests/cozy-lib-tests/charts/cozy-lib b/packages/tests/cozy-lib-tests/charts/cozy-lib new file mode 120000 index 00000000..e1813509 --- /dev/null +++ b/packages/tests/cozy-lib-tests/charts/cozy-lib @@ -0,0 +1 @@ +../../../library/cozy-lib \ No newline at end of file diff --git a/packages/tests/cozy-lib-tests/templates/tests/quota.yaml b/packages/tests/cozy-lib-tests/templates/tests/quota.yaml new file mode 100644 index 00000000..10dd8a04 --- /dev/null +++ b/packages/tests/cozy-lib-tests/templates/tests/quota.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ResourceQuota +metadata: + name: {{ .Release.Name }} +spec: +{{- with .Values.quota }} + hard: {{- include "cozy-lib.resources.flatten" (list . $) | nindent 4 }} +{{- end }} diff --git a/packages/tests/cozy-lib-tests/tests/quota_test.yaml b/packages/tests/cozy-lib-tests/tests/quota_test.yaml new file mode 100644 index 00000000..cbc6fcb7 --- /dev/null +++ b/packages/tests/cozy-lib-tests/tests/quota_test.yaml @@ -0,0 +1,30 @@ +# ./tests/quota_test.yaml +suite: quota helper + +templates: + - templates/tests/quota.yaml + +tests: + - it: correctly interprets special kubernetes quota types + values: + - quota_values.yaml + + release: + name: myrelease + namespace: default + revision: 1 + isUpgrade: false + + asserts: + - equal: + path: spec.hard["limits.cpu"] + value: "2" + + - equal: + path: spec.hard["requests.cpu"] + value: "0.2" + + - equal: + path: spec.hard["services.loadbalancers"] + value: "2" + diff --git a/packages/tests/cozy-lib-tests/tests/quota_values.yaml b/packages/tests/cozy-lib-tests/tests/quota_values.yaml new file mode 100644 index 00000000..f2ed3a03 --- /dev/null +++ b/packages/tests/cozy-lib-tests/tests/quota_values.yaml @@ -0,0 +1,3 @@ +quota: + services.loadbalancers: "2" + cpu: "2"