1 |
schoenebeck |
57 |
#include "ThreadTest.h" |
2 |
|
|
|
3 |
|
|
#include <iostream> |
4 |
|
|
|
5 |
|
|
CPPUNIT_TEST_SUITE_REGISTRATION(ThreadTest); |
6 |
|
|
|
7 |
schoenebeck |
211 |
using namespace std; |
8 |
schoenebeck |
57 |
|
9 |
schoenebeck |
211 |
|
10 |
schoenebeck |
57 |
// DummyThread |
11 |
|
|
|
12 |
schoenebeck |
503 |
ThreadTest::DummyThread::DummyThread() : Thread(false, false, 0, -4) { |
13 |
schoenebeck |
57 |
wasRunning = false; |
14 |
|
|
} |
15 |
|
|
|
16 |
|
|
int ThreadTest::DummyThread::Main() { |
17 |
|
|
wasRunning = true; |
18 |
schoenebeck |
211 |
while (true) someVariable = -1; |
19 |
schoenebeck |
57 |
} |
20 |
|
|
|
21 |
|
|
|
22 |
|
|
// HelperThread |
23 |
|
|
|
24 |
schoenebeck |
503 |
ThreadTest::HelperThread::HelperThread(DummyThread* pDummyThread) : Thread(false, false, 0, -4) { |
25 |
schoenebeck |
57 |
returnedFromDummyStop = false; |
26 |
|
|
this->pDummyThread = pDummyThread; |
27 |
|
|
} |
28 |
|
|
|
29 |
|
|
int ThreadTest::HelperThread::Main() { |
30 |
|
|
pDummyThread->StopThread(); |
31 |
schoenebeck |
211 |
pDummyThread->someVariable = 0; // we set this to another value than -1 so we can check if the DummyThread was still running |
32 |
schoenebeck |
57 |
returnedFromDummyStop = true; |
33 |
|
|
} |
34 |
|
|
|
35 |
schoenebeck |
211 |
bool ThreadTest::HelperThread::dummyThreadWasNotRunningAnymoreAfter_StopThread_call() { |
36 |
|
|
return (pDummyThread->someVariable == 0); |
37 |
|
|
} |
38 |
schoenebeck |
57 |
|
39 |
schoenebeck |
211 |
|
40 |
schoenebeck |
63 |
// WaitingThread |
41 |
|
|
|
42 |
schoenebeck |
503 |
ThreadTest::WaitingThread::WaitingThread() : Thread(false, false, 0, -4) { |
43 |
schoenebeck |
63 |
} |
44 |
|
|
|
45 |
|
|
int ThreadTest::WaitingThread::Main() { |
46 |
|
|
while (true) condition.WaitIf(false); |
47 |
|
|
} |
48 |
|
|
|
49 |
|
|
|
50 |
schoenebeck |
57 |
// ThreadTest |
51 |
|
|
|
52 |
schoenebeck |
211 |
void ThreadTest::printTestSuiteName() { |
53 |
|
|
cout << "\b \nRunning Thread Tests: " << flush; |
54 |
|
|
} |
55 |
|
|
|
56 |
schoenebeck |
63 |
// Check if Thread class actually deploys a thread |
57 |
schoenebeck |
57 |
void ThreadTest::testThreadRunning() { |
58 |
|
|
dummythread.StartThread(); |
59 |
|
|
usleep(25000); // wait 25ms |
60 |
|
|
CPPUNIT_ASSERT(dummythread.wasRunning); |
61 |
|
|
CPPUNIT_ASSERT(dummythread.IsRunning()); |
62 |
|
|
} |
63 |
|
|
|
64 |
schoenebeck |
63 |
// Check if SignalStopThread() method actually stops the thread |
65 |
schoenebeck |
57 |
void ThreadTest::testSignalStopThread() { |
66 |
|
|
dummythread.SignalStopThread(); |
67 |
|
|
usleep(40000); // wait 40ms |
68 |
|
|
CPPUNIT_ASSERT(!dummythread.IsRunning()); |
69 |
|
|
} |
70 |
|
|
|
71 |
schoenebeck |
63 |
// Check if the thread can be relaunched |
72 |
schoenebeck |
57 |
void ThreadTest::testRelaunchThread() { |
73 |
schoenebeck |
63 |
dummythread.StartThread(); |
74 |
|
|
usleep(25000); // wait 25ms |
75 |
|
|
CPPUNIT_ASSERT(dummythread.wasRunning); |
76 |
|
|
CPPUNIT_ASSERT(dummythread.IsRunning()); |
77 |
|
|
dummythread.StopThread(); |
78 |
|
|
usleep(25000); // wait 25ms |
79 |
schoenebeck |
57 |
dummythread.wasRunning = false; |
80 |
|
|
dummythread.StartThread(); |
81 |
|
|
usleep(25000); // wait 25ms |
82 |
|
|
CPPUNIT_ASSERT(dummythread.wasRunning); |
83 |
|
|
CPPUNIT_ASSERT(dummythread.IsRunning()); |
84 |
|
|
} |
85 |
|
|
|
86 |
schoenebeck |
211 |
// Check if the StopThread() method actually stops the thread and doesn't freeze the calling thread which wants to stop it and also check if the thread was still running after the StopThread() method was called. |
87 |
schoenebeck |
57 |
void ThreadTest::testStopThread() { |
88 |
|
|
HelperThread* phelper = new HelperThread(&dummythread); |
89 |
|
|
phelper->StartThread(); // let the helper thread kill the dummy thread |
90 |
|
|
usleep(25000); // wait 25ms |
91 |
|
|
CPPUNIT_ASSERT(!dummythread.IsRunning()); |
92 |
|
|
CPPUNIT_ASSERT(phelper->returnedFromDummyStop); |
93 |
schoenebeck |
211 |
bool wasnotrunning = phelper->dummyThreadWasNotRunningAnymoreAfter_StopThread_call(); |
94 |
|
|
if (wasnotrunning && phelper) delete phelper; |
95 |
|
|
CPPUNIT_ASSERT(wasnotrunning); |
96 |
schoenebeck |
57 |
} |
97 |
schoenebeck |
63 |
|
98 |
|
|
// Check if the thread can be stopped even when it's waiting for a condition |
99 |
|
|
void ThreadTest::testThreadKillableWhenWaiting() { |
100 |
schoenebeck |
211 |
WaitingThread* pwaitingthread = new WaitingThread; |
101 |
|
|
pwaitingthread->SignalStartThread(); |
102 |
|
|
usleep(150000); // wait 150ms |
103 |
|
|
CPPUNIT_ASSERT(pwaitingthread->IsRunning()); |
104 |
|
|
pwaitingthread->SignalStopThread(); |
105 |
|
|
for (uint trials = 400; trials; trials--) { |
106 |
|
|
bool success = !pwaitingthread->IsRunning(); |
107 |
|
|
if (success) { |
108 |
|
|
usleep(15000); // wait 15ms |
109 |
|
|
delete pwaitingthread; |
110 |
|
|
CPPUNIT_ASSERT(true); // success |
111 |
|
|
return; |
112 |
|
|
} |
113 |
|
|
else usleep(150000); // wait 150ms and try again |
114 |
|
|
} |
115 |
|
|
CPPUNIT_ASSERT(false); // failure |
116 |
schoenebeck |
63 |
} |