def recv_cmd_msg(zmq_driver_process):
     """
     Await commands on a ZMQ REP socket, forwaring them to the
     driver for processing and returning the result.
     """
     context = zmq.Context()
     sock = context.socket(zmq.REP)
     sock.bind(zmq_driver_process.cmd_host_string)
     mi_logger.info('Driver process cmd socket bound to %s',
                    zmq_driver_process.cmd_host_string)
 
     zmq_driver_process.stop_cmd_thread = False
     while not zmq_driver_process.stop_cmd_thread:
         try:
             msg = sock.recv_pyobj(flags=zmq.NOBLOCK)
             mi_logger.debug('Processing message %s', str(msg))
             reply = zmq_driver_process.cmd_driver(msg)
             while True:
                 try:
                     sock.send_pyobj(reply)
                     break
                 except zmq.ZMQError:
                     time.sleep(.1)
         except zmq.ZMQError:
             time.sleep(.1)
 
     sock.close()
     context.term()
     mi_logger.info('Driver process cmd socket closed.')
        def send_evt_msg(zmq_driver_process):
            """
            Await events on the driver process event queue and publish them
            on a ZMQ PUB socket to the driver process client.
            """
            context = zmq.Context()
            sock = context.socket(zmq.PUB)
            zmq_driver_process.evt_port = sock.bind_to_random_port(zmq_driver_process.event_host_string)
            mi_logger.info("Driver process event socket bound to %i", zmq_driver_process.evt_port)
            file(zmq_driver_process.evt_port_fname, "w+").write(str(zmq_driver_process.evt_port) + "\n")

            zmq_driver_process.stop_evt_thread = False
            while not zmq_driver_process.stop_evt_thread:
                try:
                    evt = zmq_driver_process.events.pop(0)
                    mi_logger.debug("Event thread sending event %s", str(evt))
                    while evt:
                        try:
                            sock.send_pyobj(evt, flags=zmq.NOBLOCK)
                            evt = None
                            mi_logger.debug("Event sent!")
                        except zmq.ZMQError:
                            time.sleep(0.1)
                            if zmq_driver_process.stop_evt_thread:
                                break
                except IndexError:
                    time.sleep(0.1)

            sock.close()
            context.term()
            mi_logger.info("Driver process event socket closed")
        def send_evt_msg(zmq_driver_process):
            """
            Await events on the driver process event queue and publish them
            on a ZMQ PUB socket to the driver process client.
            """
            context = zmq.Context()
            sock = context.socket(zmq.PUB)
            sock.bind(zmq_driver_process.event_host_string)
            mi_logger.info('Driver process event socket bound to %s',
                           zmq_driver_process.event_host_string)

            zmq_driver_process.stop_evt_thread = False
            while not zmq_driver_process.stop_evt_thread:
                try:
                    evt = zmq_driver_process.events.pop(0)
                    mi_logger.debug('Event thread sending event %s', str(evt))
                    while evt:
                        try:
                            sock.send_pyobj(evt, flags=zmq.NOBLOCK)
                            evt = None
                            mi_logger.debug('Event sent!')
                        except zmq.ZMQError:
                            time.sleep(.1)
                            
                except IndexError:
                    time.sleep(.1)

            sock.close()
            context.term()
            mi_logger.info('Driver process event socket closed')
    def test_test(self):
        """
        Test the hardware testing mode.
        """
        # Test the driver is in state unconfigured.
        state = self._dvr_client.cmd_dvr('get_current_state')
        self.assertEqual(state, DriverConnectionState.UNCONFIGURED)

        # Configure driver for comms and transition to disconnected.
        reply = self._dvr_client.cmd_dvr('configure', COMMS_CONFIG)

        # Test the driver is configured for comms.
        state = self._dvr_client.cmd_dvr('get_current_state')
        self.assertEqual(state, DriverConnectionState.DISCONNECTED)

        # Configure driver for comms and transition to disconnected.
        reply = self._dvr_client.cmd_dvr('connect')

        # Test the driver is in unknown state.
        state = self._dvr_client.cmd_dvr('get_current_state')
        self.assertEqual(state, SBE16ProtocolState.UNKNOWN)

        # Configure driver for comms and transition to disconnected.
        reply = self._dvr_client.cmd_dvr('discover')

        # Test the driver is in command mode.
        state = self._dvr_client.cmd_dvr('get_current_state')
        self.assertEqual(state, SBE16ProtocolState.COMMAND)

        start_time = time.time()
        reply = self._dvr_client.cmd_dvr('execute_test')

        # Test the driver is in unknown state.
        state = self._dvr_client.cmd_dvr('get_current_state')
        self.assertEqual(state, SBE16ProtocolState.TEST)
        
        while state != SBE16ProtocolState.COMMAND:
            gevent.sleep(5)
            elapsed = time.time() - start_time
            mi_logger.info('Device testing %f seconds elapsed.' % elapsed)
            state = self._dvr_client.cmd_dvr('get_current_state')

        # Verify we received the test result and it passed.
        test_results = [evt for evt in self._events if evt['type']==DriverAsyncEvent.TEST_RESULT]
        self.assertTrue(len(test_results) == 1)
        self.assertEqual(test_results[0]['value']['success'], 'Passed')

        # Configure driver for comms and transition to disconnected.
        reply = self._dvr_client.cmd_dvr('disconnect')

        # Test the driver is configured for comms.
        state = self._dvr_client.cmd_dvr('get_current_state')
        self.assertEqual(state, DriverConnectionState.DISCONNECTED)

        # Initialize the driver and transition to unconfigured.
        reply = self._dvr_client.cmd_dvr('initialize')
    
        # Test the driver is in state unconfigured.
        state = self._dvr_client.cmd_dvr('get_current_state')
        self.assertEqual(state, DriverConnectionState.UNCONFIGURED)
        def recv_cmd_msg(zmq_driver_process):
            """
            Await commands on a ZMQ REP socket, forwaring them to the
            driver for processing and returning the result.
            """
            context = zmq.Context()
            sock = context.socket(zmq.REP)
            zmq_driver_process.cmd_port = sock.bind_to_random_port(zmq_driver_process.cmd_host_string)
            mi_logger.info("Driver process cmd socket bound to %i", zmq_driver_process.cmd_port)
            file(zmq_driver_process.cmd_port_fname, "w+").write(str(zmq_driver_process.cmd_port) + "\n")

            zmq_driver_process.stop_cmd_thread = False
            while not zmq_driver_process.stop_cmd_thread:
                try:
                    msg = sock.recv_pyobj(flags=zmq.NOBLOCK)
                    mi_logger.debug("Processing message %s", str(msg))
                    reply = zmq_driver_process.cmd_driver(msg)
                    while True:
                        try:
                            sock.send_pyobj(reply, flags=zmq.NOBLOCK)
                            break
                        except zmq.ZMQError:
                            time.sleep(0.1)
                            if zmq_driver_process.stop_cmd_thread:
                                break
                except zmq.ZMQError:
                    time.sleep(0.1)

            sock.close()
            context.term()
            mi_logger.info("Driver process cmd socket closed.")
    def setUp(self):
        """
        Setup test cases.
        """

        # Clear driver event list.
        self._events = []

        # The port agent object. Used to start and stop the port agent.
        self._pagent = None
        
        # The driver process popen object.
        self._dvr_proc = None
        
        # The driver client.
        self._dvr_client = None

        # Create and start the port agent.
        mi_logger.info('start')
        self._start_pagent()
        self.addCleanup(self._stop_pagent)    

        # Create and start the driver.
        self._start_driver()
        self.addCleanup(self._stop_driver)        
 def _stop_pagent(self):
     """
     Stop the port agent.
     """
     if self._pagent:
         pid = self._pagent.get_pid()
         if pid:
             mi_logger.info('Stopping pagent pid %i', pid)
             self._pagent.stop()
         else:
             mi_logger.info('No port agent running.')
    def _stop_driver(self):
        """
        Method to shut down the driver process. Attempt normal shutdown,
        and kill the process if unsuccessful.
        """
        
        if self._dvr_proc:
            mi_logger.info('Stopping driver process pid %d', self._dvr_proc.pid)
            if self._dvr_client:
                self._dvr_client.done()
                self._dvr_proc.wait()
                self._dvr_client = None

            else:
                try:
                    mi_logger.info('Killing driver process.')
                    self._dvr_proc.kill()
                except OSError:
                    pass
            self._dvr_proc = None
    def _start_pagent(self):
        """
        Construct and start the port agent.
        """
        
        # Create port agent object.
        this_pid = os.getpid()
        self._pagent = EthernetDeviceLogger.launch_process(DEV_ADDR, DEV_PORT,
                        WORK_DIR, DELIM, this_pid)

        pid = self._pagent.get_pid()
        while not pid:
            gevent.sleep(.1)
            pid = self._pagent.get_pid()
        port = self._pagent.get_port()
        while not port:
            gevent.sleep(.1)
            port = self._pagent.get_port()
        
        COMMS_CONFIG['port'] = port

        mi_logger.info('Started port agent pid %d listening at port %d', pid, port)
 def _start_driver(self):
     """
     Start the driver process.
     """
     
     # Launch driver process based on test config.
     this_pid = os.getpid()
     (dvr_proc, cmd_port, evt_port) = ZmqDriverProcess.launch_process(DVR_MOD, DVR_CLS, WORK_DIR, this_pid)
     self._dvr_proc = dvr_proc
     mi_logger.info('Started driver process for %d %d %s %s', cmd_port,
         evt_port, DVR_MOD, DVR_CLS)
     mi_logger.info('Driver process pid %d', self._dvr_proc.pid)
         
     # Create driver client.            
     self._dvr_client = ZmqDriverClient('localhost', cmd_port,
         evt_port)
     mi_logger.info('Created driver client for %d %d %s %s', cmd_port,
         evt_port, DVR_MOD, DVR_CLS)
     
     # Start client messaging.
     self._dvr_client.start_messaging(self.evt_recd)
     mi_logger.info('Driver messaging started.')
     gevent.sleep(.5)