From 294be2b661778b8d8abd4c83101e5ab9c84ad61e Mon Sep 17 00:00:00 2001 From: Haijiao Zhao Date: Wed, 16 Aug 2023 06:08:57 -0400 Subject: [PATCH] Add case of connectivity check of ethernet type interface - VIRT-296218 - [ethernet] Check connectivity for ethernet type interface with managed='no' Signed-off-by: Haijiao Zhao --- .../connectivity_check_ethernet_interface.cfg | 50 ++++++ .../connectivity_check_ethernet_interface.py | 143 ++++++++++++++++++ provider/virtual_network/network_base.py | 14 +- 3 files changed, 205 insertions(+), 2 deletions(-) create mode 100644 libvirt/tests/cfg/virtual_network/connectivity/connectivity_check_ethernet_interface.cfg create mode 100644 libvirt/tests/src/virtual_network/connectivity/connectivity_check_ethernet_interface.py diff --git a/libvirt/tests/cfg/virtual_network/connectivity/connectivity_check_ethernet_interface.cfg b/libvirt/tests/cfg/virtual_network/connectivity/connectivity_check_ethernet_interface.cfg new file mode 100644 index 0000000000..9b42e95236 --- /dev/null +++ b/libvirt/tests/cfg/virtual_network/connectivity/connectivity_check_ethernet_interface.cfg @@ -0,0 +1,50 @@ +- virtual_network.connectivity_check.ethernet_interface: + type = connectivity_check_ethernet_interface + start_vm = no + timeout = 240 + outside_ip = 'www.redhat.com' + host_iface = + variants user_type: + - non_root_user: + test_user = USER.EXAMPLE + test_passwd = PASSWORD.EXAMPLE + user_id = + unpr_vm_name = UNPRIVILEGED_VM.EXAMPLE + variants: + - positive_test: + status_error = no + variants: + - no_mtu: + mtu_attrs = {} + - larger_mtu: + tap_mtu = 2000 + iface_mtu = 3000 + mtu_attrs = {'mtu': {'size': ${iface_mtu}}} + - smaller_mtu: + tap_mtu = 2000 + iface_mtu = 1400 + mtu_attrs = {'mtu': {'size': ${iface_mtu}}} + variants tap_type: + - tap: + vm_ping_outside = pass + vm_ping_host_public = pass + - macvtap: + vm_ping_outside = pass + vm_ping_host_public = fail + iface_attrs = {'target': {'dev': tap_name, 'managed': 'no'}, 'model': 'virtio', 'type_name': 'ethernet', **${mtu_attrs}, 'acpi': {'index': '1'}} + vm_iface = eno1 + - negative_test: + status_error = yes + variants: + - no_target_dev: + iface_attrs = {'model': 'virtio', 'type_name': 'ethernet', 'target': {'managed': 'no'}} + err_msg = target dev must be supplied when managed='no' + - target_dev_not_exist: + iface_attrs = {'model': 'virtio', 'type_name': 'ethernet', 'target': {'dev': 'test', 'managed': 'no'}} + err_msg = target managed='no' but specified dev doesn't exist + - managed_yes: + tap_type = tap + iface_attrs = {'model': 'virtio', 'type_name': 'ethernet', 'target': {'dev': tap_name, 'managed': 'yes'}} + err_msg = The .* interface already exists + variants: + - managed_no: diff --git a/libvirt/tests/src/virtual_network/connectivity/connectivity_check_ethernet_interface.py b/libvirt/tests/src/virtual_network/connectivity/connectivity_check_ethernet_interface.py new file mode 100644 index 0000000000..d97ad461eb --- /dev/null +++ b/libvirt/tests/src/virtual_network/connectivity/connectivity_check_ethernet_interface.py @@ -0,0 +1,143 @@ +import logging + +import aexpect +from virttest import libvirt_version +from virttest import remote +from virttest import utils_misc +from virttest import utils_net +from virttest import virsh +from virttest.libvirt_xml import vm_xml +from virttest.utils_libvirt import libvirt_unprivileged +from virttest.utils_libvirt import libvirt_vmxml +from virttest.utils_test import libvirt + +from provider.virtual_network import network_base + +LOG = logging.getLogger('avocado.' + __name__) + + +def run(test, params, env): + """ + Test passt function + """ + libvirt_version.is_libvirt_feature_supported(params) + root = 'root_user' == params.get('user_type', '') + if root: + vm_name = params.get('main_vm') + vm = env.get_vm(vm_name) + virsh_ins = virsh + else: + vm_name = params.get('unpr_vm_name') + test_user = params.get('test_user', '') + test_passwd = params.get('test_passwd', '') + unpr_vm_args = { + 'username': params.get('username'), + 'password': params.get('password'), + } + vm = libvirt_unprivileged.get_unprivileged_vm(vm_name, test_user, + test_passwd, + **unpr_vm_args) + uri = f'qemu+ssh://{test_user}@localhost/session' + virsh_ins = virsh.VirshPersistent(uri=uri) + host_session = aexpect.ShellSession('su') + remote.VMManager.set_ssh_auth(host_session, 'localhost', test_user, + test_passwd) + host_session.close() + + rand_id = utils_misc.generate_random_string(3) + bridge_name = 'br_' + rand_id + tap_type = params.get('tap_type', '') + tap_name = tap_type + '_' + rand_id + tap_mtu = params.get('tap_mtu') + iface_mtu = params.get('iface_mtu') + vm_iface = params.get('vm_iface') + host_ip = utils_net.get_host_ip_address(ip_ver='ipv4') + iface_attrs = eval(params.get('iface_attrs')) + vm_iface = params.get('vm_iface', 'eno1') + outside_ip = params.get('outside_ip') + host_iface = params.get('host_iface') + host_iface = host_iface if host_iface else utils_net.get_net_if( + state="UP")[0] + status_error = 'yes' == params.get('status_error', 'no') + err_msg = params.get('err_msg') + vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name, + virsh_instance=virsh_ins) + bkxml = vmxml.copy() + + try: + + if tap_type: + if tap_type == 'tap': + utils_net.create_linux_bridge_tmux(bridge_name, host_iface) + network_base.create_tap(tap_name, bridge_name, test_user) + elif tap_type == 'macvtap': + mac_addr = network_base.create_macvtap(tap_name, host_iface, + test_user) + iface_attrs['mac_address'] = mac_addr + + if tap_mtu: + network_base.set_tap_mtu(tap_name, tap_mtu) + + vmxml = vm_xml.VMXML.new_from_inactive_dumpxml( + vm_name, virsh_instance=virsh_ins) + vmxml.del_device('interface', by_tag=True) + libvirt_vmxml.modify_vm_device(vmxml, 'interface', iface_attrs, + virsh_instance=virsh_ins) + + start_result = virsh.start(vm_name, debug=True, uri=uri) + libvirt.check_exit_status(start_result, status_error) + + if status_error: + libvirt.check_result(start_result, err_msg) + return + + vm.create_serial_console() + session = vm.wait_for_serial_login(60) + + ips = { + 'outside_ip': outside_ip, + 'host_public_ip': host_ip, + } + network_base.ping_check(params, ips, session, force_ipv4=True) + + if iface_mtu: + # Check mtu of live vmxml + vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name, + virsh_instance=virsh_ins) + iface = vmxml.devices.by_device_tag("interface")[0] + vmxml_mtu = iface['mtu']['size'] + if int(vmxml_mtu) != int(iface_mtu): + test.fail(f'MTU in vmxml was set to be {iface_mtu}, ' + f'but actually got {vmxml_mtu}') + else: + LOG.info('MTU check of vmxml PASS') + + # Check mtu inside vm + vm_iface_info = utils_net.get_linux_iface_info(iface=vm_iface, + session=session) + vm_mtu = vm_iface_info['mtu'] + if int(vm_mtu) != int(iface_mtu): + test.fail(f'MTU of interface inside vm should be ' + f'{iface_mtu}, not {vm_mtu}') + else: + LOG.info('MTU check inside vm PASS') + + if tap_mtu: + host_tap_info = utils_net.get_linux_iface_info( + iface=tap_name) + host_mtu = host_tap_info['mtu'] + if int(host_mtu) != int(tap_mtu): + test.fail(f'MTU of host tap device should be ' + f'{tap_mtu}, not {host_mtu}') + else: + LOG.info('MTU check on host PASS') + session.close() + + finally: + bkxml.sync(virsh_instance=virsh_ins) + if not root: + del virsh_ins + if tap_type: + network_base.delete_tap(tap_name) + if tap_type == 'tap': + utils_net.delete_linux_bridge_tmux(bridge_name, host_iface) diff --git a/provider/virtual_network/network_base.py b/provider/virtual_network/network_base.py index cad7e8500e..7f60d23490 100644 --- a/provider/virtual_network/network_base.py +++ b/provider/virtual_network/network_base.py @@ -85,8 +85,8 @@ def ping_check(params, ips, session=None, force_ipv4=True, **args): force_ipv4=force_ipv4, **ping_args) msg = f'Expect ping from {source} to {destination} should ' \ - f'{expect_result}, actual result is ' \ - f'{"pass" if status == 0 else "fail"}' + f'{expect_result.upper()}, actual result is ' \ + f'{"PASS" if status == 0 else "FAIL"}' ping_result = (status == 0) == (expect_result == 'pass') if ping_result: LOG.debug(msg) @@ -136,6 +136,16 @@ def create_macvtap(macvtap_name, iface, user): return mac_addr +def set_tap_mtu(tap, mtu_size): + """ + Set mtu for tap/macvtap device + + :param tap: tap/macvtap device name + :param mtu_size: mtu size to set + """ + process.run(f'ip link set dev {tap} mtu {mtu_size}') + + def delete_tap(tap_name): """ Delete tap/macvtap device with given name