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 test_remove_ip_when_booth_resource_add_failed(self): mock_resource_create = mock.Mock(side_effect=[None, SystemExit(1)]) mock_resource_remove = mock.Mock() mock_create_id = mock.Mock(side_effect=["ip_id","booth_id","group_id"]) ip = "1.2.3.4" booth_config_file_path = rc("/path/to/booth.conf") booth_resource.get_creator(mock_resource_create, mock_resource_remove)( ip, booth_config_file_path, mock_create_id ) self.assertEqual(mock_resource_create.mock_calls, [ mock.call( clone_opts=[], group=u'group_id', meta_values=[], op_values=[], ra_id=u'ip_id', ra_type=u'ocf:heartbeat:IPaddr2', ra_values=[u'ip=1.2.3.4'], ), mock.call( clone_opts=[], group='group_id', meta_values=[], op_values=[], ra_id='booth_id', ra_type='ocf:pacemaker:booth-site', ra_values=['config=/path/to/booth.conf'], ) ]) mock_resource_remove.assert_called_once_with("ip_id")
def test_validate_all_individual_options(self): self.assertEqual( ["REQUIRES REPORT", "ROLE REPORT"], sorted( operations.validate_operation({"name": "monitor"}, [ mock.Mock(return_value=["ROLE REPORT"]), mock.Mock(return_value=["REQUIRES REPORT"]), ])))
class FindResourceElementsForOperationTest(TestCase): @patch_commands("resource.find_for_config", mock.Mock(return_value=[])) def test_raises_when_no_booth_resource_found(self): assert_raise_library_error( lambda: commands._find_resource_elements_for_operation( mock.MagicMock(), "somename", allow_multiple=False ), ( Severities.ERROR, report_codes.BOOTH_NOT_EXISTS_IN_CIB, { 'name': 'somename', } ), ) @patch_commands( "resource.find_for_config", mock.Mock(return_value=["b_el1", "b_el2"]) ) def test_raises_when_multiple_booth_resource_found(self): assert_raise_library_error( lambda: commands._find_resource_elements_for_operation( mock.MagicMock(), "somename", allow_multiple=False ), ( Severities.ERROR, report_codes.BOOTH_MULTIPLE_TIMES_IN_CIB, { 'name': 'somename', }, report_codes.FORCE_BOOTH_REMOVE_FROM_CIB, ), ) @patch_commands("get_resources", mock.Mock(return_value="resources")) @patch_commands("resource.get_remover", mock.MagicMock()) @patch_commands("resource.find_for_config", mock.Mock(return_value=[1, 2])) def test_warn_when_multiple_booth_resources_removed(self): report_processor=MockLibraryReportProcessor() commands._find_resource_elements_for_operation( mock.MagicMock(report_processor=report_processor), "somename", allow_multiple=True, ) assert_report_item_list_equal(report_processor.report_item_list, [( Severities.WARNING, report_codes.BOOTH_MULTIPLE_TIMES_IN_CIB, { 'name': 'somename', }, )])
def test_refuse_when_node_not_in_cib_and_is_not_remote(self, mock_utils): mock_cib = mock.MagicMock() mock_cib.getElementsByTagName = mock.Mock(return_value=[]) mock_utils.get_cib_dom = mock.Mock(return_value=mock_cib) mock_utils.usefile = False mock_utils.getNodeAttributesFromPacemaker = mock.Mock(return_value=[]) mock_utils.err = mock.Mock(side_effect=SystemExit) self.assertRaises(SystemExit, lambda: node.print_node_utilization("some"))
def test_raises_when_command_fail(self): mock_run = mock.Mock(return_value=("some message", "error", 1)) mock_env = mock.MagicMock(cmd_runner=mock.Mock( return_value=mock.MagicMock(run=mock_run))) assert_raise_library_error( lambda: commands.ticket_operation( "grant", mock_env, "booth", "ABC", site_ip="1.2.3.4"), (Severities.ERROR, report_codes.BOOTH_TICKET_OPERATION_FAILED, { "operation": "grant", "reason": "error\nsome message", "site_ip": "1.2.3.4", "ticket_name": "ABC", }), )
class ConfigDestroyTest(TestCase): @patch_commands("external.is_systemctl", mock.Mock(return_value=True)) @patch_commands("external.is_service_enabled", mock.Mock(return_value=True)) @patch_commands("external.is_service_running", mock.Mock(return_value=True)) @patch_commands("resource.find_for_config", mock.Mock(return_value=[True])) def test_raises_when_booth_config_in_use(self): env = mock.MagicMock() env.booth.name = "somename" assert_raise_library_error( lambda: commands.config_destroy(env), (Severities.ERROR, report_codes.BOOTH_CONFIG_IS_USED, { "name": "somename", "detail": "in cluster resource", }), (Severities.ERROR, report_codes.BOOTH_CONFIG_IS_USED, { "name": "somename", "detail": "(enabled in systemd)", }), (Severities.ERROR, report_codes.BOOTH_CONFIG_IS_USED, { "name": "somename", "detail": "(running in systemd)", })) @patch_commands("external.is_systemctl", mock.Mock(return_value=False)) @patch_commands("resource.find_for_config", mock.Mock(return_value=[])) @patch_commands("parse", mock.Mock(side_effect=LibraryError())) def test_raises_when_cannot_get_content_of_config(self): env = mock.MagicMock() env.booth.name = "somename" assert_raise_library_error( lambda: commands.config_destroy(env), (Severities.ERROR, report_codes.BOOTH_CANNOT_IDENTIFY_KEYFILE, {}, report_codes.FORCE_BOOTH_DESTROY)) @patch_commands("external.is_systemctl", mock.Mock(return_value=False)) @patch_commands("resource.find_for_config", mock.Mock(return_value=[])) @patch_commands("parse", mock.Mock(side_effect=LibraryError())) def test_remove_config_even_if_cannot_get_its_content_when_forced(self): env = mock.MagicMock() env.booth.name = "somename" env.report_processor = MockLibraryReportProcessor() commands.config_destroy(env, ignore_config_load_problems=True) env.booth.remove_config.assert_called_once_with() assert_report_item_list_equal( env.report_processor.report_item_list, [(Severities.WARNING, report_codes.BOOTH_CANNOT_IDENTIFY_KEYFILE, {})])
def test_catch_exactly_his_exception(self): report_missing = self.setup_patch("env_file.report_missing") next_in_line = mock.Mock(side_effect=LibraryEnvError( ReportItem.error(report_codes.FILE_DOES_NOT_EXIST, info={ "file_role": env_file_role_codes.BOOTH_CONFIG, }), ReportItem.error(report_codes.FILE_DOES_NOT_EXIST, info={ "file_role": env_file_role_codes.BOOTH_KEY, }), ReportItem.error("OTHER ERROR", info={}), )) mock_env = mock.MagicMock() self.read.return_value = {"content": None} booth_conf_middleware = env.middleware_config( "booth-name", "/local/file/path.conf", "/local/file/path.key", ) raised_exception = [] def run_middleware(): try: booth_conf_middleware(next_in_line, mock_env) except Exception as e: raised_exception.append(e) raise e self.assertRaises(LibraryEnvError, run_middleware) self.assertEqual(1, len(raised_exception[0].unprocessed)) self.assertEqual("OTHER ERROR", raised_exception[0].unprocessed[0].code) self.assertEqual(report_missing.mock_calls, [ mock.call('Booth config file', '/local/file/path.conf'), mock.call('Booth key file', '/local/file/path.key'), ])
def test_push_cib_on_success(self): env = mock.MagicMock() env.get_cib = mock.Mock(return_value="cib") with cmd_acl.cib_acl_section(env): pass env.get_cib.assert_called_once_with(cmd_acl.REQUIRED_CIB_VERSION) env.push_cib.assert_called_once_with("cib")
def assert_result_causes_invalid_format(self, result): self.node_communicator.call_node = mock.Mock( return_value=json.dumps(result)) assert_call_cause_reports( self.make_call, [fixture_invalid_response_format(self.node.label)], )
def test_call_library_remove_with_correct_attrs(self): lib = mock.MagicMock( constraint_ticket=mock.MagicMock(remove=mock.Mock()) ) command.remove(lib, ["TICKET", "RESOURCE"], {}) lib.constraint_ticket.remove.assert_called_once_with( "TICKET", "RESOURCE", )
def test_raises_when_implicit_site_not_found_in_cib( self, mock_find_bound_ip): mock_find_bound_ip.return_value = [] assert_raise_library_error( lambda: commands.ticket_operation( "grant", mock.Mock(), "booth", "ABC", site_ip=None), (Severities.ERROR, report_codes.BOOTH_CANNOT_DETERMINE_LOCAL_SITE_IP, {}), )
def test_success_write_content_to_path(self): mock_open = mock.mock_open() mock_file_operation = mock.Mock() with patch_env_file("open", mock_open, create=True): env_file.RealFile("some role", CONF_PATH).write( "config content", file_operation=mock_file_operation) mock_open.assert_called_once_with(CONF_PATH, "w") mock_open().write.assert_called_once_with("config content") mock_file_operation.assert_called_once_with(CONF_PATH)
def test_success_write_content_to_path(self): mock_open = mock.mock_open() mock_file_operation = mock.Mock() with mock.patch("pcs.lib.env_file.open", mock_open, create=True): RealFile("some role", "/etc/booth/some-name.conf").write( "config content", file_operation=mock_file_operation) mock_open.assert_called_once_with("/etc/booth/some-name.conf", "w") mock_open().write.assert_called_once_with("config content") mock_file_operation.assert_called_once_with( "/etc/booth/some-name.conf")
def test_ensure_support_error(self, mock_obj): mock_obj.return_value = False assert_raise_library_error( lambda: lib.ensure_wait_for_idle_support(mock.Mock()), ( Severity.ERROR, report_codes.WAIT_FOR_IDLE_NOT_SUPPORTED, {} ) )
def test_return_corrected_resurce_set(self): find_valid_id = mock.Mock() find_valid_id.side_effect = lambda id: {"A": "AA", "B": "BB"}[id] self.assertEqual( {"ids": ["AA", "BB"], "options": {"sequential": "true"}}, resource_set.prepare_set(find_valid_id, { "ids": ["A", "B"], "options": {"sequential": "true"} }) )
def test_returns_real_agent_when_is_there(self, ResourceAgent): #setup name = "ocf:heartbeat:Delay" agent = mock.MagicMock() agent.validate_metadata = mock.Mock(return_value=agent) ResourceAgent.return_value = agent #test self.assertEqual(agent, self.run(name)) ResourceAgent.assert_called_once_with(self.runner, name)
def test_show_constraints_full(self): load_constraints = mock.Mock() load_constraints.return_value = { "plain": [{ "options": { "id": "plain_id" } }], "with_resource_sets": [fixture_constraint()] } format_options = mock.Mock() format_options.return_value = "plain constraint listing" self.assertEqual([ "caption", " plain constraint listing", " Resource Sets:", " " + fixture_constraint_console(), ], command.show("caption", load_constraints, format_options, {"full": True}))
def test_success_binary(self): mock_open = mock.mock_open() mock_file_operation = mock.Mock() with patch_env_file("open", mock_open, create=True): env_file.RealFile("some role", CONF_PATH, is_binary=True).write( "config content".encode("utf-8"), file_operation=mock_file_operation, ) mock_open.assert_called_once_with(CONF_PATH, "wb") mock_open().write.assert_called_once_with( "config content".encode("utf-8")) mock_file_operation.assert_called_once_with(CONF_PATH)
def test_process_communication_exception(self): self.node_communicator.call_node = mock.Mock( side_effect=NodeAuthenticationException("node", "request", "reason")) self.assert_communicator_cause_reports([ (severity.ERROR, report_codes.NODE_COMMUNICATION_ERROR_NOT_AUTHORIZED, { 'node': 'node', 'reason': 'reason', 'command': 'request' }), ])
def test_refuse_invalid_attribute_value(self): assert_raise_library_error( lambda: resource_set.prepare_set(mock.Mock(), { "ids": ["A", "B"], "options": {"role": "invalid"} }), (severities.ERROR, report_codes.INVALID_OPTION_VALUE, { 'option_name': 'role', 'allowed_values': ('Stopped', 'Started', 'Master', 'Slave'), 'option_value': 'invalid', }), )
class UpdateNvsetTest(TestCase): @mock.patch("pcs.lib.cib.nvpair.create_subelement_id", mock.Mock(return_value="4")) def test_updates_nvset(self): nvset_element = etree.fromstring(""" <instance_attributes id="iattrs"> <nvpair id="1" name="a" value="b"/> <nvpair id="2" name="c" value="d"/> <nvpair id="3" name="e" value="f"/> </instance_attributes> """) nvpair.update_nvset(nvset_element, { "a": "B", "c": "", "g": "h", }) assert_xml_equal( """ <instance_attributes id="iattrs"> <nvpair id="1" name="a" value="B"/> <nvpair id="3" name="e" value="f"/> <nvpair id="4" name="g" value="h"/> </instance_attributes> """, etree_to_str(nvset_element)) def test_empty_value_has_no_effect(self): xml = """ <instance_attributes id="iattrs"> <nvpair id="1" name="a" value="b"/> <nvpair id="2" name="c" value="d"/> <nvpair id="3" name="e" value="f"/> </instance_attributes> """ nvset_element = etree.fromstring(xml) nvpair.update_nvset(nvset_element, {}) assert_xml_equal(xml, etree_to_str(nvset_element)) def test_remove_empty_nvset(self): xml_pre = """ <resource> <instance_attributes id="iattrs"> <nvpair id="1" name="a" value="b"/> </instance_attributes> </resource> """ xml_post = """ <resource> </resource> """ xml = etree.fromstring(xml_pre) nvset_element = xml.find("instance_attributes") nvpair.update_nvset(nvset_element, {"a": ""}) assert_xml_equal(xml_post, etree_to_str(xml))
def test_success_binary(self): mock_open = mock.mock_open() mock_file_operation = mock.Mock() with mock.patch("pcs.lib.env_file.open", mock_open, create=True): RealFile("some role", "/etc/booth/some-name.conf").write( "config content".encode("utf-8"), file_operation=mock_file_operation, is_binary=True) mock_open.assert_called_once_with("/etc/booth/some-name.conf", "wb") mock_open().write.assert_called_once_with( "config content".encode("utf-8")) mock_file_operation.assert_called_once_with( "/etc/booth/some-name.conf")
def test_report_unprocessed_library_env_errors(self, mock_process_report): report1 = ReportItem.error("OTHER ERROR", info={}) report2 = ReportItem.error("OTHER ERROR", info={}) report3 = ReportItem.error("OTHER ERROR", info={}) e = LibraryEnvError(report1, report2, report3) e.sign_processed(report2) mock_middleware = mock.Mock(side_effect=e) binded = bind(cli_env=None, run_with_middleware=mock_middleware, run_library_command=None) self.assertRaises(SystemExit, lambda: binded(cli_env=None)) mock_process_report.assert_called_once_with([report1, report3])
def test_refuse_invalid_attribute_name(self): assert_raise_library_error( lambda: resource_set.prepare_set(mock.Mock(), { "ids": ["A", "B"], "options": { "invalid_name": "true" } }), (severities.ERROR, report_codes.INVALID_OPTION, { "option_names": ["invalid_name"], "option_type": None, "allowed": ["action", "require-all", "role", "sequential"], }), )
def test_returns_guessed_agent(self, mock_guess, mock_report): #setup name = "Delay" guessed_name = "ocf:heartbeat:Delay" report = "AGENT_NAME_GUESSED" agent = mock.MagicMock(get_name=mock.Mock(return_value=guessed_name)) mock_guess.return_value = agent mock_report.return_value = report #test self.assertEqual(agent, self.run(name)) mock_guess.assert_called_once_with(self.runner, name) self.report_processor.process.assert_called_once_with(report) mock_report.assert_called_once_with(name, guessed_name)
def setUp(self): self.env_assist, self.config = get_env_tools(self) self.remove_resource = mock.Mock() (self.config.runner.cib.load(resources=self.fixture_multi_resources)) self.multiple_result_reports = (fixture.ReportStore().error( "multiple_result_found", report_codes.MULTIPLE_RESULTS_FOUND, result_identifier_list=[ NODE_NAME, REMOTE_HOST, ], result_type="resource", search_description=REMOTE_HOST, force_code=report_codes.FORCE_REMOVE_MULTIPLE_NODES).as_warn( "multiple_result_found", "multiple_result_found_warn", ))
def test_catch_exactly_his_exception(self, mock_is_file, mock_console_report): next_in_line = mock.Mock(side_effect=LibraryEnvError( ReportItem.error(report_codes.FILE_DOES_NOT_EXIST, info={ "file_role": env_file_role_codes.BOOTH_CONFIG, }), ReportItem.error(report_codes.FILE_DOES_NOT_EXIST, info={ "file_role": env_file_role_codes.BOOTH_KEY, }), ReportItem.error("OTHER ERROR", info={}), )) mock_is_file.return_value = False mock_env = mock.MagicMock() #run tested code booth_conf_middleware = middleware_config( "booth-name", "/local/file/path.conf", "/local/file/path.key", ) raised_exception = [] def run_middleware(): try: booth_conf_middleware(next_in_line, mock_env) except Exception as e: raised_exception.append(e) raise e self.assertRaises(LibraryEnvError, run_middleware) self.assertEqual(1, len(raised_exception[0].unprocessed)) self.assertEqual("OTHER ERROR", raised_exception[0].unprocessed[0].code) self.assertEqual(mock_console_report.error.mock_calls, [ mock.call( "Booth config file '/local/file/path.conf' does not exist"), mock.call("Booth key file '/local/file/path.key' does not exist"), ])
class CibRunnerNodes(TestCase): def setUp(self): self.env = create_env() @patch_env("get_cib", lambda self: "mocked cib") @patch_env("cmd_runner", lambda self: "mocked cmd_runner") @patch_env("ensure_wait_satisfiable") @patch_command("ClusterState") @patch_command("get_cluster_status_xml") def test_wire_together_all_expected_dependecies(self, get_cluster_status_xml, ClusterState, ensure_wait_satisfiable, push_cib): ClusterState.return_value = mock.MagicMock(node_section=mock.MagicMock( nodes="nodes")) get_cluster_status_xml.return_value = "mock get_cluster_status_xml" wait = 10 with lib.cib_runner_nodes(self.env, wait) as (cib, runner, nodes): self.assertEqual(cib, "mocked cib") self.assertEqual(runner, "mocked cmd_runner") self.assertEqual(nodes, "nodes") ensure_wait_satisfiable.assert_called_once_with(wait) get_cluster_status_xml.assert_called_once_with("mocked cmd_runner") ClusterState.assert_called_once_with("mock get_cluster_status_xml") push_cib.assert_called_once_with("mocked cib", wait) @patch_env("ensure_wait_satisfiable", mock.Mock(side_effect=LibraryError)) def test_raises_when_wait_is_not_satisfiable(self, push_cib): def run(): #pylint: disable=unused-variable with lib.cib_runner_nodes(self.env, "wait") as (cib, runner, nodes): pass self.assertRaises(LibraryError, run) push_cib.assert_not_called()
class RemoveTest(TestCase): @patch_commands("ticket.remove_plain", mock.Mock(return_value=1)) @patch_commands("ticket.remove_with_resource_set", mock.Mock(return_value=0)) def test_successfully_remove_plain(self): self.assertTrue(ticket_command.remove(mock.MagicMock(), "T", "R")) @patch_commands("ticket.remove_plain", mock.Mock(return_value=0)) @patch_commands("ticket.remove_with_resource_set", mock.Mock(return_value=1)) def test_successfully_remove_with_resource_set(self): self.assertTrue(ticket_command.remove(mock.MagicMock(), "T", "R")) @patch_commands("ticket.remove_plain", mock.Mock(return_value=0)) @patch_commands("ticket.remove_with_resource_set", mock.Mock(return_value=0)) def test_raises_library_error_when_no_matching_constraint_found(self): self.assertFalse(ticket_command.remove(mock.MagicMock(), "T", "R"))