Skip to content

Commit 882cb34

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 0d1af77 commit 882cb34

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
@@ -1290,3 +1290,207 @@ async def test_get_message_types(dbus, mctpd):
12901290
cmd = MCTPControlCommand(True, 0, 0x04, bytes([0x05]))
12911291
rsp = await ep.send_control(mctpd.network.mctp_socket, cmd)
12921292
assert rsp.hex(' ') == '00 04 00 01 f4 f3 f2 f1'
1293+
1294+
""" Test that we use endpoint poll interval from the config and
1295+
that we discover bridged endpoints via polling"""
1296+
async def test_bridged_endpoint_poll(dbus, sysnet, nursery, autojump_clock):
1297+
poll_interval = 2500
1298+
config = f"""
1299+
[bus-owner]
1300+
endpoint_poll_ms = {poll_interval}
1301+
"""
1302+
1303+
mctpd = MctpdWrapper(dbus, sysnet, config = config)
1304+
await mctpd.start_mctpd(nursery)
1305+
1306+
iface = mctpd.system.interfaces[0]
1307+
ep = mctpd.network.endpoints[0]
1308+
mctp = await mctpd_mctp_iface_obj(dbus, iface)
1309+
1310+
bridged_ep = [
1311+
Endpoint(iface, bytes(), types = [0, 1]),
1312+
Endpoint(iface, bytes(), types = [0, 1])
1313+
]
1314+
for bep in bridged_ep:
1315+
mctpd.network.add_endpoint(bep)
1316+
ep.add_bridged_ep(bep)
1317+
1318+
(eid, _, path, new) = await mctp.call_assign_endpoint(ep.lladdr)
1319+
assert new
1320+
1321+
mctp_obj = await dbus.get_proxy_object(MCTPD_C, MCTPD_MCTP_P)
1322+
mctp_objmgr = await mctp_obj.get_interface(DBUS_OBJECT_MANAGER_I)
1323+
endpoint_added = trio.Semaphore(initial_value=0)
1324+
1325+
# We expect two bridged endpoints to be discovered
1326+
expected_bridged_eps = len(bridged_ep)
1327+
bridged_endpoints_found = []
1328+
1329+
def ep_added(ep_path, content):
1330+
if MCTPD_ENDPOINT_I in content:
1331+
bridged_endpoints_found.append(ep_path)
1332+
endpoint_added.release()
1333+
1334+
await mctp_objmgr.on_interfaces_added(ep_added)
1335+
1336+
# Wait for all expected bridged endpoints to be discovered
1337+
with trio.move_on_after(poll_interval / 1000 * 2) as expected:
1338+
for i in range(expected_bridged_eps):
1339+
await endpoint_added.acquire()
1340+
1341+
# Verify we found all expected bridged endpoints
1342+
assert not expected.cancelled_caught, "Timeout waiting for bridged endpoints"
1343+
assert len(bridged_endpoints_found) == expected_bridged_eps
1344+
1345+
res = await mctpd.stop_mctpd()
1346+
assert res == 0
1347+
1348+
""" Test that all downstream endpoints are removed when the bridge
1349+
endpoint is removed"""
1350+
async def test_bridged_endpoint_remove(dbus, sysnet, nursery, autojump_clock):
1351+
poll_interval = 2500
1352+
config = f"""
1353+
[bus-owner]
1354+
endpoint_poll_ms = {poll_interval}
1355+
"""
1356+
1357+
mctpd = MctpdWrapper(dbus, sysnet, config = config)
1358+
await mctpd.start_mctpd(nursery)
1359+
1360+
iface = mctpd.system.interfaces[0]
1361+
ep = mctpd.network.endpoints[0]
1362+
mctp = await mctpd_mctp_iface_obj(dbus, iface)
1363+
1364+
bridged_ep = [
1365+
Endpoint(iface, bytes(), types = [0, 1]),
1366+
Endpoint(iface, bytes(), types = [0, 1])
1367+
]
1368+
for bep in bridged_ep:
1369+
mctpd.network.add_endpoint(bep)
1370+
ep.add_bridged_ep(bep)
1371+
1372+
(eid, _, path, new) = await mctp.call_assign_endpoint(ep.lladdr)
1373+
assert new
1374+
1375+
# Wait for the bridged endpoints to be discovered
1376+
await trio.sleep(poll_interval / 1000)
1377+
removed = trio.Semaphore(initial_value = 0)
1378+
removed_eps = []
1379+
1380+
# Capture the removed endpoints
1381+
def ep_removed(ep_path, interfaces):
1382+
if MCTPD_ENDPOINT_I in interfaces:
1383+
removed.release()
1384+
removed_eps.append(ep_path)
1385+
1386+
mctp_obj = await dbus.get_proxy_object(MCTPD_C, MCTPD_MCTP_P)
1387+
mctp_objmgr = await mctp_obj.get_interface(DBUS_OBJECT_MANAGER_I)
1388+
await mctp_objmgr.on_interfaces_removed(ep_removed)
1389+
1390+
# Remove the bridge endpoint
1391+
bridge_obj = await mctpd_mctp_endpoint_control_obj(dbus, path)
1392+
await bridge_obj.call_remove()
1393+
1394+
# Assert that all downstream endpoints were removed
1395+
assert len(removed_eps) == (len(bridged_ep) + 1)
1396+
res = await mctpd.stop_mctpd()
1397+
assert res == 0
1398+
1399+
""" Test that polling stops once endponit has been discovered """
1400+
async def test_bridged_endpoint_poll_stop(dbus, sysnet, nursery, autojump_clock):
1401+
poll_interval = 2500
1402+
config = f"""
1403+
[bus-owner]
1404+
endpoint_poll_ms = {poll_interval}
1405+
"""
1406+
1407+
mctpd = MctpdWrapper(dbus, sysnet, config = config)
1408+
await mctpd.start_mctpd(nursery)
1409+
1410+
iface = mctpd.system.interfaces[0]
1411+
ep = mctpd.network.endpoints[0]
1412+
mctp = await mctpd_mctp_iface_obj(dbus, iface)
1413+
poll_count = 0
1414+
1415+
class BridgedEndpoint(Endpoint):
1416+
async def handle_mctp_control(self, sock, src_addr, msg):
1417+
flags, opcode = msg[0:2]
1418+
if opcode == 0x2: # Get Endpoint ID
1419+
nonlocal poll_count
1420+
poll_count += 1
1421+
return await super().handle_mctp_control(sock, src_addr, msg)
1422+
1423+
bridged_ep = BridgedEndpoint(iface, bytes(), types = [0, 1])
1424+
mctpd.network.add_endpoint(bridged_ep)
1425+
ep.add_bridged_ep(bridged_ep)
1426+
1427+
(eid, _, path, new) = await mctp.call_assign_endpoint(ep.lladdr)
1428+
assert new
1429+
1430+
mctp_obj = await dbus.get_proxy_object(MCTPD_C, MCTPD_MCTP_P)
1431+
mctp_objmgr = await mctp_obj.get_interface(DBUS_OBJECT_MANAGER_I)
1432+
endpoint_added = trio.Semaphore(initial_value=0)
1433+
poll_count_by_discovery = 0
1434+
1435+
def ep_added(ep_path, content):
1436+
if MCTPD_ENDPOINT_I in content:
1437+
nonlocal poll_count_by_discovery
1438+
poll_count_by_discovery = poll_count
1439+
endpoint_added.release()
1440+
1441+
await mctp_objmgr.on_interfaces_added(ep_added)
1442+
1443+
# Wait longer than the poll interval for the bridged endpoint
1444+
# to be discovered
1445+
await trio.sleep(poll_interval / 1000)
1446+
1447+
# We should have only poll until the discovery thus count should
1448+
# be the same even after longer wait.
1449+
assert poll_count == poll_count_by_discovery
1450+
1451+
res = await mctpd.stop_mctpd()
1452+
assert res == 0
1453+
1454+
""" Test that polling continues until the endpoint is discovered """
1455+
async def test_bridged_endpoint_poll_continue(dbus, sysnet, nursery, autojump_clock):
1456+
poll_interval = 2500
1457+
config = f"""
1458+
[bus-owner]
1459+
endpoint_poll_ms = {poll_interval}
1460+
"""
1461+
1462+
mctpd = MctpdWrapper(dbus, sysnet, config = config)
1463+
await mctpd.start_mctpd(nursery)
1464+
1465+
iface = mctpd.system.interfaces[0]
1466+
ep = mctpd.network.endpoints[0]
1467+
mctp = await mctpd_mctp_iface_obj(dbus, iface)
1468+
poll_count = 0
1469+
1470+
class BridgedEndpoint(Endpoint):
1471+
async def handle_mctp_control(self, sock, src_addr, msg):
1472+
flags, opcode = msg[0:2]
1473+
# dont respond to simiulate device not accessible
1474+
# but increment poll count for the Get Endpoint ID
1475+
if opcode == 0x2: # Get Endpoint ID
1476+
nonlocal poll_count
1477+
poll_count += 1
1478+
return None
1479+
1480+
bridged_ep = BridgedEndpoint(iface, bytes(), types = [0, 1])
1481+
mctpd.network.add_endpoint(bridged_ep)
1482+
ep.add_bridged_ep(bridged_ep)
1483+
1484+
(eid, _, path, new) = await mctp.call_assign_endpoint(ep.lladdr)
1485+
assert new
1486+
1487+
# Wait for sometime to continue polling
1488+
await trio.sleep(poll_interval / 1000)
1489+
1490+
poll_count_before = poll_count
1491+
# Wait more to see if poll count increments
1492+
await trio.sleep(1)
1493+
assert poll_count > poll_count_before
1494+
1495+
res = await mctpd.stop_mctpd()
1496+
assert res == 0

0 commit comments

Comments
 (0)