示例#1
0
    def crash_test(vcpu):
        """
        Trigger a crash dump through sysrq-trigger

        @param vcpu: vcpu which is used to trigger a crash
        """
        session = kvm_test_utils.wait_for_login(vm, 0, timeout, 0, 2)
        session.cmd_output("rm -rf /var/crash/*")

        logging.info("Triggering crash on vcpu %d ...", vcpu)
        crash_cmd = "taskset -c %d echo c > /proc/sysrq-trigger" % vcpu
        session.sendline(crash_cmd)

        if not kvm_utils.wait_for(lambda: not session.is_responsive(), 240, 0,
                                  1):
            raise error.TestFail("Could not trigger crash on vcpu %d" % vcpu)

        logging.info("Waiting for kernel crash dump to complete")
        session = kvm_test_utils.wait_for_login(vm, 0, crash_timeout, 0, 2)

        logging.info("Probing vmcore file...")
        session.cmd("ls -R /var/crash | grep vmcore")
        logging.info("Found vmcore.")

        session.cmd_output("rm -rf /var/crash/*")
示例#2
0
def run_ioquit(test, params, env):
    """
    Emulate the poweroff under IO workload(dd so far) using kill -9.

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

    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    session = kvm_test_utils.wait_for_login(vm,
                  timeout=int(params.get("login_timeout", 360)))
    session2 = kvm_test_utils.wait_for_login(vm,
                  timeout=int(params.get("login_timeout", 360)))
    try:
        bg_cmd = params.get("background_cmd")
        logging.info("Add IO workload for guest OS.")
        session.cmd_output(bg_cmd, timeout=60)
        check_cmd = params.get("check_cmd")
        session2.cmd(check_cmd, timeout=60)

        logging.info("Sleep for a while")
        time.sleep(random.randrange(30,100))
        session2.cmd(check_cmd, timeout=60)
        logging.info("Kill the virtual machine")
        vm.process.close()
    finally:
        session.close()
        session2.close()
示例#3
0
def run_mac_change(test, params, env):
    """
    Change MAC address of guest.

    1) Get a new mac from pool, and the old mac addr of guest.
    2) Set new mac in guest and regain new IP.
    3) Re-log into guest with new MAC.

    @param test: KVM test object.
    @param params: Dictionary with the test parameters.
    @param env: Dictionary with test environment.
    """
    timeout = int(params.get("login_timeout", 360))
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    session_serial = kvm_test_utils.wait_for_login(vm, 0, timeout, 0, 2,
                                                   serial=True)
    # This session will be used to assess whether the IP change worked
    session = kvm_test_utils.wait_for_login(vm, 0, timeout, 0, 2)
    old_mac = vm.get_mac_address(0)
    while True:
        vm.free_mac_address(0)
        new_mac = kvm_utils.generate_mac_address(vm.instance, 0)
        if old_mac != new_mac:
            break
    logging.info("The initial MAC address is %s", old_mac)
    interface = kvm_test_utils.get_linux_ifname(session_serial, old_mac)
    # Start change MAC address
    logging.info("Changing MAC address to %s", new_mac)
    change_cmd = ("ifconfig %s down && ifconfig %s hw ether %s && "
                  "ifconfig %s up" % (interface, interface, new_mac, interface))
    session_serial.cmd(change_cmd)

    # Verify whether MAC address was changed to the new one
    logging.info("Verifying the new mac address")
    session_serial.cmd("ifconfig | grep -i %s" % new_mac)

    # Restart `dhclient' to regain IP for new mac address
    logging.info("Restart the network to gain new IP")
    dhclient_cmd = "dhclient -r && dhclient %s" % interface
    session_serial.sendline(dhclient_cmd)

    # Re-log into the guest after changing mac address
    if kvm_utils.wait_for(session.is_responsive, 120, 20, 3):
        # Just warning when failed to see the session become dead,
        # because there is a little chance the ip does not change.
        logging.warn("The session is still responsive, settings may fail.")
    session.close()

    # Re-log into guest and check if session is responsive
    logging.info("Re-log into the guest")
    session = kvm_test_utils.wait_for_login(vm,
              timeout=int(params.get("login_timeout", 360)))
    if not session.is_responsive():
        raise error.TestFail("The new session is not responsive.")

    session.close()
def run_iozone_windows(test, params, env):
    """
    Run IOzone for windows on a windows guest:
    1) Log into a guest
    2) Execute the IOzone test contained in the winutils.iso
    3) Get results
    4) Postprocess it with the IOzone postprocessing module

    @param test: kvm test object
    @param params: Dictionary with the test parameters
    @param env: Dictionary with test environment.
    """
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    timeout = int(params.get("login_timeout", 360))
    session = kvm_test_utils.wait_for_login(vm, timeout=timeout)
    results_path = os.path.join(test.resultsdir,
                                'raw_output_%s' % test.iteration)
    analysisdir = os.path.join(test.resultsdir, 'analysis_%s' % test.iteration)

    # Run IOzone and record its results
    c = params.get("iozone_cmd")
    t = int(params.get("iozone_timeout"))
    logging.info("Running IOzone command on guest, timeout %ss", t)
    results = session.cmd_output(command=c, timeout=t,
                                 print_func=logging.debug)
    utils.open_write_close(results_path, results)

    # Postprocess the results using the IOzone postprocessing module
    logging.info("Iteration succeed, postprocessing")
    a = postprocessing.IOzoneAnalyzer(list_files=[results_path],
                                      output_dir=analysisdir)
    a.analyze()
    p = postprocessing.IOzonePlotter(results_file=results_path,
                                     output_dir=analysisdir)
    p.plot_all()
示例#5
0
    def fuzz(session, inst_list):
        """
        Executes a series of read/write/randwrite instructions.

        If the guest SSH session hangs, an attempt to relogin will be made.
        If it fails, the guest will be reset. If during the process the VM
        process abnormally ends, the test fails.

        @param inst_list: List of instructions that will be executed.
        @raise error.TestFail: If the VM process dies in the middle of the
                fuzzing procedure.
        """
        for (op, operand) in inst_list:
            if op == "read":
                inb(session, operand[0])
            elif op =="write":
                outb(session, operand[0], operand[1])
            else:
                raise error.TestError("Unknown command %s" % op)

            if not session.is_responsive():
                logging.debug("Session is not responsive")
                if vm.process.is_alive():
                    logging.debug("VM is alive, try to re-login")
                    try:
                        session = kvm_test_utils.wait_for_login(vm, 0, 10, 0, 2)
                    except:
                        logging.debug("Could not re-login, reboot the guest")
                        session = kvm_test_utils.reboot(vm, session,
                                                        method = "system_reset")
                else:
                    raise error.TestFail("VM has quit abnormally during %s",
                                         (op, operand))
示例#6
0
def run_boot(test, params, env):
    """
    KVM reboot test:
    1) Log into a guest
    2) Send a reboot command or a system_reset monitor command (optional)
    3) Wait until the guest is up again
    4) Log into the guest to verify it's up again

    @param test: kvm test object
    @param params: Dictionary with the test parameters
    @param env: Dictionary with test environment.
    """
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    timeout = float(params.get("login_timeout", 240))
    session = kvm_test_utils.wait_for_login(vm, 0, timeout, 0, 2)

    try:
        if not params.get("reboot_method"):
            return

        # Reboot the VM
        session = kvm_test_utils.reboot(vm, session,
                                    params.get("reboot_method"),
                                    float(params.get("sleep_before_reset", 10)),
                                    0, timeout)

    finally:
        session.close()
示例#7
0
def run_shutdown(test, params, env):
    """
    KVM shutdown test:
    1) Log into a guest
    2) Send a shutdown command to the guest, or issue a system_powerdown
       monitor command (depending on the value of shutdown_method)
    3) Wait until the guest is down

    @param test: kvm test object
    @param params: Dictionary with the test parameters
    @param env: Dictionary with test environment
    """
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    timeout = int(params.get("login_timeout", 360))
    session = kvm_test_utils.wait_for_login(vm, timeout=timeout)

    try:
        if params.get("shutdown_method") == "shell":
            # Send a shutdown command to the guest's shell
            session.sendline(vm.get_params().get("shutdown_command"))
            logging.info("Shutdown command sent; waiting for guest to go " "down...")
        elif params.get("shutdown_method") == "system_powerdown":
            # Sleep for a while -- give the guest a chance to finish booting
            time.sleep(float(params.get("sleep_before_powerdown", 10)))
            # Send a system_powerdown monitor command
            vm.monitor.cmd("system_powerdown")
            logging.info("system_powerdown monitor command sent; waiting for " "guest to go down...")

        if not kvm_utils.wait_for(vm.is_dead, 240, 0, 1):
            raise error.TestFail("Guest refuses to go down")

        logging.info("Guest is down")

    finally:
        session.close()
def run_clock_getres(test, params, env):
    """
    Verify if guests using kvm-clock as the time source have a sane clock
    resolution.

    @param test: kvm test object.
    @param params: Dictionary with test parameters.
    @param env: Dictionary with the test environment.
    """
    t_name = "test_clock_getres"
    base_dir = "/tmp"

    deps_dir = os.path.join(test.bindir, "deps", t_name)
    os.chdir(deps_dir)
    try:
        utils.system("make clean")
        utils.system("make")
    except:
        raise error.TestError("Failed to compile %s" % t_name)

    test_clock = os.path.join(deps_dir, t_name)
    if not os.path.isfile(test_clock):
        raise error.TestError("Could not find %s" % t_name)

    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    timeout = int(params.get("login_timeout", 360))
    session = kvm_test_utils.wait_for_login(vm, timeout=timeout)
    if not vm.copy_files_to(test_clock, base_dir):
        raise error.TestError("Failed to copy %s to VM" % t_name)
    session.cmd(os.path.join(base_dir, t_name))
    logging.info("PASS: Guest reported appropriate clock resolution")
    logging.info("guest's dmesg:")
    session.cmd_output("dmesg")
示例#9
0
 def flood_ping(src, dst):
     # we must use a dedicated session becuase the kvm_subprocess
     # does not have the other method to interrupt the process in
     # the guest rather than close the session.
     session_flood = kvm_test_utils.wait_for_login(vm[src],
                                                   timeout = 60)
     kvm_test_utils.ping(vlan_ip[dst], flood=True,
                        interface=ifname[src],
                        session=session_flood, timeout=10)
     session_flood.close()
示例#10
0
def run_autoit(test, params, env):
    """
    A wrapper for AutoIt scripts.

    1) Log into a guest.
    2) Run AutoIt 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.
    """
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    session = kvm_test_utils.wait_for_login(vm)

    try:
        logging.info("Starting script...")

        # Collect test parameters
        binary = params.get("autoit_binary")
        script = params.get("autoit_script")
        script_params = params.get("autoit_script_params", "")
        timeout = float(params.get("autoit_script_timeout", 600))

        # Send AutoIt script to guest (this code will be replaced once we
        # support sending files to Windows guests)
        session.sendline("del script.au3")
        file = open(kvm_utils.get_path(test.bindir, script))
        for line in file.readlines():
            # Insert a '^' before each character
            line = "".join("^" + c for c in line.rstrip())
            if line:
                # Append line to the file
                session.sendline("echo %s>>script.au3" % line)
        file.close()

        session.read_up_to_prompt()

        command = "cmd /c %s script.au3 %s" % (binary, script_params)

        logging.info("---------------- Script output ----------------")
        status = session.get_command_status(command,
                                            print_func=logging.info,
                                            timeout=timeout)
        logging.info("---------------- End of script output ----------------")

        if status is None:
            raise error.TestFail("Timeout expired before script execution "
                                 "completed (or something weird happened)")
        if status != 0:
            raise error.TestFail("Script execution failed")

    finally:
        session.close()
def run_migration_with_file_transfer(test, params, env):
    """
    KVM migration test:
    1) Get a live VM and clone it.
    2) Verify that the source VM supports migration.  If it does, proceed with
            the test.
    3) Reboot the VM
    4) Send a migration command to the source VM and wait until it's finished.
    5) Kill off the source VM.
    6) Log into the destination VM after the migration is finished.

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

    def transfer_test(vm, host_path, guest_path, timeout=120):
        """
        vm.copy_files_to does not raise exception, so we need a wrapper
        in order to make it to be used by BackgroundTest.
        """
        if not vm.copy_files_to(host_path, guest_path, timeout=timeout):
            raise error.TestError("Fail to do the file transfer!")

    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    timeout = int(params.get("login_timeout", 360))
    session = kvm_test_utils.wait_for_login(vm, timeout=timeout)

    mig_timeout = float(params.get("mig_timeout", "3600"))
    mig_protocol = params.get("migration_protocol", "tcp")

    guest_path = params.get("guest_path", "/tmp")
    file_size = params.get("file_size", "1000")
    transfer_timeout = int(params.get("transfer_timeout", "240"))
    bg = None

    try:
        utils.run("dd if=/dev/zero of=/tmp/file bs=1M count=%s" % file_size)

        # Transfer file from host to guest
        bg = kvm_test_utils.BackgroundTest(transfer_test,
                                           (vm, "/tmp/file", guest_path,
                                            transfer_timeout))
        bg.start()

        while bg.is_alive():
            logging.info("File transfer is not ended, start a round of migration ...")
            # Migrate the VM
            dest_vm = kvm_test_utils.migrate(vm, env, mig_timeout, mig_protocol, False)
            vm = dest_vm
    finally:
        if bg: bg.join()
        session.close()
        utils.run("rm -rf /tmp/zero")
