diff options
author | Jhon Honce <jhonce@redhat.com> | 2018-08-20 08:40:42 -0700 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2018-08-20 21:07:09 +0000 |
commit | 75588a4333aef6a3830cd120136a664418d336e9 (patch) | |
tree | 07f4db5eef955817acb0a9d4a8dae037748c543e /contrib/python/podman | |
parent | 937398abcfa9848b36efd95d845d98d865578c71 (diff) | |
download | podman-75588a4333aef6a3830cd120136a664418d336e9.tar.gz podman-75588a4333aef6a3830cd120136a664418d336e9.tar.bz2 podman-75588a4333aef6a3830cd120136a664418d336e9.zip |
Add retry decorator for flakey tests
* Update doc strings
Signed-off-by: Jhon Honce <jhonce@redhat.com>
Closes: #1302
Approved by: baude
Diffstat (limited to 'contrib/python/podman')
-rw-r--r-- | contrib/python/podman/test/podman_testcase.py | 4 | ||||
-rw-r--r-- | contrib/python/podman/test/retry_decorator.py | 43 | ||||
-rw-r--r-- | contrib/python/podman/test/test_containers.py | 3 |
3 files changed, 50 insertions, 0 deletions
diff --git a/contrib/python/podman/test/podman_testcase.py b/contrib/python/podman/test/podman_testcase.py index 731fa26fc..da73c1024 100644 --- a/contrib/python/podman/test/podman_testcase.py +++ b/contrib/python/podman/test/podman_testcase.py @@ -1,3 +1,4 @@ +"""Base for podman tests.""" import contextlib import functools import itertools @@ -16,6 +17,7 @@ class PodmanTestCase(unittest.TestCase): @classmethod def setUpClass(cls): + """Fixture to setup podman test case.""" if hasattr(PodmanTestCase, 'alpine_process'): PodmanTestCase.tearDownClass() @@ -91,6 +93,7 @@ class PodmanTestCase(unittest.TestCase): @classmethod def tearDownClass(cls): + """Fixture to clean up after podman unittest.""" try: PodmanTestCase.alpine_process.kill() assert 0 == PodmanTestCase.alpine_process.wait(500) @@ -104,5 +107,6 @@ class PodmanTestCase(unittest.TestCase): @contextlib.contextmanager def assertRaisesNotImplemented(self): + """Sugar for unimplemented varlink methods.""" with self.assertRaisesRegex(VarlinkError, MethodNotImplemented): yield diff --git a/contrib/python/podman/test/retry_decorator.py b/contrib/python/podman/test/retry_decorator.py new file mode 100644 index 000000000..31e06f382 --- /dev/null +++ b/contrib/python/podman/test/retry_decorator.py @@ -0,0 +1,43 @@ +"""Decorator to retry failed method.""" +import functools +import time + + +def retry(ExceptionToCheck, tries=4, delay=3, backoff=2, print_=None): + """Retry calling the decorated function using an exponential backoff. + + Specialized for our unittests + from: + http://www.saltycrane.com/blog/2009/11/trying-out-retry-decorator-python/ + original from: http://wiki.python.org/moin/PythonDecoratorLibrary#Retry + + :param ExceptionToCheck: the exception to check. may be a tuple of + exceptions to check + :type ExceptionToCheck: Exception or tuple + :param tries: number of times to try (not retry) before giving up + :type tries: int + :param delay: initial delay between retries in seconds + :type delay: int + :param backoff: backoff multiplier e.g. value of 2 will double the delay + each retry + :type backoff: int + """ + def deco_retry(f): + @functools.wraps(f) + def f_retry(*args, **kwargs): + mtries, mdelay = tries, delay + while mtries > 1: + try: + return f(*args, **kwargs) + except ExceptionToCheck as e: + if print_: + print_('{}, Retrying in {} seconds...'.format( + str(e), mdelay)) + time.sleep(mdelay) + mtries -= 1 + mdelay *= backoff + return f(*args, **kwargs) + + return f_retry # true decorator + + return deco_retry diff --git a/contrib/python/podman/test/test_containers.py b/contrib/python/podman/test/test_containers.py index f84b88f4c..167aae68b 100644 --- a/contrib/python/podman/test/test_containers.py +++ b/contrib/python/podman/test/test_containers.py @@ -2,6 +2,7 @@ import os import signal import unittest from test.podman_testcase import PodmanTestCase +from test.retry_decorator import retry import podman @@ -217,6 +218,8 @@ class TestContainers(PodmanTestCase): self.assertTrue(ctnr.running) self.assertTrue(ctnr.status, 'running') + # creating cgoups can be flakey + @retry(podman.libs.errors.ErrorOccurred, tries=16, delay=2, print_=print) def test_stats(self): self.assertTrue(self.alpine_ctnr.running) |