Example #1
0
    def __init__(self, name, params, root_dir, address_cache):
        """
        Initialize the object and set a few attributes.

        @param name: The name of the object
        @param params: A dict containing VM params
                (see method make_qemu_command for a full description)
        @param root_dir: Base directory for relative filenames
        @param address_cache: A dict that maps MAC addresses to IP addresses
        """
        self.process = None
        self.serial_console = None
        self.redirs = {}
        self.vnc_port = 5900
        self.monitors = []
        self.pci_assignable = None
        self.netdev_id = []
        self.uuid = None

        self.name = name
        self.params = params
        self.root_dir = root_dir
        self.address_cache = address_cache

        # Find a unique identifier for this VM
        while True:
            self.instance = (time.strftime("%Y%m%d-%H%M%S-") +
                             kvm_utils.generate_random_string(4))
            if not glob.glob("/tmp/*%s" % self.instance):
                break
Example #2
0
    def __init__(self, name, params, root_dir, address_cache):
        """
        Initialize the object and set a few attributes.

        @param name: The name of the object
        @param params: A dict containing VM params
                (see method make_qemu_command for a full description)
        @param root_dir: Base directory for relative filenames
        @param address_cache: A dict that maps MAC addresses to IP addresses
        """
        self.process = None
        self.redirs = {}
        self.vnc_port = 5900
        self.uuid = None

        self.name = name
        self.params = params
        self.root_dir = root_dir
        self.address_cache = address_cache

        # Find available monitor filename
        while True:
            # The monitor filename should be unique
            self.instance = time.strftime("%Y%m%d-%H%M%S-") + kvm_utils.generate_random_string(4)
            self.monitor_file_name = os.path.join("/tmp", "monitor-" + self.instance)
            if not os.path.exists(self.monitor_file_name):
                break
def _take_screendumps(test, params, env):
    global _screendump_thread_termination_event
    temp_dir = test.debugdir
    if params.get("screendump_temp_dir"):
        temp_dir = kvm_utils.get_path(test.bindir,
                                      params.get("screendump_temp_dir"))
        try:
            os.makedirs(temp_dir)
        except OSError:
            pass
    temp_filename = os.path.join(temp_dir, "scrdump-%s.ppm" %
                                 kvm_utils.generate_random_string(6))
    delay = float(params.get("screendump_delay", 5))
    quality = int(params.get("screendump_quality", 30))

    cache = {}

    while True:
        for vm in env.get_all_vms():
            if not vm.is_alive():
                continue
            try:
                vm.monitor.screendump(temp_filename)
            except kvm_monitor.MonitorError, e:
                logging.warn(e)
                continue
            if not os.path.exists(temp_filename):
                logging.warn("VM '%s' failed to produce a screendump", vm.name)
                continue
            if not ppm_utils.image_verify_ppm_file(temp_filename):
                logging.warn("VM '%s' produced an invalid screendump", vm.name)
                os.unlink(temp_filename)
                continue
            screendump_dir = os.path.join(test.debugdir,
                                          "screendumps_%s" % vm.name)
            try:
                os.makedirs(screendump_dir)
            except OSError:
                pass
            screendump_filename = os.path.join(screendump_dir,
                    "%s_%s.jpg" % (vm.name,
                                   time.strftime("%Y-%m-%d_%H-%M-%S")))
            hash = utils.hash_file(temp_filename)
            if hash in cache:
                try:
                    os.link(cache[hash], screendump_filename)
                except OSError:
                    pass
            else:
                try:
                    image = PIL.Image.open(temp_filename)
                    image.save(screendump_filename, format="JPEG", quality=quality)
                    cache[hash] = screendump_filename
                except NameError:
                    pass
            os.unlink(temp_filename)
        if _screendump_thread_termination_event.isSet():
            _screendump_thread_termination_event = None
            break
        _screendump_thread_termination_event.wait(delay)
