Files
el/lang/tests/integration/async_future.sh
T
bigmerge 511db25230
El SDK CI - dev / build-and-test (pull_request) Failing after 14m31s
rerun cycle 18 rather than reconstruct it
The async/future measurements were produced by a C stub in /tmp, and that
artifact was destroyed when the session worktrees were removed. The log then
asserted results with nothing behind them -- a claim inside an evidence record,
which is exactly what turns a chain of custody into a pile.

Rerun, not reconstructed. Rebuilding the missing file would have been a
fabrication with a fresh timestamp; rerunning produces new evidence with its own.

  lang/tests/integration/fixtures/future.c   the future, as a tagged heap object
  lang/tests/integration/async_future.sh     the harness, 6/6

  ok  unbound: synchronous, correct result
  ok  unbound: el_await on a non-future passes through, no crash
  ok  bound: does not crash
  ok  bound: the awaited result is correct
  ok  bound: the caller continues BEFORE the body finishes
  ok  bound: wrap returns in <10ms while the body takes 50ms

LABELLED AS A REPLICATION. The outcomes were already known when this harness was
written, so its expectations are NOT predictions committed in advance. Its
evidentiary value is that a third party can reproduce it, not that it was called
ahead of time. Recording it as anything stronger would corrupt the record it is
meant to repair.

The fixture also carries the P5 defect and its fix in a comment: the first
el_await dereferenced ->magic off an unvalidated slot and SIGSEGV'd on the
unbound path, sixty seconds after the same defect was diagnosed elsewhere in the
runtime.
2026-08-17 11:03:59 -05:00

63 lines
2.8 KiB
Bash
Executable File

#!/usr/bin/env bash
# async_future.sh — REPLICATION of cycle 18.
#
# STATUS: replication, not a blind test. The outcomes were already observed on
# 2026-08-17 before this harness existed, so the expectations below are not
# predictions committed in advance. Its evidentiary value is that the artifact
# lives in the repository and a third party can run it — not that it was called
# ahead of time. The original run's artifact was written in /tmp and lost when
# the worktrees were removed, which broke the chain; this replaces the claim
# with something reproducible rather than reconstructing the missing file.
#
# CLAIM UNDER TEST: @async requires no compiler change. A future is one more
# magic-tagged heap object, and el_seam_wrap lets a construct bound AFTER the
# build decide whether and when to invoke the body.
set -uo pipefail
ELC="${1:?usage: async_future.sh <elc>}"
LANG_DIR="${2:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/..}"
LANG_DIR="$(cd "$LANG_DIR" && pwd)"
FIX="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/fixtures/future.c"
W=$(mktemp -d); trap 'rm -rf "$W"' EXIT; F=0
chk(){ [ "$2" = "$3" ] && printf ' ok %s\n' "$1" || { printf ' FAIL %s\n expected %s got %s\n' "$1" "$2" "$3"; F=$((F+1)); }; }
cd "$LANG_DIR"
SRCS=$(../scripts/el-runtime-sources.sh runtime)
CF="-std=c11 -O2 -rdynamic -I runtime"; LF=""
for d in /opt/homebrew/opt/openssl@3 /usr/local/opt/openssl@3; do
[ -d "$d" ] && CF="$CF -I $d/include" && LF="-L $d/lib"
done
LF="$LF -lcurl -lssl -lcrypto -lpthread -lm"
cat > "$W/p.el" <<'EOF'
extern fn el_await(h: Int) -> Int
fn work(k: Int) -> Int {
return k * 2
}
fn main() {
let h: Int = work(21)
println("CALLER_CONTINUED")
let r: Int = el_await(h)
println("RESULT " + int_to_str(r))
}
EOF
"$ELC" "$W/p.el" > "$W/p.c" 2>/dev/null
cc $CF -o "$W/p" "$W/p.c" "$FIX" $SRCS $LF 2>/dev/null || { echo " FAIL probe did not build"; exit 1; }
out=$(cd "$W" && ./p 2>&1); rc=$?
chk "unbound: no construct, synchronous, correct result" "0" "$rc"
chk "unbound: el_await on a non-future passes through, no crash" "1" "$(echo "$out" | grep -c '^RESULT 42$')"
printf 'work async wrap defer\n' > "$W/c.txt"
out=$(cd "$W" && EL_CONSTRUCTS=c.txt ./p 2>&1); rc=$?
chk "bound: does not crash" "0" "$rc"
chk "bound: the awaited result is correct" "1" "$(echo "$out" | grep -c '^RESULT 42$')"
wrap=$(echo "$out" | awk '/^WRAP_RETURNED/{print $2}')
bend=$(echo "$out" | awk '/^BODY_END/{print $2}')
caller_before_body_end=$(echo "$out" | awk '/CALLER_CONTINUED/{c=NR} /^BODY_END/{b=NR} END{print (c<b)?1:0}')
chk "bound: the caller continues BEFORE the body finishes" "1" "$caller_before_body_end"
chk "bound: the wrap returns in under 10ms while the body takes 50ms" "1" "$([ "${wrap:-999999}" -lt 10000 ] && [ "${bend:-0}" -gt 40000 ] && echo 1 || echo 0)"
echo; echo " 6 assertions, $((6-F)) passed, $F failed"; exit $F