1 /*
2 * Copyright 2018 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 "rtc_base/unique_id_generator.h"
12
13 #include <string>
14 #include <vector>
15
16 #include "absl/algorithm/container.h"
17 #include "api/array_view.h"
18 #include "rtc_base/gunit.h"
19 #include "rtc_base/helpers.h"
20 #include "test/gmock.h"
21
22 using ::testing::IsEmpty;
23 using ::testing::Test;
24
25 namespace rtc {
26
27 template <typename Generator>
28 class UniqueIdGeneratorTest : public Test {};
29
30 using test_types = ::testing::Types<UniqueNumberGenerator<uint8_t>,
31 UniqueNumberGenerator<uint16_t>,
32 UniqueNumberGenerator<uint32_t>,
33 UniqueNumberGenerator<int>,
34 UniqueRandomIdGenerator,
35 UniqueStringGenerator>;
36
37 TYPED_TEST_SUITE(UniqueIdGeneratorTest, test_types);
38
TYPED_TEST(UniqueIdGeneratorTest,ElementsDoNotRepeat)39 TYPED_TEST(UniqueIdGeneratorTest, ElementsDoNotRepeat) {
40 typedef TypeParam Generator;
41 const size_t num_elements = 255;
42 Generator generator;
43 std::vector<typename Generator::value_type> values;
44 for (size_t i = 0; i < num_elements; i++) {
45 values.push_back(generator());
46 }
47
48 EXPECT_EQ(num_elements, values.size());
49 // Use a set to check uniqueness.
50 std::set<typename Generator::value_type> set(values.begin(), values.end());
51 EXPECT_EQ(values.size(), set.size()) << "Returned values were not unique.";
52 }
53
TYPED_TEST(UniqueIdGeneratorTest,KnownElementsAreNotGenerated)54 TYPED_TEST(UniqueIdGeneratorTest, KnownElementsAreNotGenerated) {
55 typedef TypeParam Generator;
56 const size_t num_elements = 100;
57 rtc::InitRandom(0);
58 Generator generator1;
59 std::vector<typename Generator::value_type> known_values;
60 for (size_t i = 0; i < num_elements; i++) {
61 known_values.push_back(generator1());
62 }
63 EXPECT_EQ(num_elements, known_values.size());
64
65 rtc::InitRandom(0);
66 Generator generator2(known_values);
67
68 std::vector<typename Generator::value_type> values;
69 for (size_t i = 0; i < num_elements; i++) {
70 values.push_back(generator2());
71 }
72 EXPECT_THAT(values, ::testing::SizeIs(num_elements));
73 absl::c_sort(values);
74 absl::c_sort(known_values);
75 std::vector<typename Generator::value_type> intersection;
76 absl::c_set_intersection(values, known_values,
77 std::back_inserter(intersection));
78 EXPECT_THAT(intersection, IsEmpty());
79 }
80
TYPED_TEST(UniqueIdGeneratorTest,AddedElementsAreNotGenerated)81 TYPED_TEST(UniqueIdGeneratorTest, AddedElementsAreNotGenerated) {
82 typedef TypeParam Generator;
83 const size_t num_elements = 100;
84 rtc::InitRandom(0);
85 Generator generator1;
86 std::vector<typename Generator::value_type> known_values;
87 for (size_t i = 0; i < num_elements; i++) {
88 known_values.push_back(generator1());
89 }
90 EXPECT_EQ(num_elements, known_values.size());
91
92 rtc::InitRandom(0);
93 Generator generator2;
94
95 for (const typename Generator::value_type& value : known_values) {
96 generator2.AddKnownId(value);
97 }
98
99 std::vector<typename Generator::value_type> values;
100 for (size_t i = 0; i < num_elements; i++) {
101 values.push_back(generator2());
102 }
103 EXPECT_THAT(values, ::testing::SizeIs(num_elements));
104 absl::c_sort(values);
105 absl::c_sort(known_values);
106 std::vector<typename Generator::value_type> intersection;
107 absl::c_set_intersection(values, known_values,
108 std::back_inserter(intersection));
109 EXPECT_THAT(intersection, IsEmpty());
110 }
111
TYPED_TEST(UniqueIdGeneratorTest,AddKnownIdOnNewIdReturnsTrue)112 TYPED_TEST(UniqueIdGeneratorTest, AddKnownIdOnNewIdReturnsTrue) {
113 typedef TypeParam Generator;
114
115 rtc::InitRandom(0);
116 Generator generator1;
117 const typename Generator::value_type id = generator1();
118
119 rtc::InitRandom(0);
120 Generator generator2;
121 EXPECT_TRUE(generator2.AddKnownId(id));
122 }
123
TYPED_TEST(UniqueIdGeneratorTest,AddKnownIdCalledAgainForSameIdReturnsFalse)124 TYPED_TEST(UniqueIdGeneratorTest, AddKnownIdCalledAgainForSameIdReturnsFalse) {
125 typedef TypeParam Generator;
126
127 rtc::InitRandom(0);
128 Generator generator1;
129 const typename Generator::value_type id = generator1();
130
131 rtc::InitRandom(0);
132 Generator generator2;
133 ASSERT_TRUE(generator2.AddKnownId(id));
134 EXPECT_FALSE(generator2.AddKnownId(id));
135 }
136
TYPED_TEST(UniqueIdGeneratorTest,AddKnownIdOnIdProvidedAsKnownToCtorReturnsFalse)137 TYPED_TEST(UniqueIdGeneratorTest,
138 AddKnownIdOnIdProvidedAsKnownToCtorReturnsFalse) {
139 typedef TypeParam Generator;
140
141 rtc::InitRandom(0);
142 Generator generator1;
143 const typename Generator::value_type id = generator1();
144 std::vector<typename Generator::value_type> known_values = {id};
145
146 rtc::InitRandom(0);
147 Generator generator2(known_values);
148 EXPECT_FALSE(generator2.AddKnownId(id));
149 }
150
151 } // namespace rtc
152