Exemplo n.º 1
0
    def test_process_events_with_no_handlers_will_rely_on_generic(
            self, private_run_property):
        """
        `process_events` will rely only on handlers for "*" if
        a given event has no handlers.
        """
        protocol = esl.ESLProtocol()
        private_run_property.side_effect = [True, False]
        fallback_handlers = [mock.Mock(), mock.Mock()]
        protocol.event_handlers['*'] = fallback_handlers
        other_handlers = [mock.Mock(), mock.Mock()]
        protocol.event_handlers['other-handlers'] = other_handlers

        event = mock.Mock()
        event.headers = {
            'Event-Name': 'CUSTOM',
            'Event-Subclass': 'custom-subclass-without-handlers',
        }
        protocol._esl_event_queue.put(event)

        protocol.process_events()
        self.assertTrue(fallback_handlers[0].called)
        fallback_handlers[0].assert_called_with(event)
        self.assertTrue(fallback_handlers[1].called)
        fallback_handlers[1].assert_called_with(event)
        self.assertFalse(other_handlers[0].called)
        self.assertFalse(other_handlers[1].called)
Exemplo n.º 2
0
    def test_process_events_with_post_handler(self, private_run_property):
        """
        `process_events` will call for `after_handle` property
        if it was implemented on such protocol instance, but the
        event will also be passed to default handlers.
        """
        protocol = esl.ESLProtocol()
        private_run_property.side_effect = [True, False]
        protocol.after_handle = mock.Mock()
        some_handlers = [mock.Mock(), mock.Mock()]
        protocol.event_handlers['some-handlers'] = some_handlers

        event = mock.Mock()
        event.headers = {
            'Event-Name': 'CUSTOM',
            'Event-Subclass': 'some-handlers',
        }
        protocol._esl_event_queue.put(event)

        protocol.process_events()
        self.assertTrue(protocol.after_handle.called)
        protocol.after_handle.assert_called_with(event)
        self.assertTrue(some_handlers[0].called)
        some_handlers[0].assert_called_with(event)
        self.assertTrue(some_handlers[1].called)
        some_handlers[1].assert_called_with(event)
Exemplo n.º 3
0
    def test_process_events_quick_sleep_for_falsy_events_queue(
            self, gevent_sleep, private_run_property):
        """
        `process_events` sleeps for 1s if ESL queue has falsy value.
        """
        protocol = esl.ESLProtocol()
        private_run_property.side_effect = [True, False]
        protocol._process_esl_event_queue = False

        protocol.process_events()
        self.assertTrue(gevent_sleep.called)
        gevent_sleep.assert_called_with(1)
Exemplo n.º 4
0
    def test_receive_events_io_error_handling(self):
        """
        `receive_events` will close the socket and stop running in
        case of error
        """
        protocol = esl.ESLProtocol()
        protocol.sock = mock.Mock()
        protocol.sock_file = mock.Mock()
        protocol.sock_file.readline.side_effect = Exception()

        protocol.receive_events()
        self.assertTrue(protocol.sock.close.called)
        self.assertFalse(protocol.connected)
Exemplo n.º 5
0
    def test_private_safe_exec_handler(self):
        """
        `_safe_exec_handler` is a private (and almost static) method
        to apply a function to an event without letting any exception
        reach the outter scope.
        """
        protocol = esl.ESLProtocol()
        bad_handler = mock.Mock(side_effect=Exception())
        bad_handler.__name__ = 'named-handler'
        event = mock.Mock()

        protocol._safe_exec_handler(bad_handler, event)
        self.assertTrue(bad_handler.called)
        bad_handler.assert_called_with(event)
Exemplo n.º 6
0
    def test_receive_events_without_data_but_connected(self):
        """
        `receive_events` is defensive programmed to fix
        bad `connected` property flag if no data is read,
        but without trying to really closing the socket.
        """
        protocol = esl.ESLProtocol()
        protocol.connected = True
        protocol.sock = mock.Mock()
        protocol.sock_file = mock.Mock()
        protocol.sock_file.readline.return_value = None

        protocol.receive_events()
        self.assertFalse(protocol.sock.close.called)
        self.assertFalse(protocol.connected)
