Beispiel #1
0
 def test_procedures(self):
     """Test the procedure interface from the service perspective.
     """
     packet = self.proxy.event.wait_for_procedures(
         ["e8ca0abe-cfdf-4699-a07d-8cb481f4670b"])
     result = _xmlrpc._decode(packet)
     self.assertTrue(str(result.error).find("was not found") >= 0)
Beispiel #2
0
    def test_xmlrpc_execute(self):
        "Test XML-RPC encoding and decoding functions."
        cmd = _xmlrpc._CommandExecuteAndEncode(NewRemoteCommand())
        result1 = CommandResult(None)
        result1.append_result(self.rset)
        packet = cmd()
        self.assertEqual(
            packet,
            [
                _xmlrpc.FORMAT_VERSION,
                str(FABRIC_UUID),
                utils.TTL,
                '',  # No error
                [  # One result set with one row
                    {
                        'info': {
                            'names': ['foo']
                        },
                        'rows': [
                            ("executed", ),
                        ]
                    }
                ]
            ])

        result2 = _xmlrpc._decode(packet)
Beispiel #3
0
    def check_xmlrpc_command_result(self,
                                    packet,
                                    is_syncronous=True,
                                    has_error=False,
                                    returns=None):
        """Check that a packet from a procedure execution is sane.

        This check that the first command result set, which contain
        result of execution, is sane.

        """

        check = re.compile('\w{8}(-\w{4}){3}-\w{12}')
        result = _xmlrpc._decode(packet)

        self.assertEqual(bool(result.error), has_error, str(result))

        # If the procedure did not have an error, first result set,
        # first row, first column contain UUID of procedure. Just
        # check that it looks like a UUID.
        if not has_error:
            self.assertNotEqual(check.match(result.results[0][0][0]), None)

        # If the call was synchronous and succeeded, check that there
        # is at least 2 result sets and that the second result set
        # contain more than zero jobs.
        if is_syncronous and not has_error:
            self.assertTrue(len(result.results) > 1, str(result))
            self.assertNotEqual(result.results[1].rowcount, 0,
                                "had %d result sets" % len(result.results))

        if not has_error and returns is not None:
            self.assertTrue(len(result.results) > 1, str(result))
            self.assertEqual(result.results[0].rowcount, 1, str(result))
            self.assertEqual(result.results[0][0][3], returns)
Beispiel #4
0
    def test_trigger(self):
        """Test the trigger interface from the service perspective.
        """
        promoted = [None]

        def _another_my_event(param, ignored):
            """Decorator or Inner function.
            """
            promoted[0] = param

        _events.Handler().register(_NEW_SERVER_PROMOTED, _another_my_event)
        packet = self.proxy.event.trigger(
            "_NEW_SERVER_PROMOTED",
            ["lock_a", "lock_b"],
            ["my.example.com", ""],
        )
        result = _xmlrpc._decode(packet)
        self.assertTrue(len(result.results) > 0)
        self.assertEqual(result.results[0].rowcount, 2)
        jobs = [str(row[0]) for row in result.results[0]]
        try:
            self.proxy.event.wait_for_procedures(jobs)
            self.assertEqual(promoted[0], "my.example.com")
        except Exception as error:
            if str(error).find("was not found") == -1:
                raise
        _events.Handler().unregister(_NEW_SERVER_PROMOTED, _another_my_event)
Beispiel #5
0
    def test_add_slave(self):
        """Test whether some servers are made slaves or not.
        """
        # Prepare group and servers
        self.proxy.group.create("group", "Testing group...")
        address_0 = tests.utils.MySQLInstances().get_address(0)
        address_1 = tests.utils.MySQLInstances().get_address(1)
        address_2 = tests.utils.MySQLInstances().get_address(2)
        status_uuid = self.proxy.server.lookup_uuid(address_0)
        uuid_0 = status_uuid[2]
        status_uuid = self.proxy.server.lookup_uuid(address_1)
        uuid_1 = status_uuid[2]
        status_uuid = self.proxy.server.lookup_uuid(address_2)
        uuid_2 = status_uuid[2]
        status = self.proxy.group.add("group", address_0)
        self.check_xmlrpc_command_result(status, False)

        status = self.proxy.group.promote("group")
        self.check_xmlrpc_command_result(status, False)

        # Add servers and check that they are made slaves.
        self.proxy.group.add("group", address_1)
        self.proxy.group.add("group", address_2)
        status = self.proxy.group.lookup_servers("group")
        result = _xmlrpc._decode(status)
        for row in result.results[0]:
            info = dict(zip([c.name for c in result.results[0].columns], row))
            self.assertEqual(info['weight'], 1.0)
            if info['address'] == address_0:
                self.assertEqual(info['status'], _server.MySQLServer.PRIMARY)
                self.assertEqual(info['mode'], _server.MySQLServer.READ_WRITE)
            else:
                self.assertEqual(info['status'], _server.MySQLServer.SECONDARY)
                self.assertEqual(info['mode'], _server.MySQLServer.READ_ONLY)
