Пример #1
0
    def test_init(self):
        self.god.stub_function(local_host.platform, 'node')
        local_host.platform.node.expect_call().and_return('foo')

        # run the actual test
        host = local_host.LocalHost()
        self.assertEqual(host.hostname, 'foo')
        self.god.check_playback()

        host = local_host.LocalHost(hostname='bar')
        self.assertEqual(host.hostname, 'bar')
        self.god.check_playback()
Пример #2
0
def _process_images_parallel(image_func, test, params, vm_process_status=None):
    """
    The same as _process_images but in parallel.
    :param image_func: Process function
    :param test: An Autotest test object.
    :param params: A dict containing all VM and image parameters.
    :param vm_process_status: (optional) vm process status like running, dead
                              or None for no vm exist.
    """
    images = params.objects("images")
    no_threads = min(len(images) / 5, 2 * local_host.LocalHost().get_num_cpu())
    exit_event = threading.Event()
    threads = []
    for i in xrange(no_threads):
        imgs = images[i::no_threads]
        threads.append(
            _CreateImages(image_func, test, imgs, params, exit_event,
                          vm_process_status))
        threads[-1].start()
    finished = False
    while not finished:
        finished = True
        for thread in threads:
            if thread.is_alive():
                finished = False
                time.sleep(0.5)
                break
    if exit_event.is_set():  # Failure in some thread
        logging.error("Image processing failed:")
        for thread in threads:
            if thread.exc_info:  # Throw the first failure
                raise thread.exc_info[1], None, thread.exc_info[2]
    del exit_event
    del threads[:]
Пример #3
0
    def _setup_run(self, result):
        host = local_host.LocalHost()

        (local_host.utils.run.expect_call(result.command, timeout=123,
                                          ignore_status=True, stdout_tee=local_host.utils.TEE_TO_LOGS,
                                          stderr_tee=local_host.utils.TEE_TO_LOGS, stdin=None, args=())
         .and_return(result))

        return host
Пример #4
0
    def _post_record_init(self, control, options, drop_caches,
                          extra_copy_cmdline):
        """
        Perform job initialization not required by self.record().
        """
        self._init_drop_caches(drop_caches)

        self._init_packages()

        self.sysinfo = sysinfo.sysinfo(self.resultdir)
        self._load_sysinfo_state()

        if not options.cont:
            shutil.copyfile(self.control,
                            os.path.join(self.resultdir, 'control'))

        self.control = control

        self.logging = logging_manager.get_logging_manager(
            manage_stdout_and_stderr=True, redirect_fds=True)
        self.logging.start_logging()

        self._config = config.config(self)
        self.profilers = profilers.profilers(self)

        self._init_bootloader()

        self.machines = [options.hostname]
        self.hosts = set([local_host.LocalHost(hostname=options.hostname,
                                               bootloader=self.bootloader)])

        self.args = []
        if options.args:
            self.args = self._parse_args(options.args)

        if options.user:
            self.user = options.user
        else:
            self.user = getpass.getuser()

        self.sysinfo.log_per_reboot_data()

        if not options.cont:
            self.record('START', None, None)

        self.harness.run_start()

        if options.log:
            self.enable_external_logging()

        self._init_cmdline(extra_copy_cmdline)

        self.num_tests_run = None
        self.num_tests_failed = None

        self.warning_loggers = None
        self.warning_manager = None
Пример #5
0
    def test_symlink_closure_adds_missing_files(self):
        host = local_host.LocalHost()

        # create a file and a symlink to it
        fname = os.path.join(self.tmpdir.name, 'file')
        sname = os.path.join(self.tmpdir.name, 'sym')
        open(fname, 'w').close()
        os.symlink(fname, sname)

        # test that when the symlinks point to unknown files they are added
        self.assertSameElements([fname, sname], host.symlink_closure([sname]))
Пример #6
0
    def test_list_files_glob(self):
        host = local_host.LocalHost()

        files = (os.path.join(self.tmpdir.name, 'file1'),
                 os.path.join(self.tmpdir.name, 'file2'))

        # create some files in tmpdir
        open(files[0], 'w').close()
        open(files[1], 'w').close()

        self.assertTrue(
            sorted(files) ==
            sorted(host.list_files_glob(os.path.join(self.tmpdir.name, '*'))))
