Exemplo n.º 1
0
    def test_trigger(self):
        "Test that triggering an event dispatches jobs."

        global _TEST1

        # Register a function that we can check if it was called
        self.handler.register(_NEW_SERVER_LOST, test1)

        # Register a function and trigger it to see that the executor
        # really executed it.  When triggering the event, a list of
        # the jobs scheduled will be returned, so we iterate over the
        # list and wait until all jobs have been executed.
        _TEST1 = 0
        jobs = self.handler.trigger(False, _NEW_SERVER_LOST, set(["lock"]), 3,
                                    "")
        self.assertEqual(len(jobs), 1)
        for job in jobs:
            job.wait()
        self.assertEqual(_TEST1, 3)

        # Check that triggering an event by name works.
        _TEST1 = 0
        jobs = self.handler.trigger(False, "_NEW_SERVER_LOST", set(["lock"]),
                                    4, "")
        self.assertEqual(len(jobs), 1)
        for job in jobs:
            job.wait()
        self.assertEqual(_TEST1, 4)

        # Check that temporary, unnamed events, also work by
        # registering a bunch of callables with a temporary event
        callables = [Callable(n) for n in range(0, 2)]
        my_event_var = _events.Event("TestEvent")
        self.handler.register(my_event_var, callables)

        # Trigger the event and wait for all jobs to finish
        jobs = self.handler.trigger(False, my_event_var, set(["lock"]), 3, "")
        for job in jobs:
            job.wait()

        for idx, obj in enumerate(callables):
            self.assertEqual(obj.result, idx + 3)

        # Try to trigger an unknown event.
        self.assertEqual(self.handler.trigger(False, "UNKNOWN_EVENT", None),
                         [])
Exemplo n.º 2
0
    events as _events,
    group_replication as _group_replication,
    server as _server,
    replication as _replication,
    errors as _errors,
)

from mysql.fabric.command import (
    ProcedureGroup, )

from mysql.fabric.services.server import (_retrieve_server)

_LOGGER = logging.getLogger(__name__)

# Find out which operation should be executed.
DEFINE_HA_OPERATION = _events.Event()
# Find a slave that was not failing to keep with the master's pace.
FIND_CANDIDATE_FAIL = _events.Event("FAIL_OVER")
# Check if the candidate is properly configured to become a master.
CHECK_CANDIDATE_FAIL = _events.Event()
# Wait until all slaves or a candidate process the relay log.
WAIT_SLAVE_FAIL = _events.Event()
# Find a slave that is not failing to keep with the master's pace.
FIND_CANDIDATE_SWITCH = _events.Event()
# Check if the candidate is properly configured to become a master.
CHECK_CANDIDATE_SWITCH = _events.Event()
# Block any write access to the master.
BLOCK_WRITE_SWITCH = _events.Event()
# Wait until all slaves synchronize with the master.
WAIT_SLAVES_SWITCH = _events.Event()
# Enable the new master by making slaves point to it.
Exemplo n.º 3
0
)

from mysql.fabric import (
    events as _events,
    errors as _errors,
)

from mysql.fabric.provider import (
    Provider, )

from mysql.fabric.machine import (
    Machine, )

_LOGGER = logging.getLogger(__name__)

REGISTER_PROVIDER = _events.Event()


