diff options
author | Tres Seaver <tseaver@palladion.com> | 2019-07-17 13:03:13 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-07-17 13:03:13 -0400 |
commit | 461f2cc138308251fd13be0c40e9de43797f91f3 (patch) | |
tree | c4f3ee3cb30224f5391441cb70ccbb88e900cae2 /tests/unit/test_bidi.py | |
parent | 495e5cb75126d1e37e7c1af5da1421310e6483ee (diff) | |
download | python-api-core-461f2cc138308251fd13be0c40e9de43797f91f3.tar.gz |
Firestore: Add 'should_terminate' predicate for clean BiDi shutdown. (#8650)
Closes #7826.
Diffstat (limited to 'tests/unit/test_bidi.py')
-rw-r--r-- | tests/unit/test_bidi.py | 110 |
1 files changed, 104 insertions, 6 deletions
diff --git a/tests/unit/test_bidi.py b/tests/unit/test_bidi.py index 8e9f262..4d185d3 100644 --- a/tests/unit/test_bidi.py +++ b/tests/unit/test_bidi.py @@ -370,16 +370,65 @@ class CallStub(object): class TestResumableBidiRpc(object): - def test_initial_state(self): - callback = mock.Mock() - callback.return_value = True - bidi_rpc = bidi.ResumableBidiRpc(None, callback) + def test_ctor_defaults(self): + start_rpc = mock.Mock() + should_recover = mock.Mock() + bidi_rpc = bidi.ResumableBidiRpc(start_rpc, should_recover) + + assert bidi_rpc.is_active is False + assert bidi_rpc._finalized is False + assert bidi_rpc._start_rpc is start_rpc + assert bidi_rpc._should_recover is should_recover + assert bidi_rpc._should_terminate is bidi._never_terminate + assert bidi_rpc._initial_request is None + assert bidi_rpc._rpc_metadata is None + assert bidi_rpc._reopen_throttle is None + + def test_ctor_explicit(self): + start_rpc = mock.Mock() + should_recover = mock.Mock() + should_terminate = mock.Mock() + initial_request = mock.Mock() + metadata = {"x-foo": "bar"} + bidi_rpc = bidi.ResumableBidiRpc( + start_rpc, + should_recover, + should_terminate=should_terminate, + initial_request=initial_request, + metadata=metadata, + throttle_reopen=True, + ) assert bidi_rpc.is_active is False + assert bidi_rpc._finalized is False + assert bidi_rpc._should_recover is should_recover + assert bidi_rpc._should_terminate is should_terminate + assert bidi_rpc._initial_request is initial_request + assert bidi_rpc._rpc_metadata == metadata + assert isinstance(bidi_rpc._reopen_throttle, bidi._Throttle) + + def test_done_callbacks_terminate(self): + cancellation = mock.Mock() + start_rpc = mock.Mock() + should_recover = mock.Mock(spec=["__call__"], return_value=True) + should_terminate = mock.Mock(spec=["__call__"], return_value=True) + bidi_rpc = bidi.ResumableBidiRpc( + start_rpc, should_recover, should_terminate=should_terminate + ) + callback = mock.Mock(spec=["__call__"]) + + bidi_rpc.add_done_callback(callback) + bidi_rpc._on_call_done(cancellation) + + should_terminate.assert_called_once_with(cancellation) + should_recover.assert_not_called() + callback.assert_called_once_with(cancellation) + assert not bidi_rpc.is_active def test_done_callbacks_recoverable(self): start_rpc = mock.create_autospec(grpc.StreamStreamMultiCallable, instance=True) - bidi_rpc = bidi.ResumableBidiRpc(start_rpc, lambda _: True) + should_recover = mock.Mock(spec=["__call__"], return_value=True) + bidi_rpc = bidi.ResumableBidiRpc(start_rpc, should_recover) callback = mock.Mock(spec=["__call__"]) bidi_rpc.add_done_callback(callback) @@ -387,16 +436,45 @@ class TestResumableBidiRpc(object): callback.assert_not_called() start_rpc.assert_called_once() + should_recover.assert_called_once_with(mock.sentinel.future) assert bidi_rpc.is_active def test_done_callbacks_non_recoverable(self): - bidi_rpc = bidi.ResumableBidiRpc(None, lambda _: False) + start_rpc = mock.create_autospec(grpc.StreamStreamMultiCallable, instance=True) + should_recover = mock.Mock(spec=["__call__"], return_value=False) + bidi_rpc = bidi.ResumableBidiRpc(start_rpc, should_recover) callback = mock.Mock(spec=["__call__"]) bidi_rpc.add_done_callback(callback) bidi_rpc._on_call_done(mock.sentinel.future) callback.assert_called_once_with(mock.sentinel.future) + should_recover.assert_called_once_with(mock.sentinel.future) + assert not bidi_rpc.is_active + + def test_send_terminate(self): + cancellation = ValueError() + call_1 = CallStub([cancellation], active=False) + call_2 = CallStub([]) + start_rpc = mock.create_autospec( + grpc.StreamStreamMultiCallable, instance=True, side_effect=[call_1, call_2] + ) + should_recover = mock.Mock(spec=["__call__"], return_value=False) + should_terminate = mock.Mock(spec=["__call__"], return_value=True) + bidi_rpc = bidi.ResumableBidiRpc(start_rpc, should_recover, should_terminate=should_terminate) + + bidi_rpc.open() + + bidi_rpc.send(mock.sentinel.request) + + assert bidi_rpc.pending_requests == 1 + assert bidi_rpc._request_queue.get() is None + + should_recover.assert_not_called() + should_terminate.assert_called_once_with(cancellation) + assert bidi_rpc.call == call_1 + assert bidi_rpc.is_active is False + assert call_1.cancelled is True def test_send_recover(self): error = ValueError() @@ -441,6 +519,26 @@ class TestResumableBidiRpc(object): assert bidi_rpc.pending_requests == 1 assert bidi_rpc._request_queue.get() is None + def test_recv_terminate(self): + cancellation = ValueError() + call = CallStub([cancellation]) + start_rpc = mock.create_autospec( + grpc.StreamStreamMultiCallable, instance=True, return_value=call + ) + should_recover = mock.Mock(spec=["__call__"], return_value=False) + should_terminate = mock.Mock(spec=["__call__"], return_value=True) + bidi_rpc = bidi.ResumableBidiRpc(start_rpc, should_recover, should_terminate=should_terminate) + + bidi_rpc.open() + + bidi_rpc.recv() + + should_recover.assert_not_called() + should_terminate.assert_called_once_with(cancellation) + assert bidi_rpc.call == call + assert bidi_rpc.is_active is False + assert call.cancelled is True + def test_recv_recover(self): error = ValueError() call_1 = CallStub([1, error]) |