00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 #ifndef TEST_LIST_H_
00017 #define TEST_LIST_H_
00018 #include <cppunit/extensions/HelperMacros.h>
00019 #include <cppunit/TestAssert.h>
00020 #include "baseTest.h"
00021 
00022 namespace test {
00023 
00024 using namespace amino;
00025 
00026 template<typename ListType, typename ParaType, char const* CLASS_NAME> 
00027     class ListTest: public CppUnit::TestFixture, public BaseTest<ParaType> {
00028     CPPUNIT_TEST_SUITE(ListTest);       
00029     CPPUNIT_TEST(testEmptyST);
00030         CPPUNIT_TEST(testInsertST);
00031         CPPUNIT_TEST(testPush_frontST);
00032         CPPUNIT_TEST(testRemoveST);
00033         CPPUNIT_TEST(testInsertMT);
00034         CPPUNIT_TEST(testPush_frontMT);
00035         CPPUNIT_TEST(testRemoveMT);
00036         CPPUNIT_TEST(testInsertRemoveMT);
00037         CPPUNIT_TEST_SUITE_END();
00038 private:
00039         ListType *list;
00040 
00041 public:
00042         ListTest() {
00043         }
00044 
00045         ListType * getList() {
00046                 return list;
00047         }
00048 
00049         void setUp() {
00050                 list = new ListType();
00051         }
00052 
00053         void reset() {
00054                 delete list;
00055                 list = new ListType();
00056         }
00057 
00058         void tearDown() {
00059                 delete list;
00060         }
00061 
00062         void testEmptyST();
00063         void testInsertST();
00064         void testPush_frontST();
00065         void testRemoveST();
00066         void testInsertMT();
00067         void testPush_frontMT();
00068         void testRemoveMT();
00069         void testInsertRemoveMT();
00070 };
00071 
00072 #define ThreadInsert_T ThreadInsert<ListType, ParaType, CLASS_NAME>
00073 #define ThreadRemove_T ThreadRemove<ListType, ParaType, CLASS_NAME>
00074 #define ThreadPush_front_T ThreadPush_front<ListType, ParaType, CLASS_NAME>
00075 
00076 template<typename ListType, typename ParaType, char const* CLASS_NAME> 
00077 class ThreadInsert :
00078 public TestThread<ParaType> {
00079 private:
00080         ListType *list;
00081         ListTest<ListType, ParaType, CLASS_NAME> *testcase;
00082         int elementNum;
00083         int operationNum;
00084 
00085 public:
00086 
00087         ThreadInsert(ListType *l, ListTest<ListType, ParaType, CLASS_NAME>* lt,
00088                         int nElement,int nOperation, int threadId = 0) :
00089         TestThread<ParaType>(threadId), list(l), testcase(lt), elementNum(nElement),operationNum(nOperation)
00090     {
00091         }
00092 
00093         void* run() {
00094                 for (int i = 0; i< operationNum; ++i) {
00095                                 bool ret = list->insert(0, testcase->data[i + ((this->threadId) * elementNum)]);
00096                                 if (ret) {
00097                     
00098 
00099                                         this->inVec.push_back(testcase->data[i + ((this->threadId) * elementNum)]);
00100                                 }
00101                 }
00102                 return NULL;
00103         }
00104 };
00105 
00106 template<typename ListType, typename ParaType, char const* CLASS_NAME> class ThreadPush_front :
00107 public TestThread<ParaType> {
00108 private:
00109         ListType *list;
00110         ListTest<ListType, ParaType, CLASS_NAME> *testcase;
00111         int elementNum;
00112         int operationNum;
00113 
00114 public:
00115         ThreadPush_front(ListType *l, ListTest<ListType, ParaType, CLASS_NAME>* lt,
00116                         int nElement, int nOperation, int threadId = 0) :
00117         TestThread<ParaType>(threadId), list(l), testcase(lt), elementNum(nElement),operationNum(nOperation) {
00118         }
00119 
00120         void *run() {
00121                 for (int i = 0; i < operationNum; ++i) {
00122                         if (list->push_front(testcase->data[i + ((this->threadId) * elementNum)]))
00123                         this->inVec.push_back(testcase->data[i + ((this->threadId) * elementNum)]);
00124                 }
00125                 return NULL;
00126         }
00127 };
00128 
00129 template<typename ListType, typename ParaType, char const* CLASS_NAME> class ThreadRemove :
00130 public TestThread<ParaType> {
00131 private:
00132         ListType *list;
00133         ListTest<ListType, ParaType, CLASS_NAME> *testcase;
00134         int elementNum;
00135         int operationNum;
00136 
00137 public:
00138         ThreadRemove(ListType *l, ListTest<ListType, ParaType, CLASS_NAME>* lt,
00139                         int nElement, int nOperation, int nThread = 1) :
00140         TestThread<ParaType>(nThread),list(l), testcase(lt), elementNum(nElement), operationNum(nOperation) {
00141         }
00142 
00143         void *run() {
00144                 for (int i = 0; i < operationNum; ++i) {
00145 
00146                         ParaType tmp = testcase->data[i%((this->threadId+1)*elementNum)];
00147                         if (list->remove(tmp)) {
00148                                 this->outVec.push_back(tmp);
00149                         }
00150                 }
00151 
00152                 return NULL;
00153         }
00154 };
00155 
00156 template<typename ListType, typename ParaType, char const* CLASS_NAME> 
00157 class ThreadInsertFactory : public ThreadFactory<ParaType> {
00158 private:
00159         ListType *list;
00160         ListTest<ListType, ParaType, CLASS_NAME> *testcase;
00161 public:
00162         ThreadInsertFactory(ListType * l,
00163             ListTest<ListType, ParaType, CLASS_NAME> * lt) :
00164         list(l), testcase(lt) {
00165         }
00166 
00167         virtual Runnable ** createThreads(int threadNum, int elementNum, int operationNum) {
00168                 testcase->reset();
00169                 list = testcase->getList();
00170                 this->inVec.clear();
00171                 this->outVec.clear();
00172 
00173                 Runnable ** threads;
00174                 threads = new Runnable*[threadNum];
00175                 for (int i = 0; i < threadNum; ++i)
00176             threads[i] = new ThreadInsert<ListType, ParaType, CLASS_NAME>(list, 
00177                     testcase, elementNum, operationNum, i);
00178 
00179                 return threads;
00180         }
00181 
00182         virtual void verifyResult(int threadNum, int elementNum) {
00183         
00184                 ParaType tmp;
00185                 while (!list->empty()) {
00186                         list->front(tmp);
00187                         this->outVec.push_back(tmp);
00188                         list->remove(tmp);
00189                 }
00190 
00191                 ThreadFactory<ParaType>::verifyResult(threadNum, elementNum);
00192         }
00193 };
00194 
00195 template<typename ListType, typename ParaType, char const* CLASS_NAME> class ThreadPush_frontFactory :
00196 public ThreadFactory<ParaType> {
00197 private:
00198         ListType *list;
00199         ListTest<ListType, ParaType, CLASS_NAME> *testcase;
00200 public:
00201         ThreadPush_frontFactory(ListType * l,
00202                         ListTest<ListType, ParaType, CLASS_NAME> * lt) :
00203         list(l), testcase(lt) {
00204         }
00205 
00206         virtual Runnable ** createThreads(int threadNum, int elementNum, int operationNum) {
00207                 testcase->reset();
00208                 list = testcase->getList();
00209                 this->inVec.clear();
00210                 this->outVec.clear();
00211 
00212                 Runnable ** threads;
00213                 threads = new Runnable*[threadNum];
00214                 for (int i = 0; i < threadNum; ++i)
00215             threads[i] = new ThreadPush_front<ListType, ParaType, CLASS_NAME>(list, testcase, elementNum, i);
00216 
00217                 return threads;
00218         }
00219 
00220         virtual void verifyResult(int threadNum, int elementNum) {
00221                 ParaType tmp;
00222                 while (!list->empty()) {
00223                         list->front(tmp);
00224                         this->outVec.push_back(tmp);
00225                         list->remove(tmp);
00226                 }
00227                 ThreadFactory<ParaType>::verifyResult(threadNum, elementNum);
00228         }
00229 };
00230 
00231 template<typename ListType, typename ParaType, char const* CLASS_NAME>
00232 class ThreadRemoveFactory :
00233 public ThreadFactory<ParaType> {
00234 private:
00235         ListType *list;
00236         ListTest<ListType, ParaType, CLASS_NAME> *testcase;
00237 public:
00238         ThreadRemoveFactory(ListType * l,
00239                         ListTest<ListType, ParaType, CLASS_NAME> * lt) :
00240         list(l), testcase(lt) {
00241         }
00242 
00243         virtual Runnable ** createThreads(int threadNum, int elementNum, int operationNum) {
00244                 testcase->reset();
00245                 list = testcase->getList();
00246                 this->inVec.clear();
00247                 this->outVec.clear();
00248 
00249                 for (int i = 0; i < threadNum; ++i) {
00250                         ThreadInsert_T threadInsert(list, testcase, elementNum, i);
00251                         threadInsert.run();
00252 
00253                         copy(threadInsert.inVec.begin(), threadInsert.inVec.end(),
00254                                         back_inserter(this->inVec));
00255                 }
00256 
00257                 Runnable ** threads;
00258                 threads = new Runnable*[threadNum];
00259                 for (int i = 0; i < threadNum; ++i)
00260                 threads[i] = new ThreadRemove<ListType, ParaType, CLASS_NAME>(list, testcase, elementNum,operationNum, i);
00261 
00262                 return threads;
00263         }
00264 
00265         virtual void verifyResult(int threadNum, int elementNum) {
00266                 ParaType tmp;
00267                 while (!list->empty()) {
00268                         list->front(tmp);
00269                         this->outVec.push_back(tmp);
00270                         list->remove(tmp);
00271                 }
00272 
00273                 ThreadFactory<ParaType>::verifyResult(threadNum, elementNum);
00274         }
00275 };
00276 template<typename ListType, typename ParaType, char const* CLASS_NAME> 
00277 class ThreadInsertRemoveFactory : public ThreadFactory<ParaType> {
00278 private:
00279         ListType *list;
00280         ListTest<ListType, ParaType, CLASS_NAME> *testcase;
00281 public:
00282         ThreadInsertRemoveFactory(ListType * l,
00283                         ListTest<ListType, ParaType, CLASS_NAME> * lt) :
00284         list(l), testcase(lt) {
00285         }
00286 
00287         virtual Runnable ** createThreads(int threadNum, int elementNum, int operationNum) {
00288                 testcase->reset();
00289                 list = testcase->getList();
00290                 this->inVec.clear();
00291                 this->outVec.clear();
00292 
00293                 Runnable ** threads;
00294                 threads = new Runnable*[threadNum];
00295 
00296                 for (int i = 0; i < threadNum; ++i) {
00297                         ThreadInsert_T threadInsert(list, testcase, elementNum, i);
00298                         threadInsert.run();
00299 
00300                         copy(threadInsert.inVec.begin(), threadInsert.inVec.end(),
00301                                         back_inserter(this->inVec));
00302                 }
00303 
00304                 for (int i = 0; i < threadNum; i += 2) {
00305                         threads[i] = new ThreadInsert<ListType, ParaType, CLASS_NAME>(list, testcase, 
00306                     elementNum,operationNum, i);
00307 
00308                         if (i+1 < threadNum)
00309                 threads[i+1] = new ThreadRemove<ListType, ParaType, CLASS_NAME>(list, testcase,
00310                         elementNum,operationNum, i+1);
00311                 }
00312                 return threads;
00313         }
00314 
00315         virtual void verifyResult(int threadNum, int elementNum) {
00316                 ParaType tmp;
00317                 while (!list->empty()) {
00318                         list->front(tmp);
00319                         this->outVec.push_back(tmp);
00320                         list->remove(tmp);
00321                 }
00322                 ThreadFactory<ParaType>::verifyResult(threadNum, elementNum);
00323         }
00324 };
00325 
00326 template<typename ListType, typename ParaType, char const* CLASS_NAME> void ListTest<
00327 ListType, ParaType, CLASS_NAME>::testEmptyST() {
00328         CPPUNIT_ASSERT( true == list->empty());
00329 }
00330 
00331 template<typename ListType, typename ParaType, char const* CLASS_NAME> void ListTest<
00332 ListType, ParaType, CLASS_NAME>::testInsertST() {
00333         ThreadInsert_T threadInsert(list, this, BaseTest<ParaType>::NELEMENT, BaseTest<ParaType>::NOPERATION);
00334         threadInsert.run();
00335 
00336         vector<ParaType> outVec;
00337         ParaType tmp;
00338         while (!list->empty()) {
00339                 list->front(tmp);
00340                 outVec.push_back(tmp);
00341                 list->remove(tmp);
00342         }
00343 
00344         sort(threadInsert.inVec.begin(), threadInsert.inVec.end());
00345         sort(outVec.begin(), outVec.end());
00346 
00347         CPPUNIT_ASSERT(threadInsert.inVec == outVec);
00348 }
00349 
00350 template<typename ListType, typename ParaType, char const* CLASS_NAME> void ListTest<
00351 ListType, ParaType, CLASS_NAME>::testPush_frontST() {
00352         ThreadPush_front_T threadPush_front(list, this, BaseTest<ParaType>::NELEMENT, 
00353             BaseTest<ParaType>::NOPERATION);
00354         threadPush_front.run();
00355 
00356         vector<ParaType> outVec;
00357         ParaType tmp;
00358         while (!list->empty()) {
00359                 list->front(tmp);
00360                 outVec.push_back(tmp);
00361                 list->remove(tmp);
00362         }
00363 
00364         sort(threadPush_front.inVec.begin(), threadPush_front.inVec.end());
00365         sort(outVec.begin(), outVec.end());
00366 
00367         CPPUNIT_ASSERT(threadPush_front.inVec == outVec);
00368 }
00369 
00370 template<typename ListType, typename ParaType, char const* CLASS_NAME> void ListTest<
00371 ListType, ParaType, CLASS_NAME>::testRemoveST() {
00372         ThreadPush_front_T threadPush_front(list, this, BaseTest<ParaType>::NELEMENT,
00373             BaseTest<ParaType>::NOPERATION);
00374 
00375         ThreadRemove_T threadRemove(list, this, BaseTest<ParaType>::NELEMENT,
00376             BaseTest<ParaType>::NOPERATION);
00377 
00378         threadPush_front.run();
00379         threadRemove.run();
00380 
00381         ParaType tmp;
00382         while (!list->empty()) {
00383                 list->front(tmp);
00384                 threadRemove.outVec.push_back(tmp);
00385                 list->remove(tmp);
00386         }
00387 
00388         sort(threadPush_front.inVec.begin(), threadPush_front.inVec.end());
00389         sort(threadRemove.outVec.begin(), threadRemove.outVec.end());
00390 
00391         CPPUNIT_ASSERT(threadPush_front.inVec == threadRemove.outVec);
00392 }
00393 
00394 template<typename ListType, typename ParaType, char const* CLASS_NAME> void ListTest<
00395 ListType, ParaType, CLASS_NAME>::testInsertMT() {
00396         ThreadInsertFactory<ListType, ParaType, CLASS_NAME> factory(list, this);
00397         ThreadRunner::runThreads(&factory, CLASS_NAME, "testInsertMT");
00398 }
00399 
00400 template<typename ListType, typename ParaType, char const* CLASS_NAME> void ListTest<
00401 ListType, ParaType, CLASS_NAME>::testPush_frontMT() {
00402         ThreadPush_frontFactory<ListType, ParaType, CLASS_NAME> factory(list, this);
00403         ThreadRunner::runThreads(&factory, CLASS_NAME, "testPush_frontMT");
00404 }
00405 
00406 template<typename ListType, typename ParaType, char const* CLASS_NAME> void ListTest<
00407 ListType, ParaType, CLASS_NAME>::testRemoveMT() {
00408         ThreadRemoveFactory<ListType, ParaType, CLASS_NAME> factory(list, this);
00409         ThreadRunner::runThreads(&factory, CLASS_NAME, "testRemoveMT");
00410 }
00411 
00412 template<typename ListType, typename ParaType, char const* CLASS_NAME> void ListTest<
00413 ListType, ParaType, CLASS_NAME>::testInsertRemoveMT() {
00414         ThreadInsertRemoveFactory<ListType, ParaType, CLASS_NAME>
00415         factory(list, this);
00416         ThreadRunner::runThreads(&factory, CLASS_NAME, "testInsertRemoveMT");
00417 }
00418 
00419 }
00420 #endif