def test_skip_failed(self, mock_get_configs, mock_read): def _mock_read_cfg(file): if file in ["name1.conf", "name3.conf"]: raise EnvironmentError() elif file == "name2.conf": return "config2" else: raise AssertionError("unexpected input: {0}".format(file)) mock_get_configs.return_value = [ "name1.conf", "name2.conf", "name3.conf" ] mock_read.side_effect = _mock_read_cfg self.assertEqual({"name2.conf": "config2"}, config_files.read_configs(self.mock_reporter, True)) mock_get_configs.assert_called_once_with() self.assertEqual(3, mock_read.call_count) mock_read.assert_has_calls([ mock.call("name1.conf"), mock.call("name2.conf"), mock.call("name3.conf") ]) assert_report_item_list_equal( self.mock_reporter.report_item_list, [(severities.WARNING, report_codes.BOOTH_CONFIG_READ_ERROR, { "name": "name1.conf" }), (severities.WARNING, report_codes.BOOTH_CONFIG_READ_ERROR, { "name": "name3.conf" })])
def test_error_cleanup(self): expected_stdout = "some info" expected_stderr = "some error" expected_retval = 1 mock_runner = mock.MagicMock(spec_set=CommandRunner) call_list = [ mock.call(self.crm_mon_cmd()), mock.call([self.path("crm_resource"), "--cleanup"]), ] return_value_list = [ (self.fixture_status_xml(1, 1), "", 0), (expected_stdout, expected_stderr, expected_retval), ] mock_runner.run.side_effect = return_value_list assert_raise_library_error( lambda: lib.resource_cleanup(mock_runner), ( Severity.ERROR, report_codes.RESOURCE_CLEANUP_ERROR, { "reason": expected_stderr + "\n" + expected_stdout, } ) ) self.assertEqual(len(return_value_list), len(call_list)) self.assertEqual(len(return_value_list), mock_runner.run.call_count) mock_runner.run.assert_has_calls(call_list)
def test_success(self): node_id = "id_1" node_name = "name_1" node_status = self.fixture_get_node_status(node_name, node_id) expected_status = dict(node_status, offline=False) self.fixture_add_node_status( self.fixture_get_node_status("name_2", "id_2") ) self.fixture_add_node_status(node_status) self.fixture_add_node_status( self.fixture_get_node_status("name_3", "id_3") ) mock_runner = mock.MagicMock(spec_set=CommandRunner) call_list = [ mock.call(self.crm_mon_cmd()), mock.call([self.path("crm_node"), "--cluster-id"]), mock.call( [self.path("crm_node"), "--name-for-id={0}".format(node_id)] ), ] return_value_list = [ (str(self.status), "", 0), (node_id, "", 0), (node_name, "", 0) ] mock_runner.run.side_effect = return_value_list real_status = lib.get_local_node_status(mock_runner) self.assertEqual(len(return_value_list), len(call_list)) self.assertEqual(len(return_value_list), mock_runner.run.call_count) mock_runner.run.assert_has_calls(call_list) self.assertEqual(expected_status, real_status)
def test_error_3(self): node_id = "id_1" node_name = "name_1" node_status = self.fixture_get_node_status(node_name, node_id) self.fixture_add_node_status(node_status) mock_runner = mock.MagicMock(spec_set=CommandRunner) call_list = [ mock.call(self.crm_mon_cmd()), mock.call([self.path("crm_node"), "--cluster-id"]), mock.call( [self.path("crm_node"), "--name-for-id={0}".format(node_id)] ), ] return_value_list = [ (str(self.status), "", 0), (node_id, "", 0), ("(null)", "", 0), ] mock_runner.run.side_effect = return_value_list assert_raise_library_error( lambda: lib.get_local_node_status(mock_runner), ( Severity.ERROR, report_codes.PACEMAKER_LOCAL_NODE_NAME_NOT_FOUND, {"reason": "node name is null"} ) ) self.assertEqual(len(return_value_list), len(call_list)) self.assertEqual(len(return_value_list), mock_runner.run.call_count) mock_runner.run.assert_has_calls(call_list)
def test_success(self, mock_get_configs, mock_read): def _mock_read_cfg(file): if file == "name1.conf": return "config1" elif file == "name2.conf": return "config2" elif file == "name3.conf": return "config3" else: raise AssertionError("unexpected input: {0}".format(file)) mock_get_configs.return_value = [ "name1.conf", "name2.conf", "name3.conf" ] mock_read.side_effect = _mock_read_cfg self.assertEqual( { "name1.conf": "config1", "name2.conf": "config2", "name3.conf": "config3" }, config_files.read_configs(self.mock_reporter) ) mock_get_configs.assert_called_once_with() self.assertEqual(3, mock_read.call_count) mock_read.assert_has_calls([ mock.call("name1.conf"), mock.call("name2.conf"), mock.call("name3.conf") ]) self.assertEqual(0, len(self.mock_reporter.report_item_list))
def test_standard_not_specified(self, mock_list_agents, mock_list_standards): agents_ocf = [ "Delay", "Dummy", "Stateful", ] agents_service = [ "corosync", "pacemaker", "pcsd", ] mock_list_standards.return_value = ["ocf:test", "service"] mock_list_agents.side_effect = [agents_ocf, agents_service] self.assertEqual( lib.list_agents_for_standard_and_provider(self.lib_env), sorted(agents_ocf + agents_service, key=lambda x: x.lower())) mock_list_standards.assert_called_once_with("mock_runner") self.assertEqual(2, len(mock_list_agents.mock_calls)) mock_list_agents.assert_has_calls([ mock.call("mock_runner", "ocf:test"), mock.call("mock_runner", "service"), ])
def test_configs_without_authfiles(self, mock_read_authfile, mock_read_configs, mock_parse, mock_authfile, mock_run_com): def mock_authfile_fn(parsed_config): if parsed_config == "config1": return None elif parsed_config == "config2": return "/path/to/file2.key" else: raise AssertionError( "unexpected input: {0}".format(parsed_config)) mock_parse.side_effect = self.mock_parse_fn mock_authfile.side_effect = mock_authfile_fn mock_read_authfile.return_value = "another key".encode("utf-8") mock_read_configs.return_value = { "name1.conf": "config1", "name2.conf": "config2" } mock_run_com.return_value = [(self.node, { "existing": [], "failed": {}, "saved": ["name1.conf", "name2.conf", "file2.key"] })] lib.send_all_config_to_node(self.mock_com, self.mock_reporter, self.node) self.assertEqual(2, mock_parse.call_count) mock_parse.assert_has_calls( [mock.call("config1"), mock.call("config2")]) self.assertEqual(2, mock_authfile.call_count) mock_authfile.assert_has_calls( [mock.call("config1"), mock.call("config2")]) mock_read_authfile.assert_called_once_with(self.mock_reporter, "/path/to/file2.key") mock_read_configs.assert_called_once_with(self.mock_reporter, False) expected_file_list = [{ "name": "name1.conf", "data": "config1", "is_authfile": False }, { "name": "name2.conf", "data": "config2", "is_authfile": False }, { "name": "file2.key", "data": to_b64("another key"), "is_authfile": True }] communicator, com_cmd = mock_run_com.call_args[0] self.assertEqual(self.mock_com, communicator) self.assertEqual(expected_file_list, com_cmd._file_list) self.assertFalse(com_cmd._rewrite_existing) assert_report_item_list_equal( self.mock_reporter.report_item_list, [(Severities.INFO, report_codes.BOOTH_CONFIG_DISTRIBUTION_STARTED, {}), (Severities.INFO, report_codes.BOOTH_CONFIG_ACCEPTED_BY_NODE, { "node": self.node.label, "name_list": ["name1.conf", "name2.conf", "file2.key"] })])
def test_success(self, mock_get_configs, mock_read): def _mock_read_cfg(file): if file == "name1.conf": return "config1" elif file == "name2.conf": return "config2" elif file == "name3.conf": return "config3" else: raise AssertionError("unexpected input: {0}".format(file)) mock_get_configs.return_value = [ "name1.conf", "name2.conf", "name3.conf" ] mock_read.side_effect = _mock_read_cfg self.assertEqual( { "name1.conf": "config1", "name2.conf": "config2", "name3.conf": "config3" }, config_files.read_configs(self.mock_reporter)) mock_get_configs.assert_called_once_with() self.assertEqual(3, mock_read.call_count) mock_read.assert_has_calls([ mock.call("name1.conf"), mock.call("name2.conf"), mock.call("name3.conf") ]) self.assertEqual(0, len(self.mock_reporter.report_item_list))
def test_do_not_skip_failed(self, mock_get_configs, mock_read): def _mock_read_cfg(file): if file in ["name1.conf", "name3.conf"]: raise EnvironmentError() elif file == "name2.conf": return "config2" else: raise AssertionError("unexpected input: {0}".format(file)) mock_get_configs.return_value = [ "name1.conf", "name2.conf", "name3.conf" ] mock_read.side_effect = _mock_read_cfg assert_raise_library_error( lambda: config_files.read_configs(self.mock_reporter), (severities.ERROR, report_codes.BOOTH_CONFIG_READ_ERROR, { "name": "name1.conf" }, report_codes.SKIP_UNREADABLE_CONFIG), (severities.ERROR, report_codes.BOOTH_CONFIG_READ_ERROR, { "name": "name3.conf" }, report_codes.SKIP_UNREADABLE_CONFIG)) mock_get_configs.assert_called_once_with() self.assertEqual(3, mock_read.call_count) mock_read.assert_has_calls([ mock.call("name1.conf"), mock.call("name2.conf"), mock.call("name3.conf") ]) self.assertEqual(2, len(self.mock_reporter.report_item_list))
def test_failure(self, mock_role, mock_assign): def _mock_role(_, el_id): if el_id in ["role1", "role3"]: raise acl_lib.AclRoleNotFound(el_id) elif el_id == "role2": return "role2_el" else: raise AssertionError("unexpected input") mock_role.side_effect = _mock_role assert_raise_library_error( lambda: cmd_acl._assign_roles_to_element( self.cib, "el", ["role1", "role2", "role3"]), (Severities.ERROR, report_codes.ID_NOT_FOUND, { "id": "role1", "id_description": "role", }), (Severities.ERROR, report_codes.ID_NOT_FOUND, { "id": "role3", "id_description": "role", })) mock_role.assert_has_calls([ mock.call(self.cib, "role1"), mock.call(self.cib, "role2"), mock.call(self.cib, "role3") ]) mock_assign.assert_called_once_with("el", "role2_el")
def test_error_some_nodes(self): nodes = ("node1", "node2", "node3", "node4") for i, n in enumerate(nodes, 1): self.fixture_add_node_status(self.fixture_get_node_status(n, i)) mock_runner = mock.MagicMock(spec_set=CommandRunner) call_list = [mock.call(self.crm_mon_cmd())] call_list += [ mock.call([self.path("crm_standby"), "-v", "on", "-N", n]) for n in nodes ] return_value_list = [ (str(self.status), "", 0), ("dummy1", "", 0), ("dummy2", "error2", 1), ("dummy3", "", 0), ("dummy4", "error4", 1), ] mock_runner.run.side_effect = return_value_list assert_raise_library_error( lambda: lib.nodes_standby(mock_runner, all_nodes=True), (Severity.ERROR, report_codes.COMMON_ERROR, { "text": "error2\ndummy2", }), (Severity.ERROR, report_codes.COMMON_ERROR, { "text": "error4\ndummy4", })) self.assertEqual(len(return_value_list), len(call_list)) self.assertEqual(len(return_value_list), mock_runner.run.call_count) mock_runner.run.assert_has_calls(call_list)
def test_success(self, mock_remote_start, mock_remote_stop): nodes = ["node1", "node2"] node_addrs_list = NodeAddressesList( [NodeAddresses(addr) for addr in nodes] ) lib.qdevice_reload_on_nodes( self.mock_communicator, self.mock_reporter, node_addrs_list ) node_calls = [ mock.call( self.mock_reporter, self.mock_communicator, node_addrs_list[0] ), mock.call( self.mock_reporter, self.mock_communicator, node_addrs_list[1] ), ] self.assertEqual(len(node_calls), len(mock_remote_stop.mock_calls)) self.assertEqual(len(node_calls), len(mock_remote_start.mock_calls)) mock_remote_stop.assert_has_calls(node_calls, any_order=True) mock_remote_start.assert_has_calls(node_calls, any_order=True) assert_report_item_list_equal( self.mock_reporter.report_item_list, [ ( severity.INFO, report_codes.QDEVICE_CLIENT_RELOAD_STARTED, {} ), ] )
def test_standard_not_specified( self, mock_list_agents, mock_list_standards ): agents_ocf = [ "Delay", "Dummy", "Stateful", ] agents_service = [ "corosync", "pacemaker", "pcsd", ] mock_list_standards.return_value = ["ocf:test", "service"] mock_list_agents.side_effect = [agents_ocf, agents_service] self.assertEqual( lib.list_agents_for_standard_and_provider(self.lib_env), sorted(agents_ocf + agents_service, key=lambda x: x.lower()) ) mock_list_standards.assert_called_once_with("mock_runner") self.assertEqual(2, len(mock_list_agents.mock_calls)) mock_list_agents.assert_has_calls([ mock.call("mock_runner", "ocf:test"), mock.call("mock_runner", "service"), ])
def test_error_3(self): node_id = "id_1" node_name = "name_1" node_status = self.fixture_get_node_status(node_name, node_id) self.fixture_add_node_status(node_status) mock_runner = mock.MagicMock(spec_set=CommandRunner) call_list = [ mock.call(self.crm_mon_cmd()), mock.call([self.path("crm_node"), "--cluster-id"]), mock.call( [self.path("crm_node"), "--name-for-id={0}".format(node_id)]), ] return_value_list = [ (str(self.status), "", 0), (node_id, "", 0), ("(null)", "", 0), ] mock_runner.run.side_effect = return_value_list assert_raise_library_error( lambda: lib.get_local_node_status(mock_runner), (Severity.ERROR, report_codes.PACEMAKER_LOCAL_NODE_NAME_NOT_FOUND, { "reason": "node name is null" })) self.assertEqual(len(return_value_list), len(call_list)) self.assertEqual(len(return_value_list), mock_runner.run.call_count) mock_runner.run.assert_has_calls(call_list)
def test_success(self): node_id = "id_1" node_name = "name_1" node_status = self.fixture_get_node_status(node_name, node_id) expected_status = dict(node_status, offline=False) self.fixture_add_node_status( self.fixture_get_node_status("name_2", "id_2")) self.fixture_add_node_status(node_status) self.fixture_add_node_status( self.fixture_get_node_status("name_3", "id_3")) mock_runner = mock.MagicMock(spec_set=CommandRunner) call_list = [ mock.call(self.crm_mon_cmd()), mock.call([self.path("crm_node"), "--cluster-id"]), mock.call( [self.path("crm_node"), "--name-for-id={0}".format(node_id)]), ] return_value_list = [(str(self.status), "", 0), (node_id, "", 0), (node_name, "", 0)] mock_runner.run.side_effect = return_value_list real_status = lib.get_local_node_status(mock_runner) self.assertEqual(len(return_value_list), len(call_list)) self.assertEqual(len(return_value_list), mock_runner.run.call_count) mock_runner.run.assert_has_calls(call_list) self.assertEqual(expected_status, real_status)
def test_fail_doesnt_prevent_start(self, mock_remote_start, mock_remote_stop): nodes = ["node1", "node2"] node_addrs_list = NodeAddressesList( [NodeAddresses(addr) for addr in nodes]) def raiser(reporter, communicator, node): if node.ring0 == nodes[1]: raise NodeAuthenticationException(node.label, "command", "HTTP error: 401") mock_remote_stop.side_effect = raiser assert_raise_library_error( lambda: lib.qdevice_reload_on_nodes( self.mock_communicator, self.mock_reporter, node_addrs_list), (severity.ERROR, report_codes.NODE_COMMUNICATION_ERROR_NOT_AUTHORIZED, { "node": nodes[1], "command": "command", "reason": "HTTP error: 401", }, report_codes.SKIP_OFFLINE_NODES)) node_calls = [ mock.call(self.mock_reporter, self.mock_communicator, node_addrs_list[0]), mock.call(self.mock_reporter, self.mock_communicator, node_addrs_list[1]), ] self.assertEqual(len(node_calls), len(mock_remote_stop.mock_calls)) self.assertEqual(len(node_calls), len(mock_remote_start.mock_calls)) mock_remote_stop.assert_has_calls(node_calls, any_order=True) mock_remote_start.assert_has_calls(node_calls, any_order=True) assert_report_item_list_equal( self.mock_reporter.report_item_list, [ (severity.INFO, report_codes.QDEVICE_CLIENT_RELOAD_STARTED, {}), # why the same error twice? # 1. Tested piece of code calls a function which puts an error # into the reporter. The reporter raises an exception. The # exception is caught in the tested piece of code, stored, and # later put to reporter again. # 2. Mock reporter remembers everything that goes through it # and by the machanism described in 1 the error goes througt it # twice. (severity.ERROR, report_codes.NODE_COMMUNICATION_ERROR_NOT_AUTHORIZED, { "node": nodes[1], "command": "command", "reason": "HTTP error: 401", }, report_codes.SKIP_OFFLINE_NODES), (severity.ERROR, report_codes.NODE_COMMUNICATION_ERROR_NOT_AUTHORIZED, { "node": nodes[1], "command": "command", "reason": "HTTP error: 401", }, report_codes.SKIP_OFFLINE_NODES), ])
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_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_success(self, mock_attrs): lib._set_instance_attrs_all_nodes(create_env(), "attrs", False) self.assertEqual(2, len(mock_attrs.mock_calls)) mock_attrs.assert_has_calls([ mock.call("cib", "node-0", "attrs", self.cluster_nodes), mock.call("cib", "node-1", "attrs", self.cluster_nodes), ])
def test_success(self, assign_role): assign_role.return_value = [] lib.assign_all_roles("acl_section", ["1", "2", "3"], "element") assign_role.assert_has_calls([ mock.call("acl_section", "1", "element"), mock.call("acl_section", "2", "element"), mock.call("acl_section", "3", "element"), ], any_order=True)
def test_prepare( self, validate_operation, validate_value_in, validate_different_intervals, complete_all_intervals, get_remaining_defaults ): validate_operation.side_effect = lambda operation, validator_list: [ operation["name"].normalized #values comes here in ValuePairs ] validate_value_in.return_value = "value_in" validate_different_intervals.return_value = ["different_interval"] report_processor = mock.MagicMock() raw_operation_list = [ {"name": "start"}, {"name": "monitor"}, ] default_operation_list = [ {"name": "stop"}, ] allowed_operation_name_list = ["start", "stop", "monitor"] allow_invalid = True operations.prepare( report_processor, raw_operation_list, default_operation_list, allowed_operation_name_list, allow_invalid, ) validate_value_in.assert_called_once_with( "name", allowed_operation_name_list, option_name_for_report="operation name", code_to_allow_extra_values=report_codes.FORCE_OPTIONS, allow_extra_values=allow_invalid, ) validate_different_intervals.assert_called_once_with(raw_operation_list) report_processor.process_list.assert_called_once_with([ "start", "monitor", "different_interval", ]) validate_operation.assert_has_calls( [ mock.call( {"name": ValuePair("monitor", "monitor")}, ["value_in"] ), mock.call({"name": ValuePair("start", "start")}, ["value_in"]), ], any_order=True ) complete_all_intervals.assert_called_once_with(raw_operation_list)
def test_sucessfully_write_binary(self): self.assert_params_causes_calls( { "content": "filecontent", "is_binary": True }, [ mock.call(FILE_PATH, "wb"), mock.call().write("filecontent"), mock.call().close(), ])
def test_success(self, mock_attrs): lib._set_instance_attrs_node_list(create_env(), "attrs", ["node-1", "node-2"], False) self.assert_context_manager_launched(pre=True, post=True) self.assertEqual(2, len(mock_attrs.mock_calls)) mock_attrs.assert_has_calls([ mock.call("cib", "node-1", "attrs", self.cluster_nodes), mock.call("cib", "node-2", "attrs", self.cluster_nodes), ])
def test_fail_doesnt_prevent_start(self, mock_remote_start, mock_remote_stop): nodes = ["node1", "node2"] node_addrs_list = NodeAddressesList([NodeAddresses(addr) for addr in nodes]) def raiser(reporter, communicator, node): if node.ring0 == nodes[1]: raise NodeAuthenticationException(node.label, "command", "HTTP error: 401") mock_remote_stop.side_effect = raiser assert_raise_library_error( lambda: lib.qdevice_reload_on_nodes(self.mock_communicator, self.mock_reporter, node_addrs_list), ( severity.ERROR, report_codes.NODE_COMMUNICATION_ERROR_NOT_AUTHORIZED, {"node": nodes[1], "command": "command", "reason": "HTTP error: 401"}, report_codes.SKIP_OFFLINE_NODES, ), ) node_calls = [ mock.call(self.mock_reporter, self.mock_communicator, node_addrs_list[0]), mock.call(self.mock_reporter, self.mock_communicator, node_addrs_list[1]), ] self.assertEqual(len(node_calls), len(mock_remote_stop.mock_calls)) self.assertEqual(len(node_calls), len(mock_remote_start.mock_calls)) mock_remote_stop.assert_has_calls(node_calls, any_order=True) mock_remote_start.assert_has_calls(node_calls, any_order=True) assert_report_item_list_equal( self.mock_reporter.report_item_list, [ (severity.INFO, report_codes.QDEVICE_CLIENT_RELOAD_STARTED, {}), # why the same error twice? # 1. Tested piece of code calls a function which puts an error # into the reporter. The reporter raises an exception. The # exception is caught in the tested piece of code, stored, and # later put to reporter again. # 2. Mock reporter remembers everything that goes through it # and by the machanism described in 1 the error goes througt it # twice. ( severity.ERROR, report_codes.NODE_COMMUNICATION_ERROR_NOT_AUTHORIZED, {"node": nodes[1], "command": "command", "reason": "HTTP error: 401"}, report_codes.SKIP_OFFLINE_NODES, ), ( severity.ERROR, report_codes.NODE_COMMUNICATION_ERROR_NOT_AUTHORIZED, {"node": nodes[1], "command": "command", "reason": "HTTP error: 401"}, report_codes.SKIP_OFFLINE_NODES, ), ], )
def test_success(self, mock_attrs): lib._set_instance_attrs_node_list( create_env(), "attrs", ["node-1", "node-2"], False ) self.assert_context_manager_launched(pre=True, post=True) self.assertEqual(2, len(mock_attrs.mock_calls)) mock_attrs.assert_has_calls([ mock.call("cib", "node-1", "attrs", self.cluster_nodes), mock.call("cib", "node-2", "attrs", self.cluster_nodes), ])
def test_one_node_down_forced(self, mock_corosync_live): conf_text = "test conf text" nodes = ["node1", "node2"] node_addrs_list = NodeAddressesList( [NodeAddresses(addr) for addr in nodes]) mock_corosync_live.set_remote_corosync_conf = mock.MagicMock() def raiser(comm, node, conf): if node.ring0 == nodes[1]: raise NodeAuthenticationException(nodes[1], "command", "HTTP error: 401") mock_corosync_live.set_remote_corosync_conf.side_effect = raiser lib.distribute_corosync_conf(self.mock_communicator, self.mock_reporter, node_addrs_list, conf_text, skip_offline_nodes=True) corosync_live_calls = [ mock.call.set_remote_corosync_conf("mock node communicator", nodes[0], conf_text), mock.call.set_remote_corosync_conf("mock node communicator", nodes[1], conf_text), ] self.assertEqual(len(corosync_live_calls), len(mock_corosync_live.mock_calls)) mock_corosync_live.set_remote_corosync_conf.assert_has_calls( [ mock.call("mock node communicator", node_addrs_list[0], conf_text), mock.call("mock node communicator", node_addrs_list[1], conf_text), ], any_order=True) assert_report_item_list_equal(self.mock_reporter.report_item_list, [ (severity.INFO, report_codes.COROSYNC_CONFIG_DISTRIBUTION_STARTED, {}), (severity.INFO, report_codes.COROSYNC_CONFIG_ACCEPTED_BY_NODE, { "node": nodes[0] }), (severity.WARNING, report_codes.NODE_COMMUNICATION_ERROR_NOT_AUTHORIZED, { "node": nodes[1], "command": "command", "reason": "HTTP error: 401", }), (severity.WARNING, report_codes.COROSYNC_CONFIG_DISTRIBUTION_NODE_ERROR, { "node": nodes[1], }), ])
def test_success(self): self.maxDiff = None mock_open = mock.mock_open(read_data="config content") with patch_config_files("open", mock_open, create=True): self.assertEqual("config content", config_files._read_config("my-file.conf")) self.assertEqual([ mock.call(os.path.join(BOOTH_CONFIG_DIR, "my-file.conf"), "r"), mock.call().__enter__(), mock.call().read(), mock.call().__exit__(None, None, None) ], mock_open.mock_calls)
def test_success(self): path = os.path.join(BOOTH_CONFIG_DIR, "file.key") mock_open = mock.mock_open(read_data="key") with patch_config_files("open", mock_open, create=True): self.assertEqual( "key", config_files.read_authfile(self.mock_reporter, path)) self.assertEqual([ mock.call(path, "rb"), mock.call().__enter__(), mock.call().read(), mock.call().__exit__(None, None, None) ], mock_open.mock_calls) self.assertEqual(0, len(self.mock_reporter.report_item_list))
def test_success(self): mock_runner = mock.MagicMock(spec_set=CommandRunner) mock_runner.run.side_effect = [ ( "\n".join([ "ocf", "lsb", "service", "systemd", "nagios", "stonith", "", ]), "", 0 ), ( "\n".join([ "heartbeat", "openstack", "pacemaker", "booth", "", ]), "", 0 ), ] self.assertEqual( lib_ra.list_resource_agents_standards_and_providers(mock_runner), [ "lsb", "nagios", "ocf:booth", "ocf:heartbeat", "ocf:openstack", "ocf:pacemaker", "service", "systemd", ] ) self.assertEqual(2, len(mock_runner.run.mock_calls)) mock_runner.run.assert_has_calls([ mock.call(["/usr/sbin/crm_resource", "--list-standards"]), mock.call(["/usr/sbin/crm_resource", "--list-ocf-providers"]), ])
def test_success(self, mock_func): lib_sbd.remove_stonith_watchdog_timeout_on_all_nodes( self.mock_com, self.node_list ) func_calls = [mock.call(self.mock_com, node) for node in self.node_list] self.assertEqual(mock_func.call_count, len(func_calls)) mock_func.assert_has_calls(func_calls)
def test_create_config(self, mock_real_file, mock_set_keyfile_access): mock_file = mock.MagicMock( assert_no_conflict_with_existing=mock.MagicMock(), write=mock.MagicMock(), ) mock_real_file.return_value = mock_file env.BoothEnv("report processor", env_data={ "name": "booth" }).create_config("a", can_overwrite_existing=True) self.assertEqual(mock_file.assert_no_conflict_with_existing.mock_calls, [ mock.call('report processor', True), ]) self.assertEqual(mock_file.write.mock_calls, [mock.call('a')])
def test_communication_error(self, mock_func): def raiser(_, node): if node == self.node_list[1]: raise NodeConnectionException(self.node_list[1], "command", "reason") elif node == self.node_list[4]: raise NodeCommunicationException(self.node_list[4], "command", "reason") mock_func.side_effect = raiser assert_raise_library_error( lambda: lib_sbd.remove_stonith_watchdog_timeout_on_all_nodes( self.mock_com, self.node_list), (Severities.ERROR, report_codes.NODE_COMMUNICATION_ERROR_UNABLE_TO_CONNECT, { "node": self.node_list[1], "command": "command", "reason": "reason" }), (Severities.ERROR, report_codes.NODE_COMMUNICATION_ERROR, { "node": self.node_list[4], "command": "command", "reason": "reason" })) func_calls = [ mock.call(self.mock_com, node) for node in self.node_list ] self.assertEqual(mock_func.call_count, len(func_calls)) mock_func.assert_has_calls(func_calls)
def test_create_config(self, mock_real_file, mock_set_keyfile_access): mock_file = mock.MagicMock( assert_no_conflict_with_existing=mock.MagicMock(), write=mock.MagicMock(), ) mock_real_file.return_value = mock_file env.BoothEnv( "report processor", env_data={"name": "booth"} ).create_config("a", can_overwrite_existing=True) self.assertEqual(mock_file.assert_no_conflict_with_existing.mock_calls,[ mock.call('report processor', True), ]) self.assertEqual(mock_file.write.mock_calls, [mock.call('a')])
def test_remove_ip_when_is_only_booth_sibling_in_group(self): group = etree.fromstring(''' <group> <primitive id="ip" type="IPaddr2"/> <primitive id="booth" type="booth-site"> <instance_attributes> <nvpair name="config" value="/PATH/TO/CONF"/> </instance_attributes> </primitive> </group> ''') mock_resource_remove = self.call(self.find_booth_resources(group)) self.assertEqual(mock_resource_remove.mock_calls, [ mock.call('ip'), mock.call('booth'), ])
def test_success(self): self.maxDiff = None mock_open = mock.mock_open(read_data="config content") with patch_config_files("open", mock_open, create=True): self.assertEqual( "config content", config_files._read_config("my-file.conf") ) self.assertEqual( [ mock.call(os.path.join(BOOTH_CONFIG_DIR, "my-file.conf"), "r"), mock.call().__enter__(), mock.call().read(), mock.call().__exit__(None, None, None) ], mock_open.mock_calls )
def test_unstandby_all(self): nodes = ("node1", "node2", "node3") for i, n in enumerate(nodes, 1): self.fixture_add_node_status(self.fixture_get_node_status(n, i)) mock_runner = mock.MagicMock(spec_set=CommandRunner) call_list = [mock.call(self.crm_mon_cmd())] call_list += [ mock.call([self.path("crm_standby"), "-D", "-N", n]) for n in nodes ] return_value_list = [(str(self.status), "", 0)] return_value_list += [("dummy", "", 0) for n in nodes] mock_runner.run.side_effect = return_value_list output = lib.nodes_unstandby(mock_runner, all_nodes=True) self.assertEqual(len(return_value_list), len(call_list)) self.assertEqual(len(return_value_list), mock_runner.run.call_count) mock_runner.run.assert_has_calls(call_list) self.assertEqual(None, output)
def test_failure(self, mock_role, mock_assign): def _mock_role(_, el_id): if el_id in ["role1", "role3"]: raise acl_lib.AclRoleNotFound(el_id) elif el_id == "role2": return "role2_el" else: raise AssertionError("unexpected input") mock_role.side_effect = _mock_role assert_raise_library_error( lambda: cmd_acl._assign_roles_to_element(self.cib, "el", ["role1", "role2", "role3"]), (Severities.ERROR, report_codes.ID_NOT_FOUND, {"id": "role1", "id_description": "role"}), (Severities.ERROR, report_codes.ID_NOT_FOUND, {"id": "role3", "id_description": "role"}), ) mock_role.assert_has_calls( [mock.call(self.cib, "role1"), mock.call(self.cib, "role2"), mock.call(self.cib, "role3")] ) mock_assign.assert_called_once_with("el", "role2_el")
def test_success(self): path = os.path.join(BOOTH_CONFIG_DIR, "file.key") mock_open = mock.mock_open(read_data="key") with patch_config_files("open", mock_open, create=True): self.assertEqual( "key", config_files.read_authfile(self.mock_reporter, path) ) self.assertEqual( [ mock.call(path, "rb"), mock.call().__enter__(), mock.call().read(), mock.call().__exit__(None, None, None) ], mock_open.mock_calls ) self.assertEqual(0, len(self.mock_reporter.report_item_list))
def test_remove_ip_when_is_only_booth_sibling_in_group(self): group = etree.fromstring(''' <group> <primitive id="ip" type="IPaddr2"/> <primitive id="booth" type="booth-site"> <instance_attributes> <nvpair name="config" value="/PATH/TO/CONF"/> </instance_attributes> </primitive> </group> ''') mock_resource_remove = self.call(group.getchildren()[1:]) self.assertEqual( mock_resource_remove.mock_calls, [ mock.call('ip'), mock.call('booth'), ] )
def test_error_some_nodes(self): nodes = ("node1", "node2", "node3", "node4") for i, n in enumerate(nodes, 1): self.fixture_add_node_status( self.fixture_get_node_status(n, i) ) mock_runner = mock.MagicMock(spec_set=CommandRunner) call_list = [mock.call(self.crm_mon_cmd())] call_list += [ mock.call([self.path("crm_standby"), "-v", "on", "-N", n]) for n in nodes ] return_value_list = [ (str(self.status), "", 0), ("dummy1", "", 0), ("dummy2", "error2", 1), ("dummy3", "", 0), ("dummy4", "error4", 1), ] mock_runner.run.side_effect = return_value_list assert_raise_library_error( lambda: lib.nodes_standby(mock_runner, all_nodes=True), ( Severity.ERROR, report_codes.COMMON_ERROR, { "text": "error2\ndummy2", } ), ( Severity.ERROR, report_codes.COMMON_ERROR, { "text": "error4\ndummy4", } ) ) self.assertEqual(len(return_value_list), len(call_list)) self.assertEqual(len(return_value_list), mock_runner.run.call_count) mock_runner.run.assert_has_calls(call_list)
def test_one_node_down_forced(self, mock_corosync_live): conf_text = "test conf text" nodes = ["node1", "node2"] node_addrs_list = NodeAddressesList([NodeAddresses(addr) for addr in nodes]) mock_corosync_live.set_remote_corosync_conf = mock.MagicMock() def raiser(comm, node, conf): if node.ring0 == nodes[1]: raise NodeAuthenticationException(nodes[1], "command", "HTTP error: 401") mock_corosync_live.set_remote_corosync_conf.side_effect = raiser lib.distribute_corosync_conf( self.mock_communicator, self.mock_reporter, node_addrs_list, conf_text, skip_offline_nodes=True ) corosync_live_calls = [ mock.call.set_remote_corosync_conf("mock node communicator", nodes[0], conf_text), mock.call.set_remote_corosync_conf("mock node communicator", nodes[1], conf_text), ] self.assertEqual(len(corosync_live_calls), len(mock_corosync_live.mock_calls)) mock_corosync_live.set_remote_corosync_conf.assert_has_calls( [ mock.call("mock node communicator", node_addrs_list[0], conf_text), mock.call("mock node communicator", node_addrs_list[1], conf_text), ], any_order=True, ) assert_report_item_list_equal( self.mock_reporter.report_item_list, [ (severity.INFO, report_codes.COROSYNC_CONFIG_DISTRIBUTION_STARTED, {}), (severity.INFO, report_codes.COROSYNC_CONFIG_ACCEPTED_BY_NODE, {"node": nodes[0]}), ( severity.WARNING, report_codes.NODE_COMMUNICATION_ERROR_NOT_AUTHORIZED, {"node": nodes[1], "command": "command", "reason": "HTTP error: 401"}, ), (severity.WARNING, report_codes.COROSYNC_CONFIG_DISTRIBUTION_NODE_ERROR, {"node": nodes[1]}), ], )
def test_success(self, mock_create_handle, _, mock_con_successful, mock_con_failure): com = self.get_multiaddress_communicator() counter = {"counter": 0} expected_response_list = [] def _con_successful(handle): response = lib.Response(handle, True) expected_response_list.append(response) return response def _con_failure(handle, errno, err_msg): response = lib.Response(handle, False, errno, err_msg) expected_response_list.append(response) return response def _mock_create_request_handle(request, _, __): counter["counter"] += 1 return (MockCurl( request=request) if counter["counter"] > 2 else MockCurl( error=(pycurl.E_SEND_ERROR, "reason"), request=request, )) mock_con_successful.side_effect = _con_successful mock_con_failure.side_effect = _con_failure mock_create_handle.side_effect = _mock_create_request_handle request = lib.Request( lib.RequestTarget("label", ["host{0}".format(i) for i in range(4)]), lib.RequestData("action")) com.add_requests([request]) response_list = list(com.start_loop()) self.assertEqual(1, len(response_list)) response = response_list[0] self.assertIs(response, expected_response_list[-1]) self.assertTrue(response.was_connected) self.assertIs(request, response.request) self.assertEqual("host2", request.host) self.assertEqual(3, mock_create_handle.call_count) self.assertEqual(3, len(expected_response_list)) mock_create_handle.assert_has_calls([ mock.call(request, {}, settings.default_request_timeout) for _ in range(3) ]) logger_calls = (fixture_logger_request_retry_calls( expected_response_list[0], "host0") + fixture_logger_request_retry_calls( expected_response_list[1], "host1") + [ mock.call.log_request_start(request), mock.call.log_response(response), ]) self.assertEqual(logger_calls, self.mock_com_log.mock_calls) com._multi_handle.assert_no_handle_left()
def test_basic(self): expected_stdout = "expected output" expected_stderr = "expected stderr" mock_runner = mock.MagicMock(spec_set=CommandRunner) call_list = [ mock.call(self.crm_mon_cmd()), mock.call([self.path("crm_resource"), "--cleanup"]), ] return_value_list = [ (self.fixture_status_xml(1, 1), "", 0), (expected_stdout, expected_stderr, 0), ] mock_runner.run.side_effect = return_value_list real_output = lib.resource_cleanup(mock_runner) self.assertEqual(len(return_value_list), len(call_list)) self.assertEqual(len(return_value_list), mock_runner.run.call_count) mock_runner.run.assert_has_calls(call_list) self.assertEqual(expected_stdout + "\n" + expected_stderr, real_output)
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"), ])
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" ), ])
def test_skip_failed(self, mock_get_configs, mock_read): def _mock_read_cfg(file): if file in ["name1.conf", "name3.conf"]: raise EnvironmentError() elif file == "name2.conf": return "config2" else: raise AssertionError("unexpected input: {0}".format(file)) mock_get_configs.return_value = [ "name1.conf", "name2.conf", "name3.conf" ] mock_read.side_effect = _mock_read_cfg self.assertEqual( {"name2.conf": "config2"}, config_files.read_configs(self.mock_reporter, True) ) mock_get_configs.assert_called_once_with() self.assertEqual(3, mock_read.call_count) mock_read.assert_has_calls([ mock.call("name1.conf"), mock.call("name2.conf"), mock.call("name3.conf") ]) assert_report_item_list_equal( self.mock_reporter.report_item_list, [ ( severities.WARNING, report_codes.BOOTH_CONFIG_READ_ERROR, {"name": "name1.conf"} ), ( severities.WARNING, report_codes.BOOTH_CONFIG_READ_ERROR, {"name": "name3.conf"} ) ] )
def test_unstandby_nodes(self): nodes = ("node1", "node2", "node3") for i, n in enumerate(nodes, 1): self.fixture_add_node_status( self.fixture_get_node_status(n, i) ) mock_runner = mock.MagicMock(spec_set=CommandRunner) call_list = [mock.call(self.crm_mon_cmd())] call_list += [ mock.call([self.path("crm_standby"), "-D", "-N", n]) for n in nodes[:2] ] return_value_list = [(str(self.status), "", 0)] return_value_list += [("dummy", "", 0) for n in nodes[:2]] mock_runner.run.side_effect = return_value_list output = lib.nodes_unstandby(mock_runner, node_list=nodes[:2]) self.assertEqual(len(return_value_list), len(call_list)) self.assertEqual(len(return_value_list), mock_runner.run.call_count) mock_runner.run.assert_has_calls(call_list) self.assertEqual(None, output)
def test_remove_ip_when_group_is_disabled(self): group = etree.fromstring(''' <group> <primitive id="ip" type="IPaddr2"/> <primitive id="booth" type="booth-site"> <instance_attributes> <nvpair name="config" value="/PATH/TO/CONF"/> </instance_attributes> </primitive> <meta_attributes> <nvpair name="target-role" value="Stopped"/> </meta_attributes> </group> ''') mock_resource_remove = self.call(self.find_booth_resources(group)) self.assertEqual( mock_resource_remove.mock_calls, [ mock.call('ip'), mock.call('booth'), ] )
def test_put_duplicate_constraint_when_duplication_allowed(self): self.create() self.create(duplication_alowed=True) expected_calls = [ mock.call(self.cib), mock.call(self.cib), ] self.assertEqual(self.env.push_cib.call_count, len(expected_calls)) self.env.push_cib.assert_has_calls(expected_calls) constraint_section = self.independent_cib.find(".//constraints") constraint_section.append(etree.XML(""" <rsc_some id="some_id" symmetrical="true"> <resource_set id="pcs_rsc_set_A_B" role="Master"> <resource_ref id="A"></resource_ref> <resource_ref id="B"></resource_ref> </resource_set> <resource_set action="start" id="pcs_rsc_set_E_F"> <resource_ref id="E"></resource_ref> <resource_ref id="F"></resource_ref> </resource_set> </rsc_some> """)) constraint_section.append(etree.XML(""" <rsc_some id="some_id" symmetrical="true"> <resource_set id="pcs_rsc_set_A_B-1" role="Master"> <resource_ref id="A"></resource_ref> <resource_ref id="B"></resource_ref> </resource_set> <resource_set action="start" id="pcs_rsc_set_E_F-1"> <resource_ref id="E"></resource_ref> <resource_ref id="F"></resource_ref> </resource_set> </rsc_some> """)) assert_xml_equal( etree.tostring(self.independent_cib).decode(), etree.tostring(self.cib).decode() )
def test_basic(self): expected_stdout = "expected output" expected_stderr = "expected stderr" mock_runner = mock.MagicMock(spec_set=CommandRunner) call_list = [ mock.call(self.crm_mon_cmd()), mock.call([self.path("crm_resource"), "--cleanup"]), ] return_value_list = [ (self.fixture_status_xml(1, 1), "", 0), (expected_stdout, expected_stderr, 0), ] mock_runner.run.side_effect = return_value_list real_output = lib.resource_cleanup(mock_runner) self.assertEqual(len(return_value_list), len(call_list)) self.assertEqual(len(return_value_list), mock_runner.run.call_count) mock_runner.run.assert_has_calls(call_list) self.assertEqual( expected_stdout + "\n" + expected_stderr, real_output )
def test_do_not_skip_failed(self, mock_get_configs, mock_read): def _mock_read_cfg(file): if file in ["name1.conf", "name3.conf"]: raise EnvironmentError() elif file == "name2.conf": return "config2" else: raise AssertionError("unexpected input: {0}".format(file)) mock_get_configs.return_value = [ "name1.conf", "name2.conf", "name3.conf" ] mock_read.side_effect = _mock_read_cfg assert_raise_library_error( lambda: config_files.read_configs(self.mock_reporter), ( severities.ERROR, report_codes.BOOTH_CONFIG_READ_ERROR, {"name": "name1.conf"}, report_codes.SKIP_UNREADABLE_CONFIG ), ( severities.ERROR, report_codes.BOOTH_CONFIG_READ_ERROR, {"name": "name3.conf"}, report_codes.SKIP_UNREADABLE_CONFIG ) ) mock_get_configs.assert_called_once_with() self.assertEqual(3, mock_read.call_count) mock_read.assert_has_calls([ mock.call("name1.conf"), mock.call("name2.conf"), mock.call("name3.conf") ]) self.assertEqual(2, len(self.mock_reporter.report_item_list))
def test_success(self, mock_role, mock_assign): mock_role.side_effect = lambda _, el_id: "{0}_el".format(el_id) cmd_acl._assign_roles_to_element(self.cib, "el", ["role1", "role2", "role3"]) mock_role.assert_has_calls( [mock.call(self.cib, "role1"), mock.call(self.cib, "role2"), mock.call(self.cib, "role3")] ) mock_assign.assert_has_calls( [mock.call("el", "role1_el"), mock.call("el", "role2_el"), mock.call("el", "role3_el")] )
def test_dont_remove_ip_when_group_has_other_resources(self): group = etree.fromstring(''' <group> <primitive id="ip" type="IPaddr2"/> <primitive id="booth" type="booth-site"> <instance_attributes> <nvpair name="config" value="/PATH/TO/CONF"/> </instance_attributes> </primitive> <primitive id="dummy" type="Dummy"/> </group> ''') mock_resource_remove = self.call(self.find_booth_resources(group)) self.assertEqual( mock_resource_remove.mock_calls, [ mock.call('booth'), ] )