#!/usr/bin/env bash # Unit test for etc/init_cloudnative_pg.sh SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) KNOE_HOME=$(cd "$SCRIPT_DIR/../.." && pwd) ETC_DIR="$KNOE_HOME/etc" SCRIPT_UNDER_TEST="$ETC_DIR/init_cloudnative_pg.sh" TMP_DIR=$(mktemp -d) trap 'rm -rf "$TMP_DIR"' EXIT BIN_DIR="$TMP_DIR/bin" mkdir -p "$BIN_DIR" # Mock tools mock_tool() { cat < "$BIN_DIR/$1" #!/usr/bin/env bash echo "Mocked $1 called with \$@" >> "$TMP_DIR/mock_calls.log" exit 0 M_EOF chmod +x "$BIN_DIR/$1" } # Custom kubectl mock: return minimal outputs so initialize() doesn't hang. cat < "$BIN_DIR/kubectl" #!/usr/bin/env bash _log_file="${TMP_DIR}/mock_calls.log" echo "Mocked kubectl called with \$@" >> "${_log_file}" args="\$*" # API server readiness probes used by wait_for_apiserver_ready() if [[ "${args}" == *"get --raw=/readyz"* || "${args}" == *"get --raw='/readyz'"* || "${args}" == *"get --raw=\"/readyz\""* ]]; then echo "ok" exit 0 fi if [[ "${args}" == *"version --short"* ]]; then echo "Client Version: v0.0.0" echo "Server Version: v0.0.0" exit 0 fi # CNPG webhook wait: return an endpoint IP so wait passes quickly. if [[ "${args}" == *"get endpoints"*"cnpg-webhook-service"* ]]; then echo "10.42.0.10" exit 0 fi # CNPG pods listing (no-headers) used to detect pull errors. if [[ "${args}" == *"get pods"*"--no-headers"*"cnpg.io/cluster="* ]]; then echo "knoe-db-1 1/1 Running 0 1m" echo "knoe-db-2 1/1 Running 0 1m" echo "knoe-db-3 1/1 Running 0 1m" exit 0 fi # Ready pod count (jsonpath) used by wait_for_cnpg_pods. if [[ "${args}" == *"get pods"*"jsonpath="*"Ready"*"True"* || "${args}" == *"get pods"*"jsonpath="*"status.conditions"*"Ready"* ]]; then printf "True\nTrue\nTrue\n" exit 0 fi # Cluster instances; avoid defaulting logic differences. if [[ "${args}" == *"get cluster"*"jsonpath="*".spec.instances"* ]]; then echo "3" exit 0 fi exit 0 K_EOF chmod +x "$BIN_DIR/kubectl" # Create mocks for common tools mock_tool curl mock_tool docker mock_tool k3d mock_tool skopeo mock_tool ansible-playbook mock_tool tofu mock_tool terraform mock_tool ollama mock_tool jq # Mock knoe.cfg (k3s mode, but with a k3d-looking LOCAL_REGISTRY_INTERNAL to reproduce the bug). mkdir -p "$TMP_DIR/conf" cat < "$TMP_DIR/conf/knoe.cfg" [User] NAMESPACE = test-ns SERVICE_NAMESPACE = test-system KNOE_HOME = $KNOE_HOME KNOE_SERVICE = $TMP_DIR/service [Global] DEPLOYMENT_MODE = k3s PROLE_K3S_SERVER = https://myrddin.knoe.org:6443 [Docker Build] LOCAL_REGISTRY = localhost:5000 LOCAL_REGISTRY_INTERNAL = k3d-knoe-registry.localhost:5000 C_EOF mkdir -p "$TMP_DIR/service/secrets" printf '%s' "dummy-private-key" > "$TMP_DIR/service/secrets/admin.key" printf '%s' "dummy-public-key" > "$TMP_DIR/service/secrets/admin.pub" export PATH="$BIN_DIR:$PATH" export KNOE_HOME="$KNOE_HOME" export KNOE_CONF="$TMP_DIR/conf" export PROLE_PASSWD="test-password" export KNOE_SERVICE="$TMP_DIR/service" export CNPG_IMAGE="k3d-knoe-registry:5000/knoe-db:18-140" # Run the script if [[ "init_cloudnative_pg.sh" == *.py ]]; then if [[ "init_cloudnative_pg.sh" == "render_manifest.py" ]]; then echo "apiVersion: v1" > "$TMP_DIR/test.yaml" python3 "$SCRIPT_UNDER_TEST" "$TMP_DIR/test.yaml" > "$TMP_DIR/stdout" 2> "$TMP_DIR/stderr" else python3 "$SCRIPT_UNDER_TEST" --help > "$TMP_DIR/stdout" 2> "$TMP_DIR/stderr" fi RC=$? else # Run a path that triggers image resolution + preflight without long waits. bash "$SCRIPT_UNDER_TEST" --mode k3s preflight-image > "$TMP_DIR/stdout" 2> "$TMP_DIR/stderr" RC=$? fi # Assertions: in k3s mode we must never touch k3d. if grep -q "Mocked k3d called" "$TMP_DIR/mock_calls.log"; then echo "FAILURE: init_cloudnative_pg.sh invoked k3d in k3s mode" sed -n '1,200p' "$TMP_DIR/mock_calls.log" || true exit 1 fi # And we must not produce k3d registry image names. if grep -q "k3d-knoe-registry" "$TMP_DIR/stdout" "$TMP_DIR/stderr" 2>/dev/null; then echo "FAILURE: init_cloudnative_pg.sh used k3d registry prefix in k3s mode" echo "--- stdout ---" sed -n '1,200p' "$TMP_DIR/stdout" || true echo "--- stderr ---" sed -n '1,200p' "$TMP_DIR/stderr" || true exit 1 fi if ! grep -q "myrddin.knoe.org:5000/knoe-db:18-140" "$TMP_DIR/stdout" "$TMP_DIR/stderr" 2>/dev/null; then echo "FAILURE: init_cloudnative_pg.sh did not rewrite CNPG_IMAGE to k3s registry host" echo "--- stdout ---" sed -n '1,200p' "$TMP_DIR/stdout" || true echo "--- stderr ---" sed -n '1,200p' "$TMP_DIR/stderr" || true exit 1 fi if [[ $RC -eq 0 || $RC -eq 1 || $RC -eq 2 ]]; then echo "SUCCESS (RC=$RC)" exit 0 else echo "FAILURE with RC $RC" cat "$TMP_DIR/stderr" exit 1 fi