Chromium Code Reviews| Index: build/android/pylib/device/decorators.py |
| diff --git a/build/android/pylib/device/decorators.py b/build/android/pylib/device/decorators.py |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..180e8f76c5518fe22f585563c4894513cf89b260 |
| --- /dev/null |
| +++ b/build/android/pylib/device/decorators.py |
| @@ -0,0 +1,70 @@ |
| +# Copyright 2014 The Chromium Authors. All rights reserved. |
| +# Use of this source code is governed by a BSD-style license that can be |
| +# found in the LICENSE file. |
| + |
| +""" |
| +Function/method decorators that provide timeout and retry logic. |
| +""" |
| + |
| +import functools |
| + |
| +from pylib.device import device_errors |
| +from pylib.utils import reraiser_thread |
| +from pylib.utils import timeout_retry |
| + |
| + |
| +def WithTimeoutAndRetries(f): |
| + """ A decorator that handles timeouts and retries. |
|
frankf
2014/05/13 18:16:31
fit everything on 1 line
|
| + """ |
| + @functools.wraps(f) |
| + def TimeoutRetryWrapper(*args, **kwargs): |
| + # handle retries and timeouts |
| + timeout = kwargs.get('timeout') |
| + retries = kwargs.get('retries') |
| + |
| + # Check for exactly None s.t. zero values are valid. |
| + if timeout is None: |
| + raise TypeError("%s requires a 'timeout' parameter" % f.__name__) |
| + if retries is None: |
| + raise TypeError("%s requires a 'retries' parameter" % f.__name__) |
| + |
| + def impl(): |
| + return f(*args, **kwargs) |
| + try: |
| + return timeout_retry.Run(impl, timeout, retries) |
| + except reraiser_thread.TimeoutError as e: |
| + raise device_errors.CommandTimeoutError(str(e)) |
| + return TimeoutRetryWrapper |
| + |
| + |
| +def WithTimeoutAndRetriesDefaults(default_timeout, default_retries): |
| + """ A decorator that handles timeouts and retries using the provided |
| + default timeout and retry values if they aren't specified as a kwarg. |
| + """ |
| + def decorator(f): |
| + @functools.wraps(f) |
| + def TimeoutRetryWrapper(*args, **kwargs): |
| + kwargs['timeout'] = kwargs.get('timeout', default_timeout) |
| + kwargs['retries'] = kwargs.get('retries', default_retries) |
| + return WithTimeoutAndRetries(f)(*args, **kwargs) |
| + return TimeoutRetryWrapper |
| + return decorator |
| + |
| + |
| +def WithTimeoutAndRetriesFromInstance( |
| + default_timeout_name, default_retries_name): |
| + """ Returns a decorator that handles timeouts and retries using default |
|
frankf
2014/05/13 18:16:31
first sentence should fit on a line.
|
| + timeout and retry values from the object if they aren't specified as a |
| + kwarg. |
| + """ |
| + def decorator(f): |
| + @functools.wraps(f) |
| + def TimeoutRetryWrapper(device, *args, **kwargs): |
| + kwargs['timeout'] = kwargs.get( |
| + 'timeout', getattr(device, default_timeout_name)) |
| + kwargs['retries'] = kwargs.get( |
| + 'retries', getattr(device, default_retries_name)) |
| + return WithTimeoutAndRetries(f)(device, *args, **kwargs) |
| + return TimeoutRetryWrapper |
| + return decorator |
| + |