summaryrefslogtreecommitdiff
path: root/contrib/python
diff options
context:
space:
mode:
authorJhon Honce <jhonce@redhat.com>2018-08-20 08:40:42 -0700
committerAtomic Bot <atomic-devel@projectatomic.io>2018-08-20 21:07:09 +0000
commit75588a4333aef6a3830cd120136a664418d336e9 (patch)
tree07f4db5eef955817acb0a9d4a8dae037748c543e /contrib/python
parent937398abcfa9848b36efd95d845d98d865578c71 (diff)
downloadpodman-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')
-rw-r--r--contrib/python/podman/test/podman_testcase.py4
-rw-r--r--contrib/python/podman/test/retry_decorator.py43
-rw-r--r--contrib/python/podman/test/test_containers.py3
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)