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-2021 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 "../../OrthancFramework/Sources/DicomFormat/DicomArray.h"
38 #include "../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h"
39 #include "../../OrthancFramework/Sources/DicomParsing/ParsedDicomFile.h"
40 #include "../../OrthancFramework/Sources/DicomParsing/ToDcmtkBridge.h"
41 #include "../../OrthancFramework/Sources/EnumerationDictionary.h"
42 #include "../../OrthancFramework/Sources/Images/Image.h"
43 #include "../../OrthancFramework/Sources/Images/PngWriter.h"
44 #include "../../OrthancFramework/Sources/Logging.h"
45 #include "../../OrthancFramework/Sources/OrthancException.h"
46 #include "../../OrthancFramework/Sources/Toolbox.h"
47
48 #include "../Plugins/Engine/PluginsEnumerations.h"
49 #include "../Sources/DicomInstanceToStore.h"
50 #include "../Sources/OrthancConfiguration.h" // For the FontRegistry
51 #include "../Sources/OrthancInitialization.h"
52 #include "../Sources/ServerEnumerations.h"
53 #include "../Sources/ServerToolbox.h"
54 #include "../Sources/StorageCommitmentReports.h"
55
56 #include <OrthancServerResources.h>
57
58 #include <dcmtk/dcmdata/dcdeftag.h>
59
60
61 using namespace Orthanc;
62
63
TEST(EnumerationDictionary,Simple)64 TEST(EnumerationDictionary, Simple)
65 {
66 EnumerationDictionary<MetadataType> d;
67
68 ASSERT_THROW(d.Translate("ReceptionDate"), OrthancException);
69 ASSERT_EQ(MetadataType_ModifiedFrom, d.Translate("5"));
70 ASSERT_EQ(256, d.Translate("256"));
71
72 d.Add(MetadataType_Instance_ReceptionDate, "ReceptionDate");
73
74 ASSERT_EQ(MetadataType_Instance_ReceptionDate, d.Translate("ReceptionDate"));
75 ASSERT_EQ(MetadataType_Instance_ReceptionDate, d.Translate("2"));
76 ASSERT_EQ("ReceptionDate", d.Translate(MetadataType_Instance_ReceptionDate));
77
78 ASSERT_THROW(d.Add(MetadataType_Instance_ReceptionDate, "Hello"), OrthancException);
79 ASSERT_THROW(d.Add(MetadataType_ModifiedFrom, "ReceptionDate"), OrthancException); // already used
80 ASSERT_THROW(d.Add(MetadataType_ModifiedFrom, "1024"), OrthancException); // cannot register numbers
81 d.Add(MetadataType_ModifiedFrom, "ModifiedFrom"); // ok
82 }
83
84
TEST(EnumerationDictionary,ServerEnumerations)85 TEST(EnumerationDictionary, ServerEnumerations)
86 {
87 ASSERT_STREQ("Patient", EnumerationToString(ResourceType_Patient));
88 ASSERT_STREQ("Study", EnumerationToString(ResourceType_Study));
89 ASSERT_STREQ("Series", EnumerationToString(ResourceType_Series));
90 ASSERT_STREQ("Instance", EnumerationToString(ResourceType_Instance));
91
92 ASSERT_STREQ("ModifiedSeries", EnumerationToString(ChangeType_ModifiedSeries));
93
94 ASSERT_STREQ("Failure", EnumerationToString(StoreStatus_Failure));
95 ASSERT_STREQ("Success", EnumerationToString(StoreStatus_Success));
96
97 ASSERT_STREQ("CompletedSeries", EnumerationToString(ChangeType_CompletedSeries));
98
99 ASSERT_EQ("IndexInSeries", EnumerationToString(MetadataType_Instance_IndexInSeries));
100 ASSERT_EQ("LastUpdate", EnumerationToString(MetadataType_LastUpdate));
101
102 ASSERT_EQ(ResourceType_Patient, StringToResourceType("PATienT"));
103 ASSERT_EQ(ResourceType_Study, StringToResourceType("STudy"));
104 ASSERT_EQ(ResourceType_Series, StringToResourceType("SeRiEs"));
105 ASSERT_EQ(ResourceType_Instance, StringToResourceType("INStance"));
106 ASSERT_EQ(ResourceType_Instance, StringToResourceType("IMagE"));
107 ASSERT_THROW(StringToResourceType("heLLo"), OrthancException);
108
109 ASSERT_EQ(2047, StringToMetadata("2047"));
110 ASSERT_THROW(StringToMetadata("Ceci est un test"), OrthancException);
111 ASSERT_THROW(RegisterUserMetadata(128, ""), OrthancException); // too low (< 1024)
112 ASSERT_THROW(RegisterUserMetadata(128000, ""), OrthancException); // too high (> 65535)
113 RegisterUserMetadata(2047, "Ceci est un test");
114 ASSERT_EQ(2047, StringToMetadata("2047"));
115 ASSERT_EQ(2047, StringToMetadata("Ceci est un test"));
116
117 ASSERT_STREQ("Generic", EnumerationToString(StringToModalityManufacturer("Generic")));
118 ASSERT_STREQ("GenericNoWildcardInDates", EnumerationToString(StringToModalityManufacturer("GenericNoWildcardInDates")));
119 ASSERT_STREQ("GenericNoUniversalWildcard", EnumerationToString(StringToModalityManufacturer("GenericNoUniversalWildcard")));
120 ASSERT_STREQ("Vitrea", EnumerationToString(StringToModalityManufacturer("Vitrea")));
121 ASSERT_STREQ("GE", EnumerationToString(StringToModalityManufacturer("GE")));
122 // backward compatibility tests (to remove once we make these manufacturer really obsolete)
123 ASSERT_STREQ("Generic", EnumerationToString(StringToModalityManufacturer("MedInria")));
124 ASSERT_STREQ("Generic", EnumerationToString(StringToModalityManufacturer("EFilm2")));
125 ASSERT_STREQ("Generic", EnumerationToString(StringToModalityManufacturer("ClearCanvas")));
126 ASSERT_STREQ("Generic", EnumerationToString(StringToModalityManufacturer("Dcm4Chee")));
127 ASSERT_STREQ("GenericNoWildcardInDates", EnumerationToString(StringToModalityManufacturer("SyngoVia")));
128 ASSERT_STREQ("GenericNoWildcardInDates", EnumerationToString(StringToModalityManufacturer("AgfaImpax")));
129
130 ASSERT_STREQ("default", EnumerationToString(StringToVerbosity("default")));
131 ASSERT_STREQ("verbose", EnumerationToString(StringToVerbosity("verbose")));
132 ASSERT_STREQ("trace", EnumerationToString(StringToVerbosity("trace")));
133 ASSERT_THROW(StringToVerbosity("nope"), OrthancException);
134 }
135
136
137
TEST(FontRegistry,Basic)138 TEST(FontRegistry, Basic)
139 {
140 Orthanc::Image s(Orthanc::PixelFormat_RGB24, 640, 480, false);
141 memset(s.GetBuffer(), 0, s.GetPitch() * s.GetHeight());
142
143 {
144 Orthanc::OrthancConfiguration::ReaderLock lock;
145 ASSERT_GE(1u, lock.GetConfiguration().GetFontRegistry().GetSize());
146 lock.GetConfiguration().GetFontRegistry().GetFont(0).Draw
147 (s, "Hello world É\n\rComment ça va ?\nq", 50, 60, 255, 0, 0);
148 }
149
150 Orthanc::PngWriter w;
151 Orthanc::IImageWriter::WriteToFile(w, "UnitTestsResults/font.png", s);
152 }
153
154
TEST(FromDcmtkBridge,ValueRepresentationConversions)155 TEST(FromDcmtkBridge, ValueRepresentationConversions)
156 {
157 #if ORTHANC_ENABLE_PLUGINS == 1
158 ASSERT_EQ(1, ValueRepresentation_ApplicationEntity);
159 ASSERT_EQ(1, OrthancPluginValueRepresentation_AE);
160
161 for (int i = ValueRepresentation_ApplicationEntity;
162 i <= ValueRepresentation_NotSupported; i++)
163 {
164 ValueRepresentation vr = static_cast<ValueRepresentation>(i);
165
166 if (vr == ValueRepresentation_NotSupported)
167 {
168 ASSERT_THROW(ToDcmtkBridge::Convert(vr), OrthancException);
169 ASSERT_THROW(Plugins::Convert(vr), OrthancException);
170 }
171 else if (vr == ValueRepresentation_OtherDouble ||
172 vr == ValueRepresentation_OtherLong ||
173 vr == ValueRepresentation_UniversalResource ||
174 vr == ValueRepresentation_UnlimitedCharacters)
175 {
176 // These VR are not supported as of DCMTK 3.6.0
177 ASSERT_THROW(ToDcmtkBridge::Convert(vr), OrthancException);
178 ASSERT_EQ(OrthancPluginValueRepresentation_UN, Plugins::Convert(vr));
179 }
180 else
181 {
182 ASSERT_EQ(vr, FromDcmtkBridge::Convert(ToDcmtkBridge::Convert(vr)));
183
184 OrthancPluginValueRepresentation plugins = Plugins::Convert(vr);
185 ASSERT_EQ(vr, Plugins::Convert(plugins));
186 }
187 }
188
189 for (int i = OrthancPluginValueRepresentation_AE;
190 i <= OrthancPluginValueRepresentation_UT; i++)
191 {
192 OrthancPluginValueRepresentation plugins = static_cast<OrthancPluginValueRepresentation>(i);
193 ValueRepresentation orthanc = Plugins::Convert(plugins);
194 ASSERT_EQ(plugins, Plugins::Convert(orthanc));
195 }
196 #endif
197 }
198
199
200
TEST(DicomMap,DicomAsJson)201 TEST(DicomMap, DicomAsJson)
202 {
203 // This is a Latin-1 test string: "crane" with a circumflex accent
204 const unsigned char raw[] = { 0x63, 0x72, 0xe2, 0x6e, 0x65 };
205 std::string latin1((char*) &raw[0], sizeof(raw) / sizeof(char));
206
207 std::string utf8 = Toolbox::ConvertToUtf8(latin1, Encoding_Latin1, false);
208
209 ParsedDicomFile dicom(false);
210 dicom.SetEncoding(Encoding_Latin1);
211 dicom.ReplacePlainString(DICOM_TAG_PATIENT_NAME, "Hello");
212 dicom.ReplacePlainString(DICOM_TAG_STUDY_DESCRIPTION, utf8);
213 dicom.ReplacePlainString(DICOM_TAG_SERIES_DESCRIPTION, std::string(ORTHANC_MAXIMUM_TAG_LENGTH, 'a'));
214 dicom.ReplacePlainString(DICOM_TAG_MANUFACTURER, std::string(ORTHANC_MAXIMUM_TAG_LENGTH + 1, 'a'));
215 dicom.ReplacePlainString(DICOM_TAG_PIXEL_DATA, "binary");
216 dicom.ReplacePlainString(DICOM_TAG_ROWS, "512");
217
218 DcmDataset& dataset = *dicom.GetDcmtkObject().getDataset();
219 dataset.insertEmptyElement(DCM_StudyID, OFFalse);
220
221 {
222 std::unique_ptr<DcmSequenceOfItems> sequence(new DcmSequenceOfItems(DCM_ReferencedSeriesSequence));
223
224 {
225 std::unique_ptr<DcmItem> item(new DcmItem);
226 item->putAndInsertString(DCM_ReferencedSOPInstanceUID, "nope", OFFalse);
227 ASSERT_TRUE(sequence->insert(item.release(), false, false).good());
228 }
229
230 ASSERT_TRUE(dataset.insert(sequence.release(), false, false).good());
231 }
232
233
234 // Check re-encoding
235 DcmElement* element = NULL;
236 ASSERT_TRUE(dataset.findAndGetElement(DCM_StudyDescription, element).good() &&
237 element != NULL);
238
239 char* c = NULL;
240 ASSERT_TRUE(element != NULL &&
241 element->isLeaf() &&
242 element->isaString() &&
243 element->getString(c).good());
244 ASSERT_EQ(0, memcmp(c, raw, latin1.length()));
245
246 ASSERT_TRUE(dataset.findAndGetElement(DCM_Rows, element).good() &&
247 element != NULL &&
248 element->getTag().getEVR() == EVR_US);
249
250 std::unique_ptr<DicomInstanceToStore> toStore(DicomInstanceToStore::CreateFromParsedDicomFile(dicom));
251
252 Json::Value dicomAsJson;
253 OrthancConfiguration::DefaultDicomDatasetToJson(dicomAsJson, toStore->GetParsedDicomFile());
254
255 DicomMap m;
256 m.FromDicomAsJson(dicomAsJson);
257
258 ASSERT_EQ("ISO_IR 100", m.GetValue(DICOM_TAG_SPECIFIC_CHARACTER_SET).GetContent());
259
260 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).IsBinary());
261 ASSERT_EQ("Hello", m.GetValue(DICOM_TAG_PATIENT_NAME).GetContent());
262
263 ASSERT_FALSE(m.GetValue(DICOM_TAG_STUDY_DESCRIPTION).IsBinary());
264 ASSERT_EQ(utf8, m.GetValue(DICOM_TAG_STUDY_DESCRIPTION).GetContent());
265
266 ASSERT_FALSE(m.HasTag(DICOM_TAG_MANUFACTURER)); // Too long
267 ASSERT_FALSE(m.HasTag(DICOM_TAG_PIXEL_DATA)); // Pixel data
268 ASSERT_FALSE(m.HasTag(DICOM_TAG_REFERENCED_SERIES_SEQUENCE)); // Sequence
269 ASSERT_EQ(DICOM_TAG_REFERENCED_SERIES_SEQUENCE.GetGroup(), DCM_ReferencedSeriesSequence.getGroup());
270 ASSERT_EQ(DICOM_TAG_REFERENCED_SERIES_SEQUENCE.GetElement(), DCM_ReferencedSeriesSequence.getElement());
271
272 ASSERT_TRUE(m.HasTag(DICOM_TAG_SERIES_DESCRIPTION)); // Maximum length
273 ASSERT_FALSE(m.GetValue(DICOM_TAG_SERIES_DESCRIPTION).IsBinary());
274 ASSERT_EQ(ORTHANC_MAXIMUM_TAG_LENGTH,
275 static_cast<int>(m.GetValue(DICOM_TAG_SERIES_DESCRIPTION).GetContent().length()));
276
277 ASSERT_FALSE(m.GetValue(DICOM_TAG_ROWS).IsBinary());
278 ASSERT_EQ("512", m.GetValue(DICOM_TAG_ROWS).GetContent());
279
280 ASSERT_FALSE(m.GetValue(DICOM_TAG_STUDY_ID).IsNull());
281 ASSERT_FALSE(m.GetValue(DICOM_TAG_STUDY_ID).IsBinary());
282 ASSERT_EQ("", m.GetValue(DICOM_TAG_STUDY_ID).GetContent());
283
284 DicomArray a(m);
285 ASSERT_EQ(6u, a.GetSize());
286
287
288 //dicom.SaveToFile("/tmp/test.dcm");
289 //std::cout << toStore.GetJson() << std::endl;
290 //a.Print(stdout);
291 }
292
293
294
295 namespace Orthanc
296 {
297 // Namespace for the "FRIEND_TEST()" directive in "FromDcmtkBridge" to apply:
298 // https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#private-class-members
299
300 static const DicomTag REFERENCED_STUDY_SEQUENCE(0x0008, 0x1110);
301 static const DicomTag REFERENCED_PATIENT_SEQUENCE(0x0008, 0x1120);
302
CreateSampleJson(Json::Value & a)303 static void CreateSampleJson(Json::Value& a)
304 {
305 {
306 Json::Value b = Json::objectValue;
307 b["PatientName"] = "Hello";
308 b["PatientID"] = "World";
309 b["StudyDescription"] = "Toto";
310 a.append(b);
311 }
312
313 {
314 Json::Value b = Json::objectValue;
315 b["PatientName"] = "data:application/octet-stream;base64,SGVsbG8y"; // echo -n "Hello2" | base64
316 b["PatientID"] = "World2";
317 a.append(b);
318 }
319 }
320
TEST(FromDcmtkBridge,FromJson)321 TEST(FromDcmtkBridge, FromJson)
322 {
323 std::unique_ptr<DcmElement> element;
324
325 {
326 Json::Value a;
327 a = "Hello";
328 element.reset(FromDcmtkBridge::FromJson(DICOM_TAG_PATIENT_NAME, a, false, Encoding_Utf8, ""));
329
330 Json::Value b;
331 std::set<DicomTag> ignoreTagLength;
332 ignoreTagLength.insert(DICOM_TAG_PATIENT_ID);
333
334 FromDcmtkBridge::ElementToJson(b, *element, DicomToJsonFormat_Short,
335 DicomToJsonFlags_Default, 0, Encoding_Ascii, false, ignoreTagLength, 0);
336 ASSERT_TRUE(b.isMember("0010,0010"));
337 ASSERT_EQ("Hello", b["0010,0010"].asString());
338
339 FromDcmtkBridge::ElementToJson(b, *element, DicomToJsonFormat_Short,
340 DicomToJsonFlags_Default, 3, Encoding_Ascii, false, ignoreTagLength, 0);
341 ASSERT_TRUE(b["0010,0010"].isNull()); // "Hello" has more than 3 characters
342
343 FromDcmtkBridge::ElementToJson(b, *element, DicomToJsonFormat_Full,
344 DicomToJsonFlags_Default, 3, Encoding_Ascii, false, ignoreTagLength, 0);
345 ASSERT_TRUE(b["0010,0010"].isObject());
346 ASSERT_EQ("PatientName", b["0010,0010"]["Name"].asString());
347 ASSERT_EQ("TooLong", b["0010,0010"]["Type"].asString());
348 ASSERT_TRUE(b["0010,0010"]["Value"].isNull());
349
350 ignoreTagLength.insert(DICOM_TAG_PATIENT_NAME);
351 FromDcmtkBridge::ElementToJson(b, *element, DicomToJsonFormat_Short,
352 DicomToJsonFlags_Default, 3, Encoding_Ascii, false, ignoreTagLength, 0);
353 ASSERT_EQ("Hello", b["0010,0010"].asString());
354 }
355
356 {
357 Json::Value a;
358 a = "Hello";
359 // Cannot assign a string to a sequence
360 ASSERT_THROW(element.reset(FromDcmtkBridge::FromJson(REFERENCED_STUDY_SEQUENCE, a, false, Encoding_Utf8, "")), OrthancException);
361 }
362
363 {
364 Json::Value a = Json::arrayValue;
365 a.append("Hello");
366 // Cannot assign an array to a string
367 ASSERT_THROW(element.reset(FromDcmtkBridge::FromJson(DICOM_TAG_PATIENT_NAME, a, false, Encoding_Utf8, "")), OrthancException);
368 }
369
370 {
371 Json::Value a;
372 a = "data:application/octet-stream;base64,SGVsbG8="; // echo -n "Hello" | base64
373 element.reset(FromDcmtkBridge::FromJson(DICOM_TAG_PATIENT_NAME, a, true, Encoding_Utf8, ""));
374
375 Json::Value b;
376 std::set<DicomTag> ignoreTagLength;
377 FromDcmtkBridge::ElementToJson(b, *element, DicomToJsonFormat_Short,
378 DicomToJsonFlags_Default, 0, Encoding_Ascii, false, ignoreTagLength, 0);
379 ASSERT_EQ("Hello", b["0010,0010"].asString());
380 }
381
382 {
383 Json::Value a = Json::arrayValue;
384 CreateSampleJson(a);
385 element.reset(FromDcmtkBridge::FromJson(REFERENCED_STUDY_SEQUENCE, a, true, Encoding_Utf8, ""));
386
387 {
388 Json::Value b;
389 std::set<DicomTag> ignoreTagLength;
390 FromDcmtkBridge::ElementToJson(b, *element, DicomToJsonFormat_Short,
391 DicomToJsonFlags_Default, 0, Encoding_Ascii, false, ignoreTagLength, 0);
392 ASSERT_EQ(Json::arrayValue, b["0008,1110"].type());
393 ASSERT_EQ(2u, b["0008,1110"].size());
394
395 Json::Value::ArrayIndex i = (b["0008,1110"][0]["0010,0010"].asString() == "Hello") ? 0 : 1;
396
397 ASSERT_EQ(3u, b["0008,1110"][i].size());
398 ASSERT_EQ(2u, b["0008,1110"][1 - i].size());
399 ASSERT_EQ(b["0008,1110"][i]["0010,0010"].asString(), "Hello");
400 ASSERT_EQ(b["0008,1110"][i]["0010,0020"].asString(), "World");
401 ASSERT_EQ(b["0008,1110"][i]["0008,1030"].asString(), "Toto");
402 ASSERT_EQ(b["0008,1110"][1 - i]["0010,0010"].asString(), "Hello2");
403 ASSERT_EQ(b["0008,1110"][1 - i]["0010,0020"].asString(), "World2");
404 }
405
406 {
407 Json::Value b;
408 std::set<DicomTag> ignoreTagLength;
409 FromDcmtkBridge::ElementToJson(b, *element, DicomToJsonFormat_Full,
410 DicomToJsonFlags_Default, 0, Encoding_Ascii, false, ignoreTagLength, 0);
411
412 Json::Value c;
413 Toolbox::SimplifyDicomAsJson(c, b, DicomToJsonFormat_Human);
414
415 a[1]["PatientName"] = "Hello2"; // To remove the Data URI Scheme encoding
416 ASSERT_EQ(0, c["ReferencedStudySequence"].compare(a));
417 }
418 }
419 }
420 }
421
422
TEST(StorageCommitmentReports,Basic)423 TEST(StorageCommitmentReports, Basic)
424 {
425 Orthanc::StorageCommitmentReports reports(2);
426 ASSERT_EQ(2u, reports.GetMaxSize());
427
428 {
429 Orthanc::StorageCommitmentReports::Accessor accessor(reports, "nope");
430 ASSERT_EQ("nope", accessor.GetTransactionUid());
431 ASSERT_FALSE(accessor.IsValid());
432 ASSERT_THROW(accessor.GetReport(), Orthanc::OrthancException);
433 }
434
435 reports.Store("a", new Orthanc::StorageCommitmentReports::Report("aet_a"));
436 reports.Store("b", new Orthanc::StorageCommitmentReports::Report("aet_b"));
437 reports.Store("c", new Orthanc::StorageCommitmentReports::Report("aet_c"));
438
439 {
440 Orthanc::StorageCommitmentReports::Accessor accessor(reports, "a");
441 ASSERT_FALSE(accessor.IsValid());
442 }
443
444 {
445 Orthanc::StorageCommitmentReports::Accessor accessor(reports, "b");
446 ASSERT_TRUE(accessor.IsValid());
447 ASSERT_EQ("aet_b", accessor.GetReport().GetRemoteAet());
448 ASSERT_EQ(Orthanc::StorageCommitmentReports::Report::Status_Pending,
449 accessor.GetReport().GetStatus());
450 }
451
452 {
453 Orthanc::StorageCommitmentReports::Accessor accessor(reports, "c");
454 ASSERT_EQ("aet_c", accessor.GetReport().GetRemoteAet());
455 ASSERT_TRUE(accessor.IsValid());
456 }
457
458 {
459 std::unique_ptr<Orthanc::StorageCommitmentReports::Report> report
460 (new Orthanc::StorageCommitmentReports::Report("aet"));
461 report->AddSuccess("class1", "instance1");
462 report->AddFailure("class2", "instance2",
463 Orthanc::StorageCommitmentFailureReason_ReferencedSOPClassNotSupported);
464 report->MarkAsComplete();
465 reports.Store("a", report.release());
466 }
467
468 {
469 Orthanc::StorageCommitmentReports::Accessor accessor(reports, "a");
470 ASSERT_TRUE(accessor.IsValid());
471 ASSERT_EQ("aet", accessor.GetReport().GetRemoteAet());
472 ASSERT_EQ(Orthanc::StorageCommitmentReports::Report::Status_Failure,
473 accessor.GetReport().GetStatus());
474 }
475
476 {
477 Orthanc::StorageCommitmentReports::Accessor accessor(reports, "b");
478 ASSERT_FALSE(accessor.IsValid());
479 }
480
481 {
482 Orthanc::StorageCommitmentReports::Accessor accessor(reports, "c");
483 ASSERT_TRUE(accessor.IsValid());
484 }
485
486 {
487 std::unique_ptr<Orthanc::StorageCommitmentReports::Report> report
488 (new Orthanc::StorageCommitmentReports::Report("aet"));
489 report->AddSuccess("class1", "instance1");
490 report->MarkAsComplete();
491 reports.Store("a", report.release());
492 }
493
494 {
495 Orthanc::StorageCommitmentReports::Accessor accessor(reports, "a");
496 ASSERT_TRUE(accessor.IsValid());
497 ASSERT_EQ("aet", accessor.GetReport().GetRemoteAet());
498 ASSERT_EQ(Orthanc::StorageCommitmentReports::Report::Status_Success,
499 accessor.GetReport().GetStatus());
500 }
501
502 {
503 Orthanc::StorageCommitmentReports::Accessor accessor(reports, "b");
504 ASSERT_FALSE(accessor.IsValid());
505 }
506
507 {
508 Orthanc::StorageCommitmentReports::Accessor accessor(reports, "c");
509 ASSERT_TRUE(accessor.IsValid());
510 }
511 }
512
513
514
main(int argc,char ** argv)515 int main(int argc, char **argv)
516 {
517 Logging::Initialize();
518 Toolbox::InitializeGlobalLocale(NULL);
519 SetGlobalVerbosity(Verbosity_Verbose);
520 Toolbox::DetectEndianness();
521 SystemToolbox::MakeDirectory("UnitTestsResults");
522 OrthancInitialize();
523
524 ::testing::InitGoogleTest(&argc, argv);
525 int result = RUN_ALL_TESTS();
526
527 OrthancFinalize();
528 Logging::Finalize();
529
530 return result;
531 }
532