$search
00001 /*************************************************************************** 00002 tag: Peter Soetens Fri Feb 11 15:59:13 CET 2005 time_test.cpp 00003 00004 time_test.cpp - description 00005 ------------------- 00006 begin : Fri February 11 2005 00007 copyright : (C) 2005 Peter Soetens 00008 email : peter.soetens@mech.kuleuven.ac.be 00009 00010 *************************************************************************** 00011 * * 00012 * This program is free software; you can redistribute it and/or modify * 00013 * it under the terms of the GNU General Public License as published by * 00014 * the Free Software Foundation; either version 2 of the License, or * 00015 * (at your option) any later version. * 00016 * * 00017 ***************************************************************************/ 00018 00019 #include "unit.hpp" 00020 00021 #include "time_test.hpp" 00022 #include <boost/bind.hpp> 00023 #include <os/Timer.hpp> 00024 #include <rtt-detail-fwd.hpp> 00025 #include <iostream> 00026 00027 #define EPSILON 0.000000002 00028 00029 // Registers the fixture into the 'registry' 00030 //CPPUNIT_TEST_SUITE_REGISTRATION( TimeTest ); 00031 00032 using namespace std; 00033 using namespace RTT; 00034 using namespace RTT::detail; 00035 using namespace boost; 00036 00037 TimeTest::TimeTest() 00038 { 00039 hbg = TimeService::Instance(); 00040 long_ns = 9007199254740992LL; // == 2^53 00041 //long_ns = 4503599627370496LL; // == 2^52 00042 //long_ns = 123456789123456789LL; // 1.234...e17 ns == approx 4 years, but double can not represent this. 00043 long_S = 9007199.254740992; 00044 //long_S = 4.503599627370496e14; 00045 normal_ns = 1000000000; // 1s 00046 normal_S = 1.0; // 1s 00047 small_ns = 10; // 10ns 00048 small_S = 10e-9; // 10ns 00049 small_t = 10; 00050 normal_t = 1000000000; // 1e9 ticks 00051 long_t = long_ns; // == 2^53 00052 } 00053 00054 TimeTest::~TimeTest() 00055 { 00056 hbg->enableSystemClock( true ); 00057 } 00058 00059 struct TestTimer 00060 : public Timer 00061 { 00062 std::vector< std::pair<Timer::TimerId, Seconds> > occured; 00063 TimeService::Seconds mstart; 00064 TestTimer() 00065 :Timer(32, ORO_SCHED_RT, os::HighestPriority) 00066 { 00067 occured.reserve(100); 00068 mstart = TimeService::Instance()->secondsSince(0); 00069 } 00070 void timeout(Timer::TimerId id) 00071 { 00072 Seconds now = TimeService::Instance()->secondsSince( 0 ); 00073 occured.push_back( std::make_pair(id, now) ); 00074 //cout << "Occured: "<< id <<" on " << now - mstart <<"\n"; 00075 } 00076 00077 ~TestTimer() 00078 { 00079 cout.flush(); 00080 } 00081 }; 00082 00083 BOOST_FIXTURE_TEST_SUITE( TimeTestSuite, TimeTest ) 00084 00085 BOOST_AUTO_TEST_CASE( testSecondsConversion ) 00086 { 00087 // Test one way 00088 BOOST_REQUIRE_EQUAL( long_ns , Seconds_to_nsecs(long_S) ); 00089 BOOST_REQUIRE_EQUAL( normal_ns, Seconds_to_nsecs(normal_S)); 00090 BOOST_REQUIRE_EQUAL( small_ns , Seconds_to_nsecs(small_S) ); 00091 00092 // Test other way 00093 BOOST_REQUIRE_EQUAL( long_S , nsecs_to_Seconds(long_ns)); 00094 BOOST_REQUIRE_EQUAL( normal_S, nsecs_to_Seconds(normal_ns)); 00095 BOOST_REQUIRE_EQUAL( small_S , nsecs_to_Seconds(small_ns)); 00096 00097 // Test invariance of conversions : 00098 BOOST_REQUIRE_EQUAL( long_ns , Seconds_to_nsecs( nsecs_to_Seconds(long_ns) )); 00099 BOOST_REQUIRE_EQUAL( normal_ns, Seconds_to_nsecs( nsecs_to_Seconds(normal_ns) )); 00100 BOOST_REQUIRE_EQUAL( small_ns , Seconds_to_nsecs( nsecs_to_Seconds(small_ns) )); 00101 BOOST_REQUIRE_EQUAL( long_S , nsecs_to_Seconds( Seconds_to_nsecs(long_S) )); 00102 BOOST_REQUIRE_EQUAL( normal_S, nsecs_to_Seconds( Seconds_to_nsecs(normal_S) )); 00103 BOOST_REQUIRE_EQUAL( small_S , nsecs_to_Seconds( Seconds_to_nsecs(small_S) )); 00104 } 00105 00106 BOOST_AUTO_TEST_CASE( testTicksConversion ) 00107 { 00108 // Test ticks conversion invariance : 00109 // margin is in % rounding error. 00110 int margin = 1; 00111 //#if defined( OROCOS_TARGET_LXRT) || defined(OROCOS_TARGET_XENOMAI) 00112 // int small_margin = 25; // 25% of 8ns : allow a two-off. 00113 //#else 00114 // int small_margin = 10; // 10% of 8ns : allow a one-off. 00115 //#endif 00116 00117 // I'm removing the small conversions because they test more the underlying RTOS than Orocos and the underlying RTOS 00118 // isn't fixing this for years... 00119 BOOST_REQUIRE_CLOSE( (double)long_ns , (double)TimeService::ticks2nsecs( TimeService::nsecs2ticks( long_ns )), margin ); 00120 BOOST_REQUIRE_CLOSE( (double)normal_ns, (double)TimeService::ticks2nsecs( TimeService::nsecs2ticks( normal_ns )), margin ); 00121 //BOOST_REQUIRE_CLOSE( (double)small_ns , (double)TimeService::ticks2nsecs( TimeService::nsecs2ticks( small_ns )), small_margin ); 00122 BOOST_REQUIRE_CLOSE( (double)long_t , (double)TimeService::nsecs2ticks( TimeService::ticks2nsecs( long_t )), margin ); 00123 BOOST_REQUIRE_CLOSE( (double)normal_t, (double)TimeService::nsecs2ticks( TimeService::ticks2nsecs( normal_t )), margin ); 00124 //BOOST_REQUIRE_CLOSE( (double)small_t , (double)TimeService::nsecs2ticks( TimeService::ticks2nsecs( small_t )), small_margin ); 00125 } 00126 00127 BOOST_AUTO_TEST_CASE( testTimeProgress ) 00128 { 00129 // A time measurement takes time : 00130 TimeService::ticks t = hbg->getTicks(); 00131 usleep(100000); 00132 BOOST_CHECK( t != hbg->getTicks() ); 00133 BOOST_CHECK( 0 != hbg->ticksSince(t) ); 00134 BOOST_CHECK( 0 != hbg->secondsSince(t) ); 00135 00136 // With Re-init of t : 00137 t = 0; 00138 BOOST_REQUIRE_EQUAL( TimeService::ticks(0) , hbg->getTicks( t ) ); 00139 t = 0; 00140 // BOOST_REQUIRE_EQUAL( Seconds(0.0) , hbg->getSeconds( t ) ); 00141 00142 // Stop Time Progress: 00143 hbg->enableSystemClock( false ); 00144 t = hbg->getTicks(); 00145 BOOST_REQUIRE_EQUAL( t , hbg->getTicks() ); 00146 BOOST_REQUIRE_EQUAL( TimeService::ticks(0) , hbg->ticksSince(t) ); 00147 // BOOST_REQUIRE_EQUAL( Seconds(0.0) , hbg->secondsSince(t) ); 00148 00149 Seconds change_S = 0.123456789; 00150 00151 hbg->secondsChange( change_S ); 00152 BOOST_CHECK( t != hbg->getTicks() ); // ticks must have changed 00153 BOOST_CHECK( -EPSILON < (change_S - hbg->secondsSince(t)) && 00154 EPSILON > (change_S - hbg->secondsSince(t)) ); 00155 00156 // Restart Time Progress 00157 hbg->enableSystemClock( true ); 00158 BOOST_CHECK( t != hbg->getTicks() ); 00159 BOOST_CHECK( TimeService::ticks(0) != hbg->ticksSince(t) ); 00160 BOOST_CHECK( Seconds(0.0) != hbg->secondsSince(t) ); 00161 00162 } 00163 00164 BOOST_AUTO_TEST_CASE( testTimers ) 00165 { 00166 TestTimer timer; 00167 Seconds now = hbg->secondsSince( 0 ); 00168 // Test arming 00169 BOOST_CHECK( timer.arm(0, 0.5) ); 00170 BOOST_CHECK( timer.arm(1, 0.6) ); 00171 BOOST_CHECK( timer.arm(2, 0.5) ); 00172 00173 BOOST_CHECK( timer.arm(3, 0.8) ); 00174 BOOST_CHECK( timer.arm(3, 0.9) ); 00175 00176 BOOST_CHECK( timer.isArmed( 0 ) ); 00177 BOOST_CHECK( timer.isArmed( 1 ) ); 00178 BOOST_CHECK( timer.isArmed( 2 ) ); 00179 BOOST_CHECK( timer.isArmed( 3 ) ); 00180 00181 sleep(1); 00182 00183 // Test clearing 00184 BOOST_CHECK( !timer.isArmed( 0 ) ); 00185 BOOST_CHECK( !timer.isArmed( 1 ) ); 00186 BOOST_CHECK( !timer.isArmed( 2 ) ); 00187 BOOST_CHECK( !timer.isArmed( 3 ) ); 00188 00189 // Test sequence 00190 BOOST_CHECK( timer.occured.size() == 4 ); 00191 BOOST_CHECK( timer.occured[0].first == 0 ); 00192 BOOST_CHECK( timer.occured[1].first == 2 ); 00193 BOOST_CHECK( timer.occured[2].first == 1 ); 00194 BOOST_CHECK( timer.occured[3].first == 3 ); 00195 00196 // Test timeliness 00197 BOOST_REQUIRE_CLOSE( timer.occured[0].second, now+0.5, 0.1 ); 00198 BOOST_REQUIRE_CLOSE( timer.occured[1].second, now+0.5, 0.1 ); 00199 BOOST_REQUIRE_CLOSE( timer.occured[2].second, now+0.6, 0.1 ); 00200 BOOST_REQUIRE_CLOSE( timer.occured[3].second, now+0.9, 0.1 ); 00201 00202 // Test wrong parameters. 00203 BOOST_CHECK( timer.arm(4, -0.1) == false); 00204 BOOST_CHECK( timer.arm(500, 0.1) == false); 00205 00206 timer.occured.clear(); 00207 00208 // Test resize. 00209 BOOST_CHECK( timer.arm(10, 0.5) ); 00210 timer.setMaxTimers( 5 ); // clears the timer 00211 sleep(1); 00212 BOOST_CHECK( timer.occured.size() == 0 ); 00213 } 00214 00215 BOOST_AUTO_TEST_CASE( testTimerPeriod ) 00216 { 00217 TestTimer timer; 00218 Seconds now = hbg->secondsSince( 0 ); 00219 // Test starting periodics 00220 BOOST_CHECK( timer.startTimer(0, 0.1) ); 00221 BOOST_CHECK( timer.startTimer(1, 0.6) ); 00222 BOOST_CHECK( timer.startTimer(2, 0.5) ); 00223 00224 BOOST_CHECK( timer.startTimer(3, 0.5) ); 00225 BOOST_CHECK( timer.startTimer(3, 0.2) ); 00226 00227 BOOST_CHECK( timer.isArmed( 0 ) ); 00228 BOOST_CHECK( timer.isArmed( 1 ) ); 00229 BOOST_CHECK( timer.isArmed( 2 ) ); 00230 BOOST_CHECK( timer.isArmed( 3 ) ); 00231 00232 sleep(1); 00233 00234 // Test clearing 00235 BOOST_CHECK( timer.killTimer( 0 ) ); 00236 BOOST_CHECK( timer.killTimer( 1 ) ); 00237 BOOST_CHECK( timer.killTimer( 2 ) ); 00238 BOOST_CHECK( timer.killTimer( 3 ) ); 00239 BOOST_CHECK( !timer.isArmed( 0 ) ); 00240 BOOST_CHECK( !timer.isArmed( 1 ) ); 00241 BOOST_CHECK( !timer.isArmed( 2 ) ); 00242 BOOST_CHECK( !timer.isArmed( 3 ) ); 00243 00244 // Test sequence 00245 //BOOST_CHECK( timer.occured.size() == 4 ); hard to estimate 00246 BOOST_CHECK( timer.occured[0].first == 0 ); 00247 BOOST_CHECK( timer.occured[1].first == 0 ); 00248 BOOST_CHECK( timer.occured[2].first == 3 ); 00249 BOOST_CHECK( timer.occured[3].first == 0 ); 00250 BOOST_CHECK( timer.occured[4].first == 0 ); 00251 BOOST_CHECK( timer.occured[5].first == 3 ); 00252 00253 BOOST_CHECK( timer.occured[6].first == 0 ); 00254 BOOST_CHECK( timer.occured[7].first == 2 ); 00255 00256 BOOST_CHECK( timer.occured[8].first == 0 ); 00257 BOOST_CHECK( timer.occured[9].first == 1 ); 00258 BOOST_CHECK( timer.occured[10].first == 3 ); 00259 BOOST_CHECK( timer.occured[11].first == 0 ); 00260 BOOST_CHECK( timer.occured[12].first == 0 ); 00261 BOOST_CHECK( timer.occured[13].first == 3 ); 00262 BOOST_CHECK( timer.occured[14].first == 0 ); 00263 00264 // Test timeliness 00265 BOOST_REQUIRE_CLOSE( timer.occured[0].second, now+0.1, 0.1 ); 00266 BOOST_REQUIRE_CLOSE( timer.occured[1].second, now+0.2, 0.1 ); 00267 BOOST_REQUIRE_CLOSE( timer.occured[2].second, now+0.2, 0.1 ); 00268 BOOST_REQUIRE_CLOSE( timer.occured[3].second, now+0.3, 0.1 ); 00269 BOOST_REQUIRE_CLOSE( timer.occured[4].second, now+0.4, 0.1 ); 00270 BOOST_REQUIRE_CLOSE( timer.occured[5].second, now+0.4, 0.1 ); 00271 BOOST_REQUIRE_CLOSE( timer.occured[6].second, now+0.5, 0.1 ); 00272 BOOST_REQUIRE_CLOSE( timer.occured[7].second, now+0.5, 0.1 ); 00273 BOOST_REQUIRE_CLOSE( timer.occured[8].second, now+0.6, 0.1 ); 00274 BOOST_REQUIRE_CLOSE( timer.occured[9].second, now+0.6, 0.1 ); 00275 BOOST_REQUIRE_CLOSE( timer.occured[10].second, now+0.6, 0.1 ); 00276 BOOST_REQUIRE_CLOSE( timer.occured[11].second, now+0.7, 0.1 ); 00277 BOOST_REQUIRE_CLOSE( timer.occured[12].second, now+0.8, 0.1 ); 00278 BOOST_REQUIRE_CLOSE( timer.occured[13].second, now+0.8, 0.1 ); 00279 BOOST_REQUIRE_CLOSE( timer.occured[14].second, now+0.9, 0.1 ); 00280 00281 // Test wrong parameters. 00282 BOOST_CHECK( timer.startTimer(4, -0.1) == false); 00283 BOOST_CHECK( timer.startTimer(500, 0.1) == false); 00284 00285 timer.occured.clear(); 00286 00287 // Test resize. 00288 BOOST_CHECK( timer.startTimer(10, 0.5) ); 00289 timer.setMaxTimers( 5 ); // clears the timer 00290 sleep(1); 00291 BOOST_CHECK( timer.occured.size() == 0 ); 00292 } 00293 00294 BOOST_AUTO_TEST_SUITE_END()