def get_result(self):
        msg = []
        copied_db_on_server2 = [
            'util_db_clone', 'util_test', 'util_test_multi', 'db`:db_clone',
            'db`:db', 'views_test_clone', 'util_db_privileges',
            'blob_test_clone', 'blob_test_multi',
            'blob_test_no_backslash_escapes', 'util"test_copy',
            'util"test_no_backslash_escapes'
        ]
        copied_db_on_server1 = [
            "util_test_default_collation_copy",
            "util_test_default_charset_copy"
        ]

        # Check databases existence.
        query = "SHOW DATABASES LIKE '{0}'"
        for db in copied_db_on_server2:
            try:
                res = self.server2.exec_query(query.format(db))
                try:
                    if res[0][0] != db:
                        msg.append("Database {0} not found in {1}.\n"
                                   "".format(db, self.server2.role))
                except IndexError:
                    msg.append("Database {0} not found in {1}.\n"
                               "".format(db, self.server2.role))
            except UtilDBError as err:
                raise MUTLibError(err.errmsg)
        for db in copied_db_on_server1:
            try:
                res = self.server1.exec_query(query.format(db))
                try:
                    if res[0][0] != db:
                        msg.append("Database {0} not found in {1}.\n"
                                   "".format(db, self.server1.role))
                except IndexError:
                    msg.append("Database {0} not found in {1}.\n"
                               "".format(db, self.server1.role))
            except UtilDBError as err:
                raise MUTLibError(err.errmsg)

        # Compare table checksums.
        dbs2compare = [('`util_test`',
                        ('`util_test`', '`util_db_clone`', '`util_test_multi`',
                         '`util_db_privileges`')),
                       ('`db``:db`', ('`db``:db`', '`db``:db_clone`')),
                       ('`views_test`', ('`views_test_clone`', )),
                       ('blob_test', ('blob_test_clone', 'blob_test_multi',
                                      'blob_test_no_backslash_escapes'))]
        for cmp_data in dbs2compare:
            self.server1.exec_query("USE {0}".format(cmp_data[0]))
            res = self.server1.exec_query("SHOW TABLES")
            for row in res:
                table = quote_with_backticks(row[0], self.prev_sql_mode)
                base_checksum = self.server1.exec_query(
                    "CHECKSUM TABLE {0}".format(table))[0][1]
                for i in range(len(cmp_data[1])):
                    tbl_checksum = self.server2.exec_query(
                        "CHECKSUM TABLE {0}.{1}".format(cmp_data[1][i],
                                                        table))[0][1]
                    if tbl_checksum != base_checksum:
                        msg.append("Different table checksum for table "
                                   "{0}.{1}, got {2} expected "
                                   "{3}.".format(cmp_data[1][i], table,
                                                 tbl_checksum, base_checksum))

        # Check attributes (character set and collation).
        qry_db = ("SELECT {0} FROM INFORMATION_SCHEMA.SCHEMATA "
                  "WHERE SCHEMA_NAME = '{1}'")
        qry_tb = ("SELECT CCSA.{0} "
                  "FROM information_schema.`TABLES` T, "
                  "information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY`"
                  " CCSA WHERE CCSA.collation_name = T.table_collation "
                  " AND T.table_schema = '{1}' AND T.table_name = 't1'")
        check_db_info_on_server1 = [
            ("util_test_default_collation_copy", "DEFAULT_COLLATION_NAME",
             "utf8_general_ci", "COLLATION_NAME"),
            ("util_test_default_charset_copy", "DEFAULT_CHARACTER_SET_NAME",
             "utf8", "CHARACTER_SET_NAME")
        ]
        for db in check_db_info_on_server1:
            try:
                res = self.server1.exec_query(qry_db.format(db[1], db[0]))
                try:
                    if res[0][0] != db[2]:
                        msg.append("For database {0} attribute {1} copy "
                                   "failed, got {2} expected {3}.\n"
                                   "".format(db[0], db[1], res[0][0], db[2]))
                except IndexError:
                    msg.append("For database {0} no value found for attribute "
                               "{1}.\n".format(db[0], db[1]))

                res = self.server1.exec_query(qry_tb.format(db[3], db[0]))
                try:
                    if res[0][0] != db[2]:
                        msg.append("For table {0} attribute {1} copy "
                                   "failed, got {2} expected {3}.\n"
                                   "".format(db[0], db[3], res[0][0], db[2]))
                except IndexError:
                    msg.append("For table {0} no value found for attribute "
                               "{1}.\n".format(db[0], db[3]))
            except UtilDBError as err:
                raise MUTLibError(err.errmsg)
        if msg:
            return False, ("Result failure.\n", "\n".join(msg))
        else:
            return True, ""
Beispiel #2
0
    def run(self):
        self.server1 = self.servers.get_server(0)
        self.res_fname = "result.txt"

        s1_conn = "--server1={0}".format(
            self.build_connection_string(self.server1))
        s2_conn = "--server2={0}".format(
            self.build_connection_string(self.server2))

        cmd_base = "mysqldiff.py {0} {1} util_test:util_test".format(
            s1_conn, s2_conn)

        test_num = 1
        cmd_opts = "--help"
        comment = "Test case {0} - Use {1} ".format(test_num, cmd_opts)
        cmd = "{0} {1}".format(cmd_base, cmd_opts)
        res = self.run_test_case(0, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        for compacted in _COMPACT_OUTPUT:
            for frmt in _FORMATS:
                test_num += 1
                cmd_opts = "--difftype={0}{1}".format(frmt, compacted)
                comment = "Test case {0} - Use diff {1}".format(
                    test_num, cmd_opts)
                cmd = "{0} {1}".format(cmd_base, cmd_opts)
                res = self.run_test_case(1, cmd, comment)
                if not res:
                    raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        cmd_opts = "--force"
        comment = "Test case {0} - Use {1} ".format(test_num, cmd_opts)
        cmd = "{0} {1}".format(cmd_base, cmd_opts)
        res = self.run_test_case(1, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        cmd_opts = "--quiet"
        comment = "Test case {0} - Use {1} ".format(test_num, cmd_opts)
        cmd = "{0} {1}".format(cmd_base, cmd_opts)
        res = self.run_test_case(1, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        cmd_opts = "--width=65"
        comment = "Test case {0} - Use {1} ".format(test_num, cmd_opts)
        cmd = "{0} {1}".format(cmd_base, cmd_opts)
        res = self.run_test_case(1, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        cmd_opts = "--width=55"
        comment = "Test case {0} - Use {1} ".format(test_num, cmd_opts)
        cmd = "{0} {1}".format(cmd_base, cmd_opts)
        res = self.run_test_case(1, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        cmd_opts = "-vvv"
        comment = "Test case {0} - Use {1} ".format(test_num, cmd_opts)
        cmd = "{0} {1}".format(cmd_base, cmd_opts)
        res = self.run_test_case(1, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Test --changes-for and reverse
        for direct in _DIRECTIONS:
            test_num += 1
            cmd_opts = "--changes-for={0} ".format(direct)
            comment = "Test case {0} - Use {1} ".format(test_num, cmd_opts)
            cmd = "{0} {1}".format(cmd_base, cmd_opts)
            res = self.run_test_case(1, cmd, comment)
            if not res:
                raise MUTLibError("{0}: failed".format(comment))
                # now with reverse
            test_num += 1
            cmd_opts = "--changes-for={0} --show-reverse".format(direct)
            comment = "Test case {0} - Use {1} ".format(test_num, cmd_opts)
            cmd = "{0} {1}".format(cmd_base, cmd_opts)
            res = self.run_test_case(1, cmd, comment)
            if not res:
                raise MUTLibError("{0}: failed".format(comment))

        # Test use of --skip-table-options (different AUTO_INCREMENT)
        difftype_options = ['', '--difftype=context', '--difftype=sql']
        cmd_base = ("mysqldiff.py {0} {1} "
                    "db_diff_test:db_diff_test".format(s1_conn, s2_conn))
        for difftype_opt in difftype_options:
            for direct in _DIRECTIONS:
                test_num += 1
                comment = ("Test case {0}a - Changes for {1} {2} (not "
                           "skipping table options).".format(
                               test_num, direct, difftype_opt))
                cmd = "{0} --changes-for={1} {2}".format(
                    cmd_base, direct, difftype_opt)
                res = self.run_test_case(1, cmd, comment)
                if not res:
                    raise MUTLibError("{0}: failed".format(comment))
                comment = ("Test case {0}b - Changes for {1} {2} (skipping "
                           "table options).".format(test_num, direct,
                                                    difftype_opt))
                cmd = ("{0} --changes-for={1} {2} "
                       "--skip-table-options".format(cmd_base, direct,
                                                     difftype_opt))
                res = self.run_test_case(0, cmd, comment)
                if not res:
                    raise MUTLibError("{0}: failed".format(comment))

        # Now test for difftype=SQL and skip-table-options when there is
        # only one table with table options.
        self.server1.exec_query(_CREATE_FIRST_TABLE)
        self.server2.exec_query(_CREATE_SECOND_TABLE)
        test_num += 1
        cmd = "{0}{1}{2}{3}{4} {5}".format("mysqldiff.py ", "--difftype=SQL ",
                                           "--skip-table-options ",
                                           "util_test.a1:util_test.a1 ",
                                           s1_conn, s2_conn)
        comment = "Test case {0} - Use --skip-table-options ".format(test_num)
        res = self.run_test_case(1, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # The following are necessary due to changes in character spaces
        # introduced with Python 2.7.X in the difflib.
        self.replace_result("+++ util_test.t1", "+++ util_test.t1\n")
        self.replace_result("+++ util_test.t2", "+++ util_test.t2\n")
        self.replace_result("--- util_test.t1", "--- util_test.t1\n")
        self.replace_result("--- util_test.t2", "--- util_test.t2\n")
        self.replace_result("*** util_test.t1", "*** util_test.t1\n")
        self.replace_result("*** util_test.t2", "*** util_test.t2\n")
        self.replace_substring("on [::1]", "on localhost")

        # Mask version
        self.replace_result("MySQL Utilities mysqldiff version",
                            "MySQL Utilities mysqldiff version X.Y.Z\n")

        return True
Beispiel #3
0
 def check_prerequisites(self):
     # Check MySQL server version - Must be 5.6.9 or higher
     if not self.servers.get_server(0).check_version_compat(5, 6, 9):
         raise MUTLibError("Test requires server version 5.6.9 or higher")
     return self.check_num_servers(1)
    def run(self):
        self.res_fname = "result.txt"
        server_conn = "--server={0}".format(
            self.build_connection_string(self.server2))

        master_conn = "--master={0}".format(
            self.build_connection_string(self.server2))

        self.res_fname = "result.txt"
        server_conn3 = "--server={0}".format(
            self.build_connection_string(self.server3))

        master_conn3 = "--master={0}".format(
            self.build_connection_string(self.server3))

        cmd_str = "mysqlbinlogpurge.py {0}"

        test_num = 1
        comment = ("Test case {0} - No options" "".format(test_num))
        cmd = "mysqlbinlogpurge.py"
        res = self.run_test_case(2, cmd, comment)
        if not res or not binlog_file_exists(self.server2_datadir,
                                             "mysql-bin.000001", self.debug):
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - Master no Slave options"
                   "".format(test_num))
        cmd = cmd_str.format(master_conn)
        res = self.run_test_case(2, cmd, comment)
        if not res or not binlog_file_exists(self.server2_datadir,
                                             "mysql-bin.000001", self.debug):
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - Server with Slave option"
                   "".format(test_num))
        cmd = "{0} --slave={1}".format(
            cmd_str.format(server_conn),
            self.build_connection_string(self.server2))
        res = self.run_test_case(2, cmd, comment)
        if not res or not binlog_file_exists(self.server2_datadir,
                                             "mysql-bin.000001", self.debug):
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - Server without binlog" "".format(test_num))
        cmd = "{0} ".format(cmd_str.format(server_conn3),
                            self.build_connection_string(self.server2))
        res = self.run_test_case(1, cmd, comment)
        if not res or not binlog_file_exists(self.server2_datadir,
                                             "mysql-bin.000001", self.debug):
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - Master with wrong Slave"
                   "".format(test_num))
        cmd = "{0} --slave={1}".format(
            cmd_str.format(master_conn3),
            self.build_connection_string(self.server2))
        res = self.run_test_case(1, cmd, comment)
        if not res or not binlog_file_exists(self.server2_datadir,
                                             "mysql-bin.000001", self.debug):
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - Server with Discover option"
                   "".format(test_num))
        cmd = "{0} --discover={1}".format(cmd_str.format(server_conn),
                                          "root:rootpass")
        res = self.run_test_case(2, cmd, comment)
        if not res or not binlog_file_exists(self.server2_datadir,
                                             "mysql-bin.000001", self.debug):
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - Only discover option" "".format(test_num))
        cmd = "mysqlbinlogpurge.py --discover={0}".format("root:rootpass")
        res = self.run_test_case(2, cmd, comment)
        if not res or not binlog_file_exists(self.server2_datadir,
                                             "mysql-bin.000001", self.debug):
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - Only slaves option" "".format(test_num))
        cmd = "mysqlbinlogpurge.py --slaves={0}".format(server_conn)
        res = self.run_test_case(2, cmd, comment)
        if not res or not binlog_file_exists(self.server2_datadir,
                                             "mysql-bin.000001", self.debug):
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - Only dry-run and verbose options"
                   "".format(test_num))
        cmd = "{0} -vv -d".format("mysqlbinlogpurge.py")
        res = self.run_test_case(2, cmd, comment)
        if not res or not binlog_file_exists(self.server2_datadir,
                                             "mysql-bin.000001", self.debug):
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - wrong binlog base name"
                   "".format(test_num))
        cmd = "{0} --binlog={1}".format(cmd_str.format(server_conn),
                                        "wrong_binlog_name.00002")
        res = self.run_test_case(1, cmd, comment)
        if not res or not binlog_file_exists(self.server2_datadir,
                                             "mysql-bin.000001", self.debug):
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - server and master options mixed"
                   "".format(test_num))
        cmd = "{0} {1}".format(cmd_str.format(server_conn), master_conn)
        res = self.run_test_case(2, cmd, comment)
        if not res or not binlog_file_exists(self.server2_datadir,
                                             "mysql-bin.000001", self.debug):
            raise MUTLibError("{0}: failed".format(comment))

        # Mask results
        self.replace_substring("localhost", "XXXX-XXXX")
        p_n = 0
        for port in self.mask_ports:
            p_n += 1
            self.replace_substring(repr(port), "PORT{0}".format(p_n))

        return True
