aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--yardstick/common/utils.py25
-rw-r--r--yardstick/tests/unit/common/test_utils.py21
2 files changed, 39 insertions, 7 deletions
diff --git a/yardstick/common/utils.py b/yardstick/common/utils.py
index 83ddbd470..c74dd675e 100644
--- a/yardstick/common/utils.py
+++ b/yardstick/common/utils.py
@@ -28,6 +28,7 @@ import socket
import subprocess
import sys
import time
+import threading
import six
from flask import jsonify
@@ -475,6 +476,9 @@ class Timer(object):
def __del__(self): # pragma: no cover
signal.alarm(0)
+ def delta_time_sec(self):
+ return (datetime.datetime.now() - self.start).total_seconds()
+
def read_meminfo(ssh_client):
"""Read "/proc/meminfo" file and parse all keys and values"""
@@ -521,17 +525,30 @@ def open_relative_file(path, task_path):
def wait_until_true(predicate, timeout=60, sleep=1, exception=None):
"""Wait until callable predicate is evaluated as True
+ When in a thread different from the main one, Timer(timeout) will fail
+ because signal is not handled. In this case
+
: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():
+ if isinstance(threading.current_thread(), threading._MainThread):
+ 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
+ else:
+ with Timer() as timer:
+ while timer.delta_time_sec() < timeout:
+ if predicate():
+ return
time.sleep(sleep)
- except exceptions.TimerTimeout:
if exception and issubclass(exception, Exception):
raise exception # pylint: disable=raising-bad-type
raise exceptions.WaitTimeout
diff --git a/yardstick/tests/unit/common/test_utils.py b/yardstick/tests/unit/common/test_utils.py
index bf0b5181a..7c58a8243 100644
--- a/yardstick/tests/unit/common/test_utils.py
+++ b/yardstick/tests/unit/common/test_utils.py
@@ -12,12 +12,14 @@ import errno
import importlib
import ipaddress
from itertools import product, chain
-import mock
import os
-import six
-from six.moves import configparser
import socket
import time
+import threading
+
+import mock
+import six
+from six.moves import configparser
import unittest
import yardstick
@@ -1277,6 +1279,10 @@ class TimerTestCase(ut_base.BaseUnitTestCase):
time.sleep(1.1)
self.assertEqual(2, len(iterations))
+ def test_delta_time_sec(self):
+ with utils.Timer() as timer:
+ self.assertIsInstance(timer.delta_time_sec(), float)
+
class WaitUntilTrueTestCase(ut_base.BaseUnitTestCase):
@@ -1298,6 +1304,15 @@ class WaitUntilTrueTestCase(ut_base.BaseUnitTestCase):
utils.wait_until_true(lambda: False, timeout=1, sleep=1,
exception=MyTimeoutException))
+ def _run_thread(self):
+ with self.assertRaises(exceptions.WaitTimeout):
+ utils.wait_until_true(lambda: False, timeout=1, sleep=1)
+
+ def test_timeout_no_main_thread(self):
+ new_thread = threading.Thread(target=self._run_thread)
+ new_thread.start()
+ new_thread.join(timeout=3)
+
class SendSocketCommandTestCase(unittest.TestCase):