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