def rebase_test(cmd): """ Subcommand 'qemu-img rebase' test Change the backing file of a snapshot image in "unsafe mode": Assume the previous backing file had missed and we just have to change reference of snapshot to new one. After change the backing file of a snapshot image in unsafe mode, the snapshot should work still. @param cmd: qemu-img base command. """ if not 'rebase' in utils.system_output(cmd + ' --help', ignore_status=True): raise error.TestNAError("Current kvm user space version does not" " support 'rebase' subcommand") sn_fmt = params.get("snapshot_format", "qcow2") sn1 = params.get("image_name_snapshot1") sn1 = virt_utils.get_path(test.bindir, sn1) + ".%s" % sn_fmt base_img = virt_vm.get_image_filename(params, test.bindir) _create(cmd, sn1, sn_fmt, base_img=base_img, base_img_fmt=image_format) # Create snapshot2 based on snapshot1 sn2 = params.get("image_name_snapshot2") sn2 = virt_utils.get_path(test.bindir, sn2) + ".%s" % sn_fmt _create(cmd, sn2, sn_fmt, base_img=sn1, base_img_fmt=sn_fmt) rebase_mode = params.get("rebase_mode") if rebase_mode == "unsafe": os.remove(sn1) _rebase(cmd, sn2, base_img, image_format, mode=rebase_mode) # Check sn2's format and backing_file actual_base_img = _info(cmd, sn2, "backing file") base_img_name = os.path.basename(params.get("image_name")) if not base_img_name in actual_base_img: raise error.TestFail("After rebase the backing_file of 'sn2' is " "'%s' which is not expected as '%s'" % (actual_base_img, base_img_name)) s, o = _check(cmd, sn2) if not s: raise error.TestFail("Check image '%s' failed after rebase;" "got error: %s" % (sn2, o)) try: os.remove(sn2) os.remove(sn1) except: pass
def check_test(cmd): """ Subcommand 'qemu-img check' test. This tests will 'dd' to create a specified size file, and check it. Then convert it to supported image_format in each loop and check again. @param cmd: qemu-img base command. """ test_image = virt_utils.get_path(test.bindir, params.get("image_name_dd")) print "test_image = %s" % test_image create_image_cmd = params.get("create_image_cmd") create_image_cmd = create_image_cmd % test_image print "create_image_cmd = %s" % create_image_cmd utils.system(create_image_cmd) s, o = _check(cmd, test_image) if not s: raise error.TestFail("Check image '%s' failed with error: %s" % (test_image, o)) for fmt in params.get("supported_image_formats").split(): output_image = test_image + ".%s" % fmt _convert(cmd, fmt, test_image, output_image) s, o = _check(cmd, output_image) if not s: raise error.TestFail("Check image '%s' got error: %s" % (output_image, o)) os.remove(output_image) os.remove(test_image)
def run_qemu_img(test, params, env): """ 'qemu-img' functions test: 1) Judge what subcommand is going to be tested 2) Run subcommand test @param test: kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ cmd = virt_utils.get_path(test.bindir, params.get("qemu_img_binary")) if not os.path.exists(cmd): raise error.TestError("Binary of 'qemu-img' not found") image_format = params.get("image_format") image_size = params.get("image_size", "10G") image_name = virt_vm.get_image_filename(params, test.bindir) def _check(cmd, img): """ Simple 'qemu-img check' function implementation. @param cmd: qemu-img base command. @param img: image to be checked """ cmd += " check %s" % img logging.info("Checking image '%s'...", img) try: output = utils.system_output(cmd) except error.CmdError, e: if "does not support checks" in str(e): return (True, "") else: return (False, str(e)) return (True, output)
def run_qemu_iotests(test, params, env): """ Fetch from git and run qemu-iotests using the qemu binaries under test. 1) Fetch qemu-io from git 3) Run test for the file format detected 4) Report any errors found to autotest @param test: KVM test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ # First, let's get qemu-io std = "git://git.kernel.org/pub/scm/linux/kernel/git/hch/qemu-iotests.git" uri = params.get("qemu_io_uri", std) branch = params.get("qemu_io_branch", 'master') lbranch = params.get("qemu_io_lbranch", 'master') commit = params.get("qemu_io_commit", None) base_uri = params.get("qemu_io_base_uri", None) destination_dir = os.path.join(test.srcdir, "qemu_io_tests") git.get_repo(uri=uri, branch=branch, lbranch=lbranch, commit=commit, destination_dir=destination_dir, base_uri=base_uri) # Then, set the qemu paths for the use of the testsuite os.environ["QEMU_PROG"] = virt_utils.get_path( test.bindir, params.get("qemu_binary", "qemu")) os.environ["QEMU_IMG_PROG"] = virt_utils.get_path( test.bindir, params.get("qemu_img_binary", "qemu-img")) os.environ["QEMU_IO_PROG"] = virt_utils.get_path( test.bindir, params.get("qemu_io_binary", "qemu-io")) os.chdir(destination_dir) image_format = params.get("qemu_io_image_format") extra_options = params.get("qemu_io_extra_options", "") cmd = './check' if extra_options: cmd += extra_options error.context("running qemu-iotests for image format %s" % image_format) utils.system("%s -%s" % (cmd, image_format))
def run_qemu_iotests(test, params, env): """ Fetch from git and run qemu-iotests using the qemu binaries under test. 1) Fetch qemu-io from git 3) Run test for the file format detected 4) Report any errors found to autotest @param test: KVM test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ # First, let's get qemu-io std = "git://git.kernel.org/pub/scm/linux/kernel/git/hch/qemu-iotests.git" uri = params.get("qemu_io_uri", std) branch = params.get("qemu_io_branch", 'master') lbranch = params.get("qemu_io_lbranch", 'master') commit = params.get("qemu_io_commit", None) base_uri = params.get("qemu_io_base_uri", None) destination_dir = os.path.join(test.srcdir, "qemu_io_tests") git.get_repo(uri=uri, branch=branch, lbranch=lbranch, commit=commit, destination_dir=destination_dir, base_uri=base_uri) # Then, set the qemu paths for the use of the testsuite os.environ["QEMU_PROG"] = virt_utils.get_path(test.bindir, params.get("qemu_binary", "qemu")) os.environ["QEMU_IMG_PROG"] = virt_utils.get_path(test.bindir, params.get("qemu_img_binary", "qemu-img")) os.environ["QEMU_IO_PROG"] = virt_utils.get_path(test.bindir, params.get("qemu_io_binary", "qemu-io")) os.chdir(destination_dir) image_format = params.get("qemu_io_image_format") extra_options = params.get("qemu_io_extra_options", "") cmd = './check' if extra_options: cmd += extra_options error.context("running qemu-iotests for image format %s" % image_format) utils.system("%s -%s" % (cmd, image_format))
def create_test(cmd): """ Subcommand 'qemu-img create' test. @param cmd: qemu-img base command. """ image_large = params.get("image_name_large") img = virt_utils.get_path(test.bindir, image_large) img += '.' + image_format _create(cmd, img_name=img, fmt=image_format, img_size=params.get("image_size_large")) os.remove(img)
def run_stepmaker(test, params, env): vm = env.get_vm(params.get("main_vm")) if not vm: raise error.TestError("VM object not found in environment") if not vm.is_alive(): raise error.TestError("VM seems to be dead; Step Maker requires a" " living VM") steps_filename = params.get("steps") if not steps_filename: raise error.TestError("Steps filename not specified") steps_filename = virt_utils.get_path(test.virtdir, steps_filename) if os.path.exists(steps_filename): raise error.TestError("Steps file %s already exists" % steps_filename) StepMaker(vm, steps_filename, test.debugdir, params) gtk.main()
def netdev_add(vm): netdev_id = virt_utils.generate_random_id() attach_cmd = ("netdev_add tap,id=%s" % netdev_id) nic_script = params.get("nic_script") if nic_script: attach_cmd += ",script=%s" % virt_utils.get_path( vm.root_dir, nic_script) netdev_extra_params = params.get("netdev_extra_params") if netdev_extra_params: attach_cmd += ",%s" % netdev_extra_params logging.info("Adding netdev through %s", attach_cmd) vm.monitor.cmd(attach_cmd) network = vm.monitor.info("network") if netdev_id not in network: logging.error(network) raise error.TestError("Fail to add netdev: %s" % netdev_id) else: return netdev_id
def netdev_add(vm): netdev_id = virt_utils.generate_random_id() attach_cmd = ("netdev_add tap,id=%s" % netdev_id) nic_script = params.get("nic_script") if nic_script: attach_cmd += ",script=%s" % virt_utils.get_path(vm.root_dir, nic_script) netdev_extra_params = params.get("netdev_extra_params") if netdev_extra_params: attach_cmd += ",%s" % netdev_extra_params logging.info("Adding netdev through %s", attach_cmd) vm.monitor.cmd(attach_cmd) network = vm.monitor.info("network") if netdev_id not in network: logging.error(network) raise error.TestError("Fail to add netdev: %s" % netdev_id) else: return netdev_id
def run_qemu_io_blkdebug(test, params, env): """ Run qemu-io blkdebug tests: 1. Create image with given parameters 2. Write the blkdebug config file 3. Try to do operate in image with qemu-io and get the error message 4. Get the error message from perror by error number set in config file 5. Compare the error message @param test: kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ tmp_dir = params.get("tmp_dir", "/tmp") blkdebug_cfg = virt_utils.get_path(tmp_dir, params.get("blkdebug_cfg", "blkdebug.cfg")) err_command = params.get("err_command") err_event = params.get("err_event") errn_list = re.split("\s+", params.get("errn_list").strip()) re_std_msg = params.get("re_std_msg") test_timeout = int(params.get("test_timeout", "60")) pre_err_commands = params.get("pre_err_commands") image = params.get("images") blkdebug_default = params.get("blkdebug_default") error.context("Create image", logging.info) image_name = virt_vm.create_image(params.object_params(image), test.bindir) template_name = virt_utils.get_path(test.virtdir, blkdebug_default) template = ConfigParser.ConfigParser() template.read(template_name) for errn in errn_list: log_filename = virt_utils.get_path(test.outputdir, "qemu-io-log-%s" % errn) error.context("Write the blkdebug config file", logging.info) template.set("inject-error", "event", '"%s"' % err_event) template.set("inject-error", "errno", '"%s"' % errn) with open(blkdebug_cfg, 'w') as blkdebug: template.write(blkdebug) blkdebug.close() error.context("Operate in qemu-io to trigger the error", logging.info) session = qemu_io.QemuIOShellSession(test, params, image_name, blkdebug_cfg=blkdebug_cfg, log_filename=log_filename) if pre_err_commands: for cmd in re.split(",", pre_err_commands.strip()): session.cmd_output(cmd, timeout=test_timeout) output = session.cmd_output(err_command, timeout=test_timeout) error.context("Get error message from command perror", logging.info) perror_cmd = "perror %s" % errn std_msg = utils.system_output(perror_cmd) std_msg = re.findall(re_std_msg, std_msg) if std_msg: std_msg = std_msg[0] else: std_msg = "" logging.warning("Can not find error message from perror") session.close() error.context("Compare the error message", logging.info) if std_msg: if std_msg in output: logging.info("Error message is correct in qemu-io") else: fail_log = "The error message is mismatch:" fail_log += "qemu-io reports: '%s'," % output fail_log += "perror reports: '%s'" % std_msg raise error.TestFail(fail_log) else: logging.warning("Can not find error message from perror." " The output from qemu-io is %s" % output)
def run_steps(test, params, env): vm = env.get_vm(params.get("main_vm")) if not vm: raise error.TestError("VM object not found in environment") if not vm.is_alive(): e_msg = "VM seems to be dead. Guestwizard requires a living VM" raise error.TestError(e_msg) steps_filename = params.get("steps") if not steps_filename: raise error.TestError("Steps filename not specified") steps_filename = virt_utils.get_path(test.bindir, steps_filename) if not os.path.exists(steps_filename): raise error.TestError("Steps file not found: %s" % steps_filename) sf = open(steps_filename, "r") lines = sf.readlines() sf.close() vm.monitor.cmd("cont") current_step_num = 0 current_screendump = None skip_current_step = False # Iterate over the lines in the file for line in lines: line = line.strip() if not line: continue logging.info(line) if line.startswith("#"): continue words = line.split() if words[0] == "step": current_step_num += 1 current_screendump = None skip_current_step = False elif words[0] == "screendump": current_screendump = words[1] elif skip_current_step: continue elif words[0] == "sleep": timeout_multiplier = float(params.get("timeout_multiplier") or 1) time.sleep(float(words[1]) * timeout_multiplier) elif words[0] == "key": vm.send_key(words[1]) elif words[0] == "var": if not handle_var(vm, params, words[1]): logging.error("Variable not defined: %s", words[1]) elif words[0] == "barrier_2": if current_screendump: scrdump_filename = os.path.join( ppm_utils.get_data_dir(steps_filename), current_screendump) else: scrdump_filename = None if not barrier_2(vm, words, params, test.debugdir, scrdump_filename, current_step_num): skip_current_step = True else: vm.send_key(words[0])
def run_cpuflags(test, params, env): """ Boot guest with different cpu flags and check if guest works correctly. @param test: kvm test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ virt_utils.Flag.aliases = virt_utils.kvm_map_flags_aliases qemu_binary = virt_utils.get_path('.', params.get("qemu_binary", "qemu")) cpuflags_src = os.path.join(test.virtdir, "deps", "test_cpu_flags") smp = int(params.get("smp", 1)) all_host_supported_flags = params.get("all_host_supported_flags", "no") mig_timeout = float(params.get("mig_timeout", "3600")) mig_protocol = params.get("migration_protocol", "tcp") mig_speed = params.get("mig_speed", "100M") multi_host_migration = params.get("multi_host_migration", "no") class HgFlags(object): def __init__(self, cpu_model, extra_flags=set([])): virtual_flags = set(map(virt_utils.Flag, params.get("guest_spec_flags", "").split())) self.hw_flags = set(map(virt_utils.Flag, params.get("host_spec_flags", "").split())) self.qemu_support_flags = get_all_qemu_flags() self.host_support_flags = set(map(virt_utils.Flag, virt_utils.get_cpu_flags())) self.quest_cpu_model_flags = (get_guest_host_cpuflags(cpu_model) - virtual_flags) self.supported_flags = (self.qemu_support_flags & self.host_support_flags) self.cpumodel_unsupport_flags = (self.supported_flags - self.quest_cpu_model_flags) self.host_unsupported_flags = (self.quest_cpu_model_flags - self.host_support_flags) self.all_possible_guest_flags = (self.quest_cpu_model_flags - self.host_unsupported_flags) self.all_possible_guest_flags |= self.cpumodel_unsupport_flags self.guest_flags = (self.quest_cpu_model_flags - self.host_unsupported_flags) self.guest_flags |= extra_flags self.host_all_unsupported_flags = set([]) self.host_all_unsupported_flags |= self.qemu_support_flags self.host_all_unsupported_flags -= (self.host_support_flags | virtual_flags) def start_guest_with_cpuflags(cpuflags, smp=None, migration=False, wait=True): """ Try to boot guest with special cpu flags and try login in to them. """ params_b = params.copy() params_b["cpu_model"] = cpuflags if smp is not None: params_b["smp"] = smp vm_name = "vm1-cpuflags" vm = kvm_vm.VM(vm_name, params_b, test.bindir, env['address_cache']) env.register_vm(vm_name, vm) if (migration is True): vm.create(migration_mode=mig_protocol) else: vm.create() vm.verify_alive() session = None if wait: session = vm.wait_for_login() return (vm, session) def get_guest_system_cpuflags(vm_session): """ Get guest system cpuflags. @param vm_session: session to checked vm. @return: [corespond flags] """ flags_re = re.compile(r'^flags\s*:(.*)$', re.MULTILINE) out = vm_session.cmd_output("cat /proc/cpuinfo") flags = flags_re.search(out).groups()[0].split() return set(map(virt_utils.Flag, flags)) def get_guest_host_cpuflags(cpumodel): """ Get cpu flags correspond with cpumodel parameters. @param cpumodel: Cpumodel parameter sended to <qemu-kvm-cmd>. @return: [corespond flags] """ cmd = qemu_binary + " -cpu ?dump" output = utils.run(cmd).stdout re.escape(cpumodel) pattern = (".+%s.*\n.*\n +feature_edx .+ \((.*)\)\n +feature_" "ecx .+ \((.*)\)\n +extfeature_edx .+ \((.*)\)\n +" "extfeature_ecx .+ \((.*)\)\n" % (cpumodel)) flags = [] model = re.search(pattern, output) if model == None: raise error.TestFail("Cannot find %s cpu model." % (cpumodel)) for flag_group in model.groups(): flags += flag_group.split() return set(map(virt_utils.Flag, flags)) def get_all_qemu_flags(): cmd = qemu_binary + " -cpu ?cpuid" output = utils.run(cmd).stdout flags_re = re.compile(r".*\n.*f_edx:(.*)\n.*f_ecx:(.*)\n.*extf_edx:" "(.*)\n.*extf_ecx:(.*)") m = flags_re.search(output) flags = [] for a in m.groups(): flags += a.split() return set(map(virt_utils.Flag, flags)) def get_flags_full_name(cpu_flag): """ Get all name of Flag. @param cpu_flag: Flag @return: all name of Flag. """ cpu_flag = virt_utils.Flag(cpu_flag) for f in get_all_qemu_flags(): if f == cpu_flag: return virt_utils.Flag(f) return [] def parse_qemu_cpucommand(cpumodel): """ Parse qemu cpu params. @param cpumodel: Cpu model command. @return: All flags which guest must have. """ flags = cpumodel.split(",") cpumodel = flags[0] qemu_model_flag = get_guest_host_cpuflags(cpumodel) host_support_flag = set(map(virt_utils.Flag, virt_utils.get_cpu_flags())) real_flags = qemu_model_flag & host_support_flag for f in flags[1:]: if f[0].startswith("+"): real_flags |= set([get_flags_full_name(f[1:])]) if f[0].startswith("-"): real_flags -= set([get_flags_full_name(f[1:])]) return real_flags def get_cpu_models(): """ Get all cpu models from qemu. @return: cpu models. """ cmd = qemu_binary + " -cpu ?" output = utils.run(cmd).stdout cpu_re = re.compile("\w+\s+\[?(\w+)\]?") return cpu_re.findall(output) def check_cpuflags(cpumodel, vm_session): """ Check if vm flags are same like flags select by cpumodel. @param cpumodel: params for -cpu param in qemu-kvm @param vm_session: session to vm to check flags. @return: ([excess], [missing]) flags """ gf = get_guest_system_cpuflags(vm_session) rf = parse_qemu_cpucommand(cpumodel) logging.debug("Guest flags: %s", gf) logging.debug("Host flags: %s", rf) logging.debug("Flags on guest not defined by host: %s", (gf - rf)) return rf - gf def disable_cpu(vm_session, cpu, disable=True): """ Disable cpu in guest system. @param cpu: CPU id to disable. @param disable: if True disable cpu else enable cpu. """ system_cpu_dir = "/sys/devices/system/cpu/" cpu_online = system_cpu_dir + "cpu%d/online" % (cpu) cpu_state = vm_session.cmd_output("cat %s" % cpu_online).strip() if disable and cpu_state == "1": vm_session.cmd("echo 0 > %s" % cpu_online) logging.debug("Guest cpu %d is disabled.", cpu) elif cpu_state == "0": vm_session.cmd("echo 1 > %s" % cpu_online) logging.debug("Guest cpu %d is enabled.", cpu) def install_cpuflags_test_on_vm(vm, dst_dir): """ Install stress to vm. @param vm: virtual machine. @param dst_dir: Installation path. """ session = vm.wait_for_login() vm.copy_files_to(cpuflags_src, dst_dir) session.cmd("sync") session.cmd("cd %s; make EXTRA_FLAGS='';" % os.path.join(dst_dir, "test_cpu_flags")) session.cmd("sync") session.close() def check_cpuflags_work(vm, path, flags): """ Check which flags work. @param vm: Virtual machine. @param path: Path of cpuflags_test @param flags: Flags to test. @return: Tuple (Working, not working, not tested) flags. """ pass_Flags = [] not_tested = [] not_working = [] session = vm.wait_for_login() for f in flags: try: for tc in virt_utils.kvm_map_flags_to_test[f]: session.cmd("%s/cpuflags-test --%s" % (os.path.join(path, "test_cpu_flags"), tc)) pass_Flags.append(f) except aexpect.ShellCmdError: not_working.append(f) except KeyError: not_tested.append(f) return (set(map(virt_utils.Flag, pass_Flags)), set(map(virt_utils.Flag, not_working)), set(map(virt_utils.Flag, not_tested))) def run_stress(vm, timeout, guest_flags): """ Run stress on vm for timeout time. """ ret = False install_path = "/tmp" install_cpuflags_test_on_vm(vm, install_path) flags = check_cpuflags_work(vm, install_path, guest_flags) dd_session = vm.wait_for_login() stress_session = vm.wait_for_login() dd_session.sendline("dd if=/dev/[svh]da of=/tmp/stressblock" " bs=10MB count=100 &") try: stress_session.cmd("%s/cpuflags-test --stress %s%s" % (os.path.join(install_path, "test_cpu_flags"), smp, virt_utils.kvm_flags_to_stresstests(flags[0])), timeout=timeout) except aexpect.ShellTimeoutError: ret = True stress_session.close() dd_session.close() return ret def separe_cpu_model(cpu_model): try: (cpu_model, _) = cpu_model.split(":") except ValueError: cpu_model = cpu_model return cpu_model def parse_cpu_model(): """ Parse cpu_models from config file. @return: [(cpumodel, extra_flags)] """ cpu_model = params.get("cpu_model", "") logging.debug("CPU model found: %s", str(cpu_model)) try: (cpu_model, extra_flags) = cpu_model.split(":") extra_flags = set(map(virt_utils.Flag, extra_flags.split(","))) except ValueError: cpu_model = cpu_model extra_flags = set([]) return (cpu_model, extra_flags) class MiniSubtest(object): def __new__(cls, *args, **kargs): self = super(MiniSubtest, cls).__new__(cls) ret = None if args is None: args = [] try: ret = self.test(*args, **kargs) finally: if hasattr(self, "clean"): self.clean() return ret class Test_temp(MiniSubtest): def clean(self): logging.info("cleanup") if (hasattr(self, "vm")): self.vm.destroy(gracefully=False) # 1) <qemu-kvm-cmd> -cpu ?model class test_qemu_cpu_model(MiniSubtest): def test(self): cpu_models = params.get("cpu_models", "core2duo").split() cmd = qemu_binary + " -cpu ?model" result = utils.run(cmd) missing = [] cpu_models = map(separe_cpu_model, cpu_models) for cpu_model in cpu_models: if not cpu_model in result.stdout: missing.append(cpu_model) if missing: raise error.TestFail("CPU models %s are not in output " "'%s' of command \n%s" % (missing, cmd, result.stdout)) # 2) <qemu-kvm-cmd> -cpu ?dump class test_qemu_dump(MiniSubtest): def test(self): cpu_models = params.get("cpu_models", "core2duo").split() cmd = qemu_binary + " -cpu ?dump" result = utils.run(cmd) cpu_models = map(separe_cpu_model, cpu_models) missing = [] for cpu_model in cpu_models: if not cpu_model in result.stdout: missing.append(cpu_model) if missing: raise error.TestFail("CPU models %s are not in output " "'%s' of command \n%s" % (missing, cmd, result.stdout)) # 3) <qemu-kvm-cmd> -cpu ?cpuid class test_qemu_cpuid(MiniSubtest): def test(self): cmd = qemu_binary + " -cpu ?cpuid" result = utils.run(cmd) if result.stdout is "": raise error.TestFail("There aren't any cpu Flag in output" " '%s' of command \n%s" % (cmd, result.stdout)) # 1) boot with cpu_model class test_boot_cpu_model(Test_temp): def test(self): cpu_model, _ = parse_cpu_model() logging.debug("Run tests with cpu model %s", cpu_model) flags = HgFlags(cpu_model) (self.vm, session) = start_guest_with_cpuflags(cpu_model) not_enable_flags = (check_cpuflags(cpu_model, session) - flags.hw_flags) if not_enable_flags != set([]): raise error.TestFail("Flags defined on host but not found " "on guest: %s" % (not_enable_flags)) # 2) success boot with supported flags class test_boot_cpu_model_and_additional_flags(Test_temp): def test(self): cpu_model, extra_flags = parse_cpu_model() flags = HgFlags(cpu_model, extra_flags) logging.debug("Cpu mode flags %s.", str(flags.quest_cpu_model_flags)) cpuf_model = cpu_model if all_host_supported_flags == "yes": for fadd in flags.cpumodel_unsupport_flags: cpuf_model += ",+" + fadd else: for fadd in extra_flags: cpuf_model += ",+" + fadd for fdel in flags.host_unsupported_flags: cpuf_model += ",-" + fdel if all_host_supported_flags == "yes": guest_flags = flags.all_possible_guest_flags else: guest_flags = flags.guest_flags (self.vm, session) = start_guest_with_cpuflags(cpuf_model) not_enable_flags = (check_cpuflags(cpuf_model, session) - flags.hw_flags) if not_enable_flags != set([]): logging.info("Model unsupported flags: %s", str(flags.cpumodel_unsupport_flags)) logging.error("Flags defined on host but not on found " "on guest: %s", str(not_enable_flags)) logging.info("Check main instruction sets.") install_path = "/tmp" install_cpuflags_test_on_vm(self.vm, install_path) Flags = check_cpuflags_work(self.vm, install_path, flags.all_possible_guest_flags) logging.info("Woking CPU flags: %s", str(Flags[0])) logging.info("Not working CPU flags: %s", str(Flags[1])) logging.warning("Flags works even if not deffined on guest cpu " "flags: %s", str(Flags[0] - guest_flags)) logging.warning("Not tested CPU flags: %s", str(Flags[2])) if Flags[1] & guest_flags: raise error.TestFail("Some flags do not work: %s" % (str(Flags[1]))) # 3) fail boot unsupported flags class test_boot_warn_with_host_unsupported_flags(MiniSubtest): def test(self): #This is virtual cpu flags which are supported by #qemu but no with host cpu. cpu_model, extra_flags = parse_cpu_model() flags = HgFlags(cpu_model, extra_flags) logging.debug("Unsupported flags %s.", str(flags.host_all_unsupported_flags)) cpuf_model = cpu_model + ",check" # Add unsupported flags. for fadd in flags.host_all_unsupported_flags: cpuf_model += ",+" + fadd vnc_port = virt_utils.find_free_port(5900, 6100) - 5900 cmd = "%s -cpu %s -vnc :%d" % (qemu_binary, cpuf_model, vnc_port) out = None try: try: out = utils.run(cmd, timeout=5, ignore_status=True).stderr raise error.TestFail("Guest not boot with unsupported " "flags.") except error.CmdError, e: out = e.result_obj.stderr finally: uns_re = re.compile("^warning:.*flag '(.+)'", re.MULTILINE) warn_flags = set(map(virt_utils.Flag, uns_re.findall(out))) fwarn_flags = flags.host_all_unsupported_flags - warn_flags if fwarn_flags: raise error.TestFail("Qemu did not warn the use of " "flags %s" % str(fwarn_flags)) # 3) fail boot unsupported flags class test_fail_boot_with_host_unsupported_flags(MiniSubtest): def test(self): #This is virtual cpu flags which are supported by #qemu but no with host cpu. cpu_model, extra_flags = parse_cpu_model() flags = HgFlags(cpu_model, extra_flags) logging.debug("Unsupported flags %s.", str(flags.host_all_unsupported_flags)) cpuf_model = cpu_model + ",enforce" # Add unsupported flags. for fadd in flags.host_all_unsupported_flags: cpuf_model += ",+" + fadd vnc_port = virt_utils.find_free_port(5900, 6100) - 5900 cmd = "%s -cpu %s -vnc :%d" % (qemu_binary, cpuf_model, vnc_port) out = None try: try: out = utils.run(cmd, timeout=5, ignore_status=True).stderr except error.CmdError: logging.error("Host boot with unsupported flag") finally: uns_re = re.compile("^warning:.*flag '(.+)'", re.MULTILINE) warn_flags = set(map(virt_utils.Flag, uns_re.findall(out))) fwarn_flags = flags.host_all_unsupported_flags - warn_flags if fwarn_flags: raise error.TestFail("Qemu did not warn the use of " "flags %s" % str(fwarn_flags)) # 4) check guest flags under load cpu, stress and system (dd) class test_boot_guest_and_try_flags_under_load(Test_temp): def test(self): logging.info("Check guest working cpuflags under load " "cpu and stress and system (dd)") cpu_model, extra_flags = parse_cpu_model() flags = HgFlags(cpu_model, extra_flags) logging.debug("Cpu mode flags %s.", str(flags.quest_cpu_model_flags)) logging.debug("Added flags %s.", str(flags.cpumodel_unsupport_flags)) cpuf_model = cpu_model # Add unsupported flags. for fadd in flags.cpumodel_unsupport_flags: cpuf_model += ",+" + fadd for fdel in flags.host_unsupported_flags: cpuf_model += ",-" + fdel (self.vm, _) = start_guest_with_cpuflags(cpuf_model, smp) if (not run_stress(self.vm, 60, flags.guest_flags)): raise error.TestFail("Stress test ended before" " end of test.") def clean(self): logging.info("cleanup") self.vm.destroy(gracefully=False) # 5) Online/offline CPU class test_online_offline_guest_CPUs(Test_temp): def test(self): cpu_model, extra_flags = parse_cpu_model() logging.debug("Run tests with cpu model %s.", (cpu_model)) flags = HgFlags(cpu_model, extra_flags) (self.vm, session) = start_guest_with_cpuflags(cpu_model, smp) def encap(timeout): random.seed() begin = time.time() end = begin if smp > 1: while end - begin < 60: cpu = random.randint(1, smp - 1) if random.randint(0, 1): disable_cpu(session, cpu, True) else: disable_cpu(session, cpu, False) end = time.time() return True else: logging.warning("For this test is necessary smp > 1.") return False timeout = 60 test_flags = flags.guest_flags if all_host_supported_flags == "yes": test_flags = flags.all_possible_guest_flags result = virt_utils.parallel([(encap, [timeout]), (run_stress, [self.vm, timeout, test_flags])]) if not (result[0] and result[1]): raise error.TestFail("Stress tests failed before" " end of testing.") # 6) migration test class test_migration_with_additional_flags(Test_temp): def test(self): cpu_model, extra_flags = parse_cpu_model() flags = HgFlags(cpu_model, extra_flags) logging.debug("Cpu mode flags %s.", str(flags.quest_cpu_model_flags)) logging.debug("Added flags %s.", str(flags.cpumodel_unsupport_flags)) cpuf_model = cpu_model # Add unsupported flags. for fadd in flags.cpumodel_unsupport_flags: cpuf_model += ",+" + fadd for fdel in flags.host_unsupported_flags: cpuf_model += ",-" + fdel (self.vm, _) = start_guest_with_cpuflags(cpuf_model, smp) install_path = "/tmp" install_cpuflags_test_on_vm(self.vm, install_path) flags = check_cpuflags_work(self.vm, install_path, flags.guest_flags) dd_session = self.vm.wait_for_login() stress_session = self.vm.wait_for_login() dd_session.sendline("nohup dd if=/dev/[svh]da of=/tmp/" "stressblock bs=10MB count=100 &") cmd = ("nohup %s/cpuflags-test --stress %s%s &" % (os.path.join(install_path, "test_cpu_flags"), smp, virt_utils.kvm_flags_to_stresstests(flags[0]))) stress_session.sendline(cmd) time.sleep(5) self.vm.monitor.migrate_set_speed(mig_speed) self.vm.migrate(mig_timeout, mig_protocol, offline=False) time.sleep(5) #If cpuflags-test hang up during migration test raise exception try: stress_session.cmd('killall cpuflags-test') except aexpect.ShellCmdError: raise error.TestFail("Cpuflags-test should work after" " migration.") def net_send_object(socket, obj): """ Send python object over network. @param ip_addr: ipaddres of waiter for data. @param obj: object to send """ data = pickle.dumps(obj, pickle.HIGHEST_PROTOCOL) socket.sendall("%6d" % len(data)) socket.sendall(data) def net_recv_object(socket, timeout=60): """ Receive python object over network. @param ip_addr: ipaddres of waiter for data. @param obj: object to send @return: object from network """ try: time_start = time.time() data = "" d_len = int(socket.recv(6)) while (len(data) < d_len and (time.time() - time_start) < timeout): data += socket.recv(d_len - len(data)) data = pickle.loads(data) return data except: error.TestFail("Failed to receive python object over the network") raise class test_multi_host_migration(Test_temp): def test(self): """ Test migration between multiple hosts. """ def guest_active(vm): o = vm.monitor.info("status") if isinstance(o, str): return "status: running" in o else: return o.get("status") == "running" cpu_model, extra_flags = parse_cpu_model() flags = HgFlags(cpu_model, extra_flags) logging.debug("Cpu mode flags %s.", str(flags.quest_cpu_model_flags)) logging.debug("Added flags %s.", str(flags.cpumodel_unsupport_flags)) cpuf_model = cpu_model for fadd in extra_flags: cpuf_model += ",+" + fadd for fdel in flags.host_unsupported_flags: cpuf_model += ",-" + fdel install_path = "/tmp" login_timeout = int(params.get("login_timeout", 360)) role = params.get("role") srchost = params.get("srchost") dsthost = params.get("dsthost") # Port used to communicate info between source and destination comm_port = int(params.get("comm_port", 12324)) comm_timeout = float(params.get("comm_timeout", "10")) regain_ip_cmd = params.get("regain_ip_cmd", "dhclient") if role == 'source': (self.vm, session) = start_guest_with_cpuflags(cpuf_model, smp) install_cpuflags_test_on_vm(self.vm, install_path) Flags = check_cpuflags_work(self.vm, install_path, flags.all_possible_guest_flags) logging.info("Woking CPU flags: %s", str(Flags[0])) logging.info("Not working CPU flags: %s", str(Flags[1])) logging.warning("Flags works even if not deffined on" " guest cpu flags: %s", str(Flags[0] - flags.guest_flags)) logging.warning("Not tested CPU flags: %s", str(Flags[2])) session.sendline("nohup dd if=/dev/[svh]da of=/tmp/" "stressblock bs=10MB count=100 &") cmd = ("nohup %s/cpuflags-test --stress %s%s &" % (os.path.join(install_path, "test_cpu_flags"), smp, virt_utils.kvm_flags_to_stresstests(Flags[0] & flags.guest_flags))) logging.debug("Guest_flags: %s", str(flags.guest_flags)) logging.debug("Working_flags: %s", str(Flags[0])) logging.debug("Start stress on guest: %s", cmd) session.sendline(cmd) # Listen on a port to get the migration port received from # dest machine s_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s_socket.bind(('', comm_port)) s_socket.listen(1) s_socket.settimeout(comm_timeout) # Wait 30 seconds for source and dest to reach this point test.job.barrier(srchost, 'socket_started', 120).rendezvous(srchost, dsthost) c_socket = s_socket.accept()[0] mig_port = int(c_socket.recv(6)) logging.info("Received from destination the" " migration port %s" % mig_port) c_socket.close() #Wait for start cpuflags-test stress. time.sleep(10) logging.info("Start migrating now...") self.vm.monitor.migrate_set_speed(mig_speed) self.vm.migrate(dest_host=dsthost, remote_port=mig_port) # Wait up to 30 seconds for dest to reach this point test.job.barrier(srchost, 'mig_finished', 30).rendezvous(srchost, dsthost) elif role == 'destination': # Wait up to login_timeout + 30 seconds for the source to # reach this point (self.vm, _) = start_guest_with_cpuflags(cpuf_model, smp, True, False) test.job.barrier(dsthost, 'socket_started', login_timeout + 120).rendezvous(srchost, dsthost) c_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) c_socket.settimeout(comm_timeout) c_socket.connect((srchost, comm_port)) logging.info("Communicating to source migration" " port %s" % self.vm.migration_port) c_socket.send("%d" % self.vm.migration_port) c_socket.close() # Wait up to mig_timeout + 30 seconds for the source to # reach this point: migration finished test.job.barrier(dsthost, 'mig_finished', mig_timeout + 30).rendezvous(srchost, dsthost) if not guest_active(self.vm): raise error.TestFail("Guest not active after" " migration") logging.info("Migrated guest appears to be running") # Log into the guest again logging.info("Logging into migrated guest after" " migration...") session_serial = self.vm.wait_for_serial_login( timeout=login_timeout) session_serial.cmd(regain_ip_cmd) self.vm.verify_illegal_instructonn() session = self.vm.wait_for_login(timeout=login_timeout) try: session.cmd('killall cpuflags-test') except aexpect.ShellCmdError: raise error.TestFail("The cpuflags-test program should" " be active after migration and" " it's not.") Flags = check_cpuflags_work(self.vm, install_path, flags.all_possible_guest_flags) logging.info("Woking CPU flags: %s", str(Flags[0])) logging.info("Not working CPU flags: %s", str(Flags[1])) logging.warning("Flags works even if not deffined on" " guest cpu flags: %s", str(Flags[0] - flags.guest_flags)) logging.warning("Not tested CPU flags: %s", str(Flags[2])) else: raise error.TestError('Invalid role specified') test_type = params.get("test_type") if (test_type in locals()): tests_group = locals()[test_type] tests_group() else: raise error.TestFail("Test group '%s' is not defined in" " cpuflags test" % test_type)
def run_whql_client_install(test, params, env): """ WHQL DTM client installation: 1) Log into the guest (the client machine) and into a DTM server machine 2) Stop the DTM client service (wttsvc) on the client machine 3) Delete the client machine from the server's data store 4) Rename the client machine (give it a randomly generated name) 5) Move the client machine into the server's workgroup 6) Reboot the client machine 7) Install the DTM client software 8) Setup auto logon for the user created by the installation (normally DTMLLUAdminUser) 9) Reboot again @param test: kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ vm = env.get_vm(params["main_vm"]) vm.verify_alive() session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) # Collect test params server_address = params.get("server_address") server_shell_port = int(params.get("server_shell_port")) server_file_transfer_port = int(params.get("server_file_transfer_port")) server_studio_path = params.get("server_studio_path", "%programfiles%\\ " "Microsoft Driver Test Manager\\Studio") server_username = params.get("server_username") server_password = params.get("server_password") client_username = params.get("client_username") client_password = params.get("client_password") dsso_delete_machine_binary = params.get("dsso_delete_machine_binary", "deps/whql_delete_machine_15.exe") dsso_delete_machine_binary = virt_utils.get_path(test.bindir, dsso_delete_machine_binary) install_timeout = float(params.get("install_timeout", 600)) install_cmd = params.get("install_cmd") wtt_services = params.get("wtt_services") # Stop WTT service(s) on client for svc in wtt_services.split(): virt_test_utils.stop_windows_service(session, svc) # Copy dsso_delete_machine_binary to server rss_client.upload(server_address, server_file_transfer_port, dsso_delete_machine_binary, server_studio_path, timeout=60) # Open a shell session with server server_session = virt_utils.remote_login("nc", server_address, server_shell_port, "", "", session.prompt, session.linesep) server_session.set_status_test_command(session.status_test_command) # Get server and client information cmd = "echo %computername%" server_name = server_session.cmd_output(cmd).strip() client_name = session.cmd_output(cmd).strip() cmd = "wmic computersystem get domain" server_workgroup = server_session.cmd_output(cmd).strip() server_workgroup = server_workgroup.splitlines()[-1] regkey = r"HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" cmd = "reg query %s /v Domain" % regkey o = server_session.cmd_output(cmd).strip().splitlines()[-1] try: server_dns_suffix = o.split(None, 2)[2] except IndexError: server_dns_suffix = "" # Delete the client machine from the server's data store (if it's there) server_session.cmd("cd %s" % server_studio_path) cmd = "%s %s %s" % (os.path.basename(dsso_delete_machine_binary), server_name, client_name) server_session.cmd(cmd, print_func=logging.info) server_session.close() # Rename the client machine client_name = "autotest_%s" % virt_utils.generate_random_string(4) logging.info("Renaming client machine to '%s'", client_name) cmd = ('wmic computersystem where name="%%computername%%" rename name="%s"' % client_name) session.cmd(cmd, timeout=600) # Join the server's workgroup logging.info("Joining workgroup '%s'", server_workgroup) cmd = ('wmic computersystem where name="%%computername%%" call ' 'joindomainorworkgroup name="%s"' % server_workgroup) session.cmd(cmd, timeout=600) # Set the client machine's DNS suffix logging.info("Setting DNS suffix to '%s'", server_dns_suffix) cmd = 'reg add %s /v Domain /d "%s" /f' % (regkey, server_dns_suffix) session.cmd(cmd, timeout=300) # Reboot session = vm.reboot(session) # Access shared resources on the server machine logging.info("Attempting to access remote share on server") cmd = r"net use \\%s /user:%s %s" % (server_name, server_username, server_password) end_time = time.time() + 120 while time.time() < end_time: try: session.cmd(cmd) break except Exception: pass time.sleep(5) else: raise error.TestError("Could not access server share from client " "machine") # Install logging.info("Installing DTM client (timeout=%ds)", install_timeout) install_cmd = r"cmd /c \\%s\%s" % (server_name, install_cmd.lstrip("\\")) session.cmd(install_cmd, timeout=install_timeout) # Setup auto logon logging.info("Setting up auto logon for user '%s'", client_username) cmd = ('reg add ' '"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\winlogon" ' '/v "%s" /d "%s" /t REG_SZ /f') session.cmd(cmd % ("AutoAdminLogon", "1")) session.cmd(cmd % ("DefaultUserName", client_username)) session.cmd(cmd % ("DefaultPassword", client_password)) # Reboot one more time session = vm.reboot(session) session.close()
def run_whql_client_install(test, params, env): """ WHQL DTM client installation: 1) Log into the guest (the client machine) and into a DTM server machine 2) Stop the DTM client service (wttsvc) on the client machine 3) Delete the client machine from the server's data store 4) Rename the client machine (give it a randomly generated name) 5) Move the client machine into the server's workgroup 6) Reboot the client machine 7) Install the DTM client software 8) Setup auto logon for the user created by the installation (normally DTMLLUAdminUser) 9) Reboot again @param test: kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ vm = env.get_vm(params["main_vm"]) vm.verify_alive() session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) # Collect test params server_address = params.get("server_address") server_shell_port = int(params.get("server_shell_port")) server_file_transfer_port = int(params.get("server_file_transfer_port")) server_studio_path = params.get( "server_studio_path", "%programfiles%\\ " "Microsoft Driver Test Manager\\Studio") server_username = params.get("server_username") server_password = params.get("server_password") client_username = params.get("client_username") client_password = params.get("client_password") dsso_delete_machine_binary = params.get("dsso_delete_machine_binary", "deps/whql_delete_machine_15.exe") dsso_delete_machine_binary = virt_utils.get_path( test.bindir, dsso_delete_machine_binary) install_timeout = float(params.get("install_timeout", 600)) install_cmd = params.get("install_cmd") wtt_services = params.get("wtt_services") # Stop WTT service(s) on client for svc in wtt_services.split(): virt_test_utils.stop_windows_service(session, svc) # Copy dsso_delete_machine_binary to server rss_client.upload(server_address, server_file_transfer_port, dsso_delete_machine_binary, server_studio_path, timeout=60) # Open a shell session with server server_session = virt_utils.remote_login("nc", server_address, server_shell_port, "", "", session.prompt, session.linesep) server_session.set_status_test_command(session.status_test_command) # Get server and client information cmd = "echo %computername%" server_name = server_session.cmd_output(cmd).strip() client_name = session.cmd_output(cmd).strip() cmd = "wmic computersystem get domain" server_workgroup = server_session.cmd_output(cmd).strip() server_workgroup = server_workgroup.splitlines()[-1] regkey = r"HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" cmd = "reg query %s /v Domain" % regkey o = server_session.cmd_output(cmd).strip().splitlines()[-1] try: server_dns_suffix = o.split(None, 2)[2] except IndexError: server_dns_suffix = "" # Delete the client machine from the server's data store (if it's there) server_session.cmd("cd %s" % server_studio_path) cmd = "%s %s %s" % (os.path.basename(dsso_delete_machine_binary), server_name, client_name) server_session.cmd(cmd, print_func=logging.info) server_session.close() # Rename the client machine client_name = "autotest_%s" % virt_utils.generate_random_string(4) logging.info("Renaming client machine to '%s'", client_name) cmd = ( 'wmic computersystem where name="%%computername%%" rename name="%s"' % client_name) session.cmd(cmd, timeout=600) # Join the server's workgroup logging.info("Joining workgroup '%s'", server_workgroup) cmd = ('wmic computersystem where name="%%computername%%" call ' 'joindomainorworkgroup name="%s"' % server_workgroup) session.cmd(cmd, timeout=600) # Set the client machine's DNS suffix logging.info("Setting DNS suffix to '%s'", server_dns_suffix) cmd = 'reg add %s /v Domain /d "%s" /f' % (regkey, server_dns_suffix) session.cmd(cmd, timeout=300) # Reboot session = vm.reboot(session) # Access shared resources on the server machine logging.info("Attempting to access remote share on server") cmd = r"net use \\%s /user:%s %s" % (server_name, server_username, server_password) end_time = time.time() + 120 while time.time() < end_time: try: session.cmd(cmd) break except Exception: pass time.sleep(5) else: raise error.TestError("Could not access server share from client " "machine") # Install logging.info("Installing DTM client (timeout=%ds)", install_timeout) install_cmd = r"cmd /c \\%s\%s" % (server_name, install_cmd.lstrip("\\")) session.cmd(install_cmd, timeout=install_timeout) # Setup auto logon logging.info("Setting up auto logon for user '%s'", client_username) cmd = ('reg add ' '"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\winlogon" ' '/v "%s" /d "%s" /t REG_SZ /f') session.cmd(cmd % ("AutoAdminLogon", "1")) session.cmd(cmd % ("DefaultUserName", client_username)) session.cmd(cmd % ("DefaultPassword", client_password)) # Reboot one more time session = vm.reboot(session) session.close()
def run_guest_test(test, params, env): """ A wrapper for running customized tests in guests. 1) Log into a guest. 2) Run script. 3) Wait for script execution to complete. 4) Pass/fail according to exit status of script. @param test: KVM test object. @param params: Dictionary with test parameters. @param env: Dictionary with the test environment. """ login_timeout = int(params.get("login_timeout", 360)) reboot = params.get("reboot", "no") vm = env.get_vm(params["main_vm"]) vm.verify_alive() if params.get("serial_login") == "yes": session = vm.wait_for_serial_login(timeout=login_timeout) else: session = vm.wait_for_login(timeout=login_timeout) if reboot == "yes": logging.debug("Rebooting guest before test ...") session = vm.reboot(session, timeout=login_timeout) try: logging.info("Starting script...") # Collect test parameters interpreter = params.get("interpreter") script = params.get("guest_script") dst_rsc_path = params.get("dst_rsc_path", "script.au3") script_params = params.get("script_params", "") test_timeout = float(params.get("test_timeout", 600)) logging.debug("Starting preparing resouce files...") # Download the script resource from a remote server, or # prepare the script using rss? if params.get("download") == "yes": download_cmd = params.get("download_cmd") rsc_server = params.get("rsc_server") rsc_dir = os.path.basename(rsc_server) dst_rsc_dir = params.get("dst_rsc_dir") # Change dir to dst_rsc_dir, and remove the guest script dir there rm_cmd = "cd %s && (rmdir /s /q %s || del /s /q %s)" % \ (dst_rsc_dir, rsc_dir, rsc_dir) session.cmd(rm_cmd, timeout=test_timeout) logging.debug("Clean directory succeeded.") # then download the resource. rsc_cmd = "cd %s && %s %s" % (dst_rsc_dir, download_cmd, rsc_server) session.cmd(rsc_cmd, timeout=test_timeout) logging.info("Download resource finished.") else: session.cmd_output("del %s" % dst_rsc_path, internal_timeout=0) script_path = virt_utils.get_path(test.virtdir, script) vm.copy_files_to(script_path, dst_rsc_path, timeout=60) cmd = "%s %s %s" % (interpreter, dst_rsc_path, script_params) try: logging.info("------------ Script output ------------") session.cmd(cmd, print_func=logging.info, timeout=test_timeout) finally: logging.info("------------ End of script output ------------") if reboot == "yes": logging.debug("Rebooting guest after test ...") session = vm.reboot(session, timeout=login_timeout) logging.debug("guest test PASSED.") finally: session.close()
def run_guest_test(test, params, env): """ A wrapper for running customized tests in guests. 1) Log into a guest. 2) Run script. 3) Wait for script execution to complete. 4) Pass/fail according to exit status of script. @param test: KVM test object. @param params: Dictionary with test parameters. @param env: Dictionary with the test environment. """ login_timeout = int(params.get("login_timeout", 360)) reboot = params.get("reboot", "no") vm = env.get_vm(params["main_vm"]) vm.verify_alive() if params.get("serial_login") == "yes": session = vm.wait_for_serial_login(timeout=login_timeout) else: session = vm.wait_for_login(timeout=login_timeout) if reboot == "yes": logging.debug("Rebooting guest before test ...") session = vm.reboot(session, timeout=login_timeout) try: logging.info("Starting script...") # Collect test parameters interpreter = params.get("interpreter") script = params.get("guest_script") dst_rsc_path = params.get("dst_rsc_path", "script.au3") script_params = params.get("script_params", "") test_timeout = float(params.get("test_timeout", 600)) logging.debug("Starting preparing resouce files...") # Download the script resource from a remote server, or # prepare the script using rss? if params.get("download") == "yes": download_cmd = params.get("download_cmd") rsc_server = params.get("rsc_server") rsc_dir = os.path.basename(rsc_server) dst_rsc_dir = params.get("dst_rsc_dir") # Change dir to dst_rsc_dir, and remove the guest script dir there rm_cmd = "cd %s && (rmdir /s /q %s || del /s /q %s)" % \ (dst_rsc_dir, rsc_dir, rsc_dir) session.cmd(rm_cmd, timeout=test_timeout) logging.debug("Clean directory succeeded.") # then download the resource. rsc_cmd = "cd %s && %s %s" % (dst_rsc_dir, download_cmd, rsc_server) session.cmd(rsc_cmd, timeout=test_timeout) logging.info("Download resource finished.") else: session.cmd_output("del %s" % dst_rsc_path, internal_timeout=0) script_path = virt_utils.get_path(test.bindir, script) vm.copy_files_to(script_path, dst_rsc_path, timeout=60) cmd = "%s %s %s" % (interpreter, dst_rsc_path, script_params) try: logging.info("------------ Script output ------------") session.cmd(cmd, print_func=logging.info, timeout=test_timeout) finally: logging.info("------------ End of script output ------------") if reboot == "yes": logging.debug("Rebooting guest after test ...") session = vm.reboot(session, timeout=login_timeout) logging.debug("guest test PASSED.") finally: session.close()
def run_whql_submission(test, params, env): """ WHQL submission test: 1) Log into the client machines and into a DTM server machine 2) Copy the automation program binary (dsso_test_binary) to the server machine 3) Run the automation program 4) Pass the program all relevant parameters (e.g. device_data) 5) Wait for the program to terminate 6) Parse and report job results (logs and HTML reports are placed in test.debugdir) @param test: kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ # Log into all client VMs login_timeout = int(params.get("login_timeout", 360)) vms = [] sessions = [] for vm_name in params.objects("vms"): vms.append(env.get_vm(vm_name)) vms[-1].verify_alive() sessions.append(vms[-1].wait_for_login(timeout=login_timeout)) # Make sure all NICs of all client VMs are up for vm in vms: nics = vm.params.objects("nics") for nic_index in range(len(nics)): s = vm.wait_for_login(nic_index, 600) s.close() # Collect parameters server_address = params.get("server_address") server_shell_port = int(params.get("server_shell_port")) server_file_transfer_port = int(params.get("server_file_transfer_port")) server_studio_path = params.get( "server_studio_path", "%programfiles%\\ " "Microsoft Driver Test Manager\\Studio") dsso_test_binary = params.get("dsso_test_binary", "deps/whql_submission_15.exe") dsso_test_binary = virt_utils.get_path(test.bindir, dsso_test_binary) dsso_delete_machine_binary = params.get("dsso_delete_machine_binary", "deps/whql_delete_machine_15.exe") dsso_delete_machine_binary = virt_utils.get_path( test.bindir, dsso_delete_machine_binary) test_timeout = float(params.get("test_timeout", 600)) # Copy dsso binaries to the server for filename in dsso_test_binary, dsso_delete_machine_binary: rss_client.upload(server_address, server_file_transfer_port, filename, server_studio_path, timeout=60) # Open a shell session with the server server_session = virt_utils.remote_login("nc", server_address, server_shell_port, "", "", sessions[0].prompt, sessions[0].linesep) server_session.set_status_test_command(sessions[0].status_test_command) # Get the computer names of the server and clients cmd = "echo %computername%" server_name = server_session.cmd_output(cmd).strip() client_names = [session.cmd_output(cmd).strip() for session in sessions] # Delete all client machines from the server's data store server_session.cmd("cd %s" % server_studio_path) for client_name in client_names: cmd = "%s %s %s" % (os.path.basename(dsso_delete_machine_binary), server_name, client_name) server_session.cmd(cmd, print_func=logging.debug) # Reboot the client machines sessions = virt_utils.parallel( (vm.reboot, (session, )) for vm, session in zip(vms, sessions)) # Check the NICs again for vm in vms: nics = vm.params.objects("nics") for nic_index in range(len(nics)): s = vm.wait_for_login(nic_index, 600) s.close() # Run whql_pre_command and close the sessions if params.get("whql_pre_command"): for session in sessions: session.cmd(params.get("whql_pre_command"), int(params.get("whql_pre_command_timeout", 600))) session.close() # Run the automation program on the server pool_name = "%s_pool" % client_names[0] submission_name = "%s_%s" % (client_names[0], params.get("submission_name")) cmd = "%s %s %s %s %s %s" % (os.path.basename(dsso_test_binary), server_name, pool_name, submission_name, test_timeout, " ".join(client_names)) server_session.sendline(cmd) # Helper function: wait for a given prompt and raise an exception if an # error occurs def find_prompt(prompt): m, o = server_session.read_until_last_line_matches( [prompt, server_session.prompt], print_func=logging.info, timeout=600) if m != 0: errors = re.findall("^Error:.*$", o, re.I | re.M) if errors: raise error.TestError(errors[0]) else: raise error.TestError("Error running automation program: " "could not find '%s' prompt" % prompt) # Tell the automation program which device to test find_prompt("Device to test:") server_session.sendline(params.get("test_device")) # Tell the automation program which jobs to run find_prompt("Jobs to run:") server_session.sendline(params.get("job_filter", ".*")) # Set submission DeviceData find_prompt("DeviceData name:") for dd in params.objects("device_data"): dd_params = params.object_params(dd) if dd_params.get("dd_name") and dd_params.get("dd_data"): server_session.sendline(dd_params.get("dd_name")) server_session.sendline(dd_params.get("dd_data")) server_session.sendline() # Set submission descriptors find_prompt("Descriptor path:") for desc in params.objects("descriptors"): desc_params = params.object_params(desc) if desc_params.get("desc_path"): server_session.sendline(desc_params.get("desc_path")) server_session.sendline() # Set machine dimensions for each client machine for vm_name in params.objects("vms"): vm_params = params.object_params(vm_name) find_prompt(r"Dimension name\b.*:") for dp in vm_params.objects("dimensions"): dp_params = vm_params.object_params(dp) if dp_params.get("dim_name") and dp_params.get("dim_value"): server_session.sendline(dp_params.get("dim_name")) server_session.sendline(dp_params.get("dim_value")) server_session.sendline() # Set extra parameters for tests that require them (e.g. NDISTest) for vm_name in params.objects("vms"): vm_params = params.object_params(vm_name) find_prompt(r"Parameter name\b.*:") for dp in vm_params.objects("device_params"): dp_params = vm_params.object_params(dp) if dp_params.get("dp_name") and dp_params.get("dp_regex"): server_session.sendline(dp_params.get("dp_name")) server_session.sendline(dp_params.get("dp_regex")) # Make sure the prompt appears again (if the device isn't found # the automation program will terminate) find_prompt(r"Parameter name\b.*:") server_session.sendline() # Wait for the automation program to terminate try: o = server_session.read_up_to_prompt(print_func=logging.info, timeout=test_timeout + 300) # (test_timeout + 300 is used here because the automation program is # supposed to terminate cleanly on its own when test_timeout expires) done = True except aexpect.ExpectError, e: o = e.output done = False
def run_whql_submission(test, params, env): """ WHQL submission test: 1) Log into the client machines and into a DTM server machine 2) Copy the automation program binary (dsso_test_binary) to the server machine 3) Run the automation program 4) Pass the program all relevant parameters (e.g. device_data) 5) Wait for the program to terminate 6) Parse and report job results (logs and HTML reports are placed in test.debugdir) @param test: kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ # Log into all client VMs login_timeout = int(params.get("login_timeout", 360)) vms = [] sessions = [] for vm_name in params.objects("vms"): vms.append(env.get_vm(vm_name)) vms[-1].verify_alive() sessions.append(vms[-1].wait_for_login(timeout=login_timeout)) # Make sure all NICs of all client VMs are up for vm in vms: nics = vm.params.objects("nics") for nic_index in range(len(nics)): s = vm.wait_for_login(nic_index, 600) s.close() # Collect parameters server_address = params.get("server_address") server_shell_port = int(params.get("server_shell_port")) server_file_transfer_port = int(params.get("server_file_transfer_port")) server_studio_path = params.get("server_studio_path", "%programfiles%\\ " "Microsoft Driver Test Manager\\Studio") dsso_test_binary = params.get("dsso_test_binary", "deps/whql_submission_15.exe") dsso_test_binary = virt_utils.get_path(test.virtdir, dsso_test_binary) dsso_delete_machine_binary = params.get("dsso_delete_machine_binary", "deps/whql_delete_machine_15.exe") dsso_delete_machine_binary = virt_utils.get_path(test.virtdir, dsso_delete_machine_binary) test_timeout = float(params.get("test_timeout", 600)) # Copy dsso binaries to the server for filename in dsso_test_binary, dsso_delete_machine_binary: rss_client.upload(server_address, server_file_transfer_port, filename, server_studio_path, timeout=60) # Open a shell session with the server server_session = virt_utils.remote_login("nc", server_address, server_shell_port, "", "", sessions[0].prompt, sessions[0].linesep) server_session.set_status_test_command(sessions[0].status_test_command) # Get the computer names of the server and clients cmd = "echo %computername%" server_name = server_session.cmd_output(cmd).strip() client_names = [session.cmd_output(cmd).strip() for session in sessions] # Delete all client machines from the server's data store server_session.cmd("cd %s" % server_studio_path) for client_name in client_names: cmd = "%s %s %s" % (os.path.basename(dsso_delete_machine_binary), server_name, client_name) server_session.cmd(cmd, print_func=logging.debug) # Reboot the client machines sessions = virt_utils.parallel((vm.reboot, (session,)) for vm, session in zip(vms, sessions)) # Check the NICs again for vm in vms: nics = vm.params.objects("nics") for nic_index in range(len(nics)): s = vm.wait_for_login(nic_index, 600) s.close() # Run whql_pre_command and close the sessions if params.get("whql_pre_command"): for session in sessions: session.cmd(params.get("whql_pre_command"), int(params.get("whql_pre_command_timeout", 600))) session.close() # Run the automation program on the server pool_name = "%s_pool" % client_names[0] submission_name = "%s_%s" % (client_names[0], params.get("submission_name")) cmd = "%s %s %s %s %s %s" % (os.path.basename(dsso_test_binary), server_name, pool_name, submission_name, test_timeout, " ".join(client_names)) server_session.sendline(cmd) # Helper function: wait for a given prompt and raise an exception if an # error occurs def find_prompt(prompt): m, o = server_session.read_until_last_line_matches( [prompt, server_session.prompt], print_func=logging.info, timeout=600) if m != 0: errors = re.findall("^Error:.*$", o, re.I | re.M) if errors: raise error.TestError(errors[0]) else: raise error.TestError("Error running automation program: " "could not find '%s' prompt" % prompt) # Tell the automation program which device to test find_prompt("Device to test:") server_session.sendline(params.get("test_device")) # Tell the automation program which jobs to run find_prompt("Jobs to run:") server_session.sendline(params.get("job_filter", ".*")) # Set submission DeviceData find_prompt("DeviceData name:") for dd in params.objects("device_data"): dd_params = params.object_params(dd) if dd_params.get("dd_name") and dd_params.get("dd_data"): server_session.sendline(dd_params.get("dd_name")) server_session.sendline(dd_params.get("dd_data")) server_session.sendline() # Set submission descriptors find_prompt("Descriptor path:") for desc in params.objects("descriptors"): desc_params = params.object_params(desc) if desc_params.get("desc_path"): server_session.sendline(desc_params.get("desc_path")) server_session.sendline() # Set machine dimensions for each client machine for vm_name in params.objects("vms"): vm_params = params.object_params(vm_name) find_prompt(r"Dimension name\b.*:") for dp in vm_params.objects("dimensions"): dp_params = vm_params.object_params(dp) if dp_params.get("dim_name") and dp_params.get("dim_value"): server_session.sendline(dp_params.get("dim_name")) server_session.sendline(dp_params.get("dim_value")) server_session.sendline() # Set extra parameters for tests that require them (e.g. NDISTest) for vm_name in params.objects("vms"): vm_params = params.object_params(vm_name) find_prompt(r"Parameter name\b.*:") for dp in vm_params.objects("device_params"): dp_params = vm_params.object_params(dp) if dp_params.get("dp_name") and dp_params.get("dp_regex"): server_session.sendline(dp_params.get("dp_name")) server_session.sendline(dp_params.get("dp_regex")) # Make sure the prompt appears again (if the device isn't found # the automation program will terminate) find_prompt(r"Parameter name\b.*:") server_session.sendline() # Wait for the automation program to terminate try: o = server_session.read_up_to_prompt(print_func=logging.info, timeout=test_timeout + 300) # (test_timeout + 300 is used here because the automation program is # supposed to terminate cleanly on its own when test_timeout expires) done = True except aexpect.ExpectError, e: o = e.output done = False
def run_cpuflags(test, params, env): """ Boot guest with different cpu flags and check if guest works correctly. @param test: kvm test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ virt_utils.Flag.aliases = virt_utils.kvm_map_flags_aliases qemu_binary = virt_utils.get_path('.', params.get("qemu_binary", "qemu")) cpuflags_src = os.path.join(test.virtdir, "deps", "test_cpu_flags") smp = int(params.get("smp", 1)) all_host_supported_flags = params.get("all_host_supported_flags", "no") mig_timeout = float(params.get("mig_timeout", "3600")) mig_protocol = params.get("migration_protocol", "tcp") mig_speed = params.get("mig_speed", "100M") multi_host_migration = params.get("multi_host_migration", "no") class HgFlags(object): def __init__(self, cpu_model, extra_flags=set([])): virtual_flags = set( map(virt_utils.Flag, params.get("guest_spec_flags", "").split())) self.hw_flags = set( map(virt_utils.Flag, params.get("host_spec_flags", "").split())) self.qemu_support_flags = get_all_qemu_flags() self.host_support_flags = set( map(virt_utils.Flag, virt_utils.get_cpu_flags())) self.quest_cpu_model_flags = (get_guest_host_cpuflags(cpu_model) - virtual_flags) self.supported_flags = (self.qemu_support_flags & self.host_support_flags) self.cpumodel_unsupport_flags = (self.supported_flags - self.quest_cpu_model_flags) self.host_unsupported_flags = (self.quest_cpu_model_flags - self.host_support_flags) self.all_possible_guest_flags = (self.quest_cpu_model_flags - self.host_unsupported_flags) self.all_possible_guest_flags |= self.cpumodel_unsupport_flags self.guest_flags = (self.quest_cpu_model_flags - self.host_unsupported_flags) self.guest_flags |= extra_flags self.host_all_unsupported_flags = set([]) self.host_all_unsupported_flags |= self.qemu_support_flags self.host_all_unsupported_flags -= (self.host_support_flags | virtual_flags) def start_guest_with_cpuflags(cpuflags, smp=None, migration=False, wait=True): """ Try to boot guest with special cpu flags and try login in to them. """ params_b = params.copy() params_b["cpu_model"] = cpuflags if smp is not None: params_b["smp"] = smp vm_name = "vm1-cpuflags" vm = kvm_vm.VM(vm_name, params_b, test.bindir, env['address_cache']) env.register_vm(vm_name, vm) if (migration is True): vm.create(migration_mode=mig_protocol) else: vm.create() vm.verify_alive() session = None if wait: session = vm.wait_for_login() return (vm, session) def get_guest_system_cpuflags(vm_session): """ Get guest system cpuflags. @param vm_session: session to checked vm. @return: [corespond flags] """ flags_re = re.compile(r'^flags\s*:(.*)$', re.MULTILINE) out = vm_session.cmd_output("cat /proc/cpuinfo") flags = flags_re.search(out).groups()[0].split() return set(map(virt_utils.Flag, flags)) def get_guest_host_cpuflags(cpumodel): """ Get cpu flags correspond with cpumodel parameters. @param cpumodel: Cpumodel parameter sended to <qemu-kvm-cmd>. @return: [corespond flags] """ cmd = qemu_binary + " -cpu ?dump" output = utils.run(cmd).stdout re.escape(cpumodel) pattern = (".+%s.*\n.*\n +feature_edx .+ \((.*)\)\n +feature_" "ecx .+ \((.*)\)\n +extfeature_edx .+ \((.*)\)\n +" "extfeature_ecx .+ \((.*)\)\n" % (cpumodel)) flags = [] model = re.search(pattern, output) if model == None: raise error.TestFail("Cannot find %s cpu model." % (cpumodel)) for flag_group in model.groups(): flags += flag_group.split() return set(map(virt_utils.Flag, flags)) def get_all_qemu_flags(): cmd = qemu_binary + " -cpu ?cpuid" output = utils.run(cmd).stdout flags_re = re.compile(r".*\n.*f_edx:(.*)\n.*f_ecx:(.*)\n.*extf_edx:" "(.*)\n.*extf_ecx:(.*)") m = flags_re.search(output) flags = [] for a in m.groups(): flags += a.split() return set(map(virt_utils.Flag, flags)) def get_flags_full_name(cpu_flag): """ Get all name of Flag. @param cpu_flag: Flag @return: all name of Flag. """ cpu_flag = virt_utils.Flag(cpu_flag) for f in get_all_qemu_flags(): if f == cpu_flag: return virt_utils.Flag(f) return [] def parse_qemu_cpucommand(cpumodel): """ Parse qemu cpu params. @param cpumodel: Cpu model command. @return: All flags which guest must have. """ flags = cpumodel.split(",") cpumodel = flags[0] qemu_model_flag = get_guest_host_cpuflags(cpumodel) host_support_flag = set( map(virt_utils.Flag, virt_utils.get_cpu_flags())) real_flags = qemu_model_flag & host_support_flag for f in flags[1:]: if f[0].startswith("+"): real_flags |= set([get_flags_full_name(f[1:])]) if f[0].startswith("-"): real_flags -= set([get_flags_full_name(f[1:])]) return real_flags def get_cpu_models(): """ Get all cpu models from qemu. @return: cpu models. """ cmd = qemu_binary + " -cpu ?" output = utils.run(cmd).stdout cpu_re = re.compile("\w+\s+\[?(\w+)\]?") return cpu_re.findall(output) def check_cpuflags(cpumodel, vm_session): """ Check if vm flags are same like flags select by cpumodel. @param cpumodel: params for -cpu param in qemu-kvm @param vm_session: session to vm to check flags. @return: ([excess], [missing]) flags """ gf = get_guest_system_cpuflags(vm_session) rf = parse_qemu_cpucommand(cpumodel) logging.debug("Guest flags: %s", gf) logging.debug("Host flags: %s", rf) logging.debug("Flags on guest not defined by host: %s", (gf - rf)) return rf - gf def disable_cpu(vm_session, cpu, disable=True): """ Disable cpu in guest system. @param cpu: CPU id to disable. @param disable: if True disable cpu else enable cpu. """ system_cpu_dir = "/sys/devices/system/cpu/" cpu_online = system_cpu_dir + "cpu%d/online" % (cpu) cpu_state = vm_session.cmd_output("cat %s" % cpu_online).strip() if disable and cpu_state == "1": vm_session.cmd("echo 0 > %s" % cpu_online) logging.debug("Guest cpu %d is disabled.", cpu) elif cpu_state == "0": vm_session.cmd("echo 1 > %s" % cpu_online) logging.debug("Guest cpu %d is enabled.", cpu) def install_cpuflags_test_on_vm(vm, dst_dir): """ Install stress to vm. @param vm: virtual machine. @param dst_dir: Installation path. """ session = vm.wait_for_login() vm.copy_files_to(cpuflags_src, dst_dir) session.cmd("sync") session.cmd("cd %s; make EXTRA_FLAGS='';" % os.path.join(dst_dir, "test_cpu_flags")) session.cmd("sync") session.close() def check_cpuflags_work(vm, path, flags): """ Check which flags work. @param vm: Virtual machine. @param path: Path of cpuflags_test @param flags: Flags to test. @return: Tuple (Working, not working, not tested) flags. """ pass_Flags = [] not_tested = [] not_working = [] session = vm.wait_for_login() for f in flags: try: for tc in virt_utils.kvm_map_flags_to_test[f]: session.cmd("%s/cpuflags-test --%s" % (os.path.join(path, "test_cpu_flags"), tc)) pass_Flags.append(f) except aexpect.ShellCmdError: not_working.append(f) except KeyError: not_tested.append(f) return (set(map(virt_utils.Flag, pass_Flags)), set(map(virt_utils.Flag, not_working)), set(map(virt_utils.Flag, not_tested))) def run_stress(vm, timeout, guest_flags): """ Run stress on vm for timeout time. """ ret = False install_path = "/tmp" install_cpuflags_test_on_vm(vm, install_path) flags = check_cpuflags_work(vm, install_path, guest_flags) dd_session = vm.wait_for_login() stress_session = vm.wait_for_login() dd_session.sendline("dd if=/dev/[svh]da of=/tmp/stressblock" " bs=10MB count=100 &") try: stress_session.cmd( "%s/cpuflags-test --stress %s%s" % (os.path.join(install_path, "test_cpu_flags"), smp, virt_utils.kvm_flags_to_stresstests(flags[0])), timeout=timeout) except aexpect.ShellTimeoutError: ret = True stress_session.close() dd_session.close() return ret def separe_cpu_model(cpu_model): try: (cpu_model, _) = cpu_model.split(":") except ValueError: cpu_model = cpu_model return cpu_model def parse_cpu_model(): """ Parse cpu_models from config file. @return: [(cpumodel, extra_flags)] """ cpu_model = params.get("cpu_model", "") logging.debug("CPU model found: %s", str(cpu_model)) try: (cpu_model, extra_flags) = cpu_model.split(":") extra_flags = set(map(virt_utils.Flag, extra_flags.split(","))) except ValueError: cpu_model = cpu_model extra_flags = set([]) return (cpu_model, extra_flags) class MiniSubtest(object): def __new__(cls, *args, **kargs): self = super(MiniSubtest, cls).__new__(cls) ret = None if args is None: args = [] try: ret = self.test(*args, **kargs) finally: if hasattr(self, "clean"): self.clean() return ret class Test_temp(MiniSubtest): def clean(self): logging.info("cleanup") if (hasattr(self, "vm")): self.vm.destroy(gracefully=False) # 1) <qemu-kvm-cmd> -cpu ?model class test_qemu_cpu_model(MiniSubtest): def test(self): cpu_models = params.get("cpu_models", "core2duo").split() cmd = qemu_binary + " -cpu ?model" result = utils.run(cmd) missing = [] cpu_models = map(separe_cpu_model, cpu_models) for cpu_model in cpu_models: if not cpu_model in result.stdout: missing.append(cpu_model) if missing: raise error.TestFail("CPU models %s are not in output " "'%s' of command \n%s" % (missing, cmd, result.stdout)) # 2) <qemu-kvm-cmd> -cpu ?dump class test_qemu_dump(MiniSubtest): def test(self): cpu_models = params.get("cpu_models", "core2duo").split() cmd = qemu_binary + " -cpu ?dump" result = utils.run(cmd) cpu_models = map(separe_cpu_model, cpu_models) missing = [] for cpu_model in cpu_models: if not cpu_model in result.stdout: missing.append(cpu_model) if missing: raise error.TestFail("CPU models %s are not in output " "'%s' of command \n%s" % (missing, cmd, result.stdout)) # 3) <qemu-kvm-cmd> -cpu ?cpuid class test_qemu_cpuid(MiniSubtest): def test(self): cmd = qemu_binary + " -cpu ?cpuid" result = utils.run(cmd) if result.stdout is "": raise error.TestFail("There aren't any cpu Flag in output" " '%s' of command \n%s" % (cmd, result.stdout)) # 1) boot with cpu_model class test_boot_cpu_model(Test_temp): def test(self): cpu_model, _ = parse_cpu_model() logging.debug("Run tests with cpu model %s", cpu_model) flags = HgFlags(cpu_model) (self.vm, session) = start_guest_with_cpuflags(cpu_model) not_enable_flags = (check_cpuflags(cpu_model, session) - flags.hw_flags) if not_enable_flags != set([]): raise error.TestFail("Flags defined on host but not found " "on guest: %s" % (not_enable_flags)) # 2) success boot with supported flags class test_boot_cpu_model_and_additional_flags(Test_temp): def test(self): cpu_model, extra_flags = parse_cpu_model() flags = HgFlags(cpu_model, extra_flags) logging.debug("Cpu mode flags %s.", str(flags.quest_cpu_model_flags)) cpuf_model = cpu_model if all_host_supported_flags == "yes": for fadd in flags.cpumodel_unsupport_flags: cpuf_model += ",+" + str(fadd) else: for fadd in extra_flags: cpuf_model += ",+" + str(fadd) for fdel in flags.host_unsupported_flags: cpuf_model += ",-" + str(fdel) if all_host_supported_flags == "yes": guest_flags = flags.all_possible_guest_flags else: guest_flags = flags.guest_flags (self.vm, session) = start_guest_with_cpuflags(cpuf_model) not_enable_flags = (check_cpuflags(cpuf_model, session) - flags.hw_flags) if not_enable_flags != set([]): logging.info("Model unsupported flags: %s", str(flags.cpumodel_unsupport_flags)) logging.error( "Flags defined on host but not on found " "on guest: %s", str(not_enable_flags)) logging.info("Check main instruction sets.") install_path = "/tmp" install_cpuflags_test_on_vm(self.vm, install_path) Flags = check_cpuflags_work(self.vm, install_path, flags.all_possible_guest_flags) logging.info("Woking CPU flags: %s", str(Flags[0])) logging.info("Not working CPU flags: %s", str(Flags[1])) logging.warning( "Flags works even if not deffined on guest cpu " "flags: %s", str(Flags[0] - guest_flags)) logging.warning("Not tested CPU flags: %s", str(Flags[2])) if Flags[1] & guest_flags: raise error.TestFail("Some flags do not work: %s" % (str(Flags[1]))) # 3) fail boot unsupported flags class test_boot_warn_with_host_unsupported_flags(MiniSubtest): def test(self): #This is virtual cpu flags which are supported by #qemu but no with host cpu. cpu_model, extra_flags = parse_cpu_model() flags = HgFlags(cpu_model, extra_flags) logging.debug("Unsupported flags %s.", str(flags.host_all_unsupported_flags)) cpuf_model = cpu_model + ",check" # Add unsupported flags. for fadd in flags.host_all_unsupported_flags: cpuf_model += ",+" + str(fadd) vnc_port = virt_utils.find_free_port(5900, 6100) - 5900 cmd = "%s -cpu %s -vnc :%d" % (qemu_binary, cpuf_model, vnc_port) out = None try: try: out = utils.run(cmd, timeout=5, ignore_status=True).stderr raise error.TestFail("Guest not boot with unsupported " "flags.") except error.CmdError, e: out = e.result_obj.stderr finally: uns_re = re.compile("^warning:.*flag '(.+)'", re.MULTILINE) warn_flags = set(map(virt_utils.Flag, uns_re.findall(out))) fwarn_flags = flags.host_all_unsupported_flags - warn_flags if fwarn_flags: raise error.TestFail("Qemu did not warn the use of " "flags %s" % str(fwarn_flags)) # 3) fail boot unsupported flags class test_fail_boot_with_host_unsupported_flags(MiniSubtest): def test(self): #This is virtual cpu flags which are supported by #qemu but no with host cpu. cpu_model, extra_flags = parse_cpu_model() flags = HgFlags(cpu_model, extra_flags) logging.debug("Unsupported flags %s.", str(flags.host_all_unsupported_flags)) cpuf_model = cpu_model + ",enforce" # Add unsupported flags. for fadd in flags.host_all_unsupported_flags: cpuf_model += ",+" + str(fadd) vnc_port = virt_utils.find_free_port(5900, 6100) - 5900 cmd = "%s -cpu %s -vnc :%d" % (qemu_binary, cpuf_model, vnc_port) out = None try: try: out = utils.run(cmd, timeout=5, ignore_status=True).stderr except error.CmdError: logging.error("Host boot with unsupported flag") finally: uns_re = re.compile("^warning:.*flag '(.+)'", re.MULTILINE) warn_flags = set(map(virt_utils.Flag, uns_re.findall(out))) fwarn_flags = flags.host_all_unsupported_flags - warn_flags if fwarn_flags: raise error.TestFail("Qemu did not warn the use of " "flags %s" % str(fwarn_flags)) # 4) check guest flags under load cpu, stress and system (dd) class test_boot_guest_and_try_flags_under_load(Test_temp): def test(self): logging.info("Check guest working cpuflags under load " "cpu and stress and system (dd)") cpu_model, extra_flags = parse_cpu_model() flags = HgFlags(cpu_model, extra_flags) logging.debug("Cpu mode flags %s.", str(flags.quest_cpu_model_flags)) logging.debug("Added flags %s.", str(flags.cpumodel_unsupport_flags)) cpuf_model = cpu_model # Add unsupported flags. for fadd in flags.cpumodel_unsupport_flags: cpuf_model += ",+" + str(fadd) for fdel in flags.host_unsupported_flags: cpuf_model += ",-" + str(fdel) (self.vm, _) = start_guest_with_cpuflags(cpuf_model, smp) if (not run_stress(self.vm, 60, flags.guest_flags)): raise error.TestFail("Stress test ended before" " end of test.") def clean(self): logging.info("cleanup") self.vm.destroy(gracefully=False) # 5) Online/offline CPU class test_online_offline_guest_CPUs(Test_temp): def test(self): cpu_model, extra_flags = parse_cpu_model() logging.debug("Run tests with cpu model %s.", (cpu_model)) flags = HgFlags(cpu_model, extra_flags) (self.vm, session) = start_guest_with_cpuflags(cpu_model, smp) def encap(timeout): random.seed() begin = time.time() end = begin if smp > 1: while end - begin < 60: cpu = random.randint(1, smp - 1) if random.randint(0, 1): disable_cpu(session, cpu, True) else: disable_cpu(session, cpu, False) end = time.time() return True else: logging.warning("For this test is necessary smp > 1.") return False timeout = 60 test_flags = flags.guest_flags if all_host_supported_flags == "yes": test_flags = flags.all_possible_guest_flags result = virt_utils.parallel([(encap, [timeout]), (run_stress, [self.vm, timeout, test_flags])]) if not (result[0] and result[1]): raise error.TestFail("Stress tests failed before" " end of testing.") # 6) migration test class test_migration_with_additional_flags(Test_temp): def test(self): cpu_model, extra_flags = parse_cpu_model() flags = HgFlags(cpu_model, extra_flags) logging.debug("Cpu mode flags %s.", str(flags.quest_cpu_model_flags)) logging.debug("Added flags %s.", str(flags.cpumodel_unsupport_flags)) cpuf_model = cpu_model # Add unsupported flags. for fadd in flags.cpumodel_unsupport_flags: cpuf_model += ",+" + str(fadd) for fdel in flags.host_unsupported_flags: cpuf_model += ",-" + str(fdel) (self.vm, _) = start_guest_with_cpuflags(cpuf_model, smp) install_path = "/tmp" install_cpuflags_test_on_vm(self.vm, install_path) flags = check_cpuflags_work(self.vm, install_path, flags.guest_flags) dd_session = self.vm.wait_for_login() stress_session = self.vm.wait_for_login() dd_session.sendline("nohup dd if=/dev/[svh]da of=/tmp/" "stressblock bs=10MB count=100 &") cmd = ("nohup %s/cpuflags-test --stress %s%s &" % (os.path.join(install_path, "test_cpu_flags"), smp, virt_utils.kvm_flags_to_stresstests(flags[0]))) stress_session.sendline(cmd) time.sleep(5) self.vm.monitor.migrate_set_speed(mig_speed) self.vm.migrate(mig_timeout, mig_protocol, offline=False) time.sleep(5) #If cpuflags-test hang up during migration test raise exception try: stress_session.cmd('killall cpuflags-test') except aexpect.ShellCmdError: raise error.TestFail("Cpuflags-test should work after" " migration.") def net_send_object(socket, obj): """ Send python object over network. @param ip_addr: ipaddres of waiter for data. @param obj: object to send """ data = pickle.dumps(obj, pickle.HIGHEST_PROTOCOL) socket.sendall("%6d" % len(data)) socket.sendall(data) def net_recv_object(socket, timeout=60): """ Receive python object over network. @param ip_addr: ipaddres of waiter for data. @param obj: object to send @return: object from network """ try: time_start = time.time() data = "" d_len = int(socket.recv(6)) while (len(data) < d_len and (time.time() - time_start) < timeout): data += socket.recv(d_len - len(data)) data = pickle.loads(data) return data except: error.TestFail("Failed to receive python object over the network") raise class test_multi_host_migration(Test_temp): def test(self): """ Test migration between multiple hosts. """ cpu_model, extra_flags = parse_cpu_model() flags = HgFlags(cpu_model, extra_flags) logging.debug("Cpu mode flags %s.", str(flags.quest_cpu_model_flags)) logging.debug("Added flags %s.", str(flags.cpumodel_unsupport_flags)) cpuf_model = cpu_model for fadd in extra_flags: cpuf_model += ",+" + str(fadd) for fdel in flags.host_unsupported_flags: cpuf_model += ",-" + str(fdel) install_path = "/tmp" class testMultihostMigration(virt_utils.MultihostMigration): def __init__(self, test, params, env): super(testMultihostMigration, self).__init__(test, params, env) def migration_scenario(self): srchost = self.params.get("hosts")[0] dsthost = self.params.get("hosts")[1] def worker(mig_data): vm = env.get_vm("vm1") session = vm.wait_for_login(timeout=self.login_timeout) install_cpuflags_test_on_vm(vm, install_path) Flags = check_cpuflags_work( vm, install_path, flags.all_possible_guest_flags) logging.info("Woking CPU flags: %s", str(Flags[0])) logging.info("Not working CPU flags: %s", str(Flags[1])) logging.warning( "Flags works even if not deffined on" " guest cpu flags: %s", str(Flags[0] - flags.guest_flags)) logging.warning("Not tested CPU flags: %s", str(Flags[2])) session.sendline("nohup dd if=/dev/[svh]da of=/tmp/" "stressblock bs=10MB count=100 &") cmd = ( "nohup %s/cpuflags-test --stress %s%s &" % (os.path.join(install_path, "test_cpu_flags"), smp, virt_utils.kvm_flags_to_stresstests( Flags[0] & flags.guest_flags))) logging.debug("Guest_flags: %s", str(flags.guest_flags)) logging.debug("Working_flags: %s", str(Flags[0])) logging.debug("Start stress on guest: %s", cmd) session.sendline(cmd) def check_worker(mig_data): vm = env.get_vm("vm1") vm.verify_illegal_instruction() session = vm.wait_for_login(timeout=self.login_timeout) try: session.cmd('killall cpuflags-test') except aexpect.ShellCmdError: raise error.TestFail("The cpuflags-test program" " should be active after" " migration and it's not.") Flags = check_cpuflags_work( vm, install_path, flags.all_possible_guest_flags) logging.info("Woking CPU flags: %s", str(Flags[0])) logging.info("Not working CPU flags: %s", str(Flags[1])) logging.warning( "Flags works even if not deffined on" " guest cpu flags: %s", str(Flags[0] - flags.guest_flags)) logging.warning("Not tested CPU flags: %s", str(Flags[2])) self.migrate_wait(["vm1"], srchost, dsthost, worker, check_worker) params_b = params.copy() params_b["cpu_model"] = cpu_model mig = testMultihostMigration(test, params_b, env) mig.run() test_type = params.get("test_type") if (test_type in locals()): tests_group = locals()[test_type] tests_group() else: raise error.TestFail("Test group '%s' is not defined in" " cpuflags test" % test_type)
def run_cpuflags(test, params, env): """ Boot guest with different cpu flags and check if guest works correctly. @param test: kvm test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ qemu_binary = virt_utils.get_path('.', params.get("qemu_binary", "qemu")) cpuflags_path = os.path.join(test.virtdir, "deps") cpuflags_tar = "cpuflags-test.tar.bz2" cpuflags_src = os.path.join(test.virtdir, "deps", "test_cpu_flags") smp = int(params.get("smp", 1)) all_host_supported_flags = params.get("all_host_supported_flags", "no") mig_timeout = float(params.get("mig_timeout", "3600")) mig_protocol = params.get("migration_protocol", "tcp") mig_speed = params.get("mig_speed", "1G") class HgFlags(object): def __init__(self, cpu_model, extra_flags=set([])): virtual_flags = set(map(virt_utils.Flag, params.get("guest_spec_flags", "").split())) self.hw_flags = set(map(virt_utils.Flag, params.get("host_spec_flags", "").split())) self.qemu_support_flags = get_all_qemu_flags() self.host_support_flags = set(map(virt_utils.Flag, virt_utils.get_cpu_flags())) self.quest_cpu_model_flags = (get_guest_host_cpuflags(cpu_model) - virtual_flags) self.supported_flags = (self.qemu_support_flags & self.host_support_flags) self.cpumodel_unsupport_flags = (self.supported_flags - self.quest_cpu_model_flags) self.host_unsupported_flags = (self.quest_cpu_model_flags - self.host_support_flags) self.all_possible_guest_flags = (self.quest_cpu_model_flags - self.host_unsupported_flags) self.all_possible_guest_flags |= self.cpumodel_unsupport_flags self.guest_flags = (self.quest_cpu_model_flags - self.host_unsupported_flags) self.guest_flags |= extra_flags self.host_all_unsupported_flags = set([]) self.host_all_unsupported_flags |= self.qemu_support_flags self.host_all_unsupported_flags -= (self.host_support_flags | virtual_flags) def start_guest_with_cpuflags(cpuflags, smp=None): """ Try to boot guest with special cpu flags and try login in to them. """ params_b = params.copy() params_b["cpu_model"] = cpuflags if smp is not None: params_b["smp"] = smp vm_name = "vm1-cpuflags" vm = kvm_vm.VM(vm_name, params_b, test.bindir, env['address_cache']) env.register_vm(vm_name, vm) vm.create() vm.verify_alive() session = vm.wait_for_login() return (vm, session) def get_guest_system_cpuflags(vm_session): """ Get guest system cpuflags. @param vm_session: session to checked vm. @return: [corespond flags] """ flags_re = re.compile(r'^flags\s*:(.*)$', re.MULTILINE) out = vm_session.cmd_output("cat /proc/cpuinfo") flags = flags_re.search(out).groups()[0].split() return set(map(virt_utils.Flag, flags)) def get_guest_host_cpuflags(cpumodel): """ Get cpu flags correspond with cpumodel parameters. @param cpumodel: Cpumodel parameter sended to <qemu-kvm-cmd>. @return: [corespond flags] """ cmd = qemu_binary + " -cpu ?dump" output = utils.run(cmd).stdout re.escape(cpumodel) pattern = (".+%s.*\n.*\n +feature_edx .+ \((.*)\)\n +feature_" "ecx .+ \((.*)\)\n +extfeature_edx .+ \((.*)\)\n +" "extfeature_ecx .+ \((.*)\)\n" % (cpumodel)) flags = [] model = re.search(pattern, output) if model == None: raise error.TestFail("Cannot find %s cpu model." % (cpumodel)) for flag_group in model.groups(): flags += flag_group.split() return set(map(virt_utils.Flag, flags)) def get_all_qemu_flags(): cmd = qemu_binary + " -cpu ?cpuid" output = utils.run(cmd).stdout flags_re = re.compile(r".*\n.*f_edx:(.*)\n.*f_ecx:(.*)\n.*extf_edx:" "(.*)\n.*extf_ecx:(.*)") m = flags_re.search(output) flags = [] for a in m.groups(): flags += a.split() return set(map(virt_utils.Flag, flags)) def get_flags_full_name(cpu_flag): """ Get all name of Flag. @param cpu_flag: Flag @return: all name of Flag. """ cpu_flag = virt_utils.Flag(cpu_flag) for f in get_all_qemu_flags(): if f == cpu_flag: return virt_utils.Flag(f) return [] def parse_qemu_cpucommand(cpumodel): """ Parse qemu cpu params. @param cpumodel: Cpu model command. @return: All flags which guest must have. """ flags = cpumodel.split(",") cpumodel = flags[0] qemu_model_flag = get_guest_host_cpuflags(cpumodel) host_support_flag = set(map(virt_utils.Flag, virt_utils.get_cpu_flags())) real_flags = qemu_model_flag & host_support_flag for f in flags[1:]: if f[0].startswith("+"): real_flags |= set([get_flags_full_name(f[1:])]) if f[0].startswith("-"): real_flags -= set([get_flags_full_name(f[1:])]) return real_flags def get_cpu_models(): """ Get all cpu models from qemu. @return: cpu models. """ cmd = qemu_binary + " -cpu ?" output = utils.run(cmd).stdout cpu_re = re.compile("\w+\s+\[?(\w+)\]?") return cpu_re.findall(output) def check_cpuflags(cpumodel, vm_session): """ Check if vm flags are same like flags select by cpumodel. @param cpumodel: params for -cpu param in qemu-kvm @param vm_session: session to vm to check flags. @return: ([excess], [missing]) flags """ gf = get_guest_system_cpuflags(vm_session) rf = parse_qemu_cpucommand(cpumodel) logging.debug("Guest flags: %s", gf) logging.debug("Host flags: %s", rf) logging.debug("Flags on guest not defined by host: %s", (gf - rf)) return rf - gf def disable_cpu(vm_session, cpu, disable=True): """ Disable cpu in guest system. @param cpu: CPU id to disable. @param disable: if True disable cpu else enable cpu. """ system_cpu_dir = "/sys/devices/system/cpu/" cpu_online = system_cpu_dir + "cpu%d/online" % (cpu) cpu_state = vm_session.cmd_output("cat %s" % cpu_online).strip() if disable and cpu_state == "1": vm_session.cmd("echo 0 > %s" % cpu_online) logging.debug("Guest cpu %d is disabled.", cpu) elif cpu_state == "0": vm_session.cmd("echo 1 > %s" % cpu_online) logging.debug("Guest cpu %d is enabled.", cpu) def install_cpuflags_test_on_vm(vm, dst_dir): """ Install stress to vm. @param vm: virtual machine. @param dst_dir: Installation path. """ session = vm.wait_for_login() vm.copy_files_to(cpuflags_src, dst_dir) session.cmd("cd %s; make EXTRA_FLAGS='';" % os.path.join(dst_dir, "test_cpu_flags")) session.close() def check_cpuflags_work(vm, path, flags): """ Check which flags work. @param vm: Virtual machine. @param path: Path of cpuflags_test @param flags: Flags to test. @return: Tuple (Working, not working, not tested) flags. """ pass_Flags = [] not_tested = [] not_working = [] session = vm.wait_for_login() for f in flags: try: for tc in virt_utils.kvm_map_flags_to_test[f]: session.cmd("%s/cpuflags-test --%s" % (os.path.join(path,"test_cpu_flags"), tc)) pass_Flags.append(f) except aexpect.ShellCmdError: not_working.append(f) except KeyError: not_tested.append(f) return (set(map(virt_utils.Flag, pass_Flags)), set(map(virt_utils.Flag, not_working)), set(map(virt_utils.Flag, not_tested))) def run_stress(vm, timeout, guest_flags): """ Run stress on vm for timeout time. """ ret = False install_path = "/tmp" install_cpuflags_test_on_vm(vm, install_path) flags = check_cpuflags_work(vm, install_path, guest_flags) dd_session = vm.wait_for_login() stress_session = vm.wait_for_login() dd_session.sendline("dd if=/dev/[svh]da of=/tmp/stressblock" " bs=10MB count=100 &") try: stress_session.cmd("%s/cpuflags-test --stress %s%s" % (os.path.join(install_path, "test_cpu_flags"), smp, virt_utils.kvm_flags_to_stresstests(flags[0])), timeout=timeout) except aexpect.ShellTimeoutError: ret = True stress_session.close() dd_session.close() return ret def separe_cpu_model(cpu_model): try: (cpu_model, _) = cpu_model.split(":") except ValueError: cpu_model = cpu_model return cpu_model def test_qemu_interface(): """ 1) <qemu-kvm-cmd> -cpu ?model 2) <qemu-kvm-cmd> -cpu ?dump 3) <qemu-kvm-cmd> -cpu ?cpuid """ # 1) <qemu-kvm-cmd> -cpu ?model class test_qemu_cpu_model(Subtest): @subtest_fatal @subtest_nocleanup def test(self): cpu_models = params.get("cpu_models", "core2duo").split() cmd = qemu_binary + " -cpu ?model" result = utils.run(cmd) missing = [] cpu_models = map(separe_cpu_model, cpu_models) for cpu_model in cpu_models: if not cpu_model in result.stdout: missing.append(cpu_model) if missing: raise error.TestFail("CPU models %s are not in output " "'%s' of command \n%s" % (missing, cmd, result.stdout)) # 2) <qemu-kvm-cmd> -cpu ?dump class test_qemu_dump(Subtest): @subtest_nocleanup def test(self): cpu_models = params.get("cpu_models", "core2duo").split() cmd = qemu_binary + " -cpu ?dump" result = utils.run(cmd) cpu_models = map(separe_cpu_model, cpu_models) missing = [] for cpu_model in cpu_models: if not cpu_model in result.stdout: missing.append(cpu_model) if missing: raise error.TestFail("CPU models %s are not in output " "'%s' of command \n%s" % (missing, cmd, result.stdout)) # 3) <qemu-kvm-cmd> -cpu ?cpuid class test_qemu_cpuid(Subtest): @subtest_nocleanup def test(self): cmd = qemu_binary + " -cpu ?cpuid" result = utils.run(cmd) if result.stdout is "": raise error.TestFail("There aren't any cpu Flag in output" " '%s' of command \n%s" % (cmd, result.stdout)) test_qemu_cpu_model() test_qemu_dump() test_qemu_cpuid() class test_temp(Subtest): def clean(self): logging.info("cleanup") if (hasattr(self, "vm")): self.vm.destroy(gracefully=False) def test_boot_guest(): """ 1) boot with cpu_model 2) migrate with flags 3) <qemu-kvm-cmd> -cpu model_name,+Flag """ cpu_models = params.get("cpu_models","").split() if not cpu_models: cpu_models = get_cpu_models() logging.debug("CPU models found: %s", str(cpu_models)) # 1) boot with cpu_model class test_boot_cpu_model(test_temp): def test(self, cpu_model): logging.debug("Run tests with cpu model %s", cpu_model) flags = HgFlags(cpu_model) (self.vm, session) = start_guest_with_cpuflags(cpu_model) not_enable_flags = (check_cpuflags(cpu_model, session) - flags.hw_flags) if not_enable_flags != set([]): raise error.TestFail("Flags defined on host but not found " "on guest: %s" % (not_enable_flags)) # 2) success boot with supported flags class test_boot_cpu_model_and_additional_flags(test_temp): def test(self, cpu_model, extra_flags): flags = HgFlags(cpu_model, extra_flags) logging.debug("Cpu mode flags %s.", str(flags.quest_cpu_model_flags)) cpuf_model = cpu_model if all_host_supported_flags == "yes": for fadd in flags.cpumodel_unsupport_flags: cpuf_model += ",+" + fadd else: for fadd in extra_flags: cpuf_model += ",+" + fadd for fdel in flags.host_unsupported_flags: cpuf_model += ",-" + fdel if all_host_supported_flags == "yes": guest_flags = flags.all_possible_guest_flags else: guest_flags = flags.guest_flags (self.vm, session) = start_guest_with_cpuflags(cpuf_model) not_enable_flags = (check_cpuflags(cpuf_model, session) - flags.hw_flags) if not_enable_flags != set([]): logging.info("Model unsupported flags: %s", str(flags.cpumodel_unsupport_flags)) logging.error("Flags defined on host but not on found " "on guest: %s", str(not_enable_flags)) logging.info("Check main instruction sets.") install_path = "/tmp" install_cpuflags_test_on_vm(self.vm, install_path) Flags = check_cpuflags_work(self.vm, install_path, flags.all_possible_guest_flags) logging.info("Woking CPU flags: %s", str(Flags[0])) logging.info("Not working CPU flags: %s", str(Flags[1])) logging.warning("Flags works even if not deffined on guest cpu " "flags: %s", str(Flags[0] - guest_flags)) logging.warning("Not tested CPU flags: %s", str(Flags[2])) if Flags[1] & guest_flags: raise error.TestFail("Some flags do not work: %s" % (str(Flags[1]))) # 3) fail boot unsupported flags class test_fail_boot_with_host_unsupported_flags(Subtest): @subtest_nocleanup def test(self, cpu_model, extra_flags): #This is virtual cpu flags which are supported by #qemu but no with host cpu. flags = HgFlags(cpu_model, extra_flags) logging.debug("Unsupported flags %s.", str(flags.host_all_unsupported_flags)) cpuf_model = cpu_model + ",enforce" # Add unsupported flags. for fadd in flags.host_all_unsupported_flags: cpuf_model += ",+" + fadd cmd = qemu_binary + " -cpu " + cpuf_model out = None try: try: out = utils.run(cmd, timeout=5, ignore_status=True).stderr except error.CmdError: logging.error("Host boot with unsupported flag") finally: uns_re = re.compile("^warning:.*flag '(.+)'", re.MULTILINE) warn_flags = set(map(virt_utils.Flag, uns_re.findall(out))) fwarn_flags = flags.host_all_unsupported_flags - warn_flags if fwarn_flags: raise error.TestFail("Qemu did not warn the use of " "flags %s" % str(fwarn_flags)) for cpu_model in cpu_models: try: (cpu_model, extra_flags) = cpu_model.split(":") extra_flags = set(map(virt_utils.Flag, extra_flags.split(","))) except ValueError: cpu_model = cpu_model extra_flags = set([]) test_fail_boot_with_host_unsupported_flags(cpu_model, extra_flags) test_boot_cpu_model(cpu_model) test_boot_cpu_model_and_additional_flags(cpu_model, extra_flags) def test_stress_guest(): """ 4) fail boot unsupported flags 5) check guest flags under load cpu, system (dd) 6) online/offline CPU """ cpu_models = params.get("cpu_models","").split() if not cpu_models: cpu_models = get_cpu_models() logging.debug("CPU models found: %s", str(cpu_models)) # 4) check guest flags under load cpu, stress and system (dd) class test_boot_guest_and_try_flags_under_load(test_temp): def test(self, cpu_model, extra_flags): logging.info("Check guest working cpuflags under load " "cpu and stress and system (dd)") flags = HgFlags(cpu_model, extra_flags) logging.debug("Cpu mode flags %s.", str(flags.quest_cpu_model_flags)) logging.debug("Added flags %s.", str(flags.cpumodel_unsupport_flags)) cpuf_model = cpu_model # Add unsupported flags. for fadd in flags.cpumodel_unsupport_flags: cpuf_model += ",+" + fadd for fdel in flags.host_unsupported_flags: cpuf_model += ",-" + fdel (self.vm, _) = start_guest_with_cpuflags(cpuf_model, smp) if (not run_stress(self.vm, 60, flags.guest_flags)): raise error.TestFail("Stress test ended before" " end of test.") def clean(self): logging.info("cleanup") self.vm.destroy(gracefully=False) # 5) Online/offline CPU class test_online_offline_guest_CPUs(test_temp): def test(self, cpu_model, extra_flags): logging.debug("Run tests with cpu model %s.", (cpu_model)) flags = HgFlags(cpu_model, extra_flags) (self.vm, session) = start_guest_with_cpuflags(cpu_model, smp) def encap(timeout): random.seed() begin = time.time() end = begin if smp > 1: while end - begin < 60: cpu = random.randint(1, smp - 1) if random.randint(0, 1): disable_cpu(session, cpu, True) else: disable_cpu(session, cpu, False) end = time.time() return True else: logging.warning("For this test is necessary smp > 1.") return False timeout = 60 test_flags = flags.guest_flags if all_host_supported_flags == "yes": test_flags = flags.all_possible_guest_flags result = virt_utils.parallel([(encap, [timeout]), (run_stress, [self.vm, timeout, test_flags])]) if not (result[0] and result[1]): raise error.TestFail("Stress tests failed before" " end of testing.") # 6) migration test class test_migration_with_additional_flags(test_temp): def test(self, cpu_model, extra_flags): flags = HgFlags(cpu_model, extra_flags) logging.debug("Cpu mode flags %s.", str(flags.quest_cpu_model_flags)) logging.debug("Added flags %s.", str(flags.cpumodel_unsupport_flags)) cpuf_model = cpu_model # Add unsupported flags. for fadd in flags.cpumodel_unsupport_flags: cpuf_model += ",+" + fadd for fdel in flags.host_unsupported_flags: cpuf_model += ",-" + fdel (self.vm, _) = start_guest_with_cpuflags(cpuf_model, smp) install_path = "/tmp" install_cpuflags_test_on_vm(self.vm, install_path) flags = check_cpuflags_work(self.vm, install_path, flags.guest_flags) dd_session = self.vm.wait_for_login() stress_session = self.vm.wait_for_login() dd_session.sendline("nohup dd if=/dev/[svh]da of=/tmp/" "stressblock bs=10MB count=100 &") cmd = ("nohup %s/cpuflags-test --stress %s%s &" % (os.path.join(install_path, "test_cpu_flags"), smp, virt_utils.kvm_flags_to_stresstests(flags[0]))) stress_session.sendline(cmd) time.sleep(5) self.vm.monitor.migrate_set_speed(mig_speed) self.vm.migrate(mig_timeout, mig_protocol, offline=False) time.sleep(5) #If cpuflags-test hang up during migration test raise exception try: stress_session.cmd('killall cpuflags-test') except aexpect.ShellCmdError: raise error.TestFail("Cpuflags-test should work after" " migration.") for cpu_model in cpu_models: try: (cpu_model, extra_flags) = cpu_model.split(":") extra_flags = set(map(virt_utils.Flag, extra_flags.split(","))) except ValueError: cpu_model = cpu_model extra_flags = set([]) test_boot_guest_and_try_flags_under_load(cpu_model, extra_flags) test_online_offline_guest_CPUs(cpu_model, extra_flags) test_migration_with_additional_flags(cpu_model, extra_flags) try: locals()[params.get("test_type")]() finally: logging.info("RESULTS:") for line in Subtest.get_text_result().splitlines(): logging.info(line) if Subtest.has_failed(): raise error.TestFail("Some subtests failed")