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