blob: 209299d83210ff77a7c756fc019809a32de376f5 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2019 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/third_party/quiche/src/quic/core/quic_interval.h"
6
7#include <sstream>
vasilvv872e7a32019-03-12 16:42:44 -07008#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -05009#include <type_traits>
10#include <utility>
11
12#include "net/third_party/quiche/src/quic/core/quic_time.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050013#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
14
15namespace quic {
16namespace test {
17namespace {
18
19template <typename ForwardIterator>
20void STLDeleteContainerPointers(ForwardIterator begin, ForwardIterator end) {
21 while (begin != end) {
22 auto temp = begin;
23 ++begin;
24 delete *temp;
25 }
26}
27
28template <typename T>
29void STLDeleteElements(T* container) {
30 if (!container)
31 return;
32 STLDeleteContainerPointers(container->begin(), container->end());
33 container->clear();
34}
35
36class ConstructorListener {
37 public:
38 ConstructorListener(int* copy_construct_counter, int* move_construct_counter)
39 : copy_construct_counter_(copy_construct_counter),
40 move_construct_counter_(move_construct_counter) {
41 *copy_construct_counter_ = 0;
42 *move_construct_counter_ = 0;
43 }
44 ConstructorListener(const ConstructorListener& other) {
45 copy_construct_counter_ = other.copy_construct_counter_;
46 move_construct_counter_ = other.move_construct_counter_;
47 ++*copy_construct_counter_;
48 }
49 ConstructorListener(ConstructorListener&& other) {
50 copy_construct_counter_ = other.copy_construct_counter_;
51 move_construct_counter_ = other.move_construct_counter_;
52 ++*move_construct_counter_;
53 }
54 bool operator<(const ConstructorListener&) { return false; }
55 bool operator>(const ConstructorListener&) { return false; }
56 bool operator<=(const ConstructorListener&) { return true; }
57 bool operator>=(const ConstructorListener&) { return true; }
58 bool operator==(const ConstructorListener&) { return true; }
59
60 private:
61 int* copy_construct_counter_;
62 int* move_construct_counter_;
63};
64
65TEST(QuicIntervalConstructorTest, Move) {
66 int object1_copy_count, object1_move_count;
67 ConstructorListener object1(&object1_copy_count, &object1_move_count);
68 int object2_copy_count, object2_move_count;
69 ConstructorListener object2(&object2_copy_count, &object2_move_count);
70
71 QuicInterval<ConstructorListener> interval(object1, std::move(object2));
72 EXPECT_EQ(1, object1_copy_count);
73 EXPECT_EQ(0, object1_move_count);
74 EXPECT_EQ(0, object2_copy_count);
75 EXPECT_EQ(1, object2_move_count);
76}
77
78TEST(QuicIntervalConstructorTest, ImplicitConversion) {
79 struct WrappedInt {
80 WrappedInt(int value) : value(value) {}
81 bool operator<(const WrappedInt& other) { return value < other.value; }
82 bool operator>(const WrappedInt& other) { return value > other.value; }
83 bool operator<=(const WrappedInt& other) { return value <= other.value; }
84 bool operator>=(const WrappedInt& other) { return value >= other.value; }
85 bool operator==(const WrappedInt& other) { return value == other.value; }
86 int value;
87 };
88
89 static_assert(std::is_convertible<int, WrappedInt>::value, "");
90 static_assert(
91 std::is_constructible<QuicInterval<WrappedInt>, int, int>::value, "");
92
93 QuicInterval<WrappedInt> i(10, 20);
94 EXPECT_EQ(10, i.min().value);
95 EXPECT_EQ(20, i.max().value);
96}
97
98class QuicIntervalTest : public QuicTest {
99 protected:
100 // Test intersection between the two intervals i1 and i2. Tries
101 // i1.IntersectWith(i2) and vice versa. The intersection should change i1 iff
102 // changes_i1 is true, and the same for changes_i2. The resulting
103 // intersection should be result.
104 void TestIntersect(const QuicInterval<int64_t>& i1,
105 const QuicInterval<int64_t>& i2,
106 bool changes_i1,
107 bool changes_i2,
108 const QuicInterval<int64_t>& result) {
109 QuicInterval<int64_t> i;
110 i = i1;
111 EXPECT_TRUE(i.IntersectWith(i2) == changes_i1 && i == result);
112 i = i2;
113 EXPECT_TRUE(i.IntersectWith(i1) == changes_i2 && i == result);
114 }
115};
116
117TEST_F(QuicIntervalTest, ConstructorsCopyAndClear) {
118 QuicInterval<int32_t> empty;
119 EXPECT_TRUE(empty.Empty());
120
121 QuicInterval<int32_t> d2(0, 100);
122 EXPECT_EQ(0, d2.min());
123 EXPECT_EQ(100, d2.max());
124 EXPECT_EQ(QuicInterval<int32_t>(0, 100), d2);
125 EXPECT_NE(QuicInterval<int32_t>(0, 99), d2);
126
127 empty = d2;
128 EXPECT_EQ(0, d2.min());
129 EXPECT_EQ(100, d2.max());
130 EXPECT_TRUE(empty == d2);
131 EXPECT_EQ(empty, d2);
132 EXPECT_TRUE(d2 == empty);
133 EXPECT_EQ(d2, empty);
134
135 QuicInterval<int32_t> max_less_than_min(40, 20);
136 EXPECT_TRUE(max_less_than_min.Empty());
137 EXPECT_EQ(40, max_less_than_min.min());
138 EXPECT_EQ(20, max_less_than_min.max());
139
140 QuicInterval<int> d3(10, 20);
141 d3.Clear();
142 EXPECT_TRUE(d3.Empty());
143}
144
145TEST_F(QuicIntervalTest, MakeQuicInterval) {
146 static_assert(
147 std::is_same<QuicInterval<int>, decltype(MakeQuicInterval(0, 3))>::value,
148 "Type is deduced incorrectly.");
149 static_assert(std::is_same<QuicInterval<double>,
150 decltype(MakeQuicInterval(0., 3.))>::value,
151 "Type is deduced incorrectly.");
152
153 EXPECT_EQ(MakeQuicInterval(0., 3.), QuicInterval<double>(0, 3));
154}
155
156TEST_F(QuicIntervalTest, GettersSetters) {
157 QuicInterval<int32_t> d1(100, 200);
158
159 // SetMin:
160 d1.SetMin(30);
161 EXPECT_EQ(30, d1.min());
162 EXPECT_EQ(200, d1.max());
163
164 // SetMax:
165 d1.SetMax(220);
166 EXPECT_EQ(30, d1.min());
167 EXPECT_EQ(220, d1.max());
168
169 // Set:
170 d1.Clear();
171 d1.Set(30, 220);
172 EXPECT_EQ(30, d1.min());
173 EXPECT_EQ(220, d1.max());
174
175 // SpanningUnion:
176 QuicInterval<int32_t> d2;
177 EXPECT_TRUE(!d1.SpanningUnion(d2));
178 EXPECT_EQ(30, d1.min());
179 EXPECT_EQ(220, d1.max());
180
181 EXPECT_TRUE(d2.SpanningUnion(d1));
182 EXPECT_EQ(30, d2.min());
183 EXPECT_EQ(220, d2.max());
184
185 d2.SetMin(40);
186 d2.SetMax(100);
187 EXPECT_TRUE(!d1.SpanningUnion(d2));
188 EXPECT_EQ(30, d1.min());
189 EXPECT_EQ(220, d1.max());
190
191 d2.SetMin(20);
192 d2.SetMax(100);
193 EXPECT_TRUE(d1.SpanningUnion(d2));
194 EXPECT_EQ(20, d1.min());
195 EXPECT_EQ(220, d1.max());
196
197 d2.SetMin(50);
198 d2.SetMax(300);
199 EXPECT_TRUE(d1.SpanningUnion(d2));
200 EXPECT_EQ(20, d1.min());
201 EXPECT_EQ(300, d1.max());
202
203 d2.SetMin(0);
204 d2.SetMax(500);
205 EXPECT_TRUE(d1.SpanningUnion(d2));
206 EXPECT_EQ(0, d1.min());
207 EXPECT_EQ(500, d1.max());
208
209 d2.SetMin(100);
210 d2.SetMax(0);
211 EXPECT_TRUE(!d1.SpanningUnion(d2));
212 EXPECT_EQ(0, d1.min());
213 EXPECT_EQ(500, d1.max());
214 EXPECT_TRUE(d2.SpanningUnion(d1));
215 EXPECT_EQ(0, d2.min());
216 EXPECT_EQ(500, d2.max());
217}
218
219TEST_F(QuicIntervalTest, CoveringOps) {
220 const QuicInterval<int64_t> empty;
221 const QuicInterval<int64_t> d(100, 200);
222 const QuicInterval<int64_t> d1(0, 50);
223 const QuicInterval<int64_t> d2(50, 110);
224 const QuicInterval<int64_t> d3(110, 180);
225 const QuicInterval<int64_t> d4(180, 220);
226 const QuicInterval<int64_t> d5(220, 300);
227 const QuicInterval<int64_t> d6(100, 150);
228 const QuicInterval<int64_t> d7(150, 200);
229 const QuicInterval<int64_t> d8(0, 300);
230
231 // Intersection:
232 EXPECT_TRUE(d.Intersects(d));
233 EXPECT_TRUE(!empty.Intersects(d) && !d.Intersects(empty));
234 EXPECT_TRUE(!d.Intersects(d1) && !d1.Intersects(d));
235 EXPECT_TRUE(d.Intersects(d2) && d2.Intersects(d));
236 EXPECT_TRUE(d.Intersects(d3) && d3.Intersects(d));
237 EXPECT_TRUE(d.Intersects(d4) && d4.Intersects(d));
238 EXPECT_TRUE(!d.Intersects(d5) && !d5.Intersects(d));
239 EXPECT_TRUE(d.Intersects(d6) && d6.Intersects(d));
240 EXPECT_TRUE(d.Intersects(d7) && d7.Intersects(d));
241 EXPECT_TRUE(d.Intersects(d8) && d8.Intersects(d));
242
243 QuicInterval<int64_t> i;
244 EXPECT_TRUE(d.Intersects(d, &i) && d == i);
245 EXPECT_TRUE(!empty.Intersects(d, nullptr) && !d.Intersects(empty, nullptr));
246 EXPECT_TRUE(!d.Intersects(d1, nullptr) && !d1.Intersects(d, nullptr));
247 EXPECT_TRUE(d.Intersects(d2, &i) && i == QuicInterval<int64_t>(100, 110));
248 EXPECT_TRUE(d2.Intersects(d, &i) && i == QuicInterval<int64_t>(100, 110));
249 EXPECT_TRUE(d.Intersects(d3, &i) && i == d3);
250 EXPECT_TRUE(d3.Intersects(d, &i) && i == d3);
251 EXPECT_TRUE(d.Intersects(d4, &i) && i == QuicInterval<int64_t>(180, 200));
252 EXPECT_TRUE(d4.Intersects(d, &i) && i == QuicInterval<int64_t>(180, 200));
253 EXPECT_TRUE(!d.Intersects(d5, nullptr) && !d5.Intersects(d, nullptr));
254 EXPECT_TRUE(d.Intersects(d6, &i) && i == d6);
255 EXPECT_TRUE(d6.Intersects(d, &i) && i == d6);
256 EXPECT_TRUE(d.Intersects(d7, &i) && i == d7);
257 EXPECT_TRUE(d7.Intersects(d, &i) && i == d7);
258 EXPECT_TRUE(d.Intersects(d8, &i) && i == d);
259 EXPECT_TRUE(d8.Intersects(d, &i) && i == d);
260
261 // Test IntersectsWith().
262 // Arguments are TestIntersect(i1, i2, changes_i1, changes_i2, result).
263 TestIntersect(empty, d, false, true, empty);
264 TestIntersect(d, d1, true, true, empty);
265 TestIntersect(d1, d2, true, true, empty);
266 TestIntersect(d, d2, true, true, QuicInterval<int64_t>(100, 110));
267 TestIntersect(d8, d, true, false, d);
268 TestIntersect(d8, d1, true, false, d1);
269 TestIntersect(d8, d5, true, false, d5);
270
271 // Contains:
272 EXPECT_TRUE(!empty.Contains(d) && !d.Contains(empty));
273 EXPECT_TRUE(d.Contains(d));
274 EXPECT_TRUE(!d.Contains(d1) && !d1.Contains(d));
275 EXPECT_TRUE(!d.Contains(d2) && !d2.Contains(d));
276 EXPECT_TRUE(d.Contains(d3) && !d3.Contains(d));
277 EXPECT_TRUE(!d.Contains(d4) && !d4.Contains(d));
278 EXPECT_TRUE(!d.Contains(d5) && !d5.Contains(d));
279 EXPECT_TRUE(d.Contains(d6) && !d6.Contains(d));
280 EXPECT_TRUE(d.Contains(d7) && !d7.Contains(d));
281 EXPECT_TRUE(!d.Contains(d8) && d8.Contains(d));
282
283 EXPECT_TRUE(d.Contains(100));
284 EXPECT_TRUE(!d.Contains(200));
285 EXPECT_TRUE(d.Contains(150));
286 EXPECT_TRUE(!d.Contains(99));
287 EXPECT_TRUE(!d.Contains(201));
288
289 // Difference:
290 std::vector<QuicInterval<int64_t>*> diff;
291
292 EXPECT_TRUE(!d.Difference(empty, &diff));
293 EXPECT_EQ(1u, diff.size());
294 EXPECT_EQ(100, diff[0]->min());
295 EXPECT_EQ(200, diff[0]->max());
296 STLDeleteElements(&diff);
297 EXPECT_TRUE(!empty.Difference(d, &diff) && diff.empty());
298
299 EXPECT_TRUE(d.Difference(d, &diff) && diff.empty());
300 EXPECT_TRUE(!d.Difference(d1, &diff));
301 EXPECT_EQ(1u, diff.size());
302 EXPECT_EQ(100, diff[0]->min());
303 EXPECT_EQ(200, diff[0]->max());
304 STLDeleteElements(&diff);
305
306 QuicInterval<int64_t> lo;
307 QuicInterval<int64_t> hi;
308
309 EXPECT_TRUE(d.Difference(d2, &lo, &hi));
310 EXPECT_TRUE(lo.Empty());
311 EXPECT_EQ(110, hi.min());
312 EXPECT_EQ(200, hi.max());
313 EXPECT_TRUE(d.Difference(d2, &diff));
314 EXPECT_EQ(1u, diff.size());
315 EXPECT_EQ(110, diff[0]->min());
316 EXPECT_EQ(200, diff[0]->max());
317 STLDeleteElements(&diff);
318
319 EXPECT_TRUE(d.Difference(d3, &lo, &hi));
320 EXPECT_EQ(100, lo.min());
321 EXPECT_EQ(110, lo.max());
322 EXPECT_EQ(180, hi.min());
323 EXPECT_EQ(200, hi.max());
324 EXPECT_TRUE(d.Difference(d3, &diff));
325 EXPECT_EQ(2u, diff.size());
326 EXPECT_EQ(100, diff[0]->min());
327 EXPECT_EQ(110, diff[0]->max());
328 EXPECT_EQ(180, diff[1]->min());
329 EXPECT_EQ(200, diff[1]->max());
330 STLDeleteElements(&diff);
331
332 EXPECT_TRUE(d.Difference(d4, &lo, &hi));
333 EXPECT_EQ(100, lo.min());
334 EXPECT_EQ(180, lo.max());
335 EXPECT_TRUE(hi.Empty());
336 EXPECT_TRUE(d.Difference(d4, &diff));
337 EXPECT_EQ(1u, diff.size());
338 EXPECT_EQ(100, diff[0]->min());
339 EXPECT_EQ(180, diff[0]->max());
340 STLDeleteElements(&diff);
341
342 EXPECT_FALSE(d.Difference(d5, &lo, &hi));
343 EXPECT_EQ(100, lo.min());
344 EXPECT_EQ(200, lo.max());
345 EXPECT_TRUE(hi.Empty());
346 EXPECT_FALSE(d.Difference(d5, &diff));
347 EXPECT_EQ(1u, diff.size());
348 EXPECT_EQ(100, diff[0]->min());
349 EXPECT_EQ(200, diff[0]->max());
350 STLDeleteElements(&diff);
351
352 EXPECT_TRUE(d.Difference(d6, &lo, &hi));
353 EXPECT_TRUE(lo.Empty());
354 EXPECT_EQ(150, hi.min());
355 EXPECT_EQ(200, hi.max());
356 EXPECT_TRUE(d.Difference(d6, &diff));
357 EXPECT_EQ(1u, diff.size());
358 EXPECT_EQ(150, diff[0]->min());
359 EXPECT_EQ(200, diff[0]->max());
360 STLDeleteElements(&diff);
361
362 EXPECT_TRUE(d.Difference(d7, &lo, &hi));
363 EXPECT_EQ(100, lo.min());
364 EXPECT_EQ(150, lo.max());
365 EXPECT_TRUE(hi.Empty());
366 EXPECT_TRUE(d.Difference(d7, &diff));
367 EXPECT_EQ(1u, diff.size());
368 EXPECT_EQ(100, diff[0]->min());
369 EXPECT_EQ(150, diff[0]->max());
370 STLDeleteElements(&diff);
371
372 EXPECT_TRUE(d.Difference(d8, &lo, &hi));
373 EXPECT_TRUE(lo.Empty());
374 EXPECT_TRUE(hi.Empty());
375 EXPECT_TRUE(d.Difference(d8, &diff) && diff.empty());
376}
377
378TEST_F(QuicIntervalTest, Length) {
379 const QuicInterval<int> empty1;
380 const QuicInterval<int> empty2(1, 1);
381 const QuicInterval<int> empty3(1, 0);
382 const QuicInterval<QuicTime> empty4(
383 QuicTime::Zero() + QuicTime::Delta::FromSeconds(1), QuicTime::Zero());
384 const QuicInterval<int> d1(1, 2);
385 const QuicInterval<int> d2(0, 50);
386 const QuicInterval<QuicTime> d3(
387 QuicTime::Zero(), QuicTime::Zero() + QuicTime::Delta::FromSeconds(1));
388 const QuicInterval<QuicTime> d4(
389 QuicTime::Zero() + QuicTime::Delta::FromSeconds(3600),
390 QuicTime::Zero() + QuicTime::Delta::FromSeconds(5400));
391
392 EXPECT_EQ(0, empty1.Length());
393 EXPECT_EQ(0, empty2.Length());
394 EXPECT_EQ(0, empty3.Length());
395 EXPECT_EQ(QuicTime::Delta::Zero(), empty4.Length());
396 EXPECT_EQ(1, d1.Length());
397 EXPECT_EQ(50, d2.Length());
398 EXPECT_EQ(QuicTime::Delta::FromSeconds(1), d3.Length());
399 EXPECT_EQ(QuicTime::Delta::FromSeconds(1800), d4.Length());
400}
401
402TEST_F(QuicIntervalTest, IntervalOfTypeWithNoOperatorMinus) {
403 // QuicInterval<T> should work even if T does not support operator-(). We
404 // just can't call QuicInterval<T>::Length() for such types.
vasilvvc48c8712019-03-11 13:38:16 -0700405 const QuicInterval<std::string> d1("a", "b");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500406 const QuicInterval<std::pair<int, int>> d2({1, 2}, {4, 3});
407 EXPECT_EQ("a", d1.min());
408 EXPECT_EQ("b", d1.max());
409 EXPECT_EQ(std::make_pair(1, 2), d2.min());
410 EXPECT_EQ(std::make_pair(4, 3), d2.max());
411}
412
413struct NoEquals {
414 NoEquals(int v) : value(v) {} // NOLINT
415 int value;
416 bool operator<(const NoEquals& other) const { return value < other.value; }
417};
418
419TEST_F(QuicIntervalTest, OrderedComparisonForTypeWithoutEquals) {
420 const QuicInterval<NoEquals> d1(0, 4);
421 const QuicInterval<NoEquals> d2(0, 3);
422 const QuicInterval<NoEquals> d3(1, 4);
423 const QuicInterval<NoEquals> d4(1, 5);
424 const QuicInterval<NoEquals> d6(0, 4);
425 EXPECT_TRUE(d1 < d2);
426 EXPECT_TRUE(d1 < d3);
427 EXPECT_TRUE(d1 < d4);
428 EXPECT_FALSE(d1 < d6);
429}
430
431TEST_F(QuicIntervalTest, OutputReturnsOstreamRef) {
432 std::stringstream ss;
433 const QuicInterval<int> v(1, 2);
434 // If (ss << v) were to return a value, it wouldn't match the signature of
435 // return_type_is_a_ref() function.
436 auto return_type_is_a_ref = [](std::ostream&) {};
437 return_type_is_a_ref(ss << v);
438}
439
440struct NotOstreamable {
QUICHE team2d5d2342019-03-21 13:01:37 -0700441 bool operator<(const NotOstreamable&) const { return false; }
442 bool operator>=(const NotOstreamable&) const { return true; }
443 bool operator==(const NotOstreamable&) const { return true; }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500444};
445
446TEST_F(QuicIntervalTest, IntervalOfTypeWithNoOstreamSupport) {
447 const NotOstreamable v;
448 const QuicInterval<NotOstreamable> d(v, v);
449 // EXPECT_EQ builds a string representation of d. If d::operator<<() would be
450 // defined then this test would not compile because NotOstreamable objects
451 // lack the operator<<() support.
452 EXPECT_EQ(d, d);
453}
454
455} // namespace
456} // namespace test
457} // namespace quic