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 "taskthread_test.hpp"
00023
00024 #include <iostream>
00025
00026 #include <extras/Activities.hpp>
00027 #include <extras/TimerThread.hpp>
00028 #include <extras/SimulationThread.hpp>
00029 #include <os/MainThread.hpp>
00030 #include <Logger.hpp>
00031 #include <rtt-config.h>
00032
00033 using namespace std;
00034 using namespace RTT;
00035
00036 struct A {};
00037
00038 template<class T>
00039 struct TestActivity
00040 : public T
00041 {
00042 bool result, _dothrow;
00043 bool init, stepped, fini;
00044 bool wasrunning, wasactive;
00045
00046 ActivityInterface* owner;
00047
00048 TestActivity(int prio, double per, bool fail, bool dothrow = false)
00049 :T(prio,per), _dothrow(dothrow)
00050 {
00051 this->reset(fail);
00052 }
00053
00054 bool initialize() {
00055 init = true;
00056 return result;
00057 }
00058 void step() {
00059 stepped = true;
00060 wasrunning = this->isRunning();
00061 wasactive = this->isActive();
00062 #ifndef ORO_EMBEDDED
00063 if ( _dothrow )
00064 throw A();
00065 #endif
00066 }
00067 void finalize() {
00068 fini = true;
00069 }
00070
00071 void reset(bool fail) {
00072 result = fail;
00073 init = false;
00074 stepped = false;
00075 fini = false;
00076 wasrunning=false;
00077 wasactive=false;
00078 }
00079 };
00080
00081 struct TestRunner
00082 : public RunnableInterface
00083 {
00084 bool result;
00085 bool init, stepped, fini;
00086 bool looped, broke;
00087 bool wasrunning, wasactive;
00088
00089 TestRunner(bool fail)
00090 {
00091 this->reset(fail);
00092 }
00093
00094 bool initialize() {
00095 init = true;
00096 BOOST_CHECK(getActivity()->isActive());
00097 BOOST_CHECK(!getActivity()->isRunning());
00098 return result;
00099 }
00100 void step() {
00101 stepped = true;
00102 wasrunning=getActivity()->isRunning();
00103 wasactive=getActivity()->isActive();
00104 }
00105
00106 void loop() {
00107 looped = true;
00108 wasrunning=getActivity()->isRunning();
00109 wasactive=getActivity()->isActive();
00110 }
00111
00112 bool breakLoop() {
00113 broke = true;
00114 return true;
00115 }
00116
00117 void finalize() {
00118 fini = true;
00119 BOOST_CHECK(getActivity()->isActive());
00120 BOOST_CHECK(!getActivity()->isRunning());
00121 }
00122
00123 void reset(bool fail) {
00124 result = fail;
00125 init = false;
00126 stepped = false;
00127 fini = false;
00128 looped = false;
00129 broke = false;
00130 wasrunning = false;
00131 wasactive = false;
00132 }
00133 };
00134
00135
00136 void
00137 ActivitiesThreadTest::setUp()
00138 {
00139 t_task_np = new TestActivity<PeriodicActivity>(3, 0.01, true );
00140 t_task_np_bad = new TestActivity<PeriodicActivity>(3, 0.01, true, true );
00141 t_task_p = new TestActivity<PeriodicActivity>(3, 0.032, true );
00142 t_task_a = new TestActivity<Activity>(3, 0.01, true, true );
00143 }
00144
00145
00146 void
00147 ActivitiesThreadTest::tearDown()
00148 {
00149 delete t_task_np;
00150 delete t_task_np_bad;
00151 delete t_task_p;
00152 delete t_task_a;
00153 }
00154
00155
00156 BOOST_FIXTURE_TEST_SUITE( ActivitiesThreadTestSuite, ActivitiesThreadTest )
00157
00158 BOOST_AUTO_TEST_CASE(testPeriodic )
00159 {
00160
00161
00162 PeriodicActivity mtask( 15, 0.01 );
00163 BOOST_CHECK( mtask.isActive() == false );
00164 BOOST_CHECK( mtask.isRunning() == false );
00165 BOOST_CHECK( mtask.thread()->isRunning() == false );
00166 BOOST_CHECK_EQUAL( 0.01, mtask.thread()->getPeriod() );
00167
00168
00169 int bprio = 15, rtsched = ORO_SCHED_RT;
00170 os::CheckPriority( rtsched, bprio );
00171
00172 BOOST_CHECK_EQUAL( bprio, mtask.thread()->getPriority() );
00173 BOOST_CHECK_EQUAL( rtsched, mtask.thread()->getScheduler() );
00174
00175 PeriodicActivity m2task( 15, 0.01 );
00176 BOOST_CHECK( mtask.thread() == m2task.thread() );
00177
00178
00179 BOOST_CHECK( mtask.start() == true );
00180 BOOST_CHECK( mtask.isRunning() == true );
00181 BOOST_CHECK( mtask.thread()->isRunning() == true );
00182 BOOST_CHECK( m2task.isRunning() == false );
00183 BOOST_CHECK( m2task.start() == true );
00184 BOOST_CHECK( m2task.isRunning() == true );
00185
00186 usleep(100000);
00187
00188
00189 BOOST_CHECK( mtask.stop() == true );
00190 BOOST_CHECK( mtask.isRunning() == false );
00191 BOOST_CHECK( m2task.isRunning() == true );
00192 BOOST_CHECK( m2task.stop() == true );
00193 BOOST_CHECK( m2task.isRunning() == false );
00194
00195
00196 bprio = 15;
00197 rtsched = ORO_SCHED_RT;
00198 if ( os::CheckPriority( rtsched, bprio ) ) {
00199 PeriodicActivity m3task(ORO_SCHED_OTHER, 15, 0.01);
00200 bprio = 15;
00201 rtsched = ORO_SCHED_OTHER;
00202 if ( os::CheckPriority( rtsched, bprio ) ) {
00203 BOOST_CHECK( mtask.thread() != m3task.thread() );
00204 BOOST_CHECK_EQUAL( ORO_SCHED_OTHER, m3task.thread()->getScheduler() );
00205 }
00206 }
00207
00208
00209 BOOST_CHECK( mtask.thread()->stop() );
00210 BOOST_CHECK( mtask.thread()->isRunning() == false );
00211 BOOST_CHECK( mtask.start() );
00212 BOOST_CHECK( mtask.isRunning() == true );
00213 BOOST_CHECK( mtask.thread()->isRunning() == true);
00214 }
00215
00216 BOOST_AUTO_TEST_CASE( testNonPeriodic )
00217 {
00218
00219
00220 Activity mtask( 15 );
00221 usleep(100000);
00222
00223 int bprio = 15, rtsched = ORO_SCHED_RT;
00224 os::CheckPriority( rtsched, bprio );
00225
00226 BOOST_CHECK( mtask.isActive() == false );
00227 BOOST_CHECK( mtask.isRunning() == false );
00228 BOOST_CHECK( mtask.thread()->isRunning() == false );
00229 BOOST_CHECK_EQUAL( bprio, mtask.thread()->getPriority() );
00230 BOOST_CHECK_EQUAL( rtsched, mtask.thread()->getScheduler() );
00231
00232 Activity m2task( 15 );
00233 BOOST_CHECK( mtask.thread() != m2task.thread() );
00234
00235
00236 BOOST_CHECK( mtask.start() == true );
00237 BOOST_CHECK( mtask.isActive() == true );
00238 BOOST_CHECK( m2task.isActive() == false );
00239 BOOST_CHECK( m2task.start() == true );
00240 BOOST_CHECK( m2task.isActive() == true );
00241
00242 usleep(100000);
00243
00244
00245 BOOST_CHECK( mtask.stop() == true );
00246 BOOST_CHECK( mtask.isActive() == false );
00247 BOOST_CHECK( m2task.isActive() == true );
00248 BOOST_CHECK( m2task.stop() == true );
00249 BOOST_CHECK( m2task.isActive() == false );
00250
00251
00252 bprio = 15;
00253 rtsched = ORO_SCHED_OTHER;
00254 if ( os::CheckPriority( rtsched, bprio ) ) {
00255 Activity m3task(ORO_SCHED_OTHER, 15, 0.0);
00256 BOOST_CHECK( mtask.thread() != m3task.thread() );
00257 BOOST_CHECK_EQUAL( ORO_SCHED_OTHER, m3task.thread()->getScheduler() );
00258 }
00259 }
00260
00261 BOOST_AUTO_TEST_CASE( testSlave )
00262 {
00263
00264 TestRunner r(true);
00265
00266
00267 SlaveActivity mtask(&r);
00268 BOOST_CHECK( mtask.isActive() == false );
00269 BOOST_CHECK( mtask.isRunning() == false );
00270 BOOST_CHECK( mtask.isPeriodic() == false );
00271 BOOST_CHECK( mtask.getPeriod() == 0.0 );
00272 BOOST_CHECK( mtask.execute() == false );
00273 BOOST_CHECK( mtask.thread() == os::MainThread::Instance() );
00274
00275
00276 BOOST_CHECK( mtask.start() == true );
00277 BOOST_CHECK( r.init == true );
00278
00279 BOOST_CHECK( mtask.isActive() == true );
00280 BOOST_CHECK( mtask.isRunning() == false );
00281 BOOST_CHECK( mtask.start() == false );
00282
00283
00284 BOOST_CHECK( mtask.execute() );
00285 BOOST_CHECK( r.looped == true );
00286 BOOST_CHECK( mtask.execute() );
00287 BOOST_CHECK( r.wasrunning );
00288 BOOST_CHECK( r.wasactive );
00289
00290
00291 BOOST_CHECK( mtask.stop() == true );
00292 BOOST_CHECK( r.fini == true );
00293 BOOST_CHECK( mtask.isRunning() == false );
00294 BOOST_CHECK( mtask.isActive() == false );
00295 BOOST_CHECK( mtask.stop() == false );
00296
00297 BOOST_CHECK( mtask.execute() == false );
00298
00299 r.reset(true);
00300
00301
00302 SlaveActivity mslave( t_task_np, &r );
00303 BOOST_CHECK( mslave.isActive() == false );
00304 BOOST_CHECK( mslave.isRunning() == false );
00305 BOOST_CHECK( mslave.isPeriodic() == true );
00306 BOOST_CHECK_EQUAL( mslave.getPeriod(), t_task_np->getPeriod() );
00307 BOOST_CHECK( mslave.execute() == false );
00308 BOOST_CHECK( mslave.thread() == t_task_np->thread() );
00309
00310 BOOST_CHECK( !mslave.start() );
00311 BOOST_CHECK( t_task_np->start() );
00312 BOOST_CHECK( mslave.start() );
00313 BOOST_CHECK( r.init == true );
00314 BOOST_CHECK( mslave.isActive() );
00315 BOOST_CHECK( mslave.isRunning() );
00316
00317
00318 BOOST_CHECK( mslave.execute() );
00319 BOOST_CHECK( r.stepped == true );
00320 BOOST_CHECK( r.wasrunning );
00321 BOOST_CHECK( r.wasactive );
00322 BOOST_CHECK( mslave.execute() );
00323 BOOST_CHECK( !mslave.start() );
00324
00325
00326 BOOST_CHECK( mslave.stop() );
00327 BOOST_CHECK( r.fini == true );
00328 BOOST_CHECK( !mslave.isActive() );
00329 BOOST_CHECK( !mslave.isRunning() );
00330
00331 r.reset(true);
00332
00333
00334 SlaveActivity mslave_p(0.001, &r);
00335 BOOST_CHECK( mslave_p.isActive() == false );
00336 BOOST_CHECK( mslave_p.isRunning() == false );
00337 BOOST_CHECK( mslave_p.isPeriodic() == true );
00338 BOOST_CHECK( mslave_p.getPeriod() == 0.001 );
00339 BOOST_CHECK( mslave_p.execute() == false );
00340 BOOST_CHECK( mslave_p.thread() == os::MainThread::Instance() );
00341
00342 BOOST_CHECK( mslave_p.start() );
00343 BOOST_CHECK( r.init == true );
00344 BOOST_CHECK( mslave_p.isActive() );
00345 BOOST_CHECK( mslave_p.isRunning() );
00346 BOOST_CHECK( mslave_p.execute() );
00347 BOOST_CHECK( r.stepped == true );
00348 BOOST_CHECK( r.wasrunning );
00349 BOOST_CHECK( r.wasactive );
00350 BOOST_CHECK( !mslave_p.start() );
00351
00352
00353 BOOST_CHECK( mslave_p.stop() );
00354 BOOST_CHECK( r.fini == true );
00355 BOOST_CHECK( !mslave_p.isActive() );
00356 BOOST_CHECK( !mslave_p.isRunning() );
00357 BOOST_CHECK( !mslave_p.execute() );
00358 }
00359
00360 BOOST_AUTO_TEST_CASE( testSequential )
00361 {
00362
00363 TestRunner r(true);
00364
00365 SequentialActivity mtask(&r);
00366 BOOST_CHECK( mtask.isActive() == false );
00367 BOOST_CHECK( mtask.isRunning() == false );
00368 BOOST_CHECK( mtask.isPeriodic() == false );
00369 BOOST_CHECK( mtask.getPeriod() == 0.0 );
00370 BOOST_CHECK( mtask.execute() == false );
00371 BOOST_CHECK( mtask.trigger() == false );
00372 BOOST_CHECK( mtask.thread() == os::MainThread::Instance() );
00373
00374
00375 BOOST_CHECK( mtask.start() == true );
00376 BOOST_CHECK( r.init == true );
00377
00378 BOOST_CHECK( mtask.isActive() == true );
00379 BOOST_CHECK( mtask.isRunning() == false );
00380 BOOST_CHECK( mtask.start() == false );
00381
00382
00383 BOOST_CHECK( mtask.trigger() );
00384 BOOST_CHECK( r.stepped == true );
00385 BOOST_CHECK( r.wasrunning );
00386 BOOST_CHECK( r.wasactive );
00387 BOOST_CHECK( mtask.execute() == false );
00388
00389
00390 BOOST_CHECK( mtask.stop() == true );
00391 BOOST_CHECK( r.fini == true );
00392 BOOST_CHECK( mtask.isRunning() == false );
00393 BOOST_CHECK( mtask.isActive() == false );
00394 BOOST_CHECK( mtask.stop() == false );
00395
00396 BOOST_CHECK( mtask.execute() == false );
00397 BOOST_CHECK( mtask.trigger() == false );
00398
00399 r.reset(false);
00400 BOOST_CHECK( mtask.start() == false );
00401 BOOST_CHECK( r.init == true );
00402
00403 BOOST_CHECK( mtask.isActive() == false );
00404 BOOST_CHECK( mtask.isRunning() == false );
00405 BOOST_CHECK( mtask.start() == false );
00406 }
00407
00408 BOOST_AUTO_TEST_CASE( testScheduler )
00409 {
00410 int rtsched = ORO_SCHED_OTHER;
00411 int bprio = 15;
00412
00413 os::CheckPriority( rtsched, bprio );
00414 TimerThreadPtr tt = TimerThread::Instance(rtsched, bprio, 0.0123);
00415 BOOST_CHECK( tt != 0 );
00416
00417 BOOST_CHECK( tt->isRunning() == false );
00418
00419 BOOST_CHECK_EQUAL( 0.0123, tt->getPeriod());
00420
00421 BOOST_CHECK_EQUAL( bprio, tt->getPriority());
00422 BOOST_CHECK_EQUAL( rtsched, tt->getScheduler());
00423
00424
00425 rtsched = ORO_SCHED_RT;
00426 bprio = 15;
00427 if ( os::CheckPriority( rtsched, bprio ) ) {
00428 TimerThreadPtr tt2 = TimerThread::Instance(rtsched, bprio, 0.0123);
00429 BOOST_CHECK( tt2 != 0 );
00430 BOOST_CHECK( tt2 != tt );
00431 usleep(100000);
00432 BOOST_CHECK_EQUAL( rtsched, tt2->getScheduler());
00433
00434 tt = TimerThread::Instance(bprio, 0.0123);
00435 BOOST_CHECK( tt == tt2 );
00436 }
00437 }
00438
00439 #if !defined( OROCOS_TARGET_MACOSX )
00440
00443 BOOST_AUTO_TEST_CASE( testThreadPID )
00444 {
00445 unsigned int tid = t_task_a->getPid();
00446 BOOST_CHECK( tid );
00447 unsigned int mpid = MainThread::Instance()->getPid();
00448 BOOST_CHECK( mpid );
00449 BOOST_CHECK_NE( mpid, tid );
00450
00451
00452 }
00453 #endif
00454
00455 #if !defined( OROCOS_TARGET_WIN32 )
00456 BOOST_AUTO_TEST_CASE( testThreadConfig )
00457 {
00458 int rtsched = ORO_SCHED_RT;
00459 int bprio = 15;
00460 TimerThreadPtr tt = TimerThread::Instance(bprio, 0.0123);
00461
00462
00463 BOOST_CHECK( tt->isRunning() == false );
00464
00465 BOOST_CHECK_EQUAL( 0.0123, tt->getPeriod());
00466
00467
00468 if ( os::CheckPriority( rtsched, bprio ) == true)
00469 {
00470 BOOST_CHECK_EQUAL( bprio, tt->getPriority());
00471
00472
00473 TimerThreadPtr tt2 = TimerThread::Instance(bprio - 1, 0.0123);
00474 BOOST_CHECK( tt2 != 0 );
00475 BOOST_CHECK( tt2 != tt );
00476
00477
00478 TimerThreadPtr tt3 = TimerThread::Instance(bprio, 0.123);
00479 BOOST_CHECK( tt3 != 0 );
00480 BOOST_CHECK( tt3 != tt );
00481 BOOST_CHECK( tt3 != tt2 );
00482 }
00483
00484 tt = TimerThread::Instance(bprio, 0.0123);
00485 BOOST_CHECK( tt != 0 );
00486 BOOST_CHECK( tt == TimerThread::Instance(bprio,0.0123) );
00487
00488
00489
00490 if ( tt->setScheduler(ORO_SCHED_OTHER) ) {
00491 usleep(100000);
00492 BOOST_CHECK( tt->getScheduler() == ORO_SCHED_OTHER );
00493 }
00494 if ( tt->setScheduler(ORO_SCHED_RT) ) {
00495 usleep(100000);
00496 BOOST_CHECK( tt->getScheduler() == ORO_SCHED_RT );
00497 }
00498 tt->setScheduler(ORO_SCHED_OTHER);
00499 tt->setScheduler(ORO_SCHED_RT);
00500 tt->setScheduler(ORO_SCHED_OTHER);
00501 tt->setScheduler(ORO_SCHED_RT);
00502 if ( tt->setPriority( 4 ) ) {
00503 BOOST_CHECK_EQUAL( tt->getPriority(), 4 );
00504
00505
00506
00507 BOOST_CHECK( tt == TimerThread::Instance(4,0.0123) );
00508 }
00509
00510 BOOST_CHECK( tt->start() );
00511
00512
00513 BOOST_CHECK( tt->isRunning() == true );
00514
00515
00516 Logger::LogLevel ll = Logger::log().getLogLevel();
00517 Logger::log().setLogLevel(Logger::Critical);
00518 #ifndef OROCOS_TARGET_XENOMAI // disabled until 'persistent' scheduler switching is implemented for Xenomai.
00519 if ( tt->setScheduler(ORO_SCHED_RT) ) {
00520 usleep(100000);
00521 BOOST_CHECK( tt->getScheduler() == ORO_SCHED_RT );
00522 }
00523 if ( tt->setScheduler(ORO_SCHED_OTHER) ) {
00524 usleep(100000);
00525 BOOST_CHECK( tt->getScheduler() == ORO_SCHED_OTHER );
00526 }
00527 #endif
00528 Logger::log().setLogLevel( ll );
00529
00530
00531 BOOST_CHECK( tt->setPeriod(0.5) == true );
00532
00533
00534 BOOST_CHECK( tt->stop() );
00535 BOOST_CHECK( tt->setPeriod(0.3) );
00536 BOOST_CHECK_EQUAL( Seconds_to_nsecs(0.3), tt->getPeriodNS() );
00537
00538
00539 BOOST_CHECK( tt->start() );
00540 BOOST_CHECK( tt->stop() );
00541 BOOST_CHECK( tt->start() );
00542
00543 }
00544 #endif
00545
00546 #if !defined( ORO_EMBEDDED ) && !defined( OROCOS_TARGET_WIN32 )
00547 BOOST_AUTO_TEST_CASE( testExceptionRecovery )
00548 {
00549 Logger::LogLevel ll = Logger::log().getLogLevel();
00550 Logger::log().setLogLevel( Logger::Never );
00551 BOOST_CHECK(t_task_np->start());
00552 BOOST_CHECK(t_task_np_bad->start());
00553 BOOST_CHECK(t_task_p->start());
00554 BOOST_CHECK(t_task_a->start());
00555
00556 usleep(100000);
00557
00558
00559 Logger::log().setLogLevel( ll );
00560 BOOST_CHECK( !t_task_np_bad->thread()->isRunning() );
00561
00562
00563
00564
00565 BOOST_CHECK( !t_task_np->isRunning() );
00566 BOOST_CHECK( !t_task_np_bad->isRunning() );
00567 BOOST_CHECK( t_task_p->isRunning() );
00568 BOOST_CHECK( !t_task_a->isRunning() );
00569
00570 BOOST_CHECK( t_task_np->init );
00571 BOOST_CHECK( t_task_np_bad->init );
00572 BOOST_CHECK( t_task_p->init );
00573 BOOST_CHECK( t_task_a->init );
00574
00575 BOOST_CHECK( t_task_np->stepped );
00576 BOOST_CHECK( t_task_np->wasrunning );
00577 BOOST_CHECK( t_task_np->wasactive );
00578
00579 BOOST_CHECK( t_task_np_bad->stepped );
00580 BOOST_CHECK( t_task_np_bad->wasrunning );
00581 BOOST_CHECK( t_task_np_bad->wasactive );
00582
00583 BOOST_CHECK( t_task_p->stepped );
00584 BOOST_CHECK( t_task_p->wasrunning );
00585 BOOST_CHECK( t_task_p->wasactive );
00586
00587 BOOST_CHECK( t_task_a->stepped );
00588 BOOST_CHECK( t_task_a->wasrunning );
00589 BOOST_CHECK( t_task_a->wasactive );
00590
00591
00592 BOOST_CHECK( t_task_np->fini );
00593 BOOST_CHECK( t_task_np_bad->fini );
00594 BOOST_CHECK( t_task_a->fini );
00595
00596 t_task_p->stop();
00597
00598
00599 Logger::log().setLogLevel( Logger::Never );
00600
00601 BOOST_CHECK(t_task_np->start());
00602 BOOST_CHECK(t_task_a->start());
00603
00604 usleep(100000);
00605 Logger::log().setLogLevel( ll );
00606 t_task_p->reset(true);
00607 BOOST_CHECK( t_task_np->isRunning() );
00608 BOOST_CHECK( t_task_np->init );
00609 BOOST_CHECK( t_task_np->stepped );
00610 BOOST_CHECK( t_task_np->wasrunning );
00611 BOOST_CHECK( t_task_np->wasactive );
00612
00613 BOOST_CHECK(t_task_np->stop());
00614 BOOST_CHECK( t_task_np->fini );
00615 }
00616 #endif
00617
00618 BOOST_AUTO_TEST_SUITE_END()
00619