changeset 701:bdb9763d53ff find-refactoring

readonly tests
author Alain Mazy <am@orthanc.team>
date Thu, 26 Sep 2024 17:58:40 +0200
parents 8561d9c88d1a
children
files NewTests/README NewTests/ReadOnly/__init__.py NewTests/ReadOnly/test_readonly_pg.py NewTests/helpers.py
diffstat 3 files changed, 171 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/NewTests/README	Thu Sep 26 12:27:52 2024 +0200
+++ b/NewTests/README	Thu Sep 26 17:58:40 2024 +0200
@@ -192,3 +192,22 @@
 
 python3 NewTests/main.py --pattern=PostgresUpgrades.test_pg_upgrades.TestPgUpgrades.* \
                          --orthanc_under_tests_docker_image=orthancteam/orthanc:current
+
+
+Read Only PG:
+--------------
+
+Run the Read Only tests with your locally build version and break before execution to allow you to start your debugger.
+
+python3 NewTests/main.py --pattern=ReadOnly.test_readonly_pg.TestReadOnlyPG.* \
+                         --orthanc_under_tests_exe=/home/alain/o/build/orthanc/Orthanc \
+                         --orthanc_under_tests_http_port=8043 \
+                         --plugin=/home/alain/o/build/orthanc-dicomweb/libOrthancDicomWeb.so \
+                         --plugin=/home/alain/o/build/pg/libOrthancPostgreSQLIndex.so \
+                         --break_after_preparation
+
+with Docker (TODO):
+
+python3 NewTests/main.py --pattern=ReadOnly.test_readonly_pg.TestReadOnlyPG.* \
+                         --orthanc_under_tests_docker_image=orthancteam/orthanc:current \
+                         --orthanc_under_tests_http_port=8043
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NewTests/ReadOnly/test_readonly_pg.py	Thu Sep 26 17:58:40 2024 +0200
@@ -0,0 +1,149 @@
+import unittest
+import time
+import os
+import threading
+from helpers import OrthancTestCase, Helpers
+
+from orthanc_api_client import OrthancApiClient, ChangeType
+from orthanc_api_client.exceptions import HttpError
+from orthanc_api_client import helpers as OrthancHelpers
+
+from orthanc_tools import OrthancTestDbPopulator
+
+import pathlib
+import subprocess
+import glob
+here = pathlib.Path(__file__).parent.resolve()
+
+
+class TestReadOnlyPG(OrthancTestCase):
+
+    @classmethod
+    def terminate(cls):
+
+        if Helpers.is_docker():
+            subprocess.run(["docker", "rm", "-f", "pg-server"])
+        else:
+            cls.pg_service_process.terminate()
+
+
+    @classmethod
+    def prepare(cls):
+        test_name = "ReadOnlyPG"
+        cls._storage_name = "read-only-pg"  #actually not used since we are using PG storage
+        network_name = "read-only-pg"
+
+        print(f'-------------- preparing {test_name} tests')
+
+        pg_hostname = "localhost"
+        if Helpers.is_docker():
+            pg_hostname = "pg-server"
+            cls.create_docker_network(network_name)
+
+        config = { 
+            "PostgreSQL" : {
+                "EnableStorage": True,
+                "EnableIndex": True,
+                "Host": pg_hostname,
+                "Port": 5432,
+                "Database": "postgres",
+                "Username": "postgres",
+                "Password": "postgres",
+                "IndexConnectionsCount": 10,
+                "MaximumConnectionRetries" : 20,
+                "ConnectionRetryInterval" : 1,
+                "TransactionMode": "ReadCommitted",
+                "EnableVerboseLogs": True
+            },
+            "AuthenticationEnabled": False,
+            "OverwriteInstances": True,
+            "ReadOnly": False,               # disable for preparation
+            "DicomWeb": {
+                "EnableMetadataCache": False # disable for preparation
+            }
+        }
+
+        # launch the docker PG server
+        print('--------------- launching PostgreSQL server ------------------')
+
+        pg_cmd = [            
+            "docker", "run", "--rm", 
+            "-p", "5432:5432", 
+            "--name", "pg-server",
+            "--env", "POSTGRES_HOST_AUTH_METHOD=trust"
+            ]
+        
+        if Helpers.is_docker():
+            pg_cmd.extend(["--network", network_name])
+        pg_cmd.append("postgres:15")
+
+        cls.pg_service_process = subprocess.Popen(pg_cmd)
+        time.sleep(5)
+
+        print('--------------- launching Orthanc to prepare DB ------------------')
+        cls.launch_orthanc_to_prepare_db(
+            config_name=f"{test_name}",
+            storage_name=cls._storage_name,
+            config=config,
+            plugins=Helpers.plugins,
+            docker_network=network_name
+        )
+
+        # upload a study
+        cls.uploaded_instances_ids = cls.o.upload_folder(here / "../../Database/Knix/Loc")
+        cls.one_instance_id = cls.uploaded_instances_ids[0]
+        cls.one_series_id = cls.o.instances.get_parent_series_id(cls.one_instance_id)
+        cls.one_study_id = cls.o.series.get_parent_study_id(cls.one_series_id)
+        cls.one_patient_id = cls.o.studies.get_parent_patient_id(cls.one_study_id)
+
+        cls.kill_orthanc()
+
+        print('--------------- stopped preparation Orthanc  ------------------')
+
+        time.sleep(3)
+
+        # modify config for the readonly version
+        config["ReadOnly"] = True
+        config["DicomWeb"]["EnableMetadataCache"] = True
+
+        config_path = cls.generate_configuration(
+            config_name=f"{test_name}",
+            storage_name=cls._storage_name,
+            config=config,
+            plugins=Helpers.plugins
+        )
+
+        if Helpers.break_after_preparation:
+            print(f"++++ It is now time to start your Orthanc under tests with configuration file '{config_path}' +++++")
+            input("Press Enter to continue")
+        else:
+            cls.launch_orthanc_under_tests(
+                config_name=f"{test_name}",
+                storage_name=cls._storage_name,
+                config=config,
+                plugins=Helpers.plugins,
+                docker_network=network_name
+            )
+
+        cls.o = OrthancApiClient(cls.o._root_url)
+        cls.o.wait_started()
+
+
+    def test_write_methods_fail(self):
+        self.assertRaises(Exception, lambda: self.o.upload_folder(here / "../../Database/Knix/Loc"))
+        self.assertRaises(Exception, lambda: self.o.instances.delete(self.one_instance_id))
+        self.assertRaises(Exception, lambda: self.o.series.delete(self.one_series_id))
+        self.assertRaises(Exception, lambda: self.o.studies.delete(self.one_study_id))
+        self.assertRaises(Exception, lambda: self.o.patients.delete(self.one_patient_id))
+        
+        tags = self.o.instances.get_tags(self.one_instance_id)
+
+
+
+    def test_read_methods_succeed(self):
+        # nothing should raise
+        tags = self.o.instances.get_tags(self.one_instance_id)
+
+        self.o.get_json(f"/dicom-web/studies/{tags['StudyInstanceUID']}/metadata")
+        self.o.get_json(f"/dicom-web/studies/{tags['StudyInstanceUID']}/series/{tags['SeriesInstanceUID']}/metadata")
+        self.o.get_json(f"/statistics") 
--- a/NewTests/helpers.py	Thu Sep 26 12:27:52 2024 +0200
+++ b/NewTests/helpers.py	Thu Sep 26 17:58:40 2024 +0200
@@ -196,7 +196,7 @@
             subprocess.run(["docker", "network", "create", network])
 
     @classmethod
-    def launch_orthanc_to_prepare_db(cls, config_name: str = None, config: object = None, config_path: str = None, storage_name: str = None, plugins = []):
+    def launch_orthanc_to_prepare_db(cls, config_name: str = None, config: object = None, config_path: str = None, storage_name: str = None, plugins = [], docker_network: str = None):
         if config_name and storage_name and config:
             # generate the configuration file
             config_path = cls.generate_configuration(
@@ -219,7 +219,8 @@
                 docker_image=Helpers.orthanc_previous_version_docker_image,
                 storage_name=storage_name,
                 config_name=config_name,
-                config_path=config_path
+                config_path=config_path,
+                network=docker_network
             )
         else:
             raise RuntimeError("Invalid configuration, can not launch Orthanc")