xref: /aosp_15_r20/external/cronet/base/uuid_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2012 The Chromium Authors
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 "base/uuid.h"
6 
7 #include <stdint.h>
8 
9 #include <limits>
10 #include <set>
11 #include <string_view>
12 #include <unordered_set>
13 
14 #include "base/strings/string_util.h"
15 #include "build/build_config.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 
18 namespace base {
19 
20 namespace {
21 
22 // The format of Uuid version 4 must be xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx,
23 // where y is one of [8, 9, a, b].
IsValidV4(const Uuid & guid)24 bool IsValidV4(const Uuid& guid) {
25   const std::string& lowercase = guid.AsLowercaseString();
26   return guid.is_valid() && lowercase[14] == '4' &&
27          (lowercase[19] == '8' || lowercase[19] == '9' ||
28           lowercase[19] == 'a' || lowercase[19] == 'b');
29 }
30 
31 }  // namespace
32 
TEST(UuidTest,UuidBasicUniqueness)33 TEST(UuidTest, UuidBasicUniqueness) {
34   constexpr int kIterations = 10;
35   for (int i = 0; i < kIterations; ++i) {
36     const Uuid guid1 = Uuid::GenerateRandomV4();
37     const Uuid guid2 = Uuid::GenerateRandomV4();
38     EXPECT_NE(guid1, guid2);
39     EXPECT_TRUE(guid1.is_valid());
40     EXPECT_TRUE(IsValidV4(guid1));
41     EXPECT_TRUE(guid2.is_valid());
42     EXPECT_TRUE(IsValidV4(guid2));
43   }
44 }
45 
46 namespace {
47 
TestUuidValidity(std::string_view input,bool case_insensitive,bool strict)48 void TestUuidValidity(std::string_view input,
49                       bool case_insensitive,
50                       bool strict) {
51   SCOPED_TRACE(input);
52   {
53     const Uuid guid = Uuid::ParseCaseInsensitive(input);
54     EXPECT_EQ(case_insensitive, guid.is_valid());
55   }
56   {
57     const Uuid guid = Uuid::ParseLowercase(input);
58     EXPECT_EQ(strict, guid.is_valid());
59   }
60 }
61 
62 }  // namespace
63 
TEST(UuidTest,Validity)64 TEST(UuidTest, Validity) {
65   // Empty Uuid is invalid.
66   EXPECT_FALSE(Uuid().is_valid());
67 
68   enum Parsability { kDoesntParse, kParsesCaseInsensitiveOnly, kAlwaysParses };
69 
70   static constexpr struct {
71     std::string_view input;
72     Parsability parsability;
73   } kUuidValidity[] = {
74       {"invalid", kDoesntParse},
75       {"0123456789ab-cdef-fedc-ba98-76543210", kDoesntParse},
76       {"0123456789abcdeffedcba9876543210", kDoesntParse},
77       {"01234567-89Zz-ZzZz-ZzZz-Zz9876543210", kDoesntParse},
78       {"DEADBEEFDEADBEEFDEADBEEFDEADBEEF", kDoesntParse},
79       {"deadbeefWdeadXbeefYdeadZbeefdeadbeef", kDoesntParse},
80       {"XXXdeadbeefWdeadXbeefYdeadZbeefdeadbeefXXX", kDoesntParse},
81       {"01234567-89aB-cDeF-fEdC-bA9876543210", kParsesCaseInsensitiveOnly},
82       {"DEADBEEF-DEAD-BEEF-DEAD-BEEFDEADBEEF", kParsesCaseInsensitiveOnly},
83       {"00000000-0000-0000-0000-000000000000", kAlwaysParses},
84       {"deadbeef-dead-beef-dead-beefdeadbeef", kAlwaysParses},
85   };
86 
87   for (const auto& validity : kUuidValidity) {
88     const bool case_insensitive = validity.parsability != kDoesntParse;
89     const bool strict = validity.parsability == kAlwaysParses;
90     TestUuidValidity(validity.input, case_insensitive, strict);
91   }
92 }
93 
TEST(UuidTest,EqualityAndRoundTrip)94 TEST(UuidTest, EqualityAndRoundTrip) {
95   static constexpr char kCanonicalStr[] =
96       "deadbeef-dead-4eef-bead-beefdeadbeef";
97 
98   const Uuid from_lower =
99       Uuid::ParseCaseInsensitive(ToLowerASCII(kCanonicalStr));
100   EXPECT_EQ(kCanonicalStr, from_lower.AsLowercaseString());
101 
102   const Uuid from_upper =
103       Uuid::ParseCaseInsensitive(ToUpperASCII(kCanonicalStr));
104   EXPECT_EQ(kCanonicalStr, from_upper.AsLowercaseString());
105 
106   EXPECT_EQ(from_lower, from_upper);
107 
108   // Invalid Uuids are equal.
109   EXPECT_EQ(Uuid(), Uuid());
110 }
111 
TEST(UuidTest,UnorderedSet)112 TEST(UuidTest, UnorderedSet) {
113   std::unordered_set<Uuid, UuidHash> guid_set;
114 
115   static constexpr char kUuid1[] = "01234567-89ab-cdef-fedc-ba9876543210";
116   guid_set.insert(Uuid::ParseCaseInsensitive(ToLowerASCII(kUuid1)));
117   EXPECT_EQ(1u, guid_set.size());
118   guid_set.insert(Uuid::ParseCaseInsensitive(ToUpperASCII(kUuid1)));
119   EXPECT_EQ(1u, guid_set.size());
120 
121   static constexpr char kUuid2[] = "deadbeef-dead-beef-dead-beefdeadbeef";
122   guid_set.insert(Uuid::ParseCaseInsensitive(ToLowerASCII(kUuid2)));
123   EXPECT_EQ(2u, guid_set.size());
124   guid_set.insert(Uuid::ParseCaseInsensitive(ToUpperASCII(kUuid2)));
125   EXPECT_EQ(2u, guid_set.size());
126 }
127 
TEST(UuidTest,Set)128 TEST(UuidTest, Set) {
129   std::set<Uuid> guid_set;
130 
131   static constexpr char kUuid1[] = "01234567-89ab-cdef-0123-456789abcdef";
132   const Uuid guid1 = Uuid::ParseLowercase(kUuid1);
133   ASSERT_TRUE(guid1.is_valid());
134   guid_set.insert(guid1);
135 
136   static constexpr char kUuid2[] = "deadbeef-dead-beef-dead-beefdeadbeef";
137   const Uuid guid2 = Uuid::ParseLowercase(kUuid2);
138   ASSERT_TRUE(guid2.is_valid());
139   guid_set.insert(guid2);
140 
141   // Test that the order of the Uuids was preserved.
142   auto it = guid_set.begin();
143   EXPECT_EQ(guid1, *it);
144   ++it;
145   EXPECT_EQ(guid2, *it);
146   ++it;
147   EXPECT_EQ(guid_set.end(), it);
148 }
149 
TEST(UuidTest,Compare)150 TEST(UuidTest, Compare) {
151   static constexpr char kUuid[] = "21abd97f-73e8-4b88-9389-a9fee6abda5e";
152   static constexpr char kUuidLess[] = "1e0dcaca-9e7c-4f4b-bcc6-e4c02b0c99df";
153   static constexpr char kUuidGreater[] = "6eeb1bc8-186b-433c-9d6a-a827bc96b2d4";
154 
155   const Uuid guid = Uuid::ParseLowercase(kUuid);
156   const Uuid guid_eq = Uuid::ParseLowercase(kUuid);
157   const Uuid guid_lt = Uuid::ParseLowercase(kUuidLess);
158   const Uuid guid_gt = Uuid::ParseLowercase(kUuidGreater);
159   const Uuid guid_invalid = Uuid();
160 
161   EXPECT_TRUE(guid_eq == guid);
162   EXPECT_FALSE(guid_eq != guid);
163   EXPECT_FALSE(guid_eq < guid);
164   EXPECT_TRUE(guid_eq <= guid);
165   EXPECT_FALSE(guid_eq > guid);
166   EXPECT_TRUE(guid_eq >= guid);
167 
168   EXPECT_FALSE(guid_lt == guid);
169   EXPECT_TRUE(guid_lt != guid);
170   EXPECT_TRUE(guid_lt < guid);
171   EXPECT_TRUE(guid_lt <= guid);
172   EXPECT_FALSE(guid_lt > guid);
173   EXPECT_FALSE(guid_lt >= guid);
174 
175   EXPECT_FALSE(guid_gt == guid);
176   EXPECT_TRUE(guid_gt != guid);
177   EXPECT_FALSE(guid_gt < guid);
178   EXPECT_FALSE(guid_gt <= guid);
179   EXPECT_TRUE(guid_gt > guid);
180   EXPECT_TRUE(guid_gt >= guid);
181 
182   // Invalid Uuids are the "least".
183   EXPECT_FALSE(guid_invalid == guid);
184   EXPECT_TRUE(guid_invalid != guid);
185   EXPECT_TRUE(guid_invalid < guid);
186   EXPECT_TRUE(guid_invalid <= guid);
187   EXPECT_FALSE(guid_invalid > guid);
188   EXPECT_FALSE(guid_invalid >= guid);
189 }
190 
TEST(UuidTest,FormatRandomDataAsV4)191 TEST(UuidTest, FormatRandomDataAsV4) {
192   static constexpr uint64_t bytes1a[] = {0x0123456789abcdefull,
193                                          0x5a5a5a5aa5a5a5a5ull};
194   static constexpr uint64_t bytes1b[] = {bytes1a[0], bytes1a[1]};
195   static constexpr uint64_t bytes2[] = {0xfffffffffffffffdull,
196                                         0xfffffffffffffffeull};
197   static constexpr uint64_t bytes3[] = {0xfffffffffffffffdull,
198                                         0xfffffffffffffffcull};
199 
200   const Uuid guid1a =
201       Uuid::FormatRandomDataAsV4ForTesting(as_bytes(make_span(bytes1a)));
202   const Uuid guid1b =
203       Uuid::FormatRandomDataAsV4ForTesting(as_bytes(make_span(bytes1b)));
204   const Uuid guid2 =
205       Uuid::FormatRandomDataAsV4ForTesting(as_bytes(make_span(bytes2)));
206   const Uuid guid3 =
207       Uuid::FormatRandomDataAsV4ForTesting(as_bytes(make_span(bytes3)));
208 
209   EXPECT_TRUE(guid1a.is_valid());
210   EXPECT_TRUE(guid1b.is_valid());
211   EXPECT_TRUE(guid2.is_valid());
212   EXPECT_TRUE(guid3.is_valid());
213 
214   // The same input should give the same Uuid.
215   EXPECT_EQ(guid1a, guid1b);
216 
217   EXPECT_NE(guid1a, guid2);
218   EXPECT_NE(guid1a, guid3);
219   EXPECT_NE(guid2, guid3);
220 }
221 
222 }  // namespace base
223