How to run ka9q-python's test suite. Unit tests run without any
hardware; integration tests talk to a live radiod.
# Unit tests only — no radiod needed
pytest
# Integration tests against a live radiod
pytest --radiod-host=bee1-hf-status.local
RADIOD_HOST=bee1-hf-status.local pytest # equivalent via env var
# Coverage
pytest --cov=ka9q --cov-report=html
# Single file
pytest tests/test_status_decoder.py -v
# Single test
pytest tests/test_tune_method.py::TestTuneBasic::test_frequency -vInstall the package with dev extras:
pip install -e ".[dev]"This pulls in pytest and pytest-cov (see [project.optional-dependencies].dev
in pyproject.toml).
pytest with no arguments runs everything under tests/. Unit tests
mock the network, so they run anywhere — no radiod, no multicast, no
GPS hardware.
pytest # verbose output is on by default via pyproject.toml
pytest -q # quiet
pytest -x # stop at first failureExpect a few hundred tests completing in under a minute.
Some tests require a live radiod. They are gated on a
--radiod-host pytest flag or the RADIOD_HOST environment variable
(see tests/conftest.py):
parser.addoption("--radiod-host",
default=os.environ.get("RADIOD_HOST", "bee1-hf-status.local"),
...)Default host: bee1-hf-status.local.
# Explicit host
pytest --radiod-host=bee3-status.local
# Via env var (convenient in a shell session)
export RADIOD_HOST=bee3-status.local
pytest
# Target just the integration test file
pytest tests/test_integration.py --radiod-host=bee3-status.local -vIf you don't have a reachable radiod, integration tests that depend on one will either skip themselves or fail with clear timeout errors; the unit test layer is unaffected.
pytest --cov=ka9q --cov-report=term-missing
pytest --cov=ka9q --cov-report=html # writes htmlcov/index.htmltests/test_protocol_compat.py
cross-checks ka9q-python's StatusType constants against the
upstream ka9q-radio/src/status.h. It looks for a sibling
../ka9q-radio checkout; if absent, it skips.
To run it, clone the C project next to ka9q-python:
cd ..
git clone https://github.com/ka9q/ka9q-radio
cd ka9q-python
pytest tests/test_protocol_compat.py -vAny drift between the Python constants and the C header will fail
loudly — the signal you need to update ka9q/types.py.
Not pytest — standalone scripts under examples/ that exercise
real multicast paths against a host. Useful when diagnosing
network-layer issues.
examples/multi_stream_smoke.py
— two-channel MultiStream test. Provisions USB channels for FT8 and
WSPR at 20 m, runs for ~20 s, prints per-SSRC packet/sample counts.
python examples/multi_stream_smoke.py --host bee3-status.local --duration 20Success criterion: both labels show non-zero callbacks and samples;
RESULT line prints PASS.
Generated from tests/ at the time of writing. Each file is a
pytest module unless noted.
| File | Scope |
|---|---|
conftest.py |
Registers --radiod-host flag / RADIOD_HOST env var. |
test_addressing.py |
Deterministic SSRC and multicast IP generation. |
test_channel_verification.py |
ensure_channel() verification logic. |
test_create_split_encoding.py |
Channel creation with split encoding params. |
test_decode_functions.py |
TLV decode (int/float/double/string/socket). Unit. |
test_encode_functions.py |
TLV encode + round-trip encode→decode. Unit. |
test_encode_socket.py |
Socket address TLV encoding. |
test_ensure_channel_encoding.py |
Encoding parameter handling in ensure_channel(). |
test_integration.py |
Live-radiod integration: create/re-tune/gain/AGC/multiple channels. |
test_iq_20khz_f32.py |
IQ 20 kHz F32 stream handling. |
test_listen_multicast.py |
Multicast listener plumbing. |
test_managed_stream_recovery.py |
ManagedStream drop/restore behavior. |
test_monitor.py |
ChannelMonitor restart detection. |
test_multihomed.py |
interface= parameter on multi-NIC hosts. |
test_native_discovery.py |
discover_channels_native() pure-Python listener. |
test_performance_fixes.py |
Socket reuse and retry/backoff behavior. |
test_protocol_compat.py |
StatusType ↔ ka9q-radio status.h drift check (auto-skips if ../ka9q-radio is missing). |
test_remove_channel.py |
Channel teardown. |
test_rtp_recorder.py |
RTPRecorder raw-packet capture path. |
test_security_features.py |
Input validation / defensive guards. |
test_ssrc_dest_unit.py |
SSRC + destination derivation. Unit. |
test_ssrc_encoding_unit.py |
SSRC + encoding derivation. Unit. |
test_ssrc_radiod_host_unit.py |
SSRC derivation given a host. Unit. |
test_status_decoder.py |
decode_status_packet() and typed ChannelStatus/FrontendStatus/PllStatus/etc. Unit. |
test_ttl_warning.py |
Multicast TTL configuration warning. |
test_tune.py |
RadiodControl.tune() surface. |
test_tune_cli.py |
examples/tune.py CLI parsing. |
test_tune_debug.py |
Debug-tool plumbing. |
test_tune_live.py |
Live-radiod tune() path (integration). |
test_tune_method.py |
tune() method unit tests: timeouts, SSRC/tag match, decoding. |
Also in tests/:
README.md— a longer (partly historical) narrative on the tune test suite.INTEGRATION_TESTING.md,TROUBLESHOOTING_CHECKLIST.md— prose diagnostics.
Unit tests are safe for CI — no network, no hardware. A minimal workflow:
- run: pip install -e .[dev]
- run: pytest --cov=ka9q --cov-report=xmlIntegration and live-smoke tests need a reachable radiod and are typically run by a self-hosted runner on the same LAN, or manually during release QA.