From f10e4805db9a64d27552c27306532ef18d399b48 Mon Sep 17 00:00:00 2001 From: Polina Bungina <27892524+hughcapet@users.noreply.github.com> Date: Wed, 13 Dec 2023 08:40:47 +0100 Subject: [PATCH] Actually allow failover to an async candidate in sync mode (#2980) --- patroni/ctl.py | 2 +- tests/test_ctl.py | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/patroni/ctl.py b/patroni/ctl.py index e1e999ce..8ec4e646 100644 --- a/patroni/ctl.py +++ b/patroni/ctl.py @@ -1278,7 +1278,7 @@ def _do_failover_or_switchover(obj: Dict[str, Any], action: str, cluster_name: s global_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 diff --git a/tests/test_ctl.py b/tests/test_ctl.py index 85691812..0f4744a5 100644 --- a/tests/test_ctl.py +++ b/tests/test_ctl.py @@ -232,17 +232,20 @@ class TestCtl(unittest.TestCase): failover_func_mock.assert_called_once_with( DEFAULT_CONFIG, '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 mock_get_dcs.return_value.get_cluster = Mock(return_value=cluster) - result = self.runner.invoke(ctl, ['failover', 'dummy', '--group', '0', '--candidate', 'async'], input='y\ny') + # 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) - mock_get_dcs.return_value.get_cluster = Mock(return_value=cluster) 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.dcs.dcs_modules', Mock(return_value=['patroni.dcs.dummy', 'patroni.dcs.etcd'])) def test_get_dcs(self):