comparison UnitTestsSources/MultiThreadingTests.cpp @ 967:dfc076546821

add suffix Tests to unit test sources
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 27 Jun 2014 15:36:38 +0200
parents UnitTestsSources/MultiThreading.cpp@84513f2ee1f3
children b3d4f8a30324
comparison
equal deleted inserted replaced
966:886652370ff2 967:dfc076546821
1 /**
2 * Orthanc - A Lightweight, RESTful DICOM Store
3 * Copyright (C) 2012-2014 Medical Physics Department, CHU of Liege,
4 * Belgium
5 *
6 * This program is free software: you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, either version 3 of the
9 * License, or (at your option) any later version.
10 *
11 * In addition, as a special exception, the copyright holders of this
12 * program give permission to link the code of its release with the
13 * OpenSSL project's "OpenSSL" library (or with modified versions of it
14 * that use the same license as the "OpenSSL" library), and distribute
15 * the linked executables. You must obey the GNU General Public License
16 * in all respects for all of the code used other than "OpenSSL". If you
17 * modify file(s) with this exception, you may extend this exception to
18 * your version of the file(s), but you are not obligated to do so. If
19 * you do not wish to do so, delete this exception statement from your
20 * version. If you delete this exception statement from all source files
21 * in the program, then also delete it here.
22 *
23 * This program is distributed in the hope that it will be useful, but
24 * WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 * General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program. If not, see <http://www.gnu.org/licenses/>.
30 **/
31
32
33 #include "PrecompiledHeadersUnitTests.h"
34 #include "gtest/gtest.h"
35
36 #include <glog/logging.h>
37
38 #include "../Core/OrthancException.h"
39 #include "../Core/Toolbox.h"
40 #include "../Core/MultiThreading/ArrayFilledByThreads.h"
41 #include "../Core/MultiThreading/Locker.h"
42 #include "../Core/MultiThreading/Mutex.h"
43 #include "../Core/MultiThreading/ReaderWriterLock.h"
44 #include "../Core/MultiThreading/ThreadedCommandProcessor.h"
45
46 using namespace Orthanc;
47
48 namespace
49 {
50 class DynamicInteger : public ICommand
51 {
52 private:
53 int value_;
54 std::set<int>& target_;
55
56 public:
57 DynamicInteger(int value, std::set<int>& target) :
58 value_(value), target_(target)
59 {
60 }
61
62 int GetValue() const
63 {
64 return value_;
65 }
66
67 virtual bool Execute()
68 {
69 static boost::mutex mutex;
70 boost::mutex::scoped_lock lock(mutex);
71 target_.insert(value_);
72 return true;
73 }
74 };
75
76 class MyFiller : public ArrayFilledByThreads::IFiller
77 {
78 private:
79 int size_;
80 unsigned int created_;
81 std::set<int> set_;
82
83 public:
84 MyFiller(int size) : size_(size), created_(0)
85 {
86 }
87
88 virtual size_t GetFillerSize()
89 {
90 return size_;
91 }
92
93 virtual IDynamicObject* GetFillerItem(size_t index)
94 {
95 static boost::mutex mutex;
96 boost::mutex::scoped_lock lock(mutex);
97 created_++;
98 return new DynamicInteger(index * 2, set_);
99 }
100
101 unsigned int GetCreatedCount() const
102 {
103 return created_;
104 }
105
106 std::set<int> GetSet()
107 {
108 return set_;
109 }
110 };
111 }
112
113
114
115
116 TEST(MultiThreading, SharedMessageQueueBasic)
117 {
118 std::set<int> s;
119
120 SharedMessageQueue q;
121 ASSERT_TRUE(q.WaitEmpty(0));
122 q.Enqueue(new DynamicInteger(10, s));
123 ASSERT_FALSE(q.WaitEmpty(1));
124 q.Enqueue(new DynamicInteger(20, s));
125 q.Enqueue(new DynamicInteger(30, s));
126 q.Enqueue(new DynamicInteger(40, s));
127
128 std::auto_ptr<DynamicInteger> i;
129 i.reset(dynamic_cast<DynamicInteger*>(q.Dequeue(1))); ASSERT_EQ(10, i->GetValue());
130 i.reset(dynamic_cast<DynamicInteger*>(q.Dequeue(1))); ASSERT_EQ(20, i->GetValue());
131 i.reset(dynamic_cast<DynamicInteger*>(q.Dequeue(1))); ASSERT_EQ(30, i->GetValue());
132 ASSERT_FALSE(q.WaitEmpty(1));
133 i.reset(dynamic_cast<DynamicInteger*>(q.Dequeue(1))); ASSERT_EQ(40, i->GetValue());
134 ASSERT_TRUE(q.WaitEmpty(0));
135 ASSERT_EQ(NULL, q.Dequeue(1));
136 }
137
138
139 TEST(MultiThreading, SharedMessageQueueClean)
140 {
141 std::set<int> s;
142
143 try
144 {
145 SharedMessageQueue q;
146 q.Enqueue(new DynamicInteger(10, s));
147 q.Enqueue(new DynamicInteger(20, s));
148 throw OrthancException("Nope");
149 }
150 catch (OrthancException&)
151 {
152 }
153 }
154
155
156 TEST(MultiThreading, ArrayFilledByThreadEmpty)
157 {
158 MyFiller f(0);
159 ArrayFilledByThreads a(f);
160 a.SetThreadCount(1);
161 ASSERT_EQ(0, a.GetSize());
162 }
163
164
165 TEST(MultiThreading, ArrayFilledByThread1)
166 {
167 MyFiller f(100);
168 ArrayFilledByThreads a(f);
169 a.SetThreadCount(1);
170 ASSERT_EQ(100, a.GetSize());
171 for (size_t i = 0; i < a.GetSize(); i++)
172 {
173 ASSERT_EQ(2 * i, dynamic_cast<DynamicInteger&>(a.GetItem(i)).GetValue());
174 }
175 }
176
177
178 TEST(MultiThreading, ArrayFilledByThread4)
179 {
180 MyFiller f(100);
181 ArrayFilledByThreads a(f);
182 a.SetThreadCount(4);
183 ASSERT_EQ(100, a.GetSize());
184 for (size_t i = 0; i < a.GetSize(); i++)
185 {
186 ASSERT_EQ(2 * i, dynamic_cast<DynamicInteger&>(a.GetItem(i)).GetValue());
187 }
188
189 ASSERT_EQ(100u, f.GetCreatedCount());
190
191 a.Invalidate();
192
193 ASSERT_EQ(100, a.GetSize());
194 ASSERT_EQ(200u, f.GetCreatedCount());
195 ASSERT_EQ(4u, a.GetThreadCount());
196 ASSERT_TRUE(f.GetSet().empty());
197
198 for (size_t i = 0; i < a.GetSize(); i++)
199 {
200 ASSERT_EQ(2 * i, dynamic_cast<DynamicInteger&>(a.GetItem(i)).GetValue());
201 }
202 }
203
204
205 TEST(MultiThreading, CommandProcessor)
206 {
207 ThreadedCommandProcessor p(4);
208
209 std::set<int> s;
210
211 for (size_t i = 0; i < 100; i++)
212 {
213 p.Post(new DynamicInteger(i * 2, s));
214 }
215
216 p.Join();
217
218 for (size_t i = 0; i < 200; i++)
219 {
220 if (i % 2)
221 ASSERT_TRUE(s.find(i) == s.end());
222 else
223 ASSERT_TRUE(s.find(i) != s.end());
224 }
225 }
226
227
228 TEST(MultiThreading, Mutex)
229 {
230 Mutex mutex;
231 Locker locker(mutex);
232 }
233
234
235 TEST(MultiThreading, ReaderWriterLock)
236 {
237 ReaderWriterLock lock;
238
239 {
240 Locker locker1(lock.ForReader());
241 Locker locker2(lock.ForReader());
242 }
243
244 {
245 Locker locker3(lock.ForWriter());
246 }
247 }
248
249
250
251
252
253 #include "../OrthancServer/DicomProtocol/ReusableDicomUserConnection.h"
254
255 TEST(ReusableDicomUserConnection, DISABLED_Basic)
256 {
257 ReusableDicomUserConnection c;
258 c.SetMillisecondsBeforeClose(200);
259 printf("START\n"); fflush(stdout);
260 {
261 ReusableDicomUserConnection::Locker lock(c, "STORESCP", "localhost", 2000, ModalityManufacturer_Generic);
262 lock.GetConnection().StoreFile("/home/jodogne/DICOM/Cardiac/MR.X.1.2.276.0.7230010.3.1.4.2831157719.2256.1336386844.676281");
263 }
264
265 printf("**\n"); fflush(stdout);
266 Toolbox::USleep(1000000);
267 printf("**\n"); fflush(stdout);
268
269 {
270 ReusableDicomUserConnection::Locker lock(c, "STORESCP", "localhost", 2000, ModalityManufacturer_Generic);
271 lock.GetConnection().StoreFile("/home/jodogne/DICOM/Cardiac/MR.X.1.2.276.0.7230010.3.1.4.2831157719.2256.1336386844.676277");
272 }
273
274 Toolbox::ServerBarrier();
275 printf("DONE\n"); fflush(stdout);
276 }