Keep restore and save keys stable across release version rewrites, avoid inherited cross-version caches, skip unused OWASP setup, upload test results once and pack the orb once before gated publication. Co-Authored-By: Codex <noreply@openai.com> Signed-off-by: James Maes <james@kof22.com>
1439 lines
46 KiB
Bash
Executable File
1439 lines
46 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
|
FIXTURES_DIR="${SCRIPT_DIR}/fixtures"
|
|
PASS=0
|
|
FAIL=0
|
|
|
|
GENERATE_SCRIPT="${PROJECT_DIR}/src/scripts/generate_config.sh"
|
|
GENERATED_DIR=$(mktemp -d)
|
|
trap 'rm -rf "${GENERATED_DIR}"' EXIT
|
|
|
|
# --------------------------------------------------------------------------
|
|
# Helper: render a fixture by calling the real generate_config.sh script
|
|
# and returning its output file contents.
|
|
# --------------------------------------------------------------------------
|
|
render_fixture() {
|
|
local fixture="$1"
|
|
local generated_config="${GENERATED_DIR}/$(basename "${fixture}")"
|
|
|
|
# Fixtures are immutable and uniquely named: render once, assert many times.
|
|
if [[ ! -f "${generated_config}" ]]; then
|
|
MUNITOR_CONFIG="${fixture}" MUNITOR_OUTPUT_FILE="${generated_config}.tmp" \
|
|
bash "${GENERATE_SCRIPT}" >/dev/null 2>&1 || return 1
|
|
mv "${generated_config}.tmp" "${generated_config}"
|
|
fi
|
|
cat "${generated_config}"
|
|
}
|
|
|
|
run_test() {
|
|
local name="$1"
|
|
local fixture="$2"
|
|
local expected_pattern="$3"
|
|
|
|
echo -n " TEST: ${name}... "
|
|
|
|
local output
|
|
output=$(render_fixture "${fixture}") || {
|
|
echo "FAIL (script error)"
|
|
echo " Output: ${output}"
|
|
FAIL=$((FAIL + 1))
|
|
return
|
|
}
|
|
|
|
if grep -q "${expected_pattern}" <<< "${output}"; then
|
|
echo "PASS"
|
|
PASS=$((PASS + 1))
|
|
else
|
|
echo "FAIL (expected pattern '${expected_pattern}' not found)"
|
|
echo " Output (first 5 lines):"
|
|
echo "${output}" | head -5 | sed 's/^/ /'
|
|
FAIL=$((FAIL + 1))
|
|
fi
|
|
}
|
|
|
|
run_negative_test() {
|
|
local name="$1"
|
|
local fixture="$2"
|
|
local forbidden_pattern="$3"
|
|
|
|
echo -n " TEST: ${name}... "
|
|
|
|
local output
|
|
output=$(render_fixture "${fixture}") || {
|
|
echo "FAIL (script error)"
|
|
FAIL=$((FAIL + 1))
|
|
return
|
|
}
|
|
|
|
if grep -q "${forbidden_pattern}" <<< "${output}"; then
|
|
echo "FAIL (found forbidden pattern '${forbidden_pattern}')"
|
|
FAIL=$((FAIL + 1))
|
|
else
|
|
echo "PASS"
|
|
PASS=$((PASS + 1))
|
|
fi
|
|
}
|
|
|
|
# --------------------------------------------------------------------------
|
|
# Helper: assert a pattern appears within a YAML block bounded by
|
|
# start_pattern (inclusive) and end_pattern (inclusive).
|
|
# Uses sed range addressing, so it captures ALL matching blocks across
|
|
# the entire file (e.g., all docker-build-push blocks across workflows).
|
|
# --------------------------------------------------------------------------
|
|
run_context_test() {
|
|
local name="$1"
|
|
local fixture="$2"
|
|
local start_pattern="$3"
|
|
local end_pattern="$4"
|
|
local expected_pattern="$5"
|
|
|
|
echo -n " TEST: ${name}... "
|
|
|
|
local output
|
|
output=$(render_fixture "${fixture}") || {
|
|
echo "FAIL (script error)"
|
|
FAIL=$((FAIL + 1))
|
|
return
|
|
}
|
|
|
|
# Use awk index() for string matching to avoid regex delimiter issues with slashes
|
|
local block
|
|
block=$(echo "${output}" | awk -v s="${start_pattern}" -v e="${end_pattern}" \
|
|
'index($0,s){f=1} f{print} f&&index($0,e){f=0}')
|
|
|
|
if [[ -z "${block}" ]]; then
|
|
echo "FAIL (context block '${start_pattern}' not found)"
|
|
FAIL=$((FAIL + 1))
|
|
return
|
|
fi
|
|
|
|
if grep -q "${expected_pattern}" <<< "${block}"; then
|
|
echo "PASS"
|
|
PASS=$((PASS + 1))
|
|
else
|
|
echo "FAIL (expected '${expected_pattern}' within block)"
|
|
FAIL=$((FAIL + 1))
|
|
fi
|
|
}
|
|
|
|
# --------------------------------------------------------------------------
|
|
# Helper: assert a pattern does NOT appear within a YAML block bounded by
|
|
# start_pattern and end_pattern. Captures ALL matching blocks across the
|
|
# file, so the pattern must be absent from every occurrence.
|
|
# --------------------------------------------------------------------------
|
|
run_negative_context_test() {
|
|
local name="$1"
|
|
local fixture="$2"
|
|
local start_pattern="$3"
|
|
local end_pattern="$4"
|
|
local forbidden_pattern="$5"
|
|
|
|
echo -n " TEST: ${name}... "
|
|
|
|
local output
|
|
output=$(render_fixture "${fixture}") || {
|
|
echo "FAIL (script error)"
|
|
FAIL=$((FAIL + 1))
|
|
return
|
|
}
|
|
|
|
local block
|
|
block=$(echo "${output}" | awk -v s="${start_pattern}" -v e="${end_pattern}" \
|
|
'index($0,s){f=1} f{print} f&&index($0,e){f=0}')
|
|
|
|
if [[ -z "${block}" ]]; then
|
|
echo "PASS (context block not found, pattern cannot exist)"
|
|
PASS=$((PASS + 1))
|
|
return
|
|
fi
|
|
|
|
if grep -q "${forbidden_pattern}" <<< "${block}"; then
|
|
echo "FAIL (found forbidden '${forbidden_pattern}' within block)"
|
|
FAIL=$((FAIL + 1))
|
|
else
|
|
echo "PASS"
|
|
PASS=$((PASS + 1))
|
|
fi
|
|
}
|
|
|
|
echo "=== Template Rendering Tests ==="
|
|
|
|
# Container scans belong only to PR jobs; RC already builds and scans before release.
|
|
for module in java-webapp gradle-webapp node-api node-webapp; do
|
|
fixture="${FIXTURES_DIR}/${module}.munitor.yml"
|
|
run_context_test "${module}: PR builds and scans the image" \
|
|
"${fixture}" "pr-checks:" " develop:" 'munitor/docker_scan:'
|
|
run_context_test "${module}: image scan is named image-scan" \
|
|
"${fixture}" "munitor/docker_scan:" "munitor/secrets_scan:" 'name: image-scan'
|
|
run_context_test "${module}: image scan waits for build-and-test" \
|
|
"${fixture}" "munitor/docker_scan:" "munitor/secrets_scan:" '\- build-and-test'
|
|
run_negative_context_test "${module}: no duplicate scan outside PR workflow" \
|
|
"${fixture}" " develop:" "END_OF_CONFIG" 'munitor/docker_scan:'
|
|
run_context_test "${module}: RC already builds and scans" \
|
|
"${fixture}" "release-candidate:" "production:" 'munitor/docker_build_push:'
|
|
|
|
echo -n " TEST: ${module}: every image scan has exactly the PR branch filters... "
|
|
output=$(render_fixture "${fixture}")
|
|
filters=$(yq -o=json -I=0 '[.workflows[].jobs[] | select(has("munitor/docker_scan")) | ."munitor/docker_scan".filters.branches.only]' <<< "${output}")
|
|
if [[ "${filters}" == '[["/feature\\/.*/","/hotfix\\/.*/"]]' ]]; then
|
|
echo "PASS"
|
|
PASS=$((PASS + 1))
|
|
else
|
|
echo "FAIL (unexpected scan filters: ${filters})"
|
|
FAIL=$((FAIL + 1))
|
|
fi
|
|
done
|
|
|
|
run_context_test "supplemental images are wired into the PR image scan" \
|
|
"${FIXTURES_DIR}/java-webapp-supplemental.munitor.yml" \
|
|
"munitor/docker_scan:" "munitor/secrets_scan:" 'supplemental_images:.*migrations'
|
|
|
|
# Test java-webapp renders with correct values
|
|
run_test "java-webapp: renders image_name" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"me-health-portal"
|
|
|
|
run_test "java-webapp: renders java_version" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"java_version: \"21\""
|
|
|
|
run_test "java-webapp: includes e2e when enabled" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"e2e-tests"
|
|
|
|
run_test "java-webapp: includes sonar when project_key set" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"sonar-scan"
|
|
|
|
run_test "java-webapp: includes sbom when enabled" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"sbom"
|
|
|
|
run_test "java-webapp: uses mvn sbom (not node_sbom)" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"munitor/sbom"
|
|
|
|
run_negative_test "java-webapp: does not use node_sbom" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"munitor/node_sbom"
|
|
|
|
# Java-webapp sonar should still gate docker-build-push (regression guard)
|
|
run_context_test "java-webapp: sonar-scan blocks docker-build-push" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"name: docker-build-push" \
|
|
"context:" \
|
|
"sonar-scan"
|
|
|
|
# Test java-webapp-minimal: e2e/sbom/sonar should be excluded
|
|
run_test "java-webapp-minimal: renders java 17" \
|
|
"${FIXTURES_DIR}/java-webapp-minimal.munitor.yml" \
|
|
"java_version: \"17\""
|
|
|
|
run_test "java-webapp-minimal: has build-and-test" \
|
|
"${FIXTURES_DIR}/java-webapp-minimal.munitor.yml" \
|
|
"build-and-test"
|
|
|
|
run_negative_test "java-webapp-minimal: no e2e block" \
|
|
"${FIXTURES_DIR}/java-webapp-minimal.munitor.yml" \
|
|
"e2e-tests"
|
|
|
|
run_negative_test "java-webapp-minimal: no sbom block" \
|
|
"${FIXTURES_DIR}/java-webapp-minimal.munitor.yml" \
|
|
"sbom"
|
|
|
|
run_negative_test "java-webapp-minimal: no sonar block" \
|
|
"${FIXTURES_DIR}/java-webapp-minimal.munitor.yml" \
|
|
"sonar-scan"
|
|
|
|
# Test node-api renders with correct values
|
|
run_test "node-api: renders image_name" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"mes-assembly-server"
|
|
|
|
run_test "node-api: renders node_version" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"node_version: \"20\""
|
|
|
|
run_test "node-api: includes e2e when enabled" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"e2e-tests"
|
|
|
|
run_test "node-api: includes sonar when project_key set" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"sonar-scan"
|
|
|
|
run_test "node-api: uses node_sonar_scan (not mvn sonar_scan)" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"munitor/node_sonar_scan"
|
|
|
|
run_test "node-api: includes sbom when enabled" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"sbom"
|
|
|
|
run_test "node-api: uses node_sbom (not mvn sbom)" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"munitor/node_sbom"
|
|
|
|
run_negative_test "node-api: does not use mvn sbom job" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"munitor/sbom:"
|
|
|
|
# Verify the node_sbom block includes the node_version parameter
|
|
run_context_test "node-api: node_sbom passes node_version" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"munitor/node_sbom" \
|
|
"requires:" \
|
|
"node_version:"
|
|
|
|
# Sonar non-blocking: sonar-scan should NOT be in docker-build-push requires
|
|
run_negative_context_test "node-api: sonar-scan not in docker-build-push requires" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"name: docker-build-push" \
|
|
"context:" \
|
|
"sonar-scan"
|
|
|
|
# Sonar job still exists in the workflow (just not blocking docker)
|
|
run_test "node-api: sonar-scan job still present in workflow" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"name: sonar-scan"
|
|
|
|
run_test "node-api: uses node jobs" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"node_build_and_test"
|
|
|
|
run_test "node-api: includes node code quality" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"node_code_quality"
|
|
|
|
run_test "node-api: includes node security scan" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"node_security_scan"
|
|
|
|
# Test node-api-minimal: e2e/sbom/sonar/extended features should be excluded
|
|
run_test "node-api-minimal: renders node 22" \
|
|
"${FIXTURES_DIR}/node-api-minimal.munitor.yml" \
|
|
"node_version: \"22\""
|
|
|
|
run_test "node-api-minimal: has build-and-test" \
|
|
"${FIXTURES_DIR}/node-api-minimal.munitor.yml" \
|
|
"build-and-test"
|
|
|
|
run_negative_test "node-api-minimal: no e2e block" \
|
|
"${FIXTURES_DIR}/node-api-minimal.munitor.yml" \
|
|
"e2e-tests"
|
|
|
|
run_negative_test "node-api-minimal: no sbom block" \
|
|
"${FIXTURES_DIR}/node-api-minimal.munitor.yml" \
|
|
"sbom"
|
|
|
|
run_negative_test "node-api-minimal: no sonar block" \
|
|
"${FIXTURES_DIR}/node-api-minimal.munitor.yml" \
|
|
"sonar-scan"
|
|
|
|
run_negative_test "node-api-minimal: no npm_auth block" \
|
|
"${FIXTURES_DIR}/node-api-minimal.munitor.yml" \
|
|
"npm_auth"
|
|
|
|
run_negative_test "node-api-minimal: no services block" \
|
|
"${FIXTURES_DIR}/node-api-minimal.munitor.yml" \
|
|
"services:"
|
|
|
|
run_negative_test "node-api-minimal: no test_setup block" \
|
|
"${FIXTURES_DIR}/node-api-minimal.munitor.yml" \
|
|
"test_setup"
|
|
|
|
run_negative_test "node-api-minimal: no test_commands block" \
|
|
"${FIXTURES_DIR}/node-api-minimal.munitor.yml" \
|
|
"test_commands"
|
|
|
|
run_negative_test "node-api-minimal: no coverage_command block" \
|
|
"${FIXTURES_DIR}/node-api-minimal.munitor.yml" \
|
|
"coverage_command"
|
|
|
|
# Test node-api-services: full-featured fixture with all extensions
|
|
run_test "node-api-services: includes npm_auth when private_registry true" \
|
|
"${FIXTURES_DIR}/node-api-services.munitor.yml" \
|
|
"npm_auth: true"
|
|
|
|
run_test "node-api-services: includes npm_scopes parameter" \
|
|
"${FIXTURES_DIR}/node-api-services.munitor.yml" \
|
|
"npm_scopes:"
|
|
|
|
run_test "node-api-services: includes services parameter" \
|
|
"${FIXTURES_DIR}/node-api-services.munitor.yml" \
|
|
"services:"
|
|
|
|
run_test "node-api-services: includes test_setup parameter" \
|
|
"${FIXTURES_DIR}/node-api-services.munitor.yml" \
|
|
"test_setup:"
|
|
|
|
run_test "node-api-services: includes test_commands parameter" \
|
|
"${FIXTURES_DIR}/node-api-services.munitor.yml" \
|
|
"test_commands:"
|
|
|
|
run_test "node-api-services: includes coverage_tool nyc" \
|
|
"${FIXTURES_DIR}/node-api-services.munitor.yml" \
|
|
"coverage_tool: nyc"
|
|
|
|
run_test "node-api-services: includes coverage_command" \
|
|
"${FIXTURES_DIR}/node-api-services.munitor.yml" \
|
|
"coverage_command:"
|
|
|
|
run_test "node-api-services: coverage min from test.coverage.min_instruction" \
|
|
"${FIXTURES_DIR}/node-api-services.munitor.yml" \
|
|
'min_coverage: "70"'
|
|
|
|
run_test "node-api-services: uses node_sbom for sbom" \
|
|
"${FIXTURES_DIR}/node-api-services.munitor.yml" \
|
|
"munitor/node_sbom"
|
|
|
|
run_negative_test "node-api-services: does not use mvn sbom job" \
|
|
"${FIXTURES_DIR}/node-api-services.munitor.yml" \
|
|
"munitor/sbom:"
|
|
|
|
# Test node-api-partial: custom test commands + NYC but no services/npm_auth/test_setup
|
|
run_test "node-api-partial: includes test_commands" \
|
|
"${FIXTURES_DIR}/node-api-partial.munitor.yml" \
|
|
"test_commands:"
|
|
|
|
run_test "node-api-partial: includes coverage_tool nyc" \
|
|
"${FIXTURES_DIR}/node-api-partial.munitor.yml" \
|
|
"coverage_tool: nyc"
|
|
|
|
run_test "node-api-partial: includes coverage_command" \
|
|
"${FIXTURES_DIR}/node-api-partial.munitor.yml" \
|
|
"coverage_command:"
|
|
|
|
run_test "node-api-partial: coverage min from test.coverage.min_instruction" \
|
|
"${FIXTURES_DIR}/node-api-partial.munitor.yml" \
|
|
'min_coverage: "75"'
|
|
|
|
run_negative_test "node-api-partial: no npm_auth" \
|
|
"${FIXTURES_DIR}/node-api-partial.munitor.yml" \
|
|
"npm_auth"
|
|
|
|
run_negative_test "node-api-partial: no services" \
|
|
"${FIXTURES_DIR}/node-api-partial.munitor.yml" \
|
|
"services:"
|
|
|
|
run_negative_test "node-api-partial: no test_setup" \
|
|
"${FIXTURES_DIR}/node-api-partial.munitor.yml" \
|
|
"test_setup"
|
|
|
|
# Test node-webapp renders with correct values
|
|
run_test "node-webapp: renders image_name" \
|
|
"${FIXTURES_DIR}/node-webapp.munitor.yml" \
|
|
"website-frontend"
|
|
|
|
run_test "node-webapp: renders node_version" \
|
|
"${FIXTURES_DIR}/node-webapp.munitor.yml" \
|
|
"node_version: \"22\""
|
|
|
|
run_test "node-webapp: includes e2e when enabled" \
|
|
"${FIXTURES_DIR}/node-webapp.munitor.yml" \
|
|
"e2e-tests"
|
|
|
|
run_test "node-webapp: includes sonar when project_key set" \
|
|
"${FIXTURES_DIR}/node-webapp.munitor.yml" \
|
|
"sonar-scan"
|
|
|
|
run_test "node-webapp: uses node_sonar_scan (not mvn sonar_scan)" \
|
|
"${FIXTURES_DIR}/node-webapp.munitor.yml" \
|
|
"munitor/node_sonar_scan"
|
|
|
|
run_test "node-webapp: includes sbom when enabled" \
|
|
"${FIXTURES_DIR}/node-webapp.munitor.yml" \
|
|
"sbom"
|
|
|
|
run_test "node-webapp: uses node_sbom (not mvn sbom)" \
|
|
"${FIXTURES_DIR}/node-webapp.munitor.yml" \
|
|
"munitor/node_sbom"
|
|
|
|
run_test "node-webapp: uses node_build_and_test" \
|
|
"${FIXTURES_DIR}/node-webapp.munitor.yml" \
|
|
"node_build_and_test"
|
|
|
|
run_test "node-webapp: includes node code quality" \
|
|
"${FIXTURES_DIR}/node-webapp.munitor.yml" \
|
|
"node_code_quality"
|
|
|
|
run_test "node-webapp: includes node coverage" \
|
|
"${FIXTURES_DIR}/node-webapp.munitor.yml" \
|
|
"node_coverage"
|
|
|
|
run_test "node-webapp: includes node security scan" \
|
|
"${FIXTURES_DIR}/node-webapp.munitor.yml" \
|
|
"node_security_scan"
|
|
|
|
# Sonar non-blocking: sonar-scan should NOT be in docker-build-push requires
|
|
run_negative_context_test "node-webapp: sonar-scan not in docker-build-push requires" \
|
|
"${FIXTURES_DIR}/node-webapp.munitor.yml" \
|
|
"name: docker-build-push" \
|
|
"context:" \
|
|
"sonar-scan"
|
|
|
|
# Health check defaults
|
|
run_context_test "node-webapp: docker-build-push health_port defaults to 3000" \
|
|
"${FIXTURES_DIR}/node-webapp.munitor.yml" \
|
|
"name: docker-build-push" \
|
|
"context:" \
|
|
'health_port: "3000"'
|
|
|
|
run_context_test "node-webapp: docker-build-push includes health_path" \
|
|
"${FIXTURES_DIR}/node-webapp.munitor.yml" \
|
|
"name: docker-build-push" \
|
|
"context:" \
|
|
"health_path: /api/health"
|
|
|
|
run_context_test "node-webapp consolidated: production targets explicit GitOps path" \
|
|
"${FIXTURES_DIR}/node-webapp-consolidated.munitor.yml" \
|
|
"production:" \
|
|
"github-release:" \
|
|
"cd_path: tenants/investinginchester/website/kustomization.yaml"
|
|
|
|
run_negative_context_test "node-webapp consolidated: develop does not update production" \
|
|
"${FIXTURES_DIR}/node-webapp-consolidated.munitor.yml" \
|
|
"develop:" \
|
|
"staging:" \
|
|
"update-cd-repo"
|
|
|
|
run_negative_context_test "node-webapp consolidated: release does not update production" \
|
|
"${FIXTURES_DIR}/node-webapp-consolidated.munitor.yml" \
|
|
"release-candidate:" \
|
|
"production:" \
|
|
"update-cd-repo"
|
|
|
|
# Test node-webapp-minimal: e2e/sbom/sonar should be excluded
|
|
run_test "node-webapp-minimal: renders node 22" \
|
|
"${FIXTURES_DIR}/node-webapp-minimal.munitor.yml" \
|
|
"node_version: \"22\""
|
|
|
|
run_test "node-webapp-minimal: has build-and-test" \
|
|
"${FIXTURES_DIR}/node-webapp-minimal.munitor.yml" \
|
|
"build-and-test"
|
|
|
|
run_negative_test "node-webapp-minimal: no e2e block" \
|
|
"${FIXTURES_DIR}/node-webapp-minimal.munitor.yml" \
|
|
"e2e-tests"
|
|
|
|
run_negative_test "node-webapp-minimal: no sbom block" \
|
|
"${FIXTURES_DIR}/node-webapp-minimal.munitor.yml" \
|
|
"sbom"
|
|
|
|
run_negative_test "node-webapp-minimal: no sonar block" \
|
|
"${FIXTURES_DIR}/node-webapp-minimal.munitor.yml" \
|
|
"sonar-scan"
|
|
|
|
# Test sdk-distribution renders correctly
|
|
run_test "sdk-distribution: renders pipeline type" \
|
|
"${FIXTURES_DIR}/sdk-distribution.munitor.yml" \
|
|
"sdk-release"
|
|
|
|
run_test "sdk-distribution: includes github context" \
|
|
"${FIXTURES_DIR}/sdk-distribution.munitor.yml" \
|
|
"github"
|
|
|
|
# Test java-webapp: staging workflow present
|
|
run_test "java-webapp: includes staging workflow" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"staging:"
|
|
|
|
# Test java-webapp: CD update blocks when cd.repo is set
|
|
run_test "java-webapp: includes update-cd-repo when cd.repo set" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"update-cd-repo"
|
|
|
|
# Test java-webapp-no-cd: no update-cd-repo when cd.repo is missing
|
|
run_negative_test "java-webapp-no-cd: no update-cd-repo without cd.repo" \
|
|
"${FIXTURES_DIR}/java-webapp-no-cd.munitor.yml" \
|
|
"update-cd-repo"
|
|
|
|
# Test node-api: staging workflow present
|
|
run_test "node-api: includes staging workflow" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"staging:"
|
|
|
|
# Test node-api: CD update blocks when cd.repo is set
|
|
run_test "node-api: includes update-cd-repo when cd.repo set" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"update-cd-repo"
|
|
|
|
# Health check tests
|
|
run_context_test "node-api: docker-build-push includes health_path" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"name: docker-build-push" \
|
|
"context:" \
|
|
"health_path: /api/health"
|
|
|
|
run_context_test "node-api: docker-build-push health_port defaults to 3000" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"name: docker-build-push" \
|
|
"context:" \
|
|
'health_port: "3000"'
|
|
|
|
run_context_test "java-webapp: docker-build-push health_port defaults to 8080" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"name: docker-build-push" \
|
|
"context:" \
|
|
'health_port: "8080"'
|
|
|
|
run_context_test "node-api-services: custom health config overrides defaults" \
|
|
"${FIXTURES_DIR}/node-api-services.munitor.yml" \
|
|
"name: docker-build-push" \
|
|
"context:" \
|
|
"health_path: /health"
|
|
|
|
run_context_test "node-api-services: custom health_port overrides default" \
|
|
"${FIXTURES_DIR}/node-api-services.munitor.yml" \
|
|
"name: docker-build-push" \
|
|
"context:" \
|
|
'health_port: "4000"'
|
|
|
|
# Test java-webapp-portal: custom health, coverage, port settings
|
|
run_context_test "java-webapp-portal: health_port set to 8000" \
|
|
"${FIXTURES_DIR}/java-webapp-portal.munitor.yml" \
|
|
"name: docker-build-push" \
|
|
"context:" \
|
|
'health_port: "8000"'
|
|
|
|
run_context_test "java-webapp-portal: health_path set to /qqq-api/health" \
|
|
"${FIXTURES_DIR}/java-webapp-portal.munitor.yml" \
|
|
"name: docker-build-push" \
|
|
"context:" \
|
|
"health_path: /qqq-api/health"
|
|
|
|
run_test "java-webapp-portal: coverage set to 45" \
|
|
"${FIXTURES_DIR}/java-webapp-portal.munitor.yml" \
|
|
'min_instruction: "45"'
|
|
|
|
run_test "java-webapp-portal: includes e2e when enabled" \
|
|
"${FIXTURES_DIR}/java-webapp-portal.munitor.yml" \
|
|
"e2e-tests"
|
|
|
|
run_test "java-webapp-portal: includes sbom when enabled" \
|
|
"${FIXTURES_DIR}/java-webapp-portal.munitor.yml" \
|
|
"sbom"
|
|
|
|
# Test SAST fail_on_findings rendering
|
|
run_context_test "java-webapp-sast-warn: sast_scan has fail_on_findings false" \
|
|
"${FIXTURES_DIR}/java-webapp-sast-warn.munitor.yml" \
|
|
"name: sast-scan" \
|
|
"filters:" \
|
|
'fail_on_findings: "false"'
|
|
|
|
run_context_test "java-webapp: sast_scan has fail_on_findings true" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"name: sast-scan" \
|
|
"filters:" \
|
|
'fail_on_findings: "true"'
|
|
|
|
# Test terraform-sast: sast_scan has fail_on_findings true (boolean sast: true)
|
|
run_context_test "terraform-sast: sast_scan has fail_on_findings true" \
|
|
"${FIXTURES_DIR}/terraform-sast.munitor.yml" \
|
|
"name: sast-scan" \
|
|
"filters:" \
|
|
'fail_on_findings: "true"'
|
|
|
|
# --------------------------------------------------------------------------
|
|
# Release-candidate / Production workflow split tests
|
|
# --------------------------------------------------------------------------
|
|
echo ""
|
|
echo "=== Release-Candidate / Production Workflow Tests ==="
|
|
|
|
# java-webapp: has release-candidate and production workflows (not release)
|
|
run_test "java-webapp: has release-candidate workflow" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"release-candidate:"
|
|
|
|
run_test "java-webapp: has production workflow" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"production:"
|
|
|
|
run_negative_test "java-webapp: no legacy release workflow" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"^ release:"
|
|
|
|
# java-webapp: production workflow has NO quality gates
|
|
run_negative_context_test "java-webapp: production has no code-quality" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"production:" \
|
|
"release-candidate:" \
|
|
"code-quality"
|
|
|
|
run_negative_context_test "java-webapp: production has no coverage" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"production:" \
|
|
"release-candidate:" \
|
|
"mvn_coverage"
|
|
|
|
run_negative_context_test "java-webapp: production has no security-scan" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"production:" \
|
|
"release-candidate:" \
|
|
"security_scan"
|
|
|
|
# java-webapp: release-candidate has quality gates
|
|
run_context_test "java-webapp: release-candidate enables quality checks" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"release-candidate:" \
|
|
"production:" \
|
|
"quality_checks: true"
|
|
|
|
run_context_test "java-webapp: release-candidate forwards coverage threshold" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"release-candidate:" \
|
|
"production:" \
|
|
'min_instruction: "80"'
|
|
|
|
run_context_test "java-webapp: release-candidate has security-scan" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"release-candidate:" \
|
|
"production:" \
|
|
"security_scan"
|
|
|
|
# java-webapp: both workflows have github-release
|
|
run_context_test "java-webapp: release-candidate has github-release" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"release-candidate:" \
|
|
"production:" \
|
|
"github-release"
|
|
|
|
run_context_test "java-webapp: production has github-release" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"production:" \
|
|
"Results:" \
|
|
"github-release"
|
|
|
|
# java-webapp: CD environments are correct
|
|
run_context_test "java-webapp: production CD uses prod env" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"production:" \
|
|
"Results:" \
|
|
"environment: prod"
|
|
|
|
run_context_test "java-webapp: release-candidate CD uses staging env" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"release-candidate:" \
|
|
"production:" \
|
|
"environment: staging"
|
|
|
|
# node-api: has release-candidate and production workflows
|
|
run_test "node-api: has release-candidate workflow" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"release-candidate:"
|
|
|
|
run_test "node-api: has production workflow" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"production:"
|
|
|
|
run_negative_test "node-api: no legacy release workflow" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"^ release:"
|
|
|
|
# node-api: production has no quality gates
|
|
run_negative_context_test "node-api: production has no code-quality" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"production:" \
|
|
"release-candidate:" \
|
|
"code-quality"
|
|
|
|
run_negative_context_test "node-api: production has no coverage" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"production:" \
|
|
"release-candidate:" \
|
|
"node_coverage"
|
|
|
|
run_negative_context_test "node-api: production has no security-scan" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"production:" \
|
|
"release-candidate:" \
|
|
"node_security_scan"
|
|
|
|
# node-api: release-candidate has quality gates
|
|
run_context_test "node-api: release-candidate has code-quality" \
|
|
"${FIXTURES_DIR}/node-api.munitor.yml" \
|
|
"release-candidate:" \
|
|
"production:" \
|
|
"code-quality"
|
|
|
|
# node-webapp: has release-candidate and production workflows
|
|
run_test "node-webapp: has release-candidate workflow" \
|
|
"${FIXTURES_DIR}/node-webapp.munitor.yml" \
|
|
"release-candidate:"
|
|
|
|
run_test "node-webapp: has production workflow" \
|
|
"${FIXTURES_DIR}/node-webapp.munitor.yml" \
|
|
"production:"
|
|
|
|
run_negative_test "node-webapp: no legacy release workflow" \
|
|
"${FIXTURES_DIR}/node-webapp.munitor.yml" \
|
|
"^ release:"
|
|
|
|
# node-webapp: production has no quality gates
|
|
run_negative_context_test "node-webapp: production has no code-quality" \
|
|
"${FIXTURES_DIR}/node-webapp.munitor.yml" \
|
|
"production:" \
|
|
"release-candidate:" \
|
|
"code-quality"
|
|
|
|
run_negative_context_test "node-webapp: production has no coverage" \
|
|
"${FIXTURES_DIR}/node-webapp.munitor.yml" \
|
|
"production:" \
|
|
"release-candidate:" \
|
|
"node_coverage"
|
|
|
|
run_negative_context_test "node-webapp: production has no security-scan" \
|
|
"${FIXTURES_DIR}/node-webapp.munitor.yml" \
|
|
"production:" \
|
|
"release-candidate:" \
|
|
"node_security_scan"
|
|
|
|
# node-webapp: release-candidate has quality gates
|
|
run_context_test "node-webapp: release-candidate has code-quality" \
|
|
"${FIXTURES_DIR}/node-webapp.munitor.yml" \
|
|
"release-candidate:" \
|
|
"production:" \
|
|
"code-quality"
|
|
|
|
# node-webapp: staging workflow present
|
|
run_test "node-webapp: includes staging workflow" \
|
|
"${FIXTURES_DIR}/node-webapp.munitor.yml" \
|
|
"staging:"
|
|
|
|
# node-webapp: CD update blocks when cd.repo is set
|
|
run_test "node-webapp: includes update-cd-repo when cd.repo set" \
|
|
"${FIXTURES_DIR}/node-webapp.munitor.yml" \
|
|
"update-cd-repo"
|
|
|
|
# ============================================================
|
|
# pnpm node-webapp
|
|
# ============================================================
|
|
echo ""
|
|
echo "=== pnpm node-webapp tests ==="
|
|
|
|
run_test "pnpm-webapp: uses node_build_and_test" \
|
|
"${FIXTURES_DIR}/pnpm-webapp.munitor.yml" \
|
|
"node_build_and_test"
|
|
|
|
run_test "pnpm-webapp: passes package_manager param" \
|
|
"${FIXTURES_DIR}/pnpm-webapp.munitor.yml" \
|
|
'package_manager: "pnpm"'
|
|
|
|
run_negative_test "pnpm-webapp: does not reference npm_build_and_test" \
|
|
"${FIXTURES_DIR}/pnpm-webapp.munitor.yml" \
|
|
"npm_build_and_test"
|
|
|
|
# terraform: has release-candidate and production workflows
|
|
run_test "terraform: has release-candidate workflow" \
|
|
"${FIXTURES_DIR}/terraform.munitor.yml" \
|
|
"release-candidate:"
|
|
|
|
run_test "terraform: has production workflow" \
|
|
"${FIXTURES_DIR}/terraform.munitor.yml" \
|
|
"production:"
|
|
|
|
run_negative_test "terraform: no legacy release workflow" \
|
|
"${FIXTURES_DIR}/terraform.munitor.yml" \
|
|
"^ release:"
|
|
|
|
# terraform: production has only validate-repo and tf-validate
|
|
run_negative_context_test "terraform: production has no tf-security-scan" \
|
|
"${FIXTURES_DIR}/terraform.munitor.yml" \
|
|
"production:" \
|
|
"Results:" \
|
|
"tf-security-scan"
|
|
|
|
run_negative_context_test "terraform: production has no secrets-scan" \
|
|
"${FIXTURES_DIR}/terraform.munitor.yml" \
|
|
"production:" \
|
|
"Results:" \
|
|
"secrets-scan"
|
|
|
|
# terraform: release-candidate has full validation
|
|
run_context_test "terraform: release-candidate has tf-security-scan" \
|
|
"${FIXTURES_DIR}/terraform.munitor.yml" \
|
|
"release-candidate:" \
|
|
"production:" \
|
|
"tf-security-scan"
|
|
|
|
run_context_test "terraform: release-candidate has secrets-scan" \
|
|
"${FIXTURES_DIR}/terraform.munitor.yml" \
|
|
"release-candidate:" \
|
|
"production:" \
|
|
"secrets-scan"
|
|
|
|
# --------------------------------------------------------------------------
|
|
# validate-cd-repo Template Tests
|
|
# --------------------------------------------------------------------------
|
|
echo ""
|
|
echo "=== validate-cd-repo Template Tests ==="
|
|
|
|
# Basic rendering
|
|
run_test "validate-cd-repo: renders orb version" \
|
|
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
|
"kof22/munitor@dev:snapshot"
|
|
|
|
# Workflow presence
|
|
run_test "validate-cd-repo: has pr-checks workflow" \
|
|
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
|
"pr-checks:"
|
|
|
|
run_test "validate-cd-repo: has develop workflow" \
|
|
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
|
"develop:"
|
|
|
|
run_test "validate-cd-repo: has release workflow" \
|
|
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
|
"release:"
|
|
|
|
# Job presence
|
|
run_test "validate-cd-repo: has yaml-lint job" \
|
|
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
|
"name: yaml-lint"
|
|
|
|
run_test "validate-cd-repo: has kustomize-validate job" \
|
|
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
|
"name: kustomize-validate"
|
|
|
|
run_test "validate-cd-repo: has kubesec-scan job" \
|
|
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
|
"name: kubesec-scan"
|
|
|
|
run_test "validate-cd-repo: has kube-linter job" \
|
|
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
|
"name: kube-linter"
|
|
|
|
run_test "validate-cd-repo: has secrets-scan job" \
|
|
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
|
"name: secrets-scan"
|
|
|
|
# Job dependencies
|
|
run_context_test "validate-cd-repo: kubesec-scan requires kustomize-validate" \
|
|
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
|
"name: kubesec-scan" \
|
|
"filters:" \
|
|
"kustomize-validate"
|
|
|
|
run_context_test "validate-cd-repo: kube-linter requires kustomize-validate" \
|
|
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
|
"name: kube-linter" \
|
|
"filters:" \
|
|
"kustomize-validate"
|
|
|
|
# Version rendering
|
|
run_test "validate-cd-repo: renders kustomize version" \
|
|
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
|
'kustomize_version: "5.5.0"'
|
|
|
|
run_test "validate-cd-repo: renders overlays" \
|
|
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
|
"overlays: \"dev staging production\""
|
|
|
|
run_test "validate-cd-repo: renders scan_overlay" \
|
|
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
|
'scan_overlay: "production"'
|
|
|
|
run_test "validate-cd-repo: renders kube_linter config" \
|
|
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
|
"config: \".kube-linter.yaml\""
|
|
|
|
# Branch filters
|
|
run_context_test "validate-cd-repo: pr-checks has feature branch filter" \
|
|
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
|
"pr-checks:" \
|
|
"develop:" \
|
|
"feature"
|
|
|
|
run_context_test "validate-cd-repo: develop has develop branch filter" \
|
|
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
|
"develop:" \
|
|
"release:" \
|
|
"only: develop"
|
|
|
|
run_context_test "validate-cd-repo: release has main branch filter" \
|
|
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
|
"release:" \
|
|
"Results:" \
|
|
"only: main"
|
|
|
|
# Negative tests: no app-pipeline artifacts
|
|
run_negative_test "validate-cd-repo: no docker job" \
|
|
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
|
"docker-build-push"
|
|
|
|
run_negative_test "validate-cd-repo: no build-and-test job" \
|
|
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
|
"build-and-test"
|
|
|
|
run_negative_test "validate-cd-repo: no update-cd-repo job" \
|
|
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
|
"update-cd-repo"
|
|
|
|
run_negative_test "validate-cd-repo: no github-release job" \
|
|
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
|
"github-release"
|
|
|
|
# Minimal fixture tests (defaults)
|
|
run_test "validate-cd-repo-minimal: renders correctly" \
|
|
"${FIXTURES_DIR}/validate-cd-repo-minimal.munitor.yml" \
|
|
"kof22/munitor@dev:snapshot"
|
|
|
|
run_test "validate-cd-repo-minimal: has all three workflows" \
|
|
"${FIXTURES_DIR}/validate-cd-repo-minimal.munitor.yml" \
|
|
"pr-checks:"
|
|
|
|
run_test "validate-cd-repo-minimal: default kustomize version" \
|
|
"${FIXTURES_DIR}/validate-cd-repo-minimal.munitor.yml" \
|
|
'kustomize_version: "5.5.0"'
|
|
|
|
run_test "validate-cd-repo-minimal: default scan_overlay" \
|
|
"${FIXTURES_DIR}/validate-cd-repo-minimal.munitor.yml" \
|
|
'scan_overlay: "production"'
|
|
|
|
run_test "validate-cd-repo-minimal: default base_path" \
|
|
"${FIXTURES_DIR}/validate-cd-repo-minimal.munitor.yml" \
|
|
'base_path: "base/"'
|
|
|
|
# --------------------------------------------------------------------------
|
|
# argocd-apps Template Tests
|
|
# --------------------------------------------------------------------------
|
|
echo ""
|
|
echo "=== argocd-apps Template Tests ==="
|
|
|
|
# Basic rendering
|
|
run_test "argocd-apps: renders orb version" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
"kof22/munitor@dev:snapshot"
|
|
|
|
# Workflow presence
|
|
run_test "argocd-apps: has pr-checks workflow" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
"pr-checks:"
|
|
|
|
run_test "argocd-apps: has develop workflow" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
"develop:"
|
|
|
|
run_test "argocd-apps: has release workflow" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
"release:"
|
|
|
|
# Job presence
|
|
run_test "argocd-apps: has yaml-lint job" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
"name: yaml-lint"
|
|
|
|
run_test "argocd-apps: has kustomize-validate job" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
"name: kustomize-validate"
|
|
|
|
run_test "argocd-apps: has kubesec-scan job" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
"name: kubesec-scan"
|
|
|
|
run_test "argocd-apps: has kube-linter job" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
"name: kube-linter"
|
|
|
|
run_test "argocd-apps: has secrets-scan job" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
"name: secrets-scan"
|
|
|
|
# overlay_dir rendering
|
|
run_test "argocd-apps: renders overlay_dir as envs" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
'overlay_dir: "envs"'
|
|
|
|
# base_path rendering (empty string)
|
|
run_test "argocd-apps: renders empty base_path" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
'base_path: ""'
|
|
|
|
# yamllint_paths rendering
|
|
run_test "argocd-apps: renders argocd-apps yamllint paths" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
"bootstrap/ projects/ credentials/ envs/ apps/ infra/"
|
|
|
|
# Version rendering
|
|
run_test "argocd-apps: renders kustomize version" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
'kustomize_version: "5.5.0"'
|
|
|
|
run_test "argocd-apps: renders overlays" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
"overlays: \"dev staging production\""
|
|
|
|
run_test "argocd-apps: renders scan_overlay" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
'scan_overlay: "production"'
|
|
|
|
run_test "argocd-apps: renders kube_linter config" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
"config: \".kube-linter.yaml\""
|
|
|
|
# Job dependencies
|
|
run_context_test "argocd-apps: kubesec-scan requires kustomize-validate" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
"name: kubesec-scan" \
|
|
"filters:" \
|
|
"kustomize-validate"
|
|
|
|
run_context_test "argocd-apps: kube-linter requires kustomize-validate" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
"name: kube-linter" \
|
|
"filters:" \
|
|
"kustomize-validate"
|
|
|
|
# Branch filters
|
|
run_context_test "argocd-apps: pr-checks has feature branch filter" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
"pr-checks:" \
|
|
"develop:" \
|
|
"feature"
|
|
|
|
run_context_test "argocd-apps: develop has develop branch filter" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
"develop:" \
|
|
"release:" \
|
|
"only: develop"
|
|
|
|
run_context_test "argocd-apps: release has main branch filter" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
"release:" \
|
|
"Results:" \
|
|
"only: main"
|
|
|
|
# Negative tests: no app-pipeline artifacts
|
|
run_negative_test "argocd-apps: no docker job" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
"docker-build-push"
|
|
|
|
run_negative_test "argocd-apps: no build-and-test job" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
"build-and-test"
|
|
|
|
run_negative_test "argocd-apps: no update-cd-repo job" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
"update-cd-repo"
|
|
|
|
run_negative_test "argocd-apps: no github-release job" \
|
|
"${FIXTURES_DIR}/argocd-apps.munitor.yml" \
|
|
"github-release"
|
|
|
|
# Minimal fixture tests (defaults)
|
|
run_test "argocd-apps-minimal: renders correctly" \
|
|
"${FIXTURES_DIR}/argocd-apps-minimal.munitor.yml" \
|
|
"kof22/munitor@dev:snapshot"
|
|
|
|
run_test "argocd-apps-minimal: has all three workflows" \
|
|
"${FIXTURES_DIR}/argocd-apps-minimal.munitor.yml" \
|
|
"pr-checks:"
|
|
|
|
run_test "argocd-apps-minimal: default kustomize version" \
|
|
"${FIXTURES_DIR}/argocd-apps-minimal.munitor.yml" \
|
|
'kustomize_version: "5.5.0"'
|
|
|
|
run_test "argocd-apps-minimal: default scan_overlay" \
|
|
"${FIXTURES_DIR}/argocd-apps-minimal.munitor.yml" \
|
|
'scan_overlay: "production"'
|
|
|
|
run_test "argocd-apps-minimal: default overlay_dir" \
|
|
"${FIXTURES_DIR}/argocd-apps-minimal.munitor.yml" \
|
|
'overlay_dir: "overlays"'
|
|
|
|
run_test "argocd-apps-minimal: default base_path" \
|
|
"${FIXTURES_DIR}/argocd-apps-minimal.munitor.yml" \
|
|
'base_path: "base/"'
|
|
|
|
# Regression: validate-cd-repo does NOT have overlay_dir param
|
|
run_negative_test "validate-cd-repo: no overlay_dir param (regression)" \
|
|
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
|
"overlay_dir:"
|
|
|
|
# --------------------------------------------------------------------------
|
|
# Supplemental Images Tests
|
|
# --------------------------------------------------------------------------
|
|
echo ""
|
|
echo "=== Supplemental Images Template Tests ==="
|
|
|
|
# java-webapp-supplemental: supplemental_images parameter appears in docker-build-push
|
|
run_context_test "java-webapp-supplemental: docker-build-push has supplemental_images param" \
|
|
"${FIXTURES_DIR}/java-webapp-supplemental.munitor.yml" \
|
|
"name: docker-build-push" \
|
|
"context:" \
|
|
"supplemental_images:"
|
|
|
|
# java-webapp-supplemental: supplemental_images parameter appears in update-cd-repo
|
|
run_context_test "java-webapp-supplemental: update-cd-repo has supplemental_images param" \
|
|
"${FIXTURES_DIR}/java-webapp-supplemental.munitor.yml" \
|
|
"name: update-cd-repo" \
|
|
"context:" \
|
|
"supplemental_images:"
|
|
|
|
# java-webapp (no supplemental): supplemental_images should NOT appear
|
|
run_negative_test "java-webapp: no supplemental_images param when not configured" \
|
|
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
|
"supplemental_images:"
|
|
|
|
# java-webapp-minimal: supplemental_images should NOT appear
|
|
run_negative_test "java-webapp-minimal: no supplemental_images param" \
|
|
"${FIXTURES_DIR}/java-webapp-minimal.munitor.yml" \
|
|
"supplemental_images:"
|
|
|
|
# java-webapp-supplemental: still has all normal features (regression)
|
|
run_test "java-webapp-supplemental: still has e2e" \
|
|
"${FIXTURES_DIR}/java-webapp-supplemental.munitor.yml" \
|
|
"e2e-tests"
|
|
|
|
run_test "java-webapp-supplemental: still has sonar" \
|
|
"${FIXTURES_DIR}/java-webapp-supplemental.munitor.yml" \
|
|
"sonar-scan"
|
|
|
|
run_test "java-webapp-supplemental: still has update-cd-repo" \
|
|
"${FIXTURES_DIR}/java-webapp-supplemental.munitor.yml" \
|
|
"update-cd-repo"
|
|
|
|
run_test "java-webapp-supplemental: has release-candidate workflow" \
|
|
"${FIXTURES_DIR}/java-webapp-supplemental.munitor.yml" \
|
|
"release-candidate:"
|
|
|
|
run_test "java-webapp-supplemental: has production workflow" \
|
|
"${FIXTURES_DIR}/java-webapp-supplemental.munitor.yml" \
|
|
"production:"
|
|
|
|
# ==========================================================================
|
|
# gradle-webapp template rendering
|
|
# ==========================================================================
|
|
echo ""
|
|
echo "=== gradle-webapp Template Rendering Tests ==="
|
|
|
|
run_test "gradle-webapp: renders image_name" \
|
|
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
|
"concilium"
|
|
|
|
run_test "gradle-webapp: renders java_version" \
|
|
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
|
"java_version: \"21\""
|
|
|
|
run_test "gradle-webapp: uses gradle_build_and_test job" \
|
|
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
|
"munitor/gradle_build_and_test"
|
|
|
|
run_test "gradle-webapp: uses gradle_code_quality job" \
|
|
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
|
"munitor/gradle_code_quality"
|
|
|
|
run_test "gradle-webapp: uses gradle_coverage job" \
|
|
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
|
"munitor/gradle_coverage"
|
|
|
|
run_negative_test "gradle-webapp: does not use mvn_build_and_test" \
|
|
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
|
"munitor/mvn_build_and_test"
|
|
|
|
run_negative_test "gradle-webapp: does not use mvn_code_quality" \
|
|
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
|
"munitor/mvn_code_quality"
|
|
|
|
run_negative_test "gradle-webapp: does not use mvn_coverage" \
|
|
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
|
"munitor/mvn_coverage"
|
|
|
|
run_test "gradle-webapp: includes sast-scan" \
|
|
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
|
"sast-scan"
|
|
|
|
run_test "gradle-webapp: includes sbom when enabled" \
|
|
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
|
"sbom"
|
|
|
|
run_test "gradle-webapp: owasp disabled when false" \
|
|
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
|
"owasp: false"
|
|
|
|
run_test "gradle-webapp: has cd repo update" \
|
|
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
|
"update-cd-repo"
|
|
|
|
run_test "gradle-webapp: has release-candidate workflow" \
|
|
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
|
"release-candidate:"
|
|
|
|
run_test "gradle-webapp: has production workflow" \
|
|
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
|
"production:"
|
|
|
|
run_test "gradle-webapp: has pr-checks workflow" \
|
|
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
|
"pr-checks:"
|
|
|
|
run_test "gradle-webapp: coverage min is 50" \
|
|
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
|
'min_instruction: "50"'
|
|
|
|
run_test "gradle-webapp: health_port is 8000" \
|
|
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
|
'health_port: "8000"'
|
|
|
|
run_negative_test "gradle-webapp: no e2e block (e2e not enabled)" \
|
|
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
|
"e2e-tests"
|
|
|
|
run_negative_test "gradle-webapp: no sonar block (sonar not configured)" \
|
|
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
|
"sonar-scan"
|
|
|
|
# ============================================================
|
|
# obsidian-plugin template rendering
|
|
# ============================================================
|
|
echo ""
|
|
echo "=== obsidian-plugin Template Rendering Tests ==="
|
|
|
|
# Basic rendering
|
|
run_test "obsidian-plugin: renders node_version" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"node_version: \"20\""
|
|
|
|
run_test "obsidian-plugin: uses node_build_and_test" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"node_build_and_test"
|
|
|
|
run_test "obsidian-plugin: includes node code quality" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"node_code_quality"
|
|
|
|
run_test "obsidian-plugin: includes node coverage" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"node_coverage"
|
|
|
|
run_test "obsidian-plugin: includes node security scan" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"node_security_scan"
|
|
|
|
run_test "obsidian-plugin: includes sast-scan" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"sast-scan"
|
|
|
|
run_test "obsidian-plugin: includes secrets-scan" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"secrets-scan"
|
|
|
|
run_test "obsidian-plugin: includes sbom when enabled" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"sbom"
|
|
|
|
run_test "obsidian-plugin: includes test_commands" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"test_commands:"
|
|
|
|
run_test "obsidian-plugin: includes coverage_command" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"coverage_command:"
|
|
|
|
run_test "obsidian-plugin: includes coverage_tool vitest" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"coverage_tool: vitest"
|
|
|
|
# Workflow presence
|
|
run_test "obsidian-plugin: has pr-checks workflow" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"pr-checks:"
|
|
|
|
run_test "obsidian-plugin: has develop workflow" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"develop:"
|
|
|
|
run_test "obsidian-plugin: has release-candidate workflow" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"release-candidate:"
|
|
|
|
run_test "obsidian-plugin: has production workflow" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"production:"
|
|
|
|
# GitHub Release with artifacts
|
|
run_test "obsidian-plugin: has github-release job" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"github-release"
|
|
|
|
run_test "obsidian-plugin: github-release has release_artifacts" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"release_artifacts:"
|
|
|
|
run_test "obsidian-plugin: release_artifacts includes main.js" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"main.js manifest.json styles.css"
|
|
|
|
# Release-candidate has quality gates
|
|
run_context_test "obsidian-plugin: release-candidate has code-quality" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"release-candidate:" \
|
|
"production:" \
|
|
"code-quality"
|
|
|
|
run_context_test "obsidian-plugin: release-candidate has coverage" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"release-candidate:" \
|
|
"production:" \
|
|
"node_coverage"
|
|
|
|
run_context_test "obsidian-plugin: release-candidate has security-scan" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"release-candidate:" \
|
|
"production:" \
|
|
"node_security_scan"
|
|
|
|
# Production has NO quality gates (fast-path)
|
|
run_negative_context_test "obsidian-plugin: production has no code-quality" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"production:" \
|
|
"release-candidate:" \
|
|
"code-quality"
|
|
|
|
run_negative_context_test "obsidian-plugin: production has no coverage" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"production:" \
|
|
"release-candidate:" \
|
|
"node_coverage"
|
|
|
|
run_negative_context_test "obsidian-plugin: production has no security-scan" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"production:" \
|
|
"release-candidate:" \
|
|
"node_security_scan"
|
|
|
|
# Negative tests: no Docker/CD artifacts
|
|
run_negative_test "obsidian-plugin: no docker-build-push" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"docker-build-push"
|
|
|
|
run_negative_test "obsidian-plugin: no update-cd-repo" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"update-cd-repo"
|
|
|
|
run_negative_test "obsidian-plugin: no image_name" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"image_name:"
|
|
|
|
run_negative_test "obsidian-plugin: no registry" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"registry:"
|
|
|
|
run_negative_test "obsidian-plugin: no INCLUDE_DEPLOY" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"INCLUDE_DEPLOY"
|
|
|
|
run_negative_test "obsidian-plugin: no staging workflow" \
|
|
"${FIXTURES_DIR}/obsidian-plugin.munitor.yml" \
|
|
"staging:"
|
|
|
|
echo ""
|
|
echo "=== Results: ${PASS} passed, ${FAIL} failed ==="
|
|
|
|
if [[ ${FAIL} -gt 0 ]]; then
|
|
exit 1
|
|
fi
|