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