git commit -m "first commit"

This commit is contained in:
2026-05-28 10:29:58 +07:00
commit 167c52aeb6
2048 changed files with 740251 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
### Unit tests
#
# Only configured when CATKIN_ENABLE_TESTING is true.
# C++ gtests
catkin_add_gtest(test_${PROJECT_NAME}
test_${PROJECT_NAME}.cpp
second_test_${PROJECT_NAME}.cpp)
add_dependencies(test_${PROJECT_NAME} ${catkin_EXPORTED_TARGETS})
target_link_libraries(test_${PROJECT_NAME}
${Boost_LIBRARIES}
${catkin_LIBRARIES})
# Python nose tests
catkin_add_nosetests(test_${PROJECT_NAME}.py)

View File

@@ -0,0 +1,193 @@
//
// A second C++ unit test for unique_id interface, which must be able
// to be included in more than one source file.
//
#include <gtest/gtest.h>
#include <unique_id/unique_id.h>
using namespace unique_id;
typedef boost::uuids::uuid uuid;
typedef uuid_msgs::UniqueID UniqueID;
///////////////////////////////////////////////////////////////
// Test cases
///////////////////////////////////////////////////////////////
// Test random generator
TEST(BoostUUID2, fromRandom)
{
static const int N = 1000;
uuid uu[N];
for (int i = 0; i < N; ++i)
{
uu[i] = fromRandom();
for (int j = i-1; j >= 0; --j)
{
EXPECT_NE(uu[i], uu[j]);
}
}
}
TEST(BoostUUID2, emptyURL)
{
std::string s;
uuid x = fromURL(s);
uuid y = fromURL(s);
EXPECT_EQ(x, y);
// MUST yield same result as Python fromURL() function:
EXPECT_EQ(toHexString(x), "1b4db7eb-4057-5ddf-91e0-36dec72071f5");
}
TEST(BoostUUID2, sameURL)
{
std::string s("http://openstreetmap.org/node/1");
uuid x = fromURL(s);
uuid y = fromURL(s);
EXPECT_EQ(x, y);
// MUST yield same result as Python fromURL() function:
EXPECT_EQ(toHexString(x), "ef362ac8-9659-5481-b954-88e9b741c8f9");
}
TEST(BoostUUID2, differentOsmNamespace)
{
uuid x = fromURL("http://openstreetmap.org/node/1");
uuid y = fromURL("http://openstreetmap.org/way/1");
EXPECT_NE(x, y);
// MUST yield same result as Python fromURL() function:
EXPECT_EQ(toHexString(y), "b3180681-b125-5e41-bd04-3c8b046175b4");
}
TEST(BoostUUID2, actualOsmNode)
{
uuid x = fromURL("http://openstreetmap.org/node/1");
uuid y = fromURL("http://openstreetmap.org/node/152370223");
EXPECT_NE(x, y);
// MUST yield same result as Python fromURL() function:
EXPECT_EQ(toHexString(y), "8e0b7d8a-c433-5c42-be2e-fbd97ddff9ac");
}
TEST(BoostUUID2, fromHexString)
{
std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
std::string r = toHexString(fromHexString(s));
EXPECT_EQ(s, r);
}
TEST(BoostUUID2, fromStringNoDashes)
{
std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
std::string s_hex("da7c242f2efe5175996149cc621b80b9");
std::string r = toHexString(fromHexString(s_hex));
EXPECT_EQ(s, r);
}
TEST(BoostUUID2, fromBracesString)
{
std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
std::string s_braces = "{" + s + "}";
std::string r = toHexString(fromHexString(s_braces));
EXPECT_EQ(s, r);
}
TEST(BoostUUID2, fromUrnString)
{
// This documents boost 1.46.1 behavior, but is an undefined
// fromHexString() input, not really a valid test case.
std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
std::string s_urn = "urn:uuid:" + s;
std::string r = toHexString(fromHexString(s_urn));
EXPECT_NE(s, r);
}
TEST(BoostUUID2, fromTooLongString)
{
// This documents boost 1.46.1 behavior, but is an undefined
// fromHexString() input, not really a valid test case.
std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
std::string s_too_long = s + "-0001";
std::string r = toHexString(fromHexString(s_too_long));
EXPECT_EQ(s, r);
}
TEST(BoostUUID2, fromTooShortString)
{
// This documents boost 1.46.1 behavior, but is an undefined
// fromHexString() input, not really a valid test case.
std::string s("da7c242f-2efe-5175-9961-49cc621b80");
try
{
uuid x = fromHexString(s);
FAIL(); // expected exception not thrown
EXPECT_NE(toHexString(x), s);
}
catch (std::runtime_error &e)
{
EXPECT_EQ(e.what(), std::string("invalid uuid string"));
}
catch (...)
{
FAIL(); // unexpected exception
}
}
TEST(BoostUUID2, fromBogusString)
{
// This documents boost 1.46.1 behavior, but is an undefined
// fromHexString() input, not really a valid test case.
std::string s("Invalid UUID string");
try
{
uuid x = fromHexString(s);
FAIL(); // expected exception not thrown
EXPECT_NE(toHexString(x), s);
}
catch (std::runtime_error &e)
{
EXPECT_EQ(e.what(), std::string("invalid uuid string"));
}
catch (...)
{
FAIL(); // unexpected exception
}
}
TEST(UniqueID2, nilMessage)
{
UniqueID x;
UniqueID y = toMsg(uuid());
EXPECT_EQ(x.uuid, y.uuid);
}
TEST(UniqueID2, randomMessage)
{
UniqueID x;
UniqueID y = toMsg(fromRandom());
EXPECT_NE(x.uuid, y.uuid);
}
TEST(UniqueID2, equivalentMessages)
{
std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
UniqueID x = toMsg(fromHexString(s));
UniqueID y = toMsg(fromHexString(s));
EXPECT_EQ(x.uuid, y.uuid);
EXPECT_EQ(s, toHexString(y));
}
TEST(UniqueID2, toAndFromMessage)
{
std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
uuid x = uuid(fromHexString(s));
uuid y = fromMsg(toMsg(x));
EXPECT_EQ(x, y);
}
TEST(UniqueID2, messageToString)
{
std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
UniqueID x = toMsg(fromHexString(s));
std::string y = toHexString(x);
EXPECT_EQ(s, y);
}

