def run(self):
        for i in range(0, len(_TEST_CASES)):
            if self.debug:
                print "\nTest case {0} - {1}".format(i + 1, _TEST_CASES[i][0])
            try:
                src_val = get_connection_dictionary(_TEST_CASES[i][1])
                server_options = {
                    'quiet': True,
                    'version': None,
                    'src_name': "test",
                    'dest_name': None,
                }
                connect_servers(src_val, None, server_options)
            except UtilError as err:
                self.results.append((True, err.errmsg))
            except ConnectionValuesError as err:
                self.results.append((True, err.errmsg))
            except FormatError as err:
                self.results.append((True, err))
            else:
                self.results.append((False, ''))
            if self.debug:
                print "Test results:", self.results[i][0], self.results[i][1]

        return True
    def run(self):
        for i in range(0, len(_TEST_CASES)):
            if self.debug:
                print "\nTest case {0} - {1}".format(i + 1, _TEST_CASES[i][0])
            try:
                src_val = get_connection_dictionary(_TEST_CASES[i][1])
                server_options = {'quiet': True, 'version': None,
                                  'src_name': "test", 'dest_name': None, }
                connect_servers(src_val, None, server_options)
            except UtilError as err:
                self.results.append((True, err.errmsg))
            except ConnectionValuesError as err:
                self.results.append((True, err.errmsg))
            except FormatError as err:
                self.results.append((True, err))
            else:
                self.results.append((False, ''))
            if self.debug:
                print "Test results:", self.results[i][0], self.results[i][1]

        test_num = len(_TEST_CASES) + 1
        comment = "Compare dictionaries with socket only"

        if self.debug:
            print "\nTest case {0} - {1}".format(test_num, comment)
        server1_vals = get_connection_dictionary("test_server1")
        server1_vals['port'] = None
        server2_vals = get_connection_dictionary("test_server2")
        server2_vals['port'] = None
        res = check_hostname_alias(server1_vals, server2_vals)
        # Add test case so that results match.
        _TEST_CASES.append((comment, "test_server1", False))
        self.results.append((res, ''))

        if self.debug:
            print "Test results:", res, False

        self.remove_login_path_data('test_server1')
        self.remove_login_path_data('test_server2')

        return True
示例#3
0
 def run(self):
     for i in range(0, len(_TEST_CASES)):
         if self.debug:
             print "\nTest case %s - %s" % (i + 1, _TEST_CASES[i][0])
         try:
             src_val = get_connection_dictionary(_TEST_CASES[i][1])
             server_options = {
                 'quiet': True,
                 'version': None,
                 'src_name': "test",
                 'dest_name': None,
             }
             s = connect_servers(src_val, None, server_options)
         except UtilError, e:
             self.results.append((True, e.errmsg))
         except FormatError, e:
             self.results.append((True, e))
 def run(self):
     for i in range(0,len(_TEST_CASES)):
         if self.debug:
           print "\nTest case %s - %s" % (i+1, _TEST_CASES[i][0])
         try:
             src_val = get_connection_dictionary(_TEST_CASES[i][1])
             server_options = {
                 'quiet'     : True,
                 'version'   : None,
                 'src_name'  : "test",
                 'dest_name' : None,
             }
             s = connect_servers(src_val, None, server_options)
         except UtilError, e:
             self.results.append((True, e.errmsg))
         except FormatError, e:
             self.results.append((True, e))
    def run(self):
        for i in range(0, len(_TEST_CASES)):
            if self.debug:
                print "\nTest case {0} - {1}".format(i + 1, _TEST_CASES[i][0])
            try:
                src_val = get_connection_dictionary(_TEST_CASES[i][1])
                server_options = {'quiet': True, 'version': None,
                                  'src_name': "test", 'dest_name': None, }
                connect_servers(src_val, None, server_options)
            except UtilError as err:
                self.results.append((True, err.errmsg))
            except ConnectionValuesError as err:
                self.results.append((True, err.errmsg))
            except FormatError as err:
                self.results.append((True, err))
            else:
                self.results.append((False, ''))
            if self.debug:
                print "Test results:", self.results[i][0], self.results[i][1]

        return True
