From ef70cfe84565a018f121c716a97224316f604839 Mon Sep 17 00:00:00 2001 From: xin liang Date: Tue, 21 Nov 2023 10:19:03 +0800 Subject: [PATCH 1/2] Dev: workflows: Enable unit test for the master branch --- .github/workflows/crmsh-ci.yml | 3 +-- tox.ini | 7 ++++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/crmsh-ci.yml b/.github/workflows/crmsh-ci.yml index 059f9eaae8..5ef2b0b410 100644 --- a/.github/workflows/crmsh-ci.yml +++ b/.github/workflows/crmsh-ci.yml @@ -32,10 +32,9 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - python-version: ['3.10'] + python-version: ['3.10', '3.11'] fail-fast: false timeout-minutes: 5 - if: ${{ false }} steps: - uses: actions/checkout@v3 - name: Set up Python diff --git a/tox.ini b/tox.ini index 01de1acb7d..1d3a0fdc55 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ # content of: tox.ini , put in same dir as setup.py [tox] -envlist = py310 +envlist = py310, py311 skip_missing_interpreters = true [base] @@ -19,3 +19,8 @@ commands = {[base]commands} changedir = {[base]changedir} deps = {[base]deps} commands = {[base]commands} + +[testenv:3.11] +changedir = {[base]changedir} +deps = {[base]deps} +commands = {[base]commands} From 7e55d81a17223ed27d153b1478156180acf9dc63 Mon Sep 17 00:00:00 2001 From: xin liang Date: Tue, 21 Nov 2023 10:27:54 +0800 Subject: [PATCH 2/2] Dev: unittest: Adjust unit test cases --- test/unittests/test_bootstrap.py | 135 ++++++++++------- test/unittests/test_corosync.py | 238 +----------------------------- test/unittests/test_qdevice.py | 124 +++++----------- test/unittests/test_sbd.py | 4 +- test/unittests/test_ui_cluster.py | 4 +- test/unittests/test_utils.py | 56 ++----- 6 files changed, 139 insertions(+), 422 deletions(-) diff --git a/test/unittests/test_bootstrap.py b/test/unittests/test_bootstrap.py index 00717518d6..1718192848 100644 --- a/test/unittests/test_bootstrap.py +++ b/test/unittests/test_bootstrap.py @@ -58,6 +58,42 @@ def tearDownClass(cls): Global tearDown. """ + @mock.patch('crmsh.bootstrap.Validation.valid_admin_ip') + @mock.patch('crmsh.utils.fatal') + def test_validate_network_options_one_link(self, mock_error, valid_ip): + self.ctx_inst.admin_ip = "10.10.10.123" + self.ctx_inst.type = "init" + self.ctx_inst.transport = "udpu" + self.ctx_inst.nic_addr_list = ["eth1", "eth2"] + mock_error.side_effect = SystemExit + with self.assertRaises(SystemExit): + self.ctx_inst._validate_network_options() + mock_error.assert_called_once_with("Only one link is allowed for the 'udpu' transport type") + + @mock.patch('crmsh.utils.fatal') + def test_validate_network_options_max_link(self, mock_error): + self.ctx_inst.admin_ip = None + self.ctx_inst.type = "init" + self.ctx_inst.transport = "knet" + self.ctx_inst.nic_addr_list = [f"eth{x}" for x in range(10)] + mock_error.side_effect = SystemExit + with self.assertRaises(SystemExit): + self.ctx_inst._validate_network_options() + mock_error.assert_called_once_with("Maximum number of interfaces is 8") + + @mock.patch('crmsh.utils.detect_cloud') + @mock.patch('crmsh.utils.fatal') + def test_validate_network_options_udp_cloud(self, mock_error, mock_cloud): + mock_cloud.return_value = "aws" + self.ctx_inst.admin_ip = None + self.ctx_inst.type = "init" + self.ctx_inst.transport = "udp" + self.ctx_inst.nic_addr_list = ["eth1"] + mock_error.side_effect = SystemExit + with self.assertRaises(SystemExit): + self.ctx_inst._validate_network_options() + mock_error.assert_called_once_with("Transport udp(multicast) cannot be used in aws platform") + @mock.patch('crmsh.bootstrap.Context.initialize_user') def test_set_context(self, mock_initialize_user: mock.MagicMock): options = mock.Mock(yes_to_all=True, ipv6=False) @@ -135,15 +171,6 @@ def test_validate_sbd_option_error_sbd_stage(self, mock_active, mock_check_all): mock_active.assert_called_once_with("sbd.service") mock_check_all.assert_called_once_with() - @mock.patch('crmsh.utils.fatal') - def test_validate_option_error_nic_number(self, mock_error): - mock_error.side_effect = SystemExit - ctx = crmsh.bootstrap.Context() - ctx.nic_list = ["eth1", "eth2", "eth3"] - with self.assertRaises(SystemExit): - ctx.validate_option() - mock_error.assert_called_once_with("Maximum number of interface is 2") - @mock.patch('crmsh.utils.fatal') @mock.patch('socket.gethostbyname') @mock.patch('crmsh.utils.InterfacesInfo.ip_in_local') @@ -564,14 +591,15 @@ def test_join_ssh_no_seed_host(self, mock_error): bootstrap.join_ssh(None, None) mock_error.assert_called_once_with("No existing IP/hostname specified (use -c option)") + @mock.patch('crmsh.utils.HostUserConfig') @mock.patch('crmsh.bootstrap.change_user_shell') @mock.patch('crmsh.utils.su_get_stdout_or_raise_error') @mock.patch('crmsh.bootstrap.swap_public_ssh_key') @mock.patch('crmsh.utils.ssh_copy_id_no_raise') @mock.patch('crmsh.bootstrap.configure_ssh_key') @mock.patch('crmsh.utils.start_service') - def test_join_ssh(self, mock_start_service, mock_config_ssh, mock_ssh_copy_id, mock_swap, mock_invoke, mock_change): - bootstrap._context = mock.Mock(current_user="bob", user_list=["alice"], node_list=['node1'], default_nic_list=["eth1"]) + def test_join_ssh(self, mock_start_service, mock_config_ssh, mock_ssh_copy_id, mock_swap, mock_invoke, mock_change, mock_user_config): + bootstrap._context = mock.Mock(current_user="bob", user_list=["alice"], node_list=['node1'], default_nic="eth1") mock_invoke.return_value = '' mock_swap.return_value = None mock_ssh_copy_id.return_value = 0 @@ -653,7 +681,8 @@ def test_bootstrap_add_return(self, mock_this_node): @mock.patch('logging.Logger.info') @mock.patch('crmsh.utils.this_node') def test_bootstrap_add(self, mock_this_node, mock_info, mock_run): - ctx = mock.Mock(current_user="alice", user_at_node_list=["bob@node2", "carol@node3"], nic_list=["eth1"]) + mock_interface_inst = mock.Mock(input_nic_list=["eth1"]) + ctx = mock.Mock(current_user="alice", user_at_node_list=["bob@node2", "carol@node3"], interfaces_inst=mock_interface_inst) mock_this_node.return_value = "node1" bootstrap.bootstrap_add(ctx) mock_info.assert_has_calls([ @@ -837,6 +866,8 @@ def test_is_online_on_init_node(self, mock_is_online, mock_get_hostname, mock_th mock_get_hostname.assert_not_called() mock_is_online.assert_called_once_with("node1") + @mock.patch('crmsh.bootstrap._parse_user_at_host') + @mock.patch('crmsh.utils.get_stdout_or_raise_error') @mock.patch('crmsh.utils.fatal') @mock.patch('crmsh.utils.stop_service') @mock.patch('crmsh.bootstrap.sync_file') @@ -846,7 +877,9 @@ def test_is_online_on_init_node(self, mock_is_online, mock_get_hostname, mock_th @mock.patch('crmsh.bootstrap.get_node_canonical_hostname') @mock.patch('crmsh.xmlutil.CrmMonXmlParser.is_node_online') def test_is_online_peer_offline(self, mock_is_online, mock_get_hostname, mock_this_node, - mock_copy, mock_corosync_conf, mock_csync2, mock_stop_service, mock_error): + mock_copy, mock_corosync_conf, mock_csync2, mock_stop_service, mock_error, + mock_run, mock_parse_user): + mock_parse_user.return_value = ('root', "node1") bootstrap._context = mock.Mock(cluster_node='node1') mock_is_online.side_effect = [True, False] bootstrap.COROSYNC_CONF_ORIG = "/tmp/crmsh_tmpfile" @@ -918,18 +951,22 @@ def test_csync2_update(self, mock_invoke, mock_invokerc, mock_warn): mock_warn.assert_called_once_with("/etc/corosync.conf was not synced") @mock.patch('crmsh.utils.InterfacesInfo') - def test_init_network(self, mock_interfaces): - mock_interfaces_inst = mock.Mock() - mock_interfaces.return_value = mock_interfaces_inst - mock_interfaces_inst.get_default_nic_list_from_route.return_value = ["eth0", "eth1"] - bootstrap._context = mock.Mock(ipv6=False, second_heartbeat=False, nic_list=["eth0", "eth1"], default_nic_list=["eth0", "eth1"]) + def test_init_network_input_nic_list(self, mock_interface_info): + bootstrap._context = mock.Mock(ipv6=None, nic_addr_list=["eth1", "eth2"]) + mock_interface_info_inst = mock.Mock() + mock_interface_info.return_value = mock_interface_info_inst + mock_interface_info_inst.input_nic_list = ["eth1", "eth2"] + mock_interface_info_inst.input_addr_list = ["10.10.10.1", "20.20.20.1"] bootstrap.init_network() - mock_interfaces.assert_called_once_with(False, False, bootstrap._context.nic_list) - mock_interfaces_inst.get_interfaces_info.assert_called_once_with() - mock_interfaces_inst.get_default_nic_list_from_route.assert_called_once_with() - mock_interfaces_inst.get_default_ip_list.assert_called_once_with() + self.assertEqual(bootstrap._context.default_nic, "eth1") + self.assertEqual(bootstrap._context.default_ip_list, mock_interface_info_inst.input_addr_list) + + @mock.patch('crmsh.utils.InterfacesInfo') + def test_init_network_input(self, mock_interface_info): + bootstrap._context = mock.Mock(ipv6=None, nic_addr_list=[]) + bootstrap.init_network() @mock.patch('crmsh.utils.disable_service') @mock.patch('logging.Logger.info') @@ -973,7 +1010,7 @@ def test_init_qdevice_copy_ssh_key_failed( @mock.patch('crmsh.utils.UserOfHost.instance') @mock.patch('crmsh.utils.list_cluster_nodes') @mock.patch('crmsh.bootstrap.confirm') - @mock.patch('crmsh.utils.is_qdevice_configured') + @mock.patch('crmsh.corosync.is_qdevice_configured') @mock.patch('crmsh.bootstrap.configure_ssh_key') @mock.patch('crmsh.utils.check_ssh_passwd_need') @mock.patch('logging.Logger.info') @@ -1008,7 +1045,7 @@ def test_init_qdevice_already_configured( @mock.patch('crmsh.bootstrap.adjust_priority_in_rsc_defaults') @mock.patch('crmsh.utils.list_cluster_nodes') @mock.patch('crmsh.utils.this_node') - @mock.patch('crmsh.utils.is_qdevice_configured') + @mock.patch('crmsh.corosync.is_qdevice_configured') @mock.patch('crmsh.bootstrap.configure_ssh_key') @mock.patch('crmsh.utils.check_ssh_passwd_need') @mock.patch('logging.Logger.info') @@ -1125,7 +1162,7 @@ def test_configure_qdevice_interactive(self, mock_confirm, mock_info, mock_insta mock_qdevice.assert_called_once_with('qnetd-node', port=5403, ssh_user='alice', algo='ffsplit', tie_breaker='lowest', tls='on', cmds=None, mode=None, is_stage=False) @mock.patch('crmsh.utils.fatal') - @mock.patch('crmsh.utils.is_qdevice_configured') + @mock.patch('crmsh.corosync.is_qdevice_configured') def test_remove_qdevice_no_configured(self, mock_qdevice_configured, mock_error): mock_qdevice_configured.return_value = False mock_error.side_effect = SystemExit @@ -1137,7 +1174,7 @@ def test_remove_qdevice_no_configured(self, mock_qdevice_configured, mock_error) mock_error.assert_called_once_with("No QDevice configuration in this cluster") @mock.patch('crmsh.bootstrap.confirm') - @mock.patch('crmsh.utils.is_qdevice_configured') + @mock.patch('crmsh.corosync.is_qdevice_configured') def test_remove_qdevice_not_confirmed(self, mock_qdevice_configured, mock_confirm): mock_qdevice_configured.return_value = True mock_confirm.return_value = False @@ -1147,21 +1184,21 @@ def test_remove_qdevice_not_confirmed(self, mock_qdevice_configured, mock_confir mock_qdevice_configured.assert_called_once_with() mock_confirm.assert_called_once_with("Removing QDevice service and configuration from cluster: Are you sure?") - @mock.patch('crmsh.bootstrap.adjust_priority_fencing_delay') - @mock.patch('crmsh.bootstrap.adjust_priority_in_rsc_defaults') + @mock.patch('crmsh.corosync.configure_two_node') + @mock.patch('crmsh.bootstrap.sync_file') + @mock.patch('crmsh.bootstrap.adjust_properties') @mock.patch('crmsh.qdevice.QDevice.remove_certification_files_on_qnetd') @mock.patch('crmsh.qdevice.QDevice.remove_qdevice_db') @mock.patch('crmsh.qdevice.QDevice.remove_qdevice_config') - @mock.patch('crmsh.bootstrap.update_expected_votes') @mock.patch('crmsh.log.LoggerUtils.status_long') @mock.patch('crmsh.bootstrap.invoke') @mock.patch('logging.Logger.info') @mock.patch('crmsh.qdevice.evaluate_qdevice_quorum_effect') @mock.patch('crmsh.utils.check_all_nodes_reachable') @mock.patch('crmsh.bootstrap.confirm') - @mock.patch('crmsh.utils.is_qdevice_configured') + @mock.patch('crmsh.corosync.is_qdevice_configured') def test_remove_qdevice_reload(self, mock_qdevice_configured, mock_confirm, mock_reachable, mock_evaluate, - mock_status, mock_invoke, mock_status_long, mock_update_votes, mock_remove_config, mock_remove_db, mock_remove_files, mock_adjust_priority, mock_adjust_fence_delay): + mock_status, mock_invoke, mock_status_long, mock_remove_config, mock_remove_db, mock_remove_files, mock_adjust, mock_sync, mock_configure_two_node): mock_qdevice_configured.return_value = True mock_confirm.return_value = True mock_evaluate.return_value = qdevice.QdevicePolicy.QDEVICE_RELOAD @@ -1182,26 +1219,16 @@ def test_remove_qdevice_reload(self, mock_qdevice_configured, mock_confirm, mock mock.call("crm cluster run 'crm corosync reload'") ] ) mock_status_long.assert_called_once_with("Removing QDevice configuration from cluster") - mock_update_votes.assert_called_once_with() mock_remove_config.assert_called_once_with() mock_remove_db.assert_called_once_with() @mock.patch('crmsh.utils.start_service') @mock.patch('crmsh.qdevice.QDevice') @mock.patch('crmsh.corosync.get_value') - @mock.patch('crmsh.utils.is_qdevice_tls_on') - @mock.patch('crmsh.bootstrap.invoke') - @mock.patch('crmsh.bootstrap.sync_file') - @mock.patch('crmsh.corosync.conf') - @mock.patch('crmsh.corosync.add_nodelist_from_cmaptool') - @mock.patch('crmsh.corosync.is_unicast') + @mock.patch('crmsh.corosync.is_qdevice_tls_on') @mock.patch('crmsh.log.LoggerUtils.status_long') - def test_start_qdevice_on_join_node(self, mock_status_long, mock_is_unicast, mock_add_nodelist, - mock_conf, mock_csync2_update, mock_invoke, mock_qdevice_tls, - mock_get_value, mock_qdevice, mock_start_service): - mock_is_unicast.return_value = False + def test_start_qdevice_on_join_node(self, mock_status_long, mock_qdevice_tls, mock_get_value, mock_qdevice, mock_start_service): mock_qdevice_tls.return_value = True - mock_conf.return_value = "corosync.conf" mock_get_value.return_value = "10.10.10.123" mock_qdevice_inst = mock.Mock() mock_qdevice.return_value = mock_qdevice_inst @@ -1210,11 +1237,6 @@ def test_start_qdevice_on_join_node(self, mock_status_long, mock_is_unicast, moc bootstrap.start_qdevice_on_join_node("node2") mock_status_long.assert_called_once_with("Starting corosync-qdevice.service") - mock_is_unicast.assert_called_once_with() - mock_add_nodelist.assert_called_once_with() - mock_conf.assert_called_once_with() - mock_csync2_update.assert_called_once_with("corosync.conf") - mock_invoke.assert_called_once_with("crm corosync reload") mock_qdevice_tls.assert_called_once_with() mock_get_value.assert_called_once_with("quorum.device.net.host") mock_qdevice.assert_called_once_with("10.10.10.123", cluster_node="node2") @@ -1404,14 +1426,15 @@ def test_valid_mcast_address(self, mock_mcast): @mock.patch('crmsh.bootstrap.Validation._is_local_addr') def test_valid_ucast_ip(self, mock_local_addr): - bootstrap._context = mock.Mock(local_ip_list=["10.10.10.2", "10.10.10.3"]) + interfaces_inst = mock.Mock(ip_list=["10.10.10.2", "10.10.10.3"]) + bootstrap._context = mock.Mock(interfaces_inst=interfaces_inst) bootstrap.Validation.valid_ucast_ip("10.10.10.1") mock_local_addr.assert_called_once_with(["10.10.10.2", "10.10.10.3"]) - + @mock.patch('crmsh.bootstrap.Validation._is_local_addr') def test_valid_mcast_ip(self, mock_local_addr): - bootstrap._context = mock.Mock(local_ip_list=["10.10.10.2", "10.10.10.3"], - local_network_list=["10.10.10.0"]) + interfaces_inst = mock.Mock(ip_list=["10.10.10.2", "10.10.10.3"], network_list=["10.10.10.0"]) + bootstrap._context = mock.Mock(interfaces_inst=interfaces_inst) bootstrap.Validation.valid_mcast_ip("10.10.10.1") mock_local_addr.assert_called_once_with(["10.10.10.2", "10.10.10.3", "10.10.10.0"]) @@ -1803,10 +1826,9 @@ def test_remove_node_from_cluster_rm_csync_failed(self, mock_get_ip, mock_stop, @mock.patch.object(NodeMgmt, 'call_delnode') @mock.patch('crmsh.bootstrap.rm_configuration_files') - @mock.patch('crmsh.bootstrap.adjust_priority_fencing_delay') - @mock.patch('crmsh.bootstrap.adjust_priority_in_rsc_defaults') + @mock.patch('crmsh.corosync.configure_two_node') + @mock.patch('crmsh.bootstrap.adjust_properties') @mock.patch('crmsh.bootstrap.sync_file') - @mock.patch('crmsh.bootstrap.decrease_expected_votes') @mock.patch('crmsh.corosync.del_node') @mock.patch('crmsh.corosync.get_values') @mock.patch('crmsh.utils.fatal') @@ -1816,7 +1838,7 @@ def test_remove_node_from_cluster_rm_csync_failed(self, mock_get_ip, mock_stop, @mock.patch('crmsh.bootstrap.stop_services') @mock.patch('crmsh.bootstrap.get_cluster_node_ip') def test_remove_node_from_cluster_hostname(self, mock_get_ip, mock_stop, mock_status, - mock_invoke, mock_invokerc, mock_error, mock_get_values, mock_del, mock_decrease, mock_csync2, mock_adjust_priority, mock_adjust_fence_delay, mock_rm_conf_files, mock_cal_delnode): + mock_invoke, mock_invokerc, mock_error, mock_get_values, mock_del, mock_csync2, mock_adjust_priority, mock_configure_two_node, mock_rm_conf_files, mock_cal_delnode): mock_get_ip.return_value = "10.10.10.1" mock_cal_delnode.return_value = True mock_invoke.side_effect = [(True, None, None)] @@ -1840,7 +1862,6 @@ def test_remove_node_from_cluster_hostname(self, mock_get_ip, mock_stop, mock_st mock_error.assert_not_called() mock_get_values.assert_called_once_with("nodelist.node.ring0_addr") mock_del.assert_called_once_with("10.10.10.1") - mock_decrease.assert_called_once_with() mock_csync2.assert_has_calls([ mock.call(bootstrap.CSYNC2_CFG), mock.call("/etc/corosync/corosync.conf") diff --git a/test/unittests/test_corosync.py b/test/unittests/test_corosync.py index 6961e52d98..8052b7fe90 100644 --- a/test/unittests/test_corosync.py +++ b/test/unittests/test_corosync.py @@ -12,7 +12,6 @@ import pytest from unittest import mock from crmsh import corosync -from crmsh.corosync import Parser, make_section, make_value F1 = open(os.path.join(os.path.dirname(__file__), 'corosync.conf.1')).read() @@ -53,7 +52,7 @@ def test_query_status(mock_ring_status): mock_ring_status.assert_called_once_with() -@mock.patch('crmsh.utils.is_qdevice_configured') +@mock.patch('crmsh.corosync.is_qdevice_configured') def test_query_qdevice_status_exception(mock_configured): mock_configured.return_value = False with pytest.raises(ValueError) as err: @@ -64,7 +63,7 @@ def test_query_qdevice_status_exception(mock_configured): @mock.patch('crmsh.utils.print_cluster_nodes') @mock.patch('crmsh.utils.get_stdout_or_raise_error') -@mock.patch('crmsh.utils.is_qdevice_configured') +@mock.patch('crmsh.corosync.is_qdevice_configured') def test_query_qdevice_status(mock_configured, mock_run, mock_print): mock_configured.return_value = True corosync.query_qdevice_status() @@ -141,7 +140,7 @@ def test_query_quorum_status_no_quorum(mock_run, mock_print_nodes): mock_print_nodes.assert_called_once_with() -@mock.patch("crmsh.utils.is_qdevice_configured") +@mock.patch("crmsh.corosync.is_qdevice_configured") def test_query_qnetd_status_no_qdevice(mock_qdevice_configured): mock_qdevice_configured.return_value = False with pytest.raises(ValueError) as err: @@ -151,7 +150,7 @@ def test_query_qnetd_status_no_qdevice(mock_qdevice_configured): @mock.patch("crmsh.corosync.get_value") -@mock.patch("crmsh.utils.is_qdevice_configured") +@mock.patch("crmsh.corosync.is_qdevice_configured") def test_query_qnetd_status_no_cluster_name(mock_qdevice_configured, mock_get_value): mock_qdevice_configured.return_value = True mock_get_value.return_value = None @@ -163,7 +162,7 @@ def test_query_qnetd_status_no_cluster_name(mock_qdevice_configured, mock_get_va @mock.patch("crmsh.corosync.get_value") -@mock.patch("crmsh.utils.is_qdevice_configured") +@mock.patch("crmsh.corosync.is_qdevice_configured") def test_query_qnetd_status_no_host(mock_qdevice_configured, mock_get_value): mock_qdevice_configured.return_value = True mock_get_value.side_effect = ["hacluster", None] @@ -183,7 +182,7 @@ def test_query_qnetd_status_no_host(mock_qdevice_configured, mock_get_value): @mock.patch('crmsh.bootstrap.configure_ssh_key') @mock.patch("crmsh.utils.check_ssh_passwd_need") @mock.patch("crmsh.corosync.get_value") -@mock.patch("crmsh.utils.is_qdevice_configured") +@mock.patch("crmsh.corosync.is_qdevice_configured") def test_query_qnetd_status_copy_id_failed(mock_qdevice_configured, mock_get_value, mock_check_passwd, mock_config_ssh_key, mock_ssh_copy_id, mock_parallax_call, mock_user_pair_for_ssh): mock_user_pair_for_ssh.return_value = "alice", "root" @@ -211,7 +210,7 @@ def test_query_qnetd_status_copy_id_failed(mock_qdevice_configured, @mock.patch('crmsh.bootstrap.configure_ssh_key') @mock.patch("crmsh.utils.check_ssh_passwd_need") @mock.patch("crmsh.corosync.get_value") -@mock.patch("crmsh.utils.is_qdevice_configured") +@mock.patch("crmsh.corosync.is_qdevice_configured") def test_query_qnetd_status_copy(mock_qdevice_configured, mock_get_value, mock_check_passwd, mock_config_ssh_key, mock_ssh_copy_id, mock_parallax_call, mock_print_nodes, mock_user_pair_for_ssh): @@ -235,27 +234,6 @@ def test_query_qnetd_status_copy(mock_qdevice_configured, mock_get_value, mock_print_nodes.assert_called_once_with() -@mock.patch('crmsh.utils.get_nodeinfo_from_cmaptool') -@mock.patch('crmsh.corosync.add_node_ucast') -def test_add_nodelist_from_cmaptool(mock_add_ucast, mock_nodeinfo): - mock_nodeinfo.return_value = {'1': ['10.10.10.1', '20.20.20.1'],'2': ['10.10.10.2', '20.20.20.2']} - - corosync.add_nodelist_from_cmaptool() - - mock_nodeinfo.assert_called_once_with() - mock_add_ucast.assert_has_calls([ - mock.call(['10.10.10.1', '20.20.20.1'], '1'), - mock.call(['10.10.10.2', '20.20.20.2'], '2') - ]) - - -@mock.patch("crmsh.corosync.get_value") -def test_is_unicast(mock_get_value): - mock_get_value.return_value = "udpu" - assert corosync.is_unicast() is True - mock_get_value.assert_called_once_with("totem.transport") - - @mock.patch('crmsh.corosync.get_corosync_value_dict') def test_token_and_consensus_timeout(mock_get_dict): mock_get_dict.return_value = {"token": 10, "consensus": 12} @@ -286,207 +264,5 @@ def test_get_corosync_value(mock_run): mock_run.assert_called_once_with("corosync-cmapctl totem.token") -class TestCorosyncParser(unittest.TestCase): - def test_parse(self): - p = Parser(F1) - _valid(p) - self.assertEqual(p.get('logging.logfile'), '/var/log/cluster/corosync.log') - self.assertEqual(p.get('totem.interface.ttl'), '1') - p.set('totem.interface.ttl', '2') - _valid(p) - self.assertEqual(p.get('totem.interface.ttl'), '2') - p.remove('quorum') - _valid(p) - self.assertEqual(p.count('quorum'), 0) - p.add('', make_section('quorum', [])) - _valid(p) - self.assertEqual(p.count('quorum'), 1) - p.set('quorum.votequorum', '2') - _valid(p) - self.assertEqual(p.get('quorum.votequorum'), '2') - p.set('bananas', '5') - _valid(p) - self.assertEqual(p.get('bananas'), '5') - - def test_logfile(self): - self.assertEqual(corosync.logfile(F1), '/var/log/cluster/corosync.log') - self.assertEqual(corosync.logfile('# nothing\n'), None) - - def test_udpu(self): - p = Parser(F2) - _valid(p) - self.assertEqual(p.count('nodelist.node'), 5) - p.add('nodelist', - make_section('nodelist.node', - make_value('nodelist.node.ring0_addr', '10.10.10.10') + - make_value('nodelist.node.nodeid', str(corosync.get_free_nodeid(p))))) - _valid(p) - self.assertEqual(p.count('nodelist.node'), 6) - self.assertEqual(p.get_all('nodelist.node.nodeid'), - ['1', '2', '3']) - - def test_add_node_no_nodelist(self): - "test checks that if there is no nodelist, no node is added" - from crmsh.corosync import make_section, make_value, get_free_nodeid - - p = Parser(F1) - _valid(p) - nid = get_free_nodeid(p) - self.assertEqual(p.count('nodelist.node'), nid - 1) - p.add('nodelist', - make_section('nodelist.node', - make_value('nodelist.node.ring0_addr', 'foo') + - make_value('nodelist.node.nodeid', str(nid)))) - _valid(p) - self.assertEqual(p.count('nodelist.node'), nid - 1) - - @mock.patch("crmsh.utils.InterfacesInfo.get_local_ip_list") - @mock.patch("crmsh.utils.IP.is_ipv6") - @mock.patch("re.search") - @mock.patch("crmsh.corosync.Parser") - @mock.patch("crmsh.corosync.conf") - @mock.patch("crmsh.utils.read_from_file") - def test_find_configured_ip_no_exception(self, mock_read_file, mock_conf, mock_parser, mock_search, mock_isv6, mock_ip_local): - mock_conf.return_value = "/etc/corosync/corosync.conf" - mock_parser_inst = mock.Mock() - mock_parser.return_value = mock_parser_inst - mock_parser_inst.all_paths.return_value = ["nodelist.node.ring0_addr"] - mock_read_file.return_value = "data" - mock_search.return_value = mock.Mock() - mock_parser_inst.get_all.return_value = ["10.10.10.1"] - mock_isv6.return_value = False - mock_ip_local.return_value = ["192.168.1.1", "10.10.10.2", "20.20.20.2"] - - corosync.find_configured_ip(["10.10.10.2"]) - - mock_conf.assert_called_once_with() - mock_parser.assert_called_once_with("data") - mock_parser_inst.all_paths.assert_called_once_with() - mock_parser_inst.get_all.assert_called_once_with("nodelist.node.ring0_addr") - mock_isv6.assert_called_once_with("10.10.10.2") - mock_ip_local.assert_called_once_with(False) - mock_search.assert_called_once_with("nodelist.node.ring[0-9]*_addr", "nodelist.node.ring0_addr") - - @mock.patch("crmsh.utils.InterfacesInfo.get_local_ip_list") - @mock.patch("crmsh.utils.IP.is_ipv6") - @mock.patch("re.search") - @mock.patch("crmsh.corosync.Parser") - @mock.patch("crmsh.corosync.conf") - @mock.patch("crmsh.utils.read_from_file") - def test_find_configured_ip_exception(self, mock_read_file, mock_conf, mock_parser, mock_search, mock_isv6, mock_ip_local): - mock_conf.return_value = "/etc/corosync/corosync.conf" - mock_parser_inst = mock.Mock() - mock_parser.return_value = mock_parser_inst - mock_parser_inst.all_paths.return_value = ["nodelist.node.ring0_addr"] - mock_read_file.return_value = "data" - mock_search.return_value = mock.Mock() - mock_parser_inst.get_all.return_value = ["10.10.10.1", "10.10.10.2"] - mock_isv6.return_value = False - mock_ip_local.return_value = ["192.168.1.1", "10.10.10.2", "20.20.20.2"] - - with self.assertRaises(corosync.IPAlreadyConfiguredError) as err: - corosync.find_configured_ip(["10.10.10.2"]) - self.assertEqual("IP 10.10.10.2 was already configured", str(err.exception)) - - mock_conf.assert_called_once_with() - mock_parser.assert_called_once_with("data") - mock_parser_inst.all_paths.assert_called_once_with() - mock_parser_inst.get_all.assert_called_once_with("nodelist.node.ring0_addr") - mock_isv6.assert_called_once_with("10.10.10.2") - mock_ip_local.assert_called_once_with(False) - # For some reason mock_search.assert_called_once_with does not work - mock_search.assert_has_calls([mock.call("nodelist.node.ring[0-9]*_addr", "nodelist.node.ring0_addr")]) - - @mock.patch("crmsh.utils.str2file") - @mock.patch("crmsh.corosync.make_section") - @mock.patch("crmsh.corosync.get_values") - @mock.patch("crmsh.corosync.make_value") - @mock.patch("crmsh.corosync.get_free_nodeid") - @mock.patch("crmsh.corosync.Parser") - @mock.patch("crmsh.utils.read_from_file") - @mock.patch("crmsh.corosync.conf") - @mock.patch("crmsh.corosync.find_configured_ip") - def test_add_node_ucast(self, mock_find_ip, mock_conf, mock_read_file, mock_parser, - mock_free_id, mock_make_value, mock_get_values, mock_make_section, mock_str2file): - mock_parser_inst = mock.Mock() - mock_conf.side_effect = ["corosync.conf", "corosync.conf"] - mock_read_file.return_value = "data" - mock_parser.return_value = mock_parser_inst - mock_free_id.return_value = 2 - mock_make_value.side_effect = [["value1"], ["value2"]] - mock_get_values.return_value = [] - mock_make_section.side_effect = ["section1", "section2"] - mock_parser_inst.count.return_value = 2 - mock_parser_inst.get.return_value = "net" - mock_parser_inst.to_string.return_value = "string data" - - corosync.add_node_ucast(['10.10.10.1']) - - mock_find_ip.assert_called_once_with(['10.10.10.1']) - mock_parser.assert_called_once_with("data") - mock_free_id.assert_called_once_with(mock_parser_inst) - mock_make_value.assert_has_calls([ - mock.call('nodelist.node.ring0_addr', '10.10.10.1'), - mock.call('nodelist.node.nodeid', '2') - ]) - mock_get_values.assert_called_once_with("nodelist.node.ring0_addr") - mock_make_section.assert_has_calls([ - mock.call('nodelist', []), - mock.call('nodelist.node', ["value1", "value2"]) - ]) - mock_parser_inst.add.assert_has_calls([ - mock.call('', 'section1'), - mock.call('nodelist', 'section2') - ]) - mock_parser_inst.count.assert_called_once_with("nodelist.node") - mock_parser_inst.set.assert_has_calls([ - mock.call('quorum.two_node', '1'), - mock.call('quorum.two_node', '0') - ]) - mock_parser_inst.get.assert_called_once_with('quorum.device.model') - mock_parser_inst.to_string.assert_called_once_with() - mock_str2file.assert_called_once_with("string data", "corosync.conf") - - def test_add_node_nodelist(self): - from crmsh.corosync import make_section, make_value, get_free_nodeid - - p = Parser(F2) - _valid(p) - nid = get_free_nodeid(p) - c = p.count('nodelist.node') - p.add('nodelist', - make_section('nodelist.node', - make_value('nodelist.node.ring0_addr', 'foo') + - make_value('nodelist.node.nodeid', str(nid)))) - _valid(p) - self.assertEqual(p.count('nodelist.node'), c + 1) - self.assertEqual(get_free_nodeid(p), nid + 1) - - def test_remove_node(self): - p = Parser(F2) - _valid(p) - self.assertEqual(p.count('nodelist.node'), 5) - p.remove_section_where('nodelist.node', 'nodeid', '2') - _valid(p) - self.assertEqual(p.count('nodelist.node'), 4) - self.assertEqual(p.get_all('nodelist.node.nodeid'), - ['1']) - - def test_bnc862577(self): - p = Parser(F3) - _valid(p) - self.assertEqual(p.count('service.ver'), 1) - - def test_get_free_nodeid(self): - def ids(*lst): - class Ids(object): - def get_all(self, _arg): - return lst - return Ids() - self.assertEqual(1, corosync.get_free_nodeid(ids('2', '5'))) - self.assertEqual(3, corosync.get_free_nodeid(ids('1', '2', '5'))) - self.assertEqual(4, corosync.get_free_nodeid(ids('1', '2', '3'))) - - if __name__ == '__main__': unittest.main() diff --git a/test/unittests/test_qdevice.py b/test/unittests/test_qdevice.py index ea360071fc..5a0f50f78c 100644 --- a/test/unittests/test_qdevice.py +++ b/test/unittests/test_qdevice.py @@ -771,66 +771,6 @@ def test_certificate_process_on_join(self, mock_fetch_qnetd_crt_from_cluster, mo mock_fetch_p12_from_cluster.assert_called_once_with() mock_import_p12_on_local.assert_called_once_with() - @mock.patch("crmsh.utils.str2file") - @mock.patch("crmsh.corosync.make_section") - @mock.patch("crmsh.corosync.Parser") - @mock.patch("crmsh.corosync.conf") - @mock.patch("crmsh.utils.read_from_file") - def test_write_qdevice_config(self, mock_read_file, mock_conf, mock_parser, mock_mksection, mock_str2file): - mock_mksection.side_effect = [ - ["device {", "}"], - ["net {", "}"] - ] - mock_read_file.return_value = "data" - mock_conf.side_effect = ["corosync.conf", "corosync.conf"] - mock_instance = mock.Mock() - mock_parser.return_value = mock_instance - mock_instance.to_string.return_value = "string data" - - self.qdevice_with_ip.write_qdevice_config() - - mock_conf.assert_has_calls([mock.call(), mock.call()]) - mock_parser.assert_called_once_with("data") - mock_instance.remove.assert_called_once_with("quorum.device") - mock_instance.add.assert_has_calls([ - mock.call('quorum', ["device {", "}"]), - mock.call('quorum.device', ["net {", "}"]) - ]) - mock_instance.set.assert_has_calls([ - mock.call('quorum.device.votes', '1'), - mock.call('quorum.device.model', 'net'), - mock.call('quorum.device.net.tls', 'on'), - mock.call('quorum.device.net.host', '10.10.10.123'), - mock.call('quorum.device.net.port', 5403), - mock.call('quorum.device.net.algorithm', 'ffsplit'), - mock.call('quorum.device.net.tie_breaker', 'lowest') - ]) - mock_instance.to_string.assert_called_once_with() - mock_mksection.assert_has_calls([ - mock.call('quorum.device', []), - mock.call('quorum.device.net', []) - ]) - mock_str2file.assert_called_once_with("string data", "corosync.conf") - - @mock.patch("crmsh.utils.str2file") - @mock.patch("crmsh.corosync.Parser") - @mock.patch("crmsh.corosync.conf") - @mock.patch("crmsh.utils.read_from_file") - def test_remove_qdevice_config(self, mock_read_file, mock_conf, mock_parser, mock_str2file): - mock_conf.side_effect = ["corosync.conf", "corosync.conf"] - mock_read_file.return_value = "data" - mock_instance = mock.Mock() - mock_parser.return_value = mock_instance - mock_instance.to_string.return_value = "string data" - - self.qdevice_with_ip.remove_qdevice_config() - - mock_conf.assert_has_calls([mock.call(), mock.call()]) - mock_parser.assert_called_once_with("data") - mock_instance.remove.assert_called_once_with("quorum.device") - mock_instance.to_string.assert_called_once_with() - mock_str2file.assert_called_once_with("string data", "corosync.conf") - @mock.patch("crmsh.parallax.parallax_call") @mock.patch('crmsh.utils.list_cluster_nodes') @mock.patch('os.path.exists') @@ -983,29 +923,7 @@ def test_start_qdevice_service_warn(self, mock_status, mock_cluster_run, mock_wa mock_enable_qnetd.assert_called_once_with() mock_start_qnetd.assert_called_once_with() - @mock.patch('crmsh.utils.cluster_run_cmd') - @mock.patch('crmsh.bootstrap.update_expected_votes') - @mock.patch('crmsh.log.LoggerUtils.status_long') - @mock.patch('crmsh.corosync.add_nodelist_from_cmaptool') - @mock.patch('crmsh.corosync.is_unicast') - @mock.patch('crmsh.qdevice.QDevice.write_qdevice_config') - def test_config_qdevice(self, mock_write, mock_is_unicast, mock_add_nodelist, mock_status_long, - mock_update_votes, mock_run): - mock_is_unicast.return_value = False - mock_status_long.return_value.__enter__ = mock.Mock() - mock_status_long.return_value.__exit__ = mock.Mock() - self.qdevice_with_ip.qdevice_reload_policy = qdevice.QdevicePolicy.QDEVICE_RELOAD - - self.qdevice_with_ip.config_qdevice() - - mock_write.assert_called_once_with() - mock_is_unicast.assert_called_once_with() - mock_add_nodelist.assert_called_once_with() - mock_status_long.assert_called_once_with("Update configuration") - mock_update_votes.assert_called_once_with() - mock_run.assert_called_once_with("crm corosync reload") - - @mock.patch('crmsh.utils.is_qdevice_configured') + @mock.patch('crmsh.corosync.is_qdevice_configured') def test_remove_certification_files_on_qnetd_return(self, mock_configured): mock_configured.return_value = False qdevice.QDevice.remove_certification_files_on_qnetd() @@ -1013,7 +931,7 @@ def test_remove_certification_files_on_qnetd_return(self, mock_configured): @mock.patch('crmsh.utils.get_stdout_or_raise_error') @mock.patch('crmsh.corosync.get_value') - @mock.patch('crmsh.utils.is_qdevice_configured') + @mock.patch('crmsh.corosync.is_qdevice_configured') def test_remove_certification_files_on_qnetd(self, mock_configured, mock_get_value, mock_run): mock_configured.return_value = True mock_get_value.side_effect = ["qnetd-node", "cluster1"] @@ -1029,3 +947,41 @@ def test_remove_certification_files_on_qnetd(self, mock_configured, mock_get_val mock_run.assert_has_calls([ mock.call(crt_cmd, remote="qnetd-node"), mock.call(crq_cmd, remote="qnetd-node")]) + + @mock.patch('crmsh.corosync.conf') + @mock.patch('crmsh.utils.str2file') + @mock.patch('crmsh.conf_parser.ConfParser') + def test_write_qdevice_config(self, mock_parser, mock_str2file, mock_conf): + mock_parser_inst = mock.Mock() + mock_parser.return_value = mock_parser_inst + mock_parser_inst.convert2string.return_value = "data" + mock_conf.return_value = "corosync.conf" + self.qdevice_with_invalid_cmds_relative_path.write_qdevice_config() + mock_str2file.assert_called_once_with("data", "corosync.conf") + + @mock.patch('crmsh.corosync.conf') + @mock.patch('crmsh.utils.str2file') + @mock.patch('crmsh.conf_parser.ConfParser') + def test_remove_qdevice_config(self, mock_parser, mock_str2file, mock_conf): + mock_parser_inst = mock.Mock() + mock_parser.return_value = mock_parser_inst + mock_parser_inst.convert2string.return_value = "data" + mock_conf.return_value = "corosync.conf" + self.qdevice_with_invalid_cmds_relative_path.remove_qdevice_config() + mock_str2file.assert_called_once_with("data", "corosync.conf") + mock_parser_inst.remove.assert_called_once_with("quorum.device") + + @mock.patch('crmsh.utils.cluster_run_cmd') + @mock.patch('crmsh.bootstrap.sync_file') + @mock.patch('crmsh.corosync.configure_two_node') + @mock.patch('crmsh.log.LoggerUtils.status_long') + @mock.patch('crmsh.qdevice.QDevice.write_qdevice_config') + def test_config_qdevice(self, mock_write_config, mock_status_long, mock_config_two_node, mock_sync_file, mock_run_cmd): + mock_status_long.return_value.__enter__ = mock.Mock() + mock_status_long.return_value.__exit__ = mock.Mock() + self.qdevice_with_ip.qdevice_reload_policy = qdevice.QdevicePolicy.QDEVICE_RELOAD + + self.qdevice_with_ip.config_qdevice() + mock_status_long.assert_called_once_with("Update configuration") + mock_config_two_node.assert_called_once_with(qdevice_adding=True) + mock_run_cmd.assert_called_once_with("crm corosync reload") diff --git a/test/unittests/test_sbd.py b/test/unittests/test_sbd.py index 431fa70855..425d308b68 100644 --- a/test/unittests/test_sbd.py +++ b/test/unittests/test_sbd.py @@ -64,7 +64,7 @@ def test_set_sbd_msgwait(self, mock_warn): @mock.patch('logging.Logger.warning') @mock.patch('crmsh.utils.get_qdevice_sync_timeout') @mock.patch('crmsh.utils.service_is_active') - @mock.patch('crmsh.utils.is_qdevice_configured') + @mock.patch('crmsh.corosync.is_qdevice_configured') def test_adjust_sbd_watchdog_timeout_with_diskless_and_qdevice_sbd_stage(self, mock_is_configured, mock_is_active, mock_get_sync, mock_warn): mock_is_configured.return_value = True mock_is_active.return_value = True @@ -74,7 +74,7 @@ def test_adjust_sbd_watchdog_timeout_with_diskless_and_qdevice_sbd_stage(self, m mock_warn.assert_called_once_with("sbd_watchdog_timeout is set to 20 for qdevice, it was 5") @mock.patch('logging.Logger.warning') - @mock.patch('crmsh.utils.is_qdevice_configured') + @mock.patch('crmsh.corosync.is_qdevice_configured') def test_adjust_sbd_watchdog_timeout_with_diskless_and_qdevice_all(self, mock_is_configured, mock_warn): mock_is_configured.return_value = False self.sbd_timeout_inst.sbd_watchdog_timeout = 5 diff --git a/test/unittests/test_ui_cluster.py b/test/unittests/test_ui_cluster.py index eb673deb54..2c4267cd3f 100644 --- a/test/unittests/test_ui_cluster.py +++ b/test/unittests/test_ui_cluster.py @@ -39,7 +39,7 @@ def tearDownClass(cls): @mock.patch('logging.Logger.info') @mock.patch('crmsh.utils.service_is_active') @mock.patch('crmsh.ui_cluster.parse_option_for_nodes') - @mock.patch('crmsh.utils.is_qdevice_configured') + @mock.patch('crmsh.corosync.is_qdevice_configured') def test_do_start_already_started(self, mock_qdevice_configured, mock_parse_nodes, mock_active, mock_info): mock_qdevice_configured.return_value = False context_inst = mock.Mock() @@ -59,7 +59,7 @@ def test_do_start_already_started(self, mock_qdevice_configured, mock_parse_node @mock.patch('crmsh.qdevice.QDevice.check_qdevice_vote') @mock.patch('crmsh.bootstrap.start_pacemaker') @mock.patch('logging.Logger.info') - @mock.patch('crmsh.utils.is_qdevice_configured') + @mock.patch('crmsh.corosync.is_qdevice_configured') @mock.patch('crmsh.utils.start_service') @mock.patch('crmsh.utils.service_is_active') @mock.patch('crmsh.ui_cluster.parse_option_for_nodes') diff --git a/test/unittests/test_utils.py b/test/unittests/test_utils.py index 773154a8be..5e40614397 100644 --- a/test/unittests/test_utils.py +++ b/test/unittests/test_utils.py @@ -434,8 +434,8 @@ def test_get_nodeinfo_from_cmaptool(mock_get_stdout, mock_search, mock_findall): match_inst1.group.assert_called_once_with(1) match_inst2.group.assert_called_once_with(1) mock_findall.assert_has_calls([ - mock.call(r'[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}', 'runtime.totem.pg.mrp.srp.members.1.ip (str) = r(0) ip(192.168.43.129)'), - mock.call(r'[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}', 'runtime.totem.pg.mrp.srp.members.2.ip (str) = r(0) ip(192.168.43.128)') + mock.call(r'[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}', 'runtime.members.1.ip (str) = r(0) ip(192.168.43.129)'), + mock.call(r'[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}', 'runtime.members.2.ip (str) = r(0) ip(192.168.43.128)') ]) @mock.patch("crmsh.utils.get_nodeinfo_from_cmaptool") @@ -744,9 +744,8 @@ def setUp(self): Test setUp. """ self.interfaces_info = utils.InterfacesInfo() - self.interfaces_info_with_second_hb = utils.InterfacesInfo(second_heartbeat=True) - self.interfaces_info_with_custom_nic = utils.InterfacesInfo(second_heartbeat=True, custom_nic_list=['eth1']) - self.interfaces_info_with_wrong_nic = utils.InterfacesInfo(custom_nic_list=['eth7']) + self.interfaces_info_with_custom_nic = utils.InterfacesInfo(custom_nic_addr_list=['eth1']) + self.interfaces_info_with_wrong_nic = utils.InterfacesInfo(custom_nic_addr_list=['eth7']) self.interfaces_info_fake = utils.InterfacesInfo() self.interfaces_info_fake._nic_info_dict = { "eth0": [mock.Mock(ip="10.10.10.1", network="10.10.10.0"), mock.Mock(ip="10.10.10.2", network="10.10.10.0")], @@ -774,24 +773,6 @@ def test_get_interfaces_info_no_address(self, mock_run): self.assertEqual("No address configured", str(err.exception)) mock_run.assert_called_once_with("ip -4 -o addr show") - @mock.patch('crmsh.utils.Interface') - @mock.patch('crmsh.utils.get_stdout_stderr') - def test_get_interfaces_info_one_addr(self, mock_run, mock_interface): - mock_run.return_value = (0, self.network_output_error, None) - mock_interface_inst_1 = mock.Mock(is_loopback=True, is_link_local=False) - mock_interface_inst_2 = mock.Mock(is_loopback=False, is_link_local=False) - mock_interface.side_effect = [mock_interface_inst_1, mock_interface_inst_2] - - with self.assertRaises(ValueError) as err: - self.interfaces_info_with_second_hb.get_interfaces_info() - self.assertEqual("Cannot configure second heartbeat, since only one address is available", str(err.exception)) - - mock_run.assert_called_once_with("ip -4 -o addr show") - mock_interface.assert_has_calls([ - mock.call("127.0.0.1/8"), - mock.call("192.168.122.241/24") - ]) - def test_nic_list(self): res = self.interfaces_info_fake.nic_list self.assertEqual(res, ["eth0", "eth1"]) @@ -842,36 +823,19 @@ def test_network_list(self, mock_interface_list): mock_interface_list.assert_called_once_with() def test_nic_first_ip(self): - res = self.interfaces_info_fake._nic_first_ip("eth0") + res = self.interfaces_info_fake.nic_first_ip("eth0") self.assertEqual(res, "10.10.10.1") - @mock.patch('crmsh.utils.InterfacesInfo.nic_list', new_callable=mock.PropertyMock) - @mock.patch('logging.Logger.warning') - @mock.patch('crmsh.utils.InterfacesInfo.get_interfaces_info') - @mock.patch('crmsh.utils.get_stdout_stderr') - def test_get_default_nic_list_from_route_no_default(self, mock_run, mock_get_interfaces_info, mock_warn, mock_nic_list): - output = """10.10.10.0/24 dev eth1 proto kernel scope link src 10.10.10.51 - 20.20.20.0/24 dev eth2 proto kernel scope link src 20.20.20.51""" - mock_run.return_value = (0, output, None) - mock_nic_list.side_effect = [["eth0", "eth1"], ["eth0", "eth1"]] - - res = self.interfaces_info.get_default_nic_list_from_route() - self.assertEqual(res, ["eth0"]) - - mock_run.assert_called_once_with("ip -o route show") - mock_warn.assert_called_once_with("No default route configured. Using the first found nic") - mock_nic_list.assert_has_calls([mock.call(), mock.call()]) - - @mock.patch('crmsh.utils.get_stdout_stderr') - def test_get_default_nic_list_from_route(self, mock_run): + @mock.patch('crmsh.utils.get_stdout_or_raise_error') + def test_get_default_nic_from_route(self, mock_run): output = """default via 192.168.122.1 dev eth8 proto dhcp 10.10.10.0/24 dev eth1 proto kernel scope link src 10.10.10.51 20.20.20.0/24 dev eth2 proto kernel scope link src 20.20.20.51 192.168.122.0/24 dev eth8 proto kernel scope link src 192.168.122.120""" - mock_run.return_value = (0, output, None) + mock_run.return_value = output - res = self.interfaces_info.get_default_nic_list_from_route() - self.assertEqual(res, ["eth8"]) + res = self.interfaces_info.get_default_nic_from_route() + self.assertEqual(res, "eth8") mock_run.assert_called_once_with("ip -o route show")