示例#12
0
def run_set_link(test, params, env):
    """
    KVM guest link test:
    1) Boot up guest with one nic
    2) Ping guest from host
    3) Disable guest link and ping guest from host
    4) Re-enable guest link and ping guest from host
    5) Do file transfer test

    @param test: kvm test object
    @param params: Dictionary with the test parameters
    @param env: Dictionary with test environment.
    """
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    timeout = float(params.get("login_timeout", 360))
    session = kvm_test_utils.wait_for_login(vm, 0, timeout, 0, 2)

    ip = vm.get_address(0)
    linkname = vm.netdev_id[0]

    logging.info("Pinging guest from host")
    s, o = kvm_test_utils.ping(ip, count=10, timeout=20)
    if s != 0:
        raise error.TestFail("Ping failed, status: %s, output: %s" % (s, o))
    ratio = kvm_test_utils.get_loss_ratio(o)
    if ratio != 0:
        raise error.TestFail("Loss ratio is %s, output: %s" % (ratio, o))

    logging.info("Executing 'set link %s off'", linkname)
    vm.monitor.cmd("set_link %s off" % linkname)
    logging.info(vm.monitor.info("network"))
    logging.info("Pinging guest from host")
    s, o = kvm_test_utils.ping(ip, count=10, timeout=20)
    if s == 0:
        raise error.TestFail("Ping unexpectedly succeeded, status: %s,"
                             "output: %s" % (s, o))
    ratio = kvm_test_utils.get_loss_ratio(o)
    if ratio != 100:
        raise error.TestFail("Loss ratio is not 100%%,"
                             "Loss ratio is %s" % ratio)

    logging.info("Executing 'set link %s on'", linkname)
    vm.monitor.cmd("set_link %s on" % linkname)
    logging.info(vm.monitor.info("network"))
    logging.info("Pinging guest from host")
    s, o = kvm_test_utils.ping(ip, count=10, timeout=20)
    if s != 0:
        raise error.TestFail("Ping failed, status: %s, output: %s" % (s, o))
    ratio = kvm_test_utils.get_loss_ratio(o)
    if ratio != 0:
        raise error.TestFail("Loss ratio is %s, output: %s" % (ratio, o))

    file_transfer.run_file_transfer(test, params, env)
    session.close()
示例#13
0
def run_nic_bonding(test, params, env):
    """
    Nic bonding test in guest.

    1) Start guest with four nic models.
    2) Setup bond0 in guest by script bonding_setup.py.
    3) Execute file transfer test between guest and host.
    4) Repeatedly put down/up interfaces by set_link
    5) Execute file transfer test between guest and host.

    @param test: Kvm test object.
    @param params: Dictionary with the test parameters.
    @param env: Dictionary with test environment.
    """
    def control_link_loop(vm, termination_event):
        logging.info("Repeatedly put down/up interfaces by set_link")
        while True:
            for i in range(len(params.get("nics").split())):
                linkname = "%s.%s" % (params.get("nic_model"), i)
                cmd = "set_link %s down" % linkname
                vm.monitor.cmd(cmd)
                time.sleep(1)
                cmd = "set_link %s up" % linkname
                vm.monitor.cmd(cmd)
            if termination_event.isSet():
                break

    timeout = int(params.get("login_timeout", 1200))
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    session_serial = kvm_test_utils.wait_for_login(vm, 0, timeout, 0, 2,
                                                   serial=True)
    script_path = kvm_utils.get_path(test.bindir, "scripts/bonding_setup.py")
    vm.copy_files_to(script_path, "/tmp/bonding_setup.py")
    cmd = "python /tmp/bonding_setup.py %s" % vm.get_mac_address()
    session_serial.cmd(cmd)

    termination_event = threading.Event()
    t = threading.Thread(target=control_link_loop,
                         args=(vm, termination_event))
    try:
        logging.info("Do some basic test before testing high availability")
        file_transfer.run_file_transfer(test, params, env)
        t.start()
        logging.info("Do file transfer testing")
        file_transfer.run_file_transfer(test, params, env)
    finally:
        termination_event.set()
        t.join(10)
        session_serial.close()