示例#6
0
def show_server_info(servers, options):
    """Show server information for a list of servers

    This method will gather information about a running server. If the
    show_defaults option is specified, the method will also read the
    configuration file and return a list of the server default settings.

    If the format option is set, the output will be in the format specified.

    If the no_headers option is set, the output will not have a header row (no
    column names) except for format = vertical.

    If the basedir and start options are set, the method will attempt to start
    the server in read only mode to get the information. Specifying only
    basedir will not start the server. The extra start option is designed to
    make sure the user wants to start the offline server. The user may not wish
    to do this if there are certain error conditions and/or logs in place that
    may be overwritten.

    servers[in]       list of server connections in the form
                      <user>:<password>@<host>:<port>:<socket>
    options[in]       dictionary of options (no_headers, format, basedir,
                      start, show_defaults)

    Returns tuple ((server information), defaults)
    """
    no_headers = options.get("no_headers", False)
    fmt = options.get("format", "grid")
    show_defaults = options.get("show_defaults", False)
    basedir = options.get("basedir", None)
    datadir = options.get("datadir", None)
    start = options.get("start", False)
    show_servers = options.get("show_servers", 0)

    if show_servers:
        if os.name == 'nt':
            ports = options.get("ports", "3306:3333")
            start_p, end_p = ports.split(":")
            _show_running_servers(start_p, end_p)
        else:
            _show_running_servers()

    row_dict_lst = []
    warnings = []
    server_val = {}
    for server in servers:
        new_server = None
        try:
            test_connect(server, True)
        except UtilError as util_error:
            conn_dict = get_connection_dictionary(server)
            server1 = Server(options={'conn_info': conn_dict})
            server_is_off = False
            # If we got errno 2002 it means can not connect through the
            # given socket, but if path to socket not empty, server could be
            # turned off.
            if util_error.errno == CR_CONNECTION_ERROR:
                socket = conn_dict.get("unix_socket", "")
                if socket:
                    mydir = os.path.split(socket)[0]
                    if os.path.isdir(mydir) and len(os.listdir(mydir)) != 0:
                        server_is_off = True
            # If we got errno 2003 and this is a windows, we do not have
            # socket, instead we check if server is localhost.
            elif (util_error.errno == CR_CONN_HOST_ERROR and
                  os.name == 'nt' and server1.is_alias("localhost")):
                server_is_off = True
            # If we got errno 1045 it means Access denied,
            # notify the user if a password was used or not.
            elif util_error.errno == ER_ACCESS_DENIED_ERROR:
                use_pass = '******' if conn_dict['passwd'] else 'NO'
                er = ("Access denied for user '{0}'@'{1}' using password: {2}"
                      ).format(conn_dict['user'], conn_dict['host'], use_pass)
            # Use the error message from the connection attempt.
            else:
                er = [util_error.errmsg]
            # To propose to start a cloned server for extract the info,
            # can not predict if the server is really off, but we can do it
            # in case of socket error, or if one of the related
            # parameter was given.
            if (server_is_off or basedir or datadir or start):
                er = ["Server is offline. To connect, "
                      "you must also provide "]

                opts = ["basedir", "datadir", "start"]
                for opt in tuple(opts):
                    try:
                        if locals()[opt] is not None:
                            opts.remove(opt)
                    except KeyError:
                        pass
                if opts:
                    er.append(", ".join(opts[0:-1]))
                    if len(opts) > 1:
                        er.append(" and the ")
                    er.append(opts[-1])
                    er.append(" option")
                    raise UtilError("".join(er))

            if not start:
                raise UtilError("".join(er))
            else:
                try:
                    server_val = parse_connection(server, None, options)
                except:
                    raise UtilError("Source connection values invalid"
                                    " or cannot be parsed.")
                new_server = _start_server(server_val, basedir,
                                           datadir, options)
        info_dict, defaults = _server_info(server, show_defaults, options)
        warnings.extend(info_dict['warnings'])
        if info_dict:
            row_dict_lst.append(info_dict)
        if new_server:
            # Need to stop the server!
            new_server.disconnect()
            _stop_server(server_val, basedir, options)

    # Get the row values stored in the dictionaries
    rows = [[row_dict[key] for key in _COLUMNS] for row_dict in row_dict_lst]

    print_list(sys.stdout, fmt, _COLUMNS, rows, no_headers)
    if warnings:
        print("\n# List of Warnings: \n")
        for warning in warnings:
            print("WARNING: {0}\n".format(warning))

    # Print the default configurations.
    if show_defaults and len(defaults) > 0:
        for row in defaults:
            print("  {0}".format(row))
