From 6d79b5e0e3ab31e10b4d1bd9580fb1e503b3c7f2 Mon Sep 17 00:00:00 2001 From: Tully Foote Date: Tue, 15 Dec 2015 00:27:46 -0800 Subject: [PATCH 1/5] adding basic unit tests for rate --- rclcpp/CMakeLists.txt | 11 +++++ rclcpp/include/rclcpp/rate.hpp | 7 ++-- rclcpp/test/test_rate.cpp | 76 ++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 rclcpp/test/test_rate.cpp diff --git a/rclcpp/CMakeLists.txt b/rclcpp/CMakeLists.txt index 11207cb..d1ca78e 100644 --- a/rclcpp/CMakeLists.txt +++ b/rclcpp/CMakeLists.txt @@ -102,6 +102,17 @@ if(AMENT_ENABLE_TESTING) ${rosidl_generator_cpp_INCLUDE_DIRS} ) endif() + ament_add_gtest(test_rate test/test_rate.cpp) + if(TARGET test_rate) + target_include_directories(test_rate PUBLIC + ${rcl_interfaces_INCLUDE_DIRS} + ${rmw_INCLUDE_DIRS} + ${rosidl_generator_cpp_INCLUDE_DIRS} + ) + target_link_libraries(test_rate + ${PROJECT_NAME}${target_suffix} + ) + endif() endif() ament_package( diff --git a/rclcpp/include/rclcpp/rate.hpp b/rclcpp/include/rclcpp/rate.hpp index 4f25634..713b4a3 100644 --- a/rclcpp/include/rclcpp/rate.hpp +++ b/rclcpp/include/rclcpp/rate.hpp @@ -34,7 +34,7 @@ public: RCLCPP_SMART_PTR_DEFINITIONS_NOT_COPYABLE(RateBase); virtual bool sleep() = 0; - virtual bool is_steady() = 0; + virtual bool is_steady() const = 0; virtual void reset() = 0; }; @@ -89,7 +89,7 @@ public: } virtual bool - is_steady() + is_steady() const { return Clock::is_steady; } @@ -109,7 +109,8 @@ private: RCLCPP_DISABLE_COPY(GenericRate); std::chrono::nanoseconds period_; - std::chrono::time_point last_interval_; + using ClockDurationNano = std::chrono::duration; + std::chrono::time_point last_interval_; }; using Rate = GenericRate; diff --git a/rclcpp/test/test_rate.cpp b/rclcpp/test/test_rate.cpp new file mode 100644 index 0000000..256b34c --- /dev/null +++ b/rclcpp/test/test_rate.cpp @@ -0,0 +1,76 @@ +// Copyright 2015 Open Source Robotics Foundation, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include + +#include "rclcpp/rate.hpp" + +/* + Tests that funcion_traits calculates arity of several functors. + */ +TEST(TestRate, rate_basics) { + auto period = std::chrono::milliseconds(10); + auto delta = std::chrono::milliseconds(1); + + auto start = std::chrono::system_clock::now(); + rclcpp::rate::Rate r(period); + ASSERT_FALSE(r.is_steady()); + r.sleep(); + auto one = std::chrono::system_clock::now(); + ASSERT_TRUE(period - delta < one - start); + ASSERT_TRUE(period + delta > one - start); + + rclcpp::utilities::sleep_for(delta * 4); + r.sleep(); + auto two = std::chrono::system_clock::now(); + + ASSERT_TRUE(period - delta < two - one); + ASSERT_TRUE(period + delta > two - one); + + rclcpp::utilities::sleep_for(delta * 4); + r.reset(); + r.sleep(); + auto three = std::chrono::system_clock::now(); + ASSERT_TRUE(period + 3 * delta < three - two); + ASSERT_TRUE(period + 5 * delta > three - two); +} + +TEST(TestRate, wallrate_basics) { + auto period = std::chrono::milliseconds(10); + auto delta = std::chrono::milliseconds(1); + + auto start = std::chrono::system_clock::now(); + rclcpp::rate::WallRate r(period); + ASSERT_TRUE(r.is_steady()); + r.sleep(); + auto one = std::chrono::system_clock::now(); + ASSERT_TRUE(period - delta < one - start); + ASSERT_TRUE(period + delta > one - start); + + rclcpp::utilities::sleep_for(delta * 4); + r.sleep(); + auto two = std::chrono::system_clock::now(); + + ASSERT_TRUE(period - delta < two - one); + ASSERT_TRUE(period + delta > two - one); + + rclcpp::utilities::sleep_for(delta * 4); + r.reset(); + r.sleep(); + auto three = std::chrono::system_clock::now(); + ASSERT_TRUE(period + 3 * delta < three - two); + ASSERT_TRUE(period + 5 * delta > three - two); +} From aa818076f83d6070745faaec9efe160aec548f4d Mon Sep 17 00:00:00 2001 From: Tully Foote Date: Thu, 17 Dec 2015 14:02:37 -0800 Subject: [PATCH 2/5] softening tolerances on timing to pass on osx --- rclcpp/test/test_rate.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rclcpp/test/test_rate.cpp b/rclcpp/test/test_rate.cpp index 256b34c..d3d49c7 100644 --- a/rclcpp/test/test_rate.cpp +++ b/rclcpp/test/test_rate.cpp @@ -22,8 +22,8 @@ Tests that funcion_traits calculates arity of several functors. */ TEST(TestRate, rate_basics) { - auto period = std::chrono::milliseconds(10); - auto delta = std::chrono::milliseconds(1); + auto period = std::chrono::milliseconds(100); + auto delta = std::chrono::milliseconds(10); auto start = std::chrono::system_clock::now(); rclcpp::rate::Rate r(period); @@ -45,12 +45,12 @@ TEST(TestRate, rate_basics) { r.sleep(); auto three = std::chrono::system_clock::now(); ASSERT_TRUE(period + 3 * delta < three - two); - ASSERT_TRUE(period + 5 * delta > three - two); + ASSERT_TRUE(period + 7 * delta > three - two); } TEST(TestRate, wallrate_basics) { - auto period = std::chrono::milliseconds(10); - auto delta = std::chrono::milliseconds(1); + auto period = std::chrono::milliseconds(100); + auto delta = std::chrono::milliseconds(10); auto start = std::chrono::system_clock::now(); rclcpp::rate::WallRate r(period); @@ -72,5 +72,5 @@ TEST(TestRate, wallrate_basics) { r.sleep(); auto three = std::chrono::system_clock::now(); ASSERT_TRUE(period + 3 * delta < three - two); - ASSERT_TRUE(period + 5 * delta > three - two); + ASSERT_TRUE(period + 7 * delta > three - two); } From ebdf394dfabfee0e28ef45b2c27fd2b2f4eb0837 Mon Sep 17 00:00:00 2001 From: Tully Foote Date: Thu, 17 Dec 2015 18:00:57 -0800 Subject: [PATCH 3/5] updating tests to be less vulnerable to load --- rclcpp/test/test_rate.cpp | 48 +++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/rclcpp/test/test_rate.cpp b/rclcpp/test/test_rate.cpp index d3d49c7..f17abf6 100644 --- a/rclcpp/test/test_rate.cpp +++ b/rclcpp/test/test_rate.cpp @@ -23,54 +23,62 @@ */ TEST(TestRate, rate_basics) { auto period = std::chrono::milliseconds(100); - auto delta = std::chrono::milliseconds(10); + auto offset = std::chrono::milliseconds(50); + double overrun_ratio = 1.5; auto start = std::chrono::system_clock::now(); rclcpp::rate::Rate r(period); ASSERT_FALSE(r.is_steady()); r.sleep(); auto one = std::chrono::system_clock::now(); - ASSERT_TRUE(period - delta < one - start); - ASSERT_TRUE(period + delta > one - start); + auto delta = one - start; + ASSERT_TRUE(period < delta); + ASSERT_TRUE(period * overrun_ratio > delta); - rclcpp::utilities::sleep_for(delta * 4); + rclcpp::utilities::sleep_for(offset); r.sleep(); auto two = std::chrono::system_clock::now(); + delta = two - one; + ASSERT_TRUE(period < delta); + ASSERT_TRUE(period * overrun_ratio > delta); - ASSERT_TRUE(period - delta < two - one); - ASSERT_TRUE(period + delta > two - one); - - rclcpp::utilities::sleep_for(delta * 4); + rclcpp::utilities::sleep_for(offset); + auto two_offset = std::chrono::system_clock::now(); r.reset(); r.sleep(); auto three = std::chrono::system_clock::now(); - ASSERT_TRUE(period + 3 * delta < three - two); - ASSERT_TRUE(period + 7 * delta > three - two); + delta = three - two_offset; + ASSERT_TRUE(period < delta); + ASSERT_TRUE(period * overrun_ratio > delta); } TEST(TestRate, wallrate_basics) { auto period = std::chrono::milliseconds(100); - auto delta = std::chrono::milliseconds(10); + auto offset = std::chrono::milliseconds(50); + double overrun_ratio = 1.5; auto start = std::chrono::system_clock::now(); rclcpp::rate::WallRate r(period); ASSERT_TRUE(r.is_steady()); r.sleep(); auto one = std::chrono::system_clock::now(); - ASSERT_TRUE(period - delta < one - start); - ASSERT_TRUE(period + delta > one - start); + auto delta = one - start; + ASSERT_TRUE(period < delta); + ASSERT_TRUE(period * overrun_ratio > delta); - rclcpp::utilities::sleep_for(delta * 4); + rclcpp::utilities::sleep_for(offset); r.sleep(); auto two = std::chrono::system_clock::now(); + delta = two - one; + ASSERT_TRUE(period < delta); + ASSERT_TRUE(period * overrun_ratio > delta); - ASSERT_TRUE(period - delta < two - one); - ASSERT_TRUE(period + delta > two - one); - - rclcpp::utilities::sleep_for(delta * 4); + rclcpp::utilities::sleep_for(offset); + auto two_offset = std::chrono::system_clock::now(); r.reset(); r.sleep(); auto three = std::chrono::system_clock::now(); - ASSERT_TRUE(period + 3 * delta < three - two); - ASSERT_TRUE(period + 7 * delta > three - two); + delta = three - two_offset; + ASSERT_TRUE(period < delta); + ASSERT_TRUE(period * overrun_ratio > delta); } From fac550cc82d295c7a28b7bb6931349c488d800f8 Mon Sep 17 00:00:00 2001 From: Tully Foote Date: Thu, 17 Dec 2015 19:39:04 -0800 Subject: [PATCH 4/5] adding coverage and an epsilon --- rclcpp/test/test_rate.cpp | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/rclcpp/test/test_rate.cpp b/rclcpp/test/test_rate.cpp index f17abf6..af68f2a 100644 --- a/rclcpp/test/test_rate.cpp +++ b/rclcpp/test/test_rate.cpp @@ -24,61 +24,77 @@ TEST(TestRate, rate_basics) { auto period = std::chrono::milliseconds(100); auto offset = std::chrono::milliseconds(50); + auto epsilon = std::chrono::milliseconds(1); double overrun_ratio = 1.5; auto start = std::chrono::system_clock::now(); rclcpp::rate::Rate r(period); ASSERT_FALSE(r.is_steady()); - r.sleep(); + ASSERT_TRUE(r.sleep()); auto one = std::chrono::system_clock::now(); auto delta = one - start; ASSERT_TRUE(period < delta); ASSERT_TRUE(period * overrun_ratio > delta); rclcpp::utilities::sleep_for(offset); - r.sleep(); + ASSERT_TRUE(r.sleep()); auto two = std::chrono::system_clock::now(); delta = two - one; - ASSERT_TRUE(period < delta); + ASSERT_TRUE(period < delta + epsilon); ASSERT_TRUE(period * overrun_ratio > delta); rclcpp::utilities::sleep_for(offset); auto two_offset = std::chrono::system_clock::now(); r.reset(); - r.sleep(); + ASSERT_TRUE(r.sleep()); auto three = std::chrono::system_clock::now(); delta = three - two_offset; ASSERT_TRUE(period < delta); ASSERT_TRUE(period * overrun_ratio > delta); + + rclcpp::utilities::sleep_for(offset + period); + auto four = std::chrono::system_clock::now(); + ASSERT_FALSE(r.sleep()); + auto five = std::chrono::system_clock::now(); + delta = five - four; + ASSERT_TRUE(epsilon > delta); } -TEST(TestRate, wallrate_basics) { +TEST(TestRate, wall_rate_basics) { auto period = std::chrono::milliseconds(100); auto offset = std::chrono::milliseconds(50); + auto epsilon = std::chrono::milliseconds(1); double overrun_ratio = 1.5; auto start = std::chrono::system_clock::now(); rclcpp::rate::WallRate r(period); ASSERT_TRUE(r.is_steady()); - r.sleep(); + ASSERT_TRUE(r.sleep()); auto one = std::chrono::system_clock::now(); auto delta = one - start; ASSERT_TRUE(period < delta); ASSERT_TRUE(period * overrun_ratio > delta); rclcpp::utilities::sleep_for(offset); - r.sleep(); + ASSERT_TRUE(r.sleep()); auto two = std::chrono::system_clock::now(); delta = two - one; - ASSERT_TRUE(period < delta); + ASSERT_TRUE(period < delta + epsilon); ASSERT_TRUE(period * overrun_ratio > delta); rclcpp::utilities::sleep_for(offset); auto two_offset = std::chrono::system_clock::now(); r.reset(); - r.sleep(); + ASSERT_TRUE(r.sleep()); auto three = std::chrono::system_clock::now(); delta = three - two_offset; ASSERT_TRUE(period < delta); ASSERT_TRUE(period * overrun_ratio > delta); + + rclcpp::utilities::sleep_for(offset + period); + auto four = std::chrono::system_clock::now(); + ASSERT_FALSE(r.sleep()); + auto five = std::chrono::system_clock::now(); + delta = five - four; + ASSERT_TRUE(epsilon > delta); } From 8af64b95e55b2b5fdfde5ed6dbb206c3f86ee03e Mon Sep 17 00:00:00 2001 From: Tully Foote Date: Fri, 18 Dec 2015 01:52:35 -0800 Subject: [PATCH 5/5] fixing comment --- rclcpp/test/test_rate.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rclcpp/test/test_rate.cpp b/rclcpp/test/test_rate.cpp index af68f2a..8b421e8 100644 --- a/rclcpp/test/test_rate.cpp +++ b/rclcpp/test/test_rate.cpp @@ -19,7 +19,7 @@ #include "rclcpp/rate.hpp" /* - Tests that funcion_traits calculates arity of several functors. + Basic tests for the Rate and WallRate clases. */ TEST(TestRate, rate_basics) { auto period = std::chrono::milliseconds(100);