xref: /aosp_15_r20/external/pigweed/pw_bluetooth_sapphire/host/common/uuid_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 #include "pw_bluetooth_sapphire/internal/host/common/uuid.h"
16 
17 #include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h"
18 #include "pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
19 #include "pw_unit_test/framework.h"
20 
21 namespace bt {
22 namespace {
23 
24 // Variants of 16-bit ID 180d
25 constexpr uint16_t kId1As16 = 0x180d;
26 constexpr uint32_t kId1As32 = 0x0000180d;
27 constexpr UInt128 kId1As128 = {{0xFB,
28                                 0x34,
29                                 0x9B,
30                                 0x5F,
31                                 0x80,
32                                 0x00,
33                                 0x00,
34                                 0x80,
35                                 0x00,
36                                 0x10,
37                                 0x00,
38                                 0x00,
39                                 0x0d,
40                                 0x18,
41                                 0x00,
42                                 0x00}};
43 constexpr char kId1AsString[] = "0000180d-0000-1000-8000-00805f9b34fb";
44 
45 // 16-bit ID for comparison
46 constexpr uint16_t kOther16BitId = 0x1800;
47 
48 // Variants of 32-bit ID 0xdeadbeef
49 constexpr uint32_t kId2As32 = 0xdeadbeef;
50 constexpr UInt128 kId2As128 = {{0xFB,
51                                 0x34,
52                                 0x9B,
53                                 0x5F,
54                                 0x80,
55                                 0x00,
56                                 0x00,
57                                 0x80,
58                                 0x00,
59                                 0x10,
60                                 0x00,
61                                 0x00,
62                                 0xef,
63                                 0xbe,
64                                 0xad,
65                                 0xde}};
66 constexpr char kId2AsString[] = "deadbeef-0000-1000-8000-00805f9b34fb";
67 
68 constexpr UInt128 kId3As128 = {
69     {0x00,
70      0x01,
71      0x02,
72      0x03,
73      0x04,
74      0x05,
75      0x06,
76      0x07,
77      0x08,
78      0x09,
79      0x0A,
80      0x0B,
81 
82      // Make this part be the same as kId1* for the sake of testing.
83      0x0d,
84      0x18,
85      0x00,
86      0x00}};
87 constexpr char kId3AsString[] = "0000180d-0b0a-0908-0706-050403020100";
88 
89 TEST(UUIDTest, 16Bit) {
90   constexpr UUID uuid(kId1As16);
91 
92   // We perform each comparison twice, swapping the lhs and rhs, to test the
93   // top-level equality operators.
94 
95   // Direct comparison with uint16_t.
96   EXPECT_EQ(uuid, kId1As16);
97   EXPECT_NE(uuid, kOther16BitId);
98   EXPECT_EQ(kId1As16, uuid);
99   EXPECT_NE(kOther16BitId, uuid);
100 
101   // Direct comparison with uint32_t.
102   EXPECT_EQ(uuid, kId1As32);
103   EXPECT_NE(uuid, kId2As32);
104   EXPECT_EQ(kId1As32, uuid);
105   EXPECT_NE(kId2As32, uuid);
106 
107   // Direct comparison with UInt128.
108   EXPECT_EQ(kId1As128, uuid);
109   EXPECT_NE(kId2As128, uuid);
110 
111   // Direct comparison with UUID.
112   EXPECT_EQ(UUID(kId1As16), uuid);
113   EXPECT_EQ(UUID(kId1As32), uuid);
114   EXPECT_EQ(UUID(static_cast<uint16_t>(kId1As32)), uuid);
115   EXPECT_EQ(UUID(kId1As128), uuid);
116   EXPECT_NE(UUID(kOther16BitId), uuid);
117   EXPECT_NE(UUID(kId2As32), uuid);
118   EXPECT_NE(UUID(kId2As128), uuid);
119 
120   auto as16 = uuid.As16Bit();
121   EXPECT_TRUE(as16);
122   EXPECT_EQ(kId1As16, *as16);
123 }
124 
125 TEST(UUIDTest, 32Bit) {
126   constexpr UUID uuid(kId2As32);
127 
128   // Direct comparison with uint32_t.
129   EXPECT_EQ(uuid, kId2As32);
130   EXPECT_EQ(kId2As32, uuid);
131   EXPECT_NE(uuid, kId1As32);
132   EXPECT_NE(kId1As32, uuid);
133 
134   // Direct comparison with UInt128.
135   EXPECT_EQ(kId2As128, uuid);
136   EXPECT_NE(kId1As128, uuid);
137 
138   // Direct comparison with UUID.
139   EXPECT_EQ(UUID(kId2As32), uuid);
140   EXPECT_EQ(UUID(kId2As128), uuid);
141   EXPECT_NE(UUID(kId1As16), uuid);
142   EXPECT_NE(UUID(kId1As32), uuid);
143   EXPECT_NE(UUID(kId1As128), uuid);
144 
145   EXPECT_FALSE(uuid.As16Bit());
146 }
147 
148 TEST(UUIDTest, 128Bit) {
149   constexpr UUID uuid(kId3As128);
150 
151   EXPECT_EQ(kId3As128, uuid);
152 
153   // 16-bit and 32-bit comparison should fail as the base-UUID portions do not
154   // match.
155   EXPECT_NE(kId1As16, uuid);
156   EXPECT_NE(kId1As32, uuid);
157 
158   EXPECT_EQ(UUID(kId3As128), uuid);
159   EXPECT_NE(UUID(kId1As128), uuid);
160 
161   EXPECT_FALSE(uuid.As16Bit());
162 }
163 
TEST(UUIDTest,CompareBytes)164 TEST(UUIDTest, CompareBytes) {
165   StaticByteBuffer kUuid16Bytes(0x0d, 0x18);
166   StaticByteBuffer kUuid32Bytes(0x0d, 0x18, 0x00, 0x00);
167   StaticByteBuffer kUuid128Bytes(0xFB,
168                                  0x34,
169                                  0x9B,
170                                  0x5F,
171                                  0x80,
172                                  0x00,
173                                  0x00,
174                                  0x80,
175                                  0x00,
176                                  0x10,
177                                  0x00,
178                                  0x00,
179                                  0x0d,
180                                  0x18,
181                                  0x00,
182                                  0x00);
183 
184   constexpr UUID uuid(kId1As16);
185   EXPECT_TRUE(uuid.CompareBytes(kUuid16Bytes));
186   EXPECT_TRUE(uuid.CompareBytes(kUuid32Bytes));
187   EXPECT_TRUE(uuid.CompareBytes(kUuid128Bytes));
188 
189   BufferView empty;
190   EXPECT_FALSE(uuid.CompareBytes(empty));
191 }
192 
TEST(UUIDTest,ToString)193 TEST(UUIDTest, ToString) {
194   EXPECT_EQ(kId1AsString, UUID(kId1As16).ToString());
195   EXPECT_EQ(kId1AsString, UUID(kId1As32).ToString());
196   EXPECT_EQ(kId1AsString, UUID(kId1As128).ToString());
197 
198   EXPECT_EQ(kId2AsString, UUID(kId2As32).ToString());
199   EXPECT_EQ(kId2AsString, UUID(kId2As128).ToString());
200 
201   EXPECT_EQ(kId3AsString, UUID(kId3As128).ToString());
202 }
203 
TEST(UUIDTest,IsStringValidUuid)204 TEST(UUIDTest, IsStringValidUuid) {
205   EXPECT_FALSE(IsStringValidUuid("0000180d00001000800000805f9b34fb"));
206   EXPECT_FALSE(IsStringValidUuid("0000180d-0000-1000-8000000805f9b34fb"));
207   EXPECT_FALSE(IsStringValidUuid("0000180d-0000-100008000-00805f9b34fb"));
208   EXPECT_FALSE(IsStringValidUuid("0000180d-000001000-8000-00805f9b34fb"));
209   EXPECT_FALSE(IsStringValidUuid("0000180d00000-1000-8000-00805f9b34fb"));
210   EXPECT_FALSE(IsStringValidUuid("0000180d-0000-1000-8000-00805g9b34fb"));
211   EXPECT_FALSE(IsStringValidUuid("000-180d-0000-1000-8000-00805f9b34fb"));
212 
213   // Combinations of lower and upper case characters should work.
214   EXPECT_TRUE(IsStringValidUuid("0000180d-0000-1000-8000-00805f9b34fb"));
215   EXPECT_TRUE(IsStringValidUuid("0000180D-0000-1000-8000-00805F9B34FB"));
216   EXPECT_TRUE(IsStringValidUuid("0000180d-0000-1000-8000-00805F9b34fB"));
217   EXPECT_TRUE(IsStringValidUuid(kId2AsString));
218   EXPECT_TRUE(IsStringValidUuid(kId3AsString));
219 }
220 
TEST(UUIDTest,StringToUuid)221 TEST(UUIDTest, StringToUuid) {
222   UUID uuid;
223 
224   EXPECT_FALSE(StringToUuid("0000180d00001000800000805f9b34fb", &uuid));
225   EXPECT_FALSE(StringToUuid("0000180d-0000-1000-8000000805f9b34fb", &uuid));
226   EXPECT_FALSE(StringToUuid("0000180d-0000-100008000-00805f9b34fb", &uuid));
227   EXPECT_FALSE(StringToUuid("0000180d-000001000-8000-00805f9b34fb", &uuid));
228   EXPECT_FALSE(StringToUuid("0000180d00000-1000-8000-00805f9b34fb", &uuid));
229   EXPECT_FALSE(StringToUuid("0000180d-0000-1000-8000-00805g9b34fb", &uuid));
230   EXPECT_FALSE(StringToUuid("000-180d-0000-1000-8000-00805f9b34fb", &uuid));
231 
232   // Combinations of lower and upper case characters should work.
233   EXPECT_TRUE(StringToUuid("0000180d-0000-1000-8000-00805f9b34fb", &uuid));
234   EXPECT_EQ(kId1As16, uuid);
235   EXPECT_TRUE(StringToUuid("0000180D-0000-1000-8000-00805F9B34FB", &uuid));
236   EXPECT_EQ(kId1As16, uuid);
237   EXPECT_TRUE(StringToUuid("0000180d-0000-1000-8000-00805F9b34fB", &uuid));
238   EXPECT_EQ(kId1As16, uuid);
239 
240   EXPECT_TRUE(StringToUuid(kId2AsString, &uuid));
241   EXPECT_EQ(kId2As32, uuid);
242 
243   EXPECT_TRUE(StringToUuid(kId3AsString, &uuid));
244   EXPECT_EQ(kId3As128, uuid.value());
245 }
246 
TEST(UUIDTest,StringToUuid16)247 TEST(UUIDTest, StringToUuid16) {
248   UUID uuid;
249 
250   EXPECT_FALSE(StringToUuid("0180d", &uuid));
251   EXPECT_FALSE(StringToUuid("0000180d", &uuid));
252   EXPECT_FALSE(StringToUuid("why", &uuid));
253   EXPECT_FALSE(StringToUuid("d", &uuid));
254   EXPECT_FALSE(StringToUuid("0x180d", &uuid));
255 
256   // Combinations of lower and upper case characters should work.
257   EXPECT_TRUE(StringToUuid("180d", &uuid));
258   EXPECT_EQ(kId1As16, uuid);
259   EXPECT_TRUE(StringToUuid("180D", &uuid));
260   EXPECT_EQ(kId1As16, uuid);
261 }
262 
TEST(UUIDTest,FromBytes)263 TEST(UUIDTest, FromBytes) {
264   StaticByteBuffer kUuid16Bytes(0x0d, 0x18);
265   StaticByteBuffer kUuid32Bytes(0x0d, 0x18, 0x00, 0x00);
266   StaticByteBuffer kUuid128Bytes(0xFB,
267                                  0x34,
268                                  0x9B,
269                                  0x5F,
270                                  0x80,
271                                  0x00,
272                                  0x00,
273                                  0x80,
274                                  0x00,
275                                  0x10,
276                                  0x00,
277                                  0x00,
278                                  0x0d,
279                                  0x18,
280                                  0x00,
281                                  0x00);
282 
283   StaticByteBuffer kInvalid0(0x0d);
284   StaticByteBuffer kInvalid1(0x0d, 0x18, 0x00);
285   BufferView kInvalid2;
286 
287   UUID uuid;
288 
289   EXPECT_FALSE(UUID::FromBytes(kInvalid0, &uuid));
290   EXPECT_FALSE(UUID::FromBytes(kInvalid1, &uuid));
291   EXPECT_FALSE(UUID::FromBytes(kInvalid2, &uuid));
292 
293   EXPECT_TRUE(UUID::FromBytes(kUuid16Bytes, &uuid));
294   EXPECT_EQ(kId1As16, uuid);
295   EXPECT_TRUE(UUID::FromBytes(kUuid32Bytes, &uuid));
296   EXPECT_EQ(kId1As16, uuid);
297   EXPECT_TRUE(UUID::FromBytes(kUuid128Bytes, &uuid));
298   EXPECT_EQ(kId1As16, uuid);
299 }
300 
TEST(UUIDTest,ByteConstructor)301 TEST(UUIDTest, ByteConstructor) {
302   const StaticByteBuffer kUuid16(0x0d, 0x18);
303   UUID uuid(kUuid16);
304   EXPECT_EQ(kId1As16, uuid);
305 }
306 
TEST(UUIDTest,ByteConstructorAssertsOnInvalidInput)307 TEST(UUIDTest, ByteConstructorAssertsOnInvalidInput) {
308   const StaticByteBuffer kInvalidUuid(0x0d);
309   EXPECT_DEATH_IF_SUPPORTED((UUID(kInvalidUuid)), ".*");
310 }
311 
TEST(UUIDTest,CompactSize)312 TEST(UUIDTest, CompactSize) {
313   UUID direct(kId1As16);
314   UUID fromstring;
315 
316   StringToUuid(kId1AsString, &fromstring);
317 
318   EXPECT_EQ(2u, direct.CompactSize());
319   EXPECT_EQ(2u, fromstring.CompactSize());
320 
321   direct = UUID(kId2As32);
322   StringToUuid(kId2AsString, &fromstring);
323 
324   EXPECT_EQ(4u, direct.CompactSize());
325   EXPECT_EQ(4u, fromstring.CompactSize());
326   EXPECT_EQ(16u, direct.CompactSize(/*allow_32bit=*/false));
327   EXPECT_EQ(16u, fromstring.CompactSize(/*allow_32bit=*/false));
328 
329   direct = UUID(kId3As128);
330   StringToUuid(kId3AsString, &fromstring);
331 
332   EXPECT_EQ(16u, direct.CompactSize());
333   EXPECT_EQ(16u, fromstring.CompactSize());
334 }
335 
TEST(UUIDTest,ToBytes16)336 TEST(UUIDTest, ToBytes16) {
337   StaticByteBuffer kUuid16Bytes(0x0d, 0x18);
338 
339   UUID uuid(kId1As16);
340   DynamicByteBuffer bytes(uuid.CompactSize());
341 
342   EXPECT_EQ(bytes.size(), uuid.ToBytes(&bytes));
343   EXPECT_TRUE(ContainersEqual(kUuid16Bytes, bytes));
344 
345   uuid = UUID(kId1As32);
346 
347   EXPECT_EQ(bytes.size(), uuid.ToBytes(&bytes));
348   EXPECT_TRUE(ContainersEqual(kUuid16Bytes, bytes));
349 }
350 
TEST(UUIDTest,ToBytes32)351 TEST(UUIDTest, ToBytes32) {
352   StaticByteBuffer kUuid32Bytes(0xef, 0xbe, 0xad, 0xde);
353 
354   UUID uuid(kId2As32);
355   DynamicByteBuffer bytes(uuid.CompactSize());
356 
357   EXPECT_EQ(bytes.size(), uuid.ToBytes(&bytes));
358   EXPECT_TRUE(ContainersEqual(kUuid32Bytes, bytes));
359 
360   StaticByteBuffer<16> bytes128;
361   EXPECT_EQ(bytes128.size(), uuid.ToBytes(&bytes128, /*allow_32bit=*/false));
362   EXPECT_TRUE(ContainersEqual(kId2As128, bytes128));
363 }
364 
TEST(UUIDTest,CompactView16)365 TEST(UUIDTest, CompactView16) {
366   StaticByteBuffer kUuid16Bytes(0x0d, 0x18);
367 
368   UUID uuid(kId1As16);
369 
370   BufferView view = uuid.CompactView();
371   EXPECT_TRUE(ContainersEqual(kUuid16Bytes, view));
372 
373   uuid = UUID(kId1As32);
374   view = uuid.CompactView();
375   EXPECT_TRUE(ContainersEqual(kUuid16Bytes, view));
376 }
377 
TEST(UUIDTest,CompactView32)378 TEST(UUIDTest, CompactView32) {
379   StaticByteBuffer kUuid32Bytes(0xef, 0xbe, 0xad, 0xde);
380 
381   UUID uuid(kId2As32);
382 
383   BufferView view = uuid.CompactView();
384   EXPECT_TRUE(ContainersEqual(kUuid32Bytes, view));
385 
386   view = uuid.CompactView(/*allow_32bit=*/false);
387   EXPECT_TRUE(ContainersEqual(kId2As128, view));
388 }
389 
TEST(UUIDTest,Hash)390 TEST(UUIDTest, Hash) {
391   constexpr UUID uuid1(kId3As128);
392   constexpr UUID uuid2(kId3As128);
393 
394   EXPECT_EQ(uuid1, uuid2);
395   EXPECT_EQ(uuid1.Hash(), uuid2.Hash());
396 }
397 
TEST(UUIDTest,Generate)398 TEST(UUIDTest, Generate) {
399   for (int i = 0; i < 50; i++) {
400     UUID uuid = UUID::Generate();
401     EXPECT_EQ(uuid.value()[6] & 0b1111'0000, 0b0100'0000);
402     EXPECT_EQ(uuid.value()[8] & 0b1100'0000, 0b1000'0000);
403   }
404 }
405 
406 }  // namespace
407 }  // namespace bt
408