summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorhathach <[email protected]>2026-03-06 17:56:05 +0700
committerhathach <[email protected]>2026-03-06 17:56:05 +0700
commitaeb121f94cb9c5ecb220e2cf7e9e6b53e5d858b1 (patch)
tree755007599792d1758249ece23358618f6184a39d /test
parent73cd53129529f2dce70072953bfd50ec9dc6b8ea (diff)
add hil test, update readme
Diffstat (limited to 'test')
-rwxr-xr-xtest/hil/hil_test.py109
1 files changed, 109 insertions, 0 deletions
diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py
index 757456806..46cb79e01 100755
--- a/test/hil/hil_test.py
+++ b/test/hil/hil_test.py
@@ -166,6 +166,32 @@ def open_mtp_dev(uid):
return None
+def get_printer_dev(id, vendor_str, product_str, ifnum):
+ """Find /dev/usb/lpX by matching USB serial, vendor, product, and interface number via sysfs"""
+ vendor_str = vendor_str.replace(' ', '_') if vendor_str else ''
+ product_str = product_str.replace(' ', '_') if product_str else ''
+ for lp in glob.glob('/sys/class/usbmisc/lp*'):
+ try:
+ sn = open(f'{lp}/device/../serial').read().strip()
+ if sn == id:
+ return f'/dev/usb/{os.path.basename(lp)}'
+ except (FileNotFoundError, PermissionError, ValueError):
+ pass
+ return None
+
+
+def open_printer_dev(id, vendor_str, product_str, ifnum):
+ """Wait for printer device to enumerate and return its path"""
+ timeout = ENUM_TIMEOUT
+ while timeout > 0:
+ lp_dev = get_printer_dev(id, vendor_str, product_str, ifnum)
+ if lp_dev and os.path.exists(lp_dev):
+ return lp_dev
+ time.sleep(1)
+ timeout -= 1
+ assert False, f'Printer device not found for {id} if{ifnum:02d}'
+
+
# -------------------------------------------------------------
# Flashing firmware
# -------------------------------------------------------------
@@ -552,6 +578,88 @@ def test_device_hid_composite_freertos(id):
pass
+def test_device_printer_to_cdc(board):
+ import threading
+
+ uid = board['uid']
+
+ # Wait for CDC port and printer device
+ cdc_port = get_serial_dev(uid, 'TinyUSB', "TinyUSB_Device", 0)
+ ser = open_serial_dev(cdc_port)
+ lp_dev = open_printer_dev(uid, 'TinyUSB', 'TinyUSB_Device', 2)
+
+ # Test 0: Verify IEEE 1284 Device ID from sysfs
+ expected_id = 'MFG:TinyUSB;MDL:Printer to CDC;CMD:PS;CLS:PRINTER;'
+ lp_name = os.path.basename(lp_dev)
+ sysfs_id_path = f'/sys/class/usbmisc/{lp_name}/device/ieee1284_id'
+ if os.path.exists(sysfs_id_path):
+ with open(sysfs_id_path) as f:
+ ieee1284_id = f.read().strip()
+ if ieee1284_id:
+ assert ieee1284_id == expected_id, (f'IEEE 1284 ID mismatch:\n'
+ f' expected: {expected_id}\n got: {ieee1284_id}')
+
+ def rand_ascii(length):
+ return "".join(random.choices(string.ascii_letters + string.digits, k=length)).encode("ascii")
+
+ sizes = [32, 64, 128, 256, 512, random.randint(2000, 5000)]
+
+ # flush any stale data
+ ser.reset_input_buffer()
+
+ # Test 1: Printer -> CDC with multiple sizes
+ for size in sizes:
+ test_data = rand_ascii(size)
+ with open(lp_dev, 'wb') as lp:
+ lp.write(test_data)
+ lp.flush()
+ rd = b''
+ while len(rd) < size:
+ chunk = ser.read(size - len(rd))
+ assert chunk, f'Printer->CDC timeout at {len(rd)}/{size} bytes'
+ rd += chunk
+ assert rd == test_data, (f'Printer->CDC wrong data ({size} bytes):\n'
+ f' expected: {test_data[:64]}\n received: {rd[:64]}')
+
+ # Test 2: CDC -> Printer with multiple sizes
+ # Use a thread to read from printer since /dev/usb/lp read blocks
+ for size in sizes:
+ test_data = rand_ascii(size)
+ rd_result = [b'', None] # [data, error]
+
+ def lp_reader():
+ try:
+ rd = b''
+ with open(lp_dev, 'rb') as lp:
+ while len(rd) < size:
+ chunk = lp.read(size - len(rd))
+ if not chunk:
+ break
+ rd += chunk
+ rd_result[0] = rd
+ except Exception as e:
+ rd_result[1] = e
+
+ reader = threading.Thread(target=lp_reader, daemon=True)
+ reader.start()
+
+ # Write to CDC in chunks
+ offset = 0
+ while offset < size:
+ chunk_size = min(random.randint(1, 64), size - offset)
+ ser.write(test_data[offset:offset + chunk_size])
+ ser.flush()
+ offset += chunk_size
+
+ reader.join(timeout=10)
+ assert not reader.is_alive(), f'CDC->Printer timeout ({size} bytes)'
+ assert rd_result[1] is None, f'CDC->Printer read error: {rd_result[1]}'
+ assert rd_result[0] == test_data, (f'CDC->Printer wrong data ({size} bytes):\n'
+ f' expected: {test_data[:64]}\n received: {rd_result[0][:64]}')
+
+ ser.close()
+
+
def test_device_mtp(board):
uid = board['uid']
@@ -623,6 +731,7 @@ device_tests = [
'device/dfu_runtime',
'device/cdc_msc_freertos',
'device/hid_boot_interface',
+ 'device/printer_to_cdc',
# 'device/mtp'
]