changeset 691:79c06b1ed0a8

check storage access counts
author Alain Mazy <am@orthanc.team>
date Wed, 18 Sep 2024 14:54:47 +0200
parents 84b7444330a2
children 377ad9690c7a
files NewTests/ExtraMainDicomTags/test_extra_main_dicom_tags.py Tests/Tests.py
diffstat 2 files changed, 161 insertions(+), 108 deletions(-) [+]
line wrap: on
line diff
--- a/NewTests/ExtraMainDicomTags/test_extra_main_dicom_tags.py	Wed Sep 18 09:36:52 2024 +0200
+++ b/NewTests/ExtraMainDicomTags/test_extra_main_dicom_tags.py	Wed Sep 18 14:54:47 2024 +0200
@@ -28,7 +28,8 @@
                     "Series" : [
                         "RequestAttributesSequence"
                     ],
-                    "Study": [],
+                    "Study": [
+                    ],
                     "Patient": []
                 },
                 "OverwriteInstances": True,
@@ -99,123 +100,148 @@
         self.assertIn("Rows", instance["MainDicomTags"])
         self.assertIn("PerformedProtocolCodeSequence", instance["MainDicomTags"])
 
+    def get_storage_access_count(self):
+        mm = self.o.get_binary("/tools/metrics-prometheus").decode("utf-8")
+        
+        mm = [x.split(" ") for x in mm.split("\n")]
+
+        count = 0
+        for m in mm:
+            if m[0] == 'orthanc_storage_cache_hit_count':
+                # print(f"orthanc_storage_cache_hit_count = {m[1]}")
+                count += int(m[1])
+            if m[0] == 'orthanc_storage_cache_miss_count':
+                # print(f"orthanc_storage_cache_miss_count = {m[1]}")
+                count += int(m[1])
+
+        print(f"storage access count = {count}")
+        return count
+
 
     def test_tools_find(self):
+        if self.o.is_orthanc_version_at_least(12, 5, 0):
 
-        # upload a study
-        self.o.upload_file(here / "../../Database/Brainix/Flair/IM-0001-0001.dcm")
+            # upload a study
+            self.o.upload_file(here / "../../Database/Brainix/Flair/IM-0001-0001.dcm")
 
-        # instance level, only extra main dicom tags from that level
-        r = self.o.post(
-            endpoint="tools/find",
-            json={
-                "Level": "Instances",
-                "Query": {
-                    "PatientID": "5Yp0E"
-                },
-                "Expand": True,
-                "RequestedTags" : [
-                    "Rows",                             # in the ExtraMainDicomTags at instance level
-                    "PerformedProtocolCodeSequence"     # in the ExtraMainDicomTags at instance level
-                ]
-            }
-        )
+            # instance level, only extra main dicom tags from that level
+            c = self.get_storage_access_count()
+            r = self.o.post(
+                endpoint="tools/find",
+                json={
+                    "Level": "Instances",
+                    "Query": {
+                        "PatientID": "5Yp0E"
+                    },
+                    "Expand": True,
+                    "RequestedTags" : [
+                        "Rows",                             # in the ExtraMainDicomTags at instance level
+                        "PerformedProtocolCodeSequence"     # in the ExtraMainDicomTags at instance level
+                    ]
+                }
+            )
 
-        instances = r.json()
-        self.assertEqual(1, len(instances))
-        self.assertIn("Rows", instances[0]["RequestedTags"])
-        self.assertIn("PerformedProtocolCodeSequence", instances[0]["RequestedTags"])
-        # TO test manually: ReferencedStudySequence 0008,1110 should be read from disk
+            instances = r.json()
+            self.assertEqual(1, len(instances))
+            self.assertIn("Rows", instances[0]["RequestedTags"])
+            self.assertIn("PerformedProtocolCodeSequence", instances[0]["RequestedTags"])
+            self.assertEqual(c, self.get_storage_access_count()) # nothing should be read from disk
 
-        # instance level, only extra main dicom tags from that level + a tag from disk
-        r = self.o.post(
-            endpoint="tools/find",
-            json={
-                "Level": "Instances",
-                "Query": {
-                    "PatientID": "5Yp0E"
-                },
-                "Expand": True,
-                "RequestedTags" : [
-                    "Rows",                             # in the ExtraMainDicomTags at instance level
-                    "PerformedProtocolCodeSequence",    # in the ExtraMainDicomTags at instance level
-                    "ReferencedStudySequence"           # "ReferencedStudySequence" is not stored in MainDicomTags !
-                ]
-            }
-        )
+            # instance level, only extra main dicom tags from that level + a tag from disk
+            c = self.get_storage_access_count()
+            r = self.o.post(
+                endpoint="tools/find",
+                json={
+                    "Level": "Instances",
+                    "Query": {
+                        "PatientID": "5Yp0E"
+                    },
+                    "Expand": True,
+                    "RequestedTags" : [
+                        "Rows",                             # in the ExtraMainDicomTags at instance level
+                        "PerformedProtocolCodeSequence",    # in the ExtraMainDicomTags at instance level
+                        "ReferencedStudySequence"           # "ReferencedStudySequence" is not stored in MainDicomTags !
+                    ]
+                }
+            )
 