Example #4
0
    def copy_files_from(self, remote_path, local_path, nic_index=0, timeout=600):
        """
        Transfer files from the guest.

        @param local_path: Guest path
        @param remote_path: Host path
        @param nic_index: The index of the NIC to connect to.
        @param timeout: Time (seconds) before giving up on doing the remote
                copy.
        """
        username = self.params.get("username", "")
        password = self.params.get("password", "")
        client = self.params.get("file_transfer_client")
        address = self.get_address(nic_index)
        port = self.get_port(int(self.params.get("file_transfer_port")))

        if not address or not port:
            logging.debug("IP address or port unavailable")
            return None

        if client == "scp":
            log_filename = ("scp-%s-%s.log" %
                            (self.name, kvm_utils.generate_random_string(4)))
            return kvm_utils.scp_from_remote(address, port, username, password,
                                             remote_path, local_path,
                                             log_filename, timeout)
        elif client == "rss":
            c = rss_file_transfer.FileDownloadClient(address, port)
            c.download(remote_path, local_path, timeout)
            c.close()
            return True
Example #5
0
    def remote_login(self, nic_index=0, timeout=10):
        """
        Log into the guest via SSH/Telnet/Netcat.
        If timeout expires while waiting for output from the guest (e.g. a
        password prompt or a shell prompt) -- fail.

        @param nic_index: The index of the NIC to connect to.
        @param timeout: Time (seconds) before giving up logging into the
                guest.
        @return: ShellSession object on success and None on failure.
        """
        username = self.params.get("username", "")
        password = self.params.get("password", "")
        prompt = self.params.get("shell_prompt", "[\#\$]")
        linesep = eval("'%s'" % self.params.get("shell_linesep", r"\n"))
        client = self.params.get("shell_client")
        address = self.get_address(nic_index)
        port = self.get_port(int(self.params.get("shell_port")))
        log_filename = ("session-%s-%s.log" %
                        (self.name, kvm_utils.generate_random_string(4)))

        if not address or not port:
            logging.debug("IP address or port unavailable")
            return None

        session = kvm_utils.remote_login(client, address, port, username,
                                         password, prompt, linesep,
                                         log_filename, timeout)

        if session:
            session.set_status_test_command(self.params.get("status_test_"
                                                            "command", ""))
        return session
Example #6
0
    def __init__(self, name, params, qemu_path, image_dir, iso_dir):
        """
        Initialize the object and set a few attributes.

        @param name: The name of the object
        @param params: A dict containing VM params
                (see method make_qemu_command for a full description)
        @param qemu_path: The path of the qemu binary
        @param image_dir: The directory where images reside
        @param iso_dir: The directory where ISOs reside
        """
        self.process = None
        self.redirs = {}
        self.vnc_port = 5900
        self.uuid = None

        self.name = name
        self.params = params
        self.qemu_path = qemu_path
        self.image_dir = image_dir
        self.iso_dir = iso_dir


        # Find available monitor filename
        while True:
            # The monitor filename should be unique
            self.instance = (time.strftime("%Y%m%d-%H%M%S-") +
                             kvm_utils.generate_random_string(4))
            self.monitor_file_name = os.path.join("/tmp",
                                                  "monitor-" + self.instance)
            if not os.path.exists(self.monitor_file_name):
                break
Example #7
0
    def cmd(self, cmd, args=None, timeout=20):
        """
        Send a QMP monitor command and return the response.

        Note: an id is automatically assigned to the command and the response
        is checked for the presence of the same id.

        @param cmd: Command to send
        @param args: A dict containing command arguments, or None
        @param timeout: Time duration to wait for response
        @return: The response received
        @raise MonitorLockError: Raised if the lock cannot be acquired
        @raise MonitorSocketError: Raised if a socket error occurs
        @raise MonitorProtocolError: Raised if no response is received
        @raise QMPCmdError: Raised if the response is an error message
                (the exception's args are (cmd, args, data) where data is the
                error data)
        """
        if not self._acquire_lock(20):
            raise MonitorLockError("Could not acquire exclusive lock to send "
                                   "QMP command '%s'" % cmd)

        try:
            # Read any data that might be available
            self._read_objects()
            # Send command
            id = kvm_utils.generate_random_string(8)
            self._send(json.dumps(self._build_cmd(cmd, args, id)) + "\n")
            # Read response
            r = self._get_response(id, timeout)
            if r is None:
                raise MonitorProtocolError("Received no response to QMP "
                                           "command '%s', or received a "
                                           "response with an incorrect id"
                                           % cmd)
            if "return" in r:
                return r["return"]
            if "error" in r:
                raise QMPCmdError(cmd, args, r["error"])

        finally:
            self._lock.release()