示例#14
0
def run_set_link(test, params, env):
    """
    KVM guest link test:
    1) Boot up guest with one nic
    2) Ping guest from host
    3) Disable guest link and ping guest from host
    4) Re-enable guest link and ping guest from host
    5) Do file transfer test

    @param test: kvm test object
    @param params: Dictionary with the test parameters
    @param env: Dictionary with test environment.
    """
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    timeout = float(params.get("login_timeout", 360))
    session = kvm_test_utils.wait_for_login(vm, 0, timeout, 0, 2)

    def set_link_test(linkid):
        """
        Issue set_link commands and test its function

        @param linkid: id of netdev or devices to be tested
        """
        ip = vm.get_address(0)

        vm.monitor.cmd("set_link %s down" % linkid)
        s, o = kvm_test_utils.ping(ip, count=10, timeout=20)
        if kvm_test_utils.get_loss_ratio(o) != 100:
            raise error.TestFail("Still can ping the %s after down %s" %
                                 (ip, linkid))

        vm.monitor.cmd("set_link %s up" % linkid)
        s, o = kvm_test_utils.ping(ip, count=10, timeout=20)
        # we use 100% here as the notification of link status changed may be
        # delayed in guest driver
        if kvm_test_utils.get_loss_ratio(o) == 100:
            raise error.TestFail("Packet loss during ping %s after up %s" %
                                 (ip, linkid))

    netdev_id = vm.netdev_id[0]
    device_id = vm.get_peer(netdev_id)
    logging.info("Issue set_link commands for netdevs")
    set_link_test(netdev_id)
    logging.info("Issue set_link commands for network devics")
    set_link_test(device_id)

    file_transfer.run_file_transfer(test, params, env)
    session.close()
示例#15
0
def run_boot(test, params, env):
    """
    KVM reboot test:
    1) Log into a guest
    2) Send a reboot command or a system_reset monitor command (optional)
    3) Wait until the guest is up again
    4) Log into the guest to verify it's up again

    @param test: kvm test object
    @param params: Dictionary with the test parameters
    @param env: Dictionary with test environment.
    """
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    session = kvm_test_utils.wait_for_login(vm)

    try:
        if params.get("reboot_method") == "shell":
            # Send a reboot command to the guest's shell
            session.sendline(vm.get_params().get("reboot_command"))
            logging.info("Reboot command sent; waiting for guest to go "
                         "down...")
        elif params.get("reboot_method") == "system_reset":
            # Sleep for a while -- give the guest a chance to finish booting
            time.sleep(float(params.get("sleep_before_reset", 10)))
            # Send a system_reset monitor command
            vm.send_monitor_cmd("system_reset")
            logging.info("system_reset monitor command sent; waiting for "
                         "guest to go down...")
        else: return

        # Wait for the session to become unresponsive
        if not kvm_utils.wait_for(lambda: not session.is_responsive(),
                                  120, 0, 1):
            raise error.TestFail("Guest refuses to go down")

    finally:
        session.close()

    logging.info("Guest is down; waiting for it to go up again...")

    session = kvm_utils.wait_for(vm.remote_login, 240, 0, 2)
    if not session:
        raise error.TestFail("Could not log into guest after reboot")
    session.close()

    logging.info("Guest is up again")
示例#16
0
def run_yum_update(test, params, env):
    """
    Runs yum update and yum update kernel on the remote host (yum enabled
    hosts only).

    @param test: kvm test object.
    @param params: Dictionary with test parameters.
    @param env: Dictionary with the test environment.
    """
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    timeout = int(params.get("login_timeout", 360))
    session = kvm_test_utils.wait_for_login(vm, timeout=timeout)

    internal_yum_update(session, "yum update", params.get("shell_prompt"), 600)
    internal_yum_update(session, "yum update kernel", params.get("shell_prompt"), 600)

    session.close()
示例#17
0
def run_autotest(test, params, env):
    """
    Run an autotest test inside a guest.

    @param test: kvm test object.
    @param params: Dictionary with test parameters.
    @param env: Dictionary with the test environment.
    """
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    timeout = int(params.get("login_timeout", 360))
    session = kvm_test_utils.wait_for_login(vm, timeout=timeout)

    # Collect test parameters
    timeout = int(params.get("test_timeout", 300))
    control_path = os.path.join(test.bindir, "autotest_control",
                                params.get("test_control_file"))
    outputdir = test.outputdir

    kvm_test_utils.run_autotest(vm, session, control_path, timeout, outputdir)
示例#18
0
def run_linux_s3(test, params, env):
    """
    Suspend a guest Linux OS to memory.

    @param test: kvm test object.
    @param params: Dictionary with test parameters.
    @param env: Dictionary with the test environment.
    """
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    session = kvm_test_utils.wait_for_login(vm)

    logging.info("Checking that VM supports S3")
    status = session.get_command_status("grep -q mem /sys/power/state")
    if status == None:
        logging.error("Failed to check if S3 exists")
    elif status != 0:
        raise error.TestFail("Guest does not support S3")

    logging.info("Waiting for a while for X to start")
    time.sleep(10)

    src_tty = session.get_command_output("fgconsole").strip()
    logging.info("Current virtual terminal is %s" % src_tty)
    if src_tty not in map(str, range(1,10)):
        raise error.TestFail("Got a strange current vt (%s)" % src_tty)

    dst_tty = "1"
    if src_tty == "1":
        dst_tty = "2"

    logging.info("Putting VM into S3")
    command = "chvt %s && echo mem > /sys/power/state && chvt %s" % (dst_tty,
                                                                     src_tty)
    status = session.get_command_status(command, timeout=120)
    if status != 0:
        raise error.TestFail("Suspend to mem failed")

    logging.info("VM resumed after S3")

    session.close()
def run_migration_with_reboot(test, params, env):
    """
    KVM migration test:
    1) Get a live VM and clone it.
    2) Verify that the source VM supports migration.  If it does, proceed with
            the test.
    3) Reboot the VM
    4) Send a migration command to the source VM and wait until it's finished.
    5) Kill off the source VM.
    6) Log into the destination VM after the migration is finished.

    @param test: kvm test object.
    @param params: Dictionary with test parameters.
    @param env: Dictionary with the test environment.
    """
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    timeout = int(params.get("login_timeout", 360))
    session = kvm_test_utils.wait_for_login(vm, timeout=timeout)

    mig_timeout = float(params.get("mig_timeout", "3600"))
    mig_protocol = params.get("migration_protocol", "tcp")
    mig_cancel = bool(params.get("mig_cancel"))
    bg = None

    try:
        # reboot the VM in background
        bg = kvm_test_utils.BackgroundTest(kvm_test_utils.reboot, (vm, session))
        bg.start()

        while bg.is_alive():
            # Migrate the VM
            dest_vm = kvm_test_utils.migrate(vm, env, mig_timeout, mig_protocol,
                                             False)
            vm = dest_vm

    finally:
        if bg:
            bg.join()
        session.close()
示例#20
0
def run_multicast(test, params, env):
    """
    Test multicast function of nic (rtl8139/e1000/virtio)

    1) Create a VM.
    2) Join guest into multicast groups.
    3) Ping multicast addresses on host.
    4) Flood ping test with different size of packets.
    5) Final ping test and check if lose packet.

    @param test: KVM test object.
    @param params: Dictionary with the test parameters.
    @param env: Dictionary with test environment.
    """
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    session = kvm_test_utils.wait_for_login(vm,
                                  timeout=int(params.get("login_timeout", 360)))

    def run_guest(cmd):
        try:
            session.cmd(cmd)
        except kvm_subprocess.ShellError, e:
            logging.warn(e)
