mirror of
https://github.com/outbackdingo/patroni.git
synced 2026-08-25 14:53:37 +00:00
It was causing patroni failing to stop after receiving SIGTERM.
Acceptance tests was killing it with SIGKILL which was causing further tests fail because postgres was still running:
2016-06-16 14:36:24,444 INFO: no action. i am the leader with the lock
2016-06-16 14:36:25,448 INFO: Lock owner: postgres0; I am postgres0
2016-06-16 14:36:25,452 ERROR: Failed to update /service/batman/optime/leader
Traceback (most recent call last):
File "/home/akukushkin/git/patroni/patroni/dcs/zookeeper.py", line 208, in write_leader_optime
self._client.retry(self._client.set, path, last_operation)
File "/home/akukushkin/git/patroni/py2/local/lib/python2.7/site-packages/kazoo/client.py", line 273, in _retry
return self._retry.copy()(*args, **kwargs)
File "/home/akukushkin/git/patroni/py2/local/lib/python2.7/site-packages/kazoo/retry.py", line 123, in __call__
return func(*args, **kwargs)
File "/home/akukushkin/git/patroni/py2/local/lib/python2.7/site-packages/kazoo/client.py", line 1219, in set
return self.set_async(path, value, version).get()
File "/home/akukushkin/git/patroni/py2/local/lib/python2.7/site-packages/kazoo/handlers/utils.py", line 74, in get
self._condition.wait(timeout)
File "/usr/lib/python2.7/threading.py", line 340, in wait
waiter.acquire()
File "/home/akukushkin/git/patroni/patroni/utils.py", line 219, in sigterm_handler
sys.exit()
SystemExit
2016-06-16 14:36:25,453 INFO: no action. i am the leader with the lock
2016-06-16 14:36:26,443 INFO: Lock owner: postgres0; I am postgres0
2016-06-16 14:36:26,444 INFO: no action. i am the leader with the lock
71 lines
2.0 KiB
Python
71 lines
2.0 KiB
Python
import unittest
|
|
|
|
from mock import Mock, patch
|
|
from patroni.exceptions import PatroniException
|
|
from patroni.utils import reap_children, Retry, RetryFailedError, sigchld_handler, sleep
|
|
|
|
|
|
def time_sleep(_):
|
|
sigchld_handler(None, None)
|
|
|
|
|
|
class TestUtils(unittest.TestCase):
|
|
|
|
@patch('time.sleep', Mock())
|
|
def test_reap_children(self):
|
|
self.assertIsNone(reap_children())
|
|
with patch('os.waitpid', Mock(return_value=(0, 0))):
|
|
sigchld_handler(None, None)
|
|
self.assertIsNone(reap_children())
|
|
|
|
@patch('time.sleep', time_sleep)
|
|
def test_sleep(self):
|
|
self.assertIsNone(sleep(0.01))
|
|
|
|
|
|
@patch('time.sleep', Mock())
|
|
class TestRetrySleeper(unittest.TestCase):
|
|
|
|
@staticmethod
|
|
def _fail(times=1):
|
|
scope = dict(times=0)
|
|
|
|
def inner():
|
|
if scope['times'] >= times:
|
|
pass
|
|
else:
|
|
scope['times'] += 1
|
|
raise PatroniException('Failed!')
|
|
return inner
|
|
|
|
def test_reset(self):
|
|
retry = Retry(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 = Retry(delay=0)
|
|
self.assertRaises(RetryFailedError, retry, self._fail(times=999))
|
|
self.assertEquals(retry._attempts, 1)
|
|
|
|
def test_maximum_delay(self):
|
|
retry = Retry(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 = Retry(deadline=0.0001)
|
|
self.assertRaises(RetryFailedError, retry, self._fail(times=100))
|
|
|
|
def test_copy(self):
|
|
def _sleep(t):
|
|
pass
|
|
|
|
retry = Retry(sleep_func=_sleep)
|
|
rcopy = retry.copy()
|
|
self.assertTrue(rcopy.sleep_func is _sleep)
|