1 Star 1 Fork 0

smooth/virt-test

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
run 42.36 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979
#!/usr/bin/python
"""
Run virt tests outside the autotest client harness.
:copyright: Red Hat 2012
"""
import os
import sys
import traceback
import signal
import optparse
import logging
class StreamProxy(object):
"""
Mechanism to redirect a stream to a file, allowing the original stream to
be restored later.
"""
def __init__(self, filename='/dev/null', stream=sys.stdout):
"""
Keep 2 streams to write to, and eventually switch.
"""
self.terminal = stream
if filename is None:
self.log = stream
else:
self.log = open(filename, "a")
self.redirect()
def write(self, message):
"""
Write to the current stream.
"""
self.stream.write(message)
def flush(self):
"""
Flush the current stream.
"""
self.stream.flush()
def restore(self):
"""Restore original stream"""
self.stream = self.terminal
def redirect(self):
"""Redirect stream to log file"""
self.stream = self.log
def _silence_stderr():
"""
Points the stderr FD (2) to /dev/null, silencing it.
"""
out_fd = os.open('/dev/null', os.O_WRONLY | os.O_CREAT)
try:
os.dup2(out_fd, 2)
finally:
os.close(out_fd)
sys.stderr = os.fdopen(2, 'w')
def _handle_stdout(options):
"""
Replace stdout with a proxy object.
Depending on self.options.verbose, make proxy print to /dev/null, or
original sys.stdout stream.
"""
if not options.vt_verbose:
_silence_stderr()
# Replace stdout with our proxy pointing to /dev/null
sys.stdout = StreamProxy(filename="/dev/null", stream=sys.stdout)
else:
# Retain full stdout
sys.stdout = StreamProxy(filename=None, stream=sys.stdout)
def _restore_stdout():
"""
Restore stdout. Used to re-enable stdout on error paths.
"""
try:
sys.stdout.restore()
except AttributeError:
pass
def _import_autotest_modules():
"""
Import the autotest modules.
Two methods will be attempted:
1) If $AUTOTEST_PATH is set, import the libraries from an autotest checkout
at $AUTOTEST_PATH.
2) Import the libraries system wide. For this to work, the
autotest-framework package for the given distro must be installed.
"""
autotest_dir = os.environ.get('AUTOTEST_PATH')
if autotest_dir is not None:
autotest_dir = os.path.expanduser(autotest_dir)
autotest_dir = os.path.abspath(autotest_dir)
client_dir = os.path.join(autotest_dir, 'client')
setup_modules_path = os.path.join(client_dir, 'setup_modules.py')
import imp
try:
setup_modules = imp.load_source('autotest_setup_modules',
setup_modules_path)
except:
print "Failed to import autotest modules from $AUTOTEST_PATH"
print "Could not load Python module %s" % (setup_modules_path)
sys.exit(1)
setup_modules.setup(base_path=client_dir,
root_module_name="autotest.client")
try:
from autotest.client import setup_modules
except ImportError:
print "Couldn't import autotest.client module"
if autotest_dir is None:
print("Environment variable $AUTOTEST_PATH not set. "
"please set it to a path containing an autotest checkout")
print("Or install autotest-framework for your distro")
sys.exit(1)
def _find_default_qemu_paths(options_qemu=None, options_dst_qemu=None):
qemu_bin_path = None
from virttest import utils_misc
if options_qemu:
if not os.path.isfile(options_qemu):
raise RuntimeError("Invalid qemu binary provided (%s)" %
options_qemu)
qemu_bin_path = options_qemu
else:
try:
qemu_bin_path = utils_misc.find_command('qemu-kvm')
except ValueError:
qemu_bin_path = utils_misc.find_command('kvm')
if options_dst_qemu is not None:
if not os.path.isfile(options_dst_qemu):
raise RuntimeError("Invalid dst qemu binary provided (%s)" %
options_dst_qemu)
qemu_dst_bin_path = options_dst_qemu
else:
qemu_dst_bin_path = None
qemu_dirname = os.path.dirname(qemu_bin_path)
qemu_img_path = os.path.join(qemu_dirname, 'qemu-img')
qemu_io_path = os.path.join(qemu_dirname, 'qemu-io')
if not os.path.exists(qemu_img_path):
qemu_img_path = utils_misc.find_command('qemu-img')
if not os.path.exists(qemu_io_path):
qemu_io_path = utils_misc.find_command('qemu-io')
return [qemu_bin_path, qemu_img_path, qemu_io_path, qemu_dst_bin_path]
SUPPORTED_LOG_LEVELS = [
"debug", "info", "warning", "error", "critical"]
SUPPORTED_TEST_TYPES = [
'qemu', 'libvirt', 'libguestfs', 'openvswitch', 'v2v', 'lvsb']
SUPPORTED_LIBVIRT_URIS = ['qemu:///system', 'lxc:///', 'esx:///']
SUPPORTED_LIBVIRT_DRIVERS = ['qemu', 'lxc', 'xen', 'esx']
SUPPORTED_IMAGE_TYPES = ['raw', 'qcow2', 'qed', 'vmdk']
SUPPORTED_DISK_BUSES = ['ide', 'scsi', 'virtio_blk', 'virtio_scsi', 'lsi_scsi',
'ahci', 'usb2', 'xenblk']
SUPPORTED_NIC_MODELS = ["virtio_net", "e1000", "rtl8139", "spapr-vlan"]
SUPPORTED_NET_TYPES = ["bridge", "user", "none"]
class VirtTestRunParser(optparse.OptionParser):
def __init__(self):
optparse.OptionParser.__init__(self, usage='Usage: %prog [options]')
from virttest import data_dir
import virttest.defaults
self.default_guest_os = virttest.defaults.DEFAULT_GUEST_OS
try:
qemu_bin_path = _find_default_qemu_paths()[0]
except ValueError:
qemu_bin_path = "Could not find one"
if os.getuid() == 0:
nettype_default = 'bridge'
else:
nettype_default = 'user'
debug = optparse.OptionGroup(self, 'Debug Options')
debug.add_option("-v", "--verbose", action="store_true",
dest="vt_verbose", help=("Exhibit test "
"messages in the console "
"(used for debugging)"))
debug.add_option("--console-level", action="store",
dest="vt_console_level",
default="debug",
help=("Log level of test messages in the console. Only valid "
"with --verbose. "
"Supported levels: " +
", ".join(SUPPORTED_LOG_LEVELS) +
". Default: %default"))
debug.add_option("--show-open-fd", action="store_true",
dest="vt_show_open_fd", help=("Show how many "
"open fds at the end of "
"each test "
"(used for debugging)"))
self.add_option_group(debug)
general = optparse.OptionGroup(self, 'General Options')
general.add_option("-b", "--bootstrap", action="store_true",
dest="vt_bootstrap", help=("Perform test suite setup "
"procedures, such as "
"downloading JeOS and check "
"required programs and "
"libs. Requires -t to be set"))
general.add_option("--update-config", action="store_true",
default=False,
dest="vt_update_config", help=("Forces configuration "
"updates (all manual "
"config file editing "
"will be lost). "
"Requires -t to be set"))
general.add_option("--update-providers", action="store_true",
default=False,
dest="vt_update_providers", help=("Forces test "
"providers to be "
"updated (git repos "
"will be pulled)"))
general.add_option("-t", "--type", action="store", dest="vt_type",
help="Choose test type (%s)" %
", ".join(SUPPORTED_TEST_TYPES))
general.add_option("--connect-uri", action="store", dest="vt_connect_uri",
help="Choose test connect uri for libvirt (E.g: %s)" %
", ".join(SUPPORTED_LIBVIRT_URIS))
general.add_option("-c", "--config", action="store", dest="vt_config",
help=("Explicitly choose a cartesian config. "
"When choosing this, some options will be "
"ignored"))
general.add_option("--no-downloads", action="store_true",
dest="vt_no_downloads", default=False,
help="Do not attempt to download JeOS images")
general.add_option("--selinux-setup", action="store_true",
dest="vt_selinux_setup", default=False,
help="Define default contexts of directory.")
general.add_option("-k", "--keep-image", action="store_true",
dest="vt_keep_image",
help=("Don't restore the JeOS image from pristine "
"at the beginning of the test suite run "
"(faster but unsafe)"))
general.add_option("--keep-image-between-tests",
action="store_true", default=False,
dest="vt_keep_image_between_tests",
help=("Don't restore the JeOS image from pristine "
"between tests (faster but unsafe)"))
general.add_option("-g", "--guest-os", action="store", dest="vt_guest_os",
default=None,
help=("Select the guest OS to be used. "
"If -c is provided, this will be ignored. "
"Default: %s" % self.default_guest_os))
general.add_option("--arch", action="store", dest="vt_arch",
default=None,
help=("Architecture under test. "
"If -c is provided, this will be ignored. "
"Default: any that supports the given machine type"))
general.add_option("--machine-type", action="store", dest="vt_machine_type",
default=None,
help=("Machine type under test. "
"If -c is provided, this will be ignored. "
"Default: all for the chosen guests, %s if "
"--guest-os not given." % virttest.defaults.DEFAULT_MACHINE_TYPE))
general.add_option("--tests", action="store", dest="vt_tests",
default="",
help=('List of space separated tests to be '
'executed. '
'If -c is provided, this will be ignored.'
' - example: --tests "boot reboot shutdown"'))
general.add_option("--list-tests", action="store_true", dest="vt_list_tests",
help="List tests available")
general.add_option("--list-guests", action="store_true",
dest="vt_list_guests",
help="List guests available")
general.add_option("--logs-dir", action="store", dest="vt_log_dir",
help=("Path to the logs directory. "
"Default path: %s" %
os.path.join(data_dir.get_backing_data_dir(),
'logs')))
general.add_option("--data-dir", action="store", dest="vt_data_dir",
help=("Path to a data dir. "
"Default path: %s" %
data_dir.get_backing_data_dir()))
general.add_option("--keep-guest-running", action="store_true",
dest="vt_keep_guest_running", default=False,
help=("Don't shut down guests at the end of each "
"test (faster but unsafe)"))
general.add_option("-m", "--mem", action="store", dest="vt_mem",
default="1024",
help=("RAM dedicated to the main VM. Default:"
"%default"))
general.add_option("--no", action="store", dest="vt_no_filter", default="",
help=("List of space separated no filters to be "
"passed to the config parser. If -c is "
"provided, this will be ignored"))
general.add_option("--type-specific", action="store_true",
dest="vt_type_specific", default=False,
help=("Enable only type specific tests. Shared"
" tests will not be tested."))
general.add_option("--run-dropin", action="store_true", dest="vt_dropin",
default=False,
help=("Run tests present on the drop in dir on the "
"host. Incompatible with --tests."))
general.add_option("--log-level", action="store", dest="vt_log_level",
default="debug",
help=("Set log level for top level log file."
" Supported levels: " +
", ".join(SUPPORTED_LOG_LEVELS) +
". Default: %default"))
general.add_option("--no-cleanup", action="store_true",
dest="vt_no_cleanup",
default=False,
help=("Don't clean up tmp files or VM processes at "
"the end of a virt-test execution (useful "
"for debugging)"))
self.add_option_group(general)
qemu = optparse.OptionGroup(self, 'Options specific to the qemu test')
qemu.add_option("--qemu-bin", action="store", dest="vt_qemu_bin",
default=None,
help=("Path to a custom qemu binary to be tested. "
"If -c is provided and this flag is omitted, "
"no attempt to set the qemu binaries will be made. "
"Default path: %s" % qemu_bin_path))
qemu.add_option("--qemu-dst-bin", action="store", dest="vt_dst_qemu_bin",
default=None,
help=("Path to a custom qemu binary to be tested for "
"the destination of a migration, overrides "
"--qemu-bin. "
"If -c is provided and this flag is omitted, "
"no attempt to set the qemu binaries will be made. "
"Default path: %s" % qemu_bin_path))
qemu.add_option("--use-malloc-perturb", action="store",
dest="vt_malloc_perturb", default="yes",
help=("Use MALLOC_PERTURB_ env variable set to 1 "
"to help catch memory allocation problems on "
"qemu (yes or no). Default: %default"))
qemu.add_option("--accel", action="store", dest="vt_accel", default="kvm",
help=("Accelerator used to run qemu (kvm or tcg). "
"Default: kvm"))
help_msg = "QEMU network option (%s). " % ", ".join(
SUPPORTED_NET_TYPES)
help_msg += "Default: %default"
qemu.add_option("--nettype", action="store", dest="vt_nettype",
default=nettype_default, help=help_msg)
qemu.add_option("--netdst", action="store", dest="vt_netdst",
default="virbr0",
help=("Bridge name to be used "
"(if you chose bridge as nettype). "
"Default: %default"))
qemu.add_option("--vhost", action="store", dest="vt_vhost",
default="off",
help=("Whether to enable vhost for qemu "
"(on/off/force). Depends on nettype=bridge. "
"If -c is provided, this will be ignored. "
"Default: %default"))
qemu.add_option("--monitor", action="store", dest="vt_monitor",
default='human',
help="Monitor type (human or qmp). Default: %default")
qemu.add_option("--smp", action="store", dest="vt_smp",
default='2',
help=("Number of virtual cpus to use. "
"If -c is provided, this will be ignored. "
"Default: %default"))
qemu.add_option("--image-type", action="store", dest="vt_image_type",
default="qcow2",
help=("Image format type to use "
"(any valid qemu format). "
"If -c is provided, this will be ignored. "
"Default: %default"))
qemu.add_option("--nic-model", action="store", dest="vt_nic_model",
default="virtio_net",
help=("Guest network card model. "
"If -c is provided, this will be ignored. "
"(any valid qemu format). Default: %default"))
qemu.add_option("--disk-bus", action="store", dest="vt_disk_bus",
default="virtio_blk",
help=("Guest main image disk bus. One of " +
" ".join(SUPPORTED_DISK_BUSES) +
". If -c is provided, this will be ignored. "
"Default: %default"))
qemu.add_option("--qemu_sandbox", action="store", dest="vt_qemu_sandbox",
default="on",
help=("Enable qemu sandboxing "
"(on/off). Default: %default"))
qemu.add_option("--defconfig", action="store", dest="vt_defconfig",
default="yes",
help=("Prevent qemu from loading sysconfdir/qemu.conf "
"and sysconfdir/target-ARCH.conf at startup. "
"(yes/no). Default: %default"))
self.add_option_group(qemu)
libvirt = optparse.OptionGroup(self, 'Options specific to the libvirt test')
libvirt.add_option("--install", action="store_true", dest="vt_install_guest",
help=("Install the guest using import method before "
"the tests are run."))
libvirt.add_option("--remove", action="store_true", dest="vt_remove_guest",
help=("Remove the guest from libvirt. This will not "
"delete the guest's disk file."))
self.add_option_group(libvirt)
def variant_only_file(filename):
"""
Parse file containing flat list of items to append on an 'only' filter
"""
from virttest import data_dir
result = []
if not os.path.isabs(filename):
fullpath = os.path.realpath(os.path.join(data_dir.get_root_dir(),
filename))
for line in open(fullpath).readlines():
line = line.strip()
if line.startswith('#') or len(line) < 3:
continue
result.append(line)
return ", ".join(result)
QEMU_DEFAULT_SET = "migrate..tcp, migrate..unix, migrate..exec, migrate..fd"
LIBVIRT_DEFAULT_SET = variant_only_file('backends/libvirt/cfg/default_tests')
LVSB_DEFAULT_SET = ("lvsb_date")
OVS_DEFAULT_SET = ("load_module, ovs_basic")
LIBVIRT_INSTALL = "unattended_install.import.import.default_install.aio_native"
LIBVIRT_REMOVE = "remove_guest.without_disk"
class VirtTestApp(object):
"""
Class representing the execution of the virt test runner.
"""
@staticmethod
def system_setup():
"""Set up things that affect the whole process
Initialize things that will affect the whole process, such as
environment variables, setting up Python module paths, or redirecting
stdout and/or stderr.
"""
# workaround for a but in some Autotest versions, that call
# logging.basicConfig() with DEBUG loglevel as soon as the modules
# are imported
logging.basicConfig(loglevel=logging.ERROR)
_import_autotest_modules()
# set English environment
# (command output might be localized, need to be safe)
os.environ['LANG'] = 'en_US.UTF-8'
def __init__(self):
"""
Parses options and initializes attributes.
@attribute option_parser: option parser instance with app options.
@attribute options: options resulted from option parser.
@attribute cartesian_parser: specialized test config parser, it's going
to be set to something useful later.
"""
self.system_setup()
self.option_parser = VirtTestRunParser()
self.options, self.args = self.option_parser.parse_args()
self.cartesian_parser = None
def _process_qemu_bin(self):
"""
Puts the value of the qemu bin option in the cartesian parser command.
"""
if self.options.vt_config and self.options.vt_qemu_bin is None:
logging.info("Config provided and no --qemu-bin set. Not trying "
"to automatically set qemu bin.")
else:
(qemu_bin_path, qemu_img_path, qemu_io_path,
qemu_dst_bin_path) = _find_default_qemu_paths(self.options.vt_qemu_bin,
self.options.vt_dst_qemu_bin)
self.cartesian_parser.assign("qemu_binary", qemu_bin_path)
self.cartesian_parser.assign("qemu_img_binary", qemu_img_path)
self.cartesian_parser.assign("qemu_io_binary", qemu_io_path)
if qemu_dst_bin_path is not None:
self.cartesian_parser.assign("qemu_dst_binary",
qemu_dst_bin_path)
def _process_qemu_img(self):
"""
Puts the value of the qemu bin option in the cartesian parser command.
"""
if self.options.vt_config and self.options.vt_qemu_bin is None:
logging.info("Config provided and no --qemu-bin set. Not trying "
"to automatically set qemu bin.")
else:
(_, qemu_img_path,
_, _) = _find_default_qemu_paths(self.options.vt_qemu_bin,
self.options.vt_dst_qemu_bin)
self.cartesian_parser.assign("qemu_img_binary", qemu_img_path)
def _process_qemu_accel(self):
"""
Puts the value of the qemu bin option in the cartesian parser command.
"""
if self.options.vt_accel == 'tcg':
self.cartesian_parser.assign("disable_kvm", "yes")
def _process_bridge_mode(self):
if self.options.vt_nettype not in SUPPORTED_NET_TYPES:
_restore_stdout()
print("Invalid --nettype option '%s'. Valid options are: (%s)" %
(self.options.vt_nettype, ", ".join(SUPPORTED_NET_TYPES)))
sys.exit(1)
if self.options.vt_nettype == 'bridge':
if os.getuid() != 0:
_restore_stdout()
print("In order to use bridge, you need to be root, "
"aborting...")
sys.exit(1)
self.cartesian_parser.assign("nettype", "bridge")
self.cartesian_parser.assign("netdst", self.options.vt_netdst)
elif self.options.vt_nettype == 'user':
self.cartesian_parser.assign("nettype", "user")
elif self.options.vt_nettype == 'none':
self.cartesian_parser.assign("nettype", "none")
def _process_monitor(self):
if self.options.vt_monitor == 'qmp':
self.cartesian_parser.assign("monitors", "qmp1")
self.cartesian_parser.assign("monitor_type_qmp1", "qmp")
def _process_smp(self):
if not self.options.vt_config:
if self.options.vt_smp == '1':
self.cartesian_parser.only_filter("up")
elif self.options.vt_smp == '2':
self.cartesian_parser.only_filter("smp2")
else:
try:
self.cartesian_parser.only_filter("up")
self.cartesian_parser.assign(
"smp", int(self.options.vt_smp))
except ValueError:
_restore_stdout()
print("Invalid option for smp: %s, aborting..." %
self.options.vt_smp)
sys.exit(1)
else:
logging.info("Config provided, ignoring --smp option")
def _process_arch(self):
if self.options.vt_arch is None:
pass
elif not self.options.vt_config:
self.cartesian_parser.only_filter(self.options.vt_arch)
else:
logging.info("Config provided, ignoring --arch option")
def _process_machine_type(self):
if not self.options.vt_config:
if self.options.vt_machine_type is None:
# TODO: this is x86-specific, instead we can get the default
# arch from qemu binary and run on all supported machine types
if self.options.vt_arch is None and self.options.vt_guest_os is None:
import virttest.defaults
self.cartesian_parser.only_filter(
virttest.defaults.DEFAULT_MACHINE_TYPE)
else:
self.cartesian_parser.only_filter(self.options.vt_machine_type)
else:
logging.info("Config provided, ignoring --machine-type option")
def _process_image_type(self):
if not self.options.vt_config:
if self.options.vt_image_type in SUPPORTED_IMAGE_TYPES:
self.cartesian_parser.only_filter(self.options.vt_image_type)
else:
self.cartesian_parser.only_filter("raw")
# The actual param name is image_format.
self.cartesian_parser.assign("image_format",
self.options.vt_image_type)
else:
logging.info("Config provided, ignoring --image-type option")
def _process_nic_model(self):
if not self.options.vt_config:
if self.options.vt_nic_model in SUPPORTED_NIC_MODELS:
self.cartesian_parser.only_filter(self.options.vt_nic_model)
else:
self.cartesian_parser.only_filter("nic_custom")
self.cartesian_parser.assign(
"nic_model", self.options.vt_nic_model)
else:
logging.info("Config provided, ignoring --nic-model option")
def _process_disk_buses(self):
if not self.options.vt_config:
if self.options.vt_disk_bus in SUPPORTED_DISK_BUSES:
self.cartesian_parser.only_filter(self.options.vt_disk_bus)
else:
_restore_stdout()
print("Option %s is not in the list %s, aborting..." %
(self.options.vt_disk_bus, SUPPORTED_DISK_BUSES))
sys.exit(1)
else:
logging.info("Config provided, ignoring --disk-bus option")
def _process_vhost(self):
if not self.options.vt_config:
if self.options.vt_nettype == "bridge":
if self.options.vt_vhost == "on":
self.cartesian_parser.assign("vhost", "on")
elif self.options.vt_vhost == "force":
self.cartesian_parser.assign("netdev_extra_params",
'",vhostforce=on"')
self.cartesian_parser.assign("vhost", "on")
else:
if self.options.vt_vhost in ["on", "force"]:
_restore_stdout()
print("Nettype %s is incompatible with vhost %s, "
"aborting..." %
(self.options.vt_nettype, self.options.vt_vhost))
sys.exit(1)
else:
logging.info("Config provided, ignoring --vhost option")
def _process_qemu_sandbox(self):
if not self.options.vt_config:
if self.options.vt_qemu_sandbox:
self.cartesian_parser.assign("qemu_sandbox",
self.options.vt_qemu_sandbox)
else:
logging.info(
"Config provided, ignoring \"--sandbox <on|off>\" option")
def _process_qemu_defconfig(self):
if not self.options.vt_config:
if self.options.vt_defconfig == "no":
self.cartesian_parser.assign("defconfig", "no")
else:
logging.info(
"Config provided, ignoring \"--defconfig <yes|no>\" option")
def _process_malloc_perturb(self):
self.cartesian_parser.assign("malloc_perturb",
self.options.vt_malloc_perturb)
def _process_qemu_specific_options(self):
"""
Calls for processing all options specific to the qemu test.
This method modifies the cartesian set by parsing additional lines.
"""
self._process_qemu_bin()
self._process_qemu_accel()
self._process_monitor()
self._process_smp()
self._process_image_type()
self._process_nic_model()
self._process_disk_buses()
self._process_vhost()
self._process_malloc_perturb()
self._process_qemu_sandbox()
self._process_qemu_defconfig()
def _process_lvsb_specific_options(self):
"""
Calls for processing all options specific to lvsb test
"""
self.options.vt_no_downloads = True
def _process_libvirt_specific_options(self):
"""
Calls for processing all options specific to libvirt test.
"""
if self.options.vt_connect_uri:
driver_found = False
for driver in SUPPORTED_LIBVIRT_DRIVERS:
if self.options.vt_connect_uri.count(driver):
driver_found = True
self.cartesian_parser.only_filter(driver)
if not driver_found:
print("Not supported uri: %s." % self.options.vt_connect_uri)
sys.exit(1)
else:
self.cartesian_parser.only_filter("qemu")
def _process_guest_os(self):
if not self.options.vt_config:
from virttest import standalone_test
if len(standalone_test.get_guest_name_list(self.options)) == 0:
_restore_stdout()
print("Guest name %s is not on the known guest os list "
"(see --list-guests), aborting..." %
self.options.vt_guest_os)
sys.exit(1)
self.cartesian_parser.only_filter(
self.options.vt_guest_os or self.option_parser.default_guest_os)
else:
logging.info("Config provided, ignoring --guest-os option")
def _process_list(self):
from virttest import standalone_test
if self.options.vt_list_tests:
standalone_test.print_test_list(self.options,
self.cartesian_parser)
sys.exit(0)
if self.options.vt_list_guests:
standalone_test.print_guest_list(self.options)
sys.exit(0)
def _process_tests(self):
if not self.options.vt_config:
if self.options.vt_type:
if self.options.vt_tests and self.options.vt_dropin:
print("Option --tests and --run-dropin can't be set at "
"the same time")
sys.exit(1)
elif self.options.vt_tests:
tests = self.options.vt_tests.split(" ")
if self.options.vt_type == 'libvirt':
if self.options.vt_install_guest:
tests.insert(0, LIBVIRT_INSTALL)
if self.options.vt_remove_guest:
tests.append(LIBVIRT_REMOVE)
self.cartesian_parser.only_filter(", ".join(tests))
elif self.options.vt_dropin:
from virttest import data_dir
dropin_tests = os.listdir(
os.path.join(data_dir.get_root_dir(), "dropin"))
if len(dropin_tests) <= 1:
_restore_stdout()
print("No drop in tests detected, aborting. "
"Make sure you have scripts on the 'dropin' "
"directory")
sys.exit(1)
self.cartesian_parser.only_filter("dropin")
else:
if self.options.vt_type == 'qemu':
self.cartesian_parser.only_filter(QEMU_DEFAULT_SET)
self.cartesian_parser.no_filter("with_reboot")
elif self.options.vt_type == 'libvirt':
self.cartesian_parser.only_filter(LIBVIRT_DEFAULT_SET)
elif self.options.vt_type == 'lvsb':
self.cartesian_parser.only_filter(LVSB_DEFAULT_SET)
elif self.options.vt_type == 'openvswitch':
self.cartesian_parser.only_filter(OVS_DEFAULT_SET)
else:
logging.info("Config provided, ignoring --tests option")
def _process_restart_vm(self):
if not self.options.vt_config:
if not self.options.vt_keep_guest_running:
self.cartesian_parser.assign("kill_vm", "yes")
def _process_restore_image_between_tests(self):
if not self.options.vt_config:
if not self.options.vt_keep_image_between_tests:
self.cartesian_parser.assign("restore_image", "yes")
def _process_mem(self):
self.cartesian_parser.assign("mem", self.options.vt_mem)
def _process_tcpdump(self):
"""
Verify whether we can run tcpdump. If we can't, turn it off.
"""
from virttest import utils_misc
try:
tcpdump_path = utils_misc.find_command('tcpdump')
except ValueError:
tcpdump_path = None
non_root = os.getuid() != 0
if tcpdump_path is None or non_root:
self.cartesian_parser.assign("run_tcpdump", "no")
def _process_no_filter(self):
if not self.options.vt_config:
if self.options.vt_no_filter:
no_filter = ", ".join(self.options.vt_no_filter.split(' '))
self.cartesian_parser.no_filter(no_filter)
def _process_only_type_specific(self):
if not self.options.vt_config:
if self.options.vt_type_specific:
self.cartesian_parser.only_filter("(subtest=type_specific)")
def _process_general_options(self):
"""
Calls for processing all generic options.
This method modifies the cartesian set by parsing additional lines.
"""
self._process_guest_os()
self._process_arch()
self._process_machine_type()
self._process_restart_vm()
self._process_restore_image_between_tests()
self._process_mem()
self._process_tcpdump()
self._process_no_filter()
self._process_qemu_img()
self._process_bridge_mode()
self._process_only_type_specific()
def _process_options(self):
"""
Process the options given in the command line.
"""
from virttest import cartesian_config, standalone_test
from virttest import data_dir, bootstrap, arch
if (not self.options.vt_type) and (not self.options.vt_config):
_restore_stdout()
print("No type (-t) or config (-c) options specified, aborting...")
sys.exit(1)
if self.options.vt_update_config:
from autotest.client.shared import logging_manager
from virttest import utils_misc
_restore_stdout()
logging_manager.configure_logging(utils_misc.VirtLoggingConfig(),
verbose=True)
test_dir = data_dir.get_backend_dir(self.options.vt_type)
shared_dir = os.path.join(data_dir.get_root_dir(), "shared")
bootstrap.create_config_files(test_dir, shared_dir,
interactive=False,
force_update=True)
bootstrap.create_subtests_cfg(self.options.vt_type)
bootstrap.create_guest_os_cfg(self.options.vt_type)
sys.exit(0)
if self.options.vt_bootstrap:
_restore_stdout()
bootstrap.bootstrap(options=self.options,
interactive=True)
sys.exit(0)
if self.options.vt_type:
if self.options.vt_type not in SUPPORTED_TEST_TYPES:
_restore_stdout()
print("Invalid test type %s. Valid test types: %s. "
"Aborting..." % (self.options.vt_type,
" ".join(SUPPORTED_TEST_TYPES)))
sys.exit(1)
if self.options.vt_log_level not in SUPPORTED_LOG_LEVELS:
_restore_stdout()
print("Invalid log level '%s'. Valid log levels: %s. "
"Aborting..." % (self.options.vt_log_level,
" ".join(SUPPORTED_LOG_LEVELS)))
sys.exit(1)
num_level = getattr(logging, self.options.vt_log_level.upper(), None)
self.options.vt_log_level = num_level
if self.options.vt_console_level not in SUPPORTED_LOG_LEVELS:
_restore_stdout()
print("Invalid console level '%s'. Valid console levels: %s. "
"Aborting..." % (self.options.vt_console_level,
" ".join(SUPPORTED_LOG_LEVELS)))
sys.exit(1)
num_level_console = getattr(logging,
self.options.vt_console_level.upper(),
None)
self.options.vt_console_level = num_level_console
if self.options.vt_data_dir:
data_dir.set_backing_data_dir(self.options.vt_data_dir)
standalone_test.create_config_files(self.options)
self.cartesian_parser = cartesian_config.Parser(debug=False)
if self.options.vt_config:
cfg = os.path.abspath(self.options.vt_config)
if not self.options.vt_config:
cfg = data_dir.get_backend_cfg_path(
self.options.vt_type, 'tests.cfg')
self.cartesian_parser.parse_file(cfg)
if self.options.vt_type != 'lvsb':
self._process_general_options()
if self.options.vt_type == 'qemu':
self._process_qemu_specific_options()
elif self.options.vt_type == 'lvsb':
self._process_lvsb_specific_options()
elif self.options.vt_type == 'openvswitch':
self._process_qemu_specific_options()
elif self.options.vt_type == 'libvirt':
self._process_libvirt_specific_options()
# List and tests have to be the last things to be processed
self._process_list()
self._process_tests()
def main(self):
"""
Main point of execution of the test runner.
1) Handle stdout/err according to the options given.
2) Import the autotest modules.
3) Sets the console logging for tests.
4) Runs the tests according to the options given.
"""
_handle_stdout(self.options)
try:
from virttest import standalone_test
self._process_options()
standalone_test.reset_logging()
standalone_test.configure_console_logging(
loglevel=self.options.vt_console_level)
standalone_test.bootstrap_tests(self.options)
ok = standalone_test.run_tests(self.cartesian_parser, self.options)
except KeyboardInterrupt:
standalone_test.cleanup_env(self.cartesian_parser, self.options)
pid = os.getpid()
os.kill(pid, signal.SIGTERM)
except StopIteration:
_restore_stdout()
print("Empty config set generated ")
if self.options.vt_type:
print("Tests chosen: '%s'" % self.options.vt_tests)
print("Check that you typed the tests "
"names correctly, and double "
"check that tests show "
"in --list-tests for guest '%s'" %
(self.options.vt_guest_os or
self.option_parser.default_guest_os))
sys.exit(1)
if self.options.vt_config:
print("Please check your custom config file %s" %
self.options.vt_config)
sys.exit(1)
except Exception:
_restore_stdout()
print("Internal error, traceback follows...")
exc_type, exc_value, exc_traceback = sys.exc_info()
tb_info = traceback.format_exception(exc_type, exc_value,
exc_traceback.tb_next)
tb_info = "".join(tb_info)
for e_line in tb_info.splitlines():
print(e_line)
sys.exit(1)
if not ok:
sys.exit(1)
if __name__ == '__main__':
app = VirtTestApp()
app.main()
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Python
1
https://gitee.com/smooth00/virt-test.git
git@gitee.com:smooth00/virt-test.git
smooth00
virt-test
virt-test
master

搜索帮助