예제 #1
0
    def test_handle_produce_response_on_nonretriable(self, fake_decode,
                                                     fake_retry):
        m1 = Message('test_driver', {'val': 1}, None, None, 0, 1)
        m2 = Message('test_driver', {'val': 2}, None, None, 0, 1)
        response = Mock()
        response.code = 500
        response.error = False
        response.request = Mock()
        response.request._batch = [m1, m2]
        response.request._id = 1
        body = {
            'offsets': [{}, {}],
            'value_schema_id': 1,
            'key_schema_id': 2,
            'error_code': 50101,
            'message': 'Nonretriable'
        }
        fake_decode.return_value = body

        self.producer._handle_produce_response('test_driver', response)

        calls = [
            call('test_driver', m1, 'nonretriable'),
            call('test_driver', m2, 'nonretriable')
        ]
        self.client.mock_for('drop_message').assert_has_calls(calls)
예제 #2
0
    def test_message_batches_from_retry_queue(self):
        m1 = Message('test_driver', {'val': 1}, None, None, sys.maxsize, 1)
        m2 = Message('test_driver', {'val': 2}, None, None, 0, 1)
        queue = self.client.retry_queues['test_driver']
        for m in [m1, m2]:
            queue.put(m)

        result = list(self.producer._message_batches_from_queue(queue))
        self.assertEqual(len(result), 1)
        self.assertEqual(result[0], [m2])
예제 #3
0
    def test_message_batches_from_queue_multiple_batches(self):
        self.client.flush_max_batch_size = 1
        m1 = Message('test_driver', {'val': 1}, None, None, 0, 1)
        m2 = Message('test_driver', {'val': 2}, None, None, 0, 1)
        queue = self.client.message_queues['test_driver']
        for m in [m1, m2]:
            queue.put(m)

        result = list(self.producer._message_batches_from_queue(queue))
        self.assertEqual(len(result), 2)
        self.assertEqual(result[0], [m1])
        self.assertEqual(result[1], [m2])
예제 #4
0
    def test_evaluate_queue_on_length(self, fake_flush, fake_flush_timer):
        self.client.flush_length_threshold = 1
        m1 = Message('test_driver', {'val': 1}, None, None, 0, 1)
        m2 = Message('test_driver', {'val': 2}, None, None, 0, 1)
        queue = self.client.message_queues['test_driver']
        for m in [m1, m2]:
            queue.put(m)

        self.producer.evaluate_queue('test_driver',
                                     self.client.message_queues['test_driver'])

        fake_flush.assert_called_with('test_driver', FlushReason.LENGTH)
        self.assertFalse(fake_flush_timer.called)
예제 #5
0
    def test_send_batch_produce_request(self, fake_request):
        m1 = Message('test_driver', {'val': 1}, None, None, 0, 1)
        m2 = Message('test_driver', {'val': 2}, None, None, 0, 1)
        batch = [m1, m2]
        fake_request._id = 1

        self.producer._send_batch_produce_request('test_driver', batch)
        call_args = fake_request.mock_calls[0][1]

        self.assertEqual(call_args[2], 10)
        self.assertEqual(call_args[3], 60)
        self.assertEqual(call_args[5], 'test_driver')
        self.assertEqual(call_args[6], batch)
예제 #6
0
    def test_send_batch_produce_request_in_shutdown(self, fake_request):
        m1 = Message('test_driver', {'val': 1}, None, None, 0, 1)
        m2 = Message('test_driver', {'val': 2}, None, None, 0, 1)
        batch = [m1, m2]
        fake_request._id = 1

        self.client.in_shutdown = True
        self.producer._send_batch_produce_request('test_driver', batch)
        call_args = fake_request.mock_calls[0][1]

        self.assertEqual(call_args[2], 0)
        self.assertEqual(call_args[3], 0)
        self.assertEqual(call_args[5], 'test_driver')
        for idx, m in enumerate(batch):
            self.assertTrue(m.true_equals(call_args[6][idx]))
