Ejemplo n.º 1
0
    def test_start_pa_client_lost_port_agent_rx(self):
        """
        This test starts the port agent and then stops the port agent and
        verifies that the error callback was called (because the listener
        is the only one that will see the error, since there is no send
        operation).
        """

        self.resetTestVars()

        self.init_instrument_simulator()
        self.startPortAgent()

        pa_client = PortAgentClient(self.ipaddr, self.data_port, self.cmd_port)
        pa_client.init_comms(self.myGotData, self.myGotRaw,
                             self.myGotListenerError, self.myGotError)

        try:
            self.stop_port_agent()

        except InstrumentConnectionException as e:
            log.error("Exception caught: %r" % e)

        time.sleep(5)

        # Assert that the error_callback was called.  At this moment the listener
        # is seeing the error first, and that does not call the exception, so
        # don't test for that yet.
        self.assertTrue(self.errorCallbackCalled)
Ejemplo n.º 2
0
    def test_pa_client_retry(self):
        """
        Test that the port agent client will not continually try to recover
        when the port agent closes the connection gracefully because it has
        another client connected.
        """

        exception_raised = False
        self.resetTestVars()

        self.init_instrument_simulator()
        self.startPortAgent()
        time.sleep(2)

        # Start a TCP client that will connect to the data port; this sets up the
        # situation where the Port Agent will immediately close the connection
        # because it already has one
        self.tcp_client = TcpClient("localhost", self.data_port)
        time.sleep(2)

        pa_client = PortAgentClient(self.ipaddr, self.data_port, self.cmd_port)

        try:
            pa_client.init_comms(self.myGotData, self.myGotRaw,
                                 self.myGotListenerError, self.myGotError)
        except InstrumentConnectionException:
            exception_raised = True

        # Give it some time to retry
        time.sleep(4)

        self.assertTrue(exception_raised)
    def test_pa_client_retry(self):
        """
        Test that the port agent client will not continually try to recover
        when the port agent closes the connection gracefully because it has
        another client connected.
        """

        exception_raised = False
        self.resetTestVars()

        self.init_instrument_simulator()
        self.startPortAgent()
        time.sleep(2)

        # Start a TCP client that will connect to the data port; this sets up the
        # situation where the Port Agent will immediately close the connection
        # because it already has one
        self.tcp_client = TcpClient("localhost", self.data_port)
        time.sleep(2)

        pa_client = PortAgentClient(self.ipaddr, self.data_port, self.cmd_port)

        try:
            pa_client.init_comms(self.myGotData, self.myGotRaw, self.myGotListenerError, self.myGotError)
        except InstrumentConnectionException:
            exception_raised = True

        # Give it some time to retry
        time.sleep(4)

        self.assertTrue(exception_raised)
    def test_start_pa_client_lost_port_agent_rx(self):
        """
        This test starts the port agent and then stops the port agent and
        verifies that the error callback was called (because the listener
        is the only one that will see the error, since there is no send
        operation).
        """

        self.resetTestVars()

        self.init_instrument_simulator()
        self.startPortAgent()

        pa_client = PortAgentClient(self.ipaddr, self.data_port, self.cmd_port)
        pa_client.init_comms(self.myGotData, self.myGotRaw, self.myGotListenerError, self.myGotError)

        try:
            self.stop_port_agent()

        except InstrumentConnectionException as e:
            log.error("Exception caught: %r" % e)

        time.sleep(5)

        # Assert that the error_callback was called.  At this moment the listener
        # is seeing the error first, and that does not call the exception, so
        # don't test for that yet.
        self.assertTrue(self.errorCallbackCalled)
    def test_port_agent_client_send(self):
        ipaddr = "67.58.49.194"
        port = 4000
        paClient = PortAgentClient(self.ipaddr, self.port)
        # paClient = PortAgentClient(ipaddr, port)
        paClient.init_comms(self.myGotData)

        paClient.send("this is a test\n")
    def test_start_paClient_no_port_agent(self):

        print "port agent client test begin"

        paClient = PortAgentClient(self.ipaddr, self.data_port, self.cmd_port)
        
        paClient.init_comms(self.myGotData, self.myGotRaw, self.myGotError)
        
        self.assertTrue(self.errorCallbackCalled)