-        instances = r.json()
-        self.assertEqual(1, len(instances))
-        self.assertIn("Rows", instances[0]["RequestedTags"])
-        self.assertIn("PerformedProtocolCodeSequence", instances[0]["RequestedTags"])
-        self.assertIn("ReferencedStudySequence", instances[0]["RequestedTags"])
-        # TO test manually: ReferencedStudySequence 0008,1110 should be read from disk
+            instances = r.json()
+            self.assertEqual(1, len(instances))
+            self.assertIn("Rows", instances[0]["RequestedTags"])
+            self.assertIn("PerformedProtocolCodeSequence", instances[0]["RequestedTags"])
+            self.assertIn("ReferencedStudySequence", instances[0]["RequestedTags"])
+            self.assertEqual(c + 1, self.get_storage_access_count())
+            # TO test manually: ReferencedStudySequence 0008,1110 should be read from disk
 
-        # instance level, extra main dicom tags from that level + a sequence from upper level
-        r = self.o.post(
-            endpoint="tools/find",
-            json={
-                "Level": "Instances",
-                "Query": {
-                    "PatientID": "5Yp0E"
-                },
-                "Expand": True,
-                "RequestedTags" : [
-                    "Rows",                             # in the ExtraMainDicomTags at instance level
-                    "PerformedProtocolCodeSequence",    # in the ExtraMainDicomTags at instance level   0040,0260
-                    "RequestAttributesSequence"         # in the ExtraMainDicomTags at series level     0040,0275
-                ]
-            }
-        )
+            # instance level, extra main dicom tags from that level + a sequence from upper level
+            c = self.get_storage_access_count()
+            r = self.o.post(
+                endpoint="tools/find",
+                json={
+                    "Level": "Instances",
+                    "Query": {
+                        "PatientID": "5Yp0E"
+                    },
+                    "Expand": True,
+                    "RequestedTags" : [
+                        "Rows",                             # in the ExtraMainDicomTags at instance level
+                        "PerformedProtocolCodeSequence",    # in the ExtraMainDicomTags at instance level   0040,0260
+                        "RequestAttributesSequence"         # in the ExtraMainDicomTags at series level     0040,0275
+                    ]
+                }
+            )
 
-        instances = r.json()
-        self.assertEqual(1, len(instances))
-        self.assertIn("Rows", instances[0]["RequestedTags"])
-        self.assertIn("PerformedProtocolCodeSequence", instances[0]["RequestedTags"])
-        self.assertIn("RequestAttributesSequence", instances[0]["RequestedTags"])  # note that, as of 1.12.5, Orthanc reads this from the disk !
-        # TO test manually: nothing should be read from disk
+            instances = r.json()
+            self.assertEqual(1, len(instances))
+            self.assertIn("Rows", instances[0]["RequestedTags"])
+            self.assertIn("PerformedProtocolCodeSequence", instances[0]["RequestedTags"])
+            self.assertIn("RequestAttributesSequence", instances[0]["RequestedTags"])  # note that, as of 1.12.5, Orthanc reads this from the disk !
+            self.assertEqual(c, self.get_storage_access_count()) # nothing should be read from disk
 
-        # series level, request a sequence
-        r = self.o.post(
-            endpoint="tools/find",
-            json={
-                "Level": "Series",
-                "Query": {
-                    "PatientID": "5Yp0E"
-                },
-                "Expand": True,
-                "RequestedTags" : [
-                    "RequestAttributesSequence"         # in the ExtraMainDicomTags at series level
-                ]
-            }
-        )
+            # series level, request a sequence
+            c = self.get_storage_access_count()
+            r = self.o.post(
+                endpoint="tools/find",
+                json={
+                    "Level": "Series",
+                    "Query": {
+                        "PatientID": "5Yp0E"
+                    },
+                    "Expand": True,
+                    "RequestedTags" : [
+                        "RequestAttributesSequence"         # in the ExtraMainDicomTags at series level
+                    ]
+                }
+            )
 
-        series = r.json()
-        self.assertEqual(1, len(series))
-        self.assertIn("RequestAttributesSequence", series[0]["RequestedTags"])
-        # TO test manually: nothing should be read from disk
+            series = r.json()
+            self.assertEqual(1, len(series))
+            self.assertIn("RequestAttributesSequence", series[0]["RequestedTags"])
+            self.assertEqual(c, self.get_storage_access_count()) # nothing should be read from disk
 
