class TestManageInstance(unittest.TestCase): def setUp(self): self.cookie = 'secret' self.console_sock = './tmp/x.sock' self.instance = Instance(self.console_sock, self.cookie) self.instance.start() def test_create_replicaset(self): # create replicaset with instances not known by cluster self.instance.clear_calls('edit_topology') res = call_manage_replicaset(self.console_sock, alias='r1', failover_priority=['r1-master'], instances=['r1-master', 'r1-replica'], roles=['role-1']) self.assertFalse(res.success, msg=res.msg) self.assertIn( 'Leader "r1-master" (replicaset "r1") not found in cluster', res.msg) self.assertEqual(len(self.instance.get_calls('edit_topology')), 0) # add unjoined self.instance.add_unjoined_server(alias='r1-master', uri='r1-master-uri') self.instance.add_unjoined_server(alias='r1-replica', uri='r1-replica-uri') # create replicaset with instances known by cluster self.instance.clear_calls('edit_topology') res = call_manage_replicaset(self.console_sock, alias='r1', failover_priority=['r1-master'], instances=['r1-master', 'r1-replica'], roles=['role-1']) self.assertTrue(res.success, msg=res.msg) self.assertTrue(res.changed) # check performed `edit_topology` calls calls = self.instance.get_calls('edit_topology') self.assertEqual(len(calls), 2) join_leader_call = calls[0] join_replica_call = calls[1] # check join leader call self.assertIn('replicasets', join_leader_call) self.assertEqual(len(join_leader_call['replicasets']), 1) r_params = join_leader_call['replicasets'][0] self.assertEqual( r_params, { 'alias': 'r1', 'roles': ['role-1'], 'join_servers': [{ 'uri': 'r1-master-uri' }], }) # check join replica call self.assertIn('replicasets', join_replica_call) self.assertEqual(len(join_replica_call['replicasets']), 1) r_params = join_replica_call['replicasets'][0] self.assertEqual(r_params, { 'uuid': 'r1-uuid', 'join_servers': [{ 'uri': 'r1-replica-uri' }], }) # repeat the call (res.changed should be false) self.instance.clear_calls('edit_topology') res = call_manage_replicaset(self.console_sock, alias='r1', failover_priority=['r1-master'], instances=['r1-master', 'r1-replica'], roles=['role-1']) self.assertTrue(res.success, msg=res.msg) self.assertFalse(res.changed) # check performed `edit_topology` calls calls = self.instance.get_calls('edit_topology') self.assertEqual(len(calls), 1) self.assertIn('replicasets', calls[0]) r_params = calls[0]['replicasets'][0] self.assertEqual( r_params, { 'uuid': 'r1-uuid', 'roles': ['role-1'], 'failover_priority': ['r1-master-uuid'], }) def test_edit_replicaset_parameters(self): add_replicaset( self.instance, alias='r1', roles=['role-1'], servers=['r1-master'], ) params = { 'all_rw': True, 'weight': 1, 'vshard_group': 'hot', 'roles': ['role-2'], } for param, value in params.items(): self.instance.clear_calls('edit_topology') res = call_manage_replicaset( self.console_sock, alias='r1', failover_priority=['r1-master'], instances=['r1-master'], **{param: value}, ) self.assertTrue(res.success, msg=res.msg) self.assertTrue(res.changed) # check performed `edit_topology` calls calls = self.instance.get_calls('edit_topology') self.assertEqual(len(calls), 1) self.assertIn('replicasets', calls[0]) r_params = calls[0]['replicasets'][0] self.assertEqual( r_params, { 'uuid': 'r1-uuid', 'failover_priority': ['r1-master-uuid'], **{ param: value }, }) # set the same parameter again (res.changed should be false) self.instance.clear_calls('edit_topology') res = call_manage_replicaset( self.console_sock, alias='r1', failover_priority=['r1-master'], instances=['r1-master'], **{param: value}, ) self.assertTrue(res.success, msg=res.msg) self.assertFalse(res.changed) # check performed `edit_topology` calls calls = self.instance.get_calls('edit_topology') self.assertEqual(len(calls), 1) self.assertIn('replicasets', calls[0]) r_params = calls[0]['replicasets'][0] self.assertEqual( r_params, { 'uuid': 'r1-uuid', 'failover_priority': ['r1-master-uuid'], **{ param: value }, }) def test_joining_new_servers(self): add_replicaset( self.instance, alias='r1', roles=['role-1'], servers=['r1-master', 'r1-replica'], ) # add unjoined self.instance.add_unjoined_server(alias='r1-new-master', uri='r1-new-master-uri') # join new server and set it to be a new master self.instance.clear_calls('edit_topology') res = call_manage_replicaset( self.console_sock, alias='r1', failover_priority=['r1-new-master', 'r1-master'], instances=['r1-master', 'r1-replica', 'r1-new-master'], ) self.assertTrue(res.success, msg=res.msg) self.assertTrue(res.changed) # check performed `edit_topology` calls calls = self.instance.get_calls('edit_topology') self.assertEqual(len(calls), 2) join_call = calls[0] edit_priority_call = calls[1] self.assertIn('replicasets', join_call) r_params = join_call['replicasets'][0] self.assertEqual(r_params, { 'uuid': 'r1-uuid', 'join_servers': [{ 'uri': 'r1-new-master-uri' }], }) self.assertIn('replicasets', edit_priority_call) r_params = edit_priority_call['replicasets'][0] self.assertEqual( r_params, { 'uuid': 'r1-uuid', 'failover_priority': ['r1-new-master-uuid', 'r1-master-uuid'], }) # call again (res.changed should be false) res = call_manage_replicaset( self.console_sock, alias='r1', failover_priority=['r1-new-master', 'r1-master'], instances=['r1-master', 'r1-replica', 'r1-new-master'], ) self.assertTrue(res.success, msg=res.msg) self.assertFalse(res.changed) def test_fail_on_edit_topology(self): # fail on create self.instance.add_unjoined_server(alias='r1-master', uri='r1-master-uri') self.instance.clear_calls('edit_topology') self.instance.set_fail_on('edit_topology') # create replicaset with instances known by cluster self.instance.clear_calls('edit_topology') res = call_manage_replicaset(self.console_sock, alias='r1', failover_priority=['r1-master'], instances=['r1-master'], roles=['role-1']) self.assertFalse(res.success) self.assertIn('Failed to create', res.msg) self.assertIn('cartridge err', res.msg) # fail on edit add_replicaset( self.instance, alias='r1', roles=['role-1'], servers=['r1-master', 'r1-replica'], ) self.instance.clear_calls('edit_topology') self.instance.set_fail_on('edit_topology') res = call_manage_replicaset( self.console_sock, alias='r1', failover_priority=['r1-master'], instances=['r1-master'], roles=['role-1', 'role-2'], ) self.assertFalse(res.success) self.assertIn('Failed to edit replicaset', res.msg) self.assertIn('cartridge err', res.msg) self.instance.set_fail_on('edit_topology', False) def test_replicaset_in_unhealthy(self): # try to edit unhealthy replicaset add_replicaset( self.instance, alias='r1', roles=['role-1'], servers=['r1-master'], status='unhealthy', ) res = call_manage_replicaset( self.console_sock, alias='r1', roles=['role-2'], failover_priority=['r1-master'], instances=['r1-master'], ) self.assertFalse(res.success) self.assertIn('Replicaset "r1" is not healthy', res.msg) # replicaset becomes unhealthy after creation self.instance.set_variable('become_unhealthy_after_edit', True) self.instance.add_unjoined_server(alias='r2-master', uri='r2-master-uri') res = call_manage_replicaset( self.console_sock, alias='r2', roles=['role-2'], failover_priority=['r2-master'], instances=['r2-master'], ) self.assertFalse(res.success) self.assertIn('Replicaset "r2" is not healthy', res.msg) # replicaset becomes unhealthy after edit self.instance.set_variable('become_unhealthy_after_edit', True) add_replicaset( self.instance, alias='r3', roles=['role-1'], servers=['r3-master'], status='unhealthy', ) res = call_manage_replicaset( self.console_sock, alias='r3', roles=['role-2'], failover_priority=['r3-master'], instances=['r3-master'], ) self.assertFalse(res.success) self.assertIn('Replicaset "r3" is not healthy', res.msg) def tearDown(self): self.instance.stop()
class TestExpelInstance(unittest.TestCase): def setUp(self): self.cookie = 'secret' self.console_sock = './tmp/x.sock' self.instance = Instance(self.console_sock, self.cookie) self.instance.start() def test_non_existent_instance(self): self.instance.clear_calls('edit_topology') res = call_expel_intstance(self.console_sock, 'non-existent-instance') self.assertTrue(res.success, msg=res.msg) self.assertFalse(res.changed) calls = self.instance.get_calls('edit_topology') self.assertEqual(len(calls), 0) def test_unjoined_instance(self): ALIAS = 'instance' self.instance.add_unjoined_server(alias=ALIAS, uri='{}-uri'.format(ALIAS)) self.instance.clear_calls('edit_topology') res = call_expel_intstance(self.console_sock, ALIAS) self.assertTrue(res.success, msg=res.msg) self.assertFalse(res.changed) calls = self.instance.get_calls('edit_topology') self.assertEqual(len(calls), 0) def test_instance_from_replicaset(self): add_replicaset( self.instance, alias='r1', roles=['role-1'], servers=['r1-master', 'r1-replica'], ) self.instance.clear_calls('edit_topology') res = call_expel_intstance(self.console_sock, 'r1-master') self.assertTrue(res.success, msg=res.msg) self.assertTrue(res.changed) # check `edit_topology` call calls = self.instance.get_calls('edit_topology') self.assertEqual(len(calls), 1) self.assertIn('servers', calls[0]) self.assertEqual(len(calls[0]['servers']), 1) s_params = calls[0]['servers'][0] self.assertEqual(s_params, { 'uuid': 'r1-master-uuid', 'expelled': True, }) # call again (res.changed should be false) # in fact, bacause server is expelled from topology self.instance.clear_calls('edit_topology') res = call_expel_intstance(self.console_sock, 'r1-master') self.assertTrue(res.success, msg=res.msg) self.assertFalse(res.changed) calls = self.instance.get_calls('edit_topology') self.assertEqual(len(calls), 0) def test_fail_on_edit_topology(self): add_replicaset( self.instance, alias='r1', roles=['role-1'], servers=['r1-master', 'r1-replica'], ) self.instance.clear_calls('edit_topology') self.instance.set_fail_on('edit_topology') res = call_expel_intstance(self.console_sock, 'r1-master') self.assertFalse(res.success) self.assertIn('Failed to expel instance', res.msg) def tearDown(self): self.instance.stop()