示例#21
0
def run_autotest(test, params, env):
    """
    Run an autotest test inside a guest.

    @param test: kvm test object.
    @param params: Dictionary with test parameters.
    @param env: Dictionary with the test environment.
    """
    # Helper functions
    def copy_if_size_differs(vm, local_path, remote_path):
        """
        Copy a file to a guest if it doesn't exist or if its size differs.

        @param vm: VM object
        @param local_path: Local path
        @param remote_path: Remote path
        """
        copy = False
        output = session.get_command_output("ls -l %s" % remote_path)
        if ("such file" in output or
            int(output.split()[4]) != os.path.getsize(local_path)):
            basename = os.path.basename(local_path)
            logging.info("Copying %s to guest (file is missing or has a "
                         "different size)..." % basename)
            if not vm.copy_files_to(local_path, remote_path):
                raise error.TestFail("Could not copy %s to guest" % basename)

    def extract(vm, remote_path, dest_dir="."):
        """
        Extract a .tar.bz2 file on the guest.

        @param vm: VM object
        @param remote_path: Remote file path
        @param dest_dir: Destination dir for the contents
        """
        basename = os.path.basename(remote_path)
        logging.info("Extracting %s..." % basename)
        status = session.get_command_status("tar xfj %s -C %s" %
                                            (remote_path, dest_dir))
        if status != 0:
            raise error.TestFail("Could not extract %s" % basename)

    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    session = kvm_test_utils.wait_for_login(vm)

    # Collect test parameters
    test_name = params.get("test_name")
    test_timeout = int(params.get("test_timeout", 300))
    test_control_file = params.get("test_control_file", "control")
    tarred_autotest_path = "/tmp/autotest.tar.bz2"
    tarred_test_path = "/tmp/%s.tar.bz2" % test_name

    # tar the contents of bindir/autotest
    cmd = "cd %s; tar cvjf %s autotest/*"
    cmd += " --exclude=autotest/tests"
    cmd += " --exclude=autotest/results"
    cmd += " --exclude=autotest/tmp"
    cmd += " --exclude=autotest/control"
    cmd += " --exclude=*.pyc"
    cmd += " --exclude=*.svn"
    cmd += " --exclude=*.git"
    kvm_subprocess.run_fg(cmd % (test.bindir, tarred_autotest_path), timeout=30)

    # tar the contents of bindir/autotest/tests/<test_name>
    cmd = "cd %s; tar cvjf %s %s/*"
    cmd += " --exclude=*.pyc"
    cmd += " --exclude=*.svn"
    cmd += " --exclude=*.git"
    kvm_subprocess.run_fg(cmd %
                          (os.path.join(test.bindir, "autotest", "tests"),
                           tarred_test_path, test_name), timeout=30)

    # Copy autotest.tar.bz2
    copy_if_size_differs(vm, tarred_autotest_path, "autotest.tar.bz2")

    # Copy <test_name>.tar.bz2
    copy_if_size_differs(vm, tarred_test_path, test_name + ".tar.bz2")

    # Extract autotest.tar.bz2
    extract(vm, "autotest.tar.bz2")

    # mkdir autotest/tests
    session.sendline("mkdir autotest/tests")

    # Extract <test_name>.tar.bz2 into autotest/tests
    extract(vm, test_name + ".tar.bz2", "autotest/tests")

    # Copy the selected control file (located inside
    # test.bindir/autotest_control) to the autotest dir
    control_file_path = os.path.join(test.bindir, "autotest_control",
                                     test_control_file)
    if not vm.copy_files_to(control_file_path, "autotest/control"):
        raise error.TestFail("Could not copy the test control file to guest")

    # Run the test
    logging.info("Running test '%s'..." % test_name)
    session.sendline("cd autotest")
    session.sendline("rm -f control.state")
    session.sendline("rm -rf results/*")
    session.read_up_to_prompt()
    logging.info("---------------- Test output ----------------")
    status = session.get_command_status("bin/autotest control",
                                        timeout=test_timeout,
                                        print_func=logging.info)
    logging.info("---------------- End of test output ----------------")
    if status is None:
        raise error.TestFail("Timeout elapsed while waiting for test to "
                             "complete")

    # Get the results generated by autotest
    output = session.get_command_output("cat results/*/status")
    results = scan_results.parse_results(output)
    session.close

    # Copy test results to the local bindir/guest_results
    logging.info("Copying results back from guest...")
    guest_results_dir = os.path.join(test.outputdir, "guest_results")
    if not os.path.exists(guest_results_dir):
        os.mkdir(guest_results_dir)
    if not vm.copy_files_from("autotest/results/default/*", guest_results_dir):
        logging.error("Could not copy results back from guest")

    # Report test results
    logging.info("Results (test, status, duration, info):")
    for result in results:
        logging.info(str(result))

    # Make a list of FAIL/ERROR/ABORT results (make sure FAIL results appear
    # before ERROR results, and ERROR results appear before ABORT results)
    bad_results = [r for r in results if r[1] == "FAIL"]
    bad_results += [r for r in results if r[1] == "ERROR"]
    bad_results += [r for r in results if r[1] == "ABORT"]

    # Fail the test if necessary
    if not results:
        raise error.TestFail("Test '%s' did not produce any recognizable "
                             "results" % test_name)
    if bad_results:
        result = bad_results[0]
        raise error.TestFail("Test '%s' ended with %s (reason: '%s')"
                             % (result[0], result[1], result[3]))
