async def test_master_lock_changes_owner(app): # if the lock changes owner to someone else, shutdown postgresql and exist plugins = setup_plugins(app, pg_replication_role='master') assert app.initialize() == None plugins.reset_mock() with patch('time.sleep') as sleep: with patch('sys.exit') as exit: app.master_lock_changed('someone else') assert exit.called_once_with(0) assert sleep.called_once_with(10) assert plugins.mock_calls == [ call.pg_replication_role(), call.pg_replication_role(), call.pg_stop(), call.dcs_disconnect(), call.master_lock_changed('someone else') ] assert app._master_lock_owner == 'someone else' # if the lock is owned by us, carry on trucking plugins.reset_mock() with patch('time.sleep') as sleep: with patch('sys.exit') as exit: app.master_lock_changed(app.my_id) assert exit.called_once_with(0) assert sleep.called_once_with(10) assert plugins.mock_calls == [ call.pg_replication_role(), call.master_lock_changed('42') ] assert app._master_lock_owner == app.my_id
async def test_replica_tries_to_take_over(app): plugins = setup_plugins(app, pg_replication_role='replica') assert app.initialize() == None plugins.reset_mock() # if there is no lock owner, we start looping trying to become master app.master_lock_changed(None) assert plugins.mock_calls == [call.pg_replication_role(), call.master_lock_changed(None)] plugins.reset_mock() from asyncio import sleep as real_sleep with patch('asyncio.sleep') as sleep: sleeper = FakeSleeper() sleep.side_effect = sleeper # the first thing is to sleep a bit await sleeper.next() assert sleeper.log == [3] assert plugins.mock_calls == [] # takeover attempted states = [(app.my_id, {'willing': 99.0}), (app.my_id, {'willing': 100.0})] plugins.dcs_list_state.return_value = states await sleeper.next() assert sleeper.log == [3, 3] assert plugins.mock_calls == [ call.dcs_list_state(), call.best_replicas([('42', {'willing': 99.0}), ('42', {'willing': 100.0})]), call.dcs_lock('master')]
async def test_plugin_subscribes_to_master_lock_change(app): plugins = setup_plugins(app, pg_get_timeline=42, master_lock_changed=[('pluginA', None)], pg_replication_role='replica') assert app.initialize() == None plugins.reset_mock() app.master_lock_changed('someone else') assert plugins.mock_calls == [ call.pg_replication_role(), call.master_lock_changed('someone else'), ]
async def test_replica_reaction_to_master_lock_change(app): plugins = setup_plugins(app, pg_get_timeline=42, pg_replication_role='replica') assert app.initialize() == None plugins.reset_mock() # if the lock changes owner to someone else, carry on trucking plugins.reset_mock() app.master_lock_changed('someone else') assert plugins.mock_calls == [ call.pg_replication_role(), call.master_lock_changed('someone else') ] assert app._master_lock_owner == 'someone else' # if the lock is owned by us, er, we stop replication and become the master plugins.reset_mock() plugins.pg_replication_role.side_effect = ['replica', 'master'] app.master_lock_changed(app.my_id) assert plugins.mock_calls == [ call.pg_replication_role(), call.dcs_set_state({ 'replication_role': 'taking-over', 'willing': None, 'health_problems': {}, 'host': '127.0.0.1' }), call.pg_stop_replication(), call.pg_replication_role(), call.pg_get_timeline(), call.dcs_set_timeline(42), call.dcs_set_state({ 'health_problems': {}, 'replication_role': 'master', 'willing': None, 'host': '127.0.0.1' }), call.master_lock_changed('42') ] assert app._master_lock_owner == app.my_id
async def test_replica_reaction_to_master_lock_change(app): plugins = setup_plugins(app, pg_get_timeline=42, pg_replication_role='replica') assert app.initialize() == None plugins.reset_mock() # if the lock changes owner to someone else, carry on trucking plugins.reset_mock() app.master_lock_changed('someone else') assert plugins.mock_calls == [ call.pg_replication_role(), call.master_lock_changed('someone else') ] assert app._master_lock_owner == 'someone else' # if the lock is owned by us, er, we stop replication and become the master plugins.reset_mock() plugins.pg_replication_role.side_effect = ['replica', 'master'] app.master_lock_changed(app.my_id) assert plugins.mock_calls == [ call.pg_replication_role(), call.dcs_set_state({ 'replication_role': 'taking-over', 'willing': None, 'health_problems': {}, 'host': '127.0.0.1'}), call.pg_stop_replication(), call.pg_replication_role(), call.pg_get_timeline(), call.dcs_set_timeline(42), call.dcs_set_state({ 'health_problems': {}, 'replication_role': 'master', 'willing': None, 'host': '127.0.0.1'}), call.master_lock_changed('42') ] assert app._master_lock_owner == app.my_id
async def test_master_lock_broken(app): plugins = setup_plugins(app, pg_replication_role='master') assert app.initialize() == None plugins.reset_mock() # if the lock is broken, shutdown postgresql and exist with patch('time.sleep') as sleep: with patch('sys.exit') as exit: app.master_lock_changed(None) assert exit.called_once_with(0) assert sleep.called_once_with(10) assert plugins.mock_calls == [ call.pg_replication_role(), call.pg_replication_role(), call.pg_stop(), call.dcs_disconnect(), call.master_lock_changed(None) ] assert app._master_lock_owner == None
async def test_replica_tries_to_take_over(app): plugins = setup_plugins(app, pg_replication_role='replica') assert app.initialize() == None plugins.reset_mock() # if there is no lock owner, we start looping trying to become master app.master_lock_changed(None) assert plugins.mock_calls == [ call.pg_replication_role(), call.master_lock_changed(None) ] plugins.reset_mock() from asyncio import sleep as real_sleep with patch('asyncio.sleep') as sleep: sleeper = FakeSleeper() sleep.side_effect = sleeper # the first thing is to sleep a bit await sleeper.next() assert sleeper.log == [3] assert plugins.mock_calls == [] # takeover attempted states = [(app.my_id, { 'willing': 99.0 }), (app.my_id, { 'willing': 100.0 })] plugins.dcs_list_state.return_value = states await sleeper.next() assert sleeper.log == [3, 3] assert plugins.mock_calls == [ call.dcs_list_state(), call.best_replicas([('42', { 'willing': 99.0 }), ('42', { 'willing': 100.0 })]), call.dcs_lock('master') ]