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