test_unique_id.cpp
Go to the documentation of this file.
00001 //
00002 // C++ unit tests for unique_id interface.
00003 //
00004 #include <gtest/gtest.h>
00005 
00006 #include <ros/ros.h>
00007 #include <unique_id/unique_id.h>
00008 
00009 using namespace unique_id;
00010 typedef boost::uuids::uuid uuid;
00011 typedef uuid_msgs::UniqueID UniqueID;
00012 
00014 // Test cases
00016 
00017 // Test random generator
00018 TEST(BoostUUID, fromRandom)
00019 {
00020   static const int N = 1000;
00021   uuid uu[N];
00022   for (int i = 0; i < N; ++i)
00023     {
00024       uu[i] = fromRandom();
00025       for (int j = i-1; j >= 0; --j)
00026         {
00027           EXPECT_NE(uu[i], uu[j]);
00028         }
00029     }
00030 }
00031 
00032 // Test Timebased UUID
00033 TEST(BoostUUID, fromTime)
00034 {
00035   ros::Time t(1515778146, 239216089);
00036   uint64_t hw_addr = 0xAABBCCDDEEFF;
00037 
00038   // Generate UUID from time and hardware address
00039   uuid uu = fromTime(t, hw_addr);
00040 
00041   // Obtain time since epoch back from the generated uuid
00042   std::vector<uint8_t> data(uu.size());
00043   std::copy(uu.begin(), uu.end(), data.begin());
00044 
00045   uint64_t timestamp = (static_cast<uint64_t>(data[0]) << 24) + (static_cast<uint64_t>(data[1]) << 16) +
00046                        (static_cast<uint64_t>(data[2]) << 8) + static_cast<uint64_t>(data[3]) +
00047                        (static_cast<uint64_t>(data[4]) << 40) + (static_cast<uint64_t>(data[5]) << 32) +
00048                        (static_cast<uint64_t>(data[6] & 0x0F) << 56) + (static_cast<uint64_t>(data[7]) << 48);
00049   uint64_t offset = 122192928000000000;  // time offset in 100 ns intervals between RFC4122 Timestamp and Epoch Time
00050   uint64_t ns_intervals = timestamp - offset;
00051   uint64_t uu_hw_addr = 0;
00052   for (int8_t i=0; i < 6; i++)
00053   {
00054     uu_hw_addr += static_cast<uint64_t>(data[uu.size() - 1 - i]) << 8*i;
00055   }
00056 
00057   ros::Time uu_time;
00058   uu_time.sec = static_cast<int32_t>(ns_intervals / 1e9 * 100);
00059   uu_time.nsec = static_cast<int32_t>((ns_intervals - static_cast<uint64_t>(uu_time.sec) / (100 * 1e-9)) * 100);
00060 
00061   EXPECT_EQ(t.sec, uu_time.sec);
00062   // The UUID stores the timestamp in 100ns intervals,
00063   // so we lose precision for the 1's and 10's value of the nanoseconds in the time given
00064   EXPECT_EQ(t.nsec - uu_time.nsec, 89);
00065   EXPECT_EQ(hw_addr, uu_hw_addr);
00066 }
00067 
00068 TEST(BoostUUID, timeWithinSameInterval)
00069 {
00070   ros::Time t1(1515778146, 239216020);
00071   ros::Time t2(1515778146, 239216080);
00072   uint64_t hw_addr = 0xAABBCCDDEEFF;
00073 
00074   // Generate UUIDs from times and hardware address
00075   uuid uu1 = fromTime(t1, hw_addr);
00076   uuid uu2 = fromTime(t2, hw_addr);
00077 
00078   // Obtain times since epoch back from uu1
00079   std::vector<uint8_t> data(uu1.size());
00080   std::copy(uu1.begin(), uu1.end(), data.begin());
00081 
00082   uint64_t timestamp = (static_cast<uint64_t>(data[0]) << 24) + (static_cast<uint64_t>(data[1]) << 16) +
00083                        (static_cast<uint64_t>(data[2]) << 8) + static_cast<uint64_t>(data[3]) +
00084                        (static_cast<uint64_t>(data[4]) << 40) + (static_cast<uint64_t>(data[5]) << 32) +
00085                        (static_cast<uint64_t>(data[6] & 0x0F) << 56) + (static_cast<uint64_t>(data[7]) << 48);
00086   uint64_t offset = 122192928000000000;  // time offset in 100 ns intervals between RFC4122 Timestamp and Epoch Time
00087   uint64_t ns_intervals = timestamp - offset;
00088 
00089   ros::Time uu1_time;
00090   uu1_time.sec = static_cast<int32_t>(ns_intervals / 1e9 * 100);
00091   uu1_time.nsec = static_cast<int32_t>((ns_intervals - static_cast<uint64_t>(uu1_time.sec) / (100 * 1e-9)) * 100);
00092 
00093   // Obtain times since epoch back from uu2
00094   std::copy(uu2.begin(), uu2.end(), data.begin());
00095 
00096   timestamp = (static_cast<uint64_t>(data[0]) << 24) + (static_cast<uint64_t>(data[1]) << 16) +
00097               (static_cast<uint64_t>(data[2]) << 8) + static_cast<uint64_t>(data[3]) +
00098               (static_cast<uint64_t>(data[4]) << 40) + (static_cast<uint64_t>(data[5]) << 32) +
00099               (static_cast<uint64_t>(data[6] & 0x0F) << 56) + (static_cast<uint64_t>(data[7]) << 48);
00100   ns_intervals = timestamp - offset;
00101 
00102   ros::Time uu2_time;
00103   uu2_time.sec = static_cast<int32_t>(ns_intervals / 1e9 * 100);
00104   uu2_time.nsec = static_cast<int32_t>((ns_intervals - static_cast<uint64_t>(uu2_time.sec) / (100 * 1e-9)) * 100);
00105 
00106   // Compare
00107   // Since both timestamps were in the same 100ns interval, should get same timestamp
00108   EXPECT_EQ(uu1_time.sec, uu2_time.sec);
00109   EXPECT_EQ(uu1_time.nsec, uu2_time.nsec);
00110 
00111   // While timestamps are the same, the clock_id is a randomly generated 14-bit value
00112   // So, we should still expect the uuids generated to be different
00113   EXPECT_NE(uu1, uu2);
00114 }
00115 
00116 TEST(BoostUUID, timeWithinDifferentInterval)
00117 {
00118   ros::Time t1(1515778146, 239216020);
00119   ros::Time t2(1515778146, 239216120);
00120   uint64_t hw_addr = 0xAABBCCDDEEFF;
00121 
00122   // Generate UUIDs from times and hardware address
00123   uuid uu1 = fromTime(t1, hw_addr);
00124   uuid uu2 = fromTime(t2, hw_addr);
00125 
00126   // Obtain times since epoch back from uu1
00127   std::vector<uint8_t> data(uu1.size());
00128   std::copy(uu1.begin(), uu1.end(), data.begin());
00129 
00130   uint64_t timestamp = (static_cast<uint64_t>(data[0]) << 24) + (static_cast<uint64_t>(data[1]) << 16) +
00131                        (static_cast<uint64_t>(data[2]) << 8) + static_cast<uint64_t>(data[3]) +
00132                        (static_cast<uint64_t>(data[4]) << 40) + (static_cast<uint64_t>(data[5]) << 32) +
00133                        (static_cast<uint64_t>(data[6] & 0x0F) << 56) + (static_cast<uint64_t>(data[7]) << 48);
00134   uint64_t offset = 122192928000000000;  // time offset in 100 ns intervals between RFC4122 Timestamp and Epoch Time
00135   uint64_t ns_intervals = timestamp - offset;
00136 
00137   ros::Time uu1_time;
00138   uu1_time.sec = static_cast<int32_t>(ns_intervals / 1e9 * 100);
00139   uu1_time.nsec = static_cast<int32_t>((ns_intervals - static_cast<uint64_t>(uu1_time.sec) / (100 * 1e-9)) * 100);
00140 
00141   // Obtain times since epoch back from uu2
00142   std::copy(uu2.begin(), uu2.end(), data.begin());
00143 
00144   timestamp = (static_cast<uint64_t>(data[0]) << 24) + (static_cast<uint64_t>(data[1]) << 16) +
00145               (static_cast<uint64_t>(data[2]) << 8) + static_cast<uint64_t>(data[3]) +
00146               (static_cast<uint64_t>(data[4]) << 40) + (static_cast<uint64_t>(data[5]) << 32) +
00147               (static_cast<uint64_t>(data[6] & 0x0F) << 56) + (static_cast<uint64_t>(data[7]) << 48);
00148   ns_intervals = timestamp - offset;
00149 
00150   ros::Time uu2_time;
00151   uu2_time.sec = static_cast<int32_t>(ns_intervals / 1e9 * 100);
00152   uu2_time.nsec = static_cast<int32_t>((ns_intervals - static_cast<uint64_t>(uu2_time.sec) / (100 * 1e-9)) * 100);
00153 
00154   // Compare
00155   // Since both timestamps were in different 100ns intervals, should get different timestamps (at the ns level)
00156   EXPECT_EQ(uu1_time.sec, uu2_time.sec);
00157   EXPECT_NE(uu1_time.nsec, uu2_time.nsec);
00158 }
00159 
00160 TEST(BoostUUID, emptyURL)
00161 {
00162   std::string s;
00163   uuid x = fromURL(s);
00164   uuid y = fromURL(s);
00165   EXPECT_EQ(x, y);
00166   // MUST yield same result as Python fromURL() function:
00167   EXPECT_EQ(toHexString(x), "1b4db7eb-4057-5ddf-91e0-36dec72071f5");
00168 }
00169 
00170 TEST(BoostUUID, sameURL)
00171 {
00172   std::string s("http://openstreetmap.org/node/1");
00173   uuid x = fromURL(s);
00174   uuid y = fromURL(s);
00175   EXPECT_EQ(x, y);
00176   // MUST yield same result as Python fromURL() function:
00177   EXPECT_EQ(toHexString(x), "ef362ac8-9659-5481-b954-88e9b741c8f9");
00178 }
00179 
00180 TEST(BoostUUID, differentOsmNamespace)
00181 {
00182   uuid x = fromURL("http://openstreetmap.org/node/1");
00183   uuid y = fromURL("http://openstreetmap.org/way/1");
00184   EXPECT_NE(x, y);
00185   // MUST yield same result as Python fromURL() function:
00186   EXPECT_EQ(toHexString(y), "b3180681-b125-5e41-bd04-3c8b046175b4");
00187 }
00188 
00189 TEST(BoostUUID, actualOsmNode)
00190 {
00191   uuid x = fromURL("http://openstreetmap.org/node/1");
00192   uuid y = fromURL("http://openstreetmap.org/node/152370223");
00193   EXPECT_NE(x, y);
00194   // MUST yield same result as Python fromURL() function:
00195   EXPECT_EQ(toHexString(y), "8e0b7d8a-c433-5c42-be2e-fbd97ddff9ac");
00196 }
00197 
00198 TEST(BoostUUID, fromHexString)
00199 {
00200   std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
00201   std::string r = toHexString(fromHexString(s));
00202   EXPECT_EQ(s, r);
00203 }
00204 
00205 TEST(BoostUUID, fromStringNoDashes)
00206 {
00207   std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
00208   std::string s_hex("da7c242f2efe5175996149cc621b80b9");
00209   std::string r = toHexString(fromHexString(s_hex));
00210   EXPECT_EQ(s, r);
00211 }
00212 
00213 TEST(BoostUUID, fromBracesString)
00214 {
00215   std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
00216   std::string s_braces = "{" + s + "}";
00217   std::string r = toHexString(fromHexString(s_braces));
00218   EXPECT_EQ(s, r);
00219 }
00220 
00221 TEST(BoostUUID, fromUrnString)
00222 {
00223   // This documents boost 1.46.1 behavior, but is an undefined
00224   // fromHexString() input, not really a valid test case.
00225   std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
00226   std::string s_urn = "urn:uuid:" + s;
00227   std::string r = toHexString(fromHexString(s_urn));
00228   EXPECT_NE(s, r);
00229 }
00230 
00231 TEST(BoostUUID, fromTooLongString)
00232 {
00233   // This documents boost 1.46.1 behavior, but is an undefined
00234   // fromHexString() input, not really a valid test case.
00235   std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
00236   std::string s_too_long = s + "-0001";
00237   std::string r = toHexString(fromHexString(s_too_long));
00238   EXPECT_EQ(s, r);
00239 }
00240 
00241 TEST(BoostUUID, fromTooShortString)
00242 {
00243   // This documents boost 1.46.1 behavior, but is an undefined
00244   // fromHexString() input, not really a valid test case.
00245   std::string s("da7c242f-2efe-5175-9961-49cc621b80");
00246   try
00247     {
00248       uuid x = fromHexString(s);
00249       FAIL();                           // expected exception not thrown
00250       EXPECT_NE(toHexString(x), s);
00251     }
00252   catch (std::runtime_error &e)
00253     {
00254       EXPECT_EQ(e.what(), std::string("invalid uuid string"));
00255     }
00256   catch (...)
00257     {
00258       FAIL();                           // unexpected exception
00259     }
00260 }
00261 
00262 TEST(BoostUUID, fromBogusString)
00263 {
00264   // This documents boost 1.46.1 behavior, but is an undefined
00265   // fromHexString() input, not really a valid test case.
00266   std::string s("Invalid UUID string");
00267   try
00268     {
00269       uuid x = fromHexString(s);
00270       FAIL();                           // expected exception not thrown
00271       EXPECT_NE(toHexString(x), s);
00272     }
00273   catch (std::runtime_error &e)
00274     {
00275       EXPECT_EQ(e.what(), std::string("invalid uuid string"));
00276     }
00277   catch (...)
00278     {
00279       FAIL();                           // unexpected exception
00280     }
00281 }
00282 
00283 TEST(UniqueID, nilMessage)
00284 {
00285   UniqueID x;
00286   UniqueID y = toMsg(uuid());
00287   EXPECT_EQ(x.uuid, y.uuid);
00288 }
00289 
00290 TEST(UniqueID, randomMessage)
00291 {
00292   UniqueID x;
00293   UniqueID y = toMsg(fromRandom());
00294   EXPECT_NE(x.uuid, y.uuid);
00295 }
00296 
00297 TEST(UniqueID, equivalentMessages)
00298 {
00299   std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
00300   UniqueID x = toMsg(fromHexString(s));
00301   UniqueID y = toMsg(fromHexString(s));
00302   EXPECT_EQ(x.uuid, y.uuid);
00303   EXPECT_EQ(s, toHexString(y));
00304 }
00305 
00306 TEST(UniqueID, toAndFromMessage)
00307 {
00308   std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
00309   uuid x = uuid(fromHexString(s));
00310   uuid y = fromMsg(toMsg(x));
00311   EXPECT_EQ(x, y);
00312 }
00313 
00314 TEST(UniqueID, messageToString)
00315 {
00316   std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
00317   UniqueID x = toMsg(fromHexString(s));
00318   std::string y = toHexString(x);
00319   EXPECT_EQ(s, y);
00320 }
00321 
00322 // Run all the tests that were declared with TEST()
00323 int main(int argc, char **argv)
00324 {
00325   testing::InitGoogleTest(&argc, argv);
00326   return RUN_ALL_TESTS();
00327 }


unique_id
Author(s): Jack O'Quin
autogenerated on Thu Jun 6 2019 20:57:45