G
2025-12-11 15:59:08 -05:00
|
|
|
"""Tests for convert command."""
|
|
|
|
|
|
|
|
|
|
import os
|
|
|
|
|
import tempfile
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
from click.testing import CliRunner
|
|
|
|
|
|
M
2025-12-15 15:59:48 -05:00
|
|
|
from ria_toolkit_oss_cli.cli import cli
|
G
2025-12-11 15:59:08 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class TestConvert:
|
|
|
|
|
"""Test convert command functionality."""
|
|
|
|
|
|
|
|
|
|
def test_convert_help(self):
|
|
|
|
|
"""Test convert command help."""
|
|
|
|
|
runner = CliRunner()
|
|
|
|
|
result = runner.invoke(cli, ["convert", "--help"])
|
|
|
|
|
assert result.exit_code == 0
|
|
|
|
|
assert "Convert recordings between file formats" in result.output
|
|
|
|
|
assert "--format" in result.output
|
|
|
|
|
assert "--legacy" in result.output
|
|
|
|
|
assert "--wav-sample-rate" in result.output
|
|
|
|
|
assert "--blue-format" in result.output
|
|
|
|
|
assert "--overwrite" in result.output
|
|
|
|
|
assert "--metadata" in result.output
|
|
|
|
|
|
|
|
|
|
def test_missing_arguments(self):
|
|
|
|
|
"""Test that missing arguments show error."""
|
|
|
|
|
runner = CliRunner()
|
|
|
|
|
result = runner.invoke(cli, ["convert"])
|
|
|
|
|
assert result.exit_code != 0
|
|
|
|
|
assert "Missing argument" in result.output or "Error" in result.output
|
|
|
|
|
|
|
|
|
|
def test_invalid_input_format(self):
|
|
|
|
|
"""Test handling of invalid input format."""
|
|
|
|
|
runner = CliRunner()
|
|
|
|
|
with tempfile.NamedTemporaryFile(suffix=".xyz", delete=False) as f:
|
|
|
|
|
try:
|
|
|
|
|
result = runner.invoke(cli, ["convert", f.name, "output.npy"])
|
|
|
|
|
assert result.exit_code != 0
|
|
|
|
|
assert "Unknown format" in result.output or "Supported" in result.output
|
|
|
|
|
finally:
|
|
|
|
|
os.unlink(f.name)
|
|
|
|
|
|
|
|
|
|
def test_overwrite_protection(self):
|
|
|
|
|
"""Test that overwrite protection works."""
|
|
|
|
|
runner = CliRunner()
|
|
|
|
|
|
|
|
|
|
# Create a dummy input file (will use actual test data if available)
|
|
|
|
|
test_input = "/home/qrf/workarea/ash/signal-testbed/recordings/iq2440MHz234233.npy"
|
|
|
|
|
if not os.path.exists(test_input):
|
|
|
|
|
pytest.skip("Test recording file not found")
|
|
|
|
|
|
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
|
|
|
output_file = os.path.join(tmpdir, "test.sigmf")
|
|
|
|
|
|
|
|
|
|
# First conversion should succeed
|
|
|
|
|
result = runner.invoke(cli, ["convert", test_input, output_file, "--legacy", "-q"])
|
|
|
|
|
assert result.exit_code == 0
|
|
|
|
|
|
|
|
|
|
# Second conversion without --overwrite should fail
|
|
|
|
|
result = runner.invoke(cli, ["convert", test_input, output_file, "--legacy"])
|
|
|
|
|
assert result.exit_code != 0
|
|
|
|
|
assert "exist" in result.output.lower()
|
|
|
|
|
assert "--overwrite" in result.output
|
|
|
|
|
|
|
|
|
|
# Third conversion with --overwrite should succeed
|
|
|
|
|
result = runner.invoke(cli, ["convert", test_input, output_file, "--legacy", "--overwrite", "-q"])
|
|
|
|
|
assert result.exit_code == 0
|
|
|
|
|
|
|
|
|
|
def test_metadata_override(self):
|
|
|
|
|
"""Test metadata override functionality."""
|
|
|
|
|
runner = CliRunner()
|
|
|
|
|
|
|
|
|
|
test_input = "/home/qrf/workarea/ash/signal-testbed/recordings/iq2440MHz234233.npy"
|
|
|
|
|
if not os.path.exists(test_input):
|
|
|
|
|
pytest.skip("Test recording file not found")
|
|
|
|
|
|
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
|
|
|
output_file = os.path.join(tmpdir, "test.sigmf")
|
|
|
|
|
|
|
|
|
|
result = runner.invoke(
|
|
|
|
|
cli,
|
|
|
|
|
[
|
|
|
|
|
"convert",
|
|
|
|
|
test_input,
|
|
|
|
|
output_file,
|
|
|
|
|
"--legacy",
|
|
|
|
|
"--metadata",
|
|
|
|
|
"test_key=test_value",
|
|
|
|
|
"--metadata",
|
|
|
|
|
"number=42",
|
|
|
|
|
"--metadata",
|
|
|
|
|
"float_val=3.14",
|
|
|
|
|
"-v",
|
|
|
|
|
],
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
assert result.exit_code == 0
|
|
|
|
|
assert "test_key" in result.output
|
|
|
|
|
assert "number" in result.output
|
|
|
|
|
assert "float_val" in result.output
|
|
|
|
|
|
|
|
|
|
def test_format_detection(self):
|
|
|
|
|
"""Test that format detection works for different extensions."""
|
|
|
|
|
runner = CliRunner()
|
|
|
|
|
|
|
|
|
|
test_input = "/home/qrf/workarea/ash/signal-testbed/recordings/iq2440MHz234233.npy"
|
|
|
|
|
if not os.path.exists(test_input):
|
|
|
|
|
pytest.skip("Test recording file not found")
|
|
|
|
|
|
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
|
|
|
# Test NPY to SigMF
|
|
|
|
|
sigmf_out = os.path.join(tmpdir, "test.sigmf")
|
|
|
|
|
result = runner.invoke(cli, ["convert", test_input, sigmf_out, "--legacy", "-q"])
|
|
|
|
|
assert result.exit_code == 0
|
|
|
|
|
assert Path(sigmf_out).with_suffix(".sigmf-data").exists()
|
|
|
|
|
assert Path(sigmf_out).with_suffix(".sigmf-meta").exists()
|
|
|
|
|
|
|
|
|
|
# Test NPY to NPY
|
|
|
|
|
npy_out = os.path.join(tmpdir, "test.npy")
|
|
|
|
|
result = runner.invoke(cli, ["convert", test_input, npy_out, "--legacy", "-q"])
|
|
|
|
|
assert result.exit_code == 0
|
|
|
|
|
assert Path(npy_out).exists()
|
|
|
|
|
|
|
|
|
|
def test_wav_conversion_with_decimation(self):
|
|
|
|
|
"""Test WAV conversion with sample rate decimation."""
|
|
|
|
|
runner = CliRunner()
|
|
|
|
|
|
|
|
|
|
test_input = "/home/qrf/workarea/ash/signal-testbed/recordings/iq2440MHz234233.npy"
|
|
|
|
|
if not os.path.exists(test_input):
|
|
|
|
|
pytest.skip("Test recording file not found")
|
|
|
|
|
|
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
|
|
|
wav_out = os.path.join(tmpdir, "test.wav")
|
|
|
|
|
result = runner.invoke(
|
|
|
|
|
cli, ["convert", test_input, wav_out, "--legacy", "--wav-sample-rate", "48000", "--wav-bits", "16"]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
assert result.exit_code == 0
|
|
|
|
|
assert "Decimation factor" in result.output
|
|
|
|
|
assert Path(wav_out).exists()
|
|
|
|
|
# Check file is non-empty
|
|
|
|
|
assert os.path.getsize(wav_out) > 0
|
|
|
|
|
|
|
|
|
|
def test_blue_format_conversion(self):
|
|
|
|
|
"""Test MIDAS Blue format conversion."""
|
|
|
|
|
runner = CliRunner()
|
|
|
|
|
|
|
|
|
|
test_input = "/home/qrf/workarea/ash/signal-testbed/recordings/iq2440MHz234233.npy"
|
|
|
|
|
if not os.path.exists(test_input):
|
|
|
|
|
pytest.skip("Test recording file not found")
|
|
|
|
|
|
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
|
|
|
# Test each Blue format
|
|
|
|
|
for blue_fmt in ["CI", "CF", "CD"]:
|
|
|
|
|
blue_out = os.path.join(tmpdir, f"test_{blue_fmt}.blue")
|
|
|
|
|
result = runner.invoke(
|
|
|
|
|
cli, ["convert", test_input, blue_out, "--legacy", "--blue-format", blue_fmt, "-q"]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
assert result.exit_code == 0
|
|
|
|
|
assert Path(blue_out).exists()
|
|
|
|
|
# Check file is non-empty
|
|
|
|
|
assert os.path.getsize(blue_out) > 0
|
|
|
|
|
|
|
|
|
|
def test_quiet_and_verbose_modes(self):
|
|
|
|
|
"""Test quiet and verbose output modes."""
|
|
|
|
|
runner = CliRunner()
|
|
|
|
|
|
|
|
|
|
test_input = "/home/qrf/workarea/ash/signal-testbed/recordings/iq2440MHz234233.npy"
|
|
|
|
|
if not os.path.exists(test_input):
|
|
|
|
|
pytest.skip("Test recording file not found")
|
|
|
|
|
|
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
|
|
|
# Test verbose mode
|
|
|
|
|
output_file = os.path.join(tmpdir, "test_verbose.sigmf")
|
|
|
|
|
result = runner.invoke(cli, ["convert", test_input, output_file, "--legacy", "-v"])
|
|
|
|
|
assert result.exit_code == 0
|
|
|
|
|
assert "Reading input" in result.output
|
|
|
|
|
assert "Metadata preserved" in result.output
|
|
|
|
|
|
|
|
|
|
# Test quiet mode
|
|
|
|
|
output_file = os.path.join(tmpdir, "test_quiet.npy")
|
|
|
|
|
result = runner.invoke(cli, ["convert", test_input, output_file, "--legacy", "-q"])
|
|
|
|
|
assert result.exit_code == 0
|
|
|
|
|
# Should have minimal output
|
|
|
|
|
assert len(result.output) < 100 or result.output.strip() == ""
|