| /* |
| * Copyright 2019 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #include "pc/used_ids.h" |
| |
| #include "absl/strings/string_view.h" |
| #include "test/gtest.h" |
| |
| using cricket::UsedIds; |
| using cricket::UsedRtpHeaderExtensionIds; |
| |
| struct Foo { |
| int id; |
| }; |
| |
| TEST(UsedIdsTest, UniqueIdsAreUnchanged) { |
| UsedIds<Foo> used_ids(1, 5); |
| for (int i = 1; i <= 5; ++i) { |
| Foo id = {i}; |
| used_ids.FindAndSetIdUsed(&id); |
| EXPECT_EQ(id.id, i); |
| } |
| } |
| |
| TEST(UsedIdsTest, IdsOutsideRangeAreUnchanged) { |
| UsedIds<Foo> used_ids(1, 5); |
| |
| Foo id_11 = {11}; |
| Foo id_12 = {12}; |
| Foo id_12_collision = {12}; |
| Foo id_13 = {13}; |
| Foo id_13_collision = {13}; |
| |
| used_ids.FindAndSetIdUsed(&id_11); |
| EXPECT_EQ(id_11.id, 11); |
| used_ids.FindAndSetIdUsed(&id_12); |
| EXPECT_EQ(id_12.id, 12); |
| used_ids.FindAndSetIdUsed(&id_12_collision); |
| EXPECT_EQ(id_12_collision.id, 12); |
| used_ids.FindAndSetIdUsed(&id_13); |
| EXPECT_EQ(id_13.id, 13); |
| used_ids.FindAndSetIdUsed(&id_13_collision); |
| EXPECT_EQ(id_13_collision.id, 13); |
| } |
| |
| TEST(UsedIdsTest, CollisionsAreReassignedIdsInReverseOrder) { |
| UsedIds<Foo> used_ids(1, 10); |
| Foo id_1 = {1}; |
| Foo id_2 = {2}; |
| Foo id_2_collision = {2}; |
| Foo id_3 = {3}; |
| Foo id_3_collision = {3}; |
| |
| used_ids.FindAndSetIdUsed(&id_1); |
| used_ids.FindAndSetIdUsed(&id_2); |
| used_ids.FindAndSetIdUsed(&id_2_collision); |
| EXPECT_EQ(id_2_collision.id, 10); |
| used_ids.FindAndSetIdUsed(&id_3); |
| used_ids.FindAndSetIdUsed(&id_3_collision); |
| EXPECT_EQ(id_3_collision.id, 9); |
| } |
| |
| struct TestParams { |
| UsedRtpHeaderExtensionIds::IdDomain id_domain; |
| int max_id; |
| }; |
| |
| class UsedRtpHeaderExtensionIdsTest |
| : public ::testing::TestWithParam<TestParams> {}; |
| |
| constexpr TestParams kOneByteTestParams = { |
| UsedRtpHeaderExtensionIds::IdDomain::kOneByteOnly, 14}; |
| constexpr TestParams kTwoByteTestParams = { |
| UsedRtpHeaderExtensionIds::IdDomain::kTwoByteAllowed, 255}; |
| |
| INSTANTIATE_TEST_SUITE_P(All, |
| UsedRtpHeaderExtensionIdsTest, |
| ::testing::Values(kOneByteTestParams, |
| kTwoByteTestParams)); |
| |
| TEST_P(UsedRtpHeaderExtensionIdsTest, UniqueIdsAreUnchanged) { |
| UsedRtpHeaderExtensionIds used_ids(GetParam().id_domain); |
| |
| // Fill all IDs. |
| for (int j = 1; j <= GetParam().max_id; ++j) { |
| webrtc::RtpExtension extension("", j); |
| used_ids.FindAndSetIdUsed(&extension); |
| EXPECT_EQ(extension.id, j); |
| } |
| } |
| |
| TEST_P(UsedRtpHeaderExtensionIdsTest, PrioritizeReassignmentToOneByteIds) { |
| UsedRtpHeaderExtensionIds used_ids(GetParam().id_domain); |
| webrtc::RtpExtension id_1("", 1); |
| webrtc::RtpExtension id_2("", 2); |
| webrtc::RtpExtension id_2_collision("", 2); |
| webrtc::RtpExtension id_3("", 3); |
| webrtc::RtpExtension id_3_collision("", 3); |
| |
| // Expect that colliding IDs are reassigned to one-byte IDs. |
| used_ids.FindAndSetIdUsed(&id_1); |
| used_ids.FindAndSetIdUsed(&id_2); |
| used_ids.FindAndSetIdUsed(&id_2_collision); |
| EXPECT_EQ(id_2_collision.id, 14); |
| used_ids.FindAndSetIdUsed(&id_3); |
| used_ids.FindAndSetIdUsed(&id_3_collision); |
| EXPECT_EQ(id_3_collision.id, 13); |
| } |
| |
| TEST_F(UsedRtpHeaderExtensionIdsTest, TwoByteIdsAllowed) { |
| UsedRtpHeaderExtensionIds used_ids( |
| UsedRtpHeaderExtensionIds::IdDomain::kTwoByteAllowed); |
| |
| // Fill all one byte IDs. |
| for (int i = 1; i < 15; ++i) { |
| webrtc::RtpExtension id("", i); |
| used_ids.FindAndSetIdUsed(&id); |
| } |
| |
| // Add new extensions with colliding IDs. |
| webrtc::RtpExtension id1_collision("", 1); |
| webrtc::RtpExtension id2_collision("", 2); |
| webrtc::RtpExtension id3_collision("", 3); |
| |
| // Expect to reassign to two-byte header extension IDs. |
| used_ids.FindAndSetIdUsed(&id1_collision); |
| EXPECT_EQ(id1_collision.id, 15); |
| used_ids.FindAndSetIdUsed(&id2_collision); |
| EXPECT_EQ(id2_collision.id, 16); |
| used_ids.FindAndSetIdUsed(&id3_collision); |
| EXPECT_EQ(id3_collision.id, 17); |
| } |
| |
| // Death tests. |
| // Disabled on Android because death tests misbehave on Android, see |
| // base/test/gtest_util.h. |
| #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) |
| TEST(UsedIdsDeathTest, DieWhenAllIdsAreOccupied) { |
| UsedIds<Foo> used_ids(1, 5); |
| for (int i = 1; i <= 5; ++i) { |
| Foo id = {i}; |
| used_ids.FindAndSetIdUsed(&id); |
| } |
| Foo id_collision = {3}; |
| EXPECT_DEATH(used_ids.FindAndSetIdUsed(&id_collision), ""); |
| } |
| |
| using UsedRtpHeaderExtensionIdsDeathTest = UsedRtpHeaderExtensionIdsTest; |
| INSTANTIATE_TEST_SUITE_P(All, |
| UsedRtpHeaderExtensionIdsDeathTest, |
| ::testing::Values(kOneByteTestParams, |
| kTwoByteTestParams)); |
| |
| TEST_P(UsedRtpHeaderExtensionIdsDeathTest, DieWhenAllIdsAreOccupied) { |
| UsedRtpHeaderExtensionIds used_ids(GetParam().id_domain); |
| |
| // Fill all IDs. |
| for (int j = 1; j <= GetParam().max_id; ++j) { |
| webrtc::RtpExtension id("", j); |
| used_ids.FindAndSetIdUsed(&id); |
| } |
| |
| webrtc::RtpExtension id1_collision("", 1); |
| webrtc::RtpExtension id2_collision("", 2); |
| webrtc::RtpExtension id3_collision("", GetParam().max_id); |
| |
| EXPECT_DEATH(used_ids.FindAndSetIdUsed(&id1_collision), ""); |
| EXPECT_DEATH(used_ids.FindAndSetIdUsed(&id2_collision), ""); |
| EXPECT_DEATH(used_ids.FindAndSetIdUsed(&id3_collision), ""); |
| } |
| #endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) |