Beispiel #5
0
    def run(self):

        # Get the engines for the tables and save them for compare
        #
        # Note: This may show different result file if run on a server whose
        # default storage engine is set differently than version 5.1.
        #
        def _get_engines():
            for table_name in _TABLES:
                res = self.server1.exec_query(_ENGINE_QUERY % table_name)
                if res == []:
                    self.results.append("util_test.%s: ENGINE NOT FOUND!\n")
                else:
                    self.results.append("util_test.%s: ENGINE=%s\n" %
                                        (table_name, res[0][0]))

        self.res_fname = "result.txt"
        import_basic.test.drop_all(self)

        to_conn = "--server=" + self.build_connection_string(self.server1)

        import_file = os.path.normpath("./std_data/bad_engine.csv")
        case_num = 1

        cmd_str = "mysqldbimport.py %s %s --import=both --format=CSV " % \
                  (to_conn, import_file)
        comment = "Test case %d - Normal run" % case_num
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("%s: failed" % comment)
        case_num += 1

        _get_engines()

        cmd_str = "mysqldbimport.py %s %s --import=definitions " % \
                  (to_conn, import_file)
        cmd_str += "--new-storage-engine=MEMORY --drop-first --format=CSV"
        comment = "Test case %d - convert to memory storage engine" % case_num
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("%s: failed" % comment)
        case_num += 1

        _get_engines()

        cmd_str = "mysqldbimport.py %s %s --import=definitions " % \
                  (to_conn, import_file)
        cmd_str += "--new-storage-engine=NOTTHERE --drop-first --format=CSV"
        comment = "Test case %d - new storage engine missing" % case_num
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("%s: failed" % comment)
        case_num += 1

        _get_engines()

        cmd_str = "mysqldbimport.py %s %s --import=definitions " % \
                  (to_conn, import_file)
        cmd_str += "--default-storage-engine=NOPENOTHERE --drop-first" + \
                   " --format=CSV"
        comment = "Test case %d - default storage engine missing" % case_num
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("%s: failed" % comment)
        case_num += 1

        _get_engines()

        cmd_str = "mysqldbimport.py %s %s --import=definitions  " % \
                  (to_conn, import_file)
        cmd_str += "--new-storage-engine=NOTTHERE --drop-first --format=CSV "
        cmd_str += "--default-storage-engine=INNODB "
        comment = "Test case %d - new storage engine missing, default Ok" % \
                  case_num
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("%s: failed" % comment)
        case_num += 1

        _get_engines()

        cmd_str = "mysqldbimport.py %s %s --import=definitions " % \
                  (to_conn, import_file)
        cmd_str += "--default-storage-engine=NOPENOTHERE --drop-first" + \
                   " --format=CSV "
        cmd_str += "--new-storage-engine=MYISAM"
        comment = "Test case %d - default storage engine missing, new Ok" % \
                  case_num
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("%s: failed" % comment)
        case_num += 1

        _get_engines()

        self.replace_result("# Importing", "# Importing ... bad_engines.csv\n")

        return True
Beispiel #6
0
    def check_prerequisites(self):
        if self.servers.get_server(0).check_version_compat(5, 6, 5):
            raise MUTLibError("Test requires server version prior to 5.6.5")

        return copy_db_rpl.test.check_prerequisites(self)
class test(import_basic.test):
    """check parameters for import utility
    This test executes a basic check of parameters for mysqldbimport.
    It uses the import_basic test as a parent for setup and teardown methods.
    """
    def check_prerequisites(self):
        return import_basic.test.check_prerequisites(self)

    def setup(self):
        return import_basic.test.setup(self)

    def do_skip_test(self, cmd_str, comment, expected_res=0):
        # Precheck: check db and save the results.
        self.results.append("BEFORE:\n")
        self.results.append(self.check_objects(self.server2, "util_test"))

        res = self.run_test_case(expected_res, cmd_str, comment)
        if not res:
            raise MUTLibError("%s: failed" % comment)

        # Now, check db and save the results.
        self.results.append("AFTER:\n")
        res = self.server2.exec_query("SHOW DATABASES LIKE 'util_test'")
        if res == () or res == []:
            self.results.append("Database was NOT created.\n")
        else:
            self.results.append("Database was created.\n")
        self.results.append(self.check_objects(self.server2, "util_test"))
        try:
            self.drop_db(self.server2, "util_test")
        except:
            pass  # ok if this fails - it is a spawned server

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

        from_conn = "--server=" + self.build_connection_string(self.server1)
        to_conn = "--server=" + self.build_connection_string(self.server2)

        cmd_str = "mysqldbimport.py %s %s --import=definitions " % \
                  (to_conn, self.export_import_file)

        cmd_opts = " --help"
        comment = "Test case 1 - help"
        res = self.run_test_case(0, cmd_str + cmd_opts, comment)
        if not res:
            raise MUTLibError("%s: failed" % comment)

        # Now test the skips

        # Note: data and blobs must be done separately
        _SKIPS = ("grants", "events", "functions", "procedures", "triggers",
                  "views", "tables", "create_db")
        _FORMATS = ("CSV", "SQL")

        case_num = 2
        for format in _FORMATS:
            # Create an import file
            export_cmd = "mysqldbexport.py %s util_test --export=BOTH " % \
                         from_conn + " --skip-gtid "
            export_cmd += "--format=%s --display=BRIEF > %s " % \
                          (format, self.export_import_file)
            comment = "Generating import file"
            res = self.run_test_case(0, export_cmd, comment)
            if not res:
                raise MUTLibError("%s: failed" % comment)

            cmd_opts = "%s --format=%s --skip=" % (cmd_str, format)
            for skip in _SKIPS:
                if case_num != 2 and case_num != 2 + len(_SKIPS):
                    cmd_opts += ","
                cmd_opts += "%s" % skip
                comment = "Test case %d - no %s" % (case_num, skip)
                self.do_skip_test(cmd_opts, comment)
                case_num += 1

        # Now test --skip=data, --skip-blobs
        # Create an import file with blobs

        try:
            res = self.server1.exec_query("ALTER TABLE util_test.t3 "
                                          "ADD COLUMN me_blob BLOB")
            res = self.server1.exec_query("UPDATE util_test.t3 SET "
                                          "me_blob = 'This, is a BLOB!'")
        except UtilDBError, e:
            raise MUTLibError("Failed to add blob column: %s" % e.errmsg)

        export_cmd = "mysqldbexport.py %s util_test --export=BOTH " % \
                     from_conn + " --skip-gtid "
        export_cmd += "--format=%s --display=BRIEF > %s " % \
                      ("CSV", self.export_import_file)
        comment = "Generating import file"
        res = self.run_test_case(0, export_cmd, comment)
        if not res:
            raise MUTLibError("%s: failed" % comment)

        # No skips for reference (must skip events for deterministic reasons
        cmd_str = "mysqldbimport.py %s %s --import=both --dryrun " % \
                  (to_conn, self.export_import_file)
        cmd_str += " --format=CSV --bulk-insert "
        comment = "Test case %d - no %s" % (case_num, "events")
        res = self.run_test_case(0, cmd_str + "--skip=events", comment)
        if not res:
            raise MUTLibError("%s: failed" % comment)
        case_num += 1

        cmd_str = "mysqldbimport.py %s %s --import=both --dryrun " % \
                  (to_conn, self.export_import_file)
        cmd_str += " --format=CSV --bulk-insert "
        comment = "Test case %d - no %s" % (case_num, "data")
        res = self.run_test_case(0, cmd_str + "--skip=events,data", comment)
        if not res:
            raise MUTLibError("%s: failed" % comment)
        case_num += 1

        cmd_str = "mysqldbimport.py %s %s --import=both --dryrun " % \
                  (to_conn, self.export_import_file)
        cmd_str += " --format=CSV --skip-blobs --bulk-insert "
        comment = "Test case %d - no %s" % (case_num, "blobs")
        res = self.run_test_case(0, cmd_str + "--skip=events", comment)
        if not res:
            raise MUTLibError("%s: failed" % comment)
        case_num += 1

        # Lastly, do a quiet import

        cmd_str = "mysqldbimport.py %s %s --import=both --quiet " % \
                  (to_conn, self.export_import_file)
        cmd_str += " --format=CSV --bulk-insert "
        comment = "Test case %d - no %s" % (case_num, "messages (quiet)")
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("%s: failed" % comment)
        case_num += 1

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

        conn_str = self.build_connection_string(self.server1, ssl=True)
        conn_str_nossl = self.build_connection_string(self.server1, ssl=False)
        conn_ssl_opt = self.build_custom_connection_string(self.server1,
                                                           'ssl_opt',
                                                           'ssl_opt_pass')

        tests = []

        # ======== mysqlindexcheck ========= #
        tests.append({
            "utility": "mysqlindexcheck",
            "cmd_str": "mysqlindexcheck.py --server={0}",
            "comment": ("Test case {0} {1} - indexcheck with ssl connection "
                        "all tables for a single database"),
            "cmd_opts": "util_test_a"
        })

        # ======== mysqlserverinfo ========= #
        tests.append({
            "utility": "mysqlserverinfo",
            "cmd_str": "mysqlserverinfo.py --server={0}",
            "comment": "Test case {0} {1} - basic serverinfo with ssl",
            "cmd_opts": " --format=vertical "
        })

        # ======== mysqluserclone ========= #
        tests.append({
            "utility": "mysqluserclone",
            "cmd_str": "mysqluserclone.py --source={0}",
            "comment": "Test case {0} {1} - userclone dump grants with ssl",
            "cmd_opts": " -d -v {0}".format(" joe_pass@user")
        })

        # ========  mysqldbexport  ========= #
        tests.append({
            "utility": "mysqldbexport",
            "cmd_str": "mysqldbexport.py --server={0}",
            "comment": "Test case {0} {1} - basic dbexport with ssl",
            "cmd_opts": " -edefinitions {0}".format("util_test_a")
        })

        # ========  mysqldbimport  ========= #
        tests.append({
            "utility": "mysqldbimport",
            "cmd_str": "mysqldbimport.py --server={0}",
            "comment": "Test case {0} {1} - basic dbimport with ssl",
            "cmd_opts": " -d {0}".format("./std_data/import_data.sql")
        })

        # ========  mysqlmetagrep  =========#
        tests.append({
            "utility": "mysqlmetagrep",
            "cmd_str": "mysqlmetagrep.py --server={0}",
            "comment": "Test case {0} {1} - basic metagrep with ssl",
            "cmd_opts": " -e%{0}".format("mysql")
        })

        # ========  mysqlprocgrep  ========= #
        tests.append({
            "utility": "mysqlprocgrep",
            "cmd_str": "mysqlprocgrep.py --server={0}",
            "comment": "Test case {0} {1} - basic procgrep with ssl",
            "cmd_opts": " --match-user={0}".format(self.server1.user)
        })

        # ========  mysqldiskusage  ========= #
        tests.append({
            "utility": "mysqldiskusage",
            "cmd_str": "mysqldiskusage.py --server={0}",
            "comment": "Test case {0} {1} - basic diskusage with ssl",
            "cmd_opts": ""
        })

        # ========  mysqlfrm  ========= #
        tests.append({
            "utility": "mysqlfrm",
            "cmd_str": "mysqlfrm.py --server={0}",
            "comment": "Test case {0} {1} - basic mysqlfrm with ssl",
            "cmd_opts": " ./ --port={0}".format(self.servers.get_free_port())
        })

        # ========  mysqldbcopy  ========= #
        tests.append({
            "utility": "mysqldbcopy",
            "cmd_str": "mysqldbcopy.py --source={0} --destination={0}",
            "comment": "Test case {0} {1} - basic mysqldbcopy with ssl",
            "cmd_opts": " util_test_a:util_test_z"
        })

        # ========  mysqldiff  ========= #
        tests.append({
            "utility": "mysqldiff",
            "cmd_str": "mysqldiff.py --server1={0} --server2={0}",
            "comment": "Test case {0} {1} - basic mysqldiff with ssl",
            "cmd_opts": " util_test_a.t1:util_test_z.t1 --skip-table-options"
        })

        # mysqlbinlogrotate
        tests.append({
            "utility": "mysqlbinlogrotate",
            "cmd_str": "mysqlbinlogrotate.py --server={0}",
            "comment": "Test case {0} {1} - basic mysqlbinlogrotate with ssl",
            "cmd_opts": ""
        })

        # mysqlbinlogpurge
        tests.append({
            "utility": "mysqlbinlogpurge",
            "cmd_str": "mysqlbinlogpurge.py --server={0}",
            "comment": "Test case {0} {1} - basic mysqlbinlogpurge with ssl",
            "cmd_opts": ""
        })

        test_options_group = []
        test_options_group.append({
            "conn_opts": conn_str,
            "grp_comment": "Using ssl certificates"
        })
        # Run tests cases using user that requires ssl without ssl
        # certificates and only --ssl=1
        test_options_group.append({
            "conn_opts": "{0} --ssl=1".format(conn_str_nossl),
            "grp_comment": "ssl=1 user require ssl"
        })
        # Run tests cases using user that no requires ssl without ssl
        # certificates and only --ssl=0
        test_options_group.append({
            "conn_opts": "{0} --ssl=0".format(conn_ssl_opt),
            "grp_comment": "ssl=0 user no require ssl"
        })
        # Run tests cases using user that no requires ssl without ssl
        # certificates and only --ssl=1 Note: server is ssl capable
        test_options_group.append({
            "conn_opts": "{0} --ssl=1".format(conn_ssl_opt),
            "grp_comment": "ssl=1 user no require ssl"
        })

        test_num = 0
        results_list = []

        for test_options in test_options_group:
            for test in tests:
                grp_cnt = test_options["grp_comment"]
                test_num += 1
                res = self.run_test(test, test_num, test_options["conn_opts"],
                                    grp_cnt)
                if not res:
                    raise MUTLibError(
                        "{0}: failed".format(test['comment'].format(test_num,
                                                                    grp_cnt))
                    )
                else:
                    results_list.append(
                        "{0}: {1}\n"
                        "".format(test["comment"].format(test_num, grp_cnt),
                                  "passed")
                    )

            self.drop_all()
            self.load_test_data()

        self.results = results_list

        # Mask known source host name.
        self.replace_result("# Source on ",
                            "# Source on XXXX-XXXX: ... connected.\n")

        return True
 def check_prerequisites(self):
     # This test requires server version > 5.5.7, due to the lack of
     # 'GRANT PROXY ON ...' on previews versions.
     if not self.servers.get_server(0).check_version_compat(5, 5, 8):
         raise MUTLibError("Test requires server version >= 5.5.8")
     return self.check_num_servers(1)
