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 template<typename SetType, typename ParaType, char const* CLASS_NAME>
00026 class SetTest: public CppUnit::TestFixture, public BaseTest<ParaType> {
00027
00028 CPPUNIT_TEST_SUITE(SetTest)
00029 ; CPPUNIT_TEST(testEmptyST);
00030 CPPUNIT_TEST(testInsertST);
00031 CPPUNIT_TEST(testRemoveST);
00032 CPPUNIT_TEST(testInsertMT);
00033 CPPUNIT_TEST(testRemoveMT);
00034 CPPUNIT_TEST(testInsertRemoveMT);
00035 CPPUNIT_TEST_SUITE_END();
00036 private:
00037 SetType *set;
00038
00039 public:
00040 SetTest() {
00041 }
00042
00043 SetType * getSet() {
00044 return set;
00045 }
00046
00047 void setUp() {
00048 set = new SetType();
00049 }
00050
00051 void reset() {
00052 delete set;
00053 set = new SetType();
00054 }
00055
00056 void tearDown() {
00057 delete set;
00058 }
00059
00060 void testEmptyST();
00061 void testInsertST();
00062 void testRemoveST();
00063 void testInsertMT();
00064 void testRemoveMT();
00065 void testInsertRemoveMT();
00066 };
00067
00068 #define ThreadInsert_T ThreadInsert<SetType, ParaType, CLASS_NAME>
00069 #define ThreadRemove_T ThreadRemove<SetType, ParaType, CLASS_NAME>
00070
00071 template<typename SetType, typename ParaType, char const* CLASS_NAME> class ThreadInsert :
00072 public TestThread<ParaType> {
00073 private:
00074 SetType *set;
00075 SetTest<SetType, ParaType, CLASS_NAME> *testcase;
00076 int elementNum;
00077 int operationNum;
00078
00079 public:
00080
00081 ThreadInsert(SetType *s, SetTest<SetType, ParaType, CLASS_NAME>* st,
00082 int nElement, int nOperation, int threadId = 0) :
00083 TestThread<ParaType>(threadId), set(s), testcase(st), elementNum(nElement),operationNum(nOperation) {
00084 }
00085
00086 void* run() {
00087 for (int i = 0; i< operationNum; ++i) {
00088 if (set->insert(testcase->data[i%((this->threadId+1)*elementNum)]))
00089 this->inVec.push_back(testcase->data[i%((this->threadId+1)*elementNum)]);
00090 }
00091 return NULL;
00092 }
00093 };
00094
00095 template<typename SetType, typename ParaType, char const* CLASS_NAME> class ThreadRemove :
00096 public TestThread<ParaType> {
00097 private:
00098 SetType *set;
00099 SetTest<SetType, ParaType, CLASS_NAME> *testcase;
00100 int elementNum;
00101 int operationNum;
00102 public:
00103 ThreadRemove(SetType *s, SetTest<SetType, ParaType, CLASS_NAME>* st,
00104 int nElement, int nOperation, int nThread = 1) :TestThread<ParaType>(nThread),
00105 set(s), testcase(st), elementNum(nElement), operationNum(nOperation) {
00106 }
00107
00108 void *run() {
00109 for (int i = 0; i< operationNum; ++i) {
00110 ParaType tmp = testcase->data[i%((this->threadId+1)*elementNum)];
00111 if (set->remove(tmp)) {
00112 this->outVec.push_back(tmp);
00113 }
00114 }
00115
00116 return NULL;
00117 }
00118 };
00119
00120 template<typename SetType, typename ParaType, char const* CLASS_NAME> class ThreadInsertFactory :
00121 public ThreadFactory<ParaType> {
00122 private:
00123 SetType *set;
00124 SetTest<SetType, ParaType, CLASS_NAME> *testcase;
00125 public:
00126 ThreadInsertFactory(SetType * s,
00127 SetTest<SetType, ParaType, CLASS_NAME> * st) :
00128 set(s), testcase(st) {
00129 }
00130
00131 virtual Runnable ** createThreads(int threadNum, int elementNum, int operationNum) {
00132 testcase->reset();
00133 set = testcase->getSet();
00134 this->inVec.clear();
00135 this->outVec.clear();
00136
00137 Runnable ** threads;
00138 threads = new Runnable*[threadNum];
00139 for (int i = 0; i < threadNum; ++i)
00140 threads[i] = new ThreadInsert<SetType, ParaType, CLASS_NAME>(set, testcase, elementNum,operationNum, i);
00141
00142 return threads;
00143 }
00144
00145 virtual void verifyResult(int threadNum, int elementNum) {
00146 CPPUNIT_ASSERT(this->inVec.size() == set->size());
00147
00148 vector<ParaType> vec(this->inVec);
00149
00150 bool result = true;
00151 while(!(this->inVec.empty())) {
00152 if(set->search(this->inVec.back())) {
00153 this->inVec.pop_back();
00154 }
00155 else {
00156 result = false;
00157 break;
00158 }
00159 }
00160 CPPUNIT_ASSERT(result);
00161 }
00162 };
00163
00164 template<typename SetType, typename ParaType, char const* CLASS_NAME> class ThreadRemoveFactory :
00165 public ThreadFactory<ParaType> {
00166 private:
00167 SetType *set;
00168 SetTest<SetType, ParaType, CLASS_NAME> *testcase;
00169 public:
00170 ThreadRemoveFactory(SetType * s,
00171 SetTest<SetType, ParaType, CLASS_NAME> * st) :
00172 set(s), testcase(st) {
00173 }
00174
00175 virtual Runnable ** createThreads(int threadNum, int elementNum, int operationNum) {
00176 testcase->reset();
00177 set = testcase->getSet();
00178 this->inVec.clear();
00179 this->outVec.clear();
00180
00181 for (int i = 0; i < threadNum; ++i) {
00182 ThreadInsert_T threadInsert(set, testcase, elementNum, i);
00183 threadInsert.run();
00184
00185 copy(threadInsert.inVec.begin(), threadInsert.inVec.end(),
00186 back_inserter(this->inVec));
00187 }
00188
00189 Runnable ** threads;
00190 threads = new Runnable*[threadNum];
00191 for (int i = 0; i < threadNum; ++i)
00192 threads[i] = new ThreadRemove<SetType, ParaType, CLASS_NAME>(set, testcase, elementNum,operationNum, i);
00193
00194 return threads;
00195 }
00196
00197 virtual void verifyResult(int threadNum, int elementNum) {
00198 CPPUNIT_ASSERT(this->inVec.size() == this->outVec.size() + set->size());
00199
00200 bool result = true;
00201
00202 typename vector<ParaType>::iterator iter = this->outVec.begin();
00203 for(; iter != this->outVec.end(); ++iter) {
00204 typename vector<ParaType>::iterator itFound = find(this->inVec.begin(),this->inVec.end(),*iter);
00205 if(itFound != this->inVec.end())
00206 this->inVec.erase(itFound);
00207 }
00208
00209 while(!this->outVec.empty()) {
00210 if(set->search(this->outVec.back())) {
00211 result = false;
00212 break;
00213 }
00214 this->outVec.pop_back();
00215 }
00216
00217 CPPUNIT_ASSERT(result);
00218 while(!this->inVec.empty()) {
00219 if(set->search(this->inVec.back())) {
00220 this->inVec.pop_back();
00221 }
00222 else {
00223 result = false;
00224 break;
00225 }
00226 }
00227 CPPUNIT_ASSERT(result);
00228 }
00229 };
00230 template<typename SetType, typename ParaType, char const* CLASS_NAME> class ThreadInsertRemoveFactory :
00231 public ThreadFactory<ParaType> {
00232 private:
00233 SetType *set;
00234 SetTest<SetType, ParaType, CLASS_NAME> *testcase;
00235 public:
00236 ThreadInsertRemoveFactory(SetType * s,
00237 SetTest<SetType, ParaType, CLASS_NAME> * st) :
00238 set(s), testcase(st) {
00239 }
00240
00241 virtual Runnable ** createThreads(int threadNum, int elementNum, int operationNum) {
00242 testcase->reset();
00243 set = testcase->getSet();
00244 this->inVec.clear();
00245 this->outVec.clear();
00246
00247 Runnable ** threads;
00248 threads = new Runnable*[threadNum];
00249
00250 for (int i = 0; i < threadNum; ++i) {
00251 ThreadInsert_T threadInsert(set, testcase, elementNum, i);
00252 threadInsert.run();
00253
00254 copy(threadInsert.inVec.begin(), threadInsert.inVec.end(),
00255 back_inserter(this->inVec));
00256 }
00257
00258 for (int i = 0; i < threadNum; i += 2) {
00259 threads[i] = new ThreadInsert<SetType, ParaType, CLASS_NAME>(set, testcase, elementNum,operationNum, i);
00260 if (i+1 < threadNum)
00261 threads[i+1] = new ThreadRemove<SetType, ParaType, CLASS_NAME>(set, testcase, elementNum,operationNum,i);
00262 }
00263 return threads;
00264 }
00265
00266 virtual void verifyResult(int threadNum, int elementNum) {
00267 CPPUNIT_ASSERT(this->inVec.size() == this->outVec.size() + set->size());
00268
00269 bool result = true;
00270
00271 typename vector<ParaType>::iterator iter = this->outVec.begin();
00272
00273 for(iter = this->outVec.begin(); iter != this->outVec.end(); ++iter) {
00274 typename vector<ParaType>::iterator itFound = find(this->inVec.begin(),this->inVec.end(),*iter);
00275
00276 if(itFound != this->inVec.end()) {
00277 this->inVec.erase(itFound);
00278 }
00279 }
00280
00281 while(!this->inVec.empty()) {
00282 if(set->search(this->inVec.back())) {
00283 this->inVec.pop_back();
00284 }
00285 else {
00286 result = false;
00287 break;
00288 }
00289 }
00290 CPPUNIT_ASSERT(result);
00291 }
00292 };
00293
00294 template<typename SetType, typename ParaType, char const* CLASS_NAME> void SetTest<
00295 SetType, ParaType, CLASS_NAME>::testEmptyST() {
00296 CPPUNIT_ASSERT( true == set->empty());
00297 }
00298
00299 template<typename SetType, typename ParaType, char const* CLASS_NAME> void SetTest<
00300 SetType, ParaType, CLASS_NAME>::testInsertST() {
00301 ThreadInsert_T threadInsert(set, this, BaseTest<ParaType>::NELEMENT, BaseTest<ParaType>::NOPERATION);
00302 threadInsert.run();
00303
00304 CPPUNIT_ASSERT(threadInsert.inVec.size() == set->size());
00305
00306 bool result = true;
00307 while(!(threadInsert.inVec.empty())) {
00308 if(set->search(threadInsert.inVec.back())) {
00309 threadInsert.inVec.pop_back();
00310 }
00311 else {
00312 result = false;
00313 break;
00314 }
00315 }
00316 CPPUNIT_ASSERT(result);
00317 }
00318
00319 template<typename SetType, typename ParaType, char const* CLASS_NAME> void SetTest<
00320 SetType, ParaType, CLASS_NAME>::testRemoveST() {
00321 ThreadInsert_T threadInsert(set, this, BaseTest<ParaType>::NELEMENT, BaseTest<ParaType>::NOPERATION);
00322 ThreadRemove_T threadRemove(set, this, BaseTest<ParaType>::NELEMENT, BaseTest<ParaType>::NOPERATION);
00323
00324 threadInsert.run();
00325 threadRemove.run();
00326
00327 CPPUNIT_ASSERT(threadInsert.inVec.size() == threadRemove.outVec.size() + set->size());
00328
00329 bool result = true;
00330 while(!threadRemove.outVec.empty()) {
00331 if(set->search(threadRemove.outVec.back())) {
00332 result = false;
00333 break;
00334 }
00335 threadRemove.outVec.pop_back();
00336 }
00337
00338 CPPUNIT_ASSERT(result);
00339 }
00340
00341 template<typename SetType, typename ParaType, char const* CLASS_NAME> void SetTest<
00342 SetType, ParaType, CLASS_NAME>::testInsertMT() {
00343 ThreadInsertFactory<SetType, ParaType, CLASS_NAME> factory(set, this);
00344 ThreadRunner::runThreads(&factory, CLASS_NAME, "testInsertMT");
00345 }
00346 template<typename SetType, typename ParaType, char const* CLASS_NAME> void SetTest<
00347 SetType, ParaType, CLASS_NAME>::testRemoveMT() {
00348 ThreadRemoveFactory<SetType, ParaType, CLASS_NAME> factory(set, this);
00349 ThreadRunner::runThreads(&factory, CLASS_NAME, "testRemoveMT");
00350 }
00351
00352 template<typename SetType, typename ParaType, char const* CLASS_NAME> void SetTest<
00353 SetType, ParaType, CLASS_NAME>::testInsertRemoveMT() {
00354 ThreadInsertRemoveFactory<SetType, ParaType, CLASS_NAME>
00355 factory(set, this);
00356 ThreadRunner::runThreads(&factory, CLASS_NAME, "testInsertRemoveMT");
00357 }
00358 }
00359 #endif