def test_callable_retry_timeout(self): from google.api_core.retry import Retry from google.cloud.bigtable._generated.bigtable_pb2 import ( MutateRowsResponse) from google.cloud.bigtable.row import DirectRow from google.cloud.bigtable.table import DEFAULT_RETRY from google.rpc.status_pb2 import Status # Setup: # - Mutate 2 rows. # Action: # - Initial attempt will mutate all 2 rows. # Expectation: # - Both rows always return retryable errors. # - google.api_core.Retry should keep retrying. # - Check MutateRows is called multiple times. # - By the time deadline is reached, statuses should be # [retryable, retryable] client = _Client() instance = _Instance(self.INSTANCE_NAME, client=client) table = self._make_table(self.TABLE_ID, instance) row_1 = DirectRow(row_key=b'row_key', table=table) row_1.set_cell('cf', b'col', b'value1') row_2 = DirectRow(row_key=b'row_key_2', table=table) row_2.set_cell('cf', b'col', b'value2') response = MutateRowsResponse(entries=[ MutateRowsResponse.Entry( index=0, status=Status(code=4), ), MutateRowsResponse.Entry( index=1, status=Status(code=4), ), ], ) # Patch the stub used by the API method. client._data_stub = mock.MagicMock() client._data_stub.MutateRows.return_value = [response] retry = DEFAULT_RETRY.with_delay(initial=0.1, maximum=0.2, multiplier=2.0).with_deadline(0.5) worker = self._make_worker(client, table.name, [row_1, row_2]) statuses = worker(retry=retry) result = [status.code for status in statuses] expected_result = [4, 4] self.assertTrue(client._data_stub.MutateRows.call_count > 1) self.assertEqual(result, expected_result)
def test_callable_retry(self): from google.cloud.bigtable.row import DirectRow from google.cloud.bigtable.table import DEFAULT_RETRY # Setup: # - Mutate 3 rows. # Action: # - Initial attempt will mutate all 3 rows. # Expectation: # - First attempt will result in one retryable error. # - Second attempt will result in success for the retry-ed row. # - Check MutateRows is called twice. # - State of responses_statuses should be # [success, success, non-retryable] client = _Client() instance = _Instance(self.INSTANCE_NAME, client=client) table = self._make_table(self.TABLE_ID, instance) row_1 = DirectRow(row_key=b'row_key', table=table) row_1.set_cell('cf', b'col', b'value1') row_2 = DirectRow(row_key=b'row_key_2', table=table) row_2.set_cell('cf', b'col', b'value2') row_3 = DirectRow(row_key=b'row_key_3', table=table) row_3.set_cell('cf', b'col', b'value3') response_1 = self._make_responses([ self.SUCCESS, self.RETRYABLE_1, self.NON_RETRYABLE]) response_2 = self._make_responses([self.SUCCESS]) # Patch the stub used by the API method. client._data_stub = mock.MagicMock() client._data_stub.MutateRows.side_effect = [[response_1], [response_2]] retry = DEFAULT_RETRY.with_delay(initial=0.1) worker = self._make_worker(client, table.name, [row_1, row_2, row_3]) statuses = worker(retry=retry) result = [status.code for status in statuses] expected_result = [self.SUCCESS, self.SUCCESS, self.NON_RETRYABLE] client._data_stub.MutateRows.assert_has_calls([ mock.call(mock.ANY), mock.call(mock.ANY)]) self.assertEqual(client._data_stub.MutateRows.call_count, 2) self.assertEqual(result, expected_result)
def test_callable_retry(self): from google.cloud.bigtable.row import DirectRow from google.cloud.bigtable.table import DEFAULT_RETRY # Setup: # - Mutate 3 rows. # Action: # - Initial attempt will mutate all 3 rows. # Expectation: # - First attempt will result in one retryable error. # - Second attempt will result in success for the retry-ed row. # - Check MutateRows is called twice. # - State of responses_statuses should be # [success, success, non-retryable] channel = self._make_channel() client = self._make_client(project='project-id', channel=channel, admin=True) instance = client.instance(instance_id=self.INSTANCE_ID) table = self._make_table(self.TABLE_ID, instance) row_1 = DirectRow(row_key=b'row_key', table=table) row_1.set_cell('cf', b'col', b'value1') row_2 = DirectRow(row_key=b'row_key_2', table=table) row_2.set_cell('cf', b'col', b'value2') row_3 = DirectRow(row_key=b'row_key_3', table=table) row_3.set_cell('cf', b'col', b'value3') response_1 = self._make_responses([ self.SUCCESS, self.RETRYABLE_1, self.NON_RETRYABLE]) response_2 = self._make_responses([self.SUCCESS]) # Patch the stub used by the API method. client._table_data_client.bigtable_stub.MutateRows.side_effect = [ [response_1], [response_2]] retry = DEFAULT_RETRY.with_delay(initial=0.1) worker = self._make_worker(client, table.name, [row_1, row_2, row_3]) statuses = worker(retry=retry) result = [status.code for status in statuses] expected_result = [self.SUCCESS, self.SUCCESS, self.NON_RETRYABLE] self.assertEqual( client._table_data_client.bigtable_stub.MutateRows.call_count, 2) self.assertEqual(result, expected_result)
def test_callable_retry_timeout(self): from google.cloud.bigtable.row import DirectRow from google.cloud.bigtable.table import DEFAULT_RETRY # Setup: # - Mutate 2 rows. # Action: # - Initial attempt will mutate all 2 rows. # Expectation: # - Both rows always return retryable errors. # - google.api_core.Retry should keep retrying. # - Check MutateRows is called multiple times. # - By the time deadline is reached, statuses should be # [retryable, retryable] channel = self._make_channel() client = self._make_client(project='project-id', channel=channel, admin=True) instance = client.instance(instance_id=self.INSTANCE_ID) table = self._make_table(self.TABLE_ID, instance) row_1 = DirectRow(row_key=b'row_key', table=table) row_1.set_cell('cf', b'col', b'value1') row_2 = DirectRow(row_key=b'row_key_2', table=table) row_2.set_cell('cf', b'col', b'value2') response = self._make_responses([self.RETRYABLE_1, self.RETRYABLE_1]) # Patch the stub used by the API method. bigtable_stub = client._table_data_client.bigtable_stub bigtable_stub.MutateRows.return_value = [response] retry = DEFAULT_RETRY.with_delay( initial=0.1, maximum=0.2, multiplier=2.0).with_deadline(0.5) worker = self._make_worker(client, table.name, [row_1, row_2]) statuses = worker(retry=retry) result = [status.code for status in statuses] expected_result = [self.RETRYABLE_1, self.RETRYABLE_1] self.assertTrue( client._table_data_client.bigtable_stub.MutateRows.call_count > 1) self.assertEqual(result, expected_result)
def test_callable_retry_timeout(self): from google.cloud.bigtable.row import DirectRow from google.cloud.bigtable.table import DEFAULT_RETRY # Setup: # - Mutate 2 rows. # Action: # - Initial attempt will mutate all 2 rows. # Expectation: # - Both rows always return retryable errors. # - google.api_core.Retry should keep retrying. # - Check MutateRows is called multiple times. # - By the time deadline is reached, statuses should be # [retryable, retryable] client = _Client() instance = _Instance(self.INSTANCE_NAME, client=client) table = self._make_table(self.TABLE_ID, instance) row_1 = DirectRow(row_key=b'row_key', table=table) row_1.set_cell('cf', b'col', b'value1') row_2 = DirectRow(row_key=b'row_key_2', table=table) row_2.set_cell('cf', b'col', b'value2') response = self._make_responses([self.RETRYABLE_1, self.RETRYABLE_1]) # Patch the stub used by the API method. client._data_stub = mock.MagicMock() client._data_stub.MutateRows.return_value = [response] retry = DEFAULT_RETRY.with_delay( initial=0.1, maximum=0.2, multiplier=2.0).with_deadline(0.5) worker = self._make_worker(client, table.name, [row_1, row_2]) statuses = worker(retry=retry) result = [status.code for status in statuses] expected_result = [self.RETRYABLE_1, self.RETRYABLE_1] self.assertTrue(client._data_stub.MutateRows.call_count > 1) self.assertEqual(result, expected_result)
def test_callable_retry(self): from google.api_core.retry import Retry from google.cloud.bigtable._generated.bigtable_pb2 import ( MutateRowsResponse) from google.cloud.bigtable.row import DirectRow from google.cloud.bigtable.table import DEFAULT_RETRY from google.rpc.status_pb2 import Status # Setup: # - Mutate 3 rows. # Action: # - Initial attempt will mutate all 3 rows. # Expectation: # - First attempt will result in one retryable error. # - Second attempt will result in success for the retry-ed row. # - Check MutateRows is called twice. # - State of responses_statuses should be # [success, success, non-retryable] client = _Client() instance = _Instance(self.INSTANCE_NAME, client=client) table = self._make_table(self.TABLE_ID, instance) row_1 = DirectRow(row_key=b'row_key', table=table) row_1.set_cell('cf', b'col', b'value1') row_2 = DirectRow(row_key=b'row_key_2', table=table) row_2.set_cell('cf', b'col', b'value2') row_3 = DirectRow(row_key=b'row_key_3', table=table) row_3.set_cell('cf', b'col', b'value3') response_1 = MutateRowsResponse(entries=[ MutateRowsResponse.Entry( index=0, status=Status(code=0), ), MutateRowsResponse.Entry( index=1, status=Status(code=4), ), MutateRowsResponse.Entry( index=2, status=Status(code=1), ), ], ) response_2 = MutateRowsResponse(entries=[ MutateRowsResponse.Entry( index=0, status=Status(code=0), ), ], ) # Patch the stub used by the API method. client._data_stub = mock.MagicMock() client._data_stub.MutateRows.side_effect = [[response_1], [response_2]] retry = DEFAULT_RETRY.with_delay(initial=0.1) worker = self._make_worker(client, table.name, [row_1, row_2, row_3]) statuses = worker(retry=retry) result = [status.code for status in statuses] expected_result = [0, 0, 1] client._data_stub.MutateRows.assert_has_calls( [mock.call(mock.ANY), mock.call(mock.ANY)]) self.assertEqual(client._data_stub.MutateRows.call_count, 2) self.assertEqual(result, expected_result)