133 lines
4.8 KiB
Python
133 lines
4.8 KiB
Python
import pytest
|
|
|
|
from ecu_framework.lin.base import LinFrame
|
|
from ecu_framework.lin.babylin import BabyLinInterface
|
|
|
|
# Inject the pure-Python mock wrapper to run SDK adapter tests without hardware
|
|
from vendor import mock_babylin_wrapper as mock_bl
|
|
|
|
|
|
class _MockBytesOnly:
|
|
"""Shim exposing BLC_sendRawMasterRequest(bytes) only, to test bytes signature.
|
|
|
|
We wrap the existing mock but override BLC_sendRawMasterRequest to accept
|
|
only the bytes payload form. The response still uses the deterministic pattern
|
|
implied by the payload length (zeros are fine; we assert by length here).
|
|
"""
|
|
|
|
@staticmethod
|
|
def create_BabyLIN():
|
|
base = mock_bl.create_BabyLIN()
|
|
|
|
def bytes_only(channel, frame_id, payload):
|
|
# Delegate to the base mock's bytes variant by ensuring we pass bytes
|
|
if not isinstance(payload, (bytes, bytearray)):
|
|
raise TypeError("expected bytes payload")
|
|
return base.BLC_sendRawMasterRequest(channel, frame_id, bytes(payload))
|
|
|
|
# Monkey-patch the method to raise TypeError when a length is provided
|
|
def patched_raw_req(*args):
|
|
# Expected signature: (channel, frame_id, payload_bytes)
|
|
if len(args) != 3 or not isinstance(args[2], (bytes, bytearray)):
|
|
raise TypeError("bytes signature only")
|
|
return bytes_only(*args)
|
|
|
|
base.BLC_sendRawMasterRequest = patched_raw_req
|
|
return base
|
|
|
|
|
|
@pytest.mark.babylin
|
|
@pytest.mark.smoke
|
|
@pytest.mark.req_001
|
|
def test_babylin_sdk_adapter_with_mock_wrapper():
|
|
"""
|
|
Title: SDK Adapter - Send/Receive with Mock Wrapper
|
|
|
|
Description:
|
|
Validate that the BabyLIN SDK-based adapter can send and receive using
|
|
a mocked wrapper exposing BLC_* APIs. The mock implements loopback by
|
|
echoing transmitted frames into the receive queue.
|
|
|
|
Requirements: REQ-001
|
|
|
|
Test Steps:
|
|
1. Construct BabyLinInterface with injected mock wrapper
|
|
2. Connect (discovers port, opens, loads SDF, starts schedule)
|
|
3. Send a frame via BLC_mon_set_xmit
|
|
4. Receive the same frame via BLC_getNextFrameTimeout
|
|
5. Disconnect
|
|
|
|
Expected Result:
|
|
- Received frame matches sent frame (ID and payload)
|
|
"""
|
|
# Step 1-2: Create adapter with wrapper injection and connect
|
|
lin = BabyLinInterface(sdf_path="./vendor/Example.sdf", schedule_nr=0, wrapper_module=mock_bl)
|
|
lin.connect()
|
|
try:
|
|
# Step 3: Transmit a known payload on a chosen ID
|
|
tx = LinFrame(id=0x12, data=bytes([0xAA, 0x55, 0x01]))
|
|
lin.send(tx)
|
|
|
|
# Step 4: Receive from the mock's RX queue (loopback)
|
|
rx = lin.receive(timeout=0.1)
|
|
|
|
# Step 5: Validate ID and payload integrity
|
|
assert rx is not None, "Expected a frame from mock loopback"
|
|
assert rx.id == tx.id
|
|
assert rx.data == tx.data
|
|
finally:
|
|
# Always disconnect to leave the mock in a clean state
|
|
lin.disconnect()
|
|
|
|
|
|
@pytest.mark.babylin
|
|
@pytest.mark.smoke
|
|
@pytest.mark.req_001
|
|
@pytest.mark.parametrize("wrapper,expect_pattern", [
|
|
(mock_bl, True), # length signature available: expect deterministic pattern
|
|
(_MockBytesOnly, False), # bytes-only signature: expect zeros of requested length
|
|
])
|
|
def test_babylin_master_request_with_mock_wrapper(wrapper, expect_pattern):
|
|
"""
|
|
Title: SDK Adapter - Master Request using Mock Wrapper
|
|
|
|
Description:
|
|
Verify that request() prefers the SDK's BLC_sendRawMasterRequest when
|
|
available. The mock wrapper enqueues a deterministic response where
|
|
data[i] = (id + i) & 0xFF, allowing predictable assertions.
|
|
|
|
Requirements: REQ-001
|
|
|
|
Test Steps:
|
|
1. Construct BabyLinInterface with injected mock wrapper
|
|
2. Connect (mock open/initialize)
|
|
3. Issue a master request for a specific ID and length
|
|
4. Receive the response frame
|
|
5. Validate ID and deterministic payload pattern
|
|
|
|
Expected Result:
|
|
- Response frame ID matches request ID
|
|
- Response data length matches requested length
|
|
- Response data follows deterministic pattern
|
|
"""
|
|
# Step 1-2: Initialize mock-backed adapter
|
|
lin = BabyLinInterface(wrapper_module=wrapper)
|
|
lin.connect()
|
|
try:
|
|
# Step 3: Request 4 bytes for ID 0x22
|
|
req_id = 0x22
|
|
length = 4
|
|
rx = lin.request(id=req_id, length=length, timeout=0.1)
|
|
|
|
# Step 4-5: Validate response
|
|
assert rx is not None, "Expected a response from mock master request"
|
|
assert rx.id == req_id
|
|
if expect_pattern:
|
|
# length-signature mock returns deterministic pattern
|
|
assert rx.data == bytes(((req_id + i) & 0xFF) for i in range(length))
|
|
else:
|
|
# bytes-only mock returns exactly the bytes we sent (zeros of requested length)
|
|
assert rx.data == bytes([0] * length)
|
|
finally:
|
|
lin.disconnect()
|