Example #8
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 = env.get_vm(params["main_vm"])
    vm.verify_alive()
    login_timeout = int(params.get("login_timeout", 360))

    session = vm.wait_for_login(timeout=login_timeout)

    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

    host_path = os.path.join(dir_name, "tmp-%s" % kvm_utils.generate_random_string(8))
    host_path2 = host_path + ".2"
    cmd = "dd if=/dev/zero of=%s bs=10M count=%d" % (host_path, count)
    guest_path = tmp_dir + "file_transfer-%s" % kvm_utils.generate_random_string(8)

    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()
            vm.copy_files_to(host_path, guest_path, timeout=transfer_timeout)
            t_end = time.time()
            throughput = filesize / (t_end - t_begin)
            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()
            vm.copy_files_from(guest_path, host_path2, timeout=transfer_timeout)
            t_end = time.time()
            throughput = filesize / (t_end - t_begin)
            logging.info("File transfer guest -> host succeed, " "estimated throughput: %.2fMB/s", throughput)
        else:
            raise error.TestError("Unknown test file transfer mode %s" % transfer_type)

        if utils.hash_file(host_path, method="md5") != utils.hash_file(host_path2, method="md5"):
            raise error.TestFail("File changed after transfer host -> guest " "and guest -> host")

    finally:
        logging.info("Cleaning temp file on guest")
        session.cmd("rm -rf %s" % guest_path)
        logging.info("Cleaning temp files on host")
        try:
            os.remove(host_path)
            os.remove(host_path2)
        except OSError:
            pass
        session.close()
