def test_maintain_leases_outdated_items(sleep, time):
    policy = create_policy()
    policy._consumer._stopped.clear()

    # Add these items at the beginning of the timeline
    time.return_value = 0
    policy.lease([base.LeaseRequest(ack_id='ack1', byte_size=50)])

    # Add another item at towards end of the timeline
    time.return_value = policy.flow_control.max_lease_duration - 1
    policy.lease([base.LeaseRequest(ack_id='ack2', byte_size=50)])

    # Now make sure time reports that we are at the end of our timeline.
    time.return_value = policy.flow_control.max_lease_duration + 1

    # Mock the sleep object.
    def trigger_inactive(seconds):
        assert 0 < seconds < 10
        policy._consumer._stopped.set()

    sleep.side_effect = trigger_inactive

    # Also mock the consumer, which sends the request.
    with mock.patch.object(policy._consumer, 'send_request') as send:
        policy.maintain_leases()

    # Only ack2 should be renewed. ack1 should've been dropped
    send.assert_called_once_with(
        types.StreamingPullRequest(
            modify_deadline_ack_ids=['ack2'],
            modify_deadline_seconds=[10],
        ))
    assert len(policy.leased_messages) == 1

    sleep.assert_called()
def test_lease_above_threshold():
    flow_control = types.FlowControl(max_messages=2)
    policy = create_policy(flow_control=flow_control)
    consumer = policy._consumer

    with mock.patch.object(consumer, 'pause') as pause:
        policy.lease([base.LeaseRequest(ack_id='first_ack_id', byte_size=20)])
        pause.assert_not_called()
        policy.lease([base.LeaseRequest(ack_id='second_ack_id', byte_size=25)])
        pause.assert_called_once_with()
def test_lease():
    policy = create_policy()
    policy.lease([base.LeaseRequest(ack_id='ack_id_string', byte_size=20)])
    assert len(policy.leased_messages) == 1
    assert policy._bytes == 20

    # Do this again to prove idempotency.
    policy.lease([base.LeaseRequest(ack_id='ack_id_string', byte_size=20)])
    assert len(policy.leased_messages) == 1
    assert policy._bytes == 20
예제 #4
0
    def lease(self):
        """Inform the policy to lease this message continually.

        .. note::
            This method is called by the constructor, and you should never
            need to call it manually.
        """
        self._request_queue.put(
            base_policy.LeaseRequest(ack_id=self._ack_id, byte_size=self.size))
예제 #5
0
def test_lease():
    msg = create_message(b'foo', ack_id='bogus_ack_id')
    with mock.patch.object(msg._request_queue, 'put') as put:
        msg.lease()
        put.assert_called_once_with(
            base.LeaseRequest(
                ack_id='bogus_ack_id',
                byte_size=25,
            ))
        check_call_types(put, base.LeaseRequest)
def test_load_w_lease():
    flow_control = types.FlowControl(max_messages=10, max_bytes=1000)
    policy = create_policy(flow_control=flow_control)
    consumer = policy._consumer

    with mock.patch.object(consumer, 'pause') as pause:
        # This should mean that our messages count is at 10%, and our bytes
        # are at 15%; the ._load property should return the higher (0.15).
        policy.lease([base.LeaseRequest(ack_id='one', byte_size=150)])
        assert policy._load == 0.15
        pause.assert_not_called()
        # After this message is added, the messages should be higher at 20%
        # (versus 16% for bytes).
        policy.lease([base.LeaseRequest(ack_id='two', byte_size=10)])
        assert policy._load == 0.2
        pause.assert_not_called()
        # Returning a number above 100% is fine.
        policy.lease([base.LeaseRequest(ack_id='three', byte_size=1000)])
        assert policy._load == 1.16
        pause.assert_called_once_with()
def test_maintain_leases_ack_ids():
    policy = create_policy()
    policy._consumer._stopped.clear()
    policy.lease([base.LeaseRequest(ack_id='my ack id', byte_size=50)])

    # Mock the sleep object.
    with mock.patch.object(time, 'sleep', autospec=True) as sleep:

        def trigger_inactive(seconds):
            assert 0 < seconds < 10
            policy._consumer._stopped.set()

        sleep.side_effect = trigger_inactive

        # Also mock the consumer, which sends the request.
        with mock.patch.object(policy._consumer, 'send_request') as send:
            policy.maintain_leases()
            send.assert_called_once_with(
                types.StreamingPullRequest(
                    modify_deadline_ack_ids=['my ack id'],
                    modify_deadline_seconds=[10],
                ))
        sleep.assert_called()

def test_open_already_open():
    policy = create_policy()
    policy._future = mock.sentinel.future

    with pytest.raises(ValueError) as exc_info:
        policy.open(None)

    assert exc_info.value.args == ('This policy has already been opened.', )


@pytest.mark.parametrize('item,method',
                         [(base.AckRequest(0, 0, 0), 'ack'),
                          (base.DropRequest(0, 0), 'drop'),
                          (base.LeaseRequest(0, 0), 'lease'),
                          (base.ModAckRequest(0, 0), 'modify_ack_deadline'),
                          (base.NackRequest(0, 0), 'nack')])
def test_dispatch_callback_valid(item, method):
    policy = create_policy()
    with mock.patch.object(policy, method) as mocked:
        items = [item]
        policy.dispatch_callback(items)
        mocked.assert_called_once_with([item])


def test_on_exception_deadline_exceeded():
    policy = create_policy()

    details = 'Bad thing happened. Time out, go sit in the corner.'
    exc = exceptions.DeadlineExceeded(details)