Ejemplo n.º 7
0
    def _build_connection(self, config):
        """
        Constructs and returns a Connection object according to the given
        configuration. The connection object is a LoggerClient instance in
        this base class. Subclasses can overwrite this operation as needed.
        The value returned by this operation is assigned to self._connection
        and also to self._protocol._connection upon entering in the
        DriverConnectionState.CONNECTED state.

        @param config configuration dict

        @retval a Connection instance, which will be assigned to
                  self._connection

        @throws InstrumentParameterException Invalid configuration.
        """
        if 'mock_port_agent' in config:
            mock_port_agent = config['mock_port_agent']
            # check for validity here...
            if (mock_port_agent is not None):
                return mock_port_agent
        try:
            addr = config['addr']
            port = config['port']
            cmd_port = config.get('cmd_port')

            if isinstance(addr, str) and isinstance(port, int) and len(addr)>0:
                return PortAgentClient(addr, port, cmd_port)
            else:
                raise InstrumentParameterException('Invalid comms config dict.')

        except (TypeError, KeyError):
            raise InstrumentParameterException('Invalid comms config dict.')
Ejemplo n.º 8
0
    def _build_connection(self, *args, **kwargs):
        """
        Constructs and returns a Connection object according to the given
        configuration. The connection object is a LoggerClient instance in
        this base class. Subclasses can overwrite this operation as needed.
        The value returned by this operation is assigned to self._connections
        and also to self._protocol._connection upon entering in the
        DriverConnectionState.CONNECTED state.

        @param all_configs configuration dict
        @returns a dictionary of Connection instances, which will be assigned to self._connection
        @throws InstrumentParameterException Invalid configuration.
        """
        all_configs = kwargs.get('config', None)  # via kwargs
        if all_configs is None and len(args) > 0:
            all_configs = args[0]  # via first argument

        if all_configs is None:
            all_configs = {
                MCU: self._get_port_agent_config(self.refdes + '-MCU'),
                TURBO: self._get_port_agent_config(self.refdes + '-TURBO'),
                RGA: self._get_port_agent_config(self.refdes + '-RGA')
            }

        for key in all_configs:
            if all_configs[key] is None:
                raise InstrumentParameterException(
                    'No %s port agent config supplied and failed to auto-discover'
                    % key)

        connections = {}

        for name, config in all_configs.items():
            if not isinstance(config, dict):
                continue
            if 'mock_port_agent' in config:
                mock_port_agent = config['mock_port_agent']
                # check for validity here...
                if mock_port_agent is not None:
                    connections[name] = mock_port_agent
            else:
                try:
                    addr = config['addr']
                    port = config['port']
                    cmd_port = config.get('cmd_port')

                    if isinstance(addr, basestring) and isinstance(
                            port, int) and len(addr) > 0:
                        connections[name] = PortAgentClient(
                            addr, port, cmd_port, self._massp_got_data(name),
                            self._lost_connection_callback)
                    else:
                        raise InstrumentParameterException(
                            'Invalid comms config dict.')

                except (TypeError, KeyError):
                    raise InstrumentParameterException(
                        'Invalid comms config dict.')
        return connections
    def test_start_paClient_lost_port_agent_tx(self):
        """
        This test starts the port agent and then starts the port agent client
        in a special way that will not start the listener thread.  This will
        guarantee that the send context is the one the sees the error.
        """

        self.resetTestVars()

        self.init_instrument_simulator()
        self.startPortAgent()

        paClient = PortAgentClient(self.ipaddr, self.data_port, self.cmd_port)

        """
        Give the port agent time to initialize
        """
        time.sleep(5)
        
        paClient.init_comms(self.myGotData, self.myGotRaw, self.myGotError, self.myGotListenerError, start_listener = False)
        
        try:
            self.stop_port_agent()    
            data = "this big ol' test should cause send context to fail"
            paClient.send(data)
        
            time.sleep(1)

        except InstrumentConnectionException as e:
            log.error("Exception caught: %r" % (e))
            exceptionCaught = True
            
        else:
            exceptionCaught = False
        
        time.sleep(5)
    
        """
        Assert that the error_callback was called.  For this test the listener
        should not be running, so the send context should see the error, and that
        should throw an exception.  Assert that the callback WAS called and that
        an exception WAS thrown.
        """
        self.assertTrue(self.errorCallbackCalled)        
        self.assertTrue(exceptionCaught)
    def test_pa_client_rx_heartbeat(self):
        """
        Test that the port agent can send heartbeats when the pa_client has
        a heartbeat_interval of 0.  The port_agent_config() method above
        sets the heartbeat interval.
        """

        self.resetTestVars()

        self.init_instrument_simulator()
        self.startPortAgent()
        time.sleep(5)

        pa_client = PortAgentClient(self.ipaddr, self.data_port, self.cmd_port)
        pa_client.init_comms(self.myGotData, self.myGotRaw, self.myGotListenerError, self.myGotError)

        time.sleep(10)

        self.assertFalse(self.errorCallbackCalled)
    def test_pa_client_rx_heartbeat(self):
        """
        Test that the port agent can send heartbeats when the pa_client has
        a heartbeat_interval of 0.  The port_agent_config() method above
        sets the heartbeat interval.
        """

        self.resetTestVars()

        self.init_instrument_simulator()
        self.startPortAgent()
        time.sleep(5)

        pa_client = PortAgentClient(self.ipaddr, self.data_port, self.cmd_port)
        pa_client.init_comms(self.myGotData, self.myGotRaw, self.myGotListenerError, self.myGotError)

        time.sleep(10)

        self.assertFalse(self.errorCallbackCalled)
