Skip to content

Commit 36c148e

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 <[email protected]>
1 parent 9695b30 commit 36c148e

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

0 commit comments

Comments
 (0)