예제 #1
0
    def compare_databases(self, comment):
        """Compare databases.

        This method compares the databases replicated.

        comment[in]       Test comment.
        """
        # Compare command
        compare_cmd = "mysqldbcompare.py {0} {1} {2}:{2} {3}"
        from_conn = "--server1={0}".format(
            self.build_connection_string(self.server1))

        # Compare `inventory` database from master1
        to_conn = "--server2={0}".format(
            self.build_connection_string(self.server2))
        res = self.run_test_case(
            0,
            compare_cmd.format(from_conn, to_conn, "inventory",
                               ssl_util_opts()),
            "Comparing `inventory` database.")
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Compare `import_test` database from master2
        to_conn = "--server2={0}".format(
            self.build_connection_string(self.server3))
        res = self.run_test_case(
            0,
            compare_cmd.format(from_conn, to_conn, "import_test",
                               ssl_util_opts()),
            "Comparing `import_test` database.")
        if not res:
            raise MUTLibError("{0}: failed".format(comment))
예제 #2
0
    def compare_databases(self, comment):
        """Compare databases.

        This method compares the databases replicated.

        comment[in]       Test comment.
        """
        # Compare command
        compare_cmd = "mysqldbcompare.py {0} {1} {2}:{2} {3}"
        from_conn = "--server1={0}".format(
            self.build_connection_string(self.server1))

        # Compare `inventory` database from master1
        to_conn = "--server2={0}".format(
            self.build_connection_string(self.server2)
        )
        res = self.run_test_case(
            0,
            compare_cmd.format(from_conn, to_conn, "inventory",
                               ssl_util_opts()),
            "Comparing `inventory` database."
        )
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Compare `import_test` database from master2
        to_conn = "--server2={0}".format(
            self.build_connection_string(self.server3)
        )
        res = self.run_test_case(
            0,
            compare_cmd.format(from_conn, to_conn, "import_test",
                               ssl_util_opts()),
            "Comparing `import_test` database."
        )
        if not res:
            raise MUTLibError("{0}: failed".format(comment))
예제 #3
0
    def run(self):
        slave_str = "--slave={0}[{1}]".format(self.config_file_path,
                                              self.test_server_names[0])
        masters_str = "--masters={0}[{1}],{0}[{2}]".format(
            self.config_file_path, self.test_server_names[1],
            self.test_server_names[2])

        test_num = 1
        rplms_cmd = ("python ../scripts/mysqlrplms.py --log={0} --interval=5 "
                     "--switchover-interval=30 --rpl-user=rpl:rpl {1} {2} {3}"
                     "".format(_RPLMS_LOG.format(test_num), slave_str,
                               masters_str, ssl_util_opts()))
        comment = ("Test case {0} - Simple multi-source replication."
                   "".format(test_num))
        self.test_rplms(rplms_cmd, _RPLMS_LOG.format(test_num), comment, True)
        return True
예제 #4
0
    def run(self):
        slave_str = "--slave={0}[{1}]".format(self.config_file_path,
                                              self.test_server_names[0])
        masters_str = "--masters={0}[{1}],{0}[{2}]".format(
            self.config_file_path,
            self.test_server_names[1],
            self.test_server_names[2]
        )

        test_num = 1
        rplms_cmd = ("python ../scripts/mysqlrplms.py --log={0} --interval=5 "
                     "--switchover-interval=30 --rpl-user=rpl:rpl {1} {2} {3}"
                     "".format(_RPLMS_LOG.format(test_num), slave_str,
                               masters_str, ssl_util_opts()))
        comment = ("Test case {0} - Simple multi-source replication."
                   "".format(test_num))
        self.test_rplms(rplms_cmd, _RPLMS_LOG.format(test_num), comment, True)
        return True
