blob: 881e0177dd9b8588b63a056391269e81ef206d4b [file] [log] [blame]
philipel2cb73412016-03-22 10:03:43 +01001/*
2 * Copyright (c) 2016 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
Yves Gerey3e707812018-11-28 16:47:49 +010011#include <cstdint>
12#include <iterator>
philipel2cb73412016-03-22 10:03:43 +010013#include <set>
14
Bjorn Tereliusa194e582017-10-25 13:07:09 +020015#include "rtc_base/numerics/sequence_number_util.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "test/gtest.h"
philipel2cb73412016-03-22 10:03:43 +010017
18namespace webrtc {
19class TestSeqNumUtil : public ::testing::Test {
20 protected:
21 // Can't use std::numeric_limits<unsigned long>::max() since
22 // MSVC doesn't support constexpr.
23 static const unsigned long ulmax = ~0ul; // NOLINT
24};
25
26TEST_F(TestSeqNumUtil, AheadOrAt) {
27 uint8_t x = 0;
28 uint8_t y = 0;
29 ASSERT_TRUE(AheadOrAt(x, y));
30 ++x;
31 ASSERT_TRUE(AheadOrAt(x, y));
32 ASSERT_FALSE(AheadOrAt(y, x));
33 for (int i = 0; i < 256; ++i) {
34 ASSERT_TRUE(AheadOrAt(x, y));
35 ++x;
36 ++y;
37 }
38
39 x = 128;
40 y = 0;
41 ASSERT_TRUE(AheadOrAt(x, y));
42 ASSERT_FALSE(AheadOrAt(y, x));
43
44 x = 129;
45 ASSERT_FALSE(AheadOrAt(x, y));
46 ASSERT_TRUE(AheadOrAt(y, x));
47 ASSERT_TRUE(AheadOrAt<uint16_t>(x, y));
48 ASSERT_FALSE(AheadOrAt<uint16_t>(y, x));
49}
50
51TEST_F(TestSeqNumUtil, AheadOrAtWithDivisor) {
52 ASSERT_TRUE((AheadOrAt<uint8_t, 11>(5, 0)));
53 ASSERT_FALSE((AheadOrAt<uint8_t, 11>(6, 0)));
54 ASSERT_FALSE((AheadOrAt<uint8_t, 11>(0, 5)));
55 ASSERT_TRUE((AheadOrAt<uint8_t, 11>(0, 6)));
56
57 ASSERT_TRUE((AheadOrAt<uint8_t, 10>(5, 0)));
58 ASSERT_FALSE((AheadOrAt<uint8_t, 10>(6, 0)));
59 ASSERT_FALSE((AheadOrAt<uint8_t, 10>(0, 5)));
60 ASSERT_TRUE((AheadOrAt<uint8_t, 10>(0, 6)));
61
62 const uint8_t D = 211;
63 uint8_t x = 0;
64 for (int i = 0; i < D; ++i) {
65 uint8_t next_x = Add<D>(x, 1);
66 ASSERT_TRUE((AheadOrAt<uint8_t, D>(i, i)));
67 ASSERT_TRUE((AheadOrAt<uint8_t, D>(next_x, i)));
68 ASSERT_FALSE((AheadOrAt<uint8_t, D>(i, next_x)));
69 x = next_x;
70 }
71}
72
73TEST_F(TestSeqNumUtil, AheadOf) {
74 uint8_t x = 0;
75 uint8_t y = 0;
76 ASSERT_FALSE(AheadOf(x, y));
77 ++x;
78 ASSERT_TRUE(AheadOf(x, y));
79 ASSERT_FALSE(AheadOf(y, x));
80 for (int i = 0; i < 256; ++i) {
81 ASSERT_TRUE(AheadOf(x, y));
82 ++x;
83 ++y;
84 }
85
86 x = 128;
87 y = 0;
88 for (int i = 0; i < 128; ++i) {
89 ASSERT_TRUE(AheadOf(x, y));
90 ASSERT_FALSE(AheadOf(y, x));
91 x++;
92 y++;
93 }
94
95 for (int i = 0; i < 128; ++i) {
96 ASSERT_FALSE(AheadOf(x, y));
97 ASSERT_TRUE(AheadOf(y, x));
98 x++;
99 y++;
100 }
101
102 x = 129;
103 y = 0;
104 ASSERT_FALSE(AheadOf(x, y));
105 ASSERT_TRUE(AheadOf(y, x));
106 ASSERT_TRUE(AheadOf<uint16_t>(x, y));
107 ASSERT_FALSE(AheadOf<uint16_t>(y, x));
108}
109
110TEST_F(TestSeqNumUtil, AheadOfWithDivisor) {
111 ASSERT_TRUE((AheadOf<uint8_t, 11>(5, 0)));
112 ASSERT_FALSE((AheadOf<uint8_t, 11>(6, 0)));
113 ASSERT_FALSE((AheadOf<uint8_t, 11>(0, 5)));
114 ASSERT_TRUE((AheadOf<uint8_t, 11>(0, 6)));
115
116 ASSERT_TRUE((AheadOf<uint8_t, 10>(5, 0)));
117 ASSERT_FALSE((AheadOf<uint8_t, 10>(6, 0)));
118 ASSERT_FALSE((AheadOf<uint8_t, 10>(0, 5)));
119 ASSERT_TRUE((AheadOf<uint8_t, 10>(0, 6)));
120
121 const uint8_t D = 211;
122 uint8_t x = 0;
123 for (int i = 0; i < D; ++i) {
124 uint8_t next_x = Add<D>(x, 1);
125 ASSERT_FALSE((AheadOf<uint8_t, D>(i, i)));
126 ASSERT_TRUE((AheadOf<uint8_t, D>(next_x, i)));
127 ASSERT_FALSE((AheadOf<uint8_t, D>(i, next_x)));
128 x = next_x;
129 }
130}
131
132TEST_F(TestSeqNumUtil, ForwardDiffWithDivisor) {
133 const uint8_t kDivisor = 211;
134
135 for (uint8_t i = 0; i < kDivisor - 1; ++i) {
136 ASSERT_EQ(0, (ForwardDiff<uint8_t, kDivisor>(i, i)));
137 ASSERT_EQ(1, (ForwardDiff<uint8_t, kDivisor>(i, i + 1)));
138 ASSERT_EQ(kDivisor - 1, (ForwardDiff<uint8_t, kDivisor>(i + 1, i)));
139 }
140
141 for (uint8_t i = 1; i < kDivisor; ++i) {
142 ASSERT_EQ(i, (ForwardDiff<uint8_t, kDivisor>(0, i)));
143 ASSERT_EQ(kDivisor - i, (ForwardDiff<uint8_t, kDivisor>(i, 0)));
144 }
145}
146
147TEST_F(TestSeqNumUtil, ReverseDiffWithDivisor) {
148 const uint8_t kDivisor = 241;
149
150 for (uint8_t i = 0; i < kDivisor - 1; ++i) {
151 ASSERT_EQ(0, (ReverseDiff<uint8_t, kDivisor>(i, i)));
152 ASSERT_EQ(kDivisor - 1, (ReverseDiff<uint8_t, kDivisor>(i, i + 1)));
153 ASSERT_EQ(1, (ReverseDiff<uint8_t, kDivisor>(i + 1, i)));
154 }
155
156 for (uint8_t i = 1; i < kDivisor; ++i) {
157 ASSERT_EQ(kDivisor - i, (ReverseDiff<uint8_t, kDivisor>(0, i)));
158 ASSERT_EQ(i, (ReverseDiff<uint8_t, kDivisor>(i, 0)));
159 }
160}
161
162TEST_F(TestSeqNumUtil, SeqNumComparator) {
163 std::set<uint8_t, AscendingSeqNumComp<uint8_t>> seq_nums_asc;
164 std::set<uint8_t, DescendingSeqNumComp<uint8_t>> seq_nums_desc;
165
166 uint8_t x = 0;
167 for (int i = 0; i < 128; ++i) {
168 seq_nums_asc.insert(x);
169 seq_nums_desc.insert(x);
170 ASSERT_EQ(x, *seq_nums_asc.begin());
171 ASSERT_EQ(x, *seq_nums_desc.rbegin());
172 ++x;
173 }
174
175 seq_nums_asc.clear();
176 seq_nums_desc.clear();
177 x = 199;
178 for (int i = 0; i < 128; ++i) {
179 seq_nums_asc.insert(x);
180 seq_nums_desc.insert(x);
181 ASSERT_EQ(x, *seq_nums_asc.begin());
182 ASSERT_EQ(x, *seq_nums_desc.rbegin());
183 ++x;
184 }
185}
186
187TEST_F(TestSeqNumUtil, SeqNumComparatorWithDivisor) {
188 const uint8_t D = 223;
189
190 std::set<uint8_t, AscendingSeqNumComp<uint8_t, D>> seq_nums_asc;
191 std::set<uint8_t, DescendingSeqNumComp<uint8_t, D>> seq_nums_desc;
192
193 uint8_t x = 0;
194 for (int i = 0; i < D / 2; ++i) {
195 seq_nums_asc.insert(x);
196 seq_nums_desc.insert(x);
197 ASSERT_EQ(x, *seq_nums_asc.begin());
198 ASSERT_EQ(x, *seq_nums_desc.rbegin());
199 x = Add<D>(x, 1);
200 }
201
202 seq_nums_asc.clear();
203 seq_nums_desc.clear();
204 x = 200;
205 for (int i = 0; i < D / 2; ++i) {
206 seq_nums_asc.insert(x);
207 seq_nums_desc.insert(x);
208 ASSERT_EQ(x, *seq_nums_asc.begin());
209 ASSERT_EQ(x, *seq_nums_desc.rbegin());
210 x = Add<D>(x, 1);
211 }
212}
213
philipel77415f52017-07-27 04:37:18 -0700214#if GTEST_HAS_DEATH_TEST
215#if !defined(WEBRTC_ANDROID)
216TEST(SeqNumUnwrapper, NoBackWardWrap) {
philipeld4fac692017-09-04 07:03:46 -0700217 SeqNumUnwrapper<uint8_t> unwrapper(0);
philipel7956c0f2017-07-26 07:48:15 -0700218 EXPECT_EQ(0U, unwrapper.Unwrap(0));
219
220 // The unwrapped sequence is not allowed to wrap, if that happens the
221 // SeqNumUnwrapper should have been constructed with a higher start value.
philipel77415f52017-07-27 04:37:18 -0700222 EXPECT_DEATH(unwrapper.Unwrap(255), "");
philipel7956c0f2017-07-26 07:48:15 -0700223}
224
philipel77415f52017-07-27 04:37:18 -0700225TEST(SeqNumUnwrapper, NoForwardWrap) {
philipel7956c0f2017-07-26 07:48:15 -0700226 SeqNumUnwrapper<uint32_t> unwrapper(std::numeric_limits<uint64_t>::max());
227 EXPECT_EQ(std::numeric_limits<uint64_t>::max(), unwrapper.Unwrap(0));
228
229 // The unwrapped sequence is not allowed to wrap, if that happens the
230 // SeqNumUnwrapper should have been constructed with a lower start value.
philipel77415f52017-07-27 04:37:18 -0700231 EXPECT_DEATH(unwrapper.Unwrap(1), "");
philipel7956c0f2017-07-26 07:48:15 -0700232}
philipel77415f52017-07-27 04:37:18 -0700233#endif
234#endif
philipel7956c0f2017-07-26 07:48:15 -0700235
236TEST(SeqNumUnwrapper, ForwardWrap) {
philipeld4fac692017-09-04 07:03:46 -0700237 SeqNumUnwrapper<uint8_t> unwrapper(0);
philipel7956c0f2017-07-26 07:48:15 -0700238 EXPECT_EQ(0U, unwrapper.Unwrap(255));
239 EXPECT_EQ(1U, unwrapper.Unwrap(0));
240}
241
242TEST(SeqNumUnwrapper, ForwardWrapWithDivisor) {
philipeld4fac692017-09-04 07:03:46 -0700243 SeqNumUnwrapper<uint8_t, 33> unwrapper(0);
philipel7956c0f2017-07-26 07:48:15 -0700244 EXPECT_EQ(0U, unwrapper.Unwrap(30));
245 EXPECT_EQ(6U, unwrapper.Unwrap(3));
246}
247
248TEST(SeqNumUnwrapper, BackWardWrap) {
249 SeqNumUnwrapper<uint8_t> unwrapper(10);
250 EXPECT_EQ(10U, unwrapper.Unwrap(0));
251 EXPECT_EQ(8U, unwrapper.Unwrap(254));
252}
253
254TEST(SeqNumUnwrapper, BackWardWrapWithDivisor) {
255 SeqNumUnwrapper<uint8_t, 33> unwrapper(10);
256 EXPECT_EQ(10U, unwrapper.Unwrap(0));
257 EXPECT_EQ(8U, unwrapper.Unwrap(31));
258}
259
260TEST(SeqNumUnwrapper, Unwrap) {
philipeld4fac692017-09-04 07:03:46 -0700261 SeqNumUnwrapper<uint16_t> unwrapper(0);
philipel7956c0f2017-07-26 07:48:15 -0700262 const uint16_t kMax = std::numeric_limits<uint16_t>::max();
263 const uint16_t kMaxDist = kMax / 2 + 1;
264
265 EXPECT_EQ(0U, unwrapper.Unwrap(0));
266 EXPECT_EQ(kMaxDist, unwrapper.Unwrap(kMaxDist));
267 EXPECT_EQ(0U, unwrapper.Unwrap(0));
268
269 EXPECT_EQ(kMaxDist, unwrapper.Unwrap(kMaxDist));
270 EXPECT_EQ(kMax, unwrapper.Unwrap(kMax));
271 EXPECT_EQ(kMax + 1U, unwrapper.Unwrap(0));
272 EXPECT_EQ(kMax, unwrapper.Unwrap(kMax));
273 EXPECT_EQ(kMaxDist, unwrapper.Unwrap(kMaxDist));
274 EXPECT_EQ(0U, unwrapper.Unwrap(0));
275}
276
277TEST(SeqNumUnwrapper, UnwrapOddDivisor) {
278 SeqNumUnwrapper<uint8_t, 11> unwrapper(10);
279
280 EXPECT_EQ(10U, unwrapper.Unwrap(10));
281 EXPECT_EQ(11U, unwrapper.Unwrap(0));
282 EXPECT_EQ(16U, unwrapper.Unwrap(5));
283 EXPECT_EQ(21U, unwrapper.Unwrap(10));
284 EXPECT_EQ(22U, unwrapper.Unwrap(0));
285 EXPECT_EQ(17U, unwrapper.Unwrap(6));
286 EXPECT_EQ(12U, unwrapper.Unwrap(1));
287 EXPECT_EQ(7U, unwrapper.Unwrap(7));
288 EXPECT_EQ(2U, unwrapper.Unwrap(2));
289 EXPECT_EQ(0U, unwrapper.Unwrap(0));
290}
291
292TEST(SeqNumUnwrapper, ManyForwardWraps) {
293 const int kLargeNumber = 4711;
294 const int kMaxStep = kLargeNumber / 2;
295 const int kNumWraps = 100;
296 SeqNumUnwrapper<uint16_t, kLargeNumber> unwrapper;
297
298 uint16_t next_unwrap = 0;
philipeld4fac692017-09-04 07:03:46 -0700299 uint64_t expected = decltype(unwrapper)::kDefaultStartValue;
philipel7956c0f2017-07-26 07:48:15 -0700300 for (int i = 0; i < kNumWraps * 2 + 1; ++i) {
301 EXPECT_EQ(expected, unwrapper.Unwrap(next_unwrap));
302 expected += kMaxStep;
303 next_unwrap = (next_unwrap + kMaxStep) % kLargeNumber;
304 }
305}
306
307TEST(SeqNumUnwrapper, ManyBackwardWraps) {
308 const int kLargeNumber = 4711;
309 const int kMaxStep = kLargeNumber / 2;
310 const int kNumWraps = 100;
311 SeqNumUnwrapper<uint16_t, kLargeNumber> unwrapper(kLargeNumber * kNumWraps);
312
313 uint16_t next_unwrap = 0;
314 uint64_t expected = kLargeNumber * kNumWraps;
315 for (uint16_t i = 0; i < kNumWraps * 2 + 1; ++i) {
316 EXPECT_EQ(expected, unwrapper.Unwrap(next_unwrap));
317 expected -= kMaxStep;
318 next_unwrap = (next_unwrap + kMaxStep + 1) % kLargeNumber;
319 }
320}
321
philipel2cb73412016-03-22 10:03:43 +0100322} // namespace webrtc