Beispiel #6
0
    def check_xmlrpc_command_result(self,
                                    packet,
                                    has_error,
                                    error_message=None,
                                    is_syncronous=True):
        "Check that a packet from a procedure execution is sane."

        result = _xmlrpc._decode(packet)

        if has_error:
            message = "No error but error expected"
        else:
            message = "Error: %s" % result.error
        self.assertEqual(bool(result.error), has_error, message)

        # If the procedure had an error, check the error message provided
        # it was requested to do so, i.e error_message is not None.
        if has_error and error_message:
            self.assertEqual(result.error, error_message)

        # If the procedure did not have an error, first result set,
        # first row, first column contain UUID of procedure. Just
        # check that it looks like a UUID.
        if not has_error:
            self.assertNotEqual(self.uuid_cre.match(result.results[0][0][0]),
                                None, str(result))

        # If the call was synchronous and succeeded, check that there
        # is at least 2 result sets and that the second result set
        # contain more than zero jobs.
        if is_syncronous and not has_error:
            self.assertTrue(len(result.results) > 1, str(result))
            self.assertNotEqual(result.results[1].rowcount, 0,
                                "had %d result sets" % len(result.results))
Beispiel #7
0
    def test_lookup_servers(self):
        """Test searching for servers by calling group.lookup_servers().
        """
        # Prepare group and servers
        self.proxy.group.create("group", "Testing group...")
        address_0 = tests.utils.MySQLInstances().get_address(0)
        address_1 = tests.utils.MySQLInstances().get_address(1)
        address_2 = tests.utils.MySQLInstances().get_address(2)
        status = self.proxy.group.add("group", address_0)
        self.check_xmlrpc_command_result(status, False)
        status = self.proxy.group.add("group", address_1)
        self.check_xmlrpc_command_result(status, False)
        status = self.proxy.group.add("group", address_2)
        self.check_xmlrpc_command_result(status, False)
        status_uuid = self.proxy.server.lookup_uuid(address_1)
        server_1 = _server.MySQLServer.fetch(status_uuid[2])

        # Fetch all servers in a group and check the number of server.
        status = self.proxy.group.lookup_servers("group")
        result = _xmlrpc._decode(status)
        self.assertNotEqual(len(result.results), 0, str(result))
        self.assertEqual(result.results[0].rowcount, 3, str(result))

        #
        # It it not possible to specify only some of the optional
        # parameters. For that reason, this part of the test is
        # skipped as it requires to set the status without setting
        # the uuid parameter.
        # Note this is not possible though as the method has the
        #following signature:
        # lookup_servers(self, group_id, uuid=None, status=None, ...)
        #
        return
        # Fetch all running servers in a group.
        server = self.proxy.group.lookup_servers("group",
                                                 _server.MySQLServer.SECONDARY)
        self.assertEqual(len(server[2]), 3)

        # Fetch all offline servers in a group.
        server_1.status = _server.MySQLServer.FAULTY
        server = self.proxy.group.lookup_servers("group",
                                                 _server.MySQLServer.FAULTY)
        self.assertEqual(len(server[2]), 1)

        # Fetch all running servers in a group.
        server = self.proxy.group.lookup_servers("group",
                                                 _server.MySQLServer.SECONDARY)
        self.assertEqual(len(server[2]), 2)

        # Fetch all servers in a group.
        server = self.proxy.group.lookup_servers("group")
        self.assertEqual(len(server[2]), 3)

        # Try to fetch servers with a non-existing status.
        server = self.proxy.group.lookup_servers("group", 10)
        self.assertEqual(server[0], False)
        self.assertNotEqual(server[1], "")
        self.assertEqual(server[2], True)
Beispiel #8
0
    def test_xmlrpc_encoding(self):
        "Test the XML-RPC encoder and decoder."

        results = [
            CommandResult(None),
        ]

        for result in results:
            self.assertEqual(str(result),
                             str(_xmlrpc._decode(_xmlrpc._encode(result))))
Beispiel #9
0
    def check_xmlrpc_get_uuid(self, packet, has_error):
        result = _xmlrpc._decode(packet)

        # If the procedure did not have an error, first result set,
        # first row, first column contain UUID of server. Just
        # check that it looks like a UUID.
        if not has_error:
            self.assertNotEqual(self.uuid_cre.match(result.results[0][0][0]),
                                None)

        return result.results[0][0][0]