示例#22
0
def run_ping(test, params, env):
    """
    Ping the guest with different size of packets.

    Packet Loss Test:
    1) Ping the guest with different size/interval of packets.

    Stress Test:
    1) Flood ping the guest.
    2) Check if the network is still usable.

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

    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    session = kvm_test_utils.wait_for_login(vm)

    counts = params.get("ping_counts", 100)
    flood_minutes = float(params.get("flood_minutes", 10))
    nics = params.get("nics").split()
    strict_check = params.get("strict_check", "no") == "yes"

    packet_size = [0, 1, 4, 48, 512, 1440, 1500, 1505, 4054, 4055, 4096, 4192,
                   8878, 9000, 32767, 65507]

    try:
        for i, nic in enumerate(nics):
            ip = vm.get_address(i)
            if not ip:
                logging.error("Could not get the ip of nic index %d", i)
                continue

            for size in packet_size:
                logging.info("Ping with packet size %s", size)
                status, output = kvm_test_utils.ping(ip, 10,
                                                     packetsize=size,
                                                     timeout=20)
                if strict_check:
                    ratio = kvm_test_utils.get_loss_ratio(output)
                    if ratio != 0:
                        raise error.TestFail("Loss ratio is %s for packet size"
                                             " %s" % (ratio, size))
                else:
                    if status != 0:
                        raise error.TestFail("Ping failed, status: %s,"
                                             " output: %s" % (status, output))

            logging.info("Flood ping test")
            kvm_test_utils.ping(ip, None, flood=True, output_func=None,
                                timeout=flood_minutes * 60)

            logging.info("Final ping test")
            status, output = kvm_test_utils.ping(ip, counts,
                                                 timeout=float(counts) * 1.5)
            if strict_check:
                ratio = kvm_test_utils.get_loss_ratio(output)
                if ratio != 0:
                    raise error.TestFail("Ping failed, status: %s,"
                                         " output: %s" % (status, output))
            else:
                if status != 0:
                    raise error.TestFail("Ping returns non-zero value %s" %
                                         output)
    finally:
        session.close()
def run_timedrift_with_reboot(test, params, env):
    """
    Time drift test with reboot:

    1) Log into a guest.
    2) Take a time reading from the guest and host.
    3) Reboot the guest.
    4) Take a second time reading.
    5) If the drift (in seconds) is higher than a user specified value, fail.

    @param test: KVM test object.
    @param params: Dictionary with test parameters.
    @param env: Dictionary with the test environment.
    """
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    timeout = int(params.get("login_timeout", 360))
    session = kvm_test_utils.wait_for_login(vm, timeout=timeout)

    # Collect test parameters:
    # Command to run to get the current time
    time_command = params.get("time_command")
    # Filter which should match a string to be passed to time.strptime()
    time_filter_re = params.get("time_filter_re")
    # Time format for time.strptime()
    time_format = params.get("time_format")
    drift_threshold = float(params.get("drift_threshold", "10"))
    drift_threshold_single = float(params.get("drift_threshold_single", "3"))
    reboot_iterations = int(params.get("reboot_iterations", 1))

    try:
        # Get initial time
        # (ht stands for host time, gt stands for guest time)
        (ht0, gt0) = kvm_test_utils.get_time(session, time_command,
                                             time_filter_re, time_format)

        # Reboot
        for i in range(reboot_iterations):
            # Get time before current iteration
            (ht0_, gt0_) = kvm_test_utils.get_time(session, time_command,
                                                   time_filter_re, time_format)
            # Run current iteration
            logging.info("Rebooting: iteration %d of %d..." %
                         (i + 1, reboot_iterations))
            session = kvm_test_utils.reboot(vm, session)
            # Get time after current iteration
            (ht1_, gt1_) = kvm_test_utils.get_time(session, time_command,
                                                   time_filter_re, time_format)
            # Report iteration results
            host_delta = ht1_ - ht0_
            guest_delta = gt1_ - gt0_
            drift = abs(host_delta - guest_delta)
            logging.info("Host duration (iteration %d): %.2f" %
                         (i + 1, host_delta))
            logging.info("Guest duration (iteration %d): %.2f" %
                         (i + 1, guest_delta))
            logging.info("Drift at iteration %d: %.2f seconds" %
                         (i + 1, drift))
            # Fail if necessary
            if drift > drift_threshold_single:
                raise error.TestFail("Time drift too large at iteration %d: "
                                     "%.2f seconds" % (i + 1, drift))

        # Get final time
        (ht1, gt1) = kvm_test_utils.get_time(session, time_command,
                                             time_filter_re, time_format)

    finally:
        if session:
            session.close()

    # Report results
    host_delta = ht1 - ht0
    guest_delta = gt1 - gt0
    drift = abs(host_delta - guest_delta)
    logging.info("Host duration (%d reboots): %.2f" %
                 (reboot_iterations, host_delta))
    logging.info("Guest duration (%d reboots): %.2f" %
                 (reboot_iterations, guest_delta))
    logging.info("Drift after %d reboots: %.2f seconds" %
                 (reboot_iterations, drift))

    # Fail if necessary
    if drift > drift_threshold:
        raise error.TestFail("Time drift too large after %d reboots: "
                             "%.2f seconds" % (reboot_iterations, drift))
示例#24
0
def run_file_transfer(test, params, env):
    """
    Test ethrnet device function by ethtool

    1) Boot up a VM.
    2) Create a large file by dd on host.
    3) Copy this file from host to guest.
    4) Copy this file from guest to host.
    5) Check if file transfers ended good.

    @param test: KVM test object.
    @param params: Dictionary with the test parameters.
    @param env: Dictionary with test environment.
    """
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    timeout=int(params.get("login_timeout", 360))

    session = kvm_test_utils.wait_for_login(vm, timeout=timeout)
    if not session:
        raise error.TestFail("Could not log into guest '%s'" % vm.name)

    dir_name = test.tmpdir
    transfer_timeout = int(params.get("transfer_timeout"))
    transfer_type = params.get("transfer_type")
    tmp_dir = params.get("tmp_dir", "/tmp/")
    clean_cmd = params.get("clean_cmd", "rm -f")
    filesize = int(params.get("filesize", 4000))
    count = int(filesize / 10)
    if count == 0:
        count = 1
    cmd = "dd if=/dev/zero of=%s/a.out bs=10M count=%d" % (dir_name,
                                                           count)
    guest_path = tmp_dir + "b.out"

    try:
        logging.info("Creating %dMB file on host", filesize)
        utils.run(cmd)

        if transfer_type == "remote":
            logging.info("Transfering file host -> guest, timeout: %ss",
                         transfer_timeout)
            t_begin = time.time()
            success = vm.copy_files_to("%s/a.out" % dir_name, guest_path,
                                       timeout=transfer_timeout)
            t_end = time.time()
            throughput = filesize / (t_end - t_begin)
            if not success:
                raise error.TestFail("Fail to transfer file from host to guest")
            logging.info("File transfer host -> guest succeed, "
                         "estimated throughput: %.2fMB/s", throughput)

            logging.info("Transfering file guest -> host, timeout: %ss",
                         transfer_timeout)
            t_begin = time.time()
            success = vm.copy_files_from(guest_path, "%s/c.out" % dir_name,
                                         timeout=transfer_timeout)
            t_end = time.time()
            throughput = filesize / (t_end - t_begin)
            if not success:
                raise error.TestFail("Fail to transfer file from guest to host")
            logging.info("File transfer guest -> host succeed, "
                         "estimated throughput: %.2fMB/s", throughput)
        else:
            raise error.TestError("Unknown test file transfer mode %s" %
                                  transfer_type)

        for f in ['a.out', 'c.out']:
            p = os.path.join(dir_name, f)
            size = os.path.getsize(p)
            logging.debug('Size of %s: %sB', f, size)

        md5_orig = utils.hash_file("%s/a.out" % dir_name, method="md5")
        md5_new = utils.hash_file("%s/c.out" % dir_name, method="md5")

        if md5_orig != md5_new:
            raise error.TestFail("File changed after transfer host -> guest "
                                 "and guest -> host")

    finally:
        logging.info('Cleaning temp file on guest')
        clean_cmd += " %s" % guest_path
        session.cmd(clean_cmd)
        logging.info('Cleaning temp files on host')
        try:
            os.remove('%s/a.out' % dir_name)
            os.remove('%s/c.out' % dir_name)
        except OSError:
            pass
        session.close()
示例#25
0
def run_guest_s4(test, params, env):
    """
    Suspend guest to disk, supports both Linux & Windows OSes.

    @param test: kvm test object.
    @param params: Dictionary with test parameters.
    @param env: Dictionary with the test environment.
    """
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    timeout = int(params.get("login_timeout", 360))
    session = kvm_test_utils.wait_for_login(vm, timeout=timeout)

    logging.info("Checking whether guest OS supports suspend to disk (S4)...")
    session.cmd(params.get("check_s4_support_cmd"))

    logging.info("Waiting until all guest OS services are fully started...")
    time.sleep(float(params.get("services_up_timeout", 30)))

    # Start up a program (tcpdump for linux & ping for Windows), as a flag.
    # If the program died after suspend, then fails this testcase.
    test_s4_cmd = params.get("test_s4_cmd")
    session.sendline(test_s4_cmd)
    time.sleep(5)

    # Get the second session to start S4
    session2 = kvm_test_utils.wait_for_login(vm, timeout=timeout)

    # Make sure the background program is running as expected
    check_s4_cmd = params.get("check_s4_cmd")
    session2.cmd(check_s4_cmd)
    logging.info("Launched background command in guest: %s" % test_s4_cmd)

    # Suspend to disk
    logging.info("Starting suspend to disk now...")
    session2.sendline(params.get("set_s4_cmd"))

    # Make sure the VM goes down
    suspend_timeout = 240 + int(params.get("smp")) * 60
    if not kvm_utils.wait_for(vm.is_dead, suspend_timeout, 2, 2):
        raise error.TestFail("VM refuses to go down. Suspend failed.")
    logging.info("VM suspended successfully. Sleeping for a while before "
                 "resuming it.")
    time.sleep(10)

    # Start vm, and check whether the program is still running
    logging.info("Resuming suspended VM...")
    if not vm.create():
        raise error.TestError("Failed to start VM after suspend to disk")

    # Log into the resumed VM
    relogin_timeout = int(params.get("relogin_timeout", 240))
    logging.info("Logging into resumed VM, timeout %s", relogin_timeout)
    session2 = kvm_utils.wait_for(vm.remote_login, relogin_timeout, 0, 2)
    if not session2:
        raise error.TestFail("Could not log into VM after resuming from "
                             "suspend to disk")

    # Check whether the test command is still alive
    logging.info("Checking if background command is still alive...")
    session2.cmd(check_s4_cmd)

    logging.info("VM resumed successfuly after suspend to disk")
    session2.cmd_output(params.get("kill_test_s4_cmd"))
    session.close()
    session2.close()
示例#26
0
def run_nic_hotplug(test, params, env):
    """
    Test hotplug of NIC devices

    1) Boot up guest with one nic
    2) Add a host network device through monitor cmd and check if it's added
    3) Add nic device through monitor cmd and check if it's added
    4) Check if new interface gets ip address
    5) Disable primary link of guest
    6) Ping guest new ip from host
    7) Delete nic device and netdev
    8) Re-enable primary link of guest

    @param test:   KVM test object.
    @param params: Dictionary with the test parameters.
    @param env:    Dictionary with test environment.
    """
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    timeout = int(params.get("login_timeout", 360))
    guest_delay = int(params.get("guest_delay", 20))
    session = kvm_test_utils.wait_for_login(vm, timeout=timeout)
    romfile = params.get("romfile")

    # Modprobe the module if specified in config file
    module = params.get("modprobe_module")
    if module:
        session.get_command_output("modprobe %s" % module)

    def netdev_add(vm):
        netdev_id = kvm_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" % kvm_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_del(vm, n_id):
        vm.monitor.cmd("netdev_del %s" % n_id)

        network = vm.monitor.info("network")
        if n_id in network:
            logging.error(network)
            raise error.TestError("Fail to remove netdev %s" % n_id)

    def nic_add(vm, model, netdev_id, mac, rom=None):
        """
        Add a nic to virtual machine

        @vm: VM object
        @model: nic model
        @netdev_id: id of netdev
        @mac: Mac address of new nic
        @rom: Rom file
        """
        nic_id = kvm_utils.generate_random_id()
        if model == "virtio":
            model = "virtio-net-pci"
        device_add_cmd = "device_add %s,netdev=%s,mac=%s,id=%s" % (
            model, netdev_id, mac, nic_id)
        if rom:
            device_add_cmd += ",romfile=%s" % rom
        logging.info("Adding nic through %s", device_add_cmd)
        vm.monitor.cmd(device_add_cmd)

        qdev = vm.monitor.info("qtree")
        if not nic_id in qdev:
            logging.error(qdev)
            raise error.TestFail("Device %s was not plugged into qdev"
                                 "tree" % nic_id)
        else:
            return nic_id

    def nic_del(vm, nic_id, wait=True):
        """
        Remove the nic from pci tree.

        @vm: VM object
        @id: the nic id
        @wait: Whether need to wait for the guest to unplug the device
        """
        nic_del_cmd = "device_del %s" % nic_id
        vm.monitor.cmd(nic_del_cmd)
        if wait:
            logging.info("waiting for the guest to finish the unplug")
            if not kvm_utils.wait_for(
                    lambda: nic_id not in vm.monitor.info("qtree"),
                    guest_delay, 5, 1):
                logging.error(vm.monitor.info("qtree"))
                raise error.TestError("Device is not unplugged by "
                                      "guest, please check whether the "
                                      "hotplug module was loaded in guest")

    logging.info("Attach a virtio nic to vm")
    mac = kvm_utils.generate_mac_address(vm.instance, 1)
    if not mac:
        mac = "00:00:02:00:00:02"
    netdev_id = netdev_add(vm)
    device_id = nic_add(vm, "virtio", netdev_id, mac, romfile)

    if "Win" not in params.get("guest_name", ""):
        session.sendline("dhclient %s &" %
                         kvm_test_utils.get_linux_ifname(session, mac))

    logging.info("Shutting down the primary link")
    vm.monitor.cmd("set_link %s down" % vm.netdev_id[0])

    try:
        logging.info("Waiting for new nic's ip address acquisition...")
        if not kvm_utils.wait_for(
                lambda: (vm.address_cache.get(mac) is not None), 10, 1):
            raise error.TestFail("Could not get ip address of new nic")
        ip = vm.address_cache.get(mac)
        if not kvm_utils.verify_ip_address_ownership(ip, mac):
            raise error.TestFail("Could not verify the ip address of new nic")
        else:
            logging.info("Got the ip address of new nic: %s", ip)

        logging.info("Ping test the new nic ...")
        s, o = kvm_test_utils.ping(ip, 100)
        if s != 0:
            logging.error(o)
            raise error.TestFail("New nic failed ping test")

        logging.info("Detaching a virtio nic from vm")
        nic_del(vm, device_id)
        netdev_del(vm, netdev_id)

    finally:
        vm.free_mac_address(1)
        logging.info("Re-enabling the primary link")
        vm.monitor.cmd("set_link %s up" % vm.netdev_id[0])
示例#27
0
    def _vm_create(no_console=3, no_serialport=3):
        """
        Creates the VM and connects the specified number of consoles and serial
        ports.
        Ports are allocated by 2 per 1 virtio-serial-pci device starting with
        console. (3+2 => CC|CS|S; 0+2 => SS; 3+4 => CC|CS|SS|S, ...) This way
        it's easy to test communication on the same or different
        virtio-serial-pci device.
        Further in tests the consoles are being picked always from the first
        available one (3+2: 2xC => CC|cs|s <communication on the same PCI>;
        2xC,1xS => CC|cS|s <communication between 2 PCI devs)

        @param no_console: Number of desired virtconsoles.
        @param no_serialport: Number of desired virtserialports.
        @return: Tuple with (guest information, consoles information)
                guest informations = [vm, session, tmp_dir, kcrash]
                consoles informations = [consoles[], serialports[]]
        """
        consoles = []
        serialports = []
        tmp_dir = tempfile.mkdtemp(prefix="virtio-console-", dir="/tmp/")
        if not params.get('extra_params'):
            params['extra_params'] = ''

        for i in range(0, no_console):
            # Spread consoles between multiple PCI devices (2 per a dev)
            if not i % 2:
                pci = "virtio-serial-pci%d" % (i / 2)
                params['extra_params'] += (" -device virtio-serial-pci,id=" +
                                           pci)
                pci += ".0"
            params['extra_params'] += (" -chardev socket,path=%s/%d,id=vc%d,"
                                       "server,nowait" % (tmp_dir, i, i))
            params['extra_params'] += (" -device virtconsole,chardev=vc%d,"
                                       "name=console-%d,id=c%d,bus=%s" %
                                       (i, i, i, pci))

        for i in range(no_console, no_console + no_serialport):
            # Spread seroal ports between multiple PCI devices (2 per a dev)
            if not i % 2:
                pci = "virtio-serial-pci%d" % (i / 2)
                params['extra_params'] += (" -device virtio-serial-pci,id=" +
                                           pci)
                pci += ".0"
            params['extra_params'] += (" -chardev socket,path=%s/%d,id=vs%d,"
                                       "server,nowait" % (tmp_dir, i, i))
            params['extra_params'] += (" -device virtserialport,chardev=vs%d,"
                                       "name=serialport-%d,id=p%d,bus=%s" %
                                       (i, i, i, pci))

        logging.debug("Booting first guest %s", params.get("main_vm"))
        kvm_preprocessing.preprocess_vm(test, params, env,
                                        params.get("main_vm"))

        vm = env.get_vm(params.get("main_vm"))

        session = vm.wait_for_login(
            timeout=float(params.get("boot_timeout", 240)))

        sserial = kvm_test_utils.wait_for_login(
            vm, 0, float(params.get("boot_timeout", 240)), 0, 2, serial=True)

        # connect the sockets
        for i in range(0, no_console):
            consoles.append(
                Port(None, "console-%d" % i, "yes", "%s/%d" % (tmp_dir, i)))
        for i in range(no_console, no_console + no_serialport):
            serialports.append(
                Port(None, "serialport-%d" % i, "no", "%s/%d" % (tmp_dir, i)))

        kcrash = False

        return [vm, session, tmp_dir, sserial, kcrash], [consoles, serialports]
示例#28
0
def run_vlan(test, params, env):
    """
    Test 802.1Q vlan of NIC, config it by vconfig command.

    1) Create two VMs.
    2) Setup guests in 10 different vlans by vconfig and using hard-coded
       ip address.
    3) Test by ping between same and different vlans of two VMs.
    4) Test by TCP data transfer, floop ping between same vlan of two VMs.
    5) Test maximal plumb/unplumb vlans.
    6) Recover the vlan config.

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

    vm = []
    session = []
    ifname = []
    vm_ip = []
    digest_origin = []
    vlan_ip = ['', '']
    ip_unit = ['1', '2']
    subnet = params.get("subnet")
    vlan_num = int(params.get("vlan_num"))
    maximal = int(params.get("maximal"))
    file_size = params.get("file_size")

    vm.append(kvm_test_utils.get_living_vm(env, params.get("main_vm")))
    vm.append(kvm_test_utils.get_living_vm(env, "vm2"))

    def add_vlan(session, id, iface="eth0"):
        session.cmd("vconfig add %s %s" % (iface, id))

    def set_ip_vlan(session, id, ip, iface="eth0"):
        iface = "%s.%s" % (iface, id)
        session.cmd("ifconfig %s %s" % (iface, ip))

    def set_arp_ignore(session, iface="eth0"):
        ignore_cmd = "echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore"
        session.cmd(ignore_cmd)

    def rem_vlan(session, id, iface="eth0"):
        rem_vlan_cmd = "if [[ -e /proc/net/vlan/%s ]];then vconfig rem %s;fi"
        iface = "%s.%s" % (iface, id)
        return session.cmd_status(rem_vlan_cmd % (iface, iface))

    def nc_transfer(src, dst):
        nc_port = kvm_utils.find_free_port(1025, 5334, vm_ip[dst])
        listen_cmd = params.get("listen_cmd")
        send_cmd = params.get("send_cmd")

        #listen in dst
        listen_cmd = listen_cmd % (nc_port, "receive")
        session[dst].sendline(listen_cmd)
        time.sleep(2)
        #send file from src to dst
        send_cmd = send_cmd % (vlan_ip[dst], str(nc_port), "file")
        session[src].cmd(send_cmd, timeout=60)
        try:
            session[dst].read_up_to_prompt(timeout=60)
        except kvm_subprocess.ExpectError:
            raise error.TestFail ("Fail to receive file"
                                    " from vm%s to vm%s" % (src+1, dst+1))
        #check MD5 message digest of receive file in dst
        output = session[dst].cmd_output("md5sum receive").strip()
        digest_receive = re.findall(r'(\w+)', output)[0]
        if digest_receive == digest_origin[src]:
            logging.info("file succeed received in vm %s" % vlan_ip[dst])
        else:
            logging.info("digest_origin is  %s" % digest_origin[src])
            logging.info("digest_receive is %s" % digest_receive)
            raise error.TestFail("File transfered differ from origin")
        session[dst].cmd_output("rm -f receive")

    for i in range(2):
        session.append(kvm_test_utils.wait_for_login(vm[i],
                       timeout=int(params.get("login_timeout", 360))))
        if not session[i] :
            raise error.TestError("Could not log into guest(vm%d)" % i)
        logging.info("Logged in")

        ifname.append(kvm_test_utils.get_linux_ifname(session[i],
                      vm[i].get_mac_address()))
        #get guest ip
        vm_ip.append(vm[i].get_address())

        #produce sized file in vm
        dd_cmd = "dd if=/dev/urandom of=file bs=1024k count=%s"
        session[i].cmd(dd_cmd % file_size)
        #record MD5 message digest of file
        output = session[i].cmd("md5sum file", timeout=60)
        digest_origin.append(re.findall(r'(\w+)', output)[0])

        #stop firewall in vm
        session[i].cmd_output("/etc/init.d/iptables stop")

        #load 8021q module for vconfig
        session[i].cmd("modprobe 8021q")

    try:
        for i in range(2):
            for vlan_i in range(1, vlan_num+1):
                add_vlan(session[i], vlan_i, ifname[i])
                set_ip_vlan(session[i], vlan_i, "%s.%s.%s" %
                            (subnet, vlan_i, ip_unit[i]), ifname[i])
            set_arp_ignore(session[i], ifname[i])

        for vlan in range(1, vlan_num+1):
            logging.info("Test for vlan %s" % vlan)

            logging.info("Ping between vlans")
            interface = ifname[0] + '.' + str(vlan)
            for vlan2 in range(1, vlan_num+1):
                for i in range(2):
                    interface = ifname[i] + '.' + str(vlan)
                    dest = subnet +'.'+ str(vlan2)+ '.' + ip_unit[(i+1)%2]
                    s, o = kvm_test_utils.ping(dest, count=2,
                                              interface=interface,
                                              session=session[i], timeout=30)
                    if ((vlan == vlan2) ^ (s == 0)):
                        raise error.TestFail ("%s ping %s unexpected" %
                                                    (interface, dest))

            vlan_ip[0] = subnet + '.' + str(vlan) + '.' + ip_unit[0]
            vlan_ip[1] = subnet + '.' + str(vlan) + '.' + ip_unit[1]

            logging.info("Flood ping")
            def flood_ping(src, dst):
                # we must use a dedicated session becuase the kvm_subprocess
                # does not have the other method to interrupt the process in
                # the guest rather than close the session.
                session_flood = kvm_test_utils.wait_for_login(vm[src],
                                                              timeout = 60)
                kvm_test_utils.ping(vlan_ip[dst], flood=True,
                                   interface=ifname[src],
                                   session=session_flood, timeout=10)
                session_flood.close()

            flood_ping(0,1)
            flood_ping(1,0)

            logging.info("Transfering data through nc")
            nc_transfer(0, 1)
            nc_transfer(1, 0)

    finally:
        for vlan in range(1, vlan_num+1):
            rem_vlan(session[0], vlan, ifname[0])
            rem_vlan(session[1], vlan, ifname[1])
            logging.info("rem vlan: %s" % vlan)

    # Plumb/unplumb maximal unber of vlan interfaces
    i = 1
    s = 0
    try:
        logging.info("Testing the plumb of vlan interface")
        for i in range (1, maximal+1):
            add_vlan(session[0], i, ifname[0])
    finally:
        for j in range (1, i+1):
            s = s or rem_vlan(session[0], j, ifname[0])
        if s == 0:
            logging.info("maximal interface plumb test done")
        else:
            logging.error("maximal interface plumb test failed")

    session[0].close()
    session[1].close()
