|
12 | 12 | # See the License for the specific language governing permissions and |
13 | 13 | # limitations under the License. |
14 | 14 |
|
| 15 | +import mock |
15 | 16 | import pytest |
16 | | -import aiounittest |
17 | 17 |
|
18 | | -import mock |
19 | 18 | from tests.unit.v1.test__helpers import AsyncMock |
20 | 19 |
|
21 | 20 |
|
22 | | -class TestAsyncWriteBatch(aiounittest.AsyncTestCase): |
23 | | - """Tests the AsyncWriteBatch.commit method""" |
24 | | - |
25 | | - @staticmethod |
26 | | - def _get_target_class(): |
27 | | - from google.cloud.firestore_v1.async_batch import AsyncWriteBatch |
28 | | - |
29 | | - return AsyncWriteBatch |
30 | | - |
31 | | - def _make_one(self, *args, **kwargs): |
32 | | - klass = self._get_target_class() |
33 | | - return klass(*args, **kwargs) |
34 | | - |
35 | | - def test_constructor(self): |
36 | | - batch = self._make_one(mock.sentinel.client) |
37 | | - self.assertIs(batch._client, mock.sentinel.client) |
38 | | - self.assertEqual(batch._write_pbs, []) |
39 | | - self.assertIsNone(batch.write_results) |
40 | | - self.assertIsNone(batch.commit_time) |
41 | | - |
42 | | - async def _commit_helper(self, retry=None, timeout=None): |
43 | | - from google.protobuf import timestamp_pb2 |
44 | | - from google.cloud.firestore_v1 import _helpers |
45 | | - from google.cloud.firestore_v1.types import firestore |
46 | | - from google.cloud.firestore_v1.types import write |
47 | | - |
48 | | - # Create a minimal fake GAPIC with a dummy result. |
49 | | - firestore_api = AsyncMock(spec=["commit"]) |
50 | | - timestamp = timestamp_pb2.Timestamp(seconds=1234567, nanos=123456798) |
51 | | - commit_response = firestore.CommitResponse( |
52 | | - write_results=[write.WriteResult(), write.WriteResult()], |
53 | | - commit_time=timestamp, |
54 | | - ) |
55 | | - firestore_api.commit.return_value = commit_response |
56 | | - kwargs = _helpers.make_retry_timeout_kwargs(retry, timeout) |
57 | | - |
58 | | - # Attach the fake GAPIC to a real client. |
59 | | - client = _make_client("grand") |
60 | | - client._firestore_api_internal = firestore_api |
61 | | - |
62 | | - # Actually make a batch with some mutations and call commit(). |
63 | | - batch = self._make_one(client) |
64 | | - document1 = client.document("a", "b") |
65 | | - batch.create(document1, {"ten": 10, "buck": "ets"}) |
66 | | - document2 = client.document("c", "d", "e", "f") |
67 | | - batch.delete(document2) |
| 21 | +def _make_async_write_batch(client): |
| 22 | + from google.cloud.firestore_v1.async_batch import AsyncWriteBatch |
| 23 | + |
| 24 | + return AsyncWriteBatch(client) |
| 25 | + |
| 26 | + |
| 27 | +def test_constructor(): |
| 28 | + batch = _make_async_write_batch(mock.sentinel.client) |
| 29 | + assert batch._client is mock.sentinel.client |
| 30 | + assert batch._write_pbs == [] |
| 31 | + assert batch.write_results is None |
| 32 | + assert batch.commit_time is None |
| 33 | + |
| 34 | + |
| 35 | +async def _commit_helper(retry=None, timeout=None): |
| 36 | + from google.protobuf import timestamp_pb2 |
| 37 | + from google.cloud.firestore_v1 import _helpers |
| 38 | + from google.cloud.firestore_v1.types import firestore |
| 39 | + from google.cloud.firestore_v1.types import write |
| 40 | + |
| 41 | + # Create a minimal fake GAPIC with a dummy result. |
| 42 | + firestore_api = AsyncMock(spec=["commit"]) |
| 43 | + timestamp = timestamp_pb2.Timestamp(seconds=1234567, nanos=123456798) |
| 44 | + commit_response = firestore.CommitResponse( |
| 45 | + write_results=[write.WriteResult(), write.WriteResult()], commit_time=timestamp, |
| 46 | + ) |
| 47 | + firestore_api.commit.return_value = commit_response |
| 48 | + kwargs = _helpers.make_retry_timeout_kwargs(retry, timeout) |
| 49 | + |
| 50 | + # Attach the fake GAPIC to a real client. |
| 51 | + client = _make_client("grand") |
| 52 | + client._firestore_api_internal = firestore_api |
| 53 | + |
| 54 | + # Actually make a batch with some mutations and call commit(). |
| 55 | + batch = _make_async_write_batch(client) |
| 56 | + document1 = client.document("a", "b") |
| 57 | + batch.create(document1, {"ten": 10, "buck": "ets"}) |
| 58 | + document2 = client.document("c", "d", "e", "f") |
| 59 | + batch.delete(document2) |
| 60 | + write_pbs = batch._write_pbs[::] |
| 61 | + |
| 62 | + write_results = await batch.commit(**kwargs) |
| 63 | + |
| 64 | + assert write_results == list(commit_response.write_results) |
| 65 | + assert batch.write_results == write_results |
| 66 | + assert batch.commit_time.timestamp_pb() == timestamp |
| 67 | + # Make sure batch has no more "changes". |
| 68 | + assert batch._write_pbs == [] |
| 69 | + |
| 70 | + # Verify the mocks. |
| 71 | + firestore_api.commit.assert_called_once_with( |
| 72 | + request={ |
| 73 | + "database": client._database_string, |
| 74 | + "writes": write_pbs, |
| 75 | + "transaction": None, |
| 76 | + }, |
| 77 | + metadata=client._rpc_metadata, |
| 78 | + **kwargs, |
| 79 | + ) |
| 80 | + |
| 81 | + |
| 82 | +@pytest.mark.asyncio |
| 83 | +async def test_commit(): |
| 84 | + await _commit_helper() |
| 85 | + |
| 86 | + |
| 87 | +@pytest.mark.asyncio |
| 88 | +async def test_commit_w_retry_timeout(): |
| 89 | + from google.api_core.retry import Retry |
| 90 | + |
| 91 | + retry = Retry(predicate=object()) |
| 92 | + timeout = 123.0 |
| 93 | + |
| 94 | + await _commit_helper(retry=retry, timeout=timeout) |
| 95 | + |
| 96 | + |
| 97 | +@pytest.mark.asyncio |
| 98 | +async def test_as_context_mgr_wo_error(): |
| 99 | + from google.protobuf import timestamp_pb2 |
| 100 | + from google.cloud.firestore_v1.types import firestore |
| 101 | + from google.cloud.firestore_v1.types import write |
| 102 | + |
| 103 | + firestore_api = AsyncMock(spec=["commit"]) |
| 104 | + timestamp = timestamp_pb2.Timestamp(seconds=1234567, nanos=123456798) |
| 105 | + commit_response = firestore.CommitResponse( |
| 106 | + write_results=[write.WriteResult(), write.WriteResult()], commit_time=timestamp, |
| 107 | + ) |
| 108 | + firestore_api.commit.return_value = commit_response |
| 109 | + client = _make_client() |
| 110 | + client._firestore_api_internal = firestore_api |
| 111 | + batch = _make_async_write_batch(client) |
| 112 | + document1 = client.document("a", "b") |
| 113 | + document2 = client.document("c", "d", "e", "f") |
| 114 | + |
| 115 | + async with batch as ctx_mgr: |
| 116 | + assert ctx_mgr is batch |
| 117 | + ctx_mgr.create(document1, {"ten": 10, "buck": "ets"}) |
| 118 | + ctx_mgr.delete(document2) |
68 | 119 | write_pbs = batch._write_pbs[::] |
69 | 120 |
|
70 | | - write_results = await batch.commit(**kwargs) |
71 | | - |
72 | | - self.assertEqual(write_results, list(commit_response.write_results)) |
73 | | - self.assertEqual(batch.write_results, write_results) |
74 | | - self.assertEqual(batch.commit_time.timestamp_pb(), timestamp) |
75 | | - # Make sure batch has no more "changes". |
76 | | - self.assertEqual(batch._write_pbs, []) |
77 | | - |
78 | | - # Verify the mocks. |
79 | | - firestore_api.commit.assert_called_once_with( |
80 | | - request={ |
81 | | - "database": client._database_string, |
82 | | - "writes": write_pbs, |
83 | | - "transaction": None, |
84 | | - }, |
85 | | - metadata=client._rpc_metadata, |
86 | | - **kwargs, |
87 | | - ) |
88 | | - |
89 | | - @pytest.mark.asyncio |
90 | | - async def test_commit(self): |
91 | | - await self._commit_helper() |
92 | | - |
93 | | - @pytest.mark.asyncio |
94 | | - async def test_commit_w_retry_timeout(self): |
95 | | - from google.api_core.retry import Retry |
96 | | - |
97 | | - retry = Retry(predicate=object()) |
98 | | - timeout = 123.0 |
99 | | - |
100 | | - await self._commit_helper(retry=retry, timeout=timeout) |
101 | | - |
102 | | - @pytest.mark.asyncio |
103 | | - async def test_as_context_mgr_wo_error(self): |
104 | | - from google.protobuf import timestamp_pb2 |
105 | | - from google.cloud.firestore_v1.types import firestore |
106 | | - from google.cloud.firestore_v1.types import write |
107 | | - |
108 | | - firestore_api = AsyncMock(spec=["commit"]) |
109 | | - timestamp = timestamp_pb2.Timestamp(seconds=1234567, nanos=123456798) |
110 | | - commit_response = firestore.CommitResponse( |
111 | | - write_results=[write.WriteResult(), write.WriteResult()], |
112 | | - commit_time=timestamp, |
113 | | - ) |
114 | | - firestore_api.commit.return_value = commit_response |
115 | | - client = _make_client() |
116 | | - client._firestore_api_internal = firestore_api |
117 | | - batch = self._make_one(client) |
118 | | - document1 = client.document("a", "b") |
119 | | - document2 = client.document("c", "d", "e", "f") |
120 | | - |
| 121 | + assert batch.write_results == list(commit_response.write_results) |
| 122 | + assert batch.commit_time.timestamp_pb() == timestamp |
| 123 | + # Make sure batch has no more "changes". |
| 124 | + assert batch._write_pbs == [] |
| 125 | + |
| 126 | + # Verify the mocks. |
| 127 | + firestore_api.commit.assert_called_once_with( |
| 128 | + request={ |
| 129 | + "database": client._database_string, |
| 130 | + "writes": write_pbs, |
| 131 | + "transaction": None, |
| 132 | + }, |
| 133 | + metadata=client._rpc_metadata, |
| 134 | + ) |
| 135 | + |
| 136 | + |
| 137 | +@pytest.mark.asyncio |
| 138 | +async def test_as_context_mgr_w_error(): |
| 139 | + firestore_api = AsyncMock(spec=["commit"]) |
| 140 | + client = _make_client() |
| 141 | + client._firestore_api_internal = firestore_api |
| 142 | + batch = _make_async_write_batch(client) |
| 143 | + document1 = client.document("a", "b") |
| 144 | + document2 = client.document("c", "d", "e", "f") |
| 145 | + |
| 146 | + with pytest.raises(RuntimeError): |
121 | 147 | async with batch as ctx_mgr: |
122 | | - self.assertIs(ctx_mgr, batch) |
123 | 148 | ctx_mgr.create(document1, {"ten": 10, "buck": "ets"}) |
124 | 149 | ctx_mgr.delete(document2) |
125 | | - write_pbs = batch._write_pbs[::] |
126 | | - |
127 | | - self.assertEqual(batch.write_results, list(commit_response.write_results)) |
128 | | - self.assertEqual(batch.commit_time.timestamp_pb(), timestamp) |
129 | | - # Make sure batch has no more "changes". |
130 | | - self.assertEqual(batch._write_pbs, []) |
131 | | - |
132 | | - # Verify the mocks. |
133 | | - firestore_api.commit.assert_called_once_with( |
134 | | - request={ |
135 | | - "database": client._database_string, |
136 | | - "writes": write_pbs, |
137 | | - "transaction": None, |
138 | | - }, |
139 | | - metadata=client._rpc_metadata, |
140 | | - ) |
141 | | - |
142 | | - @pytest.mark.asyncio |
143 | | - async def test_as_context_mgr_w_error(self): |
144 | | - firestore_api = AsyncMock(spec=["commit"]) |
145 | | - client = _make_client() |
146 | | - client._firestore_api_internal = firestore_api |
147 | | - batch = self._make_one(client) |
148 | | - document1 = client.document("a", "b") |
149 | | - document2 = client.document("c", "d", "e", "f") |
150 | | - |
151 | | - with self.assertRaises(RuntimeError): |
152 | | - async with batch as ctx_mgr: |
153 | | - ctx_mgr.create(document1, {"ten": 10, "buck": "ets"}) |
154 | | - ctx_mgr.delete(document2) |
155 | | - raise RuntimeError("testing") |
156 | | - |
157 | | - # batch still has its changes, as _aexit_ (and commit) is not invoked |
158 | | - # changes are preserved so commit can be retried |
159 | | - self.assertIsNone(batch.write_results) |
160 | | - self.assertIsNone(batch.commit_time) |
161 | | - self.assertEqual(len(batch._write_pbs), 2) |
162 | | - |
163 | | - firestore_api.commit.assert_not_called() |
| 150 | + raise RuntimeError("testing") |
| 151 | + |
| 152 | + # batch still has its changes, as _aexit_ (and commit) is not invoked |
| 153 | + # changes are preserved so commit can be retried |
| 154 | + assert batch.write_results is None |
| 155 | + assert batch.commit_time is None |
| 156 | + assert len(batch._write_pbs) == 2 |
| 157 | + |
| 158 | + firestore_api.commit.assert_not_called() |
164 | 159 |
|
165 | 160 |
|
166 | 161 | def _make_credentials(): |
|
0 commit comments