def setUp(self): self.known_hosts = { "host{}".format(i): PcsKnownHost( "host{}".format(i), "token{}".format(i), [ Destination("addr{}{}".format(i, j), "port{}{}".format( i, j)) for j in range(2) ], ) for i in range(2) } self.report_processor = MockLibraryReportProcessor() self.factory = lib.NodeTargetLibFactory(self.known_hosts, self.report_processor)
def setUp(self): self.mock_logger = mock.MagicMock(logging.Logger) self.mock_reporter = MockLibraryReportProcessor() mock.patch("pcs.lib.env.get_service_manager", spec=ServiceManagerInterface).start() self.addCleanup(mock.patch.stopall) self.lib_env = LibraryEnvironment(self.mock_logger, self.mock_reporter)
def wrap_element_by_master(cib_file, resource_id, master_id=None): cib_file.seek(0) cib_tree = etree.parse(cib_file, etree.XMLParser(huge_tree=True)).getroot() element = cib_tree.find(f'.//*[@id="{resource_id}"]') final_master_id = ( master_id if master_id is not None else f"{resource_id}-master" ) master_element = _xml_to_element( f""" <master id="{final_master_id}"> </master> """ ) element.getparent().append(master_element) master_element.append(element) final_xml = etree_to_str(cib_tree) environ = dict(os.environ) environ["CIB_file"] = cib_file.name runner = CommandRunner( mock.MagicMock(logging.Logger), MockLibraryReportProcessor(), environ ) stdout, stderr, retval = runner.run( [ os.path.join(settings.pacemaker_binaries, "cibadmin"), "--replace", "--scope", "resources", "--xml-pipe", ], stdin_string=final_xml, ) assert retval == 0, ( "Error running wrap_element_by_master:\n" + stderr + "\n" + stdout )
def setUp(self): self.mock_logger = mock.MagicMock(logging.Logger) self.mock_reporter = MockLibraryReportProcessor() self.lib_env = LibraryEnvironment(self.mock_logger, self.mock_reporter) self.metadata = """ <resource-agent> <shortdesc>short desc</shortdesc> <longdesc>long desc</longdesc> <parameters> </parameters> <actions> </actions> </resource-agent> """ self.description = { "name": "ocf:test:Dummy", "shortdesc": "short desc", "longdesc": "long desc", "parameters": [], "actions": [], "default_actions": [{ "interval": "60s", "name": "monitor" }], }
def fixture_env(cib): env = mock.MagicMock() env.get_cib = mock.Mock() env.get_cib.return_value = cib env.push_cib = mock.Mock() env.report_processor = MockLibraryReportProcessor() return env
def setUp(self): self.mock_reporter = MockLibraryReportProcessor() self.alert = etree.Element("alert", id="alert-1") self.recipient = etree.SubElement(self.alert, "recipient", id="rec-1", value="value1")
def test_report_when_duplication_allowed(self, export_with_set): export_with_set.return_value = "exported_duplicate_element" element = mock.MagicMock() element.tag = "constraint_type" report_processor = MockLibraryReportProcessor() constraint.check_is_without_duplication( report_processor, fixture_constraint_section(["duplicate_element"]), element, are_duplicate=lambda e1, e2: True, export_element=constraint.export_with_set, duplication_alowed=True, ) assert_report_item_list_equal( report_processor.report_item_list, [ ( severities.WARNING, report_codes.DUPLICATE_CONSTRAINTS_EXIST, { 'constraint_info_list': ['exported_duplicate_element'], 'constraint_type': 'constraint_type' }, ) ] )
def get_env(self, is_systemd=True): self.__call_queue = CallQueue(self.__config.calls) # pylint: disable=attribute-defined-outside-init self._env = LibraryEnvironment( mock.MagicMock(logging.Logger), MockLibraryReportProcessor(), cib_data=self.__config.env.cib_data, corosync_conf_data=self.__config.env.corosync_conf_data, known_hosts_getter=((lambda: self.__config.spy.known_hosts) if self.__config.spy else self.__config.env.known_hosts_getter), booth_files_data=self.__config.env.booth, ) self.__unpatch = patch_env( self.__call_queue, self.__config, self._env, is_systemd=is_systemd, ) # If pushing corosync.conf has not been patched in the # LibraryEnvironment, store any corosync.conf passed to the # LibraryEnvironment for check for changes in cleanup. if not is_push_corosync_conf_call_in(self.__call_queue): self.__original_mocked_corosync_conf = ( self.__config.env.corosync_conf_data) return self._env
def setUp(self): self.mock_logger = mock.MagicMock(logging.Logger) self.mock_reporter = MockLibraryReportProcessor() self.lib_env = LibraryEnvironment(self.mock_logger, self.mock_reporter) self.metadata = """ <resource-agent> <shortdesc>short desc</shortdesc> <longdesc>long desc</longdesc> <parameters> </parameters> <actions> </actions> </resource-agent> """ self.description = { "name": "fence_dummy", "shortdesc": "short desc", "longdesc": "long desc", "parameters": [], "actions": [], "default_actions": [{ "name": "monitor", "interval": "60s", "OCF_CHECK_LEVEL": None, "automatic": None, "depth": None, "on_target": None, "role": None, "start-delay": None, "timeout": None, }], }
def setUp(self): self.mock_log = mock.MagicMock(spec_set=logging.Logger) self.mock_run = mock.MagicMock(spec_set=CommandRunner) self.mock_rep = MockLibraryReportProcessor() self.mock_env = LibraryEnvironment(self.mock_log, self.mock_rep, cib_data='<cib/>')
def setUp(self): self.name = "booth_name" self.mock_env = _env_fixture(self.name) self.mock_rep = MockLibraryReportProcessor() self.mock_run = mock.MagicMock(spec_set=CommandRunner) self.mock_env.cmd_runner.return_value = self.mock_run self.mock_env.report_processor = self.mock_rep
def test_node_invalid(self): reporter = MockLibraryReportProcessor() lib._validate_target_valuewise(reporter, self.state, TARGET_TYPE_NODE, "rh7-x") report = [(severity.ERROR, report_codes.NODE_NOT_FOUND, { "node": "rh7-x", }, report_codes.FORCE_NODE_DOES_NOT_EXIST)] assert_report_item_list_equal(reporter.report_item_list, report)
def test_empty(self): reporter = MockLibraryReportProcessor() lib._validate_devices(reporter, self.resources_el, []) report = [(severity.ERROR, report_codes.REQUIRED_OPTIONS_ARE_MISSING, { "option_type": None, "option_names": ["stonith devices"], }, None)] assert_report_item_list_equal(reporter.report_item_list, report)
def test_invalid(self): reporter = MockLibraryReportProcessor() lib._validate_devices(reporter, self.resources_el, ["dummy", "fenceX"]) report = [(severity.ERROR, report_codes.STONITH_RESOURCES_DO_NOT_EXIST, { "stonith_ids": ["dummy", "fenceX"], }, report_codes.FORCE_STONITH_RESOURCE_DOES_NOT_EXIST)] assert_report_item_list_equal(reporter.report_item_list, report)
def test_success(self): reporter = MockLibraryReportProcessor() lib._validate_level(reporter, 1) lib._validate_level(reporter, "1") lib._validate_level(reporter, 9) lib._validate_level(reporter, "9") lib._validate_level(reporter, "05") assert_report_item_list_equal(reporter.report_item_list, [])
def test_empty(self): resources = etree.fromstring("<resources />") topology = etree.fromstring("<fencing-topology />") reporter = MockLibraryReportProcessor() lib.verify(reporter, topology, resources, self.get_status()) assert_report_item_list_equal(reporter.report_item_list, [])
def test_success_on_valid_options(self): report_processor = MockLibraryReportProcessor() config_structure.validate_ticket_options( report_processor, {"timeout": "10"}, allow_unknown_options=False, ) assert_report_item_list_equal(report_processor.report_item_list, [])
def setUp(self): self.cib = "cib" self.report_processor = MockLibraryReportProcessor() self.find = partial( constraint.find_valid_resource_id, self.report_processor, self.cib, in_clone_allowed=False, )
def test_success(self): resources = etree.fromstring("<resources />") for name in ["d1", "d2", "d3", "d4", "d5", "dR", "dR-special"]: self.fixture_resource(resources, name) reporter = MockLibraryReportProcessor() lib.verify(reporter, self.tree, resources, self.get_status()) assert_report_item_list_equal(reporter.report_item_list, [])
def test_invalid_forced(self): reporter = MockLibraryReportProcessor() lib._validate_devices(reporter, self.resources_el, ["dummy", "fenceX"], force_device=True) report = [(severity.WARNING, report_codes.STONITH_RESOURCES_DO_NOT_EXIST, { "stonith_ids": ["dummy", "fenceX"], }, None)] assert_report_item_list_equal(reporter.report_item_list, report)
def test_node_invalid_not_forceable(self): reporter = MockLibraryReportProcessor() lib._validate_devices(reporter, self.resources_el, ["dummy", "fenceX"], allow_force=False) report = [(severity.ERROR, report_codes.STONITH_RESOURCES_DO_NOT_EXIST, { "stonith_ids": ["dummy", "fenceX"], }, None)] assert_report_item_list_equal(reporter.report_item_list, report)
def test_invalid(self): reporter = MockLibraryReportProcessor() lib._validate_target_typewise(reporter, "bad_target") report = [(severity.ERROR, report_codes.INVALID_OPTION_TYPE, { "option_name": "target", "allowed_types": ["node", "regular expression", "attribute_name=value"], }, None)] assert_report_item_list_equal(reporter.report_item_list, report)
def test_success_when_no_duplication_found(self, export_with_set): export_with_set.return_value = "exported_duplicate_element" element = mock.MagicMock() element.tag = "constraint_type" #no exception raised report_processor = MockLibraryReportProcessor() constraint.check_is_without_duplication( report_processor, fixture_constraint_section([]), element, are_duplicate=lambda e1, e2: True, export_element=constraint.export_with_set, )
def setUp(self): self.reporter = MockLibraryReportProcessor() self.topology_el = "a topology element" self.resources_el = "a resources element" self.level = "a level" self.target_type = "a target type" self.target_value = "a target value" self.devices = ["device1", "device2"] self.cluster_status_nodes = "a status" self.force_device = "a force for a device" self.force_node = "a force for a node"
def fixture_to_cib(cib_file, xml): environ = dict(os.environ) environ["CIB_file"] = cib_file runner = CommandRunner(mock.MagicMock(logging.Logger), MockLibraryReportProcessor(), environ) stdout, stderr, retval = runner.run([ os.path.join(settings.pacemaker_binaries, "cibadmin"), "--create", "--scope", "resources", "--xml-text", xml ]) assert retval == 0, ("Error running fixture_to_cib:\n" + stderr + "\n" + stdout)
def test_warn_when_config_exists_and_overwrite_allowed(self, mock_exists): # pylint: disable=unused-argument report_processor = MockLibraryReportProcessor() self.check(report_processor, can_overwrite_existing=True) assert_report_item_list_equal(report_processor.report_item_list, [( severities.WARNING, report_codes.FILE_ALREADY_EXISTS, { "file_path": CONF_PATH }, )])
def test_success(self, mock_find): mock_find.return_value = [] reporter = MockLibraryReportProcessor() lib._validate_level_target_devices_does_not_exist( reporter, "tree", "level", "target_type", "target_value", ["devices"]) mock_find.assert_called_once_with("tree", "level", "target_type", "target_value", ["devices"]) assert_report_item_list_equal(reporter.report_item_list, [])
def test_node_invalid_not_forceable(self): reporter = MockLibraryReportProcessor() lib._validate_target_valuewise(reporter, self.state, TARGET_TYPE_NODE, "rh7-x", allow_force=False) report = [(severity.ERROR, report_codes.NODE_NOT_FOUND, { "node": "rh7-x", }, None)] assert_report_item_list_equal(reporter.report_item_list, report)
def test_node_invalid_force(self): reporter = MockLibraryReportProcessor() lib._validate_target_valuewise(reporter, self.state, TARGET_TYPE_NODE, "rh7-x", force_node=True) report = [(severity.WARNING, report_codes.NODE_NOT_FOUND, { "node": "rh7-x", }, None)] assert_report_item_list_equal(reporter.report_item_list, report)
def test_raises_on_invalid_options(self): report_processor = MockLibraryReportProcessor() expected_errors = [ ( severities.ERROR, report_codes.INVALID_OPTIONS, { "option_names": ["site"], "option_type": "booth ticket", "allowed": list(config_structure.TICKET_KEYS), "allowed_patterns": [], }, ), ( severities.ERROR, report_codes.INVALID_OPTIONS, { "option_names": ["port"], "option_type": "booth ticket", "allowed": list(config_structure.TICKET_KEYS), "allowed_patterns": [], }, ), ( severities.ERROR, report_codes.INVALID_OPTION_VALUE, { "option_name": "timeout", "option_value": " ", "allowed_values": "no-empty", "cannot_be_empty": False, "forbidden_characters": None, }, ), (severities.ERROR, report_codes.INVALID_OPTIONS, { "option_names": ["unknown"], "option_type": "booth ticket", "allowed": list(config_structure.TICKET_KEYS), "allowed_patterns": [], }, report_codes.FORCE_OPTIONS), ] assert_raise_library_error( lambda: config_structure.validate_ticket_options( report_processor, { "site": "a", "port": "b", "timeout": " ", "unknown": "c", }, allow_unknown_options=False, ), *expected_errors) assert_report_item_list_equal(report_processor.report_item_list, expected_errors)
def setUp(self): self.known_hosts = { "host{}".format(i): PcsKnownHost( "host{}".format(i), "token{}".format(i), [ Destination( "addr{}{}".format(i, j), "port{}{}".format(i, j) ) for j in range(2) ] ) for i in range(2) } self.report_processor = MockLibraryReportProcessor() self.factory = lib.NodeTargetLibFactory( self.known_hosts, self.report_processor )
class NodeTargetLibFactory(TestCase): def setUp(self): self.known_hosts = { "host{}".format(i): PcsKnownHost( "host{}".format(i), "token{}".format(i), [ Destination( "addr{}{}".format(i, j), "port{}{}".format(i, j) ) for j in range(2) ] ) for i in range(2) } self.report_processor = MockLibraryReportProcessor() self.factory = lib.NodeTargetLibFactory( self.known_hosts, self.report_processor ) def assert_equal_known_host_target(self, known_host, target): self.assertEqual(known_host.name, target.label) self.assertEqual(known_host.token, target.token) self.assertEqual(known_host.dest_list, target.dest_list) def test_one_host(self): host = "host0" self.assert_equal_known_host_target( self.known_hosts[host], self.factory.get_target_list([host])[0] ) self.report_processor.assert_reports([]) def test_multiple_hosts(self): host_list = ["host0", "host1"] target_list = self.factory.get_target_list(host_list) for i, host in enumerate(host_list): self.assert_equal_known_host_target( self.known_hosts[host], target_list[i] ) self.report_processor.assert_reports([]) def test_multiple_not_found(self): host = "host0" unknown_hosts = ["node0", "node1"] report = fixture.error( report_codes.HOST_NOT_FOUND, force_code=report_codes.SKIP_OFFLINE_NODES, host_list=unknown_hosts ) assert_raise_library_error( lambda: self.factory.get_target_list([host] + unknown_hosts), report ) self.report_processor.assert_reports([report]) def test_multiple_skip_not_allowed(self): host = "host0" unknown_hosts = ["node0", "node1"] report = fixture.error( report_codes.HOST_NOT_FOUND, host_list=unknown_hosts ) assert_raise_library_error( lambda: self.factory.get_target_list( [host] + unknown_hosts, allow_skip=False, ), report ) self.report_processor.assert_reports([report]) def test_multiple_not_found_skip_offline(self): host = "host0" unknown_hosts = ["node0", "node1"] target_list = self.factory.get_target_list( [host] + unknown_hosts, skip_non_existing=True ) self.assert_equal_known_host_target( self.known_hosts[host], target_list[0] ) self.report_processor.assert_reports([ fixture.warn(report_codes.HOST_NOT_FOUND, host_list=unknown_hosts) ]) def test_no_host_found(self): unknown_hosts = ["node0", "node1"] report_list = [ fixture.error( report_codes.HOST_NOT_FOUND, force_code=report_codes.SKIP_OFFLINE_NODES, host_list=unknown_hosts ), fixture.error(report_codes.NONE_HOST_FOUND) ] assert_raise_library_error( lambda: self.factory.get_target_list(unknown_hosts), *report_list ) self.report_processor.assert_reports(report_list) def test_no_host_found_skip_offline(self): unknown_hosts = ["node0", "node1"] report_list = [ fixture.warn(report_codes.HOST_NOT_FOUND, host_list=unknown_hosts), fixture.error(report_codes.NONE_HOST_FOUND) ] assert_raise_library_error( lambda: self.factory.get_target_list( unknown_hosts, skip_non_existing=True ), report_list[1] ) self.report_processor.assert_reports(report_list) def test_empty_host_list(self): self.assertEqual([], self.factory.get_target_list([])) self.report_processor.assert_reports([])
class CommunicatorLoggerTest(TestCase): def setUp(self): self.logger = mock.MagicMock(spec_set=logging.Logger) self.reporter = MockLibraryReportProcessor() self.com_logger = lib.LibCommunicatorLogger(self.logger, self.reporter) def test_log_request_start(self): request = fixture_request() self.com_logger.log_request_start(request) self.reporter.assert_reports( fixture_report_item_list_send(request.url, request.data) ) self.assertEqual( [fixture_logger_call_send(request.url, request.data)], self.logger.mock_calls ) def test_log_response_connected(self): expected_code = 200 expected_data = "data" expected_debug_data = "* text\n>> data out\n" response = Response.connection_successful( MockCurlSimple( info={pycurl.RESPONSE_CODE: expected_code}, output=expected_data.encode("utf-8"), debug_output=expected_debug_data.encode("utf-8"), request=fixture_request(), ) ) self.com_logger.log_response(response) self.reporter.assert_reports( fixture_report_item_list_on_success( response.request.url, expected_code, expected_data, expected_debug_data ) ) logger_calls = fixture_logger_calls_on_success( response.request.url, expected_code, expected_data, expected_debug_data ) self.assertEqual(logger_calls, self.logger.mock_calls) @mock.patch("pcs.lib.node_communication.is_proxy_set") def test_log_response_not_connected(self, mock_proxy): mock_proxy.return_value = False expected_debug_data = "* text\n>> data out\n" error_msg = "error" response = Response.connection_failure( MockCurlSimple( debug_output=expected_debug_data.encode("utf-8"), request=fixture_request(), ), pycurl.E_HTTP_POST_ERROR, error_msg, ) self.com_logger.log_response(response) self.reporter.assert_reports( fixture_report_item_list_not_connected( response.request.host_label, error_msg ) + fixture_report_item_list_debug( response.request.url, expected_debug_data ) ) logger_calls = [ fixture_logger_call_not_connected( response.request.host_label, error_msg ), fixture_logger_call_debug_data( response.request.url, expected_debug_data ) ] self.assertEqual(logger_calls, self.logger.mock_calls) @mock.patch("pcs.lib.node_communication.is_proxy_set") def test_log_response_not_connected_with_proxy(self, mock_proxy): mock_proxy.return_value = True expected_debug_data = "* text\n>> data out\n" error_msg = "error" response = Response.connection_failure( MockCurlSimple( debug_output=expected_debug_data.encode("utf-8"), request=fixture_request(), ), pycurl.E_HTTP_POST_ERROR, error_msg, ) self.com_logger.log_response(response) self.reporter.assert_reports( fixture_report_item_list_not_connected( response.request.host_label, error_msg ) + fixture_report_item_list_proxy_set( response.request.host_label, response.request.host_label ) + fixture_report_item_list_debug( response.request.url, expected_debug_data ) ) logger_calls = [ fixture_logger_call_not_connected( response.request.host_label, error_msg ), fixture_logger_call_proxy_set(), fixture_logger_call_debug_data( response.request.url, expected_debug_data ) ] self.assertEqual(logger_calls, self.logger.mock_calls) def test_log_retry(self): prev_addr = "addr" prev_port = 2225 prev_host = Destination(prev_addr, prev_port) response = Response.connection_failure( MockCurlSimple(request=fixture_request()), pycurl.E_HTTP_POST_ERROR, "e", ) self.com_logger.log_retry(response, prev_host) self.reporter.assert_reports([( severity.WARNING, report_codes.NODE_COMMUNICATION_RETRYING, { "node": response.request.host_label, "failed_address": prev_addr, "failed_port": prev_port, "next_address": response.request.dest.addr, "next_port": settings.pcsd_default_port, "request": response.request.url, }, None )]) logger_call = mock.call.warning( ( "Unable to connect to '{label}' via address '{old_addr}' and " "port '{old_port}'. Retrying request '{req}' via address " "'{new_addr}' and port '{new_port}'" ).format( label=response.request.host_label, old_addr=prev_addr, old_port=prev_port, new_addr=response.request.dest.addr, new_port=settings.pcsd_default_port, req=response.request.url, ) ) self.assertEqual([logger_call], self.logger.mock_calls) def test_log_no_more_addresses(self): response = Response.connection_failure( MockCurlSimple(request=fixture_request()), pycurl.E_HTTP_POST_ERROR, "e" ) self.com_logger.log_no_more_addresses(response) self.reporter.assert_reports([( severity.WARNING, report_codes.NODE_COMMUNICATION_NO_MORE_ADDRESSES, { "node": response.request.host_label, "request": response.request.url, }, None )]) logger_call = mock.call.warning( "No more addresses for node {label} to run '{req}'".format( label=response.request.host_label, req=response.request.url, ) ) self.assertEqual([logger_call], self.logger.mock_calls)
def setUp(self): self.logger = mock.MagicMock(spec_set=logging.Logger) self.reporter = MockLibraryReportProcessor() self.com_logger = lib.LibCommunicatorLogger(self.logger, self.reporter)