Пример #7
0
    def test_symlink_closure_does_not_add_existent_file(self):
        host = local_host.LocalHost()

        # create a file and a symlink to it
        fname = os.path.join(self.tmpdir.name, 'file')
        sname = os.path.join(self.tmpdir.name, 'sym')
        open(fname, 'w').close()
        os.symlink(fname, sname)

        # test that when the symlinks point to already know files
        # nothing is added
        self.assertSameElements([fname, sname],
                                host.symlink_closure([fname, sname]))
Пример #8
0
 def test_wait_up(self):
     # just test that wait_up always works
     host = local_host.LocalHost()
     host.wait_up(1)
     self.god.check_playback()
Пример #9
0
def run(test, params, env):
    """
    Qemu multiqueue test for virtio-scsi controller:

    1) Boot up a guest with virtio-scsi device which support multi-queue and
       the vcpu and images number of guest should match the multi-queue number
    2) Check the multi queue option from monitor
    3) Check device init status in guest
    4) Load I/O in all targets
    5) Check the interrupt queues in guest

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def proc_interrupts_results(results):
        results_dict = {}
        cpu_count = 0
        cpu_list = []
        for line in results.splitlines():
            line = line.strip()
            if re.match("CPU0", line):
                cpu_list = re.findall("CPU\d+", line)
                cpu_count = len(cpu_list)
                continue
            if cpu_count > 0:
                irq_key = re.split(":", line)[0]
                results_dict[irq_key] = {}
                content = line[len(irq_key) + 1:].strip()
                if len(re.split("\s+", content)) < cpu_count:
                    continue
                count = 0
                irq_des = ""
                for irq_item in re.split("\s+", content):
                    if count < cpu_count:
                        if count == 0:
                            results_dict[irq_key]["count"] = []
                        results_dict[irq_key]["count"].append(irq_item)
                    else:
                        irq_des += " %s" % irq_item
                    count += 1
                results_dict[irq_key]["irq_des"] = irq_des.strip()
        return results_dict, cpu_list

    timeout = float(params.get("login_timeout", 240))
    host_cpu_num = local_host.LocalHost().get_num_cpu()
    while host_cpu_num:
        num_queues = str(host_cpu_num)
        host_cpu_num &= host_cpu_num - 1
    params['smp'] = num_queues
    params['num_queues'] = num_queues
    images_num = int(num_queues)
    extra_image_size = params.get("image_size_extra_images", "512M")
    system_image = params.get("images")
    system_image_drive_format = params.get("system_image_drive_format", "ide")
    params["drive_format_%s" % system_image] = system_image_drive_format
    dev_type = params.get("dev_type", "i440FX-pcihost")

    error.context("Boot up guest with block devcie with num_queues"
                  " is %s and smp is %s" % (num_queues, params['smp']),
                  logging.info)
    for vm in env.get_all_vms():
        if vm.is_alive():
            vm.destroy()
    for extra_image in range(images_num):
        image_tag = "stg%s" % extra_image
        params["images"] += " %s" % image_tag
        params["image_name_%s" % image_tag] = "images/%s" % image_tag
        params["image_size_%s" % image_tag] = extra_image_size
        params["force_create_image_%s" % image_tag] = "yes"
        image_params = params.object_params(image_tag)
        env_process.preprocess_image(test, image_params, image_tag)

    params["start_vm"] = "yes"
    vm = env.get_vm(params["main_vm"])
    env_process.preprocess_vm(test, params, env, vm.name)
    session = vm.wait_for_login(timeout=timeout)

    error.context("Check irqbalance service status", logging.info)
    output = session.cmd_output("systemctl status irqbalance")
    if not re.findall("Active: active", output):
        session.cmd("systemctl start irqbalance")
        output = session.cmd_output("systemctl status irqbalance")
        output = utils_misc.strip_console_codes(output)
        if not re.findall("Active: active", output):
            raise error.TestNAError("Can not start irqbalance inside guest. "
                                    "Skip this test.")

    error.context("Pin vcpus to host cpus", logging.info)
    host_numa_nodes = utils_misc.NumaInfo()
    vcpu_num = 0
    for numa_node_id in host_numa_nodes.nodes:
        numa_node = host_numa_nodes.nodes[numa_node_id]
        for _ in range(len(numa_node.cpus)):
            if vcpu_num >= len(vm.vcpu_threads):
                break
            vcpu_tid = vm.vcpu_threads[vcpu_num]
            logging.debug("pin vcpu thread(%s) to cpu"
                          "(%s)" % (vcpu_tid,
                                    numa_node.pin_cpu(vcpu_tid)))
            vcpu_num += 1

    error.context("Verify num_queues from monitor", logging.info)
    qtree = qemu_qtree.QtreeContainer()
    try:
        qtree.parse_info_qtree(vm.monitor.info('qtree'))
    except AttributeError:
        raise error.TestNAError("Monitor deson't supoort qtree "
                                "skip this test")
    error_msg = "Number of queues mismatch: expect %s"
    error_msg += " report from monitor: %s(%s)"
    scsi_bus_addr = ""
    for qdev in qtree.get_qtree().get_children():
        if qdev.qtree["type"] == dev_type:
            for pci_bus in qdev.get_children():
                for pcic in pci_bus.get_children():
                    if pcic.qtree["class_name"] == "SCSI controller":
                        qtree_queues = pcic.qtree["num_queues"].split("(")[0]
                        if qtree_queues.strip() != num_queues.strip():
                            error_msg = error_msg % (num_queues,
                                                     qtree_queues,
                                                     pcic.qtree["num_queues"])
                            raise error.TestFail(error_msg)
                    if pcic.qtree["class_name"] == "SCSI controller":
                        scsi_bus_addr = pcic.qtree['addr']
                        break

    if not scsi_bus_addr:
        raise error.TestError("Didn't find addr from qtree. Please check "
                              "the log.")
    error.context("Check device init status in guest", logging.info)
    init_check_cmd = params.get("init_check_cmd", "dmesg | grep irq")
    output = session.cmd_output(init_check_cmd)
    irqs_pattern = params.get("irqs_pattern", "%s:\s+irq\s+(\d+)")
    irqs_pattern = irqs_pattern % scsi_bus_addr
    irqs_watch = re.findall(irqs_pattern, output)
    # As there are several interrupts count for virtio device:
    # config, control, event and request. And the each queue have
    # a request count. So the totally count for virtio device should
    # equal to queus number plus three.
    if len(irqs_watch) != 3 + int(num_queues):
        raise error.TestFail("Failed to check the interrupt ids from dmesg")
    irq_check_cmd = params.get("irq_check_cmd", "cat /proc/interrupts")
    output = session.cmd_output(irq_check_cmd)
    irq_results, _ = proc_interrupts_results(output)
    for irq_watch in irqs_watch:
        if irq_watch not in irq_results:
            raise error.TestFail("Can't find irq %s from procfs" % irq_watch)

    error.context("Load I/O in all targets", logging.info)
    get_dev_cmd = params.get("get_dev_cmd", "ls /dev/[svh]d*")
    output = session.cmd_output(get_dev_cmd)
    system_dev = re.findall("[svh]d(\w+)\d+", output)[0]
    dd_timeout = int(re.findall("\d+", extra_image_size)[0])
    fill_cmd = ""
    count = 0
    for dev in re.split("\s+", output):
        if not dev:
            continue
        if not re.findall("[svh]d%s" % system_dev, dev):
            fill_cmd += " dd of=%s if=/dev/urandom bs=1M " % dev
            fill_cmd += "count=%s &&" % dd_timeout
            count += 1
    if count != images_num:
        raise error.TestError("Disks are not all show up in system. Output "
                              "from the check command: %s" % output)
    fill_cmd = fill_cmd.rstrip("&&")
    session.cmd(fill_cmd, timeout=dd_timeout)

    error.context("Check the interrupt queues in guest", logging.info)
    output = session.cmd_output(irq_check_cmd)
    irq_results, cpu_list = proc_interrupts_results(output)
    irq_bit_map = 0
    for irq_watch in irqs_watch:
        if "request" in irq_results[irq_watch]["irq_des"]:
            for index, count in enumerate(irq_results[irq_watch]["count"]):
                if int(count) > 0:
                    irq_bit_map |= 2 ** index

    cpu_count = 0
    error_msg = ""
    cpu_not_used = []
    for index, cpu in enumerate(cpu_list):
        if 2 ** index & irq_bit_map != 2 ** index:
            cpu_not_used.append(cpu)

    if cpu_not_used:
        logging.debug("Interrupt info from procfs:\n%s" % output)
        error_msg = " ".join(cpu_not_used)
        if len(cpu_not_used) > 1:
            error_msg += " are"
        else:
            error_msg += " is"
        error_msg += " not used during test. Please check debug log for"
        error_msg += " more information."
        raise error.TestFail(error_msg)
Пример #10
0
def run_tsc_drift(test, params, env):
    """
    Check the TSC(time stamp counter) frequency of guest and host whether match
    or not

    1) Test the vcpus' TSC of host by C the program
    2) Copy the C code to the guest, complie and run it to get the vcpus' TSC
       of guest
    3) Sleep sometimes and get the TSC of host and guest again
    4) Compute the TSC frequency of host and guest
    5) Compare the frequency deviation between host and guest with standard

    :param test: QEMU test object
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """

    drift_threshold = float(params.get("drift_threshold"))
    interval = float(params.get("interval"))
    cpu_chk_cmd = params.get("cpu_chk_cmd")
    tsc_freq_path = os.path.join(data_dir.get_root_dir(),
                                 'shared/deps/get_tsc.c')
    host_freq = 0

    def get_tsc(machine="host", i=0):
        cmd = "taskset -c %s ./a.out" % i
        if machine == "host":
            s, o = commands.getstatusoutput(cmd)
        else:
            s, o = session.get_command_status_output(cmd)
        if s != 0:
            raise error.TestError("Fail to get tsc of host, ncpu: %d" % i)
        o = re.findall("(\d+)", o)[0]
        return float(o)

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()

    session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360)))

    commands.getoutput("gcc %s" % tsc_freq_path)
    ncpu = local_host.LocalHost().get_num_cpu()

    logging.info("Interval is %s" % interval)
    logging.info("Determine the TSC frequency in the host")
    for i in range(ncpu):
        tsc1 = get_tsc("host", i)
        time.sleep(interval)
        tsc2 = get_tsc("host", i)

        delta = tsc2 - tsc1
        logging.info("Host TSC delta for cpu %s is %s" % (i, delta))
        if delta < 0:
            raise error.TestError("Host TSC for cpu %s warps %s" % (i, delta))

        host_freq += delta / ncpu
    logging.info("Average frequency of host's cpus: %s" % host_freq)

    vm.copy_files_to(tsc_freq_path, '/tmp/get_tsc.c')
    if session.get_command_status("gcc /tmp/get_tsc.c") != 0:
        raise error.TestError("Fail to compile program on guest")

    s, guest_ncpu = session.get_command_status_output(cpu_chk_cmd)
    if s != 0:
        raise error.TestError("Fail to get cpu number of guest")

    success = True
    for i in range(int(guest_ncpu)):
        tsc1 = get_tsc("guest", i)
        time.sleep(interval)
        tsc2 = get_tsc("guest", i)

        delta = tsc2 - tsc1
        logging.info("Guest TSC delta for vcpu %s is %s" % (i, delta))
        if delta < 0:
            logging.error("Guest TSC for vcpu %s warps %s" % (i, delta))

        ratio = 100 * (delta - host_freq) / host_freq
        logging.info("TSC drift ratio for vcpu %s is %s" % (i, ratio))
        if abs(ratio) > drift_threshold:
            logging.error("TSC drift found for vcpu %s ratio %s" % (i, ratio))
            success = False

    if not success:
        raise error.TestFail("TSC drift found for the guest, please check the "
                             "log for details")

    session.close()