Mercurial > hg > orthanc
comparison OrthancServer/UnitTestsSources/ServerIndexTests.cpp @ 4514:5b929e6b3c36
removal of "dicom-as-json" attachments
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 16 Feb 2021 12:18:41 +0100 |
parents | 8f9090b137f1 |
children | 9224e107d613 |
comparison
equal
deleted
inserted
replaced
4513:1f455b86b054 | 4514:5b929e6b3c36 |
---|---|
35 #include <gtest/gtest.h> | 35 #include <gtest/gtest.h> |
36 | 36 |
37 #include "../../OrthancFramework/Sources/Compatibility.h" | 37 #include "../../OrthancFramework/Sources/Compatibility.h" |
38 #include "../../OrthancFramework/Sources/FileStorage/FilesystemStorage.h" | 38 #include "../../OrthancFramework/Sources/FileStorage/FilesystemStorage.h" |
39 #include "../../OrthancFramework/Sources/FileStorage/MemoryStorageArea.h" | 39 #include "../../OrthancFramework/Sources/FileStorage/MemoryStorageArea.h" |
40 #include "../../OrthancFramework/Sources/Images/Image.h" | |
40 #include "../../OrthancFramework/Sources/Logging.h" | 41 #include "../../OrthancFramework/Sources/Logging.h" |
41 | 42 |
42 #include "../Sources/Database/SQLiteDatabaseWrapper.h" | 43 #include "../Sources/Database/SQLiteDatabaseWrapper.h" |
43 #include "../Sources/OrthancConfiguration.h" | 44 #include "../Sources/OrthancConfiguration.h" |
44 #include "../Sources/Search/DatabaseLookup.h" | 45 #include "../Sources/Search/DatabaseLookup.h" |
732 std::map<MetadataType, std::string> instanceMetadata; | 733 std::map<MetadataType, std::string> instanceMetadata; |
733 | 734 |
734 { | 735 { |
735 DicomMap summary; | 736 DicomMap summary; |
736 OrthancConfiguration::DefaultExtractDicomSummary(summary, toStore->GetParsedDicomFile()); | 737 OrthancConfiguration::DefaultExtractDicomSummary(summary, toStore->GetParsedDicomFile()); |
738 toStore->SetOrigin(DicomInstanceOrigin::FromPlugins()); | |
737 | 739 |
738 DicomTransferSyntax transferSyntax; | 740 DicomTransferSyntax transferSyntax; |
739 bool hasTransferSyntax = dicom.LookupTransferSyntax(transferSyntax); | 741 bool hasTransferSyntax = dicom.LookupTransferSyntax(transferSyntax); |
740 ASSERT_EQ(StoreStatus_Success, index.Store( | 742 ASSERT_EQ(StoreStatus_Success, index.Store( |
741 instanceMetadata, summary, attachments, toStore->GetMetadata(), | 743 instanceMetadata, summary, attachments, toStore->GetMetadata(), |
796 } | 798 } |
797 | 799 |
798 | 800 |
799 TEST(ServerIndex, Overwrite) | 801 TEST(ServerIndex, Overwrite) |
800 { | 802 { |
803 // Create a dummy 1x1 image | |
804 Image image(PixelFormat_Grayscale8, 1, 1, false); | |
805 reinterpret_cast<uint8_t*>(image.GetBuffer()) [0] = 128; | |
806 | |
801 for (unsigned int i = 0; i < 2; i++) | 807 for (unsigned int i = 0; i < 2; i++) |
802 { | 808 { |
803 bool overwrite = (i == 0); | 809 bool overwrite = (i == 0); |
804 | 810 |
805 MemoryStorageArea storage; | 811 MemoryStorageArea storage; |
829 ASSERT_EQ(0u, diskSize); | 835 ASSERT_EQ(0u, diskSize); |
830 | 836 |
831 { | 837 { |
832 ParsedDicomFile dicom(instance, GetDefaultDicomEncoding(), false /* be strict */); | 838 ParsedDicomFile dicom(instance, GetDefaultDicomEncoding(), false /* be strict */); |
833 | 839 |
840 // Add a pixel data so as to have one "FileContentType_DicomUntilPixelData" | |
841 // (because of "context.SetCompressionEnabled(true)") | |
842 dicom.EmbedImage(image); | |
843 | |
834 DicomInstanceHasher hasher(instance); | 844 DicomInstanceHasher hasher(instance); |
835 | 845 |
836 std::unique_ptr<DicomInstanceToStore> toStore(DicomInstanceToStore::CreateFromParsedDicomFile(dicom)); | 846 std::unique_ptr<DicomInstanceToStore> toStore(DicomInstanceToStore::CreateFromParsedDicomFile(dicom)); |
837 toStore->SetOrigin(DicomInstanceOrigin::FromPlugins()); | 847 toStore->SetOrigin(DicomInstanceOrigin::FromPlugins()); |
838 ASSERT_EQ(id, hasher.HashInstance()); | 848 ASSERT_EQ(id, hasher.HashInstance()); |
840 std::string id2; | 850 std::string id2; |
841 ASSERT_EQ(StoreStatus_Success, context.Store(id2, *toStore, StoreInstanceMode_Default)); | 851 ASSERT_EQ(StoreStatus_Success, context.Store(id2, *toStore, StoreInstanceMode_Default)); |
842 ASSERT_EQ(id, id2); | 852 ASSERT_EQ(id, id2); |
843 } | 853 } |
844 | 854 |
845 FileInfo dicom1, json1; | 855 { |
856 FileInfo nope; | |
857 ASSERT_FALSE(context.GetIndex().LookupAttachment(nope, id, FileContentType_DicomAsJson)); | |
858 } | |
859 | |
860 FileInfo dicom1, pixelData1; | |
846 ASSERT_TRUE(context.GetIndex().LookupAttachment(dicom1, id, FileContentType_Dicom)); | 861 ASSERT_TRUE(context.GetIndex().LookupAttachment(dicom1, id, FileContentType_Dicom)); |
847 ASSERT_TRUE(context.GetIndex().LookupAttachment(json1, id, FileContentType_DicomAsJson)); | 862 ASSERT_TRUE(context.GetIndex().LookupAttachment(pixelData1, id, FileContentType_DicomUntilPixelData)); |
848 | 863 |
849 context.GetIndex().GetGlobalStatistics(diskSize, uncompressedSize, countPatients, | 864 context.GetIndex().GetGlobalStatistics(diskSize, uncompressedSize, countPatients, |
850 countStudies, countSeries, countInstances); | 865 countStudies, countSeries, countInstances); |
851 ASSERT_EQ(1u, countInstances); | 866 ASSERT_EQ(1u, countInstances); |
852 ASSERT_EQ(dicom1.GetCompressedSize() + json1.GetCompressedSize(), diskSize); | 867 ASSERT_EQ(dicom1.GetCompressedSize() + pixelData1.GetCompressedSize(), diskSize); |
853 ASSERT_EQ(dicom1.GetUncompressedSize() + json1.GetUncompressedSize(), uncompressedSize); | 868 ASSERT_EQ(dicom1.GetUncompressedSize() + pixelData1.GetUncompressedSize(), uncompressedSize); |
854 | 869 |
855 Json::Value tmp; | 870 Json::Value tmp; |
856 context.ReadDicomAsJson(tmp, id); | 871 context.ReadDicomAsJson(tmp, id); |
857 ASSERT_EQ("name", tmp["0010,0010"]["Value"].asString()); | 872 ASSERT_EQ("name", tmp["0010,0010"]["Value"].asString()); |
858 | 873 |
868 instance2.Assign(instance); | 883 instance2.Assign(instance); |
869 instance2.SetValue(DICOM_TAG_PATIENT_NAME, "overwritten", false); | 884 instance2.SetValue(DICOM_TAG_PATIENT_NAME, "overwritten", false); |
870 | 885 |
871 ParsedDicomFile dicom(instance2, GetDefaultDicomEncoding(), false /* be strict */); | 886 ParsedDicomFile dicom(instance2, GetDefaultDicomEncoding(), false /* be strict */); |
872 | 887 |
888 // Add a pixel data so as to have one "FileContentType_DicomUntilPixelData" | |
889 dicom.EmbedImage(image); | |
890 | |
873 std::unique_ptr<DicomInstanceToStore> toStore(DicomInstanceToStore::CreateFromParsedDicomFile(dicom)); | 891 std::unique_ptr<DicomInstanceToStore> toStore(DicomInstanceToStore::CreateFromParsedDicomFile(dicom)); |
874 toStore->SetOrigin(DicomInstanceOrigin::FromPlugins()); | 892 toStore->SetOrigin(DicomInstanceOrigin::FromPlugins()); |
875 | 893 |
876 std::string id2; | 894 std::string id2; |
877 ASSERT_EQ(overwrite ? StoreStatus_Success : StoreStatus_AlreadyStored, | 895 ASSERT_EQ(overwrite ? StoreStatus_Success : StoreStatus_AlreadyStored, |
878 context.Store(id2, *toStore, StoreInstanceMode_Default)); | 896 context.Store(id2, *toStore, StoreInstanceMode_Default)); |
879 ASSERT_EQ(id, id2); | 897 ASSERT_EQ(id, id2); |
880 } | 898 } |
881 | 899 |
882 FileInfo dicom2, json2; | 900 { |
901 FileInfo nope; | |
902 ASSERT_FALSE(context.GetIndex().LookupAttachment(nope, id, FileContentType_DicomAsJson)); | |
903 } | |
904 | |
905 FileInfo dicom2, pixelData2; | |
883 ASSERT_TRUE(context.GetIndex().LookupAttachment(dicom2, id, FileContentType_Dicom)); | 906 ASSERT_TRUE(context.GetIndex().LookupAttachment(dicom2, id, FileContentType_Dicom)); |
884 ASSERT_TRUE(context.GetIndex().LookupAttachment(json2, id, FileContentType_DicomAsJson)); | 907 ASSERT_TRUE(context.GetIndex().LookupAttachment(pixelData2, id, FileContentType_DicomUntilPixelData)); |
885 | 908 |
886 context.GetIndex().GetGlobalStatistics(diskSize, uncompressedSize, countPatients, | 909 context.GetIndex().GetGlobalStatistics(diskSize, uncompressedSize, countPatients, |
887 countStudies, countSeries, countInstances); | 910 countStudies, countSeries, countInstances); |
888 ASSERT_EQ(1u, countInstances); | 911 ASSERT_EQ(1u, countInstances); |
889 ASSERT_EQ(dicom2.GetCompressedSize() + json2.GetCompressedSize(), diskSize); | 912 ASSERT_EQ(dicom2.GetCompressedSize() + pixelData2.GetCompressedSize(), diskSize); |
890 ASSERT_EQ(dicom2.GetUncompressedSize() + json2.GetUncompressedSize(), uncompressedSize); | 913 ASSERT_EQ(dicom2.GetUncompressedSize() + pixelData2.GetUncompressedSize(), uncompressedSize); |
891 | 914 |
892 if (overwrite) | 915 if (overwrite) |
893 { | 916 { |
894 ASSERT_NE(dicom1.GetUuid(), dicom2.GetUuid()); | 917 ASSERT_NE(dicom1.GetUuid(), dicom2.GetUuid()); |
895 ASSERT_NE(json1.GetUuid(), json2.GetUuid()); | 918 ASSERT_NE(pixelData1.GetUuid(), pixelData2.GetUuid()); |
896 ASSERT_NE(dicom1.GetUncompressedSize(), dicom2.GetUncompressedSize()); | 919 ASSERT_NE(dicom1.GetUncompressedSize(), dicom2.GetUncompressedSize()); |
897 ASSERT_NE(json1.GetUncompressedSize(), json2.GetUncompressedSize()); | 920 ASSERT_NE(pixelData1.GetUncompressedSize(), pixelData2.GetUncompressedSize()); |
898 | 921 |
899 context.ReadDicomAsJson(tmp, id); | 922 context.ReadDicomAsJson(tmp, id); |
900 ASSERT_EQ("overwritten", tmp["0010,0010"]["Value"].asString()); | 923 ASSERT_EQ("overwritten", tmp["0010,0010"]["Value"].asString()); |
901 | 924 |
902 { | 925 { |
907 } | 930 } |
908 } | 931 } |
909 else | 932 else |
910 { | 933 { |
911 ASSERT_EQ(dicom1.GetUuid(), dicom2.GetUuid()); | 934 ASSERT_EQ(dicom1.GetUuid(), dicom2.GetUuid()); |
912 ASSERT_EQ(json1.GetUuid(), json2.GetUuid()); | 935 ASSERT_EQ(pixelData1.GetUuid(), pixelData2.GetUuid()); |
913 ASSERT_EQ(dicom1.GetUncompressedSize(), dicom2.GetUncompressedSize()); | 936 ASSERT_EQ(dicom1.GetUncompressedSize(), dicom2.GetUncompressedSize()); |
914 ASSERT_EQ(json1.GetUncompressedSize(), json2.GetUncompressedSize()); | 937 ASSERT_EQ(pixelData1.GetUncompressedSize(), pixelData2.GetUncompressedSize()); |
915 | 938 |
916 context.ReadDicomAsJson(tmp, id); | 939 context.ReadDicomAsJson(tmp, id); |
917 ASSERT_EQ("name", tmp["0010,0010"]["Value"].asString()); | 940 ASSERT_EQ("name", tmp["0010,0010"]["Value"].asString()); |
918 | 941 |
919 { | 942 { |
928 db.Close(); | 951 db.Close(); |
929 } | 952 } |
930 } | 953 } |
931 | 954 |
932 | 955 |
956 TEST(ServerIndex, DicomUntilPixelData) | |
957 { | |
958 // Create a dummy 1x1 image | |
959 Image image(PixelFormat_Grayscale8, 1, 1, false); | |
960 reinterpret_cast<uint8_t*>(image.GetBuffer()) [0] = 128; | |
961 | |
962 for (unsigned int i = 0; i < 2; i++) | |
963 { | |
964 const bool compression = (i == 0); | |
965 | |
966 MemoryStorageArea storage; | |
967 SQLiteDatabaseWrapper db; // The SQLite DB is in memory | |
968 db.Open(); | |
969 ServerContext context(db, storage, true /* running unit tests */, 10); | |
970 context.SetupJobsEngine(true, false); | |
971 context.SetCompressionEnabled(compression); | |
972 | |
973 for (unsigned int j = 0; j < 2; j++) | |
974 { | |
975 const bool withPixelData = (j == 0); | |
976 | |
977 ParsedDicomFile dicom(true); | |
978 | |
979 if (withPixelData) | |
980 { | |
981 dicom.EmbedImage(image); | |
982 } | |
983 | |
984 std::string id; | |
985 size_t dicomSize; | |
986 | |
987 { | |
988 std::unique_ptr<DicomInstanceToStore> toStore(DicomInstanceToStore::CreateFromParsedDicomFile(dicom)); | |
989 dicomSize = toStore->GetBufferSize(); | |
990 toStore->SetOrigin(DicomInstanceOrigin::FromPlugins()); | |
991 ASSERT_EQ(StoreStatus_Success, context.Store(id, *toStore, StoreInstanceMode_Default)); | |
992 } | |
993 | |
994 std::set<FileContentType> attachments; | |
995 context.GetIndex().ListAvailableAttachments(attachments, id, ResourceType_Instance); | |
996 | |
997 ASSERT_TRUE(attachments.find(FileContentType_Dicom) != attachments.end()); | |
998 | |
999 if (compression && | |
1000 withPixelData) | |
1001 { | |
1002 ASSERT_EQ(2u, attachments.size()); | |
1003 ASSERT_TRUE(attachments.find(FileContentType_DicomUntilPixelData) != attachments.end()); | |
1004 } | |
1005 else | |
1006 { | |
1007 ASSERT_EQ(1u, attachments.size()); | |
1008 } | |
1009 | |
1010 std::string s; | |
1011 bool found = context.GetIndex().LookupMetadata(s, id, ResourceType_Instance, | |
1012 MetadataType_Instance_PixelDataOffset); | |
1013 | |
1014 if (withPixelData) | |
1015 { | |
1016 ASSERT_TRUE(found); | |
1017 ASSERT_GT(boost::lexical_cast<int>(s), 128 /* length of the DICOM preamble */); | |
1018 ASSERT_LT(boost::lexical_cast<size_t>(s), dicomSize); | |
1019 } | |
1020 else | |
1021 { | |
1022 ASSERT_FALSE(found); | |
1023 } | |
1024 } | |
1025 } | |
1026 } |