class AEStorageSCP(threading.Thread): def __init__(self): self.ae = AE(port=11112, scp_sop_class=StorageSOPClassList) threading.Thread.__init__(self) self.daemon = True self.start() def run(self): self.ae.start() def stop(self): self.ae.stop()
class AEVerificationSCP(threading.Thread): def __init__(self): self.ae = AE(port=11112, scp_sop_class=[VerificationSOPClass]) threading.Thread.__init__(self) self.daemon = True self.start() def run(self): self.ae.start() def stop(self): self.ae.stop()
def test_associate_establish_release(self): """ Check SCU Association with SCP """ scp = AEVerificationSCP() ae = AE(scu_sop_class=[VerificationSOPClass]) assoc = ae.associate('localhost', 11112) self.assertTrue(assoc.is_established == True) assoc.release() self.assertTrue(assoc.is_established == False) self.assertRaises(SystemExit, scp.stop)
def test_on_c_store_called(self): """ Check that SCP AE.on_c_store(dataset) was called """ scp = AEStorageSCP() ae = AE(scu_sop_class=StorageSOPClassList) assoc = ae.associate('localhost', 11112) #with patch.object(scp.ae, 'on_c_store') as mock: # assoc.send_c_store(dataset) #mock.assert_called_with() assoc.release() self.assertRaises(SystemExit, scp.stop)
def test_on_c_echo_called(self): """ Check that SCP AE.on_c_echo() was called """ scp = AEVerificationSCP() ae = AE(scu_sop_class=[VerificationSOPClass]) assoc = ae.associate('localhost', 11112) with patch.object(scp.ae, 'on_c_echo') as mock: assoc.send_c_echo() mock.assert_called_with() assoc.release() self.assertRaises(SystemExit, scp.stop)
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_ae_release_assoc(self): """ Association releases OK """ # Start Verification SCP scp = AEVerificationSCP() ae = AE(scu_sop_class=[VerificationSOPClass]) # Test N associate/release cycles for ii in range(10): assoc = ae.associate('localhost', 11112) self.assertTrue(assoc.is_established) if assoc.is_established: assoc.release() self.assertTrue(assoc.is_established == False) self.assertTrue(assoc.is_released == True) self.assertTrue(ae.active_associations == []) # Kill Verification SCP (important!) self.assertRaises(SystemExit, scp.stop)
def test_associate_max_pdu(self): """ Check Association has correct max PDUs on either end """ scp = AEVerificationSCP() scp.ae.maximum_pdu_size = 54321 ae = AE(scu_sop_class=[VerificationSOPClass]) assoc = ae.associate('localhost', 11112, max_pdu=12345) self.assertTrue(scp.ae.active_associations[0].local_max_pdu == 54321) self.assertTrue(scp.ae.active_associations[0].peer_max_pdu == 12345) self.assertTrue(assoc.local_max_pdu == 12345) self.assertTrue(assoc.peer_max_pdu == 54321) assoc.release() # Check 0 max pdu value assoc = ae.associate('localhost', 11112, max_pdu=0) self.assertTrue(assoc.local_max_pdu == 0) self.assertTrue(scp.ae.active_associations[0].peer_max_pdu == 0) assoc.release() self.assertRaises(SystemExit, scp.stop)
def test_req_called_aet(self): """ Check AE require called aet change produces good value """ ae = AE(scu_sop_class=['1.2.840.10008.1.1']) ae.require_called_aet = -10 self.assertTrue(ae.require_called_aet == '') ae.require_called_aet = ['a'] self.assertTrue(ae.require_called_aet == '') ae.require_called_aet = '10' self.assertTrue(ae.require_called_aet == '10') ae.require_called_aet = ' TEST ' self.assertTrue(ae.require_called_aet == 'TEST') ae.require_called_aet = ' TEST' self.assertTrue(ae.require_called_aet == 'TEST') ae.require_called_aet = ' TEST' self.assertTrue(ae.require_called_aet == 'TEST') ae.require_called_aet = 'a TEST' self.assertTrue(ae.require_called_aet == 'a TES')
def test_max_pdu_good(self): """ Check AE maximum pdu size change produces good value """ ae = AE(scu_sop_class=['1.2.840.10008.1.1']) ae.maximum_pdu_size = -10 self.assertTrue(ae.maximum_pdu_size == 16382) ae.maximum_pdu_size = ['a'] self.assertTrue(ae.maximum_pdu_size == 16382) ae.maximum_pdu_size = '10' self.assertTrue(ae.maximum_pdu_size == 16382) ae.maximum_pdu_size = 0 self.assertTrue(ae.maximum_pdu_size == 0) ae.maximum_pdu_size = 5000 self.assertTrue(ae.maximum_pdu_size == 5000)
def test_ae_title_good(self): """ Check AE title change produces good value """ ae = AE(scu_sop_class=['1.2.840.10008.1.1']) ae.ae_title = ' TEST ' self.assertTrue(ae.ae_title == 'TEST ') ae.ae_title = ' TEST' self.assertTrue(ae.ae_title == 'TEST ') ae.ae_title = ' TEST' self.assertTrue(ae.ae_title == 'TEST ') ae.ae_title = 'a TEST' self.assertTrue(ae.ae_title == 'a TES') ae.ae_title = 'a TEST' self.assertTrue(ae.ae_title == 'a TEST ')
def test_network_timeout(self): """ Check AE network timeout change produces good value """ ae = AE(scu_sop_class=['1.2.840.10008.1.1']) ae.network_timeout = None self.assertTrue(ae.network_timeout == 60) ae.network_timeout = -100 self.assertTrue(ae.network_timeout == 60) ae.network_timeout = 'a' self.assertTrue(ae.network_timeout == 60) ae.network_timeout = 0 self.assertTrue(ae.network_timeout == 0) ae.network_timeout = 30 self.assertTrue(ae.network_timeout == 30)
def test_max_assoc_good(self): """ Check AE maximum association change produces good value """ ae = AE(scu_sop_class=['1.2.840.10008.1.1']) ae.maximum_associations = -10 self.assertTrue(ae.maximum_associations == 1) ae.maximum_associations = ['a'] self.assertTrue(ae.maximum_associations == 1) ae.maximum_associations = '10' self.assertTrue(ae.maximum_associations == 1) ae.maximum_associations = 0 self.assertTrue(ae.maximum_associations == 1) ae.maximum_associations = 5 self.assertTrue(ae.maximum_associations == 5)
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 test_scp_handler_context(self): """Test handler event's context attribute""" attrs = {} def handle(event): attrs['context'] = event.context attrs['assoc'] = event.assoc attrs['request'] = event.request attrs['identifier'] = event.identifier yield 0xFF00, self.query handlers = [(evt.EVT_C_FIND, handle)] self.ae = ae = AE() ae.add_supported_context(ProductCharacteristicsQueryInformationModelFind) ae.add_requested_context(ProductCharacteristicsQueryInformationModelFind) scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers) 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 with pytest.raises(StopIteration): next(result) assoc.release() assert assoc.is_released cx = attrs['context'] assert cx.context_id == 1 assert cx.abstract_syntax == ProductCharacteristicsQueryInformationModelFind assert cx.transfer_syntax == '1.2.840.10008.1.2' scp.shutdown()
def test_flag_td(self, capfd): """Test --dimse-timeout flag.""" events = [] def handle_move(event): events.append(event) time.sleep(0.1) yield 'localhost', 11113 yield 0 yield 0x0000, None def handle_abort(event): events.append(event) handlers = [ (evt.EVT_C_MOVE, handle_move), (evt.EVT_ABORTED, handle_abort), ] self.ae = ae = AE() ae.acse_timeout = 5 ae.dimse_timeout = 5 ae.network_timeout = 5 ae.requested_contexts = StoragePresentationContexts ae.supported_contexts = QueryRetrievePresentationContexts scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers) p = self.func(['-td', '0.05', '-d', '-k', 'PatientName=']) p.wait() assert p.returncode == 0 time.sleep(0.1) scp.shutdown() out, err = capfd.readouterr() assert "DIMSE timeout reached while waiting for message" in err assert events[0].event == evt.EVT_C_MOVE assert events[1].event == evt.EVT_ABORTED
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_bad_req_identifier(self): """Test SCP handles a bad request identifier""" def handle(event): try: ds = event.identifier for elem in ds.iterall(): pass except NotImplementedError: yield 0xC310, None return yield 0x0000, None handlers = [(evt.EVT_C_FIND, handle)] self.ae = ae = AE() ae.add_supported_context(ProductCharacteristicsQueryInformationModelFind) ae.add_requested_context( ProductCharacteristicsQueryInformationModelFind, ExplicitVRLittleEndian ) scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers) 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) cx_id, rsp = assoc.dimse.get_msg(True) assert rsp.Status == 0xC310 assoc.release() assert assoc.is_released scp.shutdown()
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(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() self.scp.stop()
def test_flag_td(self, capfd): """Test --dimse-timeout flag.""" events = [] def handle_echo(event): events.append(event) time.sleep(0.1) return 0x0000 def handle_abort(event): events.append(event) handlers = [ (evt.EVT_C_ECHO, handle_echo), (evt.EVT_ABORTED, handle_abort), ] self.ae = ae = AE() ae.acse_timeout = 5 ae.dimse_timeout = 5 ae.network_timeout = 5 ae.add_supported_context(Verification) scp = ae.start_server(("localhost", 11112), block=False, evt_handlers=handlers) p = self.func(["-td", "0.05", "-d"]) p.wait() assert p.returncode == 0 time.sleep(0.1) scp.shutdown() out, err = capfd.readouterr() assert "DIMSE timeout reached while waiting for message" in err assert events[0].event == evt.EVT_C_ECHO assert events[1].event == evt.EVT_ABORTED
def test_scp_callback_context(self): """Test on_c_store caontext parameter""" self.scp = DummyStorageSCP() self.scp.start() ae = AE() ae.add_requested_context(CTImageStorage, '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 == CTImageStorage assert self.scp.context.transfer_syntax == '1.2.840.10008.1.2.1' 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 move_study(localAE, localPort, destIP, destAE, destPort, study): # Prepare local information ae = AE(ae_title=localAE) ae.acse_timeout = 30 # Add a requested presentation context ae.add_requested_context(StudyRootQueryRetrieveInformationModelMove) # Associate with Peer assoc = ae.associate(destIP, destPort, ae_title=destAE) if assoc.is_established: # Use the C-Move service to send identifier responses = assoc.send_c_move( study, localAE, StudyRootQueryRetrieveInformationModelMove) imageIndex = 1 for (status, identifier) in responses: if status: # print('C-MOVE query status: 0x{0:04x}'.format(status.Status)) if status.Status in (0xFF00, 0xFF01): print('Imaging is being downloaded... %s' % imageIndex) imageIndex += 1 elif status.Status in (0x0000, ): print('Download is finished') # Save study images into correct folder folderName = study.PatientID + study.StudyInstanceUID os.system("mkdir .\\images\\" + folderName) os.system("move .\\rcv\\* .\\images\\" + folderName) time.sleep(1) print('Store study into %s' % folderName) # Update task status with open('tasks.txt', 'w') as f: f.writelines(study.PatientID) else: print( 'Connection timed out, was aborted or received invalid response' ) # Release the association assoc.release() else: print('Association rejected, aborted or never connected')
def test_scp_handler_return_int(self): """Test handler returning an int status""" def handle(event): return 0x0000 handlers = [(evt.EVT_C_STORE, handle)] self.ae = ae = AE() ae.add_supported_context(HangingProtocolStorage) ae.add_requested_context(HangingProtocolStorage) scp = ae.start_server(("localhost", 11112), block=False, evt_handlers=handlers) assoc = ae.associate("localhost", 11112) assert assoc.is_established rsp = assoc.send_c_store(DATASET) assert rsp.Status == 0x0000 assert "ErrorComment" not in rsp assoc.release() assert assoc.is_released scp.shutdown()
def test_flag_debug(self, capfd): """Test --debug flag.""" self.ae = ae = AE() ae.acse_timeout = 5 ae.dimse_timeout = 5 ae.network_timeout = 5 ae.add_requested_context(Verification) self.p = p = self.func(["-d"]) time.sleep(0.5) assoc = ae.associate("localhost", 11112) assert assoc.is_established status = assoc.send_c_echo() assert status.Status == 0x0000 assoc.release() p.terminate() p.wait() out, err = capfd.readouterr() assert "pydicom.read_dataset()" in err assert "Accept Parameters" in err
def test_scp_handler_return_dataset_unknown(self): """Test a status ds with an unknown element.""" def handle(event): status = Dataset() status.Status = 0x0001 status.PatientName = 'test name' return status handlers = [(evt.EVT_C_ECHO, handle)] self.ae = ae = AE() ae.add_supported_context(VerificationSOPClass) ae.add_requested_context(VerificationSOPClass) scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers) assoc = ae.associate('localhost', 11112) assert assoc.is_established rsp = assoc.send_c_echo() assert rsp.Status == 0x0001 assoc.release() assert assoc.is_released scp.shutdown()
def test_handler_status_none(self): """Test SCP handles handler not yielding a status""" def handle(event): yield None, self.query handlers = [(evt.EVT_C_FIND, handle)] self.ae = ae = AE() ae.add_supported_context(GeneralRelevantPatientInformationQuery) ae.add_requested_context(GeneralRelevantPatientInformationQuery) scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers) ae.acse_timeout = 5 ae.dimse_timeout = 5 assoc = ae.associate('localhost', 11112) assert assoc.is_established result = assoc.send_c_find(self.query, GeneralRelevantPatientInformationQuery) status, identifier = next(result) assert status.Status == 0xC002 pytest.raises(StopIteration, next, result) assoc.release() scp.shutdown()
def test_scp_handler_return_dataset(self): """Test handler returning a Dataset status""" def handle(event): status = Dataset() status.Status = 0x0001 return status handlers = [(evt.EVT_C_ECHO, handle)] self.ae = ae = AE() ae.add_supported_context(Verification) ae.add_requested_context(Verification) scp = ae.start_server(("localhost", 11112), block=False, evt_handlers=handlers) assoc = ae.associate("localhost", 11112) assert assoc.is_established rsp = assoc.send_c_echo() assert rsp.Status == 0x0001 assoc.release() assert assoc.is_released scp.shutdown()
def test_flag_quiet(self, capfd): """Test --quiet flag.""" self.ae = ae = AE() ae.acse_timeout = 5 ae.dimse_timeout = 5 ae.network_timeout = 5 ae.add_requested_context(VerificationSOPClass) ae.add_requested_context(CTImageStorage) self.p = p = self.func(['-q']) time.sleep(0.5) assoc = ae.associate('localhost', 11112) assert assoc.is_established status = assoc.send_c_echo() assert status.Status == 0x0000 assoc.release() p.terminate() p.wait() out, err = capfd.readouterr() assert out == err == ''
def test_scp_handler_return_int(self): """Test handler returning an int status""" def handle(event): return 0x0000, self.ds handlers = [(evt.EVT_N_GET, handle)] self.ae = ae = AE() ae.add_supported_context(DisplaySystemSOPClass) ae.add_requested_context(DisplaySystemSOPClass) scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers) 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 not 'ErrorComment' in status assoc.release() scp.shutdown()
def test_no_handlers(self): """Test with no transport event handlers bound.""" self.ae = ae = AE() ae.add_supported_context(VerificationSOPClass) ae.add_requested_context(VerificationSOPClass) scp = ae.start_server(('', 11112), block=False) assert scp.get_handlers(evt.EVT_DIMSE_RECV) == [] assert scp.get_handlers(evt.EVT_DIMSE_SENT) == [] assoc = ae.associate('localhost', 11112) assert assoc.is_established assert len(scp.active_associations) == 1 assert scp.get_handlers(evt.EVT_DIMSE_RECV) == [] assert scp.get_handlers(evt.EVT_DIMSE_SENT) == [] assert assoc.get_handlers(evt.EVT_DIMSE_RECV) == [] assert assoc.get_handlers(evt.EVT_DIMSE_SENT) == [] child = scp.active_associations[0] assert child.get_handlers(evt.EVT_DIMSE_RECV) == [] assert child.get_handlers(evt.EVT_DIMSE_SENT) == [] assoc.release() scp.shutdown()
def test_flag_store_aet(self): """Test the --store-aet flag.""" # Value not actually checked events = [] def handle_move(event): events.append(event) yield 'localhost', 11113 yield 1 yield 0xFF00, self.response def handle_accepted(event): events.append(event) handlers = [ (evt.EVT_ACCEPTED, handle_accepted), (evt.EVT_C_MOVE, handle_move), ] self.ae = ae = AE() ae.acse_timeout = 5 ae.dimse_timeout = 5 ae.network_timeout = 5 ae.requested_contexts = StoragePresentationContexts ae.supported_contexts = QueryRetrievePresentationContexts scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers) p = self.func( ['--store', '--store-aet', 'SOMESCP', '-k', 'PatientName='] ) p.wait() assert p.returncode == 0 scp.shutdown() assert 'CT.1.2.3.4' in os.listdir() os.remove('CT.1.2.3.4') assert 'CT.1.2.3.4' not in os.listdir()
def test_scp_handler_identifier(self): """Test handler event's identifier property""" attrs = {} def handle(event): attrs['context'] = event.context attrs['assoc'] = event.assoc attrs['request'] = event.request attrs['identifier'] = event.identifier yield 0xFF00, self.query handlers = [(evt.EVT_C_FIND, handle)] self.ae = ae = AE() ae.add_supported_context(ProductCharacteristicsQueryInformationModelFind) ae.add_requested_context(ProductCharacteristicsQueryInformationModelFind) scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers) 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 with pytest.raises(StopIteration): next(result) assoc.release() assert assoc.is_released ds = attrs['identifier'] ds.QueryRetrieveLevel = "PATIENT" ds.PatientName = '*' scp.shutdown()
def test_flag_abort(self): """Test --abort flag.""" events = [] def handle_echo(event): events.append(event) return 0x0000 def handle_release(event): events.append(event) def handle_abort(event): events.append(event) handlers = [ (evt.EVT_C_ECHO, handle_echo), (evt.EVT_RELEASED, handle_release), (evt.EVT_ABORTED, handle_abort), ] self.ae = ae = AE() ae.acse_timeout = 5 ae.dimse_timeout = 5 ae.network_timeout = 5 ae.add_supported_context(Verification) scp = ae.start_server(("localhost", 11112), block=False, evt_handlers=handlers) p = self.func(["--abort"]) p.wait() assert p.returncode == 0 scp.shutdown() assert events[0].event == evt.EVT_C_ECHO assert events[1].event == evt.EVT_ABORTED
def test_pr_level_image(self): """Test IMAGE query level.""" self.ae = ae = AE() ae.acse_timeout = 5 ae.dimse_timeout = 5 ae.network_timeout = 5 model = PatientRootQueryRetrieveInformationModelFind ae.add_requested_context(model) self.p = p = self.func(['-d']) time.sleep(0.5) _send_datasets() time.sleep(1) assoc = ae.associate('localhost', 11112) assert assoc.is_established responses = assoc.send_c_find(self.q_image, model) for ii in range(5): status, ds = next(responses) assert status.Status == 0xFF00 assert 'PatientID' in ds assert 'StudyInstanceUID' in ds assert 'SeriesInstanceUID' in ds assert 'SOPInstanceUID' in ds assert ds.RetrieveAETitle == 'QRSCP' assert ds.QueryRetrieveLevel == 'IMAGE' assert 6 == len(ds) status, ds = next(responses) assert status.Status == 0x0000 assert ds is None pytest.raises(StopIteration, next, responses) assoc.release() p.terminate() p.wait()
def test_scp_handler_context(self): """Test handler event's context attribute""" attrs = {} def handle(event): attrs['context'] = event.context attrs['identifier'] = event.identifier attrs['request'] = event.request attrs['assoc'] = event.assoc yield 0xFF00, self.query handlers = [(evt.EVT_C_FIND, handle)] self.ae = ae = AE() ae.add_supported_context(GeneralRelevantPatientInformationQuery) ae.add_requested_context(GeneralRelevantPatientInformationQuery) scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers) ae.acse_timeout = 5 ae.dimse_timeout = 5 assoc = ae.associate('localhost', 11112) assert assoc.is_established result = assoc.send_c_find(self.query, GeneralRelevantPatientInformationQuery) status, identifier = next(result) assert status.Status == 0xFF00 status, identifier = next(result) assert status.Status == 0x0000 assoc.release() assert assoc.is_released cx = attrs['context'] assert cx.context_id == 1 assert cx.abstract_syntax == GeneralRelevantPatientInformationQuery assert cx.transfer_syntax == '1.2.840.10008.1.2' scp.shutdown()
def test_flag_debug(self, capfd): """Test --debug flag.""" def handle_store(event): return 0x0000 def handle_move(event): yield 'localhost', 11113 yield 0 yield 0x0000, None handlers = [ (evt.EVT_C_MOVE, handle_move), ] self.ae = ae = AE() ae.acse_timeout = 5 ae.dimse_timeout = 5 ae.network_timeout = 5 ae.requested_contexts = StoragePresentationContexts ae.supported_contexts = QueryRetrievePresentationContexts scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers) ae.supported_contexts = StoragePresentationContexts store_scp = ae.start_server( ('', 11113), block=False, evt_handlers=[(evt.EVT_C_STORE, handle_store)] ) p = self.func(['-d', '-k', 'PatientName=']) p.wait() assert p.returncode == 0 out, err = capfd.readouterr() assert "Releasing Association" in err assert "Accept Parameters" in err store_scp.shutdown() scp.shutdown()
def test_flag_max_pdu(self): """Test --max-pdu flag.""" events = [] def handle_find(event): events.append(event) yield 0x0000, None def handle_release(event): events.append(event) handlers = [ (evt.EVT_C_FIND, handle_find), (evt.EVT_RELEASED, handle_release) ] self.ae = ae = AE() ae.acse_timeout = 5 ae.dimse_timeout = 5 ae.network_timeout = 5 ae.supported_contexts = ( QueryRetrievePresentationContexts + BasicWorklistManagementPresentationContexts ) scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers) p = start_findscu(['--max-pdu', '123456', '-k', 'PatientName=']) p.wait() assert p.returncode == 0 scp.shutdown() assert events[0].event == evt.EVT_C_FIND assert events[1].event == evt.EVT_RELEASED requestor = events[1].assoc.requestor assert 123456 == requestor.maximum_length
def test_send_assoc_ac_sop_ext(self, caplog): """Test ACSE.debug_send_associate_ac with SOP Class Extended.""" with caplog.at_level(logging.DEBUG, logger='pynetdicom'): self.ae = ae = AE() ae.add_supported_context(VerificationSOPClass) ae.add_requested_context(VerificationSOPClass) ae.add_requested_context(VerificationSOPClass) ae.add_requested_context(VerificationSOPClass) ae.add_requested_context(VerificationSOPClass) ae.add_requested_context(VerificationSOPClass) scp = ae.start_server(('', 11112), block=False) assoc = ae.associate('localhost', 11112) self.add_sop_ext(self.associate_ac) pdu = A_ASSOCIATE_AC() pdu.from_primitive(self.associate_ac) evt.trigger(assoc, evt.EVT_PDU_SENT, {'pdu': pdu}) messages = [ "Accepted Extended Negotiation:", "SOP Class: =1.2.3.4", "00 01", "SOP Class: =1.2.840.10008.1.1", "00 01 02 03 00 01 02 03 00 01 02 03 00 01 02" " 03", "00 01 02 03 00 01 02 03 00 01 02 03 00 01 02" " 03", "00 01 02 03 00 01 02 03", "Accepted Asynchronous Operations Window Negotiation: None", "User Identity Negotiation Response: None", ] for msg in messages: assert msg in caplog.text assoc.release() scp.shutdown()
def test_event_file_meta(self): """Test basic functioning of event.file_meta""" event_out = [] def handle(event): ds = event.dataset ds.file_meta = event.file_meta event_out.append(ds) return 0x0000 handlers = [(evt.EVT_C_STORE, handle)] self.ae = ae = AE() ae.add_supported_context(CTImageStorage) ts = ae.supported_contexts[0].transfer_syntax[0] ae.add_requested_context(CTImageStorage) scp = ae.start_server(("localhost", 11112), block=False, evt_handlers=handlers) 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() assert assoc.is_released scp.shutdown() ds = event_out[0] meta = event_out[0].file_meta assert meta.MediaStorageSOPClassUID == CTImageStorage assert meta.MediaStorageSOPInstanceUID == ds.SOPInstanceUID assert meta.TransferSyntaxUID == ts
def test_handler_status_dataset_multi(self): """Test handler yielding a Dataset status with other elements""" def handle(event): status = Dataset() status.Status = 0xFF00 status.ErrorComment = 'Test' status.OffendingElement = 0x00010001 yield status, self.query handlers = [(evt.EVT_C_FIND, handle)] self.ae = ae = AE() ae.add_supported_context( ProductCharacteristicsQueryInformationModelFind) ae.add_requested_context( ProductCharacteristicsQueryInformationModelFind, ExplicitVRLittleEndian) scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers) ae.acse_timeout = 5 ae.dimse_timeout = 5 assoc = ae.associate('localhost', 11112) assert assoc.is_established result = assoc.send_c_find( self.query, ProductCharacteristicsQueryInformationModelFind) status, identifier = next(result) assert status.Status == 0xFF00 assert status.ErrorComment == 'Test' assert status.OffendingElement == 0x00010001 status, identifier = next(result) assert status.Status == 0x0000 with pytest.raises(StopIteration): next(result) assoc.release() assert assoc.is_released scp.shutdown()
def test_flag_xi(self): """Test --request-implicit flag.""" events = [] def handle_store(event): events.append(event) return 0x0000 def handle_release(event): events.append(event) handlers = [(evt.EVT_C_STORE, handle_store), (evt.EVT_RELEASED, handle_release)] self.ae = ae = AE() ae.acse_timeout = 5 ae.dimse_timeout = 5 ae.network_timeout = 5 ae.add_supported_context(CTImageStorage) scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers) p = start_storescu([DATASET_FILE, '-xi']) p.wait() assert p.returncode == 0 scp.shutdown() assert events[0].event == evt.EVT_C_STORE assert events[0].dataset.PatientName == 'CompressedSamples^CT1' assert events[1].event == evt.EVT_RELEASED requestor = events[1].assoc.requestor cxs = requestor.primitive.presentation_context_definition_list cxs = requestor.primitive.presentation_context_definition_list assert len(cxs) == 128 cxs = {cx.abstract_syntax: cx for cx in cxs} assert CTImageStorage in cxs assert cxs[CTImageStorage].transfer_syntax == [ImplicitVRLittleEndian]
def test_scp_callback_attr(self): """Test on_n_get attr parameter""" self.scp = DummyGetSCP() self.scp.start() ae = AE() ae.add_requested_context(DisplaySystemSOPClass, '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, 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.attr == [(0x7fe0, 0x0010)] self.scp.stop()
scu_sop_classes = [VerificationSOPClass] except: scu_sop_classes = [VerificationSOPClass] # -------------------------- CREATE AE and ASSOCIATE --------------------------- logger.debug("$echoscu.py v%s %s $" % ("0.5.1", "2016-04-12")) logger.debug("") # Create local AE # Binding to port 0, OS will pick an available port ae = AE( ae_title=args.calling_aet, port=0, scu_sop_class=[VerificationSOPClass], scp_sop_class=[], transfer_syntax=transfer_syntaxes, ) 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 # Request association with remote AE assoc = ae.associate(args.peer, args.port, args.called_aet) # If we successfully Associated then send N DIMSE C-ECHOs
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()
def __init__(self): self.ae = AE(port=11112, scp_sop_class=StorageSOPClassList) threading.Thread.__init__(self) self.daemon = True self.start()
def __init__(self): self.ae = AE(port=11112, scp_sop_class=[VerificationSOPClass]) threading.Thread.__init__(self) self.daemon = True self.start()
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] # Bind to port 0, OS will pick an available port ae = AE(ae_title=args.calling_aet, port=0, scu_sop_class=StorageSOPClassList, scp_sop_class=[], transfer_syntax=transfer_syntax) # Request association with remote assoc = ae.associate(args.peer, args.port, args.called_aet) if assoc.is_established: logger.info('Sending file: %s' %args.dcmfile_in) status = assoc.send_c_store(dataset) assoc.release() # Quit ae.quit()
pynetdicom_logger = logging.getLogger('pynetdicom') pynetdicom_logger.setLevel(logging.INFO) if args.debug: logger.setLevel(logging.DEBUG) pynetdicom_logger = logging.getLogger('pynetdicom') pynetdicom_logger.setLevel(logging.DEBUG) logger.debug('$movescu.py v%s %s $' %('0.1.0', '2016-03-15')) logger.debug('') # Create application entity # Binding to port 0 lets the OS pick an available port ae = AE(ae_title=args.calling_aet, port=0, scu_sop_class=QueryRetrieveSOPClassList, scp_sop_class=StorageSOPClassList, transfer_syntax=[ExplicitVRLittleEndian]) # Set the extended negotiation SCP/SCU role selection to allow us to receive # C-STORE requests for the supported SOP classes ext_neg = [] for context in ae.presentation_contexts_scu: tmp = SCP_SCU_RoleSelectionNegotiation() tmp.sop_class_uid = context.AbstractSyntax tmp.scu_role = False tmp.scp_role = True ext_neg.append(tmp) # Request association with remote