예제 #5
0
    def run(self):
        cmd_base = "mysqlrplsync.py"
        master_con = self.build_connection_string(self.server1).strip(" ")
        slave1_con = self.build_connection_string(self.server2).strip(" ")
        slave2_con = self.build_connection_string(self.server3).strip(" ")
        slaves_con = "{0},{1}".format(slave1_con, slave2_con)

        # Check the data consistency of empty servers.
        test_num = 1
        comment = ("Test case {0} - check empty servers." "").format(test_num)
        cmd = "{0} --master={1} --slaves={2} {3}".format(cmd_base, master_con, slaves_con, ssl_util_opts())
        res = self.run_test_case(0, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Create example database on master and wait for it to be replicated
        # on all slaves.
        if self.debug:
            print("\nCreate test database and tables on master.")
        rpl_sync.create_test_db(self.server1)

        # Wait for slaves to catch up, otherwise mysqlrplsync might find tables
        # missing on slaves (which is normal).
        if self.debug:
            print("\nWait for slaves to catch up with master.")
        self.wait_for_slaves()

        # Load data on the master in a separated thread to perform the data
        # consistency checks at the same time.
        load_thread = threading.Thread(target=rpl_sync.load_test_data, args=(self.server1,))
        load_thread.daemon = True
        load_thread.start()
        if self.debug:
            print("\nThread to load/insert data started.")
            start_time = time.time()
            end_time = None

        # Check data consistency specifying the master and using discovery.
        test_num += 1
        comment = (
            "Test case {0} - data consistency check with active " "replication using master and slaves discovery." ""
        ).format(test_num)
        cmd = ("{0} --master={1} --discover-slaves-login=root:root {2}" "").format(
            cmd_base, master_con, ssl_util_opts()
        )
        res = self.run_test_case(0, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        if self.debug:
            alive = load_thread.is_alive()
            print("\nIs thread (loading data) still alive? " "{0}.".format(alive))
            if not alive and not end_time:
                end_time = time.time()
                print("\nTime to load data took less than: {0} " "sec.".format(end_time - start_time))
            else:
                print("\nWaiting for thread (loading data) to finish.")

        # Wait for all the data to finish to be loaded.
        load_thread.join()
        if self.debug and not end_time:
            end_time = time.time()
            print("\nTime to load data: {0} " "sec.".format(end_time - start_time))

        # Drop test database and recreate it on master.
        if self.debug:
            print("\nDrop test database on master.")
        rpl_sync.drop_test_db(self.server1)
        if self.debug:
            print("\nCreate test database and tables on master.")
        rpl_sync.create_test_db(self.server1)

        # Wait for slaves to catch up (avoiding non-deterministic results).
        if self.debug:
            print("\nWait for slaves to catch up with master.")
        self.wait_for_slaves()

        # Start a new thread to load/insert data (can only be started once).
        load_thread = threading.Thread(target=rpl_sync.load_test_data, args=(self.server1,))
        load_thread.daemon = True
        load_thread.start()
        if self.debug:
            print("\nThread to load/insert data started.")
            start_time = time.time()
            end_time = None

        # Check data consistency specifying only the slaves.
        test_num += 1
        comment = (
            "Test case {0} - data consistency check with active " "replication only between slaves (no master)." ""
        ).format(test_num)
        cmd = "{0} --slaves={1} {2}".format(cmd_base, slaves_con, ssl_util_opts())
        res = self.run_test_case(0, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        if self.debug:
            alive = load_thread.is_alive()
            print("\nIs thread (loading data) still alive? " "{0}.".format(alive))
            if not alive and not end_time:
                end_time = time.time()
                print("\nTime to load data took less than: {0} " "sec.".format(end_time - start_time))
            else:
                print("Waiting for thread (loading data) to finish.")

        # Wait for all the data to finish to be loaded.
        load_thread.join()
        if self.debug and not end_time:
            end_time = time.time()
            print("\nTime to load data: {0} " "sec.".format(end_time - start_time))

        # Perform data consistency check after loading all data.
        test_num += 1
        comment = ("Test case {0} - data consistency check between master and " "specified slaves.").format(test_num)
        cmd = "{0} --master={1} --slaves={2} {3}".format(cmd_base, master_con, slaves_con, ssl_util_opts())
        res = self.run_test_case(0, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Mask out non-deterministic data
        self.do_masks()

        return True
    def run(self):
        self.res_fname = "result.txt"

        master_conn = self.build_connection_string(self.server1).strip(" ")
        slave1_conn = self.build_connection_string(self.server2).strip(" ")
        slave2_conn = self.build_connection_string(self.server3).strip(" ")
        slave3_conn = self.build_connection_string(self.server4).strip(" ")
        slave4_conn = self.build_connection_string(self.server5).strip(" ")
        # Failover must work even with a slave that does not exist
        slave5_conn = "doesNotExist@localhost:999999999999"

        master_str = "--master={0}".format(master_conn)
        slaves_str = "--slaves={0}".format(
            ",".join([slave1_conn, slave2_conn, slave3_conn, slave5_conn])
        )
        self.test_results = []
        self.test_cases = []

        failover_cmd = (
            "{0} {1}"
            "".format("python ../scripts/mysqlfailover.py --interval=10 "
                      "--daemon={0} --discover-slaves-login=root:root {1} "
                      "--failover-mode={2} --log={3} "
                      "--exec-post-fail=\"{4}\" --timeout=5{5}",
                      ssl_util_opts())
        )

        i = 1
        cmd = failover_cmd.format("nodetach",
                                  " ".join([master_str, slaves_str]), "auto",
                                  _FAILOVER_LOG.format("1"),
                                  self.fail_event_script,
                                  " --candidates={0}".format(slave1_conn))
        self.test_cases.append(
            (self.server1, cmd, True, _FAILOVER_LOG.format("1"),
             "Test case {0} - Simple failover with --daemon=nodetach "
             "--failover=auto.".format(i),
             _FAILOVER_COMPLETE, False)
        )

        i += 1
        cmd = failover_cmd.format("nodetach",
                                  "--master={0}".format(slave1_conn), "elect",
                                  _FAILOVER_LOG.format("2"),
                                  self.fail_event_script,
                                  " --candidates={0} ".format(slave2_conn))
        self.test_cases.append(
            (self.server2, cmd, True, _FAILOVER_LOG.format("2"),
             "Test case {0} - Simple failover with --failover=elect."
             "".format(i), _FAILOVER_COMPLETE, True)
        )

        i += 1
        cmd = failover_cmd.format("nodetach",
                                  "--master={0}".format(slave2_conn), "fail",
                                  _FAILOVER_LOG.format("3"),
                                  self.fail_event_script, "")
        self.test_cases.append(
            (self.server3, cmd, False, _FAILOVER_LOG.format("3"),
             "Test case {0} - Simple failover with --failover=fail.".format(i),
             "Master has failed and automatic", True)
        )

        i += 1
        cmd = failover_cmd.format("nodetach",
                                  "--master={0}".format(slave3_conn), "fail",
                                  _FAILOVER_LOG.format("4"),
                                  self.fail_event_script, " --force")
        self.test_cases.append(
            (self.server4, cmd, False, _FAILOVER_LOG.format("4"),
             "Test case {0} - Test with --daemon=nodetach and --force on "
             "first run.".format(i), None, True)
        )

        # Run --daemon=nodetach tests
        for test_case in self.test_cases:
            res = self.test_failover_daemon_nodetach(test_case)
            if res:
                self.test_results.append(res)
            else:
                raise MUTLibError("{0}: failed".format(test_case[4]))

        i += 1
        comment = ("Test case {0} - Start failover with --daemon=start."
                   "".format(i))
        cmd_extra = " --pidfile={0}".format(_FAILOVER_PID.format("5"))
        cmd = failover_cmd.format("start",
                                  "--master={0}".format(slave4_conn), "auto",
                                  _FAILOVER_LOG.format("5"),
                                  self.fail_event_script, cmd_extra)

        res = self.test_failover_daemon(comment, cmd,
                                        _FAILOVER_LOG.format("5"),
                                        _FAILOVER_PID.format("5"), False)
        if res:
            self.test_results.append(res)
        else:
            raise MUTLibError("{0}: failed".format(comment))

        i += 1
        comment = ("Test case {0} - Restart failover by using --daemon="
                   "restart and then stop the daemon.".format(i))
        cmd = failover_cmd.format("restart",
                                  "--master={0}".format(slave4_conn), "auto",
                                  _FAILOVER_LOG.format("5"),
                                  self.fail_event_script, cmd_extra)

        res = self.test_failover_daemon(comment, cmd,
                                        _FAILOVER_LOG.format("5"),
                                        _FAILOVER_PID.format("5"), True)
        if res:
            self.test_results.append(res)
        else:
            raise MUTLibError("{0}: failed".format(comment))

        return True
예제 #7
0
    def run(self):
        cmd_base = "mysqlrplsync.py"
        master_con = self.build_connection_string(self.server1).strip(' ')
        slave1_con = self.build_connection_string(self.server2).strip(' ')
        slave2_con = self.build_connection_string(self.server3).strip(' ')
        slaves_con = "{0},{1}".format(slave1_con, slave2_con)

        # Check the data consistency of empty servers.
        test_num = 1
        comment = ("Test case {0} - check empty servers."
                   "").format(test_num)
        cmd = "{0} --master={1} --slaves={2} {3}".format(cmd_base, master_con,
                                                         slaves_con,
                                                         ssl_util_opts())
        res = self.run_test_case(0, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Create example database on master and wait for it to be replicated
        # on all slaves.
        if self.debug:
            print("\nCreate test database and tables on master.")
        rpl_sync.create_test_db(self.server1)

        # Wait for slaves to catch up, otherwise mysqlrplsync might find tables
        # missing on slaves (which is normal).
        if self.debug:
            print("\nWait for slaves to catch up with master.")
        self.wait_for_slaves()

        # Load data on the master in a separated thread to perform the data
        # consistency checks at the same time.
        load_thread = threading.Thread(target=rpl_sync.load_test_data,
                                       args=(self.server1,))
        load_thread.daemon = True
        load_thread.start()
        if self.debug:
            print("\nThread to load/insert data started.")
            start_time = time.time()
            end_time = None

        # Check data consistency specifying the master and using discovery.
        test_num += 1
        comment = ("Test case {0} - data consistency check with active "
                   "replication using master and slaves discovery."
                   "").format(test_num)
        cmd = ("{0} --master={1} --discover-slaves-login=root:root {2}"
               "").format(cmd_base, master_con, ssl_util_opts())
        res = self.run_test_case(0, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        if self.debug:
            alive = load_thread.is_alive()
            print("\nIs thread (loading data) still alive? "
                  "{0}.".format(alive))
            if not alive and not end_time:
                end_time = time.time()
                print("\nTime to load data took less than: {0} "
                      "sec.".format(end_time - start_time))
            else:
                print("\nWaiting for thread (loading data) to finish.")

        # Wait for all the data to finish to be loaded.
        load_thread.join()
        if self.debug and not end_time:
            end_time = time.time()
            print("\nTime to load data: {0} "
                  "sec.".format(end_time - start_time))

        # Drop test database and recreate it on master.
        if self.debug:
            print("\nDrop test database on master.")
        rpl_sync.drop_test_db(self.server1)
        if self.debug:
            print("\nCreate test database and tables on master.")
        rpl_sync.create_test_db(self.server1)

        # Wait for slaves to catch up (avoiding non-deterministic results).
        if self.debug:
            print("\nWait for slaves to catch up with master.")
        self.wait_for_slaves()

        # Start a new thread to load/insert data (can only be started once).
        load_thread = threading.Thread(target=rpl_sync.load_test_data,
                                       args=(self.server1,))
        load_thread.daemon = True
        load_thread.start()
        if self.debug:
            print("\nThread to load/insert data started.")
            start_time = time.time()
            end_time = None

        # Check data consistency specifying only the slaves.
        test_num += 1
        comment = ("Test case {0} - data consistency check with active "
                   "replication only between slaves (no master)."
                   "").format(test_num)
        cmd = "{0} --slaves={1} {2}".format(cmd_base, slaves_con,
                                            ssl_util_opts())
        res = self.run_test_case(0, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        if self.debug:
            alive = load_thread.is_alive()
            print("\nIs thread (loading data) still alive? "
                  "{0}.".format(alive))
            if not alive and not end_time:
                end_time = time.time()
                print("\nTime to load data took less than: {0} "
                      "sec.".format(end_time - start_time))
            else:
                print("Waiting for thread (loading data) to finish.")

        # Wait for all the data to finish to be loaded.
        load_thread.join()
        if self.debug and not end_time:
            end_time = time.time()
            print("\nTime to load data: {0} "
                  "sec.".format(end_time - start_time))

        # Perform data consistency check after loading all data.
        test_num += 1
        comment = ("Test case {0} - data consistency check between master and "
                   "specified slaves.").format(test_num)
        cmd = "{0} --master={1} --slaves={2} {3}".format(cmd_base, master_con,
                                                         slaves_con,
                                                         ssl_util_opts())
        res = self.run_test_case(0, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Mask out non-deterministic data
        self.do_masks()

        return True
    def run(self):
        test_num = 1

        master_conn = self.build_connection_string(self.server1).strip(' ')
        slave1_conn = self.build_connection_string(self.server2).strip(' ')
        slave2_conn = self.build_connection_string(self.server3).strip(' ')
        slave3_conn = self.build_connection_string(self.server4).strip(' ')

        comment = ("Test case {0} - SSL mysqlrplshow OLD Master "
                   "before demote".format(test_num))
        cmd_str = "mysqlrplshow.py --master={0} {1} ".format(master_conn,
                                                             ssl_util_opts())
        cmd_opts = "--discover-slaves={0} ".format(master_conn.split('@')[0])
        cmds = "{0} {1}".format(cmd_str, cmd_opts)
        res = self.run_test_case(0, cmds, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - SSL "
                   "switchover demote-master ".format(test_num))
        cmd_str = ("mysqlrpladmin.py --master={0} {1} "
                   ).format(master_conn, ssl_util_opts())
        cmd_opts = (" --new-master={0} --discover-slaves={1} "
                    "--rpl-user=rpluser:hispassword --demote-master "
                    "switchover".format(slave1_conn,
                                        master_conn.split('@')[0]))
        cmds = "{0} {1}".format(cmd_str, cmd_opts)
        res = self.run_test_case(0, cmds, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))
        self.results.append("\n")

        test_num += 1
        comment = ("Test case {0} - SSL mysqlrplshow "
                   "NEW Master after demote".format(test_num))
        cmd_str = "mysqlrplshow.py --master={0} {1}".format(slave1_conn,
                                                            ssl_util_opts())
        cmd_opts = " --discover-slaves={0} ".format(master_conn.split('@')[0])
        cmds = "{0} {1}".format(cmd_str, cmd_opts)
        res = self.run_test_case(0, cmds, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - SSL mysqlrplcheck "
                   "NEW Master after demote".format(test_num))
        cmd_opts = "--slave={0} --show-slave-status".format(master_conn)
        cmd_str = "mysqlrplcheck.py --master={0} {1} ".format(slave1_conn,
                                                              ssl_util_opts())
        cmds = "{0} {1}".format(cmd_str, cmd_opts)
        res = self.run_test_case(0, cmds, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))
        self.results.append("\n")

        test_num += 1
        comment = ("Test case {0} - SSL mysqlrplcheck "
                   "NEW Master after demote".format(test_num))
        cmd_opts = "--slave={0} --show-slave-status".format(slave2_conn)
        cmds = "{0} {1}".format(cmd_str, cmd_opts)
        res = self.run_test_case(0, cmds, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))
        self.results.append("\n")

        test_num += 1
        comment = ("Test case {0} - SSL mysqlrplcheck "
                   "NEW Master after demote".format(test_num))
        cmd_opts = "--slave={0} --show-slave-status".format(slave3_conn)
        cmds = "{0} {1}".format(cmd_str, cmd_opts)
        res = self.run_test_case(0, cmds, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))
        self.results.append("\n")

        test_num += 1
        comment = ("Test case {0} - SSL "
                   "failover ".format(test_num))
        cmd_str = "mysqlrpladmin.py {0} ".format(ssl_util_opts())
        slaves = ",".join([slave2_conn, slave3_conn,
                           master_conn])
        cmd_opts = (" --slaves={0} --rpl-user=rpluser:hispassword "
                    "failover".format(slaves))
        cmds = "{0} {1}".format(cmd_str, cmd_opts)
        res = self.run_test_case(0, cmds, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))
        self.results.append("\n")

        test_num += 1
        comment = ("Test case {0} - SSL mysqlrplshow "
                   "NEW Master after failover".format(test_num))
        cmd_str = "mysqlrplshow.py --master={0} {1}".format(slave2_conn,
                                                            ssl_util_opts())
        cmd_opts = " --discover-slaves={0} ".format(master_conn.split('@')[0])
        cmds = "{0} {1}".format(cmd_str, cmd_opts)
        res = self.run_test_case(0, cmds, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - SSL mysqlrplcheck "
                   "NEW Master after demote".format(test_num))
        cmd_str = "mysqlrplcheck.py --master={0} {1} ".format(slave2_conn,
                                                              ssl_util_opts())
        cmd_opts = "--slave={0} --show-slave-status".format(master_conn)
        cmds = "{0} {1}".format(cmd_str, cmd_opts)
        res = self.run_test_case(0, cmds, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))
        self.results.append("\n")

        test_num += 1
        comment = ("Test case {0} - SSL mysqlrplcheck "
                   "NEW Master after demote".format(test_num))
        cmd_opts = "--slave={0} --show-slave-status".format(slave3_conn)
        cmds = "{0} {1}".format(cmd_str, cmd_opts)
        res = self.run_test_case(0, cmds, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))
        self.results.append("\n")

        self.mask_results()
        return True
예제 #9
0
    def run_rpl_test(self,
                     slave,
                     master,
                     comment,
                     options=None,
                     save_for_compare=False,
                     expected_result=0,
                     save_results=True,
                     ssl=False,
                     config_path=False,
                     rpl_user='******',
                     rpl_pass='******',
                     ssl_opts=ssl_util_opts(),
                     use_rpl_user_group=False):
        """Run replication test.

        slave[in]               Slave instance.
        master[in]              Master instance.
        comment[in]             Test case comment.
        options[in]             Options.
        save_for_compare[in]    True for save compare
        expected_result[in]     Expected result.
        save_results[in]        True for save results.
        ssl[in]                 use ssl by default False.
        config_path[in]         use config-path by default False.
        rpl_user[in]            the rpl user name to use by default 'rpl'.
        rpl_pass[in]            the rpl user password to use by default 'rpl'.
        ssl_opts[in]            the ssl certificate options.
        use_rpl_user_group[in]  use rpl user from config-path by default false.
        """
        if not config_path:
            master_str = "--master={0}".format(
                self.build_connection_string(master))
        else:
            master_ = 'server_{0}'.format(master.port)
            master_str = "--master={0}[{1}]".format(self.config_file_path,
                                                    master_)
        if not config_path:
            slave_str = " --slave={0}".format(
                self.build_connection_string(slave))
        else:
            slave_ = 'server_{0}'.format(slave.port)
            slave_str = " --slave={0}[{1}]".format(self.config_file_path,
                                                   slave_)
        conn_str = '{0}{1}'.format(master_str, slave_str)

        # Test case 1 - setup replication among two servers
        if not save_for_compare:
            self.results.append(comment)
        if use_rpl_user_group:
            cmd = ("mysqlreplicate.py --rpl-user={0}[{1}] {2}").format(
                self.config_file_path, _RPL_USER_GROUP_NAME, conn_str)
        else:
            cmd = ("mysqlreplicate.py --rpl-user={0}:{1} {2}").format(
                rpl_user, rpl_pass, conn_str)
        if ssl:
            cmd = "{0} {1}".format(cmd, ssl_opts)
        if options:
            cmd = "{0} {1}".format(cmd, options)
        if not save_for_compare and save_results:
            self.results.append(cmd)
        res = self.exec_util(cmd, self.res_fname)
        if not save_for_compare and save_results:
            self.results.append(res)

        if res != expected_result:
            return False

        # Now test the result and record the action.
        try:
            res = slave.exec_query("SHOW SLAVE STATUS")
            if not save_for_compare and save_results:
                self.results.append(res)
        except UtilDBError as err:
            raise MUTLibError("Cannot show slave status: "
                              "{0}".format(err.errmsg))

        if save_for_compare:
            self.results.append(comment + "\n")
            with open(self.res_fname) as f:
                for line in f:
                    # Don't save lines that have [Warning]
                    index = line.find("[Warning]")
                    if index <= 0:
                        self.results.append(line)

        return True
예제 #10
0
    def run(self):
        self.res_fname = "result.txt"

        master_conn = self.build_connection_string(self.server1).strip(" ")
        slave1_conn = self.build_connection_string(self.server2).strip(" ")
        slave2_conn = self.build_connection_string(self.server3).strip(" ")
        slave3_conn = self.build_connection_string(self.server4).strip(" ")
        slave4_conn = self.build_connection_string(self.server5).strip(" ")
        # Failover must work even with a slave that does not exist
        slave5_conn = "doesNotExist@localhost:999999999999"

        master_str = "--master={0}".format(master_conn)
        slaves_str = "--slaves={0}".format(",".join(
            [slave1_conn, slave2_conn, slave3_conn, slave5_conn]))
        self.test_results = []
        self.test_cases = []

        failover_cmd = (
            "{0} {1}"
            "".format(
                "python ../scripts/mysqlfailover.py --interval=10 "
                "--daemon={0} --discover-slaves-login=root:root {1} "
                "--failover-mode={2} --log={3} "
                "--exec-post-fail=\"{4}\" --timeout=5{5}", ssl_util_opts()))

        i = 1
        cmd = failover_cmd.format("nodetach",
                                  " ".join([master_str, slaves_str]), "auto",
                                  _FAILOVER_LOG.format("1"),
                                  self.fail_event_script,
                                  " --candidates={0}".format(slave1_conn))
        self.test_cases.append(
            (self.server1, cmd, True, _FAILOVER_LOG.format("1"),
             "Test case {0} - Simple failover with --daemon=nodetach "
             "--failover=auto.".format(i), _FAILOVER_COMPLETE, False))

        i += 1
        cmd = failover_cmd.format("nodetach",
                                  "--master={0}".format(slave1_conn), "elect",
                                  _FAILOVER_LOG.format("2"),
                                  self.fail_event_script,
                                  " --candidates={0} ".format(slave2_conn))
        self.test_cases.append(
            (self.server2, cmd, True, _FAILOVER_LOG.format("2"),
             "Test case {0} - Simple failover with --failover=elect."
             "".format(i), _FAILOVER_COMPLETE, True))

        i += 1
        cmd = failover_cmd.format("nodetach",
                                  "--master={0}".format(slave2_conn), "fail",
                                  _FAILOVER_LOG.format("3"),
                                  self.fail_event_script, "")
        self.test_cases.append(
            (self.server3, cmd, False, _FAILOVER_LOG.format("3"),
             "Test case {0} - Simple failover with --failover=fail.".format(i),
             "Master has failed and automatic", True))

        i += 1
        cmd = failover_cmd.format("nodetach",
                                  "--master={0}".format(slave3_conn), "fail",
                                  _FAILOVER_LOG.format("4"),
                                  self.fail_event_script, " --force")
        self.test_cases.append(
            (self.server4, cmd, False, _FAILOVER_LOG.format("4"),
             "Test case {0} - Test with --daemon=nodetach and --force on "
             "first run.".format(i), None, True))

        # Run --daemon=nodetach tests
        for test_case in self.test_cases:
            res = self.test_failover_daemon_nodetach(test_case)
            if res:
                self.test_results.append(res)
            else:
                raise MUTLibError("{0}: failed".format(test_case[4]))

        i += 1
        comment = ("Test case {0} - Start failover with --daemon=start."
                   "".format(i))
        cmd_extra = " --pidfile={0}".format(_FAILOVER_PID.format("5"))
        cmd = failover_cmd.format("start", "--master={0}".format(slave4_conn),
                                  "auto", _FAILOVER_LOG.format("5"),
                                  self.fail_event_script, cmd_extra)

        res = self.test_failover_daemon(comment, cmd,
                                        _FAILOVER_LOG.format("5"),
                                        _FAILOVER_PID.format("5"), False)
        if res:
            self.test_results.append(res)
        else:
            raise MUTLibError("{0}: failed".format(comment))

        i += 1
        comment = ("Test case {0} - Restart failover by using --daemon="
                   "restart and then stop the daemon.".format(i))
        cmd = failover_cmd.format("restart",
                                  "--master={0}".format(slave4_conn), "auto",
                                  _FAILOVER_LOG.format("5"),
                                  self.fail_event_script, cmd_extra)

        res = self.test_failover_daemon(comment, cmd,
                                        _FAILOVER_LOG.format("5"),
                                        _FAILOVER_PID.format("5"), True)
        if res:
            self.test_results.append(res)
        else:
            raise MUTLibError("{0}: failed".format(comment))

        return True
    def run(self):
        test_num = 1

        master_conn = self.build_connection_string(self.server1).strip(' ')
        slave1_conn = self.build_connection_string(self.server2).strip(' ')
        slave2_conn = self.build_connection_string(self.server3).strip(' ')
        slave3_conn = self.build_connection_string(self.server4).strip(' ')

        comment = ("Test case {0} - SSL mysqlrplshow OLD Master "
                   "before demote".format(test_num))
        cmd_str = "mysqlrplshow.py --master={0} {1} ".format(
            master_conn, ssl_util_opts())
        cmd_opts = "--discover-slaves={0} ".format(master_conn.split('@')[0])
        cmds = "{0} {1}".format(cmd_str, cmd_opts)
        res = self.run_test_case(0, cmds, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - SSL "
                   "switchover demote-master ".format(test_num))
        cmd_str = ("mysqlrpladmin.py --master={0} {1} ").format(
            master_conn, ssl_util_opts())
        cmd_opts = (" --new-master={0} --discover-slaves={1} "
                    "--rpl-user=rpluser:hispassword --demote-master "
                    "switchover".format(slave1_conn,
                                        master_conn.split('@')[0]))
        cmds = "{0} {1}".format(cmd_str, cmd_opts)
        res = self.run_test_case(0, cmds, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))
        self.results.append("\n")

        test_num += 1
        comment = ("Test case {0} - SSL mysqlrplshow "
                   "NEW Master after demote".format(test_num))
        cmd_str = "mysqlrplshow.py --master={0} {1}".format(
            slave1_conn, ssl_util_opts())
        cmd_opts = " --discover-slaves={0} ".format(master_conn.split('@')[0])
        cmds = "{0} {1}".format(cmd_str, cmd_opts)
        res = self.run_test_case(0, cmds, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - SSL mysqlrplcheck "
                   "NEW Master after demote".format(test_num))
        cmd_opts = "--slave={0} --show-slave-status".format(master_conn)
        cmd_str = "mysqlrplcheck.py --master={0} {1} ".format(
            slave1_conn, ssl_util_opts())
        cmds = "{0} {1}".format(cmd_str, cmd_opts)
        res = self.run_test_case(0, cmds, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))
        self.results.append("\n")

        test_num += 1
        comment = ("Test case {0} - SSL mysqlrplcheck "
                   "NEW Master after demote".format(test_num))
        cmd_opts = "--slave={0} --show-slave-status".format(slave2_conn)
        cmds = "{0} {1}".format(cmd_str, cmd_opts)
        res = self.run_test_case(0, cmds, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))
        self.results.append("\n")

        test_num += 1
        comment = ("Test case {0} - SSL mysqlrplcheck "
                   "NEW Master after demote".format(test_num))
        cmd_opts = "--slave={0} --show-slave-status".format(slave3_conn)
        cmds = "{0} {1}".format(cmd_str, cmd_opts)
        res = self.run_test_case(0, cmds, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))
        self.results.append("\n")

        test_num += 1
        comment = ("Test case {0} - SSL " "failover ".format(test_num))
        cmd_str = "mysqlrpladmin.py {0} ".format(ssl_util_opts())
        slaves = ",".join([slave2_conn, slave3_conn, master_conn])
        cmd_opts = (" --slaves={0} --rpl-user=rpluser:hispassword "
                    "failover".format(slaves))
        cmds = "{0} {1}".format(cmd_str, cmd_opts)
        res = self.run_test_case(0, cmds, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))
        self.results.append("\n")

        test_num += 1
        comment = ("Test case {0} - SSL mysqlrplshow "
                   "NEW Master after failover".format(test_num))
        cmd_str = "mysqlrplshow.py --master={0} {1}".format(
            slave2_conn, ssl_util_opts())
        cmd_opts = " --discover-slaves={0} ".format(master_conn.split('@')[0])
        cmds = "{0} {1}".format(cmd_str, cmd_opts)
        res = self.run_test_case(0, cmds, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - SSL mysqlrplcheck "
                   "NEW Master after demote".format(test_num))
        cmd_str = "mysqlrplcheck.py --master={0} {1} ".format(
            slave2_conn, ssl_util_opts())
        cmd_opts = "--slave={0} --show-slave-status".format(master_conn)
        cmds = "{0} {1}".format(cmd_str, cmd_opts)
        res = self.run_test_case(0, cmds, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))
        self.results.append("\n")

        test_num += 1
        comment = ("Test case {0} - SSL mysqlrplcheck "
                   "NEW Master after demote".format(test_num))
        cmd_opts = "--slave={0} --show-slave-status".format(slave3_conn)
        cmds = "{0} {1}".format(cmd_str, cmd_opts)
        res = self.run_test_case(0, cmds, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))
        self.results.append("\n")

        self.mask_results()
        return True
