def setUp(self): """ Setup server connection """ server_cnx = {'conn_info': self.options[SERVER_CNX_OPT][0]} self.server1 = Server(server_cnx) self.server1.connect() # default user self.server1.exec_query("drop user if exists 'rpl_user'") qry_key1 = ("select MEMBER_HOST, MEMBER_PORT from {0}" "".format(REP_GROUP_MEMBERS_TABLE)) qry_key2 = "show variables like 'group_replication_%'" frozen_queries = { qry_key1: [[self.server1.host, self.server1.port]], qry_key2: [("group_replication_group_name", "name"), ("group_replication_start_on_boot", "ON"), ("group_replication_group_seeds", "")] } variables = {GR_LOCAL_ADDRESS: "localhost:3307"} self.server = get_mock_server(self.server1, queries=frozen_queries, variables=variables) # Set directory with option files for tests. self.option_file_dir = os.path.normpath( os.path.join(__file__, "..", "std_data", "option_files")) self.session_track_system_variables_bkp = self.server1.exec_query( "select @@global.session_track_system_variables")[0][0]
def setUp(self): """ Setup server connection """ self.server_cnx = {'conn_info': self.options[SERVER_CNX_OPT][0]} self.server = Server(self.server_cnx) self.server.connect() skip_if_not_GR_approved(self.server) if self.server.select_variable(HAVE_SSL) != 'YES': raise unittest.SkipTest("Provided server must have_ssl == 'YES'.") # User without Create User privileges self.server.exec_query("drop user if exists 'nop_user'@'localhost'") self.server.exec_query("create user nop_user@'localhost'") server_conn2 = self.server_cnx.copy() server_conn2["conn_info"] = ("nop_user@localhost:{0}" "".format(self.server.port)) self.server2 = Server(self.server_cnx) self.server2.connect() columns = [MEMBER_ID, MEMBER_HOST, MEMBER_PORT, MEMBER_STATE] qry_key = "SELECT {0} FROM {1}".format(", ".join(columns), REP_GROUP_MEMBERS_TABLE) qry_key2 = ("SELECT GROUP_NAME FROM {0} where " "CHANNEL_NAME = 'group_replication_applier'" "".format(REP_CONN_STATUS_TABLE)) frozen_queries = { qry_key: [[], []], qry_key2: [], } self.mock_no_member = get_mock_server(self.server, queries=frozen_queries)
def test_re_join(self): """Tests join method over actively replicating server """ # Fill the options options = { "group_name": None, "gr_host": self.server.host, "replication_user": "******", "rep_user_passwd": "passwd", "verbose": False, "dry_run": False, } # test start leave(self.server, **options) # reconnect the server. self.server.connect() self.assertTrue(start(self.server, **options)) # reconnect the server. self.server.connect() # test health health(self.server, **options) # reconnect the server. self.server.connect() options["dry_run"] = True # test join mock_server = get_mock_server(self.server) # Trying to add server to a group while is already a member of a group # expect GadgetError: Query failed: is already a member of a GR group. with self.assertRaises(GadgetError) as test_raises: join(self.server, mock_server, **options) exception = test_raises.exception self.assertTrue( "is already a member" in exception.errmsg, "The exception message was not the expected. {0}" "".format(exception.errmsg)) # reconnect the server. self.server.connect() self.assertTrue(leave(self.server, **options)) # reconnect the server. self.server.connect()
def test_check_unique_id(self): """Tests check_unique_id method""" # Test duplicated server_id mock_server = get_mock_server(self.server) server_values = {"peers": [mock_server]} req_check = RequirementChecker() results = req_check.check_unique_id(server_values, mock_server) self.assertFalse(results["pass"]) self.assertEqual(results["duplicate"], mock_server) # Test invalid server_id = 0 frozen_variables = {"server_id": "0"} mock_server_idz = get_mock_server(self.server, variables=frozen_variables) results = req_check.check_unique_id(server_values, mock_server_idz) self.assertFalse(results["pass"]) # Servers with different server_id frozen_variables = {"server_id": "777"} mock_server2 = get_mock_server(self.server, variables=frozen_variables) server_values = {"peers": [mock_server, mock_server2]} results = req_check.check_unique_id(server_values, self.server) self.assertTrue(results["pass"])
def test_re_join(self): """Tests join method over actively replicating server """ # Fill the options options = { "group_name": None, "gr_host": self.server.host, "replication_user": "******", "rep_user_passwd": "passwd", "verbose": False, "dry_run": False, } # test start leave(self.server, **options) # reconnect the server. self.server.connect() self.assertTrue(start(self.server, **options)) # reconnect the server. self.server.connect() # test health health(self.server, **options) # reconnect the server. self.server.connect() options["dry_run"] = True # test join mock_server = get_mock_server(self.server) # Trying to add server to a group while is already a member of a group # expect GadgetError: Query failed: is already a member of a GR group. with self.assertRaises(GadgetError) as test_raises: join(self.server, mock_server, **options) exception = test_raises.exception self.assertTrue("is already a member" in exception.errmsg, "The exception message was not the expected. {0}" "".format(exception.errmsg)) # reconnect the server. self.server.connect() self.assertTrue(leave(self.server, **options)) # reconnect the server. self.server.connect()
def test_check_server_requirements(self): """Tests check_server_requirements method""" skip_if_not_GR_approved(self.server1) self.server.exec_query("drop user if exists 'new_rpl_user'") self.server.exec_query("drop user if exists 'replic_user'@'%'") self.server.exec_query("drop user if exists 'replic_user'@'localhost'") # Test with default values, server.user must have SUPER options = { "replication_user": "******", "rep_user_passwd": "rplr_pass", } rpl_settings = get_rpl_usr(options) req_dict = get_req_dict(self.server, rpl_settings["replication_user"]) self.assertTrue( check_server_requirements(self.server, req_dict, rpl_settings, verbose=True, dry_run=False, skip_backup=True)) self.assertTrue( User(self.server, "replic_user@%", None).exists(), "User was not created on check_server_requirements") # Test using an admin user without CREATE USER privilege. grant_list = ["SELECT"] self.server.exec_query("DROP USER IF EXISTS " "'replic_user'@'localhost'") change_user_privileges(self.server, "replic_user", 'localhost', "rplr_pass", grant_list=grant_list, create_user=True) server2 = Server({ "conn_info": "replic_user@localhost:{0}" "".format(self.server.port) }) server2.passwd = "rplr_pass" server2.connect() qry_key = ("select MEMBER_HOST, MEMBER_PORT from {0}" "".format(REP_GROUP_MEMBERS_TABLE)) frozen_queries = {qry_key: [[server2.host, server2.port]]} mock_server = get_mock_server(server2, variables=frozen_queries) options = { "replication_user": "******", "rep_user_passwd": "rpl_pass", } rpl_settings = get_rpl_usr(options) req_dict = get_req_dict(server2, rpl_settings["replication_user"]) # expect GadgetError: Query failed: No required privileges # to create the replication user with self.assertRaises(GadgetError) as test_raises: check_server_requirements(mock_server, req_dict, rpl_settings, verbose=True, dry_run=False, skip_backup=True) exception = test_raises.exception self.assertTrue( "required privileges to create" in exception.errmsg, "The exception message was not the expected. {0}" "".format(exception.errmsg)) # Test existing user and admin user without REPLICATION SLAVE grant grant_list = ["SELECT"] revoke_list = ["REPLICATION SLAVE"] change_user_privileges(self.server, "new_rpl_user", "%", grant_list=grant_list, revoke_list=revoke_list, create_user=True, with_grant=True) revoke_list = ["REPLICATION SLAVE"] change_user_privileges(self.server, "replic_user", "%", revoke_list=revoke_list) # expect GadgetError: does not have the REPLICATION SLAVE privilege, # and can not be granted by. with self.assertRaises(GadgetError) as test_raises: check_server_requirements(mock_server, req_dict, rpl_settings, verbose=True, dry_run=False, skip_backup=True) exception = test_raises.exception self.assertTrue( "does not have the REPLICATION SLAVE privilege, " "and can not be granted by" in exception.errmsg, "The exception message was not the expected. {0}" "".format(exception.errmsg)) self.assertTrue( "SUPER privilege required to disable the binlog." in exception.errmsg, "The exception message was not the expected. {0}" "".format(exception.errmsg)) # self.server.exec_query("drop user if exists 'replic_user'@'%'") # Test existing user and admin user without REPLICATION SLAVE grant grant_list = ["SELECT"] revoke_list = ["REPLICATION SLAVE"] change_user_privileges(self.server, "new_rpl_user", "%", grant_list=grant_list, revoke_list=revoke_list) grant_list = ["REPLICATION SLAVE", "SUPER"] change_user_privileges(self.server, "replic_user", "localhost", grant_list=grant_list, with_grant=True) # reset session to get new privileges. server2.disconnect() server2.connect() mock_server = get_mock_server(server2, variables=frozen_queries) self.assertTrue( check_server_requirements(mock_server, req_dict, rpl_settings, verbose=True, dry_run=False, skip_backup=True)) # Test existing rpl user and admin user without grant # admin user: replic_user # rpl user: new_rpl_user grant_list = ["REPLICATION SLAVE"] change_user_privileges(self.server, "new_rpl_user", "%", grant_list=grant_list) grant_list = ["SELECT", "CREATE USER"] change_user_privileges(self.server, "create_rpl", "127.0.0.1", user_passwd="c_pass", grant_list=grant_list, create_user=True, with_grant=True) server3 = Server({ "conn_info": "[email protected]:{0}" "".format(self.server.port) }) server3.passwd = "c_pass" server3.connect() req_dict3 = get_req_dict(server3, rpl_settings["replication_user"]) # expect GadgetError: No required privileges # to grant Replication Slave privilege with self.assertRaises(GadgetError) as test_raises: check_server_requirements(server3, req_dict3, rpl_settings, verbose=True, dry_run=False, skip_backup=True) exception = test_raises.exception self.assertTrue( "SUPER privilege needed to run the CHANGE MASTER " "command" in exception.errmsg, "The exception message was not the expected. {0}" "".format(exception.errmsg)) # Test invalid server_id mock_server = get_mock_server(self.server, variables={"server_id": "0"}) req_dict = get_req_dict(self.server, rpl_settings["replication_user"]) # expect GadgetError: server_id not valid with self.assertRaises(GadgetError) as test_raises: check_server_requirements(mock_server, req_dict, rpl_settings, verbose=True, dry_run=False, skip_backup=True) exception = test_raises.exception self.assertTrue( "is not valid, it must be a positive integer" in exception.errmsg, "The exception message was not the expected. {0}" "".format(exception.errmsg)) # Test duplicate server_id mock_server = get_mock_server(self.server, variables={"server_id": "101"}) req_dict["SERVER_ID"] = {"peers": [mock_server]} # expect GadgetError: server_id is already used by peer with self.assertRaises(GadgetError) as test_raises: check_server_requirements(mock_server, req_dict, rpl_settings, verbose=True, dry_run=False, skip_backup=True) exception = test_raises.exception self.assertTrue( "is already used by peer" in exception.errmsg, "The exception message was not the expected. {0}" "".format(exception.errmsg)) # Test existing user and admin with required grants req_dict = get_req_dict(self.server, rpl_settings["replication_user"]) grant_list = ["REPLICATION SLAVE"] change_user_privileges(self.server, "new_rpl_user", "%", grant_list=grant_list) self.assertTrue( check_server_requirements(self.server, req_dict, rpl_settings, verbose=True, dry_run=False, skip_backup=True)) # Tests server variables not meet required values req_dict = get_req_dict(self.server, rpl_settings["replication_user"]) req_dict[SERVER_VARIABLES] = { "log_bin": { ONE_OF: ("0", ) }, "binlog_format": { ONE_OF: ("", ) }, "binlog_checksum": { ONE_OF: ("", ) }, "gtid_mode": { ONE_OF: ("OFF", ) }, "log_slave_updates": { ONE_OF: ("0", ) }, "enforce_gtid_consistency": { ONE_OF: ("OFF", ) }, } # expect GadgetError: change the configuration values with self.assertRaises(GadgetError) as test_raises: check_server_requirements(self.server, req_dict, rpl_settings, verbose=True, dry_run=True, update=False, skip_backup=True) exception = test_raises.exception self.assertIn( "on server {0} are incompatible with Group " "Replication.".format(self.server), exception.errmsg, "The exception message was not the expected. {0}" "".format(exception.errmsg)) # Test server version req_dict[SERVER_VERSION] = "99.9.9" # expect GadgetError: Query failed: server version with self.assertRaises(GadgetError) as test_raises: check_server_requirements(self.server, req_dict, rpl_settings, verbose=True, dry_run=True, update=False, skip_backup=True) exception = test_raises.exception self.assertTrue( "does not meet the required MySQL server version" in exception.errmsg, "The exception message was not the expected. {0}" "".format(exception.errmsg)) self.server.exec_query("drop user if exists 'replic_user'") self.server.exec_query("drop user if exists 'create_rpl'") self.server.exec_query("drop user if exists 'new_rpl_user'")
def test_join(self): """Tests join method """ # Fill the options options = { "group_name": None, "gr_host": "{0}:{1}".format(self.server.host, self.server.port), "replication_user": "******", "rep_user_passwd": "passwd", "verbose": False, "dry_run": False, } # join needs start if is_member_of_group(self.server): leave(self.server, **options) # reconnect the server. self.server.connect() self.assertTrue(start(self.server, **options)) # reconnect the server. self.server.connect() # health health(self.server, **options) # reconnect the server. self.server.connect() leave(self.server, **options) # reconnect the server. self.server.connect() member_state_qry = ("SELECT MEMBER_STATE FROM {0} as m JOIN {1} " "as s on m.MEMBER_ID = s.MEMBER_ID" "".format(REP_GROUP_MEMBERS_TABLE, REP_MEMBER_STATS_TABLE)) frozen_queries = { member_state_qry: [ [ 'ONLINE', ], ], } mock_server = get_mock_server(self.server, queries=frozen_queries) # Join with defaults ("dry_run": True) and required password options = { "dry_run": True, "replication_user": "******", "rep_user_passwd": "passwd", } join(self.server, mock_server, **options) # reconnect the server. self.server.connect() # Join with no defaults ("dry_run": True) options = { "group_name": None, "gr_host": "{0}:{1}".format(self.server.host, self.server.port), "replication_user": "******", "rep_user_passwd": "passwd", "verbose": False, "dry_run": True, } # leave the group if is_member_of_group(self.server): leave(self.server, **options) self.assertFalse(join(self.server, mock_server, **options)) # reconnect the server. self.server.connect() self.assertFalse(leave(self.server, **options)) # reconnect the server. self.server.connect()
def test_join(self): """Tests join method """ # Fill the options options = { "group_name": None, "gr_host": "{0}:{1}".format(self.server.host, self.server.port), "replication_user": "******", "rep_user_passwd": "passwd", "verbose": False, "dry_run": False, } # join needs start if is_member_of_group(self.server): leave(self.server, **options) # reconnect the server. self.server.connect() self.assertTrue(start(self.server, **options)) # reconnect the server. self.server.connect() # health health(self.server, **options) # reconnect the server. self.server.connect() leave(self.server, **options) # reconnect the server. self.server.connect() member_state_qry = ("SELECT MEMBER_STATE FROM {0} as m JOIN {1} " "as s on m.MEMBER_ID = s.MEMBER_ID" "".format(REP_GROUP_MEMBERS_TABLE, REP_MEMBER_STATS_TABLE)) frozen_queries = { member_state_qry: [['ONLINE', ], ], } mock_server = get_mock_server(self.server, queries=frozen_queries) # Join with defaults ("dry_run": True) and required password options = { "dry_run": True, "replication_user": "******", "rep_user_passwd": "passwd", } join(self.server, mock_server, **options) # reconnect the server. self.server.connect() # Join with no defaults ("dry_run": True) options = { "group_name": None, "gr_host": "{0}:{1}".format(self.server.host, self.server.port), "replication_user": "******", "rep_user_passwd": "passwd", "verbose": False, "dry_run": True, } # leave the group if is_member_of_group(self.server): leave(self.server, **options) self.assertFalse(join(self.server, mock_server, **options)) # reconnect the server. self.server.connect() self.assertFalse(leave(self.server, **options)) # reconnect the server. self.server.connect()