예제 #7
0
    def test_produce_through_evaluate_into_flush(self):
        self.client.flush_length_threshold = 0
        self.client.produce('test_driver', self.test_value, self.test_schema)

        self.assertEqual(
            self.io_loop.next_callback,
            Callback(
                self.producer.evaluate_queue,
                ('test_driver', self.client.message_queues['test_driver']),
                {}))
        self.io_loop.run_next_callback()

        self.assertEqual(self.io_loop.next_callback.fn,
                         self.producer._send_batch_produce_request)
        expected_message = Message('test_driver', self.test_value, None, None,
                                   0, 1)
        self.assertTrue(self.io_loop.next_callback.args[1][0].true_equals(
            expected_message))

        self.assertEqual(self.io_loop.next_later.seconds,
                         self.client.flush_time_threshold_seconds)
        self.assertEqual(
            self.io_loop.next_later.callback,
            Callback(self.producer._flush_topic, ('test_driver', 'time'), {}))

        self.io_loop.pop_callback()
        self.io_loop.pop_later()

        self.assertTrue(self.io_loop.finished)
예제 #8
0
    def test_flush_through_send(self):
        m1 = Message('test_driver', {'val': 1}, None, None, 0, 1)
        queue = self.client.message_queues['test_driver']
        queue.put(m1)

        self.producer._flush_topic('test_driver', 'test')

        self.assertEqual(self.io_loop.next_callback.fn,
                         self.producer._send_batch_produce_request)
        self.assertTrue(self.io_loop.next_callback.args[1][0].true_equals(m1))

        self.io_loop.run_next_callback()

        # Response handler callback from Tornado's HTTP client, this function
        # is defined inline so we can't test against it very well
        self.assertEqual(self.io_loop.next_callback.fn.__name__,
                         'handle_response')
        self.io_loop.pop_callback()

        self.assertEqual(
            self.io_loop.next_later.callback,
            Callback(self.producer._flush_topic, ('test_driver', 'time'), {}))
        self.io_loop.pop_later()

        self.assertTrue(self.io_loop.finished)
예제 #9
0
    def test_handle_produce_response_transport_error(self, fake_retry):
        m1 = Message('test_driver', {'val': 1}, None, None, 0, 1)
        m2 = Message('test_driver', {'val': 2}, None, None, 0, 1)
        response = Mock()
        response.code = 599
        response.error = object()
        response.request = Mock()
        response.request._batch = [m1, m2]
        response.request._id = 1

        self.producer._handle_produce_response('test_driver', response)

        self.client.mock_for('response_5xx').assert_called_once_with(
            'test_driver', response)
        fake_retry.assert_has_calls(
            [call('test_driver', m1),
             call('test_driver', m2)])
예제 #10
0
    def test_queue_message_for_retry_when_full(self):
        m1 = Message('test_driver', {'val': 1}, None, None, 0, 1)
        self.client.retry_queues['test_driver'] = PriorityQueue(maxsize=1)
        self.client.retry_queues['test_driver'].put('whatever')

        self.producer._queue_message_for_retry('test_driver', m1)
        self.client.mock_for('drop_message').assert_called_once_with(
            'test_driver', m1, 'retry_queue_full')
예제 #11
0
    def test_handle_produce_response_on_200(self, fake_decode,
                                            fake_handle_success):
        m1 = Message('test_driver', {'val': 1}, None, None, 0, 1)
        m2 = Message('test_driver', {'val': 2}, None, None, 0, 1)
        response = Mock()
        response.code = 200
        response.error = False
        response.request = Mock()
        response.request._batch = [m1, m2]
        response.request._id = 1
        body = {'offsets': [{}, {}], 'value_schema_id': 1, 'key_schema_id': 2}
        fake_decode.return_value = body

        self.producer._handle_produce_response('test_driver', response)

        fake_handle_success.assert_called_once_with('test_driver', response,
                                                    body)
예제 #12
0
    def test_flush_topic_sends_batches(self):
        self.client.flush_max_batch_size = 1
        m1 = Message('test_driver', {'val': 1}, None, None, 0, 1)
        m2 = Message('test_driver', {'val': 2}, None, None, 0, 1)
        queue = self.client.message_queues['test_driver']
        for m in [m1, m2]:
            queue.put(m)

        self.producer._flush_topic('test_driver', 'testing')

        self.client.mock_for('flush_topic').assert_called_with(
            'test_driver', 'testing')
        self.callback_mock.assert_has_calls([
            call(self.producer._send_batch_produce_request, 'test_driver',
                 [m1]),
            call(self.producer._send_batch_produce_request, 'test_driver',
                 [m2])
        ])
