def test_scp_callback_info_move_origin(self): """Test on_c_store caontext parameter""" self.scp = DummyStorageSCP() self.scp.start() ae = AE() ae.add_requested_context(HangingProtocolStorage) ae.acse_timeout = 5 ae.dimse_timeout = 5 assoc = ae.associate('localhost', 11112) assert assoc.is_established status = assoc.send_c_store(DATASET, originator_aet=b'ORIGIN', originator_id=888) assert status.Status == 0x0000 assoc.release() assert assoc.is_released assert self.scp.info['requestor']['address'] == '127.0.0.1' assert self.scp.info['requestor']['ae_title'] == b'PYNETDICOM ' assert self.scp.info['requestor']['called_aet'] == b'ANY-SCP ' assert isinstance(self.scp.info['requestor']['port'], int) assert self.scp.info['acceptor']['port'] == 11112 assert self.scp.info['acceptor']['address'] == '127.0.0.1' assert self.scp.info['acceptor']['ae_title'] == b'PYNETDICOM ' assert self.scp.info['parameters']['message_id'] == 1 assert self.scp.info['parameters']['priority'] == 2 assert self.scp.info['parameters']['originator_aet'] == b'ORIGIN ' assert self.scp.info['parameters']['originator_message_id'] == 888 self.scp.stop()
def test_scp_callback_context(self): """Test on_c_store caontext parameter""" self.scp = DummyFindSCP() self.scp.statuses = [Dataset(), 0x0000] self.scp.statuses[0].Status = 0xFF00 self.identifiers = [self.query, None] self.scp.start() ae = AE() ae.add_requested_context( ProductCharacteristicsQueryInformationModelFind, '1.2.840.10008.1.2.1') ae.acse_timeout = 5 ae.dimse_timeout = 5 assoc = ae.associate('localhost', 11112) assert assoc.is_established result = assoc.send_c_find(self.query, query_model='PC') status, identifier = next(result) assert status.Status == 0xFF00 status, identifier = next(result) assert status.Status == 0x0000 assoc.release() assert assoc.is_released assert self.scp.context.context_id == 1 assert self.scp.context.abstract_syntax == ProductCharacteristicsQueryInformationModelFind.uid assert self.scp.context.transfer_syntax == '1.2.840.10008.1.2.1' self.scp.stop()
def test_scp_callback_info(self): """Test on_n_get caontext parameter""" self.scp = DummyGetSCP() self.scp.start() ae = AE() ae.add_requested_context(DisplaySystemSOPClass) ae.acse_timeout = 5 ae.dimse_timeout = 5 assoc = ae.associate('localhost', 11112) assert assoc.is_established status, ds = assoc.send_n_get([(0x7fe0,0x0010)], DisplaySystemSOPClass, '1.2.840.10008.5.1.1.40.1') assert status.Status == 0x0000 assert 'PatientName' in ds assoc.release() assert assoc.is_released assert self.scp.info['requestor']['address'] == '127.0.0.1' assert self.scp.info['requestor']['ae_title'] == b'PYNETDICOM ' assert self.scp.info['requestor']['called_aet'] == b'ANY-SCP ' assert isinstance(self.scp.info['requestor']['port'], int) assert self.scp.info['acceptor']['port'] == 11112 assert self.scp.info['acceptor']['address'] == '127.0.0.1' assert self.scp.info['acceptor']['ae_title'] == b'PYNETDICOM ' assert self.scp.info['parameters']['message_id'] == 1 assert self.scp.info['parameters']['requested_sop_class_uid'] == DisplaySystemSOPClass assert self.scp.info['parameters']['requested_sop_instance_uid'] == '1.2.840.10008.5.1.1.40.1' self.scp.stop()
def test_pending_cancel(self): """Test on_c_find yielding pending then cancel status""" # Note: success should be second, cancel should get ignored self.scp = DummyFindSCP() self.scp.statuses = [0xFF00, 0xFE00] self.scp.identifiers = [self.query, None] self.scp.start() ae = AE() ae.add_requested_context(GeneralRelevantPatientInformationQuery) ae.acse_timeout = 5 ae.dimse_timeout = 5 assoc = ae.associate('localhost', 11112) assert assoc.is_established result = assoc.send_c_find(self.query, query_model='G') status, identifier = next(result) assert status.Status == 0xFF00 assert identifier == self.query status, identifier = next(result) assert status.Status == 0x0000 assert identifier is None pytest.raises(StopIteration, next, result) assoc.release() self.scp.stop()
def test_multi_pending_failure(self): """Test on_c_find yielding multiple pending then failure status""" self.scp = DummyFindSCP() self.scp.statuses = [0xFF00, 0xFF01, 0xFF00, 0xA700, 0x0000] self.scp.identifiers = [self.query, self.query, self.query, None] self.scp.start() ae = AE() ae.add_requested_context( ProductCharacteristicsQueryInformationModelFind) ae.acse_timeout = 5 ae.dimse_timeout = 5 assoc = ae.associate('localhost', 11112) assert assoc.is_established result = assoc.send_c_find(self.query, query_model='PC') status, identifier = next(result) assert status.Status == 0xFF00 assert identifier == self.query status, identifier = next(result) assert status.Status == 0xFF01 assert identifier == self.query status, identifier = next(result) assert status.Status == 0xFF00 assert identifier == self.query status, identifier = next(result) assert status.Status == 0xA700 assert identifier is None pytest.raises(StopIteration, next, result) assoc.release() self.scp.stop()
def test_scp_callback_info(self): """Test on_c_store caontext parameter""" self.scp = DummyFindSCP() self.scp.statuses = [Dataset(), 0x0000] self.scp.statuses[0].Status = 0xFF00 self.identifiers = [self.query, None] self.scp.start() ae = AE() ae.add_requested_context( ProductCharacteristicsQueryInformationModelFind) ae.acse_timeout = 5 ae.dimse_timeout = 5 assoc = ae.associate('localhost', 11112) assert assoc.is_established result = assoc.send_c_find(self.query, query_model='PC') status, identifier = next(result) assert status.Status == 0xFF00 status, identifier = next(result) assert status.Status == 0x0000 assoc.release() assert assoc.is_released assert self.scp.info['requestor']['address'] == '127.0.0.1' assert self.scp.info['requestor']['ae_title'] == b'PYNETDICOM ' assert self.scp.info['requestor']['called_aet'] == b'ANY-SCP ' assert isinstance(self.scp.info['requestor']['port'], int) assert self.scp.info['acceptor']['port'] == 11112 assert self.scp.info['acceptor']['address'] == '127.0.0.1' assert self.scp.info['acceptor']['ae_title'] == b'PYNETDICOM ' assert self.scp.info['parameters']['message_id'] == 1 assert self.scp.info['parameters']['priority'] == 2 self.scp.stop()
def test_callback_status_dataset_multi(self): """Test on_c_find yielding a Dataset status with other elements""" self.scp = DummyFindSCP() self.scp.statuses = [Dataset()] self.scp.statuses[0].Status = 0xFF00 self.scp.statuses[0].ErrorComment = 'Test' self.scp.statuses[0].OffendingElement = 0x00010001 self.scp.identifiers = [self.query] self.scp.start() ae = AE() ae.add_requested_context( ProductCharacteristicsQueryInformationModelFind) ae.acse_timeout = 5 ae.dimse_timeout = 5 assoc = ae.associate('localhost', 11112) assert assoc.is_established result = assoc.send_c_find(self.query, query_model='PC') status, identifier = next(result) assert status.Status == 0xFF00 assert status.ErrorComment == 'Test' assert status.OffendingElement == 0x00010001 status, identifier = next(result) assert status.Status == 0x0000 assoc.release() self.scp.stop()
def test_scp_callback_info(self): """Test on_c_echo info parameter.""" self.scp = DummyVerificationSCP() self.scp.start() ae = AE() ae.add_requested_context(VerificationSOPClass) ae.acse_timeout = 5 ae.dimse_timeout = 5 assoc = ae.associate('localhost', 11112) assert assoc.is_established rsp = assoc.send_c_echo() assert rsp.Status == 0x0000 assoc.release() assert assoc.is_released assert self.scp.info['requestor']['address'] == '127.0.0.1' assert self.scp.info['requestor']['ae_title'] == b'PYNETDICOM ' assert self.scp.info['requestor']['called_aet'] == b'ANY-SCP ' assert isinstance(self.scp.info['requestor']['port'], int) assert self.scp.info['acceptor']['port'] == 11112 assert self.scp.info['acceptor']['address'] == '127.0.0.1' assert self.scp.info['acceptor']['ae_title'] == b'PYNETDICOM ' self.scp.stop()
def test_bad_req_identifier(self): """Test SCP handles a bad request identifier""" self.scp = DummyFindSCP() self.scp.statuses = [0xFF00] self.scp.identifiers = [self.query] self.scp.start() ae = AE() ae.add_requested_context( ProductCharacteristicsQueryInformationModelFind, ExplicitVRLittleEndian) ae.acse_timeout = 5 ae.dimse_timeout = 5 assoc = ae.associate('localhost', 11112) assert assoc.is_established req = C_FIND() req.MessageID = 1 req.AffectedSOPClassUID = ProductCharacteristicsQueryInformationModelFind.uid req.Priority = 2 req.Identifier = BytesIO( b'\x08\x00\x01\x00\x04\x00\x00\x00\x00\x08\x00\x49') assoc.dimse.send_msg(req, 1) rsp, _ = assoc.dimse.receive_msg(True) assert rsp.Status == 0xC310 assoc.release() self.scp.stop()
def test_scp_failed_ds_decode(self): """Test failure to decode the dataset""" # Hard to test directly as decode errors won't show up until the # dataset is actually used self.scp = DummyStorageSCP() self.scp.status = 0x0000 self.scp.start() ae = AE() ae.add_requested_context(HangingProtocolStorage, ExplicitVRLittleEndian) assoc = ae.associate('localhost', 11112) assert assoc.is_established req = C_STORE() req.MessageID = 1 req.AffectedSOPClassUID = DATASET.SOPClassUID req.AffectedSOPInstanceUID = DATASET.SOPInstanceUID req.Priorty = 0x0002 req.DataSet = BytesIO(b'\x08\x00\x01\x00\x04\x00\x00\x00\x00\x08\x00\x49') # Send C-STORE request to DIMSE and get response assoc.dimse.send_msg(req, 1) rsp, _ = assoc.dimse.receive_msg(True) assert rsp.Status == 0xC100 assert rsp.ErrorComment == 'Unable to decode the dataset' assoc.release() self.scp.stop()
def _setup_c_echo_assoc(self): transfer_syntax = [ImplicitVRLittleEndian, ExplicitVRLittleEndian, ExplicitVRBigEndian] ae = AE(ae_title=self.client_ae_title, port=self.client_port) ae.add_requested_context(VerificationSOPClass, transfer_syntax) assoc = ae.associate(self.pacs_ip, self.pacs_port, ae_title=self.pacs_ae_title) return assoc
def __setup_c_store_assoc(self): ae = AE(ae_title=self.client_ae_title, port=self.client_port) for context in StoragePresentationContexts: ae.add_requested_context(context.abstract_syntax, self.transfer_syntax) assoc = ae.associate(self.pacs_ip, self.pacs_port, ae_title=self.pacs_ae_title) return assoc
class DummyGetSCP(DummyBaseSCP): """A threaded dummy get SCP used for testing""" def __init__(self, port=11112): self.ae = AE(port=port) self.ae.add_supported_context( PatientRootQueryRetrieveInformationModelGet) self.ae.add_supported_context( StudyRootQueryRetrieveInformationModelGet) self.ae.add_supported_context( PatientStudyOnlyQueryRetrieveInformationModelGet) self.ae.add_supported_context( CompositeInstanceRetrieveWithoutBulkDataGet) self.ae.add_supported_context(CompositeInstanceRootRetrieveGet) self.ae.add_supported_context(HangingProtocolInformationModelGet) self.ae.add_supported_context( DefinedProcedureProtocolInformationModelGet) self.ae.add_supported_context(ColorPaletteInformationModelGet) self.ae.add_supported_context( GenericImplantTemplateInformationModelGet) self.ae.add_supported_context( ImplantAssemblyTemplateInformationModelGet) self.ae.add_supported_context(ImplantTemplateGroupInformationModelGet) self.ae.add_supported_context(CTImageStorage) self.ae.add_requested_context(CTImageStorage) DummyBaseSCP.__init__(self) self.statuses = [0x0000] ds = Dataset() ds.PatientName = 'Test' ds.SOPClassUID = CTImageStorage.UID ds.SOPInstanceUID = '1.2.3.4' self.datasets = [ds] self.no_suboperations = 1 self.cancel = False def on_c_get(self, ds, context, info): """Callback for ae.on_c_get""" self.context = context self.info = info time.sleep(self.delay) ds = Dataset() ds.PatientName = '*' ds.QueryRetrieveLevel = "PATIENT" yield self.no_suboperations for (status, ds) in zip(self.statuses, self.datasets): if self.cancel: yield 0xFE00, None return yield status, ds def on_c_cancel_get(self): """Callback for ae.on_c_cancel_get""" self.cancel = True
def _setup_c_get_assoc(self): ae = AE(ae_title=self.client_ae_title, port=self.client_port) for context in QueryRetrievePresentationContexts: ae.add_requested_context(context.abstract_syntax) for context in StoragePresentationContexts: ae.add_requested_context(context.abstract_syntax) ae.on_c_store = self.on_c_store assoc = ae.associate(self.pacs_ip, self.pacs_port, ae_title=self.pacs_ae_title) return assoc
def test_scp_callback_return_dataset_no_status(self): """Test on_c_echo returning a Dataset with no Status elem""" self.scp = DummyVerificationSCP() self.scp.status = Dataset() self.scp.start() ae = AE() ae.add_requested_context(VerificationSOPClass) assoc = ae.associate('localhost', 11112) assert assoc.is_established rsp = assoc.send_c_echo() assert rsp.Status == 0x0000 assoc.release() self.scp.stop()
def test_scp_callback_return_invalid(self): """Test on_c_store returning a valid status""" self.scp = DummyStorageSCP() self.scp.status = 0xFFF0 self.scp.start() ae = AE() ae.add_requested_context(CTImageStorage) assoc = ae.associate('localhost', 11112) assert assoc.is_established rsp = assoc.send_c_store(DATASET) assert rsp.Status == 0xFFF0 assoc.release() self.scp.stop()
def test_scp_callback_no_status(self): """Test on_c_store not returning a status""" self.scp = DummyStorageSCP() self.scp.status = None self.scp.start() ae = AE() ae.add_requested_context(HangingProtocolStorage) assoc = ae.associate('localhost', 11112) assert assoc.is_established rsp = assoc.send_c_store(DATASET) assert rsp.Status == 0xC002 assoc.release() self.scp.stop()
def test_scp_callback_return_int(self): """Test on_c_echo returning an int status""" self.scp = DummyVerificationSCP() self.scp.status = 0x0002 self.scp.start() ae = AE() ae.add_requested_context(VerificationSOPClass) assoc = ae.associate('localhost', 11112) assert assoc.is_established rsp = assoc.send_c_echo() assert rsp.Status == 0x0002 assert not 'ErrorComment' in rsp assoc.release() self.scp.stop()
def test_scp_callback_return_int(self): """Test on_c_echo returning an int status""" self.scp = DummyStorageSCP() self.scp.status = 0x0000 self.scp.start() ae = AE() ae.add_requested_context(HangingProtocolStorage) assoc = ae.associate('localhost', 11112) assert assoc.is_established rsp = assoc.send_c_store(DATASET) assert rsp.Status == 0x0000 assert not 'ErrorComment' in rsp assoc.release() self.scp.stop()
def test_scp_callback_exception(self): """Test on_c_store raising an exception""" self.scp = DummyStorageSCP() def on_c_store(ds, context, assoc_info): raise ValueError self.scp.ae.on_c_store = on_c_store self.scp.start() ae = AE() ae.add_requested_context(HangingProtocolStorage) assoc = ae.associate('localhost', 11112) assert assoc.is_established rsp = assoc.send_c_store(DATASET) assert rsp.Status == 0xC211 assoc.release() self.scp.stop()
def test_scp_callback_return_dataset_unknown(self): """Test a status ds with an unknown element.""" self.scp = DummyVerificationSCP() self.scp.status = Dataset() self.scp.status.Status = 0x0001 self.scp.status.PatientName = 'test name' self.scp.start() ae = AE() ae.add_requested_context(VerificationSOPClass) assoc = ae.associate('localhost', 11112) assert assoc.is_established rsp = assoc.send_c_echo() assert rsp.Status == 0x0001 assoc.release() self.scp.stop()
def test_scp_callback_return_dataset_multi(self): """Test on_c_echo returning a Dataset status with other elements""" self.scp = DummyVerificationSCP() self.scp.status = Dataset() self.scp.status.Status = 0x0001 self.scp.status.ErrorComment = 'Test' self.scp.start() ae = AE() ae.add_requested_context(VerificationSOPClass) assoc = ae.associate('localhost', 11112) assert assoc.is_established rsp = assoc.send_c_echo() assert rsp.Status == 0x0001 assert rsp.ErrorComment == 'Test' assoc.release() self.scp.stop()
def test_scp_callback_return_int(self): """Test on_n_get returning an int status""" self.scp = DummyGetSCP() self.scp.status = 0x0000 self.scp.start() ae = AE() ae.add_requested_context(DisplaySystemSOPClass) assoc = ae.associate('localhost', 11112) assert assoc.is_established status, ds = assoc.send_n_get([(0x7fe0,0x0010)], DisplaySystemSOPClass, '1.2.840.10008.5.1.1.40.1') assert status.Status == 0x0000 assert not 'ErrorComment' in status assoc.release() self.scp.stop()
def test_scp_callback_no_status(self): """Test on_n_get not returning a status""" self.scp = DummyGetSCP() self.scp.status = None self.scp.start() ae = AE() ae.add_requested_context(DisplaySystemSOPClass) assoc = ae.associate('localhost', 11112) assert assoc.is_established status, ds = assoc.send_n_get([(0x7fe0,0x0010)], DisplaySystemSOPClass, '1.2.840.10008.5.1.1.40.1') assert status.Status == 0xC002 assert ds is None assoc.release() self.scp.stop()
def test_scp_callback_exception(self): """Test on_c_echo raising an exception""" self.scp = DummyVerificationSCP() def on_c_echo(context, info): raise ValueError self.scp.ae.on_c_echo = on_c_echo self.scp.start() ae = AE() ae.add_requested_context(VerificationSOPClass) assoc = ae.associate('localhost', 11112) assert assoc.is_established rsp = assoc.send_c_echo() assert rsp.Status == 0x0000 assoc.release() self.scp.stop()
def test_callback_status_none(self): """Test SCP handles on_c_find not yielding a status""" self.scp = DummyFindSCP() self.scp.statuses = [None] self.scp.start() ae = AE() ae.add_requested_context(GeneralRelevantPatientInformationQuery) ae.acse_timeout = 5 ae.dimse_timeout = 5 assoc = ae.associate('localhost', 11112) assert assoc.is_established result = assoc.send_c_find(self.query, query_model='G') status, identifier = next(result) assert status.Status == 0xC002 pytest.raises(StopIteration, next, result) assoc.release() self.scp.stop()
def test_callback_exception(self): """Test SCP handles on_c_find yielding an exception""" self.scp = DummyFindSCP() def on_c_find(ds, context, info): raise ValueError self.scp.ae.on_c_find = on_c_find self.scp.start() ae = AE() ae.add_requested_context(GeneralRelevantPatientInformationQuery) ae.acse_timeout = 5 ae.dimse_timeout = 5 assoc = ae.associate('localhost', 11112) assert assoc.is_established result = assoc.send_c_find(self.query, query_model='G') status, identifier = next(result) assert status.Status == 0xC311 pytest.raises(StopIteration, next, result) assoc.release() self.scp.stop()
def test_scp_callback_return_dataset(self): """Test on_n_get returning a Dataset status""" self.scp = DummyGetSCP() self.scp.status = Dataset() # Unknown status self.scp.status.Status = 0x0001 self.scp.start() ae = AE() ae.add_requested_context(DisplaySystemSOPClass) assoc = ae.associate('localhost', 11112) assert assoc.is_established status, ds = assoc.send_n_get([(0x7fe0,0x0010)], DisplaySystemSOPClass, '1.2.840.10008.5.1.1.40.1') assert status.Status == 0x0001 assert ds.PatientName == 'Test' assoc.release() self.scp.stop()
def test_scp_callback_return_dataset_multi(self): """Test on_c_store returning a Dataset status with other elements""" self.scp = DummyStorageSCP() self.scp.status = Dataset() self.scp.status.Status = 0x0001 self.scp.status.ErrorComment = 'Test' self.scp.status.OffendingElement = 0x00080010 self.scp.start() ae = AE() ae.add_requested_context(HangingProtocolStorage) assoc = ae.associate('localhost', 11112) assert assoc.is_established rsp = assoc.send_c_store(DATASET) assert rsp.Status == 0x0001 assert rsp.ErrorComment == 'Test' assert rsp.OffendingElement == 0x00080010 assoc.release() self.scp.stop()
def test_callback_status_invalid(self): """Test SCP handles on_c_find yielding a invalid status""" self.scp = DummyFindSCP() self.scp.statuses = ['Failure'] self.scp.start() ae = AE() ae.add_requested_context( ProductCharacteristicsQueryInformationModelFind) ae.acse_timeout = 5 ae.dimse_timeout = 5 assoc = ae.associate('localhost', 11112) assert assoc.is_established result = assoc.send_c_find(self.query, query_model='PC') status, identifier = next(result) assert status.Status == 0xC002 pytest.raises(StopIteration, next, result) assoc.release() self.scp.stop()