def run_timedrift_with_stop(test, params, env):
    """
    Time drift test with stop/continue the guest:

    1) Log into a guest.
    2) Take a time reading from the guest and host.
    3) Stop the running of the guest
    4) Sleep for a while
    5) Continue the guest running
    6) Take a second time reading.
    7) If the drift (in seconds) is higher than a user specified value, fail.

    @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))
    sleep_time = int(params.get("sleep_time", 30))
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    session = kvm_test_utils.wait_for_login(vm, timeout=login_timeout)

    # Collect test parameters:
    # Command to run to get the current time
    time_command = params.get("time_command")
    # Filter which should match a string to be passed to time.strptime()
    time_filter_re = params.get("time_filter_re")
    # Time format for time.strptime()
    time_format = params.get("time_format")
    drift_threshold = float(params.get("drift_threshold", "10"))
    drift_threshold_single = float(params.get("drift_threshold_single", "3"))
    stop_iterations = int(params.get("stop_iterations", 1))
    stop_time = int(params.get("stop_time", 60))

    try:
        # Get initial time
        # (ht stands for host time, gt stands for guest time)
        (ht0, gt0) = kvm_test_utils.get_time(session, time_command,
                                             time_filter_re, time_format)

        # Stop the guest
        for i in range(stop_iterations):
            # Get time before current iteration
            (ht0_, gt0_) = kvm_test_utils.get_time(session, time_command,
                                                   time_filter_re, time_format)
            # Run current iteration
            logging.info("Stop %s second: iteration %d of %d..." %
                         (stop_time, i + 1, stop_iterations))

            vm.monitor.cmd("stop")
            time.sleep(stop_time)
            vm.monitor.cmd("cont")

            # Sleep for a while to wait the interrupt to be reinjected
            logging.info("Waiting for the interrupt to be reinjected ...")
            time.sleep(sleep_time)

            # Get time after current iteration
            (ht1_, gt1_) = kvm_test_utils.get_time(session, time_command,
                                                   time_filter_re, time_format)
            # Report iteration results
            host_delta = ht1_ - ht0_
            guest_delta = gt1_ - gt0_
            drift = abs(host_delta - guest_delta)
            logging.info("Host duration (iteration %d): %.2f" %
                         (i + 1, host_delta))
            logging.info("Guest duration (iteration %d): %.2f" %
                         (i + 1, guest_delta))
            logging.info("Drift at iteration %d: %.2f seconds" %
                         (i + 1, drift))
            # Fail if necessary
            if drift > drift_threshold_single:
                raise error.TestFail("Time drift too large at iteration %d: "
                                     "%.2f seconds" % (i + 1, drift))

        # Get final time
        (ht1, gt1) = kvm_test_utils.get_time(session, time_command,
                                             time_filter_re, time_format)

    finally:
        if session:
            session.close()

    # Report results
    host_delta = ht1 - ht0
    guest_delta = gt1 - gt0
    drift = abs(host_delta - guest_delta)
    logging.info("Host duration (%d stops): %.2f" %
                 (stop_iterations, host_delta))
    logging.info("Guest duration (%d stops): %.2f" %
                 (stop_iterations, guest_delta))
    logging.info("Drift after %d stops: %.2f seconds" %
                 (stop_iterations, drift))

    # Fail if necessary
    if drift > drift_threshold:
        raise error.TestFail("Time drift too large after %d stops: "
                             "%.2f seconds" % (stop_iterations, drift))
示例#30
0
                if vm.process.is_alive():
                    logging.debug("VM is alive, try to re-login")
                    try:
                        session = kvm_test_utils.wait_for_login(vm, 0, 10, 0, 2)
                    except:
                        logging.debug("Could not re-login, reboot the guest")
                        session = kvm_test_utils.reboot(vm, session,
                                                        method = "system_reset")
                else:
                    raise error.TestFail("VM has quit abnormally during %s",
                                         (op, operand))


    login_timeout = float(params.get("login_timeout", 240))
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    session = kvm_test_utils.wait_for_login(vm, 0, login_timeout, 0, 2)

    try:
        ports = {}
        r = random.SystemRandom()

        logging.info("Enumerate guest devices through /proc/ioports")
        ioports = session.cmd_output("cat /proc/ioports")
        logging.debug(ioports)
        devices = re.findall("(\w+)-(\w+)\ : (.*)", ioports)

        skip_devices = params.get("skip_devices","")
        fuzz_count = int(params.get("fuzz_count", 10))

        for (beg, end, name) in devices:
            ports[(int(beg, base=16), int(end, base=16))] = name.strip()
示例#31
0
def run_jumbo(test, params, env):
    """
    Test the RX jumbo frame function of vnics:

    1) Boot the VM.
    2) Change the MTU of guest nics and host taps depending on the NIC model.
    3) Add the static ARP entry for guest NIC.
    4) Wait for the MTU ok.
    5) Verify the path MTU using ping.
    6) Ping the guest with large frames.
    7) Increment size ping.
    8) Flood ping the guest with large frames.
    9) Verify the path MTU.
    10) Recover the MTU.

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

    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    session = kvm_test_utils.wait_for_login(vm)
    mtu = params.get("mtu", "1500")
    flood_time = params.get("flood_time", "300")
    max_icmp_pkt_size = int(mtu) - 28

    ifname = vm.get_ifname(0)
    ip = vm.get_address(0)
    if ip is None:
        raise error.TestError("Could not get the IP address")

    try:
        # Environment preparation
        ethname = kvm_test_utils.get_linux_ifname(session, vm.get_mac_address(0))

        logging.info("Changing the MTU of guest ...")
        guest_mtu_cmd = "ifconfig %s mtu %s" % (ethname , mtu)
        session.cmd(guest_mtu_cmd)

        logging.info("Chaning the MTU of host tap ...")
        host_mtu_cmd = "ifconfig %s mtu %s" % (ifname, mtu)
        utils.run(host_mtu_cmd)

        logging.info("Add a temporary static ARP entry ...")
        arp_add_cmd = "arp -s %s %s -i %s" % (ip, vm.get_mac_address(0), ifname)
        utils.run(arp_add_cmd)

        def is_mtu_ok():
            s, o = kvm_test_utils.ping(ip, 1, interface=ifname,
                                       packetsize=max_icmp_pkt_size,
                                       hint="do", timeout=2)
            return s == 0

        def verify_mtu():
            logging.info("Verify the path MTU")
            s, o = kvm_test_utils.ping(ip, 10, interface=ifname,
                                       packetsize=max_icmp_pkt_size,
                                       hint="do", timeout=15)
            if s != 0 :
                logging.error(o)
                raise error.TestFail("Path MTU is not as expected")
            if kvm_test_utils.get_loss_ratio(o) != 0:
                logging.error(o)
                raise error.TestFail("Packet loss ratio during MTU "
                                     "verification is not zero")

        def flood_ping():
            logging.info("Flood with large frames")
            kvm_test_utils.ping(ip, interface=ifname,
                                packetsize=max_icmp_pkt_size,
                                flood=True, timeout=float(flood_time))

        def large_frame_ping(count=100):
            logging.info("Large frame ping")
            s, o = kvm_test_utils.ping(ip, count, interface=ifname,
                                       packetsize=max_icmp_pkt_size,
                                       timeout=float(count) * 2)
            ratio = kvm_test_utils.get_loss_ratio(o)
            if ratio != 0:
                raise error.TestFail("Loss ratio of large frame ping is %s" %
                                     ratio)

        def size_increase_ping(step=random.randrange(90, 110)):
            logging.info("Size increase ping")
            for size in range(0, max_icmp_pkt_size + 1, step):
                logging.info("Ping %s with size %s" % (ip, size))
                s, o = kvm_test_utils.ping(ip, 1, interface=ifname,
                                           packetsize=size,
                                           hint="do", timeout=1)
                if s != 0:
                    s, o = kvm_test_utils.ping(ip, 10, interface=ifname,
                                               packetsize=size,
                                               adaptive=True, hint="do",
                                               timeout=20)

                    if kvm_test_utils.get_loss_ratio(o) > int(params.get(
                                                      "fail_ratio", 50)):
                        raise error.TestFail("Ping loss ratio is greater "
                                             "than 50% for size %s" % size)

        logging.info("Waiting for the MTU to be OK")
        wait_mtu_ok = 10
        if not kvm_utils.wait_for(is_mtu_ok, wait_mtu_ok, 0, 1):
            logging.debug(commands.getoutput("ifconfig -a"))
            raise error.TestError("MTU is not as expected even after %s "
                                  "seconds" % wait_mtu_ok)

        # Functional Test
        verify_mtu()
        large_frame_ping()
        size_increase_ping()

        # Stress test
        flood_ping()
        verify_mtu()

    finally:
        # Environment clean
        session.close()
        logging.info("Removing the temporary ARP entry")
        utils.run("arp -d %s -i %s" % (ip, ifname))
