Actually allow failover to an async candidate in sync mode (#2980)

This commit is contained in:
Polina Bungina
2023-12-13 08:40:47 +01:00
committed by GitHub
parent efdedc7049
commit f0719d148c
2 changed files with 7 additions and 5 deletions
+1 -1
View File
@@ -1272,7 +1272,7 @@ def _do_failover_or_switchover(action: str, cluster_name: str, group: Optional[i
config.is_synchronous_mode,
not cluster.sync.is_empty,
not cluster.sync.matches(candidate, True))):
if click.confirm(f'Are you sure you want to failover to the asynchronous node {candidate}'):
if not click.confirm(f'Are you sure you want to failover to the asynchronous node {candidate}?'):
raise PatroniCtlException('Aborting ' + action)
scheduled_at_str = None
+6 -4
View File
@@ -226,18 +226,20 @@ class TestCtl(unittest.TestCase):
self.assertIn('Supplying a leader name using this command is deprecated', result.output)
failover_func_mock.assert_called_once_with('switchover', 'dummy', None, 'leader', None, False)
# Failover to an async member in sync mode (confirm)
cluster = get_cluster_initialized_with_leader(sync=('leader', 'other'))
cluster.members.append(Member(0, 'async', 28, {'api_url': 'http://127.0.0.1:8012/patroni'}))
cluster.config.data['synchronous_mode'] = True
with patch('patroni.dcs.AbstractDCS.get_cluster', Mock(return_value=cluster)):
# Failover to an async member in sync mode (confirm)
result = self.runner.invoke(ctl,
['failover', 'dummy', '--group', '0', '--candidate', 'async'], input='y\ny')
self.assertIn('Are you sure you want to failover to the asynchronous node async', result.output)
self.assertEqual(result.exit_code, 0)
# Failover to an async member in sync mode (abort)
result = self.runner.invoke(ctl, ['failover', 'dummy', '--group', '0', '--candidate', 'async'], input='N')
self.assertEqual(result.exit_code, 1)
# Failover to an async member in sync mode (abort)
result = self.runner.invoke(ctl, ['failover', 'dummy', '--group', '0', '--candidate', 'async'], input='N')
self.assertEqual(result.exit_code, 1)
self.assertIn('Aborting failover', result.output)
@patch('patroni.dynamic_loader.iter_modules', Mock(return_value=['patroni.dcs.dummy', 'patroni.dcs.etcd']))
def test_get_dcs(self):