"""Wire vectors and DSView API boundary tests; no sigrok installation needed.""" import binascii import importlib from pathlib import Path import struct import sys import types import tempfile import importlib.util import unittest ROOT = Path(__file__).resolve().parents[1] SPEC = importlib.util.spec_from_file_location('dsview_build', ROOT / 'build.py') BUILD = importlib.util.module_from_spec(SPEC) SPEC.loader.exec_module(BUILD) RUNTIME = tempfile.TemporaryDirectory() BUILD.package_decoders(Path(RUNTIME.name)) (Path(RUNTIME.name) / 'decoders/common/__init__.py').write_text('') class FakeDecoder: def has_channel(self, channel): return channel < 2 def register(self, kind): return kind def put(self, ss, es, output, data): self.emitted.append((ss, es, output, data)) stub = types.ModuleType('sigrokdecode') stub.Decoder = FakeDecoder stub.OUTPUT_ANN, stub.OUTPUT_PYTHON, stub.SRD_CONF_SAMPLERATE = 0, 1, 2 previous = sys.modules.get('sigrokdecode') sys.modules['sigrokdecode'] = stub sys.path.insert(0, str(Path(RUNTIME.name) / 'decoders')) try: uart = importlib.import_module('set_uart.pd') wire = importlib.import_module('common.setgui_decoders.set_uart') can = importlib.import_module('set_can.pd') cancore = importlib.import_module('common.setgui_decoders.set_can') pm = importlib.import_module('pm35_uart.pd') gate = importlib.import_module('gate_driver_timing.pd') pair_decoder = importlib.import_module('transistor_pair.pd') pmcore = importlib.import_module('common.setgui_decoders.pm35_uart') finally: sys.path.pop(0) if previous is None: del sys.modules['sigrokdecode'] else: sys.modules['sigrokdecode'] = previous PING = bytes.fromhex('A5 5A 02 08 01 00 00 00 2A 00 34 12 00 00 33 EC 33 04') BRIDGE = bytes.fromhex('AA 55 08 01 01 67 45 23 01 AA BB FE 14') def crc32_frame(header, payload=b''): data = header + payload return data + struct.pack(' Vin2: 30.0 ns', text) self.assertIn('FAIL: Vin2 active', text) self.assertIn('duty', text) self.assertNotIn('ACK', text) self.assertTrue(any(e[3][0] == 3 for e in decoder.emitted)) decoder.reset() self.assertIsNone(decoder.checker) def test_status_only_and_pair_requires_two_inputs(self): decoder = instance(gate) decoder.has_channel = lambda channel: channel == 1 samples = iter([(10, 1), (1010, 0)]) def wait(conditions): self.assertEqual(conditions, [{1: 'e'}]) decoder.samplenum, status = next(samples) decoder.matched = 1 return (255, status, 255) decoder.wait = wait with self.assertRaises(StopIteration): decoder.decode() self.assertEqual(len(decoder.emitted), 1) decoder = instance(pair_decoder) decoder.has_channel = lambda channel: channel == 0 with self.assertRaisesRegex(ValueError, 'Vin1 and Vin2'): decoder.decode() def test_missing_ack_timer_emits_error(self): decoder = instance(gate) decoder.metadata(2, 100_000_000) decoder.samplenum = 0 calls = [] def wait(conditions): calls.append(conditions) if len(calls) == 1: decoder.samplenum, decoder.matched = 100, 1 elif len(calls) == 2: decoder.samplenum += conditions[2]['skip'] decoder.matched = 4 else: raise StopIteration return 1, 0 decoder.wait = wait with self.assertRaises(StopIteration): decoder.decode() self.assertEqual([item[3][0] for item in decoder.emitted], [0, 4]) def test_packaged_core_matches_canonical_templates(self): canonical = ROOT.parents[1] / 'python/logic_analyzer/decoders' packaged = Path(RUNTIME.name) / 'decoders/common/setgui_decoders' for name in ('gate_timing', 'transistor_pair', 'set_uart', 'set_can', 'pm35_uart'): self.assertEqual((canonical / (name + '.py')).read_bytes(), (packaged / (name + '.py')).read_bytes()) if __name__ == '__main__': unittest.main()