00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef QUEUETEST_H_
00017 #define QUEUETEST_H_
00018 #include <cppunit/extensions/HelperMacros.h>
00019 #include <cppunit/TestAssert.h>
00020 #include <stdexcept>
00021 #include "baseTest.h"
00022
00023 namespace test {
00024
00025 template<typename QueueType, typename ParaType, char const* CLASS_NAME>
00026 class QueueTest: public CppUnit::TestFixture, public BaseTest<ParaType> {
00027 CPPUNIT_TEST_SUITE(QueueTest);
00028 CPPUNIT_TEST(testEmptyST);
00029 CPPUNIT_TEST(testEnqueueST);
00030 CPPUNIT_TEST(testDequeueST);
00031 CPPUNIT_TEST(testEnqueueMT);
00032 CPPUNIT_TEST(testDequeueMT);
00033 CPPUNIT_TEST(testEnDequeuePairMT);
00034 CPPUNIT_TEST(testBound);
00035 CPPUNIT_TEST_SUITE_END();
00036
00037 private:
00038 QueueType *queue;
00039 public:
00040 QueueTest() {
00041 }
00042
00043 QueueType * getQueue() {
00044 return queue;
00045 }
00046
00047 void setUp() {
00048 queue = new QueueType();
00049 }
00050
00051 void reset() {
00052 delete queue;
00053 queue = new QueueType();
00054 }
00055
00056 void tearDown() {
00057 delete queue;
00058 }
00059
00060 void testEmptyST();
00061 void testEnqueueST();
00062 void testDequeueST();
00063 void testEnqueueMT();
00064 void testDequeueMT();
00065 void testEnDequeuePairMT();
00066 void testBound();
00067 };
00068
00069 #define ThreadDequeue_T ThreadDequeue<QueueType, ParaType, CLASS_NAME>
00070 #define ThreadEnqueue_T ThreadEnqueue<QueueType, ParaType, CLASS_NAME>
00071
00072 template<typename QueueType, typename ParaType, char const* CLASS_NAME>
00073 class ThreadEnqueue: public TestThread<ParaType> {
00074 private:
00075 QueueType *queue;
00076 QueueTest<QueueType, ParaType, CLASS_NAME> *testcase;
00077 int elementNum;
00078 int operationNum;
00079
00080 public:
00081 ThreadEnqueue(QueueType * q, QueueTest<QueueType, ParaType, CLASS_NAME>* qt,
00082 int nElement, int nOperation, int threadId = 0) :
00083 TestThread<ParaType>(threadId), queue(q), testcase(qt),
00084 elementNum(nElement), operationNum(nOperation)
00085 {
00086 }
00087
00088 void* run() {
00089 for (int i = 0; i < operationNum; ++i) {
00090 int index = (i + ((this->threadId) * elementNum))%(testcase->NELEMENT*testcase->MAXTHREADN);
00091 queue->enqueue(testcase->data[index]);
00092 this->inVec.push_back(testcase->data[index]);
00093 }
00094 return NULL;
00095 }
00096 };
00097
00098 template<typename QueueType, typename ParaType, char const* CLASS_NAME>
00099 class ThreadDequeue: public TestThread<ParaType> {
00100 private:
00101 QueueType *queue;
00102 QueueTest<QueueType, ParaType, CLASS_NAME> *testcase;
00103 int elementNum;
00104 int operationNum;
00105
00106 public:
00107
00108 ThreadDequeue(QueueType * q,
00109 QueueTest<QueueType, ParaType, CLASS_NAME> * qt, int nElement,
00110 int nOperation) :
00111 queue(q), testcase(qt), elementNum(nElement), operationNum(nOperation) {
00112 }
00113
00114 void* run() {
00115 for (int i = 0; i < operationNum; ++i) {
00116 ParaType tmp;
00117 if (queue->dequeue(tmp)) {
00118 this->outVec.push_back(tmp);
00119 }
00120 }
00121 return NULL;
00122 }
00123 };
00124 template<typename QueueType, typename ParaType, char const* CLASS_NAME> class ThreadDequeueFactory: public ThreadFactory<
00125 ParaType> {
00126 private:
00127 QueueType *queue;
00128 QueueTest<QueueType, ParaType, CLASS_NAME> *testcase;
00129 public:
00130 ThreadDequeueFactory(QueueType * q, QueueTest<QueueType, ParaType,
00131 CLASS_NAME> * qt) :
00132 queue(q), testcase(qt) {
00133 }
00134
00135 virtual Runnable ** createThreads(int threadNum, int elementNum,
00136 int operationNum) {
00137 testcase->reset();
00138 queue = testcase->getQueue();
00139 this->inVec.clear();
00140 this->outVec.clear();
00141
00142 for (int i = 0; i < threadNum; ++i) {
00143 ThreadEnqueue_T threadEnqueue(queue, testcase, elementNum, i);
00144 threadEnqueue.run();
00145
00146 copy(threadEnqueue.inVec.begin(), threadEnqueue.inVec.end(),
00147 back_inserter(this->inVec));
00148 }
00149 Runnable ** threads;
00150 threads = new Runnable*[threadNum];
00151 for (int i = 0; i < threadNum; ++i)
00152 threads[i]
00153 = new ThreadDequeue<QueueType, ParaType, CLASS_NAME> (queue, testcase, elementNum, operationNum);
00154
00155 return threads;
00156 }
00157
00158 virtual void verifyResult(int threadNum, int elementNum) {
00159 CPPUNIT_ASSERT(queue->size() == 0);
00160
00161 ThreadFactory<ParaType>::verifyResult(threadNum, elementNum);
00162 }
00163 };
00164
00165 template<typename QueueType, typename ParaType, char const* CLASS_NAME> class ThreadEnqueueFactory: public ThreadFactory<
00166 ParaType> {
00167 private:
00168 QueueType *queue;
00169 QueueTest<QueueType, ParaType, CLASS_NAME> *testcase;
00170 public:
00171 ThreadEnqueueFactory(QueueType * q, QueueTest<QueueType, ParaType,
00172 CLASS_NAME> * qt) :
00173 queue(q), testcase(qt) {
00174 }
00175
00176 virtual Runnable ** createThreads(int threadNum, int elementNum,
00177 int operationNum) {
00178 testcase->reset();
00179 queue = testcase->getQueue();
00180 this->inVec.clear();
00181 this->outVec.clear();
00182
00183 Runnable ** threads;
00184 threads = new Runnable*[threadNum];
00185 for (int i = 0; i < threadNum; ++i)
00186 threads[i]
00187 = new ThreadEnqueue<QueueType, ParaType, CLASS_NAME> (queue, testcase, elementNum, operationNum, i);
00188
00189 return threads;
00190 }
00191
00192 virtual void verifyResult(int threadNum, int elementNum) {
00193
00194 while (!queue->empty()) {
00195 ParaType tmp;
00196 if (queue->dequeue(tmp)) {
00197 this->outVec.push_back(tmp);
00198 }
00199 }
00200
00201 ThreadFactory<ParaType>::verifyResult(threadNum, elementNum);
00202 }
00203 };
00204
00205 template<typename QueueType, typename ParaType, char const* CLASS_NAME> class ThreadEnDequeueFactory: public ThreadFactory<
00206 ParaType> {
00207 private:
00208 QueueType *queue;
00209 QueueTest<QueueType, ParaType, CLASS_NAME> *testcase;
00210 public:
00211 ThreadEnDequeueFactory(QueueType * q, QueueTest<QueueType, ParaType,
00212 CLASS_NAME> * qt) :
00213 queue(q), testcase(qt) {
00214 }
00215
00216 virtual Runnable ** createThreads(int threadNum, int elementNum,
00217 int operationNum) {
00218 testcase->reset();
00219 queue = testcase->getQueue();
00220 this->inVec.clear();
00221 this->outVec.clear();
00222
00223 for (int i = 0; i < threadNum; ++i) {
00224 ThreadEnqueue_T threadEnqueue(queue, testcase, elementNum, i);
00225 threadEnqueue.run();
00226
00227 copy(threadEnqueue.inVec.begin(), threadEnqueue.inVec.end(),
00228 back_inserter(this->inVec));
00229 }
00230 Runnable ** threads;
00231 threads = new Runnable*[threadNum];
00232
00233 for (int i = 0; i < threadNum; i += 2) {
00234 threads[i]
00235 = new ThreadEnqueue<QueueType, ParaType, CLASS_NAME> (queue, testcase, elementNum, operationNum, i
00236 / 2);
00237 if (i + 1 < threadNum)
00238 threads[i + 1] = new ThreadDequeue<QueueType, ParaType,
00239 CLASS_NAME> (queue, testcase, elementNum, operationNum);
00240 }
00241 return threads;
00242 }
00243
00244 virtual void verifyResult(int threadNum, int elementNum) {
00245 while (!queue->empty()) {
00246 ParaType tmp;
00247 if (queue->dequeue(tmp)) {
00248 this->outVec.push_back(tmp);
00249 }
00250 }
00251
00252 ThreadFactory<ParaType>::verifyResult(threadNum, elementNum);
00253
00254 }
00255 };
00256
00257 template<typename QueueType, typename ParaType, char const* CLASS_NAME> void QueueTest<
00258 QueueType, ParaType, CLASS_NAME>::testEmptyST() {
00259 CPPUNIT_ASSERT(true == queue->empty());
00260 CPPUNIT_ASSERT(0 == queue->size());
00261 }
00262
00263 template<typename QueueType, typename ParaType, char const* CLASS_NAME> void QueueTest<
00264 QueueType, ParaType, CLASS_NAME>::testEnqueueST() {
00265 ThreadEnqueue_T threadEnqueue(queue, this, BaseTest<ParaType>::NELEMENT,
00266 BaseTest<ParaType>::NOPERATION);
00267 threadEnqueue.run();
00268 CPPUNIT_ASSERT(BaseTest<ParaType>::NOPERATION == queue->size());
00269
00270
00271 vector<ParaType> outVec;
00272 while (!queue->empty()) {
00273 ParaType tmp;
00274 if (queue->dequeue(tmp)) {
00275 outVec.push_back(tmp);
00276 }
00277 }
00278
00279 sort(threadEnqueue.inVec.begin(), threadEnqueue.inVec.end());
00280 sort(outVec.begin(), outVec.end());
00281
00282 CPPUNIT_ASSERT(threadEnqueue.inVec == outVec);
00283 }
00284
00285 template<typename QueueType, typename ParaType, char const* CLASS_NAME> void QueueTest<
00286 QueueType, ParaType, CLASS_NAME>::testDequeueST() {
00287 ThreadEnqueue_T threadEnqueue(queue, this, BaseTest<ParaType>::NELEMENT,
00288 BaseTest<ParaType>::NOPERATION);
00289 ThreadDequeue_T threadDequeue(queue, this, BaseTest<ParaType>::NELEMENT,
00290 BaseTest<ParaType>::NOPERATION);
00291 threadEnqueue.run();
00292 threadDequeue.run();
00293
00294 CPPUNIT_ASSERT(0 == queue->size());
00295
00296 sort(threadEnqueue.inVec.begin(), threadEnqueue.inVec.end());
00297 sort(threadDequeue.outVec.begin(), threadDequeue.outVec.end());
00298
00299 CPPUNIT_ASSERT(threadEnqueue.inVec == threadDequeue.outVec);
00300 }
00301
00302 template<typename QueueType, typename ParaType, char const* CLASS_NAME> void QueueTest<
00303 QueueType, ParaType, CLASS_NAME>::testEnqueueMT() {
00304 ThreadEnqueueFactory<QueueType, ParaType, CLASS_NAME> factory(queue, this);
00305 ThreadRunner::runThreads(&factory, CLASS_NAME, "testEnqueueMT");
00306 }
00307
00308 template<typename QueueType, typename ParaType, char const* CLASS_NAME> void QueueTest<
00309 QueueType, ParaType, CLASS_NAME>::testDequeueMT() {
00310 ThreadDequeueFactory<QueueType, ParaType, CLASS_NAME> dequeueFactory(queue,
00311 this);
00312 ThreadRunner::runThreads(&dequeueFactory, CLASS_NAME, "testDequeueMT");
00313 }
00314
00315 template<typename QueueType, typename ParaType, char const* CLASS_NAME> void QueueTest<
00316 QueueType, ParaType, CLASS_NAME>::testEnDequeuePairMT() {
00317 ThreadEnDequeueFactory<QueueType, ParaType, CLASS_NAME>
00318 factory(queue, this);
00319 ThreadRunner::runThreads(&factory, CLASS_NAME, "testEnDequeuePairMT");
00320 }
00321
00322 template<typename QueueType, typename ParaType, char const* CLASS_NAME> void QueueTest<
00323 QueueType, ParaType, CLASS_NAME>::testBound() {
00324 ParaType tmp;
00325 bool res = queue->dequeue(tmp);
00326 CPPUNIT_ASSERT(!res);
00327 }
00328 }
00329 #endif