46 lines
2.5 KiB
Python
46 lines
2.5 KiB
Python
"""Standalone generator configuration and independent resource cleanup."""
|
|
|
|
from dataclasses import replace
|
|
import unittest
|
|
from unittest import mock
|
|
|
|
from python_app.generator_sweep.config import GeneratorSweepConfig, resolve_generator_sweep_config
|
|
from python_app.generator_sweep.runner import GeneratorSweepRunner
|
|
|
|
|
|
class GeneratorSweepTest(unittest.TestCase):
|
|
def test_frequency_grid_includes_stop_with_and_without_an_exact_step(self) -> None:
|
|
for step, expected in ((2, (10, 12, 14, 15)), (5, (10, 15))):
|
|
config = GeneratorSweepConfig(start_hz=10, stop_hz=15, step_hz=step)
|
|
self.assertEqual(resolve_generator_sweep_config(config).frequencies_hz, expected)
|
|
config = GeneratorSweepConfig(start_hz=10, stop_hz=15, points=3)
|
|
self.assertEqual(resolve_generator_sweep_config(config).frequencies_hz, (10, 12, 15))
|
|
|
|
def test_malformed_types_nonfinite_values_and_excessive_grids_fail_before_open(self) -> None:
|
|
valid = GeneratorSweepConfig(points=3)
|
|
for changes in ({'points': 3.5}, {'port': True}, {'sweep_start_pin': 5.5},
|
|
{'power_dbm': float('inf')}, {'hold_time_ms': float('nan')},
|
|
{'points': 1_000_001}, {'points': 0, 'step_hz': 1, 'stop_hz': 10 ** 10}):
|
|
with self.subTest(changes=changes), self.assertRaises(ValueError):
|
|
resolve_generator_sweep_config(replace(valid, **changes))
|
|
|
|
def test_each_cleanup_failure_still_releases_the_other_resources(self) -> None:
|
|
for failure in ('pwm_stop', 'device_idle', 'device_close', 'marker_reset', 'marker_close'):
|
|
with self.subTest(failure=failure):
|
|
runner = GeneratorSweepRunner(GeneratorSweepConfig(points=3))
|
|
runner._pwm = mock.Mock()
|
|
runner._markers = mock.Mock()
|
|
device = runner._device = mock.Mock(is_connected=True)
|
|
actions = {
|
|
'pwm_stop': runner._pwm.disable, 'device_idle': device.generator.set_idle,
|
|
'device_close': device.disconnect, 'marker_reset': runner._markers.reset_to_idle,
|
|
'marker_close': runner._markers.close,
|
|
}
|
|
actions[failure].side_effect = OSError('cleanup failure')
|
|
with self.assertLogs('python_app.generator_sweep.runner', level='WARNING'):
|
|
runner._close()
|
|
for action in actions.values():
|
|
action.assert_called_once()
|
|
runner._pwm.close.assert_called_once()
|
|
self.assertIsNone(runner._device)
|