uuid_test.cc 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. // Copyright 2014 The Crashpad Authors. All rights reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://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,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "util/misc/uuid.h"
  15. #include <string.h>
  16. #include <sys/types.h>
  17. #include <string>
  18. #include "base/format_macros.h"
  19. #include "base/macros.h"
  20. #include "base/scoped_generic.h"
  21. #include "base/strings/stringprintf.h"
  22. #include "gtest/gtest.h"
  23. namespace crashpad {
  24. namespace test {
  25. namespace {
  26. TEST(UUID, UUID) {
  27. UUID uuid_zero;
  28. uuid_zero.InitializeToZero();
  29. EXPECT_EQ(uuid_zero.data_1, 0u);
  30. EXPECT_EQ(uuid_zero.data_2, 0u);
  31. EXPECT_EQ(uuid_zero.data_3, 0u);
  32. EXPECT_EQ(uuid_zero.data_4[0], 0u);
  33. EXPECT_EQ(uuid_zero.data_4[1], 0u);
  34. EXPECT_EQ(uuid_zero.data_5[0], 0u);
  35. EXPECT_EQ(uuid_zero.data_5[1], 0u);
  36. EXPECT_EQ(uuid_zero.data_5[2], 0u);
  37. EXPECT_EQ(uuid_zero.data_5[3], 0u);
  38. EXPECT_EQ(uuid_zero.data_5[4], 0u);
  39. EXPECT_EQ(uuid_zero.data_5[5], 0u);
  40. EXPECT_EQ(uuid_zero.ToString(), "00000000-0000-0000-0000-000000000000");
  41. static constexpr uint8_t kBytes[16] = {0x00,
  42. 0x01,
  43. 0x02,
  44. 0x03,
  45. 0x04,
  46. 0x05,
  47. 0x06,
  48. 0x07,
  49. 0x08,
  50. 0x09,
  51. 0x0a,
  52. 0x0b,
  53. 0x0c,
  54. 0x0d,
  55. 0x0e,
  56. 0x0f};
  57. UUID uuid;
  58. uuid.InitializeFromBytes(kBytes);
  59. EXPECT_EQ(uuid.data_1, 0x00010203u);
  60. EXPECT_EQ(uuid.data_2, 0x0405u);
  61. EXPECT_EQ(uuid.data_3, 0x0607u);
  62. EXPECT_EQ(uuid.data_4[0], 0x08u);
  63. EXPECT_EQ(uuid.data_4[1], 0x09u);
  64. EXPECT_EQ(uuid.data_5[0], 0x0au);
  65. EXPECT_EQ(uuid.data_5[1], 0x0bu);
  66. EXPECT_EQ(uuid.data_5[2], 0x0cu);
  67. EXPECT_EQ(uuid.data_5[3], 0x0du);
  68. EXPECT_EQ(uuid.data_5[4], 0x0eu);
  69. EXPECT_EQ(uuid.data_5[5], 0x0fu);
  70. EXPECT_EQ(uuid.ToString(), "00010203-0405-0607-0809-0a0b0c0d0e0f");
  71. // Test both operator== and operator!=.
  72. EXPECT_FALSE(uuid == uuid_zero);
  73. EXPECT_NE(uuid, uuid_zero);
  74. UUID uuid_2;
  75. uuid_2.InitializeFromBytes(kBytes);
  76. EXPECT_EQ(uuid_2, uuid);
  77. EXPECT_FALSE(uuid != uuid_2);
  78. // Make sure that operator== and operator!= check the entire UUID.
  79. ++uuid.data_1;
  80. EXPECT_NE(uuid, uuid_2);
  81. --uuid.data_1;
  82. ++uuid.data_2;
  83. EXPECT_NE(uuid, uuid_2);
  84. --uuid.data_2;
  85. ++uuid.data_3;
  86. EXPECT_NE(uuid, uuid_2);
  87. --uuid.data_3;
  88. for (size_t index = 0; index < arraysize(uuid.data_4); ++index) {
  89. ++uuid.data_4[index];
  90. EXPECT_NE(uuid, uuid_2);
  91. --uuid.data_4[index];
  92. }
  93. for (size_t index = 0; index < arraysize(uuid.data_5); ++index) {
  94. ++uuid.data_5[index];
  95. EXPECT_NE(uuid, uuid_2);
  96. --uuid.data_5[index];
  97. }
  98. // Make sure that the UUIDs are equal again, otherwise the test above may not
  99. // have been valid.
  100. EXPECT_EQ(uuid_2, uuid);
  101. static constexpr uint8_t kMoreBytes[16] = {0xff,
  102. 0xee,
  103. 0xdd,
  104. 0xcc,
  105. 0xbb,
  106. 0xaa,
  107. 0x99,
  108. 0x88,
  109. 0x77,
  110. 0x66,
  111. 0x55,
  112. 0x44,
  113. 0x33,
  114. 0x22,
  115. 0x11,
  116. 0x00};
  117. uuid.InitializeFromBytes(kMoreBytes);
  118. EXPECT_EQ(uuid.data_1, 0xffeeddccu);
  119. EXPECT_EQ(uuid.data_2, 0xbbaau);
  120. EXPECT_EQ(uuid.data_3, 0x9988u);
  121. EXPECT_EQ(uuid.data_4[0], 0x77u);
  122. EXPECT_EQ(uuid.data_4[1], 0x66u);
  123. EXPECT_EQ(uuid.data_5[0], 0x55u);
  124. EXPECT_EQ(uuid.data_5[1], 0x44u);
  125. EXPECT_EQ(uuid.data_5[2], 0x33u);
  126. EXPECT_EQ(uuid.data_5[3], 0x22u);
  127. EXPECT_EQ(uuid.data_5[4], 0x11u);
  128. EXPECT_EQ(uuid.data_5[5], 0x00u);
  129. EXPECT_EQ(uuid.ToString(), "ffeeddcc-bbaa-9988-7766-554433221100");
  130. EXPECT_NE(uuid, uuid_2);
  131. EXPECT_NE(uuid, uuid_zero);
  132. // Test that UUID is standard layout.
  133. memset(&uuid, 0x45, 16);
  134. EXPECT_EQ(uuid.data_1, 0x45454545u);
  135. EXPECT_EQ(uuid.data_2, 0x4545u);
  136. EXPECT_EQ(uuid.data_3, 0x4545u);
  137. EXPECT_EQ(uuid.data_4[0], 0x45u);
  138. EXPECT_EQ(uuid.data_4[1], 0x45u);
  139. EXPECT_EQ(uuid.data_5[0], 0x45u);
  140. EXPECT_EQ(uuid.data_5[1], 0x45u);
  141. EXPECT_EQ(uuid.data_5[2], 0x45u);
  142. EXPECT_EQ(uuid.data_5[3], 0x45u);
  143. EXPECT_EQ(uuid.data_5[4], 0x45u);
  144. EXPECT_EQ(uuid.data_5[5], 0x45u);
  145. EXPECT_EQ(uuid.ToString(), "45454545-4545-4545-4545-454545454545");
  146. UUID initialized_generated;
  147. initialized_generated.InitializeWithNew();
  148. EXPECT_NE(initialized_generated, uuid_zero);
  149. }
  150. TEST(UUID, FromString) {
  151. static constexpr struct TestCase {
  152. const char* uuid_string;
  153. bool success;
  154. } kCases[] = {
  155. // Valid:
  156. {"c6849cb5-fe14-4a79-8978-9ae6034c521d", true},
  157. {"00000000-0000-0000-0000-000000000000", true},
  158. {"ffffffff-ffff-ffff-ffff-ffffffffffff", true},
  159. // Outside HEX range:
  160. {"7318z10b-c453-4cef-9dc8-015655cb4bbc", false},
  161. {"7318a10b-c453-4cef-9dz8-015655cb4bbc", false},
  162. // Incomplete:
  163. {"15655cb4-", false},
  164. {"7318f10b-c453-4cef-9dc8-015655cb4bb", false},
  165. {"318f10b-c453-4cef-9dc8-015655cb4bb2", false},
  166. {"7318f10b-c453-4ef-9dc8-015655cb4bb2", false},
  167. {"", false},
  168. {"abcd", false},
  169. // Trailing data:
  170. {"6d247a34-53d5-40ec-a90d-d8dea9e94cc01", false}
  171. };
  172. UUID uuid_zero;
  173. uuid_zero.InitializeToZero();
  174. const std::string empty_uuid = uuid_zero.ToString();
  175. for (size_t index = 0; index < arraysize(kCases); ++index) {
  176. const TestCase& test_case = kCases[index];
  177. SCOPED_TRACE(base::StringPrintf(
  178. "index %" PRIuS ": %s", index, test_case.uuid_string));
  179. UUID uuid;
  180. uuid.InitializeToZero();
  181. EXPECT_EQ(uuid.InitializeFromString(test_case.uuid_string),
  182. test_case.success);
  183. if (test_case.success) {
  184. EXPECT_EQ(uuid.ToString(), test_case.uuid_string);
  185. } else {
  186. EXPECT_EQ(uuid.ToString(), empty_uuid);
  187. }
  188. }
  189. // Test for case insensitivty.
  190. UUID uuid;
  191. uuid.InitializeFromString("F32E5BDC-2681-4C73-A4E6-911FFD89B846");
  192. EXPECT_EQ(uuid.ToString(), "f32e5bdc-2681-4c73-a4e6-911ffd89b846");
  193. // Mixed case.
  194. uuid.InitializeFromString("5762C15D-50b5-4171-a2e9-7429C9EC6CAB");
  195. EXPECT_EQ(uuid.ToString(), "5762c15d-50b5-4171-a2e9-7429c9ec6cab");
  196. }
  197. #if defined(OS_WIN)
  198. TEST(UUID, FromSystem) {
  199. ::GUID system_uuid;
  200. ASSERT_EQ(UuidCreate(&system_uuid), RPC_S_OK);
  201. UUID uuid;
  202. uuid.InitializeFromSystemUUID(&system_uuid);
  203. RPC_WSTR system_string;
  204. ASSERT_EQ(UuidToString(&system_uuid, &system_string), RPC_S_OK);
  205. struct ScopedRpcStringFreeTraits {
  206. static RPC_WSTR* InvalidValue() { return nullptr; }
  207. static void Free(RPC_WSTR* rpc_string) {
  208. EXPECT_EQ(RpcStringFree(rpc_string), RPC_S_OK);
  209. }
  210. };
  211. using ScopedRpcString =
  212. base::ScopedGeneric<RPC_WSTR*, ScopedRpcStringFreeTraits>;
  213. ScopedRpcString scoped_system_string(&system_string);
  214. EXPECT_EQ(uuid.ToString16(), reinterpret_cast<wchar_t*>(system_string));
  215. }
  216. #endif // OS_WIN
  217. } // namespace
  218. } // namespace test
  219. } // namespace crashpad