- compose.matrix.yml: add trailing newline
- compose.ftp-222*.yml: fix YAML indentation (8->6 spaces)
- entrypoint.sh.tmpl: fix SC2198 ([ -n "$@" ] -> [ $# -gt 0 ])
- All .tmpl files: migrate from {{ env }} to {{ getenv }} for gomplate v5 compat
- uploads.ini.tmpl: add {{- / -}} whitespace trimming, fix double-space typo
- tests/run.sh: only run ShellCheck on *.sh.tmpl files
- tests/test_shell.sh: gracefully skip if shellcheck not installed
- tests/test_templates.sh: remove dead render() function,
gracefully skip if gomplate not found, use set -a/. for env sourcing
- tests/test_compose_config.sh: validate override files combined
with compose.yml, skip partial snippets needing more context
- README.md: add test instructions with brew install
302 lines
10 KiB
Bash
Executable File
302 lines
10 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
ROOT="$(dirname "$(realpath "$0")")/.."
|
|
pass=0
|
|
fail=0
|
|
|
|
# Allow overriding gomplate binary path via env var
|
|
gomplate="${GOMPLATE_BIN:-gomplate}"
|
|
|
|
# Ensure gomplate is installed before running template tests
|
|
require_gomplate() {
|
|
if ! command -v "$gomplate" &>/dev/null; then
|
|
echo " SKIP gomplate not found (install from https://github.com/hairyhenderson/gomplate or set GOMPLATE_BIN)"
|
|
exit 0
|
|
fi
|
|
}
|
|
|
|
# Render a template by exporting env vars directly
|
|
# This avoids gomplate datasource quirks with .env files
|
|
render_via_env() {
|
|
local tmpl=$1 envfile=$2
|
|
set -a
|
|
# shellcheck disable=1090,1091
|
|
. "$envfile"
|
|
set +a
|
|
"$gomplate" -f "$tmpl" 2>/dev/null
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# entrypoint.sh.tmpl tests
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Default entrypoint: no multisite, uploads guard, chown with --from, wp-cli
|
|
test_entrypoint_default() {
|
|
local envfile=$1
|
|
local output
|
|
output=$(render_via_env "entrypoint.sh.tmpl" "$envfile")
|
|
|
|
# Should NOT have multisite config
|
|
if echo "$output" | grep -q "WP_ALLOW_MULTISITE"; then
|
|
echo " FAIL entrypoint default: unexpected WP_ALLOW_MULTISITE"
|
|
return 1
|
|
fi
|
|
# Should have uploads .htaccess guard
|
|
if ! echo "$output" | grep -q "Prevent PHP execution in uploads"; then
|
|
echo " FAIL entrypoint default: missing uploads htaccess"
|
|
return 1
|
|
fi
|
|
# Should use --from=root:root on chown
|
|
if ! echo "$output" | grep -q "chown -R --from=root:root"; then
|
|
echo " FAIL entrypoint default: missing --from=root:root on chown"
|
|
return 1
|
|
fi
|
|
# Should have wp-cli download
|
|
if ! echo "$output" | grep -q "wp-cli.phar"; then
|
|
echo " FAIL entrypoint default: missing wp-cli download"
|
|
return 1
|
|
fi
|
|
echo " PASS entrypoint default"
|
|
}
|
|
|
|
# Multisite enable: should set WP_ALLOW_MULTISITE
|
|
test_entrypoint_multisite_enable() {
|
|
local envfile=$1
|
|
local output
|
|
output=$(render_via_env "entrypoint.sh.tmpl" "$envfile")
|
|
|
|
if ! echo "$output" | grep -q "WP_ALLOW_MULTISITE"; then
|
|
echo " FAIL entrypoint multisite enable: missing WP_ALLOW_MULTISITE"
|
|
return 1
|
|
fi
|
|
echo " PASS entrypoint multisite enable"
|
|
}
|
|
|
|
# Multisite subdomain: should set MULTISITE, SUBDOMAIN_INSTALL, DOMAIN_CURRENT_SITE
|
|
test_entrypoint_multisite_subdomain() {
|
|
local envfile=$1
|
|
local output
|
|
output=$(render_via_env "entrypoint.sh.tmpl" "$envfile")
|
|
|
|
if ! echo "$output" | grep -q "MULTISITE"; then
|
|
echo " FAIL entrypoint multisite subdomain: missing MULTISITE"
|
|
return 1
|
|
fi
|
|
if ! echo "$output" | grep -q "SUBDOMAIN_INSTALL"; then
|
|
echo " FAIL entrypoint multisite subdomain: missing SUBDOMAIN_INSTALL"
|
|
return 1
|
|
fi
|
|
if ! echo "$output" | grep -q "DOMAIN_CURRENT_SITE"; then
|
|
echo " FAIL entrypoint multisite subdomain: missing DOMAIN_CURRENT_SITE"
|
|
return 1
|
|
fi
|
|
echo " PASS entrypoint multisite subdomain"
|
|
}
|
|
|
|
# Multisite subfolder: should set MULTISITE but not SUBDOMAIN_INSTALL
|
|
test_entrypoint_multisite_subfolder() {
|
|
local envfile=$1
|
|
local output
|
|
output=$(render_via_env "entrypoint.sh.tmpl" "$envfile")
|
|
|
|
if ! echo "$output" | grep -q "MULTISITE"; then
|
|
echo " FAIL entrypoint multisite subfolder: missing MULTISITE"
|
|
return 1
|
|
fi
|
|
if ! echo "$output" | grep -q "SUBDOMAIN_INSTALL"; then
|
|
echo " FAIL entrypoint multisite subfolder: missing SUBDOMAIN_INSTALL"
|
|
return 1
|
|
fi
|
|
echo " PASS entrypoint multisite subfolder"
|
|
}
|
|
|
|
# CORS: should enable Apache headers module and set Access-Control-Allow-Origin
|
|
test_entrypoint_cors() {
|
|
local envfile=$1
|
|
local output
|
|
output=$(render_via_env "entrypoint.sh.tmpl" "$envfile")
|
|
|
|
if ! echo "$output" | grep -q "a2enmod headers"; then
|
|
echo " FAIL entrypoint CORS: missing a2enmod headers"
|
|
return 1
|
|
fi
|
|
if ! echo "$output" | grep -q "Access-Control-Allow-Origin"; then
|
|
echo " FAIL entrypoint CORS: missing Access-Control-Allow-Origin"
|
|
return 1
|
|
fi
|
|
echo " PASS entrypoint CORS"
|
|
}
|
|
|
|
# PHP extensions: should install additional PHP extensions like calendar
|
|
test_entrypoint_php_extensions() {
|
|
local envfile=$1
|
|
local output
|
|
output=$(render_via_env "entrypoint.sh.tmpl" "$envfile")
|
|
|
|
if ! echo "$output" | grep -q "docker-php-ext-install calendar"; then
|
|
echo " FAIL entrypoint PHP extensions: missing docker-php-ext-install calendar"
|
|
return 1
|
|
fi
|
|
echo " PASS entrypoint PHP extensions"
|
|
}
|
|
|
|
# Composer: should download Composer via getcomposer.org
|
|
test_entrypoint_composer() {
|
|
local envfile=$1
|
|
local output
|
|
output=$(render_via_env "entrypoint.sh.tmpl" "$envfile")
|
|
|
|
if ! echo "$output" | grep -q "getcomposer.org"; then
|
|
echo " FAIL entrypoint composer: missing composer download"
|
|
return 1
|
|
fi
|
|
echo " PASS entrypoint composer"
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# htaccess.tmpl tests
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Default htaccess: standard WordPress rewrite rule, no multisite section
|
|
test_htaccess_default() {
|
|
local envfile=$1
|
|
local output
|
|
output=$(render_via_env "htaccess.tmpl" "$envfile")
|
|
|
|
if ! echo "$output" | grep -q "RewriteRule . /index.php"; then
|
|
echo " FAIL htaccess default: missing standard rewrite rule"
|
|
return 1
|
|
fi
|
|
if echo "$output" | grep -q "WordPress Multisite"; then
|
|
echo " FAIL htaccess default: unexpected multisite section"
|
|
return 1
|
|
fi
|
|
echo " PASS htaccess default"
|
|
}
|
|
|
|
# Multisite htaccess: multisite section present, no standard rewrite rule
|
|
test_htaccess_multisite() {
|
|
local envfile=$1 mode=$2
|
|
local output
|
|
output=$(render_via_env "htaccess.tmpl" "$envfile")
|
|
|
|
if ! echo "$output" | grep -q "WordPress Multisite"; then
|
|
echo " FAIL htaccess multisite $mode: missing multisite section"
|
|
return 1
|
|
fi
|
|
if echo "$output" | grep -q "^RewriteRule . /index.php"; then
|
|
echo " FAIL htaccess multisite $mode: has non-multisite rewrite rule"
|
|
return 1
|
|
fi
|
|
echo " PASS htaccess multisite $mode"
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# uploads.ini.tmpl tests
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Default uploads config: 256M upload limit, 30s execution time
|
|
test_uploads_default() {
|
|
local output
|
|
output=$(render_via_env "uploads.ini.tmpl" "tests/fixtures/default.env")
|
|
|
|
if ! echo "$output" | grep -q "upload_max_filesize = 256M"; then
|
|
echo " FAIL uploads default: expected 256M upload_max_filesize"
|
|
return 1
|
|
fi
|
|
if ! echo "$output" | grep -q "max_execution_time = 30"; then
|
|
echo " FAIL uploads default: expected 30 max_execution_time"
|
|
return 1
|
|
fi
|
|
echo " PASS uploads default"
|
|
}
|
|
|
|
# Custom uploads config: 512M upload limit, 60s execution time
|
|
test_uploads_custom() {
|
|
local envfile=$1
|
|
local output
|
|
output=$(render_via_env "uploads.ini.tmpl" "$envfile")
|
|
|
|
if ! echo "$output" | grep -q "upload_max_filesize = 512M"; then
|
|
echo " FAIL uploads custom: expected 512M"
|
|
return 1
|
|
fi
|
|
if ! echo "$output" | grep -q "max_execution_time = 60"; then
|
|
echo " FAIL uploads custom: expected 60"
|
|
return 1
|
|
fi
|
|
echo " PASS uploads custom"
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# msmtp.conf.tmpl tests
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Full SMTP config: host, from, auth, passwordeval, TLS, set_from_header
|
|
test_msmtp_default() {
|
|
local output
|
|
output=$(render_via_env "msmtp.conf.tmpl" "tests/fixtures/smtp-full.env")
|
|
|
|
if ! echo "$output" | grep -q "host mail.example.com"; then
|
|
echo " FAIL msmtp default: missing host"
|
|
return 1
|
|
fi
|
|
if ! echo "$output" | grep -q "from wordpress@example.com"; then
|
|
echo " FAIL msmtp default: missing from"
|
|
return 1
|
|
fi
|
|
if ! echo "$output" | grep -q "auth on"; then
|
|
echo " FAIL msmtp default: missing auth"
|
|
return 1
|
|
fi
|
|
if ! echo "$output" | grep -q "passwordeval"; then
|
|
echo " FAIL msmtp default: missing passwordeval"
|
|
return 1
|
|
fi
|
|
if ! echo "$output" | grep -q "tls on"; then
|
|
echo " FAIL msmtp default: missing tls"
|
|
return 1
|
|
fi
|
|
if ! echo "$output" | grep -q "set_from_header on"; then
|
|
echo " FAIL msmtp default: missing set_from_header"
|
|
return 1
|
|
fi
|
|
echo " PASS msmtp full config"
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Run all template tests
|
|
# ---------------------------------------------------------------------------
|
|
echo "=== Template Rendering Tests ==="
|
|
|
|
cd "$ROOT"
|
|
|
|
echo "--- entrypoint.sh.tmpl ---"
|
|
require_gomplate
|
|
|
|
test_entrypoint_default "tests/fixtures/default.env" && pass=$((pass+1)) || fail=$((fail+1))
|
|
test_entrypoint_multisite_enable "tests/fixtures/multisite-enable.env" && pass=$((pass+1)) || fail=$((fail+1))
|
|
test_entrypoint_multisite_subdomain "tests/fixtures/multisite-subdomain.env" && pass=$((pass+1)) || fail=$((fail+1))
|
|
test_entrypoint_multisite_subfolder "tests/fixtures/multisite-subfolder.env" && pass=$((pass+1)) || fail=$((fail+1))
|
|
test_entrypoint_cors "tests/fixtures/cors.env" && pass=$((pass+1)) || fail=$((fail+1))
|
|
test_entrypoint_php_extensions "tests/fixtures/php-extensions.env" && pass=$((pass+1)) || fail=$((fail+1))
|
|
test_entrypoint_composer "tests/fixtures/composer.env" && pass=$((pass+1)) || fail=$((fail+1))
|
|
|
|
echo "--- htaccess.tmpl ---"
|
|
test_htaccess_default "tests/fixtures/default.env" && pass=$((pass+1)) || fail=$((fail+1))
|
|
test_htaccess_multisite "tests/fixtures/multisite-subfolder.env" "subfolder" && pass=$((pass+1)) || fail=$((fail+1))
|
|
test_htaccess_multisite "tests/fixtures/multisite-subdomain.env" "subdomain" && pass=$((pass+1)) || fail=$((fail+1))
|
|
|
|
echo "--- uploads.ini.tmpl ---"
|
|
test_uploads_default && pass=$((pass+1)) || fail=$((fail+1))
|
|
test_uploads_custom "tests/fixtures/upload-sizes.env" && pass=$((pass+1)) || fail=$((fail+1))
|
|
|
|
echo "--- msmtp.conf.tmpl ---"
|
|
test_msmtp_default && pass=$((pass+1)) || fail=$((fail+1))
|
|
|
|
echo "---"
|
|
echo "Passed: $pass Failed: $fail"
|
|
# Exit with failure if any template test failed
|
|
[ "$fail" -eq 0 ]
|