00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "unit.hpp"
00021
00022 #include "tasks_test.hpp"
00023
00024 #include <iostream>
00025
00026 #include <extras/PeriodicActivity.hpp>
00027 #include <os/TimeService.hpp>
00028 #include <Logger.hpp>
00029
00030 #include <boost/scoped_ptr.hpp>
00031
00032 using namespace std;
00033 using namespace boost;
00034 using namespace RTT;
00035 using namespace RTT::detail;
00036
00037 #define BOOST_CHECK_EQUAL_MESSAGE(M, v1, v2) BOOST_CHECK_MESSAGE( v1==v2, M)
00038
00039 struct TestOverrun
00040 : public RunnableInterface
00041 {
00042 bool fini;
00043 bool initialize() { fini = false; return true; }
00044
00045 void step() {
00046
00047 usleep(200*1000);
00048
00049
00050
00051 #if 0
00052 TIME_SPEC timevl;
00053 timevl = ticks2timespec( nano2ticks(200*1000*1000) );
00054 rtos_nanosleep( &timevl, 0);
00055 #endif
00056 }
00057
00058 void finalize() {
00059 fini = true;
00060 }
00061 };
00062
00063 struct TestPeriodic
00064 : public RunnableInterface
00065 {
00066 int overfail, underfail, succ;
00067 bool stepped;
00068
00069 TimeService::ticks ts;
00070
00071 TestPeriodic()
00072 : overfail(0), underfail(0), succ(0), stepped(false)
00073 {
00074 }
00075
00076 bool initialize() {
00077 this->reset();
00078 return true;
00079 }
00080 void step() {
00081 if (stepped == false ) {
00082 ts = TimeService::Instance()->getTicks();
00083 stepped = true;
00084 } else {
00085 TimeService::Seconds s = TimeService::Instance()->secondsSince( ts );
00086 if ( s < this->getThread()->getPeriod() *0.9 ) {
00087 ++underfail;
00088
00089 }
00090 else if ( s > this->getThread()->getPeriod() *1.1 ) {
00091 ++overfail;
00092
00093 }
00094 else {
00095 ++succ;
00096
00097 }
00098 ts = TimeService::Instance()->getTicks();
00099 }
00100 }
00101 void finalize() {
00102 if (overfail || underfail)
00103 cerr <<"overfail is:"<<overfail<<", underfail is:"<<underfail<< " success is: "<<succ<<endl;
00104 }
00105
00106 void reset() {
00107 overfail = 0;
00108 underfail = 0;
00109 succ = 0;
00110 stepped = false;
00111 }
00112 };
00113
00114 struct TestRunnableInterface
00115 : public RunnableInterface
00116 {
00117 bool result, breakl;
00118 bool init, stepped, looped, fini;
00119
00120 TestRunnableInterface(bool res)
00121 {
00122 this->reset(res);
00123 }
00124
00125 bool initialize() {
00126 init = true;
00127 return result;
00128 }
00129 void step() {
00130 stepped = true;
00131 }
00132 void finalize() {
00133 fini = true;
00134 }
00135
00136 void loop() {
00137 looped = true;
00138 while (breakl == false) {
00139 usleep(500*1000);
00140 }
00141 }
00142
00143 bool breakLoop() {
00144 return breakl;
00145 }
00146
00147 void reset(bool res) {
00148 result = res;
00149 init = false;
00150 stepped = false;
00151 fini = false;
00152 looped = false;
00153 breakl = true;
00154 }
00155 };
00156
00157 struct TestAllocate
00158 : public RunnableInterface
00159 {
00160 std::vector<std::string> v;
00161 char* c;
00162 std::string s;
00163
00164 bool initialize() {
00165 c = 0;
00166 return true;
00167 }
00168 void step() {
00169 v.resize( 0 );
00170 v.resize( 1025, std::string("Goodbye Memory") );
00171 delete[] c;
00172 c = new char[1025];
00173 s = "Hello World ";
00174 s += s;
00175 s += s;
00176 }
00177 void finalize() {
00178 delete[] c;
00179 v.resize(0);
00180 }
00181 };
00182
00186 struct TestSelfRemove
00187 : public RunnableInterface
00188 {
00189 int c;
00190 bool fini;
00191 bool breakl;
00192 bool initialize() {
00193 c = 0;
00194 fini = false;
00195 breakl = true;
00196 return true;
00197 }
00198 bool breakLoop() {
00199 return breakl;
00200 }
00201 void loop() {
00202 this->getActivity()->stop();
00203 }
00204 void step() {
00205 ++c;
00206 if (c == 5)
00207 this->getActivity()->stop();
00208 }
00209 void finalize() {
00210 fini = true;
00211 }
00212 };
00213
00214 void
00215 ActivitiesTest::setUp()
00216 {
00217 periodic_act = new PeriodicActivity( 15, 0.01 );
00218 t_act = new Activity(15, 0.01);
00219
00220 t_run_int_prio = new TestRunnableInterface(true);
00221 t_run_int_act = new TestRunnableInterface(true);
00222 t_run_int_fail = new TestRunnableInterface(false);
00223
00224 t_run_allocate = new TestAllocate();
00225 t_self_remove = new TestSelfRemove();
00226
00227 t_run_allocate_act = new TestAllocate();
00228 }
00229
00230
00231 void
00232 ActivitiesTest::tearDown()
00233 {
00234 delete periodic_act;
00235 delete t_act;
00236
00237 delete t_run_int_prio;
00238 delete t_run_int_act;
00239 delete t_run_int_fail;
00240
00241 delete t_run_allocate;
00242 delete t_run_allocate_act;
00243
00244 delete t_self_remove;
00245 }
00246
00247 BOOST_FIXTURE_TEST_SUITE( ActivitiesTestSuite, ActivitiesTest )
00248
00249 BOOST_AUTO_TEST_CASE( testFailInit )
00250 {
00251 periodic_act->run( t_run_int_fail );
00252
00253 BOOST_CHECK( !periodic_act->start() );
00254 BOOST_CHECK( !periodic_act->stop() );
00255
00256 BOOST_CHECK( t_act->run( t_run_int_fail ) );
00257 t_run_int_fail->reset(false);
00258
00259 BOOST_CHECK( !t_act->start() );
00260 BOOST_CHECK( !t_act->stop() );
00261
00262 }
00263
00264 #if !defined( OROCOS_TARGET_WIN32 ) && !defined(OROCOS_TARGET_LXRT)
00265 BOOST_AUTO_TEST_CASE( testOverrun )
00266 {
00267 bool r = false;
00268
00269 boost::scoped_ptr<TestOverrun> run( new TestOverrun() );
00270 boost::scoped_ptr<Activity> t( new Activity(25, 0.1, 0,"ORThread") );
00271
00272 BOOST_CHECK_EQUAL(0.1,t->getPeriod() );
00273 t->thread()->setMaxOverrun(1);
00274
00275 t->run( run.get() );
00276
00277
00278 Logger::LogLevel ll = Logger::log().getLogLevel();
00279 Logger::log().setLogLevel(Logger::Never);
00280
00281 t->start();
00282
00283
00284 usleep(100*1000);
00285 usleep(400*1000);
00286 Logger::log().setLogLevel(ll);
00287
00288 r = !t->isRunning();
00289
00290 t->run(0);
00291
00292 BOOST_REQUIRE_MESSAGE( r, "Failed to detect step overrun in Thread");
00293
00294 BOOST_CHECK_MESSAGE( run->fini, "Failed to execute finalize in emergencyStop" );
00295
00296 }
00297 #endif
00298
00299 BOOST_AUTO_TEST_CASE( testThread )
00300 {
00301 bool r = false;
00302
00303 boost::scoped_ptr<TestPeriodic> run( new TestPeriodic() );
00304
00305 boost::scoped_ptr<ActivityInterface> t( new Activity(ORO_SCHED_RT, os::HighestPriority, 0.1, 0, "PThread") );
00306 t->run( run.get() );
00307
00308 r = t->start();
00309 BOOST_CHECK_MESSAGE( r, "Failed to start Thread");
00310 usleep(1000*100);
00311 r = t->stop();
00312 BOOST_CHECK_MESSAGE( r, "Failed to stop Thread" );
00313 BOOST_CHECK_MESSAGE( run->stepped == true, "Step not executed" );
00314 BOOST_CHECK_EQUAL_MESSAGE("Periodic Failure: period of step() too long !", run->overfail, 0);
00315 BOOST_CHECK_EQUAL_MESSAGE("Periodic Failure: period of step() too short!", run->underfail, 0);
00316 t->run(0);
00317 }
00318
00319
00320 BOOST_AUTO_TEST_CASE( testNonPeriodic )
00321 {
00322 scoped_ptr<TestRunnableInterface> t_run_int_nonper
00323 ( new TestRunnableInterface(true) );
00324
00325 {
00326 scoped_ptr<Activity> t_task_nonper
00327 ( new Activity( 14 ) );
00328
00329 BOOST_CHECK( t_task_nonper->run( t_run_int_nonper.get() ) );
00330 BOOST_CHECK( t_task_nonper->start() );
00331 testPause();
00332 BOOST_CHECK( t_run_int_nonper->looped );
00333 BOOST_CHECK( !t_run_int_nonper->stepped );
00334 BOOST_CHECK( t_run_int_nonper->init );
00335 BOOST_CHECK( t_task_nonper->stop() );
00336 BOOST_CHECK( t_run_int_nonper->fini );
00337 BOOST_CHECK( !t_task_nonper->isRunning() );
00338 BOOST_CHECK( t_task_nonper->run( 0 ) );
00339 BOOST_CHECK( t_task_nonper->start() );
00340 BOOST_CHECK( t_task_nonper->stop() );
00341
00342 BOOST_CHECK( !t_task_nonper->isRunning() );
00343 }
00344 }
00345
00346 BOOST_AUTO_TEST_CASE( testActivityNP )
00347 {
00348 scoped_ptr<TestRunnableInterface> t_run_int_nonper
00349 ( new TestRunnableInterface(true) );
00350
00351 {
00352 scoped_ptr<Activity> t_task_nonper
00353 ( new Activity(15) );
00354
00355 BOOST_CHECK( t_task_nonper->run( t_run_int_nonper.get() ) );
00356 BOOST_CHECK( t_task_nonper->start() );
00357 testPause();
00358 sleep(1);
00359 BOOST_CHECK( t_run_int_nonper->looped );
00360 BOOST_CHECK( t_run_int_nonper->init );
00361 BOOST_CHECK( t_task_nonper->stop() );
00362 BOOST_CHECK( t_run_int_nonper->fini );
00363 BOOST_CHECK( !t_task_nonper->isRunning() );
00364 BOOST_CHECK( t_task_nonper->run( 0 ) );
00365 BOOST_CHECK( t_task_nonper->start() );
00366 BOOST_CHECK( t_task_nonper->stop() );
00367
00368 BOOST_CHECK( !t_task_nonper->isRunning() );
00369 }
00370 }
00371
00372 BOOST_AUTO_TEST_CASE( testActivityBreakLoop )
00373 {
00374 scoped_ptr<TestRunnableInterface> t_run_int_nonper
00375 ( new TestRunnableInterface(true) );
00376
00377 {
00378 scoped_ptr<Activity> t_task_nonper
00379 ( new Activity(15) );
00380
00381 BOOST_CHECK( t_task_nonper->run( t_run_int_nonper.get() ) );
00382 BOOST_CHECK( t_task_nonper->start() );
00383 testPause();
00384
00385 t_run_int_nonper->breakl = false;
00386 BOOST_CHECK( t_task_nonper->start() );
00387 testPause();
00388 BOOST_CHECK( t_task_nonper->stop() == false );
00389
00390 t_run_int_nonper->breakl = true;
00391 BOOST_CHECK( t_task_nonper->stop() );
00392 BOOST_CHECK( t_run_int_nonper->fini );
00393 BOOST_CHECK( !t_task_nonper->isRunning() );
00394 }
00395 }
00396
00397 BOOST_AUTO_TEST_CASE( testSelfRemove )
00398 {
00399 scoped_ptr<TestSelfRemove> t_run_int_nonper
00400 ( new TestSelfRemove() );
00401 scoped_ptr<Activity> t_task_nonper
00402 ( new Activity( 14 ) );
00403 BOOST_CHECK( t_task_nonper->run( t_run_int_nonper.get() ) );
00404 BOOST_CHECK( t_task_nonper->start() );
00405 BOOST_CHECK( periodic_act->run(t_self_remove) );
00406 BOOST_CHECK( periodic_act->start() );
00407 testPause();
00408 BOOST_CHECK( !periodic_act->isRunning() );
00409 BOOST_CHECK( t_self_remove->fini );
00410 BOOST_CHECK( !t_task_nonper->isRunning() );
00411 BOOST_CHECK( t_run_int_nonper->fini );
00412 }
00413
00414 BOOST_AUTO_TEST_CASE( testActivityNPSelfRemove )
00415 {
00416 scoped_ptr<TestSelfRemove> t_run_int_nonper
00417 ( new TestSelfRemove() );
00418 scoped_ptr<Activity> t_task_nonper
00419 ( new Activity( 14 ) );
00420 BOOST_CHECK( t_task_nonper->run( t_run_int_nonper.get() ) );
00421 BOOST_CHECK( t_task_nonper->start() );
00422 testPause();
00423 BOOST_CHECK( !t_task_nonper->isRunning() );
00424 BOOST_CHECK( t_run_int_nonper->fini );
00425 }
00426
00427 BOOST_AUTO_TEST_CASE( testActivityPSelfRemove )
00428 {
00429 scoped_ptr<TestSelfRemove> t_run_int_per
00430 ( new TestSelfRemove() );
00431 scoped_ptr<Activity> t_task_per
00432 ( new Activity( 14, 0.01 ) );
00433 BOOST_CHECK( t_task_per->run( t_run_int_per.get() ) );
00434 BOOST_CHECK( t_task_per->start() );
00435 testPause();
00436 BOOST_CHECK( !t_task_per->isRunning() );
00437 BOOST_CHECK( t_run_int_per->fini );
00438 }
00439
00440
00441 BOOST_AUTO_TEST_CASE( testStartStop )
00442 {
00443 testStart();
00444 testPause();
00445 testStop();
00446 }
00447
00448 BOOST_AUTO_TEST_CASE( testRunnableInterface )
00449 {
00450 testAddRunnableInterface();
00451 testStart();
00452 testRunnableInterfaceInit();
00453 testPause();
00454 testRunnableInterfaceExecution();
00455 testStop();
00456 testRemoveRunnableInterface();
00457 }
00458
00459 BOOST_AUTO_TEST_CASE( testAllocation )
00460 {
00461 testAddAllocate();
00462 testStart();
00463 testPause();
00464 testStop();
00465 testRemoveAllocate();
00466 }
00467
00468 BOOST_AUTO_TEST_SUITE_END()
00469
00470 void ActivitiesTest::testAddRunnableInterface()
00471 {
00472 bool adding_prio = periodic_act->run( t_run_int_prio );
00473 BOOST_CHECK( adding_prio );
00474
00475 bool adding_act = t_act->run( t_run_int_act );
00476 BOOST_CHECK( adding_act );
00477 }
00478
00479 void ActivitiesTest::testRemoveRunnableInterface()
00480 {
00481 BOOST_CHECK( t_run_int_prio->fini );
00482 BOOST_CHECK( periodic_act->run( 0 ) );
00483
00484 BOOST_CHECK( t_run_int_act->fini );
00485 BOOST_CHECK( t_act->run( 0 ) );
00486 }
00487
00488 void ActivitiesTest::testStart()
00489 {
00490 BOOST_CHECK( periodic_act->start());
00491 BOOST_CHECK( periodic_act->isRunning() );
00492
00493 BOOST_CHECK( t_act->start());
00494 BOOST_CHECK( t_act->isRunning() );
00495 }
00496
00497 void ActivitiesTest::testPause()
00498 {
00499 #if 0
00500
00501 int rv = 0;
00502 BOOST_CHECK( (rv = usleep(100000)) == 0);
00503 if ( rv != 0)
00504 BOOST_CHECK_EQUAL_MESSAGE(errno, 0, "Sleep failed. Errno is not zero.");
00505 #else
00506 TIME_SPEC t;
00507 t.tv_sec = 1;
00508 t.tv_nsec = 0;
00509 BOOST_CHECK( rtos_nanosleep(&t,0) == 0);
00510 #endif
00511 }
00512
00513 void ActivitiesTest::testRunnableInterfaceInit() {
00514 BOOST_CHECK( t_run_int_prio->init );
00515 BOOST_CHECK( t_run_int_act->init );
00516 }
00517
00518 void ActivitiesTest::testRunnableInterfaceExecution() {
00519
00520 BOOST_CHECK( t_run_int_prio->stepped );
00521 BOOST_CHECK( t_run_int_act->stepped );
00522 }
00523
00524 void ActivitiesTest::testStop()
00525 {
00526 BOOST_CHECK( periodic_act->stop());
00527 BOOST_CHECK( !periodic_act->isRunning() );
00528
00529 BOOST_CHECK( t_act->stop());
00530 BOOST_CHECK( !t_act->isRunning() );
00531 }
00532
00533 void ActivitiesTest::testAddAllocate()
00534 {
00535 BOOST_CHECK( periodic_act->run( t_run_allocate ) );
00536
00537 BOOST_CHECK( t_act->run( t_run_allocate_act ) );
00538 }
00539
00540 void ActivitiesTest::testRemoveAllocate()
00541 {
00542 BOOST_CHECK( periodic_act->run( 0 ) );
00543
00544 BOOST_CHECK( t_act->run( 0 ) );
00545 }
00546