Ejemplo n.º 12
0
    def test_start_pa_client_no_port_agent(self):

        self.resetTestVars()

        pa_client = PortAgentClient(self.ipaddr, self.data_port, self.cmd_port)

        self.assertRaises(InstrumentConnectionException, pa_client.init_comms,
                          self.myGotData, self.myGotRaw,
                          self.myGotListenerError, self.myGotError)

        self.assertFalse(self.errorCallbackCalled)
    def test_start_paClient_with_port_agent(self):

        self.resetTestVars()

        self.init_instrument_simulator()
        self.startPortAgent()

        paClient = PortAgentClient(self.ipaddr, self.data_port, self.cmd_port)

        try:
            paClient.init_comms(self.myGotData, self.myGotRaw,
                                self.myGotListenerError, self.myGotError)

        except InstrumentConnectionException as e:
            log.error("Exception caught: %r" % (e))
            exceptionCaught = True

        else:
            exceptionCaught = False

            data = "this is a great big test"
            paClient.send(data)

            time.sleep(1)

            self._instrument_simulator.send(data)

            time.sleep(5)

        paClient.stop_comms()
        """
        Assert that the error_callback was not called, that an exception was not
        caught, and that the data and raw callbacks were called.
        """
        self.assertFalse(self.errorCallbackCalled)
        self.assertFalse(exceptionCaught)
        self.assertTrue(self.rawCallbackCalled)
        self.assertTrue(self.dataCallbackCalled)
    def test_start_paClient_lost_port_agent_tx(self):
        """
        This test starts the port agent and then starts the port agent client
        in a special way that will not start the listener thread.  This will
        guarantee that the send context is the one the sees the error.
        """

        self.resetTestVars()

        self.init_instrument_simulator()
        self.startPortAgent()

        paClient = PortAgentClient(self.ipaddr, self.data_port, self.cmd_port)
        """
        Give the port agent time to initialize
        """
        time.sleep(5)

        paClient.init_comms(self.myGotData,
                            self.myGotRaw,
                            self.myGotError,
                            self.myGotListenerError,
                            start_listener=False)

        try:
            self.stop_port_agent()
            data = "this big ol' test should cause send context to fail"
            paClient.send(data)

            time.sleep(1)

        except InstrumentConnectionException as e:
            log.error("Exception caught: %r" % (e))
            exceptionCaught = True

        else:
            exceptionCaught = False

        time.sleep(5)
        """
        Assert that the error_callback was called.  For this test the listener
        should not be running, so the send context should see the error, and that
        should throw an exception.  Assert that the callback WAS called and that
        an exception WAS thrown.
        """
        self.assertTrue(self.errorCallbackCalled)
        self.assertTrue(exceptionCaught)
    def test_start_paClient_with_port_agent(self):

        self.init_instrument_simulator()
        self.startPortAgent()

        paClient = PortAgentClient(self.ipaddr, self.data_port, self.cmd_port)
        
        paClient.init_comms(self.myGotData, self.myGotRaw, self.myGotError)
        
        data = "this is a great big test"
        paClient.send(data)
        
        time.sleep(1)

        self._instrument_simulator.send(data)
        
        time.sleep(5)

        paClient.stop_comms()
        
        self.assertTrue(self.rawCallbackCalled)
        self.assertTrue(self.dataCallbackCalled)
