def run(test, params, env): """ Hot-plug virtio-serial-pci and virtserialport 1. Boot a guest with 2 chardev, no serial port & no pci 2. Hot plug virtio-serial-bus 3. Hot add virtserialport, attached on chardev 1 4. Hot plug another serial port on chardev 2 with "nr=1", should fail 5. Hot plug the serial port again with "nr=2" 6. Transfer data from host to guest via port1 7. Transfer data from guest to host via port2 :param test: kvm test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment """ params['serials'] = params.objects('serials')[0] vm = env.get_vm(params['main_vm']) char_devices = add_chardev(vm, params) for device in char_devices: extra_params = ' ' + device.cmdline() params['extra_params'] = params.get('extra_params', '') + extra_params params['start_vm'] = "yes" env_process.preprocess(test, params, env) vm = env.get_vm(params['main_vm']) vm.devices.insert(char_devices) serials = params.objects('extra_serials') buses = [] serial_devices = [] for index, serial_id in enumerate(serials): chardev_id = char_devices[index].get_qid() params['serial_name_%s' % serial_id] = serial_id devices = add_virtserial_device(vm, params, serial_id, chardev_id) for device in devices: if device.child_bus: buses.append(device) else: serial_devices.append(device) vm.devices.simple_hotplug(buses[0], vm.monitor) vm.devices.simple_hotplug(serial_devices[0], vm.monitor) pre_nr = serial_devices[0].get_param('nr') # Try hotplug different device with same 'nr' serial_devices[1].set_param('bus', serial_devices[0].get_param('bus')) serial_devices[1].set_param('nr', pre_nr) try: serial_devices[1].hotplug(vm.monitor) except QMPCmdError as e: if 'A port already exists at id %d' % pre_nr not in str(e.data): test.fail('Hotplug fail for %s, not as expected' % str(e.data)) else: test.fail('Hotplug with same "nr" option success while should fail') serial_devices[1].set_param('nr', int(pre_nr) + 1) vm.devices.simple_hotplug(serial_devices[1], vm.monitor) for device in serial_devices: add_virtio_ports_to_vm(vm, params, device) params['file_transfer_serial_port'] = serials[0] transfer_data(params, vm, sender='host') params['file_transfer_serial_port'] = serials[1] transfer_data(params, vm, sender='guest')
def run(test, params, env): """ acpi description of serial and parallel ports incorrect with -chardev/-device: 1) Check device resources(io port and irq) on host 2) Boot guest A with isa-serial with tty chardev backend 3) Check device resources inside guest A 4) Boot guest B with -serial /dev/ttyS0 5) Check device resources inside guest B 6) Check if the result are same for host, A and B. :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ outputs = [] check_cmd = params['check_cmd'] host_output = process.getoutput(check_cmd)[:35] outputs.append(host_output) for x in range(2): if x >= 1: params['serials'] = " ".join(params['serials'].split()[:-1]) params['extra_params'] = params.get('extra_params', '') + ' -serial /dev/ttyS0' env_process.preprocess(test, params, env) vm = env.get_vm(params["main_vm"]) session = vm.wait_for_login() vm_output = session.cmd_status_output(check_cmd)[1][:35] outputs.append(vm_output) vm.destroy() assert outputs.count(outputs[0]) == len(outputs), \ "Host: {} and VM 1: {} and VM 2: {} are not the same".\ format(outputs[0], outputs[1], outputs[2])
def run(test, params, env): """ KVM reboot test: 1) Log into a guest with virtio data disk 2) Format the disk and copy file to it 3) Stop the guest and boot up it again with the data disk set to readonly 4) Try to copy file to the data disk 5) Try to copy file from the data disk :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ error.context("Try to log into guest.", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = float(params.get("login_timeout", 240)) session = vm.wait_for_login(timeout=timeout) vols = utils_misc.get_winutils_vol(session) if not vols: raise error.TestError("Can not find winutils in guest.") filen = 0 error.context("Format the disk and copy file to it", logging.info) os_type = params["os_type"] copy_cmd = params.get("copy_cmd", "copy %s %s") disk_idx = params.get("disk_index", 1) fs_type = params.get("fstype", "ntfs") drive_letter = params.get("drive_letter", "I") disk_size = params.get("partition_size_data", "200M") src_file = params.get("src_file", "").replace("WIN_UTIL", vols) utils_misc.format_guest_disk(session, disk_idx, drive_letter, disk_size, fs_type, os_type) dst_file = drive_letter + ":\\" + str(filen) session.cmd(copy_cmd % (src_file, dst_file)) filen += 1 msg = "Stop the guest and boot up it again with the data disk" msg += " set to readonly" error.context(msg, logging.info) session.close() vm.destroy() data_img = params.get("images").split()[-1] params["image_readonly_%s" % data_img] = "yes" params["force_create_image_%s" % data_img] = "no" env_process.preprocess(test, params, env) vm = env.get_vm(params["main_vm"]) vm.verify_alive() session = vm.wait_for_login(timeout=timeout) try: error.context("Try to write to the readonly disk", logging.info) dst_file_readonly = drive_letter + ":\\" + str(filen) session.cmd(copy_cmd % (src_file, dst_file_readonly)) raise error.TestFail("Write in readonly disk should failed.") except aexpect.ShellCmdError: error.context("Try to read from the readonly disk", logging.info) session.cmd(copy_cmd % (dst_file, "C:\\")) session.close()
def run(test, params, env): """ Test Step: 1. boot guest with vhost enabled 2. add vhost-%pid_qemu process to a cgroup 3. check the vhost process join to the cgroup successfully :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ def assign_vm_into_cgroup(vm, cgroup, pwd=None): """ Assigns all threads of VM into cgroup :param vm: desired VM :param cgroup: cgroup handler :param pwd: desired cgroup's pwd, cgroup index or None for root cgroup """ cgroup.set_cgroup(vm.get_shell_pid(), pwd) for pid in utils.get_children_pids(vm.get_shell_pid()): try: cgroup.set_cgroup(int(pid), pwd) except Exception: # Process might not already exist raise error.TestFail("Failed to move all VM threads to cgroup") error.context("Test Setup: Cgroup initialize in host", logging.info) modules = CgroupModules() if (modules.init(['cpu']) != 1): raise error.TestFail("Can't mount cpu cgroup modules") cgroup = Cgroup('cpu', '') cgroup.initialize(modules) error.context("Boot guest and attach vhost to cgroup your setting(cpu)", logging.info) params["start_vm"] = "yes" preprocess(test, params, env) vm = env.get_vm(params["main_vm"]) timeout = int(params.get("login_timeout", 360)) vm.wait_for_login(timeout=timeout) cgroup.mk_cgroup() cgroup.set_property("cpu.cfs_period_us", 100000, 0) assign_vm_into_cgroup(vm, cgroup, 0) vhost_pids = utils.system_output("pidof vhost-%s" % vm.get_pid()) if not vhost_pids: raise error.TestError("Vhost process not exise") logging.info("Vhost have started with pid %s" % vhost_pids) for vhost_pid in vhost_pids.strip().split(): cgroup.set_cgroup(int(vhost_pid)) error.context("Check whether vhost attached to cgroup successfully", logging.info) cgroup_tasks = " ".join(cgroup.get_property("tasks")) for vhost_pid in vhost_pids.strip().split(): if vhost_pid not in cgroup_tasks: raise error.TestError("vhost process attach to cgroup FAILED!" " Tasks in cgroup is:%s" % cgroup_tasks) logging.info("Vhost process attach to cgroup successfully")
def do_test(test, params, env): """ Do ping test, check msi support and do file transfer :param session: guest session :param vm: guest vm """ login_timeout = int(params.get("login_timeout", 360)) env_process.preprocess(test, params, env) vm = env.get_vm(params["main_vm"]) vm.verify_alive() session = vm.wait_for_login(timeout=login_timeout) guest_ip = vm.get_address() ping_count = int(params.get("ping_count", 0)) if not ping_count == 0: 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 server" % package_lost) check_msi_support(session) if params.get("do_file_transfer", "no") == "yes": utils_test.run_file_transfer(test, params, env) session.close() vm.destroy(gracefully=True)
def run(test, params, env): """ acpi description of serial and parallel ports incorrect with -chardev/-device: 1) Boot guest A with isa-serial with tty chardev backend 2) Enter into guest A udevadm info --query path --name /dev/ttyS0 !! --attribute-walk | grep looking 3) Boot guest B with -serial /dev/ttyS0 4) repeat step 2 for guest B 5) Check if the result are same for A and B. :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ outputs = [] guest_cmd = params['guest_cmd'] for x in range(2): if x >= 1: params['serials'] = " ".join(params['serials'].split()[:-1]) params['extra_params'] = params.get('extra_params', '') + ' -serial /dev/ttyS0' env_process.preprocess(test, params, env) vm = env.get_vm(params["main_vm"]) session = vm.wait_for_login() vm_output1 = session.cmd_status_output(guest_cmd) # !! cannot be used because of echo $? vm_output2 = session.cmd_status_output( "{} --attribute-walk | grep looking".format(guest_cmd)) outputs.append([vm_output1, vm_output2]) vm.destroy() assert outputs.count(outputs[0]) == len( outputs), 'output 1: {} and output 2: {} are not the same'.format( outputs[0], outputs[1])
def run(test, params, env): """ qemu should try to find a free port value by to=<port> with unix socket and tcp options: 1) boot guest with socket 'host=127.0.0.1,port=num' 2) query chardev and check port number 3) boot another guest with socket 'host=127.0.0.1,port=num,to=num+' 4) query chardev and check port number, should different from 2) :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ chardev_infos = [] vms = params.get("vms").split() _vm = env.get_vm(vms[0]) char_device = add_chardev(_vm, params)[0] chardev_params = char_device.params for vm_ind, vm in enumerate(vms): if vm_ind == 1: host = chardev_params['host'] chardev_to = utils_misc.find_free_ports( int(chardev_params['port']) + 1, 6000, 1, host) chardev_params['to'] = str(chardev_to[0]) extra_params = ' ' + char_device.cmdline() params['extra_params_%s' % vm] = params.get('extra_params', '') + extra_params params['start_vm_%s' % vm] = "yes" env_process.preprocess(test, params, env) for vm in vms: _vm = env.get_vm(vm) chardev_infos.append(_vm.monitor.info("chardev")) _port, _to = int(chardev_params['port']), int(chardev_params['to']) for char_ind, chardevs in enumerate(chardev_infos): in_chardev = False for chardev in chardevs: if chardev['label'] == chardev_params['id']: tmp_pnum = int( chardev['filename'].split(':')[-1].split(',')[0]) error_context.context( "Get port %d for vm%d from monitor" % (tmp_pnum, char_ind), logging.info) break if char_ind == 0: error_context.context( "The expect port for vm%d is %d" % (char_ind, _port), logging.info) if tmp_pnum == _port: in_chardev = True else: error_context.context( "The expect port for vm%d is in [%d, %d]" % (char_ind, _port + 1, _to), logging.info) if tmp_pnum > _port and tmp_pnum <= _to: in_chardev = True assert in_chardev is True, 'The actual port does not match with the expect port in VM %d' % char_ind
def run(test, params, env): """ boot with different machine type: 1) get supported machine type 2) boot guest with different machine types :param test: kvm test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ error_context.context("Get supported machine type", logging.info) qemu_binary = utils_misc.get_qemu_binary(params) machine_types = [] machine_type_mapping = { "pc": ["i440FX", "RHEL 6"], "q35": ["Q35"], "pseries": ["pSeries"], "arm64-pci:virt": ["ARM"], "arm64-mmio:virt": ["ARM"], "s390-ccw-virtio": ["S390"] } for m_type, s_name in zip( *utils_misc.get_support_machine_type(qemu_binary)[:2]): for item in machine_type_mapping[params["machine_type"]]: if item in s_name: if "arm64" in params["machine_type"]: m_type = re.sub(r'(?<=:)\w+', m_type, params["machine_type"]) machine_types.append(m_type) if not machine_types: test.fail("Failed to get machine types") else: logging.info("Actual supported machine types are: %s", ', '.join(map(str, machine_types))) for m_type in machine_types: params["machine_type"] = m_type params["start_vm"] = "yes" vm_name = params['main_vm'] error_context.context("Start vm with machine type '%s'" % m_type, logging.info) env_process.preprocess(test, params, env) vm = env.get_vm(vm_name) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) if not session.is_responsive(): session.close() test.fail("Start vm with machine type:%s fail" % m_type) session.close() error_context.context( "Quit guest and check the process quit normally", logging.info) vm.destroy(gracefully=False)
def run(test, params, env): """ Test TPM device by Windows Hardware Lab Kit(HLK). Steps: 1. Boot HLK server in windows guest. 2. Boot another windows guest with tpm-crb device as HLK client. 3. Installation HLK client inside guest. 4. Setup environment then run corresponding test cases inside HLK server guest. :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ server_img = download_hlk_server_image(params, params.get('hlk_server_image_uri')) vm_name_hlk_server = params.get('vm_name_hlk_server') params["images_%s" % vm_name_hlk_server] = "image0" params["image_name_image0_%s" % vm_name_hlk_server] = server_img['image_name'] params["image_size_image0_%s" % vm_name_hlk_server] = server_img['image_size'] params["image_format_image0_%s" % vm_name_hlk_server] = server_img['image_format'] params["start_vm"] = "yes" params["not_preprocess"] = "no" env_process.preprocess(test, params, env) vms = env.get_all_vms() for vm in vms: vm.verify_alive() if vm.name == vm_name_hlk_server: vm_server = vm else: vm_client = vm install_hlk_client(vm_client, vm_server) pool_name = params.get('hlk_pool_name') project_name = params.get('hlk_project_name') target_name = params.get('hlk_target_name') tests_name = [ name for name in params.get('hlk_target_tests_name').split(';') ] hlk_server = HLKServer(test, vm_server) hlk_server.simple_run_test(pool_name, project_name, target_name, tests_name, timeout=24000, step=600) hlk_server.close()
def run(test, params, env): """ [Memory][Numa] NUMA memdev option, this case will: 1) Check host's numa node(s). 2) Start the VM. 3) Check query-memdev. 4) Check the memory in procfs. :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment """ error_context.context("Check host's numa node(s)!", logging.info) valid_nodes = get_host_numa_node() if len(valid_nodes) < 2: test.cancel( "The host numa nodes that whose size is not zero should be " "at least 2! But there is %d." % len(valid_nodes)) node1 = valid_nodes[0] node2 = valid_nodes[1] if params.get('policy_mem') != 'default': error_context.context("Assign host's numa node(s)!", logging.info) params['host-nodes_mem0'] = node1 params['host-nodes_mem1'] = node2 if params.get('set_node_hugepage') == 'yes': hugepage_size = utils_memory.get_huge_page_size() normalize_total_hg1 = int(normalize_data_size(params['size_mem0'], 'K')) hugepage_num1 = normalize_total_hg1 // hugepage_size if 'numa_hugepage' in params['shortname']: params['target_nodes'] = "%s %s" % (node1, node2) normalize_total_hg2 = int( normalize_data_size(params['size_mem1'], 'K')) hugepage_num2 = normalize_total_hg2 // hugepage_size params['target_num_node%s' % node2] = hugepage_num2 else: params['target_nodes'] = node1 params['target_num_node%s' % node1] = hugepage_num1 params['setup_hugepages'] = 'yes' env_process.preprocess(test, params, env) error_context.context("Starting VM!", logging.info) env_process.preprocess_vm(test, params, env, params["main_vm"]) vm = env.get_vm(params["main_vm"]) vm.verify_alive() error_context.context("Check query-memdev!", logging.info) check_query_memdev(test, params, vm) error_context.context("Check the memory in procfs!", logging.info) check_memory_in_procfs(test, params, vm) vm.verify_dmesg()
def _boot_guest_with_cpu_flag(hv_flag): """ Boot the guest, with param cpu_model_flags set to hv_flag param hv_flag: the hv flags to set to cpu return: the booted vm """ params["cpu_model_flags"] = hv_flag params["start_vm"] = "yes" vm_name = params["main_vm"] env_process.preprocess(test, params, env) return env.get_vm(vm_name)
def run(test, params, env): """ boot with different machine type: 1) get supported machine type 2) boot guest with different machine types :param test: kvm test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ error_context.context("Get supported machine type", logging.info) qemu_binary = utils_misc.get_qemu_binary(params) machine_types = [] machine_type_mapping = {"pc": ["i440FX", "RHEL 6"], "q35": ["Q35"], "pseries": ["pSeries"], "arm64-pci:virt": ["ARM"], "arm64-mmio:virt": ["ARM"], "s390-ccw-virtio": ["S390"]} for m_type, s_name in zip(*utils_misc.get_support_machine_type(qemu_binary)): for item in machine_type_mapping[params["machine_type"]]: if item in s_name: if "arm64" in params["machine_type"]: m_type = re.sub(r'(?<=:)\w+', m_type, params["machine_type"]) machine_types.append(m_type) if not machine_types: test.fail("Failed to get machine types") else: logging.info("Actual supported machine types are: " + ', '.join(map(str, machine_types))) for m_type in machine_types: params["machine_type"] = m_type params["start_vm"] = "yes" vm_name = params['main_vm'] error_context.context("Start vm with machine type '%s'" % m_type, logging.info) env_process.preprocess(test, params, env) vm = env.get_vm(vm_name) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) if not session.is_responsive(): session.close() test.fail("Start vm with machine type:%s fail" % m_type) session.close() error_context.context("Quit guest and check the process quit normally", logging.info) vm.destroy(gracefully=False)
def run(test, params, env): """ Test guest with virtio-serial-device with multiple virtserialports Scenario 1: 1.1. Boot a guest with 1 virtio-serial-bus with 3 serial ports 1.2. Transfer data via every port Scenario 2: 2.1. Start guest with 2 virtio-serial-pci, 2.2. Each virtio-serial-pci has 3 virtio-serial-ports 2.3. Transfer data via every port :param test: kvm test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment """ if params.get("start_vm") == 'no': num_bus = params.get_numeric("numberic_bus") for i in range(2, num_bus + 1): serial_name = 'vs%d' % i params['serials'] = '%s %s' % (params.get('serials', ''), serial_name) params['serial_type_%s' % serial_name] = "virtserialport" params['serial_bus_%s' % serial_name] = "<new>" params['start_vm'] = "yes" env_process.preprocess(test, params, env) vm = env.get_vm(params['main_vm']) os_type = params["os_type"] if os_type == "windows": driver_name = params["driver_name"] session = vm.wait_for_login() session = utils_test.qemu.windrv_check_running_verifier( session, vm, test, driver_name) session.close() for port in params.objects("serials"): port_params = params.object_params(port) if not port_params['serial_type'].startswith('virtserial'): continue params['file_transfer_serial_port'] = port error_context.context("Transfer data with %s" % port, logging.info) transfer_data(params, vm, sender='both') vm.verify_alive() vm.verify_kernel_crash()
def run(test, params, env): """ Test cpu flag intel-pt. 1) Check if current flags are in the supported lists, if no, cancel test 2) Otherwise, set pt_mode = 1 on host at first 3) Boot guest with cpu model 'host' without intel-pt. 4) Check cpu flags in guest(only for linux guest) 5) For q35 5.1) boot guest with cpu model with intel-pt 6) For pc 6.1) boot guest with intel-pt and min-level=0x14 7) Check cpu flags in guest(only for linux guest) 8) Restore pt_mode value on host at last :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ flags = params["flags"] check_cpu_flags(params, flags, test) set_pt_mode = params.get("set_pt_mode") get_pt_mode = params.get("get_pt_mode") origin_value = process.getoutput(get_pt_mode).strip() try: if origin_value != '1': process.system(set_pt_mode % '1', shell=True) pt_mode = process.getoutput(get_pt_mode).strip() if pt_mode != '1': test.cancel("pt_mode can't be set to 1") params["start_vm"] = "yes" env_process.preprocess(test, params, env) vm = env.get_vm(params["main_vm"]) error_context.context("Try to log into guest", test.log.info) session = vm.wait_for_login() if params["os_type"] == "linux": check_cpu_flags(params, flags, test, session) vm.verify_kernel_crash() session.close() utils_misc.wait_for(vm.destroy, 240) finally: process.system(set_pt_mode % origin_value, shell=True)
def boot_guest_with_vectors(vectors): error_context.context("Boot guest with vectors = %s" % vectors, logging.info) params["vectors"] = vectors params["start_vm"] = "yes" try: env_process.preprocess(test, params, env) except virt_vm.VMError as err: if int(vectors) < 0: txt = "Parameter 'vectors' expects uint32_t" if re.findall(txt, str(err)): return if int(vectors) < 0: msg = "Qemu did not raise correct error" msg += " when vectors = %s" % vectors test.fail(msg) vm = env.get_vm(params["main_vm"]) vm.verify_alive() return vm
def run(test, params, env): """ Test virtio serial guest file transfer with max ports. Steps: 1) Boot up a VM with 30 virtserialports on one virtio-serial-pci. 2) Transfer data via these ports one by one. :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ num_serial_ports = int(params.get("virtio_serial_ports")) for i in range(2, num_serial_ports + 1): serial_name = 'vs%d' % i params['serials'] = '%s %s' % (params.get('serials', ''), serial_name) params['serial_type_%s' % serial_name] = "virtserialport" params['start_vm'] = "yes" env_process.preprocess(test, params, env) vm = env.get_vm(params['main_vm']) os_type = params["os_type"] if os_type == "windows": session = vm.wait_for_login() driver_name = params["driver_name"] session = utils_test.qemu.windrv_check_running_verifier( session, vm, test, driver_name) session.close() serials = params.objects("serials") for serial_port in serials: port_params = params.object_params(serial_port) if not port_params['serial_type'].startswith('virtserial'): continue test.log.info("transfer data with port %s", serial_port) params['file_transfer_serial_port'] = serial_port transfer_data(params, vm, sender='both') vm.verify_alive() vm.destroy()
def run(test, params, env): """ KVM readonly_floppy test: 1) pre_command on the host to generate the floppy media : "dd if=images/fd1.img bs=512 count=2880 && dd if=images/fd2.img bs=512 count=2880" 2) Boot and login into a guest; 3) If the OS is linux, load the floppy module, or if it is a Windows,wait 20s until the floppies are ready to be used 4) Make filesystem against the floppy and reads the output of the command,check if there is 'Read-only'(for linux) or 'protected'(for windows) keyword,if not,fail the test; 5) Close session to the VM :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ vt_data_dir = data_dir.get_data_dir() if params.get("start_vm") == "no": params["start_vm"] = "yes" params["pre_command"] = params.get("pre_cmd") % (vt_data_dir, vt_data_dir) env_process.preprocess(test, params, env) error_context.context("Boot up guest with floppies", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = float(params.get("login_timeout", 240)) session = vm.wait_for_login(timeout=timeout) sleep = params.get("sleep") # if it is a windows OS,wait for 20 seconds until the floppies # are ready for testing if sleep: logging.info("Windows system being tested,sleep for 20" " seconds until floppies are ready to be use") time.sleep(20) try: # if it is a linux OS,load the floppy module if not sleep: logging.info("Loading the floppy module...") status = session.cmd_status("modprobe floppy") logging.info("Sleep 5 seconds after loading the floppy module") time.sleep(5) if status: test.error("Unable to load the floppy module") # Format floppy disk to test if it is readonly floppy_count = len(params.get("floppies", "").split()) format_cmd_list = [params.get("format_floppy0_cmd"), params.get("format_floppy1_cmd")] for floppy_index in range(floppy_count): error_context.context("Format the %s floppy disk" % floppy_index, logging.info) s, o = session.cmd_status_output( format_cmd_list[floppy_index], timeout=float(params.get("format_floppy_timeout", 60))) if s == 0: test.error("Floppy disk %s is not readonly and" " it's formatted successfully" % floppy_index) error_context.context("Check the %s floppy is readonly" % floppy_index, logging.info) found = re.search('(Read-only)|(protected)', o) logging.debug("Output of format command: %s", o) if not found: test.error("Floppy disk %s cannot be formatted" " for reasons other than readonly" % floppy_index) else: logging.info("Floppy disk %s is Read-only and cannot be" " formatted", floppy_index) finally: if session: session.close()
def run(test, params, env): """ KVM reboot test: 1) Log into a guest with virtio data disk 2) Format the disk and copy file to it 3) Stop the guest and boot up it again with the data disk set to readonly 4) Try to copy file to the data disk 5) Try to copy file from the data disk :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ error_context.context( "TEST STEPS 1: Try to log into guest.", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = float(params.get("login_timeout", 240)) session = vm.wait_for_login(timeout=timeout) error_context.context( "TEST STEPS 2: Format the disk and copy file to it", logging.info) os_type = params["os_type"] copy_cmd = params.get("copy_cmd", "copy %s %s") fstype = params.get("fstype", "ntfs") data_image_size = params.get("image_size_data", "1G") data_image_num = int(params.get("data_image_num", len(params.objects("images")) - 1)) error_context.context("Get windows disk index that to " "be formatted", logging.info) disk_index_list = utils_disk.get_windows_disks_index(session, data_image_size) if len(disk_index_list) < data_image_num: test.fail("Fail to list all data disks. " "Set disk number: %d, " "get disk number in guest: %d." % (data_image_num, len(disk_index_list))) src_file = utils_misc.set_winutils_letter( session, params["src_file"], label="WIN_UTILS") error_context.context("Clear readonly for all disks and online " "them in guest.", logging.info) if not utils_disk.update_windows_disk_attributes(session, disk_index_list): test.fail("Failed to update windows disk attributes.") error_context.context("Format disk %s in guest." % disk_index_list[0], logging.info) drive_letter = utils_disk.configure_empty_disk( session, disk_index_list[0], data_image_size, os_type, fstype=fstype) if not drive_letter: test.fail("Fail to format disks.") dst_file = params["dst_file"] % drive_letter[0] session.cmd(copy_cmd % (src_file, dst_file)) msg = "TEST STEPS 3: Stop the guest and boot up again with the data disk" msg += " set to readonly" error_context.context(msg, logging.info) session.close() vm.destroy() data_img = params.get("images").split()[-1] params["image_readonly_%s" % data_img] = "yes" params["force_create_image_%s" % data_img] = "no" env_process.preprocess(test, params, env) vm = env.get_vm(params["main_vm"]) vm.verify_alive() session = vm.wait_for_login(timeout=timeout) error_context.context( "TEST STEPS 4: Write to the readonly disk expect:" "The media is write protected", logging.info) dst_file_readonly = params["dst_file_readonly"] % drive_letter[0] o = session.cmd_output(copy_cmd % (src_file, dst_file_readonly)) if not o.find("write protect"): test.fail("Write in readonly disk should failed\n. {}".format(o)) error_context.context( "TEST STEPS 5: Try to read from the readonly disk", logging.info) s, o = session.cmd_status_output(copy_cmd % (dst_file, r"C:\\")) if s != 0: test.fail("Read file failed\n. {}".format(o)) session.close()
def run(test, params, env): """ Network stress with multi nics test with netperf. 1) Start multi vm(s) guest. 2) Select multi vm(s) or host to setup netperf server/client. 3) Execute netperf stress on multi nics. 4) Ping test after netperf testing, check whether nics still work. :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ login_timeout = float(params.get("login_timeout", 360)) netperf_server = params.get("netperf_server").split() netperf_client = params.get("netperf_client") guest_username = params.get("username", "") guest_password = params.get("password", "") shell_client = params.get("shell_client") shell_port = params.get("shell_port") os_type = params.get("os_type") shell_prompt = params.get("shell_prompt", r"^root@.*[\#\$]\s*$|#") disable_firewall = params.get("disable_firewall", "") linesep = params.get("shell_linesep", "\n").encode().decode('unicode_escape') status_test_command = params.get("status_test_command", "echo $?") ping_count = int(params.get("ping_count", 10)) compile_option_client = params.get("compile_option_client", "") compile_option_server = params.get("compile_option_server", "") vms = params.get("vms") server_infos = [] client_infos = [] server_ips = [] client_ips = [] os_type = params.get("os_type") if os_type == "windows": host_mem = utils_memory.memtotal() // (1024 * 1024) vm_mem = host_mem / (len(vms.split()) + 1) * 1024 if vm_mem < params.get_numeric("min_mem"): test.cancel("Host total memory is insufficient for this test case," "each VM's memory can not meet guest OS's requirement") params["mem"] = vm_mem params["start_vm"] = "yes" env_process.preprocess(test, params, env) for server in netperf_server: s_info = {} if server in vms: server_vm = env.get_vm(server) server_vm.verify_alive() server_ctl = server_vm.wait_for_serial_login(timeout=login_timeout) error_context.context("Stop fireware on netperf server guest.", logging.info) server_ctl.cmd(disable_firewall, ignore_all_errors=True) server_ip = server_vm.get_address() server_ips.append(server_ip) s_info["ip"] = server_ip s_info["os_type"] = params.get("os_type_%s" % server, os_type) s_info["username"] = params.get("username_%s" % server, guest_username) s_info["password"] = params.get("password_%s" % server, guest_password) s_info["shell_client"] = params.get("shell_client_%s" % server, shell_client) s_info["shell_port"] = params.get("shell_port_%s" % server, shell_port) s_info["shell_prompt"] = params.get("shell_prompt_%s" % server, shell_prompt) s_info["linesep"] = params.get("linesep_%s" % server, linesep) s_info["status_test_command"] = params.get( "status_test_command_%s" % server, status_test_command) else: err = "Only support setup netperf server in guest." test.error(err) server_infos.append(s_info) client = netperf_client.strip() c_info = {} if client in vms: client_vm = env.get_vm(client) client_vm.verify_alive() client_ctl = client_vm.wait_for_serial_login(timeout=login_timeout) if params.get("dhcp_cmd"): status, output = client_ctl.cmd_status_output(params["dhcp_cmd"], timeout=600) if status: logging.warn("Failed to execute dhcp-command, output:\n %s", output) error_context.context("Stop fireware on netperf client guest.", logging.info) client_ctl.cmd(disable_firewall, ignore_all_errors=True) client_ip = client_vm.get_address() client_ips.append(client_ip) params_client_nic = params.object_params(client) nics_count = len(params_client_nic.get("nics", "").split()) if nics_count > 1: for i in range(nics_count)[1:]: client_vm.wait_for_login(nic_index=i, timeout=login_timeout) client_ips.append(client_vm.get_address(index=i)) c_info["ip"] = client_ip c_info["os_type"] = params.get("os_type_%s" % client, os_type) c_info["username"] = params.get("username_%s" % client, guest_username) c_info["password"] = params.get("password_%s" % client, guest_password) c_info["shell_client"] = params.get("shell_client_%s" % client, shell_client) c_info["shell_port"] = params.get("shell_port_%s" % client, shell_port) c_info["shell_prompt"] = params.get("shell_prompt_%s" % client, shell_prompt) c_info["linesep"] = params.get("linesep_%s" % client, linesep) c_info["status_test_command"] = params.get( "status_test_command_%s" % client, status_test_command) else: err = "Only support setup netperf client in guest." test.error(err) client_infos.append(c_info) if params.get("os_type") == "linux": error_context.context("Config static route in netperf server guest.", logging.info) nics_list = utils_net.get_linux_ifname(client_ctl) for ip in server_ips: index = server_ips.index(ip) % len(nics_list) client_ctl.cmd("route add -host %s %s" % (ip, nics_list[index])) netperf_link = params.get("netperf_link") netperf_link = os.path.join(data_dir.get_deps_dir("netperf"), netperf_link) md5sum = params.get("pkg_md5sum") netperf_server_link = params.get("netperf_server_link_win", netperf_link) netperf_server_link = os.path.join(data_dir.get_deps_dir("netperf"), netperf_server_link) server_md5sum = params.get("server_md5sum") netperf_client_link = params.get("netperf_client_link_win", netperf_link) netperf_client_link = os.path.join(data_dir.get_deps_dir("netperf"), netperf_client_link) client_md5sum = params.get("client_md5sum") server_path_linux = params.get("server_path", "/var/tmp") client_path_linux = params.get("client_path", "/var/tmp") server_path_win = params.get("server_path_win", "c:\\") client_path_win = params.get("client_path_win", "c:\\") netperf_clients = [] netperf_servers = [] error_context.context("Setup netperf guest.", logging.info) for c_info in client_infos: if c_info["os_type"] == "windows": netperf_link_c = netperf_client_link client_path = client_path_win md5sum = client_md5sum else: netperf_link_c = netperf_link client_path = client_path_linux n_client = utils_netperf.NetperfClient( c_info["ip"], client_path, md5sum, netperf_link_c, client=c_info["shell_client"], port=c_info["shell_port"], username=c_info["username"], password=c_info["password"], prompt=c_info["shell_prompt"], linesep=c_info["linesep"], status_test_command=c_info["status_test_command"], compile_option=compile_option_client) netperf_clients.append(n_client) error_context.context("Setup netperf server.", logging.info) for s_info in server_infos: if s_info["os_type"] == "windows": netperf_link_s = netperf_server_link server_path = server_path_win md5sum = server_md5sum else: netperf_link_s = netperf_link server_path = server_path_linux n_server = utils_netperf.NetperfServer( s_info["ip"], server_path, md5sum, netperf_link_s, client=s_info["shell_client"], port=s_info["shell_port"], username=s_info["username"], password=s_info["password"], prompt=s_info["shell_prompt"], linesep=s_info["linesep"], status_test_command=s_info["status_test_command"], compile_option=compile_option_server) netperf_servers.append(n_server) try: error_context.context("Start netperf server.", logging.info) for n_server in netperf_servers: n_server.start() test_duration = int(params.get("netperf_test_duration", 60)) test_protocols = params.get("test_protocols", "TCP_STREAM") netperf_sessions = params.get("netperf_sessions", "1") p_sizes = params.get("package_sizes") netperf_cmd_prefix = params.get("netperf_cmd_prefix", "") error_context.context("Start netperf clients.", logging.info) for protocol in test_protocols.split(): error_context.context("Testing %s protocol" % protocol, logging.info) sessions_test = netperf_sessions.split() sizes_test = p_sizes.split() for size in sizes_test: for sess in sessions_test: test_option = params.get("test_option", "") test_option += " -t %s -l %s " % (protocol, test_duration) test_option += " -- -m %s" % size launch_netperf_client(test, server_ips, netperf_clients, test_option, test_duration, sess, netperf_cmd_prefix, params) error_context.context("Ping test after netperf testing.", logging.info) for s_ip in server_ips: status, output = utils_test.ping(s_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 server ip %s " % (package_lost, server)) finally: for n_server in netperf_servers: n_server.stop() n_server.cleanup(True) for n_client in netperf_clients: n_client.stop() n_client.cleanup(True) if server_ctl: server_ctl.close() if client_ctl: client_ctl.close()
def run(test, params, env): """ Ansible playbook basic test: 1) Check ansible-playbook exists and try to install it if not exists 2) Launch the guest if ansible-playbook program exists 3) Clone an ansible playbook repo 4) Generate the ansible-playbook command 5) Execute the playbook and verify the return status :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ # check ansible-playbook program if not ansible.check_ansible_playbook(params): test.cancel("No available ansible-playbook program") guest_user = params["username"] guest_passwd = params["password"] step_time = params.get_numeric("step_time", 60) ansible_callback_plugin = params.get("ansible_callback_plugin") ansible_addl_opts = params.get("ansible_addl_opts", "") ansible_ssh_extra_args = params["ansible_ssh_extra_args"] ansible_extra_vars = params.get("ansible_extra_vars", "{}") custom_extra_vars = params.objects("custom_extra_vars") playbook_repo = params["playbook_repo"] playbook_timeout = params.get_numeric("playbook_timeout") playbook_dir = params.get("playbook_dir", os.path.join(test.workdir, "ansible_playbook")) toplevel_playbook = os.path.join(playbook_dir, params["toplevel_playbook"]) # Use this directory to copy some logs back from the guest test_harness_log_dir = test.logdir # Responsive migration specific parameters mq_listen_port = params.get_numeric("mq_listen_port", find_free_port()) wait_response_timeout = params.get_numeric("wait_response_timeout", 600) params['start_vm'] = 'yes' env_process.preprocess(test, params, env) vms = env.get_all_vms() guest_ip_list = [] for vm in vms: vm.verify_alive() vm.wait_for_login() guest_ip_list.append(vm.get_address()) test.log.info("Cloning %s", playbook_repo) process.run("git clone {src} {dst}".format(src=playbook_repo, dst=playbook_dir), verbose=False) error_context.base_context("Generate playbook related options.", test.log.info) extra_vars = {"ansible_ssh_extra_args": ansible_ssh_extra_args, "ansible_ssh_pass": guest_passwd, "mq_port": mq_listen_port, "test_harness_log_dir": test_harness_log_dir} extra_vars.update(json.loads(ansible_extra_vars)) custom_params = params.object_params("extra_vars") for cev in custom_extra_vars: extra_vars[cev] = custom_params[cev] error_context.context("Execute the ansible playbook.", test.log.info) playbook_executor = ansible.PlaybookExecutor( inventory="{},".format(",".join(guest_ip_list)), site_yml=toplevel_playbook, remote_user=guest_user, extra_vars=json.dumps(extra_vars), callback_plugin=ansible_callback_plugin, addl_opts=ansible_addl_opts ) mq_publisher = message_queuing.MQPublisher(mq_listen_port) try: error_context.base_context('Confirm remote subscriber has accessed to ' 'activate migrating guests.', test.log.info) try: mq_publisher.confirm_access(wait_response_timeout) except message_queuing.MessageNotFoundError as err: test.log.error(err) test.fail("Failed to capture the 'ACCESS' message.") test.log.info("Already captured the 'ACCESS' message.") error_context.context("Migrate guests after subscriber accessed.", test.log.info) for vm in vms: vm.migrate() except VMMigrateFailedError: error_context.context("Send the 'ALERT' message to notify the remote " "subscriber to stop the test.", test.log.info) mq_publisher.alert() raise else: error_context.context("Send the 'APPROVE' message to notify the remote " "subscriber to continue the test.", test.log.info) mq_publisher.approve() finally: ansible_log = "ansible_playbook.log" try: playbook_executor.wait_for_completed(playbook_timeout, step_time) except ansible.ExecutorTimeoutError as err: test.error(str(err)) else: if playbook_executor.get_status() != 0: test.fail("Ansible playbook execution failed, please check the " "{} for details.".format(ansible_log)) test.log.info("Ansible playbook execution passed.") finally: playbook_executor.store_playbook_log(test_harness_log_dir, ansible_log) playbook_executor.close() mq_publisher.close()
def run_once(self, params): # Convert params to a Params object params = utils_params.Params(params) # If a dependency test prior to this test has failed, let's fail # it right away as TestNA. if params.get("dependency_failed") == 'yes': raise error.TestNAError("Test dependency failed") # Report the parameters we've received and write them as keyvals logging.debug("Test parameters:") keys = params.keys() keys.sort() for key in keys: logging.debug(" %s = %s", key, params[key]) self.write_test_keyval({key: params[key]}) # Set the log file dir for the logging mechanism used by kvm_subprocess # (this must be done before unpickling env) utils_misc.set_log_file_dir(self.debugdir) # Open the environment file env_filename = os.path.join(self.bindir, params.get("vm_type"), params.get("env", "env")) env = utils_env.Env(env_filename, self.env_version) test_passed = False try: try: try: subtest_dirs = [] tests_dir = self.job.testdir other_subtests_dirs = params.get("other_tests_dirs", "") for d in other_subtests_dirs.split(): # Replace split char. d = os.path.join(*d.split("/")) subtestdir = os.path.join(tests_dir, d, "tests") if not os.path.isdir(subtestdir): raise error.TestError("Directory %s not" " exist." % (subtestdir)) subtest_dirs.append(subtestdir) # Verify if we have the correspondent source file for it virt_dir = os.path.dirname(self.virtdir) subtest_dirs.append(os.path.join(virt_dir, "tests")) subtest_dirs.append(os.path.join(self.bindir, params.get("vm_type"), "tests")) subtest_dir = None # Get the test routine corresponding to the specified # test type t_types = params.get("type").split() test_modules = [] for t_type in t_types: for d in subtest_dirs: module_path = os.path.join(d, "%s.py" % t_type) if os.path.isfile(module_path): subtest_dir = d break if subtest_dir is None: msg = ("Could not find test file %s.py on tests" "dirs %s" % (t_type, subtest_dirs)) raise error.TestError(msg) # Load the test module f, p, d = imp.find_module(t_type, [subtest_dir]) test_modules.append((t_type, imp.load_module(t_type, f, p, d))) f.close() # Preprocess try: env_process.preprocess(self, params, env) finally: env.save() # Run the test function for t_type, test_module in test_modules: msg = "Running function: %s.run_%s()" % (t_type, t_type) logging.info(msg) run_func = getattr(test_module, "run_%s" % t_type) try: run_func(self, params, env) self.verify_background_errors() finally: env.save() test_passed = True except Exception, e: logging.error("Test failed: %s: %s", e.__class__.__name__, e) try: env_process.postprocess_on_error( self, params, env) finally: env.save() raise finally: # Postprocess try: try: env_process.postprocess(self, params, env) except Exception, e: if test_passed: raise logging.error("Exception raised during " "postprocessing: %s", e) finally: env.save() except Exception, e: if params.get("abort_on_error") != "yes": raise # Abort on error logging.info("Aborting job (%s)", e) if params.get("vm_type") == "kvm": for vm in env.get_all_vms(): if vm.is_dead(): continue logging.info("VM '%s' is alive.", vm.name) for m in vm.monitors: logging.info("'%s' has a %s monitor unix socket at: %s", vm.name, m.protocol, m.filename) logging.info("The command line used to start '%s' was:\n%s", vm.name, vm.make_qemu_command()) raise error.JobError("Abort requested (%s)" % e)
def run(test, params, env): """ KVM reboot test: 1) Log into a guest with virtio data disk 2) Format the disk and copy file to it 3) Stop the guest and boot up it again with the data disk set to readonly 4) Try to copy file to the data disk 5) Try to copy file from the data disk :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ error_context.context( "TEST STEPS 1: Try to log into guest.", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = float(params.get("login_timeout", 240)) session = vm.wait_for_login(timeout=timeout) error_context.context( "TEST STEPS 2: Format the disk and copy file to it", logging.info) os_type = params["os_type"] copy_cmd = params.get("copy_cmd", "copy %s %s") disk_idx = params.get("disk_index", 1) fs_type = params.get("fstype", "ntfs") drive_letter = params.get("drive_letter", "I:") disk_size = params.get("partition_size_data", "200M") src_file = utils_misc.set_winutils_letter( session, params["src_file"], label="WIN_UTILS") utils_misc.format_guest_disk(session, disk_idx, drive_letter, disk_size, fs_type, os_type) dst_file = params["dst_file"] session.cmd(copy_cmd % (src_file, dst_file)) msg = "TEST STEPS 3: Stop the guest and boot up again with the data disk" msg += " set to readonly" error_context.context(msg, logging.info) session.close() vm.destroy() data_img = params.get("images").split()[-1] params["image_readonly_%s" % data_img] = "yes" params["force_create_image_%s" % data_img] = "no" env_process.preprocess(test, params, env) vm = env.get_vm(params["main_vm"]) vm.verify_alive() session = vm.wait_for_login(timeout=timeout) error_context.context( "TEST STEPS 4: Write to the readonly disk expect:" "The media is write protected", logging.info) dst_file_readonly = params["dst_file_readonly"] o = session.cmd_output(copy_cmd % (src_file, dst_file_readonly)) if not o.find("write protect"): raise exceptions.TestFail( "Write in readonly disk should failed\n. {}".format(o)) error_context.context( "TEST STEPS 5: Try to read from the readonly disk", logging.info) s, o = session.cmd_status_output(copy_cmd % (dst_file, r"C:\\")) if s != 0: raise exceptions.TestFail("Read file failed\n. {}".format(o)) session.close()
def run_stress_kernel_compile(tests, params, env): """ Boot VMs and run kernel compile inside VM parallel. 1) Boot up VMs: Every VM has 4G vmem, the total vmem of VMs' are $overcommit times as host's mem. 2) Launch kernel compile inside every guest. :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ def kernelcompile(session, vm_name): vm = env.get_vm(vm_name) ip = vm.get_address() path = params.get("download_url") logging.info("kernel path = %s" % path) get_kernel_cmd = "wget %s" % path try: status, output = session.cmd_status_output(get_kernel_cmd, timeout=240) if status != 0: logging.error(output) raise error.TestFail("Fail to download the kernel" " in %s" % vm_name) else: logging.info("Completed download the kernel src" " in %s" % vm_name) test_cmd = params.get("test_cmd") status, output = session.cmd_status_output(test_cmd, timeout=1200) if status != 0: logging.error(output) finally: status, _ = utils_test.ping(ip, count=10, timeout=30) if status != 0: raise error.TestFail("vm no response, pls check serial log") over_c = float(params.get("overcommit", 1.5)) guest_number = int(params.get("guest_number", "1")) if guest_number < 1: logging.warn("At least boot up one guest for this test," " set up guest number to 1") guest_number = 1 for tag in range(1, guest_number): params["vms"] += " stress_guest_%s" % tag mem_host = utils_memory.memtotal() / 1024 vmem = int(mem_host * over_c / guest_number) if vmem < 256: raise error.TestNAError("The memory size set for guest is too small." " Please try less than %s guests" " in this host." % guest_number) params["mem"] = vmem params["start_vm"] = "yes" login_timeout = int(params.get("login_timeout", 360)) env_process.preprocess(tests, params, env) sessions_info = [] for vm_name in params["vms"].split(): vm = env.get_vm(vm_name) vm.verify_alive() session = vm.wait_for_login(timeout=login_timeout) if not session: raise error.TestFail("Could not log into guest %s" % vm_name) sessions_info.append([session, vm_name]) # run kernel compile in vms try: logging.info("run kernel compile in vms") bg_threads = [] for session_info in sessions_info: session = session_info[0] vm_name = session_info[1] bg_thread = utils_test.BackgroundTest(kernelcompile, (session, vm_name)) bg_thread.start() bg_threads.append(bg_thread) completed = False while not completed: completed = True for bg_thread in bg_threads: if bg_thread.is_alive(): completed = False finally: try: for bg_thread in bg_threads: if bg_thread: bg_thread.join() finally: for session_info in sessions_info: session_info[0].close()
def run(test, params, env): """ Verify the login function of chardev-serial (RHEL only): 1) Start guest with chardev-serial with backend 2) for pty and file backend: 2.1) open and close chardev 3) for unix_socket and tcp_socket 3.1) Login guest. 3.2) move, create files inside guest 4) Hot-unplug chardev which is in use, should fail. :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ def check_guest(): session.cmd('touch file.txt') session.cmd('mkdir -p tmp') session.cmd('command cp file.txt ./tmp/test.txt') serial_id = params.objects('serials')[-1] prompt = params.get("shell_prompt") if params['serial_type'] == 'spapr-vty' \ and params['inactivity_watcher'] == 'none': params['vga'] = 'none' params['start_vm'] = 'yes' for backend in ['tcp_socket', 'unix_socket', 'pty', 'file']: params['chardev_backend_%s' % serial_id] = backend env_process.preprocess(test, params, env) vm = env.get_vm(params["main_vm"]) vm.wait_for_login() serial_device = vm.devices.get(serial_id) chardev_qid = serial_device.get_param("chardev") chardev_device = vm.devices.get_by_qid(chardev_qid)[0] if backend == 'tcp_socket': session = remote.remote_login(client='nc', host=chardev_device.params['host'], port=chardev_device.params['port'], username='******', password='******', prompt=prompt, timeout=240) check_guest() elif backend == 'unix_socket': session = vm.wait_for_serial_login() check_guest() elif backend == 'pty': chardev_info = vm.monitor.human_monitor_cmd('info chardev') hostfile = re.findall( '%s: filename=pty:(/dev/pts/\\d)?' % "serial0", chardev_info)[0] if not hostfile: test.fail("Guest boot fail with pty backend.") fd_pty = os.open(hostfile, os.O_RDWR | os.O_NONBLOCK) os.close(fd_pty) elif backend == 'file': filename = chardev_device.params['path'] f = open(filename) if 'Linux' not in f.read(): f.close() test.fail("Guest boot fail with file backend.") f.close() try: vm.devices.simple_unplug(chardev_device, vm.monitor) except qemu_monitor.QMPCmdError as e: if 'is busy' not in e.data['desc']: test.fail(e.data['desc']) else: test.fail("Hot-unplug should fail.") vm.destroy()
def run(test, params, env): """ Hot-plug virtio-serial-pci and virtserialport 1. Boot a guest with 2 chardev, no serial port & no pci 2. Hot plug virtio-serial-bus 3. Hot add virtserialport, attached on chardev 1 4. Hot plug another serial port on chardev 2 with "nr=1", should fail 5. Hot plug the serial port again with "nr=2" 6. Transfer data between guest and host via port1 and port2 7. Reboot/system_reset/shudown guest after hotplug(optional) 8. Transfer data between guest and host via port1 and port2 9. Hot-unplug relative port1 and port2 10. Hot-unplug virtio-serial-bus 11. Reboot/system_reset/shudown/migration guest after hot-unplug(optional) 12. Repeat step 2 to step 10 100 times :param test: kvm test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment """ def run_interrupt_test(interrupt_test): """ Run interrupt test(reboot/shutdown/migration) after hot plug/unplug. :param interrupt_test: reboot/shutdown/migration test """ session = vm.wait_for_login() globals().get(interrupt_test)(test, params, vm, session) session.close() def run_serial_data_transfer(): """ Transfer data between two ports. """ params['file_transfer_serial_port'] = serials[0] transfer_data(params, vm, sender='host') params['file_transfer_serial_port'] = serials[1] transfer_data(params, vm, sender='guest') params['serials'] = params.objects('serials')[0] repeat_times = int(params.get("repeat_times", 1)) interrupt_test_after_plug = params.get("interrupt_test_after_plug") interrupt_test_after_unplug = params.get("interrupt_test_after_unplug") vm = env.get_vm(params['main_vm']) char_devices = add_chardev(vm, params) for device in char_devices: extra_params = ' ' + device.cmdline() params['extra_params'] = params.get('extra_params', '') + extra_params params['start_vm'] = "yes" env_process.preprocess(test, params, env) vm = env.get_vm(params['main_vm']) # Make sure the guest boot successfully before hotplug vm.wait_for_login() vm.devices.insert(char_devices) serials = params.objects('extra_serials') buses, serial_devices = get_buses_and_serial_devices( vm, params, char_devices, serials) for i in range(repeat_times): error_context.context( "Hotplug/unplug serial devices the %s time" % (i + 1), test.log.info) vm.devices.simple_hotplug(buses[0], vm.monitor) vm.devices.simple_hotplug(serial_devices[0], vm.monitor) pre_nr = serial_devices[0].get_param('nr') # Try hotplug different device with same 'nr' if params.get("plug_same_nr") == "yes": serial_devices[1].set_param('bus', serial_devices[0].get_param('bus')) serial_devices[1].set_param('nr', pre_nr) try: serial_devices[1].hotplug(vm.monitor, vm.devices.qemu_version) except QMPCmdError as e: if 'A port already exists at id %d' % pre_nr not in str( e.data): test.fail('Hotplug fail for %s, not as expected' % str(e.data)) else: test.fail( 'Hotplug with same "nr" option success while should fail') serial_devices[1].set_param('nr', int(pre_nr) + 1) vm.devices.simple_hotplug(serial_devices[1], vm.monitor) for device in serial_devices: add_virtio_ports_to_vm(vm, params, device) run_serial_data_transfer() if interrupt_test_after_plug: test.log.info("Run %s after hotplug", interrupt_test_after_plug) run_interrupt_test(interrupt_test_after_plug) if not vm.is_alive(): return run_serial_data_transfer() if params.get("unplug_pci") == "yes": vm.devices.simple_unplug(serial_devices[0], vm.monitor) vm.devices.simple_unplug(serial_devices[1], vm.monitor) out = vm.devices.simple_unplug(buses[0], vm.monitor) if out[1] is False: msg = "Hot-unplug device %s failed" % buses[0] test.fail(msg) if interrupt_test_after_unplug: test.log.info("Run %s after hot-unplug", interrupt_test_after_unplug) run_interrupt_test(interrupt_test_after_unplug)
def run_readonly_disk(test, params, env): """ KVM reboot test: 1) Log into a guest with virtio data disk 2) Format the disk and copy file to it 3) Stop the guest and boot up it again with the data disk set to readonly 4) Try to copy file to the data disk 5) Try to copy file from the data disk :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ error.context("Try to log into guest.", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = float(params.get("login_timeout", 240)) session = vm.wait_for_login(timeout=timeout) create_partition_cmd = params.get("create_partition_cmd") format_cmd = params.get("format_cmd") copy_cmd = params.get("copy_cmd") src_file = params.get("src_file") disk_letter = params.get("disk_letter") # update the cdrom letter for winutils cdrom_chk_cmd = "echo list volume > cmd && echo exit >>" cdrom_chk_cmd += " cmd && diskpart /s cmd" vols = re.findall("\s+([A-Z])\s+.*CDFS.*\n", session.cmd_output(cdrom_chk_cmd)) if vols: src_file = re.sub("WIN_UTIL", vols[0], src_file) else: raise error.TestError("Can not find winutils in guest.") filen = 0 error.context("Format the disk and copy file to it", logging.info) session.cmd(create_partition_cmd) session.cmd(format_cmd) dst_file = disk_letter + ":\\" + str(filen) session.cmd(copy_cmd % (src_file, dst_file)) filen += 1 msg = "Stop the guest and boot up it again with the data disk" msg += " set to readonly" error.context(msg, logging.info) session.close() vm.destroy() data_img = params.get("images").split()[-1] params["image_readonly_%s" % data_img] = "yes" params["force_create_image_%s" % data_img] = "no" env_process.preprocess(test, params, env) vm = env.get_vm(params["main_vm"]) vm.verify_alive() session = vm.wait_for_login(timeout=timeout) try: error.context("Try to write to the readonly disk", logging.info) dst_file_readonly = disk_letter + ":\\" + str(filen) session.cmd(copy_cmd % (src_file, dst_file_readonly)) raise error.TestFail("Write in readonly disk should failed.") except aexpect.ShellCmdError: error.context("Try to read from the readonly disk", logging.info) session.cmd(copy_cmd % (dst_file, "C:\\")) session.close()
def run(test, params, env): """ KVM reboot test: 1) Log into a guest with virtio data disk 2) Format the disk and copy file to it 3) Stop the guest and boot up it again with the data disk set to readonly 4) Try to copy file to the data disk 5) Try to copy file from the data disk :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ error_context.context("TEST STEPS 1: Try to log into guest.", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = float(params.get("login_timeout", 240)) session = vm.wait_for_login(timeout=timeout) error_context.context("TEST STEPS 2: Format the disk and copy file to it", logging.info) os_type = params["os_type"] copy_cmd = params.get("copy_cmd", "copy %s %s") disk_idx = params.get("disk_index", 1) fs_type = params.get("fstype", "ntfs") drive_letter = params.get("drive_letter", "I:") disk_size = params.get("partition_size_data", "200M") src_file = utils_misc.set_winutils_letter(session, params["src_file"], label="WIN_UTILS") utils_misc.format_guest_disk(session, disk_idx, drive_letter, disk_size, fs_type, os_type) dst_file = params["dst_file"] session.cmd(copy_cmd % (src_file, dst_file)) msg = "TEST STEPS 3: Stop the guest and boot up again with the data disk" msg += " set to readonly" error_context.context(msg, logging.info) session.close() vm.destroy() data_img = params.get("images").split()[-1] params["image_readonly_%s" % data_img] = "yes" params["force_create_image_%s" % data_img] = "no" env_process.preprocess(test, params, env) vm = env.get_vm(params["main_vm"]) vm.verify_alive() session = vm.wait_for_login(timeout=timeout) error_context.context( "TEST STEPS 4: Write to the readonly disk expect:" "The media is write protected", logging.info) dst_file_readonly = params["dst_file_readonly"] o = session.cmd_output(copy_cmd % (src_file, dst_file_readonly)) if not o.find("write protect"): raise exceptions.TestFail( "Write in readonly disk should failed\n. {}".format(o)) error_context.context("TEST STEPS 5: Try to read from the readonly disk", logging.info) s, o = session.cmd_status_output(copy_cmd % (dst_file, r"C:\\")) if s != 0: raise exceptions.TestFail("Read file failed\n. {}".format(o)) session.close()
def run_once(self, params): # Convert params to a Params object params = utils_params.Params(params) # If a dependency test prior to this test has failed, let's fail # it right away as TestNA. if params.get("dependency_failed") == 'yes': raise error.TestNAError("Test dependency failed") # Report the parameters we've received and write them as keyvals logging.debug("Test parameters:") keys = params.keys() keys.sort() for key in keys: logging.debug(" %s = %s", key, params[key]) self.write_test_keyval({key: params[key]}) # Set the log file dir for the logging mechanism used by kvm_subprocess # (this must be done before unpickling env) utils_misc.set_log_file_dir(self.debugdir) # Open the environment file env_filename = os.path.join(self.bindir, params.get("vm_type"), params.get("env", "env")) env = utils_env.Env(env_filename, self.env_version) test_passed = False try: try: try: subtest_dirs = [] tests_dir = self.job.testdir other_subtests_dirs = params.get("other_tests_dirs", "") for d in other_subtests_dirs.split(): # Replace split char. d = os.path.join(*d.split("/")) subtestdir = os.path.join(tests_dir, d, "tests") if not os.path.isdir(subtestdir): raise error.TestError("Directory %s not" " exist." % (subtestdir)) subtest_dirs.append(subtestdir) # Verify if we have the correspondent source file for it virt_dir = os.path.dirname(self.virtdir) subtest_dirs.append(os.path.join(virt_dir, "tests")) subtest_dirs.append( os.path.join(self.bindir, params.get("vm_type"), "tests")) subtest_dir = None # Get the test routine corresponding to the specified # test type t_types = params.get("type").split() test_modules = [] for t_type in t_types: for d in subtest_dirs: module_path = os.path.join(d, "%s.py" % t_type) if os.path.isfile(module_path): subtest_dir = d break if subtest_dir is None: msg = ("Could not find test file %s.py on tests" "dirs %s" % (t_type, subtest_dirs)) raise error.TestError(msg) # Load the test module f, p, d = imp.find_module(t_type, [subtest_dir]) test_modules.append( (t_type, imp.load_module(t_type, f, p, d))) f.close() # Preprocess try: env_process.preprocess(self, params, env) finally: env.save() # Run the test function for t_type, test_module in test_modules: msg = "Running function: %s.run_%s()" % (t_type, t_type) logging.info(msg) run_func = getattr(test_module, "run_%s" % t_type) try: run_func(self, params, env) self.verify_background_errors() finally: env.save() test_passed = True except Exception, e: logging.error("Test failed: %s: %s", e.__class__.__name__, e) try: env_process.postprocess_on_error(self, params, env) finally: env.save() raise finally: # Postprocess try: try: env_process.postprocess(self, params, env) except Exception, e: if test_passed: raise logging.error( "Exception raised during " "postprocessing: %s", e) finally: env.save() except Exception, e: if params.get("abort_on_error") != "yes": raise # Abort on error logging.info("Aborting job (%s)", e) if params.get("vm_type") == "qemu": for vm in env.get_all_vms(): if vm.is_dead(): continue logging.info("VM '%s' is alive.", vm.name) for m in vm.monitors: logging.info( "'%s' has a %s monitor unix socket at: %s", vm.name, m.protocol, m.filename) logging.info( "The command line used to start '%s' was:\n%s", vm.name, vm.make_qemu_command()) raise error.JobError("Abort requested (%s)" % e)
def run(test, params, env): """ Test virtio-fs by sharing the data between host and guest. Steps: 1. Create shared directories on the host. 2. Run virtiofsd daemons on the host. 3. Boot a guest on the host with virtiofs options. 4. Log into guest then mount the virtiofs targets. 5. Generate files or run stress on the mount points inside guest. :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ def get_viofs_exe(session): """ Get viofs.exe from virtio win iso,such as E:\viofs\2k19\amd64 """ logging.info("Get virtiofs exe full path.") media_type = params["virtio_win_media_type"] try: get_drive_letter = getattr(virtio_win, "drive_letter_%s" % media_type) get_product_dirname = getattr(virtio_win, "product_dirname_%s" % media_type) get_arch_dirname = getattr(virtio_win, "arch_dirname_%s" % media_type) except AttributeError: test.error("Not supported virtio win media type '%s'", media_type) viowin_ltr = get_drive_letter(session) if not viowin_ltr: test.error("Could not find virtio-win drive in guest") guest_name = get_product_dirname(session) if not guest_name: test.error("Could not get product dirname of the vm") guest_arch = get_arch_dirname(session) if not guest_arch: test.error("Could not get architecture dirname of the vm") exe_middle_path = ("{name}\\{arch}" if media_type == "iso" else "{arch}\\{name}").format(name=guest_name, arch=guest_arch) exe_file_name = "virtiofs.exe" exe_find_cmd = 'dir /b /s %s\\%s | findstr "\\%s\\\\"' exe_find_cmd %= (viowin_ltr, exe_file_name, exe_middle_path) exe_path = session.cmd(exe_find_cmd).strip() logging.info("Found exe file '%s'", exe_path) return exe_path # data io config cmd_dd = params.get('cmd_dd') cmd_md5 = params.get('cmd_md5') cmd_new_folder = params.get('cmd_new_folder') cmd_copy_file = params.get('cmd_copy_file') cmd_del_folder = params.get('cmd_del_folder') # pjdfs test config cmd_pjdfstest = params.get('cmd_pjdfstest') cmd_unpack = params.get('cmd_unpack') cmd_yum_deps = params.get('cmd_yum_deps') cmd_autoreconf = params.get('cmd_autoreconf') cmd_configure = params.get('cmd_configure') cmd_make = params.get('cmd_make') pjdfstest_pkg = params.get('pjdfstest_pkg') username = params.get('username') password = params.get('password') port = params.get('file_transfer_port') # fio config fio_options = params.get('fio_options') io_timeout = params.get_numeric('io_timeout') # xfstest config cmd_xfstest = params.get('cmd_xfstest') fs_dest_fs2 = params.get('fs_dest_fs2') cmd_download_xfstest = params.get('cmd_download_xfstest') cmd_yum_install = params.get('cmd_yum_install') cmd_make_xfs = params.get('cmd_make_xfs') cmd_setenv = params.get('cmd_setenv') cmd_setenv_nfs = params.get('cmd_setenv_nfs', '') cmd_useradd = params.get('cmd_useradd') fs_dest_fs1 = params.get('fs_dest_fs1') cmd_get_tmpfs = params.get('cmd_get_tmpfs') cmd_set_tmpfs = params.get('cmd_set_tmpfs') size_mem1 = params.get('size_mem1') # xfstest-nfs config setup_local_nfs = params.get('setup_local_nfs') if cmd_xfstest: # /dev/shm is the default memory-backend-file, the default value is the # half of the host memory. Increase it to guest memory size to avoid crash ori_tmpfs_size = process.run(cmd_get_tmpfs, shell=True).stdout_text.replace("\n", "") logging.debug("original tmpfs size is %s", ori_tmpfs_size) params["post_command"] = cmd_set_tmpfs % ori_tmpfs_size params["pre_command"] = cmd_set_tmpfs % size_mem1 if setup_local_nfs: for fs in params.objects("filesystems"): nfs_params = params.object_params(fs) params["export_dir"] = nfs_params.get("export_dir") params["nfs_mount_src"] = nfs_params.get("nfs_mount_src") params["nfs_mount_dir"] = nfs_params.get("fs_source_dir") nfs_local = nfs.Nfs(params) nfs_local.setup() params["start_vm"] = "yes" env_process.preprocess(test, params, env) os_type = params.get("os_type") vm = env.get_vm(params.get("main_vm")) vm.verify_alive() session = vm.wait_for_login() host_addr = vm.get_address() if os_type == "windows": cmd_timeout = params.get_numeric("cmd_timeout", 120) driver_name = params["driver_name"] install_path = params["install_path"] check_installed_cmd = params["check_installed_cmd"] % install_path # Check whether windows driver is running,and enable driver verifier session = utils_test.qemu.windrv_check_running_verifier(session, vm, test, driver_name) # install winfsp tool error_context.context("Install winfsp for windows guest.", logging.info) installed = session.cmd_status(check_installed_cmd) == 0 if installed: logging.info("Winfsp tool is already installed.") else: install_cmd = utils_misc.set_winutils_letter(session, params["install_cmd"]) session.cmd(install_cmd, cmd_timeout) if not utils_misc.wait_for(lambda: not session.cmd_status( check_installed_cmd), 60): test.error("Winfsp tool is not installed.") for fs in params.objects("filesystems"): fs_params = params.object_params(fs) fs_target = fs_params.get("fs_target") fs_dest = fs_params.get("fs_dest") fs_source = fs_params.get("fs_source_dir") base_dir = fs_params.get("fs_source_base_dir", data_dir.get_data_dir()) if not os.path.isabs(fs_source): fs_source = os.path.join(base_dir, fs_source) host_data = os.path.join(fs_source, 'fs_test') if os_type == "linux": error_context.context("Create a destination directory %s " "inside guest." % fs_dest, logging.info) utils_misc.make_dirs(fs_dest, session) if not cmd_xfstest: error_context.context("Mount virtiofs target %s to %s inside" " guest." % (fs_target, fs_dest), logging.info) if not utils_disk.mount(fs_target, fs_dest, 'virtiofs', session=session): test.fail('Mount virtiofs target failed.') else: error_context.context("Start virtiofs service in guest.", logging.info) viofs_sc_create_cmd = params["viofs_sc_create_cmd"] viofs_sc_start_cmd = params["viofs_sc_start_cmd"] viofs_sc_query_cmd = params["viofs_sc_query_cmd"] logging.info("Check if virtiofs service is registered.") status, output = session.cmd_status_output(viofs_sc_query_cmd) if "not exist as an installed service" in output: logging.info("Register virtiofs service in windows guest.") exe_path = get_viofs_exe(session) viofs_sc_create_cmd = viofs_sc_create_cmd % exe_path sc_create_s, sc_create_o = session.cmd_status_output(viofs_sc_create_cmd) if sc_create_s != 0: test.fail("Failed to register virtiofs service, output is %s" % sc_create_o) logging.info("Check if virtiofs service is started.") status, output = session.cmd_status_output(viofs_sc_query_cmd) if "RUNNING" not in output: logging.info("Start virtiofs service.") sc_start_s, sc_start_o = session.cmd_status_output(viofs_sc_start_cmd) if sc_start_s != 0: test.fail("Failed to start virtiofs service, output is %s" % sc_start_o) else: logging.info("Virtiofs service is running.") viofs_log_file_cmd = params.get("viofs_log_file_cmd") if viofs_log_file_cmd: error_context.context("Check if LOG file is created.", logging.info) log_dir_s = session.cmd_status(viofs_log_file_cmd) if log_dir_s != 0: test.fail("Virtiofs log is not created.") # get fs dest for vm virtio_fs_disk_label = fs_target error_context.context("Get Volume letter of virtio fs target, the disk" "lable is %s." % virtio_fs_disk_label, logging.info) vol_con = "VolumeName='%s'" % virtio_fs_disk_label vol_func = utils_misc.get_win_disk_vol(session, condition=vol_con) volume_letter = utils_misc.wait_for(lambda: vol_func, cmd_timeout) if volume_letter is None: test.fail("Could not get virtio-fs mounted volume letter.") fs_dest = "%s:" % volume_letter guest_file = os.path.join(fs_dest, 'fs_test') logging.info("The guest file in shared dir is %s", guest_file) try: if cmd_dd: error_context.context("Creating file under %s inside " "guest." % fs_dest, logging.info) session.cmd(cmd_dd % guest_file, io_timeout) if os_type == "linux": cmd_md5_vm = cmd_md5 % guest_file else: guest_file_win = guest_file.replace("/", "\\") cmd_md5_vm = cmd_md5 % (volume_letter, guest_file_win) md5_guest = session.cmd_output(cmd_md5_vm, io_timeout).strip().split()[0] logging.info(md5_guest) md5_host = process.run("md5sum %s" % host_data, io_timeout).stdout_text.strip().split()[0] if md5_guest != md5_host: test.fail('The md5 value of host is not same to guest.') if cmd_new_folder and cmd_copy_file and cmd_del_folder: error_context.context("Folder test under %s inside " "guest." % fs_dest, logging.info) session.cmd(cmd_new_folder % fs_dest) test_file = guest_file if os_type == "linux" \ else "%s:\\%s" % (volume_letter, 'fs_test') session.cmd(cmd_copy_file % (test_file, fs_dest)) session.cmd(cmd_del_folder % fs_dest) if fio_options: error_context.context("Run fio on %s." % fs_dest, logging.info) fio = generate_instance(params, vm, 'fio') try: fio.run(fio_options % guest_file, io_timeout) finally: fio.clean() vm.verify_dmesg() if cmd_pjdfstest: error_context.context("Run pjdfstest on %s." % fs_dest, logging.info) host_path = os.path.join(data_dir.get_deps_dir('pjdfstest'), pjdfstest_pkg) scp_to_remote(host_addr, port, username, password, host_path, fs_dest) session.cmd(cmd_unpack.format(fs_dest), 180) session.cmd(cmd_yum_deps, 180) session.cmd(cmd_autoreconf % fs_dest, 180) session.cmd(cmd_configure.format(fs_dest), 180) session.cmd(cmd_make % fs_dest, io_timeout) session.cmd(cmd_pjdfstest % fs_dest, io_timeout) if cmd_xfstest: error_context.context("Run xfstest on guest.", logging.info) utils_misc.make_dirs(fs_dest_fs2, session) if session.cmd_status(cmd_download_xfstest, 360): test.error("Failed to download xfstests-dev") session.cmd(cmd_yum_install, 180) session.cmd(cmd_make_xfs, 360) session.cmd(cmd_setenv, 180) session.cmd(cmd_setenv_nfs, 180) session.cmd(cmd_useradd, 180) try: output = session.cmd_output(cmd_xfstest, io_timeout) logging.info("%s", output) if 'Failed' in output: test.fail('The xfstest failed.') else: break except (aexpect.ShellStatusError, aexpect.ShellTimeoutError): test.fail('The xfstest failed.') finally: if os_type == "linux": utils_disk.umount(fs_target, fs_dest, 'virtiofs', session=session) utils_misc.safe_rmdir(fs_dest, session=session) if setup_local_nfs: session.close() vm.destroy() for fs in params.objects("filesystems"): nfs_params = params.object_params(fs) params["export_dir"] = nfs_params.get("export_dir") params["nfs_mount_dir"] = nfs_params.get("fs_source_dir") params["rm_export_dir"] = nfs_params.get("export_dir") params["rm_mount_dir"] = nfs_params.get("fs_source_dir") nfs_local = nfs.Nfs(params) nfs_local.cleanup() utils_misc.safe_rmdir(params["export_dir"]) # during all virtio fs is mounted, reboot vm if params.get('reboot_guest', 'no') == 'yes': def get_vfsd_num(): """ Get virtiofsd daemon number during vm boot up. :return: virtiofsd daemon count. """ cmd_ps_virtiofsd = params.get('cmd_ps_virtiofsd') vfsd_num = 0 for device in vm.devices: if isinstance(device, qdevices.QVirtioFSDev): sock_path = device.get_param('sock_path') cmd_ps_virtiofsd = cmd_ps_virtiofsd % sock_path vfsd_ps = process.system_output(cmd_ps_virtiofsd, shell=True) vfsd_num += len(vfsd_ps.strip().splitlines()) return vfsd_num error_context.context("Check virtiofs daemon before reboot vm.", logging.info) vfsd_num_bf = get_vfsd_num() error_context.context("Reboot guest and check virtiofs daemon.", logging.info) vm.reboot() if not vm.is_alive(): test.fail("After rebooting vm quit unexpectedly.") vfsd_num_af = get_vfsd_num() if vfsd_num_bf != vfsd_num_af: test.fail("Virtiofs daemon is different before and after reboot.\n" "Before reboot: %s\n" "After reboot: %s\n", (vfsd_num_bf, vfsd_num_af))
def _runTest(self): params = self.params # Report virt test version logging.info(version.get_pretty_version_info()) self._log_parameters() # Warn of this special condition in related location in output & logs if os.getuid() == 0 and params.get('nettype', 'user') == 'user': logging.warning("") logging.warning("Testing with nettype='user' while running " "as root may produce unexpected results!!!") logging.warning("") subtest_dirs = self._get_subtest_dirs() # Get the test routine corresponding to the specified # test type logging.debug("Searching for test modules that match " "'type = %s' and 'provider = %s' " "on this cartesian dict", params.get("type"), params.get("provider", None)) t_types = params.get("type").split() utils.insert_dirs_to_path(subtest_dirs) test_modules = utils.find_test_modules(t_types, subtest_dirs) # Open the environment file env_filename = os.path.join(data_dir.get_tmp_dir(), params.get("env", "env")) env = utils_env.Env(env_filename, self.env_version) if params.get_boolean("job_env_cleanup", "yes"): self.runner_queue.put({"func_at_exit": cleanup_env, "args": (env_filename, self.env_version), "once": True}) test_passed = False t_type = None try: try: try: # Pre-process try: params = env_process.preprocess(self, params, env) finally: self._safe_env_save(env) # Run the test function for t_type in t_types: test_module = test_modules[t_type] run_func = utils_misc.get_test_entrypoint_func( t_type, test_module) try: run_func(self, params, env) self.verify_background_errors() finally: self._safe_env_save(env) test_passed = True error_message = funcatexit.run_exitfuncs(env, t_type) if error_message: raise exceptions.TestWarn("funcatexit failed with: %s" % error_message) except: # nopep8 Old-style exceptions are not inherited from Exception() stacktrace.log_exc_info(sys.exc_info(), 'avocado.test') if t_type is not None: error_message = funcatexit.run_exitfuncs(env, t_type) if error_message: logging.error(error_message) try: env_process.postprocess_on_error(self, params, env) finally: self._safe_env_save(env) raise finally: # Post-process try: try: params['test_passed'] = str(test_passed) env_process.postprocess(self, params, env) except: # nopep8 Old-style exceptions are not inherited from Exception() stacktrace.log_exc_info(sys.exc_info(), 'avocado.test') if test_passed: raise logging.error("Exception raised during " "postprocessing: %s", sys.exc_info()[1]) finally: if self._safe_env_save(env) or params.get("env_cleanup", "no") == "yes": env.destroy() # Force-clean as it can't be stored except Exception as e: if params.get("abort_on_error") != "yes": raise # Abort on error logging.info("Aborting job (%s)", e) if params.get("vm_type") == "qemu": for vm in env.get_all_vms(): if vm.is_dead(): continue logging.info("VM '%s' is alive.", vm.name) for m in vm.monitors: logging.info("It has a %s monitor unix socket at: %s", m.protocol, m.filename) logging.info("The command line used to start it was:\n%s", vm.make_create_command()) raise exceptions.JobError("Abort requested (%s)" % e) return test_passed
def _runTest(self): params = self.params # If a dependency test prior to this test has failed, let's fail # it right away as TestNA. if params.get("dependency_failed") == 'yes': raise error.TestNAError("Test dependency failed") # Report virt test version logging.info(version.get_pretty_version_info()) # Report the parameters we've received and write them as keyvals logging.debug("Test parameters:") keys = params.keys() keys.sort() for key in keys: logging.debug(" %s = %s", key, params[key]) # Warn of this special condition in related location in output & logs if os.getuid() == 0 and params.get('nettype', 'user') == 'user': logging.warning("") logging.warning("Testing with nettype='user' while running " "as root may produce unexpected results!!!") logging.warning("") # Find the test subtest_dirs = [] test_filter = bootstrap.test_filter other_subtests_dirs = params.get("other_tests_dirs", "") for d in other_subtests_dirs.split(): d = os.path.join(*d.split("/")) subtestdir = os.path.join(self.bindir, d, "tests") if not os.path.isdir(subtestdir): raise error.TestError("Directory %s does not " "exist" % subtestdir) subtest_dirs += data_dir.SubdirList(subtestdir, test_filter) provider = params.get("provider", None) if provider is None: # Verify if we have the correspondent source file for # it generic_subdirs = asset.get_test_provider_subdirs( 'generic') for generic_subdir in generic_subdirs: subtest_dirs += data_dir.SubdirList(generic_subdir, test_filter) specific_subdirs = asset.get_test_provider_subdirs( params.get("vm_type")) for specific_subdir in specific_subdirs: subtest_dirs += data_dir.SubdirList( specific_subdir, bootstrap.test_filter) else: provider_info = asset.get_test_provider_info(provider) for key in provider_info['backends']: subtest_dirs += data_dir.SubdirList( provider_info['backends'][key]['path'], bootstrap.test_filter) subtest_dir = None # Get the test routine corresponding to the specified # test type logging.debug("Searching for test modules that match " "'type = %s' and 'provider = %s' " "on this cartesian dict", params.get("type"), params.get("provider", None)) t_types = params.get("type").split() # Make sure we can load provider_lib in tests for s in subtest_dirs: if os.path.dirname(s) not in sys.path: sys.path.insert(0, os.path.dirname(s)) test_modules = {} for t_type in t_types: for d in subtest_dirs: module_path = os.path.join(d, "%s.py" % t_type) if os.path.isfile(module_path): logging.debug("Found subtest module %s", module_path) subtest_dir = d break if subtest_dir is None: msg = ("Could not find test file %s.py on test" "dirs %s" % (t_type, subtest_dirs)) raise error.TestError(msg) # Load the test module f, p, d = imp.find_module(t_type, [subtest_dir]) test_modules[t_type] = imp.load_module(t_type, f, p, d) f.close() # TODO: the environment file is deprecated code, and should be removed # in future versions. Right now, it's being created on an Avocado temp # dir that is only persisted during the runtime of one job, which is # different from the original idea of the environment file (which was # persist information accross virt-test/avocado-vt job runs) env_filename = os.path.join(data_dir.get_tmp_dir(), params.get("env", "env")) env = utils_env.Env(env_filename, self.env_version) self.runner_queue.put({"func_at_exit": cleanup_env, "args": (env_filename, self.env_version), "once": True}) test_passed = False t_type = None try: try: try: # Preprocess try: params = env_process.preprocess(self, params, env) finally: self.__safe_env_save(env) # Run the test function for t_type in t_types: test_module = test_modules[t_type] run_func = utils_misc.get_test_entrypoint_func( t_type, test_module) try: run_func(self, params, env) self.verify_background_errors() finally: self.__safe_env_save(env) test_passed = True error_message = funcatexit.run_exitfuncs(env, t_type) if error_message: raise error.TestWarn("funcatexit failed with: %s" % error_message) except Exception: if t_type is not None: error_message = funcatexit.run_exitfuncs(env, t_type) if error_message: logging.error(error_message) try: env_process.postprocess_on_error(self, params, env) finally: self.__safe_env_save(env) raise finally: # Postprocess try: try: params['test_passed'] = str(test_passed) env_process.postprocess(self, params, env) except Exception, e: if test_passed: raise logging.error("Exception raised during " "postprocessing: %s", e) finally: if self.__safe_env_save(env): env.destroy() # Force-clean as it can't be stored except Exception, e: if params.get("abort_on_error") != "yes": raise # Abort on error logging.info("Aborting job (%s)", e) if params.get("vm_type") == "qemu": for vm in env.get_all_vms(): if vm.is_dead(): continue logging.info("VM '%s' is alive.", vm.name) for m in vm.monitors: logging.info("It has a %s monitor unix socket at: %s", m.protocol, m.filename) logging.info("The command line used to start it was:\n%s", vm.make_create_command()) raise error.JobError("Abort requested (%s)" % e)
def run(test, params, env): """ Time clock offset check when guest crash/bsod test: 1) boot guest with '-rtc base=utc,clock=host,driftfix=slew'; 2) sync host system time with ntp server; 3) inject nmi to guest/ make linux kernel crash; 4) sleep long time, then reset vm via system_reset; 5) query clock offset from ntp server; :param test: QEMU test object. :param params: Dictionary with test parameters. :param env: Dictionary with the test environment. """ clock_sync_command = params["clock_sync_command"] ntp_cmd = params["ntp_cmd"] ntp_query_cmd = params["ntp_query_cmd"] nmi_cmd = params.get("nmi_cmd", "inject-nmi") sleep_time = float(params.get("sleep_time", 1800)) deviation = float(params.get("deviation", 5)) error_context.context("sync host time with ntp server", logging.info) process.system(clock_sync_command, shell=True) error_context.context("start guest", logging.info) params["start_vm"] = "yes" preprocess(test, params, env) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) error_context.context("sync time in guest", logging.info) session.cmd(ntp_cmd) error_context.context("inject nmi interrupt in vm", logging.info) target, cmd = re.split(r"\s*:\s*", nmi_cmd) if target == "monitor": vm.monitor.send_args_cmd(cmd) else: session.sendline(cmd) try: session.cmd("dir") except Exception: pass else: test.fail("Guest OS still alive ...") error_context.context("sleep %s seconds" % sleep_time, logging.info) time.sleep(sleep_time) # Autotest parses serial output and could raise VMDeadKernelCrash # we generated using sysrq. Ignore one "BUG:" line try: session = vm.reboot(method="system_reset") except VMDeadKernelCrashError as details: details = str(details) if (re.findall(r"Trigger a crash\s.*BUG:", details, re.M) and details.count("BUG:") != 1): test.fail("Got multiple kernel crashes. Please " "note that one of them was " "intentionally generated by sysrq in " "this test.\n%s" % details) end_time = time.time() + timeout while time.time() < end_time: try: session = vm.wait_for_login(timeout=timeout) except VMDeadKernelCrashError as details: details = str(details) if (re.findall(r"Trigger a crash\s.*BUG:", details, re.M) and details.count("BUG:") != 1): test.fail("Got multiple kernel crashes. " "Please note that one of them was " "intentionally generated by sysrq " "in this test.\n%s" % details) else: break error_context.context("check time offset via ntp", logging.info) output = session.cmd_output(ntp_query_cmd) try: offset = re.findall(r"[+-](\d+\.\d+)", output, re.M)[-1] except IndexError: offset = 0.0 if float(offset) > deviation: test.fail("Unacceptable offset '%s', " % offset + "deviation '%s'" % deviation)
def run_stress_kernel_compile(tests, params, env): """ Boot VMs and run kernel compile inside VM parallel. 1) Boot up VMs: Every VM has 4G vmem, the total vmem of VMs' are $overcommit times as host's mem. 2) Launch kernel compile inside every guest. @param test: QEMU test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ def kernelcompile(session, vm_name): vm = env.get_vm(vm_name) ip = vm.get_address() path = params.get("download_url") logging.info("kernel path = %s" % path) get_kernel_cmd = "wget %s" % path try: status, output = session.cmd_status_output(get_kernel_cmd, timeout=240) if status != 0: logging.error(output) raise error.TestFail("Fail to download the kernel" " in %s" % vm_name) else: logging.info("Completed download the kernel src" " in %s" %vm_name) test_cmd = params.get("test_cmd") status, output = session.cmd_status_output(test_cmd, timeout=1200) if status != 0: logging.error(output) finally: status, _ = utils_test.ping(ip, count=10, timeout=30) if status != 0: raise error.TestFail("vm no response, pls check serial log") over_c = float(params.get("overcommit", 1.5)) guest_number = int(params.get("guest_number", "1")) if guest_number < 1: logging.warn("At least boot up one guest for this test," " set up guest number to 1") guest_number = 1 for tag in range(1, guest_number): params["vms"] += " stress_guest_%s" % tag mem_host = utils_memory.memtotal() / 1024 vmem = int(mem_host * over_c / guest_number) if vmem < 256: raise error.TestNAError("The memory size set for guest is too small." " Please try less than %s guests" " in this host." % guest_number) params["mem"] = vmem params["start_vm"] = "yes" login_timeout = int(params.get("login_timeout", 360)) env_process.preprocess(tests, params, env) sessions_info = [] for vm_name in params["vms"].split(): vm = env.get_vm(vm_name) vm.verify_alive() session = vm.wait_for_login(timeout=login_timeout) if not session: raise error.TestFail("Could not log into guest %s" % vm_name) sessions_info.append([session, vm_name]) # run kernel compile in vms try: logging.info("run kernel compile in vms") bg_threads = [] for session_info in sessions_info: session = session_info[0] vm_name = session_info[1] bg_thread = utils_test.BackgroundTest(kernelcompile, (session, vm_name)) bg_thread.start() bg_threads.append(bg_thread) completed = False while not completed: completed = True for bg_thread in bg_threads: if bg_thread.is_alive(): completed = False finally: try: for bg_thread in bg_threads: if bg_thread: bg_thread.join() finally: for session_info in sessions_info: session_info[0].close()
def run_multi_disk(test, params, env): """ Test multi disk suport of guest, this case will: 1) Create disks image in configuration file. 2) Start the guest with those disks. 3) Checks qtree vs. test params. 4) Format those disks. 5) Copy file into / out of those disks. 6) Compare the original file and the copied file using md5 or fc comand. 7) Repeat steps 3-5 if needed. @param test: kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ def _add_param(name, value): """ Converts name+value to stg_params string """ if value: value = re.sub(' ', '\\ ', value) return " %s:%s " % (name, value) else: return '' stg_image_num = 0 stg_params = params.get("stg_params", "") # Compatibility stg_params += _add_param("image_size", params.get("stg_image_size")) stg_params += _add_param("image_format", params.get("stg_image_format")) stg_params += _add_param("image_boot", params.get("stg_image_boot")) stg_params += _add_param("drive_format", params.get("stg_drive_format")) if params.get("stg_assign_index") != "no": # Assume 0 and 1 are already occupied (hd0 and cdrom) stg_params += _add_param("drive_index", 'range(2,n)') param_matrix = {} stg_params = stg_params.split(' ') i = 0 while i < len(stg_params) - 1: if not stg_params[i].strip(): i += 1 continue if stg_params[i][-1] == '\\': stg_params[i] = '%s %s' % (stg_params[i][:-1], stg_params.pop(i + 1)) i += 1 rerange = [] has_name = False for i in xrange(len(stg_params)): if not stg_params[i].strip(): continue (cmd, parm) = stg_params[i].split(':', 1) if cmd == "image_name": has_name = True if _RE_RANGE1.match(parm): parm = _range(parm) if parm == False: raise error.TestError("Incorrect cfg: stg_params %s looks " "like range(..) but doesn't contain " "numbers." % cmd) param_matrix[cmd] = parm if type(parm) is str: # When we know the stg_image_num, substitute it. rerange.append(cmd) continue else: # ',' separated list of values parm = parm.split(',') j = 0 while j < len(parm) - 1: if parm[j][-1] == '\\': parm[j] = '%s,%s' % (parm[j][:-1], parm.pop(j + 1)) j += 1 param_matrix[cmd] = parm stg_image_num = max(stg_image_num, len(parm)) stg_image_num = int(params.get('stg_image_num', stg_image_num)) for cmd in rerange: param_matrix[cmd] = _range(param_matrix[cmd], stg_image_num) # param_table* are for pretty print of param_matrix param_table = [] param_table_header = ['name'] if not has_name: param_table_header.append('image_name') for _ in param_matrix: param_table_header.append(_) stg_image_name = params.get('stg_image_name', '%s') for i in xrange(stg_image_num): name = "stg%d" % i params['images'] += " %s" % name param_table.append([]) param_table[-1].append(name) if not has_name: params["image_name_%s" % name] = stg_image_name % name param_table[-1].append(params.get("image_name_%s" % name)) for parm in param_matrix.iteritems(): params['%s_%s' % (parm[0], name)] = str(parm[1][i % len(parm[1])]) param_table[-1].append(params.get('%s_%s' % (parm[0], name))) if params.get("multi_disk_params_only") == 'yes': # Only print the test param_matrix and finish logging.info('Newly added disks:\n%s', utils.matrix_to_string(param_table, param_table_header)) return # Always recreate VM (disks are already marked for deletion env_process.preprocess(test, params, env) vm = env.get_vm(params["main_vm"]) vm.create(timeout=max(10, stg_image_num)) session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) images = params.get("images").split() n_repeat = int(params.get("n_repeat", "1")) image_num = len(images) file_system = params.get("file_system").split() fs_num = len(file_system) cmd_timeout = float(params.get("cmd_timeout", 360)) re_str = params.get("re_str") black_list = params.get("black_list").split() error.context("verifying qtree vs. test params") err = 0 qtree = kvm_qtree.QtreeContainer() qtree.parse_info_qtree(vm.monitor.info('qtree')) disks = kvm_qtree.QtreeDisksContainer(qtree.get_nodes()) (tmp1, tmp2) = disks.parse_info_block(vm.monitor.info('block')) err += tmp1 + tmp2 err += disks.generate_params() err += disks.check_disk_params(params, vm.root_dir) (tmp1, tmp2, _, _) = disks.check_guests_proc_scsi( session.cmd_output('cat /proc/scsi/scsi')) err += tmp1 + tmp2 if err: raise error.TestFail("%s errors occurred while verifying qtree vs. " "params" % err) if params.get('multi_disk_only_qtree') == 'yes': return try: if params.get("clean_cmd"): cmd = params.get("clean_cmd") session.cmd_status_output(cmd) if params.get("pre_cmd"): cmd = params.get("pre_cmd") error.context("creating partition on test disk") session.cmd(cmd, timeout=cmd_timeout) cmd = params.get("list_volume_command") output = session.cmd_output(cmd, timeout=cmd_timeout) disks = re.findall(re_str, output) disks = map(string.strip, disks) disks.sort() logging.debug("Volume list that meets regular expressions: '%s'", disks) if len(disks) < image_num: raise error.TestFail("Fail to list all the volumes!") if params.get("os_type") == "linux": df_output = session.cmd_output("df") li = re.findall("^/dev/(.*?)[ \d]", df_output, re.M) if li: black_list.extend(li) exclude_list = [d for d in disks if d in black_list] f = lambda d: logging.info("No need to check volume '%s'", d) map(f, exclude_list) disks = [d for d in disks if d not in exclude_list] for i in range(n_repeat): logging.info("iterations: %s", (i + 1)) for disk in disks: disk = disk.strip() logging.info("Format disk: %s...", disk) index = random.randint(0, fs_num - 1) # Random select one file system from file_system fs = file_system[index].strip() cmd = params.get("format_command") % (fs, disk) error.context("formatting test disk") session.cmd(cmd, timeout=cmd_timeout) if params.get("mount_command"): cmd = params.get("mount_command") % (disk, disk, disk) session.cmd(cmd, timeout=cmd_timeout) for disk in disks: disk = disk.strip() logging.info("Performing I/O on disk: %s...", disk) cmd_list = params.get("cmd_list").split() for cmd_l in cmd_list: if params.get(cmd_l): cmd = params.get(cmd_l) % disk session.cmd(cmd, timeout=cmd_timeout) cmd = params.get("compare_command") output = session.cmd_output(cmd) key_word = params.get("check_result_key_word") if key_word and key_word in output: logging.debug("Guest's virtual disk %s works fine", disk) elif key_word: raise error.TestFail("Files on guest os root fs and disk " "differ") else: raise error.TestError( "Param check_result_key_word was not " "specified! Please check your config") if params.get("umount_command"): cmd = params.get("show_mount_cmd") output = session.cmd_output(cmd) disks = re.findall(re_str, output) disks.sort() for disk in disks: disk = disk.strip() cmd = params.get("umount_command") % (disk, disk) error.context("unmounting test disk") session.cmd(cmd) finally: if params.get("post_cmd"): cmd = params.get("post_cmd") session.cmd(cmd) session.close()
def run(test, params, env): """ Time clock offset check when guest crash/bsod test: 1) boot guest with '-rtc base=utc,clock=host,driftfix=slew'; 2) sync host system time with ntp server; 3) inject nmi to guest/ make linux kernel crash; 4) sleep long time, then reset vm via system_reset; 5) query clock offset from ntp server; :param test: QEMU test object. :param params: Dictionary with test parameters. :param env: Dictionary with the test environment. """ ntp_cmd = params["ntp_cmd"] ntp_query_cmd = params["ntp_query_cmd"] nmi_cmd = params.get("nmi_cmd", "inject-nmi") sleep_time = float(params.get("sleep_time", 1800)) deviation = float(params.get("deviation", 5)) os_type = params["os_type"] ntp_host_cmd = params.get("ntp_host_cmd", ntp_cmd) error_context.context("sync host time with ntp server", logging.info) process.system(ntp_host_cmd, shell=True) error_context.context("start guest", logging.info) params["start_vm"] = "yes" preprocess(test, params, env) vm = env.get_vm(params["main_vm"]) vm.verify_alive() if params["os_type"] == 'windows': utils_time.sync_timezone_win(vm) timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) error_context.context("sync time in guest", logging.info) if os_type == "windows": w32time_conf_cmd = params["w32time_conf_cmd"] session.cmd(w32time_conf_cmd) utils_test.start_windows_service(session, "w32time") session.cmd(ntp_cmd) error_context.context("inject nmi interrupt in vm", logging.info) target, cmd = re.split(r"\s*:\s*", nmi_cmd) if target == "monitor": vm.monitor.send_args_cmd(cmd) else: session.sendline(cmd) try: session.cmd("dir") except Exception: pass else: test.fail("Guest OS still alive ...") error_context.context("sleep %s seconds" % sleep_time, logging.info) time.sleep(sleep_time) # Autotest parses serial output and could raise VMDeadKernelCrash # we generated using sysrq. Ignore one "BUG:" line vm.resume() try: session = vm.reboot(method="system_reset") except VMDeadKernelCrashError as details: details = str(details) if (re.findall(r"Trigger a crash\s.*BUG:", details, re.M) and details.count("BUG:") != 1): test.fail("Got multiple kernel crashes. Please " "note that one of them was " "intentionally generated by sysrq in " "this test.\n%s" % details) end_time = time.time() + timeout while time.time() < end_time: try: session = vm.wait_for_login(timeout=timeout) except VMDeadKernelCrashError as details: details = str(details) if (re.findall(r"Trigger a crash\s.*BUG:", details, re.M) and details.count("BUG:") != 1): test.fail("Got multiple kernel crashes. " "Please note that one of them was " "intentionally generated by sysrq " "in this test.\n%s" % details) else: break error_context.context("check time offset via ntp", logging.info) output = session.cmd_output(ntp_query_cmd) try: offset = re.findall(r"[+-]?(\d+\.\d+)", output, re.M)[-1] except IndexError: offset = 0.0 if float(offset) > deviation: test.fail("Unacceptable offset '%s', " % offset + "deviation '%s'" % deviation)
def run_multi_disk(test, params, env): """ Test multi disk suport of guest, this case will: 1) Create disks image in configuration file. 2) Start the guest with those disks. 3) Checks qtree vs. test params. 4) Format those disks. 5) Copy file into / out of those disks. 6) Compare the original file and the copied file using md5 or fc comand. 7) Repeat steps 3-5 if needed. @param test: kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ def _add_param(name, value): """ Converts name+value to stg_params string """ if value: value = re.sub(' ', '\\ ', value) return " %s:%s " % (name, value) else: return '' stg_image_num = 0 stg_params = params.get("stg_params", "") # Compatibility stg_params += _add_param("image_size", params.get("stg_image_size")) stg_params += _add_param("image_format", params.get("stg_image_format")) stg_params += _add_param("image_boot", params.get("stg_image_boot")) stg_params += _add_param("drive_format", params.get("stg_drive_format")) if params.get("stg_assign_index") != "no": # Assume 0 and 1 are already occupied (hd0 and cdrom) stg_params += _add_param("drive_index", 'range(2,n)') param_matrix = {} stg_params = stg_params.split(' ') i = 0 while i < len(stg_params) - 1: if not stg_params[i].strip(): i += 1 continue if stg_params[i][-1] == '\\': stg_params[i] = '%s %s' % (stg_params[i][:-1], stg_params.pop(i + 1)) i += 1 rerange = [] has_name = False for i in xrange(len(stg_params)): if not stg_params[i].strip(): continue (cmd, parm) = stg_params[i].split(':', 1) if cmd == "image_name": has_name = True if _RE_RANGE1.match(parm): parm = _range(parm) if parm == False: raise error.TestError("Incorrect cfg: stg_params %s looks " "like range(..) but doesn't contain " "numbers." % cmd) param_matrix[cmd] = parm if type(parm) is str: # When we know the stg_image_num, substitute it. rerange.append(cmd) continue else: # ',' separated list of values parm = parm.split(',') j = 0 while j < len(parm) - 1: if parm[j][-1] == '\\': parm[j] = '%s,%s' % (parm[j][:-1], parm.pop(j + 1)) j += 1 param_matrix[cmd] = parm stg_image_num = max(stg_image_num, len(parm)) stg_image_num = int(params.get('stg_image_num', stg_image_num)) for cmd in rerange: param_matrix[cmd] = _range(param_matrix[cmd], stg_image_num) # param_table* are for pretty print of param_matrix param_table = [] param_table_header = ['name'] if not has_name: param_table_header.append('image_name') for _ in param_matrix: param_table_header.append(_) stg_image_name = params.get('stg_image_name', '%s') for i in xrange(stg_image_num): name = "stg%d" % i params['images'] += " %s" % name param_table.append([]) param_table[-1].append(name) if not has_name: params["image_name_%s" % name] = stg_image_name % name param_table[-1].append(params.get("image_name_%s" % name)) for parm in param_matrix.iteritems(): params['%s_%s' % (parm[0], name)] = str(parm[1][i % len(parm[1])]) param_table[-1].append(params.get('%s_%s' % (parm[0], name))) if params.get("multi_disk_params_only") == 'yes': # Only print the test param_matrix and finish logging.info('Newly added disks:\n%s', utils.matrix_to_string(param_table, param_table_header)) return # Always recreate VM (disks are already marked for deletion env_process.preprocess(test, params, env) vm = env.get_vm(params["main_vm"]) vm.create(timeout=max(10, stg_image_num)) session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) images = params.get("images").split() n_repeat = int(params.get("n_repeat", "1")) image_num = len(images) file_system = params.get("file_system").split() fs_num = len(file_system) cmd_timeout = float(params.get("cmd_timeout", 360)) re_str = params.get("re_str") black_list = params.get("black_list").split() error.context("verifying qtree vs. test params") err = 0 qtree = kvm_qtree.QtreeContainer() qtree.parse_info_qtree(vm.monitor.info('qtree')) disks = kvm_qtree.QtreeDisksContainer(qtree.get_nodes()) (tmp1, tmp2) = disks.parse_info_block(vm.monitor.info('block')) err += tmp1 + tmp2 err += disks.generate_params() err += disks.check_disk_params(params, vm.root_dir) (tmp1, tmp2, _, _) = disks.check_guests_proc_scsi( session.cmd_output('cat /proc/scsi/scsi')) err += tmp1 + tmp2 if err: raise error.TestFail("%s errors occurred while verifying qtree vs. " "params" % err) if params.get('multi_disk_only_qtree') == 'yes': return try: if params.get("clean_cmd"): cmd = params.get("clean_cmd") session.cmd_status_output(cmd) if params.get("pre_cmd"): cmd = params.get("pre_cmd") error.context("creating partition on test disk") session.cmd(cmd, timeout=cmd_timeout) cmd = params.get("list_volume_command") output = session.cmd_output(cmd, timeout=cmd_timeout) disks = re.findall(re_str, output) disks = map(string.strip, disks) disks.sort() logging.debug("Volume list that meets regular expressions: '%s'", disks) if len(disks) < image_num: raise error.TestFail("Fail to list all the volumes!") if params.get("os_type") == "linux": df_output = session.cmd_output("df") li = re.findall("^/dev/(.*?)[ \d]", df_output, re.M) if li: black_list.extend(li) exclude_list = [d for d in disks if d in black_list] f = lambda d: logging.info("No need to check volume '%s'", d) map(f, exclude_list) disks = [d for d in disks if d not in exclude_list] for i in range(n_repeat): logging.info("iterations: %s", (i + 1)) for disk in disks: disk = disk.strip() logging.info("Format disk: %s...", disk) index = random.randint(0, fs_num - 1) # Random select one file system from file_system fs = file_system[index].strip() cmd = params.get("format_command") % (fs, disk) error.context("formatting test disk") session.cmd(cmd, timeout=cmd_timeout) if params.get("mount_command"): cmd = params.get("mount_command") % (disk, disk, disk) session.cmd(cmd, timeout=cmd_timeout) for disk in disks: disk = disk.strip() logging.info("Performing I/O on disk: %s...", disk) cmd_list = params.get("cmd_list").split() for cmd_l in cmd_list: if params.get(cmd_l): cmd = params.get(cmd_l) % disk session.cmd(cmd, timeout=cmd_timeout) cmd = params.get("compare_command") output = session.cmd_output(cmd) key_word = params.get("check_result_key_word") if key_word and key_word in output: logging.debug("Guest's virtual disk %s works fine", disk) elif key_word: raise error.TestFail("Files on guest os root fs and disk " "differ") else: raise error.TestError("Param check_result_key_word was not " "specified! Please check your config") if params.get("umount_command"): cmd = params.get("show_mount_cmd") output = session.cmd_output(cmd) disks = re.findall(re_str, output) disks.sort() for disk in disks: disk = disk.strip() cmd = params.get("umount_command") % (disk, disk) error.context("unmounting test disk") session.cmd(cmd) finally: if params.get("post_cmd"): cmd = params.get("post_cmd") session.cmd(cmd) session.close()
def run_once(self, params): # Convert params to a Params object params = utils_params.Params(params) # If a dependency test prior to this test has failed, let's fail # it right away as TestNA. if params.get("dependency_failed") == 'yes': raise error.TestNAError("Test dependency failed") # Report virt test version logging.info(version.get_pretty_version_info()) # Report the parameters we've received and write them as keyvals logging.debug("Test parameters:") keys = params.keys() keys.sort() for key in keys: logging.debug(" %s = %s", key, params[key]) self.write_test_keyval({key: params[key]}) # Set the log file dir for the logging mechanism used by kvm_subprocess # (this must be done before unpickling env) utils_misc.set_log_file_dir(self.debugdir) # Open the environment file custom_env_path = params.get("custom_env_path", "") if custom_env_path: env_path = custom_env_path else: env_path = params.get("vm_type") env_filename = os.path.join(self.bindir, "backends", env_path, params.get("env", "env")) env = utils_env.Env(env_filename, self.env_version) other_subtests_dirs = params.get("other_tests_dirs", "") test_passed = False t_type = None try: try: try: subtest_dirs = [] bin_dir = self.bindir for d in other_subtests_dirs.split(): # Replace split char. d = os.path.join(*d.split("/")) subtestdir = os.path.join(bin_dir, d, "tests") if not os.path.isdir(subtestdir): raise error.TestError("Directory %s not" " exist." % (subtestdir)) subtest_dirs += data_dir.SubdirList(subtestdir, bootstrap.test_filter) # Verify if we have the correspondent source file for it for generic_subdir in asset.get_test_provider_subdirs('generic'): subtest_dirs += data_dir.SubdirList(generic_subdir, bootstrap.test_filter) for specific_subdir in asset.get_test_provider_subdirs(params.get("vm_type")): subtest_dirs += data_dir.SubdirList(specific_subdir, bootstrap.test_filter) subtest_dir = None # Get the test routine corresponding to the specified # test type logging.debug("Searching for test modules that match " "'type = %s' and 'provider = %s' " "on this cartesian dict", params.get("type"), params.get("provider", None)) t_types = params.get("type").split() provider = params.get("provider", None) if provider is not None: subtest_dirs = [ d for d in subtest_dirs if provider in d] # Make sure we can load provider_lib in tests for s in subtest_dirs: if os.path.dirname(s) not in sys.path: sys.path.insert(0, os.path.dirname(s)) test_modules = {} for t_type in t_types: for d in subtest_dirs: module_path = os.path.join(d, "%s.py" % t_type) if os.path.isfile(module_path): subtest_dir = d break if subtest_dir is None: msg = ("Could not find test file %s.py on tests" "dirs %s" % (t_type, subtest_dirs)) raise error.TestError(msg) # Load the test module f, p, d = imp.find_module(t_type, [subtest_dir]) test_modules[t_type] = imp.load_module(t_type, f, p, d) f.close() # Preprocess try: params = env_process.preprocess(self, params, env) finally: env.save() # Run the test function for t_type in t_types: test_module = test_modules[t_type] run_func = utils_misc.get_test_entrypoint_func( t_type, test_module) try: run_func(self, params, env) self.verify_background_errors() finally: env.save() test_passed = True error_message = funcatexit.run_exitfuncs(env, t_type) if error_message: raise error.TestWarn("funcatexit failed with: %s" % error_message) except Exception, e: if t_type is not None: error_message = funcatexit.run_exitfuncs(env, t_type) if error_message: logging.error(error_message) logging.error("Test failed: %s: %s", e.__class__.__name__, e) try: env_process.postprocess_on_error( self, params, env) finally: env.save() raise finally: # Postprocess try: try: env_process.postprocess(self, params, env) except Exception, e: if test_passed: raise logging.error("Exception raised during " "postprocessing: %s", e) finally: env.save() except Exception, e: if params.get("abort_on_error") != "yes": raise # Abort on error logging.info("Aborting job (%s)", e) if params.get("vm_type") == "qemu": for vm in env.get_all_vms(): if vm.is_dead(): continue logging.info("VM '%s' is alive.", vm.name) for m in vm.monitors: logging.info( "'%s' has a %s monitor unix socket at: %s", vm.name, m.protocol, m.filename) logging.info( "The command line used to start '%s' was:\n%s", vm.name, vm.make_create_command()) raise error.JobError("Abort requested (%s)" % e)
def run_readonly_disk(test, params, env): """ KVM reboot test: 1) Log into a guest with virtio data disk 2) Format the disk and copy file to it 3) Stop the guest and boot up it again with the data disk set to readonly 4) Try to copy file to the data disk 5) Try to copy file from the data disk @param test: QEMU test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ error.context("Try to log into guest.", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = float(params.get("login_timeout", 240)) session = vm.wait_for_login(timeout=timeout) create_partition_cmd = params.get("create_partition_cmd") format_cmd = params.get("format_cmd") copy_cmd = params.get("copy_cmd") src_file = params.get("src_file") disk_letter = params.get("disk_letter") #update the cdrom letter for winutils cdrom_chk_cmd = "echo list volume > cmd && echo exit >>" cdrom_chk_cmd += " cmd && diskpart /s cmd" vols = re.findall("\s+([A-Z])\s+.*CDFS.*\n", session.cmd_output(cdrom_chk_cmd)) if vols: src_file = re.sub("WIN_UTIL", vols[0], src_file) else: raise error.TestError("Can not find winutils in guest.") filen = 0 error.context("Format the disk and copy file to it", logging.info) session.cmd(create_partition_cmd) session.cmd(format_cmd) dst_file = disk_letter + ":\\" + str(filen) session.cmd(copy_cmd % (src_file, dst_file)) filen += 1 msg = "Stop the guest and boot up it again with the data disk" msg += " set to readonly" error.context(msg, logging.info) session.close() vm.destroy() data_img = params.get("images").split()[-1] params["image_readonly_%s" % data_img] = "yes" params["force_create_image_%s" % data_img] = "no" env_process.preprocess(test, params, env) vm = env.get_vm(params["main_vm"]) vm.verify_alive() session = vm.wait_for_login(timeout=timeout) try: error.context("Try to write to the readonly disk", logging.info) dst_file_readonly = disk_letter + ":\\" + str(filen) session.cmd(copy_cmd % (src_file, dst_file_readonly)) raise error.TestFail("Write in readonly disk should failed.") except aexpect.ShellCmdError: error.context("Try to read from the readonly disk", logging.info) session.cmd(copy_cmd % (dst_file, "C:\\")) session.close()
def run_once(self, params): # Convert params to a Params object params = utils_params.Params(params) # If a dependency test prior to this test has failed, let's fail # it right away as TestNA. if params.get("dependency_failed") == 'yes': raise exceptions.TestSkipError("Test dependency failed") # Report virt test version logging.info(version.get_pretty_version_info()) # Report the parameters we've received and write them as keyvals logging.debug("Test parameters:") keys = params.keys() keys.sort() for key in keys: logging.debug(" %s = %s", key, params[key]) self.write_test_keyval({key: params[key]}) # Set the log file dir for the logging mechanism used by kvm_subprocess # (this must be done before unpickling env) utils_misc.set_log_file_dir(self.debugdir) # Open the environment file custom_env_path = params.get("custom_env_path", "") if custom_env_path: env_path = custom_env_path else: env_path = params.get("vm_type") env_filename = os.path.join(self.bindir, "backends", env_path, params.get("env", "env")) env = utils_env.Env(env_filename, self.env_version) other_subtests_dirs = params.get("other_tests_dirs", "") test_passed = False t_type = None try: try: try: subtest_dirs = [] bin_dir = self.bindir for d in other_subtests_dirs.split(): # Replace split char. d = os.path.join(*d.split("/")) subtestdir = os.path.join(bin_dir, d, "tests") if not os.path.isdir(subtestdir): raise exceptions.TestError("Directory %s not" " exist." % (subtestdir)) subtest_dirs += data_dir.SubdirList(subtestdir, bootstrap.test_filter) # Verify if we have the correspondent source file for it for generic_subdir in asset.get_test_provider_subdirs('generic'): subtest_dirs += data_dir.SubdirList(generic_subdir, bootstrap.test_filter) for multi_host_migration_subdir in asset.get_test_provider_subdirs( 'multi_host_migration'): subtest_dirs += data_dir.SubdirList(multi_host_migration_subdir, bootstrap.test_filter) for specific_subdir in asset.get_test_provider_subdirs(params.get("vm_type")): subtest_dirs += data_dir.SubdirList(specific_subdir, bootstrap.test_filter) subtest_dir = None # Get the test routine corresponding to the specified # test type logging.debug("Searching for test modules that match " "'type = %s' and 'provider = %s' " "on this cartesian dict", params.get("type"), params.get("provider", None)) t_types = params.get("type").split() provider = params.get("provider", None) if provider is not None: subtest_dirs = [ d for d in subtest_dirs if provider in d] # Make sure we can load provider_lib in tests for s in subtest_dirs: if os.path.dirname(s) not in sys.path: sys.path.insert(0, os.path.dirname(s)) test_modules = {} for t_type in t_types: for d in subtest_dirs: module_path = os.path.join(d, "%s.py" % t_type) if os.path.isfile(module_path): subtest_dir = d break if subtest_dir is None: msg = ("Could not find test file %s.py on tests" "dirs %s" % (t_type, subtest_dirs)) raise exceptions.TestError(msg) # Load the test module f, p, d = imp.find_module(t_type, [subtest_dir]) test_modules[t_type] = imp.load_module(t_type, f, p, d) f.close() # Preprocess try: params = env_process.preprocess(self, params, env) finally: env.save() # Run the test function for t_type in t_types: test_module = test_modules[t_type] run_func = utils_misc.get_test_entrypoint_func( t_type, test_module) try: run_func(self, params, env) self.verify_background_errors() finally: env.save() test_passed = True error_message = funcatexit.run_exitfuncs(env, t_type) if error_message: raise exceptions.TestWarn("funcatexit failed with: %s" % error_message) except Exception as e: if t_type is not None: error_message = funcatexit.run_exitfuncs(env, t_type) if error_message: logging.error(error_message) logging.error("Test failed: %s: %s", e.__class__.__name__, e) try: env_process.postprocess_on_error( self, params, env) finally: env.save() raise finally: # Postprocess try: try: env_process.postprocess(self, params, env) except Exception as e: if test_passed: raise logging.error("Exception raised during " "postprocessing: %s", e) finally: env.save() except Exception as e: if params.get("abort_on_error") != "yes": raise # Abort on error logging.info("Aborting job (%s)", e) if params.get("vm_type") == "qemu": for vm in env.get_all_vms(): if vm.is_dead(): continue logging.info("VM '%s' is alive.", vm.name) for m in vm.monitors: logging.info( "'%s' has a %s monitor unix socket at: %s", vm.name, m.protocol, m.filename) logging.info( "The command line used to start '%s' was:\n%s", vm.name, vm.make_create_command()) raise exceptions.JobError("Abort requested (%s)" % e)
def run(test, params, env): """ KVM readonly_floppy test: 1) pre_command on the host to generate the floppy media : "dd if=images/fd1.img bs=512 count=2880 && dd if=images/fd2.img bs=512 count=2880" 2) Boot and login into a guest; 3) If the OS is linux, load the floppy module, or if it is a Windows,wait 20s until the floppies are ready to be used 4) Make filesystem against the floppy and reads the output of the command,check if there is 'Read-only'(for linux) or 'protected'(for windows) keyword,if not,fail the test; 5) Close session to the VM :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ vt_data_dir = data_dir.get_data_dir() if params.get("start_vm") == "no": params["start_vm"] = "yes" params["pre_command"] = params.get("pre_cmd") % (vt_data_dir, vt_data_dir) env_process.preprocess(test, params, env) error_context.context("Boot up guest with floppies", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = float(params.get("login_timeout", 240)) session = vm.wait_for_login(timeout=timeout) sleep = params.get("sleep") # if it is a windows OS,wait for 20 seconds until the floppies # are ready for testing if sleep: logging.info("Windows system being tested,sleep for 20" " seconds until floppies are ready to be use") time.sleep(20) try: # if it is a linux OS,load the floppy module if not sleep: logging.info("Loading the floppy module...") status = session.cmd_status("modprobe floppy") logging.info("Sleep 5 seconds after loading the floppy module") time.sleep(5) if status: test.error("Unable to load the floppy module") # Format floppy disk to test if it is readonly floppy_count = len(params.get("floppies", "").split()) format_cmd_list = [params.get("format_floppy0_cmd"), params.get("format_floppy1_cmd")] for floppy_index in range(floppy_count): error_context.context("Format the %s floppy disk" % floppy_index, logging.info) s, o = session.cmd_status_output( format_cmd_list[floppy_index], timeout=float(params.get("format_floppy_timeout", 60))) if s == 0: test.error("Floppy disk %s is not readonly and" " it's formatted successfully" % floppy_index) error_context.context("Check the %s floppy is readonly" % floppy_index, logging.info) found = re.search('(Read-only)|(protected)', o) logging.debug("Output of format command: %s" % o) if not found: test.error("Floppy disk %s cannot be formatted" " for reasons other than readonly" % floppy_index) else: logging.info("Floppy disk %s is Read-only and cannot be" " formatted" % floppy_index) finally: if session: session.close()