Repository: googleapis/google-cloud-python

Issue:
Logging system tests:  gRPC/GaxError for 'NotFound' in tearDown / logger.delete
From: https://travis-ci.org/GoogleCloudPlatform/gcloud-python/builds/151551907#L647-L675

``` python
======================================================================
ERROR: test_log_struct_w_metadata (logging_.TestLogging)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/travis/build/GoogleCloudPlatform/gcloud-python/system_tests/logging_.py", line 69, in tearDown
    retry(doomed.delete)()
  File "/home/travis/build/GoogleCloudPlatform/gcloud-python/system_tests/retry.py", line 77, in wrapped_function
    return to_wrap(*args, **kwargs)
  File "/home/travis/build/GoogleCloudPlatform/gcloud-python/.tox/system-tests/lib/python2.7/site-packages/gcloud/logging/logger.py", line 268, in delete
    client.logging_api.logger_delete(self.project, self.name)
  File "/home/travis/build/GoogleCloudPlatform/gcloud-python/.tox/system-tests/lib/python2.7/site-packages/gcloud/logging/_gax.py", line 123, in logger_delete
    self._gax_api.delete_log(path, options)
  File "/home/travis/build/GoogleCloudPlatform/gcloud-python/.tox/system-tests/lib/python2.7/site-packages/google/cloud/logging/v2/logging_service_v2_api.py", line 216, in delete_log
    self._delete_log(request, options)
  File "/home/travis/build/GoogleCloudPlatform/gcloud-python/.tox/system-tests/lib/python2.7/site-packages/google/gax/api_callable.py", line 480, in inner
    return api_caller(api_call, this_settings, request)
  File "/home/travis/build/GoogleCloudPlatform/gcloud-python/.tox/system-tests/lib/python2.7/site-packages/google/gax/api_callable.py", line 468, in base_caller
    return api_call(*args)
  File "/home/travis/build/GoogleCloudPlatform/gcloud-python/.tox/system-tests/lib/python2.7/site-packages/google/gax/api_callable.py", line 433, in inner
    raise_with_traceback(GaxError('RPC failed', cause=exception))
  File "/home/travis/build/GoogleCloudPlatform/gcloud-python/.tox/system-tests/lib/python2.7/site-packages/google/gax/api_callable.py", line 430, in inner
    return a_func(*args, **kwargs)
  File "/home/travis/build/GoogleCloudPlatform/gcloud-python/.tox/system-tests/lib/python2.7/site-packages/google/gax/api_callable.py", line 64, in inner
    return a_func(*updated_args, **kwargs)
  File "/home/travis/build/GoogleCloudPlatform/gcloud-python/.tox/system-tests/lib/python2.7/site-packages/grpc/beta/_client_adaptations.py", line 305, in __call__
    self._request_serializer, self._response_deserializer)
  File "/home/travis/build/GoogleCloudPlatform/gcloud-python/.tox/system-tests/lib/python2.7/site-packages/grpc/beta/_client_adaptations.py", line 203, in _blocking_unary_unary
    raise _abortion_error(rpc_error_call)
GaxError: GaxError(RPC failed, caused by AbortionError(code=StatusCode.NOT_FOUND, details="Requested entity was not found."))
```



Discussion:
@tseaver Looks like `StatusCode.NOT_FOUND` is an eventual consistency error?

We are already retrying for `gcloud.exceptions.NotFound`:  we just need to update our GAX helper to map the gRPC `NotFound` onto that type.


Resolving patch:
diff --git a/gcloud/logging/_gax.py b/gcloud/logging/_gax.py
--- a/gcloud/logging/_gax.py
+++ b/gcloud/logging/_gax.py
@@ -120,7 +120,12 @@ def logger_delete(self, project, logger_name):
         """
         options = None
         path = 'projects/%s/logs/%s' % (project, logger_name)
-        self._gax_api.delete_log(path, options)
+        try:
+            self._gax_api.delete_log(path, options)
+        except GaxError as exc:
+            if exc_to_code(exc.cause) == StatusCode.NOT_FOUND:
+                raise NotFound(path)
+            raise
 
 
 class _SinksAPI(object):


Test patch:
diff --git a/gcloud/logging/test__gax.py b/gcloud/logging/test__gax.py
--- a/gcloud/logging/test__gax.py
+++ b/gcloud/logging/test__gax.py
@@ -406,6 +406,32 @@ def test_logger_delete(self):
         self.assertEqual(log_name, LOG_PATH)
         self.assertEqual(options, None)
 
+    def test_logger_delete_not_found(self):
+        from gcloud.exceptions import NotFound
+        LOG_PATH = 'projects/%s/logs/%s' % (self.PROJECT, self.LOG_NAME)
+        gax_api = _GAXLoggingAPI(_delete_not_found=True)
+        api = self._makeOne(gax_api)
+
+        with self.assertRaises(NotFound):
+            api.logger_delete(self.PROJECT, self.LOG_NAME)
+
+        log_name, options = gax_api._delete_log_called_with
+        self.assertEqual(log_name, LOG_PATH)
+        self.assertEqual(options, None)
+
+    def test_logger_delete_error(self):
+        from google.gax.errors import GaxError
+        LOG_PATH = 'projects/%s/logs/%s' % (self.PROJECT, self.LOG_NAME)
+        gax_api = _GAXLoggingAPI(_random_gax_error=True)
+        api = self._makeOne(gax_api)
+
+        with self.assertRaises(GaxError):
+            api.logger_delete(self.PROJECT, self.LOG_NAME)
+
+        log_name, options = gax_api._delete_log_called_with
+        self.assertEqual(log_name, LOG_PATH)
+        self.assertEqual(options, None)
+
 
 @unittest.skipUnless(_HAVE_GAX, 'No gax-python')
 class Test_SinksAPI(_Base, unittest.TestCase):
@@ -914,6 +940,8 @@ def _make_grpc_failed_precondition(self):
 
 class _GAXLoggingAPI(_GAXBaseAPI):
 
+    _delete_not_found = False
+
     def list_log_entries(
             self, projects, filter_, order_by, page_size, options):
         self._list_log_entries_called_with = (
@@ -926,7 +954,12 @@ def write_log_entries(self, entries, log_name, resource, labels,
             entries, log_name, resource, labels, partial_success, options)
 
     def delete_log(self, log_name, options):
+        from google.gax.errors import GaxError
         self._delete_log_called_with = log_name, options
+        if self._random_gax_error:
+            raise GaxError('error')
+        if self._delete_not_found:
+            raise GaxError('notfound', self._make_grpc_not_found())
 
 
 class _GAXSinksAPI(_GAXBaseAPI):