Skip to content

Commit 21d9274

Browse files
[review] updates: locking cleanup and scoped free id(s)
1 parent 4d6d726 commit 21d9274

File tree

2 files changed

+879
-366
lines changed

2 files changed

+879
-366
lines changed

dpd-client/tests/integration_tests/mcast.rs

Lines changed: 128 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,6 @@ async fn test_internal_ipv6_validation() {
599599
assert_eq!(updated.tag, Some("updated_tag".to_string()));
600600
assert_eq!(updated.ext_fwding.vlan_id, None);
601601

602-
// Cleanup
603602
cleanup_test_group(switch, created.group_ip).await;
604603
}
605604

@@ -685,7 +684,6 @@ async fn test_vlan_propagation_to_internal() {
685684
"Admin-scoped group bitmap should have VLAN 42 from external group"
686685
);
687686

688-
// Cleanup
689687
cleanup_test_group(switch, created_admin.group_ip).await;
690688
cleanup_test_group(switch, created_external.group_ip).await;
691689
}
@@ -695,7 +693,6 @@ async fn test_vlan_propagation_to_internal() {
695693
async fn test_group_api_lifecycle() {
696694
let switch = &*get_switch().await;
697695

698-
// Create admin-scoped IPv6 group for underlay replication infrastructure
699696
let egress1 = PhysPort(28);
700697
let internal_multicast_ip = IpAddr::V6(MULTICAST_NAT_IP);
701698
let underlay_group = create_test_multicast_group(
@@ -1330,7 +1327,6 @@ async fn test_api_invalid_combinations() {
13301327
),
13311328
}
13321329

1333-
// Cleanup
13341330
cleanup_test_group(switch, created_ipv4.group_ip).await;
13351331
cleanup_test_group(switch, created_non_admin.group_ip).await;
13361332
cleanup_test_group(switch, internal_multicast_ip).await;
@@ -2024,7 +2020,6 @@ async fn test_encapped_multicast_geneve_mcast_tag_to_external_members(
20242020
.await
20252021
.unwrap();
20262022

2027-
// Run the test
20282023
let result = switch.packet_test(vec![test_pkt], expected_pkts);
20292024

20302025
check_counter_incremented(
@@ -2163,7 +2158,6 @@ async fn test_encapped_multicast_geneve_mcast_tag_to_underlay_members(
21632158
.await
21642159
.unwrap();
21652160

2166-
// Run the test
21672161
let result = switch.packet_test(vec![test_pkt], expected_pkts);
21682162

21692163
check_counter_incremented(
@@ -2320,7 +2314,6 @@ async fn test_encapped_multicast_geneve_mcast_tag_to_underlay_and_external_membe
23202314
.await
23212315
.unwrap();
23222316

2323-
// Run the test
23242317
let result = switch.packet_test(vec![test_pkt], expected_pkts);
23252318

23262319
check_counter_incremented(
@@ -4335,7 +4328,6 @@ async fn test_external_group_nat_target_validation() {
43354328
"External group should have no members"
43364329
);
43374330

4338-
// Cleanup
43394331
cleanup_test_group(switch, created_admin.group_ip).await;
43404332
cleanup_test_group(switch, created_external.group_ip).await;
43414333
}
@@ -4510,3 +4502,131 @@ async fn test_ipv6_multicast_scope_validation() {
45104502
.await
45114503
.ok();
45124504
}
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+
// 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!(
4562+
!groups_after_delete1.iter().any(|g| g.group_ip == group1_ip),
4563+
"Group1 should be deleted"
4564+
);
4565+
4566+
// Create third group - should reuse the first group's ID
4567+
let group3 = create_test_multicast_group(
4568+
switch,
4569+
group3_ip,
4570+
Some("test_recycling_3"),
4571+
&[(PhysPort(13), types::Direction::External)],
4572+
None,
4573+
false,
4574+
None,
4575+
)
4576+
.await;
4577+
4578+
let group3_external_id = group3.external_group_id;
4579+
assert!(group3_external_id.is_some());
4580+
4581+
// Verify that ID recycling is working - group3 should get an ID that was
4582+
// previously used
4583+
assert_ne!(
4584+
group2_external_id, group3_external_id,
4585+
"Third group should get a different ID than the active second group"
4586+
);
4587+
4588+
// Create a fourth group after deleting group2, it should reuse group2's ID
4589+
switch
4590+
.client
4591+
.multicast_group_delete(&group2_ip)
4592+
.await
4593+
.expect("Should be able to delete second group");
4594+
4595+
// Verify group2 was actually deleted
4596+
let groups_after_delete2 = switch
4597+
.client
4598+
.multicast_groups_list_stream(None)
4599+
.try_collect::<Vec<_>>()
4600+
.await
4601+
.expect("Should be able to list groups");
4602+
assert!(
4603+
!groups_after_delete2.iter().any(|g| g.group_ip == group2_ip),
4604+
"Group2 should be deleted"
4605+
);
4606+
4607+
let group4_ip = IpAddr::V6(Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 0, 13));
4608+
let group4 = create_test_multicast_group(
4609+
switch,
4610+
group4_ip,
4611+
Some("test_recycling_4"),
4612+
&[(PhysPort(14), types::Direction::External)],
4613+
None,
4614+
false,
4615+
None,
4616+
)
4617+
.await;
4618+
4619+
let group4_external_id = group4.external_group_id;
4620+
assert!(group4_external_id.is_some());
4621+
4622+
// Group4 should reuse group2's recently freed ID due to stack-like
4623+
// allocation
4624+
assert_eq!(
4625+
group2_external_id, group4_external_id,
4626+
"Fourth group should reuse second group's recycled ID"
4627+
);
4628+
4629+
// Cleanup - clean up remaining active groups
4630+
cleanup_test_group(switch, group3_ip).await;
4631+
cleanup_test_group(switch, group4_ip).await;
4632+
}

0 commit comments

Comments
 (0)