Skip to content

Commit 87d1de3

Browse files
test: update new test cases for bridge polling
Test that bridge polling discovers downstream endpoints and creates endpoints d-bus object. Test that polling stops once downstream endpoint is discovered. and continues unless endpoint reponds to send polling command GET_ENDPOINT_ID. Test that once brige endpoint is removed, downstream endpoints associated to the brige also gets removed too. Signed-off-by: Faizan Ali <faizana@nvidia.com>
1 parent aaea0a6 commit 87d1de3

File tree

1 file changed

+204
-0
lines changed

1 file changed

+204
-0
lines changed

tests/test_mctpd.py

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1376,3 +1376,207 @@ async def test_register_vdm_type_support_errors(dbus, mctpd):
13761376
with pytest.raises(asyncdbus.errors.DBusError) as ex:
13771377
await mctp.call_register_vdm_type_support(0x00, v_type, 0x0001)
13781378
assert str(ex.value) == "VDM type already registered"
1379+
1380+
""" Test that we use endpoint poll interval from the config and
1381+
that we discover bridged endpoints via polling"""
1382+
async def test_bridged_endpoint_poll(dbus, sysnet, nursery, autojump_clock):
1383+
poll_interval = 2500
1384+
config = f"""
1385+
[bus-owner]
1386+
endpoint_poll_ms = {poll_interval}
1387+
"""
1388+
1389+
mctpd = MctpdWrapper(dbus, sysnet, config = config)
1390+
await mctpd.start_mctpd(nursery)
1391+
1392+
iface = mctpd.system.interfaces[0]
1393+
ep = mctpd.network.endpoints[0]
1394+
mctp = await mctpd_mctp_iface_obj(dbus, iface)
1395+
1396+
bridged_ep = [
1397+
Endpoint(iface, bytes(), types = [0, 1]),
1398+
Endpoint(iface, bytes(), types = [0, 1])
1399+
]
1400+
for bep in bridged_ep:
1401+
mctpd.network.add_endpoint(bep)
1402+
ep.add_bridged_ep(bep)
1403+
1404+
(eid, _, path, new) = await mctp.call_assign_endpoint(ep.lladdr)
1405+
assert new
1406+
1407+
mctp_obj = await dbus.get_proxy_object(MCTPD_C, MCTPD_MCTP_P)
1408+
mctp_objmgr = await mctp_obj.get_interface(DBUS_OBJECT_MANAGER_I)
1409+
endpoint_added = trio.Semaphore(initial_value=0)
1410+
1411+
# We expect two bridged endpoints to be discovered
1412+
expected_bridged_eps = len(bridged_ep)
1413+
bridged_endpoints_found = []
1414+
1415+
def ep_added(ep_path, content):
1416+
if MCTPD_ENDPOINT_I in content:
1417+
bridged_endpoints_found.append(ep_path)
1418+
endpoint_added.release()
1419+
1420+
await mctp_objmgr.on_interfaces_added(ep_added)
1421+
1422+
# Wait for all expected bridged endpoints to be discovered
1423+
with trio.move_on_after(poll_interval / 1000 * 2) as expected:
1424+
for i in range(expected_bridged_eps):
1425+
await endpoint_added.acquire()
1426+
1427+
# Verify we found all expected bridged endpoints
1428+
assert not expected.cancelled_caught, "Timeout waiting for bridged endpoints"
1429+
assert len(bridged_endpoints_found) == expected_bridged_eps
1430+
1431+
res = await mctpd.stop_mctpd()
1432+
assert res == 0
1433+
1434+
""" Test that all downstream endpoints are removed when the bridge
1435+
endpoint is removed"""
1436+
async def test_bridged_endpoint_remove(dbus, sysnet, nursery, autojump_clock):
1437+
poll_interval = 2500
1438+
config = f"""
1439+
[bus-owner]
1440+
endpoint_poll_ms = {poll_interval}
1441+
"""
1442+
1443+
mctpd = MctpdWrapper(dbus, sysnet, config = config)
1444+
await mctpd.start_mctpd(nursery)
1445+
1446+
iface = mctpd.system.interfaces[0]
1447+
ep = mctpd.network.endpoints[0]
1448+
mctp = await mctpd_mctp_iface_obj(dbus, iface)
1449+
1450+
bridged_ep = [
1451+
Endpoint(iface, bytes(), types = [0, 1]),
1452+
Endpoint(iface, bytes(), types = [0, 1])
1453+
]
1454+
for bep in bridged_ep:
1455+
mctpd.network.add_endpoint(bep)
1456+
ep.add_bridged_ep(bep)
1457+
1458+
(eid, _, path, new) = await mctp.call_assign_endpoint(ep.lladdr)
1459+
assert new
1460+
1461+
# Wait for the bridged endpoints to be discovered
1462+
await trio.sleep(poll_interval / 1000)
1463+
removed = trio.Semaphore(initial_value = 0)
1464+
removed_eps = []
1465+
1466+
# Capture the removed endpoints
1467+
def ep_removed(ep_path, interfaces):
1468+
if MCTPD_ENDPOINT_I in interfaces:
1469+
removed.release()
1470+
removed_eps.append(ep_path)
1471+
1472+
mctp_obj = await dbus.get_proxy_object(MCTPD_C, MCTPD_MCTP_P)
1473+
mctp_objmgr = await mctp_obj.get_interface(DBUS_OBJECT_MANAGER_I)
1474+
await mctp_objmgr.on_interfaces_removed(ep_removed)
1475+
1476+
# Remove the bridge endpoint
1477+
bridge_obj = await mctpd_mctp_endpoint_control_obj(dbus, path)
1478+
await bridge_obj.call_remove()
1479+
1480+
# Assert that all downstream endpoints were removed
1481+
assert len(removed_eps) == (len(bridged_ep) + 1)
1482+
res = await mctpd.stop_mctpd()
1483+
assert res == 0
1484+
1485+
""" Test that polling stops once endponit has been discovered """
1486+
async def test_bridged_endpoint_poll_stop(dbus, sysnet, nursery, autojump_clock):
1487+
poll_interval = 2500
1488+
config = f"""
1489+
[bus-owner]
1490+
endpoint_poll_ms = {poll_interval}
1491+
"""
1492+
1493+
mctpd = MctpdWrapper(dbus, sysnet, config = config)
1494+
await mctpd.start_mctpd(nursery)
1495+
1496+
iface = mctpd.system.interfaces[0]
1497+
ep = mctpd.network.endpoints[0]
1498+
mctp = await mctpd_mctp_iface_obj(dbus, iface)
1499+
poll_count = 0
1500+
1501+
class BridgedEndpoint(Endpoint):
1502+
async def handle_mctp_control(self, sock, src_addr, msg):
1503+
flags, opcode = msg[0:2]
1504+
if opcode == 0x2: # Get Endpoint ID
1505+
nonlocal poll_count
1506+
poll_count += 1
1507+
return await super().handle_mctp_control(sock, src_addr, msg)
1508+
1509+
bridged_ep = BridgedEndpoint(iface, bytes(), types = [0, 1])
1510+
mctpd.network.add_endpoint(bridged_ep)
1511+
ep.add_bridged_ep(bridged_ep)
1512+
1513+
(eid, _, path, new) = await mctp.call_assign_endpoint(ep.lladdr)
1514+
assert new
1515+
1516+
mctp_obj = await dbus.get_proxy_object(MCTPD_C, MCTPD_MCTP_P)
1517+
mctp_objmgr = await mctp_obj.get_interface(DBUS_OBJECT_MANAGER_I)
1518+
endpoint_added = trio.Semaphore(initial_value=0)
1519+
poll_count_by_discovery = 0
1520+
1521+
def ep_added(ep_path, content):
1522+
if MCTPD_ENDPOINT_I in content:
1523+
nonlocal poll_count_by_discovery
1524+
poll_count_by_discovery = poll_count
1525+
endpoint_added.release()
1526+
1527+
await mctp_objmgr.on_interfaces_added(ep_added)
1528+
1529+
# Wait longer than the poll interval for the bridged endpoint
1530+
# to be discovered
1531+
await trio.sleep(poll_interval / 1000)
1532+
1533+
# We should have only poll until the discovery thus count should
1534+
# be the same even after longer wait.
1535+
assert poll_count == poll_count_by_discovery
1536+
1537+
res = await mctpd.stop_mctpd()
1538+
assert res == 0
1539+
1540+
""" Test that polling continues until the endpoint is discovered """
1541+
async def test_bridged_endpoint_poll_continue(dbus, sysnet, nursery, autojump_clock):
1542+
poll_interval = 2500
1543+
config = f"""
1544+
[bus-owner]
1545+
endpoint_poll_ms = {poll_interval}
1546+
"""
1547+
1548+
mctpd = MctpdWrapper(dbus, sysnet, config = config)
1549+
await mctpd.start_mctpd(nursery)
1550+
1551+
iface = mctpd.system.interfaces[0]
1552+
ep = mctpd.network.endpoints[0]
1553+
mctp = await mctpd_mctp_iface_obj(dbus, iface)
1554+
poll_count = 0
1555+
1556+
class BridgedEndpoint(Endpoint):
1557+
async def handle_mctp_control(self, sock, src_addr, msg):
1558+
flags, opcode = msg[0:2]
1559+
# dont respond to simiulate device not accessible
1560+
# but increment poll count for the Get Endpoint ID
1561+
if opcode == 0x2: # Get Endpoint ID
1562+
nonlocal poll_count
1563+
poll_count += 1
1564+
return None
1565+
1566+
bridged_ep = BridgedEndpoint(iface, bytes(), types = [0, 1])
1567+
mctpd.network.add_endpoint(bridged_ep)
1568+
ep.add_bridged_ep(bridged_ep)
1569+
1570+
(eid, _, path, new) = await mctp.call_assign_endpoint(ep.lladdr)
1571+
assert new
1572+
1573+
# Wait for sometime to continue polling
1574+
await trio.sleep(poll_interval / 1000)
1575+
1576+
poll_count_before = poll_count
1577+
# Wait more to see if poll count increments
1578+
await trio.sleep(1)
1579+
assert poll_count > poll_count_before
1580+
1581+
res = await mctpd.stop_mctpd()
1582+
assert res == 0

0 commit comments

Comments
 (0)