Mercurial > hg > orthanc-tests
changeset 820:ae32a816cbe4 attach-custom-data
fix storage tests
author | Alain Mazy <am@orthanc.team> |
---|---|
date | Tue, 27 May 2025 16:20:18 +0200 (5 days ago) |
parents | 6fb7f40a9505 |
children | cc4f3fbcd075 |
files | NewTests/AdvancedStorage/test_advanced_storage.py NewTests/helpers.py |
diffstat | 2 files changed, 84 insertions(+), 43 deletions(-) [+] |
line wrap: on
line diff
--- a/NewTests/AdvancedStorage/test_advanced_storage.py Mon May 26 18:57:37 2025 +0200 +++ b/NewTests/AdvancedStorage/test_advanced_storage.py Tue May 27 16:20:18 2025 +0200 @@ -24,7 +24,7 @@ @classmethod def terminate(cls): - if Helpers.is_docker(): + if Helpers.db == DB.PG: subprocess.run(["docker", "rm", "-f", "pg-server"]) @@ -64,14 +64,15 @@ print(f'-------------- preparing {test_name} tests') + if Helpers.is_docker(): + cls.create_docker_network(network_name) + if Helpers.db == DB.PG: # launch the docker PG server print('--------------- launching PostgreSQL server ------------------') - if Helpers.is_docker(): - # delete previous container if any - subprocess.run(["docker", "rm", "-f", "pg-server"]) - cls.create_docker_network(network_name) + # delete previous container if any + subprocess.run(["docker", "rm", "-f", "pg-server"]) pg_cmd = [ "docker", "run", "--rm", @@ -82,6 +83,7 @@ if Helpers.is_docker(): pg_cmd.extend(["--network", network_name]) + pg_cmd.append("postgres:15") cls.pg_service_process = subprocess.Popen(pg_cmd) @@ -114,11 +116,22 @@ cls.kill_orthanc() time.sleep(3) - shutil.rmtree('/tmp/indexed-files-a', ignore_errors=True) - shutil.rmtree('/tmp/indexed-files-b', ignore_errors=True) + # the path seen by the test + cls.base_test_storage_path = cls.get_storage_path(storage_name=cls._storage_name) + '/' - pathlib.Path('/tmp/indexed-files-a').mkdir(parents=True, exist_ok=True) - pathlib.Path('/tmp/indexed-files-b').mkdir(parents=True, exist_ok=True) + # the path seen by orthanc + if Helpers.is_docker(): + cls.base_orthanc_storage_path = "/var/lib/orthanc/db/" + else: + cls.base_orthanc_storage_path = cls.base_test_storage_path + + shutil.rmtree(cls.base_test_storage_path + 'indexed-files-a', ignore_errors=True) + shutil.rmtree(cls.base_test_storage_path + 'indexed-files-b', ignore_errors=True) + shutil.rmtree(cls.base_test_storage_path + 'adopt-files', ignore_errors=True) + + pathlib.Path(cls.base_test_storage_path + 'indexed-files-a').mkdir(parents=True, exist_ok=True) + pathlib.Path(cls.base_test_storage_path + 'indexed-files-b').mkdir(parents=True, exist_ok=True) + pathlib.Path(cls.base_test_storage_path + 'adopt-files').mkdir(parents=True, exist_ok=True) config = { db_config_key : db_config_content, @@ -130,8 +143,8 @@ "MaxPathLength": 512, "MultipleStorages": { "Storages" : { - "a" : cls.get_storage_path(cls._storage_name) + "/storage-a", - "b" : cls.get_storage_path(cls._storage_name) + "/storage-b" + "a" : cls.base_orthanc_storage_path + "storage-a", + "b" : cls.base_orthanc_storage_path + "storage-b" }, "CurrentWriteStorage": "b" }, @@ -139,8 +152,8 @@ "Indexer" : { "Enable": True, "Folders": [ - "/tmp/indexed-files-a/", - "/tmp/indexed-files-b/" + cls.base_orthanc_storage_path + "indexed-files-a/", + cls.base_orthanc_storage_path + "indexed-files-b/" ], "Interval": 1 }, @@ -174,9 +187,16 @@ cls.o = OrthancApiClient(cls.o._root_url) cls.o.wait_started() + def check_file_exists(self, orthanc_path): + if Helpers.is_docker(): + orthanc_path = orthanc_path.replace("/var/lib/orthanc/db", self.get_storage_path(self._storage_name)) + return os.path.exists(orthanc_path) + def test_can_read_files_saved_without_plugin(self): info0 = self.o.get_json(endpoint=f"/instances/{self.instances_ids_before[0]}/attachments/dicom/info") - self.assertTrue(info0['Path'].startswith(self.get_storage_path(self._storage_name))) + if not Helpers.is_docker(): + self.assertTrue(info0['Path'].startswith(self.get_storage_path(self._storage_name))) + # pprint.pprint(info0) self.assertFalse(info0['Path'].endswith('.dcm')) self.assertFalse(info0['IsAdopted']) self.assertFalse('IsIndexed' in info0 and info0['IsIndexed']) @@ -195,22 +215,26 @@ info_after_move = self.o.get_json(endpoint=f"/instances/{self.instances_ids_before[0]}/attachments/dicom/info") self.assertIn('storage-a', info_after_move['Path']) self.assertEqual("a", info_after_move['StorageId']) - self.assertTrue(os.path.exists(info_after_move['Path'])) - + # self.assertTrue(os.path.exists(info_after_move['Path'])) + self.assertTrue(self.check_file_exists(info_after_move['Path'])) + self.wait_until_no_more_pending_deletion_files() - self.assertFalse(os.path.exists(info0['Path'])) + # self.assertFalse(os.path.exists(info0['Path'])) + self.assertFalse(self.check_file_exists(info0['Path'])) # now delete the instance 0 (the one that has been moved) self.o.instances.delete(orthanc_id=self.instances_ids_before[0]) self.wait_until_no_more_pending_deletion_files() - self.assertFalse(os.path.exists(info_after_move['Path'])) + # self.assertFalse(os.path.exists(info_after_move['Path'])) + self.assertFalse(self.check_file_exists(info_after_move['Path'])) # now delete the instance 1 (that has NOT been moved) self.o.instances.delete(orthanc_id=self.instances_ids_before[1]) self.wait_until_no_more_pending_deletion_files() - self.assertFalse(os.path.exists(info1['Path'])) + # self.assertFalse(os.path.exists(info1['Path'])) + self.assertFalse(self.check_file_exists(info1['Path'])) def test_basic(self): @@ -221,7 +245,8 @@ info = self.o.get_json(endpoint=f"/instances/{uploaded_instances_ids[0]}/attachments/dicom/info") self.assertIn('storage-b/2007/01/01/1.2.840.113619.2.176.2025.1499492.7391.1171285944.390 - ozp00SjY2xG/1.2.840.113619.2.176.2025.1499492.7391.1171285944.388/000001 - ', info['Path']) - self.assertTrue(os.path.exists(info['Path'])) + # self.assertTrue(os.path.exists(info['Path'])) + self.assertTrue(self.check_file_exists(info['Path'])) self.assertTrue(info['Path'].endswith(".dcm")) self.assertFalse(info['IsAdopted']) self.assertFalse(info['IsIndexed']) @@ -236,6 +261,8 @@ OrthancHelpers.wait_until(lambda: self.has_no_more_pending_deletion_files(), timeout=10, polling_interval=1) def test_move_storage(self): + + # upload a single file uploaded_instances_ids = self.o.upload_file(here / "../../Database/Knix/Loc/IM-0001-0001.dcm") @@ -243,7 +270,8 @@ info_before_move = self.o.get_json(endpoint=f"/instances/{uploaded_instances_ids[0]}/attachments/dicom/info") self.assertIn('storage-b', info_before_move['Path']) self.assertEqual("b", info_before_move['StorageId']) - self.assertTrue(os.path.exists(info_before_move['Path'])) + # self.assertTrue(os.path.exists(info_before_move['Path'])) + self.assertTrue(self.check_file_exists(info_before_move['Path'])) # move it to storage A self.o.post(endpoint="/plugins/advanced-storage/move-storage", @@ -256,10 +284,12 @@ info_after_move = self.o.get_json(endpoint=f"/instances/{uploaded_instances_ids[0]}/attachments/dicom/info") self.assertIn('storage-a', info_after_move['Path']) self.assertEqual("a", info_after_move['StorageId']) - self.assertTrue(os.path.exists(info_after_move['Path'])) + # self.assertTrue(os.path.exists(info_after_move['Path'])) + self.assertTrue(self.check_file_exists(info_after_move['Path'])) self.wait_until_no_more_pending_deletion_files() - self.assertFalse(os.path.exists(info_before_move['Path'])) + # self.assertFalse(os.path.exists(info_before_move['Path'])) + self.assertFalse(self.check_file_exists(info_before_move['Path'])) # move it to back to storage B self.o.post(endpoint="/plugins/advanced-storage/move-storage", @@ -272,21 +302,27 @@ info_after_move2 = self.o.get_json(endpoint=f"/instances/{uploaded_instances_ids[0]}/attachments/dicom/info") self.assertIn('storage-b', info_after_move2['Path']) self.assertEqual("b", info_after_move2['StorageId']) - self.assertTrue(os.path.exists(info_after_move2['Path'])) + # self.assertTrue(os.path.exists(info_after_move2['Path'])) + self.assertTrue(self.check_file_exists(info_after_move2['Path'])) self.wait_until_no_more_pending_deletion_files() - self.assertFalse(os.path.exists(info_after_move['Path'])) + # self.assertFalse(os.path.exists(info_after_move['Path'])) + self.assertFalse(self.check_file_exists(info_after_move['Path'])) + + def test_adopt_abandon(self): + + shutil.copy(here / "../../Database/Beaufix/IM-0001-0001.dcm", self.base_test_storage_path + "adopt-files/") + shutil.copy(here / "../../Database/Beaufix/IM-0001-0002.dcm", self.base_test_storage_path + "adopt-files/") - def test_adopt_abandon(self): # adopt a file r1 = self.o.post(endpoint="/plugins/advanced-storage/adopt-instance", json={ - "Path": str(here / "../../Database/Beaufix/IM-0001-0001.dcm") + "Path": self.base_orthanc_storage_path + "adopt-files/IM-0001-0001.dcm" }).json() r2 = self.o.post(endpoint="/plugins/advanced-storage/adopt-instance", json={ - "Path": str(here / "../../Database/Beaufix/IM-0001-0002.dcm") + "Path": self.base_orthanc_storage_path + "adopt-files/IM-0001-0002.dcm" }).json() # pprint.pprint(r1) @@ -297,7 +333,8 @@ self.assertNotIn('StorageId', info1) self.assertTrue(info1['IsAdopted']) self.assertFalse(info1['IsIndexed']) - self.assertTrue(os.path.exists(info1['Path'])) + # self.assertTrue(os.path.exists(info1['Path'])) + self.assertTrue(self.check_file_exists(info1['Path'])) self.assertEqual(r1['AttachmentUuid'], info1['Uuid']) info2 = self.o.get_json(endpoint=f"/instances/{r2['InstanceId']}/attachments/dicom/info") @@ -313,27 +350,29 @@ # delete an adopted file -> the file shall not be removed self.o.instances.delete(orthanc_id=r1['InstanceId']) self.assertNotIn(r1['InstanceId'], self.o.instances.get_all_ids()) - self.assertTrue(os.path.exists(info1['Path'])) + # self.assertTrue(os.path.exists(info1['Path'])) + self.assertTrue(self.check_file_exists(info1['Path'])) # abandon an adopted file -> the file shall not be removed (it shall be equivalent to a delete) self.o.post(endpoint="/plugins/advanced-storage/abandon-instance", json={ - "Path": str(here / "../../Database/Beaufix/IM-0001-0002.dcm") + "Path": self.base_orthanc_storage_path + "adopt-files/IM-0001-0002.dcm" }) self.assertNotIn(r2['InstanceId'], self.o.instances.get_all_ids()) - self.assertTrue(os.path.exists(info2['Path'])) + # self.assertTrue(os.path.exists(info2['Path'])) + self.assertTrue(self.check_file_exists(info2['Path'])) def test_indexer(self): # add 2 files to the 2 indexed folders - shutil.copy(here / "../../Database/Comunix/Ct/IM-0001-0001.dcm", "/tmp/indexed-files-a/") - shutil.copy(here / "../../Database/Comunix/Pet/IM-0001-0001.dcm", "/tmp/indexed-files-b/") + shutil.copy(here / "../../Database/Comunix/Ct/IM-0001-0001.dcm", self.base_test_storage_path + "indexed-files-a/") + shutil.copy(here / "../../Database/Comunix/Pet/IM-0001-0001.dcm", self.base_test_storage_path + "indexed-files-b/") # wait for the files to be indexed - time.sleep(3) + time.sleep(5) # check that the study has been indexed studies = self.o.studies.find(query={"PatientName": "COMUNIX"}) - self.assertEqual(2, len(studies[0].series)) + self.assertEqual(2, len(self.o.studies.get_series_ids(studies[0].orthanc_id))) instances_ids = self.o.studies.get_instances_ids(studies[0].orthanc_id) info1 = self.o.get_json(endpoint=f"/instances/{instances_ids[0]}/attachments/dicom/info") @@ -343,11 +382,11 @@ self.assertTrue(info1['IsAdopted']) # remove one of the file from the indexed folders -> it shall disappear from Orthanc - os.remove(info1['Path']) + os.remove(self.base_test_storage_path + "indexed-files-b/IM-0001-0001.dcm") - time.sleep(3) + time.sleep(5) studies = self.o.studies.find(query={"PatientName": "COMUNIX"}) - self.assertEqual(1, len(studies[0].series)) + self.assertEqual(1, len(self.o.studies.get_series_ids(studies[0].orthanc_id))) # delete the other file from the Orthanc API -> the file shall not be deleted since it is not owned by Orthanc # and it shall not be indexed anymore ... @@ -357,6 +396,6 @@ studies = self.o.studies.find(query={"PatientName": "COMUNIX"}) self.assertEqual(0, len(studies)) - self.assertTrue(os.path.exists(info2['Path'])) + # self.assertTrue(os.path.exists(info2['Path'])) + self.assertTrue(os.path.exists(self.base_test_storage_path + "indexed-files-a/IM-0001-0001.dcm")) -
--- a/NewTests/helpers.py Mon May 26 18:57:37 2025 +0200 +++ b/NewTests/helpers.py Tue May 27 16:20:18 2025 +0200 @@ -190,10 +190,12 @@ "-v", f"{storage_path}:/var/lib/orthanc/db/", "--name", "storage-cleanup", "debian:12-slim", - "rm", "-rf", "/var/lib/orthanc/db/*" + "bash", "-c", "rm -rf /var/lib/orthanc/db/*" ] + subprocess.run(cmd, check=True) + + pathlib.Path(storage_path).mkdir(parents=True, exist_ok=True) - subprocess.run(cmd, check=True) @classmethod def is_storage_empty(cls, storage_name: str):