@@ -88,9 +88,9 @@ link_if_not_exist(pwd, qemu_img, 'qemu-img')
# Build and install kvm
# ---------------------
params = {
- "name": "kvm_install",
- "shortname": "kvm_install",
- "type": "kvm_install",
+ "name": "install",
+ "shortname": "install",
+ "type": "install",
"mode": "release",
## Install from a tarball
@@ -1,13 +1,7 @@
import sys, os, time, shelve, random, resource, logging, cPickle
from autotest_lib.client.bin import test
from autotest_lib.client.common_lib import error
-
-
-class test_routine:
- def __init__(self, module_name, routine_name):
- self.module_name = module_name
- self.routine_name = routine_name
- self.routine = None
+import kvm_utils, kvm_preprocessing
def dump_env(obj, filename):
@@ -41,29 +35,11 @@ class kvm(test.test):
"""
version = 1
def initialize(self):
- # Define the test routines corresponding to different values
- # of the 'type' field
- self.test_routines = {
- # type module name routine
- "steps": test_routine("kvm_guest_wizard", "run_steps"),
- "stepmaker": test_routine("stepmaker", "run_stepmaker"),
- "boot": test_routine("kvm_tests", "run_boot"),
- "migration": test_routine("kvm_tests", "run_migration"),
- "yum_update": test_routine("kvm_tests", "run_yum_update"),
- "autotest": test_routine("kvm_tests", "run_autotest"),
- "kvm_install": test_routine("kvm_install", "run_kvm_install"),
- "linux_s3": test_routine("kvm_tests", "run_linux_s3"),
- }
-
- # Make it possible to import modules from the test's bindir
+ self.subtest_dir = os.path.join(self.bindir, 'tests')
sys.path.append(self.bindir)
def run_once(self, params):
- import logging
- import kvm_utils
- import kvm_preprocessing
-
# Seed the random number generator
random.seed()
@@ -90,25 +66,17 @@ class kvm(test.test):
try:
# Get the test routine corresponding to the specified test type
type = params.get("type")
- routine_obj = self.test_routines.get(type)
- # If type could not be found in self.test_routines...
- if not routine_obj:
- message = "Unsupported test type: %s" % type
- logging.error(message)
- raise error.TestError(message)
- # If we don't have the test routine yet...
- if not routine_obj.routine:
- # Dynamically import the module
- module = __import__(routine_obj.module_name)
- # Get the needed routine
- routine_name = "module." + routine_obj.routine_name
- routine_obj.routine = eval(routine_name)
-
+ # Load the tests directory (which was turned into a py module)
+ test_module = __import__("tests.%s" % type)
+ # Verify if we have the correspondent source file for it
+ module_path = os.path.join(self.subtest_dir, '%s.py' % type)
+ if not os.path.isfile(module_path):
+ raise error.TestError("No %s.py test file found" % type)
# Preprocess
kvm_preprocessing.preprocess(self, params, env)
dump_env(env, env_filename)
# Run the test function
- routine_obj.routine(self, params, env)
+ eval("test_module.%s.run_%s(self, params, env)" % (type, type))
dump_env(env, env_filename)
except Exception, e:
deleted file mode 100755
@@ -1,338 +0,0 @@
-import time, os, sys, urllib, re, signal, logging, datetime
-from autotest_lib.client.bin import utils, test
-from autotest_lib.client.common_lib import error
-import kvm_utils
-
-
-def load_kvm_modules(module_dir):
- """
- Unload previously loaded kvm modules, then load modules present on any
- sub directory of module_dir. Function will walk through module_dir until
- it finds the modules.
-
- @param module_dir: Directory where the KVM modules are located.
- """
- vendor = "intel"
- if os.system("grep vmx /proc/cpuinfo 1>/dev/null") != 0:
- vendor = "amd"
- logging.debug("Detected CPU vendor as '%s'" %(vendor))
-
- logging.debug("Killing any qemu processes that might be left behind")
- utils.system("pkill qemu", ignore_status=True)
-
- logging.info("Unloading previously loaded KVM modules")
- kvm_utils.unload_module("kvm")
- if utils.module_is_loaded("kvm"):
- message = "Failed to remove old KVM modules"
- logging.error(message)
- raise error.TestError(message)
-
- logging.info("Loading new KVM modules...")
- kvm_module_path = None
- kvm_vendor_module_path = None
- for folder, subdirs, files in os.walk(module_dir):
- if "kvm.ko" in files:
- kvm_module_path = os.path.join(folder, "kvm.ko")
- kvm_vendor_module_path = os.path.join(folder, "kvm-%s.ko" % vendor)
- abort = False
- if not os.path.isfile(kvm_module_path):
- logging.error("Could not find KVM module that was supposed to be"
- " built on the source dir")
- abort = True
- elif not os.path.isfile(kvm_vendor_module_path):
- logging.error("Could not find KVM (%s) module that was supposed to be"
- " built on the source dir", vendor)
- abort = True
- if abort:
- raise error.TestError("Could not load KVM modules.")
- utils.system("/sbin/insmod %s" % kvm_module_path)
- time.sleep(1)
- utils.system("/sbin/insmod %s" % kvm_vendor_module_path)
-
- if not utils.module_is_loaded("kvm"):
- message = "Failed to load the KVM modules built for the test"
- logging.error(message)
- raise error.TestError(message)
-
-
-def create_symlinks(test_bindir, prefix):
- """
- Create symbolic links for the appropriate qemu and qemu-img commands on
- the kvm test bindir.
-
- @param test_bindir: KVM test bindir
- @param prefix: KVM prefix path
- """
- qemu_path = os.path.join(test_bindir, "qemu")
- qemu_img_path = os.path.join(test_bindir, "qemu-img")
- if os.path.lexists(qemu_path):
- os.unlink(qemu_path)
- if os.path.lexists(qemu_img_path):
- os.unlink(qemu_img_path)
- kvm_qemu = os.path.join(prefix, "bin", "qemu-system-x86_64")
- if not os.path.isfile(kvm_qemu):
- raise error.TestError('Invalid qemu path')
- kvm_qemu_img = os.path.join(prefix, "bin", "qemu-img")
- if not os.path.isfile(kvm_qemu_img):
- raise error.TestError('Invalid qemu-img path')
- os.symlink(kvm_qemu, qemu_path)
- os.symlink(kvm_qemu_img, qemu_img_path)
-
-
-class SourceDirInstaller:
- """
- Class that handles building/installing KVM directly from a tarball or
- a single source code dir.
- """
- def __init__(self, test, params):
- """
- Initializes class attributes, and retrieves KVM code.
-
- @param test: kvm test object
- @param params: Dictionary with test arguments
- """
- install_mode = params["mode"]
- srcdir = params.get("srcdir")
- # KVM build prefix
- self.test_bindir = test.bindir
- prefix = os.path.join(test.bindir, 'build')
- self.prefix = os.path.abspath(prefix)
- # Are we going to load modules?
- load_modules = params.get('load_modules')
- if not load_modules:
- self.load_modules = True
- elif load_modules == 'yes':
- self.load_modules = True
- elif load_modules == 'no':
- self.load_modules = False
-
- if install_mode == 'localsrc':
- if not srcdir:
- raise error.TestError("Install from source directory specified"
- "but no source directory provided on the"
- "control file.")
- else:
- self.srcdir = srcdir
- self.repo_type = kvm_utils.check_kvm_source_dir(self.srcdir)
- return
- else:
- srcdir = test.srcdir
- if not os.path.isdir(srcdir):
- os.makedirs(srcdir)
-
- if install_mode == 'release':
- release_tag = params.get("release_tag")
- release_dir = params.get("release_dir")
- logging.info("Installing KVM from release tarball")
- if not release_tag:
- release_tag = kvm_utils.get_latest_kvm_release_tag(release_dir)
- tarball = os.path.join(release_dir, "kvm-%s.tar.gz" % release_tag)
- logging.info("Retrieving release kvm-%s" % release_tag)
- tarball = utils.unmap_url("/", tarball, "/tmp")
-
- elif install_mode == 'snapshot':
- logging.info("Installing KVM from snapshot")
- snapshot_dir = params.get("snapshot_dir")
- if not snapshot_dir:
- raise error.TestError("Snapshot dir not provided")
- snapshot_date = params.get("snapshot_date")
- if not snapshot_date:
- # Take yesterday's snapshot
- d = (datetime.date.today() -
- datetime.timedelta(1)).strftime("%Y%m%d")
- else:
- d = snapshot_date
- tarball = os.path.join(snapshot_dir, "kvm-snapshot-%s.tar.gz" % d)
- logging.info("Retrieving kvm-snapshot-%s" % d)
- tarball = utils.unmap_url("/", tarball, "/tmp")
-
- elif install_mode == 'localtar':
- tarball = params.get("tarball")
- if not tarball:
- raise error.TestError("KVM Tarball install specified but no"
- " tarball provided on control file.")
- logging.info("Installing KVM from a local tarball")
- logging.info("Using tarball %s")
- tarball = utils.unmap_url("/", params.get("tarball"), "/tmp")
-
- os.chdir(srcdir)
- self.srcdir = os.path.join(srcdir, utils.extract_tarball(tarball))
- self.repo_type = kvm_utils.check_kvm_source_dir(self.srcdir)
-
-
- def __build(self):
- os.chdir(self.srcdir)
- cfg = "./configure --prefix=%s" % self.prefix
- if self.repo_type == 1:
- steps = [cfg, "make clean", "make -j %s" % utils.count_cpus()]
- if not os.path.exists('qemu/pc-bios/bios.bin'):
- steps.append("make -C bios")
- steps.append("make -C extboot")
- steps.append("cp -f bios/BIOS-bochs-latest"
- " qemu/pc-bios/bios.bin")
- steps.append("cp -f vgabios/VGABIOS-lgpl-latest.bin"
- " qemu/pc-bios/vgabios.bin")
- steps.append("cp -f vgabios/VGABIOS-lgpl-latest.cirrus.bin"
- " qemu/pc-bios/vgabios-cirrus.bin")
- steps.append("cp -f extboot/extboot.bin"
- " qemu/pc-bios/extboot.bin")
- elif self.repo_type == 2:
- steps = [cfg, "make clean", "make -j %s" % utils.count_cpus()]
-
- logging.info("Building KVM")
- for step in steps:
- utils.system(step)
-
-
- def __install(self):
- os.chdir(self.srcdir)
- logging.info("Installing KVM userspace")
- if self.repo_type == 1:
- utils.system("make -C qemu install")
- elif self.repo_type == 2:
- utils.system("make install")
- create_symlinks(self.test_bindir, self.prefix)
-
-
- def __load_modules(self):
- load_kvm_modules(self.srcdir)
-
-
- def install(self):
- self.__build()
- self.__install()
- if self.load_modules:
- self.__load_modules()
-
-
-class GitInstaller:
- def __init__(self, test, params):
- """
- Initialize class parameters and retrieves code from git repositories.
-
- @param test: kvm test object.
- @param params: Dictionary with test parameters.
- """
- install_mode = params["mode"]
- srcdir = params.get("srcdir", test.bindir)
- if not srcdir:
- os.makedirs(srcdir)
- self.srcdir = srcdir
- # KVM build prefix
- self.test_bindir = test.bindir
- prefix = os.path.join(test.bindir, 'build')
- self.prefix = os.path.abspath(prefix)
- # Are we going to load modules?
- load_modules = params.get('load_modules')
- if not load_modules:
- self.load_modules = True
- elif load_modules == 'yes':
- self.load_modules = True
- elif load_modules == 'no':
- self.load_modules = False
-
- kernel_repo = params.get("git_repo")
- user_repo = params.get("user_git_repo")
- kmod_repo = params.get("kmod_repo")
-
- branch = params.get("git_branch", "master")
- lbranch = params.get("lbranch")
-
- tag = params.get("git_tag", "HEAD")
- user_tag = params.get("user_git_tag", "HEAD")
- kmod_tag = params.get("kmod_git_tag", "HEAD")
-
- if not kernel_repo:
- message = "KVM git repository path not specified"
- logging.error(message)
- raise error.TestError(message)
- if not user_repo:
- message = "KVM user git repository path not specified"
- logging.error(message)
- raise error.TestError(message)
-
- kernel_srcdir = os.path.join(srcdir, "kvm")
- kvm_utils.get_git_branch(kernel_repo, branch, kernel_srcdir, tag,
- lbranch)
- self.kernel_srcdir = kernel_srcdir
-
- userspace_srcdir = os.path.join(srcdir, "kvm_userspace")
- kvm_utils.get_git_branch(user_repo, branch, userspace_srcdir, user_tag,
- lbranch)
- self.userspace_srcdir = userspace_srcdir
-
- if kmod_repo:
- kmod_srcdir = os.path.join (srcdir, "kvm_kmod")
- kvm_utils.get_git_branch(kmod_repo, branch, kmod_srcdir, user_tag,
- lbranch)
- self.kmod_srcdir = kmod_srcdir
-
-
- def __build(self):
- if self.kmod_srcdir:
- logging.info('Building KVM modules')
- os.chdir(self.kmod_srcdir)
- utils.system('./configure')
- utils.system('make clean')
- utils.system('make sync LINUX=%s' % self.kernel_srcdir)
- utils.system('make -j %s' % utils.count_cpus())
- logging.info('Building KVM userspace code')
- os.chdir(self.userspace_srcdir)
- utils.system('./configure --prefix=%s' % self.prefix)
- utils.system('make clean')
- utils.system('make -j %s' % utils.count_cpus())
- else:
- os.chdir(self.userspace_srcdir)
- utils.system('./configure --prefix=%s' % self.prefix)
- logging.info('Building KVM modules')
- utils.system('make clean')
- utils.system('make -C kernel LINUX=%s sync' % self.kernel_srcdir)
- logging.info('Building KVM userspace code')
- utils.system('make -j %s' % utils.count_cpus())
-
-
- def __install(self):
- os.chdir(self.userspace_srcdir)
- utils.system('make install')
- create_symlinks(self.test_bindir, self.prefix)
-
-
- def __load_modules(self):
- if self.kmod_srcdir:
- load_kvm_modules(self.kmod_srcdir)
- else:
- load_kvm_modules(self.userspace_srcdir)
-
-
- def install(self):
- self.__build()
- self.__install()
- if self.load_modules:
- self.__load_modules()
-
-
-def run_kvm_install(test, params, env):
- """
- Installs KVM using the selected install mode. Most install methods will
- take kvm source code, build it and install it to a given location.
-
- @param test: kvm test object.
- @param params: Dictionary with test parameters.
- @param env: Test environment.
- """
- install_mode = params.get("mode")
- srcdir = params.get("srcdir", test.srcdir)
- params["srcdir"] = srcdir
-
- if install_mode == 'noinstall':
- logging.info("Skipping installation")
- return
- elif install_mode in ['localsrc', 'localtar', 'release', 'snapshot']:
- installer = SourceDirInstaller(test, params)
- elif install_mode == 'git':
- installer = GitInstaller(test, params)
- else:
- raise error.TestError('Invalid or unsupported'
- ' install mode: %s' % install_mode)
-
- installer.install()
deleted file mode 100644
@@ -1,476 +0,0 @@
-import time, os, logging
-from autotest_lib.client.common_lib import utils, error
-import kvm_utils, ppm_utils, scan_results
-
-"""
-KVM test definitions.
-
-@copyright: 2008-2009 Red Hat Inc.
-"""
-
-
-def run_boot(test, params, env):
- """
- KVM reboot test:
- 1) Log into a guest
- 2) Send a reboot command to the guest
- 3) Wait until it's up.
- 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_utils.env_get_vm(env, params.get("main_vm"))
- if not vm:
- raise error.TestError("VM object not found in environment")
- if not vm.is_alive():
- raise error.TestError("VM seems to be dead; Test requires a living VM")
-
- logging.info("Waiting for guest to be up...")
-
- session = kvm_utils.wait_for(vm.ssh_login, 240, 0, 2)
- if not session:
- raise error.TestFail("Could not log into guest")
-
- logging.info("Logged in")
-
- if params.get("reboot") == "yes":
- # Send the VM's reboot command
- session.sendline(vm.get_params().get("cmd_reboot"))
- logging.info("Reboot command sent; waiting for guest to go down...")
-
- if not kvm_utils.wait_for(lambda: not session.is_responsive(),
- 120, 0, 1):
- raise error.TestFail("Guest refuses to go down")
-
- session.close()
-
- logging.info("Guest is down; waiting for it to go up again...")
-
- session = kvm_utils.wait_for(vm.ssh_login, 120, 0, 2)
- if not session:
- raise error.TestFail("Could not log into guest after reboot")
-
- logging.info("Guest is up again")
-
- session.close()
-
-
-def run_migration(test, params, env):
- """
- KVM migration test:
-
- 1) Get two live VMs. One will be the 'source', the other will be the
- 'destination'.
- 2) Verify if the source VM supports migration. If it does, proceed with
- the test
- 3) Send a migration command to the source vm and wait until it's finished.
- 4) Kill off the source vm
- 3) Log into the destination vm after the migration is finished.
- 4) Compare the output of a reference command executed on the source with
- the output of the same command on the destination machine
-
- @param test: kvm test object.
- @param params: Dictionary with test parameters.
- @param env: Dictionary with the test environment.
- """
- src_vm_name = params.get("migration_src")
- vm = kvm_utils.env_get_vm(env, src_vm_name)
- if not vm:
- raise error.TestError("VM '%s' not found in environment" % src_vm_name)
- if not vm.is_alive():
- raise error.TestError("VM '%s' seems to be dead; Test requires a"
- " living VM" % src_vm_name)
-
- dest_vm_name = params.get("migration_dst")
- dest_vm = kvm_utils.env_get_vm(env, dest_vm_name)
- if not dest_vm:
- raise error.TestError("VM '%s' not found in environment" % dest_vm_name)
- if not dest_vm.is_alive():
- raise error.TestError("VM '%s' seems to be dead; Test requires a"
- " living VM" % dest_vm_name)
-
- pre_scrdump_filename = os.path.join(test.debugdir, "migration_pre.ppm")
- post_scrdump_filename = os.path.join(test.debugdir, "migration_post.ppm")
-
- # See if migration is supported
- s, o = vm.send_monitor_cmd("help info")
- if not "info migrate" in o:
- raise error.TestError("Migration is not supported")
-
- # Log into guest and get the output of migration_test_command
- logging.info("Waiting for guest to be up...")
-
- session = kvm_utils.wait_for(vm.ssh_login, 240, 0, 2)
- if not session:
- raise error.TestFail("Could not log into guest")
-
- logging.info("Logged in")
-
- reference_output = session.get_command_output(params.get("migration_test_"
- "command"))
- session.close()
-
- # Define the migration command
- cmd = "migrate -d tcp:localhost:%d" % dest_vm.migration_port
- logging.debug("Migration command: %s" % cmd)
-
- # Migrate
- s, o = vm.send_monitor_cmd(cmd)
- if s:
- logging.error("Migration command failed (command: %r, output: %r)" %
- (cmd, o))
- raise error.TestFail("Migration command failed")
-
- # Define some helper functions
- def mig_finished():
- s, o = vm.send_monitor_cmd("info migrate")
- if s:
- return False
- if "Migration status: active" in o:
- return False
- return True
-
- def mig_succeeded():
- s, o = vm.send_monitor_cmd("info migrate")
- if s == 0 and "Migration status: completed" in o:
- return True
- return False
-
- def mig_failed():
- s, o = vm.send_monitor_cmd("info migrate")
- if s == 0 and "Migration status: failed" in o:
- return True
- return False
-
- # Wait for migration to finish
- if not kvm_utils.wait_for(mig_finished, 90, 2, 2,
- "Waiting for migration to finish..."):
- raise error.TestFail("Timeout elapsed while waiting for migration to"
- "finish")
-
- # Report migration status
- if mig_succeeded():
- logging.info("Migration finished successfully")
- else:
- if mig_failed():
- message = "Migration failed"
- else:
- message = "Migration ended with unknown status"
- raise error.TestFail(message)
-
- # Get 'post' screendump
- dest_vm.send_monitor_cmd("screendump %s" % post_scrdump_filename)
-
- # Get 'pre' screendump
- vm.send_monitor_cmd("screendump %s" % pre_scrdump_filename)
-
- # Kill the source VM
- vm.send_monitor_cmd("quit", block=False)
-
- # Hack: it seems that the first attempt to communicate with the SSH port
- # following migration always fails (or succeeds after a very long time).
- # So just connect to the port once so the following call to ssh_login
- # succeeds.
- dest_vm.is_sshd_running(timeout=0.0)
-
- # Log into guest and get the output of migration_test_command
- logging.info("Logging into guest after migration...")
-
- session = dest_vm.ssh_login()
- if not session:
- raise error.TestFail("Could not log into guest after migration")
-
- logging.info("Logged in after migration")
-
- output = session.get_command_output(params.get("migration_test_command"))
- session.close()
-
- # Compare output to reference output
- if output != reference_output:
- logging.info("Command output before migration differs from command"
- " output after migration")
- logging.info("Command: %s" % params.get("migration_test_command"))
- logging.info("Output before:" +
- kvm_utils.format_str_for_message(reference_output))
- logging.info("Output after:" + kvm_utils.format_str_for_message(output))
- raise error.TestFail("Command produced different output before and"
- " after migration")
-
-
-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_utils.env_get_vm(env, params.get("main_vm"))
- if not vm:
- raise error.TestError("VM object not found in environment")
- if not vm.is_alive():
- raise error.TestError("VM seems to be dead; Test requires a living VM")
-
- logging.info("Logging into guest...")
-
- session = kvm_utils.wait_for(vm.ssh_login, 240, 0, 2)
- if not session:
- raise error.TestFail("Could not log into guest")
-
- logging.info("Logged in")
-
- # Collect some info
- 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_utils.run_bg(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_utils.run_bg(cmd % (os.path.join(test.bindir, "autotest", "tests"),
- tarred_test_path, test_name), timeout=30)
-
- # Check if we need to copy autotest.tar.bz2
- copy = False
- output = session.get_command_output("ls -l autotest.tar.bz2")
- if "such file" in output:
- copy = True
- else:
- size = int(output.split()[4])
- if size != os.path.getsize(tarred_autotest_path):
- copy = True
- # Perform the copy
- if copy:
- logging.info("Copying autotest.tar.bz2 to guest"
- " (file is missing or has a different size)...")
- if not vm.scp_to_remote(tarred_autotest_path, ""):
- raise error.TestFail("Could not copy autotest.tar.bz2 to guest")
-
- # Check if we need to copy <test_name>.tar.bz2
- copy = False
- output = session.get_command_output("ls -l %s.tar.bz2" % test_name)
- if "such file" in output:
- copy = True
- else:
- size = int(output.split()[4])
- if size != os.path.getsize(tarred_test_path):
- copy = True
- # Perform the copy
- if copy:
- logging.info("Copying %s.tar.bz2 to guest (file is missing or has a"
- " different size)..." % test_name)
- if not vm.scp_to_remote(tarred_test_path, ""):
- raise error.TestFail("Could not copy %s.tar.bz2 to guest" %
- test_name)
-
- # Extract autotest.tar.bz2
- logging.info("Extracting autotest.tar.bz2...")
- status = session.get_command_status("tar xvfj autotest.tar.bz2")
- if status != 0:
- raise error.TestFail("Could not extract autotest.tar.bz2")
-
- # mkdir autotest/tests
- session.sendline("mkdir autotest/tests")
-
- # Extract <test_name>.tar.bz2 into autotest/tests
- logging.info("Extracting %s.tar.bz2..." % test_name)
- status = session.get_command_status("tar xvfj %s.tar.bz2 -C "
- "autotest/tests" % test_name)
- if status != 0:
- raise error.TestFail("Could not extract %s.tar.bz2" % test_name)
-
- # Cleaning up old remaining results
- session.sendline("rm -rf autotest/results/*")
- # Copying 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.scp_to_remote(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.read_up_to_prompt()
- session.sendline("bin/autotest control")
- logging.info("---------------- Test output ----------------")
- match = session.read_up_to_prompt(timeout=test_timeout,
- print_func=logging.info)[0]
- logging.info("---------------- End of test output ----------------")
- if not match:
- 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")
-
- # Parse test results
- result_list = scan_results.parse_results(output)
-
- # Report test results and check for FAIL/ERROR status
- logging.info("Results (test, status, duration, info):")
- status_error = False
- status_fail = False
- if result_list == []:
- status_fail = True
- message_fail = ("Test '%s' did not produce any recognizable "
- "results" % test_name)
- for result in result_list:
- logging.info(str(result))
- if result[1] == "FAIL":
- status_fail = True
- message_fail = ("Test '%s' ended with FAIL "
- "(info: '%s')" % (result[0], result[3]))
- if result[1] == "ERROR":
- status_error = True
- message_error = ("Test '%s' ended with ERROR "
- "(info: '%s')" % (result[0], result[3]))
- if result[1] == "ABORT":
- status_error = True
- message_error = ("Test '%s' ended with ABORT "
- "(info: '%s')" % (result[0], result[3]))
-
- # 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.scp_from_remote("autotest/results/default/*", guest_results_dir):
- logging.error("Could not copy results back from guest")
-
- # Fail the test if necessary
- if status_fail:
- raise error.TestFail(message_fail)
- elif status_error:
- raise error.TestError(message_error)
-
-
-def internal_yum_update(session, command, prompt, timeout):
- """
- Helper function to perform the yum update test.
-
- @param session: SSH session stablished to the host
- @param command: Command to be sent to the SSH connection
- @param prompt: Machine prompt
- @param timeout: How long to wait until we get an appropriate output from
- the SSH session.
- """
- session.sendline(command)
- end_time = time.time() + timeout
- while time.time() < end_time:
- (match, text) = session.read_until_last_line_matches(
- ["[Ii]s this [Oo][Kk]", prompt], timeout=timeout)
- if match == 0:
- logging.info("Got 'Is this ok'; sending 'y'")
- session.sendline("y")
- elif match == 1:
- logging.info("Got shell prompt")
- return True
- else:
- logging.info("Timeout or process exited")
- return False
-
-
-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_utils.env_get_vm(env, params.get("main_vm"))
- if not vm:
- message = "VM object not found in environment"
- logging.error(message)
- raise error.TestError(message)
- if not vm.is_alive():
- message = "VM seems to be dead; Test requires a living VM"
- logging.error(message)
- raise error.TestError(message)
-
- logging.info("Logging into guest...")
-
- session = kvm_utils.wait_for(vm.ssh_login, 120, 0, 2)
- if not session:
- message = "Could not log into guest"
- logging.error(message)
- raise error.TestFail(message)
-
- logging.info("Logged in")
-
- internal_yum_update(session, "yum update", params.get("ssh_prompt"), 600)
- internal_yum_update(session, "yum update kernel",
- params.get("ssh_prompt"), 600)
-
- session.close()
-
-
-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_utils.env_get_vm(env, params.get("main_vm"))
- if not vm:
- raise error.TestError("VM object not found in environment")
- if not vm.is_alive():
- raise error.TestError("VM seems to be dead; Test requires a living VM")
-
- logging.info("Waiting for guest to be up...")
-
- session = kvm_utils.wait_for(vm.ssh_login, 240, 0, 2)
- if not session:
- raise error.TestFail("Could not log into guest")
-
- logging.info("Logged in")
- 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()
@@ -338,20 +338,3 @@ class StepMaker(stepeditor.StepMakerWindow):
pass
-def run_stepmaker(test, params, env):
- vm = kvm_utils.env_get_vm(env, params.get("main_vm"))
- if not vm:
- raise error.TestError("VM object not found in environment")
- if not vm.is_alive():
- raise error.TestError("VM seems to be dead; Step Maker requires a"
- " living VM")
-
- steps_filename = params.get("steps")
- if not steps_filename:
- raise error.TestError("Steps filename not specified")
- steps_filename = os.path.join(test.bindir, "steps", steps_filename)
- if os.path.exists(steps_filename):
- raise error.TestError("Steps file %s already exists" % steps_filename)
-
- StepMaker(vm, steps_filename, test.debugdir, params)
- gtk.main()
new file mode 100644
new file mode 100644
@@ -0,0 +1,165 @@
+import os, logging
+from autotest_lib.client.common_lib import error
+import kvm_utils, scan_results
+
+
+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_utils.env_get_vm(env, params.get("main_vm"))
+ if not vm:
+ raise error.TestError("VM object not found in environment")
+ if not vm.is_alive():
+ raise error.TestError("VM seems to be dead; Test requires a living VM")
+
+ logging.info("Logging into guest...")
+
+ session = kvm_utils.wait_for(vm.ssh_login, 240, 0, 2)
+ if not session:
+ raise error.TestFail("Could not log into guest")
+
+ logging.info("Logged in")
+
+ # Collect some info
+ 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_utils.run_bg(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_utils.run_bg(cmd % (os.path.join(test.bindir, "autotest", "tests"),
+ tarred_test_path, test_name), timeout=30)
+
+ # Check if we need to copy autotest.tar.bz2
+ copy = False
+ output = session.get_command_output("ls -l autotest.tar.bz2")
+ if "such file" in output:
+ copy = True
+ else:
+ size = int(output.split()[4])
+ if size != os.path.getsize(tarred_autotest_path):
+ copy = True
+ # Perform the copy
+ if copy:
+ logging.info("Copying autotest.tar.bz2 to guest"
+ " (file is missing or has a different size)...")
+ if not vm.scp_to_remote(tarred_autotest_path, ""):
+ raise error.TestFail("Could not copy autotest.tar.bz2 to guest")
+
+ # Check if we need to copy <test_name>.tar.bz2
+ copy = False
+ output = session.get_command_output("ls -l %s.tar.bz2" % test_name)
+ if "such file" in output:
+ copy = True
+ else:
+ size = int(output.split()[4])
+ if size != os.path.getsize(tarred_test_path):
+ copy = True
+ # Perform the copy
+ if copy:
+ logging.info("Copying %s.tar.bz2 to guest (file is missing or has a"
+ " different size)..." % test_name)
+ if not vm.scp_to_remote(tarred_test_path, ""):
+ raise error.TestFail("Could not copy %s.tar.bz2 to guest" %
+ test_name)
+
+ # Extract autotest.tar.bz2
+ logging.info("Extracting autotest.tar.bz2...")
+ status = session.get_command_status("tar xvfj autotest.tar.bz2")
+ if status != 0:
+ raise error.TestFail("Could not extract autotest.tar.bz2")
+
+ # mkdir autotest/tests
+ session.sendline("mkdir autotest/tests")
+
+ # Extract <test_name>.tar.bz2 into autotest/tests
+ logging.info("Extracting %s.tar.bz2..." % test_name)
+ status = session.get_command_status("tar xvfj %s.tar.bz2 -C "
+ "autotest/tests" % test_name)
+ if status != 0:
+ raise error.TestFail("Could not extract %s.tar.bz2" % test_name)
+
+ # Cleaning up old remaining results
+ session.sendline("rm -rf autotest/results/*")
+ # Copying 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.scp_to_remote(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.read_up_to_prompt()
+ session.sendline("bin/autotest control")
+ logging.info("---------------- Test output ----------------")
+ match = session.read_up_to_prompt(timeout=test_timeout,
+ print_func=logging.info)[0]
+ logging.info("---------------- End of test output ----------------")
+ if not match:
+ 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")
+
+ # Parse test results
+ result_list = scan_results.parse_results(output)
+
+ # Report test results and check for FAIL/ERROR status
+ logging.info("Results (test, status, duration, info):")
+ status_error = False
+ status_fail = False
+ if result_list == []:
+ status_fail = True
+ message_fail = ("Test '%s' did not produce any recognizable "
+ "results" % test_name)
+ for result in result_list:
+ logging.info(str(result))
+ if result[1] == "FAIL":
+ status_fail = True
+ message_fail = ("Test '%s' ended with FAIL "
+ "(info: '%s')" % (result[0], result[3]))
+ if result[1] == "ERROR":
+ status_error = True
+ message_error = ("Test '%s' ended with ERROR "
+ "(info: '%s')" % (result[0], result[3]))
+ if result[1] == "ABORT":
+ status_error = True
+ message_error = ("Test '%s' ended with ABORT "
+ "(info: '%s')" % (result[0], result[3]))
+
+ # 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.scp_from_remote("autotest/results/default/*", guest_results_dir):
+ logging.error("Could not copy results back from guest")
+
+ # Fail the test if necessary
+ if status_fail:
+ raise error.TestFail(message_fail)
+ elif status_error:
+ raise error.TestError(message_error)
new file mode 100644
@@ -0,0 +1,50 @@
+import logging
+from autotest_lib.client.common_lib import error
+import kvm_utils
+
+def run_boot(test, params, env):
+ """
+ KVM reboot test:
+ 1) Log into a guest
+ 2) Send a reboot command to the guest
+ 3) Wait until it's up.
+ 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_utils.env_get_vm(env, params.get("main_vm"))
+ if not vm:
+ raise error.TestError("VM object not found in environment")
+ if not vm.is_alive():
+ raise error.TestError("VM seems to be dead; Test requires a living VM")
+
+ logging.info("Waiting for guest to be up...")
+
+ session = kvm_utils.wait_for(vm.ssh_login, 240, 0, 2)
+ if not session:
+ raise error.TestFail("Could not log into guest")
+
+ logging.info("Logged in")
+
+ if params.get("reboot") == "yes":
+ # Send the VM's reboot command
+ session.sendline(vm.get_params().get("cmd_reboot"))
+ logging.info("Reboot command sent; waiting for guest to go down...")
+
+ if not kvm_utils.wait_for(lambda: not session.is_responsive(),
+ 120, 0, 1):
+ raise error.TestFail("Guest refuses to go down")
+
+ session.close()
+
+ logging.info("Guest is down; waiting for it to go up again...")
+
+ session = kvm_utils.wait_for(vm.ssh_login, 120, 0, 2)
+ if not session:
+ raise error.TestFail("Could not log into guest after reboot")
+
+ logging.info("Guest is up again")
+
+ session.close()
new file mode 100755
@@ -0,0 +1,338 @@
+import time, os, sys, urllib, re, signal, logging, datetime
+from autotest_lib.client.bin import utils, test
+from autotest_lib.client.common_lib import error
+import kvm_utils
+
+
+def load_kvm_modules(module_dir):
+ """
+ Unload previously loaded kvm modules, then load modules present on any
+ sub directory of module_dir. Function will walk through module_dir until
+ it finds the modules.
+
+ @param module_dir: Directory where the KVM modules are located.
+ """
+ vendor = "intel"
+ if os.system("grep vmx /proc/cpuinfo 1>/dev/null") != 0:
+ vendor = "amd"
+ logging.debug("Detected CPU vendor as '%s'" %(vendor))
+
+ logging.debug("Killing any qemu processes that might be left behind")
+ utils.system("pkill qemu", ignore_status=True)
+
+ logging.info("Unloading previously loaded KVM modules")
+ kvm_utils.unload_module("kvm")
+ if utils.module_is_loaded("kvm"):
+ message = "Failed to remove old KVM modules"
+ logging.error(message)
+ raise error.TestError(message)
+
+ logging.info("Loading new KVM modules...")
+ kvm_module_path = None
+ kvm_vendor_module_path = None
+ for folder, subdirs, files in os.walk(module_dir):
+ if "kvm.ko" in files:
+ kvm_module_path = os.path.join(folder, "kvm.ko")
+ kvm_vendor_module_path = os.path.join(folder, "kvm-%s.ko" % vendor)
+ abort = False
+ if not os.path.isfile(kvm_module_path):
+ logging.error("Could not find KVM module that was supposed to be"
+ " built on the source dir")
+ abort = True
+ elif not os.path.isfile(kvm_vendor_module_path):
+ logging.error("Could not find KVM (%s) module that was supposed to be"
+ " built on the source dir", vendor)
+ abort = True
+ if abort:
+ raise error.TestError("Could not load KVM modules.")
+ utils.system("/sbin/insmod %s" % kvm_module_path)
+ time.sleep(1)
+ utils.system("/sbin/insmod %s" % kvm_vendor_module_path)
+
+ if not utils.module_is_loaded("kvm"):
+ message = "Failed to load the KVM modules built for the test"
+ logging.error(message)
+ raise error.TestError(message)
+
+
+def create_symlinks(test_bindir, prefix):
+ """
+ Create symbolic links for the appropriate qemu and qemu-img commands on
+ the kvm test bindir.
+
+ @param test_bindir: KVM test bindir
+ @param prefix: KVM prefix path
+ """
+ qemu_path = os.path.join(test_bindir, "qemu")
+ qemu_img_path = os.path.join(test_bindir, "qemu-img")
+ if os.path.lexists(qemu_path):
+ os.unlink(qemu_path)
+ if os.path.lexists(qemu_img_path):
+ os.unlink(qemu_img_path)
+ kvm_qemu = os.path.join(prefix, "bin", "qemu-system-x86_64")
+ if not os.path.isfile(kvm_qemu):
+ raise error.TestError('Invalid qemu path')
+ kvm_qemu_img = os.path.join(prefix, "bin", "qemu-img")
+ if not os.path.isfile(kvm_qemu_img):
+ raise error.TestError('Invalid qemu-img path')
+ os.symlink(kvm_qemu, qemu_path)
+ os.symlink(kvm_qemu_img, qemu_img_path)
+
+
+class SourceDirInstaller:
+ """
+ Class that handles building/installing KVM directly from a tarball or
+ a single source code dir.
+ """
+ def __init__(self, test, params):
+ """
+ Initializes class attributes, and retrieves KVM code.
+
+ @param test: kvm test object
+ @param params: Dictionary with test arguments
+ """
+ install_mode = params["mode"]
+ srcdir = params.get("srcdir")
+ # KVM build prefix
+ self.test_bindir = test.bindir
+ prefix = os.path.join(test.bindir, 'build')
+ self.prefix = os.path.abspath(prefix)
+ # Are we going to load modules?
+ load_modules = params.get('load_modules')
+ if not load_modules:
+ self.load_modules = True
+ elif load_modules == 'yes':
+ self.load_modules = True
+ elif load_modules == 'no':
+ self.load_modules = False
+
+ if install_mode == 'localsrc':
+ if not srcdir:
+ raise error.TestError("Install from source directory specified"
+ "but no source directory provided on the"
+ "control file.")
+ else:
+ self.srcdir = srcdir
+ self.repo_type = kvm_utils.check_kvm_source_dir(self.srcdir)
+ return
+ else:
+ srcdir = test.srcdir
+ if not os.path.isdir(srcdir):
+ os.makedirs(srcdir)
+
+ if install_mode == 'release':
+ release_tag = params.get("release_tag")
+ release_dir = params.get("release_dir")
+ logging.info("Installing KVM from release tarball")
+ if not release_tag:
+ release_tag = kvm_utils.get_latest_kvm_release_tag(release_dir)
+ tarball = os.path.join(release_dir, "kvm-%s.tar.gz" % release_tag)
+ logging.info("Retrieving release kvm-%s" % release_tag)
+ tarball = utils.unmap_url("/", tarball, "/tmp")
+
+ elif install_mode == 'snapshot':
+ logging.info("Installing KVM from snapshot")
+ snapshot_dir = params.get("snapshot_dir")
+ if not snapshot_dir:
+ raise error.TestError("Snapshot dir not provided")
+ snapshot_date = params.get("snapshot_date")
+ if not snapshot_date:
+ # Take yesterday's snapshot
+ d = (datetime.date.today() -
+ datetime.timedelta(1)).strftime("%Y%m%d")
+ else:
+ d = snapshot_date
+ tarball = os.path.join(snapshot_dir, "kvm-snapshot-%s.tar.gz" % d)
+ logging.info("Retrieving kvm-snapshot-%s" % d)
+ tarball = utils.unmap_url("/", tarball, "/tmp")
+
+ elif install_mode == 'localtar':
+ tarball = params.get("tarball")
+ if not tarball:
+ raise error.TestError("KVM Tarball install specified but no"
+ " tarball provided on control file.")
+ logging.info("Installing KVM from a local tarball")
+ logging.info("Using tarball %s")
+ tarball = utils.unmap_url("/", params.get("tarball"), "/tmp")
+
+ os.chdir(srcdir)
+ self.srcdir = os.path.join(srcdir, utils.extract_tarball(tarball))
+ self.repo_type = kvm_utils.check_kvm_source_dir(self.srcdir)
+
+
+ def __build(self):
+ os.chdir(self.srcdir)
+ cfg = "./configure --prefix=%s" % self.prefix
+ if self.repo_type == 1:
+ steps = [cfg, "make clean", "make -j %s" % utils.count_cpus()]
+ if not os.path.exists('qemu/pc-bios/bios.bin'):
+ steps.append("make -C bios")
+ steps.append("make -C extboot")
+ steps.append("cp -f bios/BIOS-bochs-latest"
+ " qemu/pc-bios/bios.bin")
+ steps.append("cp -f vgabios/VGABIOS-lgpl-latest.bin"
+ " qemu/pc-bios/vgabios.bin")
+ steps.append("cp -f vgabios/VGABIOS-lgpl-latest.cirrus.bin"
+ " qemu/pc-bios/vgabios-cirrus.bin")
+ steps.append("cp -f extboot/extboot.bin"
+ " qemu/pc-bios/extboot.bin")
+ elif self.repo_type == 2:
+ steps = [cfg, "make clean", "make -j %s" % utils.count_cpus()]
+
+ logging.info("Building KVM")
+ for step in steps:
+ utils.system(step)
+
+
+ def __install(self):
+ os.chdir(self.srcdir)
+ logging.info("Installing KVM userspace")
+ if self.repo_type == 1:
+ utils.system("make -C qemu install")
+ elif self.repo_type == 2:
+ utils.system("make install")
+ create_symlinks(self.test_bindir, self.prefix)
+
+
+ def __load_modules(self):
+ load_kvm_modules(self.srcdir)
+
+
+ def install(self):
+ self.__build()
+ self.__install()
+ if self.load_modules:
+ self.__load_modules()
+
+
+class GitInstaller:
+ def __init__(self, test, params):
+ """
+ Initialize class parameters and retrieves code from git repositories.
+
+ @param test: kvm test object.
+ @param params: Dictionary with test parameters.
+ """
+ install_mode = params["mode"]
+ srcdir = params.get("srcdir", test.bindir)
+ if not srcdir:
+ os.makedirs(srcdir)
+ self.srcdir = srcdir
+ # KVM build prefix
+ self.test_bindir = test.bindir
+ prefix = os.path.join(test.bindir, 'build')
+ self.prefix = os.path.abspath(prefix)
+ # Are we going to load modules?
+ load_modules = params.get('load_modules')
+ if not load_modules:
+ self.load_modules = True
+ elif load_modules == 'yes':
+ self.load_modules = True
+ elif load_modules == 'no':
+ self.load_modules = False
+
+ kernel_repo = params.get("git_repo")
+ user_repo = params.get("user_git_repo")
+ kmod_repo = params.get("kmod_repo")
+
+ branch = params.get("git_branch", "master")
+ lbranch = params.get("lbranch")
+
+ tag = params.get("git_tag", "HEAD")
+ user_tag = params.get("user_git_tag", "HEAD")
+ kmod_tag = params.get("kmod_git_tag", "HEAD")
+
+ if not kernel_repo:
+ message = "KVM git repository path not specified"
+ logging.error(message)
+ raise error.TestError(message)
+ if not user_repo:
+ message = "KVM user git repository path not specified"
+ logging.error(message)
+ raise error.TestError(message)
+
+ kernel_srcdir = os.path.join(srcdir, "kvm")
+ kvm_utils.get_git_branch(kernel_repo, branch, kernel_srcdir, tag,
+ lbranch)
+ self.kernel_srcdir = kernel_srcdir
+
+ userspace_srcdir = os.path.join(srcdir, "kvm_userspace")
+ kvm_utils.get_git_branch(user_repo, branch, userspace_srcdir, user_tag,
+ lbranch)
+ self.userspace_srcdir = userspace_srcdir
+
+ if kmod_repo:
+ kmod_srcdir = os.path.join (srcdir, "kvm_kmod")
+ kvm_utils.get_git_branch(kmod_repo, branch, kmod_srcdir, user_tag,
+ lbranch)
+ self.kmod_srcdir = kmod_srcdir
+
+
+ def __build(self):
+ if self.kmod_srcdir:
+ logging.info('Building KVM modules')
+ os.chdir(self.kmod_srcdir)
+ utils.system('./configure')
+ utils.system('make clean')
+ utils.system('make sync LINUX=%s' % self.kernel_srcdir)
+ utils.system('make -j %s' % utils.count_cpus())
+ logging.info('Building KVM userspace code')
+ os.chdir(self.userspace_srcdir)
+ utils.system('./configure --prefix=%s' % self.prefix)
+ utils.system('make clean')
+ utils.system('make -j %s' % utils.count_cpus())
+ else:
+ os.chdir(self.userspace_srcdir)
+ utils.system('./configure --prefix=%s' % self.prefix)
+ logging.info('Building KVM modules')
+ utils.system('make clean')
+ utils.system('make -C kernel LINUX=%s sync' % self.kernel_srcdir)
+ logging.info('Building KVM userspace code')
+ utils.system('make -j %s' % utils.count_cpus())
+
+
+ def __install(self):
+ os.chdir(self.userspace_srcdir)
+ utils.system('make install')
+ create_symlinks(self.test_bindir, self.prefix)
+
+
+ def __load_modules(self):
+ if self.kmod_srcdir:
+ load_kvm_modules(self.kmod_srcdir)
+ else:
+ load_kvm_modules(self.userspace_srcdir)
+
+
+ def install(self):
+ self.__build()
+ self.__install()
+ if self.load_modules:
+ self.__load_modules()
+
+
+def run_install(test, params, env):
+ """
+ Installs KVM using the selected install mode. Most install methods will
+ take kvm source code, build it and install it to a given location.
+
+ @param test: kvm test object.
+ @param params: Dictionary with test parameters.
+ @param env: Test environment.
+ """
+ install_mode = params.get("mode")
+ srcdir = params.get("srcdir", test.srcdir)
+ params["srcdir"] = srcdir
+
+ if install_mode == 'noinstall':
+ logging.info("Skipping installation")
+ return
+ elif install_mode in ['localsrc', 'localtar', 'release', 'snapshot']:
+ installer = SourceDirInstaller(test, params)
+ elif install_mode == 'git':
+ installer = GitInstaller(test, params)
+ else:
+ raise error.TestError('Invalid or unsupported'
+ ' install mode: %s' % install_mode)
+
+ installer.install()
new file mode 100644
@@ -0,0 +1,56 @@
+import logging, time
+from autotest_lib.client.common_lib import error
+import kvm_utils
+
+
+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_utils.env_get_vm(env, params.get("main_vm"))
+ if not vm:
+ raise error.TestError("VM object not found in environment")
+ if not vm.is_alive():
+ raise error.TestError("VM seems to be dead; Test requires a living VM")
+
+ logging.info("Waiting for guest to be up...")
+
+ session = kvm_utils.wait_for(vm.ssh_login, 240, 0, 2)
+ if not session:
+ raise error.TestFail("Could not log into guest")
+
+ logging.info("Logged in")
+ 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()
new file mode 100644
@@ -0,0 +1,79 @@
+import logging, os
+from autotest_lib.client.common_lib import error
+import kvm_utils
+
+
+def run_migration(test, params, env):
+ """
+ KVM migration test:
+
+ 1) Get two live VMs. One will be the 'source', the other will be the
+ 'destination'.
+ 2) Verify if the source VM supports migration. If it does, proceed with
+ the test
+ 3) Send a migration command to the source vm and wait until it's finished.
+ 4) Kill off the source vm
+ 3) Log into the destination vm after the migration is finished.
+ 4) Compare the output of a reference command executed on the source with
+ the output of the same command on the destination machine
+
+ @param test: kvm test object.
+ @param params: Dictionary with test parameters.
+ @param env: Dictionary with the test environment.
+ """
+ src_vm_name = params.get("migration_src")
+ vm = kvm_utils.env_get_vm(env, src_vm_name)
+ if not vm:
+ raise error.TestError("VM '%s' not found in environment" % src_vm_name)
+ if not vm.is_alive():
+ raise error.TestError("VM '%s' seems to be dead; Test requires a"
+ " living VM" % src_vm_name)
+
+ dest_vm_name = params.get("migration_dst")
+ dest_vm = kvm_utils.env_get_vm(env, dest_vm_name)
+ if not dest_vm:
+ raise error.TestError("VM '%s' not found in environment" % dest_vm_name)
+ if not dest_vm.is_alive():
+ raise error.TestError("VM '%s' seems to be dead; Test requires a"
+ " living VM" % dest_vm_name)
+
+ pre_scrdump_filename = os.path.join(test.debugdir, "migration_pre.ppm")
+ post_scrdump_filename = os.path.join(test.debugdir, "migration_post.ppm")
+
+ # See if migration is supported
+ s, o = vm.send_monitor_cmd("help info")
+ if not "info migrate" in o:
+ raise error.TestError("Migration is not supported")
+
+ # Log into guest and get the output of migration_test_command
+ logging.info("Waiting for guest to be up...")
+
+ session = kvm_utils.wait_for(vm.ssh_login, 240, 0, 2)
+ if not session:
+ raise error.TestFail("Could not log into guest")
+
+ logging.info("Logged in")
+
+ reference_output = session.get_command_output(params.get("migration_test_"
+ "command"))
+ session.close()
+
+ # Define the migration command
+ cmd = "migrate -d tcp:localhost:%d" % dest_vm.migration_port
+ logging.debug("Migration command: %s" % cmd)
+
+ # Migrate
+ s, o = vm.send_monitor_cmd(cmd)
+ if s:
+ logging.error("Migration command failed (command: %r, output: %r)" %
+ (cmd, o))
+ raise error.TestFail("Migration command failed")
+
+ # Define some helper functions
+ def mig_finished():
+ s, o = vm.send_monitor_cmd("info migrate")
+ if s:
+ return False
+ if "Migration status: active" in o:
+ return False
+ return True
new file mode 100644
@@ -0,0 +1,22 @@
+import os, gtk
+from autotest_lib.client.common_lib import error
+import kvm_utils, stepmaker
+
+
+def run_stepmaker(test, params, env):
+ vm = kvm_utils.env_get_vm(env, params.get("main_vm"))
+ if not vm:
+ raise error.TestError("VM object not found in environment")
+ if not vm.is_alive():
+ raise error.TestError("VM seems to be dead; Step Maker requires a"
+ " living VM")
+
+ steps_filename = params.get("steps")
+ if not steps_filename:
+ raise error.TestError("Steps filename not specified")
+ steps_filename = os.path.join(test.bindir, "steps", steps_filename)
+ if os.path.exists(steps_filename):
+ raise error.TestError("Steps file %s already exists" % steps_filename)
+
+ stepmaker.StepMaker(vm, steps_filename, test.debugdir, params)
+ gtk.main()
new file mode 100644
@@ -0,0 +1,215 @@
+import os, time, md5, re, shutil, logging
+from autotest_lib.client.common_lib import utils, error
+import kvm_utils, ppm_utils
+
+
+def handle_var(vm, params, varname):
+ var = params.get(varname)
+ if not var:
+ return False
+ vm.send_string(var)
+ return True
+
+
+def barrier_2(vm, words, fail_if_stuck_for, stuck_detection_history,
+ output_dir, data_scrdump_filename, current_step_num):
+ if len(words) < 7:
+ logging.error("Bad barrier_2 command line")
+ return False
+
+ cmd, dx, dy, x1, y1, md5sum, timeout = words[:7]
+ dx, dy, x1, y1, timeout = map(int, [dx, dy, x1, y1, timeout])
+
+ # Timeout/5 is the time it took stepmaker to complete this step.
+ # Divide that number by 10 to poll 10 times, just in case
+ # current machine is stronger then the "stepmaker machine".
+ # Limit to 1 (min) and 10 (max) seconds between polls.
+ sleep_duration = float(timeout) / 50.0
+ if sleep_duration < 1.0: sleep_duration = 1.0
+ if sleep_duration > 10.0: sleep_duration = 10.0
+
+ scrdump_filename = os.path.join(output_dir, "scrdump.ppm")
+ cropped_scrdump_filename = os.path.join(output_dir, "cropped_scrdump.ppm")
+ expected_scrdump_filename = os.path.join(output_dir, "scrdump_expected.ppm")
+ expected_cropped_scrdump_filename = os.path.join(output_dir,
+ "cropped_scrdump_expected.ppm")
+ comparison_filename = os.path.join(output_dir, "comparison.ppm")
+
+ end_time = time.time() + timeout
+ end_time_stuck = time.time() + fail_if_stuck_for
+ start_time = time.time()
+
+ prev_whole_image_md5sums = []
+
+ failure_message = None
+
+ # Main loop
+ while True:
+ # Check for timeouts
+ if time.time() > end_time:
+ failure_message = "regular timeout"
+ break
+ if time.time() > end_time_stuck:
+ failure_message = "guest is stuck"
+ break
+
+ # Make sure vm is alive
+ if not vm.is_alive():
+ failure_message = "VM is dead"
+ break
+
+ # Request screendump
+ (status, output) = vm.send_monitor_cmd("screendump %s" %
+ scrdump_filename)
+ if status:
+ logging.error("Could not fetch screendump")
+ continue
+
+ # Make sure image is valid
+ if not ppm_utils.image_verify_ppm_file(scrdump_filename):
+ failure_message = "got invalid screendump"
+ break
+
+ # Read image file
+ (w, h, data) = ppm_utils.image_read_from_ppm_file(scrdump_filename)
+
+ # Compare md5sum of barrier region with the expected md5sum
+ calced_md5sum = ppm_utils.get_region_md5sum(w, h, data, x1, y1, dx, dy,
+ cropped_scrdump_filename)
+ if calced_md5sum == md5sum:
+ return True
+
+ # Compute md5sum of whole image in order to compare it with
+ # previous ones
+ whole_image_md5sum = ppm_utils.image_md5sum(w, h, data)
+ # If md5sum is already in queue...
+ if whole_image_md5sum in prev_whole_image_md5sums:
+ # Remove md5sum from queue
+ prev_whole_image_md5sums.remove(whole_image_md5sum)
+ else:
+ # Extend 'stuck' timeout
+ end_time_stuck = time.time() + fail_if_stuck_for
+ # Insert md5sum at beginning of queue
+ prev_whole_image_md5sums.insert(0, whole_image_md5sum)
+ # Limit queue length to stuck_detection_history
+ prev_whole_image_md5sums = \
+ prev_whole_image_md5sums[:stuck_detection_history]
+
+ # Sleep for a while
+ time.sleep(sleep_duration)
+
+ # Failure
+ message = ("Barrier failed at step %s after %.2f seconds (%s)" %
+ (current_step_num, time.time() - start_time, failure_message))
+
+ # What should we do with this failure?
+ if words[-1] == "optional":
+ logging.info(message)
+ return False
+ else:
+ # Collect information and put it in output_dir
+ if data_scrdump_filename and os.path.exists(data_scrdump_filename):
+ # Read expected screendump image
+ (ew, eh, edata) = \
+ ppm_utils.image_read_from_ppm_file(data_scrdump_filename)
+ # Write it in output_dir
+ ppm_utils.image_write_to_ppm_file(expected_scrdump_filename,
+ ew, eh, edata)
+ # Write the cropped version as well
+ ppm_utils.get_region_md5sum(ew, eh, edata, x1, y1, dx, dy,
+ expected_cropped_scrdump_filename)
+ # Perform comparison
+ (w, h, data) = ppm_utils.image_read_from_ppm_file(scrdump_filename)
+ if w == ew and h == eh:
+ (w, h, data) = ppm_utils.image_comparison(w, h, data, edata)
+ ppm_utils.image_write_to_ppm_file(comparison_filename, w, h,
+ data)
+ # Print error messages and fail the test
+ long_message = message + "\n(see analysis at %s)" % output_dir
+ logging.error(long_message)
+ raise error.TestFail, message
+
+
+def run_steps(test, params, env):
+ """
+ Performs a VM installation using step files.
+
+ @param test: kvm test instance.
+ @param params: Dictionary with test parameters.
+ @param env: Test environment.
+ """
+ vm = kvm_utils.env_get_vm(env, params.get("main_vm"))
+ if not vm:
+ raise error.TestError("VM object not found in environment")
+ if not vm.is_alive():
+ e_msg = "VM seems to be dead. Guestwizard requires a living VM"
+ raise error.TestError(e_msg)
+
+ steps_filename = params.get("steps")
+ if not steps_filename:
+ raise error.TestError("Steps filename not specified")
+ steps_filename = os.path.join(test.bindir, "steps", steps_filename)
+ if not os.path.exists(steps_filename):
+ raise error.TestError("Steps file not found: %s" % steps_filename)
+
+ fail_if_stuck_for = params.get("fail_if_stuck_for")
+ if fail_if_stuck_for:
+ fail_if_stuck_for = float(fail_if_stuck_for)
+ else:
+ fail_if_stuck_for = 1e308
+
+ stuck_detection_history = params.get("stuck_detection_history")
+ if stuck_detection_history:
+ stuck_detection_history = int(stuck_detection_history)
+ else:
+ stuck_detection_history = 2
+
+ sf = open(steps_filename, "r")
+ lines = sf.readlines()
+ sf.close()
+
+ vm.send_monitor_cmd("cont")
+
+ current_step_num = 0
+ current_screendump = None
+ skip_current_step = False
+
+ # Iterate over the lines in the file
+ for line in lines:
+ line = line.strip()
+ if not line:
+ continue
+ logging.info(line)
+
+ if line.startswith("#"):
+ continue
+
+ words = line.split()
+ if words[0] == "step":
+ current_step_num += 1
+ current_screendump = None
+ skip_current_step = False
+ elif words[0] == "screendump":
+ current_screendump = words[1]
+ elif skip_current_step:
+ continue
+ elif words[0] == "sleep":
+ time.sleep(float(words[1]))
+ elif words[0] == "key":
+ vm.send_key(words[1])
+ elif words[0] == "var":
+ if not handle_var(vm, params, words[1]):
+ logging.error("Variable not defined: %s" % words[1])
+ elif words[0] == "barrier_2":
+ if current_screendump:
+ scrdump_filename = (
+ os.path.join(ppm_utils.get_data_dir(steps_filename),
+ current_screendump))
+ else:
+ scrdump_filename = None
+ if not barrier_2(vm, words, fail_if_stuck_for,
+ stuck_detection_history, test.debugdir,
+ scrdump_filename, current_step_num):
+ skip_current_step = True
+ else:
+ vm.send_key(words[0])
new file mode 100644
@@ -0,0 +1,65 @@
+import logging, time
+from autotest_lib.client.common_lib import error
+import kvm_utils
+
+
+def internal_yum_update(session, command, prompt, timeout):
+ """
+ Helper function to perform the yum update test.
+
+ @param session: SSH session stablished to the host
+ @param command: Command to be sent to the SSH connection
+ @param prompt: Machine prompt
+ @param timeout: How long to wait until we get an appropriate output from
+ the SSH session.
+ """
+ session.sendline(command)
+ end_time = time.time() + timeout
+ while time.time() < end_time:
+ (match, text) = session.read_until_last_line_matches(
+ ["[Ii]s this [Oo][Kk]", prompt], timeout=timeout)
+ if match == 0:
+ logging.info("Got 'Is this ok'; sending 'y'")
+ session.sendline("y")
+ elif match == 1:
+ logging.info("Got shell prompt")
+ return True
+ else:
+ logging.info("Timeout or process exited")
+ return False
+
+
+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_utils.env_get_vm(env, params.get("main_vm"))
+ if not vm:
+ message = "VM object not found in environment"
+ logging.error(message)
+ raise error.TestError(message)
+ if not vm.is_alive():
+ message = "VM seems to be dead; Test requires a living VM"
+ logging.error(message)
+ raise error.TestError(message)
+
+ logging.info("Logging into guest...")
+
+ session = kvm_utils.wait_for(vm.ssh_login, 120, 0, 2)
+ if not session:
+ message = "Could not log into guest"
+ logging.error(message)
+ raise error.TestFail(message)
+
+ logging.info("Logged in")
+
+ internal_yum_update(session, "yum update", params.get("ssh_prompt"), 600)
+ internal_yum_update(session, "yum update kernel",
+ params.get("ssh_prompt"), 600)
+
+ session.close()
In order to organize better the kvm functional subtests, move them to a 'tests' subdirectory. In order to add a test, one would need to put a file 'testname.py' on 'tests', implementing a function run_testname() on that file. This way we don't have to 'register' tests on the kvm tests subdirectory, and a predictable name schema for future functional tests. I know I will have to split this into smaller patches, meanwhile this patch shows the work so far. Signed-off-by: Lucas Meneghel Rodrigues <lmr@redhat.com> --- client/tests/kvm/control | 6 +- client/tests/kvm/kvm.py | 50 +--- client/tests/kvm/kvm_install.py | 338 ------------------------ client/tests/kvm/kvm_tests.py | 476 ---------------------------------- client/tests/kvm/stepmaker.py | 17 -- client/tests/kvm/tests/autotest.py | 165 ++++++++++++ client/tests/kvm/tests/boot.py | 50 ++++ client/tests/kvm/tests/install.py | 338 ++++++++++++++++++++++++ client/tests/kvm/tests/linux_s3.py | 56 ++++ client/tests/kvm/tests/migration.py | 79 ++++++ client/tests/kvm/tests/stepmaker.py | 22 ++ client/tests/kvm/tests/steps.py | 215 +++++++++++++++ client/tests/kvm/tests/yum_update.py | 65 +++++ 13 files changed, 1002 insertions(+), 875 deletions(-) delete mode 100755 client/tests/kvm/kvm_install.py delete mode 100644 client/tests/kvm/kvm_tests.py create mode 100644 client/tests/kvm/tests/__init__.py create mode 100644 client/tests/kvm/tests/autotest.py create mode 100644 client/tests/kvm/tests/boot.py create mode 100755 client/tests/kvm/tests/install.py create mode 100644 client/tests/kvm/tests/linux_s3.py create mode 100644 client/tests/kvm/tests/migration.py create mode 100644 client/tests/kvm/tests/stepmaker.py create mode 100644 client/tests/kvm/tests/steps.py create mode 100644 client/tests/kvm/tests/yum_update.py