"""Pure, offline tests for the netfinder packet codec in progpib.discovery. Fixture bytes are taken from sampledata.txt, a captured Python 3 REPL session against real Prologix GPIB-ETHERNET hardware (all using the same sequence number, 30327 = 0x7677, reused across the whole session). """ from progpib.discovery import ( _HEADER_LEN, DeviceInfo, IpType, NfCommand, NfResult, _pack_assignment, _pack_header, _pack_identify, _unpack_assignment_reply, _unpack_identify_reply, _unpack_test_reply, ) SEQ = 30327 MAC = b"\x00!i\x01-\xaf" def test_pack_identify_matches_captured_bytes(): assert _pack_identify(SEQ) == b"Z\x00vw\xff\xff\xff\xff\xff\xff\x00\x00" def test_unpack_identify_reply_matches_captured_session(): reply = ( b"Z\x01vw\x00!i\x01-\xaf\x00\x00\x00%\x0572\x01\x00\x00\xc0\xa8\x00\xe5" b"\xff\xff\xff\x00\xc0\xa8\x00\x01\x01\x06\x06\x00\x01\x03\x00\x00" b"\x01\x03\x00\x00600" + b"\x00" * 29 ) assert len(reply) == 76 info = _unpack_identify_reply(reply) assert info == DeviceInfo( mac=MAC, mode=1, alert=0, ip_type=IpType.DYNAMIC, ip_address="192.168.0.229", netmask="255.255.255.0", gateway="192.168.0.1", app_version="1.6.6.0", boot_version="1.3.0.0", hw_version="1.3.0.0", name="600", uptime_days=37, uptime_hours=5, uptime_minutes=55, uptime_seconds=50, ) assert info.mac_str == "00:21:69:01:2d:af" def test_pack_assignment_matches_captured_bytes(): # This regression-pins the chr()->bytes([...]) fix: vendortools/nfutil.py's # MkAssignment raises struct.error on this exact call (see sampledata.txt), # since struct.pack's 'c' format needs a length-1 bytes object, not chr()'s str. packet = _pack_assignment( SEQ, MAC, IpType.DYNAMIC, "192.168.0.229", "255.255.255.0", "192.168.0.1", ) expected = ( b"Z\x02vw\x00!i\x01-\xaf\x00\x00\x00\x00\x00\x00\xc0\xa8\x00\xe5" b"\xff\xff\xff\x00\xc0\xa8\x00\x01" + b"\x00" * 32 ) assert len(expected) == 60 assert packet == expected def test_unpack_assignment_reply_matches_captured_bytes(): # This datagram is captured mid-session in sampledata.txt as a reply to # an earlier Assignment request (both used seq 30327): header id 0x03 = # ASSIGNMENT_REPLY, followed by a single 0x00 result byte = NF_SUCCESS. reply = b"Z\x03vw\x00!i\x01-\xaf\x00\x00\x00\x00\x00\x00" assert _unpack_assignment_reply(reply) == NfResult.SUCCESS def test_pack_and_unpack_test_reply_roundtrip(): # sampledata.txt has no clean captured TestReply (the byte string shown # there after a MkTest() call is actually a stale AssignmentReply still # sitting in the receive socket's buffer from an earlier command in that # REPL session -- see test_unpack_assignment_reply_matches_captured_bytes # above). So this is a synthetic round-trip instead of a captured fixture. text = "Prologix GPIB-ETHERNET Sim 1.0" body = text.encode("ascii").ljust(32, b"\x00") reply = _pack_header(NfCommand.TEST_REPLY, SEQ, MAC) + body assert len(reply) == _HEADER_LEN + 32 assert _unpack_test_reply(reply) == text