@@ -4503,105 +4503,123 @@ async fn test_ipv6_multicast_scope_validation() {
4503
4503
. ok ( ) ;
4504
4504
}
4505
4505
4506
- // #[tokio::test]
4507
- // #[ignore]
4508
- // async fn test_multicast_group_id_recycling() {
4509
- // let switch = &*get_switch().await;
4510
-
4511
- // // Use admin-scoped IPv6 addresses that get group IDs assigned
4512
- // let group1_ip = IpAddr::V6(Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 0, 10));
4513
- // let group2_ip = IpAddr::V6(Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 0, 11));
4514
- // let group3_ip = IpAddr::V6(Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 0, 12));
4515
-
4516
- // // Create first group and capture its group IDs
4517
- // let group1 = create_test_multicast_group(
4518
- // switch,
4519
- // group1_ip,
4520
- // Some("test_recycling_1"),
4521
- // &[(PhysPort(11), types::Direction::External)],
4522
- // None,
4523
- // false,
4524
- // None,
4525
- // )
4526
- // .await;
4527
-
4528
- // let group1_external_id = group1.external_group_id;
4529
- // assert!(group1_external_id.is_some());
4530
-
4531
- // // Create second group and capture its group IDs
4532
- // let group2 = create_test_multicast_group(
4533
- // switch,
4534
- // group2_ip,
4535
- // Some("test_recycling_2"),
4536
- // &[(PhysPort(12), types::Direction::External)],
4537
- // None,
4538
- // false,
4539
- // None,
4540
- // )
4541
- // .await;
4542
-
4543
- // let group2_external_id = group2.external_group_id;
4544
- // assert!(group2_external_id.is_some());
4545
- // assert_ne!(group1_external_id, group2_external_id);
4546
-
4547
- // // Delete the first group
4548
- // switch
4549
- // .client
4550
- // .multicast_group_delete(&group1_ip)
4551
- // .await
4552
- // .expect("Should be able to delete first group");
4553
-
4554
- // // Create third group - should reuse the first group's ID
4555
- // let group3 = create_test_multicast_group(
4556
- // switch,
4557
- // group3_ip,
4558
- // Some("test_recycling_3"),
4559
- // &[(PhysPort(13), types::Direction::External)],
4560
- // None,
4561
- // false,
4562
- // None,
4563
- // )
4564
- // .await;
4565
-
4566
- // let group3_external_id = group3.external_group_id;
4567
- // assert!(group3_external_id.is_some());
4568
-
4569
- // // Verify that ID recycling is working - group3 should get an ID that was previously used
4570
- // // The exact ID depends on allocation strategy, but it should be different from group2
4571
- // assert_ne!(
4572
- // group2_external_id, group3_external_id,
4573
- // "Third group should get a different ID than the active second group"
4574
- // );
4575
-
4576
- // // Create a fourth group after deleting group2, it should reuse group2's ID
4577
- // switch
4578
- // .client
4579
- // .multicast_group_delete(&group2_ip)
4580
- // .await
4581
- // .expect("Should be able to delete second group");
4582
-
4583
- // let group4_ip = IpAddr::V6(Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 0, 13));
4584
- // let group4 = create_test_multicast_group(
4585
- // switch,
4586
- // group4_ip,
4587
- // Some("test_recycling_4"),
4588
- // &[(PhysPort(14), types::Direction::External)],
4589
- // None,
4590
- // false,
4591
- // None,
4592
- // )
4593
- // .await;
4594
-
4595
- // let group4_external_id = group4.external_group_id;
4596
- // assert!(group4_external_id.is_some());
4597
-
4598
- // // Group4 should reuse group2's recently freed ID due to stack-like allocation
4599
- // assert_eq!(
4600
- // group2_external_id, group4_external_id,
4601
- // "Fourth group should reuse second group's recycled ID"
4602
- // );
4603
-
4604
- // // Cleanup
4605
- // cleanup_test_group(switch, group3_ip).await;
4606
- // cleanup_test_group(switch, group4_ip).await;
4607
- // }
4506
+ #[ tokio:: test]
4507
+ #[ ignore]
4508
+ async fn test_multicast_group_id_recycling ( ) {
4509
+ let switch = & * get_switch ( ) . await ;
4510
+
4511
+ // Use admin-scoped IPv6 addresses that get group IDs assigned
4512
+ let group1_ip = IpAddr :: V6 ( Ipv6Addr :: new ( 0xff05 , 0 , 0 , 0 , 0 , 0 , 0 , 10 ) ) ;
4513
+ let group2_ip = IpAddr :: V6 ( Ipv6Addr :: new ( 0xff05 , 0 , 0 , 0 , 0 , 0 , 0 , 11 ) ) ;
4514
+ let group3_ip = IpAddr :: V6 ( Ipv6Addr :: new ( 0xff05 , 0 , 0 , 0 , 0 , 0 , 0 , 12 ) ) ;
4515
+
4516
+ // Create first group and capture its group IDs
4517
+ let group1 = create_test_multicast_group (
4518
+ switch,
4519
+ group1_ip,
4520
+ Some ( "test_recycling_1" ) ,
4521
+ & [ ( PhysPort ( 11 ) , types:: Direction :: External ) ] ,
4522
+ None ,
4523
+ false ,
4524
+ None ,
4525
+ )
4526
+ . await ;
4527
+
4528
+ let group1_external_id = group1. external_group_id ;
4529
+ assert ! ( group1_external_id. is_some( ) ) ;
4530
+
4531
+ // Create second group and capture its group IDs
4532
+ let group2 = create_test_multicast_group (
4533
+ switch,
4534
+ group2_ip,
4535
+ Some ( "test_recycling_2" ) ,
4536
+ & [ ( PhysPort ( 12 ) , types:: Direction :: External ) ] ,
4537
+ None ,
4538
+ false ,
4539
+ None ,
4540
+ )
4541
+ . await ;
4542
+
4543
+ let group2_external_id = group2. external_group_id ;
4544
+ assert ! ( group2_external_id. is_some( ) ) ;
4545
+ assert_ne ! ( group1_external_id, group2_external_id) ;
4546
+
4547
+ // Delete the first group
4548
+ switch
4549
+ . client
4550
+ . multicast_group_delete ( & group1_ip)
4551
+ . await
4552
+ . expect ( "Should be able to delete first group" ) ;
4553
+
4554
+ // Verify group1 was actually deleted
4555
+ let groups_after_delete1 = switch
4556
+ . client
4557
+ . multicast_groups_list_stream ( None )
4558
+ . try_collect :: < Vec < _ > > ( )
4559
+ . await
4560
+ . expect ( "Should be able to list groups" ) ;
4561
+ assert ! ( !groups_after_delete1. iter( ) . any( |g| g. group_ip == group1_ip) , "Group1 should be deleted" ) ;
4562
+
4563
+ // Create third group - should reuse the first group's ID
4564
+ let group3 = create_test_multicast_group (
4565
+ switch,
4566
+ group3_ip,
4567
+ Some ( "test_recycling_3" ) ,
4568
+ & [ ( PhysPort ( 13 ) , types:: Direction :: External ) ] ,
4569
+ None ,
4570
+ false ,
4571
+ None ,
4572
+ )
4573
+ . await ;
4574
+
4575
+ let group3_external_id = group3. external_group_id ;
4576
+ assert ! ( group3_external_id. is_some( ) ) ;
4577
+
4578
+ // Verify that ID recycling is working - group3 should get an ID that was previously used
4579
+ // The exact ID depends on allocation strategy, but it should be different from group2
4580
+ assert_ne ! (
4581
+ group2_external_id, group3_external_id,
4582
+ "Third group should get a different ID than the active second group"
4583
+ ) ;
4584
+
4585
+ // The key test: create a fourth group after deleting group2, it should reuse group2's ID
4586
+ switch
4587
+ . client
4588
+ . multicast_group_delete ( & group2_ip)
4589
+ . await
4590
+ . expect ( "Should be able to delete second group" ) ;
4591
+
4592
+ // Verify group2 was actually deleted
4593
+ let groups_after_delete2 = switch
4594
+ . client
4595
+ . multicast_groups_list_stream ( None )
4596
+ . try_collect :: < Vec < _ > > ( )
4597
+ . await
4598
+ . expect ( "Should be able to list groups" ) ;
4599
+ assert ! ( !groups_after_delete2. iter( ) . any( |g| g. group_ip == group2_ip) , "Group2 should be deleted" ) ;
4600
+
4601
+ let group4_ip = IpAddr :: V6 ( Ipv6Addr :: new ( 0xff05 , 0 , 0 , 0 , 0 , 0 , 0 , 13 ) ) ;
4602
+ let group4 = create_test_multicast_group (
4603
+ switch,
4604
+ group4_ip,
4605
+ Some ( "test_recycling_4" ) ,
4606
+ & [ ( PhysPort ( 14 ) , types:: Direction :: External ) ] ,
4607
+ None ,
4608
+ false ,
4609
+ None ,
4610
+ )
4611
+ . await ;
4612
+
4613
+ let group4_external_id = group4. external_group_id ;
4614
+ assert ! ( group4_external_id. is_some( ) ) ;
4615
+
4616
+ // Group4 should reuse group2's recently freed ID due to stack-like allocation
4617
+ assert_eq ! (
4618
+ group2_external_id, group4_external_id,
4619
+ "Fourth group should reuse second group's recycled ID"
4620
+ ) ;
4621
+
4622
+ // Cleanup - clean up remaining active groups
4623
+ cleanup_test_group ( switch, group3_ip) . await ;
4624
+ cleanup_test_group ( switch, group4_ip) . await ;
4625
+ }
0 commit comments