#!/usr/bin/env bash # next/tests/pipeline_envelope.sh — Step 6b acceptance test. # # Exercises stage_envelope/1 directly and via validate_inbound / # validate_outbound. The envelope module must be loaded first # because stage_envelope delegates to envelope:validate_shape/1. # 10 cases. set -uo pipefail cd "$(git rev-parse --show-toplevel)" SX_SERVER="${SX_SERVER:-hosts/ocaml/_build/default/bin/sx_server.exe}" if [ ! -x "$SX_SERVER" ]; then SX_SERVER="/root/rose-ash/hosts/ocaml/_build/default/bin/sx_server.exe" fi if [ ! -x "$SX_SERVER" ]; then echo "ERROR: sx_server.exe not found." >&2 exit 1 fi VERBOSE="${1:-}" PASS=0; FAIL=0; ERRORS="" TMPFILE=$(mktemp); trap "rm -f $TMPFILE" EXIT cat > "$TMPFILE" <<'EPOCHS' (epoch 1) (load "lib/erlang/tokenizer.sx") (load "lib/erlang/parser.sx") (load "lib/erlang/parser-core.sx") (load "lib/erlang/parser-expr.sx") (load "lib/erlang/parser-module.sx") (load "lib/erlang/transpile.sx") (load "lib/erlang/runtime.sx") (load "lib/erlang/vm/dispatcher.sx") (epoch 2) (eval "(get (erlang-load-module (file-read \"next/kernel/envelope.erl\")) :name)") (epoch 3) (eval "(get (erlang-load-module (file-read \"next/kernel/pipeline.erl\")) :name)") ;; Stage list now has exactly one stage (epoch 10) (eval "(erlang-eval-ast \"length(pipeline:inbound_stages())\")") (epoch 11) (eval "(erlang-eval-ast \"length(pipeline:outbound_stages())\")") ;; stage_envelope on a valid envelope returns ok (epoch 12) (eval "(get (erlang-eval-ast \"pipeline:stage_envelope([{id,1},{type,create},{actor,a},{published,1},{signature,[{key_id,k},{algorithm,e},{value,v}]}]) =:= ok\") :name)") ;; stage_envelope on a non-list returns {error, not_a_proplist} (epoch 13) (eval "(get (erlang-eval-ast \"pipeline:stage_envelope(not_a_list) =:= {error, not_a_proplist}\") :name)") ;; stage_envelope on missing id surfaces the missing-field error (epoch 14) (eval "(get (erlang-eval-ast \"case pipeline:stage_envelope([{type,create}]) of {error, {missing_field, id}} -> ok; _ -> bad end\") :name)") ;; validate_inbound runs stage_envelope and returns ok for valid input (epoch 15) (eval "(get (erlang-eval-ast \"pipeline:validate_inbound([{id,1},{type,create},{actor,a},{published,1},{signature,[{key_id,k},{algorithm,e},{value,v}]}]) =:= ok\") :name)") ;; validate_inbound short-circuits with the envelope error (epoch 16) (eval "(get (erlang-eval-ast \"case pipeline:validate_inbound([{type,create}]) of {error, {missing_field, id}} -> ok; _ -> bad end\") :name)") ;; validate_outbound likewise (epoch 17) (eval "(get (erlang-eval-ast \"pipeline:validate_outbound([{id,1},{type,create},{actor,a},{published,1},{signature,[{key_id,k},{algorithm,e},{value,v}]}]) =:= ok\") :name)") (epoch 18) (eval "(get (erlang-eval-ast \"case pipeline:validate_outbound([{id,1},{actor,a}]) of {error, _} -> ok; _ -> bad end\") :name)") ;; Signature-subfield missing surfaces nested error tag (epoch 19) (eval "(get (erlang-eval-ast \"case pipeline:validate_inbound([{id,1},{type,create},{actor,a},{published,1},{signature,[{key_id,k}]}]) of {error, {bad_signature, _}} -> ok; _ -> bad end\") :name)") EPOCHS OUTPUT=$(timeout 120 "$SX_SERVER" < "$TMPFILE" 2>/dev/null) check() { local epoch="$1" desc="$2" expected="$3" local actual actual=$(echo "$OUTPUT" | awk -v e="$epoch" ' $0 ~ "^\\(ok-len " e " " { getline; print; exit } $0 ~ "^\\(ok " e " " { print; exit } $0 ~ "^\\(error " e " " { print; exit } ') [ -z "$actual" ] && actual="" if echo "$actual" | grep -qF -- "$expected"; then PASS=$((PASS+1)) [ "$VERBOSE" = "-v" ] && echo " ok $desc" else FAIL=$((FAIL+1)) ERRORS+=" FAIL [$desc] (epoch $epoch) expected: $expected | actual: $actual " fi } check 2 "envelope module loaded" "envelope" check 3 "pipeline module loaded" "pipeline" check 10 "inbound_stages length = 1" "1" check 11 "outbound_stages length = 1" "1" check 12 "stage_envelope ok on valid" "true" check 13 "stage_envelope errs on non-list" "true" check 14 "stage_envelope missing id error" "ok" check 15 "validate_inbound ok on valid" "true" check 16 "validate_inbound surfaces error" "ok" check 17 "validate_outbound ok on valid" "true" check 18 "validate_outbound errs on bad" "ok" check 19 "nested bad_signature surfaces" "ok" TOTAL=$((PASS+FAIL)) if [ $FAIL -eq 0 ]; then echo "ok $PASS/$TOTAL next/tests/pipeline_envelope.sh passed" else echo "FAIL $PASS/$TOTAL passed, $FAIL failed:" echo "$ERRORS" fi [ $FAIL -eq 0 ]