@@ -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