예제 #1
0
def patch_env(call_queue, config, init_env, patch_is_systemd=True):
    # It is mandatory to patch some env objects/methods. It is ok when command
    # does not use this objects/methods and specify no call for it. But it would
    # be a problem when the test succeded because the live call respond
    # correctly by accident. Such test would fails on different machine (with
    # another live environment)

    get_cmd_runner = init_env.cmd_runner
    get_node_communicator = init_env.get_node_communicator
    mock_communicator_factory = mock.Mock(spec_set=NodeCommunicatorFactory)
    mock_communicator_factory.get_communicator = (
        # TODO: use request_timeout
        lambda request_timeout=None: NodeCommunicator(call_queue)
        if not config.spy
        else spy.NodeCommunicator(get_node_communicator())
    )
    patcher_list = [
        patch_lib_env(
            "cmd_runner",
            lambda env: spy.Runner(get_cmd_runner())
            if config.spy
            else Runner(
                call_queue,
                env_vars={}
                if not config.env.cib_tempfile
                else {"CIB_file": config.env.cib_tempfile,},
            ),
        ),
        mock.patch(
            "pcs.lib.env.get_local_corosync_conf",
            get_get_local_corosync_conf(call_queue)
            if not config.spy
            else spy.get_local_corosync_conf,
        ),
        patch_lib_env("communicator_factory", mock_communicator_factory),
    ]
    if patch_is_systemd:
        # In all the tests we assume that we are running on top of a systemd
        # running system. If needed, this may be turned off for some particular
        # tests. Note that the patched function is cached therefore is patched
        # here and not in every tests.
        patcher_list.append(
            mock.patch("pcs.lib.external.is_systemctl", lambda: True)
        )

    if is_fs_call_in(call_queue):
        fs_mock = get_fs_mock(call_queue)
        builtin = (
            ("__builtin__" if sys.version_info[0] == 2 else "builtins") + ".{0}"
        ).format

        patcher_list.extend(
            [
                mock.patch(builtin("open"), fs_mock("open", open)),
                mock.patch(
                    "os.path.exists", fs_mock("os.path.exists", os.path.exists)
                ),
                mock.patch(
                    "os.path.isdir", fs_mock("os.path.isdir", os.path.isdir)
                ),
                mock.patch(
                    "os.path.isfile", fs_mock("os.path.isfile", os.path.isfile)
                ),
                mock.patch("os.listdir", fs_mock("os.listdir", os.listdir)),
                mock.patch("os.chmod", fs_mock("os.chmod", os.chmod)),
                mock.patch("os.chown", fs_mock("os.chown", os.chown)),
            ]
        )

    raw_file_mock = get_raw_file_mock(call_queue)
    for method_name, dummy_method in inspect.getmembers(
        RawFile, inspect.isfunction
    ):
        # patch all public methods
        # inspect.isfunction must be used instead of ismethod because we are
        # working with a class and not an instance - no method is bound yet so
        # it would return an empty list
        # "protected" methods start with _
        # "private" methods start with _<class_name>__
        if method_name.startswith("_"):
            continue
        patcher_list.append(
            mock.patch.object(
                RawFile, method_name, getattr(raw_file_mock, method_name)
            )
        )

    # It is not always desirable to patch these methods. Some tests may patch
    # only the internals (runner etc.). So these methods are only patched when
    # it is explicitly configured.
    if is_push_cib_call_in(call_queue):
        patcher_list.append(patch_lib_env("push_cib", get_push_cib(call_queue)))
    if is_push_corosync_conf_call_in(call_queue):
        patcher_list.append(
            patch_lib_env(
                "push_corosync_conf", get_push_corosync_conf(call_queue)
            )
        )

    for patcher in patcher_list:
        patcher.start()

    def unpatch():
        for patcher in patcher_list:
            patcher.stop()

    return unpatch
