1212# See the License for the specific language governing permissions and
1313# limitations under the License.
1414
15- import time
16-
1715import unittest
1816
1917from gcloud import _helpers
2018from gcloud .environment_vars import TESTS_PROJECT
2119from gcloud import logging
2220
21+ from retry import RetryErrors
22+ from retry import RetryResult
2323from system_test_utils import unique_resource_id
2424
2525
3333TOPIC_NAME = 'gcloud-python-system-testing%s' % (_RESOURCE_ID ,)
3434
3535
36- def _retry_backoff (result_predicate , meth , * args , ** kw ):
36+ def _retry_on_unavailable (exc ):
37+ """Retry only AbortionErrors whose status code is 'UNAVAILABLE'."""
3738 from grpc .beta .interfaces import StatusCode
38- from grpc .framework .interfaces .face .face import AbortionError
39- backoff_intervals = [1 , 2 , 4 , 8 ]
40- while True :
41- try :
42- result = meth (* args , ** kw )
43- except AbortionError as error :
44- if error .code != StatusCode .UNAVAILABLE :
45- raise
46- if backoff_intervals :
47- time .sleep (backoff_intervals .pop (0 ))
48- continue
49- else :
50- raise
51- if result_predicate (result ):
52- return result
53- if backoff_intervals :
54- time .sleep (backoff_intervals .pop (0 ))
55- else :
56- raise RuntimeError ('%s: %s %s' % (meth , args , kw ))
39+ return exc .code == StatusCode .UNAVAILABLE
5740
5841
5942def _has_entries (result ):
@@ -81,28 +64,26 @@ def setUp(self):
8164
8265 def tearDown (self ):
8366 from gcloud .exceptions import NotFound
67+ retry = RetryErrors (NotFound )
8468 for doomed in self .to_delete :
85- backoff_intervals = [1 , 2 , 4 , 8 ]
86- while True :
87- try :
88- doomed .delete ()
89- break
90- except NotFound :
91- if backoff_intervals :
92- time .sleep (backoff_intervals .pop (0 ))
93- else :
94- raise
69+ retry (doomed .delete )()
9570
9671 @staticmethod
9772 def _logger_name ():
9873 return 'system-tests-logger' + unique_resource_id ('-' )
9974
75+ def _list_entries (self , logger ):
76+ from grpc .framework .interfaces .face .face import AbortionError
77+ inner = RetryResult (_has_entries )(logger .list_entries )
78+ outer = RetryErrors (AbortionError , _retry_on_unavailable )(inner )
79+ return outer ()
80+
10081 def test_log_text (self ):
10182 TEXT_PAYLOAD = 'System test: test_log_text'
10283 logger = Config .CLIENT .logger (self ._logger_name ())
10384 self .to_delete .append (logger )
10485 logger .log_text (TEXT_PAYLOAD )
105- entries , _ = _retry_backoff ( _has_entries , logger . list_entries )
86+ entries , _ = self . _list_entries ( logger )
10687 self .assertEqual (len (entries ), 1 )
10788 self .assertEqual (entries [0 ].payload , TEXT_PAYLOAD )
10889
@@ -123,7 +104,7 @@ def test_log_text_w_metadata(self):
123104
124105 logger .log_text (TEXT_PAYLOAD , insert_id = INSERT_ID , severity = SEVERITY ,
125106 http_request = REQUEST )
126- entries , _ = _retry_backoff ( _has_entries , logger . list_entries )
107+ entries , _ = self . _list_entries ( logger )
127108
128109 self .assertEqual (len (entries ), 1 )
129110
@@ -146,7 +127,7 @@ def test_log_struct(self):
146127 self .to_delete .append (logger )
147128
148129 logger .log_struct (JSON_PAYLOAD )
149- entries , _ = _retry_backoff ( _has_entries , logger . list_entries )
130+ entries , _ = self . _list_entries ( logger )
150131
151132 self .assertEqual (len (entries ), 1 )
152133 self .assertEqual (entries [0 ].payload , JSON_PAYLOAD )
@@ -171,7 +152,7 @@ def test_log_struct_w_metadata(self):
171152
172153 logger .log_struct (JSON_PAYLOAD , insert_id = INSERT_ID , severity = SEVERITY ,
173154 http_request = REQUEST )
174- entries , _ = _retry_backoff ( _has_entries , logger . list_entries )
155+ entries , _ = self . _list_entries ( logger )
175156
176157 self .assertEqual (len (entries ), 1 )
177158 self .assertEqual (entries [0 ].payload , JSON_PAYLOAD )
@@ -205,10 +186,12 @@ def test_list_metrics(self):
205186 set ([DEFAULT_METRIC_NAME ]))
206187
207188 def test_reload_metric (self ):
189+ from gcloud .exceptions import Conflict
190+ retry = RetryErrors (Conflict )
208191 metric = Config .CLIENT .metric (
209192 DEFAULT_METRIC_NAME , DEFAULT_FILTER , DEFAULT_DESCRIPTION )
210193 self .assertFalse (metric .exists ())
211- metric .create ()
194+ retry ( metric .create ) ()
212195 self .to_delete .append (metric )
213196 metric .filter_ = 'logName:other'
214197 metric .description = 'local changes'
@@ -217,12 +200,14 @@ def test_reload_metric(self):
217200 self .assertEqual (metric .description , DEFAULT_DESCRIPTION )
218201
219202 def test_update_metric (self ):
203+ from gcloud .exceptions import Conflict
204+ retry = RetryErrors (Conflict )
220205 NEW_FILTER = 'logName:other'
221206 NEW_DESCRIPTION = 'updated'
222207 metric = Config .CLIENT .metric (
223208 DEFAULT_METRIC_NAME , DEFAULT_FILTER , DEFAULT_DESCRIPTION )
224209 self .assertFalse (metric .exists ())
225- metric .create ()
210+ retry ( metric .create ) ()
226211 self .to_delete .append (metric )
227212 metric .filter_ = NEW_FILTER
228213 metric .description = NEW_DESCRIPTION
@@ -324,10 +309,12 @@ def test_list_sinks(self):
324309 set ([DEFAULT_SINK_NAME ]))
325310
326311 def test_reload_sink (self ):
312+ from gcloud .exceptions import Conflict
313+ retry = RetryErrors (Conflict )
327314 uri = self ._init_bigquery_dataset ()
328315 sink = Config .CLIENT .sink (DEFAULT_SINK_NAME , DEFAULT_FILTER , uri )
329316 self .assertFalse (sink .exists ())
330- sink .create ()
317+ retry ( sink .create ) ()
331318 self .to_delete .append (sink )
332319 sink .filter_ = 'BOGUS FILTER'
333320 sink .destination = 'BOGUS DESTINATION'
@@ -336,13 +323,15 @@ def test_reload_sink(self):
336323 self .assertEqual (sink .destination , uri )
337324
338325 def test_update_sink (self ):
326+ from gcloud .exceptions import Conflict
327+ retry = RetryErrors (Conflict )
339328 bucket_uri = self ._init_storage_bucket ()
340329 dataset_uri = self ._init_bigquery_dataset ()
341330 UPDATED_FILTER = 'logName:syslog'
342331 sink = Config .CLIENT .sink (
343332 DEFAULT_SINK_NAME , DEFAULT_FILTER , bucket_uri )
344333 self .assertFalse (sink .exists ())
345- sink .create ()
334+ retry ( sink .create ) ()
346335 self .to_delete .append (sink )
347336 sink .filter_ = UPDATED_FILTER
348337 sink .destination = dataset_uri
0 commit comments