class ProviderRegister(ProcedureCommand):
    """Register a provider.
    """
    group_name = "provider"
    command_name = "register"

    def execute(self,
                provider_id,
                username,
                password,
                url,
                tenant,
                provider_type="OPENSTACK",
Exemplo n.º 4
0
        elif issubclass(manager, AbstractMachineManager):
            manager = _retrieve_machine_manager(provider_id)

        machines = manager.search(generic_filters, meta_filters)

    rset = ResultSet(names=('uuid', 'provider_id', 'av_zone', 'addresses'),
                     types=(str, str, str, str))

    for machine in machines:
        row = (str(machine.uuid), machine.provider_id, machine.av_zone,
               machine.addresses)
        rset.append_row(row)
    return CommandResult(None, results=rset)


CREATE_MACHINE = _events.Event('CREATE_MACHINE')


@_events.on_event(CREATE_MACHINE)
def _create_machine(provider_id, parameters, machine_group_uuid, skip_store,
                    wait_spawning):
    """Create a machine.
    """
    manager = _retrieve_machine_manager(provider_id)

    _preprocess_parameters(parameters, machine_group_uuid, manager.provider)
    machines = manager.create(parameters, wait_spawning)

    _LOGGER.debug("Created machine(s) (%s).", machines)

    if not skip_store:
Exemplo n.º 5
0
        rset = ResultSet(
            names=('group_id', 'description', 'failure_detector', 'master_uuid'),
            types=(str, str, str, str)
        )

        for group in groups:
            rset.append_row([
                group.group_id,                           # group_id
                group.description,                        # description
                "ACTIVE" if group.status else "INACTIVE", # failure_detector
                group.master,                             # master_uuid
            ])

        return CommandResult(None, results=rset)

CREATE_GROUP = _events.Event()
class GroupCreate(ProcedureGroup):
    """Create a group.
    """
    group_name = "group"
    command_name = "create"

    def execute(self, group_id, description=None, synchronous=True):
        """Create a group.

        :param group_id: Group's id.
        :param description: Group's description.
        :param synchronous: Whether one should wait until the execution finishes
                            or not.
        :return: Tuple with job's uuid and status.
        """
Exemplo n.º 6
0
from mysql.fabric.machine import (
    Machine, )

from mysql.fabric.services.provider import (
    _retrieve_provider, )

from mysql.fabric.node import (
    FabricNode, )

_LOGGER = logging.getLogger(__name__)

reserved_meta = ('mysql-fabric', 'mysql-fabric-version', 'mysql-fabric-uuid',
                 'mysql-fabric-group', 'mysql-fabric-machine-group-uuid')

CREATE_INSTANCE = _events.Event()


class CreateMachine(ProcedureCommand):
    """Create a virtual machine instance:

        mysqlfabric machine create provider --image name=image-mysql \
        --flavor name=vm-template --meta db=mysql --meta version=5.6

        mysqlfabric machine create provider --image name=image-mysql \
        --flavor name=vm-template --security_groups grp_fabric, grp_ham

    Options that accept a list are defined by providing the same option
    multiple times in the command-line. The image, flavor, files, meta
    and scheduler_hints are those which might be defined multiple times.
    Note the the security_groups option might be defined only once but
Exemplo n.º 7
0
    """Emulates a remote command that throws a Fault because of
    returning None.
    """
    group_name = "test"
    command_name = "error_remote_command"

    def execute(self):
        """A remote command that returns None.
        """

        rset = ResultSet(names=['foo'], types=[int])
        rset.append_row([2L**32])
        return CommandResult(None, results=rset)


NEW_PROCEDURE_COMMAND_0 = _events.Event()


class ClassCommand_0(_command.ProcedureCommand):
    """Emulates a remote command that triggers a procedure with success.
    """
    group_name = "test"
    command_name = "procedure_command_0"

    def execute(self, param, synchronous=True):
        """Method that is remotely executed.
        """
        procedures = _events.trigger(NEW_PROCEDURE_COMMAND_0,
                                     self.get_lockable_objects(), param)
        return self.wait_for_procedures(procedures, synchronous)
Exemplo n.º 8
0
 def test_events(self):
     "Test creating events."
     self.assertEqual(_events.Event().name, None)
     self.assertEqual(_events.Event("Event").name, "Event")
Exemplo n.º 9
0
from mysql.fabric import (
    events as _events,
    server as _server,
    errors as _errors,
    error_log as _error_log,
    config as _config,
)

from mysql.fabric.command import (
    ProcedureGroup, )

from mysql.fabric.services.server import (_retrieve_server)

_LOGGER = logging.getLogger(__name__)

REPORT_ERROR = _events.Event("REPORT_ERROR")


class ReportError(ProcedureGroup):
    """Report a server error.

    If there are many issues reported by different servers within a period of
    time, the server is marked as faulty. Should the server be a primary, the
    failover mechanism is triggered. Users who only want to set the server's
    status to faulty after getting enough notifications from different clients
    must set the update_only parameter to true. By default its value is false.
    """
    group_name = "threat"
    command_name = "report_error"

    _MIN_NOTIFICATIONS = 1
Exemplo n.º 10
0
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
"""Unit tests for the event handler.
"""
import unittest
import tests.utils

import mysql.fabric.protocols.xmlrpc as _xmlrpc

from mysql.fabric import (
    errors as _errors,
    events as _events,
)

_NEW_SERVER_LOST = _events.Event("_NEW_SERVER_LOST")

_TEST1 = None


def test1(param, ignored):
    """A function acting as a callable.
    """
    global _TEST1
    _TEST1 = param


class Callable(object):
    """A class acting as a callable.
    """
    def __init__(self, n=None):
Exemplo n.º 11
0
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
"""Unit tests for statistics.
"""
import unittest
import tests.utils
import sys

import mysql.fabric.command as _command
import mysql.fabric.events as _events
import mysql.fabric.protocols.xmlrpc as _xmlrpc

from mysql.fabric.node import (
    FabricNode, )

NEW_EXECUTION_EVENT_1 = _events.Event()


class ClassCommand_1(_command.ProcedureCommand):
    """Emulates a remote command that triggers a procedure with error.
    """
    group_name = "test"
    command_name = "execution_event"

    def execute(self, synchronous=True):
        """Method that is remotely executed.
        """
        procedures = _events.trigger(NEW_EXECUTION_EVENT_1,
                                     self.get_lockable_objects())
        return self.wait_for_procedures(procedures, synchronous)
Exemplo n.º 12
0
"""Unit tests for the checkpoint/recovery.
"""
import unittest
import uuid as _uuid
import tests.utils

from mysql.fabric import (
    events as _events,
    executor as _executor,
    persistence as _persistence,
    checkpoint as _checkpoint,
    recovery as _recovery,
)

EVENT_CHECK_PROPERTIES_1 = _events.Event("EVENT_CHECK_PROPERTIES_1")
EVENT_CHECK_PROPERTIES_2 = _events.Event("EVENT_CHECK_PROPERTIES_2")
EVENT_CHECK_PROPERTIES_3 = _events.Event("EVENT_CHECK_PROPERTIES_3")
EVENT_CHECK_PROPERTIES_4 = _events.Event("EVENT_CHECK_PROPERTIES_4")
EVENT_CHECK_PROPERTIES_5 = _events.Event("EVENT_CHECK_PROPERTIES_5")
EVENT_CHECK_PROPERTIES_6 = _events.Event("EVENT_CHECK_PROPERTIES_6")

EVENT_CHECK_CHAIN = _events.Event("EVENT_CHECK_CHAIN")

COUNT_1 = 0
COUNT_2 = 0

class MyTransAction(_persistence.Persistable):
    """Define a class that inherits from Persitable.
    """
    @staticmethod
Exemplo n.º 13
0
    Shards,
    SHARDING_DATATYPE_HANDLER,
    SHARDING_SPECIFICATION_HANDLER,
)

from mysql.fabric.command import (
    ProcedureShard, )

from mysql.fabric.services import (
    sharding as _services_sharding,
    utils as _services_utils,
)

_LOGGER = logging.getLogger(__name__)

PRUNE_SHARD_TABLES = _events.Event("PRUNE_SHARD_TABLES")


class PruneShardTables(ProcedureShard):
    """Given the table name prune the tables according to the defined
    sharding specification for the table.
    """
    group_name = "sharding"
    command_name = "prune_shard"

    def execute(self, table_name, synchronous=True):
        """Given the table name prune the tables according to the defined
        sharding specification for the table. The command prunes all the
        tables that are part of this shard. There might be multiple tables that
        are part of the same shard, these tables will be related together by
        the same sharding key.
Exemplo n.º 14
0
SHARDS_ALREADY_EXIST = "Shards are already present in the definition, "\
        "use split_shard to create further shards."
LOWER_BOUND_GROUP_ID_COUNT_MISMATCH = "Lower Bound, Group ID pair mismatch "\
                                    "format should be group-id/lower_bound, "\
                                    "group-id/lower_bound...."
LOWER_BOUND_AUTO_GENERATED = "Lower Bounds are auto-generated in hash "\
                            "based sharding"
SPLIT_VALUE_NOT_DEFINED = "Splitting a RANGE shard definition requires a split"\
            " value to be defined"
INVALID_SPLIT_VALUE = "Invalid value given for shard splitting"
NO_LOWER_BOUND_FOR_HASH_SHARDING = "Lower bound should not be specified "\
                                "for hash based sharding"
MYSQLDUMP_NOT_FOUND = "Unable to find MySQLDump in location %s"
MYSQLCLIENT_NOT_FOUND = "Unable to find MySQL Client in location %s"

DEFINE_SHARD_MAPPING = _events.Event("DEFINE_SHARD_MAPPING")


class DefineShardMapping(ProcedureShard):
    """Define a shard mapping.
    """
    group_name = "sharding"
    command_name = "create_definition"

    def execute(self, type_name, group_id, synchronous=True):
        """Define a shard mapping.

        :param type_name: The type of sharding scheme - RANGE, HASH, LIST etc
        :param group_id: Every shard mapping is associated with a global group
                         that stores the global updates and the schema changes
                         for this shard mapping and dissipates these to the
Exemplo n.º 15
0
SHARDS_ALREADY_EXIST = "Shards are already present in the definition, "\
        "use split_shard to create further shards."
LOWER_BOUND_GROUP_ID_COUNT_MISMATCH = "Lower Bound, Group ID pair mismatch "\
                                    "format should be group-id/lower_bound, "\
                                    "group-id/lower_bound...."
LOWER_BOUND_AUTO_GENERATED = "Lower Bounds are auto-generated in hash "\
                            "based sharding"
SPLIT_VALUE_NOT_DEFINED = "Splitting a RANGE shard definition requires a split"\
            " value to be defined"
INVALID_SPLIT_VALUE = "Invalid value given for shard splitting"
NO_LOWER_BOUND_FOR_HASH_SHARDING = "Lower bound should not be specified "\
                                "for hash based sharding"
MYSQLDUMP_NOT_FOUND = "Unable to find MySQLDump in location %s"
MYSQLCLIENT_NOT_FOUND = "Unable to find MySQL Client in location %s"

DEFINE_SHARD_MAPPING = _events.Event("DEFINE_SHARD_MAPPING")


class DefineShardMapping(ProcedureShard):
    """Define a shard mapping.
    """
    group_name = "sharding"
    command_name = "create_definition"

    def execute(self,
                type_name,
                group_id,
                update_only=False,
                synchronous=True):
        """Define a shard mapping.