blob: 43e62086696ebf6328aa49aac66ad21154700400 [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"
12#include "test/gtest.h"
13
14using cricket::UsedIds;
15using cricket::UsedRtpHeaderExtensionIds;
16
17struct Foo {
18 int id;
19};
20
21TEST(UsedIdsTest, UniqueIdsAreUnchanged) {
22 UsedIds<Foo> used_ids(1, 5);
23 for (int i = 1; i <= 5; ++i) {
24 Foo id = {i};
25 used_ids.FindAndSetIdUsed(&id);
26 EXPECT_EQ(id.id, i);
27 }
28}
29
30TEST(UsedIdsTest, IdsOutsideRangeAreUnchanged) {
31 UsedIds<Foo> used_ids(1, 5);
32
33 Foo id_11 = {11};
34 Foo id_12 = {12};
35 Foo id_12_collision = {12};
36 Foo id_13 = {13};
37 Foo id_13_collision = {13};
38
39 used_ids.FindAndSetIdUsed(&id_11);
40 EXPECT_EQ(id_11.id, 11);
41 used_ids.FindAndSetIdUsed(&id_12);
42 EXPECT_EQ(id_12.id, 12);
43 used_ids.FindAndSetIdUsed(&id_12_collision);
44 EXPECT_EQ(id_12_collision.id, 12);
45 used_ids.FindAndSetIdUsed(&id_13);
46 EXPECT_EQ(id_13.id, 13);
47 used_ids.FindAndSetIdUsed(&id_13_collision);
48 EXPECT_EQ(id_13_collision.id, 13);
49}
50
51TEST(UsedIdsTest, CollisionsAreReassignedIdsInReverseOrder) {
52 UsedIds<Foo> used_ids(1, 10);
53 Foo id_1 = {1};
54 Foo id_2 = {2};
55 Foo id_2_collision = {2};
56 Foo id_3 = {3};
57 Foo id_3_collision = {3};
58
59 used_ids.FindAndSetIdUsed(&id_1);
60 used_ids.FindAndSetIdUsed(&id_2);
61 used_ids.FindAndSetIdUsed(&id_2_collision);
62 EXPECT_EQ(id_2_collision.id, 10);
63 used_ids.FindAndSetIdUsed(&id_3);
64 used_ids.FindAndSetIdUsed(&id_3_collision);
65 EXPECT_EQ(id_3_collision.id, 9);
66}
67
68struct TestParams {
69 UsedRtpHeaderExtensionIds::IdDomain id_domain;
70 int max_id;
71};
72
73class UsedRtpHeaderExtensionIdsTest
74 : public ::testing::TestWithParam<TestParams> {};
75
76constexpr TestParams kOneByteTestParams = {
77 UsedRtpHeaderExtensionIds::IdDomain::kOneByteOnly, 14};
78constexpr TestParams kTwoByteTestParams = {
79 UsedRtpHeaderExtensionIds::IdDomain::kTwoByteAllowed, 255};
80
81INSTANTIATE_TEST_SUITE_P(,
82 UsedRtpHeaderExtensionIdsTest,
83 ::testing::Values(kOneByteTestParams,
84 kTwoByteTestParams));
85
86TEST_P(UsedRtpHeaderExtensionIdsTest, UniqueIdsAreUnchanged) {
87 UsedRtpHeaderExtensionIds used_ids(GetParam().id_domain);
88
89 // Fill all IDs.
90 for (int j = 1; j <= GetParam().max_id; ++j) {
91 webrtc::RtpExtension extension("", j);
92 used_ids.FindAndSetIdUsed(&extension);
93 EXPECT_EQ(extension.id, j);
94 }
95}
96
97TEST_P(UsedRtpHeaderExtensionIdsTest, PrioritizeReassignmentToOneByteIds) {
98 UsedRtpHeaderExtensionIds used_ids(GetParam().id_domain);
99 webrtc::RtpExtension id_1("", 1);
100 webrtc::RtpExtension id_2("", 2);
101 webrtc::RtpExtension id_2_collision("", 2);
102 webrtc::RtpExtension id_3("", 3);
103 webrtc::RtpExtension id_3_collision("", 3);
104
105 // Expect that colliding IDs are reassigned to one-byte IDs.
106 used_ids.FindAndSetIdUsed(&id_1);
107 used_ids.FindAndSetIdUsed(&id_2);
108 used_ids.FindAndSetIdUsed(&id_2_collision);
109 EXPECT_EQ(id_2_collision.id, 14);
110 used_ids.FindAndSetIdUsed(&id_3);
111 used_ids.FindAndSetIdUsed(&id_3_collision);
112 EXPECT_EQ(id_3_collision.id, 13);
113}
114
115TEST_F(UsedRtpHeaderExtensionIdsTest, TwoByteIdsAllowed) {
116 UsedRtpHeaderExtensionIds used_ids(
117 UsedRtpHeaderExtensionIds::IdDomain::kTwoByteAllowed);
118
119 // Fill all one byte IDs.
120 for (int i = 1; i < 15; ++i) {
121 webrtc::RtpExtension id("", i);
122 used_ids.FindAndSetIdUsed(&id);
123 }
124
125 // Add new extensions with colliding IDs.
126 webrtc::RtpExtension id1_collision("", 1);
127 webrtc::RtpExtension id2_collision("", 2);
128 webrtc::RtpExtension id3_collision("", 3);
129
130 // Expect to reassign to two-byte header extension IDs.
131 used_ids.FindAndSetIdUsed(&id1_collision);
132 EXPECT_EQ(id1_collision.id, 15);
133 used_ids.FindAndSetIdUsed(&id2_collision);
134 EXPECT_EQ(id2_collision.id, 16);
135 used_ids.FindAndSetIdUsed(&id3_collision);
136 EXPECT_EQ(id3_collision.id, 17);
137}
138
139// Death tests.
140// Disabled on Android because death tests misbehave on Android, see
141// base/test/gtest_util.h.
142#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
143TEST(UsedIdsDeathTest, DieWhenAllIdsAreOccupied) {
144 UsedIds<Foo> used_ids(1, 5);
145 for (int i = 1; i <= 5; ++i) {
146 Foo id = {i};
147 used_ids.FindAndSetIdUsed(&id);
148 }
149 Foo id_collision = {3};
150 EXPECT_DEATH(used_ids.FindAndSetIdUsed(&id_collision), "");
151}
152
153using UsedRtpHeaderExtensionIdsDeathTest = UsedRtpHeaderExtensionIdsTest;
154INSTANTIATE_TEST_SUITE_P(,
155 UsedRtpHeaderExtensionIdsDeathTest,
156 ::testing::Values(kOneByteTestParams,
157 kTwoByteTestParams));
158
159TEST_P(UsedRtpHeaderExtensionIdsDeathTest, DieWhenAllIdsAreOccupied) {
160 UsedRtpHeaderExtensionIds used_ids(GetParam().id_domain);
161
162 // Fill all IDs.
163 for (int j = 1; j <= GetParam().max_id; ++j) {
164 webrtc::RtpExtension id("", j);
165 used_ids.FindAndSetIdUsed(&id);
166 }
167
168 webrtc::RtpExtension id1_collision("", 1);
169 webrtc::RtpExtension id2_collision("", 2);
170 webrtc::RtpExtension id3_collision("", GetParam().max_id);
171
172 EXPECT_DEATH(used_ids.FindAndSetIdUsed(&id1_collision), "");
173 EXPECT_DEATH(used_ids.FindAndSetIdUsed(&id2_collision), "");
174 EXPECT_DEATH(used_ids.FindAndSetIdUsed(&id3_collision), "");
175}
176#endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)