#!/bin/sh # Unit tests for entrypoint.sh argument handling. # Run directly: sh docker/test-entrypoint.sh # Exit 0 on success, non-zero on first failure summary. # # These tests run as an unprivileged user with LOCALSTACK_PARITY=false. # Stub id and chroot to check the root path without changing privileges. set -eu SCRIPT="$(cd "$(dirname "$0")" && pwd)/entrypoint.sh" PASS=0 FAIL=0 assert_eq() { desc="$1"; expected="$2"; actual="$3" if [ "${actual}" = "${expected}" ]; then printf '[PASS] %s\n' "${desc}" PASS=$((PASS + 1)) else printf '[FAIL] %s\n expected: %s\n actual: %s\n' "${desc}" "${expected}" "${actual}" FAIL=$((FAIL + 1)) fi } if [ "$(id -u)" = '0' ]; then echo "These tests must run as an unprivileged user (the root path re-execs via chroot)." >&2 exit 1 fi WORK="$(mktemp -d)" trap 'rm -rf "${WORK}"' EXIT INT TERM # Stub java on PATH that prints the argv it was exec'd with. mkdir -p "${WORK}/bin" cat > "${WORK}/bin/java" <<'EOF' #!/bin/sh printf '%s\n' "java $*" EOF chmod +x "${WORK}/bin/java" mkdir -p "${WORK}/root-bin" cat > "${WORK}/root-bin/id" <<'EOF' #!/bin/sh if [ "$1" = '-u' ]; then printf '0\n' else /usr/bin/id "$@" fi EOF cat > "${WORK}/root-bin/chroot" <<'EOF' #!/bin/sh printf 'dropped privileges\n' EOF chmod +x "${WORK}/root-bin/id" "${WORK}/root-bin/chroot" assert_eq "root drops privileges by default" \ "dropped privileges" \ "$(PATH="${WORK}/root-bin:${PATH}" FLOCI_STORAGE_PERSISTENT_PATH="${WORK}/absent" LOCALSTACK_PARITY=false sh "${SCRIPT}" echo preserved)" assert_eq "false keeps the unprivileged default" \ "dropped privileges" \ "$(PATH="${WORK}/root-bin:${PATH}" FLOCI_RUN_AS_ROOT=false FLOCI_STORAGE_PERSISTENT_PATH="${WORK}/absent" LOCALSTACK_PARITY=false sh "${SCRIPT}" echo preserved)" assert_eq "other values keep the unprivileged default" \ "dropped privileges" \ "$(PATH="${WORK}/root-bin:${PATH}" FLOCI_RUN_AS_ROOT=TRUE FLOCI_STORAGE_PERSISTENT_PATH="${WORK}/absent" LOCALSTACK_PARITY=false sh "${SCRIPT}" echo preserved)" assert_eq "explicit root option preserves command arguments" \ "one two|three" \ "$(PATH="${WORK}/root-bin:${PATH}" FLOCI_RUN_AS_ROOT=true FLOCI_STORAGE_PERSISTENT_PATH="${WORK}/absent" LOCALSTACK_PARITY=false sh "${SCRIPT}" sh -c 'printf "%s|%s\n" "$1" "$2"' _ "one two" three)" assert_eq "non-root process cannot elevate with root option" \ "one two" \ "$(FLOCI_RUN_AS_ROOT=true LOCALSTACK_PARITY=false sh "${SCRIPT}" echo one two)" # --- explicit arguments are exec'd unchanged --- assert_eq "explicit command is exec'd unchanged" \ "one two" \ "$(LOCALSTACK_PARITY=false sh "${SCRIPT}" echo one two)" assert_eq "explicit java command bypasses the fallback" \ "java -jar /custom/app.jar" \ "$(PATH="${WORK}/bin:${PATH}" LOCALSTACK_PARITY=false sh "${SCRIPT}" java -jar /custom/app.jar)" # --- empty argv falls back to the image default command --- # Without /app/application (JVM image layout), the fallback must exec the # Quarkus runner jar with the same arguments as the published image CMD. if [ ! -e /app/application ]; then assert_eq "empty argv falls back to the JVM default command" \ "java -Dquarkus.http.host=0.0.0.0 -Dfloci.security.allow-unsafe-network-exposure=true -jar /app/quarkus-app/quarkus-run.jar" \ "$(PATH="${WORK}/bin:${PATH}" LOCALSTACK_PARITY=false sh "${SCRIPT}")" else printf '[SKIP] empty argv falls back to the JVM default command (/app/application exists on this host)\n' fi # With an executable /app/application (native image layout), the fallback # must prefer the native binary. Only runs where /app is writable or the # binary already exists (always true inside the published images). NATIVE_TESTABLE=false if [ -x /app/application ]; then NATIVE_TESTABLE=true elif mkdir -p /app 2>/dev/null && [ -w /app ]; then cat > /app/application <<'EOF' #!/bin/sh printf '%s\n' "/app/application $*" EOF chmod +x /app/application trap 'rm -f /app/application; rm -rf "${WORK}"' EXIT INT TERM NATIVE_TESTABLE=true fi if [ "${NATIVE_TESTABLE}" = 'true' ]; then assert_eq "empty argv prefers the native binary when present" \ "/app/application -Dquarkus.http.host=0.0.0.0 -Dfloci.security.allow-unsafe-network-exposure=true" \ "$(LOCALSTACK_PARITY=false sh "${SCRIPT}")" else printf '[SKIP] empty argv prefers the native binary when present (/app not writable)\n' fi # --- unwritable state dir prints a warning but still execs the command --- RO_DIR="${WORK}/ro-data" mkdir -p "${RO_DIR}" chmod 555 "${RO_DIR}" RO_ERR="${WORK}/ro-err.txt" assert_eq "unwritable state dir still execs the command" \ "ok" \ "$(FLOCI_STORAGE_PERSISTENT_PATH="${RO_DIR}" LOCALSTACK_PARITY=false sh "${SCRIPT}" echo ok 2>"${RO_ERR}")" if grep -q 'not writable' "${RO_ERR}"; then printf '[PASS] unwritable state dir prints a loud warning\n' PASS=$((PASS + 1)) else printf '[FAIL] unwritable state dir prints a loud warning\n stderr was:\n%s\n' "$(cat "${RO_ERR}")" FAIL=$((FAIL + 1)) fi chmod 755 "${RO_DIR}" # --- writable state dir stays quiet and leaves no probe behind --- RW_DIR="${WORK}/rw-data" mkdir -p "${RW_DIR}" RW_ERR="${WORK}/rw-err.txt" FLOCI_STORAGE_PERSISTENT_PATH="${RW_DIR}" LOCALSTACK_PARITY=false sh "${SCRIPT}" echo ok >/dev/null 2>"${RW_ERR}" if ! grep -q 'not writable' "${RW_ERR}" && [ -z "$(ls -A "${RW_DIR}")" ]; then printf '[PASS] writable state dir stays quiet and leaves no probe file\n' PASS=$((PASS + 1)) else printf '[FAIL] writable state dir stays quiet and leaves no probe file\n' FAIL=$((FAIL + 1)) fi printf '\n%d passed, %d failed\n' "${PASS}" "${FAIL}" [ "${FAIL}" -eq 0 ]