예제 #12
0
    def run_rpl_test(self, slave, master, comment, options=None,
                     save_for_compare=False, expected_result=0,
                     save_results=True, ssl=False, config_path=False,
                     rpl_user='******', rpl_pass='******',
                     ssl_opts=ssl_util_opts(), use_rpl_user_group=False):
        """Run replication test.

        slave[in]               Slave instance.
        master[in]              Master instance.
        comment[in]             Test case comment.
        options[in]             Options.
        save_for_compare[in]    True for save compare
        expected_result[in]     Expected result.
        save_results[in]        True for save results.
        ssl[in]                 use ssl by default False.
        config_path[in]         use config-path by default False.
        rpl_user[in]            the rpl user name to use by default 'rpl'.
        rpl_pass[in]            the rpl user password to use by default 'rpl'.
        ssl_opts[in]            the ssl certificate options.
        use_rpl_user_group[in]  use rpl user from config-path by default false.
        """
        if not config_path:
            master_str = "--master={0}".format(
                self.build_connection_string(master))
        else:
            master_ = 'server_{0}'.format(master.port)
            master_str = "--master={0}[{1}]".format(self.config_file_path,
                                                    master_)
        if not config_path:
            slave_str = " --slave={0}".format(
                self.build_connection_string(slave))
        else:
            slave_ = 'server_{0}'.format(slave.port)
            slave_str = " --slave={0}[{1}]".format(self.config_file_path,
                                                   slave_)
        conn_str = '{0}{1}'.format(master_str, slave_str)

        # Test case 1 - setup replication among two servers
        if not save_for_compare:
            self.results.append(comment)
        if use_rpl_user_group:
            cmd = ("mysqlreplicate.py --rpl-user={0}[{1}] {2}"
                   ).format(self.config_file_path, _RPL_USER_GROUP_NAME,
                            conn_str)
        else:
            cmd = ("mysqlreplicate.py --rpl-user={0}:{1} {2}"
                   ).format(rpl_user, rpl_pass, conn_str)
        if ssl:
            cmd = "{0} {1}".format(cmd, ssl_opts)
        if options:
            cmd = "{0} {1}".format(cmd, options)
        if not save_for_compare and save_results:
            self.results.append(cmd)
        res = self.exec_util(cmd, self.res_fname)
        if not save_for_compare and save_results:
            self.results.append(res)

        if res != expected_result:
            return False

        # Now test the result and record the action.
        try:
            res = slave.exec_query("SHOW SLAVE STATUS")
            if not save_for_compare and save_results:
                self.results.append(res)
        except UtilDBError as err:
            raise MUTLibError("Cannot show slave status: "
                              "{0}".format(err.errmsg))

        if save_for_compare:
            self.results.append(comment + "\n")
            with open(self.res_fname) as f:
                for line in f:
                    # Don't save lines that have [Warning]
                    index = line.find("[Warning]")
                    if index <= 0:
                        self.results.append(line)

        return True