def test_property_setters_getters(self): """Test Timer property setters and getters.""" timer = Timer(0) self.assertEqual(timer.timeout_seconds, 0) self.assertFalse(timer.is_expired) self.assertEqual(timer.time_remaining, 0) timer = Timer(None) self.assertEqual(timer.timeout_seconds, None) self.assertFalse(timer.is_expired) self.assertEqual(timer.time_remaining, -1) timer.timeout_seconds = 10 self.assertEqual(timer.timeout_seconds, 10) self.assertFalse(timer.is_expired) self.assertEqual(timer.time_remaining, 10) timer.timeout_seconds = 0.2 timer.start() time.sleep(0.1) self.assertTrue(timer.time_remaining < 0.1) self.assertFalse(timer.is_expired) time.sleep(0.1) self.assertTrue(timer.is_expired) timer.timeout_seconds = None self.assertEqual(timer.timeout_seconds, None)
def test_init(self): """Test Timer initialisation""" timer = Timer(10) self.assertTrue(timer.timeout_seconds == 10) timer = Timer(0) self.assertTrue(timer.timeout_seconds == 0) timer = Timer(None) self.assertTrue(timer.timeout_seconds is None)
def test_start_stop(self): """Test Timer stops.""" timer = Timer(0.2) timer.start() time.sleep(0.1) timer.stop() time.sleep(0.2) self.assertFalse(timer.is_expired)
def test_restart(self): """Test Timer restarts correctly.""" timer = Timer(0.2) timer.start() time.sleep(0.1) timer.restart() time.sleep(0.15) self.assertFalse(timer.is_expired) time.sleep(0.05) self.assertTrue(timer.is_expired)
def receive_msg(self, wait=False): """Receive a DIMSE message from the peer. Set the DIMSE provider in a mode ready to receive a response from the peer Parameters ---------- wait : bool, optional Wait until a response has been received (default: False). Returns ------- pynetdicom3.dimse_messages.DIMSEMessage, int or None, None Returns the complete DIMSE message and its presentation context ID or None, None. """ if self.message is None: self.message = DIMSEMessage() timeout = Timer(self.dimse_timeout) timeout.start() if wait: # Loop until complete DIMSE message is received # message may be split into 1 or more fragments while True: # Fix for issue #38 # Because we only progress once the next PDU arrives to be # peeked at, the DIMSE timeout in receive_pdu() doesn't # actually do anything. if timeout.is_expired: return None, None # Race condition: sometimes the DUL will be killed before the # loop exits if not self.dul.is_alive(): return None, None time.sleep(0.001) nxt = self.dul.peek_next_pdu() if nxt is None: continue if nxt.__class__ is not P_DATA: return None, None pdu = self.dul.receive_pdu(wait, self.dimse_timeout) if self.message.decode_msg(pdu): # Callback self.on_receive_dimse_message(self.message) context_id = self.message.ID primitive = self.message.message_to_primitive() # Fix for memory leak, Issue #41 # Reset the DIMSE message, ready for the next one self.message.encoded_command_set = BytesIO() self.message.data_set = BytesIO() self.message = None return primitive, context_id else: return None, None else: cls = self.dul.peek_next_pdu().__class__ if cls not in (type(None), P_DATA): return None, None pdu = self.dul.receive_pdu(wait, self.dimse_timeout) if self.message.decode_msg(pdu): # Callback self.on_receive_dimse_message(self.message) context_id = self.message.ID primitive = self.message.message_to_primitive() # Fix for memory leak, Issue #41 # Reset the DIMSE message, ready for the next one self.message.encoded_command_set = BytesIO() self.message.data_set = BytesIO() self.message = None return primitive, context_id else: return None, None
def __init__(self, socket=None, port=None, dul_timeout=None, assoc=None): """ Parameters ---------- socket : socket.socket, optional The local AE's listen socket port : int, optional The port number on which to wait for incoming connections dul_timeout : float, optional The maximum amount of time to wait for connection responses (in seconds) assoc : pynetdicom3.association.Association The DUL's current Association """ if socket and port: raise ValueError("DULServiceProvider can't be instantiated with " "both socket and port parameters") # The association thread self.assoc = assoc Thread.__init__(self) # Current primitive and PDU self.primitive = None self.pdu = None # The event_queue tracks the events the DUL state machine needs to # process self.event_queue = queue.Queue() # These queues provide communication between the DUL service # user and the DUL service provider. # An event occurs when the DUL service user adds to # the to_provider_queue self.to_provider_queue = queue.Queue() # A primitive is sent to the service user when the DUL service provider # adds to the to_user_queue. self.to_user_queue = queue.Queue() # Setup the idle timer, ARTIM timer and finite state machine # FIXME: Why do we have an idle timer? self._idle_timer = Timer(dul_timeout) # ARTIM timer self.artim_timer = Timer(dul_timeout) # State machine - PS3.8 Section 9.2 self.state_machine = StateMachine(self) if socket: # A client socket has been given, so the local AE is acting as # an SCP # generate an event 5 self.event_queue.put('Evt5') self.scu_socket = socket self.peer_address = None self.scp_socket = None elif port: # A port number has been given, so the local AE is acting as an # SCU. Create a new socket using the given port number self.scp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.scp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # The port number for the local AE to listen on self.local_port = port if self.local_port: try: local_address = os.popen('hostname').read()[:-1] self.scp_socket.bind((local_address, self.local_port)) except Exception as ex: LOGGER.exception(ex) self.scp_socket.listen(1) else: self.scp_socket = None self.scu_socket = None self.peer_address = None else: # No port nor socket self.scp_socket = None self.scu_socket = None self.peer_address = None self._kill_thread = False self.daemon = False # Controls the minimum delay between loops in run() self._run_loop_delay = 0.001