예제 #13
0
    def test_queue_message_for_retry(self):
        m1 = Message('test_driver', {'val': 1}, None, None, 0, 1)
        self.producer._queue_message_for_retry('test_driver', m1)
        retry_message = self.client.retry_queues['test_driver'].get()

        self.assertEqual(retry_message.attempt_number, m1.attempt_number + 1)
        self.assertNotEqual(retry_message.retry_after_time,
                            m1.retry_after_time)
        self.client.mock_for('retry_message').assert_called_once_with(
            'test_driver', retry_message)
예제 #14
0
    def test_handle_produce_success_simple_success(self):
        m1 = Message('test_driver', {'val': 1}, None, None, 0, 1)
        response = Mock()
        response.request = Mock()
        response.request._batch = [m1]
        body = {'offsets': [{}], 'value_schema_id': 1, 'key_schema_id': 2}

        self.producer._handle_produce_success('test_driver', response, body)

        self.client.mock_for('produce_success').assert_called_once_with(
            'test_driver', [(m1, {})], [])
예제 #15
0
    def test_produce_with_full_queue(self):
        self.client.message_queues['test_driver'] = Queue(maxsize=1)
        self.client.message_queues['test_driver'].put('whatever')

        self.client.produce('test_driver', self.test_value, self.test_schema)
        expected_message = Message('test_driver', self.test_value, None, None,
                                   0, 1)

        self.assertEqual(1, self.client.message_queues['test_driver'].qsize())
        self.assertTrue(
            self.client.mock_for('drop_message').called_with(
                'test_driver', expected_message, 'primary_queue_full'))
예제 #16
0
    def test_initial_produce(self):
        self.client.produce('test_driver', self.test_value, self.test_schema)
        expected_message = Message('test_driver', self.test_value, None, None,
                                   0, 1)

        self.assertEqual(self.client.schema_cache['test_driver']['value'],
                         self.test_schema)
        self.assertEqual(None,
                         self.client.schema_cache['test_driver'].get('key'))
        self.assertEqual(1, self.client.message_queues['test_driver'].qsize())
        self.client.mock_for('produce').assert_called_once_with(
            expected_message)
        self.callback_mock.assert_called_once_with(
            self.client.producer.evaluate_queue, 'test_driver',
            self.client.message_queues['test_driver'])
예제 #17
0
    def test_handle_produce_success_mixed_success(self, fake_retry):
        m1 = Message('test_driver', {'val': 1}, None, None, 0, 1)
        m2 = Message('test_driver', {'val': 2}, None, None, 0, 1)
        m3 = Message('test_driver', {'val': 3}, None, None, 0, 1)
        offsets = [{}, {
            'error_code': 1,
            'message': 'Nonretriable'
        }, {
            'error_code': 2,
            'message': 'Retriable'
        }]
        response = Mock()
        response.request = Mock()
        response.request._batch = [m1, m2, m3]
        response.request._id = 1
        body = {'offsets': offsets, 'value_schema_id': 1, 'key_schema_id': 2}

        self.producer._handle_produce_success('test_driver', response, body)

        self.client.mock_for('produce_success').assert_called_once_with(
            'test_driver', [(m1, {})], [(m2, offsets[1]), (m3, offsets[2])])
        self.client.mock_for('drop_message').assert_called_once_with(
            'test_driver', m2, 'nonretriable')
        fake_retry.assert_called_once_with('test_driver', m3)
예제 #18
0
 def make_response(self, response_attrs=None, request_attrs=None):
     response = Mock()
     request = Mock()
     response.code = 200
     response.error = None
     response.body = json.dumps({'offsets': [{}]})
     request._id = 1
     request._topic = 'test_driver'
     request._batch = [
         Message('test_driver', self.test_value, None, None, 0, 1)
     ]
     for k, v in (response_attrs or {}).items():
         if k == 'body':
             v = json.dumps(v)
         setattr(response, k, v)
     for k, v in (request_attrs or {}).items():
         setattr(request, k, v)
     response.request = request
     return response
예제 #19
0
 def test_queue_message_for_retry_nonretriable(self):
     m1 = Message('test_driver', {'val': 1}, None, None, 0, 10)
     self.producer._queue_message_for_retry('test_driver', m1)
     self.client.mock_for('drop_message').assert_called_once_with(
         'test_driver', m1, 'max_retries_exceeded')