diff --git a/qemu/tests/cfg/passt_transfer_tests.cfg b/qemu/tests/cfg/passt_transfer_tests.cfg new file mode 100644 index 0000000000..4e221253b4 --- /dev/null +++ b/qemu/tests/cfg/passt_transfer_tests.cfg @@ -0,0 +1,31 @@ +- passt_transfer_tests: + virt_test_type = qemu + type = passt_transfer_tests + image_snapshot = yes + vhost_nic1 = "" + nettype_nic1 = user:passt + net_port_forwards_avocado-vt-vm1 = TCP@10001 UDP@10001 + net_port_forwards_vm2 = TCP@10002 UDP@10002 + vms = "avocado-vt-vm1 vm2" + tmp_dir = "/var/tmp/" + fw_stop_cmd = systemctl stop firewalld || nft flush ruleset || iptables -F + file_md5_check_timeout = 120 + filesize = 4294967296 + dd_cmd = "dd if=/dev/zero of=%s bs=%d count=1" + variants: + - with_tcp_ipv4: + receive_protocol = TCP4 + - with_udp_ipv4: + filesize = 51200 + receive_protocol = UDP4 + receive_cmd = " & echo $! >/tmp/socat.pid && sleep 60 && kill -9 $(cat /tmp/socat.pid)" + - with_tcp_ipv6: + ipv6 = yes + receive_protocol = TCP6 + - with_udp_ipv6: + ipv6 = yes + filesize = 51200 + receive_protocol = UDP6 + receive_cmd = " & echo $! >/tmp/socat.pid && sleep 60 && kill -9 $(cat /tmp/socat.pid)" + receive_cmd <= socat -u ${receive_protocol}-LISTEN:%d,reuseaddr OPEN:%s,create + sent_cmd = socat -u FILE:%s ${receive_protocol}:%s:%d diff --git a/qemu/tests/passt_transfer_tests.py b/qemu/tests/passt_transfer_tests.py new file mode 100644 index 0000000000..4a8501128f --- /dev/null +++ b/qemu/tests/passt_transfer_tests.py @@ -0,0 +1,114 @@ +import os +import time +import re + +from avocado.utils import crypto, process +from virttest import utils_misc +from virttest import utils_net +from virttest import error_context + + +@error_context.context_aware +def run(test, params, env): + """ + Test Step + 1. boot up two virtual machine with passt device + 2. For linux guest,Transfer data via tcp&udp: + host-->guest1 & host-->guest2 & guest<-->guest2 + 3. after data transfer, check data have no change + Params: + :param test: QEMU test object + :param params: Dictionary with the test parameters + :param env: Dictionary with test environment. + """ + def get_file_md5sum(file_name, session, timeout): + """ + Get file md5sum from guest. + """ + test.log.info("Get md5sum of the file:'%s'", file_name) + s, o = session.cmd_status_output("md5sum %s" % file_name, timeout=timeout) + if s != 0: + test.error("Get file md5sum failed as %s" % o) + return re.findall(r"\w{32}", o)[0] + + def transfer_data(src, dst): + error_context.context("Transferring data from %s to %s" % + (src.name, dst.name), test.log.info) + sessions[dst].sendline(receive_cmd % (guest2guest_port, dest_path)) + time.sleep(5) + sessions[src].sendline(sent_cmd % (guest_path, gateway, guest2guest_port)) + dst_md5 = get_file_md5sum(dest_path, sessions[dst], + timeout=file_md5_check_timeout) + error_context.context("md5 value of data in %s: %s" % (dst.name, dst_md5), + test.log.info) + if dst_md5 != src_md5: + test.fail("File changed transfer %s -> %s" % (src.name, dst.name)) + + timeout = params.get_numeric("login_timeout", 360) + receive_cmd = params.get("receive_cmd") + sent_cmd = params.get("sent_cmd") + tmp_dir = params["tmp_dir"] + filesize = params.get_numeric("filesize") + dd_cmd = params["dd_cmd"] + file_md5_check_timeout = params.get_numeric("file_md5_check_timeout", 120) + fw_stop_cmd = params["fw_stop_cmd"] + + sessions = {} + ifname = {} + port_list = [] + + error_context.context("Boot vms for test", test.log.info) + vms = env.get_all_vms() + for vm in vms: + vm.verify_alive() + sessions[vm] = vm.wait_for_serial_login(timeout=timeout) + for nic in vm.virtnet: + port_id = nic.net_port_forwards + port_list += (port_id,) + + if params.get_boolean("ipv6"): + gateway_address = utils_net.get_default_gateway(ip_ver='ipv6') + local_address = "[::1]" + ifname[vm] = utils_net.get_linux_ifname(sessions[vm], + vm.get_mac_address()) + gateway = [f"{gateway_address}%{ifname[vm]}"] + else: + gateway = utils_net.get_default_gateway(ip_ver='ipv4') + local_address = "localhost" + # prepare test data + guest_path = (tmp_dir + "src-%s" % utils_misc.generate_random_string(8)) + dest_path = (tmp_dir + "dst-%s" % utils_misc.generate_random_string(8)) + host_path = os.path.join(test.tmpdir, "tmp-%s" % + utils_misc.generate_random_string(8)) + test.log.info("Test setup: Creating %dbytes file on host", filesize) + process.run(dd_cmd % (host_path, filesize), shell=True) + + try: + src_md5 = (crypto.hash_file(host_path, algorithm="md5")) + error_context.context("md5 value of data from src: %s" % src_md5, + test.log.info) + # transfer data from host to guest + host2guest_port = int(re.search(r'\d+', port_list[0]).group()) + for vm in vms: + error_context.context("Transfer data from host to %s" % vm.name, + test.log.info) + sessions[vm].cmd_output_safe(fw_stop_cmd) + sessions[vm].sendline(receive_cmd % (host2guest_port, guest_path)) + time.sleep(5) + process.run(sent_cmd % (host_path, local_address, host2guest_port), shell=True) + dst_md5 = get_file_md5sum(guest_path, sessions[vm], + timeout=file_md5_check_timeout) + error_context.context("md5 value of data in %s: %s" % (vm.name, dst_md5), + test.log.info) + if dst_md5 != src_md5: + test.fail("File changed after transfer host -> %s" % vm.name) + host2guest_port += 1 + + guest2guest_port = int(re.search(r'\d+', port_list[1]).group()) + transfer_data(*vms) + guest2guest_port -= 1 + transfer_data(*reversed(vms)) + + finally: + process.system("rm -rf %s" % host_path, timeout=timeout, + ignore_status=True)