def run_nicdriver_unload(test, params, env):
    """
    Test nic driver.

    1) Boot a VM.
    2) Get the NIC driver name.
    3) Repeatedly unload/load NIC driver.
    4) Multi-session TCP transfer on test interface.
    5) Check whether the test interface should still work.

    @param test: KVM test object.
    @param params: Dictionary with the test parameters.
    @param env: Dictionary with test environment.
    """
    timeout = int(params.get("login_timeout", 360))
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    session = kvm_test_utils.wait_for_login(vm, timeout=timeout)
    session_serial = kvm_test_utils.wait_for_login(vm, 0, timeout, 0, 2,
                                                   serial=True)

    ethname = kvm_test_utils.get_linux_ifname(session, vm.get_mac_address(0))
    sys_path = "/sys/class/net/%s/device/driver" % (ethname)
    o = session.cmd("readlink -e %s" % sys_path)
    driver = os.path.basename(o.strip())
    logging.info("driver is %s", driver)

    class ThreadScp(threading.Thread):
        def run(self):
            remote_file = '/tmp/' + self.getName()
            file_list.append(remote_file)
            ret = vm.copy_files_to(file_name, remote_file, timeout=scp_timeout)
            if ret:
                logging.debug("File %s was transfered successfuly", remote_file)
            else:
                logging.debug("Failed to transfer file %s", remote_file)

    def compare(origin_file, receive_file):
        check_sum1 = utils.hash_file(origin_file, method="md5")
        output2 = session.cmd("md5sum %s" % receive_file)
        check_sum2 = output2.strip().split()[0]
        logging.debug("original file md5: %s, received file md5: %s",
                      check_sum1, check_sum2)
        if check_sum1 != check_sum2:
            logging.error("MD5 hash of origin and received files doesn't match")
            return False
        return True

    #produce sized file in host
    file_size = params.get("file_size")
    file_name = "/tmp/nicdriver_unload_file"
    cmd = "dd if=/dev/urandom of=%s bs=%sM count=1"
    utils.system(cmd % (file_name, file_size))

    file_list = []
    connect_time = params.get("connect_time")
    scp_timeout = int(params.get("scp_timeout"))
    thread_num = int(params.get("thread_num"))
    unload_load_cmd = ("sleep %s && ifconfig %s down && modprobe -r %s && "
                       "sleep 1 && modprobe %s && sleep 4 && ifconfig %s up" %
                       (connect_time, ethname, driver, driver, ethname))
    pid = os.fork()
    if pid != 0:
        logging.info("Unload/load NIC driver repeatedly in guest...")
        while True:
            logging.debug("Try to unload/load nic drive once")
            try:
                session_serial.cmd(unload_load_cmd, timeout=120)
            except:
                session.cmd_output("rm -rf /tmp/Thread-*")
                raise
            pid, s = os.waitpid(pid, os.WNOHANG)
            status = os.WEXITSTATUS(s)
            if (pid, status) != (0, 0):
                logging.debug("Child process ending")
                break
    else:
        logging.info("Multi-session TCP data transfer")
        threads = []
        for i in range(thread_num):
            t = ThreadScp()
            t.start()
            threads.append(t)
        for t in threads:
            t.join(timeout = scp_timeout)
        os._exit(0)


    try:
        logging.info("Check MD5 hash for received files in multi-session")
        for f in file_list:
            if not compare(file_name, f):
                raise error.TestFail("Fail to compare (guest) file %s" % f)

        logging.info("Test nic function after load/unload")
        if not vm.copy_files_to(file_name, file_name):
            raise error.TestFail("Fail to copy file from host to guest")
        if not compare(file_name, file_name):
            raise error.TestFail("Test nic function after load/unload fail")

    finally:
        session.cmd_output("rm -rf /tmp/Thread-*")
        session.close()