Files
patroni/tests/test_utils.py
T
Alexander Kukushkin 9f9cb6005d Refactor Postgresql.query method to use commont retry mechanism
query method in an api.py also needs retry in some cases (for example
when we are running is_healthiest_node check).
In all cases We will retry only when connection is closed or broken, BUT
connection status must be checked via cursor.connection (old
implementation was using general connection object for that). For
multi-threaded applications this is not appropriate, because some other
thread might restore connection.

In appdition to that I've changed most of the unit tests to use `Mock` and
`patch` where it is possible.
2015-09-20 13:41:57 +02:00

74 lines
2.1 KiB
Python

import unittest
from mock import Mock, patch
from patroni.exceptions import PatroniException
from patroni.utils import Retry, RetryFailedError, reap_children, sigchld_handler, sigterm_handler, sleep
def time_sleep(_):
sigchld_handler(None, None)
class TestUtils(unittest.TestCase):
def test_sigterm_handler(self):
self.assertRaises(SystemExit, sigterm_handler, None, None)
@patch('time.sleep', Mock())
def test_reap_children(self):
reap_children()
with patch('os.waitpid', Mock(return_value=(0, 0))):
sigchld_handler(None, None)
reap_children()
@patch('time.sleep', time_sleep)
def test_sleep(self):
sleep(0.01)
@patch('time.sleep', Mock())
class TestRetrySleeper(unittest.TestCase):
def _fail(self, times=1):
scope = dict(times=0)
def inner():
if scope['times'] >= times:
pass
else:
scope['times'] += 1
raise PatroniException('Failed!')
return inner
def _makeOne(self, *args, **kwargs):
return Retry(*args, **kwargs)
def test_reset(self):
retry = self._makeOne(delay=0, max_tries=2)
retry(self._fail())
self.assertEquals(retry._attempts, 1)
retry.reset()
self.assertEquals(retry._attempts, 0)
def test_too_many_tries(self):
retry = self._makeOne(delay=0)
self.assertRaises(RetryFailedError, retry, self._fail(times=999))
self.assertEquals(retry._attempts, 1)
def test_maximum_delay(self):
retry = self._makeOne(delay=10, max_tries=100)
retry(self._fail(times=10))
self.assertTrue(retry._cur_delay < 4000, retry._cur_delay)
# gevent's sleep function is picky about the type
self.assertEquals(type(retry._cur_delay), float)
def test_deadline(self):
retry = self._makeOne(deadline=0.0001)
self.assertRaises(RetryFailedError, retry, self._fail(times=100))
def test_copy(self):
_sleep = lambda t: None
retry = self._makeOne(sleep_func=_sleep)
rcopy = retry.copy()
self.assertTrue(rcopy.sleep_func is _sleep)