| #!/bin/sh
#
# Copy C lws' state machine oracles from a C checkout:
#
# scripts/sync-c-states.sh /path/to/libwebsockets [build dir]
#
# The rows of C's event table go to crates/npro-test/states/, verbatim, and
# the state edges C's ctest suite takes beside them, from a build with
# LWS_WITH_STATE_TRACE and LWS_WITH_STATE_CHECK (so the suite also aborts on
# any edge the table does not allow). The C commit is recorded in C-COMMIT.
# The checkout should be clean, as for sync-c-oracle.sh.
#
# The build goes to <checkout>/build-npro-states unless a build dir is
# given; it is reconfigured each time. It is a default build without h3,
# which needs gnutls; C's ctest-background.sh needs netstat or ss to see its
# test servers come up. The suite takes some minutes.
set -eu
if [ $# -lt 1 ] || [ $# -gt 2 ] || [ ! -f "$1/lib/sansio/wsi-state.c" ]; then
echo "usage: $0 <libwebsockets checkout> [build dir]" >&2
exit 1
fi
c="$1"
b="${2:-$c/build-npro-states}"
here="$(cd "$(dirname "$0")/.." && pwd)"
dst="$here/crates/npro-test/states"
if [ -n "$(git -C "$c" status --porcelain -- lib include CMakeLists.txt)" ]; then
echo "$c has uncommitted changes" >&2
exit 1
fi
if ! command -v netstat >/dev/null 2>&1 && ! command -v ss >/dev/null 2>&1; then
echo "C's test fixtures need netstat or ss" >&2
exit 1
fi
cmake -S "$c" -B "$b" -DCMAKE_BUILD_TYPE=DEBUG \
-DLWS_WITH_STATE_TRACE=ON -DLWS_WITH_STATE_CHECK=ON \
-DLWS_WITH_HTTP3=OFF -DLWS_WITH_MINIMAL_EXAMPLES=ON \
-DLWS_WITHOUT_EXTENSIONS=OFF -DLWS_WITH_ZLIB=ON \
-DLWS_WITH_SYS_FAULT_INJECTION=ON
cmake --build "$b" -j "${SAI_PARALLEL:-4}"
raw="$(mktemp)"
trap 'rm -f "$raw"' EXIT
(cd "$b" && LWS_STATE_TRACE_FILE="$raw" ctest -j "${SAI_PARALLEL:-4}" --timeout 180)
# the table's rows, between its opening and its closing brace
awk '/^static const struct lws_wsi_event_edge lws_wsi_event_edges\[\] = \{/ { f = 1; next }
f && /^\};/ { exit }
f' "$c/lib/sansio/wsi-state.c" > "$dst/wsi-event-edges.txt"
# each edge once, without the connection's tag: "LRS from -> to how [ev=X]"
sed -E -e 's/^(LRS [^ ]+ -> [^ ]+ [^ ]+) .*( ev=[A-Z0-9_]+)$/\1\2/' -e t \
-e 's/^(LRS [^ ]+ -> [^ ]+ [^ ]+) .*$/\1/' "$raw" |
LC_ALL=C sort -u > "$dst/edges.txt"
git -C "$c" log -1 --format='%H %s' > "$dst/C-COMMIT"
echo "$(grep -c '^[[:space:]]*{' "$dst/wsi-event-edges.txt") rows and" \
"$(wc -l < "$dst/edges.txt") edges from $(cut -c1-12 "$dst/C-COMMIT")"
|