git commit -m "first commit"
This commit is contained in:
15
navigations/unique_identifier/unique_id/tests/CMakeLists.txt
Executable file
15
navigations/unique_identifier/unique_id/tests/CMakeLists.txt
Executable 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)
|
||||
193
navigations/unique_identifier/unique_id/tests/second_test_unique_id.cpp
Executable file
193
navigations/unique_identifier/unique_id/tests/second_test_unique_id.cpp
Executable 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);
|
||||
}
|
||||
327
navigations/unique_identifier/unique_id/tests/test_unique_id.cpp
Executable file
327
navigations/unique_identifier/unique_id/tests/test_unique_id.cpp
Executable 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();
|
||||
}
|
||||
202
navigations/unique_identifier/unique_id/tests/test_unique_id.py
Executable file
202
navigations/unique_identifier/unique_id/tests/test_unique_id.py
Executable 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)
|
||||
Reference in New Issue
Block a user