diff --git a/CMakeLists.txt b/CMakeLists.txt index 627e5ad..f7f6a7c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,9 +59,5 @@ install(FILES include/serial/serial.h include/serial/v8stdint.h ## Tests if(CATKIN_ENABLE_TESTING) - catkin_add_gtest(${PROJECT_NAME}-test tests/serial_tests.cc) - target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME} ${Boost_LIBRARIES}) - if(UNIX AND NOT APPLE) - target_link_libraries(${PROJECT_NAME}-test util) - endif() + add_subdirectory(tests) endif() diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..38718e6 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,10 @@ +if(UNIX) + catkin_add_gtest(${PROJECT_NAME}-test unix_serial_tests.cc) + target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME} ${Boost_LIBRARIES}) + if(NOT APPLE) + target_link_libraries(${PROJECT_NAME}-test util) + endif() + + catkin_add_gtest(${PROJECT_NAME}-test-timer unit/unix_timer_tests.cc) + target_link_libraries(${PROJECT_NAME}-test-timer ${PROJECT_NAME}) +endif() diff --git a/tests/unit/unix_timer_tests.cc b/tests/unit/unix_timer_tests.cc new file mode 100644 index 0000000..5bbd1ed --- /dev/null +++ b/tests/unit/unix_timer_tests.cc @@ -0,0 +1,63 @@ +#include "gtest/gtest.h" +#include "serial/impl/unix.h" + +#include +#include + +using serial::MillisecondTimer; + +namespace { + +/** + * Do 100 trials of timing gaps between 0 and 19 milliseconds. + * Expect accuracy within one millisecond. + */ +TEST(timer_tests, short_intervals) { + for (int trial = 0; trial < 100; trial++) + { + uint32_t ms = rand() % 20; + MillisecondTimer mt(ms); + usleep(1000 * ms); + int32_t r = mt.remaining(); + + // 1ms slush, for the cost of calling usleep. + EXPECT_NEAR(r+1, 0, 1); + } +} + +TEST(timer_tests, overlapping_long_intervals) { + MillisecondTimer* timers[10]; + + // Experimentally determined. Corresponds to the extra time taken by the loops, + // the big usleep, and the test infrastructure itself. + const int slush_factor = 14; + + // Set up the timers to each time one second, 1ms apart. + for (int t = 0; t < 10; t++) + { + timers[t] = new MillisecondTimer(1000); + usleep(1000); + } + + // Check in on them after 500ms. + usleep(500000); + for (int t = 0; t < 10; t++) + { + EXPECT_NEAR(timers[t]->remaining(), 500 - slush_factor + t, 5); + } + + // Check in on them again after another 500ms and free them. + usleep(500000); + for (int t = 0; t < 10; t++) + { + EXPECT_NEAR(timers[t]->remaining(), -slush_factor + t, 5); + delete timers[t]; + } +} + +} // namespace + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/tests/serial_tests.cc b/tests/unix_serial_tests.cc similarity index 100% rename from tests/serial_tests.cc rename to tests/unix_serial_tests.cc