Beispiel #10
0
    def run(self):
        
        cmd_str = "mysqlrpladmin.py %s " % self.master_str
        
        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(' ')
        
        slaves_str = ",".join([slave1_conn, slave2_conn, slave3_conn])
        
        comment = "Test case 1 - show health before switchover"
        cmd_opts = " --slaves=%s --format=vertical health" % slaves_str
        res = mutlib.System_test.run_test_case(self, 0, cmd_str+cmd_opts,
                                               comment)
        if not res:
            raise MUTLibError("%s: failed" % comment)
            
        # Build connection string with loopback address instead of localhost
        slave_ports = [self.server2.port, self.server3.port, self.server4.port]
        slaves_loopback = "root:[email protected]:%s," % self.server2.port
        slaves_loopback += "root:[email protected]:%s," % self.server3.port
        slaves_loopback += "root:[email protected]:%s" % self.server4.port
        slave3_conn_ip = slave3_conn.replace("localhost", "127.0.0.1")

        # Perform switchover from original master to all other slaves and back.
        test_cases = [
            # (master, [slaves_before], candidate, new_master, [slaves_after])
            (master_conn, [slave1_conn, slave2_conn, slave3_conn],
             slave1_conn, "slave1", [slave2_conn, slave3_conn, master_conn]),
            (slave1_conn, [slave2_conn, slave3_conn, master_conn],
             slave2_conn, "slave2", [slave1_conn, slave3_conn, master_conn]),
            (slave2_conn, [slave1_conn, slave3_conn, master_conn],
             slave3_conn, "slave3", [slave2_conn, slave1_conn, master_conn]),
            (slave3_conn_ip, ["root:[email protected]:%s" % self.server3.port,
                           slave1_conn, master_conn],
             master_conn, "master", [slave1_conn, slave2_conn, slave3_conn]),
        ]
        test_num = 2
        for case in test_cases:
            slaves_str = ",".join(case[1])
            comment = "Test case %s - switchover to %s" % (test_num, case[3])
            cmd_str = "mysqlrpladmin.py --master=%s --rpl-user=rpl:rpl " % case[0]
            cmd_opts = " --new-master=%s --demote-master " % case[2]
            cmd_opts += " --slaves=%s switchover" % slaves_str
            res = mutlib.System_test.run_test_case(self, 0, cmd_str+cmd_opts,
                                                   comment)
            if not res:
                raise MUTLibError("%s: failed" % comment)
            test_num += 1
            slaves_str = ",".join(case[4])
            cmd_str = "mysqlrpladmin.py --master=%s " % case[2]
            comment = "Test case %s - show health after switchover" % test_num
            cmd_opts = " --slaves=%s --format=vertical health" % slaves_str
            res = mutlib.System_test.run_test_case(self, 0, cmd_str+cmd_opts,
                                                   comment)
            if not res:
                raise MUTLibError("%s: failed" % comment)
            test_num += 1

        cmd_str = "mysqlrpladmin.py --master=%s " % master_conn
        cmd_opts = " health --disc=root:root "
        cmd_opts += "--slaves=%s" % slaves_loopback
        comment= "Test case %s - health with loopback and discovery" % test_num
        res = mutlib.System_test.run_test_case(self, 0, cmd_str+cmd_opts,
                                               comment)
        if not res:
            raise MUTLibError("%s: failed" % comment)
        test_num += 1

        # Perform stop, start, and reset
        commands = ['stop', 'start', 'stop', 'reset']
        for cmd in commands:
            comment = "Test case %s - run command %s" % (test_num, cmd)
            cmd_str = "mysqlrpladmin.py --master=%s " % master_conn
            cmd_opts = " --slaves=%s %s" % (slaves_str, cmd)
            res = mutlib.System_test.run_test_case(self, 0, cmd_str+cmd_opts,
                                                   comment)
            if not res:
                raise MUTLibError("%s: failed" % comment)
            test_num += 1
            
        # Now we return the topology to its original state for other tests
        self.reset_topology()

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

        return True
