Skip to content

Commit 834c3fc

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 3cce159 commit 834c3fc

File tree

1 file changed

+202
-0
lines changed

1 file changed

+202
-0
lines changed

tests/test_mctpd.py

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,3 +1506,205 @@ async def handle_mctp_control(self, sock, addr, data):
15061506
# exit mctpd
15071507
res = await mctpd.stop_mctpd()
15081508
assert res == 0
1509+
""" Test that we use endpoint poll interval from the config and
1510+
that we discover bridged endpoints via polling"""
1511+
async def test_bridged_endpoint_poll(dbus, sysnet, nursery, autojump_clock):
1512+
poll_interval = 2500
1513+
config = f"""
1514+
[bus-owner]
1515+
endpoint_poll_ms = {poll_interval}
1516+
"""
1517+
1518+
mctpd = MctpdWrapper(dbus, sysnet, config = config)
1519+
await mctpd.start_mctpd(nursery)
1520+
1521+
iface = mctpd.system.interfaces[0]
1522+
ep = mctpd.network.endpoints[0]
1523+
mctp = await mctpd_mctp_iface_obj(dbus, iface)
1524+
1525+
bridged_ep = [
1526+
Endpoint(iface, bytes(), types = [0, 1]),
1527+
Endpoint(iface, bytes(), types = [0, 1])
1528+
]
1529+
for bep in bridged_ep:
1530+
mctpd.network.add_endpoint(bep)
1531+
ep.add_bridged_ep(bep)
1532+
1533+
mctp_obj = await dbus.get_proxy_object(MCTPD_C, MCTPD_MCTP_P)
1534+
mctp_objmgr = await mctp_obj.get_interface(DBUS_OBJECT_MANAGER_I)
1535+
endpoint_added = trio.Semaphore(initial_value=0)
1536+
1537+
# We expect two bridged endpoints to be discovered
1538+
expected_bridged_eps = len(bridged_ep)
1539+
bridged_endpoints_found = []
1540+
1541+
def ep_added(ep_path, content):
1542+
if MCTPD_ENDPOINT_I in content:
1543+
bridged_endpoints_found.append(ep_path)
1544+
endpoint_added.release()
1545+
1546+
await mctp_objmgr.on_interfaces_added(ep_added)
1547+
(eid, _, path, new) = await mctp.call_assign_endpoint(ep.lladdr)
1548+
assert new
1549+
1550+
# Wait for all expected bridged endpoints to be discovered
1551+
with trio.move_on_after(poll_interval / 1000 * 2) as expected:
1552+
for i in range(expected_bridged_eps):
1553+
await endpoint_added.acquire()
1554+
1555+
# Verify we found all expected bridged endpoints
1556+
assert not expected.cancelled_caught, "Timeout waiting for bridged endpoints"
1557+
assert len(bridged_endpoints_found) == expected_bridged_eps
1558+
1559+
res = await mctpd.stop_mctpd()
1560+
assert res == 0
1561+
1562+
""" Test that all downstream endpoints are removed when the bridge
1563+
endpoint is removed"""
1564+
async def test_bridged_endpoint_remove(dbus, sysnet, nursery, autojump_clock):
1565+
poll_interval = 2500
1566+
config = f"""
1567+
[bus-owner]
1568+
endpoint_poll_ms = {poll_interval}
1569+
"""
1570+
1571+
mctpd = MctpdWrapper(dbus, sysnet, config = config)
1572+
await mctpd.start_mctpd(nursery)
1573+
1574+
iface = mctpd.system.interfaces[0]
1575+
ep = mctpd.network.endpoints[0]
1576+
mctp = await mctpd_mctp_iface_obj(dbus, iface)
1577+
1578+
bridged_ep = [
1579+
Endpoint(iface, bytes(), types = [0, 1]),
1580+
Endpoint(iface, bytes(), types = [0, 1])
1581+
]
1582+
for bep in bridged_ep:
1583+
mctpd.network.add_endpoint(bep)
1584+
ep.add_bridged_ep(bep)
1585+
1586+
(eid, _, path, new) = await mctp.call_assign_endpoint(ep.lladdr)
1587+
assert new
1588+
1589+
# Wait for the bridged endpoints to be discovered
1590+
await trio.sleep((poll_interval * 2) / 1000)
1591+
removed = trio.Semaphore(initial_value = 0)
1592+
removed_eps = []
1593+
1594+
# Capture the removed endpoints
1595+
def ep_removed(ep_path, interfaces):
1596+
if MCTPD_ENDPOINT_I in interfaces:
1597+
removed.release()
1598+
removed_eps.append(ep_path)
1599+
1600+
mctp_obj = await dbus.get_proxy_object(MCTPD_C, MCTPD_MCTP_P)
1601+
mctp_objmgr = await mctp_obj.get_interface(DBUS_OBJECT_MANAGER_I)
1602+
await mctp_objmgr.on_interfaces_removed(ep_removed)
1603+
1604+
# Remove the bridge endpoint
1605+
bridge_obj = await mctpd_mctp_endpoint_control_obj(dbus, path)
1606+
await bridge_obj.call_remove()
1607+
1608+
# Assert that all downstream endpoints were removed
1609+
assert len(removed_eps) == (len(bridged_ep) + 1)
1610+
res = await mctpd.stop_mctpd()
1611+
assert res == 0
1612+
1613+
""" Test that polling stops once endponit has been discovered """
1614+
async def test_bridged_endpoint_poll_stop(dbus, sysnet, nursery, autojump_clock):
1615+
poll_interval = 2500
1616+
config = f"""
1617+
[bus-owner]
1618+
endpoint_poll_ms = {poll_interval}
1619+
"""
1620+
1621+
mctpd = MctpdWrapper(dbus, sysnet, config = config)
1622+
await mctpd.start_mctpd(nursery)
1623+
1624+
iface = mctpd.system.interfaces[0]
1625+
ep = mctpd.network.endpoints[0]
1626+
mctp = await mctpd_mctp_iface_obj(dbus, iface)
1627+
poll_count = 0
1628+
1629+
class BridgedEndpoint(Endpoint):
1630+
async def handle_mctp_control(self, sock, src_addr, msg):
1631+
flags, opcode = msg[0:2]
1632+
if opcode == 0x2: # Get Endpoint ID
1633+
nonlocal poll_count
1634+
poll_count += 1
1635+
return await super().handle_mctp_control(sock, src_addr, msg)
1636+
1637+
bridged_ep = BridgedEndpoint(iface, bytes(), types = [0, 1])
1638+
mctpd.network.add_endpoint(bridged_ep)
1639+
ep.add_bridged_ep(bridged_ep)
1640+
1641+
(eid, _, path, new) = await mctp.call_assign_endpoint(ep.lladdr)
1642+
assert new
1643+
1644+
mctp_obj = await dbus.get_proxy_object(MCTPD_C, MCTPD_MCTP_P)
1645+
mctp_objmgr = await mctp_obj.get_interface(DBUS_OBJECT_MANAGER_I)
1646+
endpoint_added = trio.Semaphore(initial_value=0)
1647+
poll_count_by_discovery = 0
1648+
1649+
def ep_added(ep_path, content):
1650+
if MCTPD_ENDPOINT_I in content:
1651+
nonlocal poll_count_by_discovery
1652+
poll_count_by_discovery = poll_count
1653+
endpoint_added.release()
1654+
1655+
await mctp_objmgr.on_interfaces_added(ep_added)
1656+
1657+
# Wait longer than the poll interval for the bridged endpoint
1658+
# to be discovered
1659+
await trio.sleep(poll_interval / 1000)
1660+
1661+
# We should have only poll until the discovery thus count should
1662+
# be the same even after longer wait.
1663+
assert poll_count == poll_count_by_discovery
1664+
1665+
res = await mctpd.stop_mctpd()
1666+
assert res == 0
1667+
1668+
""" Test that polling continues until the endpoint is discovered """
1669+
async def test_bridged_endpoint_poll_continue(dbus, sysnet, nursery, autojump_clock):
1670+
poll_interval = 2500
1671+
config = f"""
1672+
[bus-owner]
1673+
endpoint_poll_ms = {poll_interval}
1674+
"""
1675+
1676+
mctpd = MctpdWrapper(dbus, sysnet, config = config)
1677+
await mctpd.start_mctpd(nursery)
1678+
1679+
iface = mctpd.system.interfaces[0]
1680+
ep = mctpd.network.endpoints[0]
1681+
mctp = await mctpd_mctp_iface_obj(dbus, iface)
1682+
poll_count = 0
1683+
1684+
class BridgedEndpoint(Endpoint):
1685+
async def handle_mctp_control(self, sock, src_addr, msg):
1686+
flags, opcode = msg[0:2]
1687+
# dont respond to simiulate device not accessible
1688+
# but increment poll count for the Get Endpoint ID
1689+
if opcode == 0x2: # Get Endpoint ID
1690+
nonlocal poll_count
1691+
poll_count += 1
1692+
return None
1693+
1694+
bridged_ep = BridgedEndpoint(iface, bytes(), types = [0, 1])
1695+
mctpd.network.add_endpoint(bridged_ep)
1696+
ep.add_bridged_ep(bridged_ep)
1697+
1698+
(eid, _, path, new) = await mctp.call_assign_endpoint(ep.lladdr)
1699+
assert new
1700+
1701+
# Wait for sometime to continue polling
1702+
await trio.sleep(poll_interval / 1000)
1703+
1704+
poll_count_before = poll_count
1705+
# Wait more to see if poll count increments
1706+
await trio.sleep(1)
1707+
assert poll_count > poll_count_before
1708+
1709+
res = await mctpd.stop_mctpd()
1710+
assert res == 0

0 commit comments

Comments
 (0)