diff options
author | Rodolfo Alonso Hernandez <rodolfo.alonso.hernandez@intel.com> | 2018-04-19 14:58:38 +0100 |
---|---|---|
committer | Rodolfo Alonso Hernandez <rodolfo.alonso.hernandez@intel.com> | 2018-04-27 08:25:44 +0000 |
commit | 099108aab37d1fae1b27f4e2e20136c234df1a52 (patch) | |
tree | c030dcb389a894a9902b1c5c62086131fa8470fb /yardstick/common/utils.py | |
parent | b338d3091bb0beb89d4ad9f7c144f43a31a19a74 (diff) |
Add active wait function
Added function "wait_until_true". This function will make an active
wait until the predicate passed as an argument returns True.
If the timeout expires, the function will raise a generic exception
or a user defined one passed as an argument.
This function will be used in YARDSTICK-1127.
JIRA: YARDSTICK-1128
Change-Id: I9854e465ac6b586bf4be39ab4b266d5625b39e30
Signed-off-by: Rodolfo Alonso Hernandez <rodolfo.alonso.hernandez@intel.com>
Diffstat (limited to 'yardstick/common/utils.py')
-rw-r--r-- | yardstick/common/utils.py | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/yardstick/common/utils.py b/yardstick/common/utils.py index 44cc92a7c..108ee17bc 100644 --- a/yardstick/common/utils.py +++ b/yardstick/common/utils.py @@ -23,9 +23,11 @@ import logging import os import random import re +import signal import socket import subprocess import sys +import time import six from flask import jsonify @@ -34,6 +36,8 @@ from oslo_serialization import jsonutils from oslo_utils import encodeutils import yardstick +from yardstick.common import exceptions + logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) @@ -405,15 +409,24 @@ class ErrorClass(object): class Timer(object): - def __init__(self): + def __init__(self, timeout=None): super(Timer, self).__init__() self.start = self.delta = None + self._timeout = int(timeout) if timeout else None + + def _timeout_handler(self, *args): + raise exceptions.TimerTimeout(timeout=self._timeout) def __enter__(self): self.start = datetime.datetime.now() + if self._timeout: + signal.signal(signal.SIGALRM, self._timeout_handler) + signal.alarm(self._timeout) return self def __exit__(self, *_): + if self._timeout: + signal.alarm(0) self.delta = datetime.datetime.now() - self.start def __getattr__(self, item): @@ -460,3 +473,22 @@ def open_relative_file(path, task_path): if e.errno == errno.ENOENT: return open(os.path.join(task_path, path)) raise + + +def wait_until_true(predicate, timeout=60, sleep=1, exception=None): + """Wait until callable predicate is evaluated as True + + :param predicate: (func) callable deciding whether waiting should continue + :param timeout: (int) timeout in seconds how long should function wait + :param sleep: (int) polling interval for results in seconds + :param exception: exception instance to raise on timeout. If None is passed + (default) then WaitTimeout exception is raised. + """ + try: + with Timer(timeout=timeout): + while not predicate(): + time.sleep(sleep) + except exceptions.TimerTimeout: + if exception and issubclass(exception, Exception): + raise exception # pylint: disable=raising-bad-type + raise exceptions.WaitTimeout |