示例#7
0
def show_server_info(servers, options):
    """Show server information for a list of servers

    This method will gather information about a running server. If the
    show_defaults option is specified, the method will also read the
    configuration file and return a list of the server default settings.

    If the format option is set, the output will be in the format specified.

    If the no_headers option is set, the output will not have a header row (no
    column names) except for format = vertical.

    If the basedir and start options are set, the method will attempt to start
    the server in read only mode to get the information. Specifying only
    basedir will not start the server. The extra start option is designed to
    make sure the user wants to start the offline server. The user may not wish
    to do this if there are certain error conditions and/or logs in place that
    may be overwritten.

    servers[in]       list of server connections in the form
                      <user>:<password>@<host>:<port>:<socket>
    options[in]       dictionary of options (no_headers, format, basedir,
                      start, show_defaults)

    Returns tuple ((server information), defaults)
    """
    no_headers = options.get("no_headers", False)
    fmt = options.get("format", "grid")
    show_defaults = options.get("show_defaults", False)
    basedir = options.get("basedir", None)
    datadir = options.get("datadir", None)
    start = options.get("start", False)
    show_servers = options.get("show_servers", 0)

    if show_servers:
        if os.name == 'nt':
            ports = options.get("ports", "3306:3333")
            start_p, end_p = ports.split(":")
            _show_running_servers(start_p, end_p)
        else:
            _show_running_servers()

    ssl_dict = {}
    ssl_dict['ssl_cert'] = options.get("ssl_cert", None)
    ssl_dict['ssl_ca'] = options.get("ssl_ca", None)
    ssl_dict['ssl_key'] = options.get("ssl_key", None)
    ssl_dict['ssl'] = options.get("ssl", None)

    row_dict_lst = []
    warnings = []
    server_val = {}
    for server in servers:
        new_server = None
        try:
            test_connect(server, throw_errors=True, ssl_dict=ssl_dict)
        except UtilError as util_error:
            conn_dict = get_connection_dictionary(server, ssl_dict=ssl_dict)
            server1 = Server(options={'conn_info': conn_dict})
            server_is_off = False
            # If we got errno 2002 it means can not connect through the
            # given socket.
            if util_error.errno == CR_CONNECTION_ERROR:
                socket = conn_dict.get("unix_socket", "")
                if socket:
                    msg = ("Unable to connect to server using socket "
                           "'{0}'.".format(socket))
                    if os.path.isfile(socket):
                        err_msg = ["{0} Socket file is not valid.".format(msg)]
                    else:
                        err_msg = [
                            "{0} Socket file does not "
                            "exist.".format(msg)
                        ]
            # If we got errno 2003 and we do not have
            # socket, instead we check if server is localhost.
            elif (util_error.errno == CR_CONN_HOST_ERROR
                  and server1.is_alias("localhost")):
                server_is_off = True
            # If we got errno 1045 it means Access denied,
            # notify the user if a password was used or not.
            elif util_error.errno == ER_ACCESS_DENIED_ERROR:
                use_pass = '******' if conn_dict['passwd'] else 'NO'
                err_msg = ("Access denied for user '{0}'@'{1}' using "
                           "password: {2}".format(conn_dict['user'],
                                                  conn_dict['host'], use_pass))
            # Use the error message from the connection attempt.
            else:
                err_msg = [util_error.errmsg]
            # To propose to start a cloned server for extract the info,
            # can not predict if the server is really off, but we can do it
            # in case of socket error, or if one of the related
            # parameter was given.
            if server_is_off or basedir or datadir or start:
                err_msg = [
                    "Server is offline. To connect, "
                    "you must also provide "
                ]

                opts = ["basedir", "datadir", "start"]
                for opt in tuple(opts):
                    try:
                        if locals()[opt] is not None:
                            opts.remove(opt)
                    except KeyError:
                        pass
                if opts:
                    err_msg.append(", ".join(opts[0:-1]))
                    if len(opts) > 1:
                        err_msg.append(" and the ")
                    err_msg.append(opts[-1])
                    err_msg.append(" option")
                    raise UtilError("".join(err_msg))

            if not start:
                raise UtilError("".join(err_msg))
            else:
                try:
                    server_val = parse_connection(server, None, options)
                except:
                    raise UtilError("Source connection values invalid"
                                    " or cannot be parsed.")
                new_server = _start_server(server_val, basedir, datadir,
                                           options)
        info_dict, defaults = _server_info(server, show_defaults, options)
        warnings.extend(info_dict['warnings'])
        if info_dict:
            row_dict_lst.append(info_dict)
        if new_server:
            # Need to stop the server!
            new_server.disconnect()
            _stop_server(server_val, basedir, options)

    # Get the row values stored in the dictionaries
    rows = [[row_dict[key] for key in _COLUMNS] for row_dict in row_dict_lst]

    print_list(sys.stdout, fmt, _COLUMNS, rows, no_headers)
    if warnings:
        print("\n# List of Warnings: \n")
        for warning in warnings:
            print("WARNING: {0}\n".format(warning))

    # Print the default configurations.
    if show_defaults and len(defaults) > 0:
        for row in defaults:
            print("  {0}".format(row))