def run_whql_client_install(test, params, env):
    """
    WHQL DTM client installation:
    1) Log into the guest (the client machine) and into a DTM server machine
    2) Stop the DTM client service (wttsvc) on the client machine
    3) Delete the client machine from the server's data store
    4) Rename the client machine (give it a randomly generated name)
    5) Move the client machine into the server's workgroup
    6) Reboot the client machine
    7) Install the DTM client software
    8) Setup auto logon for the user created by the installation
       (normally DTMLLUAdminUser)
    9) Reboot again

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

    # Collect test params
    server_address = params.get("server_address")
    server_shell_port = int(params.get("server_shell_port"))
    server_file_transfer_port = int(params.get("server_file_transfer_port"))
    server_studio_path = params.get("server_studio_path", "%programfiles%\\ "
                                    "Microsoft Driver Test Manager\\Studio")
    server_username = params.get("server_username")
    server_password = params.get("server_password")
    client_username = params.get("client_username")
    client_password = params.get("client_password")
    dsso_delete_machine_binary = params.get("dsso_delete_machine_binary",
                                            "deps/whql_delete_machine_15.exe")
    dsso_delete_machine_binary = kvm_utils.get_path(test.bindir,
                                                    dsso_delete_machine_binary)
    install_timeout = float(params.get("install_timeout", 600))
    install_cmd = params.get("install_cmd")
    wtt_services = params.get("wtt_services")

    # Stop WTT service(s) on client
    for svc in wtt_services.split():
        kvm_test_utils.stop_windows_service(session, svc)

    # Copy dsso_delete_machine_binary to server
    rss_file_transfer.upload(server_address, server_file_transfer_port,
                             dsso_delete_machine_binary, server_studio_path,
                             timeout=60)

    # Open a shell session with server
    server_session = kvm_utils.remote_login("nc", server_address,
                                            server_shell_port, "", "",
                                            session.prompt, session.linesep)
    server_session.set_status_test_command(session.status_test_command)

    # Get server and client information
    cmd = "echo %computername%"
    server_name = server_session.cmd_output(cmd).strip()
    client_name = session.cmd_output(cmd).strip()
    cmd = "wmic computersystem get domain"
    server_workgroup = server_session.cmd_output(cmd).strip()
    server_workgroup = server_workgroup.splitlines()[-1]
    regkey = r"HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
    cmd = "reg query %s /v Domain" % regkey
    o = server_session.cmd_output(cmd).strip().splitlines()[-1]
    try:
        server_dns_suffix = o.split(None, 2)[2]
    except IndexError:
        server_dns_suffix = ""

    # Delete the client machine from the server's data store (if it's there)
    server_session.cmd("cd %s" % server_studio_path)
    cmd = "%s %s %s" % (os.path.basename(dsso_delete_machine_binary),
                        server_name, client_name)
    server_session.cmd(cmd, print_func=logging.info)
    server_session.close()

    # Rename the client machine
    client_name = "autotest_%s" % kvm_utils.generate_random_string(4)
    logging.info("Renaming client machine to '%s'", client_name)
    cmd = ('wmic computersystem where name="%%computername%%" rename name="%s"'
           % client_name)
    session.cmd(cmd, timeout=600)

    # Join the server's workgroup
    logging.info("Joining workgroup '%s'", server_workgroup)
    cmd = ('wmic computersystem where name="%%computername%%" call '
           'joindomainorworkgroup name="%s"' % server_workgroup)
    session.cmd(cmd, timeout=600)

    # Set the client machine's DNS suffix
    logging.info("Setting DNS suffix to '%s'", server_dns_suffix)
    cmd = 'reg add %s /v Domain /d "%s" /f' % (regkey, server_dns_suffix)
    session.cmd(cmd, timeout=300)

    # Reboot
    session = vm.reboot(session)

    # Access shared resources on the server machine
    logging.info("Attempting to access remote share on server")
    cmd = r"net use \\%s /user:%s %s" % (server_name, server_username,
                                         server_password)
    end_time = time.time() + 120
    while time.time() < end_time:
        try:
            session.cmd(cmd)
            break
        except:
            pass
        time.sleep(5)
    else:
        raise error.TestError("Could not access server share from client "
                              "machine")

    # Install
    logging.info("Installing DTM client (timeout=%ds)", install_timeout)
    install_cmd = r"cmd /c \\%s\%s" % (server_name, install_cmd.lstrip("\\"))
    session.cmd(install_cmd, timeout=install_timeout)

    # Setup auto logon
    logging.info("Setting up auto logon for user '%s'", client_username)
    cmd = ('reg add '
           '"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\winlogon" '
           '/v "%s" /d "%s" /t REG_SZ /f')
    session.cmd(cmd % ("AutoAdminLogon", "1"))
    session.cmd(cmd % ("DefaultUserName", client_username))
    session.cmd(cmd % ("DefaultPassword", client_password))

    # Reboot one more time
    session = vm.reboot(session)
    session.close()
def run_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) Transfer file from host to guest.
    4) Repeatedly migrate VM and wait until transfer's finished.
    5) Transfer file from guest back to host.
    6) Repeatedly migrate VM and wait until transfer's finished.

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

    mig_timeout = float(params.get("mig_timeout", "3600"))
    mig_protocol = params.get("migration_protocol", "tcp")
    mig_cancel_delay = int(params.get("mig_cancel") == "yes") * 2

    host_path = "/tmp/file-%s" % kvm_utils.generate_random_string(6)
    host_path_returned = "%s-returned" % host_path
    guest_path = params.get("guest_path", "/tmp/file")
    file_size = params.get("file_size", "500")
    transfer_timeout = int(params.get("transfer_timeout", "240"))

    try:
        utils.run("dd if=/dev/urandom of=%s bs=1M count=%s" %
                  (host_path, file_size))

        def run_and_migrate(bg):
            bg.start()
            try:
                while bg.isAlive():
                    logging.info(
                        "File transfer not ended, starting a round of "
                        "migration...")
                    vm.migrate(mig_timeout, mig_protocol, mig_cancel_delay)
            except:
                # If something bad happened in the main thread, ignore
                # exceptions raised in the background thread
                bg.join(suppress_exception=True)
                raise
            else:
                bg.join()

        error.context("transferring file to guest while migrating",
                      logging.info)
        bg = kvm_utils.Thread(vm.copy_files_to, (host_path, guest_path),
                              dict(verbose=True, timeout=transfer_timeout))
        run_and_migrate(bg)

        error.context("transferring file back to host while migrating",
                      logging.info)
        bg = kvm_utils.Thread(vm.copy_files_from,
                              (guest_path, host_path_returned),
                              dict(verbose=True, timeout=transfer_timeout))
        run_and_migrate(bg)

        # Make sure the returned file is identical to the original one
        error.context("comparing hashes", logging.info)
        orig_hash = client_utils.hash_file(host_path)
        returned_hash = client_utils.hash_file(host_path_returned)
        if orig_hash != returned_hash:
            raise error.TestFail("Returned file hash (%s) differs from "
                                 "original one (%s)" %
                                 (returned_hash, orig_hash))
        error.context()

    finally:
        session.close()
        if os.path.isfile(host_path):
            os.remove(host_path)
        if os.path.isfile(host_path_returned):
            os.remove(host_path_returned)
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) Transfer file from host to guest.
    4) Repeatedly migrate VM and wait until transfer's finished.
    5) Transfer file from guest back to host.
    6) Repeatedly migrate VM and wait until transfer's finished.

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

    mig_timeout = float(params.get("mig_timeout", "3600"))
    mig_protocol = params.get("migration_protocol", "tcp")
    mig_cancel_delay = int(params.get("mig_cancel") == "yes") * 2

    host_path = "/tmp/file-%s" % kvm_utils.generate_random_string(6)
    host_path_returned = "%s-returned" % host_path
    guest_path = params.get("guest_path", "/tmp/file")
    file_size = params.get("file_size", "500")
    transfer_timeout = int(params.get("transfer_timeout", "240"))

    try:
        utils.run("dd if=/dev/urandom of=%s bs=1M count=%s" % (host_path,
                                                               file_size))

        def run_and_migrate(bg):
            bg.start()
            try:
                while bg.isAlive():
                    logging.info("File transfer not ended, starting a round of "
                                 "migration...")
                    vm.migrate(mig_timeout, mig_protocol, mig_cancel_delay)
            except:
                # If something bad happened in the main thread, ignore
                # exceptions raised in the background thread
                bg.join(suppress_exception=True)
                raise
            else:
                bg.join()

        error.context("transferring file to guest while migrating",
                      logging.info)
        bg = kvm_utils.Thread(vm.copy_files_to, (host_path, guest_path),
                              dict(verbose=True, timeout=transfer_timeout))
        run_and_migrate(bg)

        error.context("transferring file back to host while migrating",
                      logging.info)
        bg = kvm_utils.Thread(vm.copy_files_from,
                              (guest_path, host_path_returned),
                              dict(verbose=True, timeout=transfer_timeout))
        run_and_migrate(bg)

        # Make sure the returned file is identical to the original one
        error.context("comparing hashes", logging.info)
        orig_hash = client_utils.hash_file(host_path)
        returned_hash = client_utils.hash_file(host_path_returned)
        if orig_hash != returned_hash:
            raise error.TestFail("Returned file hash (%s) differs from "
                                 "original one (%s)" % (returned_hash,
                                                        orig_hash))
        error.context()

    finally:
        session.close()
        if os.path.isfile(host_path):
            os.remove(host_path)
        if os.path.isfile(host_path_returned):
            os.remove(host_path_returned)
    def __init__(self, command=None, id=None, auto_close=False, echo=False,
                 linesep="\n"):
        """
        Initialize the class and run command as a child process.

        @param command: Command to run, or None if accessing an already running
                server.
        @param id: ID of an already running server, if accessing a running
                server, or None if starting a new one.
        @param auto_close: If True, close() the instance automatically when its
                reference count drops to zero (default False).
        @param echo: Boolean indicating whether echo should be initially
                enabled for the pseudo terminal running the subprocess.  This
                parameter has an effect only when starting a new server.
        @param linesep: Line separator to be appended to strings sent to the
                child process by sendline().
        """
        self.id = id or kvm_utils.generate_random_string(8)

        # Define filenames for communication with server
        base_dir = "/tmp/kvm_spawn"
        try:
            os.makedirs(base_dir)
        except:
            pass
        (self.shell_pid_filename,
         self.status_filename,
         self.output_filename,
         self.inpipe_filename,
         self.lock_server_running_filename,
         self.lock_client_starting_filename) = _get_filenames(base_dir,
                                                              self.id)

        # Remember some attributes
        self.auto_close = auto_close
        self.echo = echo
        self.linesep = linesep

        # Make sure the 'readers' and 'close_hooks' attributes exist
        if not hasattr(self, "readers"):
            self.readers = []
        if not hasattr(self, "close_hooks"):
            self.close_hooks = []

        # Define the reader filenames
        self.reader_filenames = dict(
            (reader, _get_reader_filename(base_dir, self.id, reader))
            for reader in self.readers)

        # Let the server know a client intends to open some pipes;
        # if the executed command terminates quickly, the server will wait for
        # the client to release the lock before exiting
        lock_client_starting = _lock(self.lock_client_starting_filename)

        # Start the server (which runs the command)
        if command:
            sub = subprocess.Popen("%s %s" % (sys.executable, __file__),
                                   shell=True,
                                   stdin=subprocess.PIPE,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.STDOUT)
            # Send parameters to the server
            sub.stdin.write("%s\n" % self.id)
            sub.stdin.write("%s\n" % echo)
            sub.stdin.write("%s\n" % ",".join(self.readers))
            sub.stdin.write("%s\n" % command)
            # Wait for the server to complete its initialization
            while not "Server %s ready" % self.id in sub.stdout.readline():
                pass

        # Open the reading pipes
        self.reader_fds = {}
        try:
            assert(_locked(self.lock_server_running_filename))
            for reader, filename in self.reader_filenames.items():
                self.reader_fds[reader] = os.open(filename, os.O_RDONLY)
        except:
            pass

        # Allow the server to continue
        _unlock(lock_client_starting)
Example #13
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 = env.get_vm(params["main_vm"])
    vm.verify_alive()
    login_timeout = int(params.get("login_timeout", 360))

    session = vm.wait_for_login(timeout=login_timeout)

    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

    host_path = os.path.join(dir_name,
                             "tmp-%s" % kvm_utils.generate_random_string(8))
    host_path2 = host_path + ".2"
    cmd = "dd if=/dev/zero of=%s bs=10M count=%d" % (host_path, count)
    guest_path = (tmp_dir +
                  "file_transfer-%s" % kvm_utils.generate_random_string(8))

    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()
            vm.copy_files_to(host_path, guest_path, timeout=transfer_timeout)
            t_end = time.time()
            throughput = filesize / (t_end - t_begin)
            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()
            vm.copy_files_from(guest_path,
                               host_path2,
                               timeout=transfer_timeout)
            t_end = time.time()
            throughput = filesize / (t_end - t_begin)
            logging.info(
                "File transfer guest -> host succeed, "
                "estimated throughput: %.2fMB/s", throughput)
        else:
            raise error.TestError("Unknown test file transfer mode %s" %
                                  transfer_type)

        if (utils.hash_file(host_path, method="md5") != utils.hash_file(
                host_path2, method="md5")):
            raise error.TestFail("File changed after transfer host -> guest "
                                 "and guest -> host")

    finally:
        logging.info('Cleaning temp file on guest')
        session.cmd("rm -rf %s" % guest_path)
        logging.info('Cleaning temp files on host')
        try:
            os.remove(host_path)
            os.remove(host_path2)
        except OSError:
            pass
        session.close()
Example #14
0
def _take_screendumps(test, params, env):
    global _screendump_thread_termination_event
    temp_dir = test.debugdir
    if params.get("screendump_temp_dir"):
        temp_dir = kvm_utils.get_path(test.bindir,
                                      params.get("screendump_temp_dir"))
        try:
            os.makedirs(temp_dir)
        except OSError:
            pass
    temp_filename = os.path.join(
        temp_dir, "scrdump-%s.ppm" % kvm_utils.generate_random_string(6))
    delay = float(params.get("screendump_delay", 5))
    quality = int(params.get("screendump_quality", 30))

    cache = {}

    while True:
        for vm in env.get_all_vms():
            if not vm.is_alive():
                continue
            try:
                vm.monitor.screendump(temp_filename)
            except kvm_monitor.MonitorError, e:
                logging.warn(e)
                continue
            if not os.path.exists(temp_filename):
                logging.warn("VM '%s' failed to produce a screendump", vm.name)
                continue
            if not ppm_utils.image_verify_ppm_file(temp_filename):
                logging.warn("VM '%s' produced an invalid screendump", vm.name)
                os.unlink(temp_filename)
                continue
            screendump_dir = os.path.join(test.debugdir,
                                          "screendumps_%s" % vm.name)
            try:
                os.makedirs(screendump_dir)
            except OSError:
                pass
            screendump_filename = os.path.join(
                screendump_dir,
                "%s_%s.jpg" % (vm.name, time.strftime("%Y-%m-%d_%H-%M-%S")))
            hash = utils.hash_file(temp_filename)
            if hash in cache:
                try:
                    os.link(cache[hash], screendump_filename)
                except OSError:
                    pass
            else:
                try:
                    image = PIL.Image.open(temp_filename)
                    image.save(screendump_filename,
                               format="JPEG",
                               quality=quality)
                    cache[hash] = screendump_filename
                except NameError:
                    pass
            os.unlink(temp_filename)
        if _screendump_thread_termination_event.isSet():
            _screendump_thread_termination_event = None
            break
        _screendump_thread_termination_event.wait(delay)
Example #15
0
    def __init__(self, command=None, id=None, auto_close=False, echo=False,
                 linesep="\n"):
        """
        Initialize the class and run command as a child process.

        @param command: Command to run, or None if accessing an already running
                server.
        @param id: ID of an already running server, if accessing a running
                server, or None if starting a new one.
        @param auto_close: If True, close() the instance automatically when its
                reference count drops to zero (default False).
        @param echo: Boolean indicating whether echo should be initially
                enabled for the pseudo terminal running the subprocess.  This
                parameter has an effect only when starting a new server.
        @param linesep: Line separator to be appended to strings sent to the
                child process by sendline().
        """
        self.id = id or kvm_utils.generate_random_string(8)

        # Define filenames for communication with server
        base_dir = "/tmp/kvm_spawn"
        try:
            os.makedirs(base_dir)
        except:
            pass
        (self.shell_pid_filename,
         self.status_filename,
         self.output_filename,
         self.inpipe_filename,
         self.lock_server_running_filename,
         self.lock_client_starting_filename) = _get_filenames(base_dir,
                                                              self.id)

        # Remember some attributes
        self.auto_close = auto_close
        self.echo = echo
        self.linesep = linesep

        # Make sure the 'readers' and 'close_hooks' attributes exist
        if not hasattr(self, "readers"):
            self.readers = []
        if not hasattr(self, "close_hooks"):
            self.close_hooks = []

        # Define the reader filenames
        self.reader_filenames = dict(
            (reader, _get_reader_filename(base_dir, self.id, reader))
            for reader in self.readers)

        # Let the server know a client intends to open some pipes;
        # if the executed command terminates quickly, the server will wait for
        # the client to release the lock before exiting
        lock_client_starting = _lock(self.lock_client_starting_filename)

        # Start the server (which runs the command)
        if command:
            sub = subprocess.Popen("%s %s" % (sys.executable, __file__),
                                   shell=True,
                                   stdin=subprocess.PIPE,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.STDOUT)
            # Send parameters to the server
            sub.stdin.write("%s\n" % self.id)
            sub.stdin.write("%s\n" % echo)
            sub.stdin.write("%s\n" % ",".join(self.readers))
            sub.stdin.write("%s\n" % command)
            # Wait for the server to complete its initialization
            while not "Server %s ready" % self.id in sub.stdout.readline():
                pass

        # Open the reading pipes
        self.reader_fds = {}
        try:
            assert(_locked(self.lock_server_running_filename))
            for reader, filename in self.reader_filenames.items():
                self.reader_fds[reader] = os.open(filename, os.O_RDONLY)
        except:
            pass

        # Allow the server to continue
        _unlock(lock_client_starting)