. "$BST_LIB"
# makeself 2.5.0, part 2 of 5 — the ARCHIVE ROUND TRIP. This is the case that
# decides whether the port works: everything in part 1 passes for a recipe that
# merely copied two scripts into /usr/bin, and only a real create-and-unpack
# shows the fork/exec pipeline underneath -- tar and gzip on the way in,
# dd | gzip -cd | tar on the way out -- running on wasm32-hwjs.
#
# ======================================================================
# THE BUDGET THAT SHAPES ALL FIVE FILES — measured, not assumed
# ======================================================================
# `brintos-selftest makeself` runs every 66-makeself-*.test in ONE boot, and the
# image has a per-boot ceiling that makeself hits harder than any other port here
# because the tool IS a process pipeline. Measured on target by looping
# create+unpack cycles until they broke:
#
# creates work for ~11 cycles, then "Cannot allocate memory"
# real UNPACKS only the first ~2 succeed when interleaved with creates;
# from the 3rd on the extraction fails ("Extraction failed",
# rc 15 from the header's own kill -15) even though the MD5
# verify immediately before it passed
#
# So the scarce resource is running TAR THROUGH THE DECOMPRESSOR, and the whole
# surface gets about THREE such operations per boot. Note what does and does not
# count, because the distinction is not the obvious one:
#
# a run / --noexec dd | decompress | tar xp COUNTS -- writes files out
# --list 3 s dd | decompress | tar t COUNTS TOO -- fast, but it is
# still a tar that has to allocate. Cheap in TIME is not
# cheap in MEMORY, which is the trap here.
# --check 9 s dd | md5sum free of it
# --info 2 s reads header variables free of it
#
# The surface therefore spends exactly three: this file's run, part 3's --noexec,
# and part 4's --list. An earlier draft also called --list here, making four, and
# the fourth failed with "tar: Cannot allocate memory" every time -- at whatever
# position in the run order it sat, which is how the rule above was isolated.
#
# This is not a speed concern. A layout with six archives lost whole suites,
# reporting 37 cases in one run and 62 in another from the same image, because
# run-to-run variance decided where the ceiling landed. Sizing to 4 creates and
# 3 tar-decompressions is what keeps the surface inside the budget.
#
# Sizing alone still cannot GUARANTEE it, which is the last thing to know here:
# the ceiling is not a fixed count. Three runs of the same image at three
# tar-decompressions produced three different sets of survivors -- once all three
# passed, once the third failed, once the second. So every extraction goes through
# `ms_gate` from data/makeself-lib.sh, which reports the distinctive ENOMEM
# signature as `skip` (runtime-blocked) and anything else as `not ok`. A genuine
# makeself regression still fails the run; a boot that ran out of memory does not
# masquerade as one. That file's header carries the full reasoning.
#
# The secondary bound is the runner's 60 s per suite (costs: create 14 s, unpack
# 24 s with the progress bar and 14 s with --noprogress, --check 9 s). Hence
# `--noprogress` on every unpack, and hence the ONE unpack below is given the
# startup script's arguments so five assertions come out of it rather than one.
# ======================================================================
#
# Three measured contracts a suite written from expectation would get wrong:
# * The archive re-reads its OWN file to find the payload (`head -n $skip $0 |
# wc -c` for the offset, then dd from there), so it must be invoked as a path
# to a real file -- it is run as an absolute path here for that reason.
# * One cosmetic diagnostic appears on EVERY unpack and is not a failure: the
# header runs `df` on the target directory to report free space, and statfs is
# unimplemented on this runtime, so `df:
: Function not implemented`
# reaches stderr while the extraction proceeds normally.
# * makeself finishes with `chmod +x` on its product, and on this image that
# yields mode 0645 rather than 0755 -- `umask()` returns -ENOSYS here, so an
# unprefixed `+x` is masked down to o+x alone. The archive still executes
# (root needs only one x bit), so what is asserted is that it IS executable,
# not a specific mode. See the ticket's Issues Found for the umask defect.
require makeself.sh makeself/present
. "$BST_DATA/makeself-lib.sh" # ms_gate / ms_needle — see that file's header
MS=/usr/bin/makeself.sh
LC_ALL=C; export LC_ALL
W=${TMPDIR:-/tmp}/bst-makeself-arch.$$
rm -rf "$W"; mkdir -p "$W/p/sub" || { bst_notok makeself/arch-setup "cannot create $W"; exit 0; }
echo makeself-payload-marker > "$W/p/greeting.txt"
echo nested > "$W/p/sub/nested.txt"
printf '#!/bin/sh\necho MS-STARTUP-RAN\necho "MS-SEES:$(cat greeting.txt)"\necho "MS-ARGS:$*"\nexit 0\n' > "$W/p/startup.sh"
chmod 755 "$W/p/startup.sh"
A="$W/demo.run"
cd "$W" || { bst_notok makeself/arch-setup "cannot cd $W"; exit 0; }
# --- create ----------------------------------------------------------------
MSMK=$("$MS" "$W/p" "$A" "BST Demo Label" ./startup.sh 2>&1); MSMKRC=$?
if [ "$MSMKRC" -eq 0 ]; then bst_ok makeself/create
else bst_notok makeself/create "rc=$MSMKRC $(_bst_1line "$MSMK")"; fi
case "$MSMK" in
*"successfully created"*) bst_ok makeself/create-announce ;;
*) bst_notok makeself/create-announce "$(_bst_1line "$MSMK")" ;;
esac
check makeself/archive-exists test -s "$A"
check makeself/archive-executable test -x "$A"
# The product is a shell script with a binary payload appended. The version is
# asserted from the archive's OWN generated comment rather than from file(1):
# whether file(1) recognises a makeself archive depends on its magic database
# version -- it reports "Makeself 2.5.0" on this image but only "POSIX shell
# script executable (binary data)" on an older host -- so that would be an
# assertion drifting with a tool this port does not own.
check_out makeself/archive-shebang "#!/bin/sh" head -1 "$A"
check_out makeself/archive-selfid "generated using Makeself 2.5.0" head -3 "$A"
# --- UNPACK #1 of 3: one extraction, five assertions -----------------------
# Arguments after -- reach the startup script, so this single unpack also covers
# the argument pass-through. Splitting it in two would spend an unpack the whole
# surface does not have.
MSRUN=$("$A" --noprogress -- ALPHA BETA 2>&1); MSRUNRC=$?
ms_gate makeself/run-rc "$MSRUNRC" "$MSRUN"
for _pair in \
'run-integrity:MD5 checksums are OK' \
'run-startup:MS-STARTUP-RAN' \
'run-payload:MS-SEES:makeself-payload-marker' \
'run-args:MS-ARGS:ALPHA BETA'
do
ms_needle "makeself/${_pair%%:*}" "${_pair#*:}" "$MSRUN"
done
# --- read-only interrogation (--info reads header variables only: 2 s) -----
# NB there is deliberately no `--list` here, even though this is the file where
# one would expect it. `--list` runs `tar t` through the decompressor, so it costs
# a tar-decompression from the same budget as an unpack -- and the budget is ~3
# such operations per boot, not 3 unpacks plus unlimited listings. With a --list
# here the surface asked for four (this run, this listing, part 3's --noexec,
# part 4's --list) and the fourth failed with "tar: Cannot allocate memory" every
# time, at whatever position it sat. `--list` is therefore exercised once, in
# part 4, where it doubles as the proof that the bzip2 archive round-trips; and
# the payload's nested entry is asserted in part 3, which unpacks it for real.
MSINFO=$("$A" --info 2>&1)
for _pair in \
'info-label:BST Demo Label' \
'info-compress:Compression: gzip' \
'info-version:Makeself version 2.5.0'
do
_pcase=${_pair%%:*}; _pneedle=${_pair#*:}
case "$MSINFO" in
*"$_pneedle"*) bst_ok "makeself/$_pcase" ;;
*) bst_notok "makeself/$_pcase" "want:'$_pneedle' got:'$(_bst_1line "$MSINFO")'" ;;
esac
done
cd /
rm -rf "$W"