blob: 6362f2773ad80aa3ca5e42f34b5c80ca7312ff3f [file] [log] [blame]
Johannes Kron746dd0d2019-06-20 15:37:52 +02001/*
2 * Copyright 2019 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "pc/used_ids.h"
Jonas Olssona4d87372019-07-05 19:08:33 +020012
Harald Alvestrandc24a2182022-02-23 13:44:59 +000013#include "absl/strings/string_view.h"
Johannes Kron746dd0d2019-06-20 15:37:52 +020014#include "test/gtest.h"
15
16using cricket::UsedIds;
17using cricket::UsedRtpHeaderExtensionIds;
18
19struct Foo {
20 int id;
21};
22
23TEST(UsedIdsTest, UniqueIdsAreUnchanged) {
24 UsedIds<Foo> used_ids(1, 5);
25 for (int i = 1; i <= 5; ++i) {
26 Foo id = {i};
27 used_ids.FindAndSetIdUsed(&id);
28 EXPECT_EQ(id.id, i);
29 }
30}
31
32TEST(UsedIdsTest, IdsOutsideRangeAreUnchanged) {
33 UsedIds<Foo> used_ids(1, 5);
34
35 Foo id_11 = {11};
36 Foo id_12 = {12};
37 Foo id_12_collision = {12};
38 Foo id_13 = {13};
39 Foo id_13_collision = {13};
40
41 used_ids.FindAndSetIdUsed(&id_11);
42 EXPECT_EQ(id_11.id, 11);
43 used_ids.FindAndSetIdUsed(&id_12);
44 EXPECT_EQ(id_12.id, 12);
45 used_ids.FindAndSetIdUsed(&id_12_collision);
46 EXPECT_EQ(id_12_collision.id, 12);
47 used_ids.FindAndSetIdUsed(&id_13);
48 EXPECT_EQ(id_13.id, 13);
49 used_ids.FindAndSetIdUsed(&id_13_collision);
50 EXPECT_EQ(id_13_collision.id, 13);
51}
52
53TEST(UsedIdsTest, CollisionsAreReassignedIdsInReverseOrder) {
54 UsedIds<Foo> used_ids(1, 10);
55 Foo id_1 = {1};
56 Foo id_2 = {2};
57 Foo id_2_collision = {2};
58 Foo id_3 = {3};
59 Foo id_3_collision = {3};
60
61 used_ids.FindAndSetIdUsed(&id_1);
62 used_ids.FindAndSetIdUsed(&id_2);
63 used_ids.FindAndSetIdUsed(&id_2_collision);
64 EXPECT_EQ(id_2_collision.id, 10);
65 used_ids.FindAndSetIdUsed(&id_3);
66 used_ids.FindAndSetIdUsed(&id_3_collision);
67 EXPECT_EQ(id_3_collision.id, 9);
68}
69
70struct TestParams {
71 UsedRtpHeaderExtensionIds::IdDomain id_domain;
72 int max_id;
73};
74
75class UsedRtpHeaderExtensionIdsTest
76 : public ::testing::TestWithParam<TestParams> {};
77
78constexpr TestParams kOneByteTestParams = {
79 UsedRtpHeaderExtensionIds::IdDomain::kOneByteOnly, 14};
80constexpr TestParams kTwoByteTestParams = {
81 UsedRtpHeaderExtensionIds::IdDomain::kTwoByteAllowed, 255};
82
Mirko Bonadei1b575412019-09-23 08:34:50 +020083INSTANTIATE_TEST_SUITE_P(All,
Johannes Kron746dd0d2019-06-20 15:37:52 +020084 UsedRtpHeaderExtensionIdsTest,
85 ::testing::Values(kOneByteTestParams,
86 kTwoByteTestParams));
87
88TEST_P(UsedRtpHeaderExtensionIdsTest, UniqueIdsAreUnchanged) {
89 UsedRtpHeaderExtensionIds used_ids(GetParam().id_domain);
90
91 // Fill all IDs.
92 for (int j = 1; j <= GetParam().max_id; ++j) {
93 webrtc::RtpExtension extension("", j);
94 used_ids.FindAndSetIdUsed(&extension);
95 EXPECT_EQ(extension.id, j);
96 }
97}
98
99TEST_P(UsedRtpHeaderExtensionIdsTest, PrioritizeReassignmentToOneByteIds) {
100 UsedRtpHeaderExtensionIds used_ids(GetParam().id_domain);
101 webrtc::RtpExtension id_1("", 1);
102 webrtc::RtpExtension id_2("", 2);
103 webrtc::RtpExtension id_2_collision("", 2);
104 webrtc::RtpExtension id_3("", 3);
105 webrtc::RtpExtension id_3_collision("", 3);
106
107 // Expect that colliding IDs are reassigned to one-byte IDs.
108 used_ids.FindAndSetIdUsed(&id_1);
109 used_ids.FindAndSetIdUsed(&id_2);
110 used_ids.FindAndSetIdUsed(&id_2_collision);
111 EXPECT_EQ(id_2_collision.id, 14);
112 used_ids.FindAndSetIdUsed(&id_3);
113 used_ids.FindAndSetIdUsed(&id_3_collision);
114 EXPECT_EQ(id_3_collision.id, 13);
115}
116
117TEST_F(UsedRtpHeaderExtensionIdsTest, TwoByteIdsAllowed) {
118 UsedRtpHeaderExtensionIds used_ids(
119 UsedRtpHeaderExtensionIds::IdDomain::kTwoByteAllowed);
120
121 // Fill all one byte IDs.
122 for (int i = 1; i < 15; ++i) {
123 webrtc::RtpExtension id("", i);
124 used_ids.FindAndSetIdUsed(&id);
125 }
126
127 // Add new extensions with colliding IDs.
128 webrtc::RtpExtension id1_collision("", 1);
129 webrtc::RtpExtension id2_collision("", 2);
130 webrtc::RtpExtension id3_collision("", 3);
131
132 // Expect to reassign to two-byte header extension IDs.
133 used_ids.FindAndSetIdUsed(&id1_collision);
134 EXPECT_EQ(id1_collision.id, 15);
135 used_ids.FindAndSetIdUsed(&id2_collision);
136 EXPECT_EQ(id2_collision.id, 16);
137 used_ids.FindAndSetIdUsed(&id3_collision);
138 EXPECT_EQ(id3_collision.id, 17);
139}
140
141// Death tests.
142// Disabled on Android because death tests misbehave on Android, see
143// base/test/gtest_util.h.
144#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
145TEST(UsedIdsDeathTest, DieWhenAllIdsAreOccupied) {
146 UsedIds<Foo> used_ids(1, 5);
147 for (int i = 1; i <= 5; ++i) {
148 Foo id = {i};
149 used_ids.FindAndSetIdUsed(&id);
150 }
151 Foo id_collision = {3};
152 EXPECT_DEATH(used_ids.FindAndSetIdUsed(&id_collision), "");
153}
154
155using UsedRtpHeaderExtensionIdsDeathTest = UsedRtpHeaderExtensionIdsTest;
Mirko Bonadei1b575412019-09-23 08:34:50 +0200156INSTANTIATE_TEST_SUITE_P(All,
Johannes Kron746dd0d2019-06-20 15:37:52 +0200157 UsedRtpHeaderExtensionIdsDeathTest,
158 ::testing::Values(kOneByteTestParams,
159 kTwoByteTestParams));
160
161TEST_P(UsedRtpHeaderExtensionIdsDeathTest, DieWhenAllIdsAreOccupied) {
162 UsedRtpHeaderExtensionIds used_ids(GetParam().id_domain);
163
164 // Fill all IDs.
165 for (int j = 1; j <= GetParam().max_id; ++j) {
166 webrtc::RtpExtension id("", j);
167 used_ids.FindAndSetIdUsed(&id);
168 }
169
170 webrtc::RtpExtension id1_collision("", 1);
171 webrtc::RtpExtension id2_collision("", 2);
172 webrtc::RtpExtension id3_collision("", GetParam().max_id);
173
174 EXPECT_DEATH(used_ids.FindAndSetIdUsed(&id1_collision), "");
175 EXPECT_DEATH(used_ids.FindAndSetIdUsed(&id2_collision), "");
176 EXPECT_DEATH(used_ids.FindAndSetIdUsed(&id3_collision), "");
177}
178#endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)