Beispiel #10
0
    def test_statistics_group(self):
        """Test statistics on a group.
        """
        address_1 = tests.utils.MySQLInstances().get_address(0)
        address_2 = tests.utils.MySQLInstances().get_address(1)

        # Check statistics on a non-existent group.
        packet = self.proxy.statistics.group("non-existent")
        result = _xmlrpc._decode(packet)
        self.assertEqual(len(result.results), 1)
        self.assertEqual(result.results[0].rowcount, 0)

        # Check statistics on group_id_1 after a promotion.
        self.proxy.group.create("group_id_1")
        self.proxy.group.add("group_id_1", address_1)
        self.proxy.group.promote("group_id_1")
        packet = self.proxy.statistics.group()
        self.check_xmlrpc_simple(packet, {
            'group_id': 'group_id_1',
            'call_count': 1,
            'call_abort': 0,
        },
                                 rowcount=1)

        # Check statistics on group_id_1 after a demotion.
        self.proxy.group.demote("group_id_1")
        res = self.proxy.statistics.group("group_id_1")
        self.check_xmlrpc_simple(res, {
            'group_id': 'group_id_1',
            'call_count': 1,
            'call_abort': 1,
        },
                                 rowcount=1)

        # Check statistics on group_id_2 after a promotion.
        self.proxy.group.create("group_id_2")
        self.proxy.group.add("group_id_2", address_2)
        self.proxy.group.promote("group_id_2")
        res = self.proxy.statistics.group("group_id_2")
        self.check_xmlrpc_simple(res, {
            'group_id': 'group_id_2',
            'call_count': 1,
            'call_abort': 0,
        },
                                 rowcount=1)

        # Check statistics on all groups with a common pattern.
        res = self.proxy.statistics.group("group_id")
        self.check_xmlrpc_simple(res, {}, rowcount=2)

        # Check statistics on all groups.
        res = self.proxy.statistics.group()
        self.check_xmlrpc_simple(res, {}, rowcount=2)
Beispiel #11
0
    def check_xmlrpc_iter(self, packet, index=0, rowcount=None):
        """Iterate over a result set and do some basic integrity checking first.
        """

        result = _xmlrpc._decode(packet)
        self.assertTrue(len(result.results) > index, str(result))
        if rowcount is not None:
            self.assertEqual(result.results[index].rowcount, rowcount,
                             str(result))

        names = [c.name for c in result.results[index].columns]
        for row in result.results[index]:
            yield dict(zip(names, row))
Beispiel #12
0
    def check_xmlrpc_result(self, packet, expected, index=0):
        """Compare the result set of a command result with an expected value.

        Order of rows in result sets are important and have to match.

        :param ResultSet expected: Expected result set.

        """

        result = _xmlrpc._decode(packet)

        self.assertFalse(result.error, "Error: '%s'" % result.error)
        self.assertTrue(len(result.results) > index, str(result))
        self.assertEqual(result.results[index].columns, expected.columns)

        for row, exp in zip(result.results[index], expected):
            self.assertEqual(row, exp)
Beispiel #13
0
    def test_create_group_events(self):
        """Test creating a group by calling group.create().
        """
        # Look up groups.
        status = self.proxy.group.lookup_groups()
        result = _xmlrpc._decode(status)
        self.assertEqual(len(result.results), 1)
        self.assertEqual(result.results[0].rowcount, 0)

        # Insert a new group.
        status = self.proxy.group.create("group", "Testing group...")
        self.check_xmlrpc_command_result(status, False)

        # Try to insert a group twice.
        status = self.proxy.group.create("group", "Testing group...")
        self.check_xmlrpc_command_result(status, True)

        # Look up groups.
        status = self.proxy.group.lookup_groups()
        self.check_xmlrpc_simple(
            status, {
                "group_id": "group",
                "description": "Testing group...",
                "failure_detector": False,
            })

        # Look up a group.
        status = self.proxy.group.lookup_groups("group")
        self.check_xmlrpc_simple(
            status, {
                "group_id": "group",
                "description": "Testing group...",
                "failure_detector": False,
            })

        # Try to look up a group that does not exist.
        status = self.proxy.group.lookup_groups("group_1")
        self.check_xmlrpc_simple(status, {}, has_error=True)

        # Update a group.
        status = self.proxy.group.description("group", "Test Test Test")
        self.check_xmlrpc_command_result(status, False)

        # Try to update group that does not exist.
        status = self.proxy.group.description("group_1", "Test Test Test")
        self.check_xmlrpc_command_result(status, True)
    def check_xmlrpc_command_success(self, packet, expect, has_error):
        result = _xmlrpc._decode(packet)
        self.assertEqual(bool(result.error), has_error,
                         "Had error '%s'" % result.error)

        # Check that it returned the expected result (if one is
        # expected), which is in the first result set (containing
        # execution result), first row (there is just one for
        # procedures), and last column (containing the result).
        if expect is not None:
            self.assertEqual(result.results[0][0][3], expect)

        # If the call was successful, check that there is at least 2
        # result sets and that the second result set contain more than
        # zero jobs.
        if not has_error:
            self.assertTrue(len(result.results) > 1, str(result))
            self.assertNotEqual(result.results[1].rowcount, 0,
                                "had %d result sets" % len(result.results))
