Mercurial > hg > orthanc
comparison OrthancServer/UnitTestsSources/MultiThreadingTests.cpp @ 4044:d25f4c0fa160 framework
splitting code into OrthancFramework and OrthancServer
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 10 Jun 2020 20:30:34 +0200 |
parents | UnitTestsSources/MultiThreadingTests.cpp@ef696db8426f |
children | 05b8fd21089c |
comparison
equal
deleted
inserted
replaced
4043:6c6239aec462 | 4044:d25f4c0fa160 |
---|---|
1 /** | |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium | |
6 * | |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU General Public License as | |
9 * published by the Free Software Foundation, either version 3 of the | |
10 * License, or (at your option) any later version. | |
11 * | |
12 * In addition, as a special exception, the copyright holders of this | |
13 * program give permission to link the code of its release with the | |
14 * OpenSSL project's "OpenSSL" library (or with modified versions of it | |
15 * that use the same license as the "OpenSSL" library), and distribute | |
16 * the linked executables. You must obey the GNU General Public License | |
17 * in all respects for all of the code used other than "OpenSSL". If you | |
18 * modify file(s) with this exception, you may extend this exception to | |
19 * your version of the file(s), but you are not obligated to do so. If | |
20 * you do not wish to do so, delete this exception statement from your | |
21 * version. If you delete this exception statement from all source files | |
22 * in the program, then also delete it here. | |
23 * | |
24 * This program is distributed in the hope that it will be useful, but | |
25 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
27 * General Public License for more details. | |
28 * | |
29 * You should have received a copy of the GNU General Public License | |
30 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
31 **/ | |
32 | |
33 | |
34 #include "PrecompiledHeadersUnitTests.h" | |
35 #include "gtest/gtest.h" | |
36 | |
37 #include "../Core/Compatibility.h" | |
38 #include "../Core/FileStorage/MemoryStorageArea.h" | |
39 #include "../Core/JobsEngine/JobsEngine.h" | |
40 #include "../Core/Logging.h" | |
41 #include "../Core/MultiThreading/SharedMessageQueue.h" | |
42 #include "../Core/OrthancException.h" | |
43 #include "../Core/SerializationToolbox.h" | |
44 #include "../Core/SystemToolbox.h" | |
45 #include "../Core/Toolbox.h" | |
46 #include "../OrthancServer/Database/SQLiteDatabaseWrapper.h" | |
47 #include "../OrthancServer/ServerContext.h" | |
48 #include "../OrthancServer/ServerJobs/LuaJobManager.h" | |
49 #include "../OrthancServer/ServerJobs/OrthancJobUnserializer.h" | |
50 | |
51 #include "../Core/JobsEngine/Operations/JobOperationValues.h" | |
52 #include "../Core/JobsEngine/Operations/NullOperationValue.h" | |
53 #include "../Core/JobsEngine/Operations/StringOperationValue.h" | |
54 #include "../OrthancServer/ServerJobs/Operations/DicomInstanceOperationValue.h" | |
55 | |
56 #include "../Core/JobsEngine/Operations/LogJobOperation.h" | |
57 #include "../OrthancServer/ServerJobs/Operations/DeleteResourceOperation.h" | |
58 #include "../OrthancServer/ServerJobs/Operations/ModifyInstanceOperation.h" | |
59 #include "../OrthancServer/ServerJobs/Operations/StorePeerOperation.h" | |
60 #include "../OrthancServer/ServerJobs/Operations/StoreScuOperation.h" | |
61 #include "../OrthancServer/ServerJobs/Operations/SystemCallOperation.h" | |
62 | |
63 #include "../OrthancServer/ServerJobs/ArchiveJob.h" | |
64 #include "../OrthancServer/ServerJobs/DicomModalityStoreJob.h" | |
65 #include "../OrthancServer/ServerJobs/DicomMoveScuJob.h" | |
66 #include "../OrthancServer/ServerJobs/MergeStudyJob.h" | |
67 #include "../OrthancServer/ServerJobs/OrthancPeerStoreJob.h" | |
68 #include "../OrthancServer/ServerJobs/ResourceModificationJob.h" | |
69 #include "../OrthancServer/ServerJobs/SplitStudyJob.h" | |
70 | |
71 | |
72 using namespace Orthanc; | |
73 | |
74 namespace | |
75 { | |
76 class DummyJob : public IJob | |
77 { | |
78 private: | |
79 bool fails_; | |
80 unsigned int count_; | |
81 unsigned int steps_; | |
82 | |
83 public: | |
84 DummyJob() : | |
85 fails_(false), | |
86 count_(0), | |
87 steps_(4) | |
88 { | |
89 } | |
90 | |
91 explicit DummyJob(bool fails) : | |
92 fails_(fails), | |
93 count_(0), | |
94 steps_(4) | |
95 { | |
96 } | |
97 | |
98 virtual void Start() ORTHANC_OVERRIDE | |
99 { | |
100 } | |
101 | |
102 virtual void Reset() ORTHANC_OVERRIDE | |
103 { | |
104 } | |
105 | |
106 virtual JobStepResult Step(const std::string& jobId) ORTHANC_OVERRIDE | |
107 { | |
108 if (fails_) | |
109 { | |
110 return JobStepResult::Failure(ErrorCode_ParameterOutOfRange, NULL); | |
111 } | |
112 else if (count_ == steps_ - 1) | |
113 { | |
114 return JobStepResult::Success(); | |
115 } | |
116 else | |
117 { | |
118 count_++; | |
119 return JobStepResult::Continue(); | |
120 } | |
121 } | |
122 | |
123 virtual void Stop(JobStopReason reason) ORTHANC_OVERRIDE | |
124 { | |
125 } | |
126 | |
127 virtual float GetProgress() ORTHANC_OVERRIDE | |
128 { | |
129 return static_cast<float>(count_) / static_cast<float>(steps_ - 1); | |
130 } | |
131 | |
132 virtual void GetJobType(std::string& type) ORTHANC_OVERRIDE | |
133 { | |
134 type = "DummyJob"; | |
135 } | |
136 | |
137 virtual bool Serialize(Json::Value& value) ORTHANC_OVERRIDE | |
138 { | |
139 value = Json::objectValue; | |
140 value["Type"] = "DummyJob"; | |
141 return true; | |
142 } | |
143 | |
144 virtual void GetPublicContent(Json::Value& value) ORTHANC_OVERRIDE | |
145 { | |
146 value["hello"] = "world"; | |
147 } | |
148 | |
149 virtual bool GetOutput(std::string& output, | |
150 MimeType& mime, | |
151 const std::string& key) ORTHANC_OVERRIDE | |
152 { | |
153 return false; | |
154 } | |
155 }; | |
156 | |
157 | |
158 class DummyInstancesJob : public SetOfInstancesJob | |
159 { | |
160 private: | |
161 bool trailingStepDone_; | |
162 | |
163 protected: | |
164 virtual bool HandleInstance(const std::string& instance) ORTHANC_OVERRIDE | |
165 { | |
166 return (instance != "nope"); | |
167 } | |
168 | |
169 virtual bool HandleTrailingStep() ORTHANC_OVERRIDE | |
170 { | |
171 if (HasTrailingStep()) | |
172 { | |
173 if (trailingStepDone_) | |
174 { | |
175 throw OrthancException(ErrorCode_InternalError); | |
176 } | |
177 else | |
178 { | |
179 trailingStepDone_ = true; | |
180 return true; | |
181 } | |
182 } | |
183 else | |
184 { | |
185 throw OrthancException(ErrorCode_InternalError); | |
186 } | |
187 } | |
188 | |
189 public: | |
190 DummyInstancesJob() : | |
191 trailingStepDone_(false) | |
192 { | |
193 } | |
194 | |
195 DummyInstancesJob(const Json::Value& value) : | |
196 SetOfInstancesJob(value) | |
197 { | |
198 if (HasTrailingStep()) | |
199 { | |
200 trailingStepDone_ = (GetPosition() == GetCommandsCount()); | |
201 } | |
202 else | |
203 { | |
204 trailingStepDone_ = false; | |
205 } | |
206 } | |
207 | |
208 bool IsTrailingStepDone() const | |
209 { | |
210 return trailingStepDone_; | |
211 } | |
212 | |
213 virtual void Stop(JobStopReason reason) ORTHANC_OVERRIDE | |
214 { | |
215 } | |
216 | |
217 virtual void GetJobType(std::string& s) ORTHANC_OVERRIDE | |
218 { | |
219 s = "DummyInstancesJob"; | |
220 } | |
221 }; | |
222 | |
223 | |
224 class DummyUnserializer : public GenericJobUnserializer | |
225 { | |
226 public: | |
227 virtual IJob* UnserializeJob(const Json::Value& value) ORTHANC_OVERRIDE | |
228 { | |
229 if (SerializationToolbox::ReadString(value, "Type") == "DummyInstancesJob") | |
230 { | |
231 return new DummyInstancesJob(value); | |
232 } | |
233 else if (SerializationToolbox::ReadString(value, "Type") == "DummyJob") | |
234 { | |
235 return new DummyJob; | |
236 } | |
237 else | |
238 { | |
239 return GenericJobUnserializer::UnserializeJob(value); | |
240 } | |
241 } | |
242 }; | |
243 | |
244 | |
245 class DynamicInteger : public IDynamicObject | |
246 { | |
247 private: | |
248 int value_; | |
249 std::set<int>& target_; | |
250 | |
251 public: | |
252 DynamicInteger(int value, std::set<int>& target) : | |
253 value_(value), target_(target) | |
254 { | |
255 } | |
256 | |
257 int GetValue() const | |
258 { | |
259 return value_; | |
260 } | |
261 }; | |
262 } | |
263 | |
264 | |
265 TEST(MultiThreading, SharedMessageQueueBasic) | |
266 { | |
267 std::set<int> s; | |
268 | |
269 SharedMessageQueue q; | |
270 ASSERT_TRUE(q.WaitEmpty(0)); | |
271 q.Enqueue(new DynamicInteger(10, s)); | |
272 ASSERT_FALSE(q.WaitEmpty(1)); | |
273 q.Enqueue(new DynamicInteger(20, s)); | |
274 q.Enqueue(new DynamicInteger(30, s)); | |
275 q.Enqueue(new DynamicInteger(40, s)); | |
276 | |
277 std::unique_ptr<DynamicInteger> i; | |
278 i.reset(dynamic_cast<DynamicInteger*>(q.Dequeue(1))); ASSERT_EQ(10, i->GetValue()); | |
279 i.reset(dynamic_cast<DynamicInteger*>(q.Dequeue(1))); ASSERT_EQ(20, i->GetValue()); | |
280 i.reset(dynamic_cast<DynamicInteger*>(q.Dequeue(1))); ASSERT_EQ(30, i->GetValue()); | |
281 ASSERT_FALSE(q.WaitEmpty(1)); | |
282 i.reset(dynamic_cast<DynamicInteger*>(q.Dequeue(1))); ASSERT_EQ(40, i->GetValue()); | |
283 ASSERT_TRUE(q.WaitEmpty(0)); | |
284 ASSERT_EQ(NULL, q.Dequeue(1)); | |
285 } | |
286 | |
287 | |
288 TEST(MultiThreading, SharedMessageQueueClean) | |
289 { | |
290 std::set<int> s; | |
291 | |
292 try | |
293 { | |
294 SharedMessageQueue q; | |
295 q.Enqueue(new DynamicInteger(10, s)); | |
296 q.Enqueue(new DynamicInteger(20, s)); | |
297 throw OrthancException(ErrorCode_InternalError); | |
298 } | |
299 catch (OrthancException&) | |
300 { | |
301 } | |
302 } | |
303 | |
304 | |
305 | |
306 | |
307 static bool CheckState(JobsRegistry& registry, | |
308 const std::string& id, | |
309 JobState state) | |
310 { | |
311 JobState s; | |
312 if (registry.GetState(s, id)) | |
313 { | |
314 return state == s; | |
315 } | |
316 else | |
317 { | |
318 return false; | |
319 } | |
320 } | |
321 | |
322 | |
323 static bool CheckErrorCode(JobsRegistry& registry, | |
324 const std::string& id, | |
325 ErrorCode code) | |
326 { | |
327 JobInfo s; | |
328 if (registry.GetJobInfo(s, id)) | |
329 { | |
330 return code == s.GetStatus().GetErrorCode(); | |
331 } | |
332 else | |
333 { | |
334 return false; | |
335 } | |
336 } | |
337 | |
338 | |
339 TEST(JobsRegistry, Priority) | |
340 { | |
341 JobsRegistry registry(10); | |
342 | |
343 std::string i1, i2, i3, i4; | |
344 registry.Submit(i1, new DummyJob(), 10); | |
345 registry.Submit(i2, new DummyJob(), 30); | |
346 registry.Submit(i3, new DummyJob(), 20); | |
347 registry.Submit(i4, new DummyJob(), 5); | |
348 | |
349 registry.SetMaxCompletedJobs(2); | |
350 | |
351 std::set<std::string> id; | |
352 registry.ListJobs(id); | |
353 | |
354 ASSERT_EQ(4u, id.size()); | |
355 ASSERT_TRUE(id.find(i1) != id.end()); | |
356 ASSERT_TRUE(id.find(i2) != id.end()); | |
357 ASSERT_TRUE(id.find(i3) != id.end()); | |
358 ASSERT_TRUE(id.find(i4) != id.end()); | |
359 | |
360 ASSERT_TRUE(CheckState(registry, i2, JobState_Pending)); | |
361 | |
362 { | |
363 JobsRegistry::RunningJob job(registry, 0); | |
364 ASSERT_TRUE(job.IsValid()); | |
365 ASSERT_EQ(30, job.GetPriority()); | |
366 ASSERT_EQ(i2, job.GetId()); | |
367 | |
368 ASSERT_TRUE(CheckState(registry, i2, JobState_Running)); | |
369 } | |
370 | |
371 ASSERT_TRUE(CheckState(registry, i2, JobState_Failure)); | |
372 ASSERT_TRUE(CheckState(registry, i3, JobState_Pending)); | |
373 | |
374 { | |
375 JobsRegistry::RunningJob job(registry, 0); | |
376 ASSERT_TRUE(job.IsValid()); | |
377 ASSERT_EQ(20, job.GetPriority()); | |
378 ASSERT_EQ(i3, job.GetId()); | |
379 | |
380 job.MarkSuccess(); | |
381 | |
382 ASSERT_TRUE(CheckState(registry, i3, JobState_Running)); | |
383 } | |
384 | |
385 ASSERT_TRUE(CheckState(registry, i3, JobState_Success)); | |
386 | |
387 { | |
388 JobsRegistry::RunningJob job(registry, 0); | |
389 ASSERT_TRUE(job.IsValid()); | |
390 ASSERT_EQ(10, job.GetPriority()); | |
391 ASSERT_EQ(i1, job.GetId()); | |
392 } | |
393 | |
394 { | |
395 JobsRegistry::RunningJob job(registry, 0); | |
396 ASSERT_TRUE(job.IsValid()); | |
397 ASSERT_EQ(5, job.GetPriority()); | |
398 ASSERT_EQ(i4, job.GetId()); | |
399 } | |
400 | |
401 { | |
402 JobsRegistry::RunningJob job(registry, 1); | |
403 ASSERT_FALSE(job.IsValid()); | |
404 } | |
405 | |
406 JobState s; | |
407 ASSERT_TRUE(registry.GetState(s, i1)); | |
408 ASSERT_FALSE(registry.GetState(s, i2)); // Removed because oldest | |
409 ASSERT_FALSE(registry.GetState(s, i3)); // Removed because second oldest | |
410 ASSERT_TRUE(registry.GetState(s, i4)); | |
411 | |
412 registry.SetMaxCompletedJobs(1); // (*) | |
413 ASSERT_FALSE(registry.GetState(s, i1)); // Just discarded by (*) | |
414 ASSERT_TRUE(registry.GetState(s, i4)); | |
415 } | |
416 | |
417 | |
418 TEST(JobsRegistry, Simultaneous) | |
419 { | |
420 JobsRegistry registry(10); | |
421 | |
422 std::string i1, i2; | |
423 registry.Submit(i1, new DummyJob(), 20); | |
424 registry.Submit(i2, new DummyJob(), 10); | |
425 | |
426 ASSERT_TRUE(CheckState(registry, i1, JobState_Pending)); | |
427 ASSERT_TRUE(CheckState(registry, i2, JobState_Pending)); | |
428 | |
429 { | |
430 JobsRegistry::RunningJob job1(registry, 0); | |
431 JobsRegistry::RunningJob job2(registry, 0); | |
432 | |
433 ASSERT_TRUE(job1.IsValid()); | |
434 ASSERT_TRUE(job2.IsValid()); | |
435 | |
436 job1.MarkFailure(); | |
437 job2.MarkSuccess(); | |
438 | |
439 ASSERT_TRUE(CheckState(registry, i1, JobState_Running)); | |
440 ASSERT_TRUE(CheckState(registry, i2, JobState_Running)); | |
441 } | |
442 | |
443 ASSERT_TRUE(CheckState(registry, i1, JobState_Failure)); | |
444 ASSERT_TRUE(CheckState(registry, i2, JobState_Success)); | |
445 } | |
446 | |
447 | |
448 TEST(JobsRegistry, Resubmit) | |
449 { | |
450 JobsRegistry registry(10); | |
451 | |
452 std::string id; | |
453 registry.Submit(id, new DummyJob(), 10); | |
454 | |
455 ASSERT_TRUE(CheckState(registry, id, JobState_Pending)); | |
456 | |
457 registry.Resubmit(id); | |
458 ASSERT_TRUE(CheckState(registry, id, JobState_Pending)); | |
459 | |
460 { | |
461 JobsRegistry::RunningJob job(registry, 0); | |
462 ASSERT_TRUE(job.IsValid()); | |
463 job.MarkFailure(); | |
464 | |
465 ASSERT_TRUE(CheckState(registry, id, JobState_Running)); | |
466 | |
467 registry.Resubmit(id); | |
468 ASSERT_TRUE(CheckState(registry, id, JobState_Running)); | |
469 } | |
470 | |
471 ASSERT_TRUE(CheckState(registry, id, JobState_Failure)); | |
472 | |
473 registry.Resubmit(id); | |
474 ASSERT_TRUE(CheckState(registry, id, JobState_Pending)); | |
475 | |
476 { | |
477 JobsRegistry::RunningJob job(registry, 0); | |
478 ASSERT_TRUE(job.IsValid()); | |
479 ASSERT_EQ(id, job.GetId()); | |
480 | |
481 job.MarkSuccess(); | |
482 ASSERT_TRUE(CheckState(registry, id, JobState_Running)); | |
483 } | |
484 | |
485 ASSERT_TRUE(CheckState(registry, id, JobState_Success)); | |
486 | |
487 registry.Resubmit(id); | |
488 ASSERT_TRUE(CheckState(registry, id, JobState_Success)); | |
489 } | |
490 | |
491 | |
492 TEST(JobsRegistry, Retry) | |
493 { | |
494 JobsRegistry registry(10); | |
495 | |
496 std::string id; | |
497 registry.Submit(id, new DummyJob(), 10); | |
498 | |
499 ASSERT_TRUE(CheckState(registry, id, JobState_Pending)); | |
500 | |
501 { | |
502 JobsRegistry::RunningJob job(registry, 0); | |
503 ASSERT_TRUE(job.IsValid()); | |
504 job.MarkRetry(0); | |
505 | |
506 ASSERT_TRUE(CheckState(registry, id, JobState_Running)); | |
507 } | |
508 | |
509 ASSERT_TRUE(CheckState(registry, id, JobState_Retry)); | |
510 | |
511 registry.Resubmit(id); | |
512 ASSERT_TRUE(CheckState(registry, id, JobState_Retry)); | |
513 | |
514 registry.ScheduleRetries(); | |
515 ASSERT_TRUE(CheckState(registry, id, JobState_Pending)); | |
516 | |
517 { | |
518 JobsRegistry::RunningJob job(registry, 0); | |
519 ASSERT_TRUE(job.IsValid()); | |
520 job.MarkSuccess(); | |
521 | |
522 ASSERT_TRUE(CheckState(registry, id, JobState_Running)); | |
523 } | |
524 | |
525 ASSERT_TRUE(CheckState(registry, id, JobState_Success)); | |
526 } | |
527 | |
528 | |
529 TEST(JobsRegistry, PausePending) | |
530 { | |
531 JobsRegistry registry(10); | |
532 | |
533 std::string id; | |
534 registry.Submit(id, new DummyJob(), 10); | |
535 | |
536 ASSERT_TRUE(CheckState(registry, id, JobState_Pending)); | |
537 | |
538 registry.Pause(id); | |
539 ASSERT_TRUE(CheckState(registry, id, JobState_Paused)); | |
540 | |
541 registry.Pause(id); | |
542 ASSERT_TRUE(CheckState(registry, id, JobState_Paused)); | |
543 | |
544 registry.Resubmit(id); | |
545 ASSERT_TRUE(CheckState(registry, id, JobState_Paused)); | |
546 | |
547 registry.Resume(id); | |
548 ASSERT_TRUE(CheckState(registry, id, JobState_Pending)); | |
549 } | |
550 | |
551 | |
552 TEST(JobsRegistry, PauseRunning) | |
553 { | |
554 JobsRegistry registry(10); | |
555 | |
556 std::string id; | |
557 registry.Submit(id, new DummyJob(), 10); | |
558 | |
559 ASSERT_TRUE(CheckState(registry, id, JobState_Pending)); | |
560 | |
561 { | |
562 JobsRegistry::RunningJob job(registry, 0); | |
563 ASSERT_TRUE(job.IsValid()); | |
564 | |
565 registry.Resubmit(id); | |
566 job.MarkPause(); | |
567 ASSERT_TRUE(CheckState(registry, id, JobState_Running)); | |
568 } | |
569 | |
570 ASSERT_TRUE(CheckState(registry, id, JobState_Paused)); | |
571 | |
572 registry.Resubmit(id); | |
573 ASSERT_TRUE(CheckState(registry, id, JobState_Paused)); | |
574 | |
575 registry.Resume(id); | |
576 ASSERT_TRUE(CheckState(registry, id, JobState_Pending)); | |
577 | |
578 { | |
579 JobsRegistry::RunningJob job(registry, 0); | |
580 ASSERT_TRUE(job.IsValid()); | |
581 | |
582 job.MarkSuccess(); | |
583 ASSERT_TRUE(CheckState(registry, id, JobState_Running)); | |
584 } | |
585 | |
586 ASSERT_TRUE(CheckState(registry, id, JobState_Success)); | |
587 } | |
588 | |
589 | |
590 TEST(JobsRegistry, PauseRetry) | |
591 { | |
592 JobsRegistry registry(10); | |
593 | |
594 std::string id; | |
595 registry.Submit(id, new DummyJob(), 10); | |
596 | |
597 ASSERT_TRUE(CheckState(registry, id, JobState_Pending)); | |
598 | |
599 { | |
600 JobsRegistry::RunningJob job(registry, 0); | |
601 ASSERT_TRUE(job.IsValid()); | |
602 | |
603 job.MarkRetry(0); | |
604 ASSERT_TRUE(CheckState(registry, id, JobState_Running)); | |
605 } | |
606 | |
607 ASSERT_TRUE(CheckState(registry, id, JobState_Retry)); | |
608 | |
609 registry.Pause(id); | |
610 ASSERT_TRUE(CheckState(registry, id, JobState_Paused)); | |
611 | |
612 registry.Resume(id); | |
613 ASSERT_TRUE(CheckState(registry, id, JobState_Pending)); | |
614 | |
615 { | |
616 JobsRegistry::RunningJob job(registry, 0); | |
617 ASSERT_TRUE(job.IsValid()); | |
618 | |
619 job.MarkSuccess(); | |
620 ASSERT_TRUE(CheckState(registry, id, JobState_Running)); | |
621 } | |
622 | |
623 ASSERT_TRUE(CheckState(registry, id, JobState_Success)); | |
624 } | |
625 | |
626 | |
627 TEST(JobsRegistry, Cancel) | |
628 { | |
629 JobsRegistry registry(10); | |
630 | |
631 std::string id; | |
632 registry.Submit(id, new DummyJob(), 10); | |
633 | |
634 ASSERT_FALSE(registry.Cancel("nope")); | |
635 | |
636 ASSERT_TRUE(CheckState(registry, id, JobState_Pending)); | |
637 ASSERT_TRUE(CheckErrorCode(registry, id, ErrorCode_Success)); | |
638 | |
639 ASSERT_TRUE(registry.Cancel(id)); | |
640 ASSERT_TRUE(CheckState(registry, id, JobState_Failure)); | |
641 ASSERT_TRUE(CheckErrorCode(registry, id, ErrorCode_CanceledJob)); | |
642 | |
643 ASSERT_TRUE(registry.Cancel(id)); | |
644 ASSERT_TRUE(CheckState(registry, id, JobState_Failure)); | |
645 ASSERT_TRUE(CheckErrorCode(registry, id, ErrorCode_CanceledJob)); | |
646 | |
647 ASSERT_TRUE(registry.Resubmit(id)); | |
648 ASSERT_TRUE(CheckState(registry, id, JobState_Pending)); | |
649 ASSERT_TRUE(CheckErrorCode(registry, id, ErrorCode_CanceledJob)); | |
650 | |
651 { | |
652 JobsRegistry::RunningJob job(registry, 0); | |
653 ASSERT_TRUE(job.IsValid()); | |
654 | |
655 ASSERT_TRUE(CheckErrorCode(registry, id, ErrorCode_Success)); | |
656 | |
657 job.MarkSuccess(); | |
658 ASSERT_TRUE(CheckState(registry, id, JobState_Running)); | |
659 } | |
660 | |
661 ASSERT_TRUE(CheckState(registry, id, JobState_Success)); | |
662 ASSERT_TRUE(CheckErrorCode(registry, id, ErrorCode_Success)); | |
663 | |
664 ASSERT_TRUE(registry.Cancel(id)); | |
665 ASSERT_TRUE(CheckState(registry, id, JobState_Success)); | |
666 ASSERT_TRUE(CheckErrorCode(registry, id, ErrorCode_Success)); | |
667 | |
668 registry.Submit(id, new DummyJob(), 10); | |
669 | |
670 { | |
671 JobsRegistry::RunningJob job(registry, 0); | |
672 ASSERT_TRUE(job.IsValid()); | |
673 ASSERT_EQ(id, job.GetId()); | |
674 | |
675 ASSERT_TRUE(CheckErrorCode(registry, id, ErrorCode_Success)); | |
676 ASSERT_TRUE(CheckState(registry, id, JobState_Running)); | |
677 | |
678 job.MarkCanceled(); | |
679 } | |
680 | |
681 ASSERT_TRUE(CheckState(registry, id, JobState_Failure)); | |
682 ASSERT_TRUE(CheckErrorCode(registry, id, ErrorCode_CanceledJob)); | |
683 | |
684 ASSERT_TRUE(registry.Resubmit(id)); | |
685 ASSERT_TRUE(CheckState(registry, id, JobState_Pending)); | |
686 ASSERT_TRUE(CheckErrorCode(registry, id, ErrorCode_CanceledJob)); | |
687 | |
688 ASSERT_TRUE(registry.Pause(id)); | |
689 ASSERT_TRUE(CheckState(registry, id, JobState_Paused)); | |
690 ASSERT_TRUE(CheckErrorCode(registry, id, ErrorCode_CanceledJob)); | |
691 | |
692 ASSERT_TRUE(registry.Cancel(id)); | |
693 ASSERT_TRUE(CheckState(registry, id, JobState_Failure)); | |
694 ASSERT_TRUE(CheckErrorCode(registry, id, ErrorCode_CanceledJob)); | |
695 | |
696 ASSERT_TRUE(registry.Resubmit(id)); | |
697 ASSERT_TRUE(CheckState(registry, id, JobState_Pending)); | |
698 ASSERT_TRUE(CheckErrorCode(registry, id, ErrorCode_CanceledJob)); | |
699 | |
700 { | |
701 JobsRegistry::RunningJob job(registry, 0); | |
702 ASSERT_TRUE(job.IsValid()); | |
703 ASSERT_EQ(id, job.GetId()); | |
704 | |
705 ASSERT_TRUE(CheckErrorCode(registry, id, ErrorCode_Success)); | |
706 ASSERT_TRUE(CheckState(registry, id, JobState_Running)); | |
707 | |
708 job.MarkRetry(500); | |
709 } | |
710 | |
711 ASSERT_TRUE(CheckState(registry, id, JobState_Retry)); | |
712 ASSERT_TRUE(CheckErrorCode(registry, id, ErrorCode_Success)); | |
713 | |
714 ASSERT_TRUE(registry.Cancel(id)); | |
715 ASSERT_TRUE(CheckState(registry, id, JobState_Failure)); | |
716 ASSERT_TRUE(CheckErrorCode(registry, id, ErrorCode_CanceledJob)); | |
717 } | |
718 | |
719 | |
720 | |
721 TEST(JobsEngine, SubmitAndWait) | |
722 { | |
723 JobsEngine engine(10); | |
724 engine.SetThreadSleep(10); | |
725 engine.SetWorkersCount(3); | |
726 engine.Start(); | |
727 | |
728 Json::Value content = Json::nullValue; | |
729 engine.GetRegistry().SubmitAndWait(content, new DummyJob(), rand() % 10); | |
730 ASSERT_EQ(Json::objectValue, content.type()); | |
731 ASSERT_EQ("world", content["hello"].asString()); | |
732 | |
733 content = Json::nullValue; | |
734 ASSERT_THROW(engine.GetRegistry().SubmitAndWait(content, new DummyJob(true), rand() % 10), OrthancException); | |
735 ASSERT_EQ(Json::nullValue, content.type()); | |
736 | |
737 engine.Stop(); | |
738 } | |
739 | |
740 | |
741 TEST(JobsEngine, DISABLED_SequenceOfOperationsJob) | |
742 { | |
743 JobsEngine engine(10); | |
744 engine.SetThreadSleep(10); | |
745 engine.SetWorkersCount(3); | |
746 engine.Start(); | |
747 | |
748 std::string id; | |
749 SequenceOfOperationsJob* job = NULL; | |
750 | |
751 { | |
752 std::unique_ptr<SequenceOfOperationsJob> a(new SequenceOfOperationsJob); | |
753 job = a.get(); | |
754 engine.GetRegistry().Submit(id, a.release(), 0); | |
755 } | |
756 | |
757 boost::this_thread::sleep(boost::posix_time::milliseconds(500)); | |
758 | |
759 { | |
760 SequenceOfOperationsJob::Lock lock(*job); | |
761 size_t i = lock.AddOperation(new LogJobOperation); | |
762 size_t j = lock.AddOperation(new LogJobOperation); | |
763 size_t k = lock.AddOperation(new LogJobOperation); | |
764 | |
765 StringOperationValue a("Hello"); | |
766 StringOperationValue b("World"); | |
767 lock.AddInput(i, a); | |
768 lock.AddInput(i, b); | |
769 | |
770 lock.Connect(i, j); | |
771 lock.Connect(j, k); | |
772 } | |
773 | |
774 boost::this_thread::sleep(boost::posix_time::milliseconds(2000)); | |
775 | |
776 engine.Stop(); | |
777 | |
778 } | |
779 | |
780 | |
781 TEST(JobsEngine, DISABLED_Lua) | |
782 { | |
783 JobsEngine engine(10); | |
784 engine.SetThreadSleep(10); | |
785 engine.SetWorkersCount(2); | |
786 engine.Start(); | |
787 | |
788 LuaJobManager lua; | |
789 lua.SetMaxOperationsPerJob(5); | |
790 lua.SetTrailingOperationTimeout(200); | |
791 | |
792 for (size_t i = 0; i < 30; i++) | |
793 { | |
794 boost::this_thread::sleep(boost::posix_time::milliseconds(150)); | |
795 | |
796 LuaJobManager::Lock lock(lua, engine); | |
797 size_t a = lock.AddLogOperation(); | |
798 size_t b = lock.AddLogOperation(); | |
799 size_t c = lock.AddSystemCallOperation("echo"); | |
800 lock.AddStringInput(a, boost::lexical_cast<std::string>(i)); | |
801 lock.AddNullInput(a); | |
802 lock.Connect(a, b); | |
803 lock.Connect(a, c); | |
804 } | |
805 | |
806 boost::this_thread::sleep(boost::posix_time::milliseconds(2000)); | |
807 | |
808 engine.Stop(); | |
809 } | |
810 | |
811 | |
812 static bool CheckSameJson(const Json::Value& a, | |
813 const Json::Value& b) | |
814 { | |
815 std::string s = a.toStyledString(); | |
816 std::string t = b.toStyledString(); | |
817 | |
818 if (s == t) | |
819 { | |
820 return true; | |
821 } | |
822 else | |
823 { | |
824 LOG(ERROR) << "Expected serialization: " << s; | |
825 LOG(ERROR) << "Actual serialization: " << t; | |
826 return false; | |
827 } | |
828 } | |
829 | |
830 | |
831 static bool CheckIdempotentSerialization(IJobUnserializer& unserializer, | |
832 IJob& job) | |
833 { | |
834 Json::Value a = 42; | |
835 | |
836 if (!job.Serialize(a)) | |
837 { | |
838 return false; | |
839 } | |
840 else | |
841 { | |
842 std::unique_ptr<IJob> unserialized(unserializer.UnserializeJob(a)); | |
843 | |
844 Json::Value b = 43; | |
845 if (unserialized->Serialize(b)) | |
846 { | |
847 return (CheckSameJson(a, b)); | |
848 } | |
849 else | |
850 { | |
851 return false; | |
852 } | |
853 } | |
854 } | |
855 | |
856 | |
857 static bool CheckIdempotentSetOfInstances(IJobUnserializer& unserializer, | |
858 SetOfInstancesJob& job) | |
859 { | |
860 Json::Value a = 42; | |
861 | |
862 if (!job.Serialize(a)) | |
863 { | |
864 return false; | |
865 } | |
866 else | |
867 { | |
868 std::unique_ptr<SetOfInstancesJob> unserialized | |
869 (dynamic_cast<SetOfInstancesJob*>(unserializer.UnserializeJob(a))); | |
870 | |
871 Json::Value b = 43; | |
872 if (unserialized->Serialize(b)) | |
873 { | |
874 return (CheckSameJson(a, b) && | |
875 job.HasTrailingStep() == unserialized->HasTrailingStep() && | |
876 job.GetPosition() == unserialized->GetPosition() && | |
877 job.GetInstancesCount() == unserialized->GetInstancesCount() && | |
878 job.GetCommandsCount() == unserialized->GetCommandsCount()); | |
879 } | |
880 else | |
881 { | |
882 return false; | |
883 } | |
884 } | |
885 } | |
886 | |
887 | |
888 static bool CheckIdempotentSerialization(IJobUnserializer& unserializer, | |
889 IJobOperation& operation) | |
890 { | |
891 Json::Value a = 42; | |
892 operation.Serialize(a); | |
893 | |
894 std::unique_ptr<IJobOperation> unserialized(unserializer.UnserializeOperation(a)); | |
895 | |
896 Json::Value b = 43; | |
897 unserialized->Serialize(b); | |
898 | |
899 return CheckSameJson(a, b); | |
900 } | |
901 | |
902 | |
903 static bool CheckIdempotentSerialization(IJobUnserializer& unserializer, | |
904 JobOperationValue& value) | |
905 { | |
906 Json::Value a = 42; | |
907 value.Serialize(a); | |
908 | |
909 std::unique_ptr<JobOperationValue> unserialized(unserializer.UnserializeValue(a)); | |
910 | |
911 Json::Value b = 43; | |
912 unserialized->Serialize(b); | |
913 | |
914 return CheckSameJson(a, b); | |
915 } | |
916 | |
917 | |
918 TEST(JobsSerialization, BadFileFormat) | |
919 { | |
920 GenericJobUnserializer unserializer; | |
921 | |
922 Json::Value s; | |
923 | |
924 s = Json::objectValue; | |
925 ASSERT_THROW(unserializer.UnserializeValue(s), OrthancException); | |
926 ASSERT_THROW(unserializer.UnserializeJob(s), OrthancException); | |
927 ASSERT_THROW(unserializer.UnserializeOperation(s), OrthancException); | |
928 | |
929 s = Json::arrayValue; | |
930 ASSERT_THROW(unserializer.UnserializeValue(s), OrthancException); | |
931 ASSERT_THROW(unserializer.UnserializeJob(s), OrthancException); | |
932 ASSERT_THROW(unserializer.UnserializeOperation(s), OrthancException); | |
933 | |
934 s = "hello"; | |
935 ASSERT_THROW(unserializer.UnserializeValue(s), OrthancException); | |
936 ASSERT_THROW(unserializer.UnserializeJob(s), OrthancException); | |
937 ASSERT_THROW(unserializer.UnserializeOperation(s), OrthancException); | |
938 | |
939 s = 42; | |
940 ASSERT_THROW(unserializer.UnserializeValue(s), OrthancException); | |
941 ASSERT_THROW(unserializer.UnserializeJob(s), OrthancException); | |
942 ASSERT_THROW(unserializer.UnserializeOperation(s), OrthancException); | |
943 } | |
944 | |
945 | |
946 TEST(JobsSerialization, JobOperationValues) | |
947 { | |
948 Json::Value s; | |
949 | |
950 { | |
951 JobOperationValues values; | |
952 values.Append(new NullOperationValue); | |
953 values.Append(new StringOperationValue("hello")); | |
954 values.Append(new StringOperationValue("world")); | |
955 | |
956 s = 42; | |
957 values.Serialize(s); | |
958 } | |
959 | |
960 { | |
961 GenericJobUnserializer unserializer; | |
962 std::unique_ptr<JobOperationValues> values(JobOperationValues::Unserialize(unserializer, s)); | |
963 ASSERT_EQ(3u, values->GetSize()); | |
964 ASSERT_EQ(JobOperationValue::Type_Null, values->GetValue(0).GetType()); | |
965 ASSERT_EQ(JobOperationValue::Type_String, values->GetValue(1).GetType()); | |
966 ASSERT_EQ(JobOperationValue::Type_String, values->GetValue(2).GetType()); | |
967 | |
968 ASSERT_EQ("hello", dynamic_cast<const StringOperationValue&>(values->GetValue(1)).GetContent()); | |
969 ASSERT_EQ("world", dynamic_cast<const StringOperationValue&>(values->GetValue(2)).GetContent()); | |
970 } | |
971 } | |
972 | |
973 | |
974 TEST(JobsSerialization, GenericValues) | |
975 { | |
976 GenericJobUnserializer unserializer; | |
977 Json::Value s; | |
978 | |
979 { | |
980 NullOperationValue null; | |
981 | |
982 ASSERT_TRUE(CheckIdempotentSerialization(unserializer, null)); | |
983 null.Serialize(s); | |
984 } | |
985 | |
986 ASSERT_THROW(unserializer.UnserializeJob(s), OrthancException); | |
987 ASSERT_THROW(unserializer.UnserializeOperation(s), OrthancException); | |
988 | |
989 std::unique_ptr<JobOperationValue> value; | |
990 value.reset(unserializer.UnserializeValue(s)); | |
991 | |
992 ASSERT_EQ(JobOperationValue::Type_Null, value->GetType()); | |
993 | |
994 { | |
995 StringOperationValue str("Hello"); | |
996 | |
997 ASSERT_TRUE(CheckIdempotentSerialization(unserializer, str)); | |
998 str.Serialize(s); | |
999 } | |
1000 | |
1001 ASSERT_THROW(unserializer.UnserializeJob(s), OrthancException); | |
1002 ASSERT_THROW(unserializer.UnserializeOperation(s), OrthancException); | |
1003 value.reset(unserializer.UnserializeValue(s)); | |
1004 | |
1005 ASSERT_EQ(JobOperationValue::Type_String, value->GetType()); | |
1006 ASSERT_EQ("Hello", dynamic_cast<StringOperationValue&>(*value).GetContent()); | |
1007 } | |
1008 | |
1009 | |
1010 TEST(JobsSerialization, GenericOperations) | |
1011 { | |
1012 DummyUnserializer unserializer; | |
1013 Json::Value s; | |
1014 | |
1015 { | |
1016 LogJobOperation operation; | |
1017 | |
1018 ASSERT_TRUE(CheckIdempotentSerialization(unserializer, operation)); | |
1019 operation.Serialize(s); | |
1020 } | |
1021 | |
1022 ASSERT_THROW(unserializer.UnserializeJob(s), OrthancException); | |
1023 ASSERT_THROW(unserializer.UnserializeValue(s), OrthancException); | |
1024 | |
1025 { | |
1026 std::unique_ptr<IJobOperation> operation; | |
1027 operation.reset(unserializer.UnserializeOperation(s)); | |
1028 | |
1029 // Make sure that we have indeed unserialized a log operation | |
1030 Json::Value dummy; | |
1031 ASSERT_THROW(dynamic_cast<DeleteResourceOperation&>(*operation).Serialize(dummy), std::bad_cast); | |
1032 dynamic_cast<LogJobOperation&>(*operation).Serialize(dummy); | |
1033 } | |
1034 } | |
1035 | |
1036 | |
1037 TEST(JobsSerialization, GenericJobs) | |
1038 { | |
1039 Json::Value s; | |
1040 | |
1041 // This tests SetOfInstancesJob | |
1042 | |
1043 { | |
1044 DummyInstancesJob job; | |
1045 job.SetDescription("description"); | |
1046 job.AddInstance("hello"); | |
1047 job.AddInstance("nope"); | |
1048 job.AddInstance("world"); | |
1049 job.SetPermissive(true); | |
1050 ASSERT_THROW(job.Step("jobId"), OrthancException); // Not started yet | |
1051 ASSERT_FALSE(job.HasTrailingStep()); | |
1052 ASSERT_FALSE(job.IsTrailingStepDone()); | |
1053 job.Start(); | |
1054 ASSERT_EQ(JobStepCode_Continue, job.Step("jobId").GetCode()); | |
1055 ASSERT_EQ(JobStepCode_Continue, job.Step("jobId").GetCode()); | |
1056 | |
1057 { | |
1058 DummyUnserializer unserializer; | |
1059 ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); | |
1060 } | |
1061 | |
1062 ASSERT_TRUE(job.Serialize(s)); | |
1063 } | |
1064 | |
1065 { | |
1066 DummyUnserializer unserializer; | |
1067 ASSERT_THROW(unserializer.UnserializeValue(s), OrthancException); | |
1068 ASSERT_THROW(unserializer.UnserializeOperation(s), OrthancException); | |
1069 | |
1070 std::unique_ptr<IJob> job; | |
1071 job.reset(unserializer.UnserializeJob(s)); | |
1072 | |
1073 const DummyInstancesJob& tmp = dynamic_cast<const DummyInstancesJob&>(*job); | |
1074 ASSERT_FALSE(tmp.IsStarted()); | |
1075 ASSERT_TRUE(tmp.IsPermissive()); | |
1076 ASSERT_EQ("description", tmp.GetDescription()); | |
1077 ASSERT_EQ(3u, tmp.GetInstancesCount()); | |
1078 ASSERT_EQ(2u, tmp.GetPosition()); | |
1079 ASSERT_EQ(1u, tmp.GetFailedInstances().size()); | |
1080 ASSERT_EQ("hello", tmp.GetInstance(0)); | |
1081 ASSERT_EQ("nope", tmp.GetInstance(1)); | |
1082 ASSERT_EQ("world", tmp.GetInstance(2)); | |
1083 ASSERT_TRUE(tmp.IsFailedInstance("nope")); | |
1084 } | |
1085 | |
1086 // SequenceOfOperationsJob | |
1087 | |
1088 { | |
1089 SequenceOfOperationsJob job; | |
1090 job.SetDescription("hello"); | |
1091 | |
1092 { | |
1093 SequenceOfOperationsJob::Lock lock(job); | |
1094 size_t a = lock.AddOperation(new LogJobOperation); | |
1095 size_t b = lock.AddOperation(new LogJobOperation); | |
1096 lock.Connect(a, b); | |
1097 | |
1098 StringOperationValue s1("hello"); | |
1099 StringOperationValue s2("world"); | |
1100 lock.AddInput(a, s1); | |
1101 lock.AddInput(a, s2); | |
1102 lock.SetTrailingOperationTimeout(300); | |
1103 } | |
1104 | |
1105 ASSERT_EQ(JobStepCode_Continue, job.Step("jobId").GetCode()); | |
1106 | |
1107 { | |
1108 GenericJobUnserializer unserializer; | |
1109 ASSERT_TRUE(CheckIdempotentSerialization(unserializer, job)); | |
1110 } | |
1111 | |
1112 ASSERT_TRUE(job.Serialize(s)); | |
1113 } | |
1114 | |
1115 { | |
1116 GenericJobUnserializer unserializer; | |
1117 ASSERT_THROW(unserializer.UnserializeValue(s), OrthancException); | |
1118 ASSERT_THROW(unserializer.UnserializeOperation(s), OrthancException); | |
1119 | |
1120 std::unique_ptr<IJob> job; | |
1121 job.reset(unserializer.UnserializeJob(s)); | |
1122 | |
1123 std::string tmp; | |
1124 dynamic_cast<SequenceOfOperationsJob&>(*job).GetDescription(tmp); | |
1125 ASSERT_EQ("hello", tmp); | |
1126 } | |
1127 } | |
1128 | |
1129 | |
1130 static bool IsSameTagValue(ParsedDicomFile& dicom1, | |
1131 ParsedDicomFile& dicom2, | |
1132 DicomTag tag) | |
1133 { | |
1134 std::string a, b; | |
1135 return (dicom1.GetTagValue(a, tag) && | |
1136 dicom2.GetTagValue(b, tag) && | |
1137 (a == b)); | |
1138 } | |
1139 | |
1140 | |
1141 | |
1142 TEST(JobsSerialization, DicomModification) | |
1143 { | |
1144 Json::Value s; | |
1145 | |
1146 ParsedDicomFile source(true); | |
1147 source.Insert(DICOM_TAG_STUDY_DESCRIPTION, "Test 1", false, ""); | |
1148 source.Insert(DICOM_TAG_SERIES_DESCRIPTION, "Test 2", false, ""); | |
1149 source.Insert(DICOM_TAG_PATIENT_NAME, "Test 3", false, ""); | |
1150 | |
1151 std::unique_ptr<ParsedDicomFile> modified(source.Clone(true)); | |
1152 | |
1153 { | |
1154 DicomModification modification; | |
1155 modification.SetLevel(ResourceType_Series); | |
1156 modification.Clear(DICOM_TAG_STUDY_DESCRIPTION); | |
1157 modification.Remove(DICOM_TAG_SERIES_DESCRIPTION); | |
1158 modification.Replace(DICOM_TAG_PATIENT_NAME, "Test 4", true); | |
1159 | |
1160 modification.Apply(*modified); | |
1161 | |
1162 s = 42; | |
1163 modification.Serialize(s); | |
1164 } | |
1165 | |
1166 { | |
1167 DicomModification modification(s); | |
1168 ASSERT_EQ(ResourceType_Series, modification.GetLevel()); | |
1169 | |
1170 std::unique_ptr<ParsedDicomFile> second(source.Clone(true)); | |
1171 modification.Apply(*second); | |
1172 | |
1173 std::string s; | |
1174 ASSERT_TRUE(second->GetTagValue(s, DICOM_TAG_STUDY_DESCRIPTION)); | |
1175 ASSERT_TRUE(s.empty()); | |
1176 ASSERT_FALSE(second->GetTagValue(s, DICOM_TAG_SERIES_DESCRIPTION)); | |
1177 ASSERT_TRUE(second->GetTagValue(s, DICOM_TAG_PATIENT_NAME)); | |
1178 ASSERT_EQ("Test 4", s); | |
1179 | |
1180 ASSERT_TRUE(IsSameTagValue(source, *modified, DICOM_TAG_STUDY_INSTANCE_UID)); | |
1181 ASSERT_TRUE(IsSameTagValue(source, *second, DICOM_TAG_STUDY_INSTANCE_UID)); | |
1182 | |
1183 ASSERT_FALSE(IsSameTagValue(source, *second, DICOM_TAG_SERIES_INSTANCE_UID)); | |
1184 ASSERT_TRUE(IsSameTagValue(*modified, *second, DICOM_TAG_SERIES_INSTANCE_UID)); | |
1185 } | |
1186 } | |
1187 | |
1188 | |
1189 TEST(JobsSerialization, DicomInstanceOrigin) | |
1190 { | |
1191 Json::Value s; | |
1192 std::string t; | |
1193 | |
1194 { | |
1195 DicomInstanceOrigin origin; | |
1196 | |
1197 s = 42; | |
1198 origin.Serialize(s); | |
1199 } | |
1200 | |
1201 { | |
1202 DicomInstanceOrigin origin(s); | |
1203 ASSERT_EQ(RequestOrigin_Unknown, origin.GetRequestOrigin()); | |
1204 ASSERT_EQ("", std::string(origin.GetRemoteAetC())); | |
1205 ASSERT_FALSE(origin.LookupRemoteIp(t)); | |
1206 ASSERT_FALSE(origin.LookupRemoteAet(t)); | |
1207 ASSERT_FALSE(origin.LookupCalledAet(t)); | |
1208 ASSERT_FALSE(origin.LookupHttpUsername(t)); | |
1209 } | |
1210 | |
1211 { | |
1212 DicomInstanceOrigin origin(DicomInstanceOrigin::FromDicomProtocol("host", "aet", "called")); | |
1213 | |
1214 s = 42; | |
1215 origin.Serialize(s); | |
1216 } | |
1217 | |
1218 { | |
1219 DicomInstanceOrigin origin(s); | |
1220 ASSERT_EQ(RequestOrigin_DicomProtocol, origin.GetRequestOrigin()); | |
1221 ASSERT_EQ("aet", std::string(origin.GetRemoteAetC())); | |
1222 ASSERT_TRUE(origin.LookupRemoteIp(t)); ASSERT_EQ("host", t); | |
1223 ASSERT_TRUE(origin.LookupRemoteAet(t)); ASSERT_EQ("aet", t); | |
1224 ASSERT_TRUE(origin.LookupCalledAet(t)); ASSERT_EQ("called", t); | |
1225 ASSERT_FALSE(origin.LookupHttpUsername(t)); | |
1226 } | |
1227 | |
1228 { | |
1229 DicomInstanceOrigin origin(DicomInstanceOrigin::FromHttp("host", "username")); | |
1230 | |
1231 s = 42; | |
1232 origin.Serialize(s); | |
1233 } | |
1234 | |
1235 { | |
1236 DicomInstanceOrigin origin(s); | |
1237 ASSERT_EQ(RequestOrigin_RestApi, origin.GetRequestOrigin()); | |
1238 ASSERT_EQ("", std::string(origin.GetRemoteAetC())); | |
1239 ASSERT_TRUE(origin.LookupRemoteIp(t)); ASSERT_EQ("host", t); | |
1240 ASSERT_FALSE(origin.LookupRemoteAet(t)); | |
1241 ASSERT_FALSE(origin.LookupCalledAet(t)); | |
1242 ASSERT_TRUE(origin.LookupHttpUsername(t)); ASSERT_EQ("username", t); | |
1243 } | |
1244 | |
1245 { | |
1246 DicomInstanceOrigin origin(DicomInstanceOrigin::FromLua()); | |
1247 | |
1248 s = 42; | |
1249 origin.Serialize(s); | |
1250 } | |
1251 | |
1252 { | |
1253 DicomInstanceOrigin origin(s); | |
1254 ASSERT_EQ(RequestOrigin_Lua, origin.GetRequestOrigin()); | |
1255 ASSERT_FALSE(origin.LookupRemoteIp(t)); | |
1256 ASSERT_FALSE(origin.LookupRemoteAet(t)); | |
1257 ASSERT_FALSE(origin.LookupCalledAet(t)); | |
1258 ASSERT_FALSE(origin.LookupHttpUsername(t)); | |
1259 } | |
1260 | |
1261 { | |
1262 DicomInstanceOrigin origin(DicomInstanceOrigin::FromPlugins()); | |
1263 | |
1264 s = 42; | |
1265 origin.Serialize(s); | |
1266 } | |
1267 | |
1268 { | |
1269 DicomInstanceOrigin origin(s); | |
1270 ASSERT_EQ(RequestOrigin_Plugins, origin.GetRequestOrigin()); | |
1271 ASSERT_FALSE(origin.LookupRemoteIp(t)); | |
1272 ASSERT_FALSE(origin.LookupRemoteAet(t)); | |
1273 ASSERT_FALSE(origin.LookupCalledAet(t)); | |
1274 ASSERT_FALSE(origin.LookupHttpUsername(t)); | |
1275 } | |
1276 } | |
1277 | |
1278 | |
1279 namespace | |
1280 { | |
1281 class OrthancJobsSerialization : public testing::Test | |
1282 { | |
1283 private: | |
1284 MemoryStorageArea storage_; | |
1285 SQLiteDatabaseWrapper db_; // The SQLite DB is in memory | |
1286 std::unique_ptr<ServerContext> context_; | |
1287 | |
1288 public: | |
1289 OrthancJobsSerialization() | |
1290 { | |
1291 db_.Open(); | |
1292 context_.reset(new ServerContext(db_, storage_, true /* running unit tests */, 10)); | |
1293 context_->SetupJobsEngine(true, false); | |
1294 } | |
1295 | |
1296 virtual ~OrthancJobsSerialization() ORTHANC_OVERRIDE | |
1297 { | |
1298 context_->Stop(); | |
1299 context_.reset(NULL); | |
1300 db_.Close(); | |
1301 } | |
1302 | |
1303 ServerContext& GetContext() | |
1304 { | |
1305 return *context_; | |
1306 } | |
1307 | |
1308 bool CreateInstance(std::string& id) | |
1309 { | |
1310 // Create a sample DICOM file | |
1311 ParsedDicomFile dicom(true); | |
1312 dicom.Replace(DICOM_TAG_PATIENT_NAME, std::string("JODOGNE"), | |
1313 false, DicomReplaceMode_InsertIfAbsent, ""); | |
1314 | |
1315 DicomInstanceToStore toStore; | |
1316 toStore.SetParsedDicomFile(dicom); | |
1317 | |
1318 return (context_->Store(id, toStore, StoreInstanceMode_Default) == StoreStatus_Success); | |
1319 } | |
1320 }; | |
1321 } | |
1322 | |
1323 | |
1324 TEST_F(OrthancJobsSerialization, Values) | |
1325 { | |
1326 std::string id; | |
1327 ASSERT_TRUE(CreateInstance(id)); | |
1328 | |
1329 Json::Value s; | |
1330 OrthancJobUnserializer unserializer(GetContext()); | |
1331 | |
1332 { | |
1333 DicomInstanceOperationValue instance(GetContext(), id); | |
1334 | |
1335 ASSERT_TRUE(CheckIdempotentSerialization(unserializer, instance)); | |
1336 instance.Serialize(s); | |
1337 } | |
1338 | |
1339 std::unique_ptr<JobOperationValue> value; | |
1340 value.reset(unserializer.UnserializeValue(s)); | |
1341 ASSERT_EQ(JobOperationValue::Type_DicomInstance, value->GetType()); | |
1342 ASSERT_EQ(id, dynamic_cast<DicomInstanceOperationValue&>(*value).GetId()); | |
1343 | |
1344 { | |
1345 std::string content; | |
1346 dynamic_cast<DicomInstanceOperationValue&>(*value).ReadDicom(content); | |
1347 | |
1348 ParsedDicomFile dicom(content); | |
1349 ASSERT_TRUE(dicom.GetTagValue(content, DICOM_TAG_PATIENT_NAME)); | |
1350 ASSERT_EQ("JODOGNE", content); | |
1351 } | |
1352 } | |
1353 | |
1354 | |
1355 TEST_F(OrthancJobsSerialization, Operations) | |
1356 { | |
1357 std::string id; | |
1358 ASSERT_TRUE(CreateInstance(id)); | |
1359 | |
1360 Json::Value s; | |
1361 OrthancJobUnserializer unserializer(GetContext()); | |
1362 | |
1363 // DeleteResourceOperation | |
1364 | |
1365 { | |
1366 DeleteResourceOperation operation(GetContext()); | |
1367 | |
1368 ASSERT_TRUE(CheckIdempotentSerialization(unserializer, operation)); | |
1369 operation.Serialize(s); | |
1370 } | |
1371 | |
1372 std::unique_ptr<IJobOperation> operation; | |
1373 | |
1374 { | |
1375 operation.reset(unserializer.UnserializeOperation(s)); | |
1376 | |
1377 Json::Value dummy; | |
1378 ASSERT_THROW(dynamic_cast<LogJobOperation&>(*operation).Serialize(dummy), std::bad_cast); | |
1379 dynamic_cast<DeleteResourceOperation&>(*operation).Serialize(dummy); | |
1380 } | |
1381 | |
1382 // StorePeerOperation | |
1383 | |
1384 { | |
1385 WebServiceParameters peer; | |
1386 peer.SetUrl("http://localhost/"); | |
1387 peer.SetCredentials("username", "password"); | |
1388 peer.SetPkcs11Enabled(true); | |
1389 | |
1390 StorePeerOperation operation(peer); | |
1391 | |
1392 ASSERT_TRUE(CheckIdempotentSerialization(unserializer, operation)); | |
1393 operation.Serialize(s); | |
1394 } | |
1395 | |
1396 { | |
1397 operation.reset(unserializer.UnserializeOperation(s)); | |
1398 | |
1399 const StorePeerOperation& tmp = dynamic_cast<StorePeerOperation&>(*operation); | |
1400 ASSERT_EQ("http://localhost/", tmp.GetPeer().GetUrl()); | |
1401 ASSERT_EQ("username", tmp.GetPeer().GetUsername()); | |
1402 ASSERT_EQ("password", tmp.GetPeer().GetPassword()); | |
1403 ASSERT_TRUE(tmp.GetPeer().IsPkcs11Enabled()); | |
1404 } | |
1405 | |
1406 // StoreScuOperation | |
1407 | |
1408 { | |
1409 TimeoutDicomConnectionManager luaManager; | |
1410 | |
1411 { | |
1412 RemoteModalityParameters modality; | |
1413 modality.SetApplicationEntityTitle("REMOTE"); | |
1414 modality.SetHost("192.168.1.1"); | |
1415 modality.SetPortNumber(1000); | |
1416 modality.SetManufacturer(ModalityManufacturer_StoreScp); | |
1417 | |
1418 StoreScuOperation operation(GetContext(), luaManager, "TEST", modality); | |
1419 | |
1420 ASSERT_TRUE(CheckIdempotentSerialization(unserializer, operation)); | |
1421 operation.Serialize(s); | |
1422 } | |
1423 | |
1424 { | |
1425 operation.reset(unserializer.UnserializeOperation(s)); | |
1426 | |
1427 const StoreScuOperation& tmp = dynamic_cast<StoreScuOperation&>(*operation); | |
1428 ASSERT_EQ("REMOTE", tmp.GetRemoteModality().GetApplicationEntityTitle()); | |
1429 ASSERT_EQ("192.168.1.1", tmp.GetRemoteModality().GetHost()); | |
1430 ASSERT_EQ(1000, tmp.GetRemoteModality().GetPortNumber()); | |
1431 ASSERT_EQ(ModalityManufacturer_StoreScp, tmp.GetRemoteModality().GetManufacturer()); | |
1432 ASSERT_EQ("TEST", tmp.GetLocalAet()); | |
1433 } | |
1434 } | |
1435 | |
1436 // SystemCallOperation | |
1437 | |
1438 { | |
1439 SystemCallOperation operation(std::string("echo")); | |
1440 operation.AddPreArgument("a"); | |
1441 operation.AddPreArgument("b"); | |
1442 operation.AddPostArgument("c"); | |
1443 | |
1444 ASSERT_TRUE(CheckIdempotentSerialization(unserializer, operation)); | |
1445 operation.Serialize(s); | |
1446 } | |
1447 | |
1448 { | |
1449 operation.reset(unserializer.UnserializeOperation(s)); | |
1450 | |
1451 const SystemCallOperation& tmp = dynamic_cast<SystemCallOperation&>(*operation); | |
1452 ASSERT_EQ("echo", tmp.GetCommand()); | |
1453 ASSERT_EQ(2u, tmp.GetPreArgumentsCount()); | |
1454 ASSERT_EQ(1u, tmp.GetPostArgumentsCount()); | |
1455 ASSERT_EQ("a", tmp.GetPreArgument(0)); | |
1456 ASSERT_EQ("b", tmp.GetPreArgument(1)); | |
1457 ASSERT_EQ("c", tmp.GetPostArgument(0)); | |
1458 } | |
1459 | |
1460 // ModifyInstanceOperation | |
1461 | |
1462 { | |
1463 std::unique_ptr<DicomModification> modification(new DicomModification); | |
1464 modification->SetupAnonymization(DicomVersion_2008); | |
1465 | |
1466 ModifyInstanceOperation operation(GetContext(), RequestOrigin_Lua, modification.release()); | |
1467 | |
1468 ASSERT_TRUE(CheckIdempotentSerialization(unserializer, operation)); | |
1469 operation.Serialize(s); | |
1470 } | |
1471 | |
1472 { | |
1473 operation.reset(unserializer.UnserializeOperation(s)); | |
1474 | |
1475 const ModifyInstanceOperation& tmp = dynamic_cast<ModifyInstanceOperation&>(*operation); | |
1476 ASSERT_EQ(RequestOrigin_Lua, tmp.GetRequestOrigin()); | |
1477 ASSERT_TRUE(tmp.GetModification().IsRemoved(DICOM_TAG_STUDY_DESCRIPTION)); | |
1478 } | |
1479 } | |
1480 | |
1481 | |
1482 TEST_F(OrthancJobsSerialization, Jobs) | |
1483 { | |
1484 Json::Value s; | |
1485 | |
1486 // ArchiveJob | |
1487 | |
1488 { | |
1489 ArchiveJob job(GetContext(), false, false); | |
1490 ASSERT_FALSE(job.Serialize(s)); // Cannot serialize this | |
1491 } | |
1492 | |
1493 // DicomModalityStoreJob | |
1494 | |
1495 OrthancJobUnserializer unserializer(GetContext()); | |
1496 | |
1497 { | |
1498 RemoteModalityParameters modality; | |
1499 modality.SetApplicationEntityTitle("REMOTE"); | |
1500 modality.SetHost("192.168.1.1"); | |
1501 modality.SetPortNumber(1000); | |
1502 modality.SetManufacturer(ModalityManufacturer_StoreScp); | |
1503 | |
1504 DicomModalityStoreJob job(GetContext()); | |
1505 job.SetLocalAet("LOCAL"); | |
1506 job.SetRemoteModality(modality); | |
1507 job.SetMoveOriginator("MOVESCU", 42); | |
1508 | |
1509 ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); | |
1510 ASSERT_TRUE(job.Serialize(s)); | |
1511 } | |
1512 | |
1513 { | |
1514 std::unique_ptr<IJob> job; | |
1515 job.reset(unserializer.UnserializeJob(s)); | |
1516 | |
1517 DicomModalityStoreJob& tmp = dynamic_cast<DicomModalityStoreJob&>(*job); | |
1518 ASSERT_EQ("LOCAL", tmp.GetParameters().GetLocalApplicationEntityTitle()); | |
1519 ASSERT_EQ("REMOTE", tmp.GetParameters().GetRemoteModality().GetApplicationEntityTitle()); | |
1520 ASSERT_EQ("192.168.1.1", tmp.GetParameters().GetRemoteModality().GetHost()); | |
1521 ASSERT_EQ(1000, tmp.GetParameters().GetRemoteModality().GetPortNumber()); | |
1522 ASSERT_EQ(ModalityManufacturer_StoreScp, tmp.GetParameters().GetRemoteModality().GetManufacturer()); | |
1523 ASSERT_TRUE(tmp.HasMoveOriginator()); | |
1524 ASSERT_EQ("MOVESCU", tmp.GetMoveOriginatorAet()); | |
1525 ASSERT_EQ(42, tmp.GetMoveOriginatorId()); | |
1526 } | |
1527 | |
1528 // OrthancPeerStoreJob | |
1529 | |
1530 { | |
1531 WebServiceParameters peer; | |
1532 peer.SetUrl("http://localhost/"); | |
1533 peer.SetCredentials("username", "password"); | |
1534 peer.SetPkcs11Enabled(true); | |
1535 | |
1536 OrthancPeerStoreJob job(GetContext()); | |
1537 job.SetPeer(peer); | |
1538 | |
1539 ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); | |
1540 ASSERT_TRUE(job.Serialize(s)); | |
1541 } | |
1542 | |
1543 { | |
1544 std::unique_ptr<IJob> job; | |
1545 job.reset(unserializer.UnserializeJob(s)); | |
1546 | |
1547 OrthancPeerStoreJob& tmp = dynamic_cast<OrthancPeerStoreJob&>(*job); | |
1548 ASSERT_EQ("http://localhost/", tmp.GetPeer().GetUrl()); | |
1549 ASSERT_EQ("username", tmp.GetPeer().GetUsername()); | |
1550 ASSERT_EQ("password", tmp.GetPeer().GetPassword()); | |
1551 ASSERT_TRUE(tmp.GetPeer().IsPkcs11Enabled()); | |
1552 ASSERT_FALSE(tmp.IsTranscode()); | |
1553 ASSERT_THROW(tmp.GetTransferSyntax(), OrthancException); | |
1554 } | |
1555 | |
1556 { | |
1557 OrthancPeerStoreJob job(GetContext()); | |
1558 ASSERT_THROW(job.SetTranscode("nope"), OrthancException); | |
1559 job.SetTranscode("1.2.840.10008.1.2.4.50"); | |
1560 | |
1561 ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); | |
1562 ASSERT_TRUE(job.Serialize(s)); | |
1563 } | |
1564 | |
1565 { | |
1566 std::unique_ptr<IJob> job; | |
1567 job.reset(unserializer.UnserializeJob(s)); | |
1568 | |
1569 OrthancPeerStoreJob& tmp = dynamic_cast<OrthancPeerStoreJob&>(*job); | |
1570 ASSERT_EQ("http://127.0.0.1:8042/", tmp.GetPeer().GetUrl()); | |
1571 ASSERT_EQ("", tmp.GetPeer().GetUsername()); | |
1572 ASSERT_EQ("", tmp.GetPeer().GetPassword()); | |
1573 ASSERT_FALSE(tmp.GetPeer().IsPkcs11Enabled()); | |
1574 ASSERT_TRUE(tmp.IsTranscode()); | |
1575 ASSERT_EQ(DicomTransferSyntax_JPEGProcess1, tmp.GetTransferSyntax()); | |
1576 } | |
1577 | |
1578 // ResourceModificationJob | |
1579 | |
1580 { | |
1581 std::unique_ptr<DicomModification> modification(new DicomModification); | |
1582 modification->SetupAnonymization(DicomVersion_2008); | |
1583 | |
1584 ResourceModificationJob job(GetContext()); | |
1585 job.SetModification(modification.release(), ResourceType_Patient, true); | |
1586 job.SetOrigin(DicomInstanceOrigin::FromLua()); | |
1587 | |
1588 job.AddTrailingStep(); // Necessary since 1.7.0 | |
1589 ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); | |
1590 ASSERT_TRUE(job.Serialize(s)); | |
1591 } | |
1592 | |
1593 { | |
1594 std::unique_ptr<IJob> job; | |
1595 job.reset(unserializer.UnserializeJob(s)); | |
1596 | |
1597 ResourceModificationJob& tmp = dynamic_cast<ResourceModificationJob&>(*job); | |
1598 ASSERT_TRUE(tmp.IsAnonymization()); | |
1599 ASSERT_FALSE(tmp.IsTranscode()); | |
1600 ASSERT_THROW(tmp.GetTransferSyntax(), OrthancException); | |
1601 ASSERT_EQ(RequestOrigin_Lua, tmp.GetOrigin().GetRequestOrigin()); | |
1602 ASSERT_TRUE(tmp.GetModification().IsRemoved(DICOM_TAG_STUDY_DESCRIPTION)); | |
1603 } | |
1604 | |
1605 { | |
1606 ResourceModificationJob job(GetContext()); | |
1607 ASSERT_THROW(job.SetTranscode("nope"), OrthancException); | |
1608 job.SetTranscode(DicomTransferSyntax_JPEGProcess1); | |
1609 | |
1610 job.AddTrailingStep(); // Necessary since 1.7.0 | |
1611 ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); | |
1612 ASSERT_TRUE(job.Serialize(s)); | |
1613 } | |
1614 | |
1615 { | |
1616 std::unique_ptr<IJob> job; | |
1617 job.reset(unserializer.UnserializeJob(s)); | |
1618 | |
1619 ResourceModificationJob& tmp = dynamic_cast<ResourceModificationJob&>(*job); | |
1620 ASSERT_FALSE(tmp.IsAnonymization()); | |
1621 ASSERT_TRUE(tmp.IsTranscode()); | |
1622 ASSERT_EQ(DicomTransferSyntax_JPEGProcess1, tmp.GetTransferSyntax()); | |
1623 ASSERT_EQ(RequestOrigin_Unknown, tmp.GetOrigin().GetRequestOrigin()); | |
1624 } | |
1625 | |
1626 // SplitStudyJob | |
1627 | |
1628 std::string instance; | |
1629 ASSERT_TRUE(CreateInstance(instance)); | |
1630 | |
1631 std::string study, series; | |
1632 | |
1633 { | |
1634 ServerContext::DicomCacheLocker lock(GetContext(), instance); | |
1635 study = lock.GetDicom().GetHasher().HashStudy(); | |
1636 series = lock.GetDicom().GetHasher().HashSeries(); | |
1637 } | |
1638 | |
1639 { | |
1640 std::list<std::string> tmp; | |
1641 GetContext().GetIndex().GetAllUuids(tmp, ResourceType_Study); | |
1642 ASSERT_EQ(1u, tmp.size()); | |
1643 ASSERT_EQ(study, tmp.front()); | |
1644 GetContext().GetIndex().GetAllUuids(tmp, ResourceType_Series); | |
1645 ASSERT_EQ(1u, tmp.size()); | |
1646 ASSERT_EQ(series, tmp.front()); | |
1647 } | |
1648 | |
1649 std::string study2; | |
1650 | |
1651 { | |
1652 std::string a, b; | |
1653 | |
1654 { | |
1655 ASSERT_THROW(SplitStudyJob(GetContext(), std::string("nope")), OrthancException); | |
1656 | |
1657 SplitStudyJob job(GetContext(), study); | |
1658 job.SetKeepSource(true); | |
1659 job.AddSourceSeries(series); | |
1660 ASSERT_THROW(job.AddSourceSeries("nope"), OrthancException); | |
1661 job.SetOrigin(DicomInstanceOrigin::FromLua()); | |
1662 job.Replace(DICOM_TAG_PATIENT_NAME, "hello"); | |
1663 job.Remove(DICOM_TAG_PATIENT_BIRTH_DATE); | |
1664 ASSERT_THROW(job.Replace(DICOM_TAG_SERIES_DESCRIPTION, "nope"), OrthancException); | |
1665 ASSERT_THROW(job.Remove(DICOM_TAG_SERIES_DESCRIPTION), OrthancException); | |
1666 | |
1667 ASSERT_TRUE(job.GetTargetStudy().empty()); | |
1668 a = job.GetTargetStudyUid(); | |
1669 ASSERT_TRUE(job.LookupTargetSeriesUid(b, series)); | |
1670 | |
1671 job.AddTrailingStep(); | |
1672 job.Start(); | |
1673 ASSERT_EQ(JobStepCode_Continue, job.Step("jobId").GetCode()); | |
1674 ASSERT_EQ(JobStepCode_Success, job.Step("jobId").GetCode()); | |
1675 | |
1676 study2 = job.GetTargetStudy(); | |
1677 ASSERT_FALSE(study2.empty()); | |
1678 | |
1679 ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); | |
1680 ASSERT_TRUE(job.Serialize(s)); | |
1681 } | |
1682 | |
1683 { | |
1684 std::unique_ptr<IJob> job; | |
1685 job.reset(unserializer.UnserializeJob(s)); | |
1686 | |
1687 SplitStudyJob& tmp = dynamic_cast<SplitStudyJob&>(*job); | |
1688 ASSERT_TRUE(tmp.IsKeepSource()); | |
1689 ASSERT_EQ(study, tmp.GetSourceStudy()); | |
1690 ASSERT_EQ(a, tmp.GetTargetStudyUid()); | |
1691 ASSERT_EQ(RequestOrigin_Lua, tmp.GetOrigin().GetRequestOrigin()); | |
1692 | |
1693 std::string s; | |
1694 ASSERT_EQ(study2, tmp.GetTargetStudy()); | |
1695 ASSERT_FALSE(tmp.LookupTargetSeriesUid(s, "nope")); | |
1696 ASSERT_TRUE(tmp.LookupTargetSeriesUid(s, series)); | |
1697 ASSERT_EQ(b, s); | |
1698 | |
1699 ASSERT_FALSE(tmp.LookupReplacement(s, DICOM_TAG_STUDY_DESCRIPTION)); | |
1700 ASSERT_TRUE(tmp.LookupReplacement(s, DICOM_TAG_PATIENT_NAME)); | |
1701 ASSERT_EQ("hello", s); | |
1702 ASSERT_FALSE(tmp.IsRemoved(DICOM_TAG_PATIENT_NAME)); | |
1703 ASSERT_TRUE(tmp.IsRemoved(DICOM_TAG_PATIENT_BIRTH_DATE)); | |
1704 } | |
1705 } | |
1706 | |
1707 { | |
1708 std::list<std::string> tmp; | |
1709 GetContext().GetIndex().GetAllUuids(tmp, ResourceType_Study); | |
1710 ASSERT_EQ(2u, tmp.size()); | |
1711 GetContext().GetIndex().GetAllUuids(tmp, ResourceType_Series); | |
1712 ASSERT_EQ(2u, tmp.size()); | |
1713 } | |
1714 | |
1715 // MergeStudyJob | |
1716 | |
1717 { | |
1718 ASSERT_THROW(SplitStudyJob(GetContext(), std::string("nope")), OrthancException); | |
1719 | |
1720 MergeStudyJob job(GetContext(), study); | |
1721 job.SetKeepSource(true); | |
1722 job.AddSource(study2); | |
1723 ASSERT_THROW(job.AddSourceSeries("nope"), OrthancException); | |
1724 ASSERT_THROW(job.AddSourceStudy("nope"), OrthancException); | |
1725 ASSERT_THROW(job.AddSource("nope"), OrthancException); | |
1726 job.SetOrigin(DicomInstanceOrigin::FromLua()); | |
1727 | |
1728 ASSERT_EQ(job.GetTargetStudy(), study); | |
1729 | |
1730 job.AddTrailingStep(); | |
1731 job.Start(); | |
1732 ASSERT_EQ(JobStepCode_Continue, job.Step("jobId").GetCode()); | |
1733 ASSERT_EQ(JobStepCode_Success, job.Step("jobId").GetCode()); | |
1734 | |
1735 ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); | |
1736 ASSERT_TRUE(job.Serialize(s)); | |
1737 } | |
1738 | |
1739 { | |
1740 std::list<std::string> tmp; | |
1741 GetContext().GetIndex().GetAllUuids(tmp, ResourceType_Study); | |
1742 ASSERT_EQ(2u, tmp.size()); | |
1743 GetContext().GetIndex().GetAllUuids(tmp, ResourceType_Series); | |
1744 ASSERT_EQ(3u, tmp.size()); | |
1745 } | |
1746 | |
1747 { | |
1748 std::unique_ptr<IJob> job; | |
1749 job.reset(unserializer.UnserializeJob(s)); | |
1750 | |
1751 MergeStudyJob& tmp = dynamic_cast<MergeStudyJob&>(*job); | |
1752 ASSERT_TRUE(tmp.IsKeepSource()); | |
1753 ASSERT_EQ(study, tmp.GetTargetStudy()); | |
1754 ASSERT_EQ(RequestOrigin_Lua, tmp.GetOrigin().GetRequestOrigin()); | |
1755 } | |
1756 } | |
1757 | |
1758 | |
1759 TEST(JobsSerialization, Registry) | |
1760 { | |
1761 Json::Value s; | |
1762 std::string i1, i2; | |
1763 | |
1764 { | |
1765 JobsRegistry registry(10); | |
1766 registry.Submit(i1, new DummyJob(), 10); | |
1767 registry.Submit(i2, new SequenceOfOperationsJob(), 30); | |
1768 registry.Serialize(s); | |
1769 } | |
1770 | |
1771 { | |
1772 DummyUnserializer unserializer; | |
1773 JobsRegistry registry(unserializer, s, 10); | |
1774 | |
1775 Json::Value t; | |
1776 registry.Serialize(t); | |
1777 ASSERT_TRUE(CheckSameJson(s, t)); | |
1778 } | |
1779 } | |
1780 | |
1781 | |
1782 TEST(JobsSerialization, TrailingStep) | |
1783 { | |
1784 { | |
1785 Json::Value s; | |
1786 | |
1787 DummyInstancesJob job; | |
1788 ASSERT_EQ(0u, job.GetCommandsCount()); | |
1789 ASSERT_EQ(0u, job.GetInstancesCount()); | |
1790 | |
1791 job.Start(); | |
1792 ASSERT_EQ(0u, job.GetPosition()); | |
1793 ASSERT_FALSE(job.HasTrailingStep()); | |
1794 ASSERT_FALSE(job.IsTrailingStepDone()); | |
1795 | |
1796 { | |
1797 DummyUnserializer unserializer; | |
1798 ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); | |
1799 } | |
1800 | |
1801 ASSERT_EQ(JobStepCode_Success, job.Step("jobId").GetCode()); | |
1802 ASSERT_EQ(1u, job.GetPosition()); | |
1803 ASSERT_FALSE(job.IsTrailingStepDone()); | |
1804 | |
1805 { | |
1806 DummyUnserializer unserializer; | |
1807 ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); | |
1808 } | |
1809 | |
1810 ASSERT_THROW(job.Step("jobId"), OrthancException); | |
1811 } | |
1812 | |
1813 { | |
1814 Json::Value s; | |
1815 | |
1816 DummyInstancesJob job; | |
1817 job.AddInstance("hello"); | |
1818 job.AddInstance("world"); | |
1819 ASSERT_EQ(2u, job.GetCommandsCount()); | |
1820 ASSERT_EQ(2u, job.GetInstancesCount()); | |
1821 | |
1822 job.Start(); | |
1823 ASSERT_EQ(0u, job.GetPosition()); | |
1824 ASSERT_FALSE(job.HasTrailingStep()); | |
1825 ASSERT_FALSE(job.IsTrailingStepDone()); | |
1826 | |
1827 { | |
1828 DummyUnserializer unserializer; | |
1829 ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); | |
1830 } | |
1831 | |
1832 ASSERT_EQ(JobStepCode_Continue, job.Step("jobId").GetCode()); | |
1833 ASSERT_EQ(1u, job.GetPosition()); | |
1834 ASSERT_FALSE(job.IsTrailingStepDone()); | |
1835 | |
1836 { | |
1837 DummyUnserializer unserializer; | |
1838 ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); | |
1839 } | |
1840 | |
1841 ASSERT_EQ(JobStepCode_Success, job.Step("jobId").GetCode()); | |
1842 ASSERT_EQ(2u, job.GetPosition()); | |
1843 ASSERT_FALSE(job.IsTrailingStepDone()); | |
1844 | |
1845 { | |
1846 DummyUnserializer unserializer; | |
1847 ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); | |
1848 } | |
1849 | |
1850 ASSERT_THROW(job.Step("jobId"), OrthancException); | |
1851 } | |
1852 | |
1853 { | |
1854 Json::Value s; | |
1855 | |
1856 DummyInstancesJob job; | |
1857 ASSERT_EQ(0u, job.GetInstancesCount()); | |
1858 ASSERT_EQ(0u, job.GetCommandsCount()); | |
1859 job.AddTrailingStep(); | |
1860 ASSERT_EQ(0u, job.GetInstancesCount()); | |
1861 ASSERT_EQ(1u, job.GetCommandsCount()); | |
1862 | |
1863 job.Start(); // This adds the trailing step | |
1864 ASSERT_EQ(0u, job.GetPosition()); | |
1865 ASSERT_TRUE(job.HasTrailingStep()); | |
1866 ASSERT_FALSE(job.IsTrailingStepDone()); | |
1867 | |
1868 { | |
1869 DummyUnserializer unserializer; | |
1870 ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); | |
1871 } | |
1872 | |
1873 ASSERT_EQ(JobStepCode_Success, job.Step("jobId").GetCode()); | |
1874 ASSERT_EQ(1u, job.GetPosition()); | |
1875 ASSERT_TRUE(job.IsTrailingStepDone()); | |
1876 | |
1877 { | |
1878 DummyUnserializer unserializer; | |
1879 ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); | |
1880 } | |
1881 | |
1882 ASSERT_THROW(job.Step("jobId"), OrthancException); | |
1883 } | |
1884 | |
1885 { | |
1886 Json::Value s; | |
1887 | |
1888 DummyInstancesJob job; | |
1889 job.AddInstance("hello"); | |
1890 ASSERT_EQ(1u, job.GetInstancesCount()); | |
1891 ASSERT_EQ(1u, job.GetCommandsCount()); | |
1892 job.AddTrailingStep(); | |
1893 ASSERT_EQ(1u, job.GetInstancesCount()); | |
1894 ASSERT_EQ(2u, job.GetCommandsCount()); | |
1895 | |
1896 job.Start(); | |
1897 ASSERT_EQ(2u, job.GetCommandsCount()); | |
1898 ASSERT_EQ(0u, job.GetPosition()); | |
1899 ASSERT_TRUE(job.HasTrailingStep()); | |
1900 ASSERT_FALSE(job.IsTrailingStepDone()); | |
1901 | |
1902 { | |
1903 DummyUnserializer unserializer; | |
1904 ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); | |
1905 } | |
1906 | |
1907 ASSERT_EQ(JobStepCode_Continue, job.Step("jobId").GetCode()); | |
1908 ASSERT_EQ(1u, job.GetPosition()); | |
1909 ASSERT_FALSE(job.IsTrailingStepDone()); | |
1910 | |
1911 { | |
1912 DummyUnserializer unserializer; | |
1913 ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); | |
1914 } | |
1915 | |
1916 ASSERT_EQ(JobStepCode_Success, job.Step("jobId").GetCode()); | |
1917 ASSERT_EQ(2u, job.GetPosition()); | |
1918 ASSERT_TRUE(job.IsTrailingStepDone()); | |
1919 | |
1920 { | |
1921 DummyUnserializer unserializer; | |
1922 ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); | |
1923 } | |
1924 | |
1925 ASSERT_THROW(job.Step("jobId"), OrthancException); | |
1926 } | |
1927 } | |
1928 | |
1929 | |
1930 TEST(JobsSerialization, RemoteModalityParameters) | |
1931 { | |
1932 Json::Value s; | |
1933 | |
1934 { | |
1935 RemoteModalityParameters modality; | |
1936 ASSERT_FALSE(modality.IsAdvancedFormatNeeded()); | |
1937 modality.Serialize(s, false); | |
1938 ASSERT_EQ(Json::arrayValue, s.type()); | |
1939 } | |
1940 | |
1941 { | |
1942 RemoteModalityParameters modality(s); | |
1943 ASSERT_EQ("ORTHANC", modality.GetApplicationEntityTitle()); | |
1944 ASSERT_EQ("127.0.0.1", modality.GetHost()); | |
1945 ASSERT_EQ(104u, modality.GetPortNumber()); | |
1946 ASSERT_EQ(ModalityManufacturer_Generic, modality.GetManufacturer()); | |
1947 ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_Echo)); | |
1948 ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_Find)); | |
1949 ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_Get)); | |
1950 ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_Store)); | |
1951 ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_Move)); | |
1952 ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_NAction)); | |
1953 ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_NEventReport)); | |
1954 ASSERT_TRUE(modality.IsTranscodingAllowed()); | |
1955 } | |
1956 | |
1957 s = Json::nullValue; | |
1958 | |
1959 { | |
1960 RemoteModalityParameters modality; | |
1961 ASSERT_FALSE(modality.IsAdvancedFormatNeeded()); | |
1962 ASSERT_THROW(modality.SetPortNumber(0), OrthancException); | |
1963 ASSERT_THROW(modality.SetPortNumber(65535), OrthancException); | |
1964 modality.SetApplicationEntityTitle("HELLO"); | |
1965 modality.SetHost("world"); | |
1966 modality.SetPortNumber(45); | |
1967 modality.SetManufacturer(ModalityManufacturer_GenericNoWildcardInDates); | |
1968 modality.Serialize(s, true); | |
1969 ASSERT_EQ(Json::objectValue, s.type()); | |
1970 } | |
1971 | |
1972 { | |
1973 RemoteModalityParameters modality(s); | |
1974 ASSERT_EQ("HELLO", modality.GetApplicationEntityTitle()); | |
1975 ASSERT_EQ("world", modality.GetHost()); | |
1976 ASSERT_EQ(45u, modality.GetPortNumber()); | |
1977 ASSERT_EQ(ModalityManufacturer_GenericNoWildcardInDates, modality.GetManufacturer()); | |
1978 ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_Echo)); | |
1979 ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_Find)); | |
1980 ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_Get)); | |
1981 ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_Store)); | |
1982 ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_Move)); | |
1983 ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_NAction)); | |
1984 ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_NEventReport)); | |
1985 ASSERT_TRUE(modality.IsTranscodingAllowed()); | |
1986 } | |
1987 | |
1988 s["Port"] = "46"; | |
1989 | |
1990 { | |
1991 RemoteModalityParameters modality(s); | |
1992 ASSERT_EQ(46u, modality.GetPortNumber()); | |
1993 } | |
1994 | |
1995 s["Port"] = -1; ASSERT_THROW(RemoteModalityParameters m(s), OrthancException); | |
1996 s["Port"] = 65535; ASSERT_THROW(RemoteModalityParameters m(s), OrthancException); | |
1997 s["Port"] = "nope"; ASSERT_THROW(RemoteModalityParameters m(s), OrthancException); | |
1998 | |
1999 std::set<DicomRequestType> operations; | |
2000 operations.insert(DicomRequestType_Echo); | |
2001 operations.insert(DicomRequestType_Find); | |
2002 operations.insert(DicomRequestType_Get); | |
2003 operations.insert(DicomRequestType_Move); | |
2004 operations.insert(DicomRequestType_Store); | |
2005 operations.insert(DicomRequestType_NAction); | |
2006 operations.insert(DicomRequestType_NEventReport); | |
2007 | |
2008 ASSERT_EQ(7u, operations.size()); | |
2009 | |
2010 for (std::set<DicomRequestType>::const_iterator | |
2011 it = operations.begin(); it != operations.end(); ++it) | |
2012 { | |
2013 { | |
2014 RemoteModalityParameters modality; | |
2015 modality.SetRequestAllowed(*it, false); | |
2016 ASSERT_TRUE(modality.IsAdvancedFormatNeeded()); | |
2017 | |
2018 modality.Serialize(s, false); | |
2019 ASSERT_EQ(Json::objectValue, s.type()); | |
2020 } | |
2021 | |
2022 { | |
2023 RemoteModalityParameters modality(s); | |
2024 | |
2025 ASSERT_FALSE(modality.IsRequestAllowed(*it)); | |
2026 | |
2027 for (std::set<DicomRequestType>::const_iterator | |
2028 it2 = operations.begin(); it2 != operations.end(); ++it2) | |
2029 { | |
2030 if (*it2 != *it) | |
2031 { | |
2032 ASSERT_TRUE(modality.IsRequestAllowed(*it2)); | |
2033 } | |
2034 } | |
2035 } | |
2036 } | |
2037 | |
2038 { | |
2039 Json::Value s; | |
2040 s["AllowStorageCommitment"] = false; | |
2041 s["AET"] = "AET"; | |
2042 s["Host"] = "host"; | |
2043 s["Port"] = "104"; | |
2044 | |
2045 RemoteModalityParameters modality(s); | |
2046 ASSERT_TRUE(modality.IsAdvancedFormatNeeded()); | |
2047 ASSERT_EQ("AET", modality.GetApplicationEntityTitle()); | |
2048 ASSERT_EQ("host", modality.GetHost()); | |
2049 ASSERT_EQ(104u, modality.GetPortNumber()); | |
2050 ASSERT_FALSE(modality.IsRequestAllowed(DicomRequestType_NAction)); | |
2051 ASSERT_FALSE(modality.IsRequestAllowed(DicomRequestType_NEventReport)); | |
2052 ASSERT_TRUE(modality.IsTranscodingAllowed()); | |
2053 } | |
2054 | |
2055 { | |
2056 Json::Value s; | |
2057 s["AllowNAction"] = false; | |
2058 s["AllowNEventReport"] = true; | |
2059 s["AET"] = "AET"; | |
2060 s["Host"] = "host"; | |
2061 s["Port"] = "104"; | |
2062 s["AllowTranscoding"] = false; | |
2063 | |
2064 RemoteModalityParameters modality(s); | |
2065 ASSERT_TRUE(modality.IsAdvancedFormatNeeded()); | |
2066 ASSERT_EQ("AET", modality.GetApplicationEntityTitle()); | |
2067 ASSERT_EQ("host", modality.GetHost()); | |
2068 ASSERT_EQ(104u, modality.GetPortNumber()); | |
2069 ASSERT_FALSE(modality.IsRequestAllowed(DicomRequestType_NAction)); | |
2070 ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_NEventReport)); | |
2071 ASSERT_FALSE(modality.IsTranscodingAllowed()); | |
2072 } | |
2073 | |
2074 { | |
2075 Json::Value s; | |
2076 s["AllowNAction"] = true; | |
2077 s["AllowNEventReport"] = true; | |
2078 s["AET"] = "AET"; | |
2079 s["Host"] = "host"; | |
2080 s["Port"] = "104"; | |
2081 | |
2082 RemoteModalityParameters modality(s); | |
2083 ASSERT_FALSE(modality.IsAdvancedFormatNeeded()); | |
2084 ASSERT_EQ("AET", modality.GetApplicationEntityTitle()); | |
2085 ASSERT_EQ("host", modality.GetHost()); | |
2086 ASSERT_EQ(104u, modality.GetPortNumber()); | |
2087 ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_NAction)); | |
2088 ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_NEventReport)); | |
2089 ASSERT_TRUE(modality.IsTranscodingAllowed()); | |
2090 } | |
2091 } | |
2092 | |
2093 | |
2094 TEST_F(OrthancJobsSerialization, DicomAssociationParameters) | |
2095 { | |
2096 Json::Value v; | |
2097 | |
2098 { | |
2099 v = Json::objectValue; | |
2100 DicomAssociationParameters p; | |
2101 p.SerializeJob(v); | |
2102 } | |
2103 | |
2104 { | |
2105 DicomAssociationParameters p = DicomAssociationParameters::UnserializeJob(v); | |
2106 ASSERT_EQ("ORTHANC", p.GetLocalApplicationEntityTitle()); | |
2107 ASSERT_EQ("ANY-SCP", p.GetRemoteModality().GetApplicationEntityTitle()); | |
2108 ASSERT_EQ(104u, p.GetRemoteModality().GetPortNumber()); | |
2109 ASSERT_EQ(ModalityManufacturer_Generic, p.GetRemoteModality().GetManufacturer()); | |
2110 ASSERT_EQ("127.0.0.1", p.GetRemoteModality().GetHost()); | |
2111 ASSERT_EQ(DicomAssociationParameters::GetDefaultTimeout(), p.GetTimeout()); | |
2112 } | |
2113 | |
2114 { | |
2115 v = Json::objectValue; | |
2116 DicomAssociationParameters p; | |
2117 p.SetLocalApplicationEntityTitle("HELLO"); | |
2118 p.SetRemoteApplicationEntityTitle("WORLD"); | |
2119 p.SetRemotePort(42); | |
2120 p.SetRemoteHost("MY_HOST"); | |
2121 p.SetTimeout(43); | |
2122 p.SerializeJob(v); | |
2123 } | |
2124 | |
2125 { | |
2126 DicomAssociationParameters p = DicomAssociationParameters::UnserializeJob(v); | |
2127 ASSERT_EQ("HELLO", p.GetLocalApplicationEntityTitle()); | |
2128 ASSERT_EQ("WORLD", p.GetRemoteModality().GetApplicationEntityTitle()); | |
2129 ASSERT_EQ(42u, p.GetRemoteModality().GetPortNumber()); | |
2130 ASSERT_EQ(ModalityManufacturer_Generic, p.GetRemoteModality().GetManufacturer()); | |
2131 ASSERT_EQ("MY_HOST", p.GetRemoteModality().GetHost()); | |
2132 ASSERT_EQ(43u, p.GetTimeout()); | |
2133 } | |
2134 | |
2135 { | |
2136 DicomModalityStoreJob job(GetContext()); | |
2137 job.Serialize(v); | |
2138 } | |
2139 | |
2140 { | |
2141 OrthancJobUnserializer unserializer(GetContext()); | |
2142 std::unique_ptr<DicomModalityStoreJob> job( | |
2143 dynamic_cast<DicomModalityStoreJob*>(unserializer.UnserializeJob(v))); | |
2144 ASSERT_EQ("ORTHANC", job->GetParameters().GetLocalApplicationEntityTitle()); | |
2145 ASSERT_EQ("ANY-SCP", job->GetParameters().GetRemoteModality().GetApplicationEntityTitle()); | |
2146 ASSERT_EQ("127.0.0.1", job->GetParameters().GetRemoteModality().GetHost()); | |
2147 ASSERT_EQ(104u, job->GetParameters().GetRemoteModality().GetPortNumber()); | |
2148 ASSERT_EQ(ModalityManufacturer_Generic, job->GetParameters().GetRemoteModality().GetManufacturer()); | |
2149 ASSERT_EQ(DicomAssociationParameters::GetDefaultTimeout(), job->GetParameters().GetTimeout()); | |
2150 ASSERT_FALSE(job->HasMoveOriginator()); | |
2151 ASSERT_THROW(job->GetMoveOriginatorAet(), OrthancException); | |
2152 ASSERT_THROW(job->GetMoveOriginatorId(), OrthancException); | |
2153 ASSERT_FALSE(job->HasStorageCommitment()); | |
2154 } | |
2155 | |
2156 { | |
2157 RemoteModalityParameters r; | |
2158 r.SetApplicationEntityTitle("HELLO"); | |
2159 r.SetPortNumber(42); | |
2160 r.SetHost("MY_HOST"); | |
2161 | |
2162 DicomModalityStoreJob job(GetContext()); | |
2163 job.SetLocalAet("WORLD"); | |
2164 job.SetRemoteModality(r); | |
2165 job.SetTimeout(43); | |
2166 job.SetMoveOriginator("ORIGINATOR", 100); | |
2167 job.EnableStorageCommitment(true); | |
2168 job.Serialize(v); | |
2169 } | |
2170 | |
2171 { | |
2172 OrthancJobUnserializer unserializer(GetContext()); | |
2173 std::unique_ptr<DicomModalityStoreJob> job( | |
2174 dynamic_cast<DicomModalityStoreJob*>(unserializer.UnserializeJob(v))); | |
2175 ASSERT_EQ("WORLD", job->GetParameters().GetLocalApplicationEntityTitle()); | |
2176 ASSERT_EQ("HELLO", job->GetParameters().GetRemoteModality().GetApplicationEntityTitle()); | |
2177 ASSERT_EQ("MY_HOST", job->GetParameters().GetRemoteModality().GetHost()); | |
2178 ASSERT_EQ(42u, job->GetParameters().GetRemoteModality().GetPortNumber()); | |
2179 ASSERT_EQ(ModalityManufacturer_Generic, job->GetParameters().GetRemoteModality().GetManufacturer()); | |
2180 ASSERT_EQ(43u, job->GetParameters().GetTimeout()); | |
2181 ASSERT_TRUE(job->HasMoveOriginator()); | |
2182 ASSERT_EQ("ORIGINATOR", job->GetMoveOriginatorAet()); | |
2183 ASSERT_EQ(100, job->GetMoveOriginatorId()); | |
2184 ASSERT_TRUE(job->HasStorageCommitment()); | |
2185 } | |
2186 | |
2187 { | |
2188 DicomMoveScuJob job(GetContext()); | |
2189 job.Serialize(v); | |
2190 } | |
2191 | |
2192 { | |
2193 OrthancJobUnserializer unserializer(GetContext()); | |
2194 std::unique_ptr<DicomMoveScuJob> job( | |
2195 dynamic_cast<DicomMoveScuJob*>(unserializer.UnserializeJob(v))); | |
2196 ASSERT_EQ("ORTHANC", job->GetParameters().GetLocalApplicationEntityTitle()); | |
2197 ASSERT_EQ("ANY-SCP", job->GetParameters().GetRemoteModality().GetApplicationEntityTitle()); | |
2198 ASSERT_EQ("127.0.0.1", job->GetParameters().GetRemoteModality().GetHost()); | |
2199 ASSERT_EQ(104u, job->GetParameters().GetRemoteModality().GetPortNumber()); | |
2200 ASSERT_EQ(ModalityManufacturer_Generic, job->GetParameters().GetRemoteModality().GetManufacturer()); | |
2201 ASSERT_EQ(DicomAssociationParameters::GetDefaultTimeout(), job->GetParameters().GetTimeout()); | |
2202 } | |
2203 | |
2204 { | |
2205 RemoteModalityParameters r; | |
2206 r.SetApplicationEntityTitle("HELLO"); | |
2207 r.SetPortNumber(42); | |
2208 r.SetHost("MY_HOST"); | |
2209 | |
2210 DicomMoveScuJob job(GetContext()); | |
2211 job.SetLocalAet("WORLD"); | |
2212 job.SetRemoteModality(r); | |
2213 job.SetTimeout(43); | |
2214 job.Serialize(v); | |
2215 } | |
2216 | |
2217 { | |
2218 OrthancJobUnserializer unserializer(GetContext()); | |
2219 std::unique_ptr<DicomMoveScuJob> job( | |
2220 dynamic_cast<DicomMoveScuJob*>(unserializer.UnserializeJob(v))); | |
2221 ASSERT_EQ("WORLD", job->GetParameters().GetLocalApplicationEntityTitle()); | |
2222 ASSERT_EQ("HELLO", job->GetParameters().GetRemoteModality().GetApplicationEntityTitle()); | |
2223 ASSERT_EQ("MY_HOST", job->GetParameters().GetRemoteModality().GetHost()); | |
2224 ASSERT_EQ(42u, job->GetParameters().GetRemoteModality().GetPortNumber()); | |
2225 ASSERT_EQ(ModalityManufacturer_Generic, job->GetParameters().GetRemoteModality().GetManufacturer()); | |
2226 ASSERT_EQ(43u, job->GetParameters().GetTimeout()); | |
2227 } | |
2228 } |