Exemplo n.º 7
0
    def test_handle_event_rude_rejection(self):
        """
        `handle_event` handles a "text/rude-rejection" content
        by disabling `connected` flag but still reading it.
        """
        protocol = esl.ESLProtocol()
        protocol.connected = True
        protocol.sock_file = mock.Mock()
        protocol.sock_file.read.return_value = '123'
        event = mock.Mock()
        event.headers = {
            'Content-Type': 'text/rude-rejection',
            'Content-Length': '3',
        }

        protocol.handle_event(event)
        self.assertFalse(protocol.connected)
        self.assertTrue(protocol.sock_file.read.called)
Exemplo n.º 8
0
    def test_handle_event_disconnect_with_linger(self):
        """
        `handle_event` handles a "text/disconnect-notice" content
        with "Content-Disposition" header as "linger" by not
        disconnecting the socket.
        """
        protocol = esl.ESLProtocol()
        protocol.connected = True
        protocol._commands_sent.append(mock.Mock())
        protocol.sock = mock.Mock()
        event = mock.Mock()
        event.headers = {
            'Content-Type': 'text/disconnect-notice',
            'Content-Disposition': 'linger',
        }

        protocol.handle_event(event)
        self.assertTrue(protocol.connected)
        self.assertFalse(protocol.sock.close.called)
Exemplo n.º 9
0
    def test_handle_event_with_packet_loss(self):
        """
        `handle_event` detects if the data read by
        socket doesn't have enough length that its
        metadata "Content-Length" header says, and
        concats more data on event's.
        """
        protocol = esl.ESLProtocol()
        protocol._commands_sent.append(mock.Mock())
        protocol.sock = mock.Mock()
        protocol.sock_file = mock.Mock()
        protocol.sock_file.read.return_value = '123456789'
        event = mock.Mock()
        event.headers = {
            'Content-Type': 'api/response',
            'Content-Length': '10',
        }

        protocol.handle_event(event)
        self.assertEqual(event.data, '123456789123456789')
Exemplo n.º 10
0
    def test_process_events_with_log_type(self, private_run_property):
        """
        `process_events` will accept an event with "log/data" type
        and pass it to its handlers.
        """
        protocol = esl.ESLProtocol()
        private_run_property.side_effect = [True, False]
        handlers = [mock.Mock(), mock.Mock()]
        protocol.event_handlers['log'] = handlers

        event = mock.Mock()
        event.headers = {
            'Content-Type': 'log/data',
        }
        protocol._esl_event_queue.put(event)

        protocol.process_events()
        self.assertTrue(handlers[0].called)
        handlers[0].assert_called_with(event)
        self.assertTrue(handlers[1].called)
        handlers[1].assert_called_with(event)
Exemplo n.º 11
0
    def test_process_events_with_custom_name(self, private_run_property):
        """
        `process_events` will accept an event with "Event-Name" header as "CUSTOM"
        in its headers by calling the handlers indexed by its "Event-Subclass".
        """
        protocol = esl.ESLProtocol()
        private_run_property.side_effect = [True, False]
        handlers = [mock.Mock(), mock.Mock()]
        protocol.event_handlers['custom-subclass'] = handlers

        event = mock.Mock()
        event.headers = {
            'Event-Name': 'CUSTOM',
            'Event-Subclass': 'custom-subclass',
        }
        protocol._esl_event_queue.put(event)

        protocol.process_events()
        self.assertTrue(handlers[0].called)
        handlers[0].assert_called_with(event)
        self.assertTrue(handlers[1].called)
        handlers[1].assert_called_with(event)
Exemplo n.º 12
0
    def test_stop(self):
        """
        `stop` must, if connected, try to send "exit"
        but ignore any exception that `send` method may
        raise for `NotConnectedError` and keep
        process/receiving until closing the socket
        and its file.
        """
        protocol = esl.ESLProtocol()
        protocol.connected = True
        protocol.send = mock.Mock()
        protocol.send.side_effect = esl.NotConnectedError()
        protocol._receive_events_greenlet = mock.Mock()
        protocol._process_events_greenlet = mock.Mock()
        protocol.sock = mock.Mock()
        protocol.sock_file = mock.Mock()

        protocol.stop()
        self.assertTrue(protocol.send.called)
        protocol.send.assert_called_with('exit')
        self.assertTrue(protocol._receive_events_greenlet.join.called)
        self.assertTrue(protocol._process_events_greenlet.join.called)
        self.assertTrue(protocol.sock.close.called)
        self.assertTrue(protocol.sock_file.close.called)