Beispiel #11
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(' ')
        slave3_con = self.build_connection_string(self.server4).strip(' ')
        slaves_con = ",".join([slave1_con, slave2_con, slave3_con])

        # Show help.
        test_num = 1
        comment = ("Test case {0} - show help." "").format(test_num)
        cmd = "{0} --help".format(cmd_base)
        res = self.run_test_case(0, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        if self.debug:
            print("\nCreate test databases and tables on master.")
        rpl_sync.create_test_db(self.server1)
        # Add another database (empty) to be replicated on all slaves and
        # checked when using the --exclude option.
        self.server1.exec_query('CREATE DATABASE empty_db')

        if self.debug:
            print("\nInsert data into test database on master.")
        rpl_sync.load_test_data(self.server1)

        if self.debug:
            print("\nWait for slaves to catch up with master.")
        self.wait_for_slaves()

        # Skip servers with GTID disabled.
        test_num += 1
        comment = ("Test case {0} - skip slave with GTID OFF."
                   "").format(test_num)
        cmd = "{0} --master={1} --slaves={2}".format(cmd_base, master_con,
                                                     slaves_con)
        res = self.run_test_case(0, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        slaves_con = ",".join([slave1_con, slave2_con])

        if self.debug:
            print("\nStop one of the slaves.")
        self.server2.exec_query('STOP SLAVE')

        # Skip sync for stopped slaves.
        test_num += 1
        comment = ("Test case {0} - skip sync for stopped slaves."
                   "").format(test_num)
        cmd = "{0} --master={1} --slaves={2}".format(cmd_base, master_con,
                                                     slaves_con)
        res = self.run_test_case(0, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        if self.debug:
            print("\nCreate a new database on stopped slave and on master.")
        self.server2.exec_query('CREATE DATABASE `only_on_slave_db`')
        self.server1.exec_query('SET SQL_LOG_BIN=0')
        self.server1.exec_query('CREATE DATABASE `only_on_master_db`')
        self.server1.exec_query('SET SQL_LOG_BIN=1')

        # Identify missing databases.
        test_num += 1
        comment = ("Test case {0} - identify missing database."
                   "").format(test_num)
        cmd = "{0} --master={1} --slaves={2}".format(cmd_base, master_con,
                                                     slaves_con)
        res = self.run_test_case(1, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        if self.debug:
            print("\nChange table definition on slave.")
        self.server2.exec_query('ALTER TABLE `test_rplsync_db`.`t0` '
                                'MODIFY rnd_txt0 VARCHAR(50)')

        # Different table definition.
        test_num += 1
        comment = ("Test case {0} - identify table with different definition."
                   "").format(test_num)
        cmd = "{0} --master={1} --slaves={2}".format(cmd_base, master_con,
                                                     slaves_con)
        res = self.run_test_case(1, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        if self.debug:
            print("\nRemove tables on master and slave.")
        last_tbl = '`t{0}`'.format(rpl_sync.TEST_DB_NUM_TABLES - 1)
        self.server1.exec_query('SET SQL_LOG_BIN=0')
        self.server1.exec_query('DROP TABLE `test_rplsync_db`.'
                                '{0}'.format(last_tbl))
        self.server1.exec_query('SET SQL_LOG_BIN=1')
        self.server2.exec_query('DROP TABLE `test_rplsync_db`.`t0`')

        # Identify missing tables.
        test_num += 1
        comment = ("Test case {0} - identify missing tables."
                   "").format(test_num)
        cmd = "{0} --master={1} --slaves={2}".format(cmd_base, master_con,
                                                     slaves_con)
        res = self.run_test_case(1, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        if self.debug:
            print("\nChanging data on slaves.")
        self.server2.exec_query("UPDATE `test_rplsync_db`.`t1` "
                                "SET rnd_txt0='changed value' "
                                "WHERE id=1".format(last_tbl))
        self.server3.exec_query("INSERT INTO `test_rplsync_db`.`t0` "
                                "(rnd_txt0) VALUES ('new value')")

        # Identify data difference.
        test_num += 1
        comment = ("Test case {0} - identify data differences on tables."
                   "").format(test_num)
        cmd = "{0} --master={1} --slaves={2}".format(cmd_base, master_con,
                                                     slaves_con)
        res = self.run_test_case(1, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Check a specific database.
        test_num += 1
        comment = ("Test case {0} - check a specific database."
                   "").format(test_num)
        cmd = ("{0} --master={1} --slaves={2} "
               "test_rplsync_db").format(cmd_base, master_con, slaves_con)
        res = self.run_test_case(1, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Exclude check of a specific database.
        test_num += 1
        comment = ("Test case {0} - exclude a specific database."
                   "").format(test_num)
        cmd = ("{0} --master={1} --slaves={2} "
               "--exclude=test_rplsync_db").format(cmd_base, master_con,
                                                   slaves_con)
        res = self.run_test_case(1, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Check a specific table.
        test_num += 1
        comment = ("Test case {0} - check a specific table."
                   "").format(test_num)
        cmd = ("{0} --master={1} --slaves={2} "
               "test_rplsync_db.t0").format(cmd_base, master_con, slaves_con)
        res = self.run_test_case(1, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Exclude check of a specific table.
        test_num += 1
        comment = ("Test case {0} - exclude a specific table."
                   "").format(test_num)
        cmd = ("{0} --master={1} --slaves={2} "
               "--exclude=test_rplsync_db.t0").format(cmd_base, master_con,
                                                      slaves_con)
        res = self.run_test_case(1, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Include/exclude data to check (using backtick quotes).
        test_num += 1
        comment = ("Test case {0} - include/exclude data (using backticks)."
                   "").format(test_num)
        if os.name == 'posix':
            cmd_arg = ("'`test_rplsync_db`' --exclude='`test_rplsync_db`.`t0`,"
                       "`test_rplsync_db`.`t1`'")
        else:
            cmd_arg = ('"`test_rplsync_db`" --exclude="`test_rplsync_db`.`t0`,'
                       '`test_rplsync_db`.`t1`"')
        cmd = ("{0} --master={1} --slaves={2} "
               "{3}").format(cmd_base, master_con, slaves_con, cmd_arg)
        res = self.run_test_case(1, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Check a specific database that does not exist.
        test_num += 1
        comment = ("Test case {0} - check a non existing database."
                   "").format(test_num)
        cmd = ("{0} --master={1} --slaves={2} "
               "no_exist_db").format(cmd_base, master_con, slaves_con)
        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
Beispiel #12
0
            server = self.servers.get_server(index)
            try:
                res = server.show_server_variable("server_id")
            except MUTLibError, e:
                raise MUTLibError("Cannot get replication server " +
                                   "server_id: %s" % e.errmsg)
        else:
            if self.debug:
                print "# Cloning server0."
            serverid = self.servers.get_next_id()
            if mysqld is None:
                mysqld = _DEFAULT_MYSQL_OPTS % self.servers.view_next_port()
            res = self.servers.spawn_new_server(self.server0, serverid,
                                                name, mysqld)
            if not res:
                raise MUTLibError("Cannot spawn replication server '%s'." &
                                  name)
            self.servers.add_new_server(res[0], True)
            server = res[0]
            
        return server

    def setup(self):
        self.res_fname = "result.txt"
        
        # Spawn servers
        self.server0 = self.servers.get_server(0)
        self.server1 = self.spawn_server("rep_master")
        self.server2 = self.spawn_server("rep_slave1")
        self.server3 = self.spawn_server("rep_slave2")
        self.server4 = self.spawn_server("rep_slave3")
 def check_prerequisites(self):
     if not self.servers.get_server(0).check_version_compat(5, 6, 11):
         raise MUTLibError("Test requires server version 5.6.11 and later.")
     self.server0 = None
     self.server1 = None
     return self.check_num_servers(1)
    def run(self):
        self.res_fname = "result.txt"

        from_conn = "--source={0}".format(
            self.build_connection_string(self.server1))
        to_conn = "--destination={0}".format(
            self.build_connection_string(self.server2))

        cmd = "mysqldbcopy.py --skip-gtid {0} {1} ".format(from_conn, to_conn)

        test_num = 1
        comment = ("Test case {0} - copy a sample database X:Y"
                   "").format(test_num)
        cmd_str = "{0} util_test:util_db_clone".format(cmd)
        res = self.exec_util(cmd_str, self.res_fname)
        self.results.append(res)
        if res != 0:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = "Test case {0} - copy a sample database X".format(test_num)
        cmd_str = "{0} util_test".format(cmd)
        res = self.exec_util(cmd_str, self.res_fname)
        self.results.append(res)
        if res != 0:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - copy a sample database with blobs "
                   "X:Y".format(test_num))
        cmd_str = "{0} blob_test:blob_test_clone".format(cmd)
        res = self.exec_util(cmd_str, self.res_fname)
        self.results.append(res)
        if res != 0:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - copy using different engine"
                   "").format(test_num)
        cmd_str = ("{0} util_test:util_db_clone --drop-first "
                   "--new-storage-engine=MEMORY").format(cmd)
        res = self.exec_util(cmd_str, self.res_fname)
        self.results.append(res)
        if res != 0:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - copy using "
                   "multiprocessing").format(test_num)
        cmd_str = "{0} util_test:util_test_multi --multiprocess=2".format(cmd)
        res = self.exec_util(cmd_str, self.res_fname)
        self.results.append(res)
        if res != 0:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - copy blobs using "
                   "multiprocessing").format(test_num)
        cmd_str = "{0} blob_test:blob_test_multi --multiprocess=2".format(cmd)
        res = self.exec_util(cmd_str, self.res_fname)
        self.results.append(res)
        if res != 0:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - copy a sample database X:Y with weird "
                   "names (backticks)".format(test_num))
        # Set input parameter with appropriate quotes for the OS
        if os.name == 'posix':
            cmd_arg = "'\"db`:db\":\"db`:db_clone\"'"
        else:
            cmd_arg = '"\\"db`:db\\":\\"db`:db_clone\\""'
        cmd = "mysqldbcopy.py {0} {1} {2}".format(from_conn, to_conn, cmd_arg)
        res = self.exec_util(cmd, self.res_fname)
        self.results.append(res)
        if res != 0:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - copy a sample database X with weird "
                   "names (backticks)".format(test_num))
        # Set input parameter with appropriate quotes for the OS
        if os.name == 'posix':
            cmd_arg = "'\"db`:db\"'"
        else:
            cmd_arg = '"\\"db`:db\\""'
        cmd = "mysqldbcopy.py {0} {1} {2}".format(from_conn, to_conn, cmd_arg)
        res = self.exec_util(cmd, self.res_fname)
        self.results.append(res)
        if res != 0:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - copy a sample database with views"
                   "".format(test_num))
        cmd = "mysqldbcopy.py {0} {1} {2}".format(
            from_conn, to_conn, "views_test:views_test_clone")
        res = self.exec_util(cmd, self.res_fname)
        self.results.append(res)
        if res != 0:
            raise MUTLibError("{0}: failed".format(comment))

        # These two DB and tables does not contains any row, and are used
        # to test DB copy of default character set and collation.
        # was not move to ./std_data/basic_data.sql to avoid warning
        # "A partial copy from a server that has GTIDs.." messages
        # when setup is invoke from subclasses and other tests and
        # to avoid the creation of an additional file.
        queries = [
            ("CREATE DATABASE util_test_default_collation "
             "DEFAULT COLLATE utf8_general_ci"),
            ("CREATE TABLE util_test_default_collation.t1 "
             "(a char(30)) ENGINE=MEMORY"),
            ("CREATE DATABASE util_test_default_charset "
             "DEFAULT CHARACTER SET utf8"),
            ("CREATE TABLE util_test_default_charset.t1 "
             "(a char(30)) ENGINE=MEMORY"),
            'CREATE DATABASE "util""test" ',
            ('CREATE TABLE "util""test"."t""1" ('
             '"id" int(11) NOT NULL AUTO_INCREMENT,'
             '"name" varchar(100) DEFAULT NULL,'
             'PRIMARY KEY ("id")'
             ') ENGINE=InnoDB DEFAULT CHARSET=latin1'),
            ('CREATE TABLE "util""test"."t""2" ('
             '"i""d" int(11) NOT NULL AUTO_INCREMENT,'
             '"na""me" varchar(100) DEFAULT NULL,'
             'PRIMARY KEY ("i""d")'
             ') ENGINE=InnoDB DEFAULT CHARSET=latin1'),
        ]
        for query in queries:
            self.server1.exec_query(query)

        test_num += 1
        dest_c = "--destination={0}".format(
            self.build_connection_string(self.server1))
        comment = "Test case {0} - copydb default collation".format(test_num)
        dbs = ("util_test_default_collation:"
               "util_test_default_collation_copy")
        cmd = ("mysqldbcopy.py --skip-gtid {0} {1} {2}"
               "".format(from_conn, dest_c, dbs))
        res = self.exec_util(cmd, self.res_fname)
        self.results.append(res)
        if res != 0:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = "Test case {0} - copydb default charset".format(test_num)
        dbs = ("util_test_default_charset:" "util_test_default_charset_copy")
        cmd = ("mysqldbcopy.py --skip-gtid {0} {1} {2}"
               "".format(from_conn, dest_c, dbs))
        res = self.exec_util(cmd, self.res_fname)
        self.results.append(res)
        if res != 0:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        prev_sql_mode = self.server1.select_variable("SQL_MODE")
        self.server1.exec_query("SET @@SESSION.SQL_MODE=''")
        try:
            # Grant ALL on `util_test` for user 'joe'@'localhost' on source
            self.server1.exec_query("GRANT ALL ON `util_test`.* "
                                    "TO 'joe'@'localhost'")

            # Revoke all privileges to 'joe'@'localhost' in destination
            self.server2.exec_query("REVOKE ALL PRIVILEGES, GRANT OPTION FROM "
                                    "'joe'@'localhost'")

            # Add all privileges needed for 'joe'@'localhost' in destination db
            self.server2.exec_query("GRANT SELECT, CREATE, ALTER, INSERT, "
                                    "UPDATE, EXECUTE, DROP, LOCK TABLES, "
                                    "EVENT, TRIGGER, CREATE ROUTINE, "
                                    "REFERENCES, CREATE VIEW ON "
                                    "`util_db_privileges`.* TO "
                                    "'joe'@'localhost'")

            # Change DEFINER in procedures and functions on the source server
            self.server1.exec_query("UPDATE mysql.proc SET "
                                    "DEFINER='joe@localhost' WHERE "
                                    "DB='util_test'")
            self.server1.exec_query("UPDATE mysql.event SET "
                                    "DEFINER='joe@localhost' WHERE "
                                    "DB='util_test'")

            # Change DEFINER in the views on the source server
            query = """
                SELECT CONCAT("ALTER DEFINER='joe'@'localhost' VIEW ",
                table_schema, ".", table_name, " AS ", view_definition)
                FROM information_schema.views WHERE
                table_schema='util_test'
            """
            res = self.server1.exec_query(query)
            for row in res:
                self.server1.exec_query(row[0])
            self.server1.exec_query("SET @@SESSION.SQL_MODE={0}"
                                    "".format(prev_sql_mode))

            # Change DEFINER in the triggers on the source server
            self.server1.exec_query("DROP TRIGGER util_test.trg")
            self.server1.exec_query("CREATE DEFINER='joe'@'localhost' "
                                    "TRIGGER util_test.trg AFTER INSERT ON "
                                    "util_test.t1 FOR EACH ROW INSERT INTO "
                                    "util_test.t2 "
                                    "VALUES('Test objects count')")
        except UtilError as err:
            raise MUTLibError("Failed to execute query: "
                              "{0}".format(err.errmsg))

        to_conn = "--destination=joe@localhost:{0}".format(self.server2.port)
        comment = ("Test case {0} - copy using a user without SUPER privilege"
                   "").format(test_num)
        cmd = ("mysqldbcopy.py --skip-gtid --skip=grants --drop-first {0} "
               "{1} util_test:util_db_privileges".format(from_conn, to_conn))

        res = self.exec_util(cmd, self.res_fname)
        self.results.append(res)
        if res != 0:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        # Change SQL_MODE to 'NO_BACKSLASH_ESCAPES' in the destination server
        try:
            previous_sql_mode = self.server2.select_variable("SQL_MODE")
            self.server2.exec_query("SET @@GLOBAL.SQL_MODE="
                                    "'NO_BACKSLASH_ESCAPES'")
        except UtilError as err:
            raise MUTLibError("Failed to change SQL_MODE: "
                              "{0}".format(err.errmsg))

        comment = ("Test case {0} - Copy database with blobs and the "
                   "destination server with SQL_MODE='NO_BACKSLASH_ESCAPES'"
                   "").format(test_num)
        to_conn = "--destination={0}".format(
            self.build_connection_string(self.server2))
        cmd = ("mysqldbcopy.py --skip-gtid {0} {1} {2}".format(
            from_conn, to_conn, "blob_test:blob_test_no_backslash_escapes"))
        res = self.run_test_case(0, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Restore previous SQL_MODE in the destination server
        try:
            self.server2.exec_query("SET @@GLOBAL.SQL_MODE='{0}'"
                                    "".format(previous_sql_mode))
        except UtilError as err:
            raise MUTLibError("Failed to restore SQL_MODE: "
                              "{0}".format(err.errmsg))

        # Database and table with single double quotes (") on identifier
        test_num += 1
        comment = "Test case {0} - copydb single double quote".format(test_num)
        dbs = '\\"util\\"\\"test\\":\\"util\\"\\"test_copy\\"'
        cmd = ("mysqldbcopy.py --skip-gtid {0} {1} {2} -vv"
               "".format(from_conn, to_conn, dbs))
        res = self.run_test_case(0, cmd, comment)
        self.results.append(res)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Database and table with single double quotes (") on identifier
        # and destination with SQL_MODE to ''.
        # Change SQL_MODE to '' in the destination server
        try:
            previous_sql_mode = self.server2.select_variable("SQL_MODE")
            self.server2.exec_query("SET @@GLOBAL.SQL_MODE=" "''")
        except UtilError as err:
            raise MUTLibError("Failed to change SQL_MODE: "
                              "{0}".format(err.errmsg))

        test_num += 1
        comment = ("Test case {0} - copydb single double quote "
                   "and destination server with SQL_MODE set to "
                   "''".format(test_num))
        if os.name == 'posix':
            dbs = "'\"util\"\"test\":`util\"test_no_backslash_escapes`'"
        else:
            dbs = '\\"util\\"\\"test\\":`util\\"test_no_backslash_escapes`'
        cmd = ("mysqldbcopy.py --skip-gtid {0} {1} {2} -vv"
               "".format(from_conn, to_conn, dbs))
        res = self.run_test_case(0, cmd, comment)
        self.results.append(res)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Restore previous SQL_MODE in the destination server
        try:
            self.server2.exec_query("SET @@GLOBAL.SQL_MODE='{0}'"
                                    "".format(previous_sql_mode))
        except UtilError as err:
            raise MUTLibError("Failed to restore SQL_MODE: "
                              "{0}".format(err.errmsg))

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

        test_num = 1
        comment = "Test case {0} - error: no db specified".format(test_num)
        res = self.run_test_case(2, "mysqlindexcheck.py ", comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - error: invalid source "
                   "specified".format(test_num))
        res = self.run_test_case(1, "mysqlindexcheck.py util_test "
                                    "--server=nope:nada@nohost", comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - error: invalid login to "
                   "server".format(test_num))
        res = self.run_test_case(1, "mysqlindexcheck.py util_test_a "
                                    "--server=nope:nada@localhost:"
                                    "{0}".format(self.server1.port),
                                 comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - error: stats and "
                   "best=alpha".format(test_num))
        res = self.run_test_case(2, "mysqlindexcheck.py --stats --best=A "
                                    "util_test_a", comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - error: stats and "
                   "worst=alpha".format(test_num))
        res = self.run_test_case(2, "mysqlindexcheck.py --stats --worst=A "
                                    "util_test_a", comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = "Test case {0} - error: not stats ".format(test_num)
        res = self.run_test_case(2, "mysqlindexcheck.py --best=1 "
                                    "util_test_a", comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - error: stats and both best and "
                   "worst ".format(test_num))
        res = self.run_test_case(2, "mysqlindexcheck.py --stats --best=1 "
                                    "--worst=1 util_test_a", comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = "Test case {0} - error: stats and worst=-1".format(test_num)
        res = self.run_test_case(2, "mysqlindexcheck.py --stats --worst=-1 "
                                    "util_test_a", comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = "Test case {0} - error: stats and best=-1".format(test_num)
        res = self.run_test_case(2, "mysqlindexcheck.py --stats --best=-1 "
                                    "util_test_a", comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = "Test case {0} - error: stats and worst=0".format(test_num)
        res = self.run_test_case(2, "mysqlindexcheck.py --stats --worst=0 "
                                    "util_test_a", comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = "Test case {0} - error: stats and best=0".format(test_num)
        res = self.run_test_case(2, "mysqlindexcheck.py --stats --best=0 "
                                    "util_test_a", comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        self.replace_result("ERROR: Can't connect",
                            "ERROR: Can't connect to XXXX\n")
        self.replace_any_result(["Error 1045", "Error 2003",
                                 "Error Can't connect to MySQL server on",
                                 "Error Access denied for user"],
                                "Error XXXX: Access denied\n")

        return True
Beispiel #16
0
    def setup(self):
        self.res_fname = "result.txt"
        self.config_file_path = 'rpl_admin_b_ssl.cnf'

        # Spawn servers
        self.server0 = self.servers.get_server(0)
        mysqld = _DEFAULT_MYSQL_OPTS.format(self.servers.view_next_port())
        self.server1 = self.servers.spawn_server(
            "rep_master_gtid_ssl", mysqld, True
        )
        mysqld = _DEFAULT_MYSQL_OPTS.format(self.servers.view_next_port())
        self.server2 = self.servers.spawn_server(
            "rep_slave1_gtid_ssl", mysqld, True
        )
        mysqld = _DEFAULT_MYSQL_OPTS_DIFF_SSL.format(
            self.servers.view_next_port()
        )
        self.server3 = self.servers.spawn_server(
            "rep_slave2_gtid_ssl", mysqld, True
        )
        mysqld = _DEFAULT_MYSQL_OPTS.format(self.servers.view_next_port())
        self.server4 = self.servers.spawn_server(
            "rep_slave3_gtid_ssl", mysqld, True
        )

        self.servers_list = [self.server1, self.server2,
                             self.server3, self.server4]

        for server in self.servers_list:
            try:
                grant_proxy_ssl_privileges(server, ssl_user, ssl_pass)
            except UtilError as err:
                raise MUTLibError("{0} on:{1}".format(err.errmsg,
                                                      server.role))

        conn_info = {
            'user': ssl_user,
            'passwd': ssl_pass,
            'host': self.server0.host,
            'port': self.server0.port,
            'ssl_ca': ssl_c_ca,
            'ssl_cert': ssl_c_cert,
            'ssl_key': ssl_c_key,
        }

        conn_info['port'] = self.server1.port
        conn_info['port'] = self.server1.port
        self.server1 = Server.fromServer(self.server1, conn_info)
        self.server1.connect()

        conn_info['port'] = self.server2.port
        conn_info['port'] = self.server2.port
        self.server2 = Server.fromServer(self.server2, conn_info)
        self.server2.connect()

        conn_info['port'] = self.server3.port
        conn_info['port'] = self.server3.port
        conn_info['ssl_ca'] = ssl_c_ca_b
        conn_info['ssl_cert'] = ssl_c_cert_b
        conn_info['ssl_key'] = ssl_c_key_b
        self.server3 = Server.fromServer(self.server3, conn_info)
        self.server3.connect()

        conn_info['port'] = self.server4.port
        conn_info['port'] = self.server4.port
        conn_info['ssl_ca'] = ssl_c_ca
        conn_info['ssl_cert'] = ssl_c_cert
        conn_info['ssl_key'] = ssl_c_key
        self.server4 = Server.fromServer(self.server4, conn_info)
        self.server4.connect()

        server_n = 0
        for server in [self.server1, self.server2, self.server3,
                       self.server4]:
            server_n += 1
            res = server.exec_query("SHOW STATUS LIKE 'Ssl_cipher'")
            if not res[0][1]:
                raise MUTLibError("Cannot spawn the SSL server{0}."
                                  "".format(server_n))

        # Reset spawned servers (clear binary log and GTID_EXECUTED set)
        self.reset_master()

        # Update server list
        self.servers_list = [self.server1, self.server2,
                             self.server3, self.server4]

        # setup config_path
        config_p = ConfigParser.ConfigParser()
        self.test_server_names = []

        with open(self.config_file_path, 'w') as config_f:
            for server in self.servers_list:
                group_name = 'server_{0}'.format(server.port)
                self.test_server_names.append(group_name)
                config_p.add_section(group_name)
                config_p.set(group_name, 'user', server.user)
                config_p.set(group_name, 'password', server.passwd)
                config_p.set(group_name, 'host', server.host)
                config_p.set(group_name, 'port', server.port)
                config_p.set(group_name, 'ssl-ca', server.ssl_ca)
                config_p.set(group_name, 'ssl-cert', server.ssl_cert)
                config_p.set(group_name, 'ssl-key', server.ssl_key)
            config_p.write(config_f)

        master = self.servers_list[0]
        slaves_list = self.servers_list[1:]

        # Used for port masking.
        self.m_port = self.server1.port
        self.s1_port = self.server2.port
        self.s2_port = self.server3.port
        self.s3_port = self.server4.port

        return self.reset_topology(slaves_list, master=master)
    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} - mysqlrplshow OLD Master "
                   "before demote".format(test_num))
        cmd_str = "mysqlrplshow.py --master={0} ".format(master_conn)
        cmd_opts = "--discover-slaves={0} ".format(master_conn.split('@')[0])
        res = self.run_test_case(0, cmd_str + cmd_opts, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

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

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

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

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

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

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

        self.replace_result("# QUERY = SELECT "
                            "WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS(",
                            "# QUERY = SELECT "
                            "WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS(XXXXX)\n")

        self.remove_result_and_lines_before("WARNING: There are slaves that"
                                            " had connection errors.")

        self.replace_result("| 127.0.0.1  | PORT2  | MASTER  | UP     "
                            "| ON         | OK      | ",
                            "| 127.0.0.1  | PORT2  | MASTER  | UP     "
                            "| ON         | OK      | XXXXXXXX    "
                            "| XXXXXXXX          | XXXXXXXX        "
                            "|            |             |              "
                            "|                  |               |           "
                            "|                |            "
                            "|               |\n")

        self.replace_result("| 127.0.0.1  | PORT1  | SLAVE   | UP     "
                            "| ON         | OK      | ",
                            "| 127.0.0.1  | PORT1  | SLAVE   | UP     "
                            "| ON         | OK      | XXXXXXXX    "
                            "| XXXXXXXX          | XXXXXXXX        "
                            "| Yes        | Yes         | 0            "
                            "| No               | 0             |           "
                            "| 0              |            "
                            "| 0             |\n")

        self.replace_result("| 127.0.0.1  | PORT3  | SLAVE   | UP     "
                            "| ON         | OK      | ",
                            "| 127.0.0.1  | PORT3  | SLAVE   | UP     "
                            "| ON         | OK      | XXXXXXXX    "
                            "| XXXXXXXX          | XXXXXXXX        "
                            "| Yes        | Yes         | 0            "
                            "| No               | 0             |           "
                            "| 0              |            "
                            "| 0             |\n")

        self.replace_result("| 127.0.0.1  | PORT4  | SLAVE   | UP     "
                            "| ON         | OK      | ",
                            "| 127.0.0.1  | PORT4  | SLAVE   | UP     "
                            "| ON         | OK      | XXXXXXXX    "
                            "| XXXXXXXX          | XXXXXXXX        "
                            "| Yes        | Yes         | 0            "
                            "| No               | 0             |           "
                            "| 0              |            "
                            "| 0             |\n")

        self.replace_result("| 127.0.0.1  | PORT1  | MASTER  | UP     "
                            "| ON         | OK      | ",
                            "| 127.0.0.1  | PORT1  | MASTER  | UP     "
                            "| ON         | OK      | XXXXXXXX    "
                            "| XXXXXXXX          | XXXXXXXX        "
                            "|            |             |              "
                            "|                  |               |           "
                            "|                |            "
                            "|               |\n")

        self.mask_column_result("| version", "|", 2, " XXXXXXXX ")
        self.mask_column_result("| master_log_file", "|", 2, " XXXXXXXX ")
        self.mask_column_result("| master_log_pos", "|", 2, " XXXXXXXX ")

        # Mask slaves behind master.
        # It happens sometimes on windows in a non-deterministic way.
        self.replace_substring("+---------------------------------------------"
                               "------------------------------------------+",
                               "+---------+")
        self.replace_substring("+---------------------------------------------"
                               "-------------------------------------------+",
                               "+---------+")
        self.replace_substring("| health                                      "
                               "                                          |",
                               "| health  |")
        self.replace_substring("| health                                      "
                               "                                           |",
                               "| health  |")
        self.replace_substring("| OK                                          "
                               "                                          |",
                               "| OK      |")
        self.replace_substring("| OK                                          "
                               "                                           |",
                               "| OK      |")
        self.replace_substring_portion("| Slave delay is ",
                                       "transactions behind master.  |",
                                       "| OK      |")
        self.replace_substring("| Slave has 1 transactions behind master.     "
                               "                                          |",
                               "| OK      |")
        self.replace_substring("| Slave has 1 transactions behind master.     "
                               "                                           |",
                               "| OK      |")

        self.replace_substring("+------------------------------------------+",
                               "+---------+")
        self.replace_substring("| health                                   |",
                               "| health  |")
        self.replace_substring("| OK                                       |",
                               "| OK      |")
        self.replace_substring("| Slave has 1 transactions behind master.  |",
                               "| OK      |")

        return True
Beispiel #18
0
    def run(self):
        config_file = self.config_file_path
        master = '{0}[server_{1}]'.format(config_file, self.server1.port)
        slave1 = '{0}[server_{1}]'.format(config_file, self.server2.port)
        slave2 = '{0}[server_{1}]'.format(config_file, self.server3.port)
        slave3 = '{0}[server_{1}]'.format(config_file, self.server4.port)

        test_num = 1
        comment = ("Test case {0} - SSL "
                   "switchover demote-master ".format(test_num))
        cmd_str = "mysqlrpladmin.py --master={0} ".format(master)
        slaves = [slave1, slave2, slave3]
        cmd_opts = (" --new-master={0} "
                    "--rpl-user=rpluser:hispassword --demote-master "
                    "switchover --slaves={1}"
                    "").format(slave1, ",".join(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 mysqlrplcheck "
                   "NEW Master after demote".format(test_num))
        cmd_opts = "--slave={0} --show-slave-status".format(master)
        cmd_str = "mysqlrplcheck.py --master={0} ".format(slave1)
        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)
        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)
        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 --master={0}".format(slave1)
        slaves = ",".join([slave2, slave3,
                           master])
        cmd_opts = (" --slaves={0} --rpl-user=rpluser:hispassword "
                    "failover".format(slaves))
        cmd_opts = "{0} --candidates={1}".format(cmd_opts, 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 mysqlrplcheck "
                   "NEW Master after demote".format(test_num))
        cmd_str = "mysqlrplcheck.py --master={0} ".format(slave2)
        cmd_opts = "--slave={0} --show-slave-status".format(master)
        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)
        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
Beispiel #19
0
    def run(self):
        from_conn = "--server={0}".format(
            self.build_connection_string(self.server1))

        # TODO : make a test for '--skip-rpl'

        # Copy master database
        test_num = 1
        db_list = ["master_db1"]
        to_conn = "--server={0}".format(
            self.build_connection_string(self.server2))
        for exp_fmt in _FORMATS:
            cmd_list = []
            comment = ("Test case {0} - Copy extra database from master to "
                       "slave - format =".format(test_num))

            exp_cmd = _EXPORT_CMD.format(exp_fmt, "master", " ".join(db_list),
                                         from_conn, "", _RPL_FILE)
            cmd_list.append(exp_cmd)

            imp_str = _IMPORT_CMD.format(to_conn, _RPL_FILE, exp_fmt, "")
            cmd_list.append(imp_str)

            res = self.run_test_case(0, test_num, self.server1, self.server1,
                                     self.server2, cmd_list, db_list, "",
                                     comment + exp_fmt, _TEST_CASE_RESULTS,
                                     True)
            if not res:
                raise MUTLibError("{0}: failed".format(comment))
            test_num += 1

        # Provision a new slave from master
        to_conn = "--server={0}".format(
            self.build_connection_string(self.server3))
        db_list = ["util_test", "master_db1"]
        cmd_list = []
        exp_cmd = _EXPORT_CMD.format("sql", "master", " ".join(db_list),
                                     from_conn, "", _RPL_FILE)
        cmd_list.append(exp_cmd)

        imp_str = _IMPORT_CMD.format(to_conn, _RPL_FILE, "sql", "")
        cmd_list.append(imp_str)

        comment = ("Test case {0} - Provision a new slave from the "
                   "master".format(test_num))
        res = self.run_test_case(0, test_num, self.server1, self.server1,
                                 self.server3, cmd_list, db_list, "",
                                 comment + " sql", _TEST_CASE_RESULTS, True)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))
        test_num += 1

        # Provision a new slave from existing slave
        from_conn = "--server={0}".format(
            self.build_connection_string(self.server2))
        cmd_list = []
        exp_cmd = _EXPORT_CMD.format("sql", "slave", " ".join(db_list),
                                     from_conn, "", _RPL_FILE)
        cmd_list.append(exp_cmd)

        imp_str = _IMPORT_CMD.format(to_conn, _RPL_FILE, "sql", "")
        cmd_list.append(imp_str)

        comment = ("Test case {0} - Provision a new slave from existing "
                   "slave".format(test_num))
        res = self.run_test_case(0, test_num, self.server1, self.server2,
                                 self.server3, cmd_list, db_list, "",
                                 comment + " sql", _TEST_CASE_RESULTS, True)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))
        test_num += 1

        # Now show the --skip-rpl effects
        # New rows will not appear in row count because the CM and START
        # commands are skipped.
        self.server3.exec_query("STOP SLAVE")
        self.server3.exec_query("DROP DATABASE util_test")
        self.server3.exec_query("DROP DATABASE master_db1")

        cmd_list = []
        exp_cmd = _EXPORT_CMD.format("sql", "slave", " ".join(db_list),
                                     from_conn, "", _RPL_FILE)
        cmd_list.append(exp_cmd)

        imp_str = _IMPORT_CMD.format(to_conn, _RPL_FILE, "sql", " --skip-rpl ")
        cmd_list.append(imp_str)

        comment = "Test case {0} - Use --skip-rpl on import".format(test_num)
        res = self.run_test_case(0, test_num, self.server1, self.server2,
                                 self.server3, cmd_list, db_list, "",
                                 comment + " sql", _TEST_CASE_RESULTS, False,
                                 True)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))
        test_num += 1

        # Rollback here to avoid active transaction error for STOP SLAVE with
        # 5.5 servers.
        if self.servers.get_server(0).check_version_compat(5, 5, 0):
            self.server3.rollback()
        # Do the last test case again but don't skip to show rows are updated
        self.server3.exec_query("STOP SLAVE")
        self.server3.exec_query("RESET SLAVE")
        self.server3.exec_query("DROP DATABASE util_test")
        self.server3.exec_query("DROP DATABASE master_db1")

        cmd_list = []
        exp_cmd = _EXPORT_CMD.format("sql", "slave", " ".join(db_list),
                                     from_conn, "", _RPL_FILE)
        cmd_list.append(exp_cmd)

        imp_str = _IMPORT_CMD.format(to_conn, _RPL_FILE, "sql", " --skip-rpl ")
        cmd_list.append(imp_str)

        comment = "Test case {0} - Use --skip-rpl on import".format(test_num)
        res = self.run_test_case(0, test_num, self.server1, self.server2,
                                 self.server3, cmd_list, db_list, "",
                                 comment + " sql", _TEST_CASE_RESULTS, True)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        return True
    def run(self):
        self.mask_global = False  # Turn off global masks
        self.res_fname = "result.txt"

        s1_conn = "--server1={0}".format(
            self.build_connection_string(self.server1))
        s2_conn = "--server2={0}".format(
            self.build_connection_string(self.server2))
        s2_conn_dupe = "--server2={0}".format(
            self.build_connection_string(self.server1))

        cmd_base = "mysqldiff.py {0} {1} ".format(s1_conn, s2_conn)

        test_num = 1
        comment = "Test case {0} - diff a sample database".format(test_num)
        cmd = "{0} util_test:util_test".format(cmd_base)
        res = self.run_test_case(1, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - diff a single object - not "
                   "same".format(test_num))
        cmd = "{0} util_test.t2:util_test.t2".format(cmd_base)
        res = self.run_test_case(1, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - diff a single object - is "
                   "same".format(test_num))
        cmd = "{0} util_test.t3:util_test.t3".format(cmd_base)
        res = self.run_test_case(0, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - diff multiple objects - are "
                   "same".format(test_num))
        cmd = ("{0} util_test.t3:util_test.t3 "
               "util_test.t4:util_test.t4".format(cmd_base))
        res = self.run_test_case(0, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - diff multiple objects + database - some "
                   "same".format(test_num))
        cmd = ("{0} util_test.t3:util_test.t3 util_test.t4:util_test.t4 "
               "util_test:util_test --force".format(cmd_base))
        res = self.run_test_case(1, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # execute a diff on the same server to test messages

        self.server1.exec_query("CREATE DATABASE util_test1")

        test_num += 1
        comment = ("Test case {0} - diff two databases on same server "
                   "w/server2".format(test_num))
        cmd = ("mysqldiff.py {0} {1} "
               "util_test:util_test1".format(s1_conn, s2_conn_dupe))
        res = self.run_test_case(1, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - diff two databases on same "
                   "server".format(test_num))
        cmd = "mysqldiff.py {0} util_test:util_test1".format(s1_conn)
        res = self.run_test_case(1, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - diff a sample database with weird names "
                   "(backticks)".format(test_num))
        # Set input parameter with appropriate quotes for the OS
        if os.name == 'posix':
            cmd_arg = "'\"db.`:db\":\"db.`:db\"'"
        else:
            cmd_arg = '"\\"db.`:db\\":\\"db.`:db\\""'
        cmd = "mysqldiff.py {0} {1} {2}".format(s1_conn, s2_conn, cmd_arg)
        res = self.run_test_case(0, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - diff a single object with weird names "
                   "(backticks)".format(test_num))
        # Set input parameter with appropriate quotes for the OS
        if os.name == 'posix':
            cmd_arg = ("'\"db.`:db\".\"`t`.`export_2\":"
                       "\"db.`:db\".\"`t`.`export_2\"'")
        else:
            cmd_arg = ('"\\"db.`:db\\".\\"`t`.`export_2\\":'
                       '\\"db.`:db\\".\\"`t`.`export_2\\""')
        cmd = "mysqldiff.py {0} {1} {2}".format(s1_conn, s2_conn, cmd_arg)
        res = self.run_test_case(0, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - diff a sample database containing tables "
                   "with weird names (no backticks) and different table "
                   "options.".format(test_num))
        cmd_arg = "db_diff_test:db_diff_test"
        cmd = "mysqldiff.py {0} {1} {2}".format(s1_conn, s2_conn, cmd_arg)
        res = self.run_test_case(1, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - diff a sample database containing tables "
                   "with weird names (no backticks) and skipping "
                   "table options.".format(test_num))
        cmd_arg = "db_diff_test:db_diff_test --skip-table-options"
        cmd = "mysqldiff.py {0} {1} {2}".format(s1_conn, s2_conn, cmd_arg)
        res = self.run_test_case(0, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Diff databases with objects of different type with the same name

        # Create the same PROCEDURE on each server with the same name of an
        # already existing TABLE (i.e., ```t``export_1`).
        self.server1.exec_query(
            "CREATE PROCEDURE `db.``:db`.```t``export_1`() "
            "SELECT 1")
        self.server2.exec_query(
            "CREATE PROCEDURE `db.``:db`.```t``export_1`() "
            "SELECT 1")
        if os.name == 'posix':
            cmd_arg = "'\"db.`:db\":\"db.`:db\"'"
        else:
            cmd_arg = '"\\"db.`:db\\":\\"db.`:db\\""'
            # Execute test (no differences expected)
        test_num += 1
        comment = ("Test case {0} - diff a database with objects of "
                   "different types with the same name "
                   "(no differences)".format(test_num))
        cmd = "mysqldiff.py {0} {1} {2}".format(s1_conn, s2_conn, cmd_arg)
        res = self.run_test_case(0, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Replace the PROCEDURE previously created on one of the servers by a
        # different one.
        self.server2.exec_query("DROP PROCEDURE `db.``:db`.```t``export_1`")
        self.server2.exec_query(
            "CREATE PROCEDURE `db.``:db`.```t``export_1`() "
            "SELECT 2")
        # Execute test (differences expected)
        test_num += 1
        comment = ("Test case {0} - diff a database with objects of "
                   "different types with the same name "
                   "(with differences)".format(test_num))
        cmd = "mysqldiff.py {0} {1} {2}".format(s1_conn, s2_conn, cmd_arg)
        res = self.run_test_case(1, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Set input parameter with appropriate quotes for the OS
        if os.name == 'posix':
            cmd_arg = ("'\"db.`:db\".\"`t`export_1\":"
                       "\"db.`:db\".\"`t`export_1\"'")
        else:
            cmd_arg = ('"\\"db.`:db\\".\\"`t`export_1\\":'
                       '\\"db.`:db\\".\\"`t`export_1\\""')
            # Execute test for specific objects (differences expected)
        test_num += 1
        comment = ("Test case {0} - diff specific objects of "
                   "different types with the same name "
                   "(with differences)".format(test_num))
        cmd = "mysqldiff.py {0} {1} {2}".format(s1_conn, s2_conn, cmd_arg)
        res = self.run_test_case(1, cmd, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # The following are necessary due to changes in character spaces
        # introduced with Python 2.7.X in the difflib.

        self.replace_result("+++ util_test.t1", "+++ util_test.t1\n")
        self.replace_result("+++ util_test.t2", "+++ util_test.t2\n")
        self.replace_result("--- util_test.t1", "--- util_test.t1\n")
        self.replace_result("--- util_test.t2", "--- util_test.t2\n")

        self.replace_substring("on [::1]", "on localhost")

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

        from_conn = "--server={0}".format(
            self.build_connection_string(self.server1))

        cmd_str = ("mysqldbexport.py --skip=events,grants --no-headers {0} "
                   "--format=CSV util_test --skip-gtid".format(from_conn))

        test_num = 1
        comment = "Test case {0} - exclude by name.".format(test_num)
        cmd_opts = ("{0} --exclude=util_test.v1 "
                    "--exclude=util_test.t4".format(cmd_str))
        res = self.run_test_case(0, cmd_opts, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - exclude by name using "
                   "backticks.".format(test_num))
        if os.name == 'posix':
            cmd_opts = ("{0} --exclude='`util_test`.`v1`' "
                        "--exclude='`util_test`.`t4`'".format(cmd_str))
        else:
            cmd_opts = ('{0} --exclude="`util_test`.`v1`" '
                        '--exclude="`util_test`.`t4`"'.format(cmd_str))
        res = self.run_test_case(0, cmd_opts, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - exclude using SQL LIKE "
                   "pattern.".format(test_num))
        cmd_opts = "{0} -x f% -x _4".format(cmd_str)
        res = self.run_test_case(0, cmd_opts, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - exclude using REGEXP "
                   "pattern.".format(test_num))
        cmd_opts = "{0} -x ^f -x 4$ --regexp".format(cmd_str)
        res = self.run_test_case(0, cmd_opts, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - exclude by name and SQL LIKE "
                   "pattern.".format(test_num))
        cmd_opts = ("{0} --exclude=f% --exclude=_4 -x p% --exclude=v1 "
                    "--exclude=util_test.trg".format(cmd_str))
        res = self.run_test_case(0, cmd_opts, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - exclude by name and REGEXP "
                   "pattern.".format(test_num))
        cmd_opts = ("{0} --exclude=^f --exclude=4$ -x ^p --exclude=v1 "
                    "--exclude=util_test.trg --regexp".format(cmd_str))
        res = self.run_test_case(0, cmd_opts, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - exclude everything using SQL LIKE "
                   "pattern.".format(test_num))
        cmd_opts = "{0} -x % ".format(cmd_str)
        res = self.run_test_case(0, cmd_opts, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - exclude everything using REGEXP "
                   "pattern.".format(test_num))
        if os.name == 'posix':
            cmd_opts = "{0} -x '.*' --regexp".format(cmd_str)
        else:
            cmd_opts = '{0} -x ".*" --regexp'.format(cmd_str)
        res = self.run_test_case(0, cmd_opts, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Note: Unlike SQL LIKE pattern that matches the entire value, with a
        # SQL REGEXP pattern match succeeds if the pattern matches anywhere in
        # the value being tested.
        # See: http://dev.mysql.com/doc/en/pattern-matching.html
        test_num += 1
        comment = ("Test case {0}a - SQL LIKE VS REGEXP pattern (match entire "
                   "value VS match anywhere in value).".format(test_num))
        cmd_opts = "{0} -x 1 -x t".format(cmd_str)
        res = self.run_test_case(0, cmd_opts, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        comment = ("Test case {0}b - SQL LIKE VS REGEXP pattern (match entire "
                   "value VS match anywhere in value).".format(test_num))
        cmd_opts = "{0} -x 1 -x t --regexp".format(cmd_str)
        res = self.run_test_case(0, cmd_opts, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        export_parameters_def.test._mask_csv(self)

        ## Mask known source.
        self.replace_result("# Source on localhost: ... connected.",
                            "# Source on XXXX-XXXX: ... connected.\n")
        self.replace_result("# Source on [::1]: ... connected.",
                            "# Source on XXXX-XXXX: ... connected.\n")
        # Mask GTID warning when servers with GTID enabled are used
        self.remove_result("# WARNING: The server supports GTIDs but you")

        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(' ')

        master_str = "--master={0}".format(master_conn)
        slaves_str = "--slaves={0}".format(",".join(
            [slave1_conn, slave2_conn, slave3_conn]))
        candidates_str = "--candidates={0}".format(",".join(
            [slave1_conn, slave2_conn, slave3_conn]))

        test_num = 1
        comment = ("Test case {0} - warning for --exec* and not switchover or "
                   "failover".format(test_num))
        cmd_str = ("mysqlrpladmin.py {0} {1} health --quiet --format=csv "
                   " --exec-before=dummy "
                   "--exec-after=dummy".format(master_str, slaves_str))
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - warning for --candidate and not "
                   "switchover".format(test_num))
        cmd_str = ("mysqlrpladmin.py {0} {1} health --quiet --format=csv "
                   "{2}".format(master_str, slaves_str, candidates_str))
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - warning for --new-master and not "
                   "switchover".format(test_num))
        cmd_str = ("mysqlrpladmin.py {0} {1} health --quiet --format=tab "
                   " --new-master={2} ".format(master_str, slaves_str,
                                               slave2_conn))
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - warning for missing "
                   "--report-host".format(test_num))
        cmd_str = ("mysqlrpladmin.py {0} --disco=root:root health "
                   "--format=csv ".format(master_str))
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - warning for missing "
                   "--report-host (using --verbose)".format(test_num))
        cmd_str = ("mysqlrpladmin.py {0} --disco=root:root health "
                   "--format=csv --verbose".format(master_str))
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        test_num += 1
        comment = ("Test case {0} - warning for --format and not health or "
                   "gtid".format(test_num))
        cmd_str = ("mysqlrpladmin.py {0} {1} stop --quiet "
                   "--format=tab ".format(master_str, slaves_str))
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Reset the topology to its original state
        self.reset_topology(
            [self.server2, self.server3, self.server4, self.server5])

        test_num += 1
        comment = ("Test case {0} - warning for --master and "
                   "failover".format(test_num))
        cmd_str = ("mysqlrpladmin.py {0} {1} "
                   "failover".format(master_str, slaves_str))
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Reset the topology to its original state
        self.reset_topology(
            [self.server2, self.server3, self.server4, self.server5])

        test_num += 1
        comment = ("Test case {0} - warnings for switchover with offline "
                   "slave".format(test_num))
        off_slaves_str = ",".join(
            [slave2_conn, slave3_conn, "root@offline:1234"])
        cmd_str = ("mysqlrpladmin.py --master={0} --new-master={1} --slaves="
                   "{2} switchover ".format(master_conn, slave1_conn,
                                            off_slaves_str))
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Reset the topology, using a slave with GTID_MODE=OFF
        self.reset_topology([
            self.server2, self.server3, self.server4, self.server5,
            self.server7
        ])

        test_num += 1
        comment = ("Test case {0} - elect using a slave with "
                   "gtid disabled.".format(test_num))
        slave4_conn = self.build_connection_string(self.server7).strip(' ')
        slaves_str = ",".join(
            [slave1_conn, slave2_conn, slave3_conn, slave4_conn])
        cmd_str = ("mysqlrpladmin.py --master={0} --slaves={1} "
                   "elect".format(master_conn, slaves_str))
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Reset the topology, using a master with GTID_MODE=OFF
        self.reset_topology(
            [self.server2, self.server3, self.server4, self.server5],
            master=self.server6)

        test_num += 1
        comment = ("Test case {0} - elect using a master with "
                   "gtid disabled.".format(test_num))
        master2_conn = self.build_connection_string(self.server6).strip(' ')
        slaves_str = ",".join([slave1_conn, slave2_conn, slave3_conn])
        cmd_str = ("mysqlrpladmin.py --master={0} --slaves={1} "
                   "elect".format(master2_conn, slaves_str))
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Reset the topology to its original state for other tests
        self.reset_topology(
            [self.server2, self.server3, self.server4, self.server5])

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

        # Mask server port.
        self.replace_substring(str(self.server5.port), "PORT5")

        # Mask slaves behind master.
        # It happens sometimes on windows in a non-deterministic way.
        self.replace_substring(
            "+--------------------------------------------"
            "--+", "+---------------------------+")
        self.replace_substring(
            "| health                                     "
            "  |", "| health                    |")
        self.replace_substring(
            "| OK                                         "
            "  |", "| OK                        |")
        self.replace_substring(
            "| Slave delay is 1 seconds behind master., "
            "No  |", "| OK                        |")
        self.replace_substring(
            "| Cannot connect to slave.                   "
            "  |", "| Cannot connect to slave.  |")

        # Mask verbose health report.
        self.replace_result("localhost,PORT1,MASTER,UP,ON,OK,",
                            "localhost,PORT1,MASTER,UP,ON,OK, ...\n")
        self.replace_result("localhost,PORT2,SLAVE,UP,ON,OK,",
                            "localhost,PORT2,SLAVE,UP,ON,OK, ...\n")
        self.replace_result("localhost,PORT3,SLAVE,UP,ON,OK,",
                            "localhost,PORT3,SLAVE,UP,ON,OK, ...\n")
        self.replace_result("localhost,PORT4,SLAVE,UP,ON,OK,",
                            "localhost,PORT4,SLAVE,UP,ON,OK, ...\n")

        return True
Beispiel #23
0
            try:
                self.servers.spawn_new_servers(num_servers)
            except MUTLibError, e:
                raise MUTLibError("Cannot spawn needed servers: %s" % \
                                   e.errmsg)
        else:
            num_servers -= 1  # Get last server in list
        self.server0 = self.servers.get_server(0)

        index = self.servers.find_server_by_name("import_basic")
        if index >= 0:
            self.server1 = self.servers.get_server(index)
            try:
                res = self.server1.show_server_variable("server_id")
            except MUTLibError, e:
                raise MUTLibError("Cannot get import_basic server " +
                                  "server_id: %s" % e.errmsg)
            self.s1_serverid = int(res[0][1])
        else:
            self.s1_serverid = self.servers.get_next_id()
            res = self.servers.spawn_new_server(self.server0, self.s1_serverid,
                                                "import_basic")
            if not res:
                raise MUTLibError("Cannot spawn import_basic server.")
            self.server1 = res[0]
            self.servers.add_new_server(self.server1, True)
        try:
            self.server1.exec_query("SET GLOBAL default_storage_engine=MEMORY")
        except:
            self.server1.exec_query("SET GLOBAL storage_engine=MEMORY")

        return True
Beispiel #24
0
    def run(self):
        self.res_fname = "result.txt"

        base_cmd = "mysqlrpladmin.py "
        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(' ')

        master_str = "--master=" + master_conn

        # create a user for priv check
        self.server1.exec_query("CREATE USER 'joe'@'localhost'")
        self.server1.exec_query(
            "GRANT SELECT, SUPER ON *.* TO 'jane'@'localhost'")
        mock_master1 = "--master=joe@localhost:%s" % self.server1.port
        mock_master2 = "--master=jane@localhost:%s" % self.server1.port
        slaves_str = "--slaves=" + \
                     ",".join([slave1_conn, slave2_conn, slave3_conn])
        candidates_str = "--candidates=" + \
                         ",".join([slave1_conn, slave2_conn, slave3_conn])

        # List of test cases for test
        test_cases = [
            # (comment, ret_val, option1, ...),
            ("Multiple commands issued.", 2, "switchover", "start"),
            ("No commands.", 2, ""),
            ("Invalid command.", 2, "NOTACOMMAND"),
            ("Switchover but no --master, --new-master,", 2, "switchover"),
            ("No slaves or discover-slaves-login", 2, "switchover",
             master_str),
            ("Force used with failover", 2, "failover", "--force", master_str,
             slaves_str),
            ("Bad --new-master connection string", 2, "switchover", master_str,
             slaves_str, "--new-master=whatmeworry?"),
            ("Bad --master connection string", 1, "switchover", slaves_str,
             "--new-master=%s" % master_conn, "--master=whatmeworry?"),
            ("Bad --slaves connection string", 1, "switchover", master_str,
             "--new-master=%s" % master_conn, "--slaves=what,me,worry?"),
            ("Bad --candidates connection string", 1, "failover", master_str,
             slaves_str, "--candidates=what,me,worry?"),
            ("Not enough privileges - health joe", 1, "health", mock_master1,
             slaves_str),
            ("Not enough privileges - health jane", 0, "health", mock_master2,
             slaves_str),
            ("Not enough privileges - switchover jane", 1, "switchover",
             mock_master2, slaves_str, "--new-master=%s" % slave3_conn),
        ]

        test_num = 1
        for case in test_cases:
            comment = "Test case %s - %s" % (test_num, case[0])
            parts = [base_cmd]
            for opt in case[2:]:
                parts.append(opt)
            cmd_str = " ".join(parts)
            res = mutlib.System_test.run_test_case(self, case[1], cmd_str,
                                                   comment)
            if not res:
                raise MUTLibError("%s: failed" % comment)
            test_num += 1

        # Now test to see what happens when master is listed as a slave
        comment = "Test case %s - Master listed as a slave - literal" % test_num
        cmd_str = "%s health %s %s,%s" % (base_cmd, master_str, slaves_str,
                                          master_conn)
        res = mutlib.System_test.run_test_case(self, 2, cmd_str, comment)
        if not res:
            raise MUTLibError("%s: failed" % comment)
        test_num += 1

        comment = "Test case %s - Master listed as a slave - alias" % test_num
        cmd_str = "%s health %s %s" % (base_cmd, master_str,
                  "--slaves=root:root@%s:%s" % \
                    (socket.gethostname().split('.', 1)[0], self.server1.port))
        res = mutlib.System_test.run_test_case(self, 2, cmd_str, comment)
        if not res:
            raise MUTLibError("%s: failed" % comment)
        test_num += 1

        comment = "Test case %s - Master listed as a candiate - alias" % test_num
        cmd_str = "%s elect %s %s %s" % (base_cmd, master_str,
                  "--candidates=root:root@%s:%s" % \
                    (socket.gethostname().split('.', 1)[0], self.server1.port),
                  slaves_str)
        res = mutlib.System_test.run_test_case(self, 2, cmd_str, comment)
        if not res:
            raise MUTLibError("%s: failed" % comment)
        test_num += 1

        # Now we return the topology to its original state for other tests
        rpl_admin.test.reset_topology(self)

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

        self.replace_result(
            "mysqlrpladmin.py: error: New master connection "
            "values invalid", "mysqlrpladmin.py: error: New master connection "
            "values invalid\n")
        self.replace_result(
            "ERROR: Master connection values invalid or "
            "cannot be parsed", "ERROR: Master connection values invalid or "
            "cannot be parsed\n")
        self.replace_result(
            "ERROR: Slave connection values invalid or "
            "cannot be parsed", "ERROR: Slave connection values invalid or "
            "cannot be parsed\n")
        self.replace_result(
            "ERROR: Candidate connection values invalid or "
            "cannot be parsed",
            "ERROR: Candidate connection values invalid or "
            "cannot be parsed\n")

        return True
 def check_prerequisites(self):
     if not self.servers.get_server(0).check_version_compat(5, 6, 5):
         raise MUTLibError("Test requires server version prior to 5.6.5")
     return self.check_num_servers(1)
    def run(self):
        self.res_fname = "result.txt"

        from_conn = "--server={0}".format(
            self.build_connection_string(self.server1))
        conn_val = self.get_connection_values(self.server2)
        self.server2_conn = "-u{0} -p{1} --host=localhost ".format(
            conn_val[0], conn_val[1])
        if conn_val[3] is not None:
            self.server2_conn = "{0}--port={1} ".format(
                self.server2_conn, conn_val[3])

        cmd = "mysqldbexport.py {0} util_test --skip-gtid ".format(from_conn)

        test_num = 1
        comment = ("Test case {0} - export metadata to new server via the "
                   "mysql monitor".format(test_num))
        cmd_str = cmd + (" --export=definitions --format=SQL --quiet  "
                         "--skip=events,grants | "
                         "{0} {1} --protocol=tcp".format(
                             self.mysql_path, self.server2_conn))
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        self.results.append("{0}\n".format(
            self.check_objects(self.server2, "util_test", False)))

        test_num += 1
        comment = ("Test case {0} - export the data to "
                   "new server via the mysql monitor".format(test_num))
        cmd_str = cmd + (" --export=data --format=SQL --quiet  "
                         "--skip=events,grants | "
                         "{0} {1} --protocol=tcp".format(
                             self.mysql_path, self.server2_conn))
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        self.show_data("t1")
        self.show_data("t2")
        self.show_data("t3")
        self.show_data("t4")

        try:
            self.server2.exec_query("DROP DATABASE util_test")
        except UtilError:
            raise MUTLibError("Cannot drop database before import.")

        self.results.append("{0}\n".format(
            self.check_objects(self.server2, "util_test", False)))

        test_num += 1
        comment = ("Test case {0} - export all objects and data to new server "
                   "via the mysql monitor".format(test_num))
        cmd_str = cmd + (" --export=both --format=SQL --quiet  "
                         "--skip=events,grants | "
                         "{0} {1} --protocol=tcp".format(
                             self.mysql_path, self.server2_conn))
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        self.results.append("{0}\n".format(
            self.check_objects(self.server2, "util_test", False)))

        self.show_data("t1")
        self.show_data("t2")
        self.show_data("t3")
        self.show_data("t4")

        self.remove_result("Warning: Using a password on the")
        # mysql client might also issue a warning if a password is used on the
        # command line.
        self.remove_result("mysql: [Warning] Using a password on the command "
                           "line interface can be insecure.")

        return True
Beispiel #27
0
    def exec_export_import(self, server1, server2, exp_cmd, imp_cmd,
                           test_num, test_case, ret_val=True, reset=True,
                           load_data=True):
        """Execute export import.

        server1[in]     Server instance.
        server2[in]     Server instance.
        exp_cmd[in]     Export command.
        imp_cmd[in]     Import command.
        test_num[in]    Test number.
        test_case[in]   Test case.
        ret_val[in]     Return value.
        reset[in]       True for reset.
        load_data[in]   True for load data.
        """
        conn1 = "--server={0}".format(self.build_connection_string(server1))
        conn2 = "--server={0}".format(self.build_connection_string(server2))
        if load_data:
            try:
                server1.read_and_exec_SQL(self.data_file, self.debug)
            except UtilError as err:
                raise MUTLibError("Failed to read commands from file {0}: "
                                  "{1}".format(self.data_file, err.errmsg))

        comment = "Test case {0} (export phase) {1}".format(test_num,
                                                            test_case)
        cmd_str = "{0}{1} > {2}".format(exp_cmd, conn1, self.export_file)
        res = mutlib.System_test.run_test_case(self, 0, cmd_str, comment)
        if not res:
            # Output additional information if the executed command fails
            # in order to help determine the issue.
            print("Test output (results):")
            for row in self.results:
                print row,
            print("Command failing: {0}".format(cmd_str))
            print("Export file {0}:".format(self.export_file))
            with open(self.export_file.strip()) as f:
                for row in f:
                    print row,
            raise MUTLibError("{0}: failed".format(comment))

        # Display the export file if in debug mode
        if self.debug:
            with open(self.export_file.strip()) as f:
                for row in f:
                    print row,

        comment = "Test case {0} (import phase) {1}".format(test_num,
                                                            test_case)
        if reset:
            server2.exec_query("RESET MASTER")  # reset GTID_EXECUTED
        cmd_str = "{0}{1} {2}".format(imp_cmd, conn2, self.export_file)
        res = mutlib.System_test.run_test_case(self, 0, cmd_str, comment)
        if res != ret_val:
            # Output additional information if the executed command fails
            # in order to help determine the issue.
            print("Test output (results):")
            for row in self.results:
                print row,
            print("Command failing: {0}".format(cmd_str))
            print("Export file {0}:".format(self.export_file))
            with open(self.export_file.strip()) as f:
                for row in f:
                    print row,
            raise MUTLibError("{0}: failed".format(comment))
        self.drop_all()
    def run(self):
        test_num = 1

        self.server2.exec_query(_SET_SQL_LOG_BIN.format('0'))
        self.server2.exec_query(_CREATE_USER)
        self.server2.exec_query(_GRANT_QUERY)
        self.server2.exec_query(_SET_SQL_LOG_BIN.format('1'))
        self.server3.exec_query(_SET_SQL_LOG_BIN.format('0'))
        self.server3.exec_query(_CREATE_USER)
        self.server3.exec_query(_GRANT_QUERY)
        self.server3.exec_query(_SET_SQL_LOG_BIN.format('1'))
        self.server4.exec_query(_SET_SQL_LOG_BIN.format('0'))
        self.server4.exec_query(_CREATE_USER)
        self.server4.exec_query(_GRANT_QUERY)
        self.server4.exec_query(_SET_SQL_LOG_BIN.format('1'))
        self.server5.exec_query(_SET_SQL_LOG_BIN.format('0'))
        self.server5.exec_query(_CREATE_USER)
        self.server5.exec_query(_GRANT_QUERY)
        self.server5.exec_query(_SET_SQL_LOG_BIN.format('1'))

        # create a database then add data shutting down slaves to create
        # a scenario where the candidate slave has fewer transactions than
        # the slaves to execute the relay log execution logic and the
        # check for transactions to skip connecting candidate to slaves as
        # its master

        self.server1.exec_query("CREATE DATABASE test_relay")
        self.server1.exec_query("CREATE TABLE test_relay.t1"
                                "(a int, b char(20)) ENGINE=INNODB")
        self.server1.exec_query("INSERT INTO test_relay.t1 VALUES (1, 'one')")

        self.wait_for_slave(self.server1, self.server2)
        self.wait_for_slave(self.server1, self.server3)

        # Stop the candidate and one other slave
        self.server2.exec_query("STOP SLAVE")
        self.server3.exec_query("STOP SLAVE")

        self.server1.exec_query("INSERT INTO test_relay.t1 VALUES (2, 'two')")

        self.wait_for_slave(self.server1, self.server4)

        # Stop the third slave
        self.server4.exec_query("STOP SLAVE SQL_THREAD")

        self.server1.exec_query("INSERT INTO test_relay.t1 "
                                "VALUES (3, 'three')")
        self.server1.exec_query("INSERT INTO test_relay.t1 "
                                "VALUES (4, 'four')")

        self.wait_for_slave(self.server1, self.server5)

        # Show contents of server
        for server in self.servers_list:
            self.dump_table(server)

        comment = ("Test case {0} - failover to {1}:{2} with relay log "
                   "entries".format(test_num, self.server2.host,
                                    self.server2.port))
        slaves = ",".join([self.slave2_conn, self.slave3_conn,
                           self.slave4_conn])
        cmd_str = "mysqlrpladmin.py --master={0} ".format(self.master_conn)
        cmd_opts = (" --candidates={0} --slaves={1} failover -vvv "
                    "--force".format(self.slave1_conn, slaves))

        res = mutlib.System_test.run_test_case(self, 0, cmd_str + cmd_opts,
                                               comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))
        test_num += 1

        # Wait for slaves
        for slave in [self.server3, self.server4, self.server5]:
            self.wait_for_slave(self.server2, slave)

        # Show contents of server
        for server in self.servers_list:
            # ROLLBACK just to close any pending transaction, otherwise
            # dump_table() can return inconsistent values.
            server.rollback()
            self.dump_table(server)

        comment = ("Test case {0} - failover to {1}:{2} with skipping "
                   "slaves".format(test_num, self.server3.host,
                                   self.server3.port))
        slaves = ",".join([self.slave3_conn, self.slave4_conn])
        cmd_str = ("mysqlrpladmin.py --master={0} --candidates={1} "
                   "--slaves={2} failover -vvv"
                   "".format(self.slave1_conn, self.slave2_conn, slaves))
        res = mutlib.System_test.run_test_case(self, 0, cmd_str, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Now we return the topology to its original state for other tests
        rpl_admin.test.reset_topology(self)

        # Mask out non-deterministic data
        rpl_admin.test.do_masks(self)
        self.replace_substring(str(self.s4_port), "PORT5")

        # Strip health report - not needed.
        self.remove_result("+-")
        self.remove_result("| ")

        # Strip GTID detailed information
        self.replace_result("# QUERY = SELECT WAIT_UNTIL_SQL_THREAD_AFTER",
                            "# QUERY = SELECT WAIT_UNTIL_SQL_THREAD_AFTER"
                            "_GTIDS(XXXXXXXXX)\n")
        self.replace_result("# Return Code", "# Return Code = XXXX\n")

        return True
Beispiel #29
0
    def setup(self):
        self.server0 = self.servers.get_server(0)
        self.server1 = None
        self.server2 = None
        self.server3 = None

        index = self.servers.find_server_by_name("with_gtids_1")
        if index >= 0:
            self.server1 = self.servers.get_server(index)
            try:
                res = self.server1.show_server_variable("server_id")
            except UtilError as err:
                raise MUTLibError("Cannot get gtid enabled server 1 "
                                  "server_id: {0}".format(err.errmsg))
            self.s1_serverid = int(res[0][1])
        else:
            self.s1_serverid = self.servers.get_next_id()
            res = self.servers.spawn_new_server(
                self.server0, self.s1_serverid, "with_gtids_1",
                _DEFAULT_MYSQL_OPTS)
            if not res:
                raise MUTLibError("Cannot spawn gtid enabled server 1.")
            self.server1 = res[0]
            self.servers.add_new_server(self.server1, True)

        index = self.servers.find_server_by_name("with_gtids_2")
        if index >= 0:
            self.server2 = self.servers.get_server(index)
            try:
                res = self.server2.show_server_variable("server_id")
            except UtilError as err:
                raise MUTLibError("Cannot get gtid enabled server 2 "
                                  "server_id: {0}".format(err.errmsg))
            self.s2_serverid = int(res[0][1])
        else:
            self.s2_serverid = self.servers.get_next_id()
            res = self.servers.spawn_new_server(
                self.server0, self.s2_serverid, "with_gtids_2",
                _DEFAULT_MYSQL_OPTS)
            if not res:
                raise MUTLibError("Cannot spawn gtid enabled server 2.")
            self.server2 = res[0]
            self.servers.add_new_server(self.server2, True)

        index = self.servers.find_server_by_name("no_gtids")
        if index >= 0:
            self.server3 = self.servers.get_server(index)
            try:
                res = self.server3.show_server_variable("server_id")
            except UtilError as err:
                raise MUTLibError("Cannot get non-gtid server server_id: "
                                  "{0}".format(err.errmsg))
            self.s3_serverid = int(res[0][1])
        else:
            self.s3_serverid = self.servers.get_next_id()
            res = self.servers.spawn_new_server(self.server0, self.s3_serverid,
                                                "no_gtids",
                                                '"--log-bin=mysql-bin "')
            if not res:
                raise MUTLibError("Cannot spawn non-gtid server.")
            self.server3 = res[0]
            self.servers.add_new_server(self.server3, True)

        return True
Beispiel #30
0
    def test_rplms_daemon(self, cmd, logfile, comment, pidfile, stop_daemon):
        """Test multi-source replication daemon.

        cmd[in]           Command to be executed.
        logfile[in]       Log filename.
        comment[in]       Test comment.
        pidfile[in]       PID file.
        stop_daemon[in]   True to execute --daemon=stop

        This method create a process by executing the command and waits for
        the round-robin scheduling to switch all the masters. At the end
        compares the databases.
        """
        # Since this test case expects the process to stop, we can launch it
        # via a subprocess and wait for it to finish.
        if self.debug:
            print(comment)
            print("# COMMAND: {0}".format(cmd))

        # Run command
        proc, _ = self.start_process(cmd)

        # Wait for process to load
        if self.debug:
            print("# Waiting for daemon to start.")
        i = 1
        time.sleep(1)
        while proc.poll() is not None:
            time.sleep(1)
            i += 1
            if i > _TIMEOUT:
                if self.debug:
                    print("# Timeout daemon to start.")
                raise MUTLibError("{0}: failed - timeout waiting for "
                                  "daemon to start.".format(comment))

            # Since we don't have any control over the process, try to
            # read the PID to ensure that process started.
            try:
                with open(pidfile, "r") as f:
                    int(f.read().strip())
                break  # The daemon is running
            except IOError:
                continue
            except SystemExit:
                continue
            except ValueError:
                continue

        # Wait for logfile file to be created
        if self.debug:
            print("# Waiting for logfile to be created.")
        for i in range(_TIMEOUT):
            if os.path.exists(logfile):
                break
            else:
                time.sleep(1)
        else:
            raise MUTLibError("{0}: failed - timeout waiting for "
                              "logfile '{1}' to be "
                              "created.".format(comment, logfile))

        # Test if pidfile was created with the correct umask
        if oct(stat.S_IMODE(os.stat(pidfile).st_mode)) != "0640":
            raise MUTLibError("{0}: failed - the pidfile was not created with "
                              "the correct umask.".format(comment))

        # Wait for switching all the masters
        self.wait_for_switching_all_masters(logfile, comment)

        # Compare databases
        self.compare_databases(comment)

        if stop_daemon:
            # Stop daemon
            if self.debug:
                print("# Waiting for daemon to end.")

            # Build stop command by replacing (re)start for stop
            cmd_stop = re.sub("--daemon=(re)?start", "--daemon=stop", cmd)
            self.start_process(cmd_stop)
            i = 0
            while True:
                time.sleep(1)
                i += 1
                if i > _TIMEOUT:
                    if self.debug:
                        print("# Timeout daemon to stop.")
                    raise MUTLibError("{0}: failed - timeout waiting for "
                                      "daemon to stop.".format(comment))
                if not os.path.exists(pidfile):
                    break

            phrase = "Multi-source replication daemon stopped"
            if self.debug:
                print("# Waiting for multi-source replication daemon to stop.")
            i = 0
            with open(logfile, "r") as file_:
                while i < _TIMEOUT:
                    line = file_.readline()
                    if not line:
                        i += 1
                        time.sleep(1)
                    elif phrase in line:
                        break
                else:
                    if self.debug:
                        print("# Timeout waiting for multi-source replication "
                              "daemon to stop.")
                        raise MUTLibError("{0}: failed - timeout waiting for "
                                          "multi-source daemon to stop."
                                          "".format(comment))

        # Cleanup after test case
        try:
            os.unlink(logfile)
        except OSError:
            pass