示例#8
0
    def test_failover_console(self, test_case, timeout=_TIMEOUT):
        """Tests failover console.

        test_case[in]     Test case.
        """
        server = test_case[0]
        cmd = test_case[1]
        kill_console = test_case[2]
        log_filename = test_case[3]
        comment = test_case[4]
        key_phrase = test_case[5]
        unregister = test_case[6]
        server_version = server.get_version()

        if unregister:
            # Unregister any failover instance from server
            try:
                server.exec_query("DROP TABLE IF EXISTS "
                                  "mysql.failover_console")
            except UtilError:
                pass

        # Since this test case expects the console 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))

        # Cleanup in case previous test case failed
        if os.path.exists(self.failover_dir):
            try:
                os.system("rmdir {0}".format(self.failover_dir))
            except OSError:
                pass

        # Launch the console in stealth mode
        proc, f_out = self.start_process(cmd)

        # Wait for console to load
        if self.debug:
            print("# Waiting for console 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 console to start.")
                raise MUTLibError("{0}: failed - timeout waiting for "
                                  "console to start.".format(comment))

        # Wait for the failover console to register on master and start
        # its monitoring process

        phrase = "Failover console started"
        if self.debug:
            print("Waiting for failover console to register master and start "
                  "its monitoring process")
        # Wait because of the warning message that may appear due to
        # mixing hostnames and IP addresses
        time.sleep(WARNING_SLEEP_TIME + 1)
        i = 0

        # 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(log_filename):
                break
            else:
                time.sleep(1)
        else:
            raise MUTLibError("{0}: failed - timeout waiting for "
                              "logfile '{1}' to be "
                              "created.".format(comment, log_filename))

        with open(log_filename, '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 failover console to register "
                          "master and start its monitoring process")
                raise MUTLibError("{0}: failed - timeout waiting for console "
                                  "to register master and start its "
                                  "monitoring process".format(comment))

        # Now, kill the master - wha-ha-ha!
        res = server.show_server_variable('pid_file')
        pid_file = open(res[0][1])
        pid = int(pid_file.readline().strip('\n'))
        if self.debug:
            print("# Terminating server {0} via pid = {1}".format(server.port,
                                                                  pid))
        pid_file.close()

        # Get server datadir to clean directory after kill.
        res = server.show_server_variable("datadir")
        datadir = res[0][1]

        # Stop the server
        server.disconnect()
        self.kill(pid)

        # Need to wait until the process is really dead.
        if self.debug:
            print("# Waiting for master to stop.")
        i = 0
        while self.is_process_alive(pid, int(server.port) - 1,
                                    int(server.port) + 1):
            time.sleep(1)
            i += 1
            if i > timeout:
                if self.debug:
                    print("# Timeout master to fail.")
                raise MUTLibError("{0}: failed - timeout waiting for "
                                  "master to end.".format(comment))

        # Remove server from the list (and clean data directory).
        if self.debug:
            print("# Removing server name '{0}'.".format(server.role))
        delete_directory(datadir)
        self.servers.remove_server(server.role)

        # Now wait for interval to occur.
        if self.debug:
            print("# Waiting for failover to complete.")
        i = 0
        while not os.path.isdir(self.failover_dir):
            time.sleep(5)
            i += 1
            if i > timeout:
                if self.debug:
                    print("# Timeout console failover.")
                raise MUTLibError("{0}: failed - timeout waiting for "
                                  "exec_post_fail.".format(comment))

        # Need to poll here and wait for console to really end.
        ret_val = self.stop_process(proc, f_out, kill_console)
        # Wait for console to end
        if self.debug:
            print("# Waiting for console to end.")
        i = 0
        while proc.poll() is None:
            time.sleep(1)
            i += 1
            if i > timeout:
                if self.debug:
                    print("# Timeout console to end.")
                raise MUTLibError("{0}: failed - timeout waiting for "
                                  "console to end.".format(comment))

        if self.debug:
            print("# Return code from console termination = "
                  "{0}".format(ret_val))

        # Check result code from stop_process then read the log to find the
        # key phrase.
        found_row = False
        log_file = open(log_filename)
        rows = log_file.readlines()
        if self.debug:
            print("# Looking in log for: {0}".format(key_phrase))
        for row in rows:
            if key_phrase in row:
                found_row = True
                if self.debug:
                    print("# Found in row = '{0}'.".format(row[:len(row) - 1]))

        # Find MySQL Utilities version in the log
        if self.debug:
            print("# Looking in log for: {0}"
                  "".format(_UTILITIES_VERSION_PHRASE))
        for row in rows:
            if _UTILITIES_VERSION_PHRASE in row:
                found_row = True
                if self.debug:
                    print("# Found in row = '{0}'.".format(row[:-1]))
                break

        # Find MySQL server version in the log
        host_port = "{host}:{port}".format(**get_connection_dictionary(server))
        key_phrase = MSG_MYSQL_VERSION.format(server=host_port,
                                              version=server_version)
        if self.debug:
            print("# Looking in log for: {0}".format(key_phrase))
        for row in rows:
            if key_phrase in row:
                found_row = True
                if self.debug:
                    print("# Found in row = '{0}'.".format(row[:-1]))
                break

        log_file.close()

        if not found_row:
            print("# ERROR: Cannot find entry in log:")
            for row in rows:
                print row,

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

        if os.path.exists(self.failover_dir):
            try:
                os.system("rmdir {0}".format(self.failover_dir))
            except OSError:
                pass

        return comment, found_row