-        # series level, request a sequence + a tag from disk
-        r = self.o.post(
-            endpoint="tools/find",
-            json={
-                "Level": "Series",
-                "Query": {
-                    "PatientID": "5Yp0E"
-                },
-                "Expand": True,
-                "RequestedTags" : [
-                    "RequestAttributesSequence",        # in the ExtraMainDicomTags at series level
-                    "ReferencedStudySequence"           # "ReferencedStudySequence" is not stored in MainDicomTags !
-                ]
-            }
-        )
+            # series level, request a sequence + a tag from disk
+            c = self.get_storage_access_count()
+            r = self.o.post(
+                endpoint="tools/find",
+                json={
+                    "Level": "Series",
+                    "Query": {
+                        "PatientID": "5Yp0E"
+                    },
+                    "Expand": True,
+                    "RequestedTags" : [
+                        "RequestAttributesSequence",        # in the ExtraMainDicomTags at series level
+                        "ReferencedStudySequence"           # "ReferencedStudySequence" is not stored in MainDicomTags !
+                    ]
+                }
+            )
 
-        series = r.json()
-        self.assertEqual(1, len(series))
-        self.assertIn("RequestAttributesSequence", series[0]["RequestedTags"])
-        self.assertIn("ReferencedStudySequence", series[0]["RequestedTags"])
-        # TO test manually: ReferencedStudySequence 0008,1110 should be read from disk
+            series = r.json()
+            self.assertEqual(1, len(series))
+            self.assertIn("RequestAttributesSequence", series[0]["RequestedTags"])
+            self.assertIn("ReferencedStudySequence", series[0]["RequestedTags"])
+            self.assertEqual(c + 1, self.get_storage_access_count())
+            # TO test manually: ReferencedStudySequence 0008,1110 should be read from disk
 
 
     def test_dicom_web_metadata(self):
@@ -230,4 +256,22 @@
         self.assertEqual(1, len(metadata))
         self.assertIn("00280010", metadata[0])      # Rows
         self.assertNotIn("00280011", metadata[0])   # Columns should not be stored !
-        self.assertIn("00400260", metadata[0])      # PerformedProtocolCodeSequence
\ No newline at end of file
+        self.assertIn("00400260", metadata[0])      # PerformedProtocolCodeSequence
+
+    def test_storage_accesses_for_dicom_web(self):
+        if self.o.is_orthanc_version_at_least(12, 5, 0):
+
+            # upload a study
+            self.o.upload_file(here / "../../Database/Brainix/Flair/IM-0001-0001.dcm")
+
+            # study level, only tags that are in DB (note, since 1.12.5, TimezoneOffsetFromUTC is a standard MainDicomTags)
+            c = self.get_storage_access_count()
+            r = self.o.get_json("/dicom-web/studies?PatientID=5Yp0E")
+            self.assertEqual(c, self.get_storage_access_count()) # nothing should be read from disk
+
+            # series level, only tags that are in DB (note, since 1.12.5, TimezoneOffsetFromUTC is a standard MainDicomTags)
+            c = self.get_storage_access_count()
+            r = self.o.get_json("/dicom-web/series?PatientID=5Yp0E")
+            self.assertEqual(c, self.get_storage_access_count()) # nothing should be read from disk
+
+
--- a/Tests/Tests.py	Wed Sep 18 09:36:52 2024 +0200
+++ b/Tests/Tests.py	Wed Sep 18 14:54:47 2024 +0200
@@ -1303,7 +1303,10 @@
         self.assertTrue('LastUpdate' in m)
 
         m = DoGet(_REMOTE, '/series/%s/metadata' % series)
-        if IsOrthancVersionAbove(_REMOTE, 1, 11, 0):
+        if IsOrthancVersionAbove(_REMOTE, 1, 12, 5):
+            self.assertEqual(4, len(m))
+            self.assertTrue('MainDicomSequences' in m)    # since RequestAttributeSequence is now in the MainDicomTags
+        elif IsOrthancVersionAbove(_REMOTE, 1, 11, 0):
             self.assertEqual(3, len(m))
             self.assertTrue('MainDicomTagsSignature' in m)
         else:
@@ -1560,7 +1563,10 @@
 
         series = DoGet(_REMOTE, '/series')[0]
         m = DoGet(_REMOTE, '/series/%s/metadata' % series)
-        if IsOrthancVersionAbove(_REMOTE, 1, 11, 0):
+        if IsOrthancVersionAbove(_REMOTE, 1, 12, 5):
+            self.assertEqual(4, len(m))
+            self.assertTrue('MainDicomSequences' in m)    # since RequestAttributeSequence is now in the MainDicomTags
+        elif IsOrthancVersionAbove(_REMOTE, 1, 11, 0):
             self.assertEqual(3, len(m))
             self.assertTrue('MainDicomTagsSignature' in m)
         else:
@@ -10513,6 +10519,9 @@
             self.assertEqual('Instance', instance['Type'])
             self.assertEqual(1, instance['IndexInSeries'])
             self.assertEqual(0, len(instance['Labels']))
+            # if IsOrthancVersionAbove(_REMOTE, 1, 12, 5):
+            #     self.assertEqual(8, len(instance['MainDicomTags']))  # since we have added SOPClassUID
+            # else:
             self.assertEqual(7, len(instance['MainDicomTags']))
             self.assertEqual('1', instance['MainDicomTags']['AcquisitionNumber'])
             self.assertEqual('0.999841\\0.000366209\\0.0178227\\-0.000427244\\0.999995\\0.00326545', instance['MainDicomTags']['ImageOrientationPatient'])