Ejemplo n.º 16
0
    def _build_connection(self, all_configs):
        """
        Constructs and returns a Connection object according to the given
        configuration. The connection object is a LoggerClient instance in
        this base class. Subclasses can overwrite this operation as needed.
        The value returned by this operation is assigned to self._connection
        and also to self._protocol._connection upon entering in the
        DriverConnectionState.CONNECTED state.

        @param all_configs configuration dict
        @returns a dictionary of Connection instances, which will be assigned to self._connection
        @throws InstrumentParameterException Invalid configuration.
        """
        connections = {}
        for name, config in all_configs.items():
            if not isinstance(config, dict):
                continue
            if 'mock_port_agent' in config:
                mock_port_agent = config['mock_port_agent']
                # check for validity here...
                if mock_port_agent is not None:
                    connections[name] = mock_port_agent
            else:
                try:
                    addr = config['addr']
                    port = config['port']
                    cmd_port = config.get('cmd_port')

                    if isinstance(addr, str) and isinstance(port, int) and len(addr) > 0:
                        connections[name] = PortAgentClient(addr, port, cmd_port)
                    else:
                        raise InstrumentParameterException('Invalid comms config dict in build_connections.')

                except (TypeError, KeyError) as e:
                    raise InstrumentParameterException('Invalid comms config dict.. %r' % e)
        return connections
    def test_start_paClient_with_port_agent(self):

        self.resetTestVars()
        
        self.init_instrument_simulator()
        self.startPortAgent()

        paClient = PortAgentClient(self.ipaddr, self.data_port, self.cmd_port)

        try:        
            paClient.init_comms(self.myGotData, self.myGotRaw, self.myGotListenerError, self.myGotError)
        
        except InstrumentConnectionException as e:
            log.error("Exception caught: %r" % (e))
            exceptionCaught = True
            
        else:
            exceptionCaught = False
        
            data = "this is a great big test"
            paClient.send(data)
        
            time.sleep(1)
    
            self._instrument_simulator.send(data)
            
            time.sleep(5)
    
        paClient.stop_comms()

        """
        Assert that the error_callback was not called, that an exception was not
        caught, and that the data and raw callbacks were called.
        """
        self.assertFalse(self.errorCallbackCalled)        
        self.assertFalse(exceptionCaught)
        self.assertTrue(self.rawCallbackCalled)
        self.assertTrue(self.dataCallbackCalled)
    def test_callback_error(self):
        paClient = PortAgentClient(self.ipaddr, self.data_port, self.cmd_port)
        
        """
        Mock up the init_comms method; the callback_error will try to invoke
        it, which will try to connect to the port_agent
        """
        mock_init_comms = Mock(spec = "init_comms")
        paClient.init_comms = mock_init_comms
        
        """
        Test that True is returned because the callback will try a recovery, 
        and it doesn't matter at that point that there is no higher-level
        callback registered.  Also assert that mock_init_comms was called.
        """
        retValue = paClient.callback_error("This is a great big error")
        self.assertTrue(retValue)
        self.assertTrue(len(mock_init_comms.mock_calls) == 1)

        """
        Now call callback_error again.  This time it should return False
        because no higher-level callback has been registered.  Also assert
        that mock_init_calls hasn't been called again (still is 1).
        """
        retValue = paClient.callback_error("This is a big boo boo")
        self.assertFalse(retValue)
        self.assertTrue(len(mock_init_comms.mock_calls) == 1)

        """
        Now call again with a callback registered; assert that the retValue
        is True (callback registered), that mock_init_comms is still 1, and
        that the higher-level callback was called.
        """
        self.resetTestVars()
        paClient.user_callback_error = self.myGotError
        retValue = paClient.callback_error("Another big boo boo")
        self.assertTrue(retValue)
        self.assertTrue(len(mock_init_comms.mock_calls) == 1)
        self.assertTrue(self.errorCallbackCalled == 1)
    def test_start_pa_client_lost_port_agent_tx_rx(self):
        """
        This test starts the port agent and the instrument_simulator and
        tests that data is sent and received first; then it stops the port
        agent and tests that the error_callback was called.
        """

        self.resetTestVars()

        self.init_instrument_simulator()
        self.startPortAgent()

        pa_client = PortAgentClient(self.ipaddr, self.data_port, self.cmd_port)
        pa_client.init_comms(self.myGotData, self.myGotRaw, self.myGotListenerError, self.myGotError)

        # Now send some data; there should be no errors.
        try:
            data = "this is a great big test"
            pa_client.send(data)

            time.sleep(1)

            self._instrument_simulator.send(data)

        except InstrumentConnectionException as e:
            log.error("Exception caught: %r" % e)
            exception_caught = True

        else:
            exception_caught = False

        time.sleep(1)

        # Assert that the error_callback was NOT called, that an exception was NOT
        # caught, and that the data and raw callbacks WERE called.
        self.assertFalse(self.errorCallbackCalled)
        self.assertFalse(exception_caught)
        self.assertTrue(self.rawCallbackCalled)
        self.assertTrue(self.dataCallbackCalled)

        # Now reset the test variables and try again; this time after stopping
        # the port agent.  Should be errors
        self.resetTestVars()

        try:
            self.stop_port_agent()
            log.debug("Port agent stopped")
            data = "this is another great big test"
            pa_client.send(data)

            time.sleep(1)

            log.debug("Sending from simulator")
            self._instrument_simulator.send(data)

        except InstrumentConnectionException as e:
            log.error("Exception caught: %r" % e)

        time.sleep(5)

        # Assert that the error_callback WAS called.  The listener usually
        # is seeing the error first, and that does not call the exception, so
        # only assert that the error callback was called.
        self.assertTrue(self.errorCallbackCalled)
    def test_start_pa_client_no_port_agent_big_data(self):

        self.resetTestVars()

        logging.getLogger('mi.core.instrument.port_agent_client').setLevel(logging.DEBUG)

        # I put this in here because PortAgentPacket cannot make a new packet
        # with a valid checksum.
        def makepacket(msgtype, timestamp, data):
            from struct import Struct

            SYNC = (0xA3, 0x9D, 0x7A)
            HEADER_FORMAT = "!BBBBHHd"
            header_struct = Struct(HEADER_FORMAT)
            HEADER_SIZE = header_struct.size

            def calculate_checksum(data, seed=0):
                n = seed
                for datum in data:
                    n ^= datum
                return n

            def pack_header(buf, msgtype, pktsize, checksum, timestamp):
                sync1, sync2, sync3 = SYNC
                header_struct.pack_into(buf, 0, sync1, sync2, sync3, msgtype, pktsize,
                                        checksum, timestamp)

            pktsize = HEADER_SIZE + len(data)
            pkt = bytearray(pktsize)
            pack_header(pkt, msgtype, pktsize, 0, timestamp)
            pkt[HEADER_SIZE:] = data
            checksum = calculate_checksum(pkt)
            pack_header(pkt, msgtype, pktsize, checksum, timestamp)
            return pkt

        # Make a BIG packet
        data = "A" * (2 ** 16 - HEADER_SIZE - 1)
        txpkt = makepacket(PortAgentPacket.DATA_FROM_INSTRUMENT, 0.0, data)

        def handle(sock, addr):
            # Send it in pieces
            sock.sendall(txpkt[:1500])
            time.sleep(1)
            sock.sendall(txpkt[1500:])
            time.sleep(10)

        import gevent.server

        dataserver = gevent.server.StreamServer((self.ipaddr, self.data_port), handle)
        cmdserver = gevent.server.StreamServer((self.ipaddr, self.cmd_port), lambda x, y: None)

        pa_client = PortAgentClient(self.ipaddr, self.data_port, self.cmd_port)

        try:
            dataserver.start()
            cmdserver.start()
            pa_client.init_comms(self.myGotData, self.myGotRaw, self.myGotListenerError, self.myGotError)

        except InstrumentConnectionException as e:
            log.error("Exception caught: %r" % e)
            raise

        else:
            time.sleep(5)

        finally:
            pa_client.stop_comms()
            dataserver.kill()
            cmdserver.kill()

        # Assert that the error_callback was not called, that an exception was not
        # caught, and that the data and raw callbacks were called.
        self.assertFalse(self.errorCallbackCalled)
        self.assertTrue(self.rawCallbackCalled)
        self.assertTrue(self.dataCallbackCalled)

        self.assertEquals(self.pa_packet.get_data_length(), len(data))
        self.assertEquals(len(self.pa_packet.get_data()), len(data))
        # don't use assertEquals b/c it will print 64kb
        self.assert_(self.pa_packet.get_data() == data)
 def test_port_agent_client_receive(self):
     ipaddr = "67.58.49.194"
     port = 4000
     paClient = PortAgentClient(self.ipaddr, self.port)
     # paClient = PortAgentClient(ipaddr, port)
     paClient.init_comms(self.myGotData)
