#!/bin/bash
# Regression tests for the mkimage capability probe in build/mk-bootimg.sh.
#
# Guards issue #17: the probe ran the candidate binary and piped it into grep.
# mkimage with no arguments prints usage and exits non-zero, and mk-bootimg.sh
# runs under `set -euo pipefail`, so the pipeline reported failure even when
# grep matched. Every mkimage was rejected and the script failed closed with
# "no mkimage on PATH supports -B" while a capable mkimage sat first on PATH.
#
# The probe is extracted verbatim from mk-bootimg.sh between its sentinel
# comments, so these tests exercise the shipping code rather than a copy.
set -uo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
SCRIPT="$HERE/../../build/mk-bootimg.sh"
PROBE="$(mktemp)"; TMP="$(mktemp -d)"
trap 'rm -rf "$PROBE" "$TMP"' EXIT
sed -n '/^# >>> mkimage-probe/,/^# <<< mkimage-probe/p' "$SCRIPT" > "$PROBE"
grep -q 'MKIMAGE=' "$PROBE" || { echo "FAIL: probe not extracted (sentinels missing)"; exit 1; }
# The probe needs grep on PATH, but the real /usr/bin must stay off it or the
# host's own mkimage would answer these tests. Give it a directory holding
# nothing but grep.
mkdir -p "$TMP/util"
ln -s "$(command -v grep)" "$TMP/util/grep"
# A faithful stand-in for real mkimage: usage on stderr, non-zero exit.
mk_fake() { # mk_fake
mkdir -p "$1"
{ echo '#!/bin/sh'
echo 'echo "Usage: mkimage [-T type] -l image" >&2'
[ "$2" = 1 ] && echo 'echo " -B => align size in hex for FIT structure and header" >&2'
echo 'exit 1'
} > "$1/mkimage"
chmod +x "$1/mkimage"
}
fails=0
check() { # check
local name="$1" want="$2"; shift 2
local path=""; for d in "$@"; do path="$path${path:+:}$d"; done
path="$path${path:+:}$TMP/util"
local got
# /bin/bash by absolute path: a PATH holding only the fixture dirs cannot
# locate the interpreter itself.
got="$(TEST_PATH="$path" PROBE="$PROBE" /bin/bash -c \
'set -euo pipefail; PATH="$TEST_PATH"; . "$PROBE"; echo "${MKIMAGE:-}"' 2>/dev/null)"
got="${got##*/}"
if [ "$got" = "$want" ]; then
echo "PASS: $name"
else
echo "FAIL: $name (wanted '${want:-}', got '${got:-}')"
fails=$((fails + 1))
fi
}
mk_fake "$TMP/good" 1
mk_fake "$TMP/old" 0
# The regression itself: a capable mkimage that exits non-zero must be accepted.
check "capable mkimage accepted despite non-zero exit" mkimage "$TMP/good"
# The guarantee the FATAL message depends on: no false positives.
check "mkimage without -B rejected" "" "$TMP/old"
# PATH order decides, and an incapable earlier entry must not stop the scan.
check "scan continues past an incapable mkimage" mkimage "$TMP/old" "$TMP/good"
check "no mkimage anywhere selects nothing" "" "$TMP/none"
[ "$fails" -eq 0 ] && echo "All mk-bootimg probe tests passed." || echo "$fails test(s) failed."
exit "$fails"