Beispiel #15
0
    def test_statistics_procedure(self):
        """Test statistics on procedures.
        """
        # Check statistics on a non-existent procedure.
        res = self.proxy.statistics.procedure("non-existent")
        result = _xmlrpc._decode(res)
        self.assertEqual(len(result.results), 1)
        self.assertEqual(result.results[0].rowcount, 0)

        # Check statistics on procedures using the "statistics" pattern.
        self.proxy.statistics.group("group_id")
        res = self.proxy.statistics.procedure("statistics")
        self.check_xmlrpc_simple(res, {
            'proc_name': 'statistics.group',
            'call_count': 1,
            'call_abort': 0,
        },
                                 index=0)
        self.check_xmlrpc_simple(res, {
            'proc_name': 'statistics.procedure',
            'call_count': 2,
            'call_abort': 0,
        },
                                 index=1)

        # Check statistics on procedures that fail.
        self.proxy.test.execution_event()
        res = self.proxy.statistics.procedure("test.execution_event")
        self.check_xmlrpc_simple(res, {
            'proc_name': 'test.execution_event',
            'call_count': 1,
            'call_abort': 1,
        },
                                 rowcount=1)

        # Check statistics on procedures that are asynchronously executed and
        # fail. Note that an error is not reported because the procedure is
        # asynchronously executed.
        self.proxy.test.execution_event(False)
        res = self.proxy.statistics.procedure("test.execution_event")
        self.check_xmlrpc_simple(res, {
            'proc_name': 'test.execution_event',
            'call_count': 2,
            'call_abort': 1,
        },
                                 rowcount=1)

        # Check statistics on procecures executed so far, i.e. all procedures.
        res = self.proxy.statistics.procedure()
        self.check_xmlrpc_simple(res, {
            'proc_name': 'statistics.group',
            'call_count': 1,
            'call_abort': 0,
        },
                                 index=0,
                                 rowcount=3)
        self.check_xmlrpc_simple(res, {
            'proc_name': 'statistics.procedure',
            'call_count': 5,
            'call_abort': 0,
        },
                                 index=1,
                                 rowcount=3)
        self.check_xmlrpc_simple(res, {
            'proc_name': 'test.execution_event',
            'call_count': 2,
            'call_abort': 1,
        },
                                 index=2,
                                 rowcount=3)
Beispiel #16
0
    def check_xmlrpc_simple(self,
                            packet,
                            checks,
                            has_error=False,
                            index=0,
                            rowcount=None):
        """Perform assertion checks on a row of a result set.

        This will perform basic assertion checks on a command result
        returned by an XML-RPC server proxy. It will decode the result
        into a command result and pick a row from the first result set
        in the result (assuming there were no error) and do an
        equality comparison with the fields provided in the ``checks``
        parameter.

        :param packet: The Python data structure from the XML-RPC server.

        :param checks: Dictionary of values to check.

        :param has_error: True if errors are expected for this packet,
        False otherwise. Default to False.

        :param index: Index of row to check. Default to the first row
        of the result set, if there is any.

        :param rowcount: Number of rows expected in the result set, or
        None if no check should be done.

        :return: Return a dictionary of the actual contents of the
        row, or an empty dictionary in the event of an error.

        """

        result = _xmlrpc._decode(packet)

        self.assertEqual(bool(result.error), has_error, str(result))

        if not has_error:
            # Some commands are successful but have no result sets
            # anyway (e.g., set_logging_level).
            if len(result.results) == 0:
                return {}

            if rowcount is not None:
                self.assertEqual(result.results[0].rowcount, rowcount,
                                 str(result))

            if result.results[0].rowcount == 0:
                return {}

            # Check that there is enough rows in the first result set
            self.assertTrue(result.results[0].rowcount > index, str(result))

            # Create a dictionary from this row.
            info = dict(
                zip([col.name for col in result.results[0].columns],
                    result.results[0][index]))

            for key, value in checks.items():
                self.assertTrue(key in info, str(result))
                self.assertEqual(
                    info[key], value,
                    "[%s != %s]:\n%s" % (info[key], value, str(result)))

            # For convenience, allowing the simple result to be used
            # by callers.
            return info
        return {}