def setUp(self): ''' Build Libunwind library Source: https://github.com/libunwind/libunwind/archive/master.zip ''' dist = distro.detect() smm = SoftwareManager() deps = ['gcc', 'libtool', 'autoconf', 'automake', 'make'] if dist.name == 'Ubuntu': deps.extend([ 'dh-autoreconf', 'dh-dist-zilla', 'g++', 'texlive-extra-utils' ]) elif dist.name in ['SuSE', 'rhel', 'fedora', 'redhat']: deps.extend(['gcc-c++']) else: self.cancel('Test not supported in %s' % dist.name) for package in deps: if not smm.check_installed(package) and not smm.install(package): self.cancel("Failed to install %s, which is needed for" "the test to be run" % package) tarball = self.fetch_asset( 'vanilla_pathscale.zip', locations=[ 'https://github.com/libunwind/libunwind/archive/' 'master.zip' ], expire='7d') archive.extract(tarball, self.workdir) self.sourcedir = os.path.join(self.workdir, 'libunwind-master') os.chdir(self.sourcedir) process.run('./autogen.sh', shell=True) ''' For configure options on different architecture please refer https://github.com/libunwind/libunwind ''' configure_option = self.params.get('configure_option', default=None) if not configure_option: if cpu.get_vendor() == 'intel': configure_option = 'CC=icc CFLAGS="-g -O3 -ip" CXX=icc ' \ 'CCAS=gcc CCASFLAGS=-g LDFLAGS=' \ '"-L$PWD/src/.libs"' elif cpu.get_vendor() == 'ibm': configure_option = 'CFLAGS="-g -O2 -m64" CXXFLAGS="' \ '-g -O2 -m64"' else: self.cancel("Please provide configure option in YAML refer " "configure section for %s" % cpu.get_vendor()) process.run('./configure %s' % configure_option, shell=True) build.make(self.sourcedir) build.make(self.sourcedir, extra_args='install')
def run(test, params, env): """ Boot guest with iommu_platform, then do ping test 1) Boot a VM with iommu_platform=on 2) add intel_iommu=on in guest kernel line 3) reboot guest 4) do ping test :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ if cpu.get_vendor() != 'intel': test.cancel("This case only support Intel platform") login_timeout = int(params.get("login_timeout", 360)) vm = env.get_vm(params["main_vm"]) vm.verify_alive() session = vm.wait_for_login(timeout=login_timeout) ping_count = int(params.get("ping_count", 10)) guest_ip = vm.get_address() try: status, output = utils_test.ping(guest_ip, ping_count, timeout=float(ping_count) * 1.5) if status != 0: test.fail("Ping returns non-zero value %s" % output) package_lost = utils_test.get_loss_ratio(output) if package_lost != 0: test.fail("%s packeage lost when ping guest ip %s " % (package_lost, guest_ip)) finally: session.close()
def get_kvm_module_list(): if ARCH == 'x86_64': vendor = cpu.get_vendor() if hasattr( cpu, 'get_vendor') else cpu.get_cpu_vendor_name() return ["kvm", "kvm-%s" % vendor] elif ARCH in ('ppc64', 'ppc64le'): # FIXME: Please correct it if anyone still want to use KVM-PR mode return ["kvm", "kvm-hv"] elif ARCH in ('s390', 's390x', 'mips64', 'loongarch64'): return ["kvm"] elif ARCH == "aarch64": return []
def run(test, params, env): """ [seabios] seabios support IOMMU for virtio-blk [seabios] seabios support IOMMU for virtio-scsi [seabios] seabios support IOMMU for virtio-net this case will: 1) Boot guest with virtio devices and iommu is on. 2) Check 'info block'. 3) Read and write data on data disks. 4) Ping guest. :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ if cpu.get_vendor() != 'intel': test.cancel("This case only support Intel platform") vm = env.get_vm(params["main_vm"]) vm.verify_alive() login_timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=login_timeout) check_data_disks(test, params, env, vm, session) session.close() error_context.context("Ping guest!", logging.info) guest_ip = vm.get_address() status, output = utils_test.ping(guest_ip, count=10, timeout=20) if status: test.fail("Ping guest failed!") ratio = utils_test.get_loss_ratio(output) if ratio != 0: test.fail("Loss ratio is %s", ratio) error_context.context("Check kernel crash message!", logging.info) vm.verify_kernel_crash()
def run(test, params, env): """ Test cpu flags. 1) Check if current flags are in the supported lists, if no, cancel test 2) Otherwise, boot guest with the cpu flags 3) Check cpu flags inside guest(only for linux guest) 4) Reboot guest :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ vendor_id = params.get("vendor_id", "") if vendor_id: if vendor_id != cpu.get_vendor(): test.cancel("Need host vendor %s to support this test case" % vendor_id) flags = params["flags"] check_host_flags = params.get_boolean("check_host_flags") if check_host_flags: check_flags(params, flags, test) params["start_vm"] = "yes" vm_name = params['main_vm'] env_process.preprocess_vm(test, params, env, vm_name) vm = env.get_vm(vm_name) error_context.context("Try to log into guest", logging.info) session = vm.wait_for_login() if params["os_type"] == "linux": check_flags(params, flags, test, session) if params.get("reboot_method"): error_context.context("Reboot guest '%s'." % vm.name, logging.info) session = vm.reboot(session=session) vm.verify_kernel_crash() session.close()
def run(test, params, env): """ Check guest gets correct multiple vcpu dies 1) Boot guest with options: -smp n,dies=2x... 2) Check cpu dies(only for Linux guest and Intel host) :param test: QEMU test object. :param params: Dictionary with test parameters. :param env: Dictionary with the test environment. """ vm_name = params['main_vm'] vcpu_dies_list = [2, 4] params['vcpu_dies'] = random.choice(vcpu_dies_list) params['start_vm'] = 'yes' env_process.preprocess_vm(test, params, env, vm_name) vm = env.get_vm(vm_name) session = vm.wait_for_login() if params["os_type"] == "linux" and cpu.get_vendor() == 'intel': check_die_id = params['check_die_id'] check_die_cpus_list = params['check_die_cpus_list'] vcpu_sockets = vm.cpuinfo.sockets vcpu_dies = vm.cpuinfo.dies dies_id = session.cmd_output(check_die_id).strip().split('\n') dies_cpus_list = session.cmd_output( check_die_cpus_list).strip().split('\n') if len(dies_id) != int(vcpu_dies): test.fail("die_id is not right: %d != %d" % (len(dies_id), int(vcpu_dies))) if len(dies_cpus_list) != int(vcpu_sockets)*int(vcpu_dies): test.fail("die_cpus_list is not right: %d != %d" % (len(dies_cpus_list), int(vcpu_sockets)*int(vcpu_dies))) vm.verify_kernel_crash() session.close() vm.destroy()
def run(test, params, env): """ Qemu reboot test: 1) Get cpu model lists supported by host 2) Check if current cpu model is in the supported lists, if no, cancel test 3) Otherwise, boot guest with the cpu model 4) Check cpu model name in guest 5) Check cpu flags in guest(only for linux guest) 6) Reboot guest :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ qemu_binary = utils_misc.get_qemu_binary(params) qmp_cmds = [ '{"execute": "qmp_capabilities"}', '{"execute": "query-cpu-definitions", "id": "RAND91"}', '{"execute": "quit"}' ] cmd = "echo -e '{0}' | {1} -qmp stdio -vnc none -M none | grep return |"\ "grep RAND91".format(r"\n".join(qmp_cmds), qemu_binary) output = process.run(cmd, timeout=10, ignore_status=True, shell=True, verbose=False).stdout_text out = json.loads(output)["return"] model = params["model"] model_pattern = params["model_pattern"] flags = params["flags"] if cpu.get_vendor() == 'intel': model_ib = "%s-IBRS" % model flag_ib = " ibpb ibrs" name_ib = ", IBRS( update)?" else: model_ib = "%s-IBPB" % model flag_ib = " ibpb" name_ib = " \\(with IBPB\\)" models = [x["name"] for x in out if not x["unavailable-features"]] if model_ib in models: cpu_model = model_ib guest_model = model_pattern % name_ib flags += flag_ib elif model in models: cpu_model = model guest_model = model_pattern % "" else: test.cancel("This host doesn't support cpu model %s" % model) params["cpu_model"] = cpu_model params["start_vm"] = "yes" vm_name = params['main_vm'] env_process.preprocess_vm(test, params, env, vm_name) vm = env.get_vm(vm_name) error_context.context("Try to log into guest", logging.info) session = vm.wait_for_login() error_context.context("Check cpu model inside guest", logging.info) cmd = params["get_model_cmd"] out = session.cmd_output(cmd) if not re.search(guest_model, out): test.fail("Guest cpu model is not right") if params["os_type"] == "linux": check_cpu_flags(params, flags, test, session) if params.get("reboot_method"): error_context.context("Reboot guest '%s'." % vm.name, logging.info) session = vm.reboot(session=session) vm.verify_kernel_crash() session.close()
def run(test, params, env): """ Execute the libguestfs-test-tool unittest inside L1 guest. 1) Launch a guest and check if libguestfs-tools is installed. 2) Execute the libguestfs-test-tool directly launching qemu. 3) Analyze the result of libguestfs-test-tool. 4) Check the nested file exists. :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ kvm_module = arch.get_kvm_module_list()[-1].replace('-', '_') is_kvm_mode = params["nested_flag"] == "nested_flag_on" nested_file = os.path.join("/sys/module/", kvm_module, "parameters/nested") unittest_timeout = params.get_numeric("unittest_timeout") cpu_vendor = cpu.get_vendor() cpu_arch = cpu.get_arch() if cpu_arch == "powerpc" and int(cpu.get_family().strip("power")) < 9: test.cancel("Nested feature requires a POWER9 CPU") elif cpu_arch == "x86_64": flag = "vmx" if cpu_vendor == "intel" else "svm" params["cpu_model_flags"] = params["cpu_model_flags"].format(flag) params["start_vm"] = "yes" vm = env.get_vm(params["main_vm"]) vm.create(params=params) vm.verify_alive() session = vm.wait_for_login() error_context.context("Check if libguestfs-tools is installed.", logging.info) sm = utils_package.RemotePackageMgr(session, "libguestfs-tools") if not (sm.is_installed("libguestfs-tools") or sm.install()): test.cancel("Unable to install libguestfs-tools inside guest.") try: error_context.context("Execute the libguestfs-test-tool unittest " "directly launching qemu.", logging.info) stderr_file = "/tmp/lgf_stderr" lgf_cmd = ("LIBGUESTFS_BACKEND=direct libguestfs-test-tool " "--timeout {} 2> {}".format(unittest_timeout, stderr_file)) lgf_s, lgf_o = session.cmd_status_output(lgf_cmd, timeout=unittest_timeout) logging.debug("libguestfs-test-tool stdout:\n%s", lgf_o) lgf_stderr = session.cmd_output("cat " + stderr_file) lgf_tcg = re.search("Back to tcg accelerator", lgf_stderr) error_context.context("Analyze the libguestfs-test-tool test result.", logging.info) fail_msg = ("the exit status is non-zero" if lgf_s else "back to tcg accelerator" if lgf_tcg and is_kvm_mode else "") if fail_msg: logging.debug("libguestfs-test-tool stderr:\n%s", lgf_stderr) test.fail("libguestfs-test-tool execution failed due to: %s. " % fail_msg) error_context.context("Check the nested file status.", logging.info) file_s, file_o = session.cmd_status_output("cat " + nested_file) if re.match(r"[1Y]", file_o) and is_kvm_mode: logging.info("Guest runs with nested flag, the nested feature has " "been enabled.") elif file_s == 1 and not is_kvm_mode: logging.info("Guest runs without nested flag, so the nested file " "does not exist.") else: logging.error("Nested file status: %s, output: %s", file_s, file_o) test.fail("Getting the status of nested file has unexpected " "result.") finally: session.cmd("rm -f " + stderr_file, ignore_all_errors=True) session.close()
def create_host_os_cfg(options): def _forced_or_detected(forced, detected): if forced: return forced else: return detected host_os_cfg_path = data_dir.get_backend_cfg_path( get_opt(options, 'vt.type'), 'host.cfg') with open(host_os_cfg_path, 'w') as cfg: detected = distro.detect() name = host_os_get_distro_name(options, detected) version = _forced_or_detected( get_opt(options, 'vt_host_distro_version'), "m%s" % detected.version) release = _forced_or_detected( get_opt(options, 'vt_host_distro_release'), "u%s" % detected.release) arch = _forced_or_detected(get_opt(options, 'vt_host_distro_arch'), "Host_arch_%s" % detected.arch) vendor = cpu.get_vendor() if hasattr( cpu, 'get_vendor') else cpu.get_cpu_vendor_name() family = None if hasattr(cpu, 'get_family'): try: family = cpu.get_family() except Exception: pass cpu_version = cpu.get_version() if hasattr(cpu, 'get_version') else None # Replace special chars with _ to avoid bootstrap failure cpu_version = re.sub(r'[^\w-]', '_', cpu_version) if cpu_version else cpu_version cfg.write("variants:\n") cfg.write(" - @Host:\n") cfg.write(" variants:\n") cfg.write(" - @%s:\n" % name) cfg.write(" variants:\n") cfg.write(" - @%s:\n" % version) cfg.write(" variants:\n") cfg.write(" - @%s:\n" % release) cfg.write(" variants:\n") cfg.write(" - @%s:\n" % arch) if vendor: cfg.write("variants:\n") cfg.write(" - @HostCpuVendor:\n") cfg.write(" variants:\n") cfg.write(" - @%s:\n" % vendor) if family: cfg.write("variants:\n") cfg.write(" - @HostCpuFamily:\n") cfg.write(" variants:\n") cfg.write(" - @%s:\n" % family) if cpu_version: cfg.write(" variants:\n") cfg.write(" - @HostCpuVersion:\n") cfg.write(" variants:\n") cfg.write(" - @%s:\n" % cpu_version) count = [ get_opt(options, 'vt_host_distro_name'), get_opt(options, 'vt_host_distro_version'), get_opt(options, 'vt_host_distro_release'), get_opt(options, 'vt_host_distro_arch') ].count(None) if count == 4: source = "distro detection" elif count == 0: source = "command line parameters" else: source = "distro detection and command line parameters" LOG.debug("Config file %s generated from %s", host_os_cfg_path, source)
def run(test, params, env): """ Test hotplug maximum vCPU device. 1) Launch a guest without vCPU device. 2) Hotplug all vCPU devices and check successfully or not. (qemu side) 3) Check if the number of CPUs in guest changes accordingly. (guest side) 4) Reboot guest. 5) Hotunplug all vCPU devices and check successfully or not. (qemu side) :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ os_type = params["os_type"] machine_type = params["machine_type"] reboot_timeout = params.get_numeric("reboot_timeout") mismatch_text = "Actual number of guest CPUs is not equal to the expected" not_equal_text = "CPU quantity mismatched! Guest got %s but expected is %s" # Many vCPUs will be plugged, it takes some time to bring them online. verify_wait_timeout = params.get_numeric("verify_wait_timeout", 300) qemu_binary = utils_misc.get_qemu_binary(params) machine_info = utils_qemu.get_machines_info(qemu_binary)[machine_type] machine_info = re.search(r'\(alias of (\S+)\)', machine_info) current_machine = machine_info.group(1) if machine_info else machine_type supported_maxcpus = (params.get_numeric("vcpu_maxcpus") or utils_qemu.get_maxcpus_hard_limit( qemu_binary, current_machine)) if not params.get_boolean("allow_pcpu_overcommit"): supported_maxcpus = min(supported_maxcpus, cpu.online_count()) logging.info("Define the CPU topology of guest") vcpu_devices = [] if (cpu.get_vendor() == "amd" and params.get_numeric("vcpu_threads") != 1): test.cancel("AMD cpu does not support multi threads") elif machine_type.startswith("pseries"): host_kernel_ver = uname()[2].split("-")[0] if params.get_numeric("vcpu_threads") == 8: supported_maxcpus -= divmod(supported_maxcpus, 8)[1] vcpu_devices = [ "vcpu%d" % c for c in range(1, supported_maxcpus // 8) ] # The maximum value of vcpu_id in 'linux-3.x' is 2048, so # (vcpu_id * ms->smp.threads / spapr->vsmt) <= 256, need to adjust it elif (supported_maxcpus > 256 and host_kernel_ver not in VersionInterval("[4, )")): supported_maxcpus = 256 vcpu_devices = vcpu_devices or [ "vcpu%d" % vcpu for vcpu in range(1, supported_maxcpus) ] params["vcpu_maxcpus"] = str(supported_maxcpus) params["vcpu_devices"] = " ".join(vcpu_devices) params["start_vm"] = "yes" vm = env.get_vm(params["main_vm"]) vm.create(params=params) vm.verify_alive() session = vm.wait_for_login() cpuinfo = vm.cpuinfo smp = cpuinfo.smp vcpus_count = vm.params.get_numeric("vcpus_count") error_context.context("Hotplug all vCPU devices", logging.info) for vcpu_device in vcpu_devices: vm.hotplug_vcpu_device(vcpu_device) error_context.context("Check Number of vCPU in guest", logging.info) if not utils_misc.wait_for(lambda: vm.get_cpu_count() == supported_maxcpus, verify_wait_timeout, first=5, step=10): logging.error(not_equal_text, vm.get_cpu_count(), supported_maxcpus) test.fail(mismatch_text) logging.info("CPU quantity is as expected: %s", supported_maxcpus) error_context.context("Check CPU topology of guest", logging.info) if not cpu_utils.check_guest_cpu_topology(session, os_type, cpuinfo): test.fail("CPU topology of guest is not as expected.") session = vm.reboot(session, timeout=reboot_timeout) if not cpu_utils.check_guest_cpu_topology(session, os_type, cpuinfo): test.fail("CPU topology of guest is not as expected after reboot.") error_context.context("Hotunplug all vCPU devices", logging.info) for vcpu_device in reversed(vcpu_devices): vm.hotunplug_vcpu_device(vcpu_device, 10 * vcpus_count) if not utils_misc.wait_for(lambda: vm.get_cpu_count() == smp, verify_wait_timeout, first=5, step=10): logging.error(not_equal_text, vm.get_cpu_count(), smp) test.fail(mismatch_text) logging.info("CPU quantity is as expected after hotunplug: %s", smp) session.close()
def test_cpu_vendor_power9(self): with unittest.mock.patch('builtins.open', return_value=self._get_data_mock('power9')): self.assertEqual(cpu.get_vendor(), "ibm")
def test_cpu_vendor_intel(self): with unittest.mock.patch('builtins.open', return_value=self._get_data_mock('x86_64')): self.assertEqual(cpu.get_vendor(), "intel")
def run(test, params, env): """ Nested test: 1) Boot VM 2) Install ansible and related packages 3) Generate inventory file with L1 guest IP 4) Generate parameter file with parameters for tests on L2 guest 5) Execute ansible command :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ setup_bridge_sh = "/root/setup_bridge.sh" def get_live_vms(env): live_vms = [] for vm in env.get_all_vms(): if vm.is_alive(): live_vms.append(vm) if not live_vms: test.fail("No live VM.") return live_vms def generate_invent_file(env): vms = get_live_vms(env) tmp_dir = virttest_data_dir.get_tmp_dir() file_name = "inventory_file" ip_lst = list(map(lambda v: v.wait_for_get_address(0, 240), vms)) invent_file = open(os.path.join(tmp_dir, file_name), "w") invent_file.writelines(ip_lst) invent_file.close() return invent_file.name def copy_network_script(env): login_timeout = params.get_numeric("login_timeout", 360) deps_dir = virttest_data_dir.get_deps_dir() file_name = os.path.basename(setup_bridge_sh) br_file = os.path.join(deps_dir, file_name) for vm in get_live_vms(env): vm.wait_for_login(timeout=login_timeout) vm.copy_files_to(br_file, setup_bridge_sh) def generate_parameter_file(params): tmp_dir = virttest_data_dir.get_tmp_dir() file_name = "parameter_file" guest_password = params.get("password") bootstrap_options = params.get("nested_bs_options") accept_cancel = params.get_boolean("accept_cancel") kar_cmd = "python3 ./ConfigTest.py " test_type = params.get("test_type") variant_name = params.get("nested_test") case_name = params.get("case_name", "") if variant_name == "check_cpu_model_l2": host_cpu_models = virttest_cpu.get_host_cpu_models() case_name = ','.join(["%s.%s" % (case_name, i) for i in host_cpu_models]) kar_cmd += " --%s=%s " % (test_type, case_name) l2_guest_name = params.get("l2_guest_name") if l2_guest_name: kar_cmd += " --guestname=%s" % l2_guest_name clone = params.get("install_node") if clone == "yes": kar_cmd += " --clone=yes" else: kar_cmd += " --clone=no" l2_kar_options = params.get("l2_kar_options") if l2_kar_options: kar_cmd += " %s" % l2_kar_options logging.info("Kar cmd: %s", kar_cmd) results_dir = test.logdir logging.info("Result_dir: %s", results_dir) kar_repo = params.get("kar_repo") cert_url = params.get("cert_url") data = {"guest_password": guest_password, "bootstrap_options": bootstrap_options, "accept_cancel": accept_cancel, "command_line": kar_cmd, "setup_br_sh": setup_bridge_sh, "host_log_files_dir": results_dir, "kar_repo": kar_repo, "cert_url": cert_url} json_file = open(os.path.join(tmp_dir, file_name), "w") json.dump(data, json_file) json_file.close() return json_file.name if (params.get('check_vendor', 'no') == 'yes' and cpu.get_vendor() != 'intel'): test.cancel("We only test this case with Intel platform now") sm = software_manager.SoftwareManager() if not sm.check_installed("ansible"): sm.install("ansible") invent_file = generate_invent_file(env) copy_network_script(env) deps_dir = virttest_data_dir.get_deps_dir() playbook_file = os.path.join(deps_dir, "playbook.yml") params_file = generate_parameter_file(params) ansible_cmd = "export ANSIBLE_SSH_ARGS=\"-C -o ControlMaster=auto " \ "-o ControlPersist=60s " \ "-o StrictHostKeyChecking=no " \ "-o UserKnownHostsFile=/dev/null\"; " \ "ansible-playbook %s " \ "--extra-vars \"@%s\" " \ "-i %s " \ % (playbook_file, params_file, invent_file) logging.debug("ansible cmd: %s", ansible_cmd) timeout = float(params.get("test_timeout", 3600)) status, output = process.getstatusoutput(ansible_cmd, timeout) if status != 0: test.fail("ansible_cmd failed, status: %s, output: %s" % (status, output))
def test_cpu_vendor_power8(self): with unittest.mock.patch( "builtins.open", return_value=self._get_data_mock("power8") ): self.assertEqual(cpu.get_vendor(), "ibm")