Example #1
0
    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)
Example #2
0
 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)
Example #3
0
 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)
Example #4
0
 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)
Example #5
0
    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
Example #6
0
    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