ConditionTests.cpp
Go to the documentation of this file.
00001 // -*- C++ -*-
00012 /*
00013  * $Log$
00014  *
00015  */
00016 
00017 #ifndef Condition_cpp
00018 #define Condition_cpp
00019 
00020 #include <cppunit/ui/text/TestRunner.h>
00021 #include <cppunit/TextOutputter.h>
00022 #include <cppunit/extensions/TestFactoryRegistry.h>
00023 #include <cppunit/extensions/HelperMacros.h>
00024 #include <cppunit/TestAssert.h>
00025 
00026 #include <coil/Condition.h>
00027 #include <coil/Mutex.h>
00028 #include <coil/Guard.h>
00029 #include <coil/Task.h>
00030 #include <coil/Async.h>
00031 #include <coil/Time.h>
00032 #include <coil/TimeValue.h>
00033 
00034 typedef coil::Guard<coil::Mutex> Guard;
00035 
00036 class A
00037 {
00038 public:
00039   A(coil::Condition<coil::Mutex>& cond, coil::Mutex& mutex)
00040     : m_cond(cond), m_mutex(mutex) {}
00041   void signal(int usec)
00042   {
00043     coil::usleep(usec);
00044     m_mutex.lock();
00045     m_cond.signal();
00046     m_mutex.unlock();
00047   }
00048   coil::Condition<coil::Mutex>& m_cond;
00049   coil::Mutex& m_mutex;
00050 };
00051 
00056 namespace Condition
00057 {
00058 
00062   class ConditionCheckTask : public coil::Task
00063   {
00064   public:
00065     ConditionCheckTask() : id(0) { }
00066     ConditionCheckTask(coil::Mutex & aMutex,
00067                        coil::Condition<coil::Mutex> & aCondition, int anId)
00068       : mutex(&aMutex), cond(&aCondition), id(anId)
00069     {
00070       //        std::cout << "Task(" << id << ") created." << std::endl;
00071     }
00072 
00073     virtual ~ConditionCheckTask()
00074     {
00075     };
00076 
00077     virtual int svc()
00078     {
00079       Guard guard(*mutex);
00080       //      mutex->lock();
00081       cond->wait();
00082       ConditionStatus += id;
00083       //      mutex->unlock();
00084       return ConditionStatus;
00085     }
00089     static void resteStatus() { ConditionStatus =  0; }
00093     static int getStatus() { return ConditionStatus; }
00094   private:
00095 //    static int status;  // <- undefined reference
00096     coil::Mutex * mutex;
00097     coil::Condition<coil::Mutex> * cond;
00098     int id;
00099     static int ConditionStatus;
00100   };  // class ConditionCheckTask
00101 
00102   int ConditionCheckTask::ConditionStatus(0);
00103 
00104   
00105   class ConditionTests
00106    : public CppUnit::TestFixture
00107   {
00108     CPPUNIT_TEST_SUITE(ConditionTests);
00109     CPPUNIT_TEST(test_Condition_wait_and_signal);
00110     CPPUNIT_TEST(test_Condition_wait_and_broadcast);
00111     CPPUNIT_TEST(test_Condition_wait_with_time);
00112     CPPUNIT_TEST_SUITE_END();
00113   
00114   private:
00115     coil::Mutex * mu;
00116 
00117   public:
00121     ConditionTests()
00122     {
00123     }
00124     
00128     ~ConditionTests()
00129     {
00130     }
00131  
00132                 
00136     virtual void setUp()
00137     {
00138       mu = new coil::Mutex;
00139     }
00140     
00144     virtual void tearDown()
00145     { 
00146       delete mu;
00147     }
00148   
00149     /* test case */
00150 
00154     void test_Condition_wait_and_signal()
00155     {
00156       coil::Mutex mu1;
00157       coil::Condition<coil::Mutex> cond1(mu1);
00158       coil::Mutex mu2;
00159       coil::Condition<coil::Mutex> cond2(mu2);
00160       int id1(0x02);
00161       int id2(0x08);
00162 
00163       ConditionCheckTask::resteStatus();
00164       ConditionCheckTask cct1(mu1, cond1, id1);
00165       ConditionCheckTask cct2(mu1, cond1, id2);
00166 
00167       cct1.activate();
00168       cct2.activate();
00169 
00170       coil::usleep(10000); // give cpu time to tasks
00171 
00172       CPPUNIT_ASSERT_EQUAL(0x00, ConditionCheckTask::getStatus());
00173 
00174       {
00175         Guard guard(mu1);
00176         //      mu1.lock();
00177         cond1.signal();
00178         //        mu1.unlock();
00179       }
00180 
00181       coil::usleep(10000); // give cpu time to tasks
00182 
00183       CPPUNIT_ASSERT_EQUAL(id1, ConditionCheckTask::getStatus());
00184 
00185       {
00186         Guard guard(mu1);
00187         //        mu1.lock();
00188         cond1.signal();
00189         //      mu1.unlock();
00190       }
00191 
00192       coil::usleep(10000); // give cpu time to tasks
00193 
00194       CPPUNIT_ASSERT_EQUAL(id1 + id2, ConditionCheckTask::getStatus());
00195 
00196       //      cct1.wait();
00197       //      cct2.wait();
00198     }
00199 
00203     void test_Condition_wait_and_broadcast()
00204     {
00205       coil::Condition<coil::Mutex> cd(*mu);
00206       coil::Mutex mu2;
00207       coil::Condition<coil::Mutex> cond2(mu2);
00208 
00209       ConditionCheckTask::resteStatus();
00210       ConditionCheckTask cct6(*mu, cd, 0x20);
00211       ConditionCheckTask cct5(*mu, cd, 0x10);
00212       ConditionCheckTask cct4(*mu, cd, 0x08);
00213       ConditionCheckTask cct3(*mu, cd, 0x04);
00214       ConditionCheckTask cct2(*mu, cd, 0x02);
00215       ConditionCheckTask cct1(*mu, cd, 0x01);
00216 
00217       cct6.activate();
00218       cct5.activate();
00219       cct4.activate();
00220       cct3.activate();
00221       cct2.activate();
00222       cct1.activate();
00223 
00224       CPPUNIT_ASSERT_EQUAL(0, ConditionCheckTask::getStatus());
00225 
00226       {
00227         Guard guard(mu2);
00228         // mu2.lock();
00229         cond2.wait(1);
00230         // mu2.unlock();
00231       }
00232 
00233       {
00234         Guard guard(*mu);
00235         // mu->lock();
00236         cd.broadcast();
00237         // mu->unlock();
00238       }
00239 
00240       {
00241         Guard guard(mu2);
00242         // mu2.lock();
00243         cond2.wait(1);
00244         // mu2.unlock();
00245       }
00246 
00247       CPPUNIT_ASSERT_EQUAL(0x3f, ConditionCheckTask::getStatus());
00248 
00249       CPPUNIT_ASSERT(true);
00250     }
00251   
00255     void test_Condition_wait_with_time()
00256     {
00257       int waitSec(2);
00258       coil::Condition<coil::Mutex> cd(*mu);
00259       //      std::cout << "Before wait " << waitSec << " sec." << std::endl << std::flush;
00260       bool result;
00261       {
00262         Guard guard(*mu);
00263         // mu->lock();
00264         result = cd.wait(waitSec);
00265         // mu->unlock();
00266       }
00267 
00268       // result = false (timeout)
00269       //      if (result) { std::cout << "signaled..ERROR" << std::endl; }
00270       //      else        { std::cout << "timeout...OK" << std::endl;  }
00271       CPPUNIT_ASSERT(!result);
00272 
00273 
00274       A a(cd, *mu);
00275       coil::Async*
00276         invoker(coil::AsyncInvoker(&a,
00277                                    std::bind2nd(std::mem_fun(&A::signal),
00278                                                 1000000)));
00279       invoker->invoke();
00280       {
00281         Guard guard(*mu);
00282         // mu->lock();
00283         result = cd.wait(waitSec);
00284         // mu->unlock();
00285       }
00286       invoker->wait();
00287 
00288       // result = true (signal)
00289       //      if (result) { std::cout << "signaled..OK" << std::endl; }
00290       //      else        { std::cout << "timeout...ERROR" << std::endl;  }
00291       CPPUNIT_ASSERT(result);
00292     }
00293 
00294   };
00295 }; // namespace Condition
00296 
00297 /*
00298  * Register test suite
00299  */
00300 CPPUNIT_TEST_SUITE_REGISTRATION(Condition::ConditionTests);
00301 
00302 #ifdef LOCAL_MAIN
00303 int main(int argc, char* argv[])
00304 {
00305     CppUnit::TextUi::TestRunner runner;
00306     runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
00307     CppUnit::Outputter* outputter = 
00308       new CppUnit::TextOutputter(&runner.result(), std::cout);
00309     runner.setOutputter(outputter);
00310     bool retcode = runner.run();
00311     return !retcode;
00312 }
00313 #endif // MAIN
00314 #endif // Condition_cpp


openrtm_aist
Author(s): Noriaki Ando
autogenerated on Sat Jun 8 2019 18:49:03