G
2025-12-11 15:12:01 -05:00
|
|
|
# CLI Tests
|
|
|
|
|
|
F
Port annotation system from utils and fix ria package imports
Annotations package (new):
- Add threshold_qualifier with 3-pass hysteresis detector (Pass 1: strong
bursts, Pass 2: weak residual bursts, Pass 3: macro-window faint burst
detection), auto window_size scaled to 1ms, channel selection, and
stable noise_floor baseline throughout
- Add energy_detector, cusum_annotator, parallel_signal_separator,
qualify_slice, signal_isolation, annotation_transforms
- Add __init__.py exporting the four functions used by the CLI
- Fix all imports from utils.data → ria_toolkit_oss.datatypes
CLI annotate command (new):
- Port full annotate CLI from utils including list, add, remove, clear,
energy, cusum, threshold, and separate subcommands
- Fix imports from utils.* → ria_toolkit_oss.* and utils_cli.* →
ria_toolkit_oss_cli.*
- Safe overwrite logic: _annotated files always writable, originals
protected; --overwrite writes in-place only on _annotated inputs
CLI view command:
- Add 'annotations' as a valid --type, wiring view_annotations from
view_signal
view_signal.py:
- Add view_annotations function with blue/purple alternating palette and
threshold %-sorted drawing order (lower % renders on top)
recording.py (datatypes):
- Fix lazy imports in to_wav() and to_blue() from utils.io → ria_toolkit_oss.io
io/recording.py:
- Add compatibility shim in from_npy to remap utils.data.annotation.Annotation
to ria_toolkit_oss.datatypes.annotation.Annotation when loading .npy files
pickled by the utils package
2026-03-31 13:34:00 -04:00
|
|
|
Comprehensive test suite for the ria CLI commands.
|
G
2025-12-11 15:12:01 -05:00
|
|
|
|
|
|
|
|
## Test Structure
|
|
|
|
|
|
|
|
|
|
- `test_common.py` - Tests for common CLI utilities (YAML loading, metadata parsing, frequency formatting)
|
|
|
|
|
- `test_discover.py` - Tests for device discovery functionality
|
|
|
|
|
- `test_capture.py` - Tests for the capture command
|
|
|
|
|
- `test_transmit.py` - Tests for the transmit command
|
|
|
|
|
|
|
|
|
|
## Running Tests
|
|
|
|
|
|
|
|
|
|
### Run all CLI tests:
|
|
|
|
|
```bash
|
F
2026-03-31 15:27:45 -04:00
|
|
|
poetry run pytest tests/ria_toolkit_oss_cli/ -v
|
G
2025-12-11 15:12:01 -05:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Run specific test file:
|
|
|
|
|
```bash
|
F
2026-03-31 15:27:45 -04:00
|
|
|
poetry run pytest tests/ria_toolkit_oss_cli/test_common.py -v
|
|
|
|
|
poetry run pytest tests/ria_toolkit_oss_cli/test_discover.py -v
|
|
|
|
|
poetry run pytest tests/ria_toolkit_oss_cli/test_capture.py -v
|
G
2025-12-11 15:12:01 -05:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Run specific test class or function:
|
|
|
|
|
```bash
|
F
2026-03-31 15:27:45 -04:00
|
|
|
poetry run pytest tests/ria_toolkit_oss_cli/test_capture.py::TestCaptureCommand::test_capture_basic -v
|
|
|
|
|
poetry run pytest tests/ria_toolkit_oss_cli/test_common.py::test_parse_frequency -v
|
G
2025-12-11 15:12:01 -05:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Run with coverage:
|
|
|
|
|
```bash
|
F
2026-03-31 15:27:45 -04:00
|
|
|
poetry run pytest tests/ria_toolkit_oss_cli/ --cov=utils_cli --cov-report=html
|
G
2025-12-11 15:12:01 -05:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Test Coverage
|
|
|
|
|
|
|
|
|
|
### test_common.py
|
|
|
|
|
- YAML configuration file loading
|
|
|
|
|
- Metadata KEY=VALUE parsing
|
|
|
|
|
- Frequency parsing (scientific notation, suffixes)
|
|
|
|
|
- Frequency and sample rate formatting
|
|
|
|
|
|
|
|
|
|
### test_discover.py
|
|
|
|
|
- Device discovery for all supported SDR types (PlutoSDR, HackRF, BladeRF, USRP, RTL-SDR, ThinkRF)
|
|
|
|
|
- Device auto-selection logic
|
|
|
|
|
- Device connection testing
|
|
|
|
|
- CLI command options (--verbose, --json-output, --test, --type)
|
|
|
|
|
- Error handling for missing devices and multiple devices
|
|
|
|
|
|
|
|
|
|
### test_capture.py
|
|
|
|
|
- Basic capture functionality
|
|
|
|
|
- Parameter validation (sample rate, center frequency, duration/num-samples)
|
|
|
|
|
- Device auto-selection
|
|
|
|
|
- Multiple output formats (SigMF, NPY, WAV, Blue)
|
|
|
|
|
- Format auto-detection from file extension
|
|
|
|
|
- YAML configuration file loading
|
|
|
|
|
- Custom metadata handling
|
|
|
|
|
- Gain and bandwidth configuration
|
|
|
|
|
- Visualization saving (--save-image)
|
|
|
|
|
- Chunked capture for large recordings
|
|
|
|
|
- Verbose and quiet output modes
|
|
|
|
|
- Proper device cleanup on errors
|
|
|
|
|
|
|
|
|
|
### test_transmit.py
|
|
|
|
|
- TX device initialization (PlutoSDR, HackRF, BladeRF, USRP only)
|
|
|
|
|
- RX-only device rejection (RTL-SDR, ThinkRF)
|
|
|
|
|
- TX device auto-selection
|
|
|
|
|
- Input file loading (SigMF, NPY, WAV, Blue)
|
|
|
|
|
- Legacy NPY format support
|
|
|
|
|
- TX gain validation and range checking
|
|
|
|
|
- Sample rate mismatch warnings
|
|
|
|
|
- Transmission modes:
|
|
|
|
|
- Single transmission
|
|
|
|
|
- Repeat mode with delays
|
|
|
|
|
- Continuous transmission with safety warnings
|
|
|
|
|
- YAML configuration file loading
|
|
|
|
|
- Safety confirmations for continuous mode
|
|
|
|
|
- Proper device cleanup on errors
|
|
|
|
|
- Verbose and quiet output modes
|
|
|
|
|
|
|
|
|
|
## Mock Strategy
|
|
|
|
|
|
|
|
|
|
Tests use `unittest.mock` to:
|
|
|
|
|
- Mock SDR device instances to avoid requiring actual hardware
|
|
|
|
|
- Mock file I/O operations
|
|
|
|
|
- Mock discovery functions to simulate different device scenarios
|
|
|
|
|
- Verify proper function calls and parameters
|
|
|
|
|
|
|
|
|
|
## Adding New Tests
|
|
|
|
|
|
|
|
|
|
When adding new CLI commands, follow this pattern:
|
|
|
|
|
|
|
|
|
|
1. Create `test_<command>.py` in this directory
|
|
|
|
|
2. Use Click's `CliRunner` for testing CLI commands
|
|
|
|
|
3. Mock external dependencies (SDR devices, file I/O)
|
|
|
|
|
4. Test both success and error cases
|
|
|
|
|
5. Verify proper resource cleanup (device.close(), file handles, etc.)
|
|
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
```python
|
|
|
|
|
from click.testing import CliRunner
|
|
|
|
|
from unittest.mock import patch, MagicMock
|
|
|
|
|
|
|
|
|
|
def test_new_command():
|
|
|
|
|
runner = CliRunner()
|
|
|
|
|
|
|
|
|
|
with patch('module.dependency') as mock_dep:
|
|
|
|
|
mock_dep.return_value = expected_value
|
|
|
|
|
|
|
|
|
|
result = runner.invoke(command, ['--option', 'value'])
|
|
|
|
|
|
|
|
|
|
assert result.exit_code == 0
|
|
|
|
|
assert 'expected output' in result.output
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## CI/CD Integration
|
|
|
|
|
|
|
|
|
|
These tests are designed to run in CI/CD pipelines without requiring actual SDR hardware. All hardware interactions are mocked.
|
|
|
|
|
|
|
|
|
|
## Notes
|
|
|
|
|
|
|
|
|
|
- Tests use temporary directories for file operations (cleaned up automatically)
|
|
|
|
|
- Device mocks simulate real SDR behavior without hardware dependencies
|
|
|
|
|
- Tests verify both command-line interface and underlying function behavior
|