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 }