Skip to content

Commit cfe8b8d

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 935db37 commit cfe8b8d

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

0 commit comments

Comments
 (0)