00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef TEST_EXECUTOR_H_
00024 #define TEST_EXECUTOR_H_
00025 #include <cppunit/extensions/HelperMacros.h>
00026 #include <cppunit/TestAssert.h>
00027 #include "baseTest.h"
00028
00029 #include <amino/cstdatomic>
00030 #include <amino/thread.h>
00031
00032 #include <iostream>
00033 #include <assert.h>
00034 #include <unistd.h>
00035
00036 namespace test{
00037 using namespace amino;
00038
00039 class DoNothing:public Runnable{
00040 public:
00041 void* run(){
00042 cout<<"Executed in an executor!"<<endl;
00043 return NULL;
00044 }
00045 };
00046
00047 const int ACCU_COUNT=1000;
00048
00049 class Accumulate:public Runnable{
00050 private:
00051 atomic<int> * count;
00052 public:
00053 Accumulate(atomic<int> * arg){
00054 count = arg;
00055 }
00056
00057 void* run(){
00058 for(int i=0;i<ACCU_COUNT;i++)
00059 (*count)++;
00060 return NULL;
00061 }
00062 };
00063
00064 class Wait6S:public Runnable{
00065 public:
00066 void* run(){
00067 cout<<"Begin wait 6S\n";
00068 sleep(6);
00069 cout<<"End wait 6S\n";
00070 cout<<flush;
00071 return NULL;
00072 }
00073 };
00074
00075 template<typename Executor>
00076 class CallExecutor{
00077 private:
00078 Executor* exec;
00079 Wait6S * waiter;
00080 public:
00081 CallExecutor(Executor * executor, Wait6S * w6s){
00082 exec = executor;
00083 waiter = w6s;
00084 }
00085
00086 void operator()(){
00087 exec->execute(waiter);
00088 }
00089 };
00090
00091 template<typename Executor>
00092 class ExecutorTest :
00093 public CppUnit::TestFixture, public BaseTest<int> {
00094 CPPUNIT_TEST_SUITE(ExecutorTest);
00095
00096
00097 CPPUNIT_TEST(testTimedWait);
00098
00099
00100 CPPUNIT_TEST_SUITE_END();
00101
00102 public:
00103 ExecutorTest() {
00104 }
00105
00106 void setUp() {
00107 }
00108
00109 void reset() {
00110 }
00111
00112 void tearDown() {
00113 }
00114
00115 void testExecuteOne(){
00116 Executor executor;
00117 DoNothing done;
00118 executor.execute(&done);
00119 executor.shutdown();
00120 executor.waitTermination();
00121 }
00122
00123 void testAccumulate(){
00124 Executor executor;
00125 atomic<int> sum;
00126 sum = 0;
00127 Accumulate do1(&sum), do2(&sum);
00128 executor.execute(&do1);
00129 executor.execute(&do2);
00130 executor.shutdown();
00131 executor.waitTermination();
00132
00133 CPPUNIT_ASSERT(sum.load()==2*ACCU_COUNT);
00134 }
00135
00136 void testAccumulateMassive(){
00137 const int TASK_COUNT=200;
00138
00139 Executor executor;
00140 atomic<int> sum;
00141 sum = 0;
00142
00143 Accumulate * ppAcc[TASK_COUNT];
00144 for(int i=0;i<TASK_COUNT;i++){
00145 ppAcc[i] = new Accumulate(&sum);
00146 }
00147
00148 for(int i=0;i<TASK_COUNT;i++){
00149 executor.execute(ppAcc[i]);
00150 }
00151 executor.shutdown();
00152 executor.waitTermination();
00153
00154 CPPUNIT_ASSERT(sum.load()==ACCU_COUNT*TASK_COUNT);
00155 }
00156
00157 void testShutdown(){
00158 Executor executor;
00159 executor.shutdown();
00160 DoNothing done;
00161 try{
00162 executor.execute(&done);
00163 }catch(std::logic_error e){
00164 executor.waitTermination();
00165 return;
00166 }
00167 CPPUNIT_ASSERT(false);
00168 }
00169
00170 void testTimedWait(){
00171 Executor executor;
00172 Wait6S waiter;
00173 CallExecutor<Executor> *ce = new CallExecutor<Executor>(
00174 &executor, &waiter);
00175 Thread tmpThr(*ce);
00176 sleep(2);
00177 executor.shutdown();
00178 bool res;
00179 res = executor.waitTermination(2000);
00180 if(res){
00181 executor.waitTermination();
00182 CPPUNIT_ASSERT_MESSAGE("Executor finished before 6S!\n", res);
00183 }
00184
00185 res = executor.waitTermination(18000);
00186 if(!res){
00187 executor.waitTermination();
00188 CPPUNIT_ASSERT_MESSAGE("Executor is not finished after 10S\n", res);
00189 }
00190
00191 delete ce;
00192 }
00193 };
00194 }
00195 #endif