Compare commits

..
2 Commits
Author SHA1 Message Date
Oleksii Kliukin 9f9acb6a55 Fix a watchdog unit test on OS X. 2017-07-28 16:45:29 +02:00
Alexander KukushkinandGitHub f8b3703d6e Bugfix: failover via API didn't work due to change in _MemberStatus (#489)
Originally fetch_nodes_statuses was returning a tuple, later it was
wrapped into namedtuple _MemberStatus and recently _MemberStatus was
extened with watchdog_failed field, but api.py was still relying on
usual tuple and checking failover limitations on it's own instead of
calling `failover_limitation` method.
2017-07-28 15:38:55 +02:00
5 changed files with 8 additions and 5 deletions
+2 -2
View File
@@ -300,8 +300,8 @@ class RestApiHandler(BaseHTTPRequestHandler):
members = [m for m in cluster.members if m.name != cluster.leader.name and m.api_url] members = [m for m in cluster.members if m.name != cluster.leader.name and m.api_url]
if not members: if not members:
return 'failover is not possible: cluster does not have members except leader' return 'failover is not possible: cluster does not have members except leader'
for _, reachable, _, _, tags in self.server.patroni.ha.fetch_nodes_statuses(members): for st in self.server.patroni.ha.fetch_nodes_statuses(members):
if reachable and not tags.get('nofailover', False): if st.failover_limitation() is None:
return None return None
return 'failover is not possible: no good candidates have been found' return 'failover is not possible: no good candidates have been found'
+1
View File
@@ -26,6 +26,7 @@ class _MemberStatus(namedtuple('_MemberStatus', 'member,reachable,in_recovery,wa
in_recovery - `!True` if pg_is_in_recovery() == true in_recovery - `!True` if pg_is_in_recovery() == true
wal_position - value of `replayed_location` or `location` from JSON, dependin on its role. wal_position - value of `replayed_location` or `location` from JSON, dependin on its role.
tags - dictionary with values of different tags (i.e. nofailover) tags - dictionary with values of different tags (i.e. nofailover)
watchdog_failed - indicates that watchdog is required by configuration but not available or failed
""" """
@classmethod @classmethod
def from_api_response(cls, member, json): def from_api_response(cls, member, json):
+1 -1
View File
@@ -1 +1 @@
__version__ = '1.3' __version__ = '1.3.1'
+3 -2
View File
@@ -6,6 +6,7 @@ import unittest
from mock import Mock, patch from mock import Mock, patch
from patroni.api import RestApiHandler, RestApiServer from patroni.api import RestApiHandler, RestApiServer
from patroni.dcs import ClusterConfig, Member from patroni.dcs import ClusterConfig, Member
from patroni.ha import _MemberStatus
from patroni.utils import tzutc from patroni.utils import tzutc
from six import BytesIO as IO from six import BytesIO as IO
from six.moves import BaseHTTPServer from six.moves import BaseHTTPServer
@@ -38,7 +39,7 @@ class MockPostgresql(object):
class MockWatchdog(object): class MockWatchdog(object):
is_healthy = True is_healthy = False
class MockHa(object): class MockHa(object):
@@ -64,7 +65,7 @@ class MockHa(object):
@staticmethod @staticmethod
def fetch_nodes_statuses(members): def fetch_nodes_statuses(members):
return [[None, True, None, None, {}]] return [_MemberStatus(None, True, None, None, {}, False)]
@staticmethod @staticmethod
def schedule_future_restart(data): def schedule_future_restart(data):
+1
View File
@@ -135,6 +135,7 @@ class TestWatchdog(unittest.TestCase):
self.assertIsNone(wd.disable()) self.assertIsNone(wd.disable())
self.assertIsNone(wd.keepalive()) self.assertIsNone(wd.keepalive())
@patch('platform.system', Mock(return_value='Linux'))
def test_config_reload(self): def test_config_reload(self):
watchdog = Watchdog({'ttl': 30, 'loop_wait': 15, 'watchdog': {'mode': 'required'}}) watchdog = Watchdog({'ttl': 30, 'loop_wait': 15, 'watchdog': {'mode': 'required'}})
self.assertTrue(watchdog.activate()) self.assertTrue(watchdog.activate())