Capability-aware conformance harness for local Sendspin implementations.
Current scenarios:
client-initiated-pcm: start the server first, let the client discover/connect to it, negotiate PCM, and compare canonical PCM hashesserver-initiated-pcm: start the server first, let the client advertise a listener, let the server connect in, negotiate PCM, and compare canonical PCM hashesserver-initiated-metadata: start the server first, let the client advertise a listener, let the server connect in, receive a metadata snapshot, and compare normalized metadata fieldsserver-initiated-artwork: start the server first, let the client advertise a listener, let the server connect in, receive album artwork bytes, and compare the encoded image hashserver-initiated-controller: start the server first, let the client advertise a listener, let the server connect in, observe controller state, send a control command, and verify the server recorded itserver-initiated-flac: start the server first, let the server discover/connect to the client, negotiate FLAC, and compare the transported FLAC bytes instead of decoded PCM
aiosendspin: real server adapter and real client adaptersendspin-dotnet: real client adapter for client-initiated PCM plus the server-initiated PCM, metadata, artwork, controller, and FLAC scenarios; server placeholderSendspinKit: client intentionally unsupported until conformance can use the public SDK like an example application, without bespoke protocol code; server placeholdersendspin-cpp: real C++ client adapter for client-initiated PCM plus the server-initiated PCM, metadata, artwork, controller, and FLAC scenarios; server placeholdersendspin-go: real Go client adapter and real Go server adapter across the current scenario setsendspin-js: client intentionally unsupported until conformance can use the public SDK like an example application, without bespoke protocol code; server placeholdersendspin-rs: real Rust client adapter for client-initiated PCM plus the server-initiated PCM, metadata, artwork, controller, and FLAC scenarios; server placeholder
Unsupported client roles use fail-fast adapters that emit a summary and exit non-zero. Unsupported server roles are filtered out before case creation, so the matrix only shows server rows that can actually run a scenario.
python scripts/setup_workspace.py --clone
. .venv/bin/activate
python scripts/run_all.pyThat flow:
- clones the required repositories
- installs the Python harness and
aiosendspin - builds the adapter sources that are available locally
- runs the current matrix for the selected host environment
- generates the static HTML report
Run the full harness:
python scripts/run_all.py --results-dir results --build-report-path artifacts/build-report.jsonRun the full harness for an explicit host label:
python scripts/run_all.py \
--results-dir results \
--build-report-path artifacts/build-report.json \
--environment-id linux \
--environment-name LinuxRun a subset of the matrix:
conformance run --from aiosendspin,sendspin-rs --to SendspinKitRun the matrix with parallel case execution:
conformance run --jobs 4
python scripts/run_all.py --jobs 4The runner assigns a dedicated server port and client-listener port to each case,
so parallel cases do not fight over 8927/8928.
Build the adapter sources only:
conformance build --report-path artifacts/build-report.jsonGenerate the static site from existing results:
conformance report --results-dir resultsMerge multiple host result sets into one combined report:
python scripts/merge_results.py \
--output-dir artifacts/results \
artifacts/linux-results \
artifacts/macos-resultsThe generated site includes:
- a global matrix overview with one section per test scenario
- a single matrix view per scenario without host-specific grouping in the UI
- the greener PCM scenarios listed first on the index page
- a separate static HTML page per test under
results/scenarios/ - a dedicated static HTML page per pairing under
results/cases/ - a dedicated static HTML page per implementation under
results/implementations/for linkable filtered overviews - per-case status and reason with explicit server/client labeling
- summary, server, client, and build tabs on each dedicated case page when build data exists
- run artifacts under
results/data/ - the static report at
results/index.html - linked case artifacts for drill-down:
result.json, client/server summaries, and logs
src/conformance/: runner, adapters, fixture decoding, report generationadapters/sendspin-go/: Go client/server adapter sourceadapters/sendspin-dotnet/:.NETclient adapter sourceadapters/README.md: CLI contract for adaptersscripts/setup_repositories.py: clones implementation repositoriesscripts/setup_workspace.py: bootstraps a local Python environmentscripts/run_all.py: build + run + report orchestrationscripts/merge_results.py: merges multiple host result directories into one report.github/workflows/publish.yml: macOS GitHub Pages publishing