def test_start_and_stop(self):
     '''
     Basic start and stop test.
     '''
     listener = Listener(self._logger)
     listener.start()
     self.assertTrue(listener.running)
     listener.stop()
     self.assertFalse(listener.running)
 def test_stop_and_stop_again(self):
     '''
     Trying to stop twice must not fail.
     '''
     listener = Listener(self._logger)
     listener.start()
     self.assertTrue(listener.running)
     listener.stop()
     self.assertFalse(listener.running)
     listener.stop()
     self.assertFalse(listener.running)
    def test_listening(self):
        '''
        Basic listening test by connecting to the listener.
        '''
        # Trick to synchronise the the sending and receiving of data.
        event = threading.Event()
        dataTx = []
        dataRx = []

        def handler(data):
            '''
            Dummy handler to catch data received on the socket.
            :param data: the data received
            '''
            dataRx.append(data)

            # The test can proceed
            event.set()

        # Setup
        address = '0.0.0.0'
        port = 10000
        listener = Listener(self._logger, address, port, handler)
        listener.start()
        self.assertTrue(listener.running)

        # Run the test
        try:
            for i in range(0, 10):
                data = 'test' + str(i)
                dataTx.append(data)
                event.clear()
                utils.send(address, port, data)
                event.wait(10)
        except Exception, e:
            self._logger.exception(e)
            raise
    def test_registration_retry(self):
        '''
        Test that the client registers when a USB device gets connected.
        '''
        # Device details
        vendor_id_str = '0a1b'
        vendor_id = int(vendor_id_str, 16)
        product_id_str = '2c3d'
        product_id = int(product_id_str, 16)

        # Execution controllers
        server_event = Event()
        server_event.clear()

        # Config
        host = 'localhost'
        port = 9192
        username = '******'
        server_address = host
        server_port = 9191
        retry_period = 1

        # Mocks and other parameters
        mock_pyudev.vendor_id = vendor_id_str
        mock_pyudev.model_id = product_id_str
        mock_pyudev.dormant = True
        #mock_pyudev.delay = 0.1
        start_delay = retry_period
        event_delay = start_delay * 2
        mock_monitor = PyUdevDeviceMonitor(vendor_id,
                                           product_id,
                                           udev_module=mock_pyudev,
                                           logger=self._logger)
        mock_device = mock()
        when(mock_device).get_vendor_id().thenReturn(vendor_id)
        when(mock_device).get_product_id().thenReturn(product_id)
        when(mock_device).is_open().thenReturn(True)
        when(mock_device).send(any())
        when(mock_device).receive().thenReturn('')
        when(mock_device).get_packet_size().thenReturn(64)
        server_data = []

        def _server_handler(data):
            self._logger.debug('Invoked')
            server_data.append(data)
            server_event.set()

        # Client-side instances
        controller = DeviceController(mock_device,
                                      usb_transfer_types.RAW,
                                      mock_monitor,
                                      logger=self._logger)
        client = notifier_client.NotifierClient(username,
                                                controller,
                                                address=host,
                                                port=port,
                                                server_address=server_address,
                                                server_port=server_port,
                                                retry_period=retry_period,
                                                logger=self._logger)

        # Dummy server instance for receiving a registration request
        server_listener = Listener(address=server_address,
                                   port=server_port,
                                   handler=_server_handler,
                                   logger=self._logger)
        # Startup
        client.start()
        self.assertTrue(client.running)
        self.assertTrue(controller.running)

        # Delay server startup to test the registration retry
        sleep(start_delay)
        server_listener.start()
        self.assertTrue(server_listener.running)

        # mock_pyudev will raise an add event, which should result in a
        # registration request, which is what we're waiting for
        server_event.wait(event_delay * 2)
        send_failed = False
        try:
            utils.send(host, port, '')
        except:
            send_failed = True

        # Shutdown
        client.stop()
        self.assertFalse(client.running)
        self.assertFalse(controller.running)
        server_listener.stop()
        self.assertFalse(server_listener.running)

        # Test the results
        self.assertTrue(server_event.is_set(), 'Registration was not in time')
        self.assertFalse(send_failed, 'The host address is invalid')

        # Expected output similar to:
        # requesttypeid=1;hostname=bar;username=foo!
        command = server_data[0]
        self.assertTrue(command.endswith(packets.TERMINATOR))
        self.assertEqual(1, command.count(packets.TERMINATOR))
        self.assertEqual(2, command.count(packets.COMMAND_SEPARATOR))
        self.assertEqual(3, command.count(packets.FIELD_SEPARATOR))
        self.assertEqual(1, command.count('{0}={1}'.
                                          format(fields.REQUEST_TYPE_ID,
                                                 request_types.REGISTER)))
        self.assertEqual(1, command.count('{0}={1}'.
                                          format(fields.HOSTNAME,
                                                 host)))
        self.assertEqual(1, command.count('{0}={1}'.
                                          format(fields.USERNAME,
                                                 username)))