View File

@@ -0,0 +1,327 @@
//
// C++ unit tests for unique_id interface.
//
#include <gtest/gtest.h>
#include <ros/ros.h>
#include <unique_id/unique_id.h>
using namespace unique_id;
typedef boost::uuids::uuid uuid;
typedef uuid_msgs::UniqueID UniqueID;
///////////////////////////////////////////////////////////////
// Test cases
///////////////////////////////////////////////////////////////
// Test random generator
TEST(BoostUUID, fromRandom)
{
static const int N = 1000;
uuid uu[N];
for (int i = 0; i < N; ++i)
{
uu[i] = fromRandom();
for (int j = i-1; j >= 0; --j)
{
EXPECT_NE(uu[i], uu[j]);
}
}
}
// Test Timebased UUID
TEST(BoostUUID, fromTime)
{
ros::Time t(1515778146, 239216089);
uint64_t hw_addr = 0xAABBCCDDEEFF;
// Generate UUID from time and hardware address
uuid uu = fromTime(t, hw_addr);
// Obtain time since epoch back from the generated uuid
std::vector<uint8_t> data(uu.size());
std::copy(uu.begin(), uu.end(), data.begin());
uint64_t timestamp = (static_cast<uint64_t>(data[0]) << 24) + (static_cast<uint64_t>(data[1]) << 16) +
(static_cast<uint64_t>(data[2]) << 8) + static_cast<uint64_t>(data[3]) +
(static_cast<uint64_t>(data[4]) << 40) + (static_cast<uint64_t>(data[5]) << 32) +
(static_cast<uint64_t>(data[6] & 0x0F) << 56) + (static_cast<uint64_t>(data[7]) << 48);
uint64_t offset = 122192928000000000; // time offset in 100 ns intervals between RFC4122 Timestamp and Epoch Time
uint64_t ns_intervals = timestamp - offset;
uint64_t uu_hw_addr = 0;
for (int8_t i=0; i < 6; i++)
{
uu_hw_addr += static_cast<uint64_t>(data[uu.size() - 1 - i]) << 8*i;
}
ros::Time uu_time;
uu_time.sec = static_cast<int32_t>(ns_intervals / 1e9 * 100);
uu_time.nsec = static_cast<int32_t>((ns_intervals - static_cast<uint64_t>(uu_time.sec) / (100 * 1e-9)) * 100);
EXPECT_EQ(t.sec, uu_time.sec);
// The UUID stores the timestamp in 100ns intervals,
// so we lose precision for the 1's and 10's value of the nanoseconds in the time given
EXPECT_EQ(t.nsec - uu_time.nsec, 89);
EXPECT_EQ(hw_addr, uu_hw_addr);
}
TEST(BoostUUID, timeWithinSameInterval)
{
ros::Time t1(1515778146, 239216020);
ros::Time t2(1515778146, 239216080);
uint64_t hw_addr = 0xAABBCCDDEEFF;
// Generate UUIDs from times and hardware address
uuid uu1 = fromTime(t1, hw_addr);
uuid uu2 = fromTime(t2, hw_addr);
// Obtain times since epoch back from uu1
std::vector<uint8_t> data(uu1.size());
std::copy(uu1.begin(), uu1.end(), data.begin());
uint64_t timestamp = (static_cast<uint64_t>(data[0]) << 24) + (static_cast<uint64_t>(data[1]) << 16) +
(static_cast<uint64_t>(data[2]) << 8) + static_cast<uint64_t>(data[3]) +
(static_cast<uint64_t>(data[4]) << 40) + (static_cast<uint64_t>(data[5]) << 32) +
(static_cast<uint64_t>(data[6] & 0x0F) << 56) + (static_cast<uint64_t>(data[7]) << 48);
uint64_t offset = 122192928000000000; // time offset in 100 ns intervals between RFC4122 Timestamp and Epoch Time
uint64_t ns_intervals = timestamp - offset;
ros::Time uu1_time;
uu1_time.sec = static_cast<int32_t>(ns_intervals / 1e9 * 100);
uu1_time.nsec = static_cast<int32_t>((ns_intervals - static_cast<uint64_t>(uu1_time.sec) / (100 * 1e-9)) * 100);
// Obtain times since epoch back from uu2
std::copy(uu2.begin(), uu2.end(), data.begin());
timestamp = (static_cast<uint64_t>(data[0]) << 24) + (static_cast<uint64_t>(data[1]) << 16) +
(static_cast<uint64_t>(data[2]) << 8) + static_cast<uint64_t>(data[3]) +
(static_cast<uint64_t>(data[4]) << 40) + (static_cast<uint64_t>(data[5]) << 32) +
(static_cast<uint64_t>(data[6] & 0x0F) << 56) + (static_cast<uint64_t>(data[7]) << 48);
ns_intervals = timestamp - offset;
ros::Time uu2_time;
uu2_time.sec = static_cast<int32_t>(ns_intervals / 1e9 * 100);
uu2_time.nsec = static_cast<int32_t>((ns_intervals - static_cast<uint64_t>(uu2_time.sec) / (100 * 1e-9)) * 100);
// Compare
// Since both timestamps were in the same 100ns interval, should get same timestamp
EXPECT_EQ(uu1_time.sec, uu2_time.sec);
EXPECT_EQ(uu1_time.nsec, uu2_time.nsec);
// While timestamps are the same, the clock_id is a randomly generated 14-bit value
// So, we should still expect the uuids generated to be different
EXPECT_NE(uu1, uu2);
}
TEST(BoostUUID, timeWithinDifferentInterval)
{
ros::Time t1(1515778146, 239216020);
ros::Time t2(1515778146, 239216120);
uint64_t hw_addr = 0xAABBCCDDEEFF;
// Generate UUIDs from times and hardware address
uuid uu1 = fromTime(t1, hw_addr);
uuid uu2 = fromTime(t2, hw_addr);
// Obtain times since epoch back from uu1
std::vector<uint8_t> data(uu1.size());
std::copy(uu1.begin(), uu1.end(), data.begin());
uint64_t timestamp = (static_cast<uint64_t>(data[0]) << 24) + (static_cast<uint64_t>(data[1]) << 16) +
(static_cast<uint64_t>(data[2]) << 8) + static_cast<uint64_t>(data[3]) +
(static_cast<uint64_t>(data[4]) << 40) + (static_cast<uint64_t>(data[5]) << 32) +
(static_cast<uint64_t>(data[6] & 0x0F) << 56) + (static_cast<uint64_t>(data[7]) << 48);
uint64_t offset = 122192928000000000; // time offset in 100 ns intervals between RFC4122 Timestamp and Epoch Time
uint64_t ns_intervals = timestamp - offset;
ros::Time uu1_time;
uu1_time.sec = static_cast<int32_t>(ns_intervals / 1e9 * 100);
uu1_time.nsec = static_cast<int32_t>((ns_intervals - static_cast<uint64_t>(uu1_time.sec) / (100 * 1e-9)) * 100);
// Obtain times since epoch back from uu2
std::copy(uu2.begin(), uu2.end(), data.begin());
timestamp = (static_cast<uint64_t>(data[0]) << 24) + (static_cast<uint64_t>(data[1]) << 16) +
(static_cast<uint64_t>(data[2]) << 8) + static_cast<uint64_t>(data[3]) +
(static_cast<uint64_t>(data[4]) << 40) + (static_cast<uint64_t>(data[5]) << 32) +
(static_cast<uint64_t>(data[6] & 0x0F) << 56) + (static_cast<uint64_t>(data[7]) << 48);
ns_intervals = timestamp - offset;
ros::Time uu2_time;
uu2_time.sec = static_cast<int32_t>(ns_intervals / 1e9 * 100);
uu2_time.nsec = static_cast<int32_t>((ns_intervals - static_cast<uint64_t>(uu2_time.sec) / (100 * 1e-9)) * 100);
// Compare
// Since both timestamps were in different 100ns intervals, should get different timestamps (at the ns level)
EXPECT_EQ(uu1_time.sec, uu2_time.sec);
EXPECT_NE(uu1_time.nsec, uu2_time.nsec);
}
TEST(BoostUUID, emptyURL)
{
std::string s;
uuid x = fromURL(s);
uuid y = fromURL(s);
EXPECT_EQ(x, y);
// MUST yield same result as Python fromURL() function:
EXPECT_EQ(toHexString(x), "1b4db7eb-4057-5ddf-91e0-36dec72071f5");
}
TEST(BoostUUID, sameURL)
{
std::string s("http://openstreetmap.org/node/1");
uuid x = fromURL(s);
uuid y = fromURL(s);
EXPECT_EQ(x, y);
// MUST yield same result as Python fromURL() function:
EXPECT_EQ(toHexString(x), "ef362ac8-9659-5481-b954-88e9b741c8f9");
}
TEST(BoostUUID, differentOsmNamespace)
{
uuid x = fromURL("http://openstreetmap.org/node/1");
uuid y = fromURL("http://openstreetmap.org/way/1");
EXPECT_NE(x, y);
// MUST yield same result as Python fromURL() function:
EXPECT_EQ(toHexString(y), "b3180681-b125-5e41-bd04-3c8b046175b4");
}
TEST(BoostUUID, actualOsmNode)
{
uuid x = fromURL("http://openstreetmap.org/node/1");
uuid y = fromURL("http://openstreetmap.org/node/152370223");
EXPECT_NE(x, y);
// MUST yield same result as Python fromURL() function:
EXPECT_EQ(toHexString(y), "8e0b7d8a-c433-5c42-be2e-fbd97ddff9ac");
}
TEST(BoostUUID, fromHexString)
{
std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
std::string r = toHexString(fromHexString(s));
EXPECT_EQ(s, r);
}
TEST(BoostUUID, fromStringNoDashes)
{
std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
std::string s_hex("da7c242f2efe5175996149cc621b80b9");
std::string r = toHexString(fromHexString(s_hex));
EXPECT_EQ(s, r);
}
TEST(BoostUUID, fromBracesString)
{
std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
std::string s_braces = "{" + s + "}";
std::string r = toHexString(fromHexString(s_braces));
EXPECT_EQ(s, r);
}
TEST(BoostUUID, fromUrnString)
{
// This documents boost 1.46.1 behavior, but is an undefined
// fromHexString() input, not really a valid test case.
std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
std::string s_urn = "urn:uuid:" + s;
std::string r = toHexString(fromHexString(s_urn));
EXPECT_NE(s, r);
}
TEST(BoostUUID, fromTooLongString)
{
// This documents boost 1.46.1 behavior, but is an undefined
// fromHexString() input, not really a valid test case.
std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
std::string s_too_long = s + "-0001";
std::string r = toHexString(fromHexString(s_too_long));
EXPECT_EQ(s, r);
}
TEST(BoostUUID, fromTooShortString)
{
// This documents boost 1.46.1 behavior, but is an undefined
// fromHexString() input, not really a valid test case.
std::string s("da7c242f-2efe-5175-9961-49cc621b80");
try
{
uuid x = fromHexString(s);
FAIL(); // expected exception not thrown
EXPECT_NE(toHexString(x), s);
}
catch (std::runtime_error &e)
{
EXPECT_EQ(e.what(), std::string("invalid uuid string"));
}
catch (...)
{
FAIL(); // unexpected exception
}
}
TEST(BoostUUID, fromBogusString)
{
// This documents boost 1.46.1 behavior, but is an undefined
// fromHexString() input, not really a valid test case.
std::string s("Invalid UUID string");
try
{
uuid x = fromHexString(s);
FAIL(); // expected exception not thrown
EXPECT_NE(toHexString(x), s);
}
catch (std::runtime_error &e)
{
EXPECT_EQ(e.what(), std::string("invalid uuid string"));
}
catch (...)
{
FAIL(); // unexpected exception
}
}
TEST(UniqueID, nilMessage)
{
UniqueID x;
UniqueID y = toMsg(uuid());
EXPECT_EQ(x.uuid, y.uuid);
}
TEST(UniqueID, randomMessage)
{
UniqueID x;
UniqueID y = toMsg(fromRandom());
EXPECT_NE(x.uuid, y.uuid);
}
TEST(UniqueID, equivalentMessages)
{
std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
UniqueID x = toMsg(fromHexString(s));
UniqueID y = toMsg(fromHexString(s));
EXPECT_EQ(x.uuid, y.uuid);
EXPECT_EQ(s, toHexString(y));
}
TEST(UniqueID, toAndFromMessage)
{
std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
uuid x = uuid(fromHexString(s));
uuid y = fromMsg(toMsg(x));
EXPECT_EQ(x, y);
}
TEST(UniqueID, messageToString)
{
std::string s("da7c242f-2efe-5175-9961-49cc621b80b9");
UniqueID x = toMsg(fromHexString(s));
std::string y = toHexString(x);
EXPECT_EQ(s, y);
}
// Run all the tests that were declared with TEST()
int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -0,0 +1,202 @@
#!/usr/bin/env python
# enable some python3 compatibility options:
# (unicode_literals not compatible with python2 uuid module)
from __future__ import absolute_import, print_function
import sys
import unittest
import uuid # standard Python module
import rospy
from uuid_msgs.msg import UniqueID
from unique_id import *
class TestPythonUUID(unittest.TestCase):
"""Unit tests for Python UUID generation.
"""
# random UUID generation tests
def test_random_uuids(self):
N = 1000
uu = []
for i in xrange(N):
uu.append(fromRandom())
self.assertEqual(type(uu[i]), uuid.UUID)
for j in xrange(i-1, -1, -1):
self.assertNotEqual(uu[i], uu[j])
# UUID generation from URL tests
def test_empty_url(self):
x = fromURL('')
self.assertEqual(type(x), uuid.UUID)
y = fromURL('')
self.assertEqual(type(y), uuid.UUID)
self.assertEqual(x, y)
# MUST yield same result as C++ fromURL() function:
self.assertEqual(str(x), "1b4db7eb-4057-5ddf-91e0-36dec72071f5")
def test_same_url(self):
x = fromURL('http://openstreetmap.org/node/1')
self.assertEqual(type(x), uuid.UUID)
y = fromURL('http://openstreetmap.org/node/1')
self.assertEqual(type(y), uuid.UUID)
self.assertEqual(x, y)
# MUST yield same result as C++ fromURL() function:
self.assertEqual(str(x), 'ef362ac8-9659-5481-b954-88e9b741c8f9')
def test_same_id_different_osm_namespace(self):
x = fromURL('http://openstreetmap.org/node/1')
y = fromURL('http://openstreetmap.org/way/1')
self.assertNotEqual(x, y)
# MUST yield same result as C++ fromURL() function:
self.assertEqual(str(y), 'b3180681-b125-5e41-bd04-3c8b046175b4')
def test_actual_osm_node_id(self):
x = fromURL('http://openstreetmap.org/node/1')
y = fromURL('http://openstreetmap.org/node/152370223')
self.assertNotEqual(x, y)
# MUST yield same result as C++ fromURL() function:
self.assertEqual(str(y), '8e0b7d8a-c433-5c42-be2e-fbd97ddff9ac')
def test_route_segment(self):
start = 'da7c242f-2efe-5175-9961-49cc621b80b9'
end = '812f1c08-a34b-5a21-92b9-18b2b0cf4950'
x = fromURL('http://ros.org/wiki/road_network/' + start + '/' + end)
y = fromURL('http://ros.org/wiki/road_network/' + end + '/' + start)
self.assertNotEqual(x, y)
# MUST yield same result as C++ fromURL() function:
self.assertEqual(str(x), 'acaa906e-8411-5b45-a446-ccdc2fc39f29')
# UniqueID message generation tests
def test_msg_creation(self):
msg = toMsg(fromURL('http://openstreetmap.org/node/152370223'))
self.assertEqual(toHexString(msg),
'8e0b7d8a-c433-5c42-be2e-fbd97ddff9ac')
def test_msg_same_id_different_namespace(self):
x = toMsg(fromURL('http://openstreetmap.org/node/1'))
y = toMsg(fromURL('http://openstreetmap.org/way/1'))
self.assertNotEqual(x, y)
self.assertEqual(toHexString(y),
'b3180681-b125-5e41-bd04-3c8b046175b4')
def test_msg_route_segment(self):
start = 'da7c242f-2efe-5175-9961-49cc621b80b9'
end = '812f1c08-a34b-5a21-92b9-18b2b0cf4950'
x = toMsg(fromURL('http://ros.org/wiki/road_network/'
+ start + '/' + end))
y = toMsg(fromURL('http://ros.org/wiki/road_network/'
+ end + '/' + start))
self.assertNotEqual(x, y)
self.assertEqual(toHexString(x),
'acaa906e-8411-5b45-a446-ccdc2fc39f29')
def test_nil_msg(self):
x = UniqueID()
y = toMsg(uuid.UUID(hex='00000000-0000-0000-0000-000000000000'))
self.assertEqual(x, y)
def test_random_msg(self):
x = UniqueID()
y = toMsg(fromRandom())
self.assertNotEqual(x, y)
def test_equivalent_msgs(self):
s = 'da7c242f-2efe-5175-9961-49cc621b80b9'
x = toMsg(uuid.UUID(s))
y = toMsg(uuid.UUID(s))
self.assertEqual(x, y)
self.assertEqual(s, toHexString(y))
def test_to_and_from_msg(self):
x = uuid.UUID('da7c242f-2efe-5175-9961-49cc621b80b9')
y = (fromMsg(toMsg(x)))
self.assertEqual(x, y)
self.assertEqual(type(y), uuid.UUID)
def test_msg_to_string(self):
s = 'da7c242f-2efe-5175-9961-49cc621b80b9'
x = toMsg(uuid.UUID(s))
y = toHexString(x)
self.assertEqual(s, y)
self.assertEqual(type(y), str)
# UUID Time-Based Generation
def test_time(self):
hw_addr = 0xAABBCCDDEEFF
t = rospy.Time(1515778146, 239216089)
uu = fromTime(t, hw_addr) # generate UUID
offset = 122192928000000000 # in 100ns intervals between RFC4122 timestamp and epoch time
ns_intervals_rfc = uu.fields[0] + (uu.fields[1] << 32) + ((uu.fields[2] & 0x0FFF) << 48)
ns_intervals_epoch = ns_intervals_rfc - offset
uu_time = rospy.Time()
uu_time.secs = long(ns_intervals_epoch / 1e9 * 100)
uu_time.nsecs = long(ns_intervals_epoch - uu_time.secs / (100 * 1e-9)) * 100
self.assertEqual(t.secs, uu_time.secs)
# Expect 89ns to be shaved off due to timestamp being stored in 100ns intervals
self.assertEqual(t.nsecs - uu_time.nsecs, 89)
# Should be able to retrieve the hardware id
self.assertEqual(hw_addr, uu.fields[5])
def test_time_same_interval(self):
hw_addr = 0xAABBCCDDEEFF
t1 = rospy.Time(1515778146, 239216020)
t2 = rospy.Time(1515778146, 239216080)
uu1 = fromTime(t1, hw_addr) # generate UUID for t1
uu2 = fromTime(t2, hw_addr) # generate UUID for t2
offset = 122192928000000000 # in 100ns intervals between RFC4122 timestamp and epoch time
# Get time associated with uuid uu1
ns_intervals_rfc = uu1.fields[0] + (uu1.fields[1] << 32) + ((uu1.fields[2] & 0x0FFF) << 48)
ns_intervals_epoch = ns_intervals_rfc - offset
uu1_time = rospy.Time()
uu1_time.secs = long(ns_intervals_epoch / 1e9 * 100)
uu1_time.nsecs = long(ns_intervals_epoch - uu1_time.secs / (100 * 1e-9)) * 100
# Get time associated with uuid uu2
ns_intervals_rfc = uu2.fields[0] + (uu2.fields[1] << 32) + ((uu2.fields[2] & 0x0FFF) << 48)
ns_intervals_epoch = ns_intervals_rfc - offset
uu2_time = rospy.Time()
uu2_time.secs = long(ns_intervals_epoch / 1e9 * 100)
uu2_time.nsecs = long(ns_intervals_epoch - uu2_time.secs / (100 * 1e-9)) * 100
self.assertEqual(uu1_time.secs, uu2_time.secs)
# Timestamps should be same as they were generated for timestamps in the same 100ns interval
self.assertEqual(uu1_time.nsecs, uu2_time.nsecs)
# UUIDs should be different due to different (hopefully) randomly generated 14-bit clock ids
self.assertNotEqual(uu1, uu2)
def test_time_different_interval(self):
hw_addr = 0xAABBCCDDEEFF
t1 = rospy.Time(1515778146, 239216020)
t2 = rospy.Time(1515778146, 239216120)
uu1 = fromTime(t1, hw_addr) # generate UUID for t1
uu2 = fromTime(t2, hw_addr) # generate UUID for t2
offset = 122192928000000000 # in 100ns intervals between RFC4122 timestamp and epoch time
# Get time associated with uuid uu1
ns_intervals_rfc = uu1.fields[0] + (uu1.fields[1] << 32) + ((uu1.fields[2] & 0x0FFF) << 48)
ns_intervals_epoch = ns_intervals_rfc - offset
uu1_time = rospy.Time()
uu1_time.secs = long(ns_intervals_epoch / 1e9 * 100)
uu1_time.nsecs = long(ns_intervals_epoch - uu1_time.secs / (100 * 1e-9)) * 100
# Get time associated with uuid uu2
ns_intervals_rfc = uu2.fields[0] + (uu2.fields[1] << 32) + ((uu2.fields[2] & 0x0FFF) << 48)
ns_intervals_epoch = ns_intervals_rfc - offset
uu2_time = rospy.Time()
uu2_time.secs = long(ns_intervals_epoch / 1e9 * 100)
uu2_time.nsecs = long(ns_intervals_epoch - uu2_time.secs / (100 * 1e-9)) * 100
# Timestamps were generated for the same second
self.assertEqual(uu1_time.secs, uu2_time.secs)
# Timestamps should be different as they were generated for times in different 100ns intervals
self.assertNotEqual(uu1_time.nsecs, uu2_time.nsecs)
if __name__ == '__main__':
import rosunit
rosunit.unitrun('unique_id', 'test_uuid_py', TestPythonUUID)