Ejemplo n.º 22
0
    def test_start_pa_client_no_port_agent_big_data(self):

        self.resetTestVars()

        logging.getLogger('mi.core.instrument.port_agent_client').setLevel(
            logging.DEBUG)

        # I put this in here because PortAgentPacket cannot make a new packet
        # with a valid checksum.
        def makepacket(msgtype, timestamp, data):
            from struct import Struct

            SYNC = (0xA3, 0x9D, 0x7A)
            HEADER_FORMAT = "!BBBBHHd"
            header_struct = Struct(HEADER_FORMAT)
            HEADER_SIZE = header_struct.size

            def calculate_checksum(data, seed=0):
                n = seed
                for datum in data:
                    n ^= datum
                return n

            def pack_header(buf, msgtype, pktsize, checksum, timestamp):
                sync1, sync2, sync3 = SYNC
                header_struct.pack_into(buf, 0, sync1, sync2, sync3, msgtype,
                                        pktsize, checksum, timestamp)

            pktsize = HEADER_SIZE + len(data)
            pkt = bytearray(pktsize)
            pack_header(pkt, msgtype, pktsize, 0, timestamp)
            pkt[HEADER_SIZE:] = data
            checksum = calculate_checksum(pkt)
            pack_header(pkt, msgtype, pktsize, checksum, timestamp)
            return pkt

        # Make a BIG packet
        data = "A" * (2**16 - HEADER_SIZE - 1)
        txpkt = makepacket(PortAgentPacket.DATA_FROM_INSTRUMENT, 0.0, data)

        def handle(sock, addr):
            # Send it in pieces
            sock.sendall(txpkt[:1500])
            time.sleep(1)
            sock.sendall(txpkt[1500:])
            time.sleep(10)

        import gevent.server

        dataserver = gevent.server.StreamServer((self.ipaddr, self.data_port),
                                                handle)
        cmdserver = gevent.server.StreamServer((self.ipaddr, self.cmd_port),
                                               lambda x, y: None)

        pa_client = PortAgentClient(self.ipaddr, self.data_port, self.cmd_port)

        try:
            dataserver.start()
            cmdserver.start()
            pa_client.init_comms(self.myGotData, self.myGotRaw,
                                 self.myGotListenerError, self.myGotError)

        except InstrumentConnectionException as e:
            log.error("Exception caught: %r" % e)
            raise

        else:
            time.sleep(5)

        finally:
            pa_client.stop_comms()
            dataserver.kill()
            cmdserver.kill()

        # Assert that the error_callback was not called, that an exception was not
        # caught, and that the data and raw callbacks were called.
        self.assertFalse(self.errorCallbackCalled)
        self.assertTrue(self.rawCallbackCalled)
        self.assertTrue(self.dataCallbackCalled)

        self.assertEquals(self.pa_packet.get_data_length(), len(data))
        self.assertEquals(len(self.pa_packet.get_data()), len(data))
        # don't use assertEquals b/c it will print 64kb
        self.assert_(self.pa_packet.get_data() == data)
