test: add WIT compatibility tests for WASM extensions (#586)

* test: add WIT compatibility tests for all WASM tools and channels

Adds CI and integration tests to catch WIT interface breakage across
all 14 WASM extensions (10 tools + 4 channels). Previously, changing
wit/tool.wit or wit/channel.wit could silently break guest-side tools
that weren't rebuilt until release time.

Three new pieces:

1. scripts/build-wasm-extensions.sh — builds all WASM extensions from
   source by reading registry manifests. Used by CI and locally.

2. tests/wit_compat.rs — integration tests that compile and instantiate
   each .wasm binary against the current wasmtime host linker with
   stubbed host functions. Catches added/removed/renamed WIT functions,
   signature mismatches, and missing exports. Skips gracefully when
   artifacts aren't built so `cargo test` still passes standalone.

3. .github/workflows/test.yml — new wasm-wit-compat CI job that builds
   all extensions then runs instantiation tests on every PR. Added to
   the branch protection roll-up.

[skip-regression-check]

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* style: fix rustfmt formatting in wit_compat tests

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix: address PR review feedback on WIT compat tests

- Switch build script from python3 to jq for JSON parsing, consistent
  with release.yml and avoids python3 dependency (#1, #7)
- Use dirs::home_dir() instead of HOME env var for portability (#2)
- Filter extensions by manifest "kind" field instead of path (#3)
- Replace .flatten() with explicit error handling in dir iteration (#4, #5)
- Split stub_tool_host_functions into stub_shared_host_functions +
  tool-only tool-invoke stub, since tool-invoke is not in channel WIT (#6)

Co-Authored-By: Claude Opus 4.6 <[email protected]>

---------

Co-authored-by: Claude Opus 4.6 <[email protected]>
This commit is contained in:
Illia Polosukhin
2026-03-06 02:36:59 +00:00
committed by GitHub
co-authored by Claude Opus 4.6
parent 6a2a6cd050
commit 46218ec794
3 changed files with 576 additions and 2 deletions
+74
View File
@@ -0,0 +1,74 @@
#!/usr/bin/env bash
# Build all WASM tools and channels from source.
#
# Verifies that every tool/channel in the registry compiles against the
# current WIT definitions. Used by CI and can be run locally.
#
# Prerequisites:
# rustup target add wasm32-wasip2
# cargo install cargo-component --locked
#
# Usage:
# ./scripts/build-wasm-extensions.sh # build all
# ./scripts/build-wasm-extensions.sh --tools # tools only
# ./scripts/build-wasm-extensions.sh --channels # channels only
set -euo pipefail
cd "$(dirname "$0")/.."
BUILD_TOOLS=true
BUILD_CHANNELS=true
FAILED=()
if [[ "${1:-}" == "--tools" ]]; then
BUILD_CHANNELS=false
elif [[ "${1:-}" == "--channels" ]]; then
BUILD_TOOLS=false
fi
build_extension() {
local manifest_path="$1"
local source_dir
local crate_name
source_dir=$(jq -r '.source.dir' "$manifest_path")
crate_name=$(jq -r '.source.crate_name' "$manifest_path")
local name
name=$(basename "$manifest_path" .json)
if [ ! -d "$source_dir" ]; then
echo " SKIP $name (source dir $source_dir not found)"
return 0
fi
echo " BUILD $name ($crate_name) from $source_dir"
if ! cargo component build --release --manifest-path "$source_dir/Cargo.toml" 2>&1; then
echo " FAIL $name"
FAILED+=("$name")
return 1
fi
echo " OK $name"
}
if $BUILD_TOOLS; then
echo "Building WASM tools..."
for manifest in registry/tools/*.json; do
build_extension "$manifest" || true
done
fi
if $BUILD_CHANNELS; then
echo "Building WASM channels..."
for manifest in registry/channels/*.json; do
build_extension "$manifest" || true
done
fi
echo ""
if [ ${#FAILED[@]} -gt 0 ]; then
echo "FAILED: ${FAILED[*]}"
exit 1
else
echo "All WASM extensions built successfully."
fi