示例#9
0
    def run(self):
        self.res_fname = "result.txt"
        from_conn = self.build_connection_string(self.server1)
        conn_val = self.get_connection_values(self.server1)

        cmd_str = "mysqlprocgrep.py --server={0} ".format(from_conn)
        test_num = 1
        comment = "Test case {0} - do the help".format(test_num)
        res = self.run_test_case(0, cmd_str + "--help", comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Remove version information
        self.remove_result_and_lines_after(
            "MySQL Utilities mysqlprocgrep.py "
            "version", 6)

        test_num += 1
        comment = "Test case {0} - do the SQL for a simple search".format(
            test_num)
        cmd_str = "mysqlprocgrep.py --sql --match-user={0} ".format(
            conn_val[0])
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # execute the mysql client to create a new connection
        conn_dict = get_connection_dictionary(self.server1)
        arguments = [
            self.mysql_path,
            "-u{0}".format(conn_dict['user']),
            "-p{0}".format(conn_dict['passwd']),
            "-h127.0.0.1",
            "--port={0}".format(conn_dict['port']),
            "mysql",
        ]
        out_file = tempfile.TemporaryFile()
        proc = subprocess.Popen(arguments,
                                stdout=out_file,
                                stdin=subprocess.PIPE,
                                stderr=out_file)
        # wait for console to start
        time.sleep(5)
        test_num += 1
        processes = self.server1.exec_query("show processlist")
        for proc_item in processes:
            if proc_item[3] == "mysql" and proc_item[4] == "Sleep":
                proc_id = proc_item[0]
            else:
                proc_id = 0
        comment = "Test case {0} - do kill".format(test_num)
        cmd_str = "mysqlprocgrep.py {0}{1} {2} {3} {4} {5}{6} {7}".format(
            "--match-user="******"--match-command=Sleep",
            "--match-db=mysql", "--kill-connection", "--server=", from_conn,
            "--format=CSV")
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        kill_process(proc)

        # Mask out process list for deterministic result
        self.replace_result("{0},".format(proc_id), "XXX,...\n")

        self.mask_result("    USER LIKE 'root'", "    USER LIKE 'root'",
                         "    USER LIKE 'XXXX'")

        # Mask funny output on Windows
        if os.name != "posix":
            self.replace_result("    USER LIKE ", "    USER LIKE 'XXXX'\n")

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

        return True
    def run(self):
        master_conn = self.build_connection_string(self.server1).strip(' ')
        slave_conn = self.build_connection_string(self.server2).strip(' ')

        # For this test, it's OK when master and slave are the same
        master_str = "--master={0}".format(master_conn)
        slave_str = "--slave={0}".format(slave_conn)

        # command used in test cases: replace 3 element with location of
        # log file.
        cmd = [
            "mysqlrpladmin.py",
            master_str,
            slave_str,
            "--log={0}".format(_LOGNAME),
            "health",
        ]

        # Test Case 1
        test_num = 1
        comment = "Test Case {0} - Log file is newly created".format(test_num)
        res = mutlib.System_test.run_test_case(self, 0, ' '.join(cmd), comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Test Case 2
        test_num += 1
        comment = "Test Case {0} - Log file is reopened".format(test_num)
        res = mutlib.System_test.run_test_case(self, 0, ' '.join(cmd), comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Test Case 3
        test_num += 1
        comment = ("Test Case {0} - Log file can not be "
                   "written to".format(test_num))
        os.chmod(_LOGNAME, stat.S_IREAD)  # Make log read-only
        res = mutlib.System_test.run_test_case(self, 2, ' '.join(cmd), comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Find MySQL and Utilities versions in the log
        self.find_stop_phrase(
            _LOGNAME, comment,
            MSG_UTILITIES_VERSION.format(utility="mysqlrpladmin",
                                         version=VERSION_STRING))

        # Find master MySQL server version in the log
        master_host_port = ("{host}:{port}".format(
            **get_connection_dictionary(master_conn)))
        self.find_stop_phrase(
            _LOGNAME, comment,
            MSG_MYSQL_VERSION.format(server=master_host_port,
                                     version=self.server1.get_version()))

        # Find slave MySQL server version in the log
        slave_host_port = ("{host}:{port}".format(
            **get_connection_dictionary(slave_conn)))
        self.find_stop_phrase(
            _LOGNAME, comment,
            MSG_MYSQL_VERSION.format(server=slave_host_port,
                                     version=self.server2.get_version()))

        # Mask out non-deterministic data
        rpl_admin.test.do_masks(self)
        self.remove_result("NOTE: Log file 'temp_log.txt' does not exist. "
                           "Will be created.")

        return True
    def run(self):
        self.res_fname = "result.txt"
        from_conn = self.build_connection_string(self.server1)
        conn_val = self.get_connection_values(self.server1)

        cmd_str = "mysqlprocgrep.py --server={0} ".format(from_conn)
        test_num = 1
        comment = "Test case {0} - do the help".format(test_num)
        res = self.run_test_case(0, cmd_str + "--help", comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Remove version information
        self.remove_result_and_lines_after("MySQL Utilities mysqlprocgrep.py "
                                           "version", 6)

        test_num += 1
        comment = "Test case {0} - do the SQL for a simple search".format(
            test_num)
        cmd_str = "mysqlprocgrep.py --sql --match-user={0} ".format(
            conn_val[0])
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # execute the mysql client to create a new connection
        conn_dict = get_connection_dictionary(self.server1)
        arguments = [
            self.mysql_path,
            "-u{0}".format(conn_dict['user']),
            "-p{0}".format(conn_dict['passwd']),
            "-h127.0.0.1",
            "--port={0}".format(conn_dict['port']),
            "mysql",
        ]
        out_file = tempfile.TemporaryFile()
        proc = subprocess.Popen(arguments, stdout=out_file,
                                stdin=subprocess.PIPE, stderr=out_file)
        # wait for console to start
        time.sleep(5)
        test_num += 1
        processes = self.server1.exec_query("show processlist")
        for proc_item in processes:
            if proc_item[3] == "mysql" and proc_item[4] == "Sleep":
                proc_id = proc_item[0]
            else:
                proc_id = 0
        comment = "Test case {0} - do kill".format(
            test_num)
        cmd_str = "mysqlprocgrep.py {0}{1} {2} {3} {4} {5}{6} {7}".format(
            "--match-user="******"--match-command=Sleep",
            "--match-db=mysql", "--kill-connection", "--server=",
            from_conn, "--format=CSV")
        res = self.run_test_case(0, cmd_str, comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        kill_process(proc)

        # Mask out process list for deterministic result
        self.replace_result("{0},".format(proc_id), "XXX,...\n")

        self.mask_result("    USER LIKE 'root'", "    USER LIKE 'root'",
                         "    USER LIKE 'XXXX'")

        # Mask funny output on Windows
        if os.name != "posix":
            self.replace_result("    USER LIKE ", "    USER LIKE 'XXXX'\n")

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

        return True
    def run(self):
        master_conn = self.build_connection_string(self.server1).strip(' ')
        slave_conn = self.build_connection_string(self.server2).strip(' ')

        # For this test, it's OK when master and slave are the same
        master_str = "--master={0}".format(master_conn)
        slave_str = "--slave={0}".format(slave_conn)

        # command used in test cases: replace 3 element with location of
        # log file.
        cmd = [
            "mysqlrpladmin.py",
            master_str,
            slave_str,
            "--log={0}".format(_LOGNAME),
            "health",
        ]

        # Test Case 1
        test_num = 1
        comment = "Test Case {0} - Log file is newly created".format(test_num)
        res = mutlib.System_test.run_test_case(
            self, 0, ' '.join(cmd), comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Test Case 2
        test_num += 1
        comment = "Test Case {0} - Log file is reopened".format(test_num)
        res = mutlib.System_test.run_test_case(
            self, 0, ' '.join(cmd), comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Test Case 3
        test_num += 1
        comment = ("Test Case {0} - Log file can not be "
                   "written to".format(test_num))
        os.chmod(_LOGNAME, stat.S_IREAD)  # Make log read-only
        res = mutlib.System_test.run_test_case(
            self, 2, ' '.join(cmd), comment)
        if not res:
            raise MUTLibError("{0}: failed".format(comment))

        # Find MySQL and Utilities versions in the log
        self.find_stop_phrase(_LOGNAME, comment, MSG_UTILITIES_VERSION.format(
            utility="mysqlrpladmin", version=VERSION_STRING))

        # Find master MySQL server version in the log
        master_host_port = (
            "{host}:{port}".format(**get_connection_dictionary(master_conn)))
        self.find_stop_phrase(_LOGNAME, comment, MSG_MYSQL_VERSION.format(
            server=master_host_port, version=self.server1.get_version()))

        # Find slave MySQL server version in the log
        slave_host_port = (
            "{host}:{port}".format(**get_connection_dictionary(slave_conn)))
        self.find_stop_phrase(_LOGNAME, comment, MSG_MYSQL_VERSION.format(
            server=slave_host_port, version=self.server2.get_version()))

        # Mask out non-deterministic data
        rpl_admin.test.do_masks(self)
        self.remove_result("NOTE: Log file 'temp_log.txt' does not exist. "
                           "Will be created.")

        return True
示例#13
0
    def test_rplms(self, cmd, logfile, comment, kill_process=True,
                   stop_phrase=None):
        """Test multi-source replication.

        cmd[in]           Command to be executed.
        logfile[in]       Log filename.
        comment[in]       Test comment.
        kill_process[in]  True if the process is to be killed.
        stop_phrase[in]   Stop phrase to be searched in the log.

        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, f_out = self.start_process(cmd)

        # Wait for process to load
        if self.debug:
            print("# Waiting for process 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 process to start.")
                raise MUTLibError("{0}: failed - timeout waiting for "
                                  "process to start.".format(comment))

        # 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))

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

        # Compare databases
        self.compare_databases(comment)

        # Kill process
        if kill_process:
            self.kill_process(proc, f_out, comment)

        # Find stop phrase
        if stop_phrase:
            self.find_stop_phrase(logfile, comment, stop_phrase)

        # Find MySQL Utilities version in the log
        utils_phrase = MSG_UTILITIES_VERSION.format(utility="mysqlrplms",
                                                    version=VERSION_STRING)
        self.find_stop_phrase(logfile, comment, utils_phrase)

        # Find MySQL servers versions in the log
        for server in (self.server1, self.server2, self.server3,):
            host_port = "{host}:{port}".format(
                **get_connection_dictionary(server))
            server_version = server.get_version()
            mysql_phrase = MSG_MYSQL_VERSION.format(server=host_port,
                                                    version=server_version)
            self.find_stop_phrase(logfile, comment, mysql_phrase)

        # Cleanup after test case
        try:
            os.unlink(logfile)
        except OSError:
            pass
示例#14
0
    def test_rplms(self, cmd, logfile, comment, kill_process=True,
                   stop_phrase=None):
        """Test multi-source replication.

        cmd[in]           Command to be executed.
        logfile[in]       Log filename.
        comment[in]       Test comment.
        kill_process[in]  True if the process is to be killed.
        stop_phrase[in]   Stop phrase to be searched in the log.

        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, f_out = self.start_process(cmd)

        # Wait for process to load
        if self.debug:
            print("# Waiting for process 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 process to start.")
                raise MUTLibError("{0}: failed - timeout waiting for "
                                  "process to start.".format(comment))

        # 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))

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

        # Compare databases
        self.compare_databases(comment)

        # Kill process
        if kill_process:
            self.kill_process(proc, f_out, comment)

        # Find stop phrase
        if stop_phrase:
            self.find_stop_phrase(logfile, comment, stop_phrase)

        # Find MySQL Utilities version in the log
        utils_phrase = MSG_UTILITIES_VERSION.format(utility="mysqlrplms",
                                                    version=VERSION_STRING)
        self.find_stop_phrase(logfile, comment, utils_phrase)

        # Find MySQL servers versions in the log
        for server in (self.server1, self.server2, self.server3,):
            host_port = "{host}:{port}".format(
                **get_connection_dictionary(server))
            server_version = server.get_version()
            mysql_phrase = MSG_MYSQL_VERSION.format(server=host_port,
                                                    version=server_version)
            self.find_stop_phrase(logfile, comment, mysql_phrase)

        # Cleanup after test case
        try:
            os.unlink(logfile)
        except OSError:
            pass
示例#15
0
    def test_failover_console(self, test_case):
        """Tests failover console.

        test_case[in]     Test case.
        """
        server = test_case[0]
        cmd = test_case[1]
        kill_console = test_case[2]
        log_filename = test_case[3]
        comment = test_case[4]
        key_phrase = test_case[5]
        unregister = test_case[6]
        server_version = server.get_version()

        if unregister:
            # Unregister any failover instance from server
            try:
                server.exec_query("DROP TABLE IF EXISTS "
                                  "mysql.failover_console")
            except UtilError:
                pass

        # Since this test case expects the console 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))

        # Cleanup in case previous test case failed
        if os.path.exists(self.failover_dir):
            try:
                os.system("rmdir {0}".format(self.failover_dir))
            except OSError:
                pass

        # Launch the console in stealth mode
        proc, f_out = self.start_process(cmd)

        # Wait for console to load
        if self.debug:
            print("# Waiting for console 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 console to start.")
                raise MUTLibError("{0}: failed - timeout waiting for "
                                  "console to start.".format(comment))

        # Wait for the failover console to register on master and start
        # its monitoring process

        phrase = "Failover console started"
        if self.debug:
            print("Waiting for failover console to register master and start "
                  "its monitoring process")
        # Wait because of the warning message that may appear due to
        # mixing hostnames and IP addresses
        time.sleep(WARNING_SLEEP_TIME + 1)
        i = 0

        # 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(log_filename):
                break
            else:
                time.sleep(1)
        else:
            raise MUTLibError("{0}: failed - timeout waiting for "
                              "logfile '{1}' to be "
                              "created.".format(comment, log_filename))

        with open(log_filename, '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 failover console to register "
                          "master and start its monitoring process")
                raise MUTLibError("{0}: failed - timeout waiting for console "
                                  "to register master and start its "
                                  "monitoring process".format(comment))

        # Now, kill the master - wha-ha-ha!
        res = server.show_server_variable('pid_file')
        pid_file = open(res[0][1])
        pid = int(pid_file.readline().strip('\n'))
        if self.debug:
            print("# Terminating server {0} via pid = {1}".format(server.port,
                                                                  pid))
        pid_file.close()

        # Get server datadir to clean directory after kill.
        res = server.show_server_variable("datadir")
        datadir = res[0][1]

        # Stop the server
        server.disconnect()
        self.kill(pid)

        # Need to wait until the process is really dead.
        if self.debug:
            print("# Waiting for master to stop.")
        i = 0
        while self.is_process_alive(pid, int(server.port) - 1,
                                    int(server.port) + 1):
            time.sleep(1)
            i += 1
            if i > _TIMEOUT:
                if self.debug:
                    print("# Timeout master to fail.")
                raise MUTLibError("{0}: failed - timeout waiting for "
                                  "master to end.".format(comment))

        # Remove server from the list (and clean data directory).
        if self.debug:
            print("# Removing server name '{0}'.".format(server.role))
        delete_directory(datadir)
        self.servers.remove_server(server.role)

        # Now wait for interval to occur.
        if self.debug:
            print("# Waiting for failover to complete.")
        i = 0
        while not os.path.isdir(self.failover_dir):
            time.sleep(5)
            i += 1
            if i > _TIMEOUT:
                if self.debug:
                    print("# Timeout console failover.")
                raise MUTLibError("{0}: failed - timeout waiting for "
                                  "exec_post_fail.".format(comment))

        # Need to poll here and wait for console to really end.
        ret_val = self.stop_process(proc, f_out, kill_console)
        # Wait for console to end
        if self.debug:
            print("# Waiting for console to end.")
        i = 0
        while proc.poll() is None:
            time.sleep(1)
            i += 1
            if i > _TIMEOUT:
                if self.debug:
                    print("# Timeout console to end.")
                raise MUTLibError("{0}: failed - timeout waiting for "
                                  "console to end.".format(comment))

        if self.debug:
            print("# Return code from console termination = "
                  "{0}".format(ret_val))

        # Check result code from stop_process then read the log to find the
        # key phrase.
        found_row = False
        log_file = open(log_filename)
        rows = log_file.readlines()
        if self.debug:
            print("# Looking in log for: {0}".format(key_phrase))
        for row in rows:
            if key_phrase in row:
                found_row = True
                if self.debug:
                    print("# Found in row = '{0}'.".format(row[:len(row) - 1]))

        # Find MySQL Utilities version in the log
        if self.debug:
            print("# Looking in log for: {0}"
                  "".format(_UTILITIES_VERSION_PHRASE))
        for row in rows:
            if _UTILITIES_VERSION_PHRASE in row:
                found_row = True
                if self.debug:
                    print("# Found in row = '{0}'.".format(row[:-1]))
                break

        # Find MySQL server version in the log
        host_port = "{host}:{port}".format(**get_connection_dictionary(server))
        key_phrase = MSG_MYSQL_VERSION.format(server=host_port,
                                              version=server_version)
        if self.debug:
            print("# Looking in log for: {0}".format(key_phrase))
        for row in rows:
            if key_phrase in row:
                found_row = True
                if self.debug:
                    print("# Found in row = '{0}'.".format(row[:-1]))
                break

        log_file.close()

        if not found_row:
            print("# ERROR: Cannot find entry in log:")
            for row in rows:
                print row,

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

        if os.path.exists(self.failover_dir):
            try:
                os.system("rmdir {0}".format(self.failover_dir))
            except OSError:
                pass

        return comment, found_row