def test_association_acse_timeout(self): """ Check that the Association timeouts are being set correctly """ scp = AEVerificationSCP() scp.ae.acse_timeout = 0 scp.ae.dimse_timeout = 0 ae = AE(scu_sop_class=[VerificationSOPClass]) ae.acse_timeout = 0 ae.dimse_timeout = 0 assoc = ae.associate('localhost', 11112) self.assertTrue(scp.ae.active_associations[0].acse_timeout == 0) self.assertTrue(scp.ae.active_associations[0].dimse_timeout == 0) self.assertTrue(assoc.acse_timeout == 0) self.assertTrue(assoc.dimse_timeout == 0) assoc.release() scp.ae.acse_timeout = 21 scp.ae.dimse_timeout = 22 ae.acse_timeout = 31 ae.dimse_timeout = 32 assoc = ae.associate('localhost', 11112) self.assertTrue(scp.ae.active_associations[0].acse_timeout == 21) self.assertTrue(scp.ae.active_associations[0].dimse_timeout == 22) self.assertTrue(assoc.acse_timeout == 31) self.assertTrue(assoc.dimse_timeout == 32) assoc.release() self.assertRaises(SystemExit, scp.stop)
def test_dimse_timeout(self): """ Check AE DIMSE timeout change produces good value """ ae = AE(scu_sop_class=['1.2.840.10008.1.1']) ae.dimse_timeout = None self.assertTrue(ae.dimse_timeout == 0) ae.dimse_timeout = -100 self.assertTrue(ae.dimse_timeout == 0) ae.dimse_timeout = 'a' self.assertTrue(ae.dimse_timeout == 0) ae.dimse_timeout = 0 self.assertTrue(ae.dimse_timeout == 0) ae.dimse_timeout = 30 self.assertTrue(ae.dimse_timeout == 30)
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_recv_missing_data(self, caplog): """Test missing data when receiving.""" with caplog.at_level(logging.ERROR, logger="pynetdicom"): commands = [ ("recv", None), # recv a-associate-rq ("send", a_associate_ac), ("send", b"\x07\x00\x00\x00\x00\x02\x00"), # Send short PDU ("exit", None), ] self.scp = scp = start_server(commands) def handle(event): scp.step() scp.step() hh = [(evt.EVT_REQUESTED, handle)] ae = AE() ae.acse_timeout = 5 ae.dimse_timeout = 5 # ae.network_timeout = 0.5 ae.add_requested_context("1.2.840.10008.1.1") assoc = ae.associate("localhost", 11112, evt_handlers=hh) assert assoc.is_established scp.step() # send short pdu scp.step() scp.shutdown() assert assoc.is_aborted assert ( "The received PDU is shorter than expected (7 of 8 bytes received)" ) in caplog.text
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 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_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 assert self.scp.context.transfer_syntax == '1.2.840.10008.1.2.1' 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_unknown_pdu_aborts(self): commands = [ ("recv", None), # recv a-associate-rq ("send", a_associate_ac), ("send", b"\x53\x00\x00\x00\x00\x02"), ("recv", None), ("exit", None), ] self.scp = scp = start_server(commands) def handle(event): scp.step() scp.step() hh = [(evt.EVT_REQUESTED, handle)] ae = AE() ae.acse_timeout = 5 ae.dimse_timeout = 5 ae.network_timeout = 5 ae.add_requested_context("1.2.840.10008.1.1") assoc = ae.associate("localhost", 11112, evt_handlers=hh) assert assoc.is_established scp.step() # send bad PDU time.sleep(0.1) scp.step() # receive abort scp.step() scp.shutdown() assert assoc.is_aborted
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_recv_short_aborts(self): """Test receiving short PDU causes abort.""" commands = [ ('recv', None), # recv a-associate-rq ('send', a_associate_ac), ('send', b"\x07\x00\x00\x00\x00\x04\x00\x00"), # Send short PDU ('exit', None) ] self.scp = scp = start_server(commands) def handle(event): scp.step() scp.step() hh = [(evt.EVT_REQUESTED, handle)] ae = AE() ae.acse_timeout = 5 ae.dimse_timeout = 5 ae.network_timeout = 0.2 ae.add_requested_context('1.2.840.10008.1.1') assoc = ae.associate('localhost', 11112, evt_handlers=hh) assert assoc.is_established scp.step() # send short pdu # Need to wait for network timeout to expire timeout = 0 while not assoc.is_aborted and timeout < 1: time.sleep(0.05) timeout += 0.05 assert assoc.is_aborted scp.step() scp.shutdown()
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 'address' in self.scp.info['requestor'] 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 'address' in self.scp.info['acceptor'] assert self.scp.info['acceptor']['ae_title'] == b'PYNETDICOM ' self.scp.stop()
def test_recv_bad_pdu_aborts(self): """Test receiving undecodable PDU causes abort.""" commands = [ ('recv', None), # recv a-associate-rq ('send', a_associate_ac), ('send', b"\x07\x00\x00\x00\x00\x02\x00\x00"), ('recv', None), ('exit', None) ] self.scp = scp = start_server(commands) def handle(event): scp.step() scp.step() hh = [(evt.EVT_REQUESTED, handle)] ae = AE() ae.acse_timeout = 5 ae.dimse_timeout = 5 ae.network_timeout = 5 ae.add_requested_context('1.2.840.10008.1.1') assoc = ae.associate('localhost', 11112, evt_handlers=hh) assert assoc.is_established scp.step() # send bad PDU scp.step() # receive abort assert assoc.is_aborted scp.step() scp.shutdown()
def test_scp_handler_info(self): """Test handler caontext parameter""" self.scp = DummyStorageSCP() self.scp.start() ae = AE() ae.add_requested_context(CTImageStorage) ae.acse_timeout = 5 ae.dimse_timeout = 5 assoc = ae.associate('localhost', 11112) assert assoc.is_established status = assoc.send_c_store(DATASET) assert status.Status == 0x0000 assoc.release() assert assoc.is_released assert 'address' in self.scp.info['requestor'] 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 'address' in self.scp.info['acceptor'] 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'] is None assert self.scp.info['parameters']['originator_message_id'] is None assert self.scp.info['sop_class_extended'] == {} 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 'address' in self.scp.info['requestor'] 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 'address' in self.scp.info['acceptor'] 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_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 'address' in self.scp.info['requestor'] 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 'address' in self.scp.info['acceptor'] 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_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 'address' in self.scp.info['requestor'] 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 'address' in self.scp.info['acceptor'] 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 get_implicit_assoc(host, port): ae = AE(ae_title=b'robot') ae.acse_timeout = 2 ae.dimse_timeout = 2 ae.network_timeout = 2 ae.add_requested_context('1.2.840.10008.1.1', ImplicitVRLittleEndian) assoc = ae.associate(host, int(port)) return assoc
def main(args=None): """Run the application.""" if args is not None: sys.argv = args args = _setup_argparser() if args.version: print(f"echoscu.py v{__version__}") sys.exit() APP_LOGGER = setup_logging(args, "echoscu") APP_LOGGER.debug("echoscu.py v%s", __version__) APP_LOGGER.debug("") # Set Transfer Syntax options transfer_syntax = [ ExplicitVRLittleEndian, ImplicitVRLittleEndian, DeflatedExplicitVRLittleEndian, ExplicitVRBigEndian, ] if args.request_little: transfer_syntax = [ExplicitVRLittleEndian] elif args.request_big: transfer_syntax = [ExplicitVRBigEndian] elif args.request_implicit: transfer_syntax = [ImplicitVRLittleEndian] # Create local AE ae = AE(ae_title=args.calling_aet) ae.add_requested_context(Verification, transfer_syntax) # Set timeouts ae.acse_timeout = args.acse_timeout ae.dimse_timeout = args.dimse_timeout ae.network_timeout = args.network_timeout # Request association with remote AE assoc = ae.associate(args.addr, args.port, ae_title=args.called_aet, max_pdu=args.max_pdu) # If we successfully associated then send C-ECHO if assoc.is_established: for ii in range(args.repeat): assoc.send_c_echo() # Abort or release association if args.abort: assoc.abort() else: assoc.release() else: # Failed to associate: timeout, refused, connection closed, aborted sys.exit(1)
def receive_store_simultaneous(test_ds, nr_assoc, ds_per_assoc, use_yappi=False): """Run a Storage SCP and transfer datasets with simultaneous storescu's. Parameters ---------- test_ds : pydicom.dataset.Dataset The test dataset to use nr_assoc : int The number of simultaneous associations that will be made. ds_per_assoc : int The number of C-STORE requests sent per successful association. use_yappi : bool, optional True to use the yappi profiler, False otherwise (default). """ if use_yappi: init_yappi() def handle(event): return 0x0000 ae = AE() ae.acse_timeout = 5 ae.dimse_timeout = 5 ae.network_timeout = 5 ae.maximum_associations = 15 ae.add_supported_context(test_ds.SOPClassUID, ImplicitVRLittleEndian) server = ae.start_server( ("localhost", 11112), block=False, evt_handlers=[(evt.EVT_C_STORE, handle)] ) time.sleep(0.5) start_time = time.time() is_successful = True processes = [] for ii in range(nr_assoc): processes.append(start_storescu(test_ds, ds_per_assoc)) while None in [pp.poll() for pp in processes]: pass returncodes = list(set([pp.returncode for pp in processes])) if len(returncodes) != 1 or returncodes[0] != 0: is_successful = False if is_successful: print( f"C-STORE SCP transferred {nr_assoc * ds_per_assoc} total " f"{os.path.basename(test_ds.filename)} datasets over " f"{nr_assoc} association{'' if nr_assoc == 1 else 's'} " f"in {time.time() - start_time:.2f} s" ) else: print("C-STORE SCP benchmark failed") server.shutdown()
def receive_store_simultaneous(nr_assoc, ds_per_assoc, use_yappi=False): """Run a Storage SCP and transfer datasets with simultaneous storescu's. Parameters ---------- nr_assoc : int The number of simultaneous associations that will be made. ds_per_assoc : int The number of C-STORE requests sent per successful association. use_yappi : bool, optional True to use the yappi profiler, False otherwise (default). """ if use_yappi: init_yappi() def handle(event): return 0x0000 ae = AE() ae.acse_timeout = 5 ae.dimse_timeout = 5 ae.network_timeout = 5 ae.maximum_associations = 15 ae.add_supported_context(DATASET.SOPClassUID, ImplicitVRLittleEndian) server = ae.start_server( ('', 11112), block=False, evt_handlers=[(evt.EVT_C_STORE, handle)] ) time.sleep(0.5) start_time = time.time() run_times = [] is_successful = True processes = [] for ii in range(nr_assoc): processes.append(start_storescu(ds_per_assoc)) while None in [pp.poll() for pp in processes]: pass returncodes = list(set([pp.returncode for pp in processes])) if len(returncodes) != 1 or returncodes[0] != 0: is_successful = False if is_successful: print( "C-STORE SCP transferred {} total datasets over {} " "association(s) in {:.2f} s" .format(nr_assoc * ds_per_assoc, nr_assoc, time.time() - start_time) ) else: print("C-STORE SCP benchmark failed") server.shutdown()
def main(args=None): """Run the application.""" if args is not None: sys.argv = args args = _setup_argparser() if args.version: print('storescp.py v{}'.format(__version__)) sys.exit() APP_LOGGER = setup_logging(args, 'storescp') APP_LOGGER.debug('storescp.py v{0!s}'.format(__version__)) APP_LOGGER.debug('') # Set Transfer Syntax options transfer_syntax = ALL_TRANSFER_SYNTAXES[:] if args.prefer_uncompr: transfer_syntax.remove(ImplicitVRLittleEndian) transfer_syntax.append(ImplicitVRLittleEndian) elif args.prefer_little: transfer_syntax.remove(ExplicitVRLittleEndian) transfer_syntax.insert(0, ExplicitVRLittleEndian) elif args.prefer_big: transfer_syntax.remove(ExplicitVRBigEndian) transfer_syntax.insert(0, ExplicitVRBigEndian) elif args.implicit: transfer_syntax = [ImplicitVRLittleEndian] handlers = [(evt.EVT_C_STORE, handle_store, [args, APP_LOGGER])] # Create application entity ae = AE(ae_title=args.ae_title) # Add presentation contexts with specified transfer syntaxes for context in AllStoragePresentationContexts: ae.add_supported_context(context.abstract_syntax, transfer_syntax) if not args.no_echo: for context in VerificationPresentationContexts: ae.add_supported_context(context.abstract_syntax, transfer_syntax) ae.maximum_pdu_size = args.max_pdu # Set timeouts ae.network_timeout = args.network_timeout ae.acse_timeout = args.acse_timeout ae.dimse_timeout = args.dimse_timeout ae.start_server((args.bind_address, args.port), evt_handlers=handlers)
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_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()
def test_exception_in_reactor(self): """Test that an exception being raised in the DUL reactor kills the DUL and aborts the association. """ commands = [ ("recv", None), # recv a-associate-rq ("send", a_associate_ac), ("send", a_release_rq), # Trigger the exception ("recv", None), # recv a-abort ("exit", None), ] self.scp = scp = start_server(commands) def handle(event): scp.step() scp.step() hh = [(evt.EVT_REQUESTED, handle)] ae = AE() ae.acse_timeout = 5 ae.dimse_timeout = 5 ae.network_timeout = 5 ae.add_requested_context("1.2.840.10008.1.1") assoc = ae.associate("localhost", 11112, evt_handlers=hh) assert assoc.is_established def patch_read_pdu(): raise NotImplementedError assoc.dul._read_pdu_data = patch_read_pdu scp.step() while assoc.dul.is_alive(): time.sleep(0.001) scp.step() assert assoc.is_aborted scp.step() scp.shutdown()
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(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 == 0xC311 pytest.raises(StopIteration, next, result) assoc.release() self.scp.stop()
def test_callback_bad_identifier(self): """Test SCP handles a bad callback identifier""" self.scp = DummyFindSCP() self.scp.statuses = [0xFF00, 0xFE00] self.scp.identifiers = [None, 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 == 0xC312 pytest.raises(StopIteration, next, result) assoc.release() self.scp.stop()
def main(args=None): """Run the application.""" if args is not None: sys.argv = args args = _setup_argparser() if args.version: print(f"echoscp.py v{__version__}") sys.exit() APP_LOGGER = setup_logging(args, "echoscp") APP_LOGGER.debug(f"echoscp.py v{__version__}") APP_LOGGER.debug("") # Set Transfer Syntax options transfer_syntax = ALL_TRANSFER_SYNTAXES[:] if args.prefer_uncompr: transfer_syntax.remove(str(ImplicitVRLittleEndian)) transfer_syntax.append(ImplicitVRLittleEndian) elif args.prefer_little: transfer_syntax.remove(str(ExplicitVRLittleEndian)) transfer_syntax.insert(0, ExplicitVRLittleEndian) elif args.prefer_big: transfer_syntax.remove(str(ExplicitVRBigEndian)) transfer_syntax.insert(0, ExplicitVRBigEndian) elif args.implicit: transfer_syntax = [ImplicitVRLittleEndian] handlers = [(evt.EVT_C_ECHO, handle_echo)] # Create application entity ae = AE(ae_title=args.ae_title) ae.add_supported_context(Verification, transfer_syntax) ae.maximum_pdu_size = args.max_pdu ae.network_timeout = args.network_timeout ae.acse_timeout = args.acse_timeout ae.dimse_timeout = args.dimse_timeout ae.start_server((args.bind_address, args.port), evt_handlers=handlers)
def test_callback_bad_attr(self): """Test SCP handles a bad callback attribute list""" self.scp = DummyGetSCP() self.scp.statuses = 0x0000 self.scp.dataset = None 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 == 0x0110 assert ds is None assoc.release() self.scp.stop()
def test_scp_callback_context(self): """Test on_c_echo context parameter.""" self.scp = DummyVerificationSCP() self.scp.start() ae = AE() ae.add_requested_context(VerificationSOPClass, '1.2.840.10008.1.2.1') 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.context.context_id == 1 assert self.scp.context.abstract_syntax == '1.2.840.10008.1.1' assert self.scp.context.transfer_syntax == '1.2.840.10008.1.2.1' self.scp.stop()
def test_callback_status_int(self): """Test on_c_find yielding an int status""" self.scp = DummyFindSCP() self.scp.statuses = [0xFF00] self.scp.identifiers = [self.query] 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 status, identifier = next(result) assert status.Status == 0x0000 assoc.release() self.scp.stop()
def test_no_response(self): """Test on_c_find yielding success status""" self.scp = DummyFindSCP() self.scp.statuses = [] self.scp.identifiers = [] 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 == 0x0000 assert identifier is None pytest.raises(StopIteration, next, result) assoc.release() self.scp.stop()
def test_scp_callback_context(self): """Test on_c_store caontext parameter""" self.scp = DummyStorageSCP() self.scp.start() ae = AE() ae.add_requested_context(HangingProtocolStorage, '1.2.840.10008.1.2.1') ae.acse_timeout = 5 ae.dimse_timeout = 5 assoc = ae.associate('localhost', 11112) assert assoc.is_established status = assoc.send_c_store(DATASET) assert status.Status == 0x0000 assoc.release() assert assoc.is_released assert self.scp.context.context_id == 1 assert self.scp.context.abstract_syntax == HangingProtocolStorage assert self.scp.context.transfer_syntax == '1.2.840.10008.1.2.1' self.scp.stop()
dcm_files = [os.path.join(basedir, x) for x in dcm_files] for dcm in dcm_files: data = read_file(dcm, force=True) d = Dataset() d.QueryRetrieveLevel = dataset.QueryRetrieveLevel d.RetrieveAETitle = args.aetitle d.PatientName = data.PatientName yield d # Create application entity ae = AE( ae_title=args.aetitle, port=args.port, scu_sop_class=[], scp_sop_class=QueryRetrieveSOPClassList, transfer_syntax=transfer_syntax, ) ae.maximum_pdu_size = args.max_pdu # Set timeouts ae.network_timeout = args.timeout ae.acse_timeout = args.acse_timeout ae.dimse_timeout = args.dimse_timeout ae.on_c_find = on_c_find ae.start()