Mercurial > hg > orthanc-tests
changeset 981:71c6a69c02e3
worklists local-aet
| author | Alain Mazy <am@orthanc.team> |
|---|---|
| date | Thu, 24 Sep 2026 17:28:18 +0200 |
| parents | 07a74087e638 |
| children | dd2ec84ff936 |
| files | GenerateConfigurationForTests.py Tests/Tests.py Tests/Toolbox.py |
| diffstat | 3 files changed, 81 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/GenerateConfigurationForTests.py Thu Sep 24 16:47:04 2026 +0200 +++ b/GenerateConfigurationForTests.py Thu Sep 24 17:28:18 2026 +0200 @@ -127,6 +127,17 @@ 'Host': ip, 'Port': 5001, 'LocalAet': 'OT-FROM-CONFIG' + }, + # This is a Modality used to test if queries such as `find-worklist` use + # the configured `LocalAet` of the modality configuration. This modality + # configuration will allow `find-worklist` queries to succeed if the calling + # (LocalAet) is `FAKE_SELF_AET` + 'self-with-fake-local-aet': { + 'AET': 'FAKE_SELF_AET', + 'Host': '127.0.0.1', + 'Port': 4242, + 'LocalAet': 'FAKE_SELF_AET', + 'AllowFindWorklist': True } } config['DicomPort'] = args.dicom
--- a/Tests/Tests.py Thu Sep 24 16:47:04 2026 +0200 +++ b/Tests/Tests.py Thu Sep 24 17:28:18 2026 +0200 @@ -12910,3 +12910,69 @@ im = GetImage(_REMOTE, '/instances/%s/frames/2/image-uint8' % i) self.assertEqual(800, im.size[0]) self.assertEqual(600, im.size[1]) + + + def test_find_worklist_local_aet(self): + # Purpose: "/modalities/{id}/find-worklist" (and the REST handlers that + # share its SCU connection setup: the deprecated "/find", "/find-patient", + # "/find-study", "/find-series", "/find-instance", and "/echo") must use + # the "LocalAet" configured on the target modality as the calling AE + # title for the outgoing DICOM association, instead of always falling + # back to the global "DicomAet". + # + # How this test works: Orthanc is made to query a worklist/find SCP that + # is itself (a "self-loop", as used e.g. for periodic health checks), + # through the "self-with-fake-local-aet" modality, whose "LocalAet" + # ("FAKE_SELF_AET") is deliberately distinct from the global AET + # ("ORTHANC") and from every other modality's AET in this test + # configuration. The calling AE title is exactly what the SCP-side + # authorization check ("OrthancApplicationEntityFilter::IsAllowedRequest" + # in main.cpp) looks up in its own "DicomModalities" to decide whether to + # accept the incoming association: + # - If "LocalAet" is honored, Orthanc presents "FAKE_SELF_AET" to itself, + # which matches this very "DicomModalities" entry, so the association + # is authorized and the C-FIND succeeds. + # - If "LocalAet" is ignored, Orthanc presents its own global AET + # ("ORTHANC") instead, which isn't declared as any known modality's AET + # here, so the association is rejected and the REST call fails with a + # 500 error ("Peer aborted Association"). + # + # Note: this only works for request types whose "DicomAlwaysAllow*" + # option defaults to false, since otherwise an unrecognized calling AET + # is accepted anyway. This covers "FindWorklist" and the plain "Find" + # family (deprecated "/find*"), but not "Echo" or "Store" (both default + # to true, so they can't be checked this way, regardless of whether + # "LocalAet" is honored). + + if not HasWorklistsPlugin(_REMOTE): + print("skipping worklists tests, plugin is not installed") + return + + if not IsOrthancVersionAbove(_REMOTE, 1, 13, 1): + return + + answers = DoPost(_REMOTE, '/modalities/self-with-fake-local-aet/find-worklist', { + 'Query' : { 'PatientID' : '' } + }) + self.assertTrue(isinstance(answers, list)) + + # override AET from the payload (with an invalid one -> fail) + self.assertRaises(Exception, lambda: DoPost(_REMOTE, '/modalities/self-with-fake-local-aet/find-worklist', { + 'Query' : { 'PatientID' : '' }, + 'LocalAet': 'AET_FROM_PAYLOAD' + })) + + # override AET from the payload (with a valid one -> success) + answers = DoPost(_REMOTE, '/modalities/self-with-fake-local-aet/find-worklist', { + 'Query' : { 'PatientID' : '' }, + 'LocalAet': 'ORTHANC' + }) + self.assertTrue(isinstance(answers, list)) + + # Same underlying helper, different DICOM request type ("Find" instead + # of "FindWorklist"): catches a fix narrowly scoped to "find-worklist" + # alone that would still leave the deprecated "find" family broken. + answers = DoPost(_REMOTE, '/modalities/self-with-fake-local-aet/find-patient', {}) + self.assertTrue(isinstance(answers, list)) + +
--- a/Tests/Toolbox.py Thu Sep 24 16:47:04 2026 +0200 +++ b/Tests/Toolbox.py Thu Sep 24 17:28:18 2026 +0200 @@ -474,6 +474,10 @@ plugins = DoGet(orthanc, '/plugins') return ('postgresql-index' in plugins) +def HasWorklistsPlugin(orthanc): + plugins = DoGet(orthanc, '/plugins') + return ('worklists' in plugins) + def HasMySQLIndexPlugin(orthanc): plugins = DoGet(orthanc, '/plugins') return ('mysql-index' in plugins)