예제 #2
0
def patch_env(call_queue, config, init_env, is_systemd=True):
    # pylint: disable=too-many-locals
    # It is mandatory to patch some env objects/methods. It is ok when command
    # does not use this objects/methods and specify no call for it. But it would
    # be a problem when the test succeded because the live call respond
    # correctly by accident. Such test would fails on different machine (with
    # another live environment)

    orig_cmd_runner = init_env.cmd_runner
    get_node_communicator = init_env.get_node_communicator
    mock_communicator_factory = mock.Mock(spec_set=NodeCommunicatorFactory)
    mock_communicator_factory.get_communicator = (
        # TODO: use request_timeout
        lambda request_timeout=None: NodeCommunicator(call_queue)
        if not config.spy else spy.NodeCommunicator(get_node_communicator()))

    def get_cmd_runner(self, env=None):
        del self
        if config.spy:
            return spy.Runner(orig_cmd_runner())
        env_vars = {}
        if config.env.cib_tempfile:
            env_vars["CIB_file"] = config.env.cib_tempfile
        if env:
            env_vars.update(env)
        return Runner(call_queue, env_vars=env_vars)

    patcher_list = [
        patch_lib_env("cmd_runner", get_cmd_runner),
        mock.patch(
            "pcs.lib.env.get_local_corosync_conf",
            get_get_local_corosync_conf(call_queue)
            if not config.spy else spy.get_local_corosync_conf,
        ),
        patch_lib_env("communicator_factory", mock_communicator_factory),
        # Use our custom ServiceManager in tests
        # TODO: add support for Spy
        patch_lib_env("_get_service_manager",
                      lambda _: ServiceManagerMock(call_queue)),
    ]
    if is_systemd:
        # In most test cases we don't care about underlaying init system. But
        # some tests actually test different behavior based on init
        # system. This will cause pcs.lib.services.is_systemd(<instance of
        # ServiceManagerMock>) to return True because we replace SystemdDriver
        # in isinstance() call inside is_systemd function with
        # ServiceManagerMock. Otherwise is_systemd will return False.
        patcher_list.append(
            mock.patch(
                "pcs.lib.services.services.drivers.SystemdDriver",
                ServiceManagerMock,
            ))

    if is_fs_call_in(call_queue):
        fs_mock = get_fs_mock(call_queue)
        builtin = (
            ("__builtin__" if sys.version_info[0] == 2 else "builtins") +
            ".{0}").format

        patcher_list.extend([
            mock.patch(builtin("open"), fs_mock("open", open)),
            mock.patch("os.path.exists",
                       fs_mock("os.path.exists", os.path.exists)),
            mock.patch("os.path.isdir", fs_mock("os.path.isdir",
                                                os.path.isdir)),
            mock.patch("os.path.isfile",
                       fs_mock("os.path.isfile", os.path.isfile)),
            mock.patch("os.listdir", fs_mock("os.listdir", os.listdir)),
            mock.patch("os.chmod", fs_mock("os.chmod", os.chmod)),
            mock.patch("os.chown", fs_mock("os.chown", os.chown)),
        ])

    raw_file_mock = get_raw_file_mock(call_queue)
    for method_name, dummy_method in inspect.getmembers(
            RawFile, inspect.isfunction):
        # patch all public methods
        # inspect.isfunction must be used instead of ismethod because we are
        # working with a class and not an instance - no method is bound yet so
        # it would return an empty list
        # "protected" methods start with _
        # "private" methods start with _<class_name>__
        if method_name.startswith("_"):
            continue
        patcher_list.append(
            mock.patch.object(RawFile, method_name,
                              getattr(raw_file_mock, method_name)))

    # It is not always desirable to patch these methods. Some tests may patch
    # only the internals (runner etc.). So these methods are only patched when
    # it is explicitly configured.
    if is_push_cib_call_in(call_queue):
        patcher_list.append(patch_lib_env("push_cib",
                                          get_push_cib(call_queue)))
    if is_push_corosync_conf_call_in(call_queue):
        patcher_list.append(
            patch_lib_env("push_corosync_conf",
                          get_push_corosync_conf(call_queue)))

    for patcher in patcher_list:
        patcher.start()

    def unpatch():
        for patcher in patcher_list:
            patcher.stop()

    return unpatch
예제 #3
0
파일: assistant.py 프로젝트: wuyeliang/pcs
def patch_env(call_queue, config, init_env):
    #It is mandatory to patch some env objects/methods. It is ok when command
    #does not use this objects/methods and specify no call for it. But it would
    #be a problem when the test succeded because the live call respond correctly
    #by accident. Such test would fails on different machine (with another live
    #environment)

    get_cmd_runner = init_env.cmd_runner
    get_node_communicator = init_env.get_node_communicator
    mock_communicator_factory = mock.Mock(spec_set=NodeCommunicatorFactory)
    mock_communicator_factory.get_communicator = (
        # TODO: use request_timeout
        lambda request_timeout=None: NodeCommunicator(call_queue)
        if not config.spy else spy.NodeCommunicator(get_node_communicator()))
    patcher_list = [
        patch_lib_env(
            "cmd_runner", lambda env: spy.Runner(get_cmd_runner())
            if config.spy else Runner(call_queue,
                                      env_vars={}
                                      if not config.env.cib_tempfile else {
                                          "CIB_file": config.env.cib_tempfile,
                                      })),
        mock.patch(
            "pcs.lib.env.get_local_corosync_conf",
            get_get_local_corosync_conf(call_queue)
            if not config.spy else spy.get_local_corosync_conf),
        patch_lib_env("communicator_factory", mock_communicator_factory),

        # In all the tests we assume that we are running on top of a systemd
        # running system. If needed, this may be turned off for some particular
        # tests. Note that the patched function is cached therefore is patched
        # here and not in every tests.
        mock.patch("pcs.lib.external.is_systemctl", lambda: True),
    ]

    if is_fs_call_in(call_queue):
        fs_mock = get_fs_mock(call_queue)
        builtin = (
            ("__builtin__" if sys.version_info[0] == 2 else "builtins") +
            ".{0}").format

        patcher_list.extend([
            mock.patch(builtin("open"), fs_mock("open", open)),
            mock.patch("os.path.exists",
                       fs_mock("os.path.exists", os.path.exists)),
            mock.patch("os.path.isdir", fs_mock("os.path.isdir",
                                                os.path.isdir)),
            mock.patch("os.path.isfile",
                       fs_mock("os.path.isfile", os.path.isfile)),
            mock.patch("os.listdir", fs_mock("os.listdir", os.listdir)),
            mock.patch("os.chmod", fs_mock("os.chmod", os.chmod)),
            mock.patch("os.chown", fs_mock("os.chown", os.chown)),
        ])

    # It is not always desirable to patch these methods. Some tests may patch
    # only the internals (runner etc.). So these methods are only patched when
    # it is explicitly configured.
    if is_push_cib_call_in(call_queue):
        patcher_list.append(patch_lib_env("push_cib",
                                          get_push_cib(call_queue)))
    if is_push_corosync_conf_call_in(call_queue):
        patcher_list.append(
            patch_lib_env("push_corosync_conf",
                          get_push_corosync_conf(call_queue)))

    for patcher in patcher_list:
        patcher.start()

    def unpatch():
        for patcher in patcher_list:
            patcher.stop()

    return unpatch