Go to the documentation of this file.00001
00012
00013
00014
00015
00016
00017 #ifndef PeriodicTask_cpp
00018 #define PeriodicTask_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/Time.h>
00027 #include <coil/PeriodicTask.h>
00028
00029 #include <sstream>
00030 #include <math.h>
00031
00032 class Logger
00033 {
00034 public:
00035 void log(const std::string& msg)
00036 {
00037 m_log.push_back(msg);
00038 }
00039
00040 int countLog(const std::string& msg)
00041 {
00042 int count = 0;
00043 for (int i = 0; i < (int) m_log.size(); ++i)
00044 {
00045 if (m_log[i] == msg) ++count;
00046 }
00047 return count;
00048 }
00049
00050 void clearLog()
00051 {
00052 m_log.clear();
00053 }
00054 private:
00055 std::vector<std::string> m_log;
00056 };
00057
00058 class A
00059 {
00060 public:
00061 int mysvc()
00062 {
00063 static int cnt;
00064 std::cout << "mysvc(): " << cnt << std::endl;
00065 ++cnt;
00066 coil::sleep(coil::TimeValue(0, 10000));
00067 return 0;
00068 }
00069
00070 int mysvc2()
00071 {
00072 if (m_logger != NULL)
00073 {
00074 m_logger->log("mysvc2");
00075 }
00076 return 0;
00077 }
00078
00079 int mysvc3()
00080 {
00081 if (m_logger != NULL)
00082 {
00083 m_logger->log("mysvc3");
00084 }
00085
00086
00087 coil::usleep(30000);
00088 return 0;
00089 }
00090
00091 static void setLogger(Logger* logger)
00092 {
00093 m_logger = logger;
00094 }
00095
00096 private:
00097 static Logger* m_logger;
00098 };
00099 Logger* A::m_logger = NULL;
00100
00105 namespace PeriodicTask
00106 {
00107 class PeriodicTaskTests
00108 : public CppUnit::TestFixture
00109 {
00110 CPPUNIT_TEST_SUITE(PeriodicTaskTests);
00111
00112 CPPUNIT_TEST(test_setTask);
00113 CPPUNIT_TEST(test_setPeriodic);
00114 CPPUNIT_TEST(test_signal);
00115 CPPUNIT_TEST(test_executionMeasure);
00116 CPPUNIT_TEST(test_periodicMeasure);
00117 CPPUNIT_TEST_SUITE_END();
00118
00119 private:
00120
00121 public:
00122
00126 PeriodicTaskTests()
00127 {
00128 }
00129
00133 ~PeriodicTaskTests()
00134 {
00135 }
00136
00140 virtual void setUp()
00141 {
00142 }
00143
00147 virtual void tearDown()
00148 {
00149 }
00150
00151
00152 void test_case0()
00153 {
00154 A a;
00155 coil::PeriodicTask p;
00156 p.setTask(&a, &A::mysvc);
00157 p.setPeriod(0.05);
00158 p.executionMeasure(true);
00159 p.executionMeasureCount(1);
00160 p.periodicMeasure(true);
00161 p.periodicMeasureCount(1);
00162 p.activate();
00163
00164 for (int i(0); i < 10; ++i)
00165 {
00166 coil::sleep(1);
00167 std::cout << "i: " << i << std::endl;
00168 coil::TimeMeasure::Statistics estat = p.getExecStat();
00169 coil::TimeMeasure::Statistics pstat = p.getPeriodStat();
00170
00171 std::cout << "estat max: " << estat.max_interval << std::endl;
00172 std::cout << "estat min: " << estat.min_interval << std::endl;
00173 std::cout << "estat mean: " << estat.mean_interval << std::endl;
00174 std::cout << "estat sdev: " << estat.std_deviation << std::endl;
00175
00176 std::cout << "pstat max: " << pstat.max_interval << std::endl;
00177 std::cout << "pstat min: " << pstat.min_interval << std::endl;
00178 std::cout << "pstat mean: " << pstat.mean_interval << std::endl;
00179 std::cout << "pstat sdev: " << pstat.std_deviation << std::endl;
00180
00181 if (i == 1)
00182 {
00183 p.suspend();
00184 std::cout << "suspended: " << i << std::endl;
00185 }
00186 else if (i == 5)
00187 {
00188 p.resume();
00189 std::cout << "resumed: " << i << std::endl;
00190 }
00191 else if (i == 3)
00192 {
00193 std::cout << "signal: " << i << std::endl;
00194 p.signal();
00195 coil::usleep(200000);
00196 p.signal();
00197 coil::usleep(200000);
00198 }
00199
00200 }
00201
00202 p.finalize();
00203
00204
00205
00206 }
00211 void test_setTask()
00212 {
00213
00214 A a;
00215 coil::PeriodicTask p;
00216 CPPUNIT_ASSERT(p.setTask(&a, &A::mysvc2));
00217
00218 Logger logger;
00219 a.setLogger(&logger);
00220
00221 CPPUNIT_ASSERT_EQUAL(0, logger.countLog("mysvc2"));
00222 p.activate();
00223 coil::usleep(5);
00224 p.finalize();
00225 coil::usleep(5);
00226 CPPUNIT_ASSERT(1<logger.countLog("mysvc2"));
00227
00228
00229 }
00234 void test_setPeriodic()
00235 {
00236 std::ostringstream ss;
00237 A a;
00238 coil::PeriodicTask p;
00239
00240 Logger logger;
00241 a.setLogger(&logger);
00242
00243 p.setTask(&a, &A::mysvc2);
00244 p.setPeriod(0.05);
00245
00246 CPPUNIT_ASSERT_EQUAL(0, logger.countLog("mysvc2"));
00247 p.activate();
00248 coil::usleep(100000);
00249 p.suspend();
00250 coil::usleep(50000);
00251
00252
00253 CPPUNIT_ASSERT(4>logger.countLog("mysvc2"));
00254 CPPUNIT_ASSERT(0<logger.countLog("mysvc2"));
00255
00256 logger.clearLog();
00257
00258 p.setPeriod(0.01);
00259 CPPUNIT_ASSERT_EQUAL(0, logger.countLog("mysvc2"));
00260 p.resume();
00261 coil::usleep(100000);
00262 p.suspend();
00263 coil::usleep(10000);
00264
00265 CPPUNIT_ASSERT(12>logger.countLog("mysvc2"));
00266 CPPUNIT_ASSERT(8<logger.countLog("mysvc2"));
00267
00268 logger.clearLog();
00269
00270 coil::TimeValue tm(0,50000);
00271 p.setPeriod(tm);
00272 CPPUNIT_ASSERT_EQUAL(0, logger.countLog("mysvc2"));
00273 p.resume();
00274 coil::usleep(100000);
00275 p.finalize();
00276 coil::usleep(50000);
00277
00278 CPPUNIT_ASSERT(4>logger.countLog("mysvc2"));
00279 CPPUNIT_ASSERT(0<logger.countLog("mysvc2"));
00280
00281 }
00286 void test_signal()
00287 {
00288 A a;
00289 coil::PeriodicTask p;
00290
00291 Logger logger;
00292 a.setLogger(&logger);
00293
00294 p.setTask(&a, &A::mysvc2);
00295 p.setPeriod(0.05);
00296
00297 CPPUNIT_ASSERT_EQUAL(0, logger.countLog("mysvc2"));
00298 p.activate();
00299 coil::usleep(200000);
00300 p.suspend();
00301
00302 int count;
00303 count = logger.countLog("mysvc2");
00304 coil::usleep(200000);
00305 CPPUNIT_ASSERT(count == logger.countLog("mysvc2"));
00306
00307 p.signal();
00308 coil::usleep(200000);
00309 CPPUNIT_ASSERT(count+1 == logger.countLog("mysvc2"));
00310 p.signal();
00311 coil::usleep(200000);
00312 CPPUNIT_ASSERT(count+2 == logger.countLog("mysvc2"));
00313
00314 logger.clearLog();
00315 p.resume();
00316 coil::usleep(200000);
00317 p.suspend();
00318 coil::usleep(200000);
00319 CPPUNIT_ASSERT(6>logger.countLog("mysvc2"));
00320 CPPUNIT_ASSERT(2<logger.countLog("mysvc2"));
00321
00322 p.finalize();
00323 coil::usleep(200000);
00324
00325 }
00330 void test_executionMeasure()
00331 {
00332 std::cout<<"IN test_executionMeasure()"<<std::endl;
00333 const double wait(0.03);
00334 A a;
00335 coil::PeriodicTask p;
00336 p.setTask(&a, &A::mysvc3);
00337
00338 Logger logger;
00339 a.setLogger(&logger);
00340
00341 p.setPeriod(0.05);
00342 p.executionMeasure(true);
00343
00344
00345 p.activate();
00346
00347 coil::usleep(600000);
00348
00349 p.suspend();
00350 coil::usleep(50000);
00351 coil::TimeMeasure::Statistics estat = p.getExecStat();
00352
00353
00354
00355
00356
00357
00358 std::ostringstream ss;
00359 ss << "wait: " << wait << std::endl;
00360 ss << "estat max: " << estat.max_interval << std::endl;
00361 ss << "estat min: " << estat.min_interval << std::endl;
00362 ss << "estat mean: " << estat.mean_interval << std::endl;
00363 ss << "estat sdev: " << estat.std_deviation << std::endl;
00364
00365 CPPUNIT_ASSERT_MESSAGE(ss.str(),estat.max_interval < (wait + 0.030));
00366 CPPUNIT_ASSERT_MESSAGE(ss.str(),estat.min_interval > (wait - 0.015));
00367 CPPUNIT_ASSERT_MESSAGE(ss.str(),fabs(estat.mean_interval - wait) < 0.03);
00368 CPPUNIT_ASSERT_MESSAGE(ss.str(),estat.std_deviation < (wait / 5.0));
00369
00370
00371
00372
00373 p.executionMeasureCount(5);
00374 p.resume();
00375 coil::usleep(300000);
00376 p.suspend();
00377 coil::usleep(50000);
00378 estat = p.getExecStat();
00379
00380
00381
00382
00383
00384
00385 ss.str("");;
00386 ss << "wait: " << wait << std::endl;
00387 ss << "estat max: " << estat.max_interval << std::endl;
00388 ss << "estat min: " << estat.min_interval << std::endl;
00389 ss << "estat mean: " << estat.mean_interval << std::endl;
00390 ss << "estat sdev: " << estat.std_deviation << std::endl;
00391
00392 CPPUNIT_ASSERT_MESSAGE(ss.str(),estat.max_interval < (wait + 0.030));
00393 CPPUNIT_ASSERT_MESSAGE(ss.str(),estat.min_interval > (wait - 0.015));
00394 CPPUNIT_ASSERT_MESSAGE(ss.str(),fabs(estat.mean_interval - wait) < 0.03);
00395 CPPUNIT_ASSERT_MESSAGE(ss.str(),estat.std_deviation < (wait / 5.0));
00396
00397
00398 p.executionMeasureCount(10);
00399 p.resume();
00400 coil::usleep(300000);
00401 p.suspend();
00402 coil::usleep(50000);
00403 p.finalize();
00404 coil::TimeMeasure::Statistics estat2 = p.getExecStat();
00405
00406 CPPUNIT_ASSERT(estat.max_interval == estat2.max_interval);
00407 CPPUNIT_ASSERT(estat.min_interval == estat2.min_interval);
00408 CPPUNIT_ASSERT(estat.mean_interval == estat2.mean_interval);
00409 CPPUNIT_ASSERT(estat.std_deviation == estat2.std_deviation);
00410 }
00415 void test_periodicMeasure()
00416 {
00417 std::cout<<"IN test_periodicMeasure()"<<std::endl;
00418 const double wait(0.05);
00419 A a;
00420 coil::PeriodicTask p;
00421 p.setTask(&a, &A::mysvc3);
00422
00423 Logger logger;
00424 a.setLogger(&logger);
00425
00426 p.setPeriod(0.05);
00427 p.periodicMeasure(true);
00428
00429
00430 p.activate();
00431
00432 coil::usleep(600000);
00433
00434 p.suspend();
00435 coil::usleep(50000);
00436 coil::TimeMeasure::Statistics pstat = p.getPeriodStat();
00437
00438
00439
00440
00441
00442
00443 CPPUNIT_ASSERT(pstat.max_interval < (wait + 0.030));
00444 CPPUNIT_ASSERT(pstat.min_interval > (wait - 0.010));
00445 CPPUNIT_ASSERT(fabs(pstat.mean_interval - wait) < 0.03);
00446 CPPUNIT_ASSERT(pstat.std_deviation < (wait / 5.0));
00447
00448
00449
00450
00451 p.periodicMeasureCount(5);
00452 p.resume();
00453 coil::usleep(300000);
00454 p.suspend();
00455 coil::usleep(50000);
00456 pstat = p.getPeriodStat();
00457
00458
00459
00460
00461
00462
00463 CPPUNIT_ASSERT(pstat.max_interval < (wait + 0.030));
00464 CPPUNIT_ASSERT(pstat.min_interval > (wait - 0.010));
00465 CPPUNIT_ASSERT(fabs(pstat.mean_interval - wait) < 0.03);
00466 CPPUNIT_ASSERT(pstat.std_deviation < (wait / 5.0));
00467
00468
00469
00470 p.periodicMeasureCount(10);
00471 p.resume();
00472 coil::usleep(300000);
00473 p.suspend();
00474 coil::usleep(50000);
00475 p.finalize();
00476 coil::TimeMeasure::Statistics pstat2 = p.getPeriodStat();
00477
00478 CPPUNIT_ASSERT(pstat.max_interval == pstat2.max_interval);
00479 CPPUNIT_ASSERT(pstat.min_interval == pstat2.min_interval);
00480 CPPUNIT_ASSERT(pstat.mean_interval == pstat2.mean_interval);
00481 CPPUNIT_ASSERT(pstat.std_deviation == pstat2.std_deviation);
00482 }
00483 };
00484 };
00485
00486
00487
00488
00489 CPPUNIT_TEST_SUITE_REGISTRATION(PeriodicTask::PeriodicTaskTests);
00490
00491 #ifdef LOCAL_MAIN
00492 int main(int argc, char* argv[])
00493 {
00494 CppUnit::TextUi::TestRunner runner;
00495 runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
00496 CppUnit::Outputter* outputter =
00497 new CppUnit::TextOutputter(&runner.result(), std::cout);
00498 runner.setOutputter(outputter);
00499 bool retcode = runner.run();
00500 return !retcode;
00501 }
00502 #endif // MAIN
00503 #endif // PeriodicTask_cpp