import unittest from dataclasses import replace from unittest.mock import Mock from logic_analyzer.dslogic import DSLogicSettings from logic_analyzer.dslogic_trigger import program_trigger, validate_trigger class TriggerTests(unittest.TestCase): def test_invalid_modes_and_disabled_conditions(self): base = DSLogicSettings('dsview:2.6') for changes in (dict(acquisition_mode='bad'), dict(acquisition_mode='buffer', duration=0), dict(acquisition_mode='internal', trigger=dict(kind='simple', pattern='X'*15+'R')), dict(trigger=dict(kind='stages', stages=[])), dict(trigger=dict(kind='simple', pattern='R'+'X'*15)), dict(trigger=dict(kind='simple', pattern='X'*16))): with self.subTest(changes=changes), self.assertRaises(ValueError): replace(base, **changes).validate() def test_simple_maps_physical_channels_and_stream_position(self): lib = Mock() program_trigger(lib, dict(kind='simple', pattern='F'+'X'*14+'R', position=80), 'stream', lambda *_: None) lib.ds_trigger_set_pos.assert_called_once_with(1) lib.ds_trigger_probe_set.assert_any_call(0, ord('R'), ord('X')) lib.ds_trigger_probe_set.assert_any_call(15, ord('F'), ord('X')) def test_stage_count_logic_and_masks_match_driver_abi(self): trigger = dict(kind='stages', position=75, stages=[ dict(a='X'*15+'0', b='X'*14+'1X', logic='or', count=9, inv_a=True, contiguous=True), dict(a='X'*15+'R', b='X'*16)]) validate_trigger(trigger, (0,1), 'buffer') lib = Mock() program_trigger(lib, trigger, 'buffer', lambda *_: None) lib.ds_trigger_set_stage.assert_called_once_with(1) lib.ds_trigger_set_pos.assert_called_once_with(75) lib.ds_trigger_stage_set_logic.assert_any_call(0, 16, 2) lib.ds_trigger_stage_set_inv.assert_any_call(0, 16, 1, 0) lib.ds_trigger_stage_set_count.assert_any_call(0, 16, 9, 0) lib.ds_trigger_stage_set_value.assert_any_call(1, 16, b'X '*15+b'R', b'X '*15+b'X') def test_serial_mapping_and_data_channel_validation(self): trigger = dict(kind='serial', start='X'*16, stop='X'*16, clock='X'*14+'RX', data_channel=0, bits=8, value='X'*8+'10101010') validate_trigger(trigger, (0,1), 'buffer') lib = Mock() program_trigger(lib, trigger, 'buffer', lambda *_: None) lib.ds_trigger_set_mode.assert_called_once_with(2) lib.ds_trigger_set_stage.assert_called_once_with(3) lib.ds_trigger_stage_set_value.assert_any_call(2, 16, b'X '*15+b'0', b'X '*15+b'X') lib.ds_trigger_stage_set_count.assert_any_call(3, 16, 7, 0) with self.assertRaises(ValueError): validate_trigger(dict(trigger, data_channel=16), (0,1,16), 'buffer') def test_driver_errors_propagate(self): lib = Mock() def fail(*args): raise RuntimeError('driver failure') with self.assertRaisesRegex(RuntimeError, 'driver failure'): program_trigger(lib, None, 'stream', fail)