diff options
author | 2018-04-19 14:58:38 +0100 | |
---|---|---|
committer | 2018-06-22 17:38:15 +0000 | |
commit | 745db76a4cc99a1597a3570ecdc063d549839a15 (patch) | |
tree | 2cf4cc77089632d9b6e9e2fdd65bea293f30a891 /yardstick/common | |
parent | 2c77f9d9559b09299f8ef5cc3d07c847c685d79c (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>
(cherry picked from 099108aab37d1fae1b27f4e2e20136c234df1a52)
Diffstat (limited to 'yardstick/common')
-rw-r--r-- | yardstick/common/exceptions.py | 8 | ||||
-rw-r--r-- | yardstick/common/utils.py | 34 |
2 files changed, 41 insertions, 1 deletions
diff --git a/yardstick/common/exceptions.py b/yardstick/common/exceptions.py index c78fecc2c..ad246e046 100644 --- a/yardstick/common/exceptions.py +++ b/yardstick/common/exceptions.py @@ -166,6 +166,14 @@ class TaskRenderError(YardstickException): message = 'Failed to render template:\n%(input_task)s' +class TimerTimeout(YardstickException): + message = 'Timer timeout expired, %(timeout)s seconds' + + +class WaitTimeout(YardstickException): + message = 'Wait timeout while waiting for condition' + + class ScenarioCreateNetworkError(YardstickException): message = 'Create Neutron Network Scenario failed' diff --git a/yardstick/common/utils.py b/yardstick/common/utils.py index 864e6258e..869db469b 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) @@ -418,15 +422,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): @@ -473,3 +486,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 |