Ejemplo n.º 23
0
    def test_start_pa_client_lost_port_agent_tx_rx(self):
        """
        This test starts the port agent and the instrument_simulator and
        tests that data is sent and received first; then it stops the port
        agent and tests that the error_callback was called.
        """

        self.resetTestVars()

        self.init_instrument_simulator()
        self.startPortAgent()

        pa_client = PortAgentClient(self.ipaddr, self.data_port, self.cmd_port)
        pa_client.init_comms(self.myGotData, self.myGotRaw,
                             self.myGotListenerError, self.myGotError)

        # Now send some data; there should be no errors.
        try:
            data = "this is a great big test"
            pa_client.send(data)

            time.sleep(1)

            self._instrument_simulator.send(data)

        except InstrumentConnectionException as e:
            log.error("Exception caught: %r" % e)
            exception_caught = True

        else:
            exception_caught = False

        time.sleep(1)

        # Assert that the error_callback was NOT called, that an exception was NOT
        # caught, and that the data and raw callbacks WERE called.
        self.assertFalse(self.errorCallbackCalled)
        self.assertFalse(exception_caught)
        self.assertTrue(self.rawCallbackCalled)
        self.assertTrue(self.dataCallbackCalled)

        # Now reset the test variables and try again; this time after stopping
        # the port agent.  Should be errors
        self.resetTestVars()

        try:
            self.stop_port_agent()
            log.debug("Port agent stopped")
            data = "this is another great big test"
            pa_client.send(data)

            time.sleep(1)

            log.debug("Sending from simulator")
            self._instrument_simulator.send(data)

        except InstrumentConnectionException as e:
            log.error("Exception caught: %r" % e)

        time.sleep(5)

        # Assert that the error_callback WAS called.  The listener usually
        # is seeing the error first, and that does not call the exception, so
        # only assert that the error callback was called.
        self.assertTrue(self.errorCallbackCalled)