Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 #include <gtest/gtest.h> | 1 #include <gtest/gtest.h> |
2 #include <queue> | 2 #include <queue> |
3 #include <vector> | 3 #include <vector> |
4 | 4 |
5 #include "../src/Thread.h" | 5 #include "../src/Thread.h" |
6 | 6 |
7 namespace | 7 namespace |
8 { | 8 { |
9 #ifndef WIN32 | 9 #ifndef WIN32 |
10 void Sleep(const int millis) | 10 void Sleep(const int millis) |
11 { | 11 { |
12 usleep(millis * 1000); | 12 usleep(millis * 1000); |
13 } | 13 } |
14 #endif | 14 #endif |
15 | 15 |
16 class Mock : public AdblockPlus::Thread | 16 class Mock : public AdblockPlus::Thread |
17 { | 17 { |
18 public: | 18 public: |
19 int timesCalled; | 19 int timesCalled; |
20 AdblockPlus::Mutex mutex; | 20 AdblockPlus::Mutex mutex; |
21 | 21 |
22 Mock() : timesCalled(0) | 22 Mock() : timesCalled(0) |
23 { | 23 { |
24 } | 24 } |
25 | 25 |
26 void Run() | 26 void Run() |
27 { | 27 { |
28 Sleep(5); | 28 Sleep(5); |
Wladimir Palant
2013/04/04 07:09:00
Why is this necessary? Seems random.
Felix Dahlke
2013/04/04 07:27:40
See below.
| |
29 mutex.Lock(); | 29 mutex.Lock(); |
30 timesCalled++; | 30 timesCalled++; |
31 mutex.Unlock(); | 31 mutex.Unlock(); |
32 } | 32 } |
33 }; | 33 }; |
34 | 34 |
35 class LockingMock : public AdblockPlus::Thread | 35 class LockingMock : public AdblockPlus::Thread |
36 { | 36 { |
37 public: | 37 public: |
38 bool working; | 38 bool working; |
39 | 39 |
40 LockingMock(const std::string& name, std::vector<std::string>& log, | 40 LockingMock(std::vector<std::string>& log, AdblockPlus::Mutex& logMutex) |
41 AdblockPlus::Mutex& logMutex) | 41 : log(log), logMutex(logMutex) |
42 : name(name), log(log), logMutex(logMutex) | |
43 { | 42 { |
44 } | 43 } |
45 | 44 |
46 void Run() | 45 void Run() |
47 { | 46 { |
48 logMutex.Lock(); | 47 logMutex.Lock(); |
49 log.push_back(name); | 48 log.push_back("started"); |
49 Sleep(5); | |
50 log.push_back("ended"); | |
50 logMutex.Unlock(); | 51 logMutex.Unlock(); |
51 } | 52 } |
52 | 53 |
53 private: | 54 private: |
54 const std::string name; | 55 const std::string name; |
55 std::vector<std::string>& log; | 56 std::vector<std::string>& log; |
56 AdblockPlus::Mutex& logMutex; | 57 AdblockPlus::Mutex& logMutex; |
57 }; | 58 }; |
58 | 59 |
59 class Enqueuer : public AdblockPlus::Thread | 60 class Enqueuer : public AdblockPlus::Thread |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
102 AdblockPlus::Mutex& queueMutex; | 103 AdblockPlus::Mutex& queueMutex; |
103 AdblockPlus::ConditionVariable& notEmpty; | 104 AdblockPlus::ConditionVariable& notEmpty; |
104 }; | 105 }; |
105 } | 106 } |
106 | 107 |
107 TEST(ThreadTest, Run) | 108 TEST(ThreadTest, Run) |
108 { | 109 { |
109 Mock mock; | 110 Mock mock; |
110 ASSERT_EQ(0, mock.timesCalled); | 111 ASSERT_EQ(0, mock.timesCalled); |
111 mock.Start(); | 112 mock.Start(); |
112 mock.mutex.Lock(); | 113 mock.mutex.Lock(); |
Wladimir Palant
2013/04/04 07:09:00
This should be done before mock.Start(), otherwise
Felix Dahlke
2013/04/04 07:27:40
That's what the 5ms sleep above is for. It's not b
Wladimir Palant
2013/04/04 09:26:53
Oh well :-(
| |
113 ASSERT_EQ(0, mock.timesCalled); | 114 ASSERT_EQ(0, mock.timesCalled); |
114 mock.mutex.Unlock(); | 115 mock.mutex.Unlock(); |
115 mock.Join(); | 116 mock.Join(); |
116 ASSERT_EQ(1, mock.timesCalled); | 117 ASSERT_EQ(1, mock.timesCalled); |
117 } | 118 } |
118 | 119 |
119 TEST(ThreadTest, Mutex) | 120 TEST(ThreadTest, Mutex) |
120 { | 121 { |
121 std::vector<std::string> log; | 122 std::vector<std::string> log; |
122 AdblockPlus::Mutex logMutex; | 123 AdblockPlus::Mutex logMutex; |
123 LockingMock mock1("mock1", log, logMutex); | 124 LockingMock mock1(log, logMutex); |
124 LockingMock mock2("mock2", log, logMutex); | 125 LockingMock mock2(log, logMutex); |
125 mock1.Start(); | 126 mock1.Start(); |
126 Sleep(5); | |
127 mock2.Start(); | 127 mock2.Start(); |
Wladimir Palant
2013/04/04 07:09:00
This test doesn't make sense - mock1 will already
Felix Dahlke
2013/04/04 07:27:40
Yeah, that's a much better test. Did that.
| |
128 mock1.Join(); | 128 mock1.Join(); |
129 mock2.Join(); | 129 mock2.Join(); |
130 ASSERT_EQ("mock1", log[0]); | 130 ASSERT_EQ("started", log[0]); |
131 ASSERT_EQ("mock2", log[1]); | 131 ASSERT_EQ("ended", log[1]); |
132 ASSERT_EQ("started", log[2]); | |
133 ASSERT_EQ("ended", log[3]); | |
132 } | 134 } |
133 | 135 |
134 TEST(ThreadTest, ConditionVariable) | 136 TEST(ThreadTest, ConditionVariable) |
135 { | 137 { |
136 std::queue<int> queue; | 138 std::queue<int> queue; |
137 AdblockPlus::Mutex queueMutex; | 139 AdblockPlus::Mutex queueMutex; |
138 AdblockPlus::ConditionVariable notEmpty; | 140 AdblockPlus::ConditionVariable notEmpty; |
139 Dequeuer dequeuer(queue, queueMutex, notEmpty); | 141 Dequeuer dequeuer(queue, queueMutex, notEmpty); |
140 Enqueuer enqueuer(queue, queueMutex, notEmpty); | 142 Enqueuer enqueuer(queue, queueMutex, notEmpty); |
141 dequeuer.Start(); | 143 dequeuer.Start(); |
142 Sleep(5); | 144 Sleep(5); |
143 enqueuer.Start(); | 145 enqueuer.Start(); |
144 enqueuer.Join(); | 146 enqueuer.Join(); |
145 dequeuer.Join(); | 147 dequeuer.Join(); |
146 ASSERT_EQ(0, queue.size()); | 148 ASSERT_EQ(0, queue.size()); |
Wladimir Palant
2013/04/04 09:26:53
This fails to compile for me once again, 0u please
| |
147 } | 149 } |
LEFT | RIGHT |