From cda6066fb082646092e24cc8934bff2a1979053b Mon Sep 17 00:00:00 2001 From: Qingtang Zhou Date: Tue, 25 Jun 2013 11:38:13 +0800 Subject: [PATCH 001/254] shared.cfg: Disable S3/S4 test on all ppc64 guests According to https://github.com/autotest/virt-test/pull/558 All S3/S4 tests should be disabled on ppc64 guests. Signed-off-by: Qingtang Zhou --- shared/cfg/guest-os/Linux/Fedora/16.ppc64.cfg | 1 + shared/cfg/guest-os/Linux/Fedora/17.ppc64.cfg | 1 + shared/cfg/guest-os/Linux/Fedora/18.ppc64.cfg | 1 + 3 files changed, 3 insertions(+) diff --git a/shared/cfg/guest-os/Linux/Fedora/16.ppc64.cfg b/shared/cfg/guest-os/Linux/Fedora/16.ppc64.cfg index 88526e292..ba0943e9e 100644 --- a/shared/cfg/guest-os/Linux/Fedora/16.ppc64.cfg +++ b/shared/cfg/guest-os/Linux/Fedora/16.ppc64.cfg @@ -2,6 +2,7 @@ image_name = images/f16-ppc64 only pseries no unattended_install..floppy_ks + no guest_s3, guest_s4 unattended_install: kernel_params = "root=live:CDLABEL=Fedora-16-ppc64 ks=cdrom:/ks.cfg console=hvc0 serial rd_NO_PLYMOUTH" unattended_file = unattended/Fedora-16.ks diff --git a/shared/cfg/guest-os/Linux/Fedora/17.ppc64.cfg b/shared/cfg/guest-os/Linux/Fedora/17.ppc64.cfg index 2dacc89f7..af11526a1 100644 --- a/shared/cfg/guest-os/Linux/Fedora/17.ppc64.cfg +++ b/shared/cfg/guest-os/Linux/Fedora/17.ppc64.cfg @@ -2,6 +2,7 @@ image_name = images/f17-ppc64 only pseries no unattended_install..floppy_ks + no guest_s3, guest_s4 mem_chk_cmd = numactl --hardware | awk -F: '/size/ {print $2}' netdev_peer_re = "(.*?): .*?\\\s(.*?):" unattended_install: diff --git a/shared/cfg/guest-os/Linux/Fedora/18.ppc64.cfg b/shared/cfg/guest-os/Linux/Fedora/18.ppc64.cfg index 3ff948b3f..c61bcb51d 100644 --- a/shared/cfg/guest-os/Linux/Fedora/18.ppc64.cfg +++ b/shared/cfg/guest-os/Linux/Fedora/18.ppc64.cfg @@ -2,6 +2,7 @@ image_name = images/f18-ppc64 only pseries no unattended_install..floppy_ks + no guest_s3, guest_s4 mem_chk_cmd = numactl --hardware | awk -F: '/size/ {print $2}' netdev_peer_re = "(.*?): .*?\\\s(.*?):" unattended_install: From cff2c5dccc46b4bea33fcab6933b780c6b8412d0 Mon Sep 17 00:00:00 2001 From: yangdongsheng Date: Wed, 26 Jun 2013 17:45:05 +0800 Subject: [PATCH 002/254] Add a class named RemoteFile in virttest-remote module. A class to handle remote file. Currently, we support three operations on remote file. add: append lines in to file. sub: replace string which match pattern to repl. remove: delete lines that match pattern. Signed-off-by: yangdongsheng --- virttest/remote.py | 156 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 154 insertions(+), 2 deletions(-) diff --git a/virttest/remote.py b/virttest/remote.py index 264724846..5edfc67b9 100644 --- a/virttest/remote.py +++ b/virttest/remote.py @@ -1,10 +1,10 @@ """ Functions and classes used for logging into guests and transferring files. """ -import logging, time, re +import logging, time, re, os, shutil, uuid import aexpect, utils_misc, rss_client from autotest.client.shared import error -from autotest.client import utils +import data_dir class LoginError(Exception): def __init__(self, msg, output): @@ -664,3 +664,155 @@ def copy_files_from(address, client, username, password, port, remote_path, c = rss_client.FileDownloadClient(address, port, log_func) c.download(remote_path, local_path, timeout) c.close() + + +class RemoteFile(object): + """ + Class to handle the operations of file on remote host or guest. + """ + def __init__(self, address, client, username, password, port, + remote_path, limit="", log_filename=None, + verbose=False, timeout=600): + """ + Initialization of RemoteFile class. + + @param address: Address of remote host(guest) + @param client: Type of transfer client + @param username: Username (if required) + @param password: Password (if requried) + @param remote_path: Path of file which we want to edit on remote. + @param limit: Speed limit of file transfer. + @param log_filename: If specified, log all output to this file(SCP only) + @param verbose: If True, log some stats using logging.debug (RSS only) + @param timeout: The time duration (in seconds) to wait for the + transfer tocomplete. + """ + self.address = address + self.client = client + self.username = username + self.password = password + self.port = port + self.remote_path = remote_path + self.limit = limit + self.log_filename = log_filename + self.verbose = verbose + self.timeout = timeout + + #Get a local_path and all actions is taken on it. + file_id = uuid.uuid1() + filename = os.path.basename(self.remote_path) + tmp_dir = data_dir.get_tmp_dir() + self.local_path = os.path.join(tmp_dir, "%s_%s" % (filename, file_id)) + back_dir = data_dir.get_backing_data_dir() + self.backup_path = os.path.join(back_dir, "%s_%s.bak" + % (filename, file_id)) + + #Get file from remote. + self._pull_file() + #Save a backup. + shutil.copy(self.local_path, self.backup_path) + + def __del__(self): + """ + Called when the instance is about to be destroyed. + """ + self._reset_file() + if os.path.exists(self.backup_path): + os.remove(self.backup_path) + if os.path.exists(self.local_path): + os.remove(self.local_path) + + def _pull_file(self): + """ + Copy file from remote to local. + """ + if self.client == "test": + shutil.copy(self.remote_path, self.local_path) + else: + copy_files_from(self.address, self.client, self.username, + self.password, self.port, self.remote_path, + self.local_path, self.limit, self.log_filename, + self.verbose, self.timeout) + + def _push_file(self): + """ + Copy file from local to remote. + """ + if self.client == "test": + shutil.copy(self.local_path, self.remote_path) + else: + copy_files_to(self.address, self.client, self.username, + self.password, self.port, self.local_path, + self.remote_path, self.limit, self.log_filename, + self.verbose, self.timeout) + def _reset_file(self): + """ + Copy backup from local to remote. + """ + if self.client == "test": + shutil.copy(self.backup_path, self.remote_path) + else: + copy_files_to(self.address, self.client, self.username, + self.password, self.port, self.backup_path, + self.remote_path, self.limit, self.log_filename, + self.verbose, self.timeout) + + + def _read_local(self): + """ + Read file on local_path. + + @return: string list got from readlines(). + """ + local_file = open(self.local_path, "r") + lines = local_file.readlines() + local_file.close() + return lines + + def _write_local(self, lines): + """ + Write file on local_path. Call writelines method of File. + """ + local_file = open(self.local_path, "w") + local_file.writelines(lines) + local_file.close() + + def add(self, line_list): + """ + Append lines in line_list into file on remote. + """ + lines = self._read_local() + for line in line_list: + lines.append("\n%s" % line) + self._write_local(lines) + self._push_file() + + def sub(self, pattern2repl_dict): + """ + Replace the string which match the pattern + to the value contained in pattern2repl_dict. + """ + lines = self._read_local() + for pattern, repl in pattern2repl_dict.items(): + for index in range(len(lines)): + line = lines[index] + lines[index] = re.sub(pattern, repl, line) + self._write_local(lines) + self._push_file() + + def remove(self, pattern_list): + """ + Remove the lines in remote file which matchs a pattern + in pattern_list. + """ + lines = self._read_local() + for pattern in pattern_list: + for index in range(len(lines)): + line = lines[index] + if re.match(pattern, line): + lines.remove(line) + #Check this line is the last one or not. + if (not line.endswith('\n') and (index >0)): + lines[index-1] = lines[index-1].rstrip("\n") + self._write_local(lines) + self._push_file() From 93b09b0edc8c9a9bc3998ca182f8e823c785cd31 Mon Sep 17 00:00:00 2001 From: yangdongsheng Date: Wed, 26 Jun 2013 17:47:37 +0800 Subject: [PATCH 003/254] Add some unittest for RemoteFile. Signed-off-by: yangdongsheng --- virttest/remote_unittest.py | 69 +++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 virttest/remote_unittest.py diff --git a/virttest/remote_unittest.py b/virttest/remote_unittest.py new file mode 100644 index 000000000..aa4faef2e --- /dev/null +++ b/virttest/remote_unittest.py @@ -0,0 +1,69 @@ +#!/usr/bin/python + +import unittest, os +import common, remote, data_dir + +class RemoteFileTest(unittest.TestCase): + tmp_dir = data_dir.get_tmp_dir() + test_file_path = os.path.join(tmp_dir, "remote_file") + default_data = ["RemoteFile Test.\n", "Pattern Line."] + + def _new_remote_file(self): + if os.path.exists(self.test_file_path): + os.remove(self.test_file_path) + test_file = open(self.test_file_path, "w") + test_file.writelines(self.default_data) + test_file.close() + remote_file = remote.RemoteFile(None, "test", None, None, None, + self.test_file_path) + return remote_file + + def _read_test_file(self): + test_file = open(self.test_file_path, "r") + test_data = test_file.readlines() + test_file.close() + return test_data + + def testAdd(self): + remote_file = self._new_remote_file() + _add_list = ["add_line_1", "add_line_2", "add_line_3"] + remote_file.add(_add_list) + test_data = self._read_test_file() + except_data = ["RemoteFile Test.\n", + "Pattern Line.\n", + "add_line_1\n", + "add_line_2\n", + "add_line_3"] + for index in range(len(except_data)): + self.assertEqual(except_data[index], test_data[index]) + del remote_file + test_data = self._read_test_file() + self.assertEqual(test_data, self.default_data) + + def testSub(self): + remote_file = self._new_remote_file() + _pattern2repl = {r"Remote":"Local", r"^Pat.*$":"Replace Line"} + remote_file.sub(_pattern2repl) + test_data = self._read_test_file() + except_data = ["LocalFile Test.\n", + "Replace Line"] + for index in range(len(except_data)): + self.assertEqual(except_data[index], test_data[index]) + del remote_file + test_data = self._read_test_file() + self.assertEqual(test_data, self.default_data) + + def testRemove(self): + remote_file = self._new_remote_file() + _pattern_list = [r"^Pattern"] + remote_file.remove(_pattern_list) + test_data = self._read_test_file() + except_data = ["RemoteFile Test."] + for index in range(len(except_data)): + self.assertEqual(except_data[index], test_data[index]) + del remote_file + test_data = self._read_test_file() + self.assertEqual(test_data, self.default_data) + +if __name__ == "__main__": + unittest.main() From 2aabc6d18886f67c1dc6f4fbeb4ee9c73b1b99ab Mon Sep 17 00:00:00 2001 From: yangdongsheng Date: Wed, 26 Jun 2013 21:54:52 +0800 Subject: [PATCH 004/254] Fix for RemoteFile and unittest. (1).Change uuid to tempfile to build a unique filename. (2).Add a __del__ method for unittest class to remove remote_file. Signed-off-by: yangdongsheng Fix indenting error in remote.py. Signed-off-by: yangdongsheng --- virttest/remote.py | 22 +++++++++++++++------- virttest/remote_unittest.py | 4 ++++ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/virttest/remote.py b/virttest/remote.py index 5edfc67b9..1bb75ab53 100644 --- a/virttest/remote.py +++ b/virttest/remote.py @@ -1,7 +1,7 @@ """ Functions and classes used for logging into guests and transferring files. """ -import logging, time, re, os, shutil, uuid +import logging, time, re, os, shutil, tempfile import aexpect, utils_misc, rss_client from autotest.client.shared import error import data_dir @@ -684,7 +684,7 @@ def __init__(self, address, client, username, password, port, @param limit: Speed limit of file transfer. @param log_filename: If specified, log all output to this file(SCP only) @param verbose: If True, log some stats using logging.debug (RSS only) - @param timeout: The time duration (in seconds) to wait for the + @param timeout: The time duration (in seconds) to wait for the transfer tocomplete. """ self.address = address @@ -699,13 +699,21 @@ def __init__(self, address, client, username, password, port, self.timeout = timeout #Get a local_path and all actions is taken on it. - file_id = uuid.uuid1() filename = os.path.basename(self.remote_path) + + #Get a local_path. tmp_dir = data_dir.get_tmp_dir() - self.local_path = os.path.join(tmp_dir, "%s_%s" % (filename, file_id)) + local_file = tempfile.NamedTemporaryFile(prefix=("%s_" % filename), + dir=tmp_dir) + self.local_path = local_file.name + local_file.close() + + #Get a backup_path. back_dir = data_dir.get_backing_data_dir() - self.backup_path = os.path.join(back_dir, "%s_%s.bak" - % (filename, file_id)) + backup_file = tempfile.NamedTemporaryFile(prefix=("%s_" % filename), + dir=tmp_dir) + self.backup_path = backup_file.name + backup_file.close() #Get file from remote. self._pull_file() @@ -733,7 +741,7 @@ def _pull_file(self): self.password, self.port, self.remote_path, self.local_path, self.limit, self.log_filename, self.verbose, self.timeout) - + def _push_file(self): """ Copy file from local to remote. diff --git a/virttest/remote_unittest.py b/virttest/remote_unittest.py index aa4faef2e..f25d84000 100644 --- a/virttest/remote_unittest.py +++ b/virttest/remote_unittest.py @@ -8,6 +8,10 @@ class RemoteFileTest(unittest.TestCase): test_file_path = os.path.join(tmp_dir, "remote_file") default_data = ["RemoteFile Test.\n", "Pattern Line."] + def __del__(self): + if os.path.exists(self.test_file_path): + os.remove(self.test_file_path) + def _new_remote_file(self): if os.path.exists(self.test_file_path): os.remove(self.test_file_path) From 6251d67e3cd4e6f00820640a8400fd428ff5cbd1 Mon Sep 17 00:00:00 2001 From: Feng Yang Date: Fri, 28 Jun 2013 11:44:55 +0800 Subject: [PATCH 005/254] qemu.tests.cpu_hotplug: Make cpu hotplug command configurable. cpu_set command will be removed in new qemu. So make cpu hotplug command configurable. 'cpu_set 1 online' will always sent out as human monitor command no matter qmp support cpu_set or not. Update it to 'cpu_set cpu=1,state=online'. send_args_cmd() will transfer it to correct human monitor command 'cpu_set 1 online'. Or correct qmp monitor command if qmp support it. Signed-off-by: Feng Yang --- qemu/tests/cfg/cpu_hotplug.cfg | 1 + qemu/tests/cpu_hotplug.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/qemu/tests/cfg/cpu_hotplug.cfg b/qemu/tests/cfg/cpu_hotplug.cfg index a8f445756..e12740022 100644 --- a/qemu/tests/cfg/cpu_hotplug.cfg +++ b/qemu/tests/cfg/cpu_hotplug.cfg @@ -10,6 +10,7 @@ kill_vm = yes smp = 1 vcpu_maxcpus = 160 + cpu_hotplug_cmd = 'cpu_set cpu=%s,state=online' # this at least need a RHEL.6.3 host # the smp can be overrided (tests.cfg is a good place) # if you want to test with a guest booted with diff SMP, pls modify it. diff --git a/qemu/tests/cpu_hotplug.py b/qemu/tests/cpu_hotplug.py index 831cd6bf7..7089d48b3 100644 --- a/qemu/tests/cpu_hotplug.py +++ b/qemu/tests/cpu_hotplug.py @@ -35,6 +35,7 @@ def run_cpu_hotplug(test, params, env): maxcpus = int(params.get("maxcpus", 160)) current_cpus = int(params.get("smp", 1)) onoff_iterations = int(params.get("onoff_iterations", 20)) + cpu_hotplug_cmd = params['cpu_hotplug_cmd'] if n_cpus_add + current_cpus > maxcpus: logging.warn("CPU quantity more than maxcpus, set it to %s", maxcpus) @@ -49,7 +50,7 @@ def run_cpu_hotplug(test, params, env): for i in range(current_cpus, total_cpus): error.context("hot-pluging vCPU %s" % i, logging.info) - vm.monitor.send_args_cmd("cpu_set %s online" % i) + vm.monitor.send_args_cmd(cpu_hotplug_cmd % i) output = vm.monitor.send_args_cmd("info cpus") logging.debug("Output of info CPUs:\n%s", output) From 14ca45a934f23003edb2391c0fa76bc8ebad9944 Mon Sep 17 00:00:00 2001 From: yangdongsheng Date: Wed, 5 Jun 2013 10:18:38 +0800 Subject: [PATCH 006/254] small fix for nodedev_xml (1).__schema_name__ = "nodedev" (2).change get_key2syspath_dict and get_key2value_dict from @staticmethod to method of NodedevXML. Signed-off-by: yangdongsheng --- virttest/libvirt_xml/nodedev_xml.py | 16 ++++++---------- virttest/libvirt_xml_unittest.py | 7 +++++-- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/virttest/libvirt_xml/nodedev_xml.py b/virttest/libvirt_xml/nodedev_xml.py index 57307d0f3..171ce7254 100644 --- a/virttest/libvirt_xml/nodedev_xml.py +++ b/virttest/libvirt_xml/nodedev_xml.py @@ -180,7 +180,7 @@ class NodedevXMLBase(base.LibvirtXMLBase): __slots__ = base.LibvirtXMLBase.__slots__ + ('name', 'parent', 'cap_type', 'cap', 'sysfs_main_path') - __schema_name__ = "device" + __schema_name__ = "nodedev" __sysfs_dir__ = "/sys/class" @@ -305,30 +305,26 @@ def new_from_dumpxml(dev_name, virsh_instance=base.virsh): return nodedevxml - @staticmethod - def get_key2value_dict(dev_name): + def get_key2value_dict(self): """ Get the dict which contain key and value in xml. key: keys in nodedev xml need to check. value: value in xml for the key. """ - nodedevxml = NodedevXML.new_from_dumpxml(dev_name) - capxml = nodedevxml.cap + capxml = self.cap key2value_dict = capxml.get_key2value_dict() return key2value_dict - @staticmethod - def get_key2syspath_dict(dev_name): + def get_key2syspath_dict(self): """ Get the dict which contains key and path. key: keys in nodedev xml need to check. syspath: the abs path for the file stores info for the key. """ - nodedevxml = NodedevXML.new_from_dumpxml(dev_name) - sysfs_path = nodedevxml.get_sysfs_path() - capxml = nodedevxml.cap + sysfs_path = self.get_sysfs_path() + capxml = self.cap key2filename_dict = capxml.__class__.get_key2filename_dict() key2syspath_dict = {} diff --git a/virttest/libvirt_xml_unittest.py b/virttest/libvirt_xml_unittest.py index 295e90150..0c940950e 100755 --- a/virttest/libvirt_xml_unittest.py +++ b/virttest/libvirt_xml_unittest.py @@ -649,13 +649,16 @@ def test_new_from_dumpxml(self): def test_get_key2value_dict(self): NodedevXML = nodedev_xml.NodedevXML - result = NodedevXML.get_key2value_dict('pci_0000_00_00_0') + xml = NodedevXML.new_from_dumpxml('pci_0000_00_00_0') + result = xml.get_key2value_dict() + self.assertTrue(isinstance(result, dict)) def test_get_key2syspath_dict(self): NodedevXML = nodedev_xml.NodedevXML - result = NodedevXML.get_key2syspath_dict('pci_0000_00_00_0') + xml = NodedevXML.new_from_dumpxml('pci_0000_00_00_0') + result = xml.get_key2syspath_dict() self.assertTrue(isinstance(result, dict)) From 866c1182fdc5affad69baa66aefdfc0a6c3f0fd1 Mon Sep 17 00:00:00 2001 From: yangdongsheng Date: Wed, 5 Jun 2013 10:19:20 +0800 Subject: [PATCH 007/254] Add test for nodedev-dumpxml Signed-off-by: yangdongsheng --- .../nodedev/virsh_nodedev_dumpxml.cfg | 24 ++++++ .../nodedev/virsh_nodedev_dumpxml.py | 82 +++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 libvirt/tests/cfg/virsh_cmd/nodedev/virsh_nodedev_dumpxml.cfg create mode 100644 libvirt/tests/src/virsh_cmd/nodedev/virsh_nodedev_dumpxml.py diff --git a/libvirt/tests/cfg/virsh_cmd/nodedev/virsh_nodedev_dumpxml.cfg b/libvirt/tests/cfg/virsh_cmd/nodedev/virsh_nodedev_dumpxml.cfg new file mode 100644 index 000000000..7f1891149 --- /dev/null +++ b/libvirt/tests/cfg/virsh_cmd/nodedev/virsh_nodedev_dumpxml.cfg @@ -0,0 +1,24 @@ +- virsh_nodedev_dumpxml: + virt_test_type = libvirt + type = virsh_nodedev_dumpxml + vms = "" + main_vm = "" + start_vm = "no" + #nodedev_device_name need to execute dumpxml command. + nodedev_device_name = "pci_0000_00_00_0" + #nodedev_device_opt: options for nodedev-dumpxml cmd. + nodedev_device_opt = "" + variants: + - positve_test: + status_error = "no" + variants: + - normal_test: + - negative_test: + status_error = "yes" + variants: + - nodedev_notfound: + nodedev_device_name = "not_exists" + - nodedev_spacename: + nodedev_device_name = "" + - nodedev_unknowopt: + nodedev_device_opt = "--xyz" diff --git a/libvirt/tests/src/virsh_cmd/nodedev/virsh_nodedev_dumpxml.py b/libvirt/tests/src/virsh_cmd/nodedev/virsh_nodedev_dumpxml.py new file mode 100644 index 000000000..b6e106cc1 --- /dev/null +++ b/libvirt/tests/src/virsh_cmd/nodedev/virsh_nodedev_dumpxml.py @@ -0,0 +1,82 @@ +import logging +from autotest.client import utils +from autotest.client.shared import error +from virttest import libvirt_vm, virsh +from virttest.libvirt_xml import nodedev_xml + + +def do_nodedev_dumpxml(dev_name, dev_opt=""): + """ + Do dumpxml and check the result. + + (1).execute nodedev-dumpxml command. + (2).compare info in xml with info in sysfs. + + @param dev_name: name of device. + @raise TestFail: if execute command failed + or check result failed. + """ + result = virsh.nodedev_dumpxml(dev_name, options=dev_opt) + if result.exit_status: + raise error.TestError("Dumpxml node device %s failed.\n" + "Detail:%s." % (dev_name, result.stderr)) + logging.debug('Executing "virsh nodedev-dumpxml %s" finished.' % (dev_name)) + #compare info in xml with info in sysfs. + nodedevxml = nodedev_xml.NodedevXML.new_from_dumpxml(dev_name) + if not nodedevxml.validates: + raise error.TestError("nodedvxml of %s is not validated." % (dev_name)) + #Get the dict of key to value in xml. + #key2value_dict_xml contain the all keys and values in xml need checking. + key2value_dict_xml = nodedevxml.get_key2value_dict() + #Get the dict of key to path in sysfs. + #key2syspath_dict contain the all keys and the path of file which contain + # infomation for each key. + key2syspath_dict = nodedevxml.get_key2syspath_dict() + #Get the values contained in files. + #key2value_dict_sys contain the all keys and values in sysfs. + key2value_dict_sys = {} + for key, filepath in key2syspath_dict.items(): + value = utils.read_one_line(filepath) + key2value_dict_sys[key] = value + + #Compare the value in xml and in syspath. + for key in key2value_dict_xml: + value_xml = key2value_dict_xml.get(key) + value_sys = key2value_dict_sys.get(key) + if not value_xml == value_sys: + raise error.TestError("key: %s in xml is %s," + "but in sysfs is %s." % + (key, value_xml, value_sys)) + else: + continue + + logging.debug("Compare info in xml and info in sysfs finished" + "for device %s." % (dev_name)) + + +def run_virsh_nodedev_dumpxml(test, params, env): + """ + Test command virsh nodedev-dumpxml. + + (1).get param from params. + (2).do nodedev dumpxml. + (3).clean up. + """ + #Init variables. + status_error = ('yes' == params.get('status_error', 'no')) + device_name = params.get('nodedev_device_name', None) + device_opt = params.get('nodedev_device_opt', "") + + #do nodedev dumpxml. + try: + do_nodedev_dumpxml(dev_name=device_name, dev_opt=device_opt) + if status_error: + raise error.TestFail('Nodedev dumpxml successed in negitive test.') + else: + pass + except error.TestError, e: + if status_error: + pass + else: + raise error.TestFail('Nodedev dumpxml failed in positive test.' + 'Error: %s' % e) From d2d404401cb7677d71ccf358ebefeaea48274f3b Mon Sep 17 00:00:00 2001 From: Yu Mingfei Date: Mon, 1 Jul 2013 22:27:57 +0800 Subject: [PATCH 008/254] libvirt.tests: Fix pylint complaint for virsh nodedev-dumpxml. Signed-off-by: Yu Mingfei --- .../tests/src/virsh_cmd/nodedev/virsh_nodedev_dumpxml.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libvirt/tests/src/virsh_cmd/nodedev/virsh_nodedev_dumpxml.py b/libvirt/tests/src/virsh_cmd/nodedev/virsh_nodedev_dumpxml.py index b6e106cc1..af3e99779 100644 --- a/libvirt/tests/src/virsh_cmd/nodedev/virsh_nodedev_dumpxml.py +++ b/libvirt/tests/src/virsh_cmd/nodedev/virsh_nodedev_dumpxml.py @@ -1,7 +1,7 @@ import logging from autotest.client import utils from autotest.client.shared import error -from virttest import libvirt_vm, virsh +from virttest import virsh from virttest.libvirt_xml import nodedev_xml @@ -19,8 +19,8 @@ def do_nodedev_dumpxml(dev_name, dev_opt=""): result = virsh.nodedev_dumpxml(dev_name, options=dev_opt) if result.exit_status: raise error.TestError("Dumpxml node device %s failed.\n" - "Detail:%s." % (dev_name, result.stderr)) - logging.debug('Executing "virsh nodedev-dumpxml %s" finished.' % (dev_name)) + "Detail:%s." % (dev_name, result.stderr)) + logging.debug('Executing "virsh nodedev-dumpxml %s" finished.', dev_name) #compare info in xml with info in sysfs. nodedevxml = nodedev_xml.NodedevXML.new_from_dumpxml(dev_name) if not nodedevxml.validates: @@ -51,7 +51,7 @@ def do_nodedev_dumpxml(dev_name, dev_opt=""): continue logging.debug("Compare info in xml and info in sysfs finished" - "for device %s." % (dev_name)) + "for device %s.", dev_name) def run_virsh_nodedev_dumpxml(test, params, env): From 9003d6e937931b7e3ee32079ea25a4eabf087704 Mon Sep 17 00:00:00 2001 From: whuang Date: Mon, 22 Apr 2013 14:07:37 +0800 Subject: [PATCH 009/254] Add virsh domif-setlink domif-getlink test Introduce virsh domif-setlink domif-getlink testing: 1. Positive testing 1.1 Running domain and shutting off domain testing 1.2 Setlink domain interface up and down then check 1.3 Options "--config" testing 1.4 Interface name and MAC address testing 2. Negative testing 2.1 Invalid options testing 2.2 Shutting off domain with interface name Signed-off-by: whuang --- .../tests/cfg/virsh_domif_setlink_getlink.cfg | 47 +++++++ libvirt/tests/virsh_domif_setlink_getlink.py | 120 ++++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100644 libvirt/tests/cfg/virsh_domif_setlink_getlink.cfg create mode 100644 libvirt/tests/virsh_domif_setlink_getlink.py diff --git a/libvirt/tests/cfg/virsh_domif_setlink_getlink.cfg b/libvirt/tests/cfg/virsh_domif_setlink_getlink.cfg new file mode 100644 index 000000000..c84731720 --- /dev/null +++ b/libvirt/tests/cfg/virsh_domif_setlink_getlink.cfg @@ -0,0 +1,47 @@ +- virsh_domif_setlink_getlink: + type = virsh_domif_setlink_getlink + variants: + - positive_test: + status_error = "no" + libvirtd = "on" + variants: + - domif_setlink: + action = "setlink" + variants: + - setlink_up: + operation = "up" + - setlink_down: + operation = "down" + variants: + - running_guest: + start_vm = "yes" + - shutoff_guest: + start_vm = "no" + no interface_net + variants: + - no_config: + options = " " + - with_config: + options = "--config" + no interface_net + no shutoff_guest + variants: + - interface_net: + if_device = "net" + if_name = "vnet0" + - interface_mac: + if_device = "mac" + + - negative_test: + status_error = "yes" + action = "setlink" + operation = "up" + if_device = "mac" + options = " " + variants: + - running_guest_invalid_option: + options = "--xyz" + start_vm = "yes" + - shutoff_guest_with_vnet: + start_vm = "no" + if_device = "net" diff --git a/libvirt/tests/virsh_domif_setlink_getlink.py b/libvirt/tests/virsh_domif_setlink_getlink.py new file mode 100644 index 000000000..fb3947ac2 --- /dev/null +++ b/libvirt/tests/virsh_domif_setlink_getlink.py @@ -0,0 +1,120 @@ +import logging, re +from autotest.client.shared import error +from virttest import libvirt_vm, virsh +from virttest.libvirt_xml import vm_xml + +def run_virsh_domif_setlink_getlink(test, params, env): + """ + Test command: virsh domif-setlink and domif-getlink. + + The command set and get link state of a virtual interface + 1. Prepare test environment. + 2. When the libvirtd == "off", stop the libvirtd service. + 3. Perform virsh domif-setlink and domif-getlink operation. + 4. Recover test environment. + 5. Confirm the test result. + """ + + def domif_setlink(vm, device, operation, options): + """ + """ + + return virsh.domif_setlink(vm, device, operation, options, debug=True) + + def domif_getlink(vm, device, options): + """ + """ + + return virsh.domif_getlink(vm, device, options, + ignore_status=True, debug=True) + + vm_name = params.get("main_vm") + vm = env.get_vm(vm_name) + options = params.get("options") + start_vm = params.get("start_vm") + libvirtd = params.get("libvirtd", "on") + if_device = params.get("if_device") + if_name = params.get("if_name") + operation = params.get("operation") + status_error = params.get("status_error") + mac_address = vm.get_virsh_mac_address(0) + device = "vnet0" + # Vm status + if start_vm == "yes" and vm.is_dead(): + vm.start() + + elif start_vm == "no" and vm.is_alive(): + vm.destroy() + + if libvirtd == "off": + libvirt_vm.libvirtd_stop() + + # Test device net or mac address + if if_device == "net" and vm.is_alive(): + device = if_name + # Get all vm's interface device + net_dev = vm_xml.VMXML.get_net_dev(vm_name) + device = net_dev[0] + + elif if_device == "mac": + device = mac_address + + # Setlink opertation + result = domif_setlink(vm_name, device, operation, options) + status = result.exit_status + logging.info("Setlink done") + + # Getlink opertation + get_result = domif_getlink(vm_name, device, options) + getlink_output = get_result.stdout.strip() + + # Check the getlink command output + if not re.search(operation, getlink_output) and status_error == "no": + raise error.TestFail("Getlink result should " + "equal with setlink operation ", getlink_output) + + logging.info("Getlink done") + # If --config is given should restart the vm then test link status + if options == "--config" and vm.is_alive(): + vm.destroy() + vm.start() + logging.info("Restart VM") + + elif start_vm == "no": + vm.start() + + if status_error == "no": + # Serial login the vm to check link status + # Start vm check the link statue + session = vm.wait_for_serial_login() + cmd = "ip add |grep -i '%s' -B1|grep -i 'state %s' " \ + % (mac_address, operation) + cmd_status, output = session.cmd_status_output(cmd) + logging.info("====%s==%s===", cmd_status, output ) + # Set the link up make host connect with vm + domif_setlink(vm_name, device, "up", "") + session.cmd("service network restart") + + # Recover libvirtd service start + if libvirtd == "off": + libvirt_vm.libvirtd_start() + + # Check status_error + + if status_error == "yes": + if status: + logging.info("Expected error (negative testing). Output: %s", + result.stderr.strip()) + + else: + raise error.TestFail("Unexpected return code %d " + "(negative testing)" % status) + elif status_error == "no": + status = cmd_status + if status: + raise error.TestFail("Unexpected error (positive testing). " + "Output: %s" % result.stderr.strip()) + + else: + raise error.TestError("Invalid value for status_error '%s' " + "(must be 'yes' or 'no')" % status_error) From 3625fe3959daf766813a86997d1a666cbab63699 Mon Sep 17 00:00:00 2001 From: whuang Date: Mon, 22 Apr 2013 14:14:32 +0800 Subject: [PATCH 010/254] virt: add virsh functions for virsh domif-setlink and domif-getlink Signed-off-by: whuang --- virttest/virsh.py | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/virttest/virsh.py b/virttest/virsh.py index 97adb1871..852a6f159 100644 --- a/virttest/virsh.py +++ b/virttest/virsh.py @@ -2066,7 +2066,6 @@ def ttyconsole(name, **dargs): """ return command("ttyconsole %s" % name, **dargs) - def nodedev_dumpxml(name, options="", to_file=None, **dargs): """ Do dumpxml for node device. @@ -2086,7 +2085,6 @@ def nodedev_dumpxml(name, options="", to_file=None, **dargs): return result - def connect(connect_uri="", options="", **dargs): """ Run a connect command to the uri. @@ -2096,3 +2094,36 @@ def connect(connect_uri="", options="", **dargs): @return: CmdResult object. """ return command("connect %s %s" % (connect_uri, options), **dargs) + +def domif_setlink(name, interface, state, options, **dargs): + """ + Set network interface stats for a running domain. + + @param: name: Name of domain + @param: interface: interface device + @param: state: new state of the device up or down + @param: options: command options. + @param: dargs: standardized virsh function API keywords + @return: CmdResult object + """ + cmd = "domif-setlink %s %s %s " % (name, interface, state) + if options: + cmd += " %s" % options + + return command(cmd, **dargs) + +def domif_getlink(name, interface, options, **dargs): + """ + Get network interface stats for a running domain. + + @param: name: Name of domain + @param: interface: interface device + @param: options: command options. + @param: dargs: standardized virsh function API keywords + @return: domif state + """ + cmd = "domif-getlink %s %s " % (name, interface) + if options: + cmd += " %s" % options + + return command(cmd, **dargs) From 7d2201ecb75a69f25e9431ac486672d81d38606d Mon Sep 17 00:00:00 2001 From: whuang Date: Mon, 22 Apr 2013 14:19:06 +0800 Subject: [PATCH 011/254] virt: add functions get net devices of domain from guest xml Signed-off-by: whuang --- virttest/libvirt_xml/vm_xml.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/virttest/libvirt_xml/vm_xml.py b/virttest/libvirt_xml/vm_xml.py index eb7da38d7..da5262627 100644 --- a/virttest/libvirt_xml/vm_xml.py +++ b/virttest/libvirt_xml/vm_xml.py @@ -685,3 +685,29 @@ def add_feature(self, value): xml_utils.ElementTree.SubElement(cpu_node, 'feature', {'name': value}) #TODO: Add function to create from xml_utils.TemplateXML() # def new_from_template(...) + + def get_net_all(self): + """ + Return VM's net from XML definition, None if not set + """ + xmltreefile = self.dict_get('xml') + net_nodes = xmltreefile.find('devices').findall('interface') + nets = {} + for node in net_nodes: + dev = node.find('target').get('dev') + nets[dev] = node + return nets + + + @staticmethod + def get_net_dev(vm_name): + """ + Get net device of a defined VM's nets. + + @param: vm_name: Name of defined vm. + """ + vmxml = VMXML.new_from_dumpxml(vm_name) + nets = vmxml.get_net_all() + if nets != None: + return nets.keys() + return None From 4097ead4444e6de2304c398c6a6c3dafe8f51caf Mon Sep 17 00:00:00 2001 From: whuang Date: Fri, 7 Jun 2013 14:20:26 +0800 Subject: [PATCH 012/254] modify some issue according to cevich's suggestion Signed-off-by: whuang --- .../tests/cfg/virsh_domif_setlink_getlink.cfg | 11 ++- libvirt/tests/virsh_domif_setlink_getlink.py | 50 +++++++------ virttest/libvirt_xml/vm_xml.py | 71 +++++++++---------- virttest/virsh.py | 4 +- 4 files changed, 69 insertions(+), 67 deletions(-) diff --git a/libvirt/tests/cfg/virsh_domif_setlink_getlink.cfg b/libvirt/tests/cfg/virsh_domif_setlink_getlink.cfg index c84731720..b63889bed 100644 --- a/libvirt/tests/cfg/virsh_domif_setlink_getlink.cfg +++ b/libvirt/tests/cfg/virsh_domif_setlink_getlink.cfg @@ -3,15 +3,14 @@ variants: - positive_test: status_error = "no" - libvirtd = "on" variants: - domif_setlink: - action = "setlink" + if_action = "setlink" variants: - setlink_up: - operation = "up" + if_operation = "up" - setlink_down: - operation = "down" + if_operation = "down" variants: - running_guest: start_vm = "yes" @@ -34,8 +33,8 @@ - negative_test: status_error = "yes" - action = "setlink" - operation = "up" + if_action = "setlink" + if_operation = "up" if_device = "mac" options = " " variants: diff --git a/libvirt/tests/virsh_domif_setlink_getlink.py b/libvirt/tests/virsh_domif_setlink_getlink.py index fb3947ac2..69ba4158e 100644 --- a/libvirt/tests/virsh_domif_setlink_getlink.py +++ b/libvirt/tests/virsh_domif_setlink_getlink.py @@ -9,34 +9,46 @@ def run_virsh_domif_setlink_getlink(test, params, env): The command set and get link state of a virtual interface 1. Prepare test environment. - 2. When the libvirtd == "off", stop the libvirtd service. - 3. Perform virsh domif-setlink and domif-getlink operation. - 4. Recover test environment. - 5. Confirm the test result. + 2. Perform virsh domif-setlink and domif-getlink operation. + 3. Recover test environment. + 4. Confirm the test result. """ def domif_setlink(vm, device, operation, options): """ + Set the domain link state + + @param: vm : domain name + @param: device : domain virtual interface + @param: opration : domain virtual interface state + @param: options : some options like --config + """ return virsh.domif_setlink(vm, device, operation, options, debug=True) def domif_getlink(vm, device, options): """ + Get the domain link state + + @param: vm : domain name + @param: device : domain virtual interface + @param: options : some options like --config + """ return virsh.domif_getlink(vm, device, options, ignore_status=True, debug=True) - vm_name = params.get("main_vm") + vm_name = params.get("main_vm", "virt-tests-vm1") vm = env.get_vm(vm_name) - options = params.get("options") - start_vm = params.get("start_vm") + options = params.get("options", "--config") + start_vm = params.get("start_vm", "no") libvirtd = params.get("libvirtd", "on") - if_device = params.get("if_device") - if_name = params.get("if_name") - operation = params.get("operation") - status_error = params.get("status_error") + if_device = params.get("if_device", "net") + if_name = params.get("if_name", "vnet0") + if_operation = params.get("if_operation", "up") + status_error = params.get("status_error", "no") mac_address = vm.get_virsh_mac_address(0) device = "vnet0" # Vm status @@ -46,21 +58,17 @@ def domif_getlink(vm, device, options): elif start_vm == "no" and vm.is_alive(): vm.destroy() - if libvirtd == "off": - libvirt_vm.libvirtd_stop() - # Test device net or mac address if if_device == "net" and vm.is_alive(): device = if_name # Get all vm's interface device - net_dev = vm_xml.VMXML.get_net_dev(vm_name) - device = net_dev[0] + device = vm_xml.VMXML.get_net_dev(vm_name)[0] elif if_device == "mac": device = mac_address # Setlink opertation - result = domif_setlink(vm_name, device, operation, options) + result = domif_setlink(vm_name, device, if_operation, options) status = result.exit_status logging.info("Setlink done") @@ -69,7 +77,7 @@ def domif_getlink(vm, device, options): getlink_output = get_result.stdout.strip() # Check the getlink command output - if not re.search(operation, getlink_output) and status_error == "no": + if not re.search(if_operation, getlink_output) and status_error == "no": raise error.TestFail("Getlink result should " "equal with setlink operation ", getlink_output) @@ -88,17 +96,13 @@ def domif_getlink(vm, device, options): # Start vm check the link statue session = vm.wait_for_serial_login() cmd = "ip add |grep -i '%s' -B1|grep -i 'state %s' " \ - % (mac_address, operation) + % (mac_address, if_operation) cmd_status, output = session.cmd_status_output(cmd) logging.info("====%s==%s===", cmd_status, output ) # Set the link up make host connect with vm domif_setlink(vm_name, device, "up", "") session.cmd("service network restart") - # Recover libvirtd service start - if libvirtd == "off": - libvirt_vm.libvirtd_start() - # Check status_error if status_error == "yes": diff --git a/virttest/libvirt_xml/vm_xml.py b/virttest/libvirt_xml/vm_xml.py index da5262627..f204cfee7 100644 --- a/virttest/libvirt_xml/vm_xml.py +++ b/virttest/libvirt_xml/vm_xml.py @@ -372,6 +372,19 @@ def set_vm_vcpus(vm_name, value, virsh_instance=base.virsh): # when it goes out of scope here. + def check_cpu_mode(self, mode): + """ + Check input cpu mode invalid or not. + + @param mode: the mode of cpu:'host-model'... + """ + # Possible values for the mode attribute are: + # "custom", "host-model", "host-passthrough" + cpu_mode = ["custom", "host-model", "host-passthrough"] + if mode.strip() not in cpu_mode: + raise xcepts.LibvirtXMLError("The cpu mode '%s' is invalid!" % mode) + + def get_disk_all(self): """ Return VM's disk from XML definition, None if not set @@ -529,17 +542,31 @@ def get_iface_by_mac(vm_name, mac, virsh_instance=base.virsh): return None - def check_cpu_mode(self, mode): + def get_net_all(self): """ - Check input cpu mode invalid or not. + Return VM's net from XML definition, None if not set + """ + xmltreefile = self.dict_get('xml') + net_nodes = xmltreefile.find('devices').findall('interface') + nets = {} + for node in net_nodes: + dev = node.find('target').get('dev') + nets[dev] = node + return nets - @param mode: the mode of cpu:'host-model'... + #TODO re-visit this method after the libvirt_xml.devices.interface module is implemented + @staticmethod + def get_net_dev(vm_name): """ - # Possible values for the mode attribute are: - # "custom", "host-model", "host-passthrough" - cpu_mode = ["custom", "host-model", "host-passthrough"] - if mode.strip() not in cpu_mode: - raise xcepts.LibvirtXMLError("The cpu mode '%s' is invalid!" % mode) + Get net device of a defined VM's nets. + + @param: vm_name: Name of defined vm. + """ + vmxml = VMXML.new_from_dumpxml(vm_name) + nets = vmxml.get_net_all() + if nets != None: + return nets.keys() + return None @staticmethod @@ -683,31 +710,3 @@ def add_feature(self, value): xmltreefile = self.dict_get('xml') cpu_node = xmltreefile.find('/cpu') xml_utils.ElementTree.SubElement(cpu_node, 'feature', {'name': value}) - #TODO: Add function to create from xml_utils.TemplateXML() - # def new_from_template(...) - - def get_net_all(self): - """ - Return VM's net from XML definition, None if not set - """ - xmltreefile = self.dict_get('xml') - net_nodes = xmltreefile.find('devices').findall('interface') - nets = {} - for node in net_nodes: - dev = node.find('target').get('dev') - nets[dev] = node - return nets - - - @staticmethod - def get_net_dev(vm_name): - """ - Get net device of a defined VM's nets. - - @param: vm_name: Name of defined vm. - """ - vmxml = VMXML.new_from_dumpxml(vm_name) - nets = vmxml.get_net_all() - if nets != None: - return nets.keys() - return None diff --git a/virttest/virsh.py b/virttest/virsh.py index 852a6f159..4a1996cf5 100644 --- a/virttest/virsh.py +++ b/virttest/virsh.py @@ -2095,7 +2095,7 @@ def connect(connect_uri="", options="", **dargs): """ return command("connect %s %s" % (connect_uri, options), **dargs) -def domif_setlink(name, interface, state, options, **dargs): +def domif_setlink(name, interface, state, options=None, **dargs): """ Set network interface stats for a running domain. @@ -2112,7 +2112,7 @@ def domif_setlink(name, interface, state, options, **dargs): return command(cmd, **dargs) -def domif_getlink(name, interface, options, **dargs): +def domif_getlink(name, interface, options=None, **dargs): """ Get network interface stats for a running domain. From 9619b529c114f803cc672e15ab754f3a1e55c5c3 Mon Sep 17 00:00:00 2001 From: Chris Evich Date: Tue, 18 Jun 2013 14:55:48 -0400 Subject: [PATCH 013/254] virt-libvirt: moved virsh_domif_setlink_getlink Signed-off-by: Chris Evich --- .../cfg/{ => virsh_cmd/domain}/virsh_domif_setlink_getlink.cfg | 0 .../{ => src/virsh_cmd/domain}/virsh_domif_setlink_getlink.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename libvirt/tests/cfg/{ => virsh_cmd/domain}/virsh_domif_setlink_getlink.cfg (100%) rename libvirt/tests/{ => src/virsh_cmd/domain}/virsh_domif_setlink_getlink.py (100%) diff --git a/libvirt/tests/cfg/virsh_domif_setlink_getlink.cfg b/libvirt/tests/cfg/virsh_cmd/domain/virsh_domif_setlink_getlink.cfg similarity index 100% rename from libvirt/tests/cfg/virsh_domif_setlink_getlink.cfg rename to libvirt/tests/cfg/virsh_cmd/domain/virsh_domif_setlink_getlink.cfg diff --git a/libvirt/tests/virsh_domif_setlink_getlink.py b/libvirt/tests/src/virsh_cmd/domain/virsh_domif_setlink_getlink.py similarity index 100% rename from libvirt/tests/virsh_domif_setlink_getlink.py rename to libvirt/tests/src/virsh_cmd/domain/virsh_domif_setlink_getlink.py From a282da306a1d522ad3aa41520319fe5d828a906b Mon Sep 17 00:00:00 2001 From: Chris Evich Date: Tue, 18 Jun 2013 14:58:12 -0400 Subject: [PATCH 014/254] virt-libvirt: make test-specific 'options' unambiguous Signed-off-by: Chris Evich --- .../cfg/virsh_cmd/domain/virsh_domif_setlink_getlink.cfg | 8 ++++---- .../src/virsh_cmd/domain/virsh_domif_setlink_getlink.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libvirt/tests/cfg/virsh_cmd/domain/virsh_domif_setlink_getlink.cfg b/libvirt/tests/cfg/virsh_cmd/domain/virsh_domif_setlink_getlink.cfg index b63889bed..b6ebf8e4b 100644 --- a/libvirt/tests/cfg/virsh_cmd/domain/virsh_domif_setlink_getlink.cfg +++ b/libvirt/tests/cfg/virsh_cmd/domain/virsh_domif_setlink_getlink.cfg @@ -19,9 +19,9 @@ no interface_net variants: - no_config: - options = " " + if_options = " " - with_config: - options = "--config" + if_options = "--config" no interface_net no shutoff_guest variants: @@ -36,10 +36,10 @@ if_action = "setlink" if_operation = "up" if_device = "mac" - options = " " + if_options = " " variants: - running_guest_invalid_option: - options = "--xyz" + if_options = "--xyz" start_vm = "yes" - shutoff_guest_with_vnet: start_vm = "no" diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_domif_setlink_getlink.py b/libvirt/tests/src/virsh_cmd/domain/virsh_domif_setlink_getlink.py index 69ba4158e..386930cbf 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_domif_setlink_getlink.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_domif_setlink_getlink.py @@ -42,7 +42,7 @@ def domif_getlink(vm, device, options): vm_name = params.get("main_vm", "virt-tests-vm1") vm = env.get_vm(vm_name) - options = params.get("options", "--config") + options = params.get("if_options", "--config") start_vm = params.get("start_vm", "no") libvirtd = params.get("libvirtd", "on") if_device = params.get("if_device", "net") From acf70ef141fd445d8f0cedb7f943832dc15ec29b Mon Sep 17 00:00:00 2001 From: Chris Evich Date: Mon, 1 Jul 2013 09:56:27 -0400 Subject: [PATCH 015/254] virt-libvirt: restart specific interface in virsh_domif_setlink_getlink Signed-off-by: Chris Evich --- .../domain/virsh_domif_setlink_getlink.cfg | 1 + .../domain/virsh_domif_setlink_getlink.py | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/libvirt/tests/cfg/virsh_cmd/domain/virsh_domif_setlink_getlink.cfg b/libvirt/tests/cfg/virsh_cmd/domain/virsh_domif_setlink_getlink.cfg index b6ebf8e4b..4c687c771 100644 --- a/libvirt/tests/cfg/virsh_cmd/domain/virsh_domif_setlink_getlink.cfg +++ b/libvirt/tests/cfg/virsh_cmd/domain/virsh_domif_setlink_getlink.cfg @@ -1,5 +1,6 @@ - virsh_domif_setlink_getlink: type = virsh_domif_setlink_getlink + if_ifname_re = "\s*\d+:\s+([[a-zA-Z]+\d+):" variants: - positive_test: status_error = "no" diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_domif_setlink_getlink.py b/libvirt/tests/src/virsh_cmd/domain/virsh_domif_setlink_getlink.py index 386930cbf..b0cc0892d 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_domif_setlink_getlink.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_domif_setlink_getlink.py @@ -44,10 +44,11 @@ def domif_getlink(vm, device, options): vm = env.get_vm(vm_name) options = params.get("if_options", "--config") start_vm = params.get("start_vm", "no") - libvirtd = params.get("libvirtd", "on") if_device = params.get("if_device", "net") if_name = params.get("if_name", "vnet0") if_operation = params.get("if_operation", "up") + if_name_re = params.get("if_ifname_re", + r"\s*\d+:\s+([[a-zA-Z]+\d+):") status_error = params.get("status_error", "no") mac_address = vm.get_virsh_mac_address(0) device = "vnet0" @@ -95,13 +96,23 @@ def domif_getlink(vm, device, options): # Serial login the vm to check link status # Start vm check the link statue session = vm.wait_for_serial_login() - cmd = "ip add |grep -i '%s' -B1|grep -i 'state %s' " \ - % (mac_address, if_operation) + cmd = ("ip add |grep -i '%s' -B1|grep -i 'state %s' " + % (mac_address, if_operation)) cmd_status, output = session.cmd_status_output(cmd) logging.info("====%s==%s===", cmd_status, output ) # Set the link up make host connect with vm domif_setlink(vm_name, device, "up", "") - session.cmd("service network restart") + # Bring up referenced guest nic + guest_if_name = re.search(if_name_re, output).group(1) + # Ignore status of this one + cmd_status = session.cmd_status('ifdown %s' % guest_if_name) + cmd_status = session.cmd_status('ifup %s' % guest_if_name) + if cmd_status != 0: + raise error.TestFail("Could not bring up interface %s inside guest" + % guest_if_name) + else: # negative test + # stop guest, so state is always consistent on next start + vm.destroy() # Check status_error From 75a5b02bb4c45a0c582368b098fb801d488d17fd Mon Sep 17 00:00:00 2001 From: Feng Yang Date: Wed, 23 May 2012 11:56:42 +0000 Subject: [PATCH 016/254] shared.unattended: Do not use python script in RHELs' kickstart We just run some bash command in python. So directly run these command in post script. Signed-off-by: Feng Yang Acked-by: Xiaoqing Wei Signed-off-by: Qingtang Zhou --- shared/unattended/RHEL-3-series.ks | 23 ++++++++++++----- shared/unattended/RHEL-4-series.ks | 41 ++++++++++++++++++++++-------- shared/unattended/RHEL-5-series.ks | 28 ++++++++++++++------ shared/unattended/RHEL-6-series.ks | 20 ++++++++------- shared/unattended/RHEL-6.3.ks | 29 +++++++++++---------- 5 files changed, 93 insertions(+), 48 deletions(-) diff --git a/shared/unattended/RHEL-3-series.ks b/shared/unattended/RHEL-3-series.ks index 89903b57c..3a8af3ee7 100644 --- a/shared/unattended/RHEL-3-series.ks +++ b/shared/unattended/RHEL-3-series.ks @@ -21,12 +21,21 @@ skipx @ base @ development-libs @ development-tools +gcc +patch +make +nc ntp +redhat-lsb -%post --interpreter /usr/bin/python -import os -os.system('/sbin/ifconfig eth0 10.0.2.15 netmask 255.255.255.0 up') -os.system('/sbin/route add default gw 10.0.2.2') -os.system('chkconfig sshd on') -os.system('echo Post set up finished > /dev/ttyS0') -os.system('echo Post set up finished > /dev/hvc0') +%post +echo "OS install is completed" > /dev/ttyS0 +cd home +echo "s0:2345:respawn:/sbin/agetty -L -f /etc/issue 115200 ttyS0 vt100" >> /etc/inittab +echo "ttyS0" >> /etc/securetty +dhclient +chkconfig sshd on +sed -i "/^HWADDR/d" /etc/sysconfig/network-scripts/ifcfg-eth0 +echo 'Post set up finished' > /dev/ttyS0 +echo Post set up finished > /dev/hvc0 +%end diff --git a/shared/unattended/RHEL-4-series.ks b/shared/unattended/RHEL-4-series.ks index 03890ea23..357dceb5e 100644 --- a/shared/unattended/RHEL-4-series.ks +++ b/shared/unattended/RHEL-4-series.ks @@ -7,7 +7,7 @@ langsupport --default=en_US.UTF-8 en_US.UTF-9 keyboard us network --bootproto dhcp rootpw 123456 -firewall --enabled --ssh +firewall --disabled selinux --enforcing timezone --utc America/New_York firstboot --disable @@ -19,15 +19,34 @@ poweroff %packages @ base -@ development-libs -@ development-tools +@development-libs +@development-tools +gcc4 +gcc4-gfortran +patch +make +nc ntp +redhat-lsb -%post --interpreter /usr/bin/python -import os -os.system('dhclient') -os.system('chkconfig sshd on') -os.system('iptables -F') -os.system('echo 0 > /selinux/enforce') -os.system('echo Post set up finished > /dev/ttyS0') -os.system('echo Post set up finished > /dev/hvc0') +%post +echo "OS install is completed" > /dev/ttyS0 +cd home +dhclient +chkconfig sshd on +iptables -F +echo 0 > selinux/enforce +sed -i '/^HWADDR/d' /etc/sysconfig/network-scripts/ifcfg-eth0 +echo "s0:2345:respawn:/sbin/agetty -L -f /etc/issue 115200 ttyS0 vt100" >> /etc/inittab +echo "ttyS0" >> /etc/securetty +wget http://www.python.org/ftp/python/2.6.6/Python-2.6.6.tar.bz2 +tar xjf Python-2.6.6.tar.bz2 +cd Python-2.6.6 +./configure --prefix=/usr/local --exec-prefix=/usr/local +make +make install +ln -sf /usr/local/bin/python /usr/bin/python +sleep 10 +echo 'Post set up finished' > /dev/ttyS0 +echo Post set up finished > /dev/hvc0 +%end diff --git a/shared/unattended/RHEL-5-series.ks b/shared/unattended/RHEL-5-series.ks index 8edb03990..641f832b0 100644 --- a/shared/unattended/RHEL-5-series.ks +++ b/shared/unattended/RHEL-5-series.ks @@ -22,15 +22,27 @@ KVM_TEST_LOGGING @base @development-libs @development-tools +@gnome-desktop +@base-x +@core +xorg-x11-utils +xorg-x11-server-Xnest kexec-tools watchdog +gcc +patch +make +nc ntp +redhat-lsb -%post --interpreter /usr/bin/python -import os -os.system('dhclient') -os.system('chkconfig sshd on') -os.system('iptables -F') -os.system('echo 0 > /selinux/enforce') -os.system('echo Post set up finished > /dev/ttyS0') -os.system('echo Post set up finished > /dev/hvc0') +%post +echo "OS install is completed" > /dev/ttyS0 +dhclient +chkconfig sshd on +iptables -F +echo 0 > /selinux/enforce +sed -i "/^HWADDR/d" /etc/sysconfig/network-scripts/ifcfg-eth0 +echo 'Post set up finished' > /dev/ttyS0 +echo Post set up finished > /dev/hvc0 +%end diff --git a/shared/unattended/RHEL-6-series.ks b/shared/unattended/RHEL-6-series.ks index 9d7fe5bef..24dbf3f03 100644 --- a/shared/unattended/RHEL-6-series.ks +++ b/shared/unattended/RHEL-6-series.ks @@ -31,12 +31,14 @@ watchdog coreutils usbutils -%post --interpreter /usr/bin/python -import os -os.system('grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel)') -os.system('dhclient') -os.system('chkconfig sshd on') -os.system('iptables -F') -os.system('echo 0 > /selinux/enforce') -os.system('echo Post set up finished > /dev/ttyS0') -os.system('echo Post set up finished > /dev/hvc0') +%post +echo "OS install is completed" > /dev/ttyS0 +grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel) +dhclient +chkconfig sshd on +iptables -F +echo 0 > /selinux/enforce +chkconfig NetworkManager on +sed -i "/^HWADDR/d" /etc/sysconfig/network-scripts/ifcfg-eth0 +echo 'Post set up finished' > /dev/ttyS0 +echo Post set up finished > /dev/hvc0 diff --git a/shared/unattended/RHEL-6.3.ks b/shared/unattended/RHEL-6.3.ks index 576f27cf9..00cf1d8f3 100644 --- a/shared/unattended/RHEL-6.3.ks +++ b/shared/unattended/RHEL-6.3.ks @@ -41,17 +41,20 @@ usbredir SDL %end -%post --nochroot --interpreter /usr/bin/python -import os -os.system('grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel)') -os.system('dhclient') -os.system('chkconfig sshd on') -os.system('iptables -F') -os.system('echo 0 > /selinux/enforce') -os.system('echo Post set up finished > /dev/ttyS0') -os.system('echo Post set up finished > /dev/hvc0') -f = open('/mnt/sysimage/etc/gdm/custom.conf','w') -f.write('[daemon]\n' - 'AutomaticLogin=test\n' - 'AutomaticLoginEnable=True\n') +%post +echo "OS install is completed" > /dev/ttyS0 +grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel) +dhclient +chkconfig sshd on +iptables -F +echo 0 > /selinux/enforce +chkconfig NetworkManager on +sed -i "/^HWADDR/d" /etc/sysconfig/network-scripts/ifcfg-eth0 +echo 'Post set up finished' > /dev/ttyS0 +echo Post set up finished > /dev/hvc0 +cat > '/mnt/sysimage/etc/gdm/custom.conf' << EOF +[daemon] +AutomaticLogin=test +AutomaticLoginEnable=True +EOF %end From 9daa8f5f28601b62c4c8403e8da1c19cda8b194d Mon Sep 17 00:00:00 2001 From: Qingtang Zhou Date: Mon, 1 Jul 2013 23:07:13 +0800 Subject: [PATCH 017/254] shared.unattended: Do not use python script in Fedoras' kickstart Signed-off-by: Qingtang Zhou --- shared/unattended/Fedora-10.ks | 19 ++++----- shared/unattended/Fedora-11.ks | 19 ++++----- shared/unattended/Fedora-12.ks | 19 ++++----- shared/unattended/Fedora-13.ks | 19 ++++----- shared/unattended/Fedora-14.ks | 19 ++++----- shared/unattended/Fedora-15.ks | 19 ++++----- shared/unattended/Fedora-16.ks | 19 ++++----- shared/unattended/Fedora-17.ks | 19 ++++----- shared/unattended/Fedora-18.ks | 22 +++++------ shared/unattended/Fedora-8.ks | 19 ++++----- shared/unattended/Fedora-9.ks | 19 ++++----- shared/unattended/Fedora-test.ks | 19 ++++----- shared/unattended/JeOS-17.ks | 67 ++++++++++++++++---------------- 13 files changed, 155 insertions(+), 143 deletions(-) diff --git a/shared/unattended/Fedora-10.ks b/shared/unattended/Fedora-10.ks index 2cabb9445..5a5ae0640 100644 --- a/shared/unattended/Fedora-10.ks +++ b/shared/unattended/Fedora-10.ks @@ -24,12 +24,13 @@ poweroff @development-tools ntpdate -%post --interpreter /usr/bin/python -import os -os.system('grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel)') -os.system('dhclient') -os.system('chkconfig sshd on') -os.system('iptables -F') -os.system('echo 0 > /selinux/enforce') -os.system('echo Post set up finished > /dev/ttyS0') -os.system('echo Post set up finished > /dev/hvc0') +%post +echo "OS install is completed" > /dev/ttyS0 +grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel) +dhclient +chkconfig sshd on +iptables -F +echo 0 > /selinux/enforce +sed -i "/^HWADDR/d" /etc/sysconfig/network-scripts/ifcfg-eth0 +echo 'Post set up finished' > /dev/ttyS0 +echo Post set up finished > /dev/hvc0 diff --git a/shared/unattended/Fedora-11.ks b/shared/unattended/Fedora-11.ks index d5a1523c7..5a90ae65a 100644 --- a/shared/unattended/Fedora-11.ks +++ b/shared/unattended/Fedora-11.ks @@ -24,13 +24,14 @@ autopart ntpdate %end -%post --interpreter /usr/bin/python -import os -os.system('grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel)') -os.system('dhclient') -os.system('chkconfig sshd on') -os.system('iptables -F') -os.system('echo 0 > /selinux/enforce') -os.system('echo Post set up finished > /dev/ttyS0') -os.system('echo Post set up finished > /dev/hvc0') +%post +echo "OS install is completed" > /dev/ttyS0 +grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel) +dhclient +chkconfig sshd on +iptables -F +echo 0 > /selinux/enforce +sed -i "/^HWADDR/d" /etc/sysconfig/network-scripts/ifcfg-eth0 +echo 'Post set up finished' > /dev/ttyS0 +echo Post set up finished > /dev/hvc0 %end diff --git a/shared/unattended/Fedora-12.ks b/shared/unattended/Fedora-12.ks index d5a1523c7..5a90ae65a 100644 --- a/shared/unattended/Fedora-12.ks +++ b/shared/unattended/Fedora-12.ks @@ -24,13 +24,14 @@ autopart ntpdate %end -%post --interpreter /usr/bin/python -import os -os.system('grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel)') -os.system('dhclient') -os.system('chkconfig sshd on') -os.system('iptables -F') -os.system('echo 0 > /selinux/enforce') -os.system('echo Post set up finished > /dev/ttyS0') -os.system('echo Post set up finished > /dev/hvc0') +%post +echo "OS install is completed" > /dev/ttyS0 +grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel) +dhclient +chkconfig sshd on +iptables -F +echo 0 > /selinux/enforce +sed -i "/^HWADDR/d" /etc/sysconfig/network-scripts/ifcfg-eth0 +echo 'Post set up finished' > /dev/ttyS0 +echo Post set up finished > /dev/hvc0 %end diff --git a/shared/unattended/Fedora-13.ks b/shared/unattended/Fedora-13.ks index d5a1523c7..5a90ae65a 100644 --- a/shared/unattended/Fedora-13.ks +++ b/shared/unattended/Fedora-13.ks @@ -24,13 +24,14 @@ autopart ntpdate %end -%post --interpreter /usr/bin/python -import os -os.system('grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel)') -os.system('dhclient') -os.system('chkconfig sshd on') -os.system('iptables -F') -os.system('echo 0 > /selinux/enforce') -os.system('echo Post set up finished > /dev/ttyS0') -os.system('echo Post set up finished > /dev/hvc0') +%post +echo "OS install is completed" > /dev/ttyS0 +grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel) +dhclient +chkconfig sshd on +iptables -F +echo 0 > /selinux/enforce +sed -i "/^HWADDR/d" /etc/sysconfig/network-scripts/ifcfg-eth0 +echo 'Post set up finished' > /dev/ttyS0 +echo Post set up finished > /dev/hvc0 %end diff --git a/shared/unattended/Fedora-14.ks b/shared/unattended/Fedora-14.ks index f684d7ab5..9afbdf55f 100644 --- a/shared/unattended/Fedora-14.ks +++ b/shared/unattended/Fedora-14.ks @@ -25,13 +25,14 @@ ntpdate dmidecode %end -%post --interpreter /usr/bin/python -import os -os.system('grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel)') -os.system('dhclient') -os.system('chkconfig sshd on') -os.system('iptables -F') -os.system('echo 0 > /selinux/enforce') -os.system('echo Post set up finished > /dev/ttyS0') -os.system('echo Post set up finished > /dev/hvc0') +%post +echo "OS install is completed" > /dev/ttyS0 +grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel) +dhclient +chkconfig sshd on +iptables -F +echo 0 > /selinux/enforce +sed -i "/^HWADDR/d" /etc/sysconfig/network-scripts/ifcfg-eth0 +echo 'Post set up finished' > /dev/ttyS0 +echo Post set up finished > /dev/hvc0 %end diff --git a/shared/unattended/Fedora-15.ks b/shared/unattended/Fedora-15.ks index f8ff7f475..4ea002dcb 100644 --- a/shared/unattended/Fedora-15.ks +++ b/shared/unattended/Fedora-15.ks @@ -26,13 +26,14 @@ ntpdate dmidecode %end -%post --interpreter /usr/bin/python -import os -os.system('grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel)') -os.system('dhclient') -os.system('chkconfig sshd on') -os.system('iptables -F') -os.system('echo 0 > /selinux/enforce') -os.system('echo Post set up finished > /dev/ttyS0') -os.system('echo Post set up finished > /dev/hvc0') +%post +echo "OS install is completed" > /dev/ttyS0 +grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel) +dhclient +chkconfig sshd on +iptables -F +echo 0 > /selinux/enforce +sed -i "/^HWADDR/d" /etc/sysconfig/network-scripts/ifcfg-eth0 +echo 'Post set up finished' > /dev/ttyS0 +echo Post set up finished > /dev/hvc0 %end diff --git a/shared/unattended/Fedora-16.ks b/shared/unattended/Fedora-16.ks index 8b9ca73bc..9f7ba0ca7 100644 --- a/shared/unattended/Fedora-16.ks +++ b/shared/unattended/Fedora-16.ks @@ -24,13 +24,14 @@ autopart @development-tools %end -%post --interpreter /usr/bin/python -import os -os.system('grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel)') -os.system('dhclient') -os.system('chkconfig sshd on') -os.system('iptables -F') -os.system('echo 0 > /selinux/enforce') -os.system('echo Post set up finished > /dev/ttyS0') -os.system('echo Post set up finished > /dev/hvc0') +%post +echo "OS install is completed" > /dev/ttyS0 +grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel) +dhclient +chkconfig sshd on +iptables -F +echo 0 > /selinux/enforce +sed -i "/^HWADDR/d" /etc/sysconfig/network-scripts/ifcfg-eth0 +echo 'Post set up finished' > /dev/ttyS0 +echo Post set up finished > /dev/hvc0 %end diff --git a/shared/unattended/Fedora-17.ks b/shared/unattended/Fedora-17.ks index f98a3a7f7..c0a612cc3 100644 --- a/shared/unattended/Fedora-17.ks +++ b/shared/unattended/Fedora-17.ks @@ -25,13 +25,14 @@ autopart dmidecode %end -%post --interpreter /usr/bin/python -import os -os.system('grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel)') -os.system('dhclient') -os.system('chkconfig sshd on') -os.system('iptables -F') -os.system('echo 0 > /selinux/enforce') -os.system('echo Post set up finished > /dev/ttyS0') -os.system('echo Post set up finished > /dev/hvc0') +%post +echo "OS install is completed" > /dev/ttyS0 +grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel) +dhclient +chkconfig sshd on +iptables -F +echo 0 > /selinux/enforce +sed -i "/^HWADDR/d" /etc/sysconfig/network-scripts/ifcfg-eth0 +echo 'Post set up finished' > /dev/ttyS0 +echo Post set up finished > /dev/hvc0 %end diff --git a/shared/unattended/Fedora-18.ks b/shared/unattended/Fedora-18.ks index 4d1f93b06..093f278b6 100644 --- a/shared/unattended/Fedora-18.ks +++ b/shared/unattended/Fedora-18.ks @@ -25,15 +25,15 @@ autopart dmidecode %end -%post --interpreter /usr/bin/python -import os -os.system('grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel)') -os.system('dhclient') -os.system('chkconfig sshd on') -os.system('iptables -F') -os.system('systemctl mask tmp.mount') - -os.system('echo 0 > /selinux/enforce') -os.system('echo Post set up finished > /dev/ttyS0') -os.system('echo Post set up finished > /dev/hvc0') +%post +echo "OS install is completed" > /dev/ttyS0 +grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel) +dhclient +chkconfig sshd on +iptables -F +systemctl mask tmp.mount +echo 0 > /selinux/enforce +sed -i "/^HWADDR/d" /etc/sysconfig/network-scripts/ifcfg-eth0 +echo 'Post set up finished' > /dev/ttyS0 +echo Post set up finished > /dev/hvc0 %end diff --git a/shared/unattended/Fedora-8.ks b/shared/unattended/Fedora-8.ks index 0ed5fc53e..09d82b2b8 100644 --- a/shared/unattended/Fedora-8.ks +++ b/shared/unattended/Fedora-8.ks @@ -23,12 +23,13 @@ reboot @development-tools ntpdate -%post --interpreter /usr/bin/python -import os -os.system('grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel)') -os.system('dhclient') -os.system('chkconfig sshd on') -os.system('iptables -F') -os.system('echo 0 > /selinux/enforce') -os.system('echo Post set up finished > /dev/ttyS0') -os.system('echo Post set up finished > /dev/hvc0') +%post +echo "OS install is completed" > /dev/ttyS0 +grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel) +dhclient +chkconfig sshd on +iptables -F +echo 0 > /selinux/enforce +sed -i "/^HWADDR/d" /etc/sysconfig/network-scripts/ifcfg-eth0 +echo 'Post set up finished' > /dev/ttyS0 +echo Post set up finished > /dev/hvc0 diff --git a/shared/unattended/Fedora-9.ks b/shared/unattended/Fedora-9.ks index 2cabb9445..5a5ae0640 100644 --- a/shared/unattended/Fedora-9.ks +++ b/shared/unattended/Fedora-9.ks @@ -24,12 +24,13 @@ poweroff @development-tools ntpdate -%post --interpreter /usr/bin/python -import os -os.system('grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel)') -os.system('dhclient') -os.system('chkconfig sshd on') -os.system('iptables -F') -os.system('echo 0 > /selinux/enforce') -os.system('echo Post set up finished > /dev/ttyS0') -os.system('echo Post set up finished > /dev/hvc0') +%post +echo "OS install is completed" > /dev/ttyS0 +grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel) +dhclient +chkconfig sshd on +iptables -F +echo 0 > /selinux/enforce +sed -i "/^HWADDR/d" /etc/sysconfig/network-scripts/ifcfg-eth0 +echo 'Post set up finished' > /dev/ttyS0 +echo Post set up finished > /dev/hvc0 diff --git a/shared/unattended/Fedora-test.ks b/shared/unattended/Fedora-test.ks index 8bf1426fa..f382d4616 100644 --- a/shared/unattended/Fedora-test.ks +++ b/shared/unattended/Fedora-test.ks @@ -25,13 +25,14 @@ autopart dmidecode %end -%post --interpreter /usr/bin/python -import os -os.system('grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel)') -os.system('dhclient') -os.system('chkconfig sshd on') -os.system('iptables -F') -os.system('echo 0 > /selinux/enforce') -os.system('echo Post set up finished > /dev/ttyS0') -os.system('echo Post set up finished > /dev/hvc0') +%post +echo "OS install is completed" > /dev/ttyS0 +grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel) +dhclient +chkconfig sshd on +iptables -F +echo 0 > /selinux/enforce +sed -i "/^HWADDR/d" /etc/sysconfig/network-scripts/ifcfg-eth0 +echo 'Post set up finished' > /dev/ttyS0 +echo Post set up finished > /dev/hvc0 %end diff --git a/shared/unattended/JeOS-17.ks b/shared/unattended/JeOS-17.ks index 6c257766d..27aad8340 100644 --- a/shared/unattended/JeOS-17.ks +++ b/shared/unattended/JeOS-17.ks @@ -168,37 +168,38 @@ usbutils -rsyslog %end -%post --interpreter /usr/bin/python -import os -os.system('grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel)') -os.system('echo 0 > /selinux/enforce') -os.system('systemctl enable sshd.service') -os.system('systemctl mask fedora-wait-storage.service') -os.system('systemctl mask fedora-storage-init-late.service') -os.system('systemctl mask fedora-storage-init.service') -os.system('systemctl mask fedora-autoswap.service') -os.system('systemctl mask fedora-configure.service') -os.system('systemctl mask fedora-loadmodules.service') -os.system('systemctl mask fedora-readonly.service') -os.system('systemctl mask systemd-readahead-collect.service') -os.system('systemctl mask plymouth-start.service') -os.system('systemctl mask network.service') -os.system('systemctl mask remote-fs.target') -os.system('systemctl mask cryptsetup.target') -os.system('systemctl mask sys-devices-virtual-tty-tty2.device') -os.system('systemctl mask sys-devices-virtual-tty-tty3.device') -os.system('systemctl mask sys-devices-virtual-tty-tty4.device') -os.system('systemctl mask sys-devices-virtual-tty-tty5.device') -os.system('systemctl mask sys-devices-virtual-tty-tty6.device') -os.system('systemctl mask sys-devices-virtual-tty-tty7.device') -os.system('systemctl mask sys-devices-virtual-tty-tty8.device') -os.system('systemctl mask sys-devices-virtual-tty-tty9.device') -os.system('systemctl mask sys-devices-virtual-tty-tty10.device') -os.system('systemctl mask sys-devices-virtual-tty-tty11.device') -os.system('systemctl mask sys-devices-virtual-tty-tty12.device') -os.system('yum install -y hdparm ntpdate') -os.system('yum clean all') -os.system('mkdir -p /var/log/journal') -os.system('echo Post set up finished > /dev/ttyS0') -os.system('echo Post set up finished > /dev/hvc0') +%post +echo "OS install is completed" > /dev/ttyS0 +grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel) +echo 0 > /selinux/enforce +sed -i "/^HWADDR/d" /etc/sysconfig/network-scripts/ifcfg-eth0 +systemctl enable sshd.service +systemctl mask fedora-wait-storage.service +systemctl mask fedora-storage-init-late.service +systemctl mask fedora-storage-init.service +systemctl mask fedora-autoswap.service +systemctl mask fedora-configure.service +systemctl mask fedora-loadmodules.service +systemctl mask fedora-readonly.service +systemctl mask systemd-readahead-collect.service +systemctl mask plymouth-start.service +systemctl mask network.service +systemctl mask remote-fs.target +systemctl mask cryptsetup.target +systemctl mask sys-devices-virtual-tty-tty2.device +systemctl mask sys-devices-virtual-tty-tty3.device +systemctl mask sys-devices-virtual-tty-tty4.device +systemctl mask sys-devices-virtual-tty-tty5.device +systemctl mask sys-devices-virtual-tty-tty6.device +systemctl mask sys-devices-virtual-tty-tty7.device +systemctl mask sys-devices-virtual-tty-tty8.device +systemctl mask sys-devices-virtual-tty-tty9.device +systemctl mask sys-devices-virtual-tty-tty10.device +systemctl mask sys-devices-virtual-tty-tty11.device +systemctl mask sys-devices-virtual-tty-tty12.device +yum install -y hdparm ntpdate +yum clean all +mkdir -p /var/log/journal +echo 'Post set up finished' > /dev/ttyS0 +echo Post set up finished > /dev/hvc0 %end From 3bed0284fe16e115c554f60f7265ffa12f470613 Mon Sep 17 00:00:00 2001 From: Qingtang Zhou Date: Tue, 23 Oct 2012 13:40:13 +0000 Subject: [PATCH 018/254] virt.ks: Add qemu-guest-agent package in RHEL6's kickstart file qemu-guest-agent package exists in the cd image after RHEL6.3, thus install it directly in guest installation stage. For those RHEL6 guest before RHEL6.3, add a "ignoremissing" option to let them ignore this new package. Signed-off-by: Qingtang Zhou Acked-by: Feng Yang --- shared/unattended/RHEL-6-series.ks | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shared/unattended/RHEL-6-series.ks b/shared/unattended/RHEL-6-series.ks index 24dbf3f03..1af3f0638 100644 --- a/shared/unattended/RHEL-6-series.ks +++ b/shared/unattended/RHEL-6-series.ks @@ -18,7 +18,7 @@ autopart poweroff KVM_TEST_LOGGING -%packages +%packages --ignoremissing @base @core @development @@ -30,6 +30,7 @@ ntpdate watchdog coreutils usbutils +qemu-guest-agent %post echo "OS install is completed" > /dev/ttyS0 From 02b189733f5205d07d229ca0e871ad3ab8c5cdcb Mon Sep 17 00:00:00 2001 From: Xiaoqing Wei Date: Tue, 18 Dec 2012 12:13:43 +0000 Subject: [PATCH 019/254] shared.unattended: Use fixed partition for RHEL5/6 guests Currently we use autopart in all rhel guests, which bring trouble when RHEL5 RHEL6 guests w/ huge(64+G) RAM. The swap partition will be really huge and not enough space for the root partition, thus installation fails. (we met this problem on huge RAM host before). With this patch, the RHEL5 RHEL6 guest will have only 2 physical partitions(/boot, PV), and the PV contains 2 LVs(/, swap). | | / |swap| |/boot|----LVM----| | | PV | |---------------- | |guest hard drive | Note: 1) we can use plain partitions here (w/o LVM) to gain the possible tiny performance improvement, but I prefer to choose the LVM scheme, a little bit complex partioning scheme but test more (also testing the lvm layer). 2) RHEL3, RHEL4, RHEL7 kickstart config didn't update here, because: The default kernel shipped w/ RHEL3, RHEL4 dont support such huge RAM, so they will not met this issue. The anaconda of RHEL7 looks fixed this problem, install w/ autopart will not create a huge swap partition. Signed-off-by: Xiaoqing Wei Acked-by: Suqin Huang Signed-off-by: Qingtang Zhou --- shared/unattended/RHEL-5-series.ks | 7 ++++++- shared/unattended/RHEL-6-series.ks | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/shared/unattended/RHEL-5-series.ks b/shared/unattended/RHEL-5-series.ks index 641f832b0..727fdd237 100644 --- a/shared/unattended/RHEL-5-series.ks +++ b/shared/unattended/RHEL-5-series.ks @@ -13,8 +13,13 @@ timezone --utc America/New_York firstboot --disable bootloader --location=mbr --append="console=tty0 console=ttyS0,115200" zerombr +#partitioning clearpart --all --initlabel -autopart +part /boot --fstype=ext3 --size=500 +part pv.01 --grow --size=1 +volgroup VolGroup --pesize=131072 pv.01 +logvol swap --name=LogVol_swap --vgname=VolGroup --size=4096 +logvol / --fstype=ext4 --name=LogVol_root --vgname=VolGroup --size=1 --grow poweroff KVM_TEST_LOGGING diff --git a/shared/unattended/RHEL-6-series.ks b/shared/unattended/RHEL-6-series.ks index 1af3f0638..feeefd954 100644 --- a/shared/unattended/RHEL-6-series.ks +++ b/shared/unattended/RHEL-6-series.ks @@ -13,8 +13,13 @@ timezone --utc America/New_York firstboot --disable bootloader --location=mbr --append="console=tty0 console=ttyS0,115200" zerombr +#partitioning clearpart --all --initlabel -autopart +part /boot --fstype=ext4 --size=500 +part pv.01 --grow --size=1 +volgroup VolGroup --pesize=131072 pv.01 +logvol swap --name=LogVol_swap --vgname=VolGroup --size=4096 +logvol / --fstype=ext4 --name=LogVol_root --vgname=VolGroup --size=1 --grow poweroff KVM_TEST_LOGGING From e61cf72d2b8b283fa10dc15f6ea4cb5965cb0539 Mon Sep 17 00:00:00 2001 From: tian xu Date: Sun, 9 Jun 2013 09:19:16 +0000 Subject: [PATCH 020/254] shared.unattended: Add package sg3_utils sg3_utils is requried by scsi_testsuite test, so include it in unattended install files. Signed-off-by: Xu Tian Acked-by: Xiaoqing Wei Signed-off-by: Qingtang Zhou --- shared/unattended/Fedora-18.ks | 1 + shared/unattended/Fedora-test.ks | 1 + shared/unattended/OpenSUSE-11.xml | 1 + shared/unattended/OpenSUSE-12.xml | 1 + shared/unattended/RHEL-5-series.ks | 1 + shared/unattended/RHEL-6-series.ks | 1 + shared/unattended/SLES-10.xml | 1 + shared/unattended/SLES-11-SP2.xml | 1 + shared/unattended/SLES-11.xml | 1 + shared/unattended/Ubuntu-11-04.preseed | 2 +- shared/unattended/Ubuntu-11-10.preseed | 2 +- shared/unattended/Ubuntu-12-04.preseed | 2 +- shared/unattended/Ubuntu-12-10.preseed | 2 +- shared/unattended/Ubuntu-13-04.preseed | 2 +- 14 files changed, 14 insertions(+), 5 deletions(-) diff --git a/shared/unattended/Fedora-18.ks b/shared/unattended/Fedora-18.ks index 093f278b6..c2729e47c 100644 --- a/shared/unattended/Fedora-18.ks +++ b/shared/unattended/Fedora-18.ks @@ -23,6 +23,7 @@ autopart @development-libs @development-tools dmidecode +sg3_utils %end %post diff --git a/shared/unattended/Fedora-test.ks b/shared/unattended/Fedora-test.ks index f382d4616..aca885c70 100644 --- a/shared/unattended/Fedora-test.ks +++ b/shared/unattended/Fedora-test.ks @@ -23,6 +23,7 @@ autopart @development-libs @development-tools dmidecode +sg3_utils %end %post diff --git a/shared/unattended/OpenSUSE-11.xml b/shared/unattended/OpenSUSE-11.xml index 0f11ac9ce..a67aed6bd 100644 --- a/shared/unattended/OpenSUSE-11.xml +++ b/shared/unattended/OpenSUSE-11.xml @@ -181,6 +181,7 @@ service sshd restart autoyast2-installation dhcp-client dhcp-tools + sg3_utils autoyast2-installation autoyast2-installation autoyast2-installation diff --git a/shared/unattended/OpenSUSE-12.xml b/shared/unattended/OpenSUSE-12.xml index 089c70b21..12721e76b 100644 --- a/shared/unattended/OpenSUSE-12.xml +++ b/shared/unattended/OpenSUSE-12.xml @@ -189,6 +189,7 @@ service sshd restart autoyast2-installation dhcp-client dhcp-tools + sg3_utils autoyast2-installation autoyast2-installation autoyast2-installation diff --git a/shared/unattended/RHEL-5-series.ks b/shared/unattended/RHEL-5-series.ks index 727fdd237..bc541046b 100644 --- a/shared/unattended/RHEL-5-series.ks +++ b/shared/unattended/RHEL-5-series.ks @@ -40,6 +40,7 @@ make nc ntp redhat-lsb +sg3_utils %post echo "OS install is completed" > /dev/ttyS0 diff --git a/shared/unattended/RHEL-6-series.ks b/shared/unattended/RHEL-6-series.ks index feeefd954..291ad3a2a 100644 --- a/shared/unattended/RHEL-6-series.ks +++ b/shared/unattended/RHEL-6-series.ks @@ -36,6 +36,7 @@ watchdog coreutils usbutils qemu-guest-agent +sg3_utils %post echo "OS install is completed" > /dev/ttyS0 diff --git a/shared/unattended/SLES-10.xml b/shared/unattended/SLES-10.xml index cb334b476..9cdf043ea 100644 --- a/shared/unattended/SLES-10.xml +++ b/shared/unattended/SLES-10.xml @@ -552,6 +552,7 @@ service network restart dhcp-client + sg3_utils Basis-Devel diff --git a/shared/unattended/SLES-11-SP2.xml b/shared/unattended/SLES-11-SP2.xml index dbd4fc4ab..304da717c 100644 --- a/shared/unattended/SLES-11-SP2.xml +++ b/shared/unattended/SLES-11-SP2.xml @@ -552,6 +552,7 @@ service sshd restart dhcp-client open-iscsi + sg3_utils Basis-Devel diff --git a/shared/unattended/SLES-11.xml b/shared/unattended/SLES-11.xml index 1af65864d..fad360f48 100644 --- a/shared/unattended/SLES-11.xml +++ b/shared/unattended/SLES-11.xml @@ -581,6 +581,7 @@ ycpc -c Packages.ycp dhcp-client patch + sg3_utils Basis-Devel diff --git a/shared/unattended/Ubuntu-11-04.preseed b/shared/unattended/Ubuntu-11-04.preseed index c7ececca4..e846ce0b8 100644 --- a/shared/unattended/Ubuntu-11-04.preseed +++ b/shared/unattended/Ubuntu-11-04.preseed @@ -30,7 +30,7 @@ d-i mirror/udeb/components multiselect main, restricted, universe, multiverse tasksel tasksel/first multiselect standard -d-i pkgsel/include string openssh-server build-essential lvm2 ethtool +d-i pkgsel/include string openssh-server build-essential lvm2 ethtool sg3-utils d-i grub-installer/only_debian boolean true d-i grub-installer/with_other_os boolean true diff --git a/shared/unattended/Ubuntu-11-10.preseed b/shared/unattended/Ubuntu-11-10.preseed index c7ececca4..e846ce0b8 100644 --- a/shared/unattended/Ubuntu-11-10.preseed +++ b/shared/unattended/Ubuntu-11-10.preseed @@ -30,7 +30,7 @@ d-i mirror/udeb/components multiselect main, restricted, universe, multiverse tasksel tasksel/first multiselect standard -d-i pkgsel/include string openssh-server build-essential lvm2 ethtool +d-i pkgsel/include string openssh-server build-essential lvm2 ethtool sg3-utils d-i grub-installer/only_debian boolean true d-i grub-installer/with_other_os boolean true diff --git a/shared/unattended/Ubuntu-12-04.preseed b/shared/unattended/Ubuntu-12-04.preseed index c7ececca4..e846ce0b8 100644 --- a/shared/unattended/Ubuntu-12-04.preseed +++ b/shared/unattended/Ubuntu-12-04.preseed @@ -30,7 +30,7 @@ d-i mirror/udeb/components multiselect main, restricted, universe, multiverse tasksel tasksel/first multiselect standard -d-i pkgsel/include string openssh-server build-essential lvm2 ethtool +d-i pkgsel/include string openssh-server build-essential lvm2 ethtool sg3-utils d-i grub-installer/only_debian boolean true d-i grub-installer/with_other_os boolean true diff --git a/shared/unattended/Ubuntu-12-10.preseed b/shared/unattended/Ubuntu-12-10.preseed index 8cb534f02..a4ea2fa5f 100644 --- a/shared/unattended/Ubuntu-12-10.preseed +++ b/shared/unattended/Ubuntu-12-10.preseed @@ -30,7 +30,7 @@ d-i mirror/udeb/components multiselect main, restricted, universe, multiverse tasksel tasksel/first multiselect standard -d-i pkgsel/include string openssh-server build-essential lvm2 ethtool +d-i pkgsel/include string openssh-server build-essential lvm2 ethtool sg3-utils d-i grub-installer/only_debian boolean true d-i grub-installer/with_other_os boolean true diff --git a/shared/unattended/Ubuntu-13-04.preseed b/shared/unattended/Ubuntu-13-04.preseed index 8cb534f02..a4ea2fa5f 100644 --- a/shared/unattended/Ubuntu-13-04.preseed +++ b/shared/unattended/Ubuntu-13-04.preseed @@ -30,7 +30,7 @@ d-i mirror/udeb/components multiselect main, restricted, universe, multiverse tasksel tasksel/first multiselect standard -d-i pkgsel/include string openssh-server build-essential lvm2 ethtool +d-i pkgsel/include string openssh-server build-essential lvm2 ethtool sg3-utils d-i grub-installer/only_debian boolean true d-i grub-installer/with_other_os boolean true From a487e06a494cee9c1667f498423f5ccf9271a248 Mon Sep 17 00:00:00 2001 From: Qingtang Zhou Date: Tue, 2 Jul 2013 18:39:54 +0800 Subject: [PATCH 021/254] qemu.tests.usb: Disable xhci on old RHEL guests These RHEL guests older than RHEL5 aren't shipped with xhci driver. Disable xhci testing on them. Signed-off-by: Qingtang Zhou --- qemu/tests/cfg/usb.cfg | 3 +++ 1 file changed, 3 insertions(+) diff --git a/qemu/tests/cfg/usb.cfg b/qemu/tests/cfg/usb.cfg index 218a943d3..03fcd0f31 100644 --- a/qemu/tests/cfg/usb.cfg +++ b/qemu/tests/cfg/usb.cfg @@ -20,6 +20,9 @@ usb_max_port_usbtest = 6 drive_format_stg = "usb2" - xhci: + no RHEL.3 + no RHEL.4 + no RHEL.5 usb_type_usbtest = nec-usb-xhci usb_controller = xhci usb_max_port_usbtest = 4 From ebfcdad426c503d2ce60f31de00ef95ebe4961b8 Mon Sep 17 00:00:00 2001 From: Qingtang Zhou Date: Tue, 2 Jul 2013 18:41:16 +0800 Subject: [PATCH 022/254] qemu.tests.usb: Disable usb_audio on RHEL7 host The RHEL7 host doesn't have usb_audio support now. Disable it. Signed-off-by: Qingtang Zhou --- qemu/tests/cfg/usb.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/qemu/tests/cfg/usb.cfg b/qemu/tests/cfg/usb.cfg index 03fcd0f31..ac57ca75a 100644 --- a/qemu/tests/cfg/usb.cfg +++ b/qemu/tests/cfg/usb.cfg @@ -90,6 +90,7 @@ product = "QEMU USB CCID" - usb_audio: no Host_RHEL.6 + no Host_RHEL.7 only usb_boot, usb_reboot, usb_hotplug usb_type = usb-audio info_usb_name = "QEMU USB Audio" From c563bf3371985e5f72d35714cd03ac0d43391993 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Doktor?= Date: Tue, 2 Jul 2013 13:35:24 +0200 Subject: [PATCH 023/254] Merge autotest and virttest cgroup_utils library MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lukáš Doktor --- qemu/tests/cgroup.py | 13 +- virttest/utils_cgroup.py | 461 --------------------------------------- 2 files changed, 9 insertions(+), 465 deletions(-) delete mode 100755 virttest/utils_cgroup.py diff --git a/qemu/tests/cgroup.py b/qemu/tests/cgroup.py index a27bb2b41..bdbe09898 100644 --- a/qemu/tests/cgroup.py +++ b/qemu/tests/cgroup.py @@ -6,15 +6,20 @@ import logging, os, re, time from autotest.client.shared import error from autotest.client import utils -from virttest.utils_cgroup import Cgroup -from virttest.utils_cgroup import CgroupModules -from virttest.utils_cgroup import get_load_per_cpu from virttest.env_process import preprocess from virttest import qemu_monitor from virttest.aexpect import ExpectTimeoutError from virttest.aexpect import ExpectProcessTerminatedError from virttest.aexpect import ShellTimeoutError - +try: + from autotest.client.shared.utils_cgroup import Cgroup + from autotest.client.shared.utils_cgroup import CgroupModules + from autotest.client.shared.utils_cgroup import get_load_per_cpu +except ImportError: + # TODO: Obsoleted path used prior autotest-0.15.2/virttest-2013.06.24 + from virttest.utils_cgroup import Cgroup + from virttest.utils_cgroup import CgroupModules + from virttest.utils_cgroup import get_load_per_cpu @error.context_aware def run_cgroup(test, params, env): diff --git a/virttest/utils_cgroup.py b/virttest/utils_cgroup.py deleted file mode 100755 index c0055f4af..000000000 --- a/virttest/utils_cgroup.py +++ /dev/null @@ -1,461 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -""" -Helpers for cgroup testing. - -@copyright: 2011 Red Hat Inc. -@author: Lukas Doktor -""" -import logging, os, shutil, subprocess, time, re -from tempfile import mkdtemp -from autotest.client import utils -from autotest.client.shared import error - -class Cgroup(object): - """ - Cgroup handling class. - """ - def __init__(self, module, _client): - """ - Constructor - @param module: Name of the cgroup module - @param _client: Test script pwd + name - """ - self.module = module - self._client = _client - self.root = None - self.cgroups = [] - - - def __del__(self): - """ - Destructor - """ - self.cgroups.sort(reverse=True) - for pwd in self.cgroups[:]: - for task in self.get_property("tasks", pwd): - if task: - self.set_root_cgroup(int(task)) - self.rm_cgroup(pwd) - - def initialize(self, modules): - """ - Initializes object for use. - - @param modules: Array of all available cgroup modules. - """ - self.root = modules.get_pwd(self.module) - if not self.root: - raise error.TestError("cg.initialize(): Module %s not found" - % self.module) - - - def mk_cgroup(self, pwd=None): - """ - Creates new temporary cgroup - @param pwd: where to create this cgroup (default: self.root) - @return: 0 when PASSED - """ - if pwd == None: - pwd = self.root - if isinstance(pwd, int): - pwd = self.cgroups[pwd] - try: - pwd = mkdtemp(prefix='cgroup-', dir=pwd) + '/' - except Exception, inst: - raise error.TestError("cg.mk_cgroup(): %s" % inst) - self.cgroups.append(pwd) - return pwd - - - def rm_cgroup(self, pwd): - """ - Removes cgroup. - - @param pwd: cgroup directory. - """ - if isinstance(pwd, int): - pwd = self.cgroups[pwd] - try: - os.rmdir(pwd) - self.cgroups.remove(pwd) - except ValueError: - logging.warn("cg.rm_cgroup(): Removed cgroup which wasn't created" - "using this Cgroup") - except Exception, inst: - raise error.TestError("cg.rm_cgroup(): %s" % inst) - - - def test(self, cmd): - """ - Executes cgroup_client.py with cmd parameter. - - @param cmd: command to be executed - @return: subprocess.Popen() process - """ - logging.debug("cg.test(): executing paralel process '%s'", cmd) - cmd = self._client + ' ' + cmd - process = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, close_fds=True) - return process - - - def is_cgroup(self, pid, pwd): - """ - Checks if the 'pid' process is in 'pwd' cgroup - @param pid: pid of the process - @param pwd: cgroup directory - @return: 0 when is 'pwd' member - """ - if isinstance(pwd, int): - pwd = self.cgroups[pwd] - if open(pwd + '/tasks').readlines().count("%d\n" % pid) > 0: - return 0 - else: - return -1 - - - def is_root_cgroup(self, pid): - """ - Checks if the 'pid' process is in root cgroup (WO cgroup) - @param pid: pid of the process - @return: 0 when is 'root' member - """ - return self.is_cgroup(pid, self.root) - - - def set_cgroup(self, pid, pwd=None): - """ - Sets cgroup membership - @param pid: pid of the process - @param pwd: cgroup directory - """ - if pwd == None: - pwd = self.root - if isinstance(pwd, int): - pwd = self.cgroups[pwd] - try: - open(pwd+'/tasks', 'w').write(str(pid)) - except Exception, inst: - raise error.TestError("cg.set_cgroup(): %s" % inst) - if self.is_cgroup(pid, pwd): - raise error.TestError("cg.set_cgroup(): Setting %d pid into %s " - "cgroup failed" % (pid, pwd)) - - def set_root_cgroup(self, pid): - """ - Resets the cgroup membership (sets to root) - @param pid: pid of the process - @return: 0 when PASSED - """ - return self.set_cgroup(pid, self.root) - - - def get_property(self, prop, pwd=None): - """ - Gets the property value - @param prop: property name (file) - @param pwd: cgroup directory - @return: [] values or None when FAILED - """ - if pwd == None: - pwd = self.root - if isinstance(pwd, int): - pwd = self.cgroups[pwd] - try: - # Remove tailing '\n' from each line - ret = [_[:-1] for _ in open(pwd+prop, 'r').readlines()] - if ret: - return ret - else: - return [""] - except Exception, inst: - raise error.TestError("cg.get_property(): %s" % inst) - - - def set_property_h(self, prop, value, pwd=None, check=True, checkprop=None): - """ - Sets the one-line property value concerning the K,M,G postfix - @param prop: property name (file) - @param value: desired value - @param pwd: cgroup directory - @param check: check the value after setup / override checking value - @param checkprop: override prop when checking the value - """ - _value = value - try: - value = str(value) - human = {'B': 1, - 'K': 1024, - 'M': 1048576, - 'G': 1073741824, - 'T': 1099511627776 - } - if human.has_key(value[-1]): - value = int(value[:-1]) * human[value[-1]] - except Exception: - logging.warn("cg.set_prop() fallback into cg.set_property.") - value = _value - self.set_property(prop, value, pwd, check, checkprop) - - - def set_property(self, prop, value, pwd=None, check=True, checkprop=None): - """ - Sets the property value - @param prop: property name (file) - @param value: desired value - @param pwd: cgroup directory - @param check: check the value after setup / override checking value - @param checkprop: override prop when checking the value - """ - value = str(value) - if pwd == None: - pwd = self.root - if isinstance(pwd, int): - pwd = self.cgroups[pwd] - try: - open(os.path.join(pwd, prop), 'w').write(value) - except Exception, inst: - raise error.TestError("cg.set_property(): %s" % inst) - - if check is not False: - if check is True: - check = value - if checkprop is None: - checkprop = prop - _values = self.get_property(checkprop, pwd) - # Sanitize non printable characters before check - check = " ".join(check.split()) - if check not in _values: - raise error.TestError("cg.set_property(): Setting failed: " - "desired = %s, real values = %s" - % (repr(check), repr(_values))) - - - def smoke_test(self): - """ - Smoke test - Module independent basic tests - """ - pwd = self.mk_cgroup() - - ps = self.test("smoke") - if ps == None: - raise error.TestError("cg.smoke_test: Couldn't create process") - - if (ps.poll() != None): - raise error.TestError("cg.smoke_test: Process died unexpectidly") - - # New process should be a root member - if self.is_root_cgroup(ps.pid): - raise error.TestError("cg.smoke_test: Process is not a root member") - - # Change the cgroup - self.set_cgroup(ps.pid, pwd) - - # Try to remove used cgroup - try: - self.rm_cgroup(pwd) - except error.TestError: - pass - else: - raise error.TestError("cg.smoke_test: Unexpected successful deletion" - " of the used cgroup") - - # Return the process into the root cgroup - self.set_root_cgroup(ps.pid) - - # It should be safe to remove the cgroup now - self.rm_cgroup(pwd) - - # Finish the process - ps.stdin.write('\n') - time.sleep(2) - if (ps.poll() == None): - raise error.TestError("cg.smoke_test: Process is not finished") - - -class CgroupModules(object): - """ - Handles the list of different cgroup filesystems. - """ - def __init__(self): - self.modules = [] - self.modules.append([]) - self.modules.append([]) - self.modules.append([]) - self.mountdir = mkdtemp(prefix='cgroup-') + '/' - - def __del__(self): - """ - Unmount all cgroups and remove the mountdir - """ - for i in range(len(self.modules[0])): - if self.modules[2][i]: - try: - utils.system('umount %s -l' % self.modules[1][i]) - except Exception, failure_detail: - logging.warn("CGM: Couldn't unmount %s directory: %s", - self.modules[1][i], failure_detail) - try: - shutil.rmtree(self.mountdir) - except Exception: - logging.warn("CGM: Couldn't remove the %s directory", self.mountdir) - - def init(self, _modules): - """ - Checks the mounted modules and if necessary mounts them into tmp - mountdir. - @param _modules: Desired modules. - @return: Number of initialized modules. - """ - logging.debug("Desired cgroup modules: %s", _modules) - mounts = [] - proc_mounts = open('/proc/mounts', 'r') - line = proc_mounts.readline().split() - while line: - if line[2] == 'cgroup': - mounts.append(line) - line = proc_mounts.readline().split() - proc_mounts.close() - - for module in _modules: - # Is it already mounted? - i = False - for mount in mounts: - if module in mount[3].split(','): - self.modules[0].append(module) - self.modules[1].append(mount[1] + '/') - self.modules[2].append(False) - i = True - break - if not i: - # Not yet mounted - os.mkdir(self.mountdir + module) - cmd = ('mount -t cgroup -o %s %s %s' % - (module, module, self.mountdir + module)) - try: - utils.run(cmd) - self.modules[0].append(module) - self.modules[1].append(self.mountdir + module) - self.modules[2].append(True) - except error.CmdError: - logging.info("Cgroup module '%s' not available", module) - - logging.debug("Initialized cgroup modules: %s", self.modules[0]) - return len(self.modules[0]) - - - def get_pwd(self, module): - """ - Returns the mount directory of 'module' - @param module: desired module (memory, ...) - @return: mount directory of 'module' or None - """ - try: - i = self.modules[0].index(module) - except Exception, inst: - logging.error("module %s not found: %s", module, inst) - return None - return self.modules[1][i] - - -def get_load_per_cpu(_stats=None): - """ - Gather load per cpu from /proc/stat - @param _stats: previous values - @return: list of diff/absolute values of CPU times [SUM, CPU1, CPU2, ...] - """ - stats = [] - f_stat = open('/proc/stat', 'r') - if _stats: - for i in range(len(_stats)): - stats.append(int(f_stat.readline().split()[1]) - _stats[i]) - else: - line = f_stat.readline() - while line: - if line.startswith('cpu'): - stats.append(int(line.split()[1])) - else: - break - line = f_stat.readline() - return stats - - -def get_cgroup_mountpoint(controller): - controller_list = [ 'cpuacct', 'cpu', 'memory', 'cpuset', - 'devices', 'freezer', 'blkio', 'netcls' ] - - if controller not in controller_list: - raise error.TestError("Doesn't support controller <%s>" % controller) - - f_cgcon = open("/proc/mounts", "rU") - cgconf_txt = f_cgcon.read() - f_cgcon.close() - mntpt = re.findall(r"\s(\S*cgroup/%s)" % controller, cgconf_txt) - return mntpt[0] - - -def resolve_task_cgroup_path(pid, controller): - """ - Resolving cgroup mount path of a particular task - - @params: pid : process id of a task for which the cgroup path required - @params: controller: takes one of the controller names in controller list - - @return: resolved path for cgroup controllers of a given pid - """ - - # Initialise cgroup controller list - controller_list = [ 'cpuacct', 'cpu', 'memory', 'cpuset', - 'devices', 'freezer', 'blkio', 'netcls' ] - - if controller not in controller_list: - raise error.TestError("Doesn't support controller <%s>" % controller) - - root_path = get_cgroup_mountpoint(controller) - - proc_cgroup = "/proc/%d/cgroup" % pid - if not os.path.isfile(proc_cgroup): - raise NameError('File %s does not exist\n Check whether cgroup \ - installed in the system' % proc_cgroup) - - f = open(proc_cgroup, 'r') - proc_cgroup_txt = f.read() - f.close - - mount_path = re.findall(r":%s:(\S*)\n" % controller, proc_cgroup_txt) - path = root_path + mount_path[0] - return path - - -def service_cgconfig_control(action): - """ - Cgconfig control by action. - - If cmd executes successfully, return True, otherwise return False. - If the action is status, return True when it's running, otherwise return - False. - - @ param action: start|stop|status|restart|condrestart - """ - actions = ['start', 'stop', 'restart', 'condrestart'] - if action in actions: - try: - utils.run("service cgconfig %s" % action) - logging.debug("%s cgconfig successfuly", action) - return True - except error.CmdError, detail: - logging.error("Failed to %s cgconfig:\n%s", action, detail) - return False - elif action == "status": - cmd_result = utils.run("service cgconfig status", ignore_status=True) - if (not cmd_result.exit_status and - cmd_result.stdout.strip()) == "Running": - logging.info("Cgconfig service is running") - return True - else: - return False - else: - raise error.TestError("Unknown action: %s" % action) From 25b848aa5f43bd8b7a2a03a09c18b6c8632df42d Mon Sep 17 00:00:00 2001 From: yangdongsheng Date: Tue, 25 Jun 2013 16:17:30 +0800 Subject: [PATCH 024/254] Fix all libvirt_vm.libvirtd to utils_libvirtd. Signed-off-by: yangdongsheng --- libguestfs/tests/virt_edit.py | 6 +++--- libvirt/tests/src/virsh_cmd/domain/virsh_change_media.py | 6 +++--- libvirt/tests/src/virsh_cmd/domain/virsh_destroy.py | 6 +++--- libvirt/tests/src/virsh_cmd/domain/virsh_domid.py | 6 +++--- libvirt/tests/src/virsh_cmd/domain/virsh_domjobinfo.py | 6 +++--- libvirt/tests/src/virsh_cmd/domain/virsh_domname.py | 6 +++--- libvirt/tests/src/virsh_cmd/domain/virsh_domuuid.py | 6 +++--- .../src/virsh_cmd/domain/virsh_domxml_from_native.py | 6 +++--- .../tests/src/virsh_cmd/domain/virsh_domxml_to_native.py | 6 +++--- libvirt/tests/src/virsh_cmd/domain/virsh_dump.py | 6 +++--- libvirt/tests/src/virsh_cmd/domain/virsh_edit.py | 6 +++--- libvirt/tests/src/virsh_cmd/domain/virsh_managedsave.py | 6 +++--- libvirt/tests/src/virsh_cmd/domain/virsh_migrate.py | 6 +++--- libvirt/tests/src/virsh_cmd/domain/virsh_numatune.py | 6 +++--- libvirt/tests/src/virsh_cmd/domain/virsh_reboot.py | 6 +++--- libvirt/tests/src/virsh_cmd/domain/virsh_restore.py | 6 +++--- libvirt/tests/src/virsh_cmd/domain/virsh_save.py | 6 +++--- libvirt/tests/src/virsh_cmd/domain/virsh_setmem.py | 8 ++++---- libvirt/tests/src/virsh_cmd/domain/virsh_setvcpus.py | 2 +- libvirt/tests/src/virsh_cmd/domain/virsh_shutdown.py | 6 +++--- libvirt/tests/src/virsh_cmd/domain/virsh_start.py | 8 ++++---- libvirt/tests/src/virsh_cmd/domain/virsh_undefine.py | 6 +++--- libvirt/tests/src/virsh_cmd/domain/virsh_vcpuinfo.py | 6 +++--- libvirt/tests/src/virsh_cmd/domain/virsh_vncdisplay.py | 7 +++---- libvirt/tests/src/virsh_cmd/host/virsh_capabilities.py | 6 +++--- libvirt/tests/src/virsh_cmd/host/virsh_freecell.py | 6 +++--- libvirt/tests/src/virsh_cmd/host/virsh_hostname.py | 6 +++--- libvirt/tests/src/virsh_cmd/host/virsh_nodecpustats.py | 8 ++++---- libvirt/tests/src/virsh_cmd/host/virsh_nodeinfo.py | 6 +++--- libvirt/tests/src/virsh_cmd/host/virsh_nodememstats.py | 8 ++++---- libvirt/tests/src/virsh_cmd/host/virsh_uri.py | 6 +++--- libvirt/tests/src/virsh_cmd/host/virsh_version.py | 6 +++--- libvirt/tests/src/virsh_cmd/monitor/virsh_domblkstat.py | 6 +++--- libvirt/tests/src/virsh_cmd/monitor/virsh_domifstat.py | 6 +++--- libvirt/tests/src/virsh_cmd/monitor/virsh_dominfo.py | 6 +++--- libvirt/tests/src/virsh_cmd/monitor/virsh_dommemstat.py | 8 ++++---- libvirt/tests/src/virsh_cmd/monitor/virsh_domstate.py | 6 +++--- libvirt/tests/src/virsh_cmd/monitor/virsh_list.py | 6 +++--- .../tests/src/virsh_cmd/network/virsh_net_autostart.py | 4 ++-- libvirt/tests/src/virsh_cmd/network/virsh_net_list.py | 2 +- libvirt/tests/src/virsh_cmd/pool/virsh_pool.py | 6 +++--- virttest/env_process.py | 6 +++--- 42 files changed, 126 insertions(+), 127 deletions(-) diff --git a/libguestfs/tests/virt_edit.py b/libguestfs/tests/virt_edit.py index 3ab60b58d..aadf4137f 100644 --- a/libguestfs/tests/virt_edit.py +++ b/libguestfs/tests/virt_edit.py @@ -1,6 +1,6 @@ import logging, re from autotest.client.shared import utils, error -from virttest import libvirt_vm +from virttest import libvirt_vm, utils_libvirtd import virttest.utils_libguestfs as lgf @@ -88,7 +88,7 @@ def run_virt_edit(test, params, env): # Stop libvirtd if test need. libvirtd = params.get("libvirtd", "on") if libvirtd == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() # Run test virsh_dargs = {'ignore_status': True, 'debug': True, 'uri': uri} @@ -98,7 +98,7 @@ def run_virt_edit(test, params, env): # Recover libvirtd. if libvirtd == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() utils.run("rm -f %s" % created_img) diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_change_media.py b/libvirt/tests/src/virsh_cmd/domain/virsh_change_media.py index 0164d45e2..9a9f6aff7 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_change_media.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_change_media.py @@ -1,6 +1,6 @@ import logging, os, shutil from autotest.client.shared import error, utils -from virttest import libvirt_vm, virsh +from virttest import virsh, utils_libvirtd from virttest.libvirt_xml import vm_xml @@ -130,7 +130,7 @@ def update_cdrom(vm_name, init_iso, options, start_vm ): libvirtd = params.get("libvirtd", "on") if libvirtd == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() source_name = params.get("change_media_source") # Libvirt will ignore --source when action is eject @@ -158,7 +158,7 @@ def update_cdrom(vm_name, init_iso, options, start_vm ): # Recover libvirtd service start if libvirtd == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() # Clean the cdrom dir and clean the cdrom device update_cdrom(vm_name, "", options, start_vm) diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_destroy.py b/libvirt/tests/src/virsh_cmd/domain/virsh_destroy.py index 7814edeb6..f316fbec0 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_destroy.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_destroy.py @@ -1,5 +1,5 @@ from autotest.client.shared import error -from virttest import libvirt_vm, remote, virsh +from virttest import libvirt_vm, remote, virsh, utils_libvirtd def run_virsh_destroy(test, params, env): """ @@ -39,7 +39,7 @@ def run_virsh_destroy(test, params, env): vm_ref = domuuid if libvirtd == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() if vm_ref != "remote": status = virsh.destroy(vm_ref, ignore_status=True).exit_status @@ -59,7 +59,7 @@ def run_virsh_destroy(test, params, env): status = 1 if libvirtd == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() #check status_error if status_error == "yes": diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_domid.py b/libvirt/tests/src/virsh_cmd/domain/virsh_domid.py index 04397f628..6e60cd533 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_domid.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_domid.py @@ -1,5 +1,5 @@ from autotest.client.shared import error -from virttest import libvirt_vm, remote, virsh +from virttest import libvirt_vm, remote, virsh, utils_libvirtd def run_virsh_domid(test, params, env): @@ -70,7 +70,7 @@ def remote_test(params, vm_name): vm_ref = domuuid if libvirtd == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() if vm_ref != "remote": result = virsh.domid(vm_ref, ignore_status=True) @@ -82,7 +82,7 @@ def remote_test(params, vm_name): #recover libvirtd service start if libvirtd == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() #check status_error if status_error == "yes": diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_domjobinfo.py b/libvirt/tests/src/virsh_cmd/domain/virsh_domjobinfo.py index 2f6de1eb5..b92531337 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_domjobinfo.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_domjobinfo.py @@ -1,6 +1,6 @@ import os from autotest.client.shared import error -from virttest import libvirt_vm, virsh +from virttest import virsh, utils_libvirtd def run_virsh_domjobinfo(test, params, env): @@ -50,13 +50,13 @@ def run_virsh_domjobinfo(test, params, env): vm_ref = params.get(vm_ref) if libvirtd == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() status = virsh.domjobinfo(vm_ref, ignore_status=True).exit_status #recover libvirtd service start if libvirtd == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() #check status_error if status_error == "yes": diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_domname.py b/libvirt/tests/src/virsh_cmd/domain/virsh_domname.py index 6b263ef65..c55f9362a 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_domname.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_domname.py @@ -1,6 +1,6 @@ import logging from autotest.client.shared import error -from virttest import libvirt_vm, virsh +from virttest import virsh, utils_libvirtd def run_virsh_domname(test, params, env): @@ -47,14 +47,14 @@ def run_virsh_domname(test, params, env): #Prepare libvirtd status libvirtd = params.get("libvirtd", "on") if libvirtd == "off": - libvirt_vm.service_libvirtd_control("stop") + utils_libvirtd.libvirtd_stop() result = virsh.domname(options, ignore_status=True, debug=True, uri=connect_uri) #Recover libvirtd service to start if libvirtd == "off": - libvirt_vm.service_libvirtd_control("start") + utils_libvirtd.libvirtd_start() addition_status_error = "yes" #check status_error diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_domuuid.py b/libvirt/tests/src/virsh_cmd/domain/virsh_domuuid.py index 941a0e1c7..b42d96176 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_domuuid.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_domuuid.py @@ -1,6 +1,6 @@ import logging from autotest.client.shared import error -from virttest import virsh, libvirt_vm, libvirt_xml +from virttest import virsh, libvirt_xml, utils_libvirtd def run_virsh_domuuid(test, params, env): @@ -40,7 +40,7 @@ def run_virsh_domuuid(test, params, env): # Prepare libvirtd state if libvirtd == "off": - libvirt_vm.service_libvirtd_control("stop") + utils_libvirtd.libvirtd_stop() result = virsh.domuuid(vm_ref) logging.debug(result) @@ -49,7 +49,7 @@ def run_virsh_domuuid(test, params, env): # Recover libvirtd service start if libvirtd == "off": - libvirt_vm.service_libvirtd_control("start") + utils_libvirtd.libvirtd_start() # Check status_error if status_error == "yes": diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_domxml_from_native.py b/libvirt/tests/src/virsh_cmd/domain/virsh_domxml_from_native.py index 257ea59c0..71a502752 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_domxml_from_native.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_domxml_from_native.py @@ -1,7 +1,7 @@ import re, os from autotest.client.shared import error from autotest.client import utils -from virttest import libvirt_vm, virsh +from virttest import virsh, utils_libvirtd def run_virsh_domxml_from_native(test, params, env): @@ -48,7 +48,7 @@ def virsh_convxml(guest_args): #libvirtd off if libvirtd == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() #Ignore exception with ignore_status=True. ret = virsh.domxml_from_native(dfn_format, guest_args, invalid_guest_args, @@ -57,7 +57,7 @@ def virsh_convxml(guest_args): #recover libvirtd service start if libvirtd == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() #clean up if os.path.exists(guest_args): diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_domxml_to_native.py b/libvirt/tests/src/virsh_cmd/domain/virsh_domxml_to_native.py index c6d37e353..a9851bbc2 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_domxml_to_native.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_domxml_to_native.py @@ -1,7 +1,7 @@ import re, os from autotest.client.shared import error from autotest.client import utils -from virttest import libvirt_vm, virsh +from virttest import virsh, utils_libvirtd def run_virsh_domxml_to_native(test, params, env): @@ -68,7 +68,7 @@ def compare(conv_arg): status_error = params.get("status_error") virsh.dumpxml(vm_name, extra="", to_file=file_xml) if libvirtd == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() ret = virsh.domxml_to_native(dtn_format, file_xml, extra_param, ignore_status = True) status = ret.exit_status @@ -76,7 +76,7 @@ def compare(conv_arg): #recover libvirtd service start if libvirtd == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() #clean up if os.path.exists(file_xml): diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_dump.py b/libvirt/tests/src/virsh_cmd/domain/virsh_dump.py index bbd780ae7..90a303993 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_dump.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_dump.py @@ -1,6 +1,6 @@ import os, logging, commands, thread, time from autotest.client.shared import error -from virttest import libvirt_vm, virsh +from virttest import virsh, utils_libvirtd def check_flag(file_flag): """ @@ -150,7 +150,7 @@ def check_dump_format(dump_image_format, dump_file): if os.system(conf_cmd): logging.error("Config dump_image_format to %s fail", dump_image_format) - libvirt_vm.service_libvirtd_control("restart") + utils_libvirtd.libvirtd_restart() # Deal with bypass-cache option if options.find('bypass-cache') >= 0: @@ -164,7 +164,7 @@ def check_dump_format(dump_image_format, dump_file): status = cmd_result.exit_status # Check libvirtd status - if libvirt_vm.service_libvirtd_control("status"): + if utils_libvirtd.libvirtd_status(): if check_domstate(vm.state(), options): if status_error == "yes": if status == 0: diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_edit.py b/libvirt/tests/src/virsh_cmd/domain/virsh_edit.py index 2dc8ca089..508563e51 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_edit.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_edit.py @@ -1,6 +1,6 @@ import os, time from autotest.client.shared import error -from virttest import libvirt_vm, virsh, aexpect +from virttest import virsh, aexpect, utils_libvirtd def run_virsh_edit(test, params, env): @@ -77,7 +77,7 @@ def edit_vcpu(source, guest_name): virsh.dumpxml(vm_name, extra="", to_file=xml_file) if libvirtd == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() try: if vm_ref == "id": @@ -100,7 +100,7 @@ def edit_vcpu(source, guest_name): #recover libvirtd service start if libvirtd == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() #Recover VM if vm.is_alive(): diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_managedsave.py b/libvirt/tests/src/virsh_cmd/domain/virsh_managedsave.py index 9c80431eb..a577d55b4 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_managedsave.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_managedsave.py @@ -1,6 +1,6 @@ import re from autotest.client.shared import error -from virttest import libvirt_vm, virsh +from virttest import virsh, utils_libvirtd def run_virsh_managedsave(test, params, env): @@ -55,7 +55,7 @@ def vm_recover_check(guest_name): #stop the libvirtd service if libvirtd == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() #Ignore exception with "ignore_status=True" ret = virsh.managedsave(vm_ref, ignore_status=True) @@ -63,7 +63,7 @@ def vm_recover_check(guest_name): #recover libvirtd service start if libvirtd == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() #check status_error status_error = params.get("status_error") diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_migrate.py b/libvirt/tests/src/virsh_cmd/domain/virsh_migrate.py index 7eb721c15..7bab0a1c9 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_migrate.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_migrate.py @@ -1,6 +1,6 @@ import logging, os, re, time, codecs from autotest.client.shared import error -from virttest import libvirt_vm, utils_test, virsh +from virttest import utils_test, virsh, utils_libvirtd def run_virsh_migrate(test, params, env): @@ -142,7 +142,7 @@ def do_migration(delay, vm, dest_uri, options, extra): # Turn libvirtd into certain state. logging.debug("Turning libvirtd into certain status.") if libvirtd_state == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() # Test uni-direction migration. logging.debug("Doing migration test.") @@ -155,7 +155,7 @@ def do_migration(delay, vm, dest_uri, options, extra): # Recover libvirtd state. logging.debug("Recovering libvirtd status.") if libvirtd_state == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() # Check vm state on destination. logging.debug("Checking %s state on %s." % (vm.name, vm.connect_uri)) diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_numatune.py b/libvirt/tests/src/virsh_cmd/domain/virsh_numatune.py index ca2bb6150..8dc774f65 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_numatune.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_numatune.py @@ -1,6 +1,6 @@ import re, logging from autotest.client.shared import error, utils -from virttest import libvirt_vm, libvirt_xml, virsh +from virttest import libvirt_xml, virsh, utils_libvirtd from virttest import utils_cgroup @@ -238,7 +238,7 @@ def run_virsh_numatune(test, params, env): utils_cgroup.service_cgconfig_control("stop") # Refresh libvirtd service to get latest cgconfig service change if libvirtd == "restart": - libvirt_vm.service_libvirtd_control("restart") + utils_libvirtd.libvirtd_restart() # Recover previous running guest if cgconfig == "off" and libvirtd == "restart" \ and not vm.is_alive() and start_vm == "yes": @@ -251,7 +251,7 @@ def run_virsh_numatune(test, params, env): # Recover cgconfig and libvirtd service if not utils_cgroup.service_cgconfig_control("status"): utils_cgroup.service_cgconfig_control("start") - libvirt_vm.service_libvirtd_control("restart") + utils_libvirtd.libvirtd_restart() finally: vm.destroy() # Restore guest, first remove existing diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_reboot.py b/libvirt/tests/src/virsh_cmd/domain/virsh_reboot.py index bdd7bea58..8fa21a893 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_reboot.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_reboot.py @@ -1,6 +1,6 @@ import re, logging from autotest.client.shared import error -from virttest import libvirt_vm, virsh, remote +from virttest import libvirt_vm, virsh, remote, utils_libvirtd def run_virsh_reboot(test, params, env): """ @@ -28,7 +28,7 @@ def run_virsh_reboot(test, params, env): domid = vm.get_id() domuuid = vm.get_uuid() if libvirtd == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() if vm_ref == "id": vm_ref = domid @@ -70,7 +70,7 @@ def run_virsh_reboot(test, params, env): #recover libvirtd service start if libvirtd == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() #check status_error if status_error == "yes": diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_restore.py b/libvirt/tests/src/virsh_cmd/domain/virsh_restore.py index 99d48c87c..bcbc77382 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_restore.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_restore.py @@ -1,6 +1,6 @@ import re, os from autotest.client.shared import error -from virttest import libvirt_vm, virsh +from virttest import virsh, utils_libvirtd def run_virsh_restore(test, params, env): @@ -50,7 +50,7 @@ def run_virsh_restore(test, params, env): if pre_status == "start": virsh.start(vm_name) if libvirtd == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() status = virsh.restore(vm_ref, ignore_status=True).exit_status if os.path.exists(tmp_file): os.unlink(tmp_file) @@ -61,7 +61,7 @@ def run_virsh_restore(test, params, env): #recover libvirtd service start if libvirtd == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() if vm.is_alive(): vm.destroy() diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_save.py b/libvirt/tests/src/virsh_cmd/domain/virsh_save.py index 1475be688..3408ff5c9 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_save.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_save.py @@ -1,6 +1,6 @@ import os from autotest.client.shared import error -from virttest import libvirt_vm, virsh +from virttest import virsh, utils_libvirtd def run_virsh_save(test, params, env): @@ -54,12 +54,12 @@ def run_virsh_save(test, params, env): vm_ref = vm_name if libvirtd == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() status = virsh.save(vm_ref, savefile, ignore_status=True).exit_status # recover libvirtd service start if libvirtd == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() # cleanup if os.path.exists(savefile): diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_setmem.py b/libvirt/tests/src/virsh_cmd/domain/virsh_setmem.py index 3c1b602f8..b2b196355 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_setmem.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_setmem.py @@ -1,6 +1,6 @@ import re, logging, time from autotest.client.shared import error -from virttest import libvirt_vm, virsh +from virttest import virsh, utils_libvirtd def run_virsh_setmem(test, params, env): @@ -164,9 +164,9 @@ def print_debug_stats(original_inside_mem, original_outside_mem, # Prepare libvirtd status if libvirt == "off": - libvirt_vm.service_libvirtd_control("stop") + utils_libvirtd.libvirtd_stop() else: # make sure it's running - libvirt_vm.service_libvirtd_control("restart") + utils_libvirtd.libvirtd_restart() if status_error == "yes" or old_libvirt_fail == "yes": logging.info("Error Test: Expecting an error to occur!") @@ -176,7 +176,7 @@ def print_debug_stats(original_inside_mem, original_outside_mem, # Recover libvirtd status if libvirt == "off": - libvirt_vm.service_libvirtd_control("start") + utils_libvirtd.libvirtd_start() if status is 0: logging.info("Waiting %d seconds for VM memory to settle", quiesce_delay) diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_setvcpus.py b/libvirt/tests/src/virsh_cmd/domain/virsh_setvcpus.py index 205a99650..adc575108 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_setvcpus.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_setvcpus.py @@ -1,6 +1,6 @@ import re, os, logging, commands from autotest.client.shared import error -from virttest import remote, libvirt_vm, virsh, libvirt_xml +from virttest import remote, virsh, libvirt_xml from xml.dom.minidom import parse def run_virsh_setvcpus(test, params, env): diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_shutdown.py b/libvirt/tests/src/virsh_cmd/domain/virsh_shutdown.py index 7ca6b0814..64f282a44 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_shutdown.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_shutdown.py @@ -1,5 +1,5 @@ from autotest.client.shared import error -from virttest import remote, libvirt_vm, virsh +from virttest import remote, libvirt_vm, virsh, utils_libvirtd def run_virsh_shutdown(test, params, env): @@ -37,7 +37,7 @@ def run_virsh_shutdown(test, params, env): vm_ref = domuuid if libvirtd == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() if vm_ref != "remote": status = virsh.shutdown(vm_ref, ignore_status = True).exit_status @@ -59,7 +59,7 @@ def run_virsh_shutdown(test, params, env): #recover libvirtd service start if libvirtd == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() #check status_error status_error = params.get("status_error") diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_start.py b/libvirt/tests/src/virsh_cmd/domain/virsh_start.py index 57ee9f498..b64666e9f 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_start.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_start.py @@ -1,5 +1,5 @@ from autotest.client.shared import error -from virttest import remote, libvirt_vm, virsh, libvirt_xml +from virttest import remote, libvirt_vm, virsh, libvirt_xml, utils_libvirtd class StartError(Exception): @@ -63,9 +63,9 @@ def run_virsh_start(test, params, env): try: #prepare before start vm if libvirtd_state == "on": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() elif libvirtd_state == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() if pre_operation == "rename": new_vm_name = params.get("vs_new_vm_name", "virsh_start_vm1") @@ -103,7 +103,7 @@ def run_virsh_start(test, params, env): finally: #clean up if libvirtd_state == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() if (pre_operation == "undefine") and (not vmxml.xml == None): vmxml.define() diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_undefine.py b/libvirt/tests/src/virsh_cmd/domain/virsh_undefine.py index 9dd57ffc1..8d6334383 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_undefine.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_undefine.py @@ -1,6 +1,6 @@ import os, logging from autotest.client.shared import error -from virttest import libvirt_vm, virsh, remote +from virttest import libvirt_vm, virsh, remote, utils_libvirtd def run_virsh_undefine(test, params, env): """ @@ -49,7 +49,7 @@ def run_virsh_undefine(test, params, env): # Turn libvirtd into certain state. if libvirtd_state == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() # Test virsh undefine command. status = 0 @@ -80,7 +80,7 @@ def run_virsh_undefine(test, params, env): # Recover libvirtd state. if libvirtd_state == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() # Shutdown VM. if virsh.domain_exists(vm.name, uri=uri): diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_vcpuinfo.py b/libvirt/tests/src/virsh_cmd/domain/virsh_vcpuinfo.py index 0484bcac9..f88bbca6c 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_vcpuinfo.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_vcpuinfo.py @@ -1,5 +1,5 @@ from autotest.client.shared import error -from virttest import virsh, libvirt_vm +from virttest import virsh, utils_libvirtd def run_virsh_vcpuinfo(test, params, env): """ @@ -18,7 +18,7 @@ def run_virsh_vcpuinfo(test, params, env): status_error = params.get("status_error", "no") libvirtd = params.get("libvirtd", "on") if libvirtd == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() #run test case vm_ref = params.get("vcpuinfo_vm_ref") @@ -85,7 +85,7 @@ def remote_case(params, vm_name): #recover libvirtd service start if libvirtd == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() #check status_error if status_error == "yes": diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_vncdisplay.py b/libvirt/tests/src/virsh_cmd/domain/virsh_vncdisplay.py index 2141f327f..461a56ae7 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_vncdisplay.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_vncdisplay.py @@ -1,6 +1,5 @@ -import logging from autotest.client.shared import error -from virttest import libvirt_vm, virsh, remote +from virttest import libvirt_vm, virsh, remote, utils_libvirtd def run_virsh_vncdisplay(test, params, env): """ @@ -65,7 +64,7 @@ def remote_case(params, vm_name): vm_ref = domuuid if libvirtd == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() if vm_ref == "remote": status, output = remote_case(params, vm_name) @@ -75,7 +74,7 @@ def remote_case(params, vm_name): output = result.stdout.strip() if libvirtd == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() #check status_error if status_error == "yes": diff --git a/libvirt/tests/src/virsh_cmd/host/virsh_capabilities.py b/libvirt/tests/src/virsh_cmd/host/virsh_capabilities.py index cc7235a31..37afb39c8 100644 --- a/libvirt/tests/src/virsh_cmd/host/virsh_capabilities.py +++ b/libvirt/tests/src/virsh_cmd/host/virsh_capabilities.py @@ -1,7 +1,7 @@ import logging, re from xml.dom.minidom import parseString from autotest.client.shared import utils, error -from virttest import libvirt_vm, virsh +from virttest import libvirt_vm, virsh, utils_libvirtd def run_virsh_capabilities(test, params, env): """ @@ -72,7 +72,7 @@ def compare_capabilities_xml(source): if params.has_key("libvirtd"): libvirtd = params.get("libvirtd") if libvirtd == "off": - libvirt_vm.service_libvirtd_control("stop") + utils_libvirtd.libvirtd_stop() # Run test case option = params.get("virsh_cap_options") @@ -86,7 +86,7 @@ def compare_capabilities_xml(source): # Recover libvirtd service start if libvirtd == "off": - libvirt_vm.service_libvirtd_control("start") + utils_libvirtd.libvirtd_start() # Check status_error status_error = params.get("status_error") diff --git a/libvirt/tests/src/virsh_cmd/host/virsh_freecell.py b/libvirt/tests/src/virsh_cmd/host/virsh_freecell.py index fc0b00c3a..33937c86e 100644 --- a/libvirt/tests/src/virsh_cmd/host/virsh_freecell.py +++ b/libvirt/tests/src/virsh_cmd/host/virsh_freecell.py @@ -1,6 +1,6 @@ import re from autotest.client.shared import error -from virttest import libvirt_vm, virsh +from virttest import libvirt_vm, virsh, utils_libvirtd def run_virsh_freecell(test, params, env): """ @@ -22,7 +22,7 @@ def run_virsh_freecell(test, params, env): if check_libvirtd: libvirtd = params.get("libvirtd") if libvirtd == "off": - libvirt_vm.service_libvirtd_control("stop") + utils_libvirtd.libvirtd_stop() # Run test case cmd_result = virsh.freecell(ignore_status=True, extra=option, @@ -32,7 +32,7 @@ def run_virsh_freecell(test, params, env): # Recover libvirtd service start if libvirtd == "off": - libvirt_vm.service_libvirtd_control("start") + utils_libvirtd.libvirtd_start() # Check the output if virsh.has_help_command('numatune'): diff --git a/libvirt/tests/src/virsh_cmd/host/virsh_hostname.py b/libvirt/tests/src/virsh_cmd/host/virsh_hostname.py index 983a7f683..58f43d469 100644 --- a/libvirt/tests/src/virsh_cmd/host/virsh_hostname.py +++ b/libvirt/tests/src/virsh_cmd/host/virsh_hostname.py @@ -1,5 +1,5 @@ from autotest.client.shared import utils, error -from virttest import libvirt_vm, virsh +from virttest import virsh, utils_libvirtd def run_virsh_hostname(test, params, env): @@ -19,7 +19,7 @@ def run_virsh_hostname(test, params, env): if check_libvirtd: libvirtd = params.get("libvirtd") if libvirtd == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() # Run test case option = params.get("virsh_hostname_options") @@ -34,7 +34,7 @@ def run_virsh_hostname(test, params, env): # Recover libvirtd service start if libvirtd == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() # Check status_error status_error = params.get("status_error") diff --git a/libvirt/tests/src/virsh_cmd/host/virsh_nodecpustats.py b/libvirt/tests/src/virsh_cmd/host/virsh_nodecpustats.py index 038b09839..9542ae100 100644 --- a/libvirt/tests/src/virsh_cmd/host/virsh_nodecpustats.py +++ b/libvirt/tests/src/virsh_cmd/host/virsh_nodecpustats.py @@ -1,7 +1,7 @@ import re from autotest.client.shared import error from autotest.client import utils -from virttest import libvirt_vm, virsh +from virttest import virsh, utils_libvirtd def run_virsh_nodecpustats(test, params, env): """ @@ -133,7 +133,7 @@ def parse_percentage_output(output): # Prepare libvirtd service if libvirtd == "off": - libvirt_vm.service_libvirtd_control("stop") + utils_libvirtd.libvirtd_stop() # Get the host cpu count host_cpu_count = utils.count_cpus() @@ -147,7 +147,7 @@ def parse_percentage_output(output): if status == 0: if libvirtd == "off": - libvirt_vm.service_libvirtd_control("start") + utils_libvirtd.libvirtd_start() raise error.TestFail("Command 'virsh nodecpustats' " "succeeded with libvirtd service " "stopped, incorrect") @@ -209,4 +209,4 @@ def parse_percentage_output(output): # Recover libvirtd service start if libvirtd == "off": - libvirt_vm.service_libvirtd_control("start") + utils_libvirtd.libvirtd_start() diff --git a/libvirt/tests/src/virsh_cmd/host/virsh_nodeinfo.py b/libvirt/tests/src/virsh_cmd/host/virsh_nodeinfo.py index 8b126b57c..de8f9b52d 100644 --- a/libvirt/tests/src/virsh_cmd/host/virsh_nodeinfo.py +++ b/libvirt/tests/src/virsh_cmd/host/virsh_nodeinfo.py @@ -1,7 +1,7 @@ import re, logging from autotest.client import utils from autotest.client.shared import error -from virttest import libvirt_vm, virsh +from virttest import virsh, utils_libvirtd def run_virsh_nodeinfo(test, params, env): @@ -77,7 +77,7 @@ def output_check(nodeinfo_output): if check_libvirtd: libvirtd = params.get("libvirtd") if libvirtd == "off": - libvirt_vm.service_libvirtd_control("stop") + utils_libvirtd.libvirtd_stop() # Run test case option = params.get("virsh_node_options") @@ -91,7 +91,7 @@ def output_check(nodeinfo_output): # Recover libvirtd service start if libvirtd == "off": - libvirt_vm.service_libvirtd_control("start") + utils_libvirtd.libvirtd_start() # Check status_error status_error = params.get("status_error") diff --git a/libvirt/tests/src/virsh_cmd/host/virsh_nodememstats.py b/libvirt/tests/src/virsh_cmd/host/virsh_nodememstats.py index b6129827b..9a3d0d574 100644 --- a/libvirt/tests/src/virsh_cmd/host/virsh_nodememstats.py +++ b/libvirt/tests/src/virsh_cmd/host/virsh_nodememstats.py @@ -1,7 +1,7 @@ import logging, re from autotest.client.shared import error from autotest.client import utils -from virttest import libvirt_vm, virsh +from virttest import virsh, utils_libvirtd def run_virsh_nodememstats(test, params, env): """ @@ -50,7 +50,7 @@ def virsh_check_nodememtats(actual_stats, expected_stats, delta): if check_libvirtd: libvirtd = params.get("libvirtd") if libvirtd == "off": - libvirt_vm.service_libvirtd_control("stop") + utils_libvirtd.libvirtd_stop() # Get the option for the test case option = params.get("virsh_nodememstats_options") @@ -69,7 +69,7 @@ def virsh_check_nodememtats(actual_stats, expected_stats, delta): if status_error == "yes": if status == 0: if libvirtd == "off": - libvirt_vm.service_libvirtd_control("start") + utils_libvirtd.libvirtd_start() raise error.TestFail("Command 'virsh nodememstats' " "succeeded with libvirtd service" " stopped, incorrect") @@ -120,7 +120,7 @@ def virsh_check_nodememtats(actual_stats, expected_stats, delta): # Recover libvirtd service start if libvirtd == "off": - libvirt_vm.service_libvirtd_control("start") + utils_libvirtd.libvirtd_start() # Print the deviated values for all iterations if status_error == "no": diff --git a/libvirt/tests/src/virsh_cmd/host/virsh_uri.py b/libvirt/tests/src/virsh_cmd/host/virsh_uri.py index 5c58df54e..80155af15 100644 --- a/libvirt/tests/src/virsh_cmd/host/virsh_uri.py +++ b/libvirt/tests/src/virsh_cmd/host/virsh_uri.py @@ -1,6 +1,6 @@ import logging from autotest.client.shared import error -from virttest import libvirt_vm, virsh +from virttest import libvirt_vm, virsh, utils_libvirtd def run_virsh_uri(test, params, env): """ @@ -31,7 +31,7 @@ def run_virsh_uri(test, params, env): if check_libvirtd: libvirtd = params.get("libvirtd") if libvirtd == "off": - libvirt_vm.service_libvirtd_control("stop") + utils_libvirtd.libvirtd_stop() # Run test case logging.info("The command: %s", cmd) @@ -48,7 +48,7 @@ def run_virsh_uri(test, params, env): # Recover libvirtd service start if libvirtd == "off": - libvirt_vm.service_libvirtd_control("start") + utils_libvirtd.libvirtd_start() # Check status_error status_error = params.get("status_error") diff --git a/libvirt/tests/src/virsh_cmd/host/virsh_version.py b/libvirt/tests/src/virsh_cmd/host/virsh_version.py index e155b08eb..396b15b31 100644 --- a/libvirt/tests/src/virsh_cmd/host/virsh_version.py +++ b/libvirt/tests/src/virsh_cmd/host/virsh_version.py @@ -1,5 +1,5 @@ from autotest.client.shared import error -from virttest import libvirt_vm, virsh +from virttest import libvirt_vm, virsh, utils_libvirtd def run_virsh_version(test, params, env): @@ -19,7 +19,7 @@ def run_virsh_version(test, params, env): if check_libvirtd: libvirtd = params.get("libvirtd") if libvirtd == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() # Run test case option = params.get("virsh_version_options") @@ -32,7 +32,7 @@ def run_virsh_version(test, params, env): # Recover libvirtd service start if libvirtd == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() # Check status_error status_error = params.get("status_error") diff --git a/libvirt/tests/src/virsh_cmd/monitor/virsh_domblkstat.py b/libvirt/tests/src/virsh_cmd/monitor/virsh_domblkstat.py index bbc397380..a7f3878a9 100644 --- a/libvirt/tests/src/virsh_cmd/monitor/virsh_domblkstat.py +++ b/libvirt/tests/src/virsh_cmd/monitor/virsh_domblkstat.py @@ -1,5 +1,5 @@ from autotest.client.shared import error -from virttest import libvirt_vm, virsh, libvirt_xml +from virttest import virsh, libvirt_xml, utils_libvirtd def run_virsh_domblkstat(test, params, env): """ @@ -46,7 +46,7 @@ def run_virsh_domblkstat(test, params, env): status_error = "yes" break if libvirtd == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() result = virsh.domblkstat(vm_ref, blk, options, ignore_status=True) status = result.exit_status @@ -55,7 +55,7 @@ def run_virsh_domblkstat(test, params, env): #recover libvirtd service start if libvirtd == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() #check status_error if status_error == "yes": if status == 0 or err == "": diff --git a/libvirt/tests/src/virsh_cmd/monitor/virsh_domifstat.py b/libvirt/tests/src/virsh_cmd/monitor/virsh_domifstat.py index 74ec923d2..e7bae1bb1 100644 --- a/libvirt/tests/src/virsh_cmd/monitor/virsh_domifstat.py +++ b/libvirt/tests/src/virsh_cmd/monitor/virsh_domifstat.py @@ -1,5 +1,5 @@ from autotest.client.shared import error, utils -from virttest import libvirt_vm, virsh +from virttest import virsh, utils_libvirtd from xml.dom.minidom import parseString @@ -68,13 +68,13 @@ def get_interface(guest_name): interface = "%s %s" % (interface, params.get("domifstat_extra")) if libvirtd == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() status = virsh.domifstat(vm_ref, interface, ignore_status=True).exit_status #recover libvirtd service start if libvirtd == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() #check status_error if status_error == "yes": diff --git a/libvirt/tests/src/virsh_cmd/monitor/virsh_dominfo.py b/libvirt/tests/src/virsh_cmd/monitor/virsh_dominfo.py index f16fb0846..50cf99e12 100644 --- a/libvirt/tests/src/virsh_cmd/monitor/virsh_dominfo.py +++ b/libvirt/tests/src/virsh_cmd/monitor/virsh_dominfo.py @@ -1,5 +1,5 @@ from autotest.client.shared import error -from virttest import libvirt_vm, remote, virsh +from virttest import libvirt_vm, remote, virsh, utils_libvirtd def run_virsh_dominfo(test, params, env): """ @@ -71,7 +71,7 @@ def remote_test(params, vm_name): vm_ref = domuuid if libvirtd == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() if vm_ref != "remote": result = virsh.dominfo(vm_ref, ignore_status=True) @@ -83,7 +83,7 @@ def remote_test(params, vm_name): #recover libvirtd service start if libvirtd == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() #check status_error if status_error == "yes": diff --git a/libvirt/tests/src/virsh_cmd/monitor/virsh_dommemstat.py b/libvirt/tests/src/virsh_cmd/monitor/virsh_dommemstat.py index 1a3681255..d10ea582c 100644 --- a/libvirt/tests/src/virsh_cmd/monitor/virsh_dommemstat.py +++ b/libvirt/tests/src/virsh_cmd/monitor/virsh_dommemstat.py @@ -1,5 +1,5 @@ from autotest.client.shared import error -from virttest import libvirt_vm, virsh, remote +from virttest import libvirt_vm, virsh, remote, utils_libvirtd def run_virsh_dommemstat(test, params, env): """ @@ -23,7 +23,7 @@ def run_virsh_dommemstat(test, params, env): libvirtd = params.get("libvirtd", "on") extra = params.get("dommemstat_extra", "") if libvirtd == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() #run test case if vm_ref == "id": @@ -39,7 +39,7 @@ def run_virsh_dommemstat(test, params, env): vm_ref = "%s" % vm_name if libvirtd == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() if vm_ref != "remote": status = virsh.dommemstat(vm_ref, extra, ignore_status=True, @@ -65,7 +65,7 @@ def run_virsh_dommemstat(test, params, env): #recover libvirtd service start if libvirtd == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() #check status_error if status_error == "yes": diff --git a/libvirt/tests/src/virsh_cmd/monitor/virsh_domstate.py b/libvirt/tests/src/virsh_cmd/monitor/virsh_domstate.py index 14dc10625..21e34ca42 100644 --- a/libvirt/tests/src/virsh_cmd/monitor/virsh_domstate.py +++ b/libvirt/tests/src/virsh_cmd/monitor/virsh_domstate.py @@ -1,6 +1,6 @@ import re from autotest.client.shared import error -from virttest import libvirt_vm, remote, virsh +from virttest import libvirt_vm, remote, virsh, utils_libvirtd def run_virsh_domstate(test, params, env): """ @@ -34,7 +34,7 @@ def run_virsh_domstate(test, params, env): vm_ref = domuuid if libvirtd == "off": - libvirt_vm.libvirtd_stop() + utils_libvirtd.libvirtd_stop() if vm_ref == "remote": remote_ip = params.get("remote_ip", "REMOTE.EXAMPLE.COM") @@ -61,7 +61,7 @@ def run_virsh_domstate(test, params, env): #recover libvirtd service start if libvirtd == "off": - libvirt_vm.libvirtd_start() + utils_libvirtd.libvirtd_start() #check status_error if status_error == "yes": diff --git a/libvirt/tests/src/virsh_cmd/monitor/virsh_list.py b/libvirt/tests/src/virsh_cmd/monitor/virsh_list.py index 63bab1a17..943ebbb3f 100644 --- a/libvirt/tests/src/virsh_cmd/monitor/virsh_list.py +++ b/libvirt/tests/src/virsh_cmd/monitor/virsh_list.py @@ -1,6 +1,6 @@ import re, logging, time from autotest.client.shared import error -from virttest import virsh, libvirt_vm, remote +from virttest import virsh, libvirt_vm, remote, utils_libvirtd def run_virsh_list(test, params, env): @@ -67,7 +67,7 @@ def list_local_domains_on_remote(options_ref, remote_ip, remote_passwd, local_ip #Prepare libvirtd status libvirtd = params.get("libvirtd", "on") if libvirtd == "off": - libvirt_vm.service_libvirtd_control("stop") + utils_libvirtd.libvirtd_stop() #run test case if list_ref == "--uuid": @@ -112,7 +112,7 @@ def list_local_domains_on_remote(options_ref, remote_ip, remote_passwd, local_ip #Recover libvirtd service status if libvirtd == "off": - libvirt_vm.service_libvirtd_control("start") + utils_libvirtd.libvirtd_start() #Recover of domain if vm_ref == "transient": diff --git a/libvirt/tests/src/virsh_cmd/network/virsh_net_autostart.py b/libvirt/tests/src/virsh_cmd/network/virsh_net_autostart.py index f6c2e7a43..985086245 100644 --- a/libvirt/tests/src/virsh_cmd/network/virsh_net_autostart.py +++ b/libvirt/tests/src/virsh_cmd/network/virsh_net_autostart.py @@ -1,6 +1,6 @@ import logging from autotest.client.shared import error -from virttest import virsh, libvirt_vm +from virttest import virsh, libvirt_vm, utils_libvirtd from virttest.libvirt_xml import network_xml, xcepts @@ -77,7 +77,7 @@ def run_virsh_net_autostart(test, params, env): # Check if autostart or disable is successful with libvirtd restart. # TODO: Since autostart is designed for host reboot, # we'd better check it with host reboot. - libvirt_vm.libvirtd_restart() + utils_libvirtd.libvirtd_restart() # Reopen default_xml virsh_instance = virsh.VirshPersistent(**virsh_dargs) diff --git a/libvirt/tests/src/virsh_cmd/network/virsh_net_list.py b/libvirt/tests/src/virsh_cmd/network/virsh_net_list.py index 130822654..e246d899f 100644 --- a/libvirt/tests/src/virsh_cmd/network/virsh_net_list.py +++ b/libvirt/tests/src/virsh_cmd/network/virsh_net_list.py @@ -1,5 +1,5 @@ import re, os -from autotest.client.shared import utils, error +from autotest.client.shared import error from virttest import virsh def run_virsh_net_list(test, params, env): diff --git a/libvirt/tests/src/virsh_cmd/pool/virsh_pool.py b/libvirt/tests/src/virsh_cmd/pool/virsh_pool.py index d34c6a145..3221184fa 100644 --- a/libvirt/tests/src/virsh_cmd/pool/virsh_pool.py +++ b/libvirt/tests/src/virsh_cmd/pool/virsh_pool.py @@ -1,6 +1,6 @@ import logging, re, os, shutil from autotest.client.shared import error -from virttest import libvirt_vm, virsh +from virttest import virsh, utils_libvirtd def run_virsh_pool(test, params, env): @@ -191,9 +191,9 @@ def define_pool(pool_name, pool_type, pool_target): "instead of yes" % pool_name) # Step (7.a) - libvirt_vm.service_libvirtd_control("stop") + utils_libvirtd.libvirtd_stop() # TODO: Add more negative cases after libvirtd stopped - libvirt_vm.service_libvirtd_control("start") + utils_libvirtd.libvirtd_start() # Step (7.b) if not check_list_state(pool_name, "active"): diff --git a/virttest/env_process.py b/virttest/env_process.py index 70a6e2831..732953acf 100644 --- a/virttest/env_process.py +++ b/virttest/env_process.py @@ -2,7 +2,7 @@ from autotest.client import utils from autotest.client.shared import error import aexpect, qemu_monitor, ppm_utils, test_setup, virt_vm -import libvirt_vm, video_maker, utils_misc, storage, qemu_storage +import libvirt_vm, video_maker, utils_misc, storage, qemu_storage, utils_libvirtd import remote, data_dir, utils_net @@ -418,7 +418,7 @@ def preprocess(test, params, env): h = test_setup.HugePageConfig(params) h.setup() if params.get("vm_type") == "libvirt": - libvirt_vm.libvirtd_restart() + utils_libvirtd.libvirtd_restart() if params.get("setup_thp") == "yes": thp = test_setup.TransparentHugePageConfig(test, params) @@ -563,7 +563,7 @@ def postprocess(test, params, env): h = test_setup.HugePageConfig(params) h.cleanup() if params.get("vm_type") == "libvirt": - libvirt_vm.libvirtd_restart() + utils_libvirtd.libvirtd_restart() if params.get("setup_thp") == "yes": thp = test_setup.TransparentHugePageConfig(test, params) From 713574cdea4f2d2bcacc983da9bc574035124b66 Mon Sep 17 00:00:00 2001 From: yangdongsheng Date: Tue, 25 Jun 2013 16:21:39 +0800 Subject: [PATCH 025/254] Add utils_libvirtd module into virttest. Signed-off-by: yangdongsheng Add remote implement for status action. Signed-off-by: yangdongsheng --- virttest/libvirt_vm.py | 69 ----------------- virttest/utils_libvirtd.py | 151 +++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+), 69 deletions(-) create mode 100644 virttest/utils_libvirtd.py diff --git a/virttest/libvirt_vm.py b/virttest/libvirt_vm.py index 0af1cdb53..992d7b388 100644 --- a/virttest/libvirt_vm.py +++ b/virttest/libvirt_vm.py @@ -11,75 +11,6 @@ import data_dir, xml_utils -def libvirtd_restart(): - """ - Restart libvirt daemon. - """ - try: - utils.run("service libvirtd restart") - logging.debug("Restarted libvirtd successfuly") - return True - except error.CmdError, detail: - logging.error("Failed to restart libvirtd:\n%s", detail) - return False - - -def libvirtd_stop(): - """ - Stop libvirt daemon. - """ - try: - utils.run("service libvirtd stop") - logging.debug("Stop libvirtd successfuly") - return True - except error.CmdError, detail: - logging.error("Failed to stop libvirtd:\n%s", detail) - return False - - -def libvirtd_start(): - """ - Start libvirt daemon. - """ - try: - utils.run("service libvirtd start") - logging.debug("Start libvirtd successfuly") - return True - except error.CmdError, detail: - logging.error("Failed to start libvirtd:\n%s", detail) - return False - - -def service_libvirtd_control(action): - """ - Libvirtd control by action, if cmd executes successfully, - return True, otherwise return False. - If the action is status, return True when it's running, - otherwise return False. - @ param action: start|stop|status|restart|condrestart| - reload|force-reload|try-restart - """ - actions = ['start', 'stop', 'restart', 'condrestart', 'reload', - 'force-reload', 'try-restart'] - if action in actions: - try: - utils.run("service libvirtd %s" % action) - logging.debug("%s libvirtd successfuly", action) - return True - except error.CmdError, detail: - logging.error("Failed to %s libvirtd:\n%s", action, detail) - return False - elif action == "status": - cmd_result = utils.run("service libvirtd status", ignore_status=True) - if re.search("running", cmd_result.stdout.strip()): - logging.info("Libvirtd service is running") - return True - else: - return False - else: - raise error.TestError("Unknown action: %s" % action) - - def normalize_connect_uri(connect_uri): """ Processes connect_uri Cartesian into something virsh can use diff --git a/virttest/utils_libvirtd.py b/virttest/utils_libvirtd.py new file mode 100644 index 000000000..dd2c2549e --- /dev/null +++ b/virttest/utils_libvirtd.py @@ -0,0 +1,151 @@ +""" +Module to control libvirtd service. +""" +import logging, re +from virttest import remote, aexpect +from autotest.client.shared import error +from autotest.client import utils, os_dep + + +class LibvirtdError(Exception): + """ + Base Error of libvirtd. + """ + pass + + +class LibvirtdActionError(LibvirtdError): + """ + Error in service command. + """ + def __init__(self, action, detail): + LibvirtdError.__init__(self) + self.action = action + self.detail = detail + + def __str__(self): + return ('Failed to %s libvirtd.\n' + 'Detail: %s.' % (self.action, self.detail)) + + +class LibvirtdActionUnknownError(LibvirtdActionError): + """ + Error in service command when service name is unkown. + """ + def __init__(self, action): + self.action = action + self.detail = 'Action %s is Unknown.' % self.action + LibvirtdActionError.__init__(self, self.action, self.detail) + +try: + os_dep.command("libvirtd") + LIBVIRTD = "libvirtd" +except ValueError: + raise LibvirtdError("There is no libvirtd on the host.") + + +def service_libvirtd_control(action, remote_ip=None, + remote_pwd=None, remote_user='root', + libvirtd=LIBVIRTD): + """ + Libvirtd control by action, if cmd executes successfully, + return True, otherwise raise LibvirtActionError. + + If the action is status, return True when it's running, + otherwise return False. + + @ param action: start|stop|status|restart|condrestart| + reload|force-reload|try-restart + @ raise LibvirtdActionUnknownError: Action is not supported. + @ raise LibvirtdActionError: Take the action on libvirtd Failed. + """ + service_cmd = ('service %s %s' % (libvirtd, action)) + + actions = ['start', 'stop', 'restart', 'condrestart', 'reload', + 'force-reload', 'try-restart'] + + session = None + if remote_ip: + try: + session = remote.wait_for_login('ssh', remote_ip, '22', + remote_user, remote_pwd, + r"[\#\$]\s*$") + except remote.LoginError, detail: + raise LibvirtdActionError(action, detail) + + if action in actions: + try: + if session: + session.cmd(service_cmd) + else: + utils.run(service_cmd) + except (error.CmdError, aexpect.ShellError), detail: + raise LibvirtdActionError(action, detail) + + elif action == "status": + if session: + status, output = session.cmd_status_output(service_cmd) + if status: + raise LibvirtdActionError(action, output) + else: + cmd_result = utils.run(service_cmd, ignore_status=True) + if cmd_result.exit_status: + raise LibvirtdActionError(action, cmd_result.stderr) + output = cmd_result.stdout + + if re.search("running", output): + return True + else: + return False + else: + raise LibvirtdActionUnknownError(action) + + +def libvirtd_restart(): + """ + Restart libvirt daemon. + """ + try: + service_libvirtd_control('restart') + logging.debug("Restarted libvirtd successfuly") + return True + except LibvirtdActionError, detail: + logging.debug("Failed to restart libvirtd:\n%s", detail) + return False + + +def libvirtd_stop(): + """ + Stop libvirt daemon. + """ + try: + service_libvirtd_control('stop') + logging.debug("Stop libvirtd successfuly") + return True + except LibvirtdActionError, detail: + logging.debug("Failed to stop libvirtd:\n%s", detail) + return False + + +def libvirtd_start(): + """ + Start libvirt daemon. + """ + try: + service_libvirtd_control('start') + logging.debug("Start libvirtd successfuly") + return True + except LibvirtdActionError, detail: + logging.debug("Failed to start libvirtd:\n%s", detail) + return False + + +def libvirtd_status(): + """ + Get the status of libvirt daemon. + """ + try: + return service_libvirtd_control('status') + except LibvirtdActionError, detail: + logging.debug("Failed to get status of libvirtd:\n%s", detail) + return False From 7635850684722989e6602c42852e281800b79941 Mon Sep 17 00:00:00 2001 From: yangdongsheng Date: Tue, 25 Jun 2013 16:24:42 +0800 Subject: [PATCH 026/254] Add unittest for utils_libvirtd. Signed-off-by: yangdongsheng --- virttest/utils_libvirtd_unittest.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100755 virttest/utils_libvirtd_unittest.py diff --git a/virttest/utils_libvirtd_unittest.py b/virttest/utils_libvirtd_unittest.py new file mode 100755 index 000000000..9fd5d4ba3 --- /dev/null +++ b/virttest/utils_libvirtd_unittest.py @@ -0,0 +1,23 @@ +#!/usr/bin/python + +import unittest +import common +from virttest import utils_libvirtd + +class UtilsLibvirtdTest(unittest.TestCase): + def test_service_libvirtd_control(self): + service_libvirtd_control = utils_libvirtd.service_libvirtd_control + self.assertRaises(utils_libvirtd.LibvirtdActionUnknownError, + service_libvirtd_control, 'UnknowAction') + self.assertTrue(service_libvirtd_control('status') in (True, False)) + + def test_libvirtd_error(self): + action_list = ["restart", "start", "stop", "status"] + + for action in action_list: + self.assertRaises(utils_libvirtd.LibvirtdActionError, + utils_libvirtd.service_libvirtd_control, + action=action, libvirtd="") + +if __name__ == "__main__": + unittest.main() From 95197ba566614c18088bf1e33831ddd2ebde85a4 Mon Sep 17 00:00:00 2001 From: Yu Mingfei Date: Tue, 2 Jul 2013 23:12:36 +0800 Subject: [PATCH 027/254] virttest.utils_libvirtd: Catch session exception for status action. Signed-off-by: Yu Mingfei --- virttest/utils_libvirtd.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/virttest/utils_libvirtd.py b/virttest/utils_libvirtd.py index dd2c2549e..c46fbe2cf 100644 --- a/virttest/utils_libvirtd.py +++ b/virttest/utils_libvirtd.py @@ -84,7 +84,10 @@ def service_libvirtd_control(action, remote_ip=None, elif action == "status": if session: - status, output = session.cmd_status_output(service_cmd) + try: + status, output = session.cmd_status_output(service_cmd) + except aexpect.ShellError, detail: + raise LibvirtdActionError(action, detail) if status: raise LibvirtdActionError(action, output) else: From cabd6428cbd0e201fad3446362820dca678d713e Mon Sep 17 00:00:00 2001 From: Qingtang Zhou Date: Wed, 3 Jul 2013 11:33:46 +0800 Subject: [PATCH 028/254] tests.guest_suspend: Fix the wrong separator for cpu flags Signed-off-by: Qingtang Zhou --- tests/cfg/guest_suspend.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cfg/guest_suspend.cfg b/tests/cfg/guest_suspend.cfg index ea16b307a..b5faf80c3 100644 --- a/tests/cfg/guest_suspend.cfg +++ b/tests/cfg/guest_suspend.cfg @@ -44,7 +44,7 @@ type = clock_getres sub_test = guest_suspend - without_kvmclock: - cpu_model_flags += " -kvmclock" + cpu_model_flags += ",-kvmclock" variants: - guest_s3: guest_suspend_type = "mem" From 53b6d1e2a1b5e8ff36c67be4b8ce440b318a7156 Mon Sep 17 00:00:00 2001 From: Qingtang Zhou Date: Wed, 3 Jul 2013 13:20:05 +0800 Subject: [PATCH 029/254] qemu: Reset image_extra_params parameter in some block tests. These tests will create some other format of image, so the options for qcow3 would affect them. To make these cases still work with qcow3 format, reset the 'image_extra_params' parameter in them. Signed-off-by: Qingtang Zhou --- qemu/tests/cfg/multi_disk.cfg | 1 + tests/cfg/block_hotplug.cfg | 2 ++ tests/cfg/whql.cfg | 1 + 3 files changed, 4 insertions(+) diff --git a/qemu/tests/cfg/multi_disk.cfg b/qemu/tests/cfg/multi_disk.cfg index fc373b65f..21bd1e153 100644 --- a/qemu/tests/cfg/multi_disk.cfg +++ b/qemu/tests/cfg/multi_disk.cfg @@ -23,6 +23,7 @@ cdroms = "" ide: # 3 + boot disk = 4 disks + image_extra_params = "" stg_image_num = 3 stg_params = "image_size:1G,10G,5G " stg_params += "image_format:qcow2,qcow2,raw " diff --git a/tests/cfg/block_hotplug.cfg b/tests/cfg/block_hotplug.cfg index ede1ad2d2..84d5b0408 100644 --- a/tests/cfg/block_hotplug.cfg +++ b/tests/cfg/block_hotplug.cfg @@ -16,10 +16,12 @@ kill_vm_on_error = yes variants: - fmt_qcow2: + image_extra_params = "" image_format_stg = qcow2 image_format_stg0 = qcow2 image_format_stg1 = qcow2 - fmt_raw: + image_extra_params = "" image_format_stg = raw image_format_stg0 = raw image_format_stg1 = raw diff --git a/tests/cfg/whql.cfg b/tests/cfg/whql.cfg index af3b7c18a..87ab96f05 100644 --- a/tests/cfg/whql.cfg +++ b/tests/cfg/whql.cfg @@ -203,6 +203,7 @@ - block_device: image_snapshot = yes images += " stg stg2 stg3 stg4" + image_extra_params = "" image_format_stg = raw image_name_stg = images/storage image_size_stg = 2G From c47e4971ddf89b2b966e84ff27c24f112af9c9f3 Mon Sep 17 00:00:00 2001 From: Qingtang Zhou Date: Wed, 3 Jul 2013 13:31:49 +0800 Subject: [PATCH 030/254] tests.boot_savevm: Get parameters with new method in virt-test If the parameters are missing, just skip this test. Signed-off-by: Qingtang Zhou --- tests/boot_savevm.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/boot_savevm.py b/tests/boot_savevm.py index a79de410e..d1bae381e 100644 --- a/tests/boot_savevm.py +++ b/tests/boot_savevm.py @@ -34,9 +34,9 @@ def run_boot_savevm(test, params, env): vm.create(params=params) vm.verify_alive() # This shouldn't require logging in to guest - savevm_delay = float(params.get("savevm_delay")) - savevm_login_delay = float(params.get("savevm_login_delay")) - savevm_login_timeout = float(params.get("savevm_timeout")) + savevm_delay = float(params["savevm_delay"]) + savevm_login_delay = float(params["savevm_login_delay"]) + savevm_login_timeout = float(params["savevm_timeout"]) savevm_statedir = params.get("savevm_statedir", tempfile.gettempdir()) fd, savevm_statefile = tempfile.mkstemp(suffix='.img', prefix=vm.name+'-', dir=savevm_statedir) From 3f96f1d826bbe7cc28bc41c4b10b785a0b8be679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20=C5=BDupka?= Date: Wed, 3 Jul 2013 15:26:47 +0200 Subject: [PATCH 031/254] virt: repair Cart config unittest test data. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jiří Župka --- .../testcfg.huge/test1.cfg.repr.gz | Bin 18312 -> 26814 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/virttest/unittest_data/testcfg.huge/test1.cfg.repr.gz b/virttest/unittest_data/testcfg.huge/test1.cfg.repr.gz index 3a3d70f572658668a1adc1ef3fb92e81b37eb279..562707ffbd157ba71e08c2287361bda5ac5fce36 100644 GIT binary patch literal 26814 zcmeFYc|4Tu`#x^pvWzvmF~(N*U3LaDB(#W-orpvtOZFK1R`#V3g~uLBc0x#KL1kaE zlwD-|UH7P-=ly$qKkw)B$M?_gA9FgdtC{;cj`KQ?^SthvJFX})GBLh)hIoV?cDFpl zMQrRHMBMFey5oKOVtR|GJB{zF?-675ShCunM`fysU=2g%SmTI%$;kFt@8^=I)na@R zy)z8@Q%^4reLA{JNQ-@#L==J_7J_Z#NqR>2ohywRwsvoCh`cd?{76~hMSVjim&KR9 zeo=iUhbm{+?WHOEZG9`(?b)w8^Yz8M-3wdpo8g}}itp@f?tlGcE$`;G>wL%GTU_O^ zQSQ*Yv97W4Wo)sCsO$WER8;-!@a)Gjnvj%}ogK9bv0nzOlJ(ybn+KREcI+;RBqbHpWolwLKM$?_<8#)H@$c%(%9C?rE;+2E$!!4A=j8S zZk{8;e~!r_?)#e?#ZUJ-w!ZBzF8UpAZ92P2_FI${N4fUQ8>`g+{4`%Sz4jw#zH^?x zXVUd!RB;1Mr|;#DDVn6<(FrfiP8r?WN0{VVHUAMK}% zj5E!9ZRD)<&mY}#^OijN^kreKfA3_F?VjG>D$W2tX+Sl?$qdj+gP-+nP_8n*46!e(VoVp9~l|@O#>;4FW+|TA=97Boe}+TN%6(* zdz}?NBeOtExANDeT=?9|whXd-R{Xdk=0`Bf#9?v{1o6=R`-2ZrO^SiY- zzj5QO`O7`EA8xN9k3J1-b&nk-G-YfD1h{$EdsSa%{3bkZJ&-b=wYRxcw&8TpAZiI$peDlx>^cDdH%d zTQ3tlc{AY9P1?iL(_69WbuFXUM~mFYS)y-xbSH-97u~9}cEXc3_BF56JZhk+_2oM9 zUOD=t@N;&)f#%3=muYupcXp#~tjWS0B6JbgSI@^n_dUk^w(XZHjWZ3=p2d< z&{vICw2MT$O*i{o);5pUj}AA7R1UXl1LSvB3!4rL#~)}G?jFuBRVK8j?72%F`PZg& zrf7!$+zVey+Q{=c#wDyoyWIS?1blgbcm0gD13xQ;xOC?*|J5IZeS1ueGc>7h> ze$F}cUYT0oGe6+<{#!s2-uW%mDyNteXcSdH%7agzV81(<@tV1>W}TEyp4=01(nb4 z7DYRo)l*IhM;sqJig$+eWseRQat^0!_nMAAj@$X}9vwX0>DQAt2rwMEym5KHXG=}m z_~2!uSx)v$c$oF(=FX(?#m40KcSd;h<9fKP59x~=_nmjoq=eLZ$BB;d%l2rzYx{6` z>Zs))k?Tg}btRSH{mGlseqKqgnXglX#uaCO>}$s?t;H#3*EO2SyjgcOZoIcHDl-11 zBV$q5fByO5GoLu6=$z~TUx^>wT#<94IeIAp<6F6M*_y7087p43{3%UlGqqd$bo+Lf zE-5W&E2OwDeyTj3ef5%_qj%Qq%J+t(mD#a{eqULKU306I>6RR>S4I|BocXSvu{Zkb zOcVFa<i*QR z+ZOSn&MiPC;7XFKY@^v&d-2t)Z#PyfVmZgcxFTb29>xmHr<6Ir{PuE}Ge%|PMk&dL z`R*n0Os^kJ%SVTWIfv;h{D-x6h5e!_<44m)Qb&VDYSPjv+AfbDU9VoGe4pWXz_#pr zKvFLlAXn_LweMqcmDo$RpLJ_$XK!{)L+^ZnS_ zpL1E^#bRPWouH!P``n4|Kb^1cymqV@j0^Z#eYCb32kQ9jktx$>zwQ)IH{ZM7o;Ayi zJtyjy1HHyCt9-J)LqY?o89}}?rO4Y*Ar=!zL?L3e0-m==kq*&cH&^r=0=l+XzaNu`c9{r z%^3^-jFlIc>mTlw@zZoB@0%NDD}HZc{J7BP;w^NiW^k(EqGxzWc;vcyjSu-c=hZiv z{c)vnO)Bh-)JJ!W^)5cUt#9GtSFC66A1vZ;|31TJxAL%41z%-?bl>O26<`CoRtf#_ zclt=k{Of3bbcFj1lkQn^E&Eo8K5V4idej*B)4-x%Cg=&xvCp-rareoJ_|_NBkLp@K z(H2{tcy}MtYz8&*y9906WyWm~zv6`{m1V%}@KqWvwh>l%jX}`u&Q%2xs&B z?#HbweW!>Q4e^T?RaNf#SVaY&`Q?-D!ntOAqy3_qL}Qo8du6@nipOc7C6wR(sQ#Zo zWx%)Y9)|v$n(dh(D_^1A7LG0Le|>1`hbr?U?WGC5#Xz6&!s0!)*#a*hFQ|!0DK`XP zi(_x{@D_|wRUJ)6-V+{Q&KwpRe-mDOFEk!Tr>>4>hEF;NqOoMOlcUoraH7ya7_8<)}(s)dqfN=*?jVP9&$%)qGbfn+hCiN!^~^@Bmn{GB%IyvnOeD;Oc#kH zc#Xi>Y(t#I7E_$#sVZBVNgN2P)x5c{-R$eOxJkx>4B3jwqAXpZv4l|uw@^|BtBH}3 zw7{9c#hHmhEX4xB#jOlpk+GWjZl09EUEFzqdle2=W&tk0RMqhjTK-FP^5xkrsl`8jTYo1OZ3^ zhYbc$-!nLi5pN;O!Eb()nrIyiDEws7Cud7XIq@q-Q^;}i&xFouoHM4prG8E>{=K{U zxh{w^WhNlOpC5YvrV^f*x>gq%i&X}b8g%VmGH&SF(1K4aAmx)0a%WN*l6Bn2YkgK2 zAkGUAt+#ws_@DCc4!AHU!v%HHk68yD_nXz^jK@bOCr(fWL#dxy0o4GU{tcTz4Tz^A zk&$D|rHT{;%Aq;3*4Y8oF64g>y%J+9NN#ho;#plm@*&>V{ZoR`Vn^fW@kA)_1RfW^ z^!VOyTA0Kz{=-5mtSp{^!CMm!!CjE0db3u{AvwjHXlLd1S!UoQgF5eiROI$L=^kBS(VTc zPGvT(U};H0Xk{4~Bv$UgrpZip?88V}Rhb1GiAZHQ7C!MtuV9-1fuPK)%shlr&_h=lJQW-(%PjOv~Lv#Sns1jk7j3s~_Si}vIh*2hj zWNY`@n%**iR>N(58FiL6Cm4c52?0Sx4~OvDprV=o;)DirCR+E)&YulzpU1l?U_s2w zWQu?8;p3?yAl?GlO zx3viATP%hO>w>W$AfgFS1aO1< zWx=pLHSGE&GK3lu`-R9&clQ*;7Zpf$O!)U;wiw>t2+Q?j{6+Nhl|~A!<9Pqt0o>q5 z2yO8z>DyW*SK;`lHOVob6#lYV(8&a0i;sm`PTe};3uAsF+6FNztc zok9~og)=e)5D>HJZ&~Z7!s%^;T_szH9Qkocx6Vx`6bAB+y~_z$R4|w%LCUcq$aN&S zgX7+8g6)9Ah=N@STE0*6g2Z2MUgxF}3iF23fKLF6Qv(Sn5IrdcKX)eb&VE_d91h4>BJVjV`(ZhCYLmso$XCVhas|N_vc-*6+`tW#cLxp3? zHBVzW%>7`DtElWQ`krvb3g)>8MK^fyY=mM0|2it0`OcIxHXBXvIHgO}OlN}7wT;LU zPCzE2647)^YQSI+7-R%;&FVhV9$6uPh-gbfCGf%5?rk(V)5mtv%3EL7J{#};KPRHO z7DI?S?Z=$M*+;4mRlZP)1l=;ip#^Zz?&V^qjNk}V zD3*iPP1o)8KVY>9EiQEY2wwQfzE1>Zn_CcNXvb*svT#hK*CZw&#B`@UUlqx%xuqRxuocUFd95||W z1j)fj!6frdaK2&(^>iZdf)WKPNB~CM_?Kf~GbK@QGaiAOWq%D84pJ2I;bcTXaDxxz zq<*{T9JvW(X>%Ymj4(DHpFT9rK$QZG-xJPI&Rh`4051PHkRhJnyeb8=0JuDbKoJpv z7U|FGU8EZ^p=}`L%}|nIr6?kNgesA-GAgh`i~to#Xd(67rgc?)wph7_}gLVR{%9LboGOFrCSUk6bT`sOE4L>YR zeGSbWGMY&%5}HYF#nA9o7^l_&9cQb?9p(veuD>IY5Xw=iv>(OyG$n?5!0K+Cc6f#d zjXRpU+e(YNn_C_kJ`>Llj<4*A8t%+p;1liw9YpM<3O}PHyX&}RXTmtrNoCr@hQ-># zhGA^h8qQcMa2}2l3U_{onHyCWiRx>i+NeCgb=%e*7GWqKnXbV)~X6Req3EJV|54_44Lu;>zY`0uyjvh!BcD_TeXNgMMa3si*-R|z8^Q9wQ!l!*8BTJhOpHzhC!*f?>#sx=w~i*l_v5+j!E0T^zl&zq>YeB=x5`X-5Em$Z;RHIXlRu}M@)LbV zHsd)zczOHO8SVu_`EL(iApgmLDBg+UM1jxwCJY;{t~We6+ScTeM9Gn>;W7N!H(mqi zKoZgdP6yz&6=)%`O_ka~Ix8F#x=2153zt?GL4|M_*q)PDODp~T0w+nK9)h;pnU|! zm;f5aNuoeF9V!?NQ}{uHBl!wi2e$@LCB&S0XVMw#FQ7=wRjP7$LLY1`z;idHFr4k# ze^Ea6j({Rg2`BWs-*TTpg`2-1l}Copi19#z2VzH4gS#GxIpqvE*UK|xw^Cck9h}gA z6b{1a`JD?#GWu8OxmCc834}^)^BoOT%~e1(SKvK+61Jf!+<&y&ah{-A)9p}ntN5im zIH>a%NEtC$*2OY)Qin6rxNF>yW0L(`?c%Yj4(hs_Z$(9ZN_^ok zXa%SA^C;2|0(CvNxmKDAmKvlAV^)QeEsrqK5(OXoL_wga>PSuoigGQO+NDYvS*lWE z@eA7n$%AzTpj@5RpfIMqph^MiCMfE-1g2yFwThTQmjFMH@NR}!;wuW0E&>L^YSds$d%L)yy@rzci3M)23FR}X45%Nc z2DaVS4shdR0fqf@xyD8_RMhQ%7xoIE7f{&S!|>VOkaUG5>NijRtZE`-0EK

f<&( zgrau>hXg|L!~&->LPc=qrg{9BfqrLoWcSG63I!m6CypV+=wZPTMjeGEtMJ3ZqO1T- z5GaT&0!-p_gXlt$E>$_2h8o%0zb{eV_AETWQE-bM75=rnu`{nt@4qFrs{DPZSaTda zer)?Wp3S|Dx{r_zbg)z_4ba7KM8TIlPy|Sv!S^t1I=cAbOZ|s~=a2RBi4+&|5U8Z! zi01i|LlK}<>SzPEsvI=ndl)kv!&aKSAD#Z-H1q6MfC%5?Bz7ZZGU}E|;Hn37%%0Wy+K4U~E?Nr?igqn!y-TwQyfO){v;iY6Q%mNvG01mJx z8KHzS>>*hXR65?K<4N8W1f^FxJUy_I?z{x{1=4SIN$p$Pf9hv|$!B$Ul zqSqLHf)bSUZRaEa;n=TiCcpCVomC6B)arv<2S2~QB_u~whIhkR&JL-a@1)^E5ray1 zzI~lrQz#77IB>u}u5<|ql1Ok%fRI3i?F8e&P{H7~!unsTDe?V@wyn+p4DS|we)wj2 zW6w}q%;^8L8>=9WiVRMz)E_wyA7|Kpg>mGziF^rxN?d9JROWylkl}_+I6aWK11#(m z>Q>>RnTNc&Z#8_-H2+$7AE&~x{lpUncPKQ#;a6Ob6!RC9*qWe@SNNf6qpTv)v>>s8 z#ZeAIya{`P1x=t4jz^RLr$Yq~KMz>d@b99L1h3=b4up)Wugx?L8k-uEf;%@4)-3Mm z91tyVE0wIQZ{E!NZ)&3j{RSt6NkNt~C?EyhA8<(R_P;B8HxM$8b`blUFoE#a3&WEq z3IiquL1iCodvg#1RrS<04gZ}knvL&O%g=h6D(`ffk8uQudUmS_jf?T`KCkmjVdyBQ zm1%tyWNG6EyAr!{x2|qK{s{bLnlxZ}&%O-Px3F{Pw$C*k z>Q*E)^fWDW&+d-RF0OTaajN3FYqxf*-uRoQvQk!`*WBeb*)nQkuET0CcREJdwQChk zelK2&9xZJy4pmn8@2v73k@&`a*lSu*y86A%>rVBkit^d9{q%A66xWI(SBuYAvu66d zR@zb;ihFvh4))g$XSXPR-VrXFeWtKBTJ%Hz%k|>fCh=nX5w`ClxkKv$99|sMem`IO zaPS4a+)|sAA2Ksb*12T}*TdYOo%IaJ7W=?g%3Qx_}xcQE~`aA9pQST+y z8|)md7w>-M`|FH0>BqYcHNrB7TV99Z*7HX>_D9o4`?W`z-wx)kt;o)+?9a`FkMFDa zHto8OxE>1c^#zO{^&OdyeTynnlt1`++uzgYYWj5Nfr_Hv(7t=qU%q3mN7AR8X7yDL z&L4WMcr|@F`T>5ri5s82pmI>1vm&x_bSUz3{pZb9XL38k5ZV5v93w-W>>TPuhxN1B z-M6?t>SlLKdh_+qq$wsjtbY#ho_q88dA-5~hsCp5IcLw$Uw)q^ui|%Mt~WDH@|H+A zF!pa6j3t2WO_P_L|Ek@UnYLlt_xutcle^X%y_rk_<s;|!b^XJb>PBAh= zb48&tL-wO*GaPSOT-MESlyoWRt4@<49aY4*+(>EY%<#UIBwHA{5Oo?W>BjeFnrWV4 z%@2UO%nKoN0EqWqTsg)Kz{*Fz&r}JpezUetOm=>rVezHh3+2=Go@)y`>s#quXgVQ2 z8RD-+cWJ+>KFrgMHGOEh8BfjJP?G^lQgyn~WnN&0oUZ5Mc@wtSAuBY<1 zC;k)9F*xvv3nvVb@5vwkG{9Pmw-lM&wtVkex!C3sCcvrnf1N&x7NXA``G>xbDR<;C zUvoe5{HuCuPUtT`-mCwK1^#(`x~KO9Bo=M8gi*AHJd1%(#?kLgDGZS~%8OIFWLr*= z2K0-KWyycSK^^Los4k33Fyxo|wN@4sYM<-ek;kmTT7_5j+?>vVwcP*gkX6Y!^R2_D z3b(fiFovl298X{PUHFzVb>-^KAM=CsQ4x9xFLJMG^*sSO^8Sg13kQb>t8&|X5s`A6 z!wzN6B*@egIg^rpVg0Kt%A`ArdVX5{U*++YLL62pvvbY{&wrd`Q2=sUj?Su(^b`pP z<`pC-V24>0Y=E4wSrr=@BPOr7Z+|a+Q%Utm(u4Y~w}!_#m?IF{txK($X_B`e^B4^6ItM5FCm=E-ETmia_b|QXODOJ~Xo$ z|G51OSi|n!!GSH^MOVD{4G$-i@YFLL7fvYU zzq^0NV6pbp?H@ZDKx>5ml-h6IEsnqvt|%i4&UL>Frc;xC;(vy`NH%bhAt3@lBK-%L zzmZjOpMQ2%(>RN+n8xlD6MY@)Wm2;PnNsD?_61W`7x4hmO9UlBxB$EW`v8Rj7XZTY zY(C>@C$p@?Vk;;B`utW~B*uT!J=p<8;qL&P8QVJ-R%CZ7aWV9~@CDk7A&dM;4}A!q zj2RUm3US5eq($q~%NGFkA9tVq4gjS4ArGgtNGJw97k|fKD_Mf^xY)edp+h&M2fvGd zu~K~RPwgSh&*nSdbFuxMVA_=e#1j&LPHl_CpaC#F4uVJ{(WSBi1L>mgdrrSMC~r~B zsHoKE=-ty7R~pfpMh%ZH&3`lsdcS*={LaG=eF0NCOY9Xec1EXSr}3zAv`ETn>&5Ge z;@fsZZ&|N^yy3p$^;MLEECa~7DD;<_Z-e^(r^Jz}D`6hZ4f&n9$2H)1Mz3&TGr9gm zhW(Ipx?Yu|Ov800yI(HHuoReH6Uz90V@RETz=J^1i7^>nK$yliwB;Fe*7bu~vs5a{ zkR|KckOlK0!QU=kL5oystV4^3S88%%*W>yj!we6U5J$OGa;fYIW1qY+^~X=89uy2- zOxIZ%)%)#|p3-~#)I(ACaeZ;MF-jz>HFmUvJ8?m^pxdLt3O>Z?DNs* z^)L5Kxg(gK9x;+R*rm^iO%WwaI9Irq*DFBrX8Usn8h^kRn71(zbdXN2#w^PMDJ3bHPy zV`T>TMp3?>a{H>hW%}nv6f+!7b^x>Coc()70c2H26|u|oyZ9x}qy;>;Z*q`)nKxsDnUV6$t|P2nCvX4ob< zC+byVWV-oAkP4$SiOZ^$l3*fZ4!w;=nwInQoGUs@#|hCM`Sf9#!6XhqA^n5opRlU% zeQLzexqt%oJvE7M)`Tt9Y1{R;)87@{Wo9&RDKdWmj2^@u94n4v0N8(1ea8P3IyCS< z;LFvkj*uA`tGV_!S55Kb5d5Br{n2<~&DknmPJvgFJR~35p{5HNK{&#HvsW0MZC%Ez zk_6$%n6unQiW) zeEHt`D`V63R<7tnQG!H93hknYVow46aP?PBsVuxWlt`kZgkC}I$iHZdAT>E3TaffM zfk;!1s&I0%=FAQ-WjJVmGRx+;D0boyBuB12o zYSdWaFKIQGCsfZKZGSNQo2y9VaR`3Tc)t9RMd{cRh8)E_!pI=sl8mbEHTLtss|718N^{Osdd*d3Xl3Luk_?Or`H;+rfd2Uj%uLk5mzwa23 zW7VF%#vYSL7@LjM?zxmdkTomdl4@;+pJyc%oekIWqB&xB2<6MY6R4lD(7SfhI4XXrHM?B{Ya3V{$M3Wru!VZ9(#t(E$7&VZ` zf-)Ti!webL7n~#YDg?o{J{}ITb^sHyeTK^k0yR4*Y?eXVjKGH;`(a82v1J#Jlc6!? z;2Qz0VKO!=9%nGf(-Uc>CR5NDCaZU(wu%ca*A$^!_IQQ#6(=0VQy?7vbX{aW-D2aq ze_z?Ibkp2NFwpij^XJ&P{iD#?ufPSL`%}cj} zu;Yz@OvjD%ykQTHAi1Y6ypaA5Vi*!&kDC7+@)H}vn$Dt}T71WnQUn55=uF3#p zK~}DL^>B#uKLWtv;!f+SI?MthqIZkT7a1x%nqXNd$u|(o(o8bU(mZzc)+EIF9|1Ts zI=#NsTqX%3k}adb3Cl0Z%QkMMIx&GSn{~ zT)4cvNSyeMtg>F`!fxrPD3Hz6_kO!Go`_|NB669QSSESF7XN2u9_81iVhW1sfEkcV z*BSz46xeI5dU=jg9B((J99hBni6JobafMX!t3lJnQwFR$8jb=~j~{K8jxhXkJpu>8 zbZ3>p8GIextG0vWo9HR)24`eUeuBsA0(B^Rae2EkdiJ+V3MDl-QRUNPtKpjPFJEGb z1nfcLZ+zWUB0g3V5ZIV>>J%g_;8H^(`+A2-n}6ckbFAtaV$N<2)F7G_KSD028u(LCY1YHBy?fS%Ycqr#|$& z8fI3oT>h*2-_lF7f>#WeUXkK9KwLJ%rpqF~MfE$uv@^^?Ibfb)<+PwFwQ`=Y(sc

xsSH_{15Y=WFIaRLg0(i}QIq0q6YNk1IZ z2Pp**y+jTS6ab(UCMXQJ08q>Mre{)BS$Up!QXhc=u>9ALlMv_MOF#k0a}nvHhAR+` zz=7y(U z6{%kOk>$rQalN}!AXPc|a)7m5*5x$E1n4shMWMR5X7k*`;&RWgW|OWjl}zg11C$@;}4b`;4kW7K?&nJQ0``Jno7`L*Be zrT)YD-)<1pdpPXC z3-xn@AHgANQNo>cu2nlKZ>g%%71r>eV z{u%Nl5Y*YC&|hU1oK$*_yA7znq{&K{9zJjz!7JtF9NSkRzYUIwVDJB$OUyG?Q48xUCu|$j`nRM&lbOySTFyC~tvo3Sc26>}p<%A| zPpdgDySJ-5XFmp6IDk4V+qbrqu=6ZcD>#cTZAMzc87x!#N316VM5k_`AwkJS~Smef_tZ zKyDS~i5y;t##Gyol;eAnl-GVV+xgXKe>a`j?YjLlt4q-q8%qW9{z`OBOyAJu7Z6F; zv;ljTf7=*Y_73PP0mgctAX|mt<4V1d>idmY9#ImEiOmEl-<|(-y=(jPIwPO~bf&HW3%5=rnJcla;E>qfu z071qpF?A(x0zsZh%J2M1ZtWb+A+~Ka`Y+|BGj}+V6IWg~Q^lRbvc#8#J^$@Ed#{{V zNqsrL7r8)dW8)nC_fga#A`+jUDJlAcNV3lK)>azG^uCsr=ye&I+ zMY{B<@AYTO*kEO%w(fxX;XjN`$ChjTu zmn}nDBU@VQK&6y;tnv!iUp|_oq<0t(&3<*Ncr=3^NW z5a&^mXj(x;2c;l&8bc7mU^&?}n4a)ldxTuYU6r5+FjRO7fyGy z+sapnKbF6{qhrdr$q+0QzC;=@nm#r2sBXyn6QVtb;W~arW7@@MuG5`0r;Oz<`~YQ|D4k_zFW2-DNyfAQ_Aw zA6t15_oUu`F7Jj670`X0n#zut>+w~>Jab9bvAK8F9>hnx2b&>72NAL+`9liFP%>W5 z77YSfaRI!U7^31fiv0&4Xy%w4?&|m8o?Yi1OYpFGwD5CmFuSL?-_!qt*Y2d;zCkjD zvfnM}ic0z6n>R;&1ayfxTQ&awPgUa^CR3<`NV;)wSGHdL zhA`niZF?_>u~OZri^9ap=GyDN_tu72>5iUp@?d%B+BZ4|`o65+t=d;pQQ4N|ds5J2 z5OLbGKMec_T*bNB+7I3b=OXGUjESNw*KQm8eKzM~$USf1v{o`-{Bgo>x9U`Hq<}pt zL4Zy(7tIiXFcjhk1{sNRbI$Fe_qJBh&ySEw;2Uf&P4A*JLFn2>2qo}VqLRDl^8CA@ z2}&XG6sT^r%|!!*&S%de9Wym3bu*KZv8RoQk+}FS=_#O>`+U?8P$E@`;6d5csF4jl zlWZD$IpQ=fm4~d`4QGoDP?11K)(tj=*aj0(O`Ntq96!zBMQ#M17Is^b2T6rNMj+j; zB+6AjWCTb6ijp7Sgeqj0>~QGXUj#xB1@7GAyK#YjW2sPc!s*l32e+U1YUteLiw>>u zIMteZo>^g&Z5_=?=#7jEQcTnaZZ{9`XT;+>NAPA76x=&&s8u;t#W9q~W%O1s4i@((xWxmGak{?t3 z>+3T@7x1JM8*$s}s~VEGBCKI@blOvB_N3cvV0FSwnfPh|P`XMka}Djf>>V1X+@?E;d5fnHb=%YXRTeW+DcBKMt)Z%n~SFsr8|Y zwbm&nKS3%{3%cdyaYV-Ci!Y`?6R%WR9SHAhS&7?`U-Rq3qjTtJXUt5Hbk}+#fFO~y z*6PKwi1XODN2h}Kr_xGVzY1h=Ahgw@71t!U^V7o{l)nLWgX#E0{AO#*ogwQdg zr=0@_1*pTMMOfe#qf1ZAU8XHrPv`3oX^qMmx_qwgTh$t4zQf~6`G+hIU>+pWmjKrc~)4D@spi}@W& z>agR`o9a%Rto?XE#e0-7)kLacji!`GhLzl)%rPnqcKI|j@a;#@^`r9rt847FGs&M5 zO{sf?b3%JwKDpmBcJs2#5LcenowO}q-||a<~TboABV?+pDop-SzuZtXG?K?^g9=|rM4%walNs}*%;4e$ zB4u|pbN(!K-Deoj72?^OJT~IRq74@EoyvM^F_T55hyj8Zzy@@6gx?mt_zv~=qBGHqJUZ#HbIa0Iw#MoqV zkg0o5ME&DCoX7jq+r|3}QO_(T@K~NR^tXvz7`3ypzw^^0yN=+By6!a=lE7q_45DZG z$?p=coY!@dC%c&U%f$#kwL5wT7VM#t4>qRLwZ;f(uC3}^?LO_zTQ>9HW#Z-aUjv4Y zkkh`c4H;yE+5 z(~i7H)hEZ2c-R{u!YcM$lN+PR zC%nIi_NYB%{lgg}yjKWC_C^T;mV7e-M3K&S5q}U+TA`X_kCB2s5-A212Mk9RAg%t#sa$g6Y($;;@>WTiFB93n_dbWxjP>(`bDU`Ug zF${=+_XisdzE(Z0T@2oThZl;q#M0seNLJmG@iR!ax549j@p?Ex){&@dTWF9HYxBiOyuP_aJ_CyW$u5jFQ&B*YXc=mOx z`(UzCU@G3m4NZaJ9%tBWg|i?-Y~ux4se*dRkU_|Jnh>HyRXQ{Q22MWHCIBXF4N>q; zMEsN`-V7Uo)ecXT24zGi+_9E&YBfWWlDP=%eBVi@5kH$CWRtbr;T?Eohk2r zmXjkw%2WGZkX>PI6258v;psX zuVLC#Xm&t$x!VUvxxGRJ4h7+ZDdQuFUbmBT!y@4A!Dr4x)bG8%sr{X~Zu-sVwXfFR z>E>7cc9*h_Ccei-I@DfBe)+P#E9b*U@8>VRUc(piZMbSlE)>LDUUDLkw|tq!SUD5* zn!a=0!1v~=>+F8rjC*c{)b5^DAI+}KmSi@O3zPoda|J2;kpkV4h|__5Z;8^U@%k!@ zH{}!N)M%gEDfS6J=dGPd1}71B-5cG)&+XQ(7qcSWj&_Zv`?LR9ulx zEN=xn$rDFG?Z?97yL!yJA_*U5hoA;g`hYRY$BhJaYydMxNwJxh~ zUc9{7J;k16b8bjnVUwk?TXvUkoYGHnwJ&>vZG0xfFUj=-F)-_TYl|?BSSbsX^3c95T zhbYfh&Ck4&O5+={1@8vt>;)m%d-g!5niC{b$Jc)IUy=C1J}pPM$k=BW>eED?e#rMO zG<{mDujbo5r}KJ67-_=ylozY!ziLT8<$IqGRsiPWg=?^(Vzoq!1jZhorW7s% zd3@a^C(wM|$TaI9WBVgv$=jz4%+w?u`T8=;?I{SSpp`{B0T6bQ+BFE9x4n6@q&Htb z0|`pXODKIe@v1)j1{=vcWA4dJM~S|Ow7G)+%9#0o&zOP`$Joe9HHJ|t$$s!`x*#PP z;7W<(YsJ?an&ze*n0CxskP>TmqfO#dD897O!?X7zBn%70;Ku|hkx90RXA@bxh>pj| zwAMi5IZvS~b7lh@Tr87tRD&Gs6*mr)Zt+`2@b1053aJX2TymlunY>J|8ym&JpFSc< zZen(*>bgGNzK$56rZtd zZqw~`wBVur!jN+CM{BrlV+&X^HY*!*JT@yH=lh;*tm6Z$^s}Swj8AB#b6-UmPM1nL zqj?;WG5HBniCTZ|K@+4RbMa%80$)izl5`_>n2FAGvwl-I9mvv){dLz#`;U7ucWYG} z(TC!f5a9lo)sV+2lUe$^;sG%P0W8kr92#?s2MqE&m_P4Oe@?X!7CvwNX|Am#DwR{4 zSvnXMuWt{Vsh47xir^zmMPiumm-Xx3)jg zfKEr5BNY0h-knu;Qb!#lK+d~F0L-KOY8JlTQofN>t|S-)1{r|__we8^VFEG{m52tH z29^$kFgXc>{`v7BUiS~8Zkgv&iiz6mXwI~vk-zVlD*2a=@0hw?;6eRCuz>{KD2lG> zDLeiz=G`9ONB{sl-bcv$p@~W+qQC-3ABZ7b7(rQM2_;>b0;fWn=f7^2=-0Yx?m{J-Hs&wcN#J~_>Mr7pH&E@H|TG7npJhf2?0(6?n94P2dZWo}bnTuwKKr9ge zW0;R(qub4ppY3Dy!iTHOK`vacOt^1U8OcT^_tc$hS<9NmP)T|T+n;r{>Cb>;C;ZhbsU zYSQ&)N+nB}8JcVvHyKK{8nck4FsLj;B}*ptiV_i~Y_k|9TDVj$DPt+hwJ(FZNhPI( zkrr)k*Uc?@f6olv?jP?Toz6MWbI$pG&-47g=XZY3e2$8G^}zyHqunJ_6IE-c6rF+& z2sfLvw3M+Y#@_}*YM%+wR0VmWnwE{M!@QdLaV;62l{XK!drT=?ftQ-oNCHn4o+6|} zn4_hN&oM_6Gc0cx`DKhpU}9*z;H4fHNS{(PNn0~+F1)A>u{TVHm@R$hMVKR4sL<5T zsBJDaS_=p6-=?X0yfxL@rhh0gT{FEg>*QEP2R-7lcs{3$dReyItrFp-x@NZ@6n zUEdw8gVdJdKwn`^aX{gV`qp)7s|J>QU1hJj1Xp0s3%!YwSg6D-5skp|z);Hs7#>EM zg5MCwRJ88b9ZTA#U?tLLv67YlFytLw{uk1jlk>14)M}?uQWq5ID zXIY9hYK;u;g1n>vEaRA1YZy&z7KL_dBAcW1ZVq7)K_u95K@NfCzeEuy&J@Xr7{hUS zH)Lri$m@vnb9kqlaW&X%F~^5F_GXmh!-0@eZ5$OM7Wfqls7lGW-nQWumF*mgs|bI& z@Mrb8skpi8-^#Vm+>_~GAh1}hS2mC9i>5ir=mtIqB^Kn9L5<-pgR}>Grd07Rf{$?E zIV1c4VRg(Vuj`=-P5~!V!(h_dJGr@&%0DukrR!t5U=2x@2a_9?pf`lgOXMC9syP)P zJ)0u^itqHDMtZmB9+E-WyDBIN)H7+-oel6IK!Ro!pgBM`5+Pg%rlO^c!SoTroehng zW;l(HD_ArtV1kkqx$6gRRpu^K{ioGp?qb<8cVWggivR(*&4!*i;g}r7(Z;Py7AUY^F{?J3II0#F?bH1 zf;tEfsk2;$lbgVZt*Tns5t_@WFxu+<+^jH>S0X}b1tvd}H6FswKZM|pPk+wh;{pFB*qyi2gA!T@l#*)?2s z3;&U@w23bT#xg9&Rr{DG85UwJp|){=3>*sMZWHE~%;%&xOG4zXK&#DeWg3)l84yn{~y z95-esi&&JWL1W=fa2H#6)1JnV=Ahjk&WFUGLbSZVbaob41nHGoXMwIdrLHY{BgKL% z9q)>kf`LU4K}6|m%$gqRJeq%X&tKJ!eGuDQpkxp~D&N5D<)4u93sjMk1lqtD9xa22 z79umNUmK?%fh%jtdZo5V%8$Q8N)jbyy#IyosKYhaTBVW!1;a`T^ezEZKzU_>u%oz= z*Tz)sf)r@O76aja?~wIq+y$Xyty94KOJW|d1%$khCCO5*pjrRo`pN>~+HbT|5)h=o z0`ddZzG%O|!Sac*si(JJbEYHX)+y^Y+2<_$qi5@(=ZW}(3;fN_Gz+~q_a(Kh8I1IU z(CKwCe}I`8M*oxRms^Q5+JqTKTRtMJCsa}g=enhDv-$VfQXs_j zwY(lV<3ZV<(nLeAFww({g2{%(qdE75p{9-eAIu(v0PXEh4I!?thS3P+rdm|wZ4c~p zmo<+E1u`yyk*uV`Y!3Tdb+5H~Hi>$wI^iCgDe;@8jVOAvv zs_+}HF&BFZ%o6p=e6t{W;?%Y_@cjjf)ZZESGuj3Bt9_Q#1;WQHa8H-hcO$)TQ9+cX zQ*@xHMFW(@6#m6SzluNLVOe%C=P?AvAOBLww@GAzec zOBgz(AyY^jUo4d|fiPXVR4EeUoB~ zi3@K$z=gv3p(*_E^@%r|2y@S)DN>d=Pn+K~PD zM}WRew|$(gac0paF%MY|C{7|g5jR`t3@LRYFV>-1zHK}itPT+jOW~=oNZzETs~mWwQ&FC14AJwV3b^L7D*_^RidinxiU^o zWb+yuJ3np+#}T4#B3&fTHd_#+JmvNid z49;7Wruy`i8w4i70Ui>k91w;Y=W`=DPWQ+bWW86|vxTz-LD~*I7>xD?#o*95WP;!t zcg`skbHEd1l8r>T8f!gTa`#^>l zYW~nVk#-K_u{!v6WF0b=sKQxx+ztyOZcvhfWn($^90!St_H`?Z*eQjd)pP|9(XN*U zXI<;!%Y}Ei@JA3G(_fc#n`O8Ta-n0L$fmt z77O!DG|M)aRNa>MoLy%^4FWH1G`(9G9sewekLeYW=ZSkQ?;Rvu_Gfzh;oa1JL)OBU z^wL~D^60}&k0Ve0x25&%KEGn;)O7)gshP?I+pQgNgeg(9P*oeFE>Mo0X<0b3B1M_d zv?BF@-$oo^tPY$*=UyehrdRmE3wXTDk;lQ`q zCav1F1;77%a7)?e7L`9XG>;4>JREhq{U+A0VE2`mZg-AGtS7odh;Q@9{;^b?umuh! z^#9$AW5AZ?b*K#1Oq#z-3z|NhwC7vc`PigWjrCrIr?!7IJlndb5G1Nw`gMv88U|-f zeb=qJTO;9asK>FCGn*9 zJyj(8(Jxba*KEU=$Q5X5Wpm=_A<>CTYWligZmJ&hIUNX7uP44DMW>kujn1gnsMq_JNgYZI7d3 zd@xUc3Aler?y-4D=tj}`ndGmev)@L?R`aj6&h*_Xn&udPY|j3wGIL~e{pw@-cQ$@$ zZ5(?y`6=YwhP1I1=jpbp(}z}{D1BzFfg_YXs)LOPjFpDJ)66T|y zH3^Ri%u;mu=6312Y2cSALF`O3IfP|Mt!v`HZ{vr*wO_Y1sEL-N>Z{wGC_wT^_?rgt zeZQcG?=7bfn^b(+T%#Vm-K?3BgYz=!)>su(qL3){hGqP8Xo)N&-@QZ^@s5}J1x^3f z8~&%=2x^8H6mar*lH}@9ryRBQTGBfg!%fmwK}kqU^_6~Y@fM4@e$`*I4vwmIgx87r z|LFz4?zfTfI-e>n#32eaq3DmSMRK?+Ql|()ABb<%8EiV(=RLi=^4`^YaW?!WWU|3{ zT9*c2Lr!}^QXG`gM_pg6`(W;S2shaEwpH=P!33bE+dVE9^mkT{0XI-ccJRVcHhCMiu%CZdTFi)n@Od2O0NuA@?!_hh&g@{|Mzz1yz0hO4>_g zRvPTpsh1l&`{M6+!H%&>gU4BT6WqmtMQ&Dat?F7k^b`$Wu(2HJiXeJ+WjR@gj0MeP zSaVF_f08vPR)jpdOy+e5;z~2gj>?u9=?0hD10XNU}XKHoAjMMqbL7*Y3Xx}KK}IF z*lynLh&?eS0e7DDe0=cg8Tpxt(&qQa>TfGry`7$(d>w7P+h*o=#_xZH-RU}JSU>EM zJEcfRqs2LH0at^UsV31 r;~ur-PC+F6*@v+St<$Q)XC}?7tsVySx+T>oeOn#FSm#uxtvm03y;x6e literal 18312 zcmb80bzD_Xx9}+mr4a#X&HGy6yzf{p!x`noC#x`XLUhkJLQnwj6VH?_4# z`91mQC1pnp-OS!GX`t?_`oFk$WZ7P>**hHUY zv(Z;EMEKD~YSOK2-KTm=zl|b~qM5~9*MEOseSg)~{#7-3+Vn(NAsN|Vo)IVcsgOS2 z89lB)?X4w|iOEoQvo5Qhp5MDlLPFK4ZmDJ@+bz*QH;sjb>ylH?I8yJ%g_u%((U}M@ z%-XKDvf5l8Jee`}NUfW2;r{$Jeo6nA8T&e8Ju5VDN8=&)Sn8s zu`Xy!Gt(X%=0Evry_i*~`vZV{dU&t8J%v6X;LCD(_FvCAapBZDpa9yA`Fyf+J$Yzmk}%q0vKrD!U2dTSMF z({|#>`X^XV#yxJDXSq8`izKv*G`m?}?_t~K;!6x&^q3IfOG(SRwY=Z8W?Xf9OVn-3 z9DQzl!KC((TR*(7&}{I)wUY1AV%PEZy8gXNomAzKpzUMJdl988OV!IOyq@A!i>oca z9llm2Khc-!dm^%7&zWR%gR>k$ir-3tR<;t^n z+jH>51m%Kl$At(j8{wLhw&;zygN6CF&6b_6HK8XbuFU%Taah-MpAbBZO`|y-&KvVw zP<9tQ9C@~5ovM#h0(<2aO|92;taLhV;&N}FcDdi-aP?r;iG$*;nC}{4NNTFt`dC(4 z+k(S!45^LDcI=e2?_6JqRBi9^>(sl0+V@XB>m+Ax(78mrTbD1#Z83%SqzR@aPxsb# zTYEmNTV7tVw~MK39iI-Dj#%x}7kx<&5 z+Gg6!!K5RF$2+9L$ep77dns1mMiET+ z4E7x{xr>Y~A1%1<&bt^C%u80KXZz}o2Y=1K@;p5A%rPZ$;WQnzsPAV^g>LP^d$W8dN>S(*k;$9_X z;XXX&lfQ@3_@JZm`zSW$L=$uY9t={@SznM6bEJjfih>hh1lp_GbV= zUR~``K;6mK&dAwLo=N2CG{J$VR!jY&oRqYZNMb~n>U|v#UD~+P5Qpl>h~C}}KFJm= z-EguoJEtdZzRM$;!Y9l}ks%G^+|^519n9mxlhZ@f8Ph)^mdlt#x(0jNY34TG21;MM_sSHy zdb%rY*ni*4u5%IEj;rp_bam+~#7%FDE+1Sys&Vk>sQv0e6+QLL?Q#CBrn&j{{?^?5 zDTh#pjrSnzLwuj`*uMWuM~X0!s{Y3WnR|152eyeLXCS5tXit-;!NR*qe}Uh(LGT>s#9SIZ39+1r4L zhaTbeYEl1Ti^LT zW}`e^t8iA1t>dm3$6Kd=x1gXzGAdae={v1hTater?oVJ_~Stb$u2lb+Q{{r0A% z+g;Ns8R)mhx@z1xPG;B@V8H>V?UoN73!5j_MI1|n3;(oobFZnb3=t`{nl(P$T;HB+ z*x6Fa2$v}&HtpjVqCVx6v(Z_Km@7puoY2jD)n6*JO*ZDEwP}vPe^8qvj}^BNRnr~& z7SE%DeDSaS{glVelwrH=YqJD(iZ*25_ z(V>7t6$4TCY=Yh0$it~R3HQyd;opebXEGuwtcAhzNh3?7GWE_GUV8_#+L?6oWRV8u z?HiA9KA@dQRUV#pas{J}(ovfDwn*^C6O@Yajv|Ij#CY2=$LJ_=t!zidDK%C@Fw57D zNly@BoE4Qt(G9;3P;q_4IO4s;IIuAr=*TgARckSP4GD2EIry#UadQczeIJ#dUVZbE zj>^yXwF$ORAl9a#57s6fO|!2vA%XM(F~O{u5c!{(qBla>neq6-lSgSecl>>A3GqDy z#fDz^nyaD!AgdzhcFb)ffbytB?;Oa)*BcN2(KBDm;QpD|l)6M?PFYMoGAGW82O>xq zl1m^%j?Op$xd57NxNQJ{0?}AaEzjrUiI~{!QPk@bDP+t#bSo0>*@e!5hg(L# z0(vESkR512C+aTVxU9RSpPa$xbZtu9Ls0{?!?MgPy>Yg}y=0JAjIz-|PQecJHporX zw-gSYUM$BPmI!}uJFHD5e`X+l^vvL$`{zQVa_`R(fBS1ikDk%~UVZ;}c_YhktFc7GC zu~B$PhTquG^N||ggHfyqGBnBM+**N2vx>wkX{g5xc=1{6O{0VD(V{^M2kpGCn{C>4 zF>D-qdPQt{dbpooBq4F*Z3AL)aanA1da5#2Y*I4xMz-oRu9g-z;JpnGI3*{AoNrv2 zfdE1RoH=M)eVvOK^I9MW0926i!-TRc;_weMR*iMPssJ$`f$i#Xtl31*vj(vde)#@#W)mp(QysCLK10_smEM7O`R^9Wkyf zAr9}F84(VH7@QpFl0FaMV$@fLuaPuRzdrmu*(iNAV3$nN_nEE1&10>bIn_%ux33xo z;zrTmAfPZ7?k1!#255v73=$@Rxc4}kjjrLThTRjNsM^!EQX~Z5n$Hx7b*TH)3!4y? zK@=kpg@_JK@={qr5E-jut9o-v`UMgeGc(Yvl}FrTkZuknCxRJEh6WN{D!Hbafnh4m zTwl5gi5SG2Ed!mMiu4vsZ+p>mO8V;vnFJniNSFk&>9PR{&^Vjx2?N-;CBJlI+pSI+ zuyKjO12Kvd>1eWJDgN#8|FC?}GxHn0F0RpqOGM8gnI9a8m1o-e9}vdP5*)?}6^Ffn z3s@QP6tLLwv)Nz#Y&&`UFF8?EnjdQtD8T#z{uGruR|vk=;E({%j56FL#93?tb6jTf z1xN-61f7_wEDB?oiKGGRwJT4DC?Pgl1DUtsu9^u=JFxU-B-UaRFg>^f$SqOOiB3RO z){h=@lcYf=$(6BHF%pNffh^IGI;KS<@~T?HEIny=Kn@+LRfi>z89t!X-#_==sqfW* z_cOivCx2UwV5H551Os9M73KIIED=MKp0?Mo7(z1~523h06 z_{Q~tO}v~RK9~hpxbGEaQ!t222I>$I5oinnw`2GZ7FAU)DXVY>X3NDuswkM2Q?oBA zPxOC4$j#Eji$RKwYqmeIOgvf-+?FanN?S@gYpe|(WEwvidDKoN<1mSqKm9;2xg8rn{P2;#nOeKXnA4!F1 znx((r9ne94A0Pq=4*;E*_5hJ8mjN?iyzI0yh{U=buhQtvyf%3VgMX_Rn|ua|JfCiqD&HJ(j^=M z@$)hXAP^(8a~J>u7IcV^{3a;aW>*AhVre7oO`R*IPROv@EQ}0Vf}($)#oW2Y&fTPj z8AZ>z#!RvP@Fr;nAvC!aZC;52|VPW!)*5I z>!Y~N@!sn?hl=Rc(IQI8tFowf4BtUcpeA}XJ3bzLePWP>fyo;liBZe(yr|yqN=bb^ znyz7!HL)(;H4|^|D}WA^sgfMzjV-~GM!JXEPjX4TXv+` zy{YiWZwJUnj{VejI3q@$h)bJ?*=JiNP|t;&}oV&)kLD6{D(btL?PZJ1y&;sWzwA4w)Y&S?$#+f7hUcjnABI8#SHGoY+bfJxq;=fS5#+kf2wQ5hHD&`m_4z z@b~X}X?b5q67Z)YvYB;3BRcbL1x}8I`(?Y($uuOUdPY>@Y)gc!(^+oLdE+o?kQm;e6O)kN3Wkv@yy&$V`()V82TG=H9=-3p zaDd^xLEiSCqyr%;i;50(WVp68Q`s)1J|Vh?1NVmid86xlg^4xt3g(S=G)kxFb~F&K zxIizdr_p;?>m%>0I#Zx@^0(Iz#?yFsl~arf3~6Xm8?2znfrWsnrS%8vK4ab+C|IC8 zH1o44%sD$bp4xiyIFIGwHz+S^mS91X%0Z8uSSUHByU9Uj$DIf9cVEM&8^5mPNIOK4 z0EBCPvdBIZ6FA^=9{%}79F+!tJTRa$cI@Z(p1P6+45VQgUn5gA2^6yQNVLwlOPjxVD`DET_J^g~)3j?R zl4hW(^S~EM8u1`x_v;A;*P<7GtQB@gRJ2SUn0mw=GYJ~r9dNg^dpqAyM8wawDtkK#bJDfKr@$?_#nx&maPPb2eWOpsD zpke(UvGi&+>Eu_!!5*){bja7&LP=8z)6MKptgk-w;H#(z^m(=U%)|4*IfnM^xzqMt zh5TE$Xa~v2g>*JNX@wrIpRfq&{I=P+r7e<0*0x5-virt~wqr81UC>A{r+JIRp;L3R~p&C-n#Lg2e#qPeBksW zyS}n8|I5M2>0->;-MXJ=M?XD}`$SG(a_(Dm?yn#AydtxyJreQVIAuFnkLY-H=5aWA zcK7bq0T;Vjns8X5*~k^1+6N~+Cn1?jhrgMAo@}KdW*J4?_KWv7X0+>sPFBaKPkw7J z4+RipEi0KGP8&!mPp{#mvcAXu(a=5Dqa71~w$$cZPr;9FJ~Pq0i)KE9o9xYHi`fgh z_-K>&mRakQT(HsTNvJwZ+!$t6oEqRk+?m zkvG*OEM+H$hQ%#q@p9;SGW>^7)%J*UzWg*C`aTO(ZpA=!kiDtl@`yvJ@)7ilaYg!^=sk(z|4f z6cAl`!tlk3HnfU2{rft)Ds06o+dy^*%W_Zb9OghBd)GA>kY*Of{=%a+Xd^vnldFQ& z$z+Bs8a}m*#omt=rtMo;CVs!nof3XyOfzLFg^&3i_y25^?#i^qe0MDS0>$1RPK4&O zipgnrdWWkWQOsu^`vZaW7V8zuOP@hsLP8-M(Te{h-jwF2XBZr|`Y z)xylF#@e}k6_}+8_veK@fbs4BF_E|W-eAt|T>a4Qy)Ug)z%E$wCu$!HraqvnNvxop zJIJM7klqsMIx3yeC^emgf^)9kG@slNbpXoe{^cKB$6w5vag}u&8v1t)#tBqTsIng_=ReLJ zJY!3?Naa%hiS&X&;orhrWG79BOr}}tHX&AZ70npu6s!>%X|9q|C<7!d*$xYYDWzo!zokf3dMG>y*A`9N0%rWjH zv%$9S>X%J#rBVxC>b@0$Pcc}D!uU!y8{~omgAxRm(mmO$oGUgT6RM8XB0iwR?(#j~G^o5;@)urZISuNwgJ0 zsYK4nAzGmXz2l)QZ^smmOo<@Fn4W*pnqG|D24Nx~`1_uxI{Yq!P?9-TYEP*PZ{Ok= zXm49xDorXi0Zi*d%YOiWf72Ye z3u+X(>c_QCFwrB%UT%Zy-Q0aKIijPpCSCD4Q#3G8jciuIEuDG_(xv`37VLH2A^mz& zX6_d!hRobEs<3oB2X*a`bUW_w)_(q*GFViT3gO?`{G_#G(_J6=H4|~%ly3S(W9+c& zM8}#a6-N(5>9ZR>AAli%)a4E_>t_`x`t?Nbvl%US6{bLLb(0KLL%Iuh#QJ-gk^UZE zS(0T=KUoqB2BnN3@F<0hAnqup0m($!fP&!9r-O-(D9cr1uCEnFqY9|?9!6Vmy3ees zy{cOV$HhfNP82>+!6-e7U7eFBHHuAX1heuBD?)EvXEb{LN33X-iz!8z*bA?S#LK;6 zzOnFtr*3iNIMHDHxkpdofulo2S0Q@c!+oB*DW0}M!P${SAHp?(D7jaJ{yjw$f8P&Y zYsnnFo@A_U6|7VYLLzgtU;l0k{&m6kqt{=LP_?WF8b61l6+c(cEGcro{2odOoPFbdtk$#sh`F)s&4!2v?} z&wimqnUOSg+Y67F`}NfK&bf2U{qlkwCEVQ30gviaA68@mdc@A2=z#1^IojKKq87LD zKECIE>p#$DrheH(m6x!%4bu68PtUQUg%NT#8~B0)wGtZ^{CHUeDNk0`A3O*~yUp8j zR{{v6Edbg-7IAtvdZJ;KB24EL)|s&&(^y2|)L29iuTO|{i3?`{{t<3%Pvj&ziqj}P zTD?fcUP6=9%03zr3nPw_q8R$*rkRPeUQ#MdekuSATu9dnFMu&U?E7^=xF(7Ta{ zKBn(&MJ>hebzNX)g&Rc@Wug^q1icApOEF;$Dz$?Fn%iCM`y_ z@Y8{180sjBAnIsn+*s%zo5%cL0yt9eZY24($>xUBr4Jj7>|_P?@8Ga%Vy z;r|D=C?p#<@&6aw7n$O&iRo7@cSYz@ByT%0nla<&45Ar@46^w$QA;AoW*y~*))Mt) zLe^sRHy$#Rwu8w2A95}h!=!T5cXA9_?Q$5N7%@#xx{Jff{VNwM0e84CZ~QEBQQ!{8 zhg{~D^9`Ai`u;;Vlx2ZGvYrI+u#Bi3?~>T8^S7YP>>M+)a@7gz)5)f4&HSh+q4~L}rBLmqKUd2bOcAS8s|OvAjpWa7OdelT$u@y5_q? z_D_&go=1H8_~S@wQ75z#vA+fPBPU7QzpMH^9a&N|7YH`A3JoiU@{raVIOY0Z*ixD^Jew3p^`(gdnnrmJzEH(?D+BUy) z+U-t0>RPDF*pO<|`9fx2Rr}z~&gr%8M7juR_`wI1aF=z;H>ada%9vEU+(m(~s)COn zgBl04o77nK{JwX8P>yaZCy}~x>Sj7Q@y4%3kR3OekjW3c7!?;E&DaG}78~a$lNY2r z-=?3)%0i)2OmvqMK_UD;NJSSu;|pGtI`v@X#U0EwV1W0v;3IbNw)XrTsk0T$MBx)k zLZ+VDY+4lTRpzhZFhY6;Nk4s9qkw!iy%8D?@1Wt@Bhe{RO>vnd2w7q|V{u|R203^TJPMAG1RW%ZQ8PJ>FkE7T zClTF5=rZ$xRCd!=K1BBzq!l?Br2p-mps^3pcz0lKteEkaD$}>*Dh%?HK}Sm@@z^9r z#%Lr)42ph197IfwlAwbme$-4+V{+oDLjEbN^GLy%N{kSPL2NCUZaqfoza6l(6M$1_ z#eJis6BQ*cVYfGkMSdTe0SVX9YY#L!z~MK&5I9^Tq-m76JXA}mmx$@!{}XdHVGi31 zn-JBQ9YytoQ(Q6-n~0u4(l3yZh~Zpu@*^B(-%}wRTo~S&>lTDLh=TW^#id^R`K*oS z52Y8mJmv!wMvVmHYXK{9n?FNV<6cRBlW>(KIQj%S{uAL(5s7oQ2L-KGuE7)qDj_O^ z=o%kgu7Na!U=5Sh8qKbj)oQ=0Yh?H)Ka#XWTx)+g$FKJlXWe|RM=_`!^WG6wWOKjsxc3T=XV=^= zmTii=>U~Y`W(>HGWF$7R7=tWEPzxLgIwH6e9&viGX?Qyk!Q*-=8RUz`qn5ywT*J&j z=)0PGs0F30x?S%uNM!_Gw<8fH0xh?g0puM|I;dnKA&)p>45DT+H49>mVk~LyaTino zcjz)Gm;|xfk<=4|md1}zVgl))|wR>qjCF4e;XxuHo?+nDBVrY0W-smC*m@e?hd552QzC9MdiYO)E;^@XPdB7 zr!7KGLb|;o)h9G^^UWRqdz`KH6RO(JZ8{N+@|PuXilPDHnGX%lJZG`9vH03~R?F}{!&Ciu&rlXOh<>~| za^cO-Nmp&#XGzHuPhxeCl>X{%QkBogP9PqYb+OG6uYuoF#geZFD;~OYE8dMZo2Il9 zdvjd7*I@c5hgIY3U?qhJZ*3X-xZtpnhY-D0D!hAMw`p8{w zs{u>Pi!5Bx7HPE-m(`XieqxzfS*jqIoyj&oC-ZP-6n9B%S|tb`m=QeGibuMvAR|$# zq`jU&7an2~^+J~oNLGYYiR_Irf)F>A0VSA)iIPY_4VRD1mMqPfWrUT{GEWp7;SEw6 zgB*OkL=VUyIOvfqp=HR?p_H{2<$Msda`jXP zqxY7V&0@wfE1E~lE19u<>4EN@Rqsu`V!xFvJtIb_EH#PkM(A>O`RNKL z7{+#U5~v+3u@M*(9mROQ?5bz0H0_&Ii{h_@$IT-iGl366!CvlehbgZF5aM@9gM7Pw z%#<7|yKeNw+F=wl$5e2B_F~!VBrGDGUofm^fbwT{F%R{ORQ>R z>P+R$tjd^+`yxyJ%Fhgh20~s2LPclB!ugo52<@#-D}NyTw3*S{Vqz*e^$nCnNNc&oN96S=o|#g9 z+0vyz`v=47&Bq2L97I%9;-Zs-o2)6U!0`7D`ZNV#G8K(U`6zEX^FK3jBAG@Daox-@ zK4rvsYdLAL#CUJZLsX_}!z_@&5Wnd=&{rTw@GCxQjGwA8KT6+<{qy^9q54Y1>*1H^ ztr=r+hitAYG*!wy?+zoJHbS2nDtGKuX;^IxD6BZY^lKi&;M1CGT@zA_IBjS#wX54b zYFJ^eLEuh>dw7bJc`!#?70Owc$fxI4YQNgcFRL^$Cn3FOPsS4K*~hQnr^oWLqA?gp zt2tPQh{aecKaey;4v1m~tu-8$b#)gd(r7b-}+h(_r^9Vo4cz82@L8c z!HQ9LIHfY%uLETQg9B>ul`|{lMr8)el@{*q<{0afezU{So)3Op%vazXdes6rb;r4% zpL;kTD&*@eJ)eRZeq|M6-^i;sc3m0TO&=Z?xK)D6$(**+uF7&_aMDL&AVjAKh-J~_=y2fP z@W{P%sMCeedo5U$xptjaRO<|9<>cUAczyUNk)Ts5^`1QYw|m~<--raJ2*hQ6VN<_{ zIrxR|r9+)Agbr(01(++%!UOUu!eNmxd&%$1PW~P-*QM}KC zIc9{PsJEGaB>NRF3Q=reAvpk+c-xUG=xh_h7I3;k9iz?FwiK(q5h@zqPIR9^W?}e} zg|g(yd6JsIAcWEtuw!Rl!rZ-XySgoq`i7ze)MQq&za|RWx7AZeEQUwBlqK~%tlimu zSXaRweLP7W!$|gOd*_AwO|ra@vK#d!{i|1E>xp&Hx|C3gFk5p`NwY*= ztAkmWG0!9>OqUbL{uQK>ucpfXDL*&HaX6%n2$>W-oEM5$8-f^%;jzsK9byIJv3N!j z1!Ia&sgNSaO6rT=MQxanYT$VCcCYL-MnIof(PvD#!Oa5Ekf=lQ+_=Y!2mQNMMU|0K zeh^RbA`{AUW2O9@XUUelPk8q3PzE616!iq(_qX6w%Ix4qAH-EG{W;$X?Nv<@lTbic zLguV}?ikweMB&%u=k`hk9Xu@N6eV)J9ZX}mCR~v{{!NtU$IRAf?M$E*{H?)^#IW>G z8L`oqXou0;oWNf?o?NMI?VZ3uV%FG=!iC;#Rq>@kF&>A@2mqNiD#qvRB%AV1a;|<7 zih!vwbxI~Y$W*+t1TUq6C%~gkFcD+6&tOms(XE8i0s7P%?sr+$nts=}p^^Efm?+2f zIzOSa+l8rbK4FX;h~G23sU2KEpTPK|2wE`-bKOtv&8jjIJyzVz{R$Geqs{&*a;3#Q zGGyxZOW@$D2UwKWFCak0_(~iv2$h-3JVB|v+r6{vS zB7(vk<6MV>r|T{nvA(S1+)g0^Up}CinA4qXj+vV9r+Z|tJKc*h)@sZ3+=})jUW~;i z(K;oM)<)Yb|2zS|f_PIfP}986P-B$p>0ya7?D@paTr#gpyFeK~SC%wqwp?@5&f3B{ zZ103&`+h39@^qv9*C=>sY6Ncb zHcJ0<3`umMq_0?fcYgLi@c5iNRDF=OFM?Ru(J#H*!+J3x{Cx_*N&^;=O`BYqJ*a0;b~P;lu)3Ns7dj~T9GJx*Z&3_QjPbqdzz*ay zVkK)dq`p$oVZvp?Nu9UcRt2^_;Q9s=ZKEw+Ilup)>0m7Hw(AJ5$Pln*)fG`#S8oFe z1j+L}Mx*V2v*hA(S0Tvq#0@eqyb zFoxBvc2~>ti-3Q{SW+DGgO2z-7{p9`wXZRVL7_*->D6v@jb5#WH&_Tm>bqtkwM@M% zIS#BkBnq#fw>9cK0|mh-zv@A|A$WLm6sio^ibh#}wwUMQ;e0T>a`@%@=x>*<-#dagW-h&}nms7#)ayMe%MOC^MsGGYW9UBn&#yz(($doP?EZ)K*g(wP! zIIP~LL|0h78A0Ju4@wXP!%9Bbwk0U=wVNwQR~+xc1`xA%XLT4cNMXA|k)!wN|CJFntVE_IEM_Yak$t$uZ`@ zV=@3#&RU>GE;d#Sme(8CYmIZ*4?FJMH|Po{1xuNZWP4;9ko z9cSK^XsYPGqPW=TtWjv@p8Cg}Z;i&@?l#Ip8>9s$6fMxoIZV>zZDt;P^L?jj1{~_- zO2%ZDU}+rWyNRDONL`0O02-2NA@;u77*USK2_7>6%C#d6&yCQTx5)@~d->t%c+S%u z4n~Lycznw_n-U77tL^e-Tajw4Yl8(1P4k1iMi8^6XA=^GG2iODtC8to@m9d*q@{aj zEhW98Ul0coQ=^-0`Vad?4U&f(b@=$YxgPR(!=6_`72pxmjL>nCVBN+TXqDgSQDTmm zkMfp*au$s8vmT9ZII`&ik9aI%T`H4%+#2O*Z}Na~+72TOEVd;fH^)X@t;s2rn;=Ir z0^8+oOCyu}SD_|IJN73PJ>)sHlrrDDq8v$`+K5DnWzjnB`k46Ul|`8dT`Xy`CHL~A z5DT{vk_cI1IfjniIo{|D*B1#y^ zgRPRWd_MM4Ia-WesVX+DX)RJV<@Ipeq*W8W5S`cZImA?8gMa}=C@2Kbx-xwk&$H7`29v+C2!Qo>Qh0EXXQ?{j<7(r7nH; z#mfH5ijMNK6BR17FI%G%;4R}%`qu#(-eb0xCgI&t{~V)fjt&)TIp*hK3Wm>wPechi zeWRv)Y^p?q4jdG@3}c?ByJSgYi2gN0YIiurADHR{4kp7)2!&o=s^?J#0N@Rdlg zR%$bN|LZ#V+sm6097q{s9Jo3J?!2E0Ugt-XV~~T7ks&nNmEb|}DAo^w@F*}E1QaxK z@bYe=j_|+?acd^sLdGHeHfk9aIgoUYJ|H^FFV|Qa_nPx%7Zh6v&|;o$MYNf9IK1IG z;RfrDK4T6%X01eCm?cUSiTp1VWZ|G#6%4*C!6fBvk@CUcUTlcMWJ6BvfEVH@31s*O z2K-@yQwA=`fV{pYw#Wdw9?F3x8=BzyxOwRD_8sYkaX=PSns}sbw&T!@QkI&;g5`v! zgSCs`m+7;ydns#IM1^Y^9x(cr{2X^Z72PM7L2jVOy~34C+JqBkN$oam^>l7uhbfZN z!%X}_BZ)Z0rF9g6XvY>b^V^ud*SL>v>=*inMVcS_pNEpk@p%C4)BjQ8AG7!BD4EK|3j>ON&S{OR8N< zJt^p)m?rJRUkV1l3V|*uc5Wx#HUbxcpVyy0ZcA0;W z9!swMV#sPo!QpJzcF>O{KX9H64zP`ztl_#03MN6`j3tt>?ZhXPEkc3dPv+|uQ)7aHPtl&^imUS|@K4&i{(!JCe_ z*?&?PSy7;$mlB6$p)Q1=**AVzr-kYW?vmdjAk#IrVN;#tcFYKe&Li4@bp_O9R%EGj zV2-%R9?ZO_C#HjT7|<2P+AG<50`H+qrwA@DL*7}YPpzq-F0-@%{X8i5BY;4DI|u@Z1eDku~d&K|jJnm>w{ zsXg<0BrrOH;kjhc?K-8meeL4Yz4r=r%xkKuUsd%GZznY6%vT&gYdw%r=OE8eq+`tR zdmBltCN3|ls|W-RRDk0~a_&&v>6(5sdaRxm$F*=O!amsT$sfd4Z2De%bZdBY>th18 zS)(F2fIx?K|0Ga5p&rtWn7Y9`!H*)WW?E;r;$EEOSowEwT>ESsFT>qkLrmBx8IMh3 zgn3?9fHs#Hq%$b`C2$|fdw%<{dGqxCVlVa?F0%9BEk|067aFRa&bMl{V6p4zbv!m-Tm@lwe3ne$b7Ow z@Gj^1KswZ7(#iCX2dx_>Eu0b06I`E`D8?eMx0-i7zw0GQJ#@cY zf@!S|+w|EDJtr!*mx;24^%j}BQ*HkMUPe(>!5fe_*{TaQ%? zGswX~nuH^8W$i&CH^Gusi&lVaw_q1lVtT^%uL49X|Azht1*j%56^)Ys{|ZXR3Fs0l z7|XFnu*ND`8~>|5C^P<2Ppku$YaCYeA}a9j7;4c_0qE&M%ko<2uP?z%VMf*x$_i#cpkl6}Nm)am)$oqmbd5#aXk%zuRpM#=C=-Tc!d!pZb2yHoyLJm5(;d zcYJk6Zkgg0kB-et%;@c;u^EP*tL7V6ape~E)eXw!d|hHyK07Uag;;s3v$e4Xn|VtI zq Date: Tue, 2 Jul 2013 19:32:51 +0800 Subject: [PATCH 032/254] qemu.test: make block_stream test work with qmp monitor Fix qemu-img create snapshot file failed when image format is raw Corrected block stream command in human monitor (block-stream -> block_stream) changes from v1: Removed configuration to set QMP as default monitor Signed-off-by: Xu Tian --- qemu/tests/block_stream.py | 72 +++++++++++++-------------------- qemu/tests/cfg/block_stream.cfg | 4 ++ virttest/qemu_monitor.py | 2 +- 3 files changed, 34 insertions(+), 44 deletions(-) diff --git a/qemu/tests/block_stream.py b/qemu/tests/block_stream.py index 7d48a7068..faf2f4474 100644 --- a/qemu/tests/block_stream.py +++ b/qemu/tests/block_stream.py @@ -1,6 +1,6 @@ import re, os, logging, time from autotest.client.shared import utils, error -from virttest import qemu_monitor, env_process, data_dir +from virttest import qemu_monitor, env_process, data_dir, storage @error.context_aware @@ -17,53 +17,48 @@ def run_block_stream(test, params, env): 7) TODO(extra): Block job completion can be check in QMP """ image_format = params["image_format"] - image_name = params.get("image_name", "image") - if not os.path.isabs(image_name): - image_name = os.path.join(data_dir.get_data_dir(), image_name) - drive_format = params["drive_format"] - backing_file_name = "%s_bak" % (image_name) + image_name = storage.get_image_filename(params, data_dir.get_data_dir()) + backing_file_name = "%s_bak" % image_name + snapshot_format = params.get("snapshot_format", "qcow2") qemu_img = params["qemu_img_binary"] - block_stream_cmd = "block-stream" - def check_block_jobs_info(): + def check_block_jobs_info(device_id): """ Verify the status of block-jobs reported by monitor command info block-jobs. @return: parsed output of info block-jobs """ fail = 0 - + status = {} try: - output = vm.monitor.info("block-jobs") + status = vm.get_job_status(device_id) except qemu_monitor.MonitorError, e: logging.error(e) fail += 1 - return None, None - return (re.match("\w+", str(output)), re.findall("\d+", str(output))) + return status + return status try: - # Remove the existing backing file backing_file = "%s.%s" % (backing_file_name, image_format) + # Remove the existing backing file if os.path.isfile(backing_file): os.remove(backing_file) # Create the new backing file - create_cmd = "%s create -b %s.%s -f %s %s.%s" % (qemu_img, - image_name, - image_format, - image_format, - backing_file_name, - image_format) + create_cmd = "%s create -b %s -f %s %s" % (qemu_img, + image_name, + snapshot_format, + backing_file) error.context("Creating backing file") utils.system(create_cmd) - info_cmd = "%s info %s.%s" % (qemu_img,image_name,image_format) + info_cmd = "%s info %s" % (qemu_img, image_name) error.context("Image file can not be find") results = utils.system_output(info_cmd) logging.info("Infocmd output of basefile: %s" ,results) # Set the qemu harddisk to the backing file - logging.info("Original image_name is: %s", params['image_name']) + logging.info("Original image file is: %s", image_name) params['image_name'] = backing_file_name logging.info("Param image_name changed to: %s", params['image_name']) @@ -71,11 +66,11 @@ def check_block_jobs_info(): vm_name = params['main_vm'] env_process.preprocess_vm(test, params, env, vm_name) vm = env.get_vm(vm_name) - vm.create() + vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) - info_cmd = "%s info %s.%s" % (qemu_img, backing_file_name, image_format) + info_cmd = "%s info %s" % (qemu_img, backing_file) error.context("Image file can not be find") results = utils.system_output(info_cmd) logging.info("Infocmd output of backing file before block streaming: " @@ -85,32 +80,22 @@ def check_block_jobs_info(): raise error.TestFail("Backing file is not available in the " "backdrive image") - if vm.monitor.protocol == "human": - block_stream_cmd = "block_stream" - - # Start streaming in qemu-cmd line - if 'ide' in drive_format: - error.context("Block streaming on qemu monitor (ide drive)") - vm.monitor.cmd("%s ide0-hd0" % block_stream_cmd) - elif 'virtio' in drive_format: - error.context("Block streaming on qemu monitor (virtio drive)") - vm.monitor.cmd("%s virtio0" % block_stream_cmd) - else: - raise error.TestError("The drive format is not supported") + device_id = vm.get_block({"file": backing_file}) + vm.block_stream(device_id, speed=0) while True: - blkjobout, blkjobstatus = check_block_jobs_info() - if 'Streaming' in blkjobout.group(0): + info = check_block_jobs_info(device_id) + if info.get("type","") == "stream": logging.info("[(Completed bytes): %s (Total bytes): %s " - "(Speed in bytes/s): %s]", blkjobstatus[-3], - blkjobstatus[-2], blkjobstatus[-1]) + "(Speed in bytes/s): %s]", info["len"], + info["offset"], info["speed"]) time.sleep(10) continue - if 'No' in blkjobout.group(0): + if not info: logging.info("Block job completed") break - info_cmd = "%s info %s.%s" % (qemu_img,backing_file_name,image_format) + info_cmd = "%s info %s" % (qemu_img, backing_file) error.context("Image file can not be find") results = utils.system_output(info_cmd) logging.info("Infocmd output of backing file after block streaming: %s", @@ -124,9 +109,10 @@ def check_block_jobs_info(): # Shutdown the virtual machine vm.destroy() - # Relogin with the backup-harddrive - vm.create() + env_process.preprocess_vm(test, params, env, vm_name) + vm = env.get_vm(vm_name) + vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) logging.info("Checking whether the guest with backup-harddrive boot " diff --git a/qemu/tests/cfg/block_stream.cfg b/qemu/tests/cfg/block_stream.cfg index 679be22a9..479808c15 100644 --- a/qemu/tests/cfg/block_stream.cfg +++ b/qemu/tests/cfg/block_stream.cfg @@ -1,3 +1,6 @@ +# Below case works stablly on QMP monitor, but have no more test with Human +# monitor, so suggest to use QMP monitor as default qemu monitor run below test +# - block_stream: backup_image_before_testing = yes restore_image_after_testing = yes @@ -6,6 +9,7 @@ default_speed_image1 = 0 snapshot_chain = "/tmp/sn1 /tmp/sn2" wait_timeout = 1800 + snapshot_format = qcow2 kill_vm = yes alive_check_cmd = dir variants: diff --git a/virttest/qemu_monitor.py b/virttest/qemu_monitor.py index d1c802f5a..06ef26174 100644 --- a/virttest/qemu_monitor.py +++ b/virttest/qemu_monitor.py @@ -706,7 +706,7 @@ def block_stream(self, device, speed=None, base=None): @return: The command's output """ - cmd = "block-stream %s" % device + cmd = "block_stream %s" % device if speed is not None: cmd = "%s %sB" % (cmd, speed) if base: From f2662837db78f55d82f8dc9939c884523eefbbd9 Mon Sep 17 00:00:00 2001 From: Xu Tian Date: Wed, 3 Jul 2013 11:31:31 +0800 Subject: [PATCH 033/254] qemu.tests: move snapshot file to images dir Signed-off-by: Xu Tian --- qemu/tests/blk_stream.py | 3 ++- qemu/tests/cfg/block_stream.cfg | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/qemu/tests/blk_stream.py b/qemu/tests/blk_stream.py index 21873c357..e3daba285 100644 --- a/qemu/tests/blk_stream.py +++ b/qemu/tests/blk_stream.py @@ -1,5 +1,5 @@ import logging, time -from virttest import utils_misc +from virttest import utils_misc, data_dir from autotest.client.shared import error from qemu.tests import block_copy @@ -52,6 +52,7 @@ def create_snapshots(self): format = params.get("snapshot_format", "qcow2") error.context("create live snapshots", logging.info) for sn in snapshots: + sn = utils_misc.get_path(data_dir.get_data_dir(), sn) image_file = self.get_block_file() device = self.vm.live_snapshot(image_file, sn, format) if device != self.device: diff --git a/qemu/tests/cfg/block_stream.cfg b/qemu/tests/cfg/block_stream.cfg index 479808c15..b516326d5 100644 --- a/qemu/tests/cfg/block_stream.cfg +++ b/qemu/tests/cfg/block_stream.cfg @@ -7,7 +7,7 @@ wait_finished = yes source_image = image1 default_speed_image1 = 0 - snapshot_chain = "/tmp/sn1 /tmp/sn2" + snapshot_chain = "images/sn1 images/sn2" wait_timeout = 1800 snapshot_format = qcow2 kill_vm = yes From f40a50463deb7f3faec5fb215cccd214253b7f65 Mon Sep 17 00:00:00 2001 From: yangdongsheng Date: Fri, 21 Jun 2013 11:13:49 +0800 Subject: [PATCH 034/254] Fix virsh.start to return CmdResult object Signed-off-by: yangdongsheng Adapt all virsh.start() to new @return. Signed-off-by: yangdongsheng --- virttest/libvirt_vm.py | 3 ++- virttest/virsh.py | 12 ++---------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/virttest/libvirt_vm.py b/virttest/libvirt_vm.py index 992d7b388..d37a4665b 100644 --- a/virttest/libvirt_vm.py +++ b/virttest/libvirt_vm.py @@ -1373,7 +1373,8 @@ def start(self, autoconsole=True): " vm %s" % (index, self.name)) logging.debug("Starting vm '%s'", self.name) - if virsh.start(self.name, uri=self.connect_uri): + result = virsh.start(self.name, uri=self.connect_uri) + if not result.exit_status: # Wait for the domain to be created has_started = utils_misc.wait_for(func=self.is_alive, timeout=60, text=("waiting for domain %s " diff --git a/virttest/virsh.py b/virttest/virsh.py index 4a1996cf5..04d8b2a5a 100644 --- a/virttest/virsh.py +++ b/virttest/virsh.py @@ -949,17 +949,9 @@ def start(name, **dargs): @param: name: VM name @param: dargs: standardized virsh function API keywords - @return: True operation was successful + @return: CmdResult object. """ - if is_alive(name, **dargs): - return True - dargs['ignore_status'] = False - try: - command("start %s" % (name), **dargs) - return True - except error.CmdError, detail: - logging.error("Start VM %s failed:\n%s", name, detail) - return False + return command("start %s" % name, **dargs) def shutdown(name, **dargs): From 36e9b5b4efef4631b8ac6af8db97bea4e378c04f Mon Sep 17 00:00:00 2001 From: yangdongsheng Date: Wed, 3 Jul 2013 17:13:44 +0800 Subject: [PATCH 035/254] Fix the nodedev_xml. Signed-off-by: yangdongsheng --- virttest/libvirt_xml/nodedev_xml.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/virttest/libvirt_xml/nodedev_xml.py b/virttest/libvirt_xml/nodedev_xml.py index 171ce7254..0278cb8c1 100644 --- a/virttest/libvirt_xml/nodedev_xml.py +++ b/virttest/libvirt_xml/nodedev_xml.py @@ -40,9 +40,9 @@ class SystemXML(CAPXML): class for capability which type is system. """ __slots__ = CAPXML.__slots__ + ('product', 'hdware_vendor', - 'hdware_serial', 'hdware_uuid', - 'firmware_vendor','firmversion' - 'firm_release_date') + 'hdware_serial', 'hdware_uuid', + 'firmware_vendor','firmversion' + 'firm_release_date') __sysfs_sub_path__ = 'dmi/id/' @@ -123,8 +123,8 @@ def make_sysfs_sub_path(domain, bus, slot, function): pci_bus_path = ("%04x:%02x" % (domain, bus)) pci_device_path = ("%04x:%02x:%02x.%01x" % (domain, bus, slot, function)) - pci_sysfs_sub_path = ("pci_bus/%s/device/%s" % - (pci_bus_path, pci_device_path)) + pci_sysfs_sub_path = ("pci_bus/%s/device/%s" + % (pci_bus_path, pci_device_path)) return pci_sysfs_sub_path @@ -178,7 +178,8 @@ class NodedevXMLBase(base.LibvirtXMLBase): """ __slots__ = base.LibvirtXMLBase.__slots__ + ('name', 'parent', - 'cap_type', 'cap', 'sysfs_main_path') + 'cap_type', 'cap', + 'sysfs_main_path') __schema_name__ = "nodedev" @@ -199,7 +200,7 @@ def __init__(self, virsh_instance=base.virsh): accessors.XMLElementText('parent', self, parent_xpath='/', tag_name='parent') accessors.XMLAttribute('cap_type', self, parent_xpath='/', - tag_name='capability', attribute='type') + tag_name='capability', attribute='type') super(NodedevXMLBase, self).__init__(virsh_instance=virsh_instance) self.xml = '' @@ -299,7 +300,8 @@ def new_from_dumpxml(dev_name, virsh_instance=base.virsh): dumpxml_result = virsh_instance.nodedev_dumpxml(dev_name) if dumpxml_result.exit_status: raise xcepts.LibvirtXMLError("Nodedev_dumpxml %s failed.\n" - "Error: %s." % (dumpxml_result.stderr)) + "Error: %s." + % (dev_name, dumpxml_result.stderr)) nodedevxml.xml = dumpxml_result.stdout return nodedevxml From 2a9acdcf30110b272e35c944dab053eabc6a9264 Mon Sep 17 00:00:00 2001 From: yangdongsheng Date: Wed, 3 Jul 2013 09:46:34 +0800 Subject: [PATCH 036/254] virttest: Fix utils_selinux module. Fix the context_pattern in get_context_from_str method. The old pattern will not match the '_' in context such as 'svirt_image_t'. utils_selinux_unittest: replace assertIn with assertTrue. Signed-off-by: yangdongsheng --- virttest/utils_selinux.py | 2 +- virttest/utils_selinux_unittest.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/virttest/utils_selinux.py b/virttest/utils_selinux.py index 5f895ed07..3cf3736b6 100644 --- a/virttest/utils_selinux.py +++ b/virttest/utils_selinux.py @@ -115,7 +115,7 @@ def get_context_from_str(string): @raise SelinuxError: if there is no context in string. """ - context_pattern = r"[a-z]*_u:[a-z]*_r:[a-z]*_t:[s,\-,0-9,:[c,\,,0-9]*]*" + context_pattern = r"[a-z,_]*_u:[a-z,_]*_r:[a-z,_]*_t:[s,\-,0-9,:[c,\,,0-9]*]*" if re.search(context_pattern, string): context_list = re.findall(context_pattern, string) return context_list[0] diff --git a/virttest/utils_selinux_unittest.py b/virttest/utils_selinux_unittest.py index 3262d745c..48108aaeb 100755 --- a/virttest/utils_selinux_unittest.py +++ b/virttest/utils_selinux_unittest.py @@ -32,9 +32,9 @@ def test_is_or_not_disabled(self): Test the method about selinux disabled. """ is_disabled = utils_selinux.is_disabled() - self.assertIn(is_disabled, [True, False]) + self.assertTrue(is_disabled in [True, False]) is_not_disabled = utils_selinux.is_not_disabled() - self.assertIn(is_not_disabled, [True, False]) + self.assertTrue(is_not_disabled in [True, False]) self.assertEqual(not is_disabled, is_not_disabled) def test_context(self): From 978b98f6090c1a748fe949e3f8475ac53c6e8553 Mon Sep 17 00:00:00 2001 From: Lucas Meneghel Rodrigues Date: Thu, 4 Jul 2013 14:07:12 -0300 Subject: [PATCH 037/254] virttest.remote_unittest: Permission fix Signed-off-by: Lucas Meneghel Rodrigues --- virttest/remote_unittest.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 virttest/remote_unittest.py diff --git a/virttest/remote_unittest.py b/virttest/remote_unittest.py old mode 100644 new mode 100755 From 9c24f76f753e706c4c4ee92a791adc75b015910a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20=C5=BDupka?= Date: Thu, 4 Jul 2013 11:23:36 +0200 Subject: [PATCH 038/254] virt: Replace deprecated template with eval in cart-config. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace templates.subtitution by eval in Cartesian config. It allows use basic python expression in configuration code. Speed is almost same as with tempaltes.subtitution. Example: cfg: mem = 1000 real_mem = ${float(mem) * 0.7}M output: mem = 1000 real_mem = 700M Signed-off-by: Jiří Župka --- virttest/cartesian_config.py | 18 ++++++++++++++++-- virttest/cartesian_config_unittest.py | 8 ++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/virttest/cartesian_config.py b/virttest/cartesian_config.py index 65b88b5f9..df54c2c88 100755 --- a/virttest/cartesian_config.py +++ b/virttest/cartesian_config.py @@ -535,6 +535,9 @@ def dump(self, indent, recurse=False): child.dump(indent + 3, recurse) +match_subtitute = re.compile("\$\{(.+)\}") + + def _subtitution(value, d): """ Only optimization string Template subtitute is quite expensive operation. @@ -545,8 +548,19 @@ def _subtitution(value, d): @return: Substituted string """ if "$" in value: - st = string.Template(value) - return st.safe_substitute(d) + start = 0 + st = "" + try: + match = match_subtitute.search(value, start) + while match: + val = eval(match.group(1), None, d) + st += value[start:match.start()] + str(val) + start = match.end() + match = match_subtitute.search(value, start) + except: + pass + st += value[start:len(value)] + return st else: return value diff --git a/virttest/cartesian_config_unittest.py b/virttest/cartesian_config_unittest.py index 8680559c5..b0eba75c7 100755 --- a/virttest/cartesian_config_unittest.py +++ b/virttest/cartesian_config_unittest.py @@ -339,7 +339,9 @@ def testVariableAssignment(self): var += a var <= b system = 2 - s.* ?= ${tests}4 + ddd = ${tests + str(int(system) + 3)}4 + error = ${tests + str(system + 3)}4 + s.* ?= ${tests + "ahoj"}4 s.* ?+= c s.* ?<= d system += 4 @@ -349,7 +351,9 @@ def testVariableAssignment(self): {'dep': [], 'name': '(tests=system1)', 'shortname': '(tests=system1)', - 'system': 'dsystem14c4', + 'system': 'dsystem1ahoj4c4', + 'ddd': 'system154', + 'error': '${tests + str(system + 3)}4', 'tests': 'system1', 'var': 'b2atest'}, ], From b01c5451febd0821247b3e3dcc0168571550c617 Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Thu, 4 Jul 2013 16:11:14 -0300 Subject: [PATCH 039/254] tests/autotest_regression.py: do not depend on wget The JeOS image itself has no wget preinstalled, and other images that could be used with this may share the same characteristic. So, use plain python (and ugly command line) to download the installer script. Signed-off-by: Cleber Rosa --- tests/autotest_regression.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/autotest_regression.py b/tests/autotest_regression.py index e1c071002..2dcfad8ad 100644 --- a/tests/autotest_regression.py +++ b/tests/autotest_regression.py @@ -49,9 +49,16 @@ def run_autotest_regression(test, params, env): step1 = "autotest-server-install" try: + installer_file = "install-autotest-server.sh" + installer_url = ("https://raw.github.com/autotest/autotest/master" + "/contrib/%s" % installer_file) + # Download the install script and execute it - download_cmd = ("wget https://raw.github.com/autotest/autotest/master" - "/contrib/install-autotest-server.sh") + download_cmd = ("python -c 'from urllib2 import urlopen; " + "r = urlopen(\"%s\"); " + "f = open(\"%s\", \"w\"); " + "f.write(r.read())'" % (installer_url, + installer_file)) session_server.cmd(download_cmd) permission_cmd = ("chmod +x install-autotest-server.sh") session_server.cmd(permission_cmd) From f0226d213d02f6521c746bbf0e7eac2cf0e77076 Mon Sep 17 00:00:00 2001 From: Qingtang Zhou Date: Wed, 3 Jul 2013 15:21:31 +0800 Subject: [PATCH 040/254] qemu.tests.cfg: Give the 'usb_default' variant a meaningful name Signed-off-by: Qingtang Zhou --- qemu/tests/cfg/usb.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu/tests/cfg/usb.cfg b/qemu/tests/cfg/usb.cfg index 218a943d3..0becc14bf 100644 --- a/qemu/tests/cfg/usb.cfg +++ b/qemu/tests/cfg/usb.cfg @@ -27,7 +27,7 @@ # usb toplogy variants: - - usb_default: + - without_usb_hub: - with_usb_hub: no usb_nodev usb_devices += " hub1" From 03386442b356302f71e0ef53d4588d73027a22a6 Mon Sep 17 00:00:00 2001 From: Qingtang Zhou Date: Wed, 3 Jul 2013 15:11:44 +0800 Subject: [PATCH 041/254] qemu.tests.usb: Make usb hotplug test able to run multiple times Signed-off-by: Qingtang Zhou --- qemu/tests/cfg/usb.cfg | 5 +++ qemu/tests/usb_hotplug.py | 74 ++++++++++++++++++++++++--------------- 2 files changed, 51 insertions(+), 28 deletions(-) diff --git a/qemu/tests/cfg/usb.cfg b/qemu/tests/cfg/usb.cfg index 0becc14bf..6dde2800b 100644 --- a/qemu/tests/cfg/usb.cfg +++ b/qemu/tests/cfg/usb.cfg @@ -158,6 +158,11 @@ usb_type_usbtest = usb-ehci usb_negative_test = "yes" usb_reply_msg = "Warning: speed mismatch trying to attach usb device" + variants: + - usb_one_time: + usb_repeat_times = 1 + - usb_multi_times: + usb_repeat_times = 5000 - usb_storage: type = usb_storage images += " stg" diff --git a/qemu/tests/usb_hotplug.py b/qemu/tests/usb_hotplug.py index 12b370fa3..ad02590d7 100644 --- a/qemu/tests/usb_hotplug.py +++ b/qemu/tests/usb_hotplug.py @@ -10,6 +10,46 @@ def run_usb_hotplug(test, params, env): @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ + @error.context_aware + def usb_dev_hotplug(): + error.context("Plugin usb device", logging.info) + session.cmd(clear_guest_log_cmd) + reply = vm.monitor.cmd(monitor_add) + if params.get("usb_negative_test") == "yes": + if params["usb_reply_msg"] not in reply: + raise error.TestFail("Could not get expected warning" + " msg in negative test, monitor" + " returns: '%s'" % reply) + return + + monitor_pattern = "Parameter 'driver' expects a driver name" + if reply.find(monitor_pattern) != -1: + raise error.TestNAError("usb device %s not available" % device) + + + @error.context_aware + def usb_dev_verify(): + error.context("Verify usb device is pluged on guest", logging.info) + time.sleep(sleep_time) + session.cmd(udev_refresh_cmd) + messages_add = session.cmd(query_syslog_cmd) + for line in messages_add.splitlines(): + logging.debug("[Guest add] %s" % line) + if not re.search(match_add, messages_add, re.I): + raise error.TestFail("Guest didn't detect plugin") + + + @error.context_aware + def usb_dev_unplug(): + error.context("Unplug usb device", logging.info) + vm.monitor.cmd(monitor_del) + time.sleep(sleep_time) + messages_del = session.cmd(query_syslog_cmd) + for line in messages_del.splitlines(): + logging.debug("[Guest del] %s" % line) + if messages_del.find(match_del) == -1: + raise error.TestFail("Guest didn't detect unplug") + device = params.object_params("testdev")["usb_type"] vendor_id = params["vendor_id"] @@ -31,34 +71,12 @@ def run_usb_hotplug(test, params, env): vm = env.get_vm(params["main_vm"]) vm.verify_alive() session = vm.wait_for_login() - session.cmd(clear_guest_log_cmd) - - error.context("Plugin usb device", logging.info) - reply = vm.monitor.cmd(monitor_add) - if params.get("usb_negative_test") == "yes": - if params["usb_reply_msg"] not in reply: - raise error.TestFail("Could not get expected warning msg in" - " negative test, monitor returns: '%s'" % reply) - return - - if reply.find("Parameter 'driver' expects a driver name") != -1: - raise error.TestNAError("usb device %s not available" % device) - - time.sleep(sleep_time) - session.cmd(udev_refresh_cmd) - messages_add = session.cmd(query_syslog_cmd) - for line in messages_add.splitlines(): - logging.debug("[Guest add] %s" % line) - if not re.search(match_add, messages_add, re.I): - raise error.TestFail("Guest didn't detect plugin") - error.context("Unplug usb device", logging.info) - vm.monitor.cmd(monitor_del) - time.sleep(sleep_time) - messages_del = session.cmd(query_syslog_cmd) - for line in messages_del.splitlines(): - logging.debug("[Guest del] %s" % line) - if messages_del.find(match_del) == -1: - raise error.TestFail("Guest didn't detect unplug") + repeat_times = int(params["usb_repeat_times"]) + for i in range(repeat_times): + error.context("Hotplug (iteration %i)" % (i + 1), logging.info) + usb_dev_hotplug() + usb_dev_verify() + usb_dev_unplug() session.close() From 72d187e2e400005f242da41bc1d863bb48ce801b Mon Sep 17 00:00:00 2001 From: Yiqiao Pu Date: Thu, 4 Jul 2013 20:37:17 +0800 Subject: [PATCH 042/254] qemu.cfg: Update KSM query_regex for check KSM status Update the query_regex for check KSM status for RHEL 5 host. The old one is out of date, and can not work any more. Signed-off-by: Yiqiao Pu --- qemu/cfg/host-kernel.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu/cfg/host-kernel.cfg b/qemu/cfg/host-kernel.cfg index e28146f48..4e174c6ef 100644 --- a/qemu/cfg/host-kernel.cfg +++ b/qemu/cfg/host-kernel.cfg @@ -61,7 +61,7 @@ variants: status_query_cmd = "ksmctl info" setup_cmd = "ksmctl start 5000 50" query_cmd = "top -p QEMU_PID -n 1" - query_regex = "(\d+.\d+\w)\s+.\s+\d+\.\d+\s+\d+\.\d+\s+\d+:\d+\.\d+\s+qemu" + query_regex = "([\d\.]+\w)\s+.\s+\d+\.\d+\s+\d+\.\d+\s+\d+:\d+\.\d+\s+qemu" ksm_module = "ksm" cpuinfo_query.qmachine_type: cpu_info = "pc,rhel5.4.0,rhel5.4.4,rhel5.5.0,rhel5.6.0" From 0562ed5b950a732d9f5814ce587124c569446473 Mon Sep 17 00:00:00 2001 From: Yiqiao Pu Date: Thu, 4 Jul 2013 20:45:14 +0800 Subject: [PATCH 043/254] qemu.tests: fix die() not response in ksm_overcommit.ksm_serial After we kill the previous guest. We still need wait the command line finish in the last guest. Also need send the die() command in the session for the last vm. Signed-off-by: Yiqiao Pu --- qemu/tests/ksm_overcommit.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qemu/tests/ksm_overcommit.py b/qemu/tests/ksm_overcommit.py index 2933aea1f..1d7c5d7a2 100644 --- a/qemu/tests/ksm_overcommit.py +++ b/qemu/tests/ksm_overcommit.py @@ -232,7 +232,6 @@ def split_guest(): logging.debug("Only %s free memory, killing %d guests", free_mem, (i - 1)) last_vm = i - break out = session.read_nonblocking(0.1, 1) time.sleep(2) except OSError: @@ -267,7 +266,7 @@ def split_guest(): (mem / 200 * 50 * perf_ratio)) logging.debug(utils_test.get_memory_info([lvms[last_vm]])) - lsessions[i].cmd_output("die()", 20) + lsessions[last_vm].cmd_output("die()", 20) lvms[last_vm].destroy(gracefully=False) logging.info("Phase 3b: PASS") From 5d4c007d6f483dc5ad4bc5e52d13f9dbbe1ab55b Mon Sep 17 00:00:00 2001 From: Qingtang Zhou Date: Mon, 1 Jul 2013 14:02:32 +0800 Subject: [PATCH 044/254] qemu.tests: Add new test timerdevice.tscwrite Signed-off-by: Qingtang Zhou --- qemu/tests/cfg/timerdevice.cfg | 9 +++++ qemu/tests/timerdevice_tscwrite.py | 56 ++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 qemu/tests/cfg/timerdevice.cfg create mode 100644 qemu/tests/timerdevice_tscwrite.py diff --git a/qemu/tests/cfg/timerdevice.cfg b/qemu/tests/cfg/timerdevice.cfg new file mode 100644 index 000000000..1a3a1a88c --- /dev/null +++ b/qemu/tests/cfg/timerdevice.cfg @@ -0,0 +1,9 @@ +- timerdevice: + only Fedora.19, RHEL.7 + no Host_RHEL.5, Host_RHEL.6 + restart_vm = yes + variants: + - tscwrite: + type = timerdevice_tscwrite + msr_tools_install_cmd = "yum install -y msr-tools" + msr_tools_cmd = "a=$(rdmsr -d 0x00000010); echo -e ibase=16\\n $a | tail -n 1 | while read n; do wrmsr 0x00000010 $(($n+100000000000)); echo $n; done" diff --git a/qemu/tests/timerdevice_tscwrite.py b/qemu/tests/timerdevice_tscwrite.py new file mode 100644 index 000000000..6d34ea99e --- /dev/null +++ b/qemu/tests/timerdevice_tscwrite.py @@ -0,0 +1,56 @@ +import logging +from autotest.client.shared import error +from autotest.client import utils + + +@error.context_aware +def run_timerdevice_tscwrite(test, params, env): + """ + Timer device tscwrite test: + + 1) Check for an appropriate clocksource on host. + 2) Boot the guest. + 3) Download and compile the newest msr-tools. + 4) Execute cmd in guest. + + @param test: QEMU test object. + @param params: Dictionary with test parameters. + @param env: Dictionary with the test environment. + """ + error.context("Check for an appropriate clocksource on host", logging.info) + host_cmd = "cat /sys/devices/system/clocksource/" + host_cmd += "clocksource0/current_clocksource" + if not "tsc" in utils.system_output(host_cmd): + raise error.TestNAError("Host must use 'tsc' clocksource") + + error.context("Boot the guest", logging.info) + vm = env.get_vm(params["main_vm"]) + vm.verify_alive() + + timeout = int(params.get("login_timeout", 360)) + session = vm.wait_for_login(timeout=timeout) + + error.context("Download and compile the newest msr-tools", logging.info) + msr_tools_install_cmd = params["msr_tools_install_cmd"] + session.cmd(msr_tools_install_cmd) + + error.context("Execute cmd in guest", logging.info) + cmd = "dmesg -c > /dev/null" + session.cmd(cmd) + + date_cmd = "strace date 2>&1 | egrep 'clock_gettime|gettimeofday' | wc -l" + output = session.cmd(date_cmd) + if not '0' in output: + raise error.TestFail("Test failed before run msr tools." + " Output: '%s'" % output) + + msr_tools_cmd = params["msr_tools_cmd"] + session.cmd(msr_tools_cmd) + + cmd = "dmesg" + session.cmd(cmd) + + output = session.cmd(date_cmd) + if not "1" in output: + raise error.TestFail("Test failed after run msr tools." + " Output: '%s'" % output) From 53a6b0a38938d6008415190fb7cb55a64d2a7d2a Mon Sep 17 00:00:00 2001 From: Qingtang Zhou Date: Mon, 1 Jul 2013 13:40:31 +0800 Subject: [PATCH 045/254] shared.deps: Add time-warp-test source code This C code is used for time device testing. Signed-off-by: Qingtang Zhou --- shared/deps/time-warp-test.c | 368 +++++++++++++++++++++++++++++++++++ 1 file changed, 368 insertions(+) create mode 100644 shared/deps/time-warp-test.c diff --git a/shared/deps/time-warp-test.c b/shared/deps/time-warp-test.c new file mode 100644 index 000000000..7fceeda93 --- /dev/null +++ b/shared/deps/time-warp-test.c @@ -0,0 +1,368 @@ +/* +* Copyright (C) 2005, Ingo Molnar +* +* time-warp-test.c: check TSC synchronity on x86 CPUs. Also detects +* gettimeofday()-level time warps. +* +* Compile with: gcc -Wall -O2 -o time-warp-test time-warp-test.c -lrt +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TEST_TSC 1 +#define TEST_TOD 1 +#define TEST_CLOCK 1 + +#if !TEST_TSC && !TEST_TOD && !TEST_CLOCK +# error this setting makes no sense ... +#endif + +#if DEBUG +# define Printf(x...) printf(x) +#else +# define Printf(x...) do { } while (0) +#endif + +/* + * Shared locks and variables between the test tasks: + */ +enum { + SHARED_LOCK = 0, + SHARED_TSC = 2, + SHARED_TOD = 4, + SHARED_CLOCK = 6, + SHARED_WORST_TSC = 8, + SHARED_WORST_TOD = 10, + SHARED_WORST_CLOCK = 12, + SHARED_NR_TSC_LOOPS = 14, + SHARED_NR_TSC_WARPS = 16, + SHARED_NR_TOD_LOOPS = 18, + SHARED_NR_TOD_WARPS = 20, + SHARED_NR_CLOCK_LOOPS = 22, + SHARED_NR_CLOCK_WARPS = 24, + SHARED_END = 26, +}; + +#define SHARED(x) (*(shared + SHARED_##x)) +#define SHARED_LL(x) (*(long long *)(shared + SHARED_##x)) + +#define BUG_ON(c) assert(!(c)) + +typedef unsigned long long cycles_t; +typedef unsigned long long usecs_t; +typedef unsigned long long u64; + +#ifdef __x86_64__ +#define DECLARE_ARGS(val, low, high) unsigned low, high +#define EAX_EDX_VAL(val, low, high) ((low) | ((u64)(high) << 32)) +#define EAX_EDX_ARGS(val, low, high) "a" (low), "d" (high) +#define EAX_EDX_RET(val, low, high) "=a" (low), "=d" (high) +#else +#define DECLARE_ARGS(val, low, high) unsigned long long val +#define EAX_EDX_VAL(val, low, high) (val) +#define EAX_EDX_ARGS(val, low, high) "A" (val) +#define EAX_EDX_RET(val, low, high) "=A" (val) +#endif + +static inline unsigned long long __rdtscll(void) +{ + DECLARE_ARGS(val, low, high); + + asm volatile("cpuid; rdtsc" : EAX_EDX_RET(val, low, high)); + + return EAX_EDX_VAL(val, low, high); +} + +#define rdtscll(val) do { (val) = __rdtscll(); } while (0) + +#define rdtod(val) \ + do { \ + struct timeval tv; \ + \ + gettimeofday(&tv, NULL); \ + (val) = tv.tv_sec * 1000000ULL + tv.tv_usec; \ + } while (0) + +#define rdclock(val) \ + do { \ + struct timespec ts; \ + \ + clock_gettime(CLOCK_MONOTONIC, &ts); \ + (val) = ts.tv_sec * 1000000000ULL + ts.tv_nsec; \ + } while (0) + +static unsigned long *setup_shared_var(void) +{ + char zerobuff [4096] = { 0, }; + int ret, fd; + unsigned long *buf; + + fd = creat(".tmp_mmap", 0700); + BUG_ON(fd == -1); + close(fd); + + fd = open(".tmp_mmap", O_RDWR|O_CREAT|O_TRUNC); + BUG_ON(fd == -1); + ret = write(fd, zerobuff, 4096); + BUG_ON(ret != 4096); + + buf = (void *)mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + BUG_ON(buf == (void *)-1); + + close(fd); + unlink(".tmp_mmap"); + + return buf; +} + +static inline void lock(unsigned long *flag) +{ +#if 0 + __asm__ __volatile__( + "1: lock; btsl $0,%0\n" + "jc 1b\n" + : "=g"(*flag) : : "memory"); +#else + __asm__ __volatile__( + "1: lock; btsl $0,%0\n\t" + "jnc 3f\n" + "2: testl $1,%0\n\t" + "je 1b\n\t" + "rep ; nop\n\t" + "jmp 2b\n" + "3:" + : "+m"(*flag) : : "memory"); +#endif +} + +static inline void unlock(unsigned long *flag) +{ +#if 0 + __asm__ __volatile__( + "lock; btrl $0,%0\n" + : "=g"(*flag) :: "memory"); + __asm__ __volatile__("rep; nop"); +#else + __asm__ __volatile__("mov $0,%0; rep; nop" : "=g"(*flag) :: "memory"); +#endif +} + +static void print_status(unsigned long *shared) +{ + const char progress[] = "\\|/-"; + + static unsigned long long sum_tsc_loops, sum_tod_loops, sum_clock_loops, + sum_tod; + static unsigned int count1, count2; + static usecs_t prev_tod; + + usecs_t tod; + + if (!prev_tod) + rdtod(prev_tod); + + count1++; + if (count1 < 1000) + return; + count1 = 0; + + rdtod(tod); + if (abs(tod - prev_tod) < 100000ULL) + return; + + sum_tod += tod - prev_tod; + sum_tsc_loops += SHARED_LL(NR_TSC_LOOPS); + sum_tod_loops += SHARED_LL(NR_TOD_LOOPS); + sum_clock_loops += SHARED_LL(NR_CLOCK_LOOPS); + SHARED_LL(NR_TSC_LOOPS) = 0; + SHARED_LL(NR_TOD_LOOPS) = 0; + SHARED_LL(NR_CLOCK_LOOPS) = 0; + + if (TEST_TSC) + printf(" | TSC: %.2fus, fail:%ld", + (double)sum_tod/(double)sum_tsc_loops, + SHARED(NR_TSC_WARPS)); + + if (TEST_TOD) + printf(" | TOD: %.2fus, fail:%ld", + (double)sum_tod/(double)sum_tod_loops, + SHARED(NR_TOD_WARPS)); + + if (TEST_CLOCK) + printf(" | CLK: %.2fus, fail:%ld", + (double)sum_tod/(double)sum_clock_loops, + SHARED(NR_CLOCK_WARPS)); + + prev_tod = tod; + count2++; + printf(" %c\r", progress[count2 & 3]); + fflush(stdout); +} + +static inline void test_TSC(unsigned long *shared) +{ +#if TEST_TSC + cycles_t t0, t1; + long long delta; + + lock(&SHARED(LOCK)); + rdtscll(t1); + t0 = SHARED_LL(TSC); + SHARED_LL(TSC) = t1; + SHARED_LL(NR_TSC_LOOPS)++; + unlock(&SHARED(LOCK)); + + delta = t1-t0; + if (delta < 0) { + lock(&SHARED(LOCK)); + SHARED(NR_TSC_WARPS)++; + if (delta < SHARED_LL(WORST_TSC)) { + SHARED_LL(WORST_TSC) = delta; + fprintf(stderr, "\rnew TSC-warp maximum: %9Ld cycles, %016Lx -> %016Lx\n", + delta, t0, t1); + } + unlock(&SHARED(LOCK)); + } + if (!((unsigned long)t0 & 31)) + asm volatile ("rep; nop"); +#endif +} + +static inline void test_TOD(unsigned long *shared) +{ +#if TEST_TOD + usecs_t T0, T1; + long long delta; + + lock(&SHARED(LOCK)); + rdtod(T1); + T0 = SHARED_LL(TOD); + SHARED_LL(TOD) = T1; + SHARED_LL(NR_TOD_LOOPS)++; + unlock(&SHARED(LOCK)); + + delta = T1-T0; + if (delta < 0) { + lock(&SHARED(LOCK)); + SHARED(NR_TOD_WARPS)++; + if (delta < SHARED_LL(WORST_TOD)) { + SHARED_LL(WORST_TOD) = delta; + fprintf(stderr, "\rnew TOD-warp maximum: %9Ld usecs, %016Lx -> %016Lx\n", + delta, T0, T1); + } + unlock(&SHARED(LOCK)); + } +#endif +} + +static inline void test_CLOCK(unsigned long *shared) +{ +#if TEST_CLOCK + usecs_t T0, T1; + long long delta; + + lock(&SHARED(LOCK)); + rdclock(T1); + T0 = SHARED_LL(CLOCK); + SHARED_LL(CLOCK) = T1; + SHARED_LL(NR_CLOCK_LOOPS)++; + unlock(&SHARED(LOCK)); + + delta = T1-T0; + if (delta < 0) { + lock(&SHARED(LOCK)); + SHARED(NR_CLOCK_WARPS)++; + if (delta < SHARED_LL(WORST_CLOCK)) { + SHARED_LL(WORST_CLOCK) = delta; + fprintf(stderr, "\rnew CLOCK-warp maximum: %9Ld nsecs, %016Lx -> %016Lx\n", + delta, T0, T1); + } + unlock(&SHARED(LOCK)); + } +#endif +} + +int main(int argc, char **argv) +{ + int i, parent, me; + unsigned long *shared; + unsigned long cpus, tasks; + + cpus = system("exit `grep ^processor /proc/cpuinfo | wc -l`"); + cpus = WEXITSTATUS(cpus); + + if (argc > 2) { +usage: + fprintf(stderr, + "usage: tsc-sync-test \n"); + exit(-1); + } + if (argc == 2) { + tasks = atol(argv[1]); + if (!tasks) + goto usage; + } else + tasks = cpus; + + printf("%ld CPUs, running %ld parallel test-tasks.\n", cpus, tasks); + printf("checking for time-warps via:\n" +#if TEST_TSC + "- read time stamp counter (RDTSC) instruction (cycle resolution)\n" +#endif +#if TEST_TOD + "- gettimeofday (TOD) syscall (usec resolution)\n" +#endif +#if TEST_CLOCK + "- clock_gettime(CLOCK_MONOTONIC) syscall (nsec resolution)\n" +#endif + "\n" + ); + shared = setup_shared_var(); + + parent = getpid(); + + for (i = 1; i < tasks; i++) { + if (!fork()) + break; + } + me = getpid(); + + while (1) { + int i; + + for (i = 0; i < 10; i++) + test_TSC(shared); + for (i = 0; i < 10; i++) + test_TOD(shared); + for (i = 0; i < 10; i++) + test_CLOCK(shared); + + if (me == parent) + print_status(shared); + } + + return 0; +} From 606f610643fd3bee541ef26acead8840366c74f8 Mon Sep 17 00:00:00 2001 From: Qingtang Zhou Date: Mon, 1 Jul 2013 14:48:42 +0800 Subject: [PATCH 046/254] qemu.test: Add test for checking TSC sync for long time Signed-off-by: Qingtang Zhou --- qemu/tests/cfg/timerdevice.cfg | 12 ++++ qemu/tests/timerdevice_tscsync_longtime.py | 68 ++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 qemu/tests/timerdevice_tscsync_longtime.py diff --git a/qemu/tests/cfg/timerdevice.cfg b/qemu/tests/cfg/timerdevice.cfg index 1a3a1a88c..2e7605a4a 100644 --- a/qemu/tests/cfg/timerdevice.cfg +++ b/qemu/tests/cfg/timerdevice.cfg @@ -7,3 +7,15 @@ type = timerdevice_tscwrite msr_tools_install_cmd = "yum install -y msr-tools" msr_tools_cmd = "a=$(rdmsr -d 0x00000010); echo -e ibase=16\\n $a | tail -n 1 | while read n; do wrmsr 0x00000010 $(($n+100000000000)); echo $n; done" + - tscsync: + variants: + - longtime: + type = timerdevice_tscsync_longtime + host_socket_cnt_cmd = "cat /proc/cpuinfo | grep "physical id" | uniq | wc -l" + test_timeout = 36000 + test_run_timeout = 14400 + variants: + - one_socket: + vcpu_socket = 1 + - two_sockets: + vcpu_socket = 2 diff --git a/qemu/tests/timerdevice_tscsync_longtime.py b/qemu/tests/timerdevice_tscsync_longtime.py new file mode 100644 index 000000000..11cc93a2d --- /dev/null +++ b/qemu/tests/timerdevice_tscsync_longtime.py @@ -0,0 +1,68 @@ +import logging, os, re +from autotest.client.shared import error +from autotest.client import utils +from virttest import data_dir + +@error.context_aware +def run_timerdevice_tscsync_longtime(test, params, env): + """ + Timer device check TSC synchronity for long time test: + + 1) Check for an appropriate clocksource on host. + 2) Check host has more than one cpu socket. + 3) Boot the guest with specified cpu socket. + 4) Copy time-warp-test.c to guest. + 5) Compile the time-warp-test.c. + 6) Run time-warp-test for minimum 4 hours. + + @param test: QEMU test object. + @param params: Dictionary with test parameters. + @param env: Dictionary with the test environment. + """ + error.context("Check for an appropriate clocksource on host", logging.info) + host_cmd = "cat /sys/devices/system/clocksource/" + host_cmd += "clocksource0/current_clocksource" + if not "tsc" in utils.system_output(host_cmd): + raise error.TestNAError("Host must use 'tsc' clocksource") + + error.context("Check host has more than one cpu socket", logging.info) + host_socket_cnt_cmd = params["host_socket_cnt_cmd"] + if utils.system_output(host_socket_cnt_cmd).strip() == "1": + raise error.TestNAError("Host must have more than 1 socket") + + error.context("Boot the guest with one cpu socket", logging.info) + vm = env.get_vm(params["main_vm"]) + vm.verify_alive() + + timeout = int(params.get("login_timeout", 360)) + session = vm.wait_for_login(timeout=timeout) + + error.context("Copy time-warp-test.c to guest", logging.info) + src_file_name = os.path.join(data_dir.get_root_dir(), "shared", "deps", + "time-warp-test.c") + vm.copy_files_to(src_file_name, "/tmp") + + error.context("Compile the time-warp-test.c", logging.info) + cmd = "cd /tmp/;" + cmd += " yum install -y popt-devel;" + cmd += " rm -f time-warp-test;" + cmd += " gcc -Wall -o time-warp-test time-warp-test.c -lrt" + session.cmd(cmd) + + error.context("Run time-warp-test for minimum 4 hours", logging.info) + test_run_timeout = int(params.get("test_run_timeout", 14400)) + session.sendline("$(sleep %d; pkill time-warp-test) &" % test_run_timeout) + cmd = "/tmp/time-warp-test" + _, output = session.cmd_status_output(cmd, timeout=(test_run_timeout + 60)) + + re_str = "fail:(\d+).*?fail:(\d+).*fail:(\d+)" + fail_cnt = re.findall(re_str, output) + if not fail_cnt: + raise error.TestError("Could not get correct test output." + " Output: '%s'" % output) + + tsc_cnt, tod_cnt, clk_cnt = [int(_) for _ in fail_cnt[-1]] + if tsc_cnt or tod_cnt or clk_cnt: + msg = output.splitlines()[-5:] + raise error.TestFail("Get error when running time-warp-test." + " Output (last 5 lines): '%s'" % msg) From 6767f574cf0c0efcccdff02bbe5c67d5c89f5f8d Mon Sep 17 00:00:00 2001 From: Qingtang Zhou Date: Mon, 1 Jul 2013 17:52:55 +0800 Subject: [PATCH 047/254] qemu.tests: Add test timerdevice.tscsync.change_host_clksource Signed-off-by: Qingtang Zhou --- qemu/tests/cfg/timerdevice.cfg | 3 + ...merdevice_tscsync_change_host_clksource.py | 110 ++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 qemu/tests/timerdevice_tscsync_change_host_clksource.py diff --git a/qemu/tests/cfg/timerdevice.cfg b/qemu/tests/cfg/timerdevice.cfg index 2e7605a4a..4bd355a31 100644 --- a/qemu/tests/cfg/timerdevice.cfg +++ b/qemu/tests/cfg/timerdevice.cfg @@ -9,6 +9,9 @@ msr_tools_cmd = "a=$(rdmsr -d 0x00000010); echo -e ibase=16\\n $a | tail -n 1 | while read n; do wrmsr 0x00000010 $(($n+100000000000)); echo $n; done" - tscsync: variants: + - change_host_clksource: + type = timerdevice_tscsync_change_host_clksource + test_run_timeout = 10 - longtime: type = timerdevice_tscsync_longtime host_socket_cnt_cmd = "cat /proc/cpuinfo | grep "physical id" | uniq | wc -l" diff --git a/qemu/tests/timerdevice_tscsync_change_host_clksource.py b/qemu/tests/timerdevice_tscsync_change_host_clksource.py new file mode 100644 index 000000000..230e97cc7 --- /dev/null +++ b/qemu/tests/timerdevice_tscsync_change_host_clksource.py @@ -0,0 +1,110 @@ +import logging, os, re +from autotest.client.shared import error +from autotest.client import utils +from virttest import data_dir + +@error.context_aware +def run_timerdevice_tscsync_change_host_clksource(test, params, env): + """ + Timer device check TSC synchronity after change host clocksource: + + 1) Check for an appropriate clocksource on host. + 2) Boot the guest. + 3) Check the guest is using vsyscall. + 4) Copy time-warp-test.c to guest. + 5) Compile the time-warp-test.c. + 6) Switch host to hpet clocksource. + 6) Run time-warp-test. + 7) Check the guest is using vsyscall. + + @param test: QEMU test object. + @param params: Dictionary with test parameters. + @param env: Dictionary with the test environment. + """ + error.context("Check for an appropriate clocksource on host", logging.info) + host_cmd = "cat /sys/devices/system/clocksource/" + host_cmd += "clocksource0/current_clocksource" + if not "tsc" in utils.system_output(host_cmd): + raise error.TestNAError("Host must use 'tsc' clocksource") + + error.context("Boot the guest with one cpu socket", logging.info) + vm = env.get_vm(params["main_vm"]) + vm.verify_alive() + + timeout = int(params.get("login_timeout", 360)) + session = vm.wait_for_login(timeout=timeout) + + error.context("Check the guest is using vsyscall", logging.info) + date_cmd = "strace date 2>&1|egrep 'clock_gettime|gettimeofday'|wc -l" + output = session.cmd(date_cmd) + if not '0' in output: + raise error.TestFail("Failed to check vsyscall. Output: '%s'" % output) + + error.context("Copy time-warp-test.c to guest", logging.info) + src_file_name = os.path.join(data_dir.get_root_dir(), "shared", "deps", + "time-warp-test.c") + vm.copy_files_to(src_file_name, "/tmp") + + error.context("Compile the time-warp-test.c", logging.info) + cmd = "cd /tmp/;" + cmd += " yum install -y popt-devel;" + cmd += " rm -f time-warp-test;" + cmd += " gcc -Wall -o time-warp-test time-warp-test.c -lrt" + session.cmd(cmd) + + error.context("Run time-warp-test", logging.info) + test_run_timeout = int(params.get("test_run_timeout", 10)) + session.sendline("$(sleep %d; pkill time-warp-test) &" % test_run_timeout) + cmd = "/tmp/time-warp-test" + _, output = session.cmd_status_output(cmd, timeout=(test_run_timeout + 60)) + + re_str = "fail:(\d+).*?fail:(\d+).*fail:(\d+)" + fail_cnt = re.findall(re_str, output) + if not fail_cnt: + raise error.TestError("Could not get correct test output." + " Output: '%s'" % output) + + tsc_cnt, tod_cnt, clk_cnt = [int(_) for _ in fail_cnt[-1]] + if tsc_cnt or tod_cnt or clk_cnt: + msg = output.splitlines()[-5:] + raise error.TestFail("Get error when running time-warp-test." + " Output (last 5 lines): '%s'" % msg) + + try: + error.context("Switch host to hpet clocksource", logging.info) + cmd = "echo hpet > /sys/devices/system/clocksource/" + cmd += "clocksource0/current_clocksource" + utils.system(cmd) + + error.context("Run time-warp-test after change the host clock source", + logging.info) + cmd = "$(sleep %d; pkill time-warp-test) &" + session.sendline(cmd % test_run_timeout) + cmd = "/tmp/time-warp-test" + _, output = session.cmd_status_output(cmd, + timeout=(test_run_timeout + 60)) + + fail_cnt = re.findall(re_str, output) + if not fail_cnt: + raise error.TestError("Could not get correct test output." + " Output: '%s'" % output) + + tsc_cnt, tod_cnt, clk_cnt = [int(_) for _ in fail_cnt[-1]] + if tsc_cnt or tod_cnt or clk_cnt: + msg = output.splitlines()[-5:] + raise error.TestFail("Get error when running time-warp-test." + " Output (last 5 lines): '%s'" % msg) + + output = session.cmd(date_cmd) + if not "1" in output: + raise error.TestFail("Failed to check vsyscall." + " Output: '%s'" % output) + finally: + error.context("Restore host to tsc clocksource", logging.info) + cmd = "echo tsc > /sys/devices/system/clocksource/" + cmd += "clocksource0/current_clocksource" + try: + utils.system(cmd) + except Exception, detail: + logging.error("Failed to restore host clocksource." + "Detail: %s" % detail) From 8e1576305a4aa7213778047d849c5ccadc126802 Mon Sep 17 00:00:00 2001 From: Qingtang Zhou Date: Mon, 1 Jul 2013 20:04:05 +0800 Subject: [PATCH 048/254] qemu.tests: Add test timerdevice.clock_drift_with_ntp Signed-off-by: Qingtang Zhou --- qemu/tests/cfg/timerdevice.cfg | 4 + .../tests/timerdevice_clock_drift_with_ntp.py | 100 ++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 qemu/tests/timerdevice_clock_drift_with_ntp.py diff --git a/qemu/tests/cfg/timerdevice.cfg b/qemu/tests/cfg/timerdevice.cfg index 4bd355a31..8ba889f48 100644 --- a/qemu/tests/cfg/timerdevice.cfg +++ b/qemu/tests/cfg/timerdevice.cfg @@ -7,6 +7,10 @@ type = timerdevice_tscwrite msr_tools_install_cmd = "yum install -y msr-tools" msr_tools_cmd = "a=$(rdmsr -d 0x00000010); echo -e ibase=16\\n $a | tail -n 1 | while read n; do wrmsr 0x00000010 $(($n+100000000000)); echo $n; done" + - clock_drift_with_ntp: + type = timerdevice_clock_drift_with_ntp + host_cpu_cnt_cmd = "cat /proc/cpuinfo | grep "physical id" | wc -l" + test_run_timeout = 7200 - tscsync: variants: - change_host_clksource: diff --git a/qemu/tests/timerdevice_clock_drift_with_ntp.py b/qemu/tests/timerdevice_clock_drift_with_ntp.py new file mode 100644 index 000000000..c626c1995 --- /dev/null +++ b/qemu/tests/timerdevice_clock_drift_with_ntp.py @@ -0,0 +1,100 @@ +import logging, os +from autotest.client.shared import error +from autotest.client import utils +from virttest import data_dir, utils_misc, aexpect + +@error.context_aware +def run_timerdevice_clock_drift_with_ntp(test, params, env): + """ + Timer device check clock frequency offset using NTP on CPU starved guest: + + 1) Check for an appropriate clocksource on host. + 2) Boot the guest. + 3) Copy time-warp-test.c to guest. + 4) Compile the time-warp-test.c. + 5) Stop ntpd and apply load on guest. + 6) Pin every vcpu to a physical cpu. + 7) Verify each vcpu is pinned on host. + 8) Run time-warp-test on guest. + 9) Start ntpd on guest. + 10) Check the drift in /var/lib/ntp/drift file on guest after hours + of running. + + @param test: QEMU test object. + @param params: Dictionary with test parameters. + @param env: Dictionary with the test environment. + """ + def _drift_file_exist(): + try: + session.cmd("test -f /var/lib/ntp/drift") + return True + except Exception: + return False + + error.context("Check for an appropriate clocksource on host", logging.info) + host_cmd = "cat /sys/devices/system/clocksource/" + host_cmd += "clocksource0/current_clocksource" + if not "tsc" in utils.system_output(host_cmd): + raise error.TestNAError("Host must use 'tsc' clocksource") + + error.context("Boot the guest", logging.info) + vm = env.get_vm(params["main_vm"]) + vm.verify_alive() + + timeout = int(params.get("login_timeout", 360)) + sess_guest_load = vm.wait_for_login(timeout=timeout) + + error.context("Copy time-warp-test.c to guest", logging.info) + src_file_name = os.path.join(data_dir.get_root_dir(), "shared", "deps", + "time-warp-test.c") + vm.copy_files_to(src_file_name, "/tmp") + + error.context("Compile the time-warp-test.c", logging.info) + cmd = "cd /tmp/;" + cmd += " yum install -y popt-devel;" + cmd += " rm -f time-warp-test;" + cmd += " gcc -Wall -o time-warp-test time-warp-test.c -lrt" + sess_guest_load.cmd(cmd) + + error.context("Stop ntpd and apply load on guest", logging.info) + sess_guest_load.cmd("yum install -y ntp; service ntpd stop") + load_cmd = "for ((I=0; I<`grep 'processor id' /proc/cpuinfo| wc -l`; I++));" + load_cmd += " do taskset -c $I /bin/bash -c 'for ((;;)); do X=1; done &';" + load_cmd += " done" + sess_guest_load.sendline(load_cmd) + + error.context("Pin every vcpu to a physical cpu", logging.info) + host_cpu_cnt_cmd = params["host_cpu_cnt_cmd"] + host_cpu_num = utils.system_output(host_cpu_cnt_cmd).strip() + host_cpu_list = (_ for _ in range(int(host_cpu_num))) + cpu_pin_list = zip(vm.vcpu_threads, host_cpu_list) + if len(cpu_pin_list) < len(vm.vcpu_threads): + raise error.TestNAError("There isn't enough physical cpu to" + " pin all the vcpus") + for vcpu, pcpu in cpu_pin_list: + utils.system("taskset -p -c %s %s" % (pcpu, vcpu)) + + error.context("Verify each vcpu is pinned on host", logging.info) + + error.context("Run time-warp-test", logging.info) + session = vm.wait_for_login(timeout=timeout) + cmd = "/tmp/time-warp-test > /dev/null &" + session.sendline(cmd) + + error.context("Start ntpd on guest", logging.info) + cmd = "service ntpd start; sleep 1; echo" + session.cmd(cmd) + + error.context("Check if the drift file exists on guest", logging.info) + test_run_timeout = float(params["test_run_timeout"]) + try: + utils_misc.wait_for(_drift_file_exist, test_run_timeout, step=5) + except aexpect.ShellCmdError, detail: + raise error.TestError("Failed to wait for the creation of" + " /var/lib/ntp/drift file. Detail: '%s'" % detail) + + error.context("Verify the drift file content on guest", logging.info) + output = session.cmd("cat /var/lib/ntp/drift") + if int(output) > 20: + raise error.TestFail("Failed to check the ntp drift." + " Output: '%s'" % output) From e1d1c61d2d6ca3e7bea995cbb8aad799f3497826 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Doktor?= Date: Thu, 27 Jun 2013 13:24:17 +0200 Subject: [PATCH 049/254] virttest.qemu_devices: Remove readconfig-like format of qemu representation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After a disucssion I'm removing the support for readconfig-like format of qemu format. Signed-off-by: Lukáš Doktor --- virttest/qemu_devices.py | 53 +++------------------------------------- 1 file changed, 3 insertions(+), 50 deletions(-) diff --git a/virttest/qemu_devices.py b/virttest/qemu_devices.py index 77ace8b79..5add26768 100644 --- a/virttest/qemu_devices.py +++ b/virttest/qemu_devices.py @@ -138,7 +138,7 @@ def __str__(self): def __eq__(self, dev2): """ @return: True when devs are similar, False when different. """ try: - for check_attr in ('cmdline', 'readconfig', 'hotplug_hmp', + for check_attr in ('cmdline', 'hotplug_hmp', 'hotplug_qmp'): try: _ = getattr(self, check_attr)() @@ -234,10 +234,6 @@ def verify_hotplug(self, out, monitor): """ return out - def readconfig(self): - """ @return: readconfig-like config of this device """ - raise NotImplementedError - class QStringDevice(QBaseDevice): """ @@ -246,7 +242,7 @@ class QStringDevice(QBaseDevice): "%(type)s,id=%(id)s,addr=%(addr)s" -- params will be used to subst %()s """ def __init__(self, dev_type, params=None, aobject=None, - parent_bus=None, child_bus=None, cmdline="", readconfig=""): + parent_bus=None, child_bus=None, cmdline=""): """ @param dev_type: type of this component @param params: component's parameters @@ -254,12 +250,10 @@ def __init__(self, dev_type, params=None, aobject=None, @param parent_bus: bus(es), in which this device is plugged in @param child_bus: bus, which this device provides @param cmdline: cmdline string - @param readconfig: readconfig string """ super(QStringDevice, self).__init__(dev_type, params, aobject, parent_bus, child_bus) self._cmdline = cmdline - self._readconfig = readconfig def cmdline(self): """ @return: cmdline command to define this device """ @@ -269,19 +263,11 @@ def cmdline(self): raise KeyError("Param %s required for cmdline is not present in %s" % (details, self.str_long())) - def readconfig(self): - """ @return: readconfig-like config of this device """ - try: - return self._readconfig % self.params - except KeyError, details: - raise KeyError("Param %s required for readconfig is not present in" - " %s" % (details, self.str_long())) - class QCustomDevice(QBaseDevice): """ Representation of the '-$option $param1=$value1,$param2...' qemu object. - This representation handles only cmdline and readconfig outputs. + This representation handles only cmdline. """ def __init__(self, dev_type, params=None, aobject=None, parent_bus=None, child_bus=None): @@ -300,21 +286,6 @@ def cmdline(self): out = out[:-1] return out - def readconfig(self): - """ @return: readconfig-like config of this device """ - out = "[%s" % self.type - if self.get_qid(): - out += ' "%s"' % self.get_qid() - out += "]\n" - for key, value in self.params.iteritems(): - if key == "id": - continue - if value.startswith("'") and value.endswith("'"): - out += ' %s = "%s"\n' % (key, value[1:-1]) - else: - out += ' %s = "%s"\n' % (key, value) - return out - class QDevice(QCustomDevice): """ @@ -1303,24 +1274,6 @@ def cmdline(self): out += " %s" % device.cmdline() return out - def readconfig(self): - """ - Creates -readconfig-like config for all defined devices. - @return: list, where first item is -readconfig-like config for all - inserted devices. and second item are cmdline options of - devices, which don't have -readconfig fmt specified - """ - out = ["", ""] - for device in self.__devices: - if device.readconfig(): - out[0] += "%s\n\n" % device.readconfig() - elif device.cmdline(): - out[1] += "%s " % device.cmdline() - if out[0]: - out[0] = out[0][:-2] - if out[1]: - out[1] = out[1][:-1] - return out # Machine related methods def machine_by_variables(self, params=None): From f87c6609ce38b110674f896da629b022ab92fc77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Doktor?= Date: Thu, 27 Jun 2013 13:24:09 +0200 Subject: [PATCH 050/254] virttest.qemu_devices: Support for NO_EQUAL_STRING and EMPTY_STRING MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It seems that some test uses those special keywords for negative testing. Signed-off-by: Lukáš Doktor --- virttest/qemu_devices.py | 9 ++++++--- virttest/qemu_vm.py | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/virttest/qemu_devices.py b/virttest/qemu_devices.py index 5add26768..6885eec9c 100644 --- a/virttest/qemu_devices.py +++ b/virttest/qemu_devices.py @@ -100,8 +100,8 @@ def set_param(self, option, value, option_type=None): elif value in ['no', 'off', False]: self.params[option] = "off" elif value or value == 0: - if option_type is 'NEED_QUOTE': - self.params[option] = "'%s'" % value + if value == "EMPTY_STRING": + self.params[option] = '""' else: self.params[option] = value elif value is None and option in self.params: @@ -281,7 +281,10 @@ def cmdline(self): """ @return: cmdline command to define this device """ out = "-%s " % self.type for key, value in self.params.iteritems(): - out += "%s=%s," % (key, value) + if value != "NO_EQUAL_STRING": + out += "%s=%s," % (key, value) + else: + out += "%s," % key if out[-1] == ',': out = out[:-1] return out diff --git a/virttest/qemu_vm.py b/virttest/qemu_vm.py index a2924c99e..7d31f2609 100644 --- a/virttest/qemu_vm.py +++ b/virttest/qemu_vm.py @@ -581,8 +581,8 @@ def add_log_anaconda(devices): dev.set_param('backend', 'socket') dev.set_param('id', chardev_id) dev.set_param("path", filename) - dev.set_param("server", True, bool) - dev.set_param("wait", False, bool) + dev.set_param("server", 'NO_EQUAL_STRING') + dev.set_param("nowait", 'NO_EQUAL_STRING') devices.insert(dev) dev = QDevice('virtio-serial-pci', parent_bus={'type': 'pci'}) dev.set_param("id", vioser_id) From d188d8ca19435a1bc1fbe9559a887400292b0ceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Doktor?= Date: Thu, 27 Jun 2013 16:34:23 +0200 Subject: [PATCH 051/254] virttest.qemu_devices: Fix __getitem__() of QSparseBus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit iterate over values instead of keys. Signed-off-by: Lukáš Doktor --- virttest/qemu_devices.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/virttest/qemu_devices.py b/virttest/qemu_devices.py index 6885eec9c..05556a8c2 100644 --- a/virttest/qemu_devices.py +++ b/virttest/qemu_devices.py @@ -371,10 +371,10 @@ def __getitem__(self, item): elif item in self.badbus.itervalues(): return item elif item: - for device in self.bus: + for device in self.bus.itervalues(): if device.get_aid() == item: return device - for device in self.badbus: + for device in self.badbus.itervalues(): if device.get_aid() == item: return device raise KeyError("Device %s is not in %s" % (item, self)) From 05f0dda1653fa0523042ea81aa14878fdb3f9ffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Doktor?= Date: Thu, 27 Jun 2013 16:36:59 +0200 Subject: [PATCH 052/254] virttest.qemu_devices: Fix the _dev2addr() function of QSparseBus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QSparseBus uses integers for addressing. We have to get integer from the device's address. Signed-off-by: Lukáš Doktor --- virttest/qemu_devices.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/virttest/qemu_devices.py b/virttest/qemu_devices.py index 05556a8c2..6d660d695 100644 --- a/virttest/qemu_devices.py +++ b/virttest/qemu_devices.py @@ -526,7 +526,11 @@ def _dev2addr(self, device): """ addr = [] for key in self.addr_items: - addr.append(device.get_param(key)) + value = device.get_param(key) + if value is None: + addr.append(None) + else: + addr.append(int(value)) return addr def _set_first_addr(self, addr_pattern): @@ -622,7 +626,14 @@ def insert(self, device, strict_mode=False, force=False): device.set_param(self.bus_item, self.busid) else: return False - addr_pattern = self._dev2addr(device) + try: + addr_pattern = self._dev2addr(device) + except (ValueError, LookupError): + if force: + err += "BasicAddress, " + addr_pattern = [None] * len(self.addr_items) + else: + return False addr = self.get_free_slot(addr_pattern) if addr is None: if force: From 09f2a9037e09bb76e80ecba531102ed245579cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Doktor?= Date: Thu, 27 Jun 2013 16:40:53 +0200 Subject: [PATCH 053/254] virttest.qemu_devices_unittest: Add qemu_devices unittest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a first part of unittest which is focused on qemu devices. Signed-off-by: Lukáš Doktor --- virttest/qemu_devices_unittest.py | 76 +++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 virttest/qemu_devices_unittest.py diff --git a/virttest/qemu_devices_unittest.py b/virttest/qemu_devices_unittest.py new file mode 100644 index 000000000..f2ee56418 --- /dev/null +++ b/virttest/qemu_devices_unittest.py @@ -0,0 +1,76 @@ +#!/usr/bin/python +""" +This is a unittest for qemu_qtree library. + +@author: Lukas Doktor +@copyright: 2012 Red Hat, Inc. +""" +__author__ = """Lukas Doktor (ldoktor@redhat.com)""" + +import unittest +import qemu_devices + + +class Devices(unittest.TestCase): + """ set of qemu devices tests """ + def test_q_base_device(self): + """ QBaseDevice tests """ + qdevice = qemu_devices.QBaseDevice('MyType', + {'ParamA': 'ValueA', 'AUTOREMOVE': None}, + 'Object1', + {'type': 'pci'}) + self.assertEqual(qdevice['ParamA'], 'ValueA', 'Param added during ' + '__init__ is corrupted %s != %s' % (qdevice['ParamA'], + 'ValueA')) + qdevice['ParamA'] = 'ValueB' + qdevice.set_param('BoolTrue', True) + qdevice.set_param('BoolFalse', 'off', bool) + qdevice['Empty'] = 'EMPTY_STRING' + + out = """MyType + aid = None + aobject = Object1 + parent_bus = {'type': 'pci'} + child_bus = () + params: + ParamA = ValueB + BoolTrue = on + BoolFalse = off + Empty = "" +""" + self.assertEqual(qdevice.str_long(), out, "Device output doesn't match" + "\n%s\n\n%s" % (qdevice.str_long(), out)) + + def test_q_string_device(self): + """ QStringDevice tests """ + qdevice = qemu_devices.QStringDevice('MyType', {'addr': '0x7'}, + cmdline='-qdevice ahci,addr=%(addr)s') + self.assertEqual(qdevice.cmdline(), '-qdevice ahci,addr=0x7', "Cmdline" + " doesn't match expected one:\n%s\n%s" + % (qdevice.cmdline(), '-qdevice ahci,addr=0x7')) + + def test_q_device(self): + """ QDevice tests """ + qdevice = qemu_devices.QDevice('ahci', {'addr': '0x7'}) + + self.assertEqual(str(qdevice), "a'ahci'", "Alternative name error %s " + "!= %s" % (str(qdevice), "a'ahci'")) + + qdevice['id'] = 'ahci1' + self.assertEqual(str(qdevice), "q'ahci1'", "Id name error %s " + "!= %s" % (str(qdevice), "q'ahci1'")) + + exp = "device_add addr=0x7,driver=ahci,id=ahci1" + out = qdevice.hotplug_hmp() + self.assertEqual(out, exp, "HMP command corrupted:\n%s\n%s" + % (out, exp)) + + exp = ("('device_add', OrderedDict([('addr', '0x7'), " + "('driver', 'ahci'), ('id', 'ahci1')]))") + out = str(qdevice.hotplug_qmp()) + self.assertEqual(out, exp, "QMP command corrupted:\n%s\n%s" + % (out, exp)) + + +if __name__ == "__main__": + unittest.main() From 733fdfc9468c16b54e73c207b1f2df198c3e305f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Doktor?= Date: Thu, 27 Jun 2013 16:43:29 +0200 Subject: [PATCH 054/254] virttest.qemu_devices_unittest: Add tests related to buses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lukáš Doktor --- virttest/qemu_devices_unittest.py | 514 ++++++++++++++++++++++++++++++ 1 file changed, 514 insertions(+) diff --git a/virttest/qemu_devices_unittest.py b/virttest/qemu_devices_unittest.py index f2ee56418..900cec3e3 100644 --- a/virttest/qemu_devices_unittest.py +++ b/virttest/qemu_devices_unittest.py @@ -72,5 +72,519 @@ def test_q_device(self): % (out, exp)) + + +class Buses(unittest.TestCase): + def test_q_sparse_bus(self): + """ Sparse bus tests (general bus testing) """ + bus = qemu_devices.QSparseBus('bus', + (['addr1', 'addr2', 'addr3'], [2, 6, 4]), + 'my_bus', + 'bus_type', + 'autotest_bus') + + qdevice = qemu_devices.QDevice + + # Correct records + params = {'addr1': '0', 'addr2': '0', 'addr3': '0', 'bus': 'my_bus'} + dev = qdevice('dev1', params, parent_bus={'type': 'bus_type'}) + exp = True + out = bus.insert(dev, False, False) + self.assertEqual(out, exp, "Failed to add device; %s != %s\n%s\n\n%s" + % (out, exp, dev.str_long(), bus.str_long())) + + params = {'addr1': '1', 'addr2': '0', 'addr3': '0', 'bus': 'my_bus'} + dev = qdevice('dev2', params, parent_bus={'type': 'bus_type'}) + exp = True + out = bus.insert(dev, False, False) + self.assertEqual(out, exp, "Failed to add device; %s != %s\n%s\n\n%s" + % (out, exp, dev.str_long(), bus.str_long())) + + params = {'addr1': '1', 'addr2': '1', 'addr3': '0', 'bus': 'my_bus'} + dev = qdevice('dev3', params, parent_bus={'type': 'bus_type'}) + exp = True + out = bus.insert(dev, False, False) + self.assertEqual(out, exp, "Failed to add device; %s != %s\n%s\n\n%s" + % (out, exp, dev.str_long(), bus.str_long())) + + params = {'addr1': '1', 'addr2': '1', 'addr3': '1', 'bus': 'my_bus'} + dev = qdevice('dev4', params, parent_bus={'type': 'bus_type'}) + exp = True + out = bus.insert(dev, False, False) + self.assertEqual(out, exp, "Failed to add device; %s != %s\n%s\n\n%s" + % (out, exp, dev.str_long(), bus.str_long())) + + params = {'addr1': '1', 'bus': 'my_bus'} + dev = qdevice('dev5', params, parent_bus={'type': 'bus_type'}) + exp = True + out = bus.insert(dev, False, False) + self.assertEqual(out, exp, "Failed to add device; %s != %s\n%s\n\n%s" + % (out, exp, dev.str_long(), bus.str_long())) + + params = {'bus': 'my_bus'} + dev = qdevice('dev6', params, parent_bus={'type': 'bus_type'}) + exp = True + out = bus.insert(dev, False, False) + self.assertEqual(out, exp, "Failed to add device; %s != %s\n%s\n\n%s" + % (out, exp, dev.str_long(), bus.str_long())) + + params = {} + dev = qdevice('dev7', params, parent_bus={'type': 'bus_type'}) + exp = True + out = bus.insert(dev, False, False) + self.assertEqual(out, exp, "Failed to add device; %s != %s\n%s\n\n%s" + % (out, exp, dev.str_long(), bus.str_long())) + + # Compare short repr + exp = ("my_bus(bus_type): {0-0-0:a'dev1',0-0-1:a'dev6',0-0-2:a'dev7'," + "1-0-0:a'dev2',1-0-1:a'dev5',1-1-0:a'dev3',1-1-1:a'dev4'} {}") + out = str(bus.str_short()) + self.assertEqual(out, exp, "Short representation corrupted:\n%s\n%s" + "\n\n%s" % (out, exp, bus.str_long())) + + # Incorrect records + # Used address + params = {'addr1': '0', 'addr2': '0', 'addr3': '0', 'bus': 'my_bus'} + dev = qdevice('devI1', params, parent_bus={'type': 'bus_type'}) + exp = None + out = bus.insert(dev, False, False) + self.assertEqual(out, exp, "Added bad device; %s != %s\n%s\n\n%s" + % (out, exp, dev.str_long(), bus.str_long())) + + # Out of range address + params = {'addr1': '0', 'addr2': '6', 'addr3': '0', 'bus': 'my_bus'} + dev = qdevice('devI2', params, parent_bus={'type': 'bus_type'}) + exp = False + out = bus.insert(dev, False, False) + self.assertEqual(out, exp, "Added bad device; %s != %s\n%s\n\n%s" + % (out, exp, dev.str_long(), bus.str_long())) + + # Incorrect bus name + params = {'bus': 'other_bus'} + dev = qdevice('devI3', params, parent_bus={'type': 'bus_type'}) + exp = False + out = bus.insert(dev, False, False) + self.assertEqual(out, exp, "Added bad device; %s != %s\n%s\n\n%s" + % (out, exp, dev.str_long(), bus.str_long())) + + # Compare short repr + exp = ("my_bus(bus_type): {0-0-0:a'dev1',0-0-1:a'dev6',0-0-2:a'dev7'," + "1-0-0:a'dev2',1-0-1:a'dev5',1-1-0:a'dev3',1-1-1:a'dev4'} {}") + out = str(bus.str_short()) + self.assertEqual(out, exp, "Short representation corrupted:\n%s\n%s" + "\n\n%s" % (out, exp, bus.str_long())) + + # Forced records + # Used address + params = {'addr1': '0', 'addr2': '0', 'addr3': '0', 'bus': 'my_bus'} + dev = qdevice('devB1', params, parent_bus={'type': 'bus_type'}) + exp = "(errors: UsedSlot)" + out = bus.insert(dev, False, True) + self.assertEqual(exp in out, True, "%s not in %s\n%s\n\n%s" + % (exp, out, dev.str_long(), bus.str_long())) + + # Out of range address + params = {'addr1': '0', 'addr2': '6', 'addr3': '0', 'bus': 'my_bus'} + dev = qdevice('devB2', params, parent_bus={'type': 'bus_type'}) + exp = "(errors: BadAddr([0, 6, 0]))" + out = bus.insert(dev, False, True) + self.assertEqual(exp in out, True, "%s not in %s\n%s\n\n%s" + % (exp, out, dev.str_long(), bus.str_long())) + + # Incorrect bus name + params = {'bus': 'other_bus'} + dev = qdevice('devB3', params, parent_bus={'type': 'bus_type'}) + exp = "(errors: BusId)" + out = bus.insert(dev, False, True) + self.assertEqual(exp in out, True, "%s not in %s\n%s\n\n%s" + % (exp, out, dev.str_long(), bus.str_long())) + + # Compare short repr + exp = ("my_bus(bus_type): {0-0-0:a'dev1',0-0-1:a'dev6',0-0-2:a'dev7'," + "0-0-3:a'devB3',1-0-0:a'dev2',1-0-1:a'dev5',1-1-0:a'dev3'," + "1-1-1:a'dev4'} {0-0-0(2x):a'devB1',o0-6-0:a'devB2'}") + out = str(bus.str_short()) + self.assertEqual(out, exp, "Short representation corrupted:\n%s\n%s" + "\n\n%s" % (out, exp, bus.str_long())) + + # Compare long repr + exp = """Bus my_bus, type=bus_type +Slots: +---------------< 1-0-0 >--------------- + device + aid = None + aobject = None + parent_bus = {'type': 'bus_type'} + child_bus = () + params: + bus = my_bus + addr2 = 0 + addr3 = 0 + addr1 = 1 + driver = dev2 +---------------< 1-0-1 >--------------- + device + aid = None + aobject = None + parent_bus = {'type': 'bus_type'} + child_bus = () + params: + bus = my_bus + addr1 = 1 + driver = dev5 +---------------< 1-1-1 >--------------- + device + aid = None + aobject = None + parent_bus = {'type': 'bus_type'} + child_bus = () + params: + bus = my_bus + addr2 = 1 + addr3 = 1 + addr1 = 1 + driver = dev4 +---------------< 1-1-0 >--------------- + device + aid = None + aobject = None + parent_bus = {'type': 'bus_type'} + child_bus = () + params: + bus = my_bus + addr2 = 1 + addr3 = 0 + addr1 = 1 + driver = dev3 +---------------< 0-0-1 >--------------- + device + aid = None + aobject = None + parent_bus = {'type': 'bus_type'} + child_bus = () + params: + bus = my_bus + driver = dev6 +---------------< 0-0-0 >--------------- + device + aid = None + aobject = None + parent_bus = {'type': 'bus_type'} + child_bus = () + params: + bus = my_bus + addr2 = 0 + addr3 = 0 + addr1 = 0 + driver = dev1 +---------------< 0-0-3 >--------------- + device + aid = None + aobject = None + parent_bus = {'type': 'bus_type'} + child_bus = () + params: + bus = my_bus + driver = devB3 +---------------< 0-0-2 >--------------- + device + aid = None + aobject = None + parent_bus = {'type': 'bus_type'} + child_bus = () + params: + driver = dev7 + +---------------< o0-6-0 >--------------- + device + aid = None + aobject = None + parent_bus = {'type': 'bus_type'} + child_bus = () + params: + bus = my_bus + addr2 = 6 + addr3 = 0 + addr1 = 0 + driver = devB2 +---------------< 0-0-0(2x) >--------------- + device + aid = None + aobject = None + parent_bus = {'type': 'bus_type'} + child_bus = () + params: + bus = my_bus + addr2 = 0 + addr3 = 0 + addr1 = 0 + driver = devB1 +""" + out = str(bus.str_long()) + self.assertEqual(out, exp, "Long representation corrupted:\n%s\n%s" + % (repr(out), exp)) + + # Low level functions + # Get device by object + exp = dev + out = bus.get(dev) + self.assertEqual(out, exp, "Failed to get device from bus:\n%s\n%s" + "\n\n%s" % (out, exp, bus.str_long())) + + dev.aid = 'bad_device3' + exp = dev + out = bus.get('bad_device3') + self.assertEqual(out, exp, "Failed to get device from bus:\n%s\n%s" + "\n\n%s" % (out, exp, bus.str_long())) + + exp = None + out = bus.get('missing_bad_device') + self.assertEqual(out, exp, "Got device while expecting None:\n%s\n%s" + "\n\n%s" % (out, exp, bus.str_long())) + + # Remove all devices + devs = [dev for dev in bus] + for dev in devs: + bus.remove(dev) + + exp = 'Bus my_bus, type=bus_type\nSlots:\n\n' + out = str(bus.str_long()) + self.assertEqual(out, exp, "Long representation corrupted:\n%s\n%s" + % (out, exp)) + + def test_q_pci_bus(self): + """ PCI bus tests """ + bus = qemu_devices.QPCIBus('pci.0', 'pci', 'my_pci') + qdevice = qemu_devices.QDevice + + # Good devices + params = {'addr': '0'} + dev = qdevice('dev1', params, parent_bus={'type': 'pci'}) + exp = True + out = bus.insert(dev, False, False) + self.assertEqual(out, exp, "Failed to add device; %s != %s\n%s\n\n%s" + % (out, exp, dev.str_long(), bus.str_long())) + + params = {'addr': 10, 'bus': 'pci.0'} + dev = qdevice('dev2', params, parent_bus={'type': 'pci'}) + exp = True + out = bus.insert(dev, False, False) + self.assertEqual(out, exp, "Failed to add device; %s != %s\n%s\n\n%s" + % (out, exp, dev.str_long(), bus.str_long())) + + params = {'addr': '0x1f'} + dev = qdevice('dev3', params, parent_bus={'type': 'pci'}) + exp = True + out = bus.insert(dev, False, False) + self.assertEqual(out, exp, "Failed to add device; %s != %s\n%s\n\n%s" + % (out, exp, dev.str_long(), bus.str_long())) + + # Compare short repr + exp = ("pci.0(pci): [a'dev1',None,None,None,None,None,None,None,None," + "None,a'dev2',None,None,None,None,None,None,None,None,None," + "None,None,None,None,None,None,None,None,None,None,None," + "a'dev3'] {}") + out = str(bus.str_short()) + self.assertEqual(out, exp, "Short representation corrupted:\n%s\n%s" + "\n\n%s" % (out, exp, bus.str_long())) + + # Incorrect records + # Used address + params = {'addr': 0} + dev = qdevice('devI1', params, parent_bus={'type': 'pci'}) + exp = None + out = bus.insert(dev, False, False) + self.assertEqual(out, exp, "Added bad device; %s != %s\n%s\n\n%s" + % (out, exp, dev.str_long(), bus.str_long())) + + # Out of range address + params = {'addr': '0xffff'} + dev = qdevice('devI2', params, parent_bus={'type': 'pci'}) + exp = False + out = bus.insert(dev, False, False) + self.assertEqual(out, exp, "Added bad device; %s != %s\n%s\n\n%s" + % (out, exp, dev.str_long(), bus.str_long())) + + # Compare short repr + exp = ("pci.0(pci): [a'dev1',None,None,None,None,None,None,None,None," + "None,a'dev2',None,None,None,None,None,None,None,None,None," + "None,None,None,None,None,None,None,None,None,None,None," + "a'dev3'] {}") + out = str(bus.str_short()) + self.assertEqual(out, exp, "Short representation corrupted:\n%s\n%s" + "\n\n%s" % (out, exp, bus.str_long())) + + # Forced records + # Used address + params = {'addr': '0x0'} + dev = qdevice('devB1', params, parent_bus={'type': 'pci'}) + exp = "(errors: UsedSlot)" + out = bus.insert(dev, False, True) + self.assertEqual(exp in out, True, "%s not in %s\n%s\n\n%s" + % (exp, out, dev.str_long(), bus.str_long())) + + # Out of range address + params = {'addr': '0xffff'} + dev = qdevice('devB2', params, parent_bus={'type': 'pci'}) + exp = "(errors: BadAddr([65535]))" + out = bus.insert(dev, False, True) + self.assertEqual(exp in out, True, "%s not in %s\n%s\n\n%s" + % (exp, out, dev.str_long(), bus.str_long())) + + # Incorrect bus name + params = {'bus': 'other_bus'} + dev = qdevice('devB3', params, parent_bus={'type': 'pci'}) + exp = "(errors: BusId)" + out = bus.insert(dev, False, True) + self.assertEqual(exp in out, True, "%s not in %s\n%s\n\n%s" + % (exp, out, dev.str_long(), bus.str_long())) + + # Compare short repr + exp = ("pci.0(pci): [a'dev1',a'devB3',None,None,None,None,None,None," + "None,None,a'dev2',None,None,None,None,None,None,None,None," + "None,None,None,None,None,None,None,None,None,None,None,None," + "a'dev3'] {0x0(2x):a'devB1',o0xffff:a'devB2'}") + out = str(bus.str_short()) + self.assertEqual(out, exp, "Short representation corrupted:\n%s\n%s" + "\n\n%s" % (out, exp, bus.str_long())) + + def test_q_pci_bus_strict(self): + """ PCI bus tests in strict_mode (enforce additional options) """ + bus = qemu_devices.QPCIBus('pci.0', 'pci', 'my_pci') + qdevice = qemu_devices.QDevice + + params = {} + bus.insert(qdevice('dev1', params, parent_bus={'type': 'pci'}), True) + bus.insert(qdevice('dev2', params, parent_bus={'type': 'pci'}), True) + bus.insert(qdevice('dev3', params, parent_bus={'type': 'pci'}), True) + params = {'addr': '0x1f'} + bus.insert(qdevice('dev1', params, parent_bus={'type': 'pci'}), True) + params = {'addr': 30} + bus.insert(qdevice('dev1', params, parent_bus={'type': 'pci'}), True) + params = {'addr': 12} + bus.insert(qdevice('dev1', params, parent_bus={'type': 'pci'}), True) + + # All devices will have 'addr' set as we are in the strict mode + exp = """Bus pci.0, type=pci +Slots: +---------------< 0x0 >--------------- + device + aid = None + aobject = None + parent_bus = {'type': 'pci'} + child_bus = () + params: + driver = dev1 + bus = pci.0 + addr = 0x0 +---------------< 0x1 >--------------- + device + aid = None + aobject = None + parent_bus = {'type': 'pci'} + child_bus = () + params: + driver = dev2 + bus = pci.0 + addr = 0x1 +---------------< 0x2 >--------------- + device + aid = None + aobject = None + parent_bus = {'type': 'pci'} + child_bus = () + params: + driver = dev3 + bus = pci.0 + addr = 0x2 +---------------< 0x3 >--------------- + None +---------------< 0x4 >--------------- + None +---------------< 0x5 >--------------- + None +---------------< 0x6 >--------------- + None +---------------< 0x7 >--------------- + None +---------------< 0x8 >--------------- + None +---------------< 0x9 >--------------- + None +---------------< 0xa >--------------- + None +---------------< 0xb >--------------- + None +---------------< 0xc >--------------- + device + aid = None + aobject = None + parent_bus = {'type': 'pci'} + child_bus = () + params: + addr = 0xc + driver = dev1 + bus = pci.0 +---------------< 0xd >--------------- + None +---------------< 0xe >--------------- + None +---------------< 0xf >--------------- + None +---------------< 0x10 >--------------- + None +---------------< 0x11 >--------------- + None +---------------< 0x12 >--------------- + None +---------------< 0x13 >--------------- + None +---------------< 0x14 >--------------- + None +---------------< 0x15 >--------------- + None +---------------< 0x16 >--------------- + None +---------------< 0x17 >--------------- + None +---------------< 0x18 >--------------- + None +---------------< 0x19 >--------------- + None +---------------< 0x1a >--------------- + None +---------------< 0x1b >--------------- + None +---------------< 0x1c >--------------- + None +---------------< 0x1d >--------------- + None +---------------< 0x1e >--------------- + device + aid = None + aobject = None + parent_bus = {'type': 'pci'} + child_bus = () + params: + addr = 0x1e + driver = dev1 + bus = pci.0 +---------------< 0x1f >--------------- + device + aid = None + aobject = None + parent_bus = {'type': 'pci'} + child_bus = () + params: + addr = 0x1f + driver = dev1 + bus = pci.0 + +""" + out = str(bus.str_long()) + self.assertEqual(out, exp, "Long representation corrupted:\n%s\n%s" + % (repr(out), exp)) + + if __name__ == "__main__": unittest.main() From b9cf3a07adeef6684c95779ba9bb145ca21fe3fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Doktor?= Date: Mon, 1 Jul 2013 08:48:44 +0200 Subject: [PATCH 055/254] virttest.qemu_devices: Remove tailing ']' in DevContainer.str_long() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lukáš Doktor --- virttest/qemu_devices.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virttest/qemu_devices.py b/virttest/qemu_devices.py index 6d660d695..b3d7a9c26 100644 --- a/virttest/qemu_devices.py +++ b/virttest/qemu_devices.py @@ -1063,7 +1063,7 @@ def str_long(self): out += device.str_long() if out[-1] == '\n': out = out[:-1] - return out + "]" + return out def str_bus_short(self): """ Short representation of all buses """ From 36e8f97e36fe6da5faeb7944d2d6963f0992e6cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Doktor?= Date: Mon, 1 Jul 2013 08:57:58 +0200 Subject: [PATCH 056/254] virttest.qemu_devices: Use is None for checking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lukáš Doktor --- virttest/qemu_devices.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/virttest/qemu_devices.py b/virttest/qemu_devices.py index b3d7a9c26..da22b4ac9 100644 --- a/virttest/qemu_devices.py +++ b/virttest/qemu_devices.py @@ -602,10 +602,10 @@ def _update_device_props(self, device, addr): @param device: QBaseDevice device @param addr: internal address [addr1, addr2, ...] """ - if device.get_param(self.bus_item): + if device.get_param(self.bus_item) is not None: device.set_param(self.bus_item, self.busid) for i in xrange(len(self.addr_items)): - if device.get_param(self.addr_items[i]): + if device.get_param(self.addr_items[i]) is not None: device.set_param(self.addr_items[i], addr[i]) def insert(self, device, strict_mode=False, force=False): From 9ec066111a40aecaa0009879f40c0be8f293071e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Doktor?= Date: Mon, 1 Jul 2013 10:44:53 +0200 Subject: [PATCH 057/254] virttest.qemu_devices: Fix DevContainer.cmdline() to start with char MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lukáš Doktor --- virttest/qemu_devices.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/virttest/qemu_devices.py b/virttest/qemu_devices.py index da22b4ac9..68f9aff0d 100644 --- a/virttest/qemu_devices.py +++ b/virttest/qemu_devices.py @@ -1286,7 +1286,8 @@ def cmdline(self): for device in self.__devices: if device.cmdline(): out += " %s" % device.cmdline() - return out + if out: + return out[1:] # Machine related methods From 8932d5bf4f08e3dc5b899f765501205c4569d0c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Doktor?= Date: Mon, 1 Jul 2013 13:30:12 +0200 Subject: [PATCH 058/254] virttest.qemu_devices: Fix HMP commands regexp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lukáš Doktor --- virttest/qemu_devices.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/virttest/qemu_devices.py b/virttest/qemu_devices.py index 68f9aff0d..94c55d06f 100644 --- a/virttest/qemu_devices.py +++ b/virttest/qemu_devices.py @@ -877,11 +877,12 @@ def get_hmp_cmds(qemu_binary): "stdio -vnc none" % qemu_binary, timeout=10, ignore_status=True, verbose=False) - _ = re.findall(r'^([^\| ]+\|?\w+)', _, re.M) + _ = re.findall(r'^([^\| \[\n]+\|?\w+)', _, re.M) hmp_cmds = [] for cmd in _: if '|' not in cmd: - hmp_cmds.append(cmd) + if cmd != 'The': + hmp_cmds.append(cmd) else: hmp_cmds.extend(cmd.split('|')) return hmp_cmds From 3a5c4f1e84f1fc3cec922d4eccd3f5f583da98e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Doktor?= Date: Tue, 2 Jul 2013 08:33:41 +0200 Subject: [PATCH 059/254] virttest.qemu_devices: Fix machine_by_params name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This function accepts params and not variables now. Signed-off-by: Lukáš Doktor --- virttest/qemu_devices.py | 3 +-- virttest/qemu_vm.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/virttest/qemu_devices.py b/virttest/qemu_devices.py index 94c55d06f..84783deee 100644 --- a/virttest/qemu_devices.py +++ b/virttest/qemu_devices.py @@ -1290,9 +1290,8 @@ def cmdline(self): if out: return out[1:] - # Machine related methods - def machine_by_variables(self, params=None): + def machine_by_params(self, params=None): """ Choose the used machine and set the default devices accordingly @param params: VM params diff --git a/virttest/qemu_vm.py b/virttest/qemu_vm.py index 7d31f2609..2cc12b574 100644 --- a/virttest/qemu_vm.py +++ b/virttest/qemu_vm.py @@ -1356,7 +1356,7 @@ def add_option_rom(devices, opt_rom): # Add the VM's name devices.insert(StrDev('vmname', cmdline=add_name(devices, name))) - devs = devices.machine_by_variables(params) + devs = devices.machine_by_params(params) for dev in devs: devices.insert(dev) From 40ec23f8a485d64398f04d0be2d0f25cc2d92a99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Doktor?= Date: Tue, 2 Jul 2013 08:34:00 +0200 Subject: [PATCH 060/254] virttest.qemu_devices_unittest: Add unittest for DevContainer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lukáš Doktor --- virttest/qemu_devices_unittest.py | 377 +++++++++++++++++- .../unittest_data/qemu-1.5.0__devices_help | 135 +++++++ virttest/unittest_data/qemu-1.5.0__help | 301 ++++++++++++++ virttest/unittest_data/qemu-1.5.0__hmp_help | 90 +++++ .../unittest_data/qemu-1.5.0__machine_help | 19 + virttest/unittest_data/qemu-1.5.0__qmp_help | 1 + 6 files changed, 919 insertions(+), 4 deletions(-) create mode 100644 virttest/unittest_data/qemu-1.5.0__devices_help create mode 100644 virttest/unittest_data/qemu-1.5.0__help create mode 100644 virttest/unittest_data/qemu-1.5.0__hmp_help create mode 100644 virttest/unittest_data/qemu-1.5.0__machine_help create mode 100644 virttest/unittest_data/qemu-1.5.0__qmp_help diff --git a/virttest/qemu_devices_unittest.py b/virttest/qemu_devices_unittest.py index 900cec3e3..69d452b1e 100644 --- a/virttest/qemu_devices_unittest.py +++ b/virttest/qemu_devices_unittest.py @@ -1,14 +1,29 @@ #!/usr/bin/python """ -This is a unittest for qemu_qtree library. +This is a unittest for qemu_devices library. @author: Lukas Doktor @copyright: 2012 Red Hat, Inc. """ __author__ = """Lukas Doktor (ldoktor@redhat.com)""" -import unittest +from autotest.client.shared.test_utils import mock import qemu_devices +import re +import unittest + + +# Dummy variables +# qemu-1.5.0 human monitor help output +QEMU_HMP = open("unittest_data/qemu-1.5.0__hmp_help").read() +# qemu-1.5.0 QMP monitor commands output +QEMU_QMP = open("unittest_data/qemu-1.5.0__qmp_help").read() +# qemu-1.5.0 -help +QEMU_HELP = open("unittest_data/qemu-1.5.0__help").read() +# qemu-1.5.0 -devices ? +QEMU_DEVICES = open("unittest_data/qemu-1.5.0__devices_help").read() +# qemu-1.5.0 -M ? +QEMU_MACHINE = open("unittest_data/qemu-1.5.0__machine_help").read() class Devices(unittest.TestCase): @@ -72,9 +87,8 @@ def test_q_device(self): % (out, exp)) - - class Buses(unittest.TestCase): + """ Set of bus-representation tests """ def test_q_sparse_bus(self): """ Sparse bus tests (general bus testing) """ bus = qemu_devices.QSparseBus('bus', @@ -586,5 +600,360 @@ def test_q_pci_bus_strict(self): % (repr(out), exp)) +class Container(unittest.TestCase): + """ Tests related to the abstract representation of qemu machine """ + def setUp(self): + self.god = mock.mock_god(ut=self) + self.god.stub_function(qemu_devices.utils, "system_output") + + def tearDown(self): + self.god.unstub_all() + + def create_qdev(self, vm_name='vm1'): + """ @return: Initialized qemu_devices.DevContainer object """ + qemu_cmd = '/usr/bin/qemu_kvm' + qemu_devices.utils.system_output.expect_call('%s -help' % qemu_cmd, + timeout=10, ignore_status=True, verbose=False + ).and_return(QEMU_HELP) + qemu_devices.utils.system_output.expect_call("%s -device ? 2>&1" + % qemu_cmd, timeout=10, + ignore_status=True, verbose=False + ).and_return(QEMU_DEVICES) + qemu_devices.utils.system_output.expect_call("%s -M ?" % qemu_cmd, + timeout=10, ignore_status=True, verbose=False + ).and_return(QEMU_MACHINE) + cmd = "echo -e 'help\nquit' | %s -monitor stdio -vnc none" % qemu_cmd + qemu_devices.utils.system_output.expect_call(cmd, timeout=10, + ignore_status=True, verbose=False + ).and_return(QEMU_HMP) + cmd = ('echo -e \'{ "execute": "qmp_capabilities" }\n' + '{ "execute": "query-commands", "id": "RAND91" }\n' + '{ "execute": "quit" }\'' + '| %s -qmp stdio -vnc none | grep return |' + ' grep RAND91' % qemu_cmd) + qemu_devices.utils.system_output.expect_call(cmd, timeout=10, + ignore_status=True, verbose=False + ).and_return('') + + cmd = ('echo -e \'{ "execute": "qmp_capabilities" }\n' + '{ "execute": "query-commands", "id": "RAND91" }\n' + '{ "execute": "quit" }\' | (sleep 1; cat )' + '| %s -qmp stdio -vnc none | grep return |' + ' grep RAND91' % qemu_cmd) + qemu_devices.utils.system_output.expect_call(cmd, timeout=10, + ignore_status=True, verbose=False + ).and_return(QEMU_QMP) + + qdev = qemu_devices.DevContainer(qemu_cmd, vm_name, False) + + self.god.check_playback() + return qdev + + def test_qdev_functional(self): + """ Test basic qdev workflow """ + qdev = self.create_qdev('vm1') + + # Add basic 'pc' devices + for dev in qdev.machine_by_params({'machine_type': 'pc'}): + out = qdev.insert(dev, False) + self.assertEqual(out, None, "Failed to insert device, ret=%s\n%s" + % (out, qdev.str_long())) + + exp = r"""Devices of vm1: +machine + aid = __0 + aobject = None + parent_bus = \(\) + child_bus = \(.*QPCIBus.*\) + params: +i440FX + aid = __1 + aobject = None + parent_bus = \({'type': 'pci'},\) + child_bus = \(\) + params: + addr = 0x0 +PIIX3 + aid = __2 + aobject = None + parent_bus = \({'type': 'pci'},\) + child_bus = \(\) + params: + addr = 0x1""" + out = qdev.str_long() + self.assertNotEqual(re.match(exp, out), None, 'Long representation is' + 'corrupted:\n%s\n%s' % (out, exp)) + + exp = (r"Buses of vm1\n pci.0\(pci\): \[t'i440FX',t'PIIX3'%s\] {}" + % (',None' * 30)) + out = qdev.str_bus_short() + self.assertNotEqual(re.match(exp, out), None, 'Bus representation is' + 'corrupted:\n%s\n%s' % (out, exp)) + + # Insert some good devices + qdevice = qemu_devices.QDevice + + # Device with child bus + bus = qemu_devices.QSparseBus('bus', [['addr'], [6]], 'hba1.0', 'hba', + 'a_hba') + dev = qdevice('HBA', {'id': 'hba1', 'addr': 10}, + parent_bus={'type': 'pci'}, child_bus=bus) + out = qdev.insert(dev, False) + self.assertEqual(out, None, "Failed to insert device, ret=%s\n%s" + % (out, qdev.str_long())) + + # Device inside a child bus by type (most common) + dev = qdevice('dev', {}, parent_bus={'type': 'hba'}) + out = qdev.insert(dev, False) + self.assertEqual(out, None, "Failed to insert device, ret=%s\n%s" + % (out, qdev.str_long())) + + # Device inside a child bus by autotest_id + dev = qdevice('dev', {}, 'autotest_remove', {'aobject': 'a_hba'}) + out = qdev.insert(dev, False) + self.assertEqual(out, None, "Failed to insert device, ret=%s\n%s" + % (out, qdev.str_long())) + + # Device inside a child bus by busid + dev = qdevice('dev', {}, 'autoremove', {'busid': 'hba1.0'}) + out = qdev.insert(dev, False) + self.assertEqual(out, None, "Failed to insert device, ret=%s\n%s" + % (out, qdev.str_long())) + + # Check the representation + exp = ("Devices of vm1: [t'machine',t'i440FX',t'PIIX3',hba1,a'dev'," + "a'dev',a'dev']") + out = qdev.str_short() + self.assertEqual(out, exp, "Short representation is corrupted:\n%s\n%s" + % (out, exp)) + exp = (r"Buses of vm1" + r"\n hba1.0\(hba\): {0:a'dev',1:a'dev',2:a'dev'} {}" + r"\n pci.0\(pci\): \[t'i440FX',t'PIIX3'%s,hba1%s\] {}" + % (',None' * 8, ',None' * 21)) + out = qdev.str_bus_short() + self.assertNotEqual(re.match(exp, out), None, 'Bus representation is' + 'corrupted:\n%s\n%s' % (out, exp)) + + # Force insert bad devices: No matching bus + dev = qdevice('baddev', {}, 'badbus', {'type': 'missing_bus'}) + self.assertRaises(qemu_devices.DeviceInsertError, qdev.insert, dev, + False) + out = qdev.insert(dev, True) + self.assertEqual("No matching bus" in out, True, "Incorrect output of " + "force insertion of the bad dev, ret=%s\n%s" + % (out, qdev.str_long())) + + # Force insert bad devices: Incorrect addr + dev = qdevice('baddev', {'addr': 'bad_value'}, 'badaddr', + {'type': 'pci'}) + self.assertRaises(qemu_devices.DeviceInsertError, qdev.insert, dev, + False) + out = qdev.insert(dev, True) + self.assertEqual("errors: BasicAddress" in out, True, "Incorrect " + "output of force insertion of the bad dev, ret=%s\n%s" + % (out, qdev.str_long())) + + # Force insert bad devices: Duplicite qid + dev = qdevice('baddev', {'id': 'hba1'}, 'badid') + self.assertRaises(qemu_devices.DeviceInsertError, qdev.insert, dev, + False) + out = qdev.insert(dev, True) + self.assertEqual("Devices qid hba1 already used in VM" in out, True, + "Incorrect output of force insertion of the bad dev, " + "ret=%s\n%s" % (out, qdev.str_long())) + + # Check the representation + exp = ("Devices of vm1: [t'machine',t'i440FX',t'PIIX3',hba1,a'dev'," + "a'dev',a'dev',a'baddev',a'baddev',hba1__0]") + out = qdev.str_short() + self.assertEqual(out, exp, "Short representation is corrupted:\n%s\n%s" + % (out, exp)) + exp = (r"Buses of vm1" + r"\n hba1.0\(hba\): {0:a'dev',1:a'dev',2:a'dev'} {}" + r"\n pci.0\(pci\): \[t'i440FX',t'PIIX3',a'baddev'%s,hba1%s\] " + r"{}" % (',None' * 7, ',None' * 21)) + out = qdev.str_bus_short() + self.assertNotEqual(re.match(exp, out), None, 'Bus representation is' + 'corrupted:\n%s\n%s' % (out, exp)) + + # Now representation contains some devices, play with it a bit + # length + out = len(qdev) + self.assertEqual(out, 10, "Length of qdev is incorrect: %s != %s" + % (out, 10)) + + # compare + qdev2 = self.create_qdev('vm1') + self.assertNotEqual(qdev, qdev2, "This qdev matches empty one:" + "\n%s\n%s" % (qdev, qdev2)) + self.assertNotEqual(qdev2, qdev, "Empty qdev matches current one:" + "\n%s\n%s" % (qdev, qdev2)) + for _ in xrange(10): + qdev2.insert(qdevice()) + self.assertNotEqual(qdev, qdev2, "This qdev matches different one:" + "\n%s\n%s" % (qdev, qdev2)) + self.assertNotEqual(qdev2, qdev, "Other qdev matches this one:\n%s\n%s" + % (qdev, qdev2)) + + # cmdline + exp = ("-M pc -device id=hba1,addr=0xa,driver=HBA -device driver=dev " + "-device driver=dev -device driver=dev -device driver=baddev " + "-device addr=0x2,driver=baddev -device id=hba1,driver=baddev") + out = qdev.cmdline() + self.assertEqual(out, exp, 'Corrupted qdev.cmdline() output:\n%s\n%s' + % (out, exp)) + + # get_by_qid (currently we have 2 devices of the same qid) + out = qdev.get_by_qid('hba1') + self.assertEqual(len(out), 2, 'Incorrect number of devices by qid ' + '"hba1": %s != 2\n%s' % (len(out), qdev.str_long())) + + # Remove some devices + # Remove based on aid + out = qdev.remove('hba1__0') + self.assertEqual(out, None, 'Failed to remove device:\n%s\nRepr:\n%s' + % ('hba1__0', qdev.str_long())) + + # Remove device which contains other devices + out = qdev.remove('hba1') + self.assertEqual(out, None, 'Failed to remove device:\n%s\nRepr:\n%s' + % ('hba1', qdev.str_long())) + + # Check the representation + exp = ("Devices of vm1: [t'machine',t'i440FX',t'PIIX3',a'baddev'," + "a'baddev']") + out = qdev.str_short() + self.assertEqual(out, exp, "Short representation is corrupted:\n%s\n%s" + % (out, exp)) + exp = (r"Buses of vm1" + r"\n pci.0\(pci\): \[t'i440FX',t'PIIX3',a'baddev'%s\] " + r"{}" % (',None' * 29)) + out = qdev.str_bus_short() + self.assertNotEqual(re.match(exp, out), None, 'Bus representation is' + 'corrupted:\n%s\n%s' % (out, exp)) + + # pylint: disable=W0212 + def test_qdev_low_level(self): + """ Test low level functions """ + qdev = self.create_qdev('vm1') + + # Representation state (used for hotplug or other nasty things) + qdev._set_dirty() + out = qdev.get_state() + self.assertEqual(out, 1, "qdev state is incorrect %s != %s" % (out, 1)) + + qdev._set_dirty() + out = qdev.get_state() + self.assertEqual(out, 2, "qdev state is incorrect %s != %s" % (out, 1)) + + qdev._set_clean() + out = qdev.get_state() + self.assertEqual(out, 1, "qdev state is incorrect %s != %s" % (out, 1)) + + qdev._set_clean() + out = qdev.get_state() + self.assertEqual(out, 0, "qdev state is incorrect %s != %s" % (out, 1)) + + # __create_unique_aid + dev = qemu_devices.QDevice() + qdev.insert(dev) + out = dev.get_aid() + self.assertEqual(out, '__0', "incorrect aid %s != %s" % (out, '__0')) + + dev = qemu_devices.QDevice(None, {'id': 'qid'}) + qdev.insert(dev) + out = dev.get_aid() + self.assertEqual(out, 'qid', "incorrect aid %s != %s" % (out, 'qid')) + + dev = qemu_devices.QDevice(None, {'id': 'qid'}) + qdev.insert(dev, True) + out = dev.get_aid() + self.assertEqual(out, 'qid__0', "incorrect aid %s != %s" + % (out, 'qid__0')) + + dev = qemu_devices.QDevice(None, {'id': 'qid__1'}) + qdev.insert(dev, True) + out = dev.get_aid() + self.assertEqual(out, 'qid__1', "incorrect aid %s != %s" + % (out, 'qid__1')) + + dev = qemu_devices.QDevice(None, {'id': 'qid'}) + qdev.insert(dev, True) + out = dev.get_aid() + self.assertEqual(out, 'qid__2', "incorrect aid %s != %s" + % (out, 'qid__2')) + + # has_option + out = qdev.has_option('device') + self.assertEqual(out, True) + + out = qdev.has_option('missing_option') + self.assertEqual(out, False) + + # has_device + out = qdev.has_device('ide-drive') + self.assertEqual(out, True) + + out = qdev.has_device('missing_device') + self.assertEqual(out, False) + + # get_help_text + out = qdev.get_help_text() + self.assertEqual(out, QEMU_HELP) + + # has_hmp_cmd + self.assertTrue(qdev.has_hmp_cmd('pcie_aer_inject_error')) + self.assertTrue(qdev.has_hmp_cmd('c')) + self.assertTrue(qdev.has_hmp_cmd('cont')) + self.assertFalse(qdev.has_hmp_cmd('off')) + self.assertFalse(qdev.has_hmp_cmd('\ndump-guest-memory')) + self.assertFalse(qdev.has_hmp_cmd('The')) + + # has_qmp_cmd + self.assertTrue(qdev.has_qmp_cmd('device_add')) + self.assertFalse(qdev.has_qmp_cmd('RAND91')) + + # Add some buses + bus1 = qemu_devices.QPCIBus('pci.0', 'pci', 'a_pci0') + qdev.insert(qemu_devices.QDevice(child_bus=bus1)) + bus2 = qemu_devices.QPCIBus('pci.1', 'pci', 'a_pci1') + qdev.insert(qemu_devices.QDevice(child_bus=bus2)) + bus3 = qemu_devices.QPCIBus('pci.2', 'pci', 'a_pci2') + qdev.insert(qemu_devices.QDevice(child_bus=bus3)) + bus4 = qemu_devices.QPCIBus('pcie.0', 'pcie', 'a_pcie0') + qdev.insert(qemu_devices.QDevice(child_bus=bus4)) + + # get_buses (all buses of this type) + out = qdev.get_buses({'type': 'pci'}) + self.assertEqual(len(out), 3, 'get_buses should return 3 buses but ' + 'returned %s instead:\n%s' % (len(out), out)) + + # get_first_free_bus (last added bus of this type) + out = qdev.get_first_free_bus({'type': 'pci'}, [None]) + self.assertEqual(bus3, out) + + # fill the first pci bus + for _ in xrange(32): + qdev.insert(qemu_devices.QDevice(parent_bus={'type': 'pci'})) + + # get_first_free_bus (last one is full, return the previous one) + out = qdev.get_first_free_bus({'type': 'pci'}, [None]) + self.assertEqual(bus2, out) + + # list_named_buses + out = qdev.list_missing_named_buses('pci.', 'pci', 5) + self.assertEqual(len(out), 2, 'Number of missing named buses is ' + 'incorrect: %s != %s\n%s' % (len(out), 2, out)) + out = qdev.list_missing_named_buses('pci.', 'abc', 5) + self.assertEqual(len(out), 5, 'Number of missing named buses is ' + 'incorrect: %s != %s\n%s' % (len(out), 2, out)) + + # idx_of_next_named_bus + out = qdev.idx_of_next_named_bus('pci.') + self.assertEqual(out, 3, 'Incorrect idx of next named bus: %s !=' + ' %s' % (out, 3)) + # pylint: enable=W0212 + + if __name__ == "__main__": unittest.main() diff --git a/virttest/unittest_data/qemu-1.5.0__devices_help b/virttest/unittest_data/qemu-1.5.0__devices_help new file mode 100644 index 000000000..723681430 --- /dev/null +++ b/virttest/unittest_data/qemu-1.5.0__devices_help @@ -0,0 +1,135 @@ +name "VGA", bus PCI +name "gus", bus ISA, desc "Gravis Ultrasound GF1" +name "tpci200", bus PCI, desc "TEWS TPCI200 IndustryPack carrier" +name "usb-storage", bus usb-bus +name "scsi-hd", bus SCSI, desc "virtual SCSI disk" +name "i82559a", bus PCI, desc "Intel i82559A Ethernet" +name "i82559b", bus PCI, desc "Intel i82559B Ethernet" +name "i82559c", bus PCI, desc "Intel i82559C Ethernet" +name "esp", bus System +name "sysbus-ohci", bus System, desc "OHCI USB Controller" +name "virtio-blk-pci", bus PCI, alias "virtio-blk" +name "vhost-scsi-pci", bus PCI +name "usb-uas", bus usb-bus +name "x3130-upstream", bus PCI, desc "TI X3130 Upstream Port of PCI Express Switch" +name "ide-drive", bus IDE, desc "virtual IDE disk or CD-ROM (legacy)" +name "virtio-9p-pci", bus PCI +name "cirrus-vga", bus PCI, desc "Cirrus CLGD 54xx VGA" +name "ide-hd", bus IDE, desc "virtual IDE disk" +name "ES1370", bus PCI, desc "ENSONIQ AudioPCI ES1370" +name "ioh3420", bus PCI, desc "Intel IOH device id 3420 PCIE Root Port" +name "virtio-rng-device", bus virtio-bus +name "isa-debug-exit", bus ISA +name "sga", bus ISA, desc "Serial Graphics Adapter" +name "scsi-block", bus SCSI, desc "SCSI block device passthrough" +name "pc-sysfw", bus System, desc "PC System Firmware" +name "usb-serial", bus usb-bus +name "cs4231a", bus ISA, desc "Crystal Semiconductor CS4231A" +name "usb-mouse", bus usb-bus +name "usb-hub", bus usb-bus +name "usb-net", bus usb-bus +name "ne2k_isa", bus ISA +name "icc-bridge", bus System +name "virtio-serial-device", bus virtio-bus +name "virtio-scsi-common", bus virtio-bus +name "scsi-generic", bus SCSI, desc "pass through generic scsi device (/dev/sg*)" +name "pcnet", bus PCI +name "lsi53c895a", bus PCI, alias "lsi" +name "vhost-scsi", bus virtio-bus +name "scsi-disk", bus SCSI, desc "virtual SCSI disk or CD-ROM (legacy)" +name "hda-micro", bus HDA, desc "HDA Audio Codec, duplex (speaker, microphone)" +name "xio3130-downstream", bus PCI, desc "TI X3130 Downstream Port of PCI Express Switch" +name "pci-serial-2x", bus PCI +name "virtserialport", bus virtio-serial-bus +name "usb-braille", bus usb-bus +name "pci-ohci", bus PCI, desc "Apple USB Controller" +name "scsi-cd", bus SCSI, desc "virtual SCSI CD-ROM" +name "q35-pcihost", bus System +name "usb-wacom-tablet", bus usb-bus, desc "QEMU PenPartner Tablet" +name "virtio-net-device", bus virtio-bus +name "ich9-intel-hda", bus PCI, desc "Intel HD Audio Controller (ich9)" +name "nec-usb-xhci", bus PCI +name "isa-serial", bus ISA +name "i82550", bus PCI, desc "Intel i82550 Ethernet" +name "i82551", bus PCI, desc "Intel i82551 Ethernet" +name "usb-bot", bus usb-bus +name "isa-debugcon", bus ISA +name "ide-cd", bus IDE, desc "virtual IDE CD-ROM" +name "SUNW,fdtwo", bus System +name "adlib", bus ISA, desc "Yamaha YM3812 (OPL2)" +name "ich9-usb-uhci1", bus PCI +name "ich9-usb-uhci2", bus PCI +name "pci-serial", bus PCI +name "isa-parallel", bus ISA +name "ich9-usb-uhci4", bus PCI +name "virtconsole", bus virtio-serial-bus +name "ich9-usb-uhci3", bus PCI +name "ich9-usb-uhci5", bus PCI +name "ich9-usb-uhci6", bus PCI +name "ne2k_pci", bus PCI +name "virtio-serial-pci", bus PCI, alias "virtio-serial" +name "hda-duplex", bus HDA, desc "HDA Audio Codec, duplex (line-out, line-in)" +name "intel-hda", bus PCI, desc "Intel HD Audio Controller (ich6)" +name "megasas", bus PCI, desc "LSI MegaRAID SAS 1078" +name "virtio-balloon-device", bus virtio-bus +name "i82559er", bus PCI, desc "Intel i82559ER Ethernet" +name "pci-serial-4x", bus PCI +name "hda-output", bus HDA, desc "HDA Audio Codec, output-only (line-out)" +name "i82562", bus PCI, desc "Intel i82562 Ethernet" +name "sysbus-ahci", bus System +name "usb-ccid", bus usb-bus, desc "CCID Rev 1.1 smartcard reader" +name "ivshmem", bus PCI +name "mch", bus PCI, desc "Host bridge" +name "ipoctal232", bus IndustryPack, desc "GE IP-Octal 232 8-channel RS-232 IndustryPack" +name "AC97", bus PCI, desc "Intel 82801AA AC97 Audio" +name "e1000", bus PCI, desc "Intel Gigabit Ethernet" +name "sysbus-fdc", bus System +name "usb-bt-dongle", bus usb-bus +name "virtio-rng-pci", bus PCI +name "usb-tablet", bus usb-bus +name "pci-testdev", bus PCI, desc "PCI Test Device" +name "isa-vga", bus ISA +name "vfio-pci", bus PCI, desc "VFIO-based PCI device assignment" +name "usb-kbd", bus usb-bus +name "cfi.pflash01", bus System +name "kvm-pci-assign", bus PCI, alias "pci-assign", desc "KVM-based PCI passthrough" +name "isa-applesmc", bus ISA +name "rtl8139", bus PCI +name "pvscsi", bus PCI +name "i82557a", bus PCI, desc "Intel i82557A Ethernet" +name "i82557b", bus PCI, desc "Intel i82557B Ethernet" +name "i82557c", bus PCI, desc "Intel i82557C Ethernet" +name "usb-audio", bus usb-bus +name "ib700", bus ISA +name "piix3-usb-uhci", bus PCI +name "i82801", bus PCI, desc "Intel i82801 Ethernet" +name "ccid-card-passthru", bus ccid-bus, desc "passthrough smartcard" +name "piix4-usb-uhci", bus PCI +name "smbus-eeprom", bus i2c-bus +name "vmware-svga", bus PCI +name "dc390", bus PCI, desc "Tekram DC-390 SCSI adapter" +name "isa-cirrus-vga", bus ISA +name "vmxnet3", bus PCI, desc "VMWare Paravirtualized Ethernet v3" +name "i82801b11-bridge", bus PCI +name "sb16", bus ISA, desc "Creative Sound Blaster 16" +name "xlnx,ps7-usb", bus System +name "am53c974", bus PCI, desc "AMD Am53c974 PCscsi-PCI SCSI adapter" +name "pci-bridge", bus PCI, desc "Standard PCI Bridge" +name "i82558a", bus PCI, desc "Intel i82558A Ethernet" +name "i82558b", bus PCI, desc "Intel i82558B Ethernet" +name "vt82c686b-usb-uhci", bus PCI +name "virtio-balloon-pci", bus PCI, alias "virtio-balloon" +name "isa-ide", bus ISA +name "ich9-usb-ehci1", bus PCI +name "ich9-ahci", bus PCI, alias "ahci" +name "usb-ehci", bus PCI +name "ich9-usb-ehci2", bus PCI +name "usb-host", bus usb-bus +name "i6300esb", bus PCI +name "exynos4210-ehci-usb", bus System +name "virtio-scsi-pci", bus PCI +name "virtio-blk-device", bus virtio-bus +name "pc-testdev", bus ISA +name "virtio-scsi-device", bus virtio-bus +name "virtio-9p-device", bus virtio-bus +name "virtio-net-pci", bus PCI, alias "virtio-net" \ No newline at end of file diff --git a/virttest/unittest_data/qemu-1.5.0__help b/virttest/unittest_data/qemu-1.5.0__help new file mode 100644 index 000000000..3295cf891 --- /dev/null +++ b/virttest/unittest_data/qemu-1.5.0__help @@ -0,0 +1,301 @@ +QEMU emulator version 1.5.0, Copyright (c) 2003-2008 Fabrice Bellard +usage: qemu-system-x86_64 [options] [disk_image] + +'disk_image' is a raw hard disk image for IDE hard disk 0 + +Standard options: +-h or -help display this help and exit +-version display version information and exit +-machine [type=]name[,prop[=value][,...]] + selects emulated machine ('-machine help' for list) + property accel=accel1[:accel2[:...]] selects accelerator + supported accelerators are kvm, xen, tcg (default: tcg) + kernel_irqchip=on|off controls accelerated irqchip support + kvm_shadow_mem=size of KVM shadow MMU + dump-guest-core=on|off include guest memory in a core dump (default=on) + mem-merge=on|off controls memory merge support (default: on) +-cpu cpu select CPU ('-cpu help' for list) +-smp n[,maxcpus=cpus][,cores=cores][,threads=threads][,sockets=sockets] + set the number of CPUs to 'n' [default=1] + maxcpus= maximum number of total cpus, including + offline CPUs for hotplug, etc + cores= number of CPU cores on one socket + threads= number of threads on one CPU core + sockets= number of discrete sockets in the system +-numa node[,mem=size][,cpus=cpu[-cpu]][,nodeid=node] +-add-fd fd=fd,set=set[,opaque=opaque] + Add 'fd' to fd 'set' +-set group.id.arg=value + set parameter for item of type + i.e. -set drive.$id.file=/path/to/image +-global driver.prop=value + set a global default for a driver property +-boot [order=drives][,once=drives][,menu=on|off] + [,splash=sp_name][,splash-time=sp_time][,reboot-timeout=rb_time][,strict=on|off] + 'drives': floppy (a), hard disk (c), CD-ROM (d), network (n) + 'sp_name': the file's name that would be passed to bios as logo picture, if menu=on + 'sp_time': the period that splash picture last if menu=on, unit is ms + 'rb_timeout': the timeout before guest reboot when boot failed, unit is ms +-m megs set virtual RAM size to megs MB [default=128] +-mem-path FILE provide backing storage for guest RAM +-mem-prealloc preallocate guest memory (use with -mem-path) +-k language use keyboard layout (for example 'fr' for French) +-audio-help print list of audio drivers and their options +-soundhw c1,... enable audio support + and only specified sound cards (comma separated list) + use '-soundhw help' to get the list of supported cards + use '-soundhw all' to enable all of them +-balloon none disable balloon device +-balloon virtio[,addr=str] + enable virtio balloon device (default) +-device driver[,prop[=value][,...]] + add device (based on driver) + prop=value,... sets driver properties + use '-device help' to print all possible drivers + use '-device driver,help' to print all possible properties +-name string1[,process=string2] + set the name of the guest + string1 sets the window title and string2 the process name (on Linux) +-uuid %08x-%04x-%04x-%04x-%012x + specify machine UUID + +Block device options: +-fda/-fdb file use 'file' as floppy disk 0/1 image +-hda/-hdb file use 'file' as IDE hard disk 0/1 image +-hdc/-hdd file use 'file' as IDE hard disk 2/3 image +-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master) +-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i] + [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off] + [,cache=writethrough|writeback|none|directsync|unsafe][,format=f] + [,serial=s][,addr=A][,id=name][,aio=threads|native] + [,readonly=on|off][,copy-on-read=on|off] + [[,bps=b]|[[,bps_rd=r][,bps_wr=w]]][[,iops=i]|[[,iops_rd=r][,iops_wr=w]] + use 'file' as a drive image +-mtdblock file use 'file' as on-board Flash memory image +-sd file use 'file' as SecureDigital card image +-pflash file use 'file' as a parallel flash image +-snapshot write to temporary files instead of disk image files +-hdachs c,h,s[,t] + force hard disk 0 physical geometry and the optional BIOS + translation (t=none or lba) (usually QEMU can guess them) +-fsdev fsdriver,id=id[,path=path,][security_model={mapped-xattr|mapped-file|passthrough|none}] + [,writeout=immediate][,readonly][,socket=socket|sock_fd=sock_fd] +-virtfs local,path=path,mount_tag=tag,security_model=[mapped-xattr|mapped-file|passthrough|none] + [,writeout=immediate][,readonly][,socket=socket|sock_fd=sock_fd] +-virtfs_synth Create synthetic file system image + +USB options: +-usb enable the USB driver (will be the default soon) +-usbdevice name add the host or guest USB device 'name' + +Display options: +-display sdl[,frame=on|off][,alt_grab=on|off][,ctrl_grab=on|off] + [,window_close=on|off]|curses|none| + vnc=[,] + select display type +-nographic disable graphical output and redirect serial I/Os to console +-curses use a curses/ncurses interface instead of SDL +-no-frame open SDL window without a frame and window decorations +-alt-grab use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt) +-ctrl-grab use Right-Ctrl to grab mouse (instead of Ctrl-Alt) +-no-quit disable SDL window close capability +-sdl enable SDL +-spice [port=port][,tls-port=secured-port][,x509-dir=

] + [,x509-key-file=][,x509-key-password=] + [,x509-cert-file=][,x509-cacert-file=] + [,x509-dh-key-file=][,addr=addr][,ipv4|ipv6] + [,tls-ciphers=] + [,tls-channel=[main|display|cursor|inputs|record|playback]] + [,plaintext-channel=[main|display|cursor|inputs|record|playback]] + [,sasl][,password=][,disable-ticketing] + [,image-compression=[auto_glz|auto_lz|quic|glz|lz|off]] + [,jpeg-wan-compression=[auto|never|always]] + [,zlib-glz-wan-compression=[auto|never|always]] + [,streaming-video=[off|all|filter]][,disable-copy-paste] + [,agent-mouse=[on|off]][,playback-compression=[on|off]] + [,seamless-migration=[on|off]] + enable spice + at least one of {port, tls-port} is mandatory +-portrait rotate graphical output 90 deg left (only PXA LCD) +-rotate rotate graphical output some deg left (only PXA LCD) +-vga [std|cirrus|vmware|qxl|xenfb|none] + select video card type +-full-screen start in full screen +-vnc display start a VNC server on display + +i386 target only: +-win2k-hack use it when installing Windows 2000 to avoid a disk full bug +-no-fd-bootchk disable boot signature checking for floppy disks +-no-acpi disable ACPI +-no-hpet disable HPET +-acpitable [sig=str][,rev=n][,oem_id=str][,oem_table_id=str][,oem_rev=n][,asl_compiler_id=str][,asl_compiler_rev=n][,{data|file}=file1[:file2]...] + ACPI table description +-smbios file=binary + load SMBIOS entry from binary file +-smbios type=0[,vendor=str][,version=str][,date=str][,release=%d.%d] + specify SMBIOS type 0 fields +-smbios type=1[,manufacturer=str][,product=str][,version=str][,serial=str] + [,uuid=uuid][,sku=str][,family=str] + specify SMBIOS type 1 fields + +Network options: +-net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v] + create a new Network Interface Card and connect it to VLAN 'n' +-net user[,vlan=n][,name=str][,net=addr[/mask]][,host=addr][,restrict=on|off] + [,hostname=host][,dhcpstart=addr][,dns=addr][,dnssearch=domain][,tftp=dir] + [,bootfile=f][,hostfwd=rule][,guestfwd=rule][,smb=dir[,smbserver=addr]] + connect the user mode network stack to VLAN 'n', configure its + DHCP server and enabled optional services +-net tap[,vlan=n][,name=str][,fd=h][,fds=x:y:...:z][,ifname=name][,script=file][,downscript=dfile][,helper=helper][,sndbuf=nbytes][,vnet_hdr=on|off][,vhost=on|off][,vhostfd=h][,vhostfds=x:y:...:z][,vhostforce=on|off][,queues=n] + connect the host TAP network interface to VLAN 'n' + use network scripts 'file' (default=/etc/qemu-ifup) + to configure it and 'dfile' (default=/etc/qemu-ifdown) + to deconfigure it + use '[down]script=no' to disable script execution + use network helper 'helper' (default=/usr/local/libexec/qemu-bridge-helper) to + configure it + use 'fd=h' to connect to an already opened TAP interface + use 'fds=x:y:...:z' to connect to already opened multiqueue capable TAP interfaces + use 'sndbuf=nbytes' to limit the size of the send buffer (the + default is disabled 'sndbuf=0' to enable flow control set 'sndbuf=1048576') + use vnet_hdr=off to avoid enabling the IFF_VNET_HDR tap flag + use vnet_hdr=on to make the lack of IFF_VNET_HDR support an error condition + use vhost=on to enable experimental in kernel accelerator + (only has effect for virtio guests which use MSIX) + use vhostforce=on to force vhost on for non-MSIX virtio guests + use 'vhostfd=h' to connect to an already opened vhost net device + use 'vhostfds=x:y:...:z to connect to multiple already opened vhost net devices + use 'queues=n' to specify the number of queues to be created for multiqueue TAP +-net bridge[,vlan=n][,name=str][,br=bridge][,helper=helper] + connects a host TAP network interface to a host bridge device 'br' + (default=br0) using the program 'helper' + (default=/usr/local/libexec/qemu-bridge-helper) +-net socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port] + connect the vlan 'n' to another VLAN using a socket connection +-net socket[,vlan=n][,name=str][,fd=h][,mcast=maddr:port[,localaddr=addr]] + connect the vlan 'n' to multicast maddr and port + use 'localaddr=addr' to specify the host address to send packets from +-net socket[,vlan=n][,name=str][,fd=h][,udp=host:port][,localaddr=host:port] + connect the vlan 'n' to another VLAN using an UDP tunnel +-net dump[,vlan=n][,file=f][,len=n] + dump traffic on vlan 'n' to file 'f' (max n bytes per packet) +-net none use it alone to have zero network devices. If no -net option + is provided, the default is '-net nic -net user' +-netdev [user|tap|bridge|socket|hubport],id=str[,option][,option][,...] + +Character device options: +-chardev null,id=id[,mux=on|off] +-chardev socket,id=id[,host=host],port=host[,to=to][,ipv4][,ipv6][,nodelay] + [,server][,nowait][,telnet][,mux=on|off] (tcp) +-chardev socket,id=id,path=path[,server][,nowait][,telnet],[mux=on|off] (unix) +-chardev udp,id=id[,host=host],port=port[,localaddr=localaddr] + [,localport=localport][,ipv4][,ipv6][,mux=on|off] +-chardev msmouse,id=id[,mux=on|off] +-chardev vc,id=id[[,width=width][,height=height]][[,cols=cols][,rows=rows]] + [,mux=on|off] +-chardev ringbuf,id=id[,size=size] +-chardev file,id=id,path=path[,mux=on|off] +-chardev pipe,id=id,path=path[,mux=on|off] +-chardev pty,id=id[,mux=on|off] +-chardev stdio,id=id[,mux=on|off][,signal=on|off] +-chardev serial,id=id,path=path[,mux=on|off] +-chardev tty,id=id,path=path[,mux=on|off] +-chardev parallel,id=id,path=path[,mux=on|off] +-chardev parport,id=id,path=path[,mux=on|off] + +Device URL Syntax: +-iscsi [user=user][,password=password] + [,header-digest=CRC32C|CR32C-NONE|NONE-CRC32C|NONE + [,initiator-name=iqn] + iSCSI session parameters +Bluetooth(R) options: +-bt hci,null dumb bluetooth HCI - doesn't respond to commands +-bt hci,host[:id] + use host's HCI with the given name +-bt hci[,vlan=n] + emulate a standard HCI in virtual scatternet 'n' +-bt vhci[,vlan=n] + add host computer to virtual scatternet 'n' using VHCI +-bt device:dev[,vlan=n] + emulate a bluetooth device 'dev' in scatternet 'n' + +Linux/Multiboot boot specific: +-kernel bzImage use 'bzImage' as kernel image +-append cmdline use 'cmdline' as kernel command line +-initrd file use 'file' as initial ram disk +-dtb file use 'file' as device tree image + +Debug/Expert options: +-serial dev redirect the serial port to char device 'dev' +-parallel dev redirect the parallel port to char device 'dev' +-monitor dev redirect the monitor to char device 'dev' +-qmp dev like -monitor but opens in 'control' mode +-mon chardev=[name][,mode=readline|control][,default] +-debugcon dev redirect the debug console to char device 'dev' +-pidfile file write PID to 'file' +-singlestep always run in singlestep mode +-S freeze CPU at startup (use 'c' to start execution) +-realtime [mlock=on|off] + run qemu with realtime features + mlock=on|off controls mlock support (default: on) +-gdb dev wait for gdb connection on 'dev' +-s shorthand for -gdb tcp::1234 +-d item1,... enable logging of specified items (use '-d help' for a list of log items) +-D logfile output log to logfile (default stderr) +-L path set the directory for the BIOS, VGA BIOS and keymaps +-bios file set the filename for the BIOS +-enable-kvm enable KVM full virtualization support +-xen-domid id specify xen guest domain id +-xen-create create domain using xen hypercalls, bypassing xend + warning: should not be used when xend is in use +-xen-attach attach to existing xen domain + xend will use this when starting QEMU +-no-reboot exit instead of rebooting +-no-shutdown stop before shutdown +-loadvm [tag|id] + start right away with a saved state (loadvm in monitor) +-daemonize daemonize QEMU after initializing +-option-rom rom load a file, rom, into the option ROM space +-clock force the use of the given methods for timer alarm. + To see what timers are available use '-clock help' +-rtc [base=utc|localtime|date][,clock=host|rt|vm][,driftfix=none|slew] + set the RTC base and clock, enable drift fix for clock ticks (x86 only) +-icount [N|auto] + enable virtual instruction counter with 2^N clock ticks per + instruction +-watchdog i6300esb|ib700 + enable virtual hardware watchdog [default=none] +-watchdog-action reset|shutdown|poweroff|pause|debug|none + action when watchdog fires [default=reset] +-echr chr set terminal escape character instead of ctrl-a +-virtioconsole c + set virtio console +-show-cursor show cursor +-tb-size n set TB size +-incoming p prepare for incoming migration, listen on port p +-nodefaults don't create default devices +-chroot dir chroot to dir just before starting the VM +-runas user change to user id user just before starting the VM +-sandbox Enable seccomp mode 2 system call filter (default 'off'). +-readconfig +-writeconfig + read/write config file +-nodefconfig + do not load default config files at startup +-no-user-config + do not load user-provided config files at startup +-trace [events=][,file=] + specify tracing options +-enable-fips enable FIPS 140-2 compliance +-object TYPENAME[,PROP1=VALUE1,...] + create an new object of type TYPENAME setting properties + in the order they are specified. Note that the 'id' + property must be set. These objects are placed in the + '/objects' path. + +During emulation, the following keys are useful: +ctrl-alt-f toggle full screen +ctrl-alt-n switch to virtual console 'n' +ctrl-alt toggle mouse and keyboard grab + +When using -nographic, press 'ctrl-a h' to get some help. \ No newline at end of file diff --git a/virttest/unittest_data/qemu-1.5.0__hmp_help b/virttest/unittest_data/qemu-1.5.0__hmp_help new file mode 100644 index 000000000..90b2746f9 --- /dev/null +++ b/virttest/unittest_data/qemu-1.5.0__hmp_help @@ -0,0 +1,90 @@ +help +acl_add aclname match allow|deny [index] -- add a match rule to the access control list +acl_policy aclname allow|deny -- set default access control list policy +acl_remove aclname match -- remove a match rule from the access control list +acl_reset aclname -- reset the access control list +acl_show aclname -- list rules in the access control list +balloon target -- request VM to change its memory allocation (in MB) +block_job_cancel [-f] device -- stop an active background block operation (use -f + if the operation is currently paused) +block_job_complete device -- stop an active background block operation +block_job_pause device -- pause an active background block operation +block_job_resume device -- resume a paused background block operation +block_job_set_speed device speed -- set maximum speed for a background block operation +block_passwd block_passwd device password -- set the password of encrypted block devices +block_resize device size -- resize a block image +block_set_io_throttle device bps bps_rd bps_wr iops iops_rd iops_wr -- change I/O throttle limits for a block drive +block_stream device [speed [base]] -- copy data from a backing file into a block device +boot_set bootdevice -- define new values for the boot device list +change device filename [format] -- change a removable medium, optional format +chardev-add args -- add chardev +chardev-remove id -- remove chardev +client_migrate_info protocol hostname port tls-port cert-subject -- send migration info to spice/vnc client +closefd closefd name -- close a file descriptor previously passed via SCM rights +commit device|all -- commit changes to the disk images (if -snapshot is used) or backing files +cpu index -- set the default CPU +c|cont -- resume emulation +delvm tag|id -- delete a VM snapshot from its tag or id +device_add driver[,prop=value][,...] -- add device, like -device on the command line +device_del device -- remove device +drive_add [[:]:] +[file=file][,if=type][,bus=n] +[,unit=m][,media=d][,index=i] +[,cyls=c,heads=h,secs=s[,trans=t]] +[,snapshot=on|off][,cache=on|off] +[,readonly=on|off][,copy-on-read=on|off] -- add drive to PCI storage controller +drive_del device -- remove host block device +drive_mirror [-n] [-f] device target [format] -- initiates live storage + migration for a device. The device's contents are + copied to the new image file, including data that + is written after the command is started. + The -n flag requests QEMU to reuse the image found + in new-image-file, instead of recreating it from scratch. + The -f flag requests QEMU to copy the whole disk, + so that the result does not need a backing file. + +dump-guest-memory [-p] filename [begin] [length] -- dump guest memory to file + begin(optional): the starting physical address + length(optional): the memory size, in bytes +eject [-f] device -- eject a removable medium (use -f to force it) +expire_password protocol time -- set spice/vnc password expire-time +gdbserver [device] -- start gdbserver on given device (default 'tcp::1234'), stop with 'none' +getfd getfd name -- receive a file descriptor via SCM rights and assign it a name +help|? [cmd] -- show the help +host_net_add tap|user|socket|vde|dump [options] -- add host VLAN client +host_net_remove vlan_id name -- remove host VLAN client +hostfwd_add [vlan_id name] [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport -- redirect TCP or UDP connections from host to guest (requires -net user) +hostfwd_remove [vlan_id name] [tcp|udp]:[hostaddr]:hostport -- remove host-to-guest TCP or UDP redirection +i /fmt addr -- I/O port read +info [subcommand] -- show various information about the system state +loadvm tag|id -- restore a VM snapshot from its tag or id +log item1[,...] -- activate logging of the specified items +logfile filename -- output logs to 'filename' +mce [-b] cpu bank status mcgstatus addr misc -- inject a MCE on the given CPU [and broadcast to other CPUs with -b option] +memsave addr size file -- save to disk virtual memory dump starting at 'addr' of size 'size' +migrate [-d] [-b] [-i] uri -- migrate to URI (using -d to not wait for completion) + -b for migration without shared storage with full copy of disk + -i for migration without shared storage with incremental copy of disk (base image shared between src and destination) +migrate_cancel -- cancel the current VM migration +migrate_set_cache_size value -- set cache size (in bytes) for XBZRLE migrations,the cache size will be rounded down to the nearest power of 2. +The cache size affects the number of cache misses.In case of a high cache miss ratio you need to increase the cache size +migrate_set_capability capability state -- Enable/Disable the usage of a capability for migration +migrate_set_downtime value -- set maximum tolerated downtime (in seconds) for migrations +migrate_set_speed value -- set maximum speed (in bytes) for migrations. Defaults to MB if no size suffix is specified, ie. B/K/M/G/T +mouse_button state -- change mouse button state (1=L, 2=M, 4=R) +mouse_move dx dy [dz] -- send mouse move events +mouse_set index -- set which mouse device receives events +nbd_server_add nbd_server_add [-w] device -- export a block device via NBD +nbd_server_start nbd_server_start [-a] [-w] host:port -- serve block devices on the given host and port +nbd_server_stop nbd_server_stop -- stop serving block devices using the NBD protocol +netdev_add [user|tap|socket|hubport],id=str[,prop=value][,...] -- add host network device +netdev_del id -- remove host network device +nmi -- inject an NMI on all guest's CPUs +o /fmt addr value -- I/O port write +pci_add auto|[[:]:] nic|storage [[vlan=n][,macaddr=addr][,model=type]] [file=file][,if=type][,bus=nr]... -- hot-add PCI device +pci_del [[:]:] -- hot remove PCI device +pcie_aer_inject_error [-a] [-c] id [ []] -- inject pcie aer error + -a for advisory non fatal error + -c for correctable error + = qdev device id + = error string or 32bit \ No newline at end of file diff --git a/virttest/unittest_data/qemu-1.5.0__machine_help b/virttest/unittest_data/qemu-1.5.0__machine_help new file mode 100644 index 000000000..1a9ca1419 --- /dev/null +++ b/virttest/unittest_data/qemu-1.5.0__machine_help @@ -0,0 +1,19 @@ +Supported machines are: +none empty machine +pc Standard PC (i440FX + PIIX, 1996) (alias of pc-i440fx-1.5) +pc-i440fx-1.5 Standard PC (i440FX + PIIX, 1996) (default) +pc-i440fx-1.4 Standard PC (i440FX + PIIX, 1996) +pc-1.3 Standard PC +pc-1.2 Standard PC +pc-1.1 Standard PC +pc-1.0 Standard PC +pc-0.15 Standard PC +pc-0.14 Standard PC +pc-0.13 Standard PC +pc-0.12 Standard PC +pc-0.11 Standard PC, qemu 0.11 +pc-0.10 Standard PC, qemu 0.10 +isapc ISA-only PC +q35 Standard PC (Q35 + ICH9, 2009) (alias of pc-q35-1.5) +pc-q35-1.5 Standard PC (Q35 + ICH9, 2009) +pc-q35-1.4 Standard PC (Q35 + ICH9, 2009) \ No newline at end of file diff --git a/virttest/unittest_data/qemu-1.5.0__qmp_help b/virttest/unittest_data/qemu-1.5.0__qmp_help new file mode 100644 index 000000000..e7a86623c --- /dev/null +++ b/virttest/unittest_data/qemu-1.5.0__qmp_help @@ -0,0 +1 @@ +{"return": [{"name": "chardev-remove"}, {"name": "chardev-add"}, {"name": "query-tpm-types"}, {"name": "query-tpm-models"}, {"name": "query-tpm"}, {"name": "query-target"}, {"name": "query-cpu-definitions"}, {"name": "query-machines"}, {"name": "device-list-properties"}, {"name": "qom-list-types"}, {"name": "change-vnc-password"}, {"name": "nbd-server-stop"}, {"name": "nbd-server-add"}, {"name": "nbd-server-start"}, {"name": "qom-get"}, {"name": "qom-set"}, {"name": "qom-list"}, {"name": "query-block-jobs"}, {"name": "query-balloon"}, {"name": "query-migrate-capabilities"}, {"name": "migrate-set-capabilities"}, {"name": "query-migrate"}, {"name": "query-command-line-options"}, {"name": "query-uuid"}, {"name": "query-name"}, {"name": "query-vnc"}, {"name": "query-mice"}, {"name": "query-status"}, {"name": "query-kvm"}, {"name": "query-pci"}, {"name": "query-cpus"}, {"name": "query-blockstats"}, {"name": "query-block"}, {"name": "query-chardev"}, {"name": "query-events"}, {"name": "query-commands"}, {"name": "query-version"}, {"name": "human-monitor-command"}, {"name": "qmp_capabilities"}, {"name": "add_client"}, {"name": "expire_password"}, {"name": "set_password"}, {"name": "block_set_io_throttle"}, {"name": "block_passwd"}, {"name": "query-fdsets"}, {"name": "remove-fd"}, {"name": "add-fd"}, {"name": "closefd"}, {"name": "getfd"}, {"name": "set_link"}, {"name": "balloon"}, {"name": "drive-mirror"}, {"name": "blockdev-snapshot-sync"}, {"name": "transaction"}, {"name": "block-job-complete"}, {"name": "block-job-resume"}, {"name": "block-job-pause"}, {"name": "block-job-cancel"}, {"name": "block-job-set-speed"}, {"name": "block-commit"}, {"name": "block-stream"}, {"name": "block_resize"}, {"name": "netdev_del"}, {"name": "netdev_add"}, {"name": "dump-guest-memory"}, {"name": "client_migrate_info"}, {"name": "migrate_set_downtime"}, {"name": "migrate_set_speed"}, {"name": "query-migrate-cache-size"}, {"name": "migrate-set-cache-size"}, {"name": "migrate_cancel"}, {"name": "migrate"}, {"name": "xen-set-global-dirty-log"}, {"name": "xen-save-devices-state"}, {"name": "ringbuf-read"}, {"name": "ringbuf-write"}, {"name": "inject-nmi"}, {"name": "pmemsave"}, {"name": "memsave"}, {"name": "cpu-add"}, {"name": "cpu"}, {"name": "send-key"}, {"name": "device_del"}, {"name": "device_add"}, {"name": "system_powerdown"}, {"name": "system_reset"}, {"name": "system_wakeup"}, {"name": "cont"}, {"name": "stop"}, {"name": "screendump"}, {"name": "change"}, {"name": "eject"}, {"name": "quit"}], "id": "RAND91"} \ No newline at end of file From 1f75e009e89af660663a28a5f44983b7b53d1950 Mon Sep 17 00:00:00 2001 From: Lucas Meneghel Rodrigues Date: Fri, 5 Jul 2013 16:18:25 -0300 Subject: [PATCH 061/254] virttest.qemu_devices_unittest: Fix path references Signed-off-by: Lucas Meneghel Rodrigues --- virttest/qemu_devices_unittest.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) mode change 100644 => 100755 virttest/qemu_devices_unittest.py diff --git a/virttest/qemu_devices_unittest.py b/virttest/qemu_devices_unittest.py old mode 100644 new mode 100755 index 69d452b1e..60fc4b07c --- a/virttest/qemu_devices_unittest.py +++ b/virttest/qemu_devices_unittest.py @@ -7,23 +7,24 @@ """ __author__ = """Lukas Doktor (ldoktor@redhat.com)""" +import re, unittest, os +import common from autotest.client.shared.test_utils import mock -import qemu_devices -import re -import unittest +import qemu_devices, data_dir +UNITTEST_DATA_DIR = os.path.join(data_dir.get_root_dir(), "virttest", "unittest_data") # Dummy variables # qemu-1.5.0 human monitor help output -QEMU_HMP = open("unittest_data/qemu-1.5.0__hmp_help").read() +QEMU_HMP = open(os.path.join(UNITTEST_DATA_DIR, "qemu-1.5.0__hmp_help")).read() # qemu-1.5.0 QMP monitor commands output -QEMU_QMP = open("unittest_data/qemu-1.5.0__qmp_help").read() +QEMU_QMP = open(os.path.join(UNITTEST_DATA_DIR, "qemu-1.5.0__qmp_help")).read() # qemu-1.5.0 -help -QEMU_HELP = open("unittest_data/qemu-1.5.0__help").read() +QEMU_HELP = open(os.path.join(UNITTEST_DATA_DIR, "qemu-1.5.0__help")).read() # qemu-1.5.0 -devices ? -QEMU_DEVICES = open("unittest_data/qemu-1.5.0__devices_help").read() +QEMU_DEVICES = open(os.path.join(UNITTEST_DATA_DIR, "qemu-1.5.0__devices_help")).read() # qemu-1.5.0 -M ? -QEMU_MACHINE = open("unittest_data/qemu-1.5.0__machine_help").read() +QEMU_MACHINE = open(os.path.join(UNITTEST_DATA_DIR, "qemu-1.5.0__machine_help")).read() class Devices(unittest.TestCase): From 39f1942584976f9312946d6bdee548dc10589ac6 Mon Sep 17 00:00:00 2001 From: yangdongsheng Date: Mon, 8 Jul 2013 17:41:22 +0800 Subject: [PATCH 062/254] virttest.virsh: Add nodedev functions. Signed-off-by: yangdongsheng --- virttest/virsh.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/virttest/virsh.py b/virttest/virsh.py index 04d8b2a5a..07e981ffc 100644 --- a/virttest/virsh.py +++ b/virttest/virsh.py @@ -2119,3 +2119,48 @@ def domif_getlink(name, interface, options=None, **dargs): cmd += " %s" % options return command(cmd, **dargs) + +def nodedev_list(options="", **dargs): + """ + List the node devices. + + @return: CmdResult object. + """ + cmd = "nodedev-list %s" % (options) + CmdResult = command(cmd, **dargs) + + return CmdResult + + +def nodedev_detach(name, options="", **dargs): + """ + Detach node device from host. + + @return: cmdresult object. + """ + cmd = ("nodedev-detach --device %s %s" % (name, options)) + CmdResult = command(cmd, **dargs) + + return CmdResult + + +def nodedev_dettach(name, options="", **dargs): + """ + Detach node device from host. + + @return: nodedev_detach(name). + """ + return nodedev_detach(name, options, **datgs) + + +def nodedev_reattach(name, options="", **dargs): + """ + If node device is detached, this action will + reattach it to its device driver. + + @return: cmdresult object. + """ + cmd = ("nodedev-reattach --device %s %s" % (name, options)) + CmdResult = command(cmd, **dargs) + + return CmdResult From 42383175e4ad6d55b53dbb0c6701d7983942c8a4 Mon Sep 17 00:00:00 2001 From: yangdongsheng Date: Mon, 8 Jul 2013 17:41:57 +0800 Subject: [PATCH 063/254] Add test for virsh nodedev-detach and nodedev-reatach. Signed-off-by: yangdongsheng --- .../nodedev/virsh_nodedev_detach_reattach.cfg | 23 +++++ .../nodedev/virsh_nodedev_detach_reattach.py | 87 +++++++++++++++++++ virttest/libvirt_xml/nodedev_xml.py | 12 +-- 3 files changed, 116 insertions(+), 6 deletions(-) create mode 100644 libvirt/tests/cfg/virsh_cmd/nodedev/virsh_nodedev_detach_reattach.cfg create mode 100644 libvirt/tests/src/virsh_cmd/nodedev/virsh_nodedev_detach_reattach.py diff --git a/libvirt/tests/cfg/virsh_cmd/nodedev/virsh_nodedev_detach_reattach.cfg b/libvirt/tests/cfg/virsh_cmd/nodedev/virsh_nodedev_detach_reattach.cfg new file mode 100644 index 000000000..459675013 --- /dev/null +++ b/libvirt/tests/cfg/virsh_cmd/nodedev/virsh_nodedev_detach_reattach.cfg @@ -0,0 +1,23 @@ +- virsh_nodedev_detach_reattach: + virt_test_type = libvirt + type = virsh_nodedev_detach_reattach + start_vm = "no" + # Name of pci device witch is detachable in host. + # eg. pci_0000_00_1f_5 + nodedev_device_name = 'ENTER.YOUR.PCI.DEVICE.TO.DETACH' + variants: + - positive: + status_error = "no" + variants: + - normal_test: + - negative: + status_error = "yes" + variants: + - no_arg: + nodedev_device_name = '' + - name_unrecognized: + nodedev_device_name = 'unrecognize' + - multi_detach: + nodedev_device_name = "${nodedev_device_name} xyz" + - not_pci_device: + nodedev_device_name = 'computer' diff --git a/libvirt/tests/src/virsh_cmd/nodedev/virsh_nodedev_detach_reattach.py b/libvirt/tests/src/virsh_cmd/nodedev/virsh_nodedev_detach_reattach.py new file mode 100644 index 000000000..1a70ea836 --- /dev/null +++ b/libvirt/tests/src/virsh_cmd/nodedev/virsh_nodedev_detach_reattach.py @@ -0,0 +1,87 @@ +import os, logging +from autotest.client.shared import error +from virttest import virsh +from virttest.libvirt_xml import nodedev_xml + + +def driver_readlink(device_name): + """ + readlink the driver of device. + """ + nodedevxml = nodedev_xml.NodedevXML.new_from_dumpxml(device_name) + driver_path = ('%s/driver') % (nodedevxml.get_sysfs_path()) + try: + driver = os.readlink(driver_path) + except (OSError, UnicodeError): + return None + return driver + +def do_nodedev_detach_reattach(device_name): + """ + do the detach and reattach. + + (1).do detach. + (2).check the result of detach. + (3).do reattach. + (4).check the result of reattach + """ + #do the detach + logging.debug('Node device name is %s.' % device_name) + CmdResult = virsh.nodedev_detach(device_name) + #check the exit_status. + if CmdResult.exit_status: + raise error.TestFail("Failed to detach %s.\n" + "Detail: %s." + % (device_name, CmdResult.stderr)) + #check the driver. + driver = driver_readlink(device_name) + logging.debug('Driver after detach is %s.' % driver) + if (driver is None) or (not driver.endswith('pci-stub')): + raise error.TestFail("Driver for %s is not pci-stub " + "after nodedev-detach" % (device_name)) + else: + pass + logging.debug('Nodedev-detach %s successed.' % device_name) + #do the reattach. + CmdResult = virsh.nodedev_reattach(device_name) + #check the exit_status. + if CmdResult.exit_status: + raise error.TestFail("Failed to reattach %s.\n" + "Detail: %s." + % (device_name, CmdResult.stderr)) + #check the driver. + driver = driver_readlink(device_name) + if (driver is None) or (not driver.endswith('pci-stub')): + pass + else: + raise error.TestFail("Driver for %s is not be reset after " + "nodedev-reattach" % (device_name)) + logging.debug('Nodedev-reattach %s successed.' % device_name) + +def run_virsh_nodedev_detach_reattach(test, params, env): + """ + Test virsh nodedev-detach and virsh nodedev-reattach + + (1).Init variables for test. + (2).Check variables. + (3).do nodedev_detach_reattach. + """ + #Init variables + device_name = params.get('nodedev_device_name', 'ENTER.YOUR.PCI.DEVICE') + status_error = ('yes' == params.get('status_error', 'no')) + #check variables. + if device_name.count('ENTER'): + raise error.TestNAError('Param device_name is not configured.') + #do nodedev_detach_reattach + try: + do_nodedev_detach_reattach(device_name) + except error.TestFail, e: + #Do nodedev detach and reattach failed. + if status_error: + return + else: + raise error.TestFail("Test failed in positive case." + "error: %s" % e) + #Do nodedev detach and reattach success. + if status_error: + raise error.TestFail('Test successed in negative case.') diff --git a/virttest/libvirt_xml/nodedev_xml.py b/virttest/libvirt_xml/nodedev_xml.py index 0278cb8c1..913901860 100644 --- a/virttest/libvirt_xml/nodedev_xml.py +++ b/virttest/libvirt_xml/nodedev_xml.py @@ -100,17 +100,17 @@ class for capability whose type is pci. def __init__(self, virsh_instance=base.virsh): accessors.XMLElementInt('domain', self, parent_xpath='/', - tag_name='domain', radix=16) + tag_name='domain') accessors.XMLElementInt('bus', self, parent_xpath='/', - tag_name='bus', radix=16) + tag_name='bus') accessors.XMLElementInt('slot', self, parent_xpath='/', - tag_name='slot', radix=16) + tag_name='slot') accessors.XMLElementInt('function', self, parent_xpath='/', - tag_name='function', radix=16) + tag_name='function') accessors.XMLAttribute('product_id', self, parent_xpath='/', - tag_name='product', attribute='id') + tag_name='product', attribute='id') accessors.XMLAttribute('vendor_id', self, parent_xpath='/', - tag_name='vendor', attribute='id') + tag_name='vendor', attribute='id') super(PCIXML, self).__init__(virsh_instance=virsh_instance) self.xml = ( ' ') From fc65afacb5f47c9a0bfff972bc3060070cbf2f5b Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Mon, 8 Jul 2013 00:08:27 -0300 Subject: [PATCH 064/254] Fedora 18: remove sg3_utils package from kickstart file As it's not present in the DVD image. Signed-off-by: Cleber Rosa --- shared/unattended/Fedora-18.ks | 1 - 1 file changed, 1 deletion(-) diff --git a/shared/unattended/Fedora-18.ks b/shared/unattended/Fedora-18.ks index c2729e47c..093f278b6 100644 --- a/shared/unattended/Fedora-18.ks +++ b/shared/unattended/Fedora-18.ks @@ -23,7 +23,6 @@ autopart @development-libs @development-tools dmidecode -sg3_utils %end %post From 54f95029266b7c43016f19206b49eeff9624c5c7 Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Thu, 4 Jul 2013 13:00:53 -0300 Subject: [PATCH 065/254] Guest support: add Fedora 19 asset file Pointing to the latest and greatest, newly released Fedora. Signed-off-by: Cleber Rosa --- shared/downloads/fedora-19-x86_64.ini | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 shared/downloads/fedora-19-x86_64.ini diff --git a/shared/downloads/fedora-19-x86_64.ini b/shared/downloads/fedora-19-x86_64.ini new file mode 100644 index 000000000..21ca3576e --- /dev/null +++ b/shared/downloads/fedora-19-x86_64.ini @@ -0,0 +1,4 @@ +[fedora-19-x86_64] +title = Fedora 19 x86_64 DVD +url = http://download.fedoraproject.org/pub/fedora/linux/releases/19/Fedora/x86_64/iso/Fedora-19-x86_64-DVD.iso +destination = isos/linux/Fedora-19-x86_64-DVD.iso From 2e426321bbb6c6fa85aacf6f75c58a6dfce8c9aa Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Thu, 4 Jul 2013 13:03:58 -0300 Subject: [PATCH 066/254] Guest support: add Fedora 19 kickstart file It is basically a copy of the Fedora 18 file, with the only exception the development-libs package group does not exist on Fedora 19. Signed-off-by: Cleber Rosa --- shared/unattended/Fedora-19.ks | 38 ++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 shared/unattended/Fedora-19.ks diff --git a/shared/unattended/Fedora-19.ks b/shared/unattended/Fedora-19.ks new file mode 100644 index 000000000..56f00e733 --- /dev/null +++ b/shared/unattended/Fedora-19.ks @@ -0,0 +1,38 @@ +install +KVM_TEST_MEDIUM +text +reboot +lang en_US +keyboard us +network --bootproto dhcp --hostname atest-guest +rootpw 123456 +firewall --enabled --ssh +selinux --enforcing +timezone --utc America/New_York +firstboot --disable +bootloader --location=mbr --append="console=tty0 console=ttyS0,115200" +zerombr +poweroff +KVM_TEST_LOGGING + +clearpart --all --initlabel +autopart + +%packages +@standard +@development-tools +dmidecode +%end + +%post +echo "OS install is completed" > /dev/ttyS0 +grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel) +dhclient +chkconfig sshd on +iptables -F +systemctl mask tmp.mount +echo 0 > /selinux/enforce +sed -i "/^HWADDR/d" /etc/sysconfig/network-scripts/ifcfg-eth0 +echo 'Post set up finished' > /dev/ttyS0 +echo Post set up finished > /dev/hvc0 +%end From bbd27f2dd42f7558439d64af0b089f39499e2317 Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Sun, 7 Jul 2013 21:34:26 -0300 Subject: [PATCH 067/254] Guest support: add Fedora 19 x86_64, i386 and ppc64 configuration This was tested with guest installs on x86_64 and i386. Test on real ppc64 hardware still pending. Signed-off-by: Cleber Rosa --- shared/cfg/guest-os/Linux/Fedora/19.i386.cfg | 17 ++++++++++++++++ shared/cfg/guest-os/Linux/Fedora/19.ppc64.cfg | 20 +++++++++++++++++++ .../cfg/guest-os/Linux/Fedora/19.x86_64.cfg | 17 ++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 shared/cfg/guest-os/Linux/Fedora/19.i386.cfg create mode 100644 shared/cfg/guest-os/Linux/Fedora/19.ppc64.cfg create mode 100644 shared/cfg/guest-os/Linux/Fedora/19.x86_64.cfg diff --git a/shared/cfg/guest-os/Linux/Fedora/19.i386.cfg b/shared/cfg/guest-os/Linux/Fedora/19.i386.cfg new file mode 100644 index 000000000..7edf3b024 --- /dev/null +++ b/shared/cfg/guest-os/Linux/Fedora/19.i386.cfg @@ -0,0 +1,17 @@ +- 19.i386: + image_name = images/f19-32 + vm_arch_name = i386 + no unattended_install..floppy_ks + unattended_install: + kernel_params = "repo=cdrom:/dev/sr0 ks=cdrom:/dev/sr1 nicdelay=60 console=ttyS0,115200 console=tty0" + unattended_file = unattended/Fedora-19.ks + cdrom_unattended = images/f19-32/ks.iso + kernel = images/f19-32/vmlinuz + initrd = images/f19-32/initrd.img + syslog_server_proto = tcp + unattended_install.cdrom: + cdrom_cd1 = isos/linux/Fedora-19-i386-DVD.iso + md5sum_cd1 = d3b02fda3010220a26d7fa41c929509c + md5sum_1m_cd1 = 31fcaf802010041f06928fa51fd3e452 + unattended_install.url: + url = http://dl.fedoraproject.org/pub/fedora/linux/releases/19/Fedora/i386/os diff --git a/shared/cfg/guest-os/Linux/Fedora/19.ppc64.cfg b/shared/cfg/guest-os/Linux/Fedora/19.ppc64.cfg new file mode 100644 index 000000000..ef938eead --- /dev/null +++ b/shared/cfg/guest-os/Linux/Fedora/19.ppc64.cfg @@ -0,0 +1,20 @@ +- 19.ppc64: + image_name = images/f19-ppc64 + only pseries + no unattended_install..floppy_ks + mem_chk_cmd = numactl --hardware | awk -F: '/size/ {print $2}' + netdev_peer_re = "(.*?): .*?\\\s(.*?):" + unattended_install: + kernel_params = "root=live:CDLABEL=Fedora-19-ppc64 ks=cdrom:/ks.cfg console=hvc0 serial rd_NO_PLYMOUTH" + unattended_file = unattended/Fedora-19.ks + cdrom_unattended = images/f19-ppc64/ks.iso + kernel = images/f19-ppc64/vmlinuz + initrd = images/f19-ppc64/initrd.img + syslog_server_proto = tcp + unattended_install.cdrom: + boot_path = ppc/ppc64 + cdrom_cd1 = isos/linux/Fedora-19-ppc64-DVD.iso + md5sum_cd1 = 26b6e0068a2c76742c0f097a0c9e1eb9 + md5sum_1m_cd1 = 10043a86d6e8929f80cad16c5ff5eccb + unattended_install.url: + url = http://dl.fedoraproject.org/pub/fedora-secondary/releases/19/Everything/ppc64/os diff --git a/shared/cfg/guest-os/Linux/Fedora/19.x86_64.cfg b/shared/cfg/guest-os/Linux/Fedora/19.x86_64.cfg new file mode 100644 index 000000000..a9016491b --- /dev/null +++ b/shared/cfg/guest-os/Linux/Fedora/19.x86_64.cfg @@ -0,0 +1,17 @@ +- 19.x86_64: + image_name = images/f19-64 + vm_arch_name = x86_64 + no unattended_install..floppy_ks + unattended_install: + kernel_params = "repo=cdrom:/dev/sr0 ks=cdrom:/dev/sr1 nicdelay=60 console=ttyS0,115200 console=tty0" + unattended_file = unattended/Fedora-19.ks + cdrom_unattended = images/f19-64/ks.iso + kernel = images/f19-64/vmlinuz + initrd = images/f19-64/initrd.img + syslog_server_proto = tcp + unattended_install.cdrom: + cdrom_cd1 = isos/linux/Fedora-19-x86_64-DVD.iso + md5sum_cd1 = 638d69c23621d5befc714bcd66b0611e + md5sum_1m_cd1 = 21204a7d8e018064dd85ca1ecbc5f1c4 + unattended_install.url: + url = http://dl.fedoraproject.org/pub/fedora/linux/releases/19/Fedora/x86_64/os From c4e6dca5eef6a430aa01bbccca07d44b9b559f18 Mon Sep 17 00:00:00 2001 From: Feng Yang Date: Mon, 8 Jul 2013 15:46:01 +0800 Subject: [PATCH 068/254] qemu.qemu_vm: spice related bug fix This patch fix several spice related script issue. 1. 19:20:54 ERROR| Original Traceback (most recent call last): File "/usr/code/autotest/client/tests/virt/virttest/qemu_vm.py", line 2240, in create self.devices = self.make_create_command() File "/usr/code/autotest/client/tests/virt/virttest/qemu_vm.py", line 1916, in make_create_command cmd += add_spice() File "/usr/code/autotest/client/tests/virt/virttest/qemu_vm.py", line 1034, in add_spice if (not os.path.exists(prefix) and File "/usr/lib64/python2.6/genericpath.py", line 18, in exists st = os.stat(path) TypeError: coercing to Unicode: need string or buffer, NoneType found 2. Traceback (most recent call last): File "/root/ypu/autotest_upstream_master/client/shared/test.py", line 426, in _exec _call_test_function(self.execute, *p_args, **p_dargs) File "/root/ypu/autotest_upstream_master/client/shared/test.py", line 853, in _call_test_function raise error.UnhandledTestFail(e) UnhandledTestFail: Unhandled KeyError: 'spice_port' [context: migrating 'virt-tests-vm1'] Traceback (most recent call last): File "/root/ypu/autotest_upstream_master/client/shared/test.py", line 846, in _call_test_function return func(*args, **dargs) File "/root/ypu/autotest_upstream_master/client/shared/test.py", line 299, in execute postprocess_profiled_run, args, dargs) File "/root/ypu/autotest_upstream_master/client/shared/test.py", line 216, in _call_run_once *args, **dargs) File "/root/ypu/autotest_upstream_master/client/shared/test.py", line 322, in run_once_profiling self.run_once(*args, **dargs) File "/root/ypu/autotest_upstream_master/client/tests/virt/virt.py", line 133, in run_once run_func(self, params, env) File "/root/ypu/autotest_upstream_master/client/tests/virt/qemu/tests/timedrift_with_migration.py", line 59, in run_timedrift_with_migration vm.migrate() File "/root/ypu/autotest_upstream_master/client/shared/error.py", line 138, in new_fn return fn(*args, **kwargs) File "/root/ypu/autotest_upstream_master/client/tests/virt/virttest/qemu_vm.py", line 3149, in migrate dest_port = clone.spice_options['spice_port'] KeyError: 'spice_port' 3. simple the way to send spice related human/qmp monitor in vm.migrate(). Signed-off-by: Feng Yang --- virttest/qemu_vm.py | 73 ++++++++++++++++----------------------------- 1 file changed, 26 insertions(+), 47 deletions(-) diff --git a/virttest/qemu_vm.py b/virttest/qemu_vm.py index 2cc12b574..7eaae5fe6 100644 --- a/virttest/qemu_vm.py +++ b/virttest/qemu_vm.py @@ -1031,7 +1031,7 @@ def set_value(opt_string, key, fallback=None): set_value("tls-port=%s", "spice_tls_port") prefix = optget("spice_x509_prefix") - if (not os.path.exists(prefix) and + if ((prefix is None or not os.path.exists(prefix)) and (optget("spice_gen_x509") == "yes")): # Generate spice_x509_* is not always necessary, # Regenerate them will make your existing VM @@ -3173,11 +3173,13 @@ def migrate(self, timeout=virt_vm.BaseVM.MIGRATE_TIMEOUT, protocol="tcp", if (self.params["display"] == "spice" and not (protocol == "exec" and "gzip" in migration_exec_cmd_src)): host_ip = utils_net.get_host_ip_address(self.params) - dest_port = clone.spice_options['spice_port'] - if self.params["spice_ssl"] == "yes": - dest_tls_port = clone.spice_options["spice_tls_port"] - cert_subj = clone.spice_options["spice_x509_server_subj"] - cert_subj = "\"%s\"" % cert_subj.replace('/', ',')[1:] + dest_port = clone.spice_options.get('spice_port', '') + if self.params.get("spice_ssl") == "yes": + dest_tls_port = clone.spice_options.get("spice_tls_port", + "") + cert_s = clone.spice_options.get("spice_x509_server_subj", + "") + cert_subj = "\"%s\"" % cert_s.replace('/', ',')[1:] else: dest_tls_port = "" cert_subj = "" @@ -3186,47 +3188,24 @@ def migrate(self, timeout=virt_vm.BaseVM.MIGRATE_TIMEOUT, protocol="tcp", "spice_migrate_info", "client_migrate_info"] - if self.monitor.protocol == "human": - out = self.monitor.cmd("help", debug=False) - for command in commands: - if "\n%s" % command in out: - # spice_migrate_info requires host_ip, dest_port - if command in commands[:2]: - command = "%s %s %s %s %s" % (command, host_ip, - dest_port, dest_tls_port, - cert_subj) - # client_migrate_info also requires protocol - else: - command = "%s %s %s %s %s %s" % (command, - self.params['display'], - host_ip, dest_port, - dest_tls_port, cert_subj) - break - self.monitor.cmd(command) - - elif self.monitor.protocol == "qmp": - out = self.monitor.cmd_obj({"execute": "query-commands"}) - for command in commands: - if {'name': command} in out['return']: - # spice_migrate_info requires host_ip, dest_port - if command in commands[:2]: - command_dict = {"execute": command, - "arguments": - {"hostname": host_ip, - "port": dest_port, - "tls-port": dest_tls_port, - "cert-subject": cert_subj}} - # client_migrate_info also requires protocol - else: - command_dict = {"execute": command, - "arguments": - {"protocol": self.params['display'], - "hostname": host_ip, - "port": dest_port, - "tls-port": dest_tls_port, - "cert-subject": cert_subj}} - break - self.monitor.cmd_obj(command_dict) + for command in commands: + try: + self.monitor.verify_supported_cmd(command) + except qemu_monitor.MonitorNotSupportedCmdError: + continue + # spice_migrate_info requires host_ip, dest_port + # client_migrate_info also requires protocol + cmdline = "%s hostname=%s" % (command, host_ip) + if command == "client_migrate_info": + cmdline += ",protocol=%s" % self.params['display'] + if dest_port: + cmdline += ",port=%s" % dest_port + if dest_tls_port: + cmdline += ",tls-port=%s" % dest_tls_port + if cert_subj: + cmdline += ",cert-subject=%s" % cert_subj + break + self.monitor.send_args_cmd(cmdline) if protocol in [ "tcp", "rdma", "x-rdma" ]: if local: From 92c93d4acdbf800e78464885d94b8e74b4de9d0d Mon Sep 17 00:00:00 2001 From: Lucas Meneghel Rodrigues Date: Mon, 8 Jul 2013 13:04:02 -0300 Subject: [PATCH 069/254] virttest.virsh: Fix typo Signed-off-by: Lucas Meneghel Rodrigues --- virttest/virsh.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virttest/virsh.py b/virttest/virsh.py index 07e981ffc..803e8fa7f 100644 --- a/virttest/virsh.py +++ b/virttest/virsh.py @@ -2150,7 +2150,7 @@ def nodedev_dettach(name, options="", **dargs): @return: nodedev_detach(name). """ - return nodedev_detach(name, options, **datgs) + return nodedev_detach(name, options, **dargs) def nodedev_reattach(name, options="", **dargs): From e939495a47e089d8ef8941e9e17187ae72e22aac Mon Sep 17 00:00:00 2001 From: Yu Mingfei Date: Tue, 16 Apr 2013 15:00:48 +0800 Subject: [PATCH 070/254] virt: enhancement of class utils_libguestfs.LibguestfsBase. Signed-off-by: Yu Mingfei --- virttest/utils_libguestfs.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/virttest/utils_libguestfs.py b/virttest/utils_libguestfs.py index 5d9af6c15..c524d0ea4 100644 --- a/virttest/utils_libguestfs.py +++ b/virttest/utils_libguestfs.py @@ -88,13 +88,15 @@ class LibguestfsBase(propcan.PropCanBase): Base class of libguestfs tools. """ - __slots__ = ('ignore_status', 'debug', 'timeout') + __slots__ = ('ignore_status', 'debug', 'timeout', 'uri', 'lgf_exec') def __init__(self, *args, **dargs): init_dict = dict(*args, **dargs) init_dict['ignore_status'] = init_dict.get('ignore_status', True) init_dict['debug'] = init_dict.get('debug', False) init_dict['timeout'] = init_dict.get('timeout', 60) + init_dict['uri'] = init_dict.get('uri', None) + init_dict['lgf_exec'] = init_dict.get('lgf_exec', '/bin/true') super(LibguestfsBase, self).__init__(init_dict) @@ -126,6 +128,20 @@ def set_debug(self, debug): logging.debug("Libguestfs debugging disabled") + def get_uri(self): + """ + Accessor method for 'uri' property that must exist + """ + # self.get() would call get_uri() recursivly + try: + return self.dict_get('uri') + except KeyError: + return None + + +##### libguestfs module functions follow ##### + + def libguest_test_tool_cmd(qemuarg=None, qemudirarg=None, timeoutarg=None, **dargs): """ From 54c443334e85f4057931748695a6e098d4faa761 Mon Sep 17 00:00:00 2001 From: Yu Mingfei Date: Tue, 25 Jun 2013 14:40:59 -0400 Subject: [PATCH 071/254] virttest.utils_libguestfs: Add guestfish about classes. Signed-off-by: Yu Mingfei --- virttest/utils_libguestfs.py | 436 ++++++++++++++++++++++++++++++++++- 1 file changed, 433 insertions(+), 3 deletions(-) diff --git a/virttest/utils_libguestfs.py b/virttest/utils_libguestfs.py index c524d0ea4..2e4594fb6 100644 --- a/virttest/utils_libguestfs.py +++ b/virttest/utils_libguestfs.py @@ -2,11 +2,11 @@ libguestfs tools test utility functions. """ -import logging +import logging, signal from autotest.client import os_dep, utils from autotest.client.shared import error -import propcan +import aexpect, propcan class LibguestfsCmdError(Exception): @@ -128,6 +128,20 @@ def set_debug(self, debug): logging.debug("Libguestfs debugging disabled") + def set_timeout(self, timeout): + """ + Accessor method for 'timeout' property, timeout should be digit + """ + if type(timeout) is int: + self.dict_set('timeout', timeout) + else: + try: + timeout = int(str(timeout)) + self.dict_set('timeout', timeout) + except ValueError: + logging.debug("Set timeout failed.") + + def get_uri(self): """ Accessor method for 'uri' property that must exist @@ -139,8 +153,424 @@ def get_uri(self): return None -##### libguestfs module functions follow ##### +# There are two ways to call guestfish: +# 1.Guestfish classies provided below(shell session) +# 2.guestfs module provided in system libguestfs package + +class Guestfish(LibguestfsBase): + """ + Execute guestfish, using a new guestfish shell each time. + """ + + __slots__ = LibguestfsBase.__slots__ + + def __init__(self, disk_img=None, ro_mode=False, + libvirt_domain=None, inspector=False, + uri=None): + """ + Initialize guestfish command with options. + + @param: disk_img: if it is not None, use option '-a disk'. + @param: ro_mode: only for disk_img. add option '--ro' if it is True. + @param: libvirt_domain: if it is not None, use option '-d domain'. + @param: inspector: guestfish mounts vm's disks automatically + @param: uri: guestfish's connect uri + """ + guestfs_exec = "guestfish" + if lgf_cmd_check(guestfs_exec) is None: + raise LibguestfsCmdError + + if uri: + guestfs_exec += " -c '%s'" % uri + + if disk_img: + guestfs_exec += " -a '%s'" % disk_img + if libvirt_domain: + guestfs_exec += " -d '%s'" % libvirt_domain + if ro_mode: + guestfs_exec += " --ro" + if inspector: + guestfs_exec += " -i" + + self.dict_set('lgf_exec', guestfs_exec) + super(Guestfish, self).__init__(self) + + + def complete_cmd(self, command): + """ + Execute built-in command in a complete guestfish command + (Not a guestfish session). + command: guestfish [--options] [commands] + """ + guestfs_exec = self.dict_get('lgf_exec') + if command: + guestfs_exec += " %s" % command + return lgf_command(guestfs_exec, **self) + else: + raise LibguestfsCmdError("No built-in command was passed.") + + +class GuestfishSession(aexpect.ShellSession): + """ + A shell session of guestfish. + """ + + # Check output against list of known error-status strings + ERROR_REGEX_LIST = ['libguestfs: error:\s*'] + + def __init__(self, guestfs_exec=None, a_id=None, prompt=r">\s*"): + """ + Initialize guestfish session server, or client if id set. + + @param: guestfs_cmd: path to guestfish executable + @param: id: ID of an already running server, if accessing a running + server, or None if starting a new one. + @param prompt: Regular expression describing the shell's prompt line. + """ + # aexpect tries to auto close session because no clients connected yet + aexpect.ShellSession.__init__(self, guestfs_exec, a_id, + prompt=prompt, auto_close=False) + + + def cmd_status_output(self, cmd, timeout=60, internal_timeout=None, + print_func=None): + """ + Send a guestfish command and return its exit status and output. + + @param cmd: guestfish command to send (must not contain newline characters) + @param timeout: The duration (in seconds) to wait for the prompt to + return + @param internal_timeout: The timeout to pass to read_nonblocking + @param print_func: A function to be used to print the data being read + (should take a string parameter) + @return: A tuple (status, output) where status is the exit status and + output is the output of cmd + @raise ShellTimeoutError: Raised if timeout expires + @raise ShellProcessTerminatedError: Raised if the shell process + terminates while waiting for output + @raise ShellStatusError: Raised if the exit status cannot be obtained + @raise ShellError: Raised if an unknown error occurs + """ + out = self.cmd_output(cmd, timeout, internal_timeout, print_func) + for line in out.splitlines(): + if self.match_patterns(line, self.ERROR_REGEX_LIST) is not None: + return 1, out + return 0, out + + + def cmd_result(self, cmd, ignore_status=False): + """Mimic utils.run()""" + exit_status, stdout = self.cmd_status_output(cmd) + stderr = '' # no way to retrieve this separately + result = utils.CmdResult(cmd, stdout, stderr, exit_status) + if not ignore_status and exit_status: + raise error.CmdError(cmd, result, + "Guestfish Command returned non-zero exit status") + return result + + +class GuestfishPersistent(Guestfish): + """ + Execute operations using persistent guestfish session. + """ + + __slots__ = Guestfish.__slots__ + ('session_id', ) + + # Help detect leftover sessions + SESSION_COUNTER = 0 + + def __init__(self, *args, **dargs): + super(GuestfishPersistent, self).__init__(*args, **dargs) + if self.get('session_id') is None: + # set_uri does not call when INITIALIZED = False + # and no session_id passed to super __init__ + self.new_session() + + # Check whether guestfish session is prepared. + guestfs_session = self.open_session() + if guestfs_session.cmd_status('is-ready', timeout=60) != 0: + logging.debug("Persistent guestfish session is not responding.") + raise aexpect.ShellStatusError(self.lgf_exec, 'is-ready') + + + def close_session(self): + """ + If a persistent session exists, close it down. + """ + try: + existing = self.open_session() + # except clause exits function + # Try to end session with inner command 'quit' + try: + existing.cmd("quit") + # It should jump to exception followed normally + except aexpect.ShellProcessTerminatedError: + self.__class__.SESSION_COUNTER -= 1 + self.dict_del('session_id') + return # guestfish session was closed normally + # Close with 'quit' did not respond + # So close with aexpect functions + if existing.is_alive(): + # try nicely first + existing.close() + if existing.is_alive(): + # Be mean, incase it's hung + existing.close(sig=signal.SIGTERM) + # Keep count: + self.__class__.SESSION_COUNTER -= 1 + self.dict_del('session_id') + except LibguestfsCmdError: + # Allow other exceptions to be raised + pass # session was closed already + + + def new_session(self): + """ + Open new session, closing any existing + """ + # Accessors may call this method, avoid recursion + guestfs_exec = self.dict_get('lgf_exec') # Must exist, can't be None + self.close_session() + # Always create new session + new_session = GuestfishSession(guestfs_exec) + # Keep count + self.__class__.SESSION_COUNTER += 1 + session_id = new_session.get_id() + self.dict_set('session_id', session_id) + + + def open_session(self): + """ + Return session with session_id in this class. + """ + try: + session_id = self.dict_get('session_id') + if session_id: + try: + return GuestfishSession(a_id=session_id) + except aexpect.ShellStatusError: + # session was already closed + self.dict_del('session_id') + raise LibguestfsCmdError( + "Open session '%s' failed." % session_id) + except KeyError: + raise LibguestfsCmdError("No session id.") + + + # Inner command for guestfish should be executed in a guestfish session + def inner_cmd(self, command): + """ + Execute inner command of guestfish in a pesistent session. + + @param command: inner command to be executed. + """ + session = self.open_session() + # Allow to raise error by default. + ignore_status = self.dict_get('ignore_status') + return session.cmd_result(command, ignore_status=ignore_status) + + + def add_drive(self, filename): + """ + add-drive - add an image to examine or modify + + This function is the equivalent of calling "add_drive_opts" with no + optional parameters, so the disk is added writable, with the format + being detected automatically. + """ + return self.inner_cmd("add-drive %s" % filename) + + + def add_drive_opts(self, filename, readonly=False, format=None, + iface=None, name=None): + """ + add-drive-opts - add an image to examine or modify. + + This function adds a disk image called "filename" to the handle. + "filename" may be a regular host file or a host device. + """ + cmd = "add-drive-opts %s" % filename + + if readonly: + cmd += " readonly:true" + else: + cmd += " readonly:false" + if format: + cmd += " format:%s" % format + if iface: + cmd += " iface:%s" % iface + if name: + cmd += " name:%s" % name + + return self.inner_cmd(cmd) + + + def add_drive_ro(self, filename): + """ + add-ro/add-drive-ro - add a drive in snapshot mode (read-only) + This function is the equivalent of calling "add_drive_opts" with the + optional parameter "GUESTFS_ADD_DRIVE_OPTS_READONLY" set to 1, so the + disk is added read-only, with the format being detected automatically. + """ + return self.inner_cmd("add-drive-ro %s" % filename) + + + def add_domain(self, domain, libvirturi=None, readonly=False, iface=None, + live=False, allowuuid=False, readonlydisk=None): + """ + domain/add-domain - add the disk(s) from a named libvirt domain + + This function adds the disk(s) attached to the named libvirt domain + "dom". It works by connecting to libvirt, requesting the domain and + domain XML from libvirt, parsing it for disks, and calling + "add_drive_opts" on each one. + """ + cmd = "add-domain %s" % domain + + if libvirturi: + cmd += " libvirturi:%s" % libvirturi + if readonly: + cmd += " readonly:true" + else: + cmd += " readonly:false" + if iface: + cmd += " iface:%s" % iface + if live: + cmd += " live:true" + if allowuuid: + cmd += " allowuuid:true" + if readonlydisk: + cmd += " readonlydisk:%s" % readonlydisk + + return self.inner_cmd(cmd) + + + def run(self): + """ + run/launch - launch the qemu subprocess + + Internally libguestfs is implemented by running a virtual machine + using qemu. + """ + return self.inner_cmd("launch") + + + def df(self): + """ + df - report file system disk space usage + + This command runs the "df" command to report disk space used. + """ + return self.inner_cmd("df") + + + def list_partitions(self): + """ + list-partitions - list the partitions + + List all the partitions detected on all block devices. + """ + return self.inner_cmd("list-partitions") + + + def mount(self, device, mountpoint): + """ + mount - mount a guest disk at a position in the filesystem + + Mount a guest disk at a position in the filesystem. + """ + return self.inner_cmd("mount %s %s" % (device, mountpoint)) + + + def mount_ro(self, device, mountpoint): + """ + mount-ro - mount a guest disk, read-only + + This is the same as the "mount" command, but it mounts the + filesystem with the read-only (*-o ro*) flag. + """ + return self.inner_cmd("mount-ro %s %s" % (device, mountpoint)) + + + def mount_options(self, options, device, mountpoint): + """ + mount - mount a guest disk at a position in the filesystem + + Mount a guest disk at a position in the filesystem. + """ + return self.inner_cmd("mount %s %s %s" % (options, device, mountpoint)) + + + def mounts(self): + """ + mounts - show mounted filesystems + + This returns the list of currently mounted filesystems. + """ + return self.inner_cmd("mounts") + + + def mountpoints(self): + """ + mountpoints - show mountpoints + + This call is similar to "mounts". + That call returns a list of devices. + """ + return self.inner_cmd("mountpoints") + + + def read_file(self, path): + """ + read-file - read a file + + This calls returns the contents of the file "path" as a buffer. + """ + return self.inner_cmd("read-file %s" % path) + + + def cat(self, path): + """ + cat - list the contents of a file + + Return the contents of the file named "path". + """ + return self.inner_cmd("cat %s" % path) + + + def write(self, path, content): + """ + write - create a new file + + This call creates a file called "path". The content of the file + is the string "content" (which can contain any 8 bit data). + """ + return self.inner_cmd("write %s %s" % (path, content)) + + + def write_append(self, path, content): + """ + write-append - append content to end of file + + This call appends "content" to the end of file "path". + If "path" does not exist, then a new file is created. + """ + return self.inner_cmd("write-append %s %s" % (path, content)) + + + def inspect_os(self): + """ + inspect-os - inspect disk and return list of operating systems found + + This function uses other libguestfs functions and certain heuristics to + inspect the disk(s) (usually disks belonging to a virtual machine), + looking for operating systems. + """ + return self.inner_cmd("inspect-os") + + +##### libguestfs module functions follow ##### def libguest_test_tool_cmd(qemuarg=None, qemudirarg=None, timeoutarg=None, **dargs): From 0859bdb5998ca801f02652884c408b20279f743e Mon Sep 17 00:00:00 2001 From: Yu Mingfei Date: Tue, 25 Jun 2013 14:41:43 -0400 Subject: [PATCH 072/254] libguestfs.tests: Add a sample test about guestfish. Signed-off-by: Yu Mingfei --- libguestfs/tests/cfg/guestfs_add.cfg | 25 ++++ libguestfs/tests/guestfs_add.py | 188 +++++++++++++++++++++++++++ 2 files changed, 213 insertions(+) create mode 100644 libguestfs/tests/cfg/guestfs_add.cfg create mode 100644 libguestfs/tests/guestfs_add.py diff --git a/libguestfs/tests/cfg/guestfs_add.cfg b/libguestfs/tests/cfg/guestfs_add.cfg new file mode 100644 index 000000000..a76c17934 --- /dev/null +++ b/libguestfs/tests/cfg/guestfs_add.cfg @@ -0,0 +1,25 @@ +- guestfs_add: + type = guestfs_add + start_vm = "no" + # If login to check whether write content successfully. + login_to_check_write = "yes" + variants: + - normal_test: + status_error = "no" + guestfs_add_readonly = "no" + variants: + - add_disk: + guestfs_add_ref = "disk" + - add_domain: + guestfs_add_ref = "domain" + - error_test: + status_error = "yes" + guestfs_add_readonly = "yes" + # normally write content will be failed. + login_to_check_write = "no" + variants: + # Write content to readonly disk or domain + - add_disk_ro: + guestfs_add_ref = "disk" + - add_domain_ro: + guestfs_add_ref = "domain" diff --git a/libguestfs/tests/guestfs_add.py b/libguestfs/tests/guestfs_add.py new file mode 100644 index 000000000..9728e292f --- /dev/null +++ b/libguestfs/tests/guestfs_add.py @@ -0,0 +1,188 @@ +import logging, re, commands +from autotest.client.shared import error +from virttest import utils_libguestfs as lgf +from virttest import aexpect + + +def set_guestfs_args(guestfs, ignore_status=True, debug=False, timeout=60): + """ + Maintain Guestfish class' arguments. + """ + guestfs.set_ignore_status(ignore_status) + guestfs.set_debug(debug) + guestfs.set_timeout(timeout) + + +def add_disk_or_domain(guestfs, disk_or_domain, add_ref="domain", + readonly=False): + """ + Add disk or domain to guestfish + + @param guestfs: a session of guestfish + @param disk_or_domain: a disk or a domain + @param add_ref: domain or disk + @param readonly: is added disk or domain readonly. + """ + if add_ref == "domain": + add_result = guestfs.add_domain(disk_or_domain, readonly=readonly) + elif add_ref == "disk": + add_result = guestfs.add_drive_opts(disk_or_domain, readonly=readonly) + else: + guestfs.close_session() + raise error.TestFail("Added must be a disk or a domain.") + + if add_result.exit_status: + guestfs.close_session() + raise error.TestFail("Add %s failed:%s" % (add_ref, add_result)) + logging.debug("Add %s successfully.", add_ref) + + +def launch_disk(guestfs): + # Launch added disk or domain + launch_result = guestfs.run() + if launch_result.exit_status: + guestfs.close_session() + raise error.TestFail("Launch failed:%s" % launch_result) + logging.debug("Launch successfully.") + + +def get_root(guestfs): + getroot_result = guestfs.inspect_os() + roots_list = getroot_result.stdout.splitlines() + if getroot_result.exit_status or not len(roots_list): + guestfs.close_session() + raise error.TestFail("Get root failed:%s" % getroot_result) + return roots_list[0] + + +def mount_filesystem(guestfs, filesystem, mountpoint): + mount_result = guestfs.mount(filesystem, mountpoint) + if mount_result.exit_status: + guestfs.close_session() + raise error.TestFail("Mount filesystem failed:%s" % mount_result) + logging.debug("Mount filesystem successfully.") + + +def run_guestfs_add(test, params, env): + """ + Test of built-in 'add-xxx' commands in guestfish. + + 1) Get parameters for test + 2) Set options for commands + 3) Run key commands: + a.add disk or domain with readonly or not + b.launch + c.mount root device + 4) Write a file to help result checking + 5) Check result + """ + + vm_name = params.get("main_vm") + vm = env.get_vm(vm_name) + + # Get parameters + add_ref = params.get("guestfs_add_ref", "domain") + add_readonly = "yes" == params.get("guestfs_add_readonly", "no") + status_error = "yes" == params.get("status_error", "no") + login_to_check = "yes" == params.get("login_to_check_write", "no") + # Any failed info will be recorded in this dict + # Result check will rely on it. + fail_flag = 0 + fail_info = {} + + if vm.is_alive(): + # Execute guestfish when vm is alive is dangerous. + # Do not support this test right now. + vm.destroy() + + if add_ref == "domain": + disk_or_domain = vm_name + elif add_ref == "disk": + # Get system disk path of tested domain + disks = vm.get_disk_devices() + if len(disks): + disk = disks.values()[0] + disk_or_domain = disk['source'] + else: + # No need to test since getting vm's disk failed. + raise error.TestFail("Can not get disk of %s" % vm_name) + + guestfs = lgf.GuestfishPersistent() + set_guestfs_args(guestfs) + + # Add tested disk or domain + add_disk_or_domain(guestfs, disk_or_domain, add_ref, add_readonly) + + # Launch added disk or domain + launch_disk(guestfs) + + # Mount root filesystem + root = get_root(guestfs) + mount_filesystem(guestfs, root, '/') + + # Write content to file + status, content = commands.getstatusoutput("uuidgen") + write_result = guestfs.write("/guestfs_temp", content) + if write_result.exit_status: + fail_flag = 1 + fail_info['write_content'] = ("Write content to file failed:" + "%s" % write_result) + else: + logging.debug("Write content to file successfully.") + fail_info['write_content'] = "Write content to file successfully." + + # Check writed file in a new guestfish session + guestfs.new_session() + set_guestfs_args(guestfs) + add_disk_or_domain(guestfs, disk_or_domain, add_ref, add_readonly) + launch_disk(guestfs) + mount_filesystem(guestfs, root, '/') + cat_result = guestfs.cat("/guestfs_temp") + if cat_result.exit_status: + fail_flag = 1 + fail_info['cat_writed'] = ("Cat writed file failed:" + "%s" % cat_result) + else: + guestfs_writed_text = cat_result.stdout + if not re.search(content, guestfs_writed_text): + fail_flag = 1 + fail_info['cat_writed'] = ("Catted text is not match with writed:" + "%s" % cat_result) + logging.debug("Catted text is not match with writed") + else: + logging.debug("Cat content of file successfully.") + fail_info['cat_writed'] = "Cat content of file successfully." + + # Start vm and login to check writed file. + guestfs.close_session() + if login_to_check: + try: + vm.start() + session = vm.wait_for_login() + session.cmd("mount %s /mnt" % root) + try: + login_wrote_text = session.cmd_output("cat /mnt/guestfs_temp", + timeout=5) + except aexpect.ShellTimeoutError, detail: + # writen content with guestfs.write won't contain line break + # Is is a bug of guestfish.write? + login_wrote_text = str(detail) + if not re.search(content, login_wrote_text): + fail_flag = 1 + fail_info['login_to_check'] = ("Login to check failed:" + "%s" % login_wrote_text) + else: + logging.debug("Login to check successfully.") + fail_info['login_to_check'] = "Login to check successfully." + except aexpect.ShellError, detail: + fail_flag = 1 + fail_info['login_to_check'] = detail + vm.destroy() + + if status_error: + if not fail_flag: + raise error.TestFail("Expected error is successful:" + "%s" % fail_info) + else: + if fail_flag: + raise error.TestFail(fail_info) From 186503a922dab99d7282f298d5ac2a604be662e7 Mon Sep 17 00:00:00 2001 From: Yu Mingfei Date: Wed, 3 Jul 2013 13:17:28 -0400 Subject: [PATCH 073/254] virttest.utils_libguestfs: Replace dictionary args. Signed-off-by: Yu Mingfei --- virttest/utils_libguestfs.py | 51 +++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/virttest/utils_libguestfs.py b/virttest/utils_libguestfs.py index 2e4594fb6..218fb71a3 100644 --- a/virttest/utils_libguestfs.py +++ b/virttest/utils_libguestfs.py @@ -30,7 +30,7 @@ def lgf_cmd_check(cmd): @param cmd: the cmd to use a libguest tool. @return: None if the cmd is not exist, otherwise return its path. """ - libguestfs_cmds = ['libguestfs_test_tool', 'guestfish', 'guestmount', + libguestfs_cmds = ['libguestfs-test-tool', 'guestfish', 'guestmount', 'virt-alignment-scan', 'virt-cat', 'virt-copy-in', 'virt-copy-out', 'virt-df', 'virt-edit', 'virt-filesystems', 'virt-format', 'virt-inspector', @@ -50,20 +50,15 @@ def lgf_cmd_check(cmd): return None -def lgf_command(cmd, **dargs): +def lgf_command(cmd, ignore_status=True, debug=False, timeout=60): """ Interface of libguestfs tools' commands. @param cmd: Command line to execute. - @param dargs: standardized command keywords. @return: CmdResult object. @raise: LibguestfsCmdError if non-zero exit status and ignore_status=False """ - ignore_status = dargs.get('ignore_status', True) - debug = dargs.get('debug', False) - timeout = dargs.get('timeout', 60) - if debug: logging.debug("Running command %s in debug mode.", cmd) @@ -90,13 +85,14 @@ class LibguestfsBase(propcan.PropCanBase): __slots__ = ('ignore_status', 'debug', 'timeout', 'uri', 'lgf_exec') - def __init__(self, *args, **dargs): - init_dict = dict(*args, **dargs) - init_dict['ignore_status'] = init_dict.get('ignore_status', True) - init_dict['debug'] = init_dict.get('debug', False) - init_dict['timeout'] = init_dict.get('timeout', 60) - init_dict['uri'] = init_dict.get('uri', None) - init_dict['lgf_exec'] = init_dict.get('lgf_exec', '/bin/true') + def __init__(self, lgf_exec="/bin/true", ignore_status=True, + debug=False, timeout=60, uri=None): + init_dict = {} + init_dict['ignore_status'] = ignore_status + init_dict['debug'] = debug + init_dict['timeout'] = timeout + init_dict['uri'] = uri + init_dict['lgf_exec'] = lgf_exec super(LibguestfsBase, self).__init__(init_dict) @@ -192,8 +188,7 @@ def __init__(self, disk_img=None, ro_mode=False, if inspector: guestfs_exec += " -i" - self.dict_set('lgf_exec', guestfs_exec) - super(Guestfish, self).__init__(self) + super(Guestfish, self).__init__(guestfs_exec) def complete_cmd(self, command): @@ -203,9 +198,12 @@ def complete_cmd(self, command): command: guestfish [--options] [commands] """ guestfs_exec = self.dict_get('lgf_exec') + ignore_status = self.dict_get('ignore_status') + debug = self.dict_get('debug') + timeout = self.dict_get('timeout') if command: guestfs_exec += " %s" % command - return lgf_command(guestfs_exec, **self) + return lgf_command(guestfs_exec, ignore_status, debug, timeout) else: raise LibguestfsCmdError("No built-in command was passed.") @@ -279,8 +277,11 @@ class GuestfishPersistent(Guestfish): # Help detect leftover sessions SESSION_COUNTER = 0 - def __init__(self, *args, **dargs): - super(GuestfishPersistent, self).__init__(*args, **dargs) + def __init__(self, disk_img=None, ro_mode=False, + libvirt_domain=None, inspector=False, + uri=None): + super(GuestfishPersistent, self).__init__(disk_img, ro_mode, + libvirt_domain, inspector, uri) if self.get('session_id') is None: # set_uri does not call when INITIALIZED = False # and no session_id passed to super __init__ @@ -573,7 +574,8 @@ def inspect_os(self): ##### libguestfs module functions follow ##### def libguest_test_tool_cmd(qemuarg=None, qemudirarg=None, - timeoutarg=None, **dargs): + timeoutarg=None, ignore_status=True, + debug=False, timeout=60): """ Execute libguest-test-tool command. @@ -583,7 +585,7 @@ def libguest_test_tool_cmd(qemuarg=None, qemudirarg=None, @return: a CmdResult object @raise: raise LibguestfsCmdError """ - cmd = "libguest-test-tool" + cmd = "libguestfs-test-tool" if qemuarg is not None: cmd += " --qemu '%s'" % qemuarg if qemudirarg is not None: @@ -592,11 +594,12 @@ def libguest_test_tool_cmd(qemuarg=None, qemudirarg=None, cmd += " --timeout %s" % timeoutarg # Allow to raise LibguestfsCmdError if ignore_status is False. - return lgf_command(cmd, **dargs) + return lgf_command(cmd, ignore_status, debug, timeout) def virt_edit_cmd(disk_or_domain, file_path, options=None, - extra=None, expr=None, **dargs): + extra=None, expr=None, ignore_status=True, + debug=False, timeout=60): """ Execute virt-edit command to check whether it is ok. @@ -618,4 +621,4 @@ def virt_edit_cmd(disk_or_domain, file_path, options=None, if expr is not None: cmd += " -e '%s'" % expr - return lgf_command(cmd, **dargs) + return lgf_command(cmd, ignore_status, debug, timeout) From 7a94ebf0326ad102d93f9c9019dbf52cc881bf98 Mon Sep 17 00:00:00 2001 From: Yu Mingfei Date: Wed, 3 Jul 2013 17:32:45 +0800 Subject: [PATCH 074/254] virttest: Add unittest for utils_libguestfs module. Signed-off-by: Yu Mingfei --- virttest/utils_libguestfs_unittest.py | 77 +++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100755 virttest/utils_libguestfs_unittest.py diff --git a/virttest/utils_libguestfs_unittest.py b/virttest/utils_libguestfs_unittest.py new file mode 100755 index 000000000..ca054d72e --- /dev/null +++ b/virttest/utils_libguestfs_unittest.py @@ -0,0 +1,77 @@ +#!/usr/bin/python +import unittest, logging + +try: + import autotest.common as common +except ImportError: + import common + +from autotest.client import os_dep +import utils_libguestfs as lgf + + +class LibguestfsTest(unittest.TestCase): + def test_lgf_cmd_check(self): + cmds = ['virt-ls', 'virt-cat'] + for cmd in cmds: + try: + os_dep.command(cmd) + self.assertTrue(lgf.lgf_cmd_check(cmd)) + except ValueError: + logging.warning("Command %s not installed, skipping " + "unittest...", cmd) + + def test_lgf_cmd_check_raises(self): + cmds = ['virt-test-fail', ''] + for cmd in cmds: + self.assertRaises(lgf.LibguestfsCmdError, + lgf.lgf_cmd_check, cmd) + + def test_lgf_cmd(self): + cmd = "libguestfs-test-tool" + try: + os_dep.command(cmd) + self.assertEqual(lgf.lgf_command(cmd).exit_status, 0) + except ValueError: + logging.warning("Command %s not installed, skipping unittest...", + cmd) + + +class SlotsCheckTest(unittest.TestCase): + def test_LibguestfsBase_default_slots(self): + """Default slots' value check""" + lfb = lgf.LibguestfsBase() + self.assertEqual(lfb.ignore_status, True) + self.assertEqual(lfb.debug, False) + self.assertEqual(lfb.timeout, 60) + self.assertEqual(lfb.uri, None) + self.assertEqual(lfb.lgf_exec, "/bin/true") + + def test_LibguestfsBase_update_slots(self): + """Update slots""" + lfb = lgf.LibguestfsBase() + lfb.set_ignore_status(False) + self.assertEqual(lfb.ignore_status, False) + lfb.set_debug(True) + self.assertEqual(lfb.debug, True) + lfb.set_timeout(240) + self.assertEqual(lfb.timeout, 240) + + def test_Guestfish_slots(self): + """Test Guestfish slots""" + try: + gf = lgf.Guestfish() + self.assertEqual(gf.lgf_exec, "guestfish") + gf = lgf.Guestfish(disk_img="test.img", ro_mode=True, inspector=True) + self.assertEqual(gf.lgf_exec, "guestfish -a 'test.img' --ro -i") + gf = lgf.Guestfish(libvirt_domain="test", inspector=True, + uri="qemu+ssh://root@EXAMPLE/system") + gf_cmd = "guestfish -c 'qemu+ssh://root@EXAMPLE/system' -d 'test' -i" + self.assertEqual(gf.lgf_exec, gf_cmd) + except lgf.LibguestfsCmdError: + logging.warning("Command guestfish not present, skipping " + "unittest...") + + +if __name__ == "__main__": + unittest.main() From e7733525cd2f49c111aa94540c1d7fb5dc8213fa Mon Sep 17 00:00:00 2001 From: Lucas Meneghel Rodrigues Date: Mon, 8 Jul 2013 17:23:17 -0300 Subject: [PATCH 075/254] virttest.utils_libguestfs: Fix GuestfishSession constructor Signed-off-by: Lucas Meneghel Rodrigues --- virttest/utils_libguestfs.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/virttest/utils_libguestfs.py b/virttest/utils_libguestfs.py index 218fb71a3..4d6d54fed 100644 --- a/virttest/utils_libguestfs.py +++ b/virttest/utils_libguestfs.py @@ -226,8 +226,9 @@ def __init__(self, guestfs_exec=None, a_id=None, prompt=r">\s*"): @param prompt: Regular expression describing the shell's prompt line. """ # aexpect tries to auto close session because no clients connected yet - aexpect.ShellSession.__init__(self, guestfs_exec, a_id, - prompt=prompt, auto_close=False) + super(GuestfishSession, self).__init__(guestfs_exec, a_id, + prompt=prompt, + auto_close=False) def cmd_status_output(self, cmd, timeout=60, internal_timeout=None, From be9107bfadf02ca1e1d78c9d925307a199e651bd Mon Sep 17 00:00:00 2001 From: Yiqiao Pu Date: Sat, 8 Jun 2013 15:09:00 +0800 Subject: [PATCH 076/254] virttest.env_process: Update iscsi setup related code As iscsi setup need update the params to get the right image_name move it from image pre/post function to preprocess/postprocess. And update the params for the whole tests. Signed-off-by: Yiqiao Pu --- virt.py | 2 +- virttest/env_process.py | 93 +++++++++++++++++++------------------ virttest/standalone_test.py | 2 +- 3 files changed, 51 insertions(+), 46 deletions(-) diff --git a/virt.py b/virt.py index 8316d8e82..c7b72e140 100644 --- a/virt.py +++ b/virt.py @@ -121,7 +121,7 @@ def run_once(self, params): f.close() # Preprocess try: - env_process.preprocess(self, params, env) + params = env_process.preprocess(self, params, env) finally: env.save() # Run the test function diff --git a/virttest/env_process.py b/virttest/env_process.py index 732953acf..1b047b76c 100644 --- a/virttest/env_process.py +++ b/virttest/env_process.py @@ -28,27 +28,23 @@ def preprocess_image(test, params, image_name): """ base_dir = params.get("images_base_dir", data_dir.get_data_dir()) - if params.get("storage_type") == "iscsi": - iscsidev = qemu_storage.Iscsidev(params, base_dir, image_name) - params["image_name"] = iscsidev.setup() - else: - image_filename = storage.get_image_filename(params, - base_dir) + image_filename = storage.get_image_filename(params, + base_dir) - create_image = False + create_image = False - if params.get("force_create_image") == "yes": - create_image = True - elif (params.get("create_image") == "yes" and not - os.path.exists(image_filename)): - create_image = True + if params.get("force_create_image") == "yes": + create_image = True + elif (params.get("create_image") == "yes" and not + os.path.exists(image_filename)): + create_image = True - if params.get("backup_image_before_testing", "no") == "yes": - image = qemu_storage.QemuImg(params, base_dir, image_name) - image.backup_image(params, base_dir, "backup", True, True) - if create_image: - image = qemu_storage.QemuImg(params, base_dir, image_name) - image.create(params) + if params.get("backup_image_before_testing", "no") == "yes": + image = qemu_storage.QemuImg(params, base_dir, image_name) + image.backup_image(params, base_dir, "backup", True, True) + if create_image: + image = qemu_storage.QemuImg(params, base_dir, image_name) + image.create(params) def preprocess_vm(test, params, env, name): @@ -134,36 +130,32 @@ def postprocess_image(test, params, image_name): """ clone_master = params.get("clone_master", None) base_dir = data_dir.get_data_dir() - if params.get("storage_type") == "iscsi": - iscsidev = qemu_storage.Iscsidev(params, base_dir, image_name) - iscsidev.cleanup() - else: - image = qemu_storage.QemuImg(params, base_dir, image_name) - if params.get("check_image") == "yes": - try: - if clone_master is None: - image.check_image(params, base_dir) - elif clone_master == "yes": - if image_name in params.get("master_images_clone").split(): - image.check_image(params, base_dir) - if params.get("restore_image", "no") == "yes": - image.backup_image(params, base_dir, "restore", True) - except Exception, e: - if params.get("restore_image_on_check_error", "no") == "yes": - image.backup_image(params, base_dir, "restore", True) - if params.get("remove_image_on_check_error", "no") == "yes": - cl_images = params.get("master_images_clone", "") - if image_name in cl_images.split(): - image.remove() - raise e - if params.get("restore_image_after_testing", "no") == "yes": - image.backup_image(params, base_dir, "restore", True) - if params.get("remove_image") == "yes": + image = qemu_storage.QemuImg(params, base_dir, image_name) + if params.get("check_image") == "yes": + try: if clone_master is None: - image.remove() + image.check_image(params, base_dir) elif clone_master == "yes": if image_name in params.get("master_images_clone").split(): + image.check_image(params, base_dir) + if params.get("restore_image", "no") == "yes": + image.backup_image(params, base_dir, "restore", True) + except Exception, e: + if params.get("restore_image_on_check_error", "no") == "yes": + image.backup_image(params, base_dir, "restore", True) + if params.get("remove_image_on_check_error", "no") == "yes": + cl_images = params.get("master_images_clone", "") + if image_name in cl_images.split(): image.remove() + raise e + if params.get("restore_image_after_testing", "no") == "yes": + image.backup_image(params, base_dir, "restore", True) + if params.get("remove_image") == "yes": + if clone_master is None: + image.remove() + elif clone_master == "yes": + if image_name in params.get("master_images_clone").split(): + image.remove() def postprocess_vm(test, params, env, name): @@ -324,6 +316,12 @@ def preprocess(test, params, env): brcfg = test_setup.PrivateBridgeConfig(params_pb) brcfg.setup() + base_dir = data_dir.get_data_dir() + if params.get("storage_type") == "iscsi": + iscsidev = qemu_storage.Iscsidev(params, base_dir, "iscsi") + params["image_name"] = iscsidev.setup() + params["image_raw_device"] = "yes" + # Start tcpdump if it isn't already running if "address_cache" not in env: env["address_cache"] = {} @@ -462,6 +460,8 @@ def preprocess(test, params, env): args=(test, params, env)) _screendump_thread.start() + return params + @error.context_aware def postprocess(test, params, env): @@ -579,6 +579,11 @@ def postprocess(test, params, env): int(params.get("post_command_timeout", "600")), params.get("post_command_noncritical") == "yes") + base_dir = data_dir.get_data_dir() + if params.get("storage_type") == "iscsi": + iscsidev = qemu_storage.Iscsidev(params, base_dir, "iscsi") + iscsidev.cleanup() + setup_pb = False for nic in params.get('nics', "").split(): if params.get('netdst_%s' % nic) == 'private': diff --git a/virttest/standalone_test.py b/virttest/standalone_test.py index 9a4988a02..42172343e 100644 --- a/virttest/standalone_test.py +++ b/virttest/standalone_test.py @@ -188,7 +188,7 @@ def run_once(self): # Preprocess try: - env_process.preprocess(self, params, env) + params = env_process.preprocess(self, params, env) finally: env.save() From 57d5b31b33a86958da991e78e291629001b4d365 Mon Sep 17 00:00:00 2001 From: Yunping Zheng Date: Mon, 8 Jul 2013 21:54:04 -0300 Subject: [PATCH 077/254] virttest.env_process : add pci msi on/off support in autotest Using this patch you can enable or disable pci msi by modify the guest disk directly before test start. if you want to disable (pci=nomsi) pci msi before test, just set: pci_msi_sensitive = yes disable_pci_msi = yes in tests.cfg. Install python-libguestfs before using this patch. chang_log: V2 from V1: using python guestfs lib. V3 from v2: remove the env setting, make case more independent modify the default configure Yunping Zheng --- shared/cfg/guest-os/Linux/RHEL/5.3/i386.cfg | 1 + shared/cfg/guest-os/Linux/RHEL/5.3/x86_64.cfg | 1 + shared/cfg/guest-os/Linux/RHEL/5.4/i386.cfg | 1 + shared/cfg/guest-os/Linux/RHEL/5.4/x86_64.cfg | 1 + shared/cfg/guest-os/Linux/RHEL/5.5/i386.cfg | 1 + shared/cfg/guest-os/Linux/RHEL/5.5/x86_64.cfg | 1 + shared/cfg/guest-os/Linux/RHEL/5.6/i386.cfg | 1 + shared/cfg/guest-os/Linux/RHEL/5.6/x86_64.cfg | 1 + shared/cfg/guest-os/Linux/RHEL/5.7/i386.cfg | 1 + shared/cfg/guest-os/Linux/RHEL/5.7/x86_64.cfg | 1 + shared/cfg/guest-os/Linux/RHEL/5.8/i386.cfg | 1 + shared/cfg/guest-os/Linux/RHEL/5.8/x86_64.cfg | 1 + shared/cfg/guest-os/Linux/RHEL/5.9/i386.cfg | 1 + shared/cfg/guest-os/Linux/RHEL/5.9/x86_64.cfg | 1 + shared/cfg/guest-os/Linux/RHEL/6.0/i386.cfg | 1 + shared/cfg/guest-os/Linux/RHEL/6.0/x86_64.cfg | 1 + shared/cfg/guest-os/Linux/RHEL/6.1/i386.cfg | 1 + shared/cfg/guest-os/Linux/RHEL/6.1/x86_64.cfg | 1 + shared/cfg/guest-os/Linux/RHEL/6.2/i386.cfg | 1 + shared/cfg/guest-os/Linux/RHEL/6.2/x86_64.cfg | 1 + shared/cfg/guest-os/Linux/RHEL/6.3/i386.cfg | 1 + shared/cfg/guest-os/Linux/RHEL/6.3/x86_64.cfg | 1 + shared/cfg/guest-os/Linux/RHEL/6.4/i386.cfg | 1 + shared/cfg/guest-os/Linux/RHEL/6.4/x86_64.cfg | 1 + .../cfg/guest-os/Linux/RHEL/6.devel/i386.cfg | 1 + .../guest-os/Linux/RHEL/6.devel/x86_64.cfg | 1 + virttest/env_process.py | 42 +++++- virttest/utils_disk.py | 135 +++++++++++++++++- 28 files changed, 200 insertions(+), 3 deletions(-) diff --git a/shared/cfg/guest-os/Linux/RHEL/5.3/i386.cfg b/shared/cfg/guest-os/Linux/RHEL/5.3/i386.cfg index 221b70d20..29a821d13 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.3/i386.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.3/i386.cfg @@ -1,4 +1,5 @@ - i386: + grub_file = /boot/grub/grub.conf vm_arch_name = i686 image_name += -32 install: diff --git a/shared/cfg/guest-os/Linux/RHEL/5.3/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/5.3/x86_64.cfg index 33596a566..5deaa42d6 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.3/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.3/x86_64.cfg @@ -1,4 +1,5 @@ - x86_64: + grub_file = /boot/grub/grub.conf vm_arch_name = x86_64 image_name += -64 install: diff --git a/shared/cfg/guest-os/Linux/RHEL/5.4/i386.cfg b/shared/cfg/guest-os/Linux/RHEL/5.4/i386.cfg index 6f928fa57..99990bc2c 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.4/i386.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.4/i386.cfg @@ -1,4 +1,5 @@ - i386: + grub_file = /boot/grub/grub.conf vm_arch_name = i686 image_name += -32 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/shared/cfg/guest-os/Linux/RHEL/5.4/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/5.4/x86_64.cfg index 77756ec62..ca256065a 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.4/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.4/x86_64.cfg @@ -1,4 +1,5 @@ - x86_64: + grub_file = /boot/grub/grub.conf vm_arch_name = x86_64 image_name += -64 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/shared/cfg/guest-os/Linux/RHEL/5.5/i386.cfg b/shared/cfg/guest-os/Linux/RHEL/5.5/i386.cfg index 65244fb07..f426bf124 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.5/i386.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.5/i386.cfg @@ -1,4 +1,5 @@ - i386: + grub_file = /boot/grub/grub.conf vm_arch_name = i686 image_name += -32 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/shared/cfg/guest-os/Linux/RHEL/5.5/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/5.5/x86_64.cfg index 5392a2540..f0218ea1d 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.5/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.5/x86_64.cfg @@ -1,4 +1,5 @@ - x86_64: + grub_file = /boot/grub/grub.conf vm_arch_name = x86_64 image_name += -64 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/shared/cfg/guest-os/Linux/RHEL/5.6/i386.cfg b/shared/cfg/guest-os/Linux/RHEL/5.6/i386.cfg index e61ed2c22..2270a2d82 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.6/i386.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.6/i386.cfg @@ -1,4 +1,5 @@ - i386: + grub_file = /boot/grub/grub.conf vm_arch_name = i686 image_name += -32 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/shared/cfg/guest-os/Linux/RHEL/5.6/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/5.6/x86_64.cfg index 42e4df0a5..aafedefbb 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.6/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.6/x86_64.cfg @@ -1,4 +1,5 @@ - x86_64: + grub_file = /boot/grub/grub.conf vm_arch_name = x86_64 image_name += -64 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/shared/cfg/guest-os/Linux/RHEL/5.7/i386.cfg b/shared/cfg/guest-os/Linux/RHEL/5.7/i386.cfg index de3e032b6..95435996b 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.7/i386.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.7/i386.cfg @@ -1,4 +1,5 @@ - i386: + grub_file = /boot/grub/grub.conf vm_arch_name = i686 image_name += -32 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/shared/cfg/guest-os/Linux/RHEL/5.7/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/5.7/x86_64.cfg index 868180457..df3b45ddb 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.7/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.7/x86_64.cfg @@ -1,4 +1,5 @@ - x86_64: + grub_file = /boot/grub/grub.conf vm_arch_name = x86_64 image_name += -64 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/shared/cfg/guest-os/Linux/RHEL/5.8/i386.cfg b/shared/cfg/guest-os/Linux/RHEL/5.8/i386.cfg index e1709b6f3..cec9b4f57 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.8/i386.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.8/i386.cfg @@ -1,4 +1,5 @@ - i386: + grub_file = /boot/grub/grub.conf vm_arch_name = i686 image_name += -32 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/shared/cfg/guest-os/Linux/RHEL/5.8/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/5.8/x86_64.cfg index 5b9a568b3..0d6308ee3 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.8/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.8/x86_64.cfg @@ -1,4 +1,5 @@ - x86_64: + grub_file = /boot/grub/grub.conf vm_arch_name = x86_64 image_name += -64 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/shared/cfg/guest-os/Linux/RHEL/5.9/i386.cfg b/shared/cfg/guest-os/Linux/RHEL/5.9/i386.cfg index 17f1dfad6..afe304554 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.9/i386.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.9/i386.cfg @@ -1,4 +1,5 @@ - i386: + grub_file = /boot/grub/grub.conf vm_arch_name = i686 image_name += -32 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/shared/cfg/guest-os/Linux/RHEL/5.9/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/5.9/x86_64.cfg index 38c1f3d26..a38124a70 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.9/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.9/x86_64.cfg @@ -1,4 +1,5 @@ - x86_64: + grub_file = /boot/grub/grub.conf vm_arch_name = x86_64 image_name += -64 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/shared/cfg/guest-os/Linux/RHEL/6.0/i386.cfg b/shared/cfg/guest-os/Linux/RHEL/6.0/i386.cfg index b074d13e2..662941fcc 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.0/i386.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.0/i386.cfg @@ -1,4 +1,5 @@ - i386: + grub_file = /boot/grub/grub.conf vm_arch_name = i686 image_name += -32 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/shared/cfg/guest-os/Linux/RHEL/6.0/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/6.0/x86_64.cfg index 21deab392..74b5a2472 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.0/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.0/x86_64.cfg @@ -1,4 +1,5 @@ - x86_64: + grub_file = /boot/grub/grub.conf vm_arch_name = x86_64 image_name += -64 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/shared/cfg/guest-os/Linux/RHEL/6.1/i386.cfg b/shared/cfg/guest-os/Linux/RHEL/6.1/i386.cfg index 7d1eba4cd..dec8ab187 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.1/i386.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.1/i386.cfg @@ -1,4 +1,5 @@ - i386: + grub_file = /boot/grub/grub.conf vm_arch_name = i686 image_name += -32 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/shared/cfg/guest-os/Linux/RHEL/6.1/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/6.1/x86_64.cfg index 03bec2dc7..db845083f 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.1/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.1/x86_64.cfg @@ -1,4 +1,5 @@ - x86_64: + grub_file = /boot/grub/grub.conf vm_arch_name = x86_64 image_name += -64 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/shared/cfg/guest-os/Linux/RHEL/6.2/i386.cfg b/shared/cfg/guest-os/Linux/RHEL/6.2/i386.cfg index 82408d451..ddaa86977 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.2/i386.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.2/i386.cfg @@ -1,4 +1,5 @@ - i386: + grub_file = /boot/grub/grub.conf vm_arch_name = i686 image_name += -32 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/shared/cfg/guest-os/Linux/RHEL/6.2/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/6.2/x86_64.cfg index 5259403f0..17201a793 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.2/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.2/x86_64.cfg @@ -1,4 +1,5 @@ - x86_64: + grub_file = /boot/grub/grub.conf vm_arch_name = x86_64 image_name += -64 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/shared/cfg/guest-os/Linux/RHEL/6.3/i386.cfg b/shared/cfg/guest-os/Linux/RHEL/6.3/i386.cfg index 835582034..e6da796d2 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.3/i386.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.3/i386.cfg @@ -1,4 +1,5 @@ - i386: + grub_file = /boot/grub/grub.conf vm_arch_name = i686 image_name += -32 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/shared/cfg/guest-os/Linux/RHEL/6.3/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/6.3/x86_64.cfg index 6acc93a90..66bca09bc 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.3/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.3/x86_64.cfg @@ -1,4 +1,5 @@ - x86_64: + grub_file = /boot/grub/grub.conf vm_arch_name = x86_64 image_name += -64 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/shared/cfg/guest-os/Linux/RHEL/6.4/i386.cfg b/shared/cfg/guest-os/Linux/RHEL/6.4/i386.cfg index 72b02bcdd..dc36f411d 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.4/i386.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.4/i386.cfg @@ -1,4 +1,5 @@ - i386: + grub_file = /boot/grub/grub.conf vm_arch_name = i686 image_name += -32 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/shared/cfg/guest-os/Linux/RHEL/6.4/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/6.4/x86_64.cfg index c37453486..a750ab665 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.4/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.4/x86_64.cfg @@ -1,4 +1,5 @@ - x86_64: + grub_file = /boot/grub/grub.conf vm_arch_name = x86_64 image_name += -64 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/shared/cfg/guest-os/Linux/RHEL/6.devel/i386.cfg b/shared/cfg/guest-os/Linux/RHEL/6.devel/i386.cfg index 3a4a37c82..025923443 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.devel/i386.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.devel/i386.cfg @@ -1,4 +1,5 @@ - i386: + grub_file = /boot/grub/grub.conf vm_arch_name = i386 image_name += -32 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/shared/cfg/guest-os/Linux/RHEL/6.devel/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/6.devel/x86_64.cfg index 798d395a6..5bfb1da6f 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.devel/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.devel/x86_64.cfg @@ -1,4 +1,5 @@ - x86_64: + grub_file = /boot/grub/grub.conf vm_arch_name = x86_64 image_name += -64 unattended_install, check_block_size.4096_512, check_block_size.512_512: diff --git a/virttest/env_process.py b/virttest/env_process.py index 1b047b76c..875403ca7 100644 --- a/virttest/env_process.py +++ b/virttest/env_process.py @@ -3,7 +3,7 @@ from autotest.client.shared import error import aexpect, qemu_monitor, ppm_utils, test_setup, virt_vm import libvirt_vm, video_maker, utils_misc, storage, qemu_storage, utils_libvirtd -import remote, data_dir, utils_net +import remote, data_dir, utils_net, utils_disk try: @@ -433,6 +433,46 @@ def preprocess(test, params, env): int(params.get("pre_command_timeout", "600")), params.get("pre_command_noncritical") == "yes") + + #if you want set "pci=nomsi" before test, set "disable_pci_msi = yes" + #and pci_msi_sensitive = "yes" + if params.get("pci_msi_sensitive", "no") == "yes": + disable_pci_msi = params.get("disable_pci_msi", "no") + image_filename = storage.get_image_filename(params, + data_dir.get_data_dir()) + grub_file = params.get("grub_file", "/boot/grub2/grub.cfg") + kernel_cfg_pos_reg = params.get("kernel_cfg_pos_reg", + r".*vmlinuz-\d+.*") + msi_keyword = params.get("msi_keyword", " pci=nomsi") + + disk_obj = utils_disk.GuestFSModiDisk(image_filename) + kernel_config_ori = disk_obj.read_file(grub_file) + kernel_config = re.findall(kernel_cfg_pos_reg, kernel_config_ori) + if not kernel_config: + raise error.TestError("Cannot find the kernel config, reg is %s" % + kernel_cfg_pos_reg) + kernel_config_line = kernel_config[0] + + kernel_need_modify = False + if disable_pci_msi == "yes": + if not re.findall(msi_keyword, kernel_config_line): + kernel_config_set = kernel_config_line + msi_keyword + kernel_need_modify = True + else: + if re.findall(msi_keyword, kernel_config_line): + kernel_config_set = re.sub(msi_keyword, "", kernel_config_line) + kernel_need_modify = True + + if kernel_need_modify: + for vm in env.get_all_vms(): + if vm: + vm.destroy() + env.unregister_vm(vm.name) + disk_obj.replace_image_file_content(grub_file, kernel_config_line, + kernel_config_set) + logging.debug("Guest cmdline 'pci=nomsi' setting is: [ %s ]" % + disable_pci_msi) + #Clone master image from vms. base_dir = data_dir.get_data_dir() if params.get("master_images_clone"): diff --git a/virttest/utils_disk.py b/virttest/utils_disk.py index 0d8539f62..8ffb3ec6f 100644 --- a/virttest/utils_disk.py +++ b/virttest/utils_disk.py @@ -3,8 +3,7 @@ @copyright: Red Hat Inc. """ - -import os, glob, shutil, tempfile, logging, ConfigParser +import os, glob, shutil, tempfile, logging, ConfigParser,re from autotest.client import utils from autotest.client.shared import error @@ -260,3 +259,135 @@ def close(self): cleanup(self.source_cdrom) logging.debug("unattended install CD image %s successfully created", self.path) + + +class GuestFSModiDisk(object): + """ + class of guest disk using guestfs lib to do some operation(like read/write) + on guest disk: + """ + + def __init__(self, disk): + try: + import guestfs + except ImportError: + install_cmd = "yum -y install python-libguestfs" + try: + utils.run(install_cmd) + import guestfs + except Exception: + raise error.TestNAError('We need python-libguestfs (or the ' + 'equivalent for your distro) for this ' + 'particular feature (modifying guest ' + 'files with libguestfs)') + + self.g = guestfs.GuestFS() + self.disk = disk + self.g.add_drive(disk) + logging.debug("Launch the disk %s, wait..." % self.disk) + self.g.launch() + + def os_inspects(self): + self.roots = self.g.inspect_os() + if self.roots: + return self.roots + else: + return None + + def mounts(self): + return self.g.mounts() + + def mount_all(self): + def compare (a, b): + if len(a[0]) > len(b[0]): + return 1 + elif len(a[0]) == len(b[0]): + return 0 + else: + return -1 + + roots = self.os_inspects() + if roots: + for root in roots: + mps = self.g.inspect_get_mountpoints(root) + mps.sort(compare) + for mp_dev in mps: + try: + msg = "Mount dev '%s' partitions '%s' to '%s'" + logging.info(msg % (root, mp_dev[1], mp_dev[0])) + self.g.mount(mp_dev[1], mp_dev[0]) + except RuntimeError as err_msg: + logging.info("%s (ignored)" % err_msg) + else: + raise error.TestError("inspect_vm: no operating systems found") + + def umount_all (self): + logging.debug("Umount all device partitions") + if self.mounts(): + self.g.umount_all() + + def read_file(self, file_name): + """ + read file from the guest disk, return the content of the file + + @Param file_name: the file you want to read. + """ + + try: + self.mount_all() + o = self.g.cat(file_name) + if o: + return o + else: + err_msg = "Can't read file '%s', check is it exist?" + raise error.TestError(err_msg % file_name) + finally: + self.umount_all() + + def write_to_image_file(self, file_name, content, w_append=False): + """ + wirte content to the file on the guest disk. + when using this method all the original content will be overriding. + if you don't hope your original data be override make: + 'w_append=True' + + @Param file_name: the file you want to write + @Param content: the content you want to write. + @Param w_append append the content or override + """ + + try: + self.mount_all() + if w_append: + self.g.write_append(file_name, content) + else: + self.g.write(file_name, content) + except Exception: + raise error.TestError("write '%s' to file '%s' error!" + % (content, file_name )) + finally: + self.umount_all() + + def replace_image_file_content(self, file_name, find_con, rep_con): + """ + replace file content matchs in the file with rep_con. + suport using Regular expression + + @Param file_name: the file you want to replace + @Param find_con: the orign content you want to replace. + @Param rep_con: the replace content you want. + """ + + try: + self.mount_all() + file_content = self.g.cat(file_name) + if file_content: + file_content_after_replace = re.sub(find_con, rep_con, + file_content) + if file_content != file_content_after_replace: + self.g.write(file_name, file_content_after_replace) + else: + err_msg = "Can't read file '%s', check is it exist?" + raise error.TestError(err_msg % file_name) + finally: + self.umount_all() From 82e83b1d08532ea47b8df476f1c81759eece1635 Mon Sep 17 00:00:00 2001 From: Xiaoqing Wei Date: Fri, 5 Jul 2013 17:18:55 +0800 Subject: [PATCH 078/254] add commas of qemu cpu flags in cfg, not qemu_vm(issue 604) otherwise would generate qemu cmd like -cpu SandyBridge,,+sep This fix is for https://github.com/autotest/virt-test/issues/604 Signed-off-by: Xiaoqing Wei --- qemu/cfg/multi-host-tests.cfg | 2 +- virttest/qemu_vm.py | 2 +- virttest/unittest_data/testcfg.huge/multi-host-tests.cfg | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/qemu/cfg/multi-host-tests.cfg b/qemu/cfg/multi-host-tests.cfg index b61be3d23..25af363ae 100644 --- a/qemu/cfg/multi-host-tests.cfg +++ b/qemu/cfg/multi-host-tests.cfg @@ -24,7 +24,7 @@ variants: only pc only Fedora.17.x86_64 cpu_model = "core2duo" - cpu_model_flags = "+sse3" + cpu_model_flags = ",+sse3" only migrate_multi_host # Runs qemu, f16 64 bit guest OS, install, boot, shutdown diff --git a/virttest/qemu_vm.py b/virttest/qemu_vm.py index 7eaae5fe6..412dcc9ba 100644 --- a/virttest/qemu_vm.py +++ b/virttest/qemu_vm.py @@ -1158,7 +1158,7 @@ def add_cpu_flags(devices, cpu_model, flags=None, vendor_id=None, if vendor_id: cmd += ",vendor=\"%s\"" % vendor_id if flags: - cmd += ",%s" % flags + cmd += "%s" % flags if family is not None: cmd += ",family=%s" % family return cmd diff --git a/virttest/unittest_data/testcfg.huge/multi-host-tests.cfg b/virttest/unittest_data/testcfg.huge/multi-host-tests.cfg index f27ecc52f..dcd9c8b4b 100644 --- a/virttest/unittest_data/testcfg.huge/multi-host-tests.cfg +++ b/virttest/unittest_data/testcfg.huge/multi-host-tests.cfg @@ -24,7 +24,7 @@ variants: only pc only Fedora.17.64 cpu_model = "core2duo" - cpu_model_flags = "+sse3" + cpu_model_flags = ",+sse3" only migrate_multi_host # Runs qemu, f16 64 bit guest OS, install, boot, shutdown From 2eeb1b752e115b550c6b5de161661f76e7743b8f Mon Sep 17 00:00:00 2001 From: Feng Yang Date: Tue, 9 Jul 2013 20:51:08 +0800 Subject: [PATCH 079/254] tests.netperf: Update iptables stop command to ignore fail status In some host 'service iptables stop' command exit with error code 5. It will fail our case. Signed-off-by: Feng Yang --- tests/netperf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/netperf.py b/tests/netperf.py index 91c460935..fcc7a07ed 100644 --- a/tests/netperf.py +++ b/tests/netperf.py @@ -81,7 +81,7 @@ def run_netperf(test, params, env): """ def env_setup(session, ip, user, port, password): error.context("Setup env for %s" % ip) - ssh_cmd(session, "service iptables stop") + ssh_cmd(session, "service iptables stop; true") ssh_cmd(session, "echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore") netperf_dir = os.path.join(data_dir.get_root_dir(), "shared/deps") From e8727ef9712cf1f4fbb623b4bbb364e4abde2b82 Mon Sep 17 00:00:00 2001 From: Lucas Meneghel Rodrigues Date: Tue, 9 Jul 2013 10:40:15 -0300 Subject: [PATCH 080/254] MAINTAINERS: Add Yang Dongsheng as libvirt subsystem maintainer Signed-off-by: Lucas Meneghel Rodrigues --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 5189fd3f1..8c6acf196 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -26,7 +26,7 @@ Pull request maintenance - Libvirt subtests M: Christopher Evich M: Yu Mingfei - +M: Yang Dongsheng Pull request maintenance - Libguestfs ------------------------------------- From 8f868a4131f00dfe6be5d65006296111682af78a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Doktor?= Date: Tue, 9 Jul 2013 08:53:56 +0200 Subject: [PATCH 081/254] utils_cgroup: Fix the remaining imports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lukáš Doktor --- libvirt/tests/src/virsh_cmd/domain/virsh_numatune.py | 6 +++++- qemu/tests/vhost_with_cgroup.py | 7 ++++++- virttest/utils_test.py | 8 +++++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_numatune.py b/libvirt/tests/src/virsh_cmd/domain/virsh_numatune.py index 8dc774f65..28e14a978 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_numatune.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_numatune.py @@ -1,7 +1,11 @@ import re, logging from autotest.client.shared import error, utils from virttest import libvirt_xml, virsh, utils_libvirtd -from virttest import utils_cgroup +try: + from autotest.client.shared import utils_cgroup +except ImportError: + # TODO: Obsoleted path used prior autotest-0.15.2/virttest-2013.06.24 + from virttest import utils_cgroup def num_numa_nodes(): diff --git a/qemu/tests/vhost_with_cgroup.py b/qemu/tests/vhost_with_cgroup.py index fcb143460..19a151aac 100644 --- a/qemu/tests/vhost_with_cgroup.py +++ b/qemu/tests/vhost_with_cgroup.py @@ -1,9 +1,14 @@ import logging from autotest.client.shared import error from autotest.client import utils -from virttest.utils_cgroup import Cgroup, CgroupModules from virttest.env_process import preprocess +try: + from autotest.client.shared.utils_cgroup import Cgroup, CgroupModules +except ImportError: + # TODO: Obsoleted path used prior autotest-0.15.2/virttest-2013.06.24 + from virttest.utils_cgroup import Cgroup, CgroupModules + @error.context_aware def run_vhost_with_cgroup(test, params, env): diff --git a/virttest/utils_test.py b/virttest/utils_test.py index 4a9b5dc18..371f9df8a 100644 --- a/virttest/utils_test.py +++ b/virttest/utils_test.py @@ -28,9 +28,15 @@ from autotest.client import utils, os_dep from autotest.client.tools import scan_results from autotest.client.shared.syncdata import SyncData, SyncListenServer -import aexpect, utils_misc, virt_vm, remote, storage, env_process, utils_cgroup +import aexpect, utils_misc, virt_vm, remote, storage, env_process import virttest +try: + from autotest.client.shared import utils_cgroup +except ImportError: + # TODO: Obsoleted path used prior autotest-0.15.2/virttest-2013.06.24 + from virttest import utils_cgroup + # Handle transition from autotest global_config (0.14.x series) to # settings (0.15.x onwards) try: From cbfa08f9e8ef7d6b7b46e181134924830a26bc6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Doktor?= Date: Tue, 9 Jul 2013 08:54:49 +0200 Subject: [PATCH 082/254] virttest.env_process: Process all images at once MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously each image check paused and unpaused the VM. With this patch it pause vm, checks all images and unpause again (if required). Additionally this processes the all remaining images in case of failure thus image check failure won't prevent other images to be checked/deleted (in postprocess). Signed-off-by: Lukáš Doktor --- virttest/env_process.py | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/virttest/env_process.py b/virttest/env_process.py index 875403ca7..a64997e92 100644 --- a/virttest/env_process.py +++ b/virttest/env_process.py @@ -255,18 +255,25 @@ def _call_image_func(): for vm_name in params.objects("vms"): vm_params = params.object_params(vm_name) vm = env.get_vm(vm_name) - for image_name in vm_params.objects("images"): - image_params = vm_params.object_params(image_name) - # Call image_func for each image - unpause_vm = False - if vm is not None and vm.is_alive() and not vm.is_paused(): - vm.pause() - unpause_vm = True - try: - image_func(test, image_params, image_name) - finally: - if unpause_vm: - vm.resume() + unpause_vm = False + if vm is not None and vm.is_alive() and not vm.is_paused(): + vm.pause() + unpause_vm = True + try: + err = "" + for image_name in vm_params.objects("images"): + image_params = vm_params.object_params(image_name) + # Call image_func for each image + try: + image_func(test, image_params, image_name) + except Exception, details: + err += "\n%s: %s" % (image_name, details) + if err: + raise virt_vm.VMImageCheckError("Error(s) occured " + "while processing images: %s" % err) + finally: + if unpause_vm: + vm.resume() else: for image_name in params.objects("images"): image_params = params.object_params(image_name) From 861990543c5dcf8479b8f9684f616956cc2d3f72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Doktor?= Date: Tue, 9 Jul 2013 10:22:48 +0200 Subject: [PATCH 083/254] virttest.env_process: Avoid autotest hang in postprocess MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When process fails in postprocess, screendump thread is not killed and autotest hangs forever. Additionally continue with postprocess when some part fails and reraise the exception at the end. Signed-off-by: Lukáš Doktor --- virttest/env_process.py | 81 +++++++++++++++++++++++++++++------------ 1 file changed, 57 insertions(+), 24 deletions(-) diff --git a/virttest/env_process.py b/virttest/env_process.py index a64997e92..2d0d3f2aa 100644 --- a/virttest/env_process.py +++ b/virttest/env_process.py @@ -113,7 +113,7 @@ def preprocess_vm(test, params, env, name): if params.get("paused_after_start_vm") == "yes": pause_vm = True - #Check the status of vm + # Check the status of vm if not vm.is_alive(): pause_vm = False @@ -202,7 +202,7 @@ def postprocess_vm(test, params, env, name): kill_vm_timeout = float(params.get("kill_vm_timeout", 0)) if kill_vm_timeout: utils_misc.wait_for(vm.is_dead, kill_vm_timeout, 0, 1) - vm.destroy(gracefully = params.get("kill_vm_gracefully") == "yes") + vm.destroy(gracefully=params.get("kill_vm_gracefully") == "yes") def process_command(test, params, env, command, command_timeout, @@ -441,14 +441,14 @@ def preprocess(test, params, env): params.get("pre_command_noncritical") == "yes") - #if you want set "pci=nomsi" before test, set "disable_pci_msi = yes" - #and pci_msi_sensitive = "yes" + # if you want set "pci=nomsi" before test, set "disable_pci_msi = yes" + # and pci_msi_sensitive = "yes" if params.get("pci_msi_sensitive", "no") == "yes": disable_pci_msi = params.get("disable_pci_msi", "no") image_filename = storage.get_image_filename(params, data_dir.get_data_dir()) grub_file = params.get("grub_file", "/boot/grub2/grub.cfg") - kernel_cfg_pos_reg = params.get("kernel_cfg_pos_reg", + kernel_cfg_pos_reg = params.get("kernel_cfg_pos_reg", r".*vmlinuz-\d+.*") msi_keyword = params.get("msi_keyword", " pci=nomsi") @@ -480,7 +480,7 @@ def preprocess(test, params, env): logging.debug("Guest cmdline 'pci=nomsi' setting is: [ %s ]" % disable_pci_msi) - #Clone master image from vms. + # Clone master image from vms. base_dir = data_dir.get_data_dir() if params.get("master_images_clone"): for vm_name in params.get("vms").split(): @@ -495,7 +495,7 @@ def preprocess(test, params, env): image_obj.clone_image(params, vm_name, image, base_dir) # Preprocess all VMs and images - if params.get("not_preprocess","no") == "no": + if params.get("not_preprocess", "no") == "no": process(test, params, env, preprocess_image, preprocess_vm) # Start the screendump thread @@ -520,9 +520,15 @@ def postprocess(test, params, env): @param env: The environment (a dict-like object). """ error.context("postprocessing") + err = "" # Postprocess all VMs and images - process(test, params, env, postprocess_image, postprocess_vm, vm_first=True) + try: + process(test, params, env, postprocess_image, postprocess_vm, + vm_first=True) + except Exception, details: + err += "\nPostprocess: %s" % details + logging.error(details) # Terminate the screendump thread global _screendump_thread, _screendump_thread_termination_event @@ -607,29 +613,49 @@ def postprocess(test, params, env): del env["tcpdump"] if params.get("setup_hugepages") == "yes": - h = test_setup.HugePageConfig(params) - h.cleanup() - if params.get("vm_type") == "libvirt": - utils_libvirtd.libvirtd_restart() + try: + h = test_setup.HugePageConfig(params) + h.cleanup() + if params.get("vm_type") == "libvirt": + utils_libvirtd.libvirtd_restart() + except Exception, details: + err += "\nHP cleanup: %s" % details + logging.error(details) if params.get("setup_thp") == "yes": - thp = test_setup.TransparentHugePageConfig(test, params) - thp.cleanup() + try: + thp = test_setup.TransparentHugePageConfig(test, params) + thp.cleanup() + except Exception, details: + err += "\nTHP cleanup: %s" % details + logging.error(details) if params.get("setup_ksm") == "yes": - ksm = test_setup.KSMConfig(params, env) - ksm.cleanup(env) + try: + ksm = test_setup.KSMConfig(params, env) + ksm.cleanup(env) + except Exception, details: + err += "\nKSM cleanup: %s" % details + logging.error(details) # Execute any post_commands if params.get("post_command"): - process_command(test, params, env, params.get("post_command"), - int(params.get("post_command_timeout", "600")), - params.get("post_command_noncritical") == "yes") + try: + process_command(test, params, env, params.get("post_command"), + int(params.get("post_command_timeout", "600")), + params.get("post_command_noncritical") == "yes") + except Exception, details: + err += "\nPostprocess command: %s" % details + logging.error(details) base_dir = data_dir.get_data_dir() if params.get("storage_type") == "iscsi": - iscsidev = qemu_storage.Iscsidev(params, base_dir, "iscsi") - iscsidev.cleanup() + try: + iscsidev = qemu_storage.Iscsidev(params, base_dir, "iscsi") + iscsidev.cleanup() + except Exception, details: + err += "\niscsi cleanup: %s" % details + logging.error(details) setup_pb = False for nic in params.get('nics', "").split(): @@ -640,8 +666,15 @@ def postprocess(test, params, env): setup_pb = params.get("netdst") == 'private' if setup_pb: - brcfg = test_setup.PrivateBridgeConfig() - brcfg.cleanup() + try: + brcfg = test_setup.PrivateBridgeConfig() + brcfg.cleanup() + except Exception, details: + err += "\nPB cleanup: %s" % details + logging.error(details) + + if err: + raise virt_vm.VMError("Failures occured while postprocess:%s" % err) def postprocess_on_error(test, params, env): @@ -769,7 +802,7 @@ def _take_screendumps(test, params, env): time_inactive = time.time() - inactivity[vm] if time_inactive > inactivity_treshold: msg = ("%s screen is inactive for more than %d s (%d min)" % - (vm.name, time_inactive, time_inactive/60)) + (vm.name, time_inactive, time_inactive / 60)) if inactivity_watcher == "error": try: raise virt_vm.VMScreenInactiveError(vm, From 65acf7f864cedfd87f11babcb22f93c181c850b2 Mon Sep 17 00:00:00 2001 From: Feng Yang Date: Tue, 9 Jul 2013 12:13:45 +0800 Subject: [PATCH 084/254] qemu.tests.hdparm: Fix issue that start VM twice Now hdparm will start VM twice. hdparm no need special setup before starting VM. So only start VM in framework. Signed-off-by: Feng Yang --- qemu/tests/hdparm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu/tests/hdparm.py b/qemu/tests/hdparm.py index 268ee1a7f..893e8331a 100644 --- a/qemu/tests/hdparm.py +++ b/qemu/tests/hdparm.py @@ -61,7 +61,7 @@ def perform_read_timing(disk, timeout, num=5): ignore_string = params.get("ignore_string") vm = env.get_vm(params["main_vm"]) - vm.create() + vm.verify_alive() session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) try: timeout = float(params.get("cmd_timeout", 60)) From f9e348c37e4c1cc9395cb8968d851d15755b471b Mon Sep 17 00:00:00 2001 From: Feng Yang Date: Tue, 9 Jul 2013 19:04:39 +0800 Subject: [PATCH 085/254] qemu.tests.physical_resources_check: Always use human monitor info command Current code only works with human monitor info command, so always use human monitor info command for qmp/human monitor. Signed-off-by: Feng Yang --- qemu/tests/physical_resources_check.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qemu/tests/physical_resources_check.py b/qemu/tests/physical_resources_check.py index 7237a2663..20527d1f8 100644 --- a/qemu/tests/physical_resources_check.py +++ b/qemu/tests/physical_resources_check.py @@ -23,7 +23,7 @@ def check_num(devices, info_cmd, check_str): expected_num = params.objects(devices).__len__() o = "" try: - o = vm.monitor.info(info_cmd) + o = vm.monitor.human_monitor_cmd("info %s " % info_cmd) except qemu_monitor.MonitorError, e: fail_log = e + "\n" fail_log += "info/query monitor command failed (%s)" % info_cmd @@ -49,7 +49,7 @@ def chk_fmt_model(device, fmt_model, info_cmd, regexp): expected = "rtl8139" o = "" try: - o = vm.monitor.info(info_cmd) + o = vm.monitor.human_monitor_cmd("info %s" % info_cmd) except qemu_monitor.MonitorError, e: fail_log = e + "\n" fail_log += "info/query monitor command failed (%s)" % info_cmd @@ -257,7 +257,7 @@ def verify_machine_type(): logging.info("Network card MAC check") o = "" try: - o = vm.monitor.info("network") + o = vm.monitor.human_monitor_cmd("info network") except qemu_monitor.MonitorError, e: fail_log = e + "\n" fail_log += "info/query monitor command failed (network)" From 8efde9d30cc3d51ac519a3627b1f71c29f0b3792 Mon Sep 17 00:00:00 2001 From: Qingtang Zhou Date: Wed, 10 Jul 2013 10:35:14 +0800 Subject: [PATCH 086/254] qemu.tests.cfg: Enable usb_nodev variant on RHEL host Signed-off-by: Qingtang Zhou --- qemu/tests/cfg/usb.cfg | 2 -- 1 file changed, 2 deletions(-) diff --git a/qemu/tests/cfg/usb.cfg b/qemu/tests/cfg/usb.cfg index 5045ff7ef..c1a4bd1d6 100644 --- a/qemu/tests/cfg/usb.cfg +++ b/qemu/tests/cfg/usb.cfg @@ -53,8 +53,6 @@ # usb devices variants: - @usb_nodev: - # Not used in RHEL testing. - no Host_RHEL only usb_storage, usb_host, usb_multi_disk - usb_kbd: only usb_boot, usb_reboot, usb_hotplug From 7ddbeffdc2a95f6d98e73d148ad91dba0e8a9c9a Mon Sep 17 00:00:00 2001 From: Qingtang Zhou Date: Wed, 10 Jul 2013 10:36:09 +0800 Subject: [PATCH 087/254] shared.cfg: Fix the s4_support_chk_cmd for Fedora guest Signed-off-by: Qingtang Zhou --- shared/cfg/guest-os/Linux/Fedora.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/cfg/guest-os/Linux/Fedora.cfg b/shared/cfg/guest-os/Linux/Fedora.cfg index 91a93f3a5..e23b42484 100644 --- a/shared/cfg/guest-os/Linux/Fedora.cfg +++ b/shared/cfg/guest-os/Linux/Fedora.cfg @@ -10,6 +10,6 @@ s4_log_chk_cmd = 'dmesg | grep -E "PM: Image restored successfully."' global_disable_s4: s4_support_chk_cmd = "yum install -y iasl" - s4_support_chk_cmd += " && cat cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" s4_support_chk_cmd += " && iasl -d /tmp/ssdt" s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" From d1a6625882dba24f87eab1db84e945c2ccc5e346 Mon Sep 17 00:00:00 2001 From: Feng Yang Date: Wed, 10 Jul 2013 17:12:15 +0800 Subject: [PATCH 088/254] shared.cfg.guest-os.Windows: Ignore post_cmd status in multi_disk case Signed-off-by: Feng Yang --- shared/cfg/guest-os/Windows.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/cfg/guest-os/Windows.cfg b/shared/cfg/guest-os/Windows.cfg index c3fc7db82..e677f2bf2 100644 --- a/shared/cfg/guest-os/Windows.cfg +++ b/shared/cfg/guest-os/Windows.cfg @@ -183,7 +183,7 @@ black_list += " E:" shell_port = 23 shell_client = telnet - post_cmd = del c:\cmd.exe + post_cmd = del c:\cmd.exe; true file_system = "ntfs fat32" cmd_list = "copy_to_command copy_from_command" list_volume_command = wmic volume get driveletter @@ -224,7 +224,7 @@ black_list += " E:" shell_port = 23 shell_client = telnet - post_cmd = del c:\cmd.exe + post_cmd = del c:\cmd.exe; true file_system = "ntfs fat32" cmd_list = "copy_to_command copy_from_command" list_volume_command = wmic volume get driveletter From c0ce5256cca388324d66f39838b7b34b314f78fa Mon Sep 17 00:00:00 2001 From: Feng Yang Date: Fri, 28 Jun 2013 17:37:18 +0800 Subject: [PATCH 089/254] qemu.qemu_vm: support vhostfd in netdev. vhostfd only works when vhost on. add enable_vhost parameter. set default value to 'yes' Signed-off-by: Feng Yang --- qemu/cfg/host-kernel.cfg | 4 ++++ virttest/qemu_vm.py | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/qemu/cfg/host-kernel.cfg b/qemu/cfg/host-kernel.cfg index 4e174c6ef..83c16af07 100644 --- a/qemu/cfg/host-kernel.cfg +++ b/qemu/cfg/host-kernel.cfg @@ -91,6 +91,8 @@ variants: query_cmd = "cat /sys/kernel/mm/ksm/pages_sharing" virtio_net: vhost = "vhost=on" + # enable_vhostfd only works with vhost=on + enable_vhostfd = yes Win2008, Win2008r2, Win7: cpu_model_flags += ",hv_relaxed" block_stream, drive_mirror, live_snapshot, live_snapshot_chain: @@ -135,6 +137,8 @@ variants: cpu_model_flags += ",hv_relaxed" virtio_net: vhost = "vhost=on" + # enable_vhostfd only works with vhost=on + enable_vhostfd = yes monitor_cmds_check.qmp: black_cmds = "block-stream block-job-cancel block-job-set-speed drive-mirror block-job-complete block-job-pause block-job-resume" monitor_cmds_check.human: diff --git a/virttest/qemu_vm.py b/virttest/qemu_vm.py index 412dcc9ba..5b79ce4d7 100644 --- a/virttest/qemu_vm.py +++ b/virttest/qemu_vm.py @@ -844,6 +844,10 @@ def add_net(devices, vlan, nettype, ifname=None, tftp=None, cmd = " -netdev %s,id=%s" % (mode, netdev_id) if vhost: cmd += ",%s" % vhost + enable_vhostfd = params.get("enable_vhostfd", "yes") + if vhost == 'vhost=on' and enable_vhostfd == 'yes': + vhostfd = os.open("/dev/vhost-net", os.O_RDWR) + cmd += ",vhostfd=%s" % vhostfd if netdev_extra_params: cmd += "%s" % netdev_extra_params else: From c7de69337e97231cd5e174c699be5463bdc9d75f Mon Sep 17 00:00:00 2001 From: yangdongsheng Date: Thu, 11 Jul 2013 15:28:05 +0800 Subject: [PATCH 090/254] utils_libvirtd: if libvirt is not availible in host, No error, but a warning. Signed-off-by: yangdongsheng --- virttest/utils_libvirtd.py | 4 +++- virttest/utils_libvirtd_unittest.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/virttest/utils_libvirtd.py b/virttest/utils_libvirtd.py index c46fbe2cf..51cdd4673 100644 --- a/virttest/utils_libvirtd.py +++ b/virttest/utils_libvirtd.py @@ -41,7 +41,9 @@ def __init__(self, action): os_dep.command("libvirtd") LIBVIRTD = "libvirtd" except ValueError: - raise LibvirtdError("There is no libvirtd on the host.") + LIBVIRTD = None + logging.warning("Libvirtd service is not availible in host, " + "utils_libvirtd module will not function normally") def service_libvirtd_control(action, remote_ip=None, diff --git a/virttest/utils_libvirtd_unittest.py b/virttest/utils_libvirtd_unittest.py index 9fd5d4ba3..71512a808 100755 --- a/virttest/utils_libvirtd_unittest.py +++ b/virttest/utils_libvirtd_unittest.py @@ -5,6 +5,7 @@ from virttest import utils_libvirtd class UtilsLibvirtdTest(unittest.TestCase): + @unittest.skipIf(not utils_libvirtd.LIBVIRTD, "skip if libvirtd is not available") def test_service_libvirtd_control(self): service_libvirtd_control = utils_libvirtd.service_libvirtd_control self.assertRaises(utils_libvirtd.LibvirtdActionUnknownError, @@ -18,6 +19,5 @@ def test_libvirtd_error(self): self.assertRaises(utils_libvirtd.LibvirtdActionError, utils_libvirtd.service_libvirtd_control, action=action, libvirtd="") - if __name__ == "__main__": unittest.main() From a8d2044ea969063c9d47390dbc0a6d5098a33aa5 Mon Sep 17 00:00:00 2001 From: Li Yang Date: Fri, 12 Jul 2013 14:51:19 +0800 Subject: [PATCH 091/254] virt: modify libvirtd_status() to libvirtd_is_running() Signed-off-by: Li Yang --- libvirt/tests/src/virsh_cmd/domain/virsh_dump.py | 2 +- virttest/utils_libvirtd.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_dump.py b/libvirt/tests/src/virsh_cmd/domain/virsh_dump.py index 90a303993..dda56640a 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_dump.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_dump.py @@ -164,7 +164,7 @@ def check_dump_format(dump_image_format, dump_file): status = cmd_result.exit_status # Check libvirtd status - if utils_libvirtd.libvirtd_status(): + if utils_libvirtd.libvirtd_is_running(): if check_domstate(vm.state(), options): if status_error == "yes": if status == 0: diff --git a/virttest/utils_libvirtd.py b/virttest/utils_libvirtd.py index 51cdd4673..c78b95565 100644 --- a/virttest/utils_libvirtd.py +++ b/virttest/utils_libvirtd.py @@ -145,9 +145,9 @@ def libvirtd_start(): return False -def libvirtd_status(): +def libvirtd_is_running(): """ - Get the status of libvirt daemon. + Check if libvirt service is running. """ try: return service_libvirtd_control('status') From df3f719d1aed5a21f74e851053f74fddbee8c91a Mon Sep 17 00:00:00 2001 From: Yu Mingfei Date: Fri, 12 Jul 2013 10:41:55 +0800 Subject: [PATCH 092/254] virttest.aexpect: Fix old class Spawn definition. The base class Spawn for ShellSession was defined in old way(class Spawn). Then we can not use super() for inherited classes: TypeError: super() argument 1 must be type, not classobj Signed-off-by: Yu Mingfei --- virttest/aexpect.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virttest/aexpect.py b/virttest/aexpect.py index 08646cd28..0e434a68c 100755 --- a/virttest/aexpect.py +++ b/virttest/aexpect.py @@ -342,7 +342,7 @@ def run_fg(command, output_func=None, output_prefix="", timeout=1.0): return (status, output) -class Spawn: +class Spawn(object): """ This class is used for spawning and controlling a child process. From 5bff6d49754c9887aed7d1d5fcf8fad3bb17b17d Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Sat, 13 Jul 2013 23:45:01 -0300 Subject: [PATCH 093/254] README.rst: add basic troubleshooting instructions As suggested by Juan Quintela. CC: Juan Quintela Signed-off-by: Cleber Rosa --- README.rst | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/README.rst b/README.rst index 88c9e7c50..500ffe707 100644 --- a/README.rst +++ b/README.rst @@ -119,3 +119,30 @@ platform. Autotest is a modular framework, and this suite can be used as a submodule of the client module. If you do not want to use or know about autotest, this is fine too, and we'll provide documentation and tools to perform development style testing with it. + + +Basic Troubleshooting +--------------------- + +If you have problems with the basic usage described here, it's possible +that there's some local change in your working copy of virt-test. These +changes can come in (at least) two different categories: + +- Code changes, which you can check with the git tools (try "git diff" + and "git branch" first) +- Configuration changes that can you reset with "update_config.py" + +If you find that you have local changes in the code, please try to reset +your checked out copy to upstream's master by running:: + +$ git checkout master +$ git pull + + +And then, reset you configuration. If you're going to run qemu tests, run:: + +$ qemu/update_config.py + + +If you're still having problems after these basic troubleshoot steps, +please contact us! From fd52ca7f407ce31821c4349e6de2d7c6101c357c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Doktor?= Date: Mon, 15 Jul 2013 16:46:54 +0200 Subject: [PATCH 094/254] virttest.env_process: Fix postprocess logging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lukáš Doktor --- virttest/env_process.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/virttest/env_process.py b/virttest/env_process.py index 2d0d3f2aa..dee6b3fb6 100644 --- a/virttest/env_process.py +++ b/virttest/env_process.py @@ -527,7 +527,7 @@ def postprocess(test, params, env): process(test, params, env, postprocess_image, postprocess_vm, vm_first=True) except Exception, details: - err += "\nPostprocess: %s" % details + err += "\nPostprocess: %s" % str(details).replace('\\n', '\n ') logging.error(details) # Terminate the screendump thread @@ -619,7 +619,7 @@ def postprocess(test, params, env): if params.get("vm_type") == "libvirt": utils_libvirtd.libvirtd_restart() except Exception, details: - err += "\nHP cleanup: %s" % details + err += "\nHP cleanup: %s" % str(details).replace('\\n', '\n ') logging.error(details) if params.get("setup_thp") == "yes": @@ -627,7 +627,7 @@ def postprocess(test, params, env): thp = test_setup.TransparentHugePageConfig(test, params) thp.cleanup() except Exception, details: - err += "\nTHP cleanup: %s" % details + err += "\nTHP cleanup: %s" % str(details).replace('\\n', '\n ') logging.error(details) if params.get("setup_ksm") == "yes": @@ -635,7 +635,7 @@ def postprocess(test, params, env): ksm = test_setup.KSMConfig(params, env) ksm.cleanup(env) except Exception, details: - err += "\nKSM cleanup: %s" % details + err += "\nKSM cleanup: %s" % str(details).replace('\\n', '\n ') logging.error(details) # Execute any post_commands @@ -645,7 +645,8 @@ def postprocess(test, params, env): int(params.get("post_command_timeout", "600")), params.get("post_command_noncritical") == "yes") except Exception, details: - err += "\nPostprocess command: %s" % details + err += "\nPostprocess command: %s" % str(details).replace('\n', + '\n ') logging.error(details) base_dir = data_dir.get_data_dir() @@ -654,7 +655,7 @@ def postprocess(test, params, env): iscsidev = qemu_storage.Iscsidev(params, base_dir, "iscsi") iscsidev.cleanup() except Exception, details: - err += "\niscsi cleanup: %s" % details + err += "\niscsi cleanup: %s" % str(details).replace('\\n', '\n ') logging.error(details) setup_pb = False @@ -670,7 +671,7 @@ def postprocess(test, params, env): brcfg = test_setup.PrivateBridgeConfig() brcfg.cleanup() except Exception, details: - err += "\nPB cleanup: %s" % details + err += "\nPB cleanup: %s" % str(details).replace('\\n', '\n ') logging.error(details) if err: From b9419cc43f1eb2711d8f3b845945ff2587f4e52f Mon Sep 17 00:00:00 2001 From: Qingtang Zhou Date: Tue, 16 Jul 2013 11:20:46 +0800 Subject: [PATCH 095/254] qemu.tests.cfg: Enable qemu guest agent test for RHEL guest Signed-off-by: Qingtang Zhou --- qemu/tests/cfg/qemu_guest_agent.cfg | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qemu/tests/cfg/qemu_guest_agent.cfg b/qemu/tests/cfg/qemu_guest_agent.cfg index 4b571e549..77128b9c2 100644 --- a/qemu/tests/cfg/qemu_guest_agent.cfg +++ b/qemu/tests/cfg/qemu_guest_agent.cfg @@ -1,5 +1,6 @@ - qemu_guest_agent: install setup image_copy unattended_install.cdrom - only Fedora.16, Fedora.17, Fedora.18, Fedora.test, Windows + only Fedora, RHEL, Windows + no 8, 9, 10, 11, 12, 13, 14, 15 type = qemu_guest_agent gagent_name = "org.qemu.guest_agent.0" gagent_install_cmd = "rpm -q qemu-guest-agent || yum install -y qemu-guest-agent" From 21302133813fd19e773802c179264287698ff40a Mon Sep 17 00:00:00 2001 From: Qingtang Zhou Date: Tue, 16 Jul 2013 13:02:22 +0800 Subject: [PATCH 096/254] qemu.tests.cfg: Disable xhci on old windows for RHEL host Signed-off-by: Qingtang Zhou --- qemu/tests/cfg/usb.cfg | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qemu/tests/cfg/usb.cfg b/qemu/tests/cfg/usb.cfg index c1a4bd1d6..0f2c5968e 100644 --- a/qemu/tests/cfg/usb.cfg +++ b/qemu/tests/cfg/usb.cfg @@ -27,6 +27,8 @@ usb_controller = xhci usb_max_port_usbtest = 4 drive_format_stg = "usb3" + Host_RHEL: + no Win2000, WinXP, Win2003, WinVista, Win7, Win2008 # usb toplogy variants: From 52de024c08cf830d21c4adc8e8886ac1ac7c423a Mon Sep 17 00:00:00 2001 From: Qingtang Zhou Date: Tue, 16 Jul 2013 13:10:25 +0800 Subject: [PATCH 097/254] qemu.tests.cfg: Move usb_(re)boot config for win guest to Windows.cfg These parameters would be overridden by the parameters in each usb device config block. So move it into guest-os's config files. Signed-off-by: Qingtang Zhou --- qemu/tests/cfg/usb.cfg | 10 ---------- shared/cfg/guest-os/Windows.cfg | 6 +++++- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/qemu/tests/cfg/usb.cfg b/qemu/tests/cfg/usb.cfg index 0f2c5968e..0a69fd1e3 100644 --- a/qemu/tests/cfg/usb.cfg +++ b/qemu/tests/cfg/usb.cfg @@ -114,22 +114,12 @@ usb_devices += " testdev" deviceid_str = "%s:%s" chk_usb_info_cmd = "lsusb -v" - Windows: - deviceid_str = "VID_%s&PID_%s" - chk_usb_info_cmd = 'wmic path Win32_USBControllerDevice get Dependent | find "USB"' - vendor_equal = "" - product_equal = "" - usb_reboot: type = usb_basic_check reboot_method = shell usb_devices += " testdev" deviceid_str = "%s:%s" chk_usb_info_cmd = "lsusb -v" - Windows: - deviceid_str = "VID_%s&PID_%s" - chk_usb_info_cmd = 'wmic path Win32_USBControllerDevice get Dependent | find "USB"' - vendor_equal = "" - product_equal = "" - usb_hotplug: #XXX: usb_hotplug uses some linux-only cmds. # And the pattern to verify device is pluged can't diff --git a/shared/cfg/guest-os/Windows.cfg b/shared/cfg/guest-os/Windows.cfg index c3fc7db82..f9abba597 100644 --- a/shared/cfg/guest-os/Windows.cfg +++ b/shared/cfg/guest-os/Windows.cfg @@ -326,4 +326,8 @@ bg_cmd = copy C:\1.txt C:\2.txt /y check_op = echo cd C:\ > C:\tmp.bat&& echo for /F "tokens=1,*" %%i in ('D:\coreutils\md5sum.exe C:\1.txt') do D:\coreutils\md5sum.exe C:\2.txt ^| find "%%i" >> C:\tmp.bat && C:\tmp.bat clean_op = dir C:\ && del C:\1.txt C:\2.txt C:\tmp.bat && dir C:\ - + usb..usb_boot, usb..usb_reboot: + deviceid_str = "VID_%s&PID_%s" + chk_usb_info_cmd = 'wmic path Win32_USBControllerDevice get Dependent | find "USB"' + vendor = "" + product = "" From 121e1f47d420975a71ac6ed4c1408c6af50eaed6 Mon Sep 17 00:00:00 2001 From: Mike Qiu Date: Tue, 16 Jul 2013 03:40:59 -0700 Subject: [PATCH 098/254] qemu.balloon_check: reset the memory to origin value The memory should be reset to the origin value after evict or enlarge. So that the next iterations tests can pass when check memory before test Signed-off-by: Mike Qiu --- qemu/tests/balloon_check.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/qemu/tests/balloon_check.py b/qemu/tests/balloon_check.py index 084640d37..f83faa5bd 100644 --- a/qemu/tests/balloon_check.py +++ b/qemu/tests/balloon_check.py @@ -219,4 +219,14 @@ def balloon_memory(new_mem): ballooned_mem = 0 memory_check("after subtest when enlarging memory", ballooned_mem, monitor_boot_mem , guest_boot_mem, ratio) + + # we should reset the memory to the origin value, so that next + # iterations can pass when check memory before test + error.context("Reset the memory to monitor boot memory", logging.info) + + balloon_memory(monitor_boot_mem) + ballooned_mem = vm_assigned_mem - monitor_boot_mem + memory_check("after reset memory", ballooned_mem, + monitor_boot_mem, guest_boot_mem, ratio) + session.close() From 281c2322746e4976216a882d511a4795dc0d54c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Doktor?= Date: Tue, 16 Jul 2013 10:34:39 +0200 Subject: [PATCH 099/254] virttest.qemu_devices: Fix QStringDevice.cmdline problem MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit when False/None was set as cmdline this device always failed. Signed-off-by: Lukáš Doktor --- virttest/qemu_devices.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/virttest/qemu_devices.py b/virttest/qemu_devices.py index 84783deee..a97c02f1c 100644 --- a/virttest/qemu_devices.py +++ b/virttest/qemu_devices.py @@ -258,7 +258,8 @@ def __init__(self, dev_type, params=None, aobject=None, def cmdline(self): """ @return: cmdline command to define this device """ try: - return self._cmdline % self.params + if self._cmdline: + return self._cmdline % self.params except KeyError, details: raise KeyError("Param %s required for cmdline is not present in %s" % (details, self.str_long())) @@ -1285,8 +1286,9 @@ def cmdline(self): """ out = "" for device in self.__devices: - if device.cmdline(): - out += " %s" % device.cmdline() + _out = device.cmdline() + if _out: + out += " %s" % _out if out: return out[1:] From fc0e410b73f04bbbb612f911d479b21b4d585856 Mon Sep 17 00:00:00 2001 From: Yiqiao Pu Date: Fri, 12 Jul 2013 14:39:16 +0800 Subject: [PATCH 100/254] tests: Correct the wrong import module for trans_hugepage_memory_stress Should import utils under client but not under client.shared. Signed-off-by: Yiqiao Pu --- tests/trans_hugepage_memory_stress.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/trans_hugepage_memory_stress.py b/tests/trans_hugepage_memory_stress.py index 573522760..277200533 100644 --- a/tests/trans_hugepage_memory_stress.py +++ b/tests/trans_hugepage_memory_stress.py @@ -1,5 +1,6 @@ import logging, os -from autotest.client.shared import error, utils +from autotest.client.shared import error +from autotest.client import utils from virttest import utils_test @error.context_aware From 7a3d0b96e47c191dc51013370da9cc687c79b181 Mon Sep 17 00:00:00 2001 From: Yiqiao Pu Date: Fri, 12 Jul 2013 16:16:15 +0800 Subject: [PATCH 101/254] shared.control: Update the stress_memory_heavy.control Fix some variables missing problem and typo. Signed-off-by: Yiqiao Pu --- shared/control/stress_memory_heavy.control | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/shared/control/stress_memory_heavy.control b/shared/control/stress_memory_heavy.control index 1a27a4a74..c97c535ea 100644 --- a/shared/control/stress_memory_heavy.control +++ b/shared/control/stress_memory_heavy.control @@ -10,6 +10,7 @@ Call the stress control file, only with custom params to heavily stress a machine's memory. ''' +import os from autotest.client import utils # Assemble the parameters specially to stress memory @@ -20,15 +21,17 @@ threads = 2 * utils.count_cpus() mem = utils.memtotal() / 1024 / 512 memory_per_thread = 256 * 1024 -free_disk = utils.freespace(self.srcdir) +free_disk = utils.freespace(os.getcwd()) file_size_per_thread = 1024 ** 2 if (0.9 * free_disk) < file_size_per_thread * threads: file_size_per_thread = (0.9 * free_disk) / threads +stress_length = 60 + # Number of CPU workers spinning on sqrt() args = '--cpu %d ' % threads # Number of IO workers spinning on sync() -args += '--io %d ' % threadsfrom autotest.client import utils +args += '--io %d ' % threads # Number of Memory workers spinning on malloc()/free() args += '--vm %d ' % mem # Amount of memory used per each worker @@ -42,5 +45,4 @@ args += '--timeout %d ' % stress_length # Verbose flag args += '--verbose' - -job.run_test('stress_memory_heavy', args=args) +job.run_test('stress', args=args) From 3c8ce07292ac05763b73d512defa729a1fba0b38 Mon Sep 17 00:00:00 2001 From: Yiqiao Pu Date: Fri, 12 Jul 2013 18:59:20 +0800 Subject: [PATCH 102/254] virttest.aexpect: A work aound for new style class pickle The new style class will not call __getinitargs__ anymore. So this will help aexpect works as we expect. Signed-off-by: Yiqiao Pu --- virttest/aexpect.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/virttest/aexpect.py b/virttest/aexpect.py index 0e434a68c..97ccdd5f3 100755 --- a/virttest/aexpect.py +++ b/virttest/aexpect.py @@ -457,6 +457,10 @@ def __init__(self, command=None, a_id=None, auto_close=False, echo=False, # The following two functions are defined to make sure the state is set # exclusively by the constructor call as specified in __getinitargs__(). + def __reduce__(self): + return self.__class__, (self.__getinitargs__()) + + def __getstate__(self): pass @@ -722,6 +726,10 @@ def __init__(self, command=None, a_id=None, auto_close=False, echo=False, self._start_thread() + def __reduce__(self): + return self.__class__, (self.__getinitargs__()) + + def __getinitargs__(self): return Spawn.__getinitargs__(self) + (self.termination_func, self.termination_params, @@ -919,6 +927,10 @@ def __init__(self, command=None, a_id=None, auto_close=True, echo=False, output_func, output_params, output_prefix) + def __reduce__(self): + return self.__class__, (self.__getinitargs__()) + + def __getinitargs__(self): return Tail.__getinitargs__(self) @@ -1201,6 +1213,10 @@ def __init__(self, command=None, a_id=None, auto_close=True, echo=False, self.status_test_command = status_test_command + def __reduce__(self): + return self.__class__, (self.__getinitargs__()) + + def __getinitargs__(self): return Expect.__getinitargs__(self) + (self.prompt, self.status_test_command) From 0e98970ca318ab57e96b5124bf2d6c3c787fa6af Mon Sep 17 00:00:00 2001 From: yangdongsheng Date: Fri, 21 Jun 2013 11:26:56 +0800 Subject: [PATCH 103/254] Fix libvirt_xml/vm_xml. This patch fix define and undefine method in VMXML class to return False if define or undefine fail. Fixing the comment of virsh.undefine by the way. Signed-off-by: yangdongsheng --- virttest/libvirt_xml/vm_xml.py | 12 ++++++++---- virttest/virsh.py | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/virttest/libvirt_xml/vm_xml.py b/virttest/libvirt_xml/vm_xml.py index f204cfee7..5676dffb6 100644 --- a/virttest/libvirt_xml/vm_xml.py +++ b/virttest/libvirt_xml/vm_xml.py @@ -296,14 +296,18 @@ def get_device_class(type_name): def undefine(self): """Undefine this VM with libvirt retaining XML in instance""" - # Allow any exceptions to propigate up - self.virsh.remove_domain(self.vm_name) + return self.virsh.remove_domain(self.vm_name) def define(self): """Define VM with virsh from this instance""" - # Allow any exceptions to propigate up - self.virsh.define(self.xml) + result = self.virsh.define(self.xml) + if result.exit_status: + logging.debug("Define %s failed.\n" + "Detail: %s." + % (self.vm_name, result.stderr)) + return False + return True @staticmethod diff --git a/virttest/virsh.py b/virttest/virsh.py index 803e8fa7f..bf4ab2d26 100644 --- a/virttest/virsh.py +++ b/virttest/virsh.py @@ -991,7 +991,7 @@ def define(xml_path, **dargs): def undefine(name, **dargs): """ - Return True on successful domain undefine (after shutdown/destroy). + Return cmd result of domain undefine (after shutdown/destroy). @param: name: VM name @param: dargs: standardized virsh function API keywords From e94f5ccf082bdb79bb83c5f589d612a58b2f6e60 Mon Sep 17 00:00:00 2001 From: Yu Mingfei Date: Tue, 16 Jul 2013 09:43:48 +0800 Subject: [PATCH 104/254] libvirt.tests: Fix testcases to new XML define-undefine. Signed-off-by: Yu Mingfei --- .../tests/src/virsh_cmd/domain/virsh_console.py | 9 ++++----- libvirt/tests/src/virsh_cmd/domain/virsh_start.py | 3 ++- .../tests/src/virsh_cmd/domain/virsh_ttyconsole.py | 9 ++++----- virttest/libvirt_xml/vm_xml.py | 14 +++++++------- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_console.py b/libvirt/tests/src/virsh_cmd/domain/virsh_console.py index e520743cd..fd64adf35 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_console.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_console.py @@ -17,12 +17,11 @@ def xml_console_recover(vmxml): """ Recover older xml config with backup vmxml. """ - try: - vmxml.undefine() - vmxml.define() + vmxml.undefine() + if vmxml.define(): return True - except xcepts.LibvirtXMLError, detail: - logging.error("Recover older serial failed:%s.", detail) + else: + logging.error("Recover older serial failed:%s.", vmxml.get('xml')) return False diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_start.py b/libvirt/tests/src/virsh_cmd/domain/virsh_start.py index b64666e9f..29bbc472a 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_start.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_start.py @@ -106,6 +106,7 @@ def run_virsh_start(test, params, env): utils_libvirtd.libvirtd_start() if (pre_operation == "undefine") and (not vmxml.xml == None): - vmxml.define() + if not vmxml.define(): + raise error.TestError("Restore vm failed.") elif pre_operation == "rename": libvirt_xml.VMXML.vm_rename(vm, backup_name) diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_ttyconsole.py b/libvirt/tests/src/virsh_cmd/domain/virsh_ttyconsole.py index 008bbaa17..8ac17f7b4 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_ttyconsole.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_ttyconsole.py @@ -17,12 +17,11 @@ def xml_console_recover(vmxml): """ Recover older xml config with backup vmxml. """ - try: - vmxml.undefine() - vmxml.define() + vmxml.undefine() + if vmxml.define(): return True - except xcepts.LibvirtXMLError, detail: - logging.error("Recover older serial failed:%s.", detail) + else: + logging.error("Recover older serial failed:%s.", vmxml.get('xml')) return False diff --git a/virttest/libvirt_xml/vm_xml.py b/virttest/libvirt_xml/vm_xml.py index 5676dffb6..523272c74 100644 --- a/virttest/libvirt_xml/vm_xml.py +++ b/virttest/libvirt_xml/vm_xml.py @@ -326,10 +326,7 @@ def vm_rename(vm, new_name, uuid=None, virsh_instance=base.virsh): virsh_instance=virsh_instance) backup = vmxml.copy() # can't do in-place rename, must operate on XML - try: - vmxml.undefine() - # All failures trip a single exception - except error.CmdError, detail: + if not vmxml.undefine(): del vmxml # clean up temporary files raise xcepts.LibvirtXMLError("Error reported while undefining VM:\n" "%s" % detail) @@ -344,14 +341,17 @@ def vm_rename(vm, new_name, uuid=None, virsh_instance=base.virsh): vm.uuid = uuid # Re-define XML to libvirt logging.debug("Rename %s to %s.", vm.name, new_name) + # error message for failed define + error_msg = "Error reported while defining VM:\n" try: - vmxml.define() + if not vmxml.define(): + raise xcepts.LibvirtXMLError(error_msg + "%s" + % vmxml.get('xml')) except error.CmdError, detail: del vmxml # clean up temporary files # Allow exceptions thrown here since state will be undefined backup.define() - raise xcepts.LibvirtXMLError("Error reported while defining VM:\n%s" - % detail) + raise xcepts.LibvirtXMLError(error_msg + "%s" % detail) # Keep names uniform vm.name = new_name return vm From c50b220afd328ab1a30fd50943b56763cf534cc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Doktor?= Date: Thu, 18 Jul 2013 09:39:56 +0200 Subject: [PATCH 105/254] virttest.qemu_devices: Fix in-code OrderedDict MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the correct implementation of itervalues() and add iteritems(). Signed-off-by: Lukáš Doktor --- virttest/qemu_devices.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/virttest/qemu_devices.py b/virttest/qemu_devices.py index a97c02f1c..0eb719211 100644 --- a/virttest/qemu_devices.py +++ b/virttest/qemu_devices.py @@ -26,7 +26,10 @@ class OrderedDict(dict): @warning: This is not the full OrderedDict implementation! """ def itervalues(self, *args, **kwargs): - return sorted(dict.itervalues(self, *args, **kwargs), + return (_[1] for _ in sorted(dict.iteritems(self, *args, **kwargs))) + + def iteritems(self, *args, **kwargs): + return sorted(dict.iteritems(self, *args, **kwargs), key=lambda item: item[0]) From 84637b0550e1dacdecdbadbe4f4e7d131e99076f Mon Sep 17 00:00:00 2001 From: Lucas Meneghel Rodrigues Date: Thu, 18 Jul 2013 14:01:42 -0300 Subject: [PATCH 106/254] virttest.libvirt_xml.vm_xml: Fix undefined variable error Signed-off-by: Lucas Meneghel Rodrigues --- virttest/libvirt_xml/vm_xml.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/virttest/libvirt_xml/vm_xml.py b/virttest/libvirt_xml/vm_xml.py index 523272c74..faa02581d 100644 --- a/virttest/libvirt_xml/vm_xml.py +++ b/virttest/libvirt_xml/vm_xml.py @@ -328,8 +328,7 @@ def vm_rename(vm, new_name, uuid=None, virsh_instance=base.virsh): # can't do in-place rename, must operate on XML if not vmxml.undefine(): del vmxml # clean up temporary files - raise xcepts.LibvirtXMLError("Error reported while undefining VM:\n" - "%s" % detail) + raise xcepts.LibvirtXMLError("Error reported while undefining VM") # Alter the XML vmxml.vm_name = new_name if uuid is None: From 46405eba954341f812f5e8aa413e104785a08d28 Mon Sep 17 00:00:00 2001 From: Amos Kong Date: Thu, 13 Jun 2013 15:29:35 +0800 Subject: [PATCH 107/254] monitor: fix pattern of float @ netdev_add type=tap,id=id1,fds=12:13 '12:13' would be wrongly matched as a float. '.' matches an arbitrary char, '\.' matches a dot. Signed-off-by: Amos Kong --- virttest/qemu_monitor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virttest/qemu_monitor.py b/virttest/qemu_monitor.py index 06ef26174..1e3358abc 100644 --- a/virttest/qemu_monitor.py +++ b/virttest/qemu_monitor.py @@ -1472,7 +1472,7 @@ def send_args_cmd(self, cmdlines, timeout=CMD_TIMEOUT, convert=True): try: if re.match("^[0-9]+$", opt[1]): value = int(opt[1]) - elif re.match("^[0-9]+.[0-9]*$", opt[1]): + elif re.match("^[0-9]+\.[0-9]*$", opt[1]): value = float(opt[1]) elif "True" in opt[1] or "true" in opt[1]: value = True From 247f904dabfedbd4065af9f6e4108e7b7a732d9f Mon Sep 17 00:00:00 2001 From: Amos Kong Date: Thu, 13 Jun 2013 13:56:16 +0800 Subject: [PATCH 108/254] enable mq feature in qemu cmdline/commands MQ was disabled in qemu by default, this patch enables it if user assigns multiple queues, hotplug cases will hotadd MQ nics. | commit 32ab06bcf1352848eec42629a85e20efa4e105dc | Author: Jesse Larrew | Date: Tue Feb 5 17:47:17 2013 -0600 | | hw/virtio-net: disable multiqueue by default | | The new multiqueue feature adds fields to the virtio device config, which | breaks Windows guests. Disable the feature by default until the Windows | drivers are fixed. Signed-off-by: Amos Kong --- qemu/tests/pci_hotplug.py | 11 +++++++---- virttest/qemu_vm.py | 13 ++++++++++--- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/qemu/tests/pci_hotplug.py b/qemu/tests/pci_hotplug.py index aac322941..37b7a4c46 100644 --- a/qemu/tests/pci_hotplug.py +++ b/qemu/tests/pci_hotplug.py @@ -77,7 +77,7 @@ def verify_supported_device(dev): (cmd_type, dev)) - def device_add_nic(pci_num): + def device_add_nic(pci_num, queues=1): device_id = pci_type + "-" + utils_misc.generate_random_id() pci_info.append([device_id, device_id]) @@ -87,6 +87,8 @@ def device_add_nic(pci_num): verify_supported_device(pci_model) pci_add_cmd = "device_add id=%s,driver=%s" % (pci_info[pci_num][1], pci_model) + if queues > 1 and "virtio" in pci_model: + pci_add_cmd += ",mq=on" return device_add(pci_num, pci_add_cmd) @@ -151,7 +153,7 @@ def device_add(pci_num, pci_add_cmd): # Hot add a pci device - def add_device(pci_num): + def add_device(pci_num, queues=1): info_pci_ref = vm.monitor.info("pci") reference = session.cmd_output(reference_cmd) @@ -164,7 +166,7 @@ def add_device(pci_num): after_add = None if add_fuction: # Do add pci device. - after_add = add_fuction(pci_num) + after_add = add_fuction(pci_num, queues) try: # Define a helper function to compare the output @@ -278,6 +280,7 @@ def _device_removed(): local_functions = locals() pci_num_range = int(params.get("pci_num")) + queues = int(params.get("queues")) rp_times = int(params.get("repeat_times")) img_list = params.get("images").split() context_msg = "Running sub test '%s' %s" @@ -297,7 +300,7 @@ def _device_removed(): utils_test.run_virt_sub_test(test, params, env, sub_type) error.context("Start hot-adding pci device, repeat %d" % j) - add_device(pci_num) + add_device(pci_num, queues) sub_type = params.get("sub_type_after_plug") if sub_type: diff --git a/virttest/qemu_vm.py b/virttest/qemu_vm.py index 5b79ce4d7..8616eebe7 100644 --- a/virttest/qemu_vm.py +++ b/virttest/qemu_vm.py @@ -793,7 +793,7 @@ def add_drive(devices, filename, index=None, fmt=None, cache=None, def add_nic(devices, vlan, model=None, mac=None, device_id=None, netdev_id=None, nic_extra_params=None, pci_addr=None, - bootindex=None): + bootindex=None, queues=1): if model == 'none': return if devices.has_option("device"): @@ -821,6 +821,8 @@ def add_nic(devices, vlan, model=None, mac=None, device_id=None, dev.set_param('model', model) dev.set_param('macaddr', mac, 'NEED_QUOTE') dev.set_param('id', device_id, 'NEED_QUOTE') + if int(queues) > 1 and "virtio" in model: + dev.set_param('mq', 'on') if devices.has_option("netdev"): dev.set_param('netdev', netdev_id) else: @@ -1636,12 +1638,15 @@ def add_option_rom(devices, opt_rom): else: tapfds = None ifname = nic.get('ifname') + queues = nic.get("queues", 1) # Handle the '-net nic' part + queues = nic.get("queues", 1) + add_nic(devices, vlan, nic_model, mac, device_id, netdev_id, nic_extra, nic_params.get("nic_pci_addr"), - bootindex) - queues = nic.get("queues", 1) + bootindex, queues) + # Handle the '-net tap' or '-net user' or '-netdev' part cmd = add_net(devices, vlan, nettype, ifname, tftp, bootp, redirs, netdev_id, netdev_extra, @@ -2968,6 +2973,8 @@ def activate_nic(self, nic_index_or_name): if nic.has_key('mac'): device_add_cmd += ",mac=%s" % nic.mac device_add_cmd += ",id=%s" % nic.nic_name + if int(nic['queues']) > 1 and nic['nic_model'] == 'virtio-net-pci': + device_add_cmd += ",mq=on" device_add_cmd += nic.get('nic_extra_params', '') if nic.has_key('romfile'): device_add_cmd += ",romfile=%s" % nic.romfile From 66b13a8dc255fdfa0cecd48625f403e26951f764 Mon Sep 17 00:00:00 2001 From: Amos Kong Date: Thu, 13 Jun 2013 16:31:43 +0800 Subject: [PATCH 109/254] update config file to assign the queue number Signed-off-by: Amos Kong --- shared/cfg/guest-hw.cfg | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shared/cfg/guest-hw.cfg b/shared/cfg/guest-hw.cfg index ca78e53c7..95b0ad119 100644 --- a/shared/cfg/guest-hw.cfg +++ b/shared/cfg/guest-hw.cfg @@ -8,6 +8,8 @@ variants: nic_model = e1000 - virtio_net: nic_model = virtio + # Assign the queue number of nic device + #queues = 4 # You can add advanced attributes on nic_extra_params such as mrg_rxbuf #nic_extra_params = # You can add advanced attributes through netdev_extra_params From 46ef8d808e92c0a0f7d03f46dd6df2d613b7490d Mon Sep 17 00:00:00 2001 From: Amos Kong Date: Thu, 13 Jun 2013 17:19:30 +0800 Subject: [PATCH 110/254] add testcase to enable MQ feature in guests Currently MQ feature was disabled by default in guests, it can be enabled by 'ethtool -L' This patch added a new testcase to enable all virtio-nic of all vms, it can be used to enable this feature before real tests. Signed-off-by: Amos Kong --- tests/cfg/enable_mq.cfg | 4 ++++ tests/enable_mq.py | 42 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 tests/cfg/enable_mq.cfg create mode 100644 tests/enable_mq.py diff --git a/tests/cfg/enable_mq.cfg b/tests/cfg/enable_mq.cfg new file mode 100644 index 000000000..43bb5076b --- /dev/null +++ b/tests/cfg/enable_mq.cfg @@ -0,0 +1,4 @@ +- enable_mq: install setup image_copy unattended_install.cdrom + virt_test_type = qemu libvirt + only Linux + type = enable_mq diff --git a/tests/enable_mq.py b/tests/enable_mq.py new file mode 100644 index 000000000..ea13cc7a6 --- /dev/null +++ b/tests/enable_mq.py @@ -0,0 +1,42 @@ +import logging, re +from autotest.client.shared import error +from virttest import utils_net + +@error.context_aware +def run_enable_mq(test, params, env): + """ + Enable MULTI_QUEUE feature in guest + + 1) Boot up VM(s) + 2) Login guests one by one + 3) Enable MQ for all virtio nics by ethtool -L + + @param test: QEMU test object. + @param params: Dictionary with the test parameters. + @param env: Dictionary with test environment. + """ + + login_timeout = int(params.get("login_timeout", 360)) + queues = int(params.get("queues", 1)) + vms = params.get("vms").split() + if queues == 1: + logging.info("No need to enable MQ feature for single queue") + return + + for vm in vms: + vm = env.get_vm(vm) + vm.verify_alive() + session = vm.wait_for_login(timeout=login_timeout) + for i, nic in enumerate(vm.virtnet): + if "virtio" in nic['nic_model']: + ifname = utils_net.get_linux_ifname(session, vm.get_mac_address(0)) + session.cmd_output("ethtool -L %s combined %d" + % (ifname, queues)) + o = session.cmd_output("ethtool -l %s" % ifname) + if len(re.findall("Combined:\s+%d\s" % queues, o)) != 2: + raise error.TestError("Fail to enable MQ feature of (%s)" + % nic.nic_name) + + logging.info("MQ feature of (%s) is enabled" % nic.nic_name) + + session.close() From 2b7b3de1ef963894402a762691440ff7850cfcf2 Mon Sep 17 00:00:00 2001 From: Lucas Meneghel Rodrigues Date: Wed, 17 Jul 2013 12:35:14 -0300 Subject: [PATCH 111/254] shared: Add GPG keys dir Signed-off-by: Lucas Meneghel Rodrigues --- shared/gpg/README | 1 + 1 file changed, 1 insertion(+) create mode 100644 shared/gpg/README diff --git a/shared/gpg/README b/shared/gpg/README new file mode 100644 index 000000000..9e2945f10 --- /dev/null +++ b/shared/gpg/README @@ -0,0 +1 @@ +You may add a file with your trusted GPG keys in this dir. From 67f94d74149b8140a51b75106e6145861beec3e6 Mon Sep 17 00:00:00 2001 From: Lucas Meneghel Rodrigues Date: Wed, 17 Jul 2013 17:11:38 -0300 Subject: [PATCH 112/254] virttest.build_helper: Fix problem with verifying signed tags Michael pointed out that there are 2 problems with the current implementation of the signed tags verification: 1) If the tag is signed by Malicious.Hacker@somewhere and you trick gpg into downloading this key, it will still happily accept the tag as long as it's in the server. 2) If one runs this test from her/his account, it will add random stuff to her/his .gnupg directory. In order to bypass chain of trust issues, the user will specify directly which keys are allowed, those keys will be copied to a special shared location on virt test (shared/gpg), the environment variable GNUPGHOME will be set to a temporary directory, the specified key will be imported and then the tag will be verified. CC: Michael S. Tirskin Signed-off-by: Lucas Meneghel Rodrigues --- qemu/cfg/build.cfg | 4 +++- virttest/build_helper.py | 28 +++++++++++++++++----------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/qemu/cfg/build.cfg b/qemu/cfg/build.cfg index 5fbd1afb9..10ed6b1a5 100644 --- a/qemu/cfg/build.cfg +++ b/qemu/cfg/build.cfg @@ -49,7 +49,9 @@ variants: #git_repo_qemu_tag = for_anthony # If tag_signed is provided, then we will be strict and verify the # tag. If the tag verification fails, the entire build test will fail. - #git_repo_qemu_tag_signed = pgp.mit.edu:AFBE8E67 + # A file with the trusted GPG keys should be put at shared/gpg. The + # build test will look for it. If not found, the test will fail. + #git_repo_qemu_tag_signed = mst.keys # SPICE installation from a GIT repo git_repo_spice_uri = git://anongit.freedesktop.org/spice/spice diff --git a/virttest/build_helper.py b/virttest/build_helper.py index 287990873..928e11f11 100644 --- a/virttest/build_helper.py +++ b/virttest/build_helper.py @@ -75,8 +75,7 @@ def _parse_params(self): else: logging.debug('Git repo %s tag: %s' % (self.name, self.tag)) - self.key_id = None - self.key_server = None + self.key_file = None tag_signed = self.params.get('%s_tag_signed' % config_prefix) if tag_signed is None: logging.warning('Git repo %s tag is not signed' % self.name) @@ -84,10 +83,15 @@ def _parse_params(self): 'made by whomever claims to have made it ' '(dangerous)') else: - self.key_server, self.key_id = tag_signed.split(":") - logging.debug('Git repo %s tag %s was signed with GPG key ID %s ' - 'present on key server %s', self.name, self.tag, - self.key_id, self.key_server) + self.key_file = os.path.join(data_dir.get_data_dir(), 'gpg', + tag_signed) + if os.path.isfile(self.key_file): + logging.debug('Git repo %s tag %s will be verified with public ' + 'key file %s', self.name, self.tag, self.key_file) + else: + raise error.TestError('GPG public key file %s not found, will ' + 'not proceed with testing' % + self.key_file) self.cmd = os_dep.command('git') @@ -106,12 +110,14 @@ def execute(self): if self.tag: utils.system('git checkout %s' % self.tag) - if self.key_server is not None and self.key_id is not None: + if self.key_file is not None: try: - logging.debug('Downloading GPG key ID %s from key server ' - '%s', self.key_id, self.key_server) - utils.system('gpg --batch --keyserver %s --recv-keys %s' % - (self.key_server, self.key_id)) + gnupg_home = os.path.join(os.path.dirname(self.key_file), + 'gnupg') + if not os.path.isdir(gnupg_home): + os.makedirs(gnupg_home) + os.environ['GNUPGHOME'] = gnupg_home + utils.system('gpg --import %s' % self.key_file) logging.debug('Verifying if tag is actually signed with ' 'GPG key ID %s' % self.key_id) utils.system('git tag -v %s' % self.tag) From 9c5f674b094ddd1d063e0735c1ea96daef97c71d Mon Sep 17 00:00:00 2001 From: Yunping Zheng Date: Thu, 20 Jun 2013 18:53:33 +0800 Subject: [PATCH 113/254] virt.test : Make file_transfer support vhostforce on and off This patch makes test file_transfer support vhostforce on and off. Signed-off-by: Yunping Zheng --- tests/cfg/file_transfer.cfg | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/cfg/file_transfer.cfg b/tests/cfg/file_transfer.cfg index 3e314eeb0..d23416705 100644 --- a/tests/cfg/file_transfer.cfg +++ b/tests/cfg/file_transfer.cfg @@ -6,3 +6,9 @@ variants: - remote: transfer_type = remote + variants: + - no_vhostforce: + - vhostforce_off: + netdev_extra_params_nic1 += ',vhostforce=off' + - vhostforce_on: + netdev_extra_params_nic1 += ',vhostforce=on' From 34e71261dc15130b8c0baed07ead8adfc9c9c5a5 Mon Sep 17 00:00:00 2001 From: Xiaoqing Wei Date: Fri, 19 Jul 2013 10:59:58 +0800 Subject: [PATCH 114/254] rename qcow3 to qcow2_v3 and disable it on unsupported hosts Signed-off-by: Xiaoqing Wei --- qemu/cfg/host-kernel.cfg | 2 ++ shared/cfg/guest-hw.cfg | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/qemu/cfg/host-kernel.cfg b/qemu/cfg/host-kernel.cfg index 83c16af07..f00aa68e9 100644 --- a/qemu/cfg/host-kernel.cfg +++ b/qemu/cfg/host-kernel.cfg @@ -27,6 +27,7 @@ variants: host_kernel_ver_str = Host_RHEL variants: - 5: + no qcow2v3 host_kernel_ver_str += ".5" monitor_type = human monitors = hmp1 @@ -84,6 +85,7 @@ variants: host_kernel_ver_str += ".9" requires_kernel = [">= 2.6.18-348", "< 2.6.19"] - 6: + no qcow2v3 # RHEL-6 pointer host_kernel_ver_str += ".6" netdev_peer_re = "\s{2,}(.*?):.*?peer=(.*?)\s" diff --git a/shared/cfg/guest-hw.cfg b/shared/cfg/guest-hw.cfg index 95b0ad119..2ce2cd8a8 100644 --- a/shared/cfg/guest-hw.cfg +++ b/shared/cfg/guest-hw.cfg @@ -85,8 +85,8 @@ variants: # placeholder variants: - - qcow3: - image_format = qcow2 + - qcow2v3: + image_format = qcow2v3 image_extra_params = "compat=1.1" - qcow2: image_format = qcow2 From 9c7331bd3d0e0beffafbb338926f0e5945a02560 Mon Sep 17 00:00:00 2001 From: Yu Mingfei Date: Thu, 18 Jul 2013 22:59:20 +0800 Subject: [PATCH 115/254] virttest.virsh: Allow pool-info return result. Signed-off-by: Yu Mingfei --- .../src/virsh_cmd/pool/virsh_pool_create_as.py | 15 +++++++++------ virttest/virsh.py | 8 +------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/libvirt/tests/src/virsh_cmd/pool/virsh_pool_create_as.py b/libvirt/tests/src/virsh_cmd/pool/virsh_pool_create_as.py index 29db5b495..b0dd33e00 100644 --- a/libvirt/tests/src/virsh_cmd/pool/virsh_pool_create_as.py +++ b/libvirt/tests/src/virsh_cmd/pool/virsh_pool_create_as.py @@ -28,7 +28,7 @@ def run_virsh_pool_create_as(test, params, env): else: os.makedirs(pool_target) - logging.info('Creating a %s type pool %s' % (pool_type, pool_name)) + logging.info('Creating a %s type pool %s', pool_type, pool_name) status = virsh.pool_create_as(pool_name, pool_type, pool_target, extra=pool_options, uri=virsh.canonical_uri()) @@ -36,15 +36,18 @@ def run_virsh_pool_create_as(test, params, env): status_error = params.get('status_error') if status_error == 'yes': if status: - raise error.TestFail("%d not a expected command return value" % status) + raise error.TestFail("%d not a expected command return value" + % status) else: logging.info("It's an expected error") elif status_error == 'no': - if not virsh.pool_info(pool_name, uri=virsh.canonical_uri()): + result = virsh.pool_info(pool_name, uri=virsh.canonical_uri()) + if result.exit_status: raise error.TestFail('Failed to check pool information') else: - logging.info('Pool %s is running' % pool_name) + logging.info('Pool %s is running', pool_name) if not status: - raise error.TestFail('%d not a expected command return value' % status) + raise error.TestFail('%d not a expected command return value' + % status) else: - logging.info('Succeed to create pool %s' % pool_name) + logging.info('Succeed to create pool %s', pool_name) diff --git a/virttest/virsh.py b/virttest/virsh.py index bf4ab2d26..43af3caf3 100644 --- a/virttest/virsh.py +++ b/virttest/virsh.py @@ -1398,13 +1398,7 @@ def pool_info(name, **dargs): @param: dargs: standardized virsh function API keywords """ cmd = "pool-info %s" % name - dargs['ignore_status'] = False - try: - command(cmd, **dargs) - return True - except error.CmdError, detail: - logging.error("Pool %s doesn't exist:\n%s", name, detail) - return False + return command(cmd, **dargs) def pool_destroy(name, **dargs): From ae1c7792e77e31f8debcef714c11607d69d95875 Mon Sep 17 00:00:00 2001 From: Yu Mingfei Date: Thu, 18 Jul 2013 22:49:01 +0800 Subject: [PATCH 116/254] libvirt.tests: Recover missing virsh_pool_create_as configuration. Signed-off-by: Yu Mingfei --- libvirt/tests/cfg/virsh_cmd/pool/virsh_pool_create_as.cfg | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 libvirt/tests/cfg/virsh_cmd/pool/virsh_pool_create_as.cfg diff --git a/libvirt/tests/cfg/virsh_cmd/pool/virsh_pool_create_as.cfg b/libvirt/tests/cfg/virsh_cmd/pool/virsh_pool_create_as.cfg new file mode 100644 index 000000000..ee2923008 --- /dev/null +++ b/libvirt/tests/cfg/virsh_cmd/pool/virsh_pool_create_as.cfg @@ -0,0 +1,7 @@ +- virsh_pool_create_as: + type = virsh_pool_create_as + vms = "" + # type in [ 'dir', 'fs', 'netfs', 'disk', 'iscsi', 'logical' ] + pool_type = dir + pool_name = custom_pool_name + pool_target = /mnt From 70605dc979a923da6a0a1b8e2f55b51d6ab06cac Mon Sep 17 00:00:00 2001 From: Yiqiao Pu Date: Fri, 19 Jul 2013 19:41:05 +0800 Subject: [PATCH 117/254] virttest.utils_misc: Add cpu model Opteron_G5 to get_host_cpu_models Add the new AMD cpu model to the the cpu_model list. Signed-off-by: Yiqiao Pu --- virttest/utils_misc.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/virttest/utils_misc.py b/virttest/utils_misc.py index 6d12d5cb1..be26b259f 100644 --- a/virttest/utils_misc.py +++ b/virttest/utils_misc.py @@ -1250,12 +1250,13 @@ def _make_up_pattern(flags): vendor_re = "vendor_id\s+:\s+(\w+)" cpu_flags_re = "flags\s+:\s+([\w\s]+)\n" - cpu_types = {"AuthenticAMD": ["Opteron_G4", "Opteron_G3", "Opteron_G2", - "Opteron_G1"], + cpu_types = {"AuthenticAMD": ["Opteron_G5", "Opteron_G4", "Opteron_G3", + "Opteron_G2", "Opteron_G1"], "GenuineIntel": ["SandyBridge", "Westmere", "Nehalem", "Penryn", "Conroe"]} - cpu_type_re = {"Opteron_G4": - "avx,xsave,aes,sse4.2|sse4_2,sse4.1|sse4_1,cx16,ssse3,sse4a", + cpu_type_re = {"Opteron_G5": "f16c,fma,tbm", + "Opteron_G4": + "avx,xsave,aes,sse4.2|sse4_2,sse4.1|sse4_1,cx16,ssse3,sse4a", "Opteron_G3": "cx16,sse4a", "Opteron_G2": "cx16", "Opteron_G1": "", From 55ab0fa5f4d69bad96bf54446236798ecd33deb2 Mon Sep 17 00:00:00 2001 From: yangdongsheng Date: Wed, 10 Jul 2013 11:59:54 +0800 Subject: [PATCH 118/254] env_process: preprocess_vm start_vm fix. (1). Introduce a param named "kill_vm_before_test". (2). Fix when restart_vm=yes. (3). Fix when vm need to paused. Signed-off-by: yangdongsheng --- virttest/env_process.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/virttest/env_process.py b/virttest/env_process.py index dee6b3fb6..eb8f65faa 100644 --- a/virttest/env_process.py +++ b/virttest/env_process.py @@ -73,6 +73,8 @@ def preprocess_vm(test, params, env, name): start_vm = False if params.get("restart_vm") == "yes": + if vm.is_alive(): + vm.destroy(gracefully=True, free_mac_addresses=False) start_vm = True elif params.get("migration_mode"): start_vm = True @@ -105,7 +107,10 @@ def preprocess_vm(test, params, env, name): if params.get("mac_changeable") == "yes": utils_net.update_mac_ip_address(vm, params) else: - # Don't start the VM, just update its params + # Update params of VM. + if params.get("kill_vm_before_test") == "yes": + # Destroy the VM if kill_vm_before_test = "yes". + vm.destroy(gracefully=True, free_mac_addresses=False) vm.devices = None vm.params = params @@ -114,7 +119,7 @@ def preprocess_vm(test, params, env, name): if params.get("paused_after_start_vm") == "yes": pause_vm = True # Check the status of vm - if not vm.is_alive(): + if (not vm.is_alive()) or (vm.is_paused()): pause_vm = False if pause_vm: From b62595bd599242c500d062b1a205df7a1a93ed46 Mon Sep 17 00:00:00 2001 From: yangdongsheng Date: Tue, 16 Jul 2013 09:10:52 +0800 Subject: [PATCH 119/254] Add kill_vm_before_test=no in base.cfg Signed-off-by: yangdongsheng --- shared/cfg/base.cfg | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/shared/cfg/base.cfg b/shared/cfg/base.cfg index 6b7778468..245e09aa5 100644 --- a/shared/cfg/base.cfg +++ b/shared/cfg/base.cfg @@ -316,9 +316,14 @@ restore_image = no # after the test runs (corruption checking, etc.) skip_image_processing = no -# Some preprocessor/postprocessor params +# Some preprocessor params +# If there is any conflict between 'start_vm' and 'kill_vm_before_test', +# the final desicion is made by start_vm. start_vm = yes +kill_vm_before_test = no paused_after_start_vm = no + +# Some postprocessor params kill_vm = no kill_vm_gracefully = yes kill_unresponsive_vms = yes From 32cfd67c61946ef3da42eaf0acc095f723a9914e Mon Sep 17 00:00:00 2001 From: Yiqiao Pu Date: Mon, 22 Jul 2013 15:39:13 +0800 Subject: [PATCH 120/254] virttest.env_process: Remove unused import libvirt_vm Signed-off-by: Yiqiao Pu --- virttest/env_process.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virttest/env_process.py b/virttest/env_process.py index eb8f65faa..5d8b3b09b 100644 --- a/virttest/env_process.py +++ b/virttest/env_process.py @@ -2,7 +2,7 @@ from autotest.client import utils from autotest.client.shared import error import aexpect, qemu_monitor, ppm_utils, test_setup, virt_vm -import libvirt_vm, video_maker, utils_misc, storage, qemu_storage, utils_libvirtd +import video_maker, utils_misc, storage, qemu_storage, utils_libvirtd import remote, data_dir, utils_net, utils_disk From a1ee5c31ae41920e14a90ec22433fb149db0f5b1 Mon Sep 17 00:00:00 2001 From: Xu Tian Date: Mon, 22 Jul 2013 17:35:41 +0800 Subject: [PATCH 121/254] disable hdparm test for virtio-scsi disk hdparm can't read sensor data from virtio-scsi disk, so disable it; Signed-off-by: Xu Tian --- qemu/tests/cfg/hdparm.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/qemu/tests/cfg/hdparm.cfg b/qemu/tests/cfg/hdparm.cfg index 713ee2462..0c2b97061 100644 --- a/qemu/tests/cfg/hdparm.cfg +++ b/qemu/tests/cfg/hdparm.cfg @@ -1,6 +1,7 @@ - hdparm: install setup image_copy unattended_install.cdrom only Linux no sd + no virtio_scsi type = hdparm get_disk_cmd = \ls /dev/[vhs]da low_status_cmd = hdparm -a64 -d0 -u0 %s From d5a828049e3ccaa2c5ee6d45deb1d7d6ed2b1216 Mon Sep 17 00:00:00 2001 From: Xu Tian Date: Mon, 22 Jul 2013 18:29:22 +0800 Subject: [PATCH 122/254] qemu.tests: disable lsi device on Host_RHEL6.5 and Host_RHEL7.0 since lsi device is not support by RHEL6.5 and RHEL.7.0 host, so disable it; And disable virtio-scsi on WinXP guest because it not support too; Signed-off-by: Xu Tian --- shared/cfg/guest-hw.cfg | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shared/cfg/guest-hw.cfg b/shared/cfg/guest-hw.cfg index 2ce2cd8a8..306101511 100644 --- a/shared/cfg/guest-hw.cfg +++ b/shared/cfg/guest-hw.cfg @@ -56,6 +56,7 @@ variants: # then kvm_vm will ignore this option. image_boot=yes - virtio_scsi: + no WinXP # supported formats are: scsi-hd, scsi-cd, scsi-disk, scsi-block, # scsi-generic # Use drive_format_$DISKNAME = "scsi-generic" to force disk driver @@ -70,6 +71,7 @@ variants: scsi_hba=spapr-vscsi only pseries - lsi_scsi: + no Host_RHEL drive_format=scsi-hd cd_format=scsi-cd scsi_hba=lsi53c895a From 745cd808f6ccbb25fb57dc3d1e88088e28ef8533 Mon Sep 17 00:00:00 2001 From: Xu Tian Date: Mon, 22 Jul 2013 20:21:31 +0800 Subject: [PATCH 123/254] virttest: fix save_to_file time when use qmp monitor when QMP monitor used, migrate complete check always failed until timeout; This commit update check method and raise QemuMigrationTimeout expection when migrate timeout; Signed-off-by: Xu Tian --- tests/cfg/boot_savevm.cfg | 1 + virttest/qemu_vm.py | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/cfg/boot_savevm.cfg b/tests/cfg/boot_savevm.cfg index 75e73e63d..061f6919b 100644 --- a/tests/cfg/boot_savevm.cfg +++ b/tests/cfg/boot_savevm.cfg @@ -14,6 +14,7 @@ - default_savevm: - with_floppy: + no Host_RHEL.7 virt_test_type = qemu save_method = save_to_tag with_floppy = yes diff --git a/virttest/qemu_vm.py b/virttest/qemu_vm.py index 8616eebe7..d46b23eb2 100644 --- a/virttest/qemu_vm.py +++ b/virttest/qemu_vm.py @@ -3415,7 +3415,9 @@ def save_to_file(self, path): self.monitor.migrate("exec:cat>%s" % path, wait=False) utils_misc.wait_for( # no monitor.migrate-status method - lambda : "status: completed" in self.monitor.info("migrate"), + lambda : + re.search("(status.*completed)", + str(self.monitor.info("migrate")), re.M), self.MIGRATE_TIMEOUT, 2, 2, "Waiting for save to %s to complete" % path) # Restore the speed and downtime to default values From 56425f4346209a09f3d73ae45d9563dbfe26cdfe Mon Sep 17 00:00:00 2001 From: Yunping Zheng Date: Tue, 23 Jul 2013 11:10:04 +0800 Subject: [PATCH 124/254] virt.tests.jumbo : Fix some issues of jumbo test make a check before delete an arp item. using 'get_win_wol' to get the drive number of win_utils Signed-off-by: Yunping Zheng --- tests/jumbo.py | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/tests/jumbo.py b/tests/jumbo.py index 58a24bea9..7373ab29f 100644 --- a/tests/jumbo.py +++ b/tests/jumbo.py @@ -1,4 +1,4 @@ -import logging, commands, random, re +import logging, commands, random from autotest.client.shared import error from autotest.client import utils from virttest import utils_misc, utils_test, utils_net @@ -23,19 +23,6 @@ def run_jumbo(test, params, env): @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ - def get_drive_num(session, path): - - """ - return file path drive - """ - cmd = "wmic datafile where \"path='%s'\" get drive" % path - info = session.cmd_output(cmd, timeout=360).strip() - drive_num = re.search(r'(\w):', info, re.M) - if not drive_num: - raise error.TestError("No path %s in your guest" % path) - return drive_num.group() - - timeout = int(params.get("login_timeout", 360)) mtu = params.get("mtu", "1500") max_icmp_pkt_size = int(mtu) - 28 @@ -75,9 +62,8 @@ def get_drive_num(session, path): "netconnectionid", connection_id, "pnpdeviceid") - devcon_path = r"\\devcon\\wxp_x86\\" - cd_num = get_drive_num(session, devcon_path) - copy_cmd = r"xcopy %s\devcon\wxp_x86\devcon.exe c:\ " % cd_num + cd_num = utils_misc.get_winutils_vol(session) + copy_cmd = r"xcopy %s:\devcon\wxp_x86\devcon.exe c:\ " % cd_num session.cmd(copy_cmd) @@ -180,5 +166,6 @@ def size_increase_ping(step=random.randrange(90, 110)): # Environment clean if session: session.close() - logging.info("Removing the temporary ARP entry") - utils.run("arp -d %s -i %s" % (ip, ifname)) + if utils.system("grep '%s.*%s' /proc/net/arp" % (ip, ifname)) == '0': + utils.run("arp -d %s -i %s" % (ip, ifname)) + logging.info("Removing the temporary ARP entry successfully") From c8a94ea26d0c54ed653279dbfd867a7cf4180d2e Mon Sep 17 00:00:00 2001 From: Yiqiao Pu Date: Wed, 21 Nov 2012 14:38:30 +0000 Subject: [PATCH 125/254] shared.deps.finish.bat: Add vds service start in finish.bat Start this service to ignore diskpart failed in some windows guests like win2003. Signed-off-by: Yiqiao Pu Acked-by: Xiaoqing Wei --- shared/deps/finish.bat | 1 + 1 file changed, 1 insertion(+) diff --git a/shared/deps/finish.bat b/shared/deps/finish.bat index 41f2beb4e..7015ea582 100644 --- a/shared/deps/finish.bat +++ b/shared/deps/finish.bat @@ -26,5 +26,6 @@ reg add "HKLM\System\CurrentControlSet\Control\CrashControl" /v DumpFile /d %Sys reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /v bsod /d "D:\autoit3.exe D:\dump_control.au3" /t REG_SZ /f reg add "HKLM\System\CurrentControlSet\Control\CrashControl" /v AlwaysKeepMemoryDump /d 1 /t REG_DWORD /f reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\Windows Error Reporting" /v Disabled /d 1 /t REG_DWORD /f +reg add "HKLM\SYSTEM\CurrentControlSet\Services\vds" /v Start /t REG_DWORD /d 3 /f echo Post set up finished> COM1 From 677ad7cb7e3f772dd1c0d55cf97de434495e64a7 Mon Sep 17 00:00:00 2001 From: Yiqiao Pu Date: Thu, 20 Jun 2013 17:07:21 +0800 Subject: [PATCH 126/254] tests: Add a function for copy image from nfs when install failed As this is a prepare case for test loops, we should make sure there is a good image for the rest of the tests. So will copy images from nfs if this case failed. Signed-off-by: Yiqiao Pu --- tests/unattended_install.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/unattended_install.py b/tests/unattended_install.py index 736c0da32..ef6b63616 100644 --- a/tests/unattended_install.py +++ b/tests/unattended_install.py @@ -831,6 +831,20 @@ def run_unattended_install(test, params, env): @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ + @error.context_aware + def copy_images(): + error.base_context("Copy image from NFS after installation failure") + image_copy_on_error = params.get("image_copy_on_error", "yes") + if "yes" in image_copy_on_error: + try: + error.context("Quit qemu-kvm before copying guest image") + vm.monitor.quit() + except Exception, e: + logging.warn(e) + from autotest.client.virt.tests import image_copy + error.context("Copy image from NFS Server") + image_copy.run_image_copy(test, params, env) + vm = env.get_vm(params["main_vm"]) unattended_install_config = UnattendedInstallConfig(test, params, vm) unattended_install_config.setup() @@ -862,7 +876,11 @@ def run_unattended_install(test, params, env): if params.get("wait_no_ack", "no") == "yes": break else: + # Print out the original exception before copying images. + logging.error(e) + copy_images() raise e + test.verify_background_errors() finish_signal = vm.serial_console.get_output() if (params.get("wait_no_ack", "no") == "no" and @@ -883,6 +901,9 @@ def run_unattended_install(test, params, env): else: time.sleep(1) else: + logging.warn("Timeout elapsed while waiting for install to finish." + "Will run image_copy to copy image from NFS.") + copy_images() raise error.TestFail("Timeout elapsed while waiting for install to " "finish") From da7e29417b901b45cf6083feb69b7a650d73b5df Mon Sep 17 00:00:00 2001 From: Feng Yang Date: Thu, 3 May 2012 09:08:55 +0000 Subject: [PATCH 127/254] shared.unattended: Make win2008r2 support key during installation. Multiple Activation Key (MAK) could not work in 2008r2 answer file in the WindowsPE phase of setup. Always get following error: The unattend answer file contains an invalid product key. Either remove the invalid key or provide a valid product key in the unattend answer file to proceed with Windows Installation So add key in Microsoft-Windows-Shell-Setup in component. http://technet.microsoft.com/en-us/library/cc749389%28v=ws.10%29.aspx Signed-off-by: Feng Yang Acked-by: Suqin Huang --- shared/unattended/win2008-32-autounattend.xml | 11 +++++++---- tests/unattended_install.py | 8 ++++++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/shared/unattended/win2008-32-autounattend.xml b/shared/unattended/win2008-32-autounattend.xml index fcf8766d6..f2404159d 100644 --- a/shared/unattended/win2008-32-autounattend.xml +++ b/shared/unattended/win2008-32-autounattend.xml @@ -74,10 +74,6 @@ - - KVM_TEST_CDKEY - OnError - true Autotest Mindless Drone Autotest @@ -85,6 +81,13 @@ false true + + KVM_TEST_CDKEY + Date: Fri, 25 May 2012 14:51:19 +0000 Subject: [PATCH 128/254] tests: Read serial output from the log file in unattended_install Read serial output from vm.serial will loss infos when do migrate operates. The migrate will start new session when boot up the dst guest. And the infos from src guest will loss in checkout step. This will cause the case can not get the finish strings. So use serail log file to instead it. changes from v1: - move fd.close to finally branch to ignore the multi open problem changes from v2: - to ignore the try:except:finally problem in python 2.4 use a old method. Signed-off-by: Yiqiao Pu Acked-by: Qingtang Zhou --- tests/unattended_install.py | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/tests/unattended_install.py b/tests/unattended_install.py index 99a627bf0..3c1781876 100644 --- a/tests/unattended_install.py +++ b/tests/unattended_install.py @@ -859,7 +859,7 @@ def copy_images(): post_finish_str = params.get("post_finish_str", "Post set up finished") - install_timeout = int(params.get("timeout", 3000)) + install_timeout = int(params.get("install_timeout", 3000)) migrate_background = params.get("migrate_background") == "yes" if migrate_background: @@ -871,6 +871,13 @@ def copy_images(): error.context("waiting for installation to finish") start_time = time.time() + + log_file = utils_misc.get_path(test.outputdir, + "debug/serial-%s.log" % vm.name)) + serial_log_msg = "" + serial_log_file = None + + while (time.time() - start_time) < install_timeout: try: vm.verify_alive() @@ -886,9 +893,20 @@ def copy_images(): raise e test.verify_background_errors() - finish_signal = vm.serial_console.get_output() + + # To ignore the try:except:finally problem in old version of python + try: + try: + serial_log_file = open(log_file, 'r') + serial_log_msg = serial_log_file.read() + except Exception, e: + logging.warn("Can not read from serail log file: %s", e) + finally: + if serial_log_file and not serial_log_file.closed: + serial_log_file.close() + if (params.get("wait_no_ack", "no") == "no" and - (post_finish_str in finish_signal)): + (post_finish_str in serial_log_msg)): break # Due to libvirt automatically start guest after import From 2e7594487a33051c2101408b40980770691d06d4 Mon Sep 17 00:00:00 2001 From: Qingtang Zhou Date: Tue, 30 Oct 2012 17:02:27 +0800 Subject: [PATCH 129/254] tests: unattended_install: Fix serial log file path The isa serial console's log file path is updated in commit 5e320327ecfb1ef25cc1656029b071a26ff1378d So we need to update unattended_install as well. Signed-off-by: Qingtang Zhou Update the serial log path to fit both control mode and standard alone mode. Singed-off-by: Yiqiao Pu --- tests/unattended_install.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/unattended_install.py b/tests/unattended_install.py index 3c1781876..65816d0e9 100644 --- a/tests/unattended_install.py +++ b/tests/unattended_install.py @@ -872,8 +872,14 @@ def copy_images(): start_time = time.time() - log_file = utils_misc.get_path(test.outputdir, - "debug/serial-%s.log" % vm.name)) + try: + serial_name = vm.serial_ports[0] + except IndexError: + raise virt_vm.VMConfigMissingError(vm.name, "isa_serial") + + log_file = utils_misc.get_path(test.debugdir, + "serial-%s-%s.log" % (serial_name, + vm.name)) serial_log_msg = "" serial_log_file = None From 8874044ee1eb49dd660535bfe90e7bf7a5791b60 Mon Sep 17 00:00:00 2001 From: Qingtang Zhou Date: Tue, 30 Oct 2012 17:02:51 +0800 Subject: [PATCH 130/254] tests: unattended_install: Create missing serial log file If the serial log file is missing, try to create an empty file to avoid redundant warning msg. Signed-off-by: Qingtang Zhou --- tests/unattended_install.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/unattended_install.py b/tests/unattended_install.py index 65816d0e9..aaf1c1aa5 100644 --- a/tests/unattended_install.py +++ b/tests/unattended_install.py @@ -1,6 +1,7 @@ import logging, time, re, os, tempfile, ConfigParser import threading import xml.dom.minidom +import errno from autotest.client.shared import error, iso9660 from autotest.client import utils from virttest import virt_vm, utils_misc, utils_disk @@ -906,7 +907,15 @@ def copy_images(): serial_log_file = open(log_file, 'r') serial_log_msg = serial_log_file.read() except Exception, e: - logging.warn("Can not read from serail log file: %s", e) + if e.errno == errno.ENOENT: + logging.warn("Log file '%s' doesn't exist," + " just create it.", log_file) + try: + open(log_file, 'w').close() + except Exception: + pass + else: + logging.warn("Can not read from serail log file: %s", e) finally: if serial_log_file and not serial_log_file.closed: serial_log_file.close() From 998e13529ffa9ed2689de4e6740f4bcd3c9f8cf4 Mon Sep 17 00:00:00 2001 From: Feng Yang Date: Thu, 8 Nov 2012 12:11:11 +0000 Subject: [PATCH 131/254] tests: Support copy iso file to local host in unattended_install.cdrom case. This patch is useful for performance testing. So comment it out by default. Changes from v3: Do not copy again, if file already there with same md5 value. Changes from v2: Check parameter available before using it. Changes from v1: Add copy_to_local parameter to set which file need copy to local host. Signed-off-by: Feng Yang --- tests/cfg/unattended_install.cfg | 7 +++++++ tests/unattended_install.py | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/tests/cfg/unattended_install.cfg b/tests/cfg/unattended_install.cfg index 9ce8961b9..d15f0522a 100644 --- a/tests/cfg/unattended_install.cfg +++ b/tests/cfg/unattended_install.cfg @@ -51,6 +51,13 @@ variants: # Install guest from cdrom - cdrom: + + # set copy_to_local if you want copy files from nfs to local host before testing. + # local_dir: local folder used to save nfs file, kvm folder will be used by default. + # Both absolute path and relative path are supported in local_dir + # local_dir = /root/ + # copy_to_local = cdrom_cd1 cdrom_winutils + # TODO: is this needed for both kvm and libvirt? # This option is only used in windows installation case, # since linux use kernel/initrd option of qemu. diff --git a/tests/unattended_install.py b/tests/unattended_install.py index aaf1c1aa5..3f4aff258 100644 --- a/tests/unattended_install.py +++ b/tests/unattended_install.py @@ -851,6 +851,30 @@ def copy_images(): image_copy.run_image_copy(test, params, env) vm = env.get_vm(params["main_vm"]) + local_dir = params.get("local_dir") + if local_dir: + local_dir = utils_misc.get_path(test.bindir, local_dir) + else: + local_dir = test.bindir + if params.get("copy_to_local"): + for param in params.get("copy_to_local").split(): + l_value = params.get(param) + if l_value: + need_copy = True + nfs_link = utils_misc.get_path(test.bindir, l_value) + i_name = os.path.basename(l_value) + local_link = os.path.join(local_dir, i_name) + if os.path.isfile(local_link): + file_hash = utils.hash_file(local_link, "md5") + expected_hash = utils.hash_file(nfs_link, "md5") + if file_hash == expected_hash: + need_copy = False + if need_copy: + msg = "Copy %s to %s in local host." % (i_name, local_link) + error.context(msg, logging.info) + utils.get_file(nfs_link, local_link) + params[param] = local_link + unattended_install_config = UnattendedInstallConfig(test, params, vm) unattended_install_config.setup() From 91113420401022553b3c79ec3ae2e44830de941a Mon Sep 17 00:00:00 2001 From: Yiqiao Pu Date: Fri, 21 Jun 2013 18:10:34 +0800 Subject: [PATCH 132/254] tests: Update the unattended install string update function Make the Windows guests unattended files can support more type of driver install. Signed-off-by: Yiqiao Pu --- tests/unattended_install.py | 64 +++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 17 deletions(-) diff --git a/tests/unattended_install.py b/tests/unattended_install.py index 3f4aff258..f0a537962 100644 --- a/tests/unattended_install.py +++ b/tests/unattended_install.py @@ -135,7 +135,14 @@ def __init__(self, test, params, vm): if self.install_virtio == 'yes': v_attributes = ['virtio_floppy', 'virtio_storage_path', 'virtio_network_path', 'virtio_oemsetup_id', - 'virtio_network_installer_path'] + 'virtio_network_installer_path', + 'virtio_balloon_installer_path', + 'virtio_qxl_installer_path', + 'virtio_scsi_cdrom'] + else: + v_attributes = ['virtio_balloon_installer_path', + 'virtio_qxl_installer_path'] + for va in v_attributes: setattr(self, va, params.get(va, '')) @@ -273,11 +280,18 @@ def answer_windows_ini(self, answer_path): else: driver = 'dir' - dummy_re = 'KVM_TEST_VIRTIO_NETWORK_INSTALLER' - installer = parser.get('GuiRunOnce', 'Command0') - if dummy_re in installer: - installer = re.sub(dummy_re, driver, installer) - parser.set('GuiRunOnce', 'Command0', installer) + dummy_re_dirver = {'KVM_TEST_VIRTIO_NETWORK_INSTALLER': + 'virtio_network_installer_path', + 'KVM_TEST_VIRTIO_BALLOON_INSTALLER': + 'virtio_balloon_installer_path', + 'KVM_TEST_VIRTIO_QXL_INSTALLER': + 'virtio_qxl_installer_path'} + dummy_re = "" + for dummy in dummy_re_dirver: + if dummy_re: + dummy_re += "|%s" % dummy + else: + dummy_re = dummy # Replace the process check in finish command dummy_process_re = r'\bPROCESS_CHECK\b' @@ -288,7 +302,11 @@ def answer_windows_ini(self, answer_path): "%s" % self.process_check, process_check) parser.set('GuiRunOnce', opt, process_check) - + elif re.findall(dummy_re, check): + dummy = re.findall(dummy_re, check)[0] + driver = getattr(self, dummy_re_dirver[dummy]) + check = re.sub(dummy, driver, check) + parser.set('GuiRunOnce', opt, check) # Now, writing the in memory config state to the unattended file fp = open(answer_path, 'w') parser.write(fp) @@ -341,22 +359,34 @@ def answer_windows_xml(self, answer_path): # Last but not least important, replacing the virtio installer command # And process check in finish command command_lines = doc.getElementsByTagName("CommandLine") + dummy_re_dirver = {'KVM_TEST_VIRTIO_NETWORK_INSTALLER': + 'virtio_network_installer_path', + 'KVM_TEST_VIRTIO_BALLOON_INSTALLER': + 'virtio_balloon_installer_path', + 'KVM_TEST_VIRTIO_QXL_INSTALLER': + 'virtio_qxl_installer_path'} + process_check_re = 'PROCESS_CHECK' + dummy_re = "" + for dummy in dummy_re_dirver: + if dummy_re: + dummy_re += "|%s" % dummy + else: + dummy_re = dummy + for command_line in command_lines: command_line_text = command_line.childNodes[0] assert command_line_text.nodeType == doc.TEXT_NODE - dummy_re = 'KVM_TEST_VIRTIO_NETWORK_INSTALLER' - process_check_re = 'PROCESS_CHECK' - if (self.install_virtio == 'yes' and - hasattr(self, 'virtio_network_installer_path')): - driver = self.virtio_network_installer_path - else: - driver = 'dir' - if driver.endswith("msi"): - driver = 'msiexec /passive /package ' + driver - if dummy_re in command_line_text.data: + + if re.findall(dummy_re, command_line_text.data): + dummy = re.findall(dummy_re, command_line_text.data)[0] + driver = getattr(self, dummy_re_dirver[dummy]) + + if driver.endswith("msi"): + driver = 'msiexec /passive /package ' + driver t = command_line_text.data t = re.sub(dummy_re, driver, t) command_line_text.data = t + if process_check_re in command_line_text.data: t = command_line_text.data t = re.sub(process_check_re, self.process_check, t) From d9909ccc0cf980db00f6142fe2eed1bb333aa3c8 Mon Sep 17 00:00:00 2001 From: Feng Yang Date: Fri, 21 Jun 2013 17:14:16 +0800 Subject: [PATCH 133/254] tests: Read driver id from inf file for Windows drivers Update the driver id according the inf file of driver for virtio drivers in Windows guests Signed-off-by: Feng Yang --- tests/unattended_install.py | 142 ++++++++++++++++++++++++++++++------ 1 file changed, 118 insertions(+), 24 deletions(-) diff --git a/tests/unattended_install.py b/tests/unattended_install.py index f0a537962..b739c74b3 100644 --- a/tests/unattended_install.py +++ b/tests/unattended_install.py @@ -6,7 +6,7 @@ from autotest.client import utils from virttest import virt_vm, utils_misc, utils_disk from virttest import qemu_monitor, remote, syslog_server -from virttest import http_server, data_dir, utils_net +from virttest import http_server, data_dir, utils_net, utils_test # Whether to print all shell commands called @@ -127,24 +127,24 @@ def __init__(self, test, params, vm): 'floppy_name', 'cdrom_unattended', 'boot_path', 'kernel_params', 'extra_params', 'qemu_img_binary', 'cdkey', 'finish_program', 'vm_type', - 'process_check', 'vfd_size'] + 'process_check', 'vfd_size', 'cdrom_mount_point', + 'floppy_mount_point', 'cdrom_virtio', + 'virtio_floppy', 're_driver_match', + 're_hardware_id', 'driver_in_floppy'] for a in self.attributes: setattr(self, a, params.get(a, '')) - if self.install_virtio == 'yes': - v_attributes = ['virtio_floppy', 'virtio_storage_path', - 'virtio_network_path', 'virtio_oemsetup_id', - 'virtio_network_installer_path', - 'virtio_balloon_installer_path', - 'virtio_qxl_installer_path', - 'virtio_scsi_cdrom'] - else: - v_attributes = ['virtio_balloon_installer_path', - 'virtio_qxl_installer_path'] + # Will setup the virtio attributes + v_attributes = ['virtio_floppy', 'virtio_storage_path', + 'virtio_network_path', 'virtio_oemsetup_id', + 'virtio_network_installer_path', + 'virtio_balloon_installer_path', + 'virtio_qxl_installer_path', + 'virtio_scsi_cdrom'] - for va in v_attributes: - setattr(self, va, params.get(va, '')) + for va in v_attributes: + setattr(self, va, params.get(va, '')) self.tmpdir = test.tmpdir @@ -170,6 +170,13 @@ def __init__(self, test, params, vm): if getattr(self, 'cdrom_unattended'): self.cdrom_unattended = os.path.join(root_dir, self.cdrom_unattended) + + if getattr(self, 'virtio_floppy'): + self.virtio_floppy = os.path.join(root_dir, self.virtio_floppy) + + if getattr(self, 'cdrom_virtio'): + self.cdrom_virtio = os.path.join(root_dir, self.cdrom_virtio) + if getattr(self, 'kernel'): self.kernel = os.path.join(root_dir, self.kernel) if getattr(self, 'initrd'): @@ -211,6 +218,91 @@ def __init__(self, test, params, vm): self.vm = vm + @error.context_aware + def get_driver_hardware_id(self, driver, run_cmd=True): + """ + Get windows driver's hardware id from inf files. + + @param dirver: Configurable driver name. + @param run_cmd: Use hardware id in windows cmd command or not. + @param return: Windows driver's hardware id + """ + if not os.path.exists(self.cdrom_mount_point): + os.mkdir(self.cdrom_mount_point) + if not os.path.exists(self.floppy_mount_point): + os.mkdir(self.floppy_mount_point) + if not os.path.ismount(self.cdrom_mount_point): + utils.system("mount %s %s -o loop" % (self.cdrom_virtio, + self.cdrom_mount_point), timeout=60) + if not os.path.ismount(self.floppy_mount_point): + utils.system("mount %s %s -o loop" % (self.virtio_floppy, + self.floppy_mount_point), timeout=60) + drivers_d = [] + driver_link = None + if self.driver_in_floppy is not None: + driver_in_floppy = self.driver_in_floppy + drivers_d = driver_in_floppy.split() + else: + drivers_d.append('qxl.inf') + for driver_d in drivers_d: + if driver_d in driver: + driver_link = os.path.join(self.floppy_mount_point, driver) + if driver_link is None: + driver_link = os.path.join(self.cdrom_mount_point, driver) + try: + txt = open(driver_link, "r").read() + hwid = re.findall(self.re_hardware_id, txt)[-1].rstrip() + if run_cmd: + hwid = '^&'.join(hwid.split('&')) + return hwid + except Exception, e: + logging.error("Fail to get hardware id with exception: %s" % e) + + + @error.context_aware + def update_driver_hardware_id(self, driver): + """ + Update driver string with the hardware id get from inf files + + @driver: driver string + @return new driver string + """ + if 'hwid' in driver: + if 'hwidcmd' in driver: + run_cmd = True + else: + run_cmd = False + if self.re_driver_match is not None: + d_str = self.re_driver_match + else: + d_str = "(\S+)\s*hwid" + + drivers_in_floppy = [] + if self.driver_in_floppy is not None: + drivers_in_floppy = self.driver_in_floppy.split() + + + mount_point = self.cdrom_mount_point + storage_path = self.cdrom_virtio + for driver_in_floppy in drivers_in_floppy: + if driver_in_floppy in driver: + mount_point = self.floppy_mount_point + storage_path = self.virtio_floppy + break + + d_link = re.findall(d_str, driver)[0].split(":")[1] + d_link = "/".join(d_link.split("\\\\")[1:]) + hwid = utils_test.get_driver_hardware_id(d_link, mount_point, + storage_path, + run_cmd=run_cmd) + if hwid: + driver = driver.replace("hwidcmd", hwid.strip()) + else: + raise error.TestError("Can not find hwid from the driver" + " inf file") + return driver + + def answer_kickstart(self, answer_path): """ Replace KVM_TEST_CDKEY (in the unattended file) with the cdkey @@ -274,12 +366,6 @@ def answer_windows_ini(self, answer_path): else: parser.remove_option('Unattended', 'OemPnPDriversPath') - # Replace the virtio installer command - if self.install_virtio == 'yes': - driver = self.virtio_network_installer_path - else: - driver = 'dir' - dummy_re_dirver = {'KVM_TEST_VIRTIO_NETWORK_INSTALLER': 'virtio_network_installer_path', 'KVM_TEST_VIRTIO_BALLOON_INSTALLER': @@ -296,15 +382,21 @@ def answer_windows_ini(self, answer_path): # Replace the process check in finish command dummy_process_re = r'\bPROCESS_CHECK\b' for opt in parser.options('GuiRunOnce'): - process_check = parser.get('GuiRunOnce', opt) - if re.search(dummy_process_re, process_check): + check = parser.get('GuiRunOnce', opt) + if re.search(dummy_process_re, check): process_check = re.sub(dummy_process_re, - "%s" % self.process_check, - process_check) + "%s" % self.process_check, + check) parser.set('GuiRunOnce', opt, process_check) elif re.findall(dummy_re, check): dummy = re.findall(dummy_re, check)[0] driver = getattr(self, dummy_re_dirver[dummy]) + if driver.endswith("msi"): + driver = 'msiexec /passive /package ' + driver + elif 'INSTALLER' in dummy: + driver = self.update_driver_hardware_id(driver) + elif driver is None: + driver = 'dir' check = re.sub(dummy, driver, check) parser.set('GuiRunOnce', opt, check) # Now, writing the in memory config state to the unattended file @@ -383,6 +475,8 @@ def answer_windows_xml(self, answer_path): if driver.endswith("msi"): driver = 'msiexec /passive /package ' + driver + elif 'INSTALLER' in dummy: + driver = self.update_driver_hardware_id(driver) t = command_line_text.data t = re.sub(dummy_re, driver, t) command_line_text.data = t From a35554ad220df2fb21907bd900c3abe155ec65fb Mon Sep 17 00:00:00 2001 From: Yiqiao Pu Date: Mon, 8 Jul 2013 15:17:43 +0800 Subject: [PATCH 134/254] virttest.utils_test: Update get_driver_hardware_id to ignore device is busy Update get_driver_hardware_id to close the txt_file before umount the driver disk for virtio drivers. Also update the re_hw_id. Signed-off-by: Yiqiao Pu --- virttest/utils_test.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/virttest/utils_test.py b/virttest/utils_test.py index 371f9df8a..4fdba0e9e 100644 --- a/virttest/utils_test.py +++ b/virttest/utils_test.py @@ -2227,7 +2227,7 @@ def find_substring(string, pattern1, pattern2=None): def get_driver_hardware_id(driver_path, mount_point="/tmp/mnt-virtio", storage_path="/tmp/prewhql.iso", - re_hw_id="(PCI.{14,50})\r\n", run_cmd=True): + re_hw_id="(PCI.{14,50})", run_cmd=True): """ Get windows driver's hardware id from inf files. @@ -2246,6 +2246,7 @@ def get_driver_hardware_id(driver_path, mount_point="/tmp/mnt-virtio", utils.system("mount %s %s -o loop" % (storage_path, mount_point), timeout=60) driver_link = os.path.join(mount_point, driver_path) + txt_file = "" try: txt_file = open(driver_link, "r") txt = txt_file.read() @@ -2257,7 +2258,9 @@ def get_driver_hardware_id(driver_path, mount_point="/tmp/mnt-virtio", return hwid except Exception, e: logging.error("Fail to get hardware id with exception: %s" % e) - utils.system("umount %s" % mount_point) + if txt_file: + txt_file.close() + utils.system("umount %s" % mount_point, ignore_status=True) return "" From 24dd981ba831004f734a4c2fefac122caf01c0a0 Mon Sep 17 00:00:00 2001 From: Yunping Zheng Date: Fri, 1 Feb 2013 10:52:42 +0000 Subject: [PATCH 135/254] tests: Win guest unattended_install support latest driver This patch modify win8 and win2012 using their own driver. This patch also make windows unattended_install support scsi disk and scsi cdrom. Signed-off-by: Yunping Zheng Acked-by: Suqin Huang --- tests/unattended_install.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/unattended_install.py b/tests/unattended_install.py index b739c74b3..21cac8a2d 100644 --- a/tests/unattended_install.py +++ b/tests/unattended_install.py @@ -435,6 +435,8 @@ def answer_windows_xml(self, answer_path): # component PnpCustomizationsWinPE Element Node if self.install_virtio == 'yes': paths = doc.getElementsByTagName("Path") + if self.virtio_scsi_cdrom == 'yes': + self.virtio_network_path = self.virtio_storage_path values = [self.virtio_storage_path, self.virtio_network_path] for path, value in zip(paths, values): path_text = path.childNodes[0] From bf71a5a2429cc2c4884056a01cf3443cf8534308 Mon Sep 17 00:00:00 2001 From: Yiqiao Pu Date: Tue, 9 Jul 2013 16:44:34 +0800 Subject: [PATCH 136/254] test: Store the boot disk to results dir Copy the boot disk to results dir for furthur debug especially for Windows guests. You can configure it by the store_boot_disk, and this is disabled by default. Signed-off-by: Yiqiao Pu --- tests/cfg/unattended_install.cfg | 5 +++++ tests/unattended_install.py | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/cfg/unattended_install.cfg b/tests/cfg/unattended_install.cfg index d15f0522a..b1b6f76f1 100644 --- a/tests/cfg/unattended_install.cfg +++ b/tests/cfg/unattended_install.cfg @@ -18,6 +18,11 @@ # Set migrate_background to yes to run migration in parallel # migrate_background = yes image_verify_bootable = no + # Copy boot image to results dir or not + # boot image will include the ks file or other files you need + # during install. Could be helpful to debug the install failed + # reasons. + # store_boot_disk = yes # Way of delivering ks file into the guest variants: diff --git a/tests/unattended_install.py b/tests/unattended_install.py index 21cac8a2d..dad2dbc38 100644 --- a/tests/unattended_install.py +++ b/tests/unattended_install.py @@ -1,5 +1,5 @@ import logging, time, re, os, tempfile, ConfigParser -import threading +import threading, shutil import xml.dom.minidom import errno from autotest.client.shared import error, iso9660 @@ -119,6 +119,7 @@ def __init__(self, test, params, vm): root_dir = data_dir.get_data_dir() self.deps_dir = os.path.join(test.virtdir, 'deps') self.unattended_dir = os.path.join(test.virtdir, 'unattended') + self.results_dir = test.debugdir self.params = params self.attributes = ['kernel_args', 'finish_program', 'cdrom_cd1', @@ -916,6 +917,12 @@ def setup(self): self.medium) if self.unattended_file and (self.floppy or self.cdrom_unattended): self.setup_boot_disk() + if self.params.get("store_boot_disk") == "yes": + logging.info("Sotre the boot disk to result directory for" + " further debug") + src_dir = self.floppy or self.cdrom_unattended + dst_dir = self.results_dir + shutil.copy(src_dir, dst_dir) # Update params dictionary as some of the values could be updated for a in self.attributes: From 6a8045cfa06809455a201411916dbbd3df6ac34a Mon Sep 17 00:00:00 2001 From: Yiqiao Pu Date: Wed, 10 Jul 2013 19:56:53 +0800 Subject: [PATCH 137/254] tests: Copy image when unattended install failed even in the start steps We use unattended install in test loops as an image prepare case. So we need it copy image from nfs if the case is failed. Otherwise the following cases in the test loop will failed because the image is not bootable. Signed-off-by: Yiqiao Pu --- tests/cfg/unattended_install.cfg | 4 ++++ tests/unattended_install.py | 31 ++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/tests/cfg/unattended_install.cfg b/tests/cfg/unattended_install.cfg index b1b6f76f1..9f3808dcf 100644 --- a/tests/cfg/unattended_install.cfg +++ b/tests/cfg/unattended_install.cfg @@ -23,6 +23,10 @@ # during install. Could be helpful to debug the install failed # reasons. # store_boot_disk = yes + # Backup images from nfs when install failed + # images_good = + # Mount point for your back up images + # dst_dir = # Way of delivering ks file into the guest variants: diff --git a/tests/unattended_install.py b/tests/unattended_install.py index dad2dbc38..358a534fe 100644 --- a/tests/unattended_install.py +++ b/tests/unattended_install.py @@ -7,6 +7,7 @@ from virttest import virt_vm, utils_misc, utils_disk from virttest import qemu_monitor, remote, syslog_server from virttest import http_server, data_dir, utils_net, utils_test +from virttest import funcatexit # Whether to print all shell commands called @@ -958,6 +959,15 @@ def terminate_syslog_server_thread(): return False +def copy_file_from_nfs(src, dst, mount_point, image_name): + logging.info("Test failed before the install process start." + " So just copy a good image from nfs for following tests.") + utils_misc.mount(src, mount_point, "nfs", perm="ro") + image_src = utils_misc.get_path(mount_point, image_name) + shutil.copy(image_src, dst) + utils_misc.umount(src, mount_point, "nfs") + + @error.context_aware def run_unattended_install(test, params, env): """ @@ -983,6 +993,15 @@ def copy_images(): error.context("Copy image from NFS Server") image_copy.run_image_copy(test, params, env) + image = '%s.%s' % (params['image_name'], params['image_format']) + image_name = os.path.basename(image) + src = params.get('images_good') + dst = '%s/%s' % (data_dir.get_data_dir(), image) + mount_point = params.get("dst_dir") + if mount_point and src: + funcatexit.register(env, params.get("type"), copy_file_from_nfs, src, + dst, mount_point, image_name) + vm = env.get_vm(params["main_vm"]) local_dir = params.get("local_dir") if local_dir: @@ -1041,6 +1060,12 @@ def copy_images(): serial_log_msg = "" serial_log_file = None + # As the the install process start. We may need collect informations from + # the image. So use the test case instead this simple function in the + # following code. + if mount_point and src: + funcatexit.unregister(env, params.get("type"), copy_file_from_nfs, + src, dst, mount_point, image_name) while (time.time() - start_time) < install_timeout: try: @@ -1056,7 +1081,11 @@ def copy_images(): copy_images() raise e - test.verify_background_errors() + try: + test.verify_background_errors() + except Exception, e: + copy_images() + raise e # To ignore the try:except:finally problem in old version of python try: From 294881dd0adbb430f3bdc07a4fba8697d8fe23ac Mon Sep 17 00:00:00 2001 From: Yiqiao Pu Date: Wed, 10 Jul 2013 20:41:08 +0800 Subject: [PATCH 138/254] shared.unattended: Update the unattended files Update the format of unattended files. Add some commands for Windows test enviroment prepare. Also enlarge the Windows image size to 30G as we will install more package inside the guests. For the RHEL guests ks, we update some package that we needed. And start X when guest booted up. Signed-off-by: Yiqiao Pu --- shared/cfg/guest-os/Windows.cfg | 1 + shared/cfg/guest-os/Windows/Win2003.cfg | 1 - shared/cfg/guest-os/Windows/Win2008.cfg | 1 - shared/cfg/guest-os/Windows/Win2012.cfg | 1 - shared/cfg/guest-os/Windows/Win7.cfg | 1 - shared/cfg/guest-os/Windows/Win8.cfg | 1 - shared/cfg/guest-os/Windows/WinVista.cfg | 1 - shared/unattended/RHEL-3-series.ks | 1 - shared/unattended/RHEL-4-series.ks | 5 +- shared/unattended/RHEL-5-series.ks | 3 + shared/unattended/RHEL-6-series.ks | 17 +- shared/unattended/win2003-32.sif | 44 ++-- shared/unattended/win2003-64.sif | 43 ++-- shared/unattended/win2008-32-autounattend.xml | 44 ++-- shared/unattended/win2008-64-autounattend.xml | 47 +++- shared/unattended/win2008-r2-autounattend.xml | 62 +++-- shared/unattended/win2012-autounattend.xml | 213 ++++++++++++++++++ shared/unattended/win7-32-autounattend.xml | 52 ++++- shared/unattended/win7-64-autounattend.xml | 48 +++- shared/unattended/win8-32-autounattend.xml | 211 +++++++++++++++++ shared/unattended/win8-64-autounattend.xml | 207 +++++++++++++++++ shared/unattended/winxp32.sif | 106 +++++---- 22 files changed, 954 insertions(+), 156 deletions(-) create mode 100644 shared/unattended/win2012-autounattend.xml create mode 100644 shared/unattended/win8-32-autounattend.xml create mode 100644 shared/unattended/win8-64-autounattend.xml diff --git a/shared/cfg/guest-os/Windows.cfg b/shared/cfg/guest-os/Windows.cfg index 72860012c..5a972a04e 100644 --- a/shared/cfg/guest-os/Windows.cfg +++ b/shared/cfg/guest-os/Windows.cfg @@ -1,6 +1,7 @@ - @Windows: vfd_size = 2880k os_type = windows + image_size = 30G use_libvirt_cdrom_switch = yes shutdown_command = shutdown /s /f /t 0 reboot_command = shutdown /r /f /t 0 diff --git a/shared/cfg/guest-os/Windows/Win2003.cfg b/shared/cfg/guest-os/Windows/Win2003.cfg index 7aec7d683..b4253b7f6 100644 --- a/shared/cfg/guest-os/Windows/Win2003.cfg +++ b/shared/cfg/guest-os/Windows/Win2003.cfg @@ -1,7 +1,6 @@ - Win2003: os_variant = win2k3 image_name = images/win2003 - image_size = 20G netperf_win.netperf_exe.best_registry_setting: shell_port = 23 shell_client = telnet diff --git a/shared/cfg/guest-os/Windows/Win2008.cfg b/shared/cfg/guest-os/Windows/Win2008.cfg index 0e823b327..ab55d5b72 100644 --- a/shared/cfg/guest-os/Windows/Win2008.cfg +++ b/shared/cfg/guest-os/Windows/Win2008.cfg @@ -1,7 +1,6 @@ - Win2008: os_variant = win2k8 image_name = images/win2008 - image_size = 20G netperf_win.netperf_exe.best_registry_setting: shell_port = 23 shell_client = telnet diff --git a/shared/cfg/guest-os/Windows/Win2012.cfg b/shared/cfg/guest-os/Windows/Win2012.cfg index 584b5ade2..c141d856e 100644 --- a/shared/cfg/guest-os/Windows/Win2012.cfg +++ b/shared/cfg/guest-os/Windows/Win2012.cfg @@ -1,7 +1,6 @@ - Win2012: image_name = images/win2012 guest_name = Win2012 - image_size = 30G shutdown_command = shutdown /s /f /t 0 reboot_command = shutdown /r /f /t 0 format_disk: diff --git a/shared/cfg/guest-os/Windows/Win7.cfg b/shared/cfg/guest-os/Windows/Win7.cfg index 79672b5d2..e4252c97d 100644 --- a/shared/cfg/guest-os/Windows/Win7.cfg +++ b/shared/cfg/guest-os/Windows/Win7.cfg @@ -1,7 +1,6 @@ - Win7: os_variant = win7 image_name = images/win7 - image_size = 20G whql.submission: desc_path_desc1 = $\WDK\Logo Type\Device Logo\Windows 7 Client\Logo desc_path_desc2 = $\WDK\Logo Type\Device Logo\Windows 7 Client diff --git a/shared/cfg/guest-os/Windows/Win8.cfg b/shared/cfg/guest-os/Windows/Win8.cfg index 431b3ce5c..85a3c6a96 100644 --- a/shared/cfg/guest-os/Windows/Win8.cfg +++ b/shared/cfg/guest-os/Windows/Win8.cfg @@ -1,7 +1,6 @@ - Win8: os_variant = win8 image_name = images/win8 - image_size = 30G shutdown_command = shutdown /s /f /t 0 reboot_command = shutdown /r /f /t 0 # it can be removed while bug 821741 is fixed diff --git a/shared/cfg/guest-os/Windows/WinVista.cfg b/shared/cfg/guest-os/Windows/WinVista.cfg index 5cc2e719c..8c0401aa1 100644 --- a/shared/cfg/guest-os/Windows/WinVista.cfg +++ b/shared/cfg/guest-os/Windows/WinVista.cfg @@ -1,7 +1,6 @@ - WinVista: os_variant = vista image_name = images/winvista - image_size = 20G whql.submission: desc_path_desc1 = $\WDK\Logo Type\Device Logo\Vista Client\Device Premium desc_path_desc2 = $\WDK\Logo Type\Device Logo\Vista Client\Device Standard diff --git a/shared/unattended/RHEL-3-series.ks b/shared/unattended/RHEL-3-series.ks index 3a8af3ee7..bc7721aa7 100644 --- a/shared/unattended/RHEL-3-series.ks +++ b/shared/unattended/RHEL-3-series.ks @@ -1,7 +1,6 @@ install KVM_TEST_MEDIUM text -reboot lang en_US.UTF-8 langsupport --default=en_US.UTF-8 en_US.UTF-9 keyboard us diff --git a/shared/unattended/RHEL-4-series.ks b/shared/unattended/RHEL-4-series.ks index 357dceb5e..e3e69c05a 100644 --- a/shared/unattended/RHEL-4-series.ks +++ b/shared/unattended/RHEL-4-series.ks @@ -1,13 +1,12 @@ install KVM_TEST_MEDIUM text -reboot lang en_US.UTF-8 langsupport --default=en_US.UTF-8 en_US.UTF-9 keyboard us network --bootproto dhcp rootpw 123456 -firewall --disabled +firewall --enabled --ssh selinux --enforcing timezone --utc America/New_York firstboot --disable @@ -31,6 +30,8 @@ redhat-lsb %post echo "OS install is completed" > /dev/ttyS0 +grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel) +grubby --args="divider=10" --update-kernel=$(grubby --default-kernel) cd home dhclient chkconfig sshd on diff --git a/shared/unattended/RHEL-5-series.ks b/shared/unattended/RHEL-5-series.ks index bc541046b..dc65ac421 100644 --- a/shared/unattended/RHEL-5-series.ks +++ b/shared/unattended/RHEL-5-series.ks @@ -13,6 +13,7 @@ timezone --utc America/New_York firstboot --disable bootloader --location=mbr --append="console=tty0 console=ttyS0,115200" zerombr +xconfig --startxonboot #partitioning clearpart --all --initlabel part /boot --fstype=ext3 --size=500 @@ -44,6 +45,8 @@ sg3_utils %post echo "OS install is completed" > /dev/ttyS0 +grubby --remove-args="rhgb quiet" --update-kernel=$(grubby --default-kernel) +grubby --args="divider=10 crashkernel=128M@16M" --update-kernel=$(grubby --default-kernel) dhclient chkconfig sshd on iptables -F diff --git a/shared/unattended/RHEL-6-series.ks b/shared/unattended/RHEL-6-series.ks index 291ad3a2a..577aca4d9 100644 --- a/shared/unattended/RHEL-6-series.ks +++ b/shared/unattended/RHEL-6-series.ks @@ -1,7 +1,6 @@ install KVM_TEST_MEDIUM text -reboot lang en_US.UTF-8 keyboard us key --skip @@ -13,6 +12,7 @@ timezone --utc America/New_York firstboot --disable bootloader --location=mbr --append="console=tty0 console=ttyS0,115200" zerombr +xconfig --startxonboot #partitioning clearpart --all --initlabel part /boot --fstype=ext4 --size=500 @@ -30,8 +30,22 @@ KVM_TEST_LOGGING @additional-devel @debugging-tools @network-tools +@basic-desktop +@desktop-platform +@fonts +@general-desktop +@graphical-admin-tools +@x11 +lftp +gcc +gcc-c++ +patch +make +git +nc NetworkManager ntpdate +redhat-lsb watchdog coreutils usbutils @@ -49,3 +63,4 @@ chkconfig NetworkManager on sed -i "/^HWADDR/d" /etc/sysconfig/network-scripts/ifcfg-eth0 echo 'Post set up finished' > /dev/ttyS0 echo Post set up finished > /dev/hvc0 +%end diff --git a/shared/unattended/win2003-32.sif b/shared/unattended/win2003-32.sif index 5d06d219b..c19e3228f 100644 --- a/shared/unattended/win2003-32.sif +++ b/shared/unattended/win2003-32.sif @@ -10,7 +10,7 @@ OemPreinstall = No UnattendSwitch = Yes CrashDumpSetting = 1 DriverSigningPolicy = ignore -OemPnPDriversPath = KVM_TEST_NETWORK_DRIVER_PATH +OemPnPDriversPath="KVM_TEST_NETWORK_DRIVER_PATH" WaitForReboot = no Repartition = yes @@ -23,20 +23,20 @@ TimeZone = 85 OemSkipWelcome = 1 [UserData] -ProductKey = KVM_TEST_CDKEY -FullName = "Autotest Mindless Drone" -OrgName = "Autotest" -ComputerName = * +ProductKey=KVM_TEST_CDKEY +FullName="Autotest Mindless Drone" +OrgName="Autotest" +ComputerName=* [LicenseFilePrintData] -AutoMode = PerServer -AutoUsers = 15 +AutoMode=PerServer +AutoUsers=15 [Identification] -JoinWorkgroup = WORKGROUP +JoinWorkgroup=WORKGROUP [Networking] -InstallDefaultComponents = Yes +InstallDefaultComponents=Yes [Components] @@ -50,17 +50,23 @@ Profiles = WindowsFirewall.TurnOffFirewall Mode = 0 [SetupParams] -local = "Local Area Connection" +local="Local Area Connection" [Display] -Xresolution = 1024 -YResolution = 768 +Xresolution=1024 +YResolution=768 [GuiRunOnce] -Command0 = "cmd /c KVM_TEST_VIRTIO_NETWORK_INSTALLER" -Command1 = "cmd /c sc config TlntSvr start= auto" -Command2 = "cmd /c netsh firewall set opmode disable" -Command3 = "cmd /c net start telnet" -Command4 = "cmd /c E:\setuprss.bat" -Command5 = "cmd /c netsh interface ip set address local dhcp" -Command6 = "cmd /c A:\finish.bat PROCESS_CHECK" +Command0="cmd /c echo OS install is completed > COM1" +Command1="cmd /c KVM_TEST_VIRTIO_NETWORK_INSTALLER" +Command2="cmd /c sc config TlntSvr start= auto" +Command3="cmd /c netsh firewall set opmode disable" +Command4="cmd /c net start telnet" +Command5="cmd /c E:\autoit3.exe E:\git\git.au3" +Command6="cmd /c E:\cfg\use_pmtmr.bat" +Command7="cmd /c netsh interface ip set address local dhcp" +Command8="cmd /c E:\setuprss.bat" +Command9="cmd /c start /wait E:\dotnetfx35.exe /lang:ENU /norestart /passive" +Command10="cmd /c E:\setupsp.bat" +Command11="cmd /c E:\software_install_32.bat" +Command12="cmd /c A:\finish.bat PROCESS_CHECK" diff --git a/shared/unattended/win2003-64.sif b/shared/unattended/win2003-64.sif index 5d06d219b..d64ab2168 100644 --- a/shared/unattended/win2003-64.sif +++ b/shared/unattended/win2003-64.sif @@ -10,7 +10,7 @@ OemPreinstall = No UnattendSwitch = Yes CrashDumpSetting = 1 DriverSigningPolicy = ignore -OemPnPDriversPath = KVM_TEST_NETWORK_DRIVER_PATH +OemPnPDriversPath="KVM_TEST_NETWORK_DRIVER_PATH" WaitForReboot = no Repartition = yes @@ -23,20 +23,20 @@ TimeZone = 85 OemSkipWelcome = 1 [UserData] -ProductKey = KVM_TEST_CDKEY -FullName = "Autotest Mindless Drone" -OrgName = "Autotest" -ComputerName = * +ProductKey=KVM_TEST_CDKEY +FullName="Autotest Mindless Drone" +OrgName="Autotest" +ComputerName=* [LicenseFilePrintData] -AutoMode = PerServer -AutoUsers = 15 +AutoMode=PerServer +AutoUsers=15 [Identification] -JoinWorkgroup = WORKGROUP +JoinWorkgroup=WORKGROUP [Networking] -InstallDefaultComponents = Yes +InstallDefaultComponents=Yes [Components] @@ -50,17 +50,22 @@ Profiles = WindowsFirewall.TurnOffFirewall Mode = 0 [SetupParams] -local = "Local Area Connection" +local="Local Area Connection" [Display] -Xresolution = 1024 -YResolution = 768 +Xresolution=1024 +YResolution=768 [GuiRunOnce] -Command0 = "cmd /c KVM_TEST_VIRTIO_NETWORK_INSTALLER" -Command1 = "cmd /c sc config TlntSvr start= auto" -Command2 = "cmd /c netsh firewall set opmode disable" -Command3 = "cmd /c net start telnet" -Command4 = "cmd /c E:\setuprss.bat" -Command5 = "cmd /c netsh interface ip set address local dhcp" -Command6 = "cmd /c A:\finish.bat PROCESS_CHECK" +Command0="cmd /c echo OS install is completed > COM1" +Command1="cmd /c KVM_TEST_VIRTIO_NETWORK_INSTALLER" +Command2="cmd /c sc config TlntSvr start= auto" +Command3="cmd /c netsh firewall set opmode disable" +Command4="cmd /c net start telnet" +Command5="cmd /c E:\autoit3.exe E:\git\git.au3" +Command6="cmd /c netsh interface ip set address local dhcp" +Command7="cmd /c E:\setuprss.bat" +Command8="cmd /c start /wait E:\dotnetfx35.exe /lang:ENU /norestart /passive" +Command9="cmd /c E:\setupsp.bat" +Command10="cmd /c E:\software_install_64.bat" +Command11="cmd /c A:\finish.bat PROCESS_CHECK" diff --git a/shared/unattended/win2008-32-autounattend.xml b/shared/unattended/win2008-32-autounattend.xml index f2404159d..2a943bb3d 100644 --- a/shared/unattended/win2008-32-autounattend.xml +++ b/shared/unattended/win2008-32-autounattend.xml @@ -39,7 +39,7 @@ 1 - 20000 + 30000 Primary @@ -64,7 +64,8 @@ /IMAGE/INDEX - 1 + + 3 @@ -74,6 +75,10 @@ + + KVM_TEST_CDKEY + OnError + true Autotest Mindless Drone Autotest @@ -81,13 +86,6 @@ false true - - KVM_TEST_CDKEY - 5 - %WINDIR%\System32\cmd /c bcdedit /set {current} bootstatuspolicy ignoreallfailures - 6 + %WINDIR%\System32\cmd /c E:\autoit3.exe E:\git\git.au3 + 6 - %WINDIR%\System32\cmd /c E:\setuprss.bat + %WINDIR%\System32\cmd /c bcdedit /set {current} bootstatuspolicy ignoreallfailures 7 @@ -164,9 +162,29 @@ 8 - %WINDIR%\System32\cmd /c A:\finish.bat PROCESS_CHECK + %WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_BALLOON_INSTALLER 9 + + %WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_QXL_INSTALLER + 10 + + + %WINDIR%\System32\cmd /c E:\setuprss.bat + 11 + + + %WINDIR%\System32\cmd /c E:\setupsp.bat + 12 + + + %WINDIR%\System32\cmd /c E:\software_install_32.bat + 13 + + + %WINDIR%\System32\cmd /c A:\finish.bat PROCESS_CHECK + 14 + 1 diff --git a/shared/unattended/win2008-64-autounattend.xml b/shared/unattended/win2008-64-autounattend.xml index f6af85d31..a4f06a556 100644 --- a/shared/unattended/win2008-64-autounattend.xml +++ b/shared/unattended/win2008-64-autounattend.xml @@ -12,7 +12,7 @@ 1 - 20000 + 30000 Primary @@ -36,7 +36,8 @@ /IMAGE/INDEX - 1 + + 3 @@ -138,41 +139,65 @@ - %WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_NETWORK_INSTALLER" + %WINDIR%\System32\cmd /c echo OS install is completed > COM1 1 - %WINDIR%\System32\cmd /c start /w pkgmgr /iu:"TelnetServer" + %WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_NETWORK_INSTALLER 2 - %WINDIR%\System32\cmd /c sc config TlntSvr start= auto + %WINDIR%\System32\cmd /c start /w pkgmgr /iu:"TelnetServer" 3 - %WINDIR%\System32\cmd /c netsh firewall set opmode disable + %WINDIR%\System32\cmd /c sc config TlntSvr start= auto 4 - %WINDIR%\System32\cmd /c net start telnet + %WINDIR%\System32\cmd /c netsh firewall set opmode disable 5 - %WINDIR%\System32\cmd /c bcdedit /set {current} bootstatuspolicy ignoreallfailures + %WINDIR%\System32\cmd /c net start telnet 6 - %WINDIR%\System32\cmd /c E:\setuprss.bat + %WINDIR%\System32\cmd /c bcdedit /set {current} bootstatuspolicy ignoreallfailures 7 - %WINDIR%\System32\cmd /c netsh interface ip set address "Local Area Connection" dhcp + %WINDIR%\System32\cmd /c E:\autoit3.exe E:\git\git.au3 8 - %WINDIR%\System32\cmd /c A:\finish.bat PROCESS_CHECK + %WINDIR%\System32\cmd /c netsh interface ip set address "Local Area Connection" dhcp 9 + + %WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_BALLOON_INSTALLER + 10 + + + %WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_QXL_INSTALLER + 11 + + + %WINDIR%\System32\cmd /c E:\setuprss.bat + 12 + + + %WINDIR%\System32\cmd /c E:\setupsp.bat + 13 + + + %WINDIR%\System32\cmd /c E:\software_install_64.bat + 14 + + + %WINDIR%\System32\cmd /c A:\finish.bat PROCESS_CHECK + 15 + true diff --git a/shared/unattended/win2008-r2-autounattend.xml b/shared/unattended/win2008-r2-autounattend.xml index f6af85d31..4fc3eef28 100644 --- a/shared/unattended/win2008-r2-autounattend.xml +++ b/shared/unattended/win2008-r2-autounattend.xml @@ -12,7 +12,7 @@ 1 - 20000 + 30000 Primary @@ -36,7 +36,8 @@ /IMAGE/INDEX - 1 + + 5 @@ -47,10 +48,6 @@ - - KVM_TEST_CDKEY - OnError - true Autotest Mindless Drone Autotest @@ -114,6 +111,13 @@ en-US en-US + + KVM_TEST_CDKEY + - %WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_NETWORK_INSTALLER" + %WINDIR%\System32\cmd /c echo OS install is completed > COM1 1 - %WINDIR%\System32\cmd /c start /w pkgmgr /iu:"TelnetServer" + %WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_NETWORK_INSTALLER" 2 - %WINDIR%\System32\cmd /c sc config TlntSvr start= auto + %WINDIR%\System32\cmd /c start /w pkgmgr /iu:"TelnetServer" 3 - %WINDIR%\System32\cmd /c netsh firewall set opmode disable + %WINDIR%\System32\cmd /c sc config TlntSvr start= auto 4 - %WINDIR%\System32\cmd /c net start telnet + %WINDIR%\System32\cmd /c netsh firewall set opmode disable 5 - %WINDIR%\System32\cmd /c bcdedit /set {current} bootstatuspolicy ignoreallfailures + %WINDIR%\System32\cmd /c net start telnet 6 - %WINDIR%\System32\cmd /c E:\setuprss.bat + %WINDIR%\System32\cmd /c bcdedit /set {current} bootstatuspolicy ignoreallfailures 7 - %WINDIR%\System32\cmd /c netsh interface ip set address "Local Area Connection" dhcp + %WINDIR%\System32\cmd /c E:\autoit3.exe E:\git\git.au3 8 - %WINDIR%\System32\cmd /c A:\finish.bat PROCESS_CHECK + %WINDIR%\System32\cmd /c bcdedit /set {current} USEPLATFORMCLOCK yes 9 + + %WINDIR%\System32\cmd /c netsh interface ip set address "Local Area Connection" dhcp + 10 + + + %WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_BALLOON_INSTALLER + 11 + + + %WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_QXL_INSTALLER + 12 + + + %WINDIR%\System32\cmd /c E:\setuprss.bat + 13 + + + %WINDIR%\System32\cmd /c E:\setupsp.bat + 14 + + + %WINDIR%\System32\cmd /c E:\software_install_64.bat + 15 + + + %WINDIR%\System32\cmd /c A:\finish.bat PROCESS_CHECK + 16 + true diff --git a/shared/unattended/win2012-autounattend.xml b/shared/unattended/win2012-autounattend.xml new file mode 100644 index 000000000..47e6b38db --- /dev/null +++ b/shared/unattended/win2012-autounattend.xml @@ -0,0 +1,213 @@ + + + + + + en-us + + 0409:00000409 + en-us + en-us + en-us + en-us + + + + + KVM_TEST_STORAGE_DRIVER_PATH + + + KVM_TEST_NETWORK_DRIVER_PATH + + + + + + OnError + + + + 1 + 30000 + Primary + + + + + true + false + NTFS + + C + 1 + 1 + + + 0 + true + + + + + + + /IMAGE/NAME + Windows Server 2012 SERVERDATACENTER + + + + 0 + 1 + + + + + + KVM_TEST_CDKEY + OnError + + true + + + + + + + + EnableAdmin + 1 + cmd /c net user Administrator /active:yes + + + UnfilterAdministratorToken + 2 + cmd /c reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v FilterAdministratorToken /t REG_DWORD /d 0 /f + + + + + 0409:00000409 + en-US + en-US + en-US + + + + + + + 1q2w3eP + true</PlainText> + </AdministratorPassword> + </UserAccounts> + <OOBE> + <HideEULAPage>true</HideEULAPage> + <NetworkLocation>Work</NetworkLocation> + <ProtectYourPC>1</ProtectYourPC> + <SkipUserOOBE>true</SkipUserOOBE> + <SkipMachineOOBE>true</SkipMachineOOBE> + </OOBE> + <AutoLogon> + <Password> + <Value>1q2w3eP</Value> + <PlainText>true</PlainText> + </Password> + <Enabled>true</Enabled> + <LogonCount>1000</LogonCount> + <Username>Administrator</Username> + </AutoLogon> + <FirstLogonCommands> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c echo OS install is completed > COM1</CommandLine> + <Order>1</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_NETWORK_INSTALLER</CommandLine> + <Order>2</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c start /w pkgmgr /iu:"TelnetServer"</CommandLine> + <Order>3</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c sc config TlntSvr start= auto</CommandLine> + <Order>4</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c netsh firewall set opmode disable</CommandLine> + <Order>5</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c net start telnet</CommandLine> + <Order>6</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c E:\autoit3.exe E:\git\git.au3</CommandLine> + <Order>7</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c bcdedit /set {current} USEPLATFORMCLOCK yes</CommandLine> + <Order>8</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c bcdedit /set {current} bootstatuspolicy ignoreallfailures</CommandLine> + <Order>9</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c netsh interface ip set address "Local Area Connection" dhcp</CommandLine> + <Order>10</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_BALLOON_INSTALLER</CommandLine> + <Order>11</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_QXL_INSTALLER</CommandLine> + <Order>12</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c E:\setuprss.bat</CommandLine> + <Order>13</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\Dism /online /enable-feature /featurename:NetFx3 /All /Source:D:\sources\sxs /LimitAccess</CommandLine> + <Order>14</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c E:\setupsp.bat</CommandLine> + <Order>15</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c A:\finish.bat PROCESS_CHECK</CommandLine> + <Order>16</Order> + </SynchronousCommand> + </FirstLogonCommands> + </component> + </settings> + <cpi:offlineImage cpi:source="wim:c:/install.wim#Windows Longhorn SERVERSTANDARD" + xmlns:cpi="urn:schemas-microsoft-com:cpi" /> +</unattend> diff --git a/shared/unattended/win7-32-autounattend.xml b/shared/unattended/win7-32-autounattend.xml index 878d1ce38..ae54717d6 100644 --- a/shared/unattended/win7-32-autounattend.xml +++ b/shared/unattended/win7-32-autounattend.xml @@ -40,7 +40,7 @@ <CreatePartitions> <CreatePartition wcm:action="add"> <Order>1</Order> - <Size>20000</Size> + <Size>30000</Size> <Type>Primary</Type> </CreatePartition> </CreatePartitions> @@ -136,41 +136,73 @@ </AutoLogon> <FirstLogonCommands> <SynchronousCommand wcm:action="add"> - <CommandLine>%WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_NETWORK_INSTALLER"</CommandLine> + <CommandLine>%WINDIR%\System32\cmd /c echo OS install is completed > COM1</CommandLine> <Order>1</Order> </SynchronousCommand> <SynchronousCommand wcm:action="add"> - <CommandLine>%WINDIR%\System32\cmd /c start /w pkgmgr /iu:"TelnetServer"</CommandLine> + <CommandLine>%WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_NETWORK_INSTALLER</CommandLine> <Order>2</Order> </SynchronousCommand> <SynchronousCommand wcm:action="add"> - <CommandLine>%WINDIR%\System32\cmd /c sc config TlntSvr start= auto</CommandLine> + <CommandLine>%WINDIR%\System32\cmd /c start /w pkgmgr /iu:"TelnetServer"</CommandLine> <Order>3</Order> </SynchronousCommand> <SynchronousCommand wcm:action="add"> - <CommandLine>%WINDIR%\System32\cmd /c netsh firewall set opmode disable</CommandLine> + <CommandLine>%WINDIR%\System32\cmd /c sc config TlntSvr start= auto</CommandLine> <Order>4</Order> </SynchronousCommand> <SynchronousCommand wcm:action="add"> - <CommandLine>%WINDIR%\System32\cmd /c net start telnet</CommandLine> + <CommandLine>%WINDIR%\System32\cmd /c netsh firewall set opmode disable</CommandLine> <Order>5</Order> </SynchronousCommand> <SynchronousCommand wcm:action="add"> - <CommandLine>%WINDIR%\System32\cmd /c bcdedit /set {current} bootstatuspolicy ignoreallfailures</CommandLine> + <CommandLine>%WINDIR%\System32\cmd /c net start telnet</CommandLine> <Order>6</Order> </SynchronousCommand> <SynchronousCommand wcm:action="add"> - <CommandLine>%WINDIR%\System32\cmd /c E:\setuprss.bat</CommandLine> + <CommandLine>%WINDIR%\System32\cmd /c E:\autoit3.exe E:\git\git.au3</CommandLine> <Order>7</Order> </SynchronousCommand> <SynchronousCommand wcm:action="add"> - <CommandLine>%WINDIR%\System32\cmd /c netsh interface ip set address "Local Area Connection" dhcp</CommandLine> + <CommandLine>%WINDIR%\System32\cmd /c bcdedit /set {current} USEPLATFORMCLOCK yes</CommandLine> <Order>8</Order> </SynchronousCommand> <SynchronousCommand wcm:action="add"> - <CommandLine>%WINDIR%\System32\cmd /c A:\finish.bat PROCESS_CHECK</CommandLine> + <CommandLine>%WINDIR%\System32\cmd /c bcdedit /set {current} bootstatuspolicy ignoreallfailures</CommandLine> <Order>9</Order> </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c E:\setuprss.bat</CommandLine> + <Order>10</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c netsh interface ip set address "Local Area Connection" dhcp</CommandLine> + <Order>11</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_BALLOON_INSTALLER</CommandLine> + <Order>12</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_QXL_INSTALLER</CommandLine> + <Order>13</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c E:\setuprss.bat</CommandLine> + <Order>14</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c E:\setupsp.bat</CommandLine> + <Order>15</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c E:\software_install_32.bat</CommandLine> + <Order>16</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c A:\finish.bat PROCESS_CHECK</CommandLine> + <Order>17</Order> + </SynchronousCommand> </FirstLogonCommands> </component> </settings> diff --git a/shared/unattended/win7-64-autounattend.xml b/shared/unattended/win7-64-autounattend.xml index 2321003f2..2bcb891bd 100644 --- a/shared/unattended/win7-64-autounattend.xml +++ b/shared/unattended/win7-64-autounattend.xml @@ -40,7 +40,7 @@ <CreatePartitions> <CreatePartition wcm:action="add"> <Order>1</Order> - <Size>20000</Size> + <Size>30000</Size> <Type>Primary</Type> </CreatePartition> </CreatePartitions> @@ -136,41 +136,69 @@ </AutoLogon> <FirstLogonCommands> <SynchronousCommand wcm:action="add"> - <CommandLine>%WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_NETWORK_INSTALLER"</CommandLine> + <CommandLine>%WINDIR%\System32\cmd /c echo OS install is completed > COM1</CommandLine> <Order>1</Order> </SynchronousCommand> <SynchronousCommand wcm:action="add"> - <CommandLine>%WINDIR%\System32\cmd /c start /w pkgmgr /iu:"TelnetServer"</CommandLine> + <CommandLine>%WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_NETWORK_INSTALLER</CommandLine> <Order>2</Order> </SynchronousCommand> <SynchronousCommand wcm:action="add"> - <CommandLine>%WINDIR%\System32\cmd /c sc config TlntSvr start= auto</CommandLine> + <CommandLine>%WINDIR%\System32\cmd /c start /w pkgmgr /iu:"TelnetServer"</CommandLine> <Order>3</Order> </SynchronousCommand> <SynchronousCommand wcm:action="add"> - <CommandLine>%WINDIR%\System32\cmd /c netsh firewall set opmode disable</CommandLine> + <CommandLine>%WINDIR%\System32\cmd /c sc config TlntSvr start= auto</CommandLine> <Order>4</Order> </SynchronousCommand> <SynchronousCommand wcm:action="add"> - <CommandLine>%WINDIR%\System32\cmd /c net start telnet</CommandLine> + <CommandLine>%WINDIR%\System32\cmd /c netsh firewall set opmode disable</CommandLine> <Order>5</Order> </SynchronousCommand> <SynchronousCommand wcm:action="add"> - <CommandLine>%WINDIR%\System32\cmd /c bcdedit /set {current} bootstatuspolicy ignoreallfailures</CommandLine> + <CommandLine>%WINDIR%\System32\cmd /c net start telnet</CommandLine> <Order>6</Order> </SynchronousCommand> <SynchronousCommand wcm:action="add"> - <CommandLine>%WINDIR%\System32\cmd /c E:\setuprss.bat</CommandLine> + <CommandLine>%WINDIR%\System32\cmd /c E:\autoit3.exe E:\git\git.au3</CommandLine> <Order>7</Order> </SynchronousCommand> <SynchronousCommand wcm:action="add"> - <CommandLine>%WINDIR%\System32\cmd /c netsh interface ip set address "Local Area Connection" dhcp</CommandLine> + <CommandLine>%WINDIR%\System32\cmd /c bcdedit /set {current} USEPLATFORMCLOCK yes</CommandLine> <Order>8</Order> </SynchronousCommand> <SynchronousCommand wcm:action="add"> - <CommandLine>%WINDIR%\System32\cmd /c A:\finish.bat PROCESS_CHECK</CommandLine> + <CommandLine>%WINDIR%\System32\cmd /c bcdedit /set {current} bootstatuspolicy ignoreallfailures</CommandLine> <Order>9</Order> </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c netsh interface ip set address "Local Area Connection" dhcp</CommandLine> + <Order>10</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_BALLOON_INSTALLER</CommandLine> + <Order>11</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_QXL_INSTALLER</CommandLine> + <Order>12</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c E:\setuprss.bat</CommandLine> + <Order>13</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c E:\setupsp.bat</CommandLine> + <Order>14</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c E:\software_install_64.bat</CommandLine> + <Order>15</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c A:\finish.bat PROCESS_CHECK</CommandLine> + <Order>16</Order> + </SynchronousCommand> </FirstLogonCommands> </component> </settings> diff --git a/shared/unattended/win8-32-autounattend.xml b/shared/unattended/win8-32-autounattend.xml new file mode 100644 index 000000000..3a02b3142 --- /dev/null +++ b/shared/unattended/win8-32-autounattend.xml @@ -0,0 +1,211 @@ +<?xml version="1.0" encoding="utf-8"?> +<unattend xmlns="urn:schemas-microsoft-com:unattend"> + <settings pass="windowsPE"> + <component name="Microsoft-Windows-International-Core-WinPE" + processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" + language="neutral" versionScope="nonSxS" + xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <SetupUILanguage> + <UILanguage>en-us</UILanguage> + </SetupUILanguage> + <InputLocale>0409:00000409</InputLocale> + <SystemLocale>en-us</SystemLocale> + <UILanguage>en-us</UILanguage> + <UILanguageFallback>en-us</UILanguageFallback> + <UserLocale>en-us</UserLocale> + </component> + <component name="Microsoft-Windows-PnpCustomizationsWinPE" + processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" + language="neutral" versionScope="nonSxS" + xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <DriverPaths> + <PathAndCredentials wcm:keyValue="1" wcm:action="add"> + <Path>KVM_TEST_STORAGE_DRIVER_PATH</Path> + </PathAndCredentials> + <PathAndCredentials wcm:keyValue="2" wcm:action="add"> + <Path>KVM_TEST_NETWORK_DRIVER_PATH</Path> + </PathAndCredentials> + </DriverPaths> + </component> + <component name="Microsoft-Windows-Setup" + processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" + language="neutral" versionScope="nonSxS" + xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <DiskConfiguration> + <WillShowUI>OnError</WillShowUI> + <Disk wcm:action="add"> + <CreatePartitions> + <CreatePartition wcm:action="add"> + <Order>1</Order> + <Size>30000</Size> + <Type>Primary</Type> + </CreatePartition> + </CreatePartitions> + <ModifyPartitions> + <ModifyPartition wcm:action="add"> + <Active>true</Active> + <Extend>false</Extend> + <Format>NTFS</Format> + <Label>OS_Install</Label> + <Letter>C</Letter> + <Order>1</Order> + <PartitionID>1</PartitionID> + </ModifyPartition> + </ModifyPartitions> + <DiskID>0</DiskID> + <WillWipeDisk>true</WillWipeDisk> + </Disk> + </DiskConfiguration> + <ImageInstall> + <OSImage> + <InstallTo> + <DiskID>0</DiskID> + <PartitionID>1</PartitionID> + </InstallTo> + </OSImage> + </ImageInstall> + <UserData> + <ProductKey> + <Key>KVM_TEST_CDKEY</Key> + <WillShowUI>OnError</WillShowUI> + </ProductKey> + <AcceptEula>true</AcceptEula> + </UserData> + </component> + </settings> + <settings pass="specialize"> + <component name="Microsoft-Windows-Deployment" + processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" + language="neutral" versionScope="nonSxS" + xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <RunSynchronous> + <RunSynchronousCommand wcm:action="add"> + <Description>EnableAdmin</Description> + <Order>1</Order> + <Path>cmd /c net user Administrator /active:yes</Path> + </RunSynchronousCommand> + <RunSynchronousCommand wcm:action="add"> + <Description>UnfilterAdministratorToken</Description> + <Order>2</Order> + <Path>cmd /c reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v FilterAdministratorToken /t REG_DWORD /d 0 /f</Path> + </RunSynchronousCommand> + </RunSynchronous> + </component> + <component name="Microsoft-Windows-International-Core" + processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" + language="neutral" versionScope="nonSxS" + xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <InputLocale>0409:00000409</InputLocale> + <SystemLocale>en-US</SystemLocale> + <UILanguage>en-US</UILanguage> + <UserLocale>en-US</UserLocale> + </component> + </settings> + <settings pass="oobeSystem"> + <component name="Microsoft-Windows-Shell-Setup" + processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" + language="neutral" versionScope="nonSxS" + xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <UserAccounts> + <AdministratorPassword> + <Value>1q2w3eP</Value> + <PlainText>true</PlainText> + </AdministratorPassword> + </UserAccounts> + <OOBE> + <HideEULAPage>true</HideEULAPage> + <NetworkLocation>Work</NetworkLocation> + <ProtectYourPC>1</ProtectYourPC> + <SkipUserOOBE>true</SkipUserOOBE> + <SkipMachineOOBE>true</SkipMachineOOBE> + </OOBE> + <AutoLogon> + <Password> + <Value>1q2w3eP</Value> + <PlainText>true</PlainText> + </Password> + <Enabled>true</Enabled> + <LogonCount>1000</LogonCount> + <Username>Administrator</Username> + </AutoLogon> + <FirstLogonCommands> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c echo OS install is completed > COM1</CommandLine> + <Order>1</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_NETWORK_INSTALLER</CommandLine> + <Order>2</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c start /w pkgmgr /iu:"TelnetServer"</CommandLine> + <Order>3</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c sc config TlntSvr start= auto</CommandLine> + <Order>4</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c netsh firewall set opmode disable</CommandLine> + <Order>5</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c net start telnet</CommandLine> + <Order>6</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c E:\autoit3.exe E:\git\git.au3</CommandLine> + <Order>7</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c bcdedit /set {current} USEPLATFORMCLOCK yes</CommandLine> + <Order>8</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c bcdedit /set {current} bootstatuspolicy ignoreallfailures</CommandLine> + <Order>9</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c E:\setuprss.bat</CommandLine> + <Order>10</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c netsh interface ip set address "Local Area Connection" dhcp</CommandLine> + <Order>11</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_BALLOON_INSTALLER</CommandLine> + <Order>12</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_QXL_INSTALLER</CommandLine> + <Order>13</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c E:\setuprss.bat</CommandLine> + <Order>14</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\Dism /online /enable-feature /featurename:NetFx3 /All /Source:D:\sources\sxs /LimitAccess</CommandLine> + <Order>15</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c E:\setupsp.bat</CommandLine> + <Order>16</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c A:\finish.bat PROCESS_CHECK</CommandLine> + <Order>17</Order> + </SynchronousCommand> + </FirstLogonCommands> + </component> + </settings> + <cpi:offlineImage cpi:source="wim:c:/install.wim#Windows Longhorn SERVERSTANDARD" + xmlns:cpi="urn:schemas-microsoft-com:cpi" /> +</unattend> diff --git a/shared/unattended/win8-64-autounattend.xml b/shared/unattended/win8-64-autounattend.xml new file mode 100644 index 000000000..03fc58f59 --- /dev/null +++ b/shared/unattended/win8-64-autounattend.xml @@ -0,0 +1,207 @@ +<?xml version="1.0" encoding="utf-8"?> +<unattend xmlns="urn:schemas-microsoft-com:unattend"> + <settings pass="windowsPE"> + <component name="Microsoft-Windows-International-Core-WinPE" + processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" + language="neutral" versionScope="nonSxS" + xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <SetupUILanguage> + <UILanguage>en-us</UILanguage> + </SetupUILanguage> + <InputLocale>0409:00000409</InputLocale> + <SystemLocale>en-us</SystemLocale> + <UILanguage>en-us</UILanguage> + <UILanguageFallback>en-us</UILanguageFallback> + <UserLocale>en-us</UserLocale> + </component> + <component name="Microsoft-Windows-PnpCustomizationsWinPE" + processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" + language="neutral" versionScope="nonSxS" + xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <DriverPaths> + <PathAndCredentials wcm:keyValue="1" wcm:action="add"> + <Path>KVM_TEST_STORAGE_DRIVER_PATH</Path> + </PathAndCredentials> + <PathAndCredentials wcm:keyValue="2" wcm:action="add"> + <Path>KVM_TEST_NETWORK_DRIVER_PATH</Path> + </PathAndCredentials> + </DriverPaths> + </component> + <component name="Microsoft-Windows-Setup" + processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" + language="neutral" versionScope="nonSxS" + xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <DiskConfiguration> + <WillShowUI>OnError</WillShowUI> + <Disk wcm:action="add"> + <CreatePartitions> + <CreatePartition wcm:action="add"> + <Order>1</Order> + <Size>30000</Size> + <Type>Primary</Type> + </CreatePartition> + </CreatePartitions> + <ModifyPartitions> + <ModifyPartition wcm:action="add"> + <Active>true</Active> + <Extend>false</Extend> + <Format>NTFS</Format> + <Label>OS_Install</Label> + <Letter>C</Letter> + <Order>1</Order> + <PartitionID>1</PartitionID> + </ModifyPartition> + </ModifyPartitions> + <DiskID>0</DiskID> + <WillWipeDisk>true</WillWipeDisk> + </Disk> + </DiskConfiguration> + <ImageInstall> + <OSImage> + <InstallTo> + <DiskID>0</DiskID> + <PartitionID>1</PartitionID> + </InstallTo> + </OSImage> + </ImageInstall> + <UserData> + <ProductKey> + <Key>KVM_TEST_CDKEY</Key> + <WillShowUI>OnError</WillShowUI> + </ProductKey> + <AcceptEula>true</AcceptEula> + </UserData> + </component> + </settings> + <settings pass="specialize"> + <component name="Microsoft-Windows-Deployment" + processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" + language="neutral" versionScope="nonSxS" + xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <RunSynchronous> + <RunSynchronousCommand wcm:action="add"> + <Description>EnableAdmin</Description> + <Order>1</Order> + <Path>cmd /c net user Administrator /active:yes</Path> + </RunSynchronousCommand> + <RunSynchronousCommand wcm:action="add"> + <Description>UnfilterAdministratorToken</Description> + <Order>2</Order> + <Path>cmd /c reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v FilterAdministratorToken /t REG_DWORD /d 0 /f</Path> + </RunSynchronousCommand> + </RunSynchronous> + </component> + <component name="Microsoft-Windows-International-Core" + processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" + language="neutral" versionScope="nonSxS" + xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <InputLocale>0409:00000409</InputLocale> + <SystemLocale>en-US</SystemLocale> + <UILanguage>en-US</UILanguage> + <UserLocale>en-US</UserLocale> + </component> + </settings> + <settings pass="oobeSystem"> + <component name="Microsoft-Windows-Shell-Setup" + processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" + language="neutral" versionScope="nonSxS" + xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <UserAccounts> + <AdministratorPassword> + <Value>1q2w3eP</Value> + <PlainText>true</PlainText> + </AdministratorPassword> + </UserAccounts> + <OOBE> + <HideEULAPage>true</HideEULAPage> + <NetworkLocation>Work</NetworkLocation> + <ProtectYourPC>1</ProtectYourPC> + <SkipUserOOBE>true</SkipUserOOBE> + <SkipMachineOOBE>true</SkipMachineOOBE> + </OOBE> + <AutoLogon> + <Password> + <Value>1q2w3eP</Value> + <PlainText>true</PlainText> + </Password> + <Enabled>true</Enabled> + <LogonCount>1000</LogonCount> + <Username>Administrator</Username> + </AutoLogon> + <FirstLogonCommands> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c echo OS install is completed > COM1</CommandLine> + <Order>1</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_NETWORK_INSTALLER</CommandLine> + <Order>2</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c start /w pkgmgr /iu:"TelnetServer"</CommandLine> + <Order>3</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c sc config TlntSvr start= auto</CommandLine> + <Order>4</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c netsh firewall set opmode disable</CommandLine> + <Order>5</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c net start telnet</CommandLine> + <Order>6</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c E:\autoit3.exe E:\git\git.au3</CommandLine> + <Order>7</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c bcdedit /set {current} USEPLATFORMCLOCK yes</CommandLine> + <Order>8</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c bcdedit /set {current} bootstatuspolicy ignoreallfailures</CommandLine> + <Order>9</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c netsh interface ip set address "Local Area Connection" dhcp</CommandLine> + <Order>10</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_BALLOON_INSTALLER</CommandLine> + <Order>11</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c KVM_TEST_VIRTIO_QXL_INSTALLER</CommandLine> + <Order>12</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c E:\setuprss.bat</CommandLine> + <Order>13</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\Dism /online /enable-feature /featurename:NetFx3 /All /Source:D:\sources\sxs /LimitAccess</CommandLine> + <Order>14</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c E:\setupsp.bat</CommandLine> + <Order>15</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%WINDIR%\System32\cmd /c A:\finish.bat PROCESS_CHECK</CommandLine> + <Order>16</Order> + </SynchronousCommand> + </FirstLogonCommands> + </component> + </settings> + <cpi:offlineImage cpi:source="wim:c:/install.wim#Windows Longhorn SERVERSTANDARD" + xmlns:cpi="urn:schemas-microsoft-com:cpi" /> +</unattend> diff --git a/shared/unattended/winxp32.sif b/shared/unattended/winxp32.sif index 5fc7c6f4c..6bfe8df28 100644 --- a/shared/unattended/winxp32.sif +++ b/shared/unattended/winxp32.sif @@ -1,76 +1,84 @@ [Data] -AutoPartition = 1 -MsDosInitiated = "0" -UnattendedInstall = "Yes" +AutoPartition=1 +MsDosInitiated="0" +UnattendedInstall="Yes" [Unattended] -Repartition = Yes -UnattendMode = FullUnattended -OemSkipEula = Yes -OemPreinstall = No -TargetPath = \WINDOWS -UnattendSwitch = Yes -CrashDumpSetting = 1 -DriverSigningPolicy = ignore -OemPnPDriversPath = KVM_TEST_NETWORK_DRIVER_PATH -WaitForReboot = no +Repartition=Yes +UnattendMode=FullUnattended +OemSkipEula=Yes +OemPreinstall=No +TargetPath=\WINDOWS +UnattendSwitch=Yes +CrashDumpSetting=1 +DriverSigningPolicy=ignore +OemPnPDriversPath="KVM_TEST_NETWORK_DRIVER_PATH" +WaitForReboot=no [GuiUnattended] -AdminPassword = "1q2w3eP" -EncryptedAdminPassword = NO -TimeZone = 85 -OemSkipWelcome = 1 -AutoLogon = Yes -AutoLogonCount = 1000 -OEMSkipRegional = 1 +AdminPassword="1q2w3eP" +EncryptedAdminPassword=NO +TimeZone=85 +OemSkipWelcome=1 +AutoLogon=Yes +AutoLogonCount=1000 +OEMSkipRegional=1 [UserData] -ProductKey = KVM_TEST_CDKEY -FullName = "Autotest Mindless Drone" -OrgName = "Autotest" -ComputerName = * +ProductKey=KVM_TEST_CDKEY +FullName="Autotest Mindless Drone" +OrgName="Autotest" +ComputerName=* [Identification] -JoinWorkgroup = WORKGROUP +JoinWorkgroup=WORKGROUP [Networking] -InstallDefaultComponents = Yes +InstallDefaultComponents=Yes [Proxy] -Proxy_Enable = 0 -Use_Same_Proxy = 0 +Proxy_Enable=0 +Use_Same_Proxy=0 [Components] -dialer = off -media_clips = off -media_utopia = off -msnexplr = off -netoc = off -OEAccess = off -templates = off -WMAccess = off -zonegames = off +dialer=off +media_clips=off +media_utopia=off +msnexplr=off +netoc=off +OEAccess=off +templates=off +WMAccess=off +zonegames=off [TerminalServices] -AllowConnections = 1 +AllowConnections=1 [WindowsFirewall] -Profiles = WindowsFirewall.TurnOffFirewall +Profiles=WindowsFirewall.TurnOffFirewall [WindowsFirewall.TurnOffFirewall] -Mode = 0 +Mode=0 [Branding] -BrandIEUsingUnattended = Yes +BrandIEUsingUnattended=Yes [Display] -Xresolution = 1024 -YResolution = 768 +Xresolution=1024 +YResolution=768 [GuiRunOnce] -Command0 = "cmd /c KVM_TEST_VIRTIO_NETWORK_INSTALLER" -Command1 = "cmd /c E:\setuprss.bat" -Command2 = "cmd /c netsh interface ip set address local dhcp" -Command3 = "cmd /c sc config tlntsvr start= auto" -Command4 = "cmd /c net start telnet" -Command5 = "cmd /c A:\finish.bat PROCESS_CHECK" +Command0="cmd /c echo OS install is completed > COM1" +Command1="cmd /c E:\autoit3.exe E:\git\git.au3" +Command2="cmd /c E:\cfg\screensave.bat" +Command3="cmd /c E:\cfg\use_pmtmr.bat" +Command4="cmd /c netsh interface ip set address local dhcp" +Command5="cmd /c E:\setuprss.bat" +Command6="cmd /c start /wait E:\dotnetfx35.exe /lang:ENU /norestart /passive" +Command7="cmd /c msiexec /i D:\SUPPORT\TOOLS\SUPTOOLS.MSI /q" +Command8="cmd /c md C:\sysprep & expand D:\SUPPORT\TOOLS\DEPLOY.CAB -F:* C:\sysprep" +Command9="cmd /c E:\setupsp.bat" +Command10="cmd /c sc config tlntsvr start= auto" +Command11="cmd /c net start telnet" +Command12="cmd /c E:\software_install_32.bat" +Command13="cmd /c A:\finish.bat PROCESS_CHECK" From cb7d7c26a523cbf1df8536ea7769b436c2d81f21 Mon Sep 17 00:00:00 2001 From: Yiqiao Pu <ypu@redhat.com> Date: Wed, 17 Jul 2013 19:20:22 +0800 Subject: [PATCH 139/254] test.cfg: Add some sub test in unattended install Add some sub test in unattended install. Signed-off-by: Yiqiao Pu <ypu@redhat.com> --- tests/cfg/unattended_install.cfg | 55 ++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/tests/cfg/unattended_install.cfg b/tests/cfg/unattended_install.cfg index 9f3808dcf..447d78c8c 100644 --- a/tests/cfg/unattended_install.cfg +++ b/tests/cfg/unattended_install.cfg @@ -27,7 +27,58 @@ # images_good = # Mount point for your back up images # dst_dir = - + variants: + - aio_native: + image_aio = native + - aio_threads: + image_aio = threads + # Add some special type install + variants: + - @default_install: + #install for performance + - perf: + - multi_disk_install: + no ide + only unattended_install..cdrom + images += " stg stg2 stg3 stg4 stg5 stg6 stg7 stg8 stg9 stg10 stg11 stg12 stg13 stg14 stg15 stg16 stg17 stg18 stg19 stg20 stg21 stg22 stg23 stg24" + image_name_stg = images/storage + image_name_stg2 = images/storage2 + image_name_stg3 = images/storage3 + image_name_stg4 = images/storage4 + image_name_stg5 = images/storage5 + image_name_stg6 = images/storage6 + image_name_stg7 = images/storage7 + image_name_stg8 = images/storage8 + image_name_stg9 = images/storage9 + image_name_stg10 = images/storage10 + image_name_stg11 = images/storage11 + image_name_stg12 = images/storage12 + image_name_stg13 = images/storage13 + image_name_stg14 = images/storage14 + image_name_stg15 = images/storage15 + image_name_stg16 = images/storage16 + image_name_stg17 = images/storage17 + image_name_stg18 = images/storage18 + image_name_stg19 = images/storage19 + image_name_stg20 = images/storage20 + image_name_stg21 = images/storage21 + image_name_stg22 = images/storage22 + image_name_stg23 = images/storage23 + image_name_stg24 = images/storage24 + image_name_stg25 = images/storage25 + image_size_equal = 1G + - large_image: + only unattended_install.cdrom + only qcow2 qcow2v3 + image_size_image1 = 2300G + image_size = 2300G + - with_migration: + migrate_background = yes + - setting_cluster_size: + # qemu-kvm bug 812705 + no Host_RHEL.5 + cluster_size = 4096 + only qcow2 qcow2v3 # Way of delivering ks file into the guest variants: # Additional iso with kickstart is attached into the guest @@ -47,7 +98,6 @@ unattended_delivery_method = url # Image with kickstart is attached into the guest as floppy drive - floppy_ks: - only Linux unattended_delivery_method = floppy # Only perform a libvirt import. No cdroms, no floppies, no nothing - import: @@ -56,7 +106,6 @@ cdroms = "" floppy = "" timeout = 180 - variants: # Install guest from cdrom - cdrom: From b1a08f2ac3c6a9d2156ad2b0c679255a6b94a538 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20=C5=BDupka?= <jzupka@redhat.com> Date: Thu, 20 Jun 2013 12:40:10 +0200 Subject: [PATCH 140/254] virt: Replace Versionable class with new version. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit new version pros) multiple version of class in one process change version of class by parameters passed by class factory. support of pickling. cons) It is necessary use factory and line with registration of module. For access to specific class version is necessary to use class manager. usage: from versionable_class import Manager, factory, VersionableClass #register module to class manager. Necessary for pickling. man = Manager(__name__) class VM1(object): @classmethod def _is_right_ver(cls, version): return True def __init__(self, *args, **kargs): super(VM1, self).__init__(*args, **kargs) def fn1(self): print "fn1_VM1" class VM_container(test_vers.VersionableClass): __master__ = VM1 o = test_vers.factory(VM_container) # return class o = o() # create instance of class o.fn1() Already used by openvswitch. Signed-off-by: Jiří Župka <jzupka@redhat.com> --- virttest/versionable_class.py | 493 +++++++++++++--------- virttest/versionable_class_unittest.py | 547 ++++++++++++++++--------- 2 files changed, 656 insertions(+), 384 deletions(-) diff --git a/virttest/versionable_class.py b/virttest/versionable_class.py index e0792e6fd..bab80ad79 100644 --- a/virttest/versionable_class.py +++ b/virttest/versionable_class.py @@ -1,267 +1,360 @@ +import sys, types + + """ -VersionableClass provides class hierarchy which automatically select the right -version of a class. Class manipulation is used for this reason. -""" +Versioning system provides class hierarchy which automatically select the right +version of a class. Class and module manipulation is used for this reason. +By this reason is: + Advantage) Only one class with some version is working in one process. + It is possible use class variables. Others version of same + class have different class variables. Supports pickling. + Much cleaner debugging and faster running of code than + using of __getattribute__. + Disadvantage) It is necessary create class with + fatory(orig_class, params for is_right_ver) + access to specific class through class Manager. -class VersionableClass(object): - """ - VersionableClass provides class hierarchy which automatically select right - version of class. Class manipulation is used for this reason. - By this reason is: - Advantage) Only one version is working in one process. Class is changed in - whole process. - Disadvantage) Only one version is working in one process. - Example of usage (in base_utils_unittest): +Example of usage (in versionable_class_unittest): - class FooC(object): - pass - #Not implemented get_version -> not used for versioning. - class VCP(FooC, VersionableClass): - def __new__(cls, *args, **kargs): - VCP.master_class = VCP - return super(VCP, cls).__new__(cls, *args, **kargs) - - def foo(self): - pass - - class VC2(VCP, VersionableClass): - @staticmethod - def get_version(): - return "get_version_from_system" - - @classmethod - def is_right_version(cls, version): - if version is not None: - if "version is satisfied": - return True - return False +# SIMPLE EXAPMLE - def func1(self): - print "func1" +from versionable_class import Manager, factory, VersionableClass +#register module to class manager. Necessary for pickling. +man = Manager(__name__) +# pylint: disable=E1003 - def func2(self): - print "func2" +class VM(object): + @classmethod + def _is_right_ver(cls, version): + return version < 1 - # get_version could be inherited. - class VC3(VC2, VersionableClass): - @classmethod - def is_right_version(cls, version): - if version is not None: - if "version+1 is satisfied": - return True - return False + def __init__(self, *args, **kargs): + super(VM, self).__init__(*args, **kargs) + + def fn1(self): + print "fn1_VM" - def func2(self): - print "func2_2" - class M(VCP): - pass - m = M() # <- When class is constructed the right version is - # automatically selected. In this case VC3 is selected. - m.func2() # call VC3.func2(m) - m.func1() # call VC2.func1(m) - m.foo() # call VC1.foo(m) +class VM1(VM): + @classmethod + def _is_right_ver(cls, version): + return version >= 1 - # When controlled "program" version is changed then is necessary call - check_repair_versions or recreate object. + def __init__(self, *args, **kargs): + super(VM1, self).__init__(*args, **kargs) - m.check_repair_versions() + def fn1(self): + print "fn1_VM1" - # priority of class. (change place where is method searched first in group - # of verisonable class.) +class VM_container(test_vers.VersionableClass): + __master__ = VM1 - class PP(VersionableClass): - def __new__(cls, *args, **kargs): - PP.master_class = PP - return super(PP, cls).__new__(cls, *args, **kargs) - class PP2(PP, VersionableClass): - @staticmethod - def get_version(): - return "get_version_from_system" +o = test_vers.factory(VM_container, version=0) # return class. +o = o() # create instance of class +p = test_vers.factory(VM_container, version=2)() +o.fn1() +p.fn1() - @classmethod - def is_right_version(cls, version): - if version is not None: - if "version is satisfied": - return True + +# ADVANCED EXAPMLE + +from versionable_class import Manager, factory, VersionableClass +man = Manager(__name__) +# pylint: disable=E1003 + + +def qemu_verison(): + return 2 + + +class VM(object): + __slot__ = ["cls"] + + test_class_vm1 = None + + @classmethod + def _is_right_ver(cls, *args, **kargs): + ver = None + if "qemu_version" in kargs: + ver = kargs['qemu_version'] + else: + ver = qemu_verison() + if ver < 1: + return True + else: return False - def func1(self): - print "PP func1" - class N(VCP, PP): + def __new__(cls, *args, **kargs): + return super(VM, cls).__new__(cls, *args, **kargs) + + + def __init__(self, *args, **kargs): + super(VM, self).__init__() + self.cls = self.__class__.__name__ + + + def __str__(self): + return "%s" % self.cls + + + def func1(self): + print "VM_func1" + + + def func3(self): pass - n = N() - n.func1() # -> "func2" +class VM1(VM): + __slot__ = ["VM1_cls"] + @classmethod + def _is_right_ver(cls, *args, **kargs): + ver = None + if "qemu_version" in kargs: + ver = kargs['qemu_version'] + else: + ver = qemu_verison() + if ver > 1: + return True + else: + return False + + def __init__(self, *args, **kargs): + super(VM1, self).__init__(*args, **kargs) + self.cls = self.__class__.__name__ + self.VM1_cls = "VM1" + - n.set_priority_class(PP, [VCP, PP]) + def __str__(self): + return "%s" % self.cls - n.func1() # -> "PP func1" - Necessary for using: - 1) Subclass of versionable class must have implemented class methods - get_version and is_right_version. These two methods are necessary - for correct version section. Class without this method will be never - chosen like suitable class. + def func1(self): + super(VM1, self).func1() - 2) Every class derived from master_class have to add to class definition - inheritance from VersionableClass. Direct inheritance from Versionable - Class is use like a mark for manipulation with VersionableClass. - 3) Master of VersionableClass have to defined class variable - cls.master_class. - """ + def func2(self): + print "func2" + + + def func3(self): + pass + + +class VM_container(VersionableClass): + __master__ = VM1 + def __new__(cls, *args, **kargs): - cls.check_repair_versions() - return super(VersionableClass, cls).__new__(cls, *args, **kargs) + return super(man[cls, VM_container], cls).__new__(cls, *args, **kargs) - #VersionableClass class management class. - @classmethod - def check_repair_versions(cls, master_classes=None): - """ - Check version of versionable class and if version not - match repair version to correct version. +class BB(VM_container): + test_class_bb = None - @param master_classes: Check and repair only master_class. - @type master_classes: list. - """ - if master_classes is None: - master_classes = cls._find_versionable_baseclass() - for base in master_classes: - cls._check_repair_version_class(base) + def __new__(cls, *args, **kargs): + return super(man[cls, BB], cls).__new__(cls, *args, **kargs) - @classmethod - def set_priority_class(cls, prioritized_class, group_classes): + def func1(self): + super(man[self.__class__, BB], self).func1() + + + def func2(self): + super(man[self.__class__, BB], self).func2() +""" + + +def isclass(obj): + """ + :param obj: Object for inspection if obj is class. + :return: true if the object is a class. + """ + return isinstance(obj, (type, types.ClassType)) + + +class ModuleWrapper(object): + """ + Wrapper around module. + + Necessary for pickling of dynamic class. + """ + def __init__(self, wrapped): """ - Set class priority. Limited only for change bases class priority inside - one subclass.__bases__ after that continue to another class. + :param wrapped: module for wrapping. + :type wrapped: Module. """ - def change_position(ccls): - if not VersionableClass in ccls.__bases__: - bases = list(ccls.__bases__) - - index = None - remove_variant = None - for i, item in enumerate(ccls.__bases__): - if (VersionableClass in item.__bases__ and - item.master_class in group_classes): - if index is None: - index = i - if item.master_class is prioritized_class: - remove_variant = item - bases.remove(item) - break - else: - return + self.wrapped = wrapped - bases.insert(index, remove_variant) - ccls.__bases__ = tuple(bases) - def find_cls(ccls): - change_position(ccls) - for base in ccls.__bases__: - find_cls(base) + def __dir__(self): + return dir(self.wrapped) - find_cls(cls) + def __getattr__(self, name): + """ + Override method `__getattr__` allows manipulate with modules. - @classmethod - def _check_repair_version_class(cls, master_class): - version = None - for class_version in master_class._find_versionable_subclass(): - try: - version = class_version.get_version() - if class_version.is_right_version(version): - cls._switch_by_class(class_version) - break - except NotImplementedError: - continue + :param name: Name of specific object. + :type name: string. + :return: specific class when name of class starts with managed or + normal attribute from wrapped class. + """ + if not name in self.wrapped.__dict__: + if name.startswith("managed"): + cls_name = name.split("_") + cls = self.wrapped.__dict__[cls_name[1]] + m_cls, _ = Manager(self.wrapped.__name__, self).factory(cls, + _class_names=cls_name) + return m_cls else: - cls._switch_by_class(class_version) + cls = getattr(self.wrapped, name) + return cls - @classmethod - def _find_versionable_baseclass(cls): +class VersionableClass(object): + """ + Class used for marking of mutable class. + """ + def __new__(cls, *args, **kargs): """ - Find versionable class in master class. + If this method is invoked it means that something went wrong because + this class should be replaced by :class:`Manager` factory. """ - ver_class = [] - for superclass in cls.mro(): - if VersionableClass in superclass.__bases__: - ver_class.append(superclass.master_class) - - return set(ver_class) + raise Exception("Class %s is not prepared for usage. " + "You have to call versionable_class.factory(cls) " + "before you can use it" % (cls)) - @classmethod - def _find_versionable_subclass(cls): +class Manager(object): + def __init__(self, name, wrapper=None): """ - Find versionable subclasses which subclass.master_class == cls + Manager for module. + + :param name: Name of module. + :type name: string + :param wrapper: Module dictionary wrapper. Should be None. """ - subclasses = [cls] - for sub in cls.__subclasses__(): - if VersionableClass in list(sub.__bases__): - subclasses.extend(sub._find_versionable_subclass()) - return subclasses + __import__(name) + if not wrapper: + if not isinstance(sys.modules[name], ModuleWrapper): + self.wrapper = ModuleWrapper(sys.modules[name]) + sys.modules[name] = self.wrapper + else: + self.wrapper = sys.modules[name] + else: + self.wrapper = wrapper - @classmethod - def _switch_by_class(cls, new_class): + def factory(self, _class, *args, **kargs): """ - Finds all class with same master_class as new_class in class tree - and replaces them by new_class. + Create new class with right version of subclasses. - @param new_class: Class for replacing. + Goes through class structure and search subclasses with right version. + + :param _class: Class which should be prepared. + :type _class: class. + :param *args: Params for _is_right_ver function. + :param *kargs: Params for _is_right_ver function. """ - def find_replace_class(bases): - for base in bases: - if (VersionableClass in base.__bases__ and - base.master_class == new_class.master_class): - bnew = list(bases) - bnew[bnew.index(base)] = new_class - return tuple(bnew) + def add_to_structure(cl, new_bases): + if VersionableClass in cl.__mro__: + cls, cls_vn = self.factory(cl, *args, **kargs) + new_bases.append(cls) + return cls_vn + else: + new_bases.append(cl) + return "" + + + _class_names = None + if "_class_names" in kargs: + _class_names = kargs["_class_names"] + if (_class.__name__.startswith("managed") and + hasattr(_class, "__original_class__")): + _class = _class.__original_class__ + new_bases = [] + cls_ver_name = "" + if VersionableClass in _class.__bases__: # parent is VersionableClass + for m_cls in _class.__bases__: + if m_cls is VersionableClass: + mro = _class.__master__.__mro__ # Find good version. + if _class_names: + for cl in mro[:-1]: + if cl.__name__ in _class_names: + cls_ver_name += "_" + cl.__name__ + cls_ver_name += add_to_structure(cl, new_bases) + break + else: + for cl in mro[:-1]: + if cl._is_right_ver(*args, **kargs): + cls_ver_name += "_" + cl.__name__ + cls_ver_name += add_to_structure(cl, new_bases) + break + else: + cls_ver_name += add_to_structure(m_cls, new_bases) + else: + for m_cls in _class.__bases__: + if (VersionableClass in m_cls.__mro__ or + hasattr(m_cls, "__original_class__")): + cls, cls_vn = self.factory(m_cls, *args, **kargs) + new_bases.append(cls) + cls_ver_name += cls_vn else: - bnew = find_replace_class(base.__bases__) - if bnew: - base.__bases__ = bnew + new_bases.append(m_cls) + class_name = "managed_%s%s" % (_class.__name__, cls_ver_name) - bnew = find_replace_class(cls.__bases__) - if bnew: - cls.__bases__ = bnew + if hasattr(self.wrapper.wrapped, class_name): + # Don't override already created class. + return self.wrapper.wrapped.__dict__[class_name], cls_ver_name + class_dict = _class.__dict__.copy() + class_dict["__original_class__"] = _class + cls = type(class_name, tuple(new_bases), class_dict) + self.wrapper.wrapped.__dict__[class_name] = cls - # Method defined in part below must be defined in - # verisonable class subclass. + return cls, cls_ver_name - @classmethod - def get_version(cls): - """ - Get version of installed OpenVSwtich. - Must be re-implemented for in child class. - @return: Version or None when get_version is unsuccessful. - """ - raise NotImplementedError("Method 'get_verison' must be" - " implemented in child class") + def __getitem__(self, o_cls): + return self.getcls(*o_cls) - @classmethod - def is_right_version(cls, version): + def getcls(self, cls, orig_class): """ - Check condition for select control class. - Function must be re-implemented in new OpenVSwitchControl class. - Must be re-implemented for in child class. + Return class correspond class and original class. + + :param cls: class for which should be found derived alternative. + :type cls: class + :param orig_class: Original class + :type orig_class: class - @param version: version of OpenVSwtich + :return: Derived alternative class + :rtype: class """ - raise NotImplementedError("Method 'is_right_version' must be" - " implemented in child class") + for m_cls in cls.__mro__: + if hasattr(m_cls, "__original_class__"): + if m_cls.__original_class__ is orig_class: + return m_cls + elif m_cls is orig_class: + return m_cls + raise Exception("Couldn't find derived alternative in %s for" + " class %s" % (cls, orig_class)) + + +def factory(orig_cls, *args, **kargs): + """ + Create class with specific version. + + :param orig_class: Class from which should be derived good version. + :param *args: list of parameters for _ir_right_ver + :param *kargs: dict of named parameters for _ir_right_ver + :return: params specific class. + :rtype: class + """ + return Manager(orig_cls.__module__).factory(orig_cls, *args, **kargs)[0] diff --git a/virttest/versionable_class_unittest.py b/virttest/versionable_class_unittest.py index 34a808296..5f1b4dfe1 100755 --- a/virttest/versionable_class_unittest.py +++ b/virttest/versionable_class_unittest.py @@ -1,13 +1,283 @@ #!/usr/bin/python -import unittest, logging +import unittest, cPickle, sys try: import autotest.common as common except ImportError: import common from autotest.client.shared import base_utils from autotest.client.shared.test_utils import mock -import versionable_class +from versionable_class import Manager, factory, VersionableClass +man = Manager(__name__) + +# pylint: disable=E1003 + + +def qemu_verison(): + return 2 + + +class VM(object): + __slot__ = ["cls"] + + test_class_vm1 = None + + @classmethod + def _is_right_ver(cls, *args, **kargs): + ver = None + if "qemu_version" in kargs: + ver = kargs['qemu_version'] + else: + ver = qemu_verison() + if ver < 1: + return True + else: + return False + + + def __new__(cls, *args, **kargs): + return super(VM, cls).__new__(cls, *args, **kargs) + + + def __init__(self, *args, **kargs): + super(VM, self).__init__() + self.cls = self.__class__.__name__ + + + def __str__(self): + return "%s" % self.cls + + + def func1(self): + print "VM_func1" + + + def func3(self): + pass + + +class VM1(VM): + __slot__ = ["VM1_cls"] + @classmethod + def _is_right_ver(cls, *args, **kargs): + ver = None + if "qemu_version" in kargs: + ver = kargs['qemu_version'] + else: + ver = qemu_verison() + if ver > 1: + return True + else: + return False + + def __init__(self, *args, **kargs): + super(VM1, self).__init__(*args, **kargs) + self.cls = self.__class__.__name__ + self.VM1_cls = "VM1" + + + def __str__(self): + return "%s" % self.cls + + + def func1(self): + super(VM1, self).func1() + + + def func2(self): + print "func2" + + + def func3(self): + pass + + +class VM_container(VersionableClass): + __master__ = VM1 + + def __new__(cls, *args, **kargs): + return super(man[cls, VM_container], cls).__new__(cls, *args, **kargs) + + +class BB(VM_container): + test_class_bb = None + + def __new__(cls, *args, **kargs): + return super(man[cls, BB], cls).__new__(cls, *args, **kargs) + + + def func1(self): + super(man[self.__class__, BB], self).func1() + + + def func2(self): + super(man[self.__class__, BB], self).func2() + + +def system_version(): + return 2 + + +class System(object): + @classmethod + def _is_right_ver(cls, *args, **kargs): + ver = None + if "system_version" in kargs: + ver = kargs['system_version'] + else: + ver = system_version() + if ver < 1: + return True + else: + return False + + + def __init__(self, *args, **kargs): + super(System, self).__init__() + self.aa = self.__class__.__name__ + + + def __str__(self): + return "VM1 %s" % self.aa + + + +class System1(System): + @classmethod + def _is_right_ver(cls, *args, **kargs): + ver = None + if "system_version" in kargs: + ver = kargs['system_version'] + else: + ver = system_version() + if ver > 1: + return True + else: + return False + + def __init__(self, *args, **kargs): + super(System1, self).__init__(*args, **kargs) + self.aa = self.__class__.__name__ + + + def __str__(self): + return "VM1 %s" % self.aa + + +class System_Container(VersionableClass): + __master__ = System1 + + def __new__(cls, *args, **kargs): + return super(man[cls, System_Container], cls).__new__(cls, *args, **kargs) + + +class Q(object): + @classmethod + def _is_right_ver(cls, *args, **kargs): + ver = None + if "q_version" in kargs: + ver = kargs['q_version'] + else: + ver = system_version() + if ver < 1: + return True + else: + return False + + + def __init__(self, *args, **kargs): + super(Q, self).__init__() + self.cls = self.__class__.__name__ + + + def __str__(self): + return "%s" % self.cls + + + +class Q1(Q): + @classmethod + def _is_right_ver(cls, *args, **kargs): + ver = None + if "q_version" in kargs: + ver = kargs['q_version'] + else: + ver = system_version() + if ver > 1: + return True + else: + return False + + def __init__(self, *args, **kargs): + super(man[self.__class__, Q1], self).__init__(*args, **kargs) + self.cls = self.__class__.__name__ + + + def __str__(self): + return "%s" % self.cls + + +class Q_Container(VersionableClass): + __master__ = Q1 + + +class Sys(Q_Container): + @classmethod + def _is_right_ver(cls, *args, **kargs): + ver = None + if "system_version" in kargs: + ver = kargs['system_version'] + else: + ver = system_version() + if ver < 1: + return True + else: + return False + + + def __init__(self, *args, **kargs): + super(man[self.__class__, Sys], self).__init__(*args, **kargs) + self.cls = self.__class__.__name__ + + + def __str__(self): + return "%s" % self.cls + + + +class Sys1(Sys): + @classmethod + def _is_right_ver(cls, *args, **kargs): + ver = None + if "system_version" in kargs: + ver = kargs['system_version'] + else: + ver = system_version() + if ver > 1: + return True + else: + return False + + def __init__(self, *args, **kargs): + super(man[self.__class__, Sys1], self).__init__(*args, **kargs) + self.cls = self.__class__.__name__ + + + def __str__(self): + return "%s" % self.cls + + +class Sys_Container(VersionableClass): + __master__ = Sys1 + + def __new__(cls, *args, **kargs): + return super(man[cls, Sys_Container], cls).__new__(cls, *args, **kargs) + + +class AA(Sys_Container, BB, System_Container): + def __new__(cls, *args, **kargs): + return super(man[cls, AA], cls).__new__(cls, *args, **kargs) + class TestVersionableClass(unittest.TestCase): def setUp(self): @@ -21,225 +291,134 @@ def tearDown(self): self.god.unstub_all() - class FooC(object): - pass + def test_simple_versioning(self): + self.god.stub_function(VM, "func1") + self.god.stub_function(VM1, "func2") - #Not implemented get_version -> not used for versioning. - class VCP(FooC, versionable_class.VersionableClass): - def __new__(cls, *args, **kargs): - TestVersionableClass.VCP.version = 1 # Only for unittesting. - TestVersionableClass.VCP.master_class = TestVersionableClass.VCP - return (super(TestVersionableClass.VCP, cls) - .__new__(cls, *args, **kargs)) + VM1.func2.expect_call() + VM.func1.expect_call() + mm = factory(BB)() + # check class name. + self.assertEqual(str(mm), "managed_BB_VM1") + mm.func2() # call BB.func2(m) -> VM1.func2 + mm.func1() # call VM1.func1(m) -> VM.func1 - def foo(self): - pass + self.god.check_playback() - class VC2(VCP, versionable_class.VersionableClass): - @classmethod - def get_version(cls): - return cls.version - @classmethod - def is_right_version(cls, version): - if version is not None: - if version == 1: - return True - return False + def test_simple_create_by_params_v0(self): + def wrap(mm): + mm.VM1_cls - def func1(self): - logging.info("func1") + self.god.stub_function(VM, "func3") + self.god.stub_function(VM1, "func3") - def func2(self): - logging.info("func2") + VM.func3.expect_call() - # get_version could be inherited. - class VC3(VC2, versionable_class.VersionableClass): - @classmethod - def is_right_version(cls, version): - if version is not None: - if version == 2: - return True - return False + mm = factory(BB, qemu_version=0)() + # check class name. + self.assertEqual(str(mm), "managed_BB_VM") + mm.func3() # call VM1.func1(m) -> VM.func1 + self.assertRaises(AttributeError, wrap, mm) - def func2(self): - logging.info("func2_2") - - class PP(versionable_class.VersionableClass): - def __new__(cls, *args, **kargs): - TestVersionableClass.PP.version = 1 # Only for unittesting. - TestVersionableClass.PP.master_class = TestVersionableClass.PP - return (super(TestVersionableClass.PP, cls) - .__new__(cls, *args, **kargs)) - - class PP2(PP, versionable_class.VersionableClass): - @classmethod - def get_version(cls): - return cls.version - - @classmethod - def is_right_version(cls, version): - if version is not None: - if cls.version == 1: - return True - return False + self.god.check_playback() - def func1(self): - print "PP func1" + def test_simple_create_by_params_v1(self): + self.god.stub_function(VM, "func3") + self.god.stub_function(VM1, "func3") - class WP(versionable_class.VersionableClass): - def __new__(cls, *args, **kargs): - TestVersionableClass.WP.version = 1 # Only for unittesting. - TestVersionableClass.WP.master_class = TestVersionableClass.WP - return (super(TestVersionableClass.WP, cls) - .__new__(cls, *args, **kargs)) + VM1.func3.expect_call() - class WP2(WP, versionable_class.VersionableClass): - @classmethod - def get_version(cls): - return cls.version + mm = factory(BB, qemu_version=2)() + # check class name. + self.assertEqual(str(mm), "managed_BB_VM1") + mm.func3() # call VM1.func1(m) -> VM.func1 + self.assertEqual(mm.VM1_cls, "VM1") - def func1(self): - print "WP func1" + self.god.check_playback() - class N(VCP, PP): - pass + def test_sharing_data_in_same_version(self): + mm = factory(BB)() + bb = factory(BB)() + cc = factory(BB, qemu_version=0)() - class NN(N): - pass - class M(VCP): - pass + # Get corespond class in versionable class + man[bb.__class__, VM].test_class_vm1 = 1 + man[bb.__class__, BB].test_class_bb = 2 + man[cc.__class__, BB].test_class_bb = 3 + # check class name. + self.assertEqual(bb.__class__.test_class_vm1, + mm.__class__.test_class_vm1) + self.assertEqual(bb.__class__.test_class_bb, + mm.__class__.test_class_bb) - class MM(M): - pass + # In class hierarchy is class which don't have to be versioned + # because that first value should be equal and second one shouldn't. + self.assertEqual(bb.__class__.test_class_vm1, + cc.__class__.test_class_vm1) + self.assertNotEqual(bb.__class__.test_class_bb, + cc.__class__.test_class_bb) - class W(WP): - pass - def test_simple_versioning(self): - self.god.stub_function(TestVersionableClass.VCP, "foo") - self.god.stub_function(TestVersionableClass.VC2, "func1") - self.god.stub_function(TestVersionableClass.VC2, "func2") - self.god.stub_function(TestVersionableClass.VC3, "func2") - - TestVersionableClass.VC2.func2.expect_call() - TestVersionableClass.VC2.func1.expect_call() - TestVersionableClass.VCP.foo.expect_call() - TestVersionableClass.VC3.func2.expect_call() - - TestVersionableClass.VC2.func2.expect_call() - TestVersionableClass.VC2.func1.expect_call() - TestVersionableClass.VCP.foo.expect_call() - TestVersionableClass.VC3.func2.expect_call() - - m = TestVersionableClass.M() - m.func2() # call VC3.func2(m) - m.func1() # call VC2.func1(m) - m.foo() # call VC1.foo(m) - m.version = 2 - m.check_repair_versions() - m.func2() - - #m.version = 1 - #m.check_repair_versions() - - mm = TestVersionableClass.MM() - mm.func2() # call VC3.func2(m) - mm.func1() # call VC2.func1(m) - mm.foo() # call VC1.foo(m) - mm.version = 2 - mm.check_repair_versions() - mm.func2() + def test_complicated_versioning(self): + self.god.stub_function(VM, "func3") + self.god.stub_function(VM1, "func3") - self.god.check_playback() + VM1.func3.expect_call() - def test_set_class_priority(self): - self.god.stub_function(TestVersionableClass.VC2, "func1") - self.god.stub_function(TestVersionableClass.VC2, "func2") - self.god.stub_function(TestVersionableClass.VC3, "func2") - self.god.stub_function(TestVersionableClass.PP2, "func1") - - TestVersionableClass.VC2.func1.expect_call() - TestVersionableClass.PP2.func1.expect_call() - TestVersionableClass.VC3.func2.expect_call() - TestVersionableClass.PP2.func1.expect_call() - TestVersionableClass.VC2.func1.expect_call() - TestVersionableClass.VC2.func2.expect_call() - - m = TestVersionableClass.N() - m.func1() - m.set_priority_class(TestVersionableClass.PP, - [TestVersionableClass.PP, - TestVersionableClass.VCP]) - m.func1() - - m.version = 2 - m.check_repair_versions() - m.func2() - m.func1() - - m.set_priority_class(TestVersionableClass.VCP, - [TestVersionableClass.PP, - TestVersionableClass.VCP]) - - m.func1() - - m.version = 1 - m.check_repair_versions() - m.func2() + mm = factory(AA)() + # check class name. + self.assertEqual(str(mm), "managed_AA_Sys1_Q1_VM1_System1") + mm.func3() # call VM1.func1(m) -> VM.func1 self.god.check_playback() - def test_set_class_priority_deep(self): - self.god.stub_function(TestVersionableClass.VC2, "func1") - self.god.stub_function(TestVersionableClass.VC2, "func2") - self.god.stub_function(TestVersionableClass.VC3, "func2") - self.god.stub_function(TestVersionableClass.PP2, "func1") + def test_complicated_multiple_create_params(self): + self.god.stub_function(VM, "func3") + self.god.stub_function(VM1, "func3") - TestVersionableClass.VC2.func1.expect_call() - TestVersionableClass.PP2.func1.expect_call() - TestVersionableClass.VC3.func2.expect_call() - TestVersionableClass.PP2.func1.expect_call() - TestVersionableClass.VC2.func1.expect_call() - TestVersionableClass.VC2.func2.expect_call() + VM1.func3.expect_call() - m = TestVersionableClass.NN() - m.func1() - m.set_priority_class(TestVersionableClass.PP, - [TestVersionableClass.PP, - TestVersionableClass.VCP]) - m.func1() + mm = factory(AA, qemu_version=0, system_version=2, q_version=0)() + # check class name. + self.assertEqual(str(mm), "managed_AA_Sys1_Q_VM_System1") + mm.func3() # call VM1.func1(m) -> VM.func1 - m.version = 2 - m.check_repair_versions() - m.func2() - m.func1() + self.god.check_playback() - m.set_priority_class(TestVersionableClass.VCP, - [TestVersionableClass.PP, - TestVersionableClass.VCP]) - m.func1() + def test_pickleing(self): + """ + Test pickling for example save vm env. + """ + m = factory(AA, system_version=0, qemu_version=0)() + mm = factory(BB, qemu_version=3)() - m.version = 1 - m.check_repair_versions() - m.func2() + f = open("/tmp/pick", "w+") + cPickle.dump(m, f, cPickle.HIGHEST_PROTOCOL) + cPickle.dump(mm, f, cPickle.HIGHEST_PROTOCOL) + f.close() - self.god.check_playback() + # Delete classes for ensure that pickel works correctly. + name = m.__class__.__name__ + del m + del globals()[name] + + name = mm.__class__.__name__ + del mm + del globals()[name] + f = open("/tmp/pick", "r+") + c = cPickle.load(f) + cc = cPickle.load(f) + f.close() - def test_check_not_implemented(self): - m = TestVersionableClass.W() - self.assertEqual(m.__class__.__bases__, - tuple([TestVersionableClass.WP2]), - "Class should be WP2 (last defined class in class" - " hierarchy).") if __name__ == "__main__": unittest.main() From 57da1f03058bc3e035fe3a7e5d43611d35bd9fd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20=C5=BDupka?= <jzupka@redhat.com> Date: Thu, 20 Jun 2013 12:43:09 +0200 Subject: [PATCH 141/254] virt: Adds compatibility with new versionable class. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jiří Župka <jzupka@redhat.com> --- openvswitch/tests/ovs_basic.py | 3 +- virttest/openvswitch.py | 131 +++++++++++++-------------------- virttest/utils_net.py | 3 +- 3 files changed, 54 insertions(+), 83 deletions(-) diff --git a/openvswitch/tests/ovs_basic.py b/openvswitch/tests/ovs_basic.py index 522b62211..0048b327b 100644 --- a/openvswitch/tests/ovs_basic.py +++ b/openvswitch/tests/ovs_basic.py @@ -1,5 +1,6 @@ import logging, time, os from virttest import utils_misc, aexpect, utils_net, openvswitch, ovs_utils +from virttest import versionable_class from autotest.client.shared import error @@ -40,7 +41,7 @@ def setup(self, test, params, env): vm.verify_alive() error.context("Start OpenVSwitch.") - self.ovs = openvswitch.OpenVSwitchSystem() + self.ovs = versionable_class.factory(openvswitch.OpenVSwitchSystem)() self.ovs.init_system() self.ovs.check() error.context("Add new bridge %s." % (self.br0_name)) diff --git a/virttest/openvswitch.py b/virttest/openvswitch.py index 57ad63dd4..a59641d17 100644 --- a/virttest/openvswitch.py +++ b/virttest/openvswitch.py @@ -5,11 +5,14 @@ import common from autotest.client import utils, os_dep from autotest.client.shared import error -from versionable_class import VersionableClass +from versionable_class import VersionableClass, Manager, factory import utils_misc +# Register to class manager. +man = Manager(__name__) -class ServiceManagerInterface(VersionableClass): + +class ServiceManagerInterface(object): def __new__(cls, *args, **kargs): ServiceManagerInterface.master_class = ServiceManagerInterface return super(ServiceManagerInterface, cls).__new__(cls, *args, **kargs) @@ -42,51 +45,53 @@ def status(self, service_name): " implemented in child class") -class ServiceManagerSystemD(ServiceManagerInterface, VersionableClass): +class ServiceManagerSysvinit(ServiceManagerInterface): @classmethod - def is_right_version(cls, version): - if version == "systemd": + def _is_right_ver(cls): + version = cls.get_version() + if version == "init": return True return False + def stop(self, service_name): - utils.run("systemctl stop %s.service" % (service_name)) + utils.run("/etc/init.d/%s stop" % (service_name)) def start(self, service_name): - utils.run("systemctl start %s.service" % (service_name)) + utils.run("/etc/init.d/%s start" % (service_name)) def restart(self, service_name): - utils.run("systemctl restart %s.service" % (service_name)) - - - def status(self, service_name): - utils.run("systemctl show %s.service" % (service_name)) + utils.run("/etc/init.d/%s restart" % (service_name)) -class ServiceManagerSysvinit(ServiceManagerInterface, VersionableClass): +class ServiceManagerSystemD(ServiceManagerSysvinit): @classmethod - def is_right_version(cls, version): - if version == "init": + def _is_right_ver(cls): + version = cls.get_version() + if version == "systemd": return True return False - def stop(self, service_name): - utils.run("/etc/init.d/%s stop" % (service_name)) + utils.run("systemctl stop %s.service" % (service_name)) def start(self, service_name): - utils.run("/etc/init.d/%s start" % (service_name)) + utils.run("systemctl start %s.service" % (service_name)) def restart(self, service_name): - utils.run("/etc/init.d/%s restart" % (service_name)) + utils.run("systemctl restart %s.service" % (service_name)) -class ServiceManager(ServiceManagerInterface): - pass + def status(self, service_name): + utils.run("systemctl show %s.service" % (service_name)) + + +class ServiceManager(VersionableClass): + __master__ = ServiceManagerSystemD class OpenVSwitchControl(object): @@ -219,75 +224,48 @@ def check_port_in_br(self, br_name, port_name): raise NotImplementedError() -class OpenVSwitchControlCli(OpenVSwitchControl, VersionableClass): - """ - Class select the best matches control class for installed version - of OpenVSwitch. - """ - def __new__(cls, db_path=None, db_socket=None, db_pidfile=None, - ovs_pidfile=None, dbschema=None, install_prefix=None): - OpenVSwitchControlCli.master_class = OpenVSwitchControlCli - return super(OpenVSwitchControlCli, cls).__new__(cls, db_path, - db_socket, - db_pidfile, - ovs_pidfile, - dbschema, - install_prefix) - - -class OpenVSwitchControlDB(OpenVSwitchControl, VersionableClass): - """ - Class select the best matches control class for installed version - of OpenVSwitch. - """ - - def __new__(cls, db_path=None, db_socket=None, db_pidfile=None, - ovs_pidfile=None, dbschema=None, install_prefix=None): - OpenVSwitchControlDB.master_class = OpenVSwitchControlDB - return super(OpenVSwitchControlDB, cls).__new__(cls, db_path, - db_socket, - db_pidfile, - ovs_pidfile, - dbschema, - install_prefix) - - -class OpenVSwitchControlDB_140(OpenVSwitchControlDB, VersionableClass): +class OpenVSwitchControlDB_140(OpenVSwitchControl): """ Don't use this class directly. This class is automatically selected by OpenVSwitchControl. """ @classmethod - def is_right_version(cls, version): + def _is_right_ver(cls): """ Check condition for select control class. @param version: version of OpenVSwtich """ + version = cls.get_version() if version is not None: int_ver = cls.convert_version_to_int(version) - if int_ver <= 140: + if int_ver >= 140: return True return False #TODO: implement database manipulation methods. -class OpenVSwitchControlCli_140(OpenVSwitchControlCli, VersionableClass): +class OpenVSwitchControlDB_CNT(VersionableClass): + __master__ = OpenVSwitchControlDB_140 + + +class OpenVSwitchControlCli_140(OpenVSwitchControl): """ Don't use this class directly. This class is automatically selected by OpenVSwitchControl. """ @classmethod - def is_right_version(cls, version): + def _is_right_ver(cls): """ Check condition for select control class. @param version: version of OpenVSwtich """ + version = cls.get_version() if version is not None: int_ver = cls.convert_version_to_int(version) - if int_ver <= 140: + if int_ver >= 140: return True return False @@ -378,17 +356,14 @@ def port_to_br(self, port_name): return bridge -class OpenVSwitchSystem(OpenVSwitchControlCli, OpenVSwitchControlDB): +class OpenVSwitchControlCli_CNT(VersionableClass): + __master__ = OpenVSwitchControlCli_140 + + +class OpenVSwitchSystem(OpenVSwitchControlCli_CNT, OpenVSwitchControlDB_CNT): """ OpenVSwtich class. """ - def __new__(cls, db_path=None, db_socket=None, db_pidfile=None, - ovs_pidfile=None, dbschema=None, install_prefix=None): - return super(OpenVSwitchSystem, cls).__new__(cls, db_path, db_socket, - db_pidfile, ovs_pidfile, - dbschema, install_prefix) - - def __init__(self, db_path=None, db_socket=None, db_pidfile=None, ovs_pidfile=None, dbschema=None, install_prefix=None): """ @@ -400,9 +375,9 @@ def __init__(self, db_path=None, db_socket=None, db_pidfile=None, @param ovs_pidfile: Path of OVS ovs-vswitchd pid. @param install_prefix: Path where is openvswitch installed. """ - super(OpenVSwitchSystem, self).__init__(self, db_path, db_socket, - db_pidfile, ovs_pidfile, - dbschema, install_prefix) + sup = super(man[self.__class__, OpenVSwitchSystem], self) + sup.__init__(self, db_path, db_socket, db_pidfile, ovs_pidfile, + dbschema, install_prefix) self.cleanup = False self.pid_files_path = None @@ -473,7 +448,7 @@ def init_system(self): """ Create new dbfile without any configuration. """ - sm = ServiceManager() + sm = factory(ServiceManager)() try: if utils.load_module("openvswitch"): sm.restart("openvswitch") @@ -495,13 +470,6 @@ class OpenVSwitch(OpenVSwitchSystem): """ OpenVSwtich class. """ - def __new__(cls, tmpdir, db_path=None, db_socket=None, db_pidfile=None, - ovs_pidfile=None, dbschema=None, install_prefix=None): - return super(OpenVSwitch, cls).__new__(cls, db_path, db_socket, - db_pidfile, ovs_pidfile, - dbschema, install_prefix) - - def __init__(self, tmpdir, db_path=None, db_socket=None, db_pidfile=None, ovs_pidfile=None, dbschema=None, install_prefix=None): """ @@ -514,8 +482,9 @@ def __init__(self, tmpdir, db_path=None, db_socket=None, db_pidfile=None, @param ovs_pidfile: Path of OVS ovs-vswitchd pid. @param install_prefix: Path where is openvswitch installed. """ - super(OpenVSwitch, self).__init__(db_path, db_socket, db_pidfile, - ovs_pidfile, dbschema, install_prefix) + super(man[self, OpenVSwitch], self).__init__(db_path, db_socket, + db_pidfile, ovs_pidfile, + dbschema, install_prefix) self.tmpdir = "/%s/openvswitch" % (tmpdir) try: os.mkdir(self.tmpdir) diff --git a/virttest/utils_net.py b/virttest/utils_net.py index 8dfbf3605..fd39916ec 100644 --- a/virttest/utils_net.py +++ b/virttest/utils_net.py @@ -4,6 +4,7 @@ from autotest.client import utils, os_dep from autotest.client.shared import error import propcan, utils_misc, arch, aexpect +from versionable_class import factory CTYPES_SUPPORT = True try: @@ -579,7 +580,7 @@ def wrap_init(*args, **kargs): global __ovs if __ovs is None: try: - __ovs = openvswitch.OpenVSwitchSystem() + __ovs = factory(openvswitch.OpenVSwitchSystem)() __ovs.init_system() if (not __ovs.check()): raise Exception("Check of OpenVSwitch failed.") From 356d4e78f8798fcc2bfa5f9ccbf1fc1a0d49bcd5 Mon Sep 17 00:00:00 2001 From: Swapna Krishnan <skrishna@redhat.com> Date: Mon, 22 Jul 2013 08:13:31 -0700 Subject: [PATCH 142/254] qemu_vm: Update qemu_binary to be able to use LD_LIBRARY_PATH Signed-off-by: Swapna Krishnan <skrishna@redhat.com> --- virttest/qemu_vm.py | 5 ----- virttest/utils_misc.py | 16 +++++++++++++--- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/virttest/qemu_vm.py b/virttest/qemu_vm.py index d46b23eb2..791adb09c 100644 --- a/virttest/qemu_vm.py +++ b/virttest/qemu_vm.py @@ -1327,11 +1327,6 @@ def add_option_rom(devices, opt_rom): # Set the X11 display parameter if requested if params.get("x11_display"): cmd += "DISPLAY=%s " % params.get("x11_display") - # Update LD_LIBRARY_PATH for built libraries (libspice-server) - library_path = os.path.join(self.root_dir, 'build', 'lib') - if os.path.isdir(library_path): - library_path = os.path.abspath(library_path) - cmd += "LD_LIBRARY_PATH=%s " % library_path if params.get("qemu_audio_drv"): cmd += "QEMU_AUDIO_DRV=%s " % params.get("qemu_audio_drv") # Add command prefix for qemu-kvm. like taskset, valgrind and so on diff --git a/virttest/utils_misc.py b/virttest/utils_misc.py index be26b259f..aebf9b1f9 100644 --- a/virttest/utils_misc.py +++ b/virttest/utils_misc.py @@ -1338,9 +1338,19 @@ def get_qemu_binary(params): """ Get the path to the qemu binary currently in use. """ - return get_path(os.path.join(data_dir.get_root_dir(), - params.get("vm_type")), - params.get("qemu_binary", "qemu")) + # Update LD_LIBRARY_PATH for built libraries (libspice-server) + qemu_binary_path = get_path(os.path.join(data_dir.get_root_dir(), + params.get("vm_type")), + params.get("qemu_binary", "qemu")) + + library_path = os.path.join(data_dir.get_root_dir(), params.get('vm_type'), 'install_root', 'lib') + if os.path.isdir(library_path): + library_path = os.path.abspath(library_path) + qemu_binary = "LD_LIBRARY_PATH=%s %s" % (library_path, qemu_binary_path) + else: + qemu_binary = qemu_binary_path + + return qemu_binary def get_qemu_img_binary(params): From 5f89bc0b92d6e2944a5e3c906d9bf66bf8475c8d Mon Sep 17 00:00:00 2001 From: Swapna Krishnan <skrishna@redhat.com> Date: Mon, 22 Jul 2013 17:35:31 -0700 Subject: [PATCH 143/254] Removing spice_common as it's obsolete --- qemu/cfg/build.cfg | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/qemu/cfg/build.cfg b/qemu/cfg/build.cfg index 10ed6b1a5..8bf534bfe 100644 --- a/qemu/cfg/build.cfg +++ b/qemu/cfg/build.cfg @@ -54,9 +54,8 @@ variants: #git_repo_qemu_tag_signed = mst.keys # SPICE installation from a GIT repo - git_repo_spice_uri = git://anongit.freedesktop.org/spice/spice - git_repo_spice_common_uri = git://anongit.freedesktop.org/spice/spice-common - git_repo_spice_protocol_uri = git://anongit.freedesktop.org/spice/spice-protocol + git_repo_spice_uri = git://cgit.freedesktop.org/spice/spice + git_repo_spice_protocol_uri = git://git.freedesktop.org/git/spice/spice-protocol # QEMU (KVM) installation from a YUM repo # yum_qemu_kvm_pkgs = ['qemu-kvm', 'qemu-kvm-tools', 'qemu-system-x86', 'qemu-common', 'qemu-img'] @@ -83,7 +82,7 @@ variants: # INSTALLERS SELECTION # Choose here what components you want to install ###################################################################### - installers = git_repo_spice_protocol git_repo_spice_common git_repo_spice git_repo_qemu + installers = git_repo_spice_protocol git_repo_spice git_repo_qemu # Choose wether you want to include debug information/symbols install_debug_info = yes From 0eb07eef29ad5ebfdc3dd5ee5e538aeafbc66c6d Mon Sep 17 00:00:00 2001 From: Yunping Zheng <yunzheng@redhat.com> Date: Mon, 22 Jul 2013 15:13:24 +0800 Subject: [PATCH 144/254] tests.mac_change : change mac when the interface is active this patch make the mac_change test support changing mac when the interface is active this patch also modify the method of get drive number of win_utils Signed-off-by: Yunping Zheng <yunzheng@redhat.com> --- shared/cfg/guest-os/Linux.cfg | 2 +- tests/cfg/mac_change.cfg | 10 ++++++++++ tests/mac_change.py | 29 +++++++++++------------------ 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/shared/cfg/guest-os/Linux.cfg b/shared/cfg/guest-os/Linux.cfg index 40e994d85..6df38ea09 100644 --- a/shared/cfg/guest-os/Linux.cfg +++ b/shared/cfg/guest-os/Linux.cfg @@ -46,7 +46,7 @@ readlink_command = readlink -e sys_path = "/sys/class/net/%s/device/driver" mac_change: - change_cmd = ifconfig %s down && ifconfig %s hw ether %s && ifconfig %s up + change_cmd = ifconfig %s hw ether %s multi_disk: show_mount_cmd = mount|gawk '/mnt/{print $1}' clean_cmd = "\rm -rf /mnt/*" diff --git a/tests/cfg/mac_change.cfg b/tests/cfg/mac_change.cfg index eaf01d0c6..37ee252da 100644 --- a/tests/cfg/mac_change.cfg +++ b/tests/cfg/mac_change.cfg @@ -2,3 +2,13 @@ virt_test_type = qemu libvirt type = mac_change kill_vm = yes + variants: + - down_change: + only Linux + shutdown_int = yes + int_shutdown_cmd = ifconfig %s down + int_activate_cmd = ifconfig %s up + - @up_change: + virtio_net: + no RHEL.5, RHEL.6.0, RHEL.6.1, RHEL.6.2, RHEL.6.3 + shutdown_int = no diff --git a/tests/mac_change.py b/tests/mac_change.py index 6940851b9..fc861d42a 100644 --- a/tests/mac_change.py +++ b/tests/mac_change.py @@ -15,18 +15,6 @@ def run_mac_change(test, params, env): @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ - def get_drive_num(session, path): - """ - return file path drive - """ - cmd = "wmic datafile where \"path='%s'\" get drive" % path - info = session.cmd_output(cmd, timeout=360).strip() - drive_num = re.search(r'(\w):', info, re.M) - if not drive_num: - raise error.TestError("No path %s in your guest" % path) - return drive_num.group() - - vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) @@ -47,6 +35,10 @@ def get_drive_num(session, path): logging.info("The initial MAC address is %s", old_mac) if os_type == "linux": interface = utils_net.get_linux_ifname(session_serial, old_mac) + if params.get("shutdown_int", "yes") == "yes": + int_shutdown_cmd = params.get("int_shutdown_cmd", + "ifconfig %s down") + session_serial.cmd(int_shutdown_cmd % interface) else: connection_id = utils_net.get_windows_nic_attribute(session, @@ -62,17 +54,14 @@ def get_drive_num(session, path): "netconnectionid", connection_id, "pnpdeviceid") - devcon_path = r"\\devcon\\wxp_x86\\" - cd_drive = get_drive_num(session, devcon_path) - - copy_cmd = r"xcopy %s\devcon\wxp_x86\devcon.exe c:\ " % cd_drive + cd_drive = utils_misc.get_winutils_vol(session) + copy_cmd = r"xcopy %s:\devcon\wxp_x86\devcon.exe c:\ " % cd_drive session.cmd(copy_cmd) # Start change MAC address error.context("Changing MAC address to %s" % new_mac, logging.info) if os_type == "linux": - change_cmd = change_cmd_pattern % (interface, - interface, new_mac, interface) + change_cmd = change_cmd_pattern % (interface, new_mac) else: change_cmd = change_cmd_pattern % (int(nic_index), "".join(new_mac.split(":"))) @@ -83,6 +72,10 @@ def get_drive_num(session, path): error.context("Verify the new mac address, and restart the network", logging.info) if os_type == "linux": + if params.get("shutdown_int", "yes") == "yes": + int_activate_cmd = params.get("int_activate_cmd", + "ifconfig %s up") + session_serial.cmd(int_activate_cmd % interface) session_serial.cmd("ifconfig | grep -i %s" % new_mac) logging.info("Mac address change successfully, net restart...") dhclient_cmd = "dhclient -r && dhclient %s" % interface From 5b6077ed9e957ff1627c84194ed49d2265283436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Doktor?= <ldoktor@redhat.com> Date: Thu, 25 Jul 2013 15:14:31 +0200 Subject: [PATCH 145/254] qemu.tests.virtio_console: Raise correct exception MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit virtio_console catches exceptions and raises TestFail when unknown exception occurs (because any Shell/... exception usually means test failure. Anyway it should raise TestError and TestNAError in case they occurs. Signed-off-by: Lukáš Doktor <ldoktor@redhat.com> --- qemu/tests/virtio_console.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/qemu/tests/virtio_console.py b/qemu/tests/virtio_console.py index cb2caa830..0ab0d6902 100644 --- a/qemu/tests/virtio_console.py +++ b/qemu/tests/virtio_console.py @@ -1907,4 +1907,9 @@ def test_delete_guest_script(): "".join(traceback.format_exception( exc_type, exc_value, exc_traceback.tb_next))) - raise error.TestFail('%s failed: %s' % (_fce, details)) + if isinstance(details, error.TestError): + raise error.TestError('%s error: %s' % (_fce, details)) + elif isinstance(details, error.TestNAError): + raise error.TestNAError('%s skipped: %s' % (_fce, details)) + else: + raise error.TestFail('%s failed: %s' % (_fce, details)) From 1887847aa860462335b26ef288402a25afbb27d4 Mon Sep 17 00:00:00 2001 From: Xiaoqing Wei <xwei@redhat.com> Date: Thu, 25 Jul 2013 18:57:57 +0800 Subject: [PATCH 146/254] share.cfg: disable xfstests on old RHEL OSes dont have xfs support and add xfsprogs in RHEL-6 ks Signed-off-by: Xiaoqing Wei <xwei@redhat.com> --- shared/cfg/guest-os/Linux/RHEL/3.9.cfg | 2 +- shared/cfg/guest-os/Linux/RHEL/4.7.cfg | 2 +- shared/cfg/guest-os/Linux/RHEL/4.8.cfg | 2 +- shared/cfg/guest-os/Linux/RHEL/5.3.cfg | 2 +- shared/cfg/guest-os/Linux/RHEL/5.4.cfg | 2 +- shared/cfg/guest-os/Linux/RHEL/5.5.cfg | 2 +- shared/cfg/guest-os/Linux/RHEL/5.6.cfg | 2 +- shared/cfg/guest-os/Linux/RHEL/5.7.cfg | 2 +- shared/cfg/guest-os/Linux/RHEL/5.8.cfg | 2 +- shared/cfg/guest-os/Linux/RHEL/5.9.cfg | 2 +- shared/unattended/RHEL-6-series.ks | 1 + 11 files changed, 11 insertions(+), 10 deletions(-) diff --git a/shared/cfg/guest-os/Linux/RHEL/3.9.cfg b/shared/cfg/guest-os/Linux/RHEL/3.9.cfg index 60d0218b0..235cb7949 100644 --- a/shared/cfg/guest-os/Linux/RHEL/3.9.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/3.9.cfg @@ -1,6 +1,6 @@ - 3.9: no virtio_net, virtio_blk, e1000 - no setup autotest linux_s3 guest_s4 shutdown multi_disk + no setup autotest linux_s3 guest_s4 shutdown multi_disk xfstests no usb_multi_disk, balloon_check mem_chk_cmd = dmidecode | awk -F: '/Maximum Capacity/ {print $2}' image_name = images/rhel39 diff --git a/shared/cfg/guest-os/Linux/RHEL/4.7.cfg b/shared/cfg/guest-os/Linux/RHEL/4.7.cfg index 73e14dbb9..aa3781790 100644 --- a/shared/cfg/guest-os/Linux/RHEL/4.7.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/4.7.cfg @@ -1,5 +1,5 @@ - 4.7: - no setup autotest + no setup autotest xfstests image_name = images/rhel47 unattended_install, check_block_size.4096_512, check_block_size.512_512: unattended_file = unattended/RHEL-4-series.ks diff --git a/shared/cfg/guest-os/Linux/RHEL/4.8.cfg b/shared/cfg/guest-os/Linux/RHEL/4.8.cfg index a75e92c89..abd43649b 100644 --- a/shared/cfg/guest-os/Linux/RHEL/4.8.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/4.8.cfg @@ -1,5 +1,5 @@ - 4.8: - no setup autotest + no setup autotest xfstests image_name = images/rhel48 unattended_install, check_block_size.4096_512, check_block_size.512_512: unattended_file = unattended/RHEL-4-series.ks diff --git a/shared/cfg/guest-os/Linux/RHEL/5.3.cfg b/shared/cfg/guest-os/Linux/RHEL/5.3.cfg index dfc6474f2..9f04e9ecd 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.3.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.3.cfg @@ -1,5 +1,5 @@ - 5.3: - no setup + no setup xfstests image_name = images/rhel53 unattended_install, check_block_size.4096_512, check_block_size.512_512: unattended_file = unattended/RHEL-5-series.ks diff --git a/shared/cfg/guest-os/Linux/RHEL/5.4.cfg b/shared/cfg/guest-os/Linux/RHEL/5.4.cfg index 0975b89e2..cbe7ef54d 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.4.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.4.cfg @@ -1,5 +1,5 @@ - 5.4: - no setup + no setup xfstests image_name = images/rhel54 unattended_install, check_block_size.4096_512, check_block_size.512_512: unattended_file = unattended/RHEL-5-series.ks diff --git a/shared/cfg/guest-os/Linux/RHEL/5.5.cfg b/shared/cfg/guest-os/Linux/RHEL/5.5.cfg index e2c877939..85e30f87b 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.5.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.5.cfg @@ -1,5 +1,5 @@ - 5.5: - no setup + no setup xfstests image_name = images/rhel55 unattended_install, check_block_size.4096_512, check_block_size.512_512: unattended_file = unattended/RHEL-5-series.ks diff --git a/shared/cfg/guest-os/Linux/RHEL/5.6.cfg b/shared/cfg/guest-os/Linux/RHEL/5.6.cfg index a5063efd6..bac247a58 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.6.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.6.cfg @@ -1,5 +1,5 @@ - 5.6: - no setup + no setup xfstests image_name = images/rhel56 unattended_install, check_block_size.4096_512, check_block_size.512_512: unattended_file = unattended/RHEL-5-series.ks diff --git a/shared/cfg/guest-os/Linux/RHEL/5.7.cfg b/shared/cfg/guest-os/Linux/RHEL/5.7.cfg index 42b3556cb..1214941ee 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.7.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.7.cfg @@ -1,5 +1,5 @@ - 5.7: - no setup + no setup xfstests image_name = images/rhel57 unattended_install, check_block_size.4096_512, check_block_size.512_512: unattended_file = unattended/RHEL-5-series.ks diff --git a/shared/cfg/guest-os/Linux/RHEL/5.8.cfg b/shared/cfg/guest-os/Linux/RHEL/5.8.cfg index 196030d0a..c67491ccf 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.8.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.8.cfg @@ -1,5 +1,5 @@ - 5.8: - no setup + no setup xfstests image_name = images/rhel58 unattended_install, check_block_size.4096_512, check_block_size.512_512: unattended_file = unattended/RHEL-5-series.ks diff --git a/shared/cfg/guest-os/Linux/RHEL/5.9.cfg b/shared/cfg/guest-os/Linux/RHEL/5.9.cfg index 43f7964fe..0a4d01949 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.9.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.9.cfg @@ -1,5 +1,5 @@ - 5.9: - no setup + no setup xfstests image_name = images/rhel59 unattended_install, check_block_size.4096_512, check_block_size.512_512: unattended_file = unattended/RHEL-5-series.ks diff --git a/shared/unattended/RHEL-6-series.ks b/shared/unattended/RHEL-6-series.ks index 291ad3a2a..3766dda99 100644 --- a/shared/unattended/RHEL-6-series.ks +++ b/shared/unattended/RHEL-6-series.ks @@ -37,6 +37,7 @@ coreutils usbutils qemu-guest-agent sg3_utils +xfsprogs %post echo "OS install is completed" > /dev/ttyS0 From fa4a7e41e126b165fac63377e78e69b4983ec6cc Mon Sep 17 00:00:00 2001 From: Feng Yang <fyang@redhat.com> Date: Fri, 26 Jul 2013 11:13:40 +0800 Subject: [PATCH 147/254] tests.boot: Support multi VMs Signed-off-by: Feng Yang <fyang@redhat.com> --- tests/boot.py | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/tests/boot.py b/tests/boot.py index 38c0bd07f..d27d3685d 100644 --- a/tests/boot.py +++ b/tests/boot.py @@ -17,21 +17,25 @@ def run_boot(test, params, env): @param env: Dictionary with test environment. """ - error.context("Try to log into guest.", logging.info) - vm = env.get_vm(params["main_vm"]) - vm.verify_alive() timeout = float(params.get("login_timeout", 240)) - session = vm.wait_for_login(timeout=timeout) + vms = env.get_all_vms() + for vm in vms: + error.context("Try to log into guest '%s'." % vm.name, logging.info) + session = vm.wait_for_login(timeout=timeout) if params.get("rh_perf_envsetup_script"): - utils_test.service_setup(vm, session, test.virtdir) + for vm in vms: + utils_test.service_setup(vm, session, test.virtdir) if params.get("reboot_method"): - error.context("Reboot guest.", logging.info) - if params["reboot_method"] == "system_reset": - time.sleep(int(params.get("sleep_before_reset", 10))) + for vm in vms: + error.context("Reboot guest '%s'." % vm.name, logging.info) + if params["reboot_method"] == "system_reset": + time.sleep(int(params.get("sleep_before_reset", 10))) # Reboot the VM - for i in range(int(params.get("reboot_count", 1))): - session = vm.reboot(session, params["reboot_method"], 0, timeout) - - session.close() + for i in range(int(params.get("reboot_count", 1))): + session = vm.reboot(session, + params["reboot_method"], + 0, + timeout) + session.close() From 2a17857d0188c6ab987baa67cdcd3de02b9bbbad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20=C5=BDupka?= <jzupka@redhat.com> Date: Fri, 26 Jul 2013 15:33:17 +0200 Subject: [PATCH 148/254] virt: Fix bug in cart config. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - "aaaa": could cycle for ever. Signed-off-by: Jiří Župka <jzupka@redhat.com> --- virttest/cartesian_config.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/virttest/cartesian_config.py b/virttest/cartesian_config.py index df54c2c88..3b8f17685 100755 --- a/virttest/cartesian_config.py +++ b/virttest/cartesian_config.py @@ -1029,10 +1029,11 @@ def match(self, line, pos): elif char in tokens_map: token = tokens_map[char]() elif char == "\"": - pos, char = li.next() chars = "" + pos, char = li.next() while char != "\"": chars += char + pos, char = li.next() yield LString(chars) elif char == "#": break From 13132a153c02306d4f72c745343f12ba75295e2f Mon Sep 17 00:00:00 2001 From: Feng Yang <fyang@redhat.com> Date: Fri, 26 Jul 2013 11:40:48 +0800 Subject: [PATCH 149/254] virttest: Correct default sysfs_dir parameter update sys -> /sys Signed-off-by: Feng Yang <fyang@redhat.com> --- virttest/standalone_test.py | 2 +- virttest/utils_misc.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/virttest/standalone_test.py b/virttest/standalone_test.py index 42172343e..c48288248 100644 --- a/virttest/standalone_test.py +++ b/virttest/standalone_test.py @@ -804,7 +804,7 @@ def run_tests(parser, options): # Add kvm module status dct["kvm_default"] = utils_misc.get_module_params( - dct.get("sysfs_dir", "sys"), "kvm") + dct.get("sysfs_dir", "/sys"), "kvm") if dct.get("skip") == "yes": continue diff --git a/virttest/utils_misc.py b/virttest/utils_misc.py index aebf9b1f9..f9c9a229f 100644 --- a/virttest/utils_misc.py +++ b/virttest/utils_misc.py @@ -429,7 +429,7 @@ def run_tests(parser, job): index += 1 # Add kvm module status - sysfs_dir = param_dict.get("sysfs_dir", "sys") + sysfs_dir = param_dict.get("sysfs_dir", "/sys") param_dict["kvm_default"] = get_module_params(sysfs_dir, 'kvm') if param_dict.get("skip") == "yes": From a6a2e3016487102e20257de81e6fbaefb0bb809b Mon Sep 17 00:00:00 2001 From: Li Yang <liyang.fnst@cn.fujitsu.com> Date: Wed, 17 Jul 2013 13:47:48 +0800 Subject: [PATCH 150/254] virt: Modify cgroup service control function Signed-off-by: Li Yang <liyang.fnst@cn.fujitsu.com> --- libvirt/tests/src/virsh_cmd/domain/virsh_numatune.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_numatune.py b/libvirt/tests/src/virsh_cmd/domain/virsh_numatune.py index 28e14a978..c9fc0bc22 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_numatune.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_numatune.py @@ -238,8 +238,8 @@ def run_virsh_numatune(test, params, env): # and will start the guest after restarting libvirtd service if vm.is_alive(): vm.destroy() - if utils_cgroup.service_cgconfig_control("status"): - utils_cgroup.service_cgconfig_control("stop") + if utils_cgroup.cgconfig_is_running(): + utils_cgroup.cgconfig_stop() # Refresh libvirtd service to get latest cgconfig service change if libvirtd == "restart": utils_libvirtd.libvirtd_restart() @@ -253,8 +253,8 @@ def run_virsh_numatune(test, params, env): else: set_numa_parameter(params) # Recover cgconfig and libvirtd service - if not utils_cgroup.service_cgconfig_control("status"): - utils_cgroup.service_cgconfig_control("start") + if not utils_cgroup.cgconfig_is_running(): + utils_cgroup.cgconfig_start() utils_libvirtd.libvirtd_restart() finally: vm.destroy() From 274c0cb7fb4ec8715e6440b950a1c7561d07dc7e Mon Sep 17 00:00:00 2001 From: Ross Brattain <ross.b.brattain@intel.com> Date: Sun, 28 Jul 2013 20:18:23 -0700 Subject: [PATCH 151/254] autotest_regression: Too few arguments for format string Fix TypeError: not enough arguments for format string Found by PyCharm inspection. Signed-off-by: Ross Brattain <ross.b.brattain@intel.com> --- tests/autotest_regression.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/autotest_regression.py b/tests/autotest_regression.py index 2dcfad8ad..e5daaf2b2 100644 --- a/tests/autotest_regression.py +++ b/tests/autotest_regression.py @@ -201,7 +201,7 @@ def job_is_status(status): return False else: raise ValueError("Job %s does not show in the " - "output of %s" % list_jobs_cmd) + "output of %s" % (job_name, list_jobs_cmd)) def job_is_completed(): return job_is_status("Completed") From c792b5f5a0cb42e9841be9254b7a20230cddaddc Mon Sep 17 00:00:00 2001 From: Ross Brattain <ross.b.brattain@intel.com> Date: Sun, 28 Jul 2013 20:22:57 -0700 Subject: [PATCH 152/254] autotest_regression: replace error.ValueError with ValueError I think we mean ValueError here, I couldn't find any error.ValueError. Signed-off-by: Ross Brattain <ross.b.brattain@intel.com> --- tests/autotest_regression.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/autotest_regression.py b/tests/autotest_regression.py index e5daaf2b2..0cd44ba1b 100644 --- a/tests/autotest_regression.py +++ b/tests/autotest_regression.py @@ -221,7 +221,7 @@ def job_is_running(): # Wait for the session to become unresponsive if not utils_misc.wait_for(lambda: not session_client.is_responsive(), timeout=300): - raise error.ValueError("Client machine did not reboot") + raise ValueError("Client machine did not reboot") # Establish a new client session session_client = vm_client.wait_for_login(timeout=timeout) From 889a2cfc6c2826a27eadde3c9f2d3173a7ac0330 Mon Sep 17 00:00:00 2001 From: Ross Brattain <ross.b.brattain@intel.com> Date: Sun, 28 Jul 2013 20:26:52 -0700 Subject: [PATCH 153/254] autotest_regression: move copy of install-autotest-server*log outside try/except We need the install log file to debug any error, so move it outside the try/except, otherwise any errors will trigger aexpect.ShellCmdError and skip the copy Signed-off-by: Ross Brattain <ross.b.brattain@intel.com> --- tests/autotest_regression.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/autotest_regression.py b/tests/autotest_regression.py index 0cd44ba1b..3404dcab2 100644 --- a/tests/autotest_regression.py +++ b/tests/autotest_regression.py @@ -67,12 +67,12 @@ def run_autotest_regression(test, params, env): if autotest_commit: install_cmd += " -c %s" % autotest_commit session_server.cmd(install_cmd, timeout=autotest_install_timeout) - vm_server.copy_files_from(guest_path="/tmp/install-autotest-server*log", - host_path=test.resultsdir) except aexpect.ShellCmdError, e: for line in e.output.splitlines(): logging.error(line) step_failures.append(step1) + vm_server.copy_files_from(guest_path="/tmp/install-autotest-server*log", + host_path=test.resultsdir) top_commit = None try: From 9eaded3354e3049a3346fcd66ea721eefe458354 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 2 Jul 2013 13:41:15 +0800 Subject: [PATCH 154/254] virttest: enhanced run_autotest function changes: 1. increased default timeout values when execute commands in guest; 2. instread result files one by one to copy results tarball 3. cleanup autotest subprocess after guest test done Signed-off-by: Xu Tian <xutian@redhat.com> rollback utils_test Signed-off-by: Xu Tian <xutian@redhat.com> --- virttest/utils_test.py | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/virttest/utils_test.py b/virttest/utils_test.py index 4fdba0e9e..cf980d44e 100644 --- a/virttest/utils_test.py +++ b/virttest/utils_test.py @@ -1629,12 +1629,12 @@ def extract(vm, remote_path, dest_dir): """ basename = os.path.basename(remote_path) logging.debug("Extracting %s on VM %s", basename, vm.name) - session.cmd("rm -rf %s" % dest_dir) + session.cmd("rm -rf %s" % dest_dir, timeout=240) dirname = os.path.dirname(remote_path) session.cmd("cd %s" % dirname) session.cmd("mkdir -p %s" % os.path.dirname(dest_dir)) e_cmd = "tar xjvf %s -C %s" % (basename, os.path.dirname(dest_dir)) - output = session.cmd(e_cmd, timeout=120) + output = session.cmd(e_cmd, timeout=240) autotest_dirname = "" for line in output.splitlines()[1:]: autotest_dirname = line.split("/")[0] @@ -1656,9 +1656,25 @@ def get_results(base_results_dir): except OSError, detail: if detail.errno != errno.EEXIST: raise - vm.copy_files_from("%s/results/default/*" % base_results_dir, - guest_results_dir) - + # result info tarball to host result dir + session = vm.wait_for_login(timeout=360) + results_dir = "%s/results/default" % base_results_dir + results_tarball = "/tmp/results.tgz" + compress_cmd = "cd %s && " % results_dir + compress_cmd += "tar cjvf %s ./* --exclude=*core*" % results_tarball + session.cmd(compress_cmd, timeout=600) + vm.copy_files_from(results_tarball, guest_results_dir) + # cleanup autotest subprocess which not terminated, change PWD to + # avoid current connection kill by fuser command; + clean_cmd = "cd /tmp && fuser -k %s" % results_dir + session.sendline(clean_cmd) + session.cmd("rm -f %s" % results_tarball, timeout=240) + results_tarball = os.path.basename(results_tarball) + results_tarball = os.path.join(guest_results_dir, results_tarball) + uncompress_cmd = "tar xjvf %s -C %s" % (results_tarball, + guest_results_dir) + utils.run(uncompress_cmd) + utils.run("rm -f %s" % results_tarball) def get_results_summary(): """ @@ -1724,7 +1740,7 @@ def get_results_summary(): (autotest_parentdir, compressed_autotest_path, autotest_basename)) # Until we have nested virtualization, we don't need the virt test :) cmd += " --exclude=%s/tests/virt" % autotest_basename - cmd += " --exclude=%s/results" % autotest_basename + cmd += " --exclude=%s/results*" % autotest_basename cmd += " --exclude=%s/tmp" % autotest_basename cmd += " --exclude=%s/control*" % autotest_basename cmd += " --exclude=*.pyc" From d4f51d73edda951b20467ef43786f4d5060fab74 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 2 Jul 2013 14:35:45 +0800 Subject: [PATCH 155/254] virt.tests: update autotest.iozone cfg update cfg to make iozone run when AIO is threads and native Signed-off-by: Xu Tian <xutian@redhat.com> --- tests/cfg/autotest_control.cfg | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/cfg/autotest_control.cfg b/tests/cfg/autotest_control.cfg index 99214b57c..2d5f3c572 100644 --- a/tests/cfg/autotest_control.cfg +++ b/tests/cfg/autotest_control.cfg @@ -40,7 +40,14 @@ - rtc: test_control_file = rtc.control - iozone: + test_timeout = 4200 test_control_file = iozone.control + profilers += " sar iostat " + variants: + - aio_native: + image_aio = native + - aio_threads: + image_aio = threads - flail: test_control_file = flail.control - systemtap: From 3a4b25765614be893cfc618d3ac0609e8bb93e39 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 2 Jul 2013 14:44:22 +0800 Subject: [PATCH 156/254] shared.control: make xfstests run on real partation update xfstests.control to make it run on a real partation in guest; Signed-off-by: Xu Tian <xutian@redhat.com> --- shared/control/xfstests.control | 38 +++++++++++++++++++++++++-------- tests/cfg/autotest_control.cfg | 10 +++++++++ 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/shared/control/xfstests.control b/shared/control/xfstests.control index 9ab1f69df..61bb11156 100644 --- a/shared/control/xfstests.control +++ b/shared/control/xfstests.control @@ -60,15 +60,34 @@ Make sure you have them or a real spare device to test things. """ # Define the partitions you want to use. # -# Here, by default we use the concept of virtual partition (a partition of 1GB -# of size), to avoid setup by the user. However, you'll most likely use a real -# block device for your tests. from autotest.client import partition -file_img = os.path.join(job.tmpdir, 'xfstests.img') -vp = partition.virtual_partition(file_img=file_img, file_size=1024*1024) -device = vp.device -# You can use a real block device, such as /dev/sdc1 -#device=/dev/sdc1 +import re + +disks=[] +boot_disk = [] +for line in open("/proc/partitions").readlines(): + try: + major,minor, blocks, name = line.split() + except: + continue + if re.match("[shv]d.*", name): + if name[-1].isdigit(): + boot_disk.append(name[:-1]) + else: + disks.append(name) + +device = set(disks) - set(boot_disk) +try: + device = device.pop() +except KeyError: + raise error.TestError("No realy partation found") + +device = os.path.join("/dev", device) +cmd = "parted -s %s mklabel gpt && " % device +cmd += "parted -s %s mkpart primary 1 1G" % device +utils.run(cmd) +# Make test run on first partition of the disc +device += "1" # By default, we create a directory under autotest mountpoint = os.path.join(job.tmpdir, 'xfstests') @@ -140,4 +159,5 @@ for fs_type in FS_TYPES: # It is good practice to unmount the partition created p.unmount() # If you are using the virtual partition, you may destroy it here -vp.destroy() +cmd = "parted -s %s rm 1 && partprobe %s" % (device, device) +utils.run(cmd) diff --git a/tests/cfg/autotest_control.cfg b/tests/cfg/autotest_control.cfg index 2d5f3c572..823450d0d 100644 --- a/tests/cfg/autotest_control.cfg +++ b/tests/cfg/autotest_control.cfg @@ -79,5 +79,15 @@ - scsi-disk: drive_format_asd = scsi-disk - xfstests: + # Below packages requried to installed in guest before start test: + # xfsdump, xfsprogs xfsprogs-devel + no RHEL.3 RHEL.4 RHEL.5 RHEL.6 + kill_vm = yes + images += " stg1" + image_name_stg1 = "images/stg1" + image_format_stg1 = "qcow2" + image_size_stg1 = 2G + force_create_image_stg1 = yes + force_remove_image_stg1= yes test_timeout = 4800 test_control_file = xfstests.control From 6c24df91987c478143fa888f4e0faee3d15a8b07 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 2 Jul 2013 14:53:47 +0800 Subject: [PATCH 157/254] virt.tests: sync linus_stress testing to autotest_control testsuite Signed-off-by: Xu Tian <xutian@redhat.com> --- shared/control/linus_stress.control | 12 ++++++++++++ tests/cfg/autotest_control.cfg | 2 ++ 2 files changed, 14 insertions(+) create mode 100644 shared/control/linus_stress.control diff --git a/shared/control/linus_stress.control b/shared/control/linus_stress.control new file mode 100644 index 000000000..3f9d22d2c --- /dev/null +++ b/shared/control/linus_stress.control @@ -0,0 +1,12 @@ +AUTHOR = 'mbligh@google.com (Martin Bligh)' +TIME = 'MEDIUM' +NAME = 'Linus Stress' +TEST_TYPE = 'client' +TEST_CLASS = 'Kernel' +TEST_CATEGORY = 'Stress' + +DOC = ''' +Runs the standard linus_stress test. +''' + +job.run_test('linus_stress') diff --git a/tests/cfg/autotest_control.cfg b/tests/cfg/autotest_control.cfg index 823450d0d..026761ea4 100644 --- a/tests/cfg/autotest_control.cfg +++ b/tests/cfg/autotest_control.cfg @@ -91,3 +91,5 @@ force_remove_image_stg1= yes test_timeout = 4800 test_control_file = xfstests.control + - linus_stress: + test_control_file = linus_stress.control From 3e751bf0aa02ba1db5de1ebda3f5b5b75d331fff Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 2 Jul 2013 14:56:35 +0800 Subject: [PATCH 158/254] virt.tests: sync signaltest to autotest_control testsuite Signed-off-by: Xu Tian <xutian@redhat.com> --- shared/control/signaltest.control | 10 ++++++++++ tests/cfg/autotest_control.cfg | 2 ++ 2 files changed, 12 insertions(+) create mode 100644 shared/control/signaltest.control diff --git a/shared/control/signaltest.control b/shared/control/signaltest.control new file mode 100644 index 000000000..13ebb4d89 --- /dev/null +++ b/shared/control/signaltest.control @@ -0,0 +1,10 @@ +NAME='Signal Test' +AUTHOR='Michal Piotrowski <michal.k.k.piotrowski@gmail.com>' +TIME='SHORT' +TEST_TYPE='client' +TEST_CLASS='Kernel' +TEST_CATEGORY='Functional' +DOC='''\ +Test signal passing to processes +''' +job.run_test('signaltest') diff --git a/tests/cfg/autotest_control.cfg b/tests/cfg/autotest_control.cfg index 026761ea4..583584a70 100644 --- a/tests/cfg/autotest_control.cfg +++ b/tests/cfg/autotest_control.cfg @@ -93,3 +93,5 @@ test_control_file = xfstests.control - linus_stress: test_control_file = linus_stress.control + - signaltest: + test_control_file = signaltest.control From 291d9475885aa21293abba8bc5f8f370d0c3454d Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 2 Jul 2013 14:58:42 +0800 Subject: [PATCH 159/254] virt.tests: sync parallel_dd to autotest_control testsuite Signed-off-by: Xu Tian <xutian@redhat.com> --- shared/control/parallel_dd.control | 21 +++++++++++++++++++++ tests/cfg/autotest_control.cfg | 9 +++++++++ 2 files changed, 30 insertions(+) create mode 100644 shared/control/parallel_dd.control diff --git a/shared/control/parallel_dd.control b/shared/control/parallel_dd.control new file mode 100644 index 000000000..4020287e4 --- /dev/null +++ b/shared/control/parallel_dd.control @@ -0,0 +1,21 @@ +NAME = "Parallel DD" +AUTHOR = "Martin Bligh <mbligh@google.com>" +TIME = "MEDIUM" +TEST_CATEGORY = "PERFORMANCE" +TEST_CLASS = "HARDWARE" +TEST_TYPE = "CLIENT" +DOC = """ +Measures the performance of writing and reading multiple streams of files onto +the files system. +""" + +# YOU NEED TO SPECIFY A FILESYSTEM +if os.path.exists("/dev/sdb"): + fs = job.filesystem('/dev/sdb', job.tmpdir) +elif os.path.exists("/dev/hdb"): + fs = job.filesystem("/dev/hdb", job.tmpdir) +else: + fs = job.filesystem("/dev/vdb", job.tmpdir) +job.run_test('parallel_dd', fs=fs, fstype='ext3', iterations=5, megabytes=1000, streams=2) + + diff --git a/tests/cfg/autotest_control.cfg b/tests/cfg/autotest_control.cfg index 583584a70..d711eda08 100644 --- a/tests/cfg/autotest_control.cfg +++ b/tests/cfg/autotest_control.cfg @@ -95,3 +95,12 @@ test_control_file = linus_stress.control - signaltest: test_control_file = signaltest.control + - parallel_dd: + test_timeout = 36000 + images += " stg" + image_format_stg = qcow2 + boot_drive_stg = yes + image_name_stg = images/storage + image_size_stg = 10G + force_create_image_stg = yes + test_control_file = parallel_dd.control From b6873b0e1fd43a13f083c4eff25410f6306bdaa3 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 2 Jul 2013 15:02:44 +0800 Subject: [PATCH 160/254] virt.tests: update autotest.cpu_hotplug cfg add filter "only exclue RHEL.3.9 RHEL.4" to avoid run cpu_hotplug on unsupported guest; add parm "kill_vm = yes" to avoid impact next tests Signed-off-by: Xu Tian <xutian@redhat.com> --- tests/cfg/autotest_control.cfg | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/cfg/autotest_control.cfg b/tests/cfg/autotest_control.cfg index d711eda08..d032f81f8 100644 --- a/tests/cfg/autotest_control.cfg +++ b/tests/cfg/autotest_control.cfg @@ -30,6 +30,9 @@ - hackbench: test_control_file = hackbench.control - cpu_hotplug: + no RHEL.3.9 + no RHEL.4 + kill_vm = yes test_control_file = cpu_hotplug.control - monotonic_time: test_control_file = monotonic_time.control From 5e70ef19bc20499ed9e6fe8825ffcfdbfd4fe9f3 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 2 Jul 2013 15:07:36 +0800 Subject: [PATCH 161/254] virt.tests: sync compliebench to autotest_control testsuite Signed-off-by: Xu Tian <xutian@redhat.com> --- shared/control/compilebench.control | 13 +++++++++++++ tests/cfg/autotest_control.cfg | 2 ++ 2 files changed, 15 insertions(+) create mode 100644 shared/control/compilebench.control diff --git a/shared/control/compilebench.control b/shared/control/compilebench.control new file mode 100644 index 000000000..813c3b451 --- /dev/null +++ b/shared/control/compilebench.control @@ -0,0 +1,13 @@ +AUTHOR = "Curt Wohlgemuth <curtw@google.com>" +NAME = "compilebench" +TEST_CATEGORY = "Functional" +TEST_CLASS = "General" +TEST_TYPE = "client" +TIME = "SHORT" +DOC=""" +Compilebench is a filesystem performance test. It simulates some of the disk +IO common in creating, compiling, patching, stating and reading kernel trees. +It indirectly measures how well filesystems can maintain directory locality as +the disk fills up and directories age. +""" +job.run_test("compilebench") diff --git a/tests/cfg/autotest_control.cfg b/tests/cfg/autotest_control.cfg index d032f81f8..cd2de1f79 100644 --- a/tests/cfg/autotest_control.cfg +++ b/tests/cfg/autotest_control.cfg @@ -107,3 +107,5 @@ image_size_stg = 10G force_create_image_stg = yes test_control_file = parallel_dd.control + - compliebench: + test_control_file = compilebench.control From 439cea29576e95f99bd306e3c55061c45f891f9b Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 2 Jul 2013 15:14:51 +0800 Subject: [PATCH 162/254] virt.tests: sync fsstress testing to autotest_control testsuite Signed-off-by: Xu Tian <xutian@redhat.com> --- shared/control/fsstress.control | 16 ++++++++++++++++ tests/cfg/autotest_control.cfg | 3 +++ 2 files changed, 19 insertions(+) create mode 100644 shared/control/fsstress.control diff --git a/shared/control/fsstress.control b/shared/control/fsstress.control new file mode 100644 index 000000000..20b9dad5d --- /dev/null +++ b/shared/control/fsstress.control @@ -0,0 +1,16 @@ +AUTHOR = "Ricardo Salveti de Araujo <rsalveti@linux.vnet.ibm.com" +NAME = "fsstress" +TEST_CATEGORY = "Stress" +TEST_CLASS = "General" +TEST_TYPE = "client" +TIME = 'MEDIUM' +DOC=''' +A benchmark that tries to capture both transactional DB workloads and +random web server ones. It writes about 24MB/s but has many small writes a +second. It does a lot of this randomly but lets you go back to replay the +randomness + +More information about fsstress can be found at +http://www.cs.duke.edu/ari/fstress/ +''' +job.run_test('fsstress') diff --git a/tests/cfg/autotest_control.cfg b/tests/cfg/autotest_control.cfg index cd2de1f79..33d976f41 100644 --- a/tests/cfg/autotest_control.cfg +++ b/tests/cfg/autotest_control.cfg @@ -109,3 +109,6 @@ test_control_file = parallel_dd.control - compliebench: test_control_file = compilebench.control + - fsstress: + test_timeout = 36000 + test_control_file = fsstress.control From 07b5c901066d689d5d9e8a6a0f2ce16e0bd6c68d Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 2 Jul 2013 15:17:44 +0800 Subject: [PATCH 163/254] virt.tests: sync aiostress testing to autotest_control testsuite Signed-off-by: Xu Tian <xutian@redhat.com> --- shared/control/aiostress.control | 24 ++++++++++++++++++++++++ tests/cfg/autotest_control.cfg | 7 +++++++ 2 files changed, 31 insertions(+) create mode 100644 shared/control/aiostress.control diff --git a/shared/control/aiostress.control b/shared/control/aiostress.control new file mode 100644 index 000000000..16e059fa4 --- /dev/null +++ b/shared/control/aiostress.control @@ -0,0 +1,24 @@ +AUTHOR = "Masoud S <masouds@google.com>" +NAME = "aio stress" +TEST_CATEGORY = "Stress" +TEST_CLASS = "Kernel" +TIME = "SHORT" +TEST_TYPE = "client" +DOC = """\ +aio-stress + +will open or create each file on the command line, and start a series +of aio to it. + +aio is done in a rotating loop. first file1 gets 8 requests, then +file2, then file3 etc. As each file finishes writing, it is switched +to reads + +io buffers are aligned in case you want to do raw io + +This test takes less than a minute. It ends up writing and reading less +than a few Megs. It is a sequential workload. This test stresses the aio +interface not the disk, or kernel. +""" + +job.run_test('aiostress') diff --git a/tests/cfg/autotest_control.cfg b/tests/cfg/autotest_control.cfg index 33d976f41..da27b0332 100644 --- a/tests/cfg/autotest_control.cfg +++ b/tests/cfg/autotest_control.cfg @@ -112,3 +112,10 @@ - fsstress: test_timeout = 36000 test_control_file = fsstress.control + - aiostress: + test_control_file = aiostress.control + variants: + - aio_native: + image_aio = native + - aio_threads: + image_aio = threads From e334fed7f2ff386d5567e4d9f3f2bdc75751961b Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 2 Jul 2013 15:20:01 +0800 Subject: [PATCH 164/254] virt.tests: sync interbench testing to autotest_control testsuite Signed-off-by: Xu Tian <xutian@redhat.com> --- shared/control/interbench.control | 15 +++++++++++++++ tests/cfg/autotest_control.cfg | 2 ++ 2 files changed, 17 insertions(+) create mode 100644 shared/control/interbench.control diff --git a/shared/control/interbench.control b/shared/control/interbench.control new file mode 100644 index 000000000..64a895da0 --- /dev/null +++ b/shared/control/interbench.control @@ -0,0 +1,15 @@ +AUTHOR = "Brandon Philips <brandon@ifup.org>" +NAME = "interbench" +TEST_CATEGORY = "Benchmark" +TEST_CLASS = "General" +TEST_TYPE = "client" +TIME = 'MEDIUM' +EXPERIMENTAL = "True" +DOC=''' +interbench is designed to measure the effect of changes in Linux kernel +design or systemconfiguration changes such as cpu, I/O scheduler and +filesystem changes andoptions; this test run will run a standard benchmark; + +more info, please see: http://users.on.net/~ckolivas/interbench/ +''' +job.run_test('interbench') diff --git a/tests/cfg/autotest_control.cfg b/tests/cfg/autotest_control.cfg index da27b0332..defddbfc6 100644 --- a/tests/cfg/autotest_control.cfg +++ b/tests/cfg/autotest_control.cfg @@ -119,3 +119,5 @@ image_aio = native - aio_threads: image_aio = threads + - interbench: + test_control_file = interbench.control From e6dcd7a124ca59e145631d33f9ffac5cfa344710 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 2 Jul 2013 15:36:02 +0800 Subject: [PATCH 165/254] virt.tests: sync kernbench testing to autotest_control testsuite Signed-off-by: Xu Tian <xutian@redhat.com> --- tests/cfg/autotest_control.cfg | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/cfg/autotest_control.cfg b/tests/cfg/autotest_control.cfg index defddbfc6..86d2efd0b 100644 --- a/tests/cfg/autotest_control.cfg +++ b/tests/cfg/autotest_control.cfg @@ -121,3 +121,5 @@ image_aio = threads - interbench: test_control_file = interbench.control + - kernbench: + test_control_file = kernbench.control From 56165e75568bde514486eefec821824f4efe3092 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 2 Jul 2013 15:42:06 +0800 Subject: [PATCH 166/254] virt.tests: sync posixtest to autotest_control testsuite Signed-off-by: Xu Tian <xutian@redhat.com> --- shared/control/posixtest.control | 19 +++++++++++++++++++ tests/cfg/autotest_control.cfg | 3 +++ 2 files changed, 22 insertions(+) create mode 100644 shared/control/posixtest.control diff --git a/shared/control/posixtest.control b/shared/control/posixtest.control new file mode 100644 index 000000000..ad14145a3 --- /dev/null +++ b/shared/control/posixtest.control @@ -0,0 +1,19 @@ +AUTHOR = '''mohd.omar@in.ibm.com (Mohammed Omar)''' + +NAME = "Posix test" + +TIME = "MEDIUM" +TEST_CLASS = "Kernel" +TEST_CATEGORY = "Functional" +TEST_TYPE = "Client" + +DOC = """ +The Open POSIX Test Suite is a test suite for POSIX 2001 APIs, not tied to +specific implementations. It provides conformance, functional, and stress +testing. Initial focus is on Threads, Clocks & Timers, Signals, Message Queues, +and Semaphores; + +more info, please see: http://sourceforge.net/p/posixtest/wiki/Home/ +""" + +job.run_test('posixtest') diff --git a/tests/cfg/autotest_control.cfg b/tests/cfg/autotest_control.cfg index 86d2efd0b..5177b38af 100644 --- a/tests/cfg/autotest_control.cfg +++ b/tests/cfg/autotest_control.cfg @@ -123,3 +123,6 @@ test_control_file = interbench.control - kernbench: test_control_file = kernbench.control + - posixtest: + test_timeout = 3600 + test_control_file = posixtest.control From 0c74b84dea740fecc6d96d960053662bded8816d Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 2 Jul 2013 15:44:12 +0800 Subject: [PATCH 167/254] virt.tests: sync rmaptest to autotest_control testsuite Signed-off-by: Xu Tian <xutian@redhat.com> --- shared/control/rmaptest.control | 15 +++++++++++++++ tests/cfg/autotest_control.cfg | 2 ++ 2 files changed, 17 insertions(+) create mode 100644 shared/control/rmaptest.control diff --git a/shared/control/rmaptest.control b/shared/control/rmaptest.control new file mode 100644 index 000000000..472212168 --- /dev/null +++ b/shared/control/rmaptest.control @@ -0,0 +1,15 @@ +AUTHOR = "mbligh@google.com" + +NAME = "Rmap test" + +TIME = "MEDIUM" +TEST_CLASS = "Kernel" +TEST_CATEGORY = "Fuctional" +TEST_TYPE = "Client" +EXPERIMENTAL = "True" + +DOC = """ +Create lots of VMAs mapped by lots of tasks. To tickle objrmap and the +virtual scan. +""" +job.run_test('rmaptest') diff --git a/tests/cfg/autotest_control.cfg b/tests/cfg/autotest_control.cfg index 5177b38af..5d8a3f983 100644 --- a/tests/cfg/autotest_control.cfg +++ b/tests/cfg/autotest_control.cfg @@ -126,3 +126,5 @@ - posixtest: test_timeout = 3600 test_control_file = posixtest.control + - rmaptest: + test_control_file = rmaptest.control From 7f160dfe366399d24b20ada9b17fa2e1d710aa35 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 2 Jul 2013 15:46:52 +0800 Subject: [PATCH 168/254] virt.tests: sync synctest to autotest_control testsuite Signed-off-by: Xu Tian <xutian@redhat.com> --- shared/control/synctest.control | 15 +++++++++++++++ tests/cfg/autotest_control.cfg | 2 ++ 2 files changed, 17 insertions(+) create mode 100644 shared/control/synctest.control diff --git a/shared/control/synctest.control b/shared/control/synctest.control new file mode 100644 index 000000000..4d8742fb7 --- /dev/null +++ b/shared/control/synctest.control @@ -0,0 +1,15 @@ +NAME='Sync Test' +AUTHOR='Amrita Nayal <amritan@google.com>' +TIME='SHORT' +TEST_TYPE='client' +TEST_CLASS='Kernel' +TEST_CATEGORY='Functional' +DOC='''\ +Test interrupting sync system call. +Child process creates enough dirty data and issues fsync. +In the meanwhile parent process issues kill. +On success, child is killed immediately while data sync is on. +IPC occurs through semaphore and shared memory. + +''' +job.run_test('synctest' ,len='100', loop='10') diff --git a/tests/cfg/autotest_control.cfg b/tests/cfg/autotest_control.cfg index 5d8a3f983..f9d7b06e3 100644 --- a/tests/cfg/autotest_control.cfg +++ b/tests/cfg/autotest_control.cfg @@ -128,3 +128,5 @@ test_control_file = posixtest.control - rmaptest: test_control_file = rmaptest.control + - synctest: + test_control_file = synctest.control From d667cb78165b840410aa8b6351dda4b6820fbe0c Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 2 Jul 2013 15:49:23 +0800 Subject: [PATCH 169/254] virt.tests: sync tbench testing to autotest_control testsuite Signed-off-by: Xu Tian <xutian@redhat.com> --- shared/control/tbench.control | 18 ++++++++++++++++++ tests/cfg/autotest_control.cfg | 2 ++ 2 files changed, 20 insertions(+) create mode 100644 shared/control/tbench.control diff --git a/shared/control/tbench.control b/shared/control/tbench.control new file mode 100644 index 000000000..c2aa96b72 --- /dev/null +++ b/shared/control/tbench.control @@ -0,0 +1,18 @@ +NAME = 'TBench' +AUTHOR = 'mbligh@google.com (Martin Bligh)' +TIME = 'MEDIUM' +TEST_CLASS = 'IO' +TEST_CATEGORY = 'Benchmark' +TEST_TYPE = 'client' + +DOC = """ +tbench produces only the TCP and process load. It does the same socket +calls that smbd would do under a netbench load. It does no filesystem +calls. The idea behind tbench is to eliminate smbd from the netbench +test, as though the smbd code could be made infinately fast. The +throughput results of tbench tell us how fast a netbench run could go +if we eliminated all filesystem IO and SMB packet processing. tbench +is built as part of the dbench package. +""" + +job.run_test('tbench') diff --git a/tests/cfg/autotest_control.cfg b/tests/cfg/autotest_control.cfg index f9d7b06e3..be29fccaa 100644 --- a/tests/cfg/autotest_control.cfg +++ b/tests/cfg/autotest_control.cfg @@ -130,3 +130,5 @@ test_control_file = rmaptest.control - synctest: test_control_file = synctest.control + - tbench: + test_control_file = tbench.control From 36106c2ed927bcaa63a2a19498dd113d69bd0da3 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 2 Jul 2013 17:01:47 +0800 Subject: [PATCH 170/254] virt.tests: sync tiobench testing to autotest_control testsuite test threads IO in guest when drive AIO is native or threads; Signed-off-by: Xu Tian <xutian@redhat.com> --- shared/control/tiobench.control | 16 ++++++++++++++++ tests/cfg/autotest_control.cfg | 8 ++++++++ 2 files changed, 24 insertions(+) create mode 100644 shared/control/tiobench.control diff --git a/shared/control/tiobench.control b/shared/control/tiobench.control new file mode 100644 index 000000000..3a630fe7a --- /dev/null +++ b/shared/control/tiobench.control @@ -0,0 +1,16 @@ +NAME = 'Threaded IO Bench' +TIME = 'MEDIUM' +TEST_CLASS = 'IO' +TEST_CATEGORY = 'Benchmark' +TEST_TYPE = 'client' + +DOC = """ +Performs threaded I/O benchmarks. + +100000 random IO request, 10 threads and create 1.5G file +""" + +job.run_test('tiobench', + args='--block=512 --random=100000 --threads=10 --size=1536', + iterations=1, + dir='/mnt') diff --git a/tests/cfg/autotest_control.cfg b/tests/cfg/autotest_control.cfg index be29fccaa..37124ef44 100644 --- a/tests/cfg/autotest_control.cfg +++ b/tests/cfg/autotest_control.cfg @@ -132,3 +132,11 @@ test_control_file = synctest.control - tbench: test_control_file = tbench.control + - tiobench: + test_timeout = 4200 + test_control_file = tiobench.control + variants: + - aio_native: + image_aio = native + - aio_threads: + image_aio = threads From 36bd0ec6205fd12589c00120b47727b8e49fb7a3 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 16 Jul 2013 13:51:41 +0800 Subject: [PATCH 171/254] virt.tests: sync fio test to autotest_control testsuite Signed-off-by: Xu Tian <xutian@redhat.com> --- shared/control/fio.control | 13 +++++++++++++ tests/cfg/autotest_control.cfg | 5 +++++ 2 files changed, 18 insertions(+) create mode 100644 shared/control/fio.control diff --git a/shared/control/fio.control b/shared/control/fio.control new file mode 100644 index 000000000..2b5e75f68 --- /dev/null +++ b/shared/control/fio.control @@ -0,0 +1,13 @@ +AUTHOR = "Randy.Dunlap <rdunlap@xenotime.net>" +NAME = "fio" +TEST_CATEGORY = "Stress" +TEST_CLASS = "General" +TEST_TYPE = "client" +TIME = 'MEDIUM' +EXPERIMENTAL = "True" +DOC=''' +fio is an I/O tool meant to be used both for benchmark and stress/hardware +verification. This test runs the fio tool. Details can be found at : +http://freecode.com/projects/fio +''' +job.run_test('fio', args="-rw=randread -bs=8k -size 1G -numjobs=8 -runtime=600 -iodepth=32 -iodepth_batch=16") diff --git a/tests/cfg/autotest_control.cfg b/tests/cfg/autotest_control.cfg index 37124ef44..583fa9b93 100644 --- a/tests/cfg/autotest_control.cfg +++ b/tests/cfg/autotest_control.cfg @@ -140,3 +140,8 @@ image_aio = native - aio_threads: image_aio = threads + - fio: + no RHEL.3 RHEL.4 + test_timeout =1800 + test_control_file = fio.control + From 0e3c5b0c645fe45c0cf6ce5607cd9fd502c29805 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 16 Jul 2013 13:57:09 +0800 Subject: [PATCH 172/254] virt.tests: sync unixbench5 to autotest_control testsuite Signed-off-by: Xu Tian <xutian@redhat.com> --- shared/control/unixbench5.control | 26 ++++++++++++++++++++++++++ tests/cfg/autotest_control.cfg | 5 ++++- 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 shared/control/unixbench5.control diff --git a/shared/control/unixbench5.control b/shared/control/unixbench5.control new file mode 100644 index 000000000..862a52160 --- /dev/null +++ b/shared/control/unixbench5.control @@ -0,0 +1,26 @@ +NAME = 'Unix Bench 5' +AUTHOR = 'adrianbg@google.com' +TIME = 'MEDIUM' +PURPOSE = 'Measure system level performance.' +CRITERIA = 'This test is a benchmark.' +TEST_CLASS = 'Kernel' +TEST_CATEGORY = 'Benchmark' +TEST_TYPE = 'client' +DOC = """ +This test measure system wide performance by running the following tests: + - Dhrystone - focuses on string handling. + - Whetstone - measure floating point operations. + - Execl Throughput - measure the number of execl calls per second. + - File Copy + - Pipe throughput + - Pipe-based context switching + - Process creation - number of times a process can fork and reap + - Shell Scripts - number of times a process can start and reap a script + - System Call Overhead - estimates the cost of entering and leaving the + kernel. + +For more information visit: +http://code.google.com/p/byte-unixbench/ +""" + +job.run_test('unixbench5') diff --git a/tests/cfg/autotest_control.cfg b/tests/cfg/autotest_control.cfg index 583fa9b93..a9e161de5 100644 --- a/tests/cfg/autotest_control.cfg +++ b/tests/cfg/autotest_control.cfg @@ -144,4 +144,7 @@ no RHEL.3 RHEL.4 test_timeout =1800 test_control_file = fio.control - + - unixbench5: + no RHEL.3 RHEL.4 + test_timeout = 4200 + test_control_file = unixbench5.control From ef032a268f688d32046d6675e0c0465d7c2b28e2 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 16 Jul 2013 14:01:11 +0800 Subject: [PATCH 173/254] virt.tests: sync wb_kupdate test to autotest_control testsuite Signed-off-by: Xu Tian <xutian@redhat.com> --- shared/control/wb_kupdate.control | 44 +++++++++++++++++++++++++++++++ tests/cfg/autotest_control.cfg | 3 +++ 2 files changed, 47 insertions(+) create mode 100644 shared/control/wb_kupdate.control diff --git a/shared/control/wb_kupdate.control b/shared/control/wb_kupdate.control new file mode 100644 index 000000000..eed8847e4 --- /dev/null +++ b/shared/control/wb_kupdate.control @@ -0,0 +1,44 @@ +AUTHOR = "Akshay Lal <akshaylal@google.com>" +NAME = "wb_kupdate" +TEST_CATEGORY = "Functional" +TEST_CLASS = "General" +TEST_TYPE = "client" +TIME = 'MEDIUM' +DOC=''' +This tests checks the wb_kupdate code path by writting data to a sparse file +and waiting at max of `max_flush_time` for the file to be flushed from the +cache to disk. +''' + +import os +# Required Parameters: +# -------------------- +mount_point='/export/wb_kupdate' # Absolute path. +file_count=5 # The number of files to write. +write_size=1 # In MB. + +# Optional Parameters: +# -------------------- +max_flush_time=1 # In minutes. +file_system='ext4' # mkfs.<file_system> must already exist on + # the machine. To avoid device initialization + # set to None. +remove_previous=False # Boolean. +sparse_file=os.path.join( # Absolute path to the sparse file. + job.tmpdir, + 'sparse_file') +old_cleanup=False # Remove a previously created mount_point if it + # exits and not mounted. + +# Beginning execution of the xfstests: +# ------------------------------------ +job.run_test('wb_kupdate', + mount_point=mount_point, + file_count=int(file_count), + write_size=int(write_size), + max_flush_time=int(max_flush_time), + file_system=file_system, + remove_previous=remove_previous, + sparse_file=sparse_file, + old_cleanup=old_cleanup, + tag='wb_kupdate_execution') diff --git a/tests/cfg/autotest_control.cfg b/tests/cfg/autotest_control.cfg index a9e161de5..8b48f009e 100644 --- a/tests/cfg/autotest_control.cfg +++ b/tests/cfg/autotest_control.cfg @@ -148,3 +148,6 @@ no RHEL.3 RHEL.4 test_timeout = 4200 test_control_file = unixbench5.control + - wb_kupdate: + test_timeout =1800 + test_control_file = wb_kupdate.control From d1770500c68cda431a21beae340a61ab136867cf Mon Sep 17 00:00:00 2001 From: Li Yang <liyang.fnst@cn.fujitsu.com> Date: Thu, 1 Aug 2013 13:56:09 +0800 Subject: [PATCH 174/254] libvirt: Fix a bug in virsh_change_media test and modify format Signed-off-by: Li Yang <liyang.fnst@cn.fujitsu.com> --- .../virsh_cmd/domain/virsh_change_media.cfg | 59 ++++++++------- .../virsh_cmd/domain/virsh_change_media.py | 75 +++++++++++-------- 2 files changed, 72 insertions(+), 62 deletions(-) diff --git a/libvirt/tests/cfg/virsh_cmd/domain/virsh_change_media.cfg b/libvirt/tests/cfg/virsh_cmd/domain/virsh_change_media.cfg index 9f3c44800..f0dd2b767 100644 --- a/libvirt/tests/cfg/virsh_cmd/domain/virsh_change_media.cfg +++ b/libvirt/tests/cfg/virsh_cmd/domain/virsh_change_media.cfg @@ -1,14 +1,15 @@ - virsh_change_media: + virt_test_type = libvirt type = virsh_change_media - old_iso = "change_media_old.iso" - new_iso = "change_media_new.iso" - update_iso_xml = "update_iso.xml" - disk_device = "hdc" - vm_ref = "name" - init_cdrom = "''" + change_media_update_iso_xml = "update_iso.xml" + change_media_disk_device = "hdc" + change_media_vm_ref = "name" + change_media_init_cdrom = "''" + change_media_old_iso = "change_media_old.iso" + change_media_new_iso = "change_media_new.iso" libvirtd = "on" - init_iso = "change_media_old.iso" change_media_source = + change_media_init_iso = "change_media_old.iso" variants: - positive_test: status_error = "no" @@ -21,52 +22,52 @@ - options: variants: - none: - options = " " + change_media_options = " " - current: - options = "--current" + change_media_options = "--current" - live: no shutoff_guest - options = "--live" + change_media_options = "--live" - force: - options = "--force" + change_media_options = "--force" - config: - options = "--config" + change_media_options = "--config" variants: - eject: - action = "--eject " - check_file = + change_media_action = "--eject " + change_media_check_file = - insert: change_media_source = "change_media_old.iso" - action = "--insert " - check_file = "old" - init_iso = + change_media_action = "--insert " + change_media_check_file = "old" + change_media_init_iso = - update: change_media_source = "change_media_new.iso" - action = "--update " - check_file = "new" + change_media_action = "--update " + change_media_check_file = "new" - negative_test: status_error = "yes" start_vm = "no" - options = "--current" + change_media_options = "--current" variants: - no_option: only insert - options = " " + change_media_options = " " - no_name: - vm_ref = " " + change_media_vm_ref = " " - unexpect_option: - vm_ref = "\#" + change_media_vm_ref = "\#" - invalid_option: - options = "--xyz" + change_media_options = "--xyz" - with_libvirtd_stop: - requires_root = "yes" + change_media_requires_root = "yes" libvirtd = "off" - shutoff_guest_with_live: - options = "--live" + change_media_options = "--live" variants: - eject: - action = "--eject " + change_media_action = "--eject " - insert: - action = "--insert " + change_media_action = "--insert " - update: - action = "--update " + change_media_action = "--update " diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_change_media.py b/libvirt/tests/src/virsh_cmd/domain/virsh_change_media.py index 9a9f6aff7..9f83cef07 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_change_media.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_change_media.py @@ -1,4 +1,4 @@ -import logging, os, shutil +import logging, os from autotest.client.shared import error, utils from virttest import virsh, utils_libvirtd from virttest.libvirt_xml import vm_xml @@ -20,6 +20,9 @@ def run_virsh_change_media(test, params, env): def env_pre(old_iso, new_iso): """ Prepare ISO image for test + + @param: old_iso: sourse file for insert + @param: new_iso: sourse file for update """ error.context("Preparing ISO images") utils.run("dd if=/dev/urandom of=%s/old bs=10M count=1" % cdrom_dir) @@ -31,9 +34,10 @@ def env_pre(old_iso, new_iso): def check_media(session, target_file, action): """ Check guest cdrom files - 1. guest session - 2. the expected files - 3. test case action + + @param: session: guest session + @param: target_file: the expected files + @action: action: test case action """ if action != "--eject ": error.context("Checking guest cdrom files") @@ -49,26 +53,34 @@ def check_media(session, target_file, action): def add_cdrom_device(vm_name, init_cdrom): """ Add cdrom device for test vm + + @param: vm_name: guest name + @param: init_cdrom: source file """ if vm.is_alive(): virsh.destroy(vm_name) virsh.attach_disk(vm_name, init_cdrom, - " hdc", " --type cdrom --sourcetype file --config", + disk_device, " --type cdrom --sourcetype file --config", debug=True) - def update_cdrom(vm_name, init_iso, options, start_vm ): + def update_cdrom(vm_name, init_iso, options, start_vm): """ Update cdrom iso file for test case + + @param: vm_name: guest name + @param: init_iso: source file + @param: options: update-device option + @param: start_vm: guest start flag """ snippet = """ <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='%s'/> -<target dev='hdc' bus='ide'/> +<target dev='%s' bus='ide'/> <readonly/> </disk> -""" % (init_iso) +""" % (init_iso, disk_device) update_iso_file = open(update_iso_xml, "w") update_iso_file.write(snippet) update_iso_file.close() @@ -84,27 +96,31 @@ def update_cdrom(vm_name, init_iso, options, start_vm ): vm_name = params.get("main_vm") vm = env.get_vm(vm_name) - vm_ref = params.get("vm_ref") - action = params.get("action") + vm_ref = params.get("change_media_vm_ref") + action = params.get("change_media_action") start_vm = params.get("start_vm") - options = params.get("options") + options = params.get("change_media_options") + disk_device = params.get("change_media_disk_device") + libvirtd = params.get("libvirtd", "on") + source_name = params.get("change_media_source") + status_error = params.get("status_error", "no") + check_file = params.get("change_media_check_file") + init_cdrom = params.get("change_media_init_cdrom") + update_iso_xml_name = params.get("change_media_update_iso_xml") + init_iso_name = params.get("change_media_init_iso") + old_iso_name = params.get("change_media_old_iso") + new_iso_name = params.get("change_media_new_iso") cdrom_dir = os.path.join(test.tmpdir, "tmp") + + old_iso = os.path.join(cdrom_dir, old_iso_name) + new_iso = os.path.join(cdrom_dir, new_iso_name) + update_iso_xml = os.path.join(cdrom_dir, update_iso_xml_name) if not os.path.exists(cdrom_dir): os.mkdir(cdrom_dir) - - old_iso_name = params.get("old_iso") - new_iso_name = params.get("new_iso") - old_iso = cdrom_dir + old_iso_name - new_iso = cdrom_dir + new_iso_name - init_cdrom = params.get("init_cdrom") - update_iso_xml_name = params.get("update_iso_xml") - update_iso_xml = cdrom_dir + update_iso_xml_name - init_iso_name = params.get("init_iso") if not init_iso_name : init_iso = "" - else: - init_iso = cdrom_dir + init_iso_name + init_iso = os.path.join(cdrom_dir, init_iso_name) if vm_ref == "name": vm_ref = vm_name @@ -113,7 +129,7 @@ def update_cdrom(vm_name, init_iso, options, start_vm ): # Check domain's disk device disk_blk = vm_xml.VMXML.get_disk_blk(vm_name) logging.info("disk_blk %s" % disk_blk) - if "hdc" not in disk_blk: + if disk_device not in disk_blk: logging.info("Adding cdrom device") add_cdrom_device(vm_name, init_cdrom) @@ -126,33 +142,27 @@ def update_cdrom(vm_name, init_iso, options, start_vm ): vm.start() update_cdrom(vm_name, init_iso, options, start_vm) - disk_device = params.get("disk_device") - libvirtd = params.get("libvirtd", "on") if libvirtd == "off": utils_libvirtd.libvirtd_stop() - source_name = params.get("change_media_source") # Libvirt will ignore --source when action is eject if action == "--eject ": source = "" - else: - source = cdrom_dir + source_name + source = os.path.join(cdrom_dir, source_name) all_options = action + options + " " + source result = virsh.change_media(vm_ref, disk_device, all_options, ignore_status=True, debug=True) status = result.exit_status - status_error = params.get("status_error", "no") if status_error == "no": if options == "--config" and vm.is_alive(): vm.destroy() - - vm.start() + if vm.is_dead(): + vm.start() session = vm.wait_for_login() - check_file = params.get("check_file") check_media(session, check_file, action) session.close() @@ -162,7 +172,6 @@ def update_cdrom(vm_name, init_iso, options, start_vm ): # Clean the cdrom dir and clean the cdrom device update_cdrom(vm_name, "", options, start_vm) - shutil.rmtree(cdrom_dir) # Check status_error From adfe1a9b92daef85c67ba52dffbeca8deb04215f Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 16 Jul 2013 00:35:22 +0800 Subject: [PATCH 175/254] qemu.tests: enhance base_copy modules New property self.events to contain block job events; And simplify reboot function; Signed-off-by: Xu Tian <xutian@redhat.com> --- qemu/tests/block_copy.py | 44 +++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/qemu/tests/block_copy.py b/qemu/tests/block_copy.py index cd4a9215c..8c581c8a5 100644 --- a/qemu/tests/block_copy.py +++ b/qemu/tests/block_copy.py @@ -26,7 +26,9 @@ def __init__(self, test, params, env, tag): self.params = params self.tag = tag self.vm = self.get_vm() + self.data_dir = data_dir.get_data_dir() self.device = self.get_device() + self.image_file = self.get_image_file() def parser_test_args(self): @@ -57,7 +59,7 @@ def get_device(self): """ according configuration get target device ID; """ - root_dir = data_dir.get_data_dir() + root_dir = self.data_dir params = self.parser_test_args() image_file = storage.get_image_filename(params, root_dir) device = self.vm.get_block({"file": image_file}) @@ -132,12 +134,14 @@ def is_cancelled(): timeout = params.get("cancel_timeout") if self.vm.monitor.protocol == "qmp": - self.vm.monitor.clear_events() + self.vm.monitor.clear_event("BLOCK_JOB_CANCELLED") self.vm.cancel_block_job(self.device) cancelled = utils_misc.wait_for(is_cancelled, timeout=timeout) if not cancelled: msg = "Cancel block job timeout in %ss" % timeout raise error.TestFail(msg) + if self.vm.monitor.protocol == "qmp": + self.vm.monitor.clear_event("BLOCK_JOB_CANCELLED") @error.context_aware @@ -178,37 +182,27 @@ def reboot(self, method="shell", boot_check=True): """ reboot VM, alias of vm.reboot(); """ - def reseted(): - """ - check reset event recived after system_reset execute, only for qmp - monitor; - """ - return self.vm.monitor.get_event("RESET") - params = self.parser_test_args() timeout = params["login_timeout"] if boot_check: session = self.get_session() - return self.vm.reboot(session=session, timeout=timeout, method=method) - if method == "system_reset": + return self.vm.reboot(session=session, + timeout=timeout, method=method) + if self.monitor.protocol == "qmp": error.context("reset guest via system_reset", logging.info) - event_check = False - if self.vm.monitor.protocol == "qmp": - event_check = True - self.vm.monitor.clear_events() + self.vm.monitor.clear_event("RESET") self.vm.monitor.cmd("system_reset") - if event_check: - reseted = utils_misc.wait_for(reseted, timeout=timeout) - if not reseted: - raise error.TestFail("No RESET event recived after" - "execute system_reset %ss" % timeout) - elif method == "shell": - reboot_cmd = params.get("reboot_command") - session = self.get_session() - session.sendline(reboot_cmd) + reseted = utils_misc.wait_for(lambda: + self.vm.monitor.get_event("RESET"), + timeout=timeout) + if not reseted: + raise error.TestFail("No RESET event recived after" + "execute system_reset %ss" % timeout) + self.vm.monitor.clear_event("RESET") else: - raise error.TestError("Unsupport reboot method '%s'" % method) + self.vm.monitor.cmd("system_reset") + return None @error.context_aware From 2d439c52cf898b9e3ccb4cb75da88d8472df9538 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Mon, 29 Jul 2013 17:42:47 +0800 Subject: [PATCH 176/254] qemu.tests: fix bug in get_image_file() update regrex to avoid get incorrect image file when images has backing file; Signed-off-by: Xu Tian <xutian@redhat.com> --- qemu/tests/block_copy.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/qemu/tests/block_copy.py b/qemu/tests/block_copy.py index 8c581c8a5..ba3383e61 100644 --- a/qemu/tests/block_copy.py +++ b/qemu/tests/block_copy.py @@ -243,11 +243,9 @@ def get_block_file(self): """ blocks = self.vm.monitor.info("block") if isinstance(blocks, str): - image_file = re.findall('%s: .*file=(\S*) ' % self.device, blocks) - if not image_file: - return None - else: - image_file = image_file[0] + image_file = re.findall('%s.*\s+file=(\S*)' % self.device, blocks) + if image_file: + return image_file[0] else: for block in blocks: if block['device'] == self.device: From 212e3154fcbc636af370359e063dca4023927021 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 16 Jul 2013 00:50:24 +0800 Subject: [PATCH 177/254] qemu.tests: enhanced drive_mirror module update drive_mirror module to make script works more stable; Signed-off-by: Xu Tian <xutian@redhat.com> --- qemu/tests/drive_mirror.py | 56 ++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/qemu/tests/drive_mirror.py b/qemu/tests/drive_mirror.py index 90416353c..b88f28acb 100644 --- a/qemu/tests/drive_mirror.py +++ b/qemu/tests/drive_mirror.py @@ -1,6 +1,6 @@ import logging, time from autotest.client.shared import error -from virttest import utils_misc +from virttest import utils_misc, storage from qemu.tests import block_copy class DriveMirror(block_copy.BlockCopy): @@ -10,6 +10,7 @@ class DriveMirror(block_copy.BlockCopy): def __init__(self, test, params, env, tag): super(DriveMirror, self).__init__(test, params, env, tag) + self.target_image = self.get_target_image() def parser_test_args(self): """ @@ -21,30 +22,38 @@ def parser_test_args(self): params["reopen_timeout"] = int(params.get("reopen_timeout", 60)) params["full_copy"] = params.get("full_copy", "").lower() params["check_event"] = params.get("check_event", "no").lower() - cmd = params.get("block_mirror_cmd", "__com.redhat.drive-mirror") - if cmd.startswith("__com.redhat"): + if params["block_mirror_cmd"].startswith("__"): params["full_copy"] = (params["full_copy"] == "full") return params + def get_target_image(self): + params = self.parser_test_args() + t_params = {} + t_params["image_name"] = params["target_image"] + t_params["image_format"] = params["target_format"] + target_image = storage.get_image_filename(t_params, self.data_dir) + return target_image + @error.context_aware def start(self): """ start block device mirroring job; """ params = self.parser_test_args() - target_image = params.get("target_image") - default_speed = params.get("default_speed") - full_copy = params.get("full_copy") - create_mode = params.get("create_mode") - target_format = params.get("target_format") - - error.context("start to mirror block device", logging.info) - self.vm.block_mirror(self.device, target_image, default_speed, + target_image = self.target_image + device = self.device + default_speed = params["default_speed"] + target_format = params["target_format"] + create_mode = params["create_mode"] + full_copy = params["full_copy"] + + error.context("Start to mirror block device", logging.info) + self.vm.block_mirror(device, target_image, default_speed, full_copy, target_format, create_mode) time.sleep(0.5) started = self.get_status() if not started: - raise error.TestFail("No active mirror job found") + raise error.TestFail("No active mirroring job found") self.trash.append(target_image) @error.context_aware @@ -55,12 +64,11 @@ def reopen(self): """ params = self.parser_test_args() - target_image = params.get("target_image") - target_format = params.get("target_format") - reopen_timeout = params.get("reopen_timeout") + target_format = params["target_format"] + timeout = params["reopen_timeout"] def is_opened(): - device = self.vm.get_block({"file": target_image}) + device = self.vm.get_block({"file": self.target_image}) ret = (device == self.device) if self.vm.monitor.protocol == "qmp": ret &= bool(self.vm.monitor.get_event("BLOCK_JOB_COMPLETED")) @@ -68,11 +76,11 @@ def is_opened(): error.context("reopen new target image", logging.info) if self.vm.monitor.protocol == "qmp": - self.vm.monitor.clear_events() - self.vm.block_reopen(self.device, target_image, target_format) - opened = utils_misc.wait_for(is_opened, timeout=reopen_timeout) + self.vm.monitor.clear_event("BLOCK_JOB_COMPLETED") + self.vm.block_reopen(self.device, self.target_image, target_format) + opened = utils_misc.wait_for(is_opened, first=3.0, timeout=timeout) if not opened: - msg = "Wait open new image timeout(%ss)" % reopen_timeout + msg = "Target image not used,wait timeout in %ss" % timeout raise error.TestFail(msg) def is_steady(self): @@ -95,10 +103,12 @@ def wait_for_steady(self): """ params = self.parser_test_args() timeout = params.get("wait_timeout") - steady =utils_misc.wait_for(self.is_steady, - step=2.0, timeout=timeout) + if self.vm.monitor.protocol == "qmp": + self.vm.monitor.clear_event("BLOCK_JOB_READY") + steady =utils_misc.wait_for(self.is_steady, step=2.0, + timeout=timeout) if not steady: - raise error.TestFail("wait job goin ready status" + raise error.TestFail("Wait mirroring job ready " "timeout in %ss" % timeout) def action_before_start(self): From ab2307ce2b5c5701bd9e567dc71b6fc8b6832f65 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 16 Jul 2013 00:56:14 +0800 Subject: [PATCH 178/254] qemu.tests: update mirroring with reboot test update tests steps to make it more reasonable; Signed-off-by: Xu Tian <xutian@redhat.com> --- qemu/tests/block_copy.py | 2 +- qemu/tests/drive_mirror_reboot.py | 41 +++---------------------------- 2 files changed, 5 insertions(+), 38 deletions(-) diff --git a/qemu/tests/block_copy.py b/qemu/tests/block_copy.py index ba3383e61..66201a51a 100644 --- a/qemu/tests/block_copy.py +++ b/qemu/tests/block_copy.py @@ -189,7 +189,7 @@ def reboot(self, method="shell", boot_check=True): session = self.get_session() return self.vm.reboot(session=session, timeout=timeout, method=method) - if self.monitor.protocol == "qmp": + if self.vm.monitor.protocol == "qmp": error.context("reset guest via system_reset", logging.info) self.vm.monitor.clear_event("RESET") self.vm.monitor.cmd("system_reset") diff --git a/qemu/tests/drive_mirror_reboot.py b/qemu/tests/drive_mirror_reboot.py index 7120a6082..315002b1b 100644 --- a/qemu/tests/drive_mirror_reboot.py +++ b/qemu/tests/drive_mirror_reboot.py @@ -1,42 +1,11 @@ -import time, random, logging -from autotest.client.shared import error, utils from qemu.tests import drive_mirror -class DriveMirrorReboot(drive_mirror.DriveMirror): - - STOP = False - - def __init__(self, test, params, env, tag): - super(DriveMirrorReboot, self).__init__(test, params, env, tag) - - @error.context_aware - def start_reset(self): - """ - Reset guest with system_reset in loop; - """ - reboot_method = self.params.get("reboot_method", "system_reset") - error.context("reset/restart guest in loop", logging.info) - while not self.STOP: - self.reboot(method=reboot_method) - random_sleep =random.randint(3, 20) - time.sleep(random_sleep) - return None - - @error.context_aware - def stop_reset(self): - """ - stop reset guest loop; - """ - error.context("stop reset/restart guest loop", logging.info) - self.STOP = True - - def run_drive_mirror_reboot(test, params, env): """ drive_mirror_reboot test: - 1). boot guest, do system_reset in loop + 1). boot guest, do system_reset 2). start mirroring, wait go into steady status - 3). reopen new image and stop system_reset, then reboot guest + 3). reopen new image then reboot guest 4). check guest alive @param test: QEMU test object @@ -44,13 +13,11 @@ def run_drive_mirror_reboot(test, params, env): @param env: Dictionary with test environment. """ tag = params.get("source_images", "image1") - reboot_test = DriveMirrorReboot(test, params, env, tag) + reboot_test = drive_mirror.DriveMirror(test, params, env, tag) try: - bg = utils.InterruptedThread(reboot_test.start_reset) - bg.start() + reboot_test.reboot("system_reset", False) reboot_test.start() reboot_test.action_when_steady() - bg.join() reboot_test.action_after_reopen() finally: reboot_test.clean() From f1f0803ad2b31070352634b2d8b74c97aa3d56b0 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 16 Jul 2013 01:13:42 +0800 Subject: [PATCH 179/254] qemu.tests: enhance drive mirror with stress test update stress app install steps Signed-off-by: Xu Tian <xutian@redhat.com> --- qemu/tests/drive_mirror_stress.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/qemu/tests/drive_mirror_stress.py b/qemu/tests/drive_mirror_stress.py index 3177efdef..24dbd8205 100644 --- a/qemu/tests/drive_mirror_stress.py +++ b/qemu/tests/drive_mirror_stress.py @@ -11,22 +11,24 @@ def __init__(self, test, params, env, tag): @error.context_aware def install_stress_app(self): - error.context("install stress app in guest") params = self.parser_test_args() session = self.get_session() - installed = session.cmd_status(params.get("app_check_cmd")) == 0 - if installed: - return + if session.cmd_status(params.get("app_check_cmd","true")) == 0: + return True + error.context("install stress app in guest", logging.info) link = params.get("download_link") md5sum = params.get("md5sum") tmp_dir = params.get("tmp_dir") - install_cmd = params.get("install_cmd") % tmp_dir + install_cmd = params.get("install_cmd") config_cmd = params.get("config_cmd") + logging.info("Fetch package: %s" % link) pkg = utils.unmap_url_cache(self.test.tmpdir, link, md5sum) self.vm.copy_files_to(pkg, tmp_dir) + logging.info("Install app: %s" % install_cmd) s, o = session.cmd_status_output(install_cmd, timeout=300) if s != 0: raise error.TestError("Fail to install stress app(%s)" % o) + logging.info("Configure app: %s" % config_cmd) s, o = session.cmd_status_output(config_cmd, timeout=300) if s != 0: raise error.TestError("Fail to conifg stress app(%s)" % o) @@ -43,8 +45,8 @@ def load_stress(self): session = self.get_session() error.context("launch stress app in guest", logging.info) session.sendline(cmd) - logging.info("Command: %s" % cmd) - runing = utils_misc.wait_for(self.app_runing, first=0.5, timeout=300) + logging.info("Start command: %s" % cmd) + runing = utils_misc.wait_for(self.app_runing, timeout=150, step=5) if not runing: raise error.TestFail("stress app isn't running") return None From 0aae60fec912af8a2a264303687cb5ce6c886bc7 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 16 Jul 2013 01:16:34 +0800 Subject: [PATCH 180/254] qemu.tests: update powerup with target image step Signed-off-by: Xu Tian <xutian@redhat.com> --- qemu/tests/drive_mirror_powerdown.py | 46 +++++++++------------------- 1 file changed, 14 insertions(+), 32 deletions(-) diff --git a/qemu/tests/drive_mirror_powerdown.py b/qemu/tests/drive_mirror_powerdown.py index 473bb84be..b53ad85a1 100644 --- a/qemu/tests/drive_mirror_powerdown.py +++ b/qemu/tests/drive_mirror_powerdown.py @@ -1,61 +1,43 @@ import logging -from virttest import storage, data_dir -from autotest.client.shared import error, utils +from virttest import env_process +from autotest.client.shared import error from qemu.tests import drive_mirror_stress class DriveMirrorPowerdown(drive_mirror_stress.DriveMirrorStress): def __init__(self, test, params, env, tag): super(DriveMirrorPowerdown, self).__init__(test, params, env, tag) - params = self.params.object_params(self.tag) - image_file = storage.get_image_filename(params, - data_dir.get_data_dir()) - self.params["image_file"] = image_file @error.context_aware def powerdown(self): """ power down guest via quit qemu; """ - params = self.parser_test_args() error.context("powerdown vm", logging.info) - self.vm.destroy() - error.context("backup base image", logging.info) - image_file = params.get("image_file") - cmd = "mv %s %s-bak" % (image_file, image_file) - utils.system(cmd) - return + return self.vm.destroy() @error.context_aware def powerup(self): """ - bootup guest with target image, same as reopen new image; - steps are: - 1). backup base image, move target image as base image - 2). bootup guest with target image; + bootup guest with target image; """ params = self.parser_test_args() - image_file = params.get("image_file") - target_image = params.get("target_image") - cmd = "mv -f %s %s" % (target_image, image_file) - error.context("copy target image") - utils.system(cmd) + vm_name = params['main_vm'] + self.params["image_name"] = params["target_image"] + self.params["image_format"] = params["target_format"] + logging.info("Target image: %s" % self.target_image) error.context("powerup vm with target image", logging.info) - self.vm.create() - - def clean(self): - params = self.parser_test_args() - image_file = params.get("image_file") - super(DriveMirrorPowerdown, self).clean() - cmd = "mv -f %s-bak %s" % (image_file, image_file) - utils.system(cmd) + env_process.preprocess_vm(self.test, self.params, self.env, vm_name) + vm = self.env.get_vm(vm_name) + vm.verify_alive() + self.vm = vm def run_drive_mirror_powerdown(test, params, env): """ drive_mirror_powerdown test: 1). boot guest, do kernel build - 3). mirror disk to target image - 4). wait go into steady status, then quit qemu + 3). mirror boot disk to target image + 4). wait mirroring go into ready status then quit qemu 5). bootup guest with target image 6). check guest can response correctly From d07427f0e90ec08fbce9f7adee44185e073c781b Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 16 Jul 2013 01:22:54 +0800 Subject: [PATCH 181/254] qemu.tests: refactor block mirror test with exist framework The test add by commit 4436fb03c30317597848a7ea7e87577b90582aa9 and it only support human monitors commands; This commit split sub-test in this commit into two case and refactor it with exist test framework to make it support both QMP monitor and windows guest; Signed-off-by: Xu Tian <xutian@redhat.com> --- qemu/tests/block_mirror.py | 138 ------------------- qemu/tests/cfg/drive_mirror.cfg | 10 +- qemu/tests/drive_mirror_complete.py | 33 +++++ qemu/tests/drive_mirror_continuous_backup.py | 41 ++++++ 4 files changed, 82 insertions(+), 140 deletions(-) delete mode 100644 qemu/tests/block_mirror.py create mode 100644 qemu/tests/drive_mirror_complete.py create mode 100644 qemu/tests/drive_mirror_continuous_backup.py diff --git a/qemu/tests/block_mirror.py b/qemu/tests/block_mirror.py deleted file mode 100644 index ac4fb6158..000000000 --- a/qemu/tests/block_mirror.py +++ /dev/null @@ -1,138 +0,0 @@ -import os, logging, time -from autotest.client.shared import utils, error -from virttest import qemu_monitor, qemu_storage, storage, env_process, data_dir -from virttest import utils_misc - - -@error.context_aware -def run_block_mirror(test, params, env): - """ - Test block mirroring functionality - - Test consists of two subtests: - - 1) Mirror the guest and switch to the mirrored one - 2) Synchronize disk and then do continuous backup - - "qemu-img compare" is used to verify disk is mirrored successfully. - """ - image_name = params.get("image_name", "image") - image_format = params.get("image_format", "qcow2") - image_mirror = utils_misc.get_path(data_dir.get_data_dir(), - "%s-mirror.%s" % (image_name, - image_format)) - block_mirror_cmd = params.get("block_mirror_cmd", "drive-mirror") - qemu_img = qemu_storage.QemuImg(params, data_dir.get_data_dir(), - "block-mirror") - source_images = params.get("source_images", "image1").split() - source_image = source_images[0] - _params = params.object_params(source_image) - speed = int(_params.get("default_speed", 0)) - sync = _params.get("full_copy").lower() - if block_mirror_cmd.startswith("__"): - sync = (sync == "full") - mode = _params.get("create_mode", "absolute-paths") - format = _params.get("target_format", "qcow2") - check_event = _params.get("check_event") - - - def check_block_jobs_info(device_id): - """ - Verify block-jobs status reported by monitor command info block-jobs. - - @return: parsed output of info block-jobs - """ - fail = 0 - status = dict() - try: - status = vm.get_job_status(device_id) - except qemu_monitor.MonitorError, e: - logging.error(e) - fail += 1 - return status - return status - - - def run_mirroring(vm, device, dest, sync, speed=0, foramt="qcow2", - mode="absolute-paths", complete = True): - """ - Run block mirroring. - - @param vm: Virtual machine object - @param device: Guest device that has to be mirrored - @param dest: Location image has to be mirrored into - @param speed: limited speed - @param format: target image format - @param mode: image create mode - @param complete: If True, mirroring will complete (switch to mirror), - If False, finish image synchronization and keep - mirroring running (any changes will be mirrored) - """ - vm.block_mirror(device, dest, speed, sync, format, mode) - while True: - status = check_block_jobs_info(device) - if 'mirror' in status.get("type", ""): - logging.info("[(Completed bytes): %s (Total bytes): %s " - "(Speed limit in bytes/s): %s]", status["offset"], - status["len"], status["speed"]) - if status["offset"] != int(status["len"]): - time.sleep(10) - continue - elif vm.monitor.protocol == "qmp" and check_event == "yes": - if vm.monitor.get_event("BLOCK_JOB_READY") is None: - continue - else: - logging.info("Target synchronized with source") - if complete: - logging.info("Start mirroring completing") - vm.pause() - vm.block_reopen(device, dest, format) - time.sleep(5) - else: - break - elif not status: - logging.info("Block job completed") - break - - try: - # Setup phase - vm_name = params['main_vm'] - env_process.preprocess_vm(test, params, env, vm_name) - vm = env.get_vm(vm_name) - vm.create() - - timeout = int(params.get("login_timeout", 360)) - session = vm.wait_for_login(timeout=timeout) - img_path = storage.get_image_filename(params, data_dir.get_data_dir()) - device_id = vm.get_block({"file": img_path}) - - - # Subtest 1 - Complete mirroring - error.context("Testing complete mirroring") - run_mirroring(vm, device_id, image_mirror, sync, speed, format, mode) - _device_id = vm.get_block({"file": image_mirror}) - if device_id != _device_id: - raise error.TestError("Mirrored image not being used by guest") - error.context("Compare fully mirrored images") - qemu_img.compare_images(img_path, image_mirror) - vm.destroy() - - # Subtest 2 - Continuous backup - error.context("Testing continuous backup") - vm.create() - session = vm.wait_for_login(timeout=timeout) - run_mirroring(vm, device_id, image_mirror, sync, - speed, format, mode, False) - for fn in range(0,128): - session.cmd("dd bs=1024 count=1024 if=/dev/urandom of=tmp%d.file" - % fn) - time.sleep(10) - vm.pause() - time.sleep(5) - error.context("Compare original and backup images") - qemu_img.compare_images(img_path, image_mirror) - vm.destroy() - - finally: - if os.path.isfile(image_mirror): - os.remove(image_mirror) diff --git a/qemu/tests/cfg/drive_mirror.cfg b/qemu/tests/cfg/drive_mirror.cfg index 79b312254..a68a52ea4 100644 --- a/qemu/tests/cfg/drive_mirror.cfg +++ b/qemu/tests/cfg/drive_mirror.cfg @@ -30,7 +30,7 @@ target_image_image1 = "/tmp/target1" check_event = no variants: - - simple: + - simple_test: type = drive_mirror_simple repeat_times = 3 cancel_timeout = 3 @@ -50,7 +50,13 @@ default_speed_image1 = 3M max_speed_image1 = 10M - mirroring: - type = block_mirror + variants: + - block_job_complete: + type = drive_mirror_complete + - continuous_backup: + type = drive_mirror_continuous_backup + clean_cmd = "rm -f tmp*.file" + dd_cmd = "dd if=/dev/zero bs=1024 count=1024 of=tmp%s.file" - with_stress: type = drive_mirror_stress reopen_timeout = 360 diff --git a/qemu/tests/drive_mirror_complete.py b/qemu/tests/drive_mirror_complete.py new file mode 100644 index 000000000..9fa9fe8b8 --- /dev/null +++ b/qemu/tests/drive_mirror_complete.py @@ -0,0 +1,33 @@ +import logging, time +from autotest.client.shared import error +from virttest import qemu_storage, data_dir +from qemu.tests import drive_mirror + +@error.context_aware +def run_drive_mirror_complete(test, params, env): + """ + Test block mirroring functionality + + 1) Mirror the guest and switch to the mirrored one + + "qemu-img compare" is used to verify disk is mirrored successfully. + """ + tag = params.get("source_images", "image1") + qemu_img = qemu_storage.QemuImg(params, data_dir.get_data_dir(), tag) + mirror_test = drive_mirror.DriveMirror(test, params, env, tag) + try: + source_image = mirror_test.get_image_file() + target_image = mirror_test.get_target_image() + mirror_test.start() + mirror_test.wait_for_steady() + mirror_test.vm.pause() + mirror_test.reopen() + device_id = mirror_test.vm.get_block({"file": target_image}) + if device_id != mirror_test.device: + raise error.TestError("Mirrored image not being used by guest") + time.sleep(5) + error.context("Compare fully mirrored images", logging.info) + qemu_img.compare_images(source_image, target_image) + mirror_test.vm.destroy() + finally: + mirror_test.clean() diff --git a/qemu/tests/drive_mirror_continuous_backup.py b/qemu/tests/drive_mirror_continuous_backup.py new file mode 100644 index 000000000..f710b1323 --- /dev/null +++ b/qemu/tests/drive_mirror_continuous_backup.py @@ -0,0 +1,41 @@ +import logging, time +from autotest.client.shared import error +from virttest import qemu_storage, data_dir +from qemu.tests import drive_mirror + +@error.context_aware +def run_drive_mirror_continuous_backup(test, params, env): + """ + 1) Synchronize disk and then do continuous backup + + "qemu-img compare" is used to verify disk is mirrored successfully. + """ + tag = params.get("source_images", "image1") + qemu_img = qemu_storage.QemuImg(params, data_dir.get_data_dir(), tag) + mirror_test = drive_mirror.DriveMirror(test, params, env, tag) + tmp_dir = params.get("tmp_dir", "c:\\") + clean_cmd = params.get("clean_cmd", "del /f /s /q tmp*.file") + dd_cmd = "dd if=/dev/zero bs=1024 count=1024 of=tmp%s.file" + dd_cmd = params.get("dd_cmd", dd_cmd) + try: + source_image = mirror_test.get_image_file() + target_image = mirror_test.get_target_image() + mirror_test.start() + mirror_test.wait_for_steady() + error.context("Testing continuous backup") + session = mirror_test.get_session() + session.cmd("cd %s" % tmp_dir) + for fn in range(0, 128): + session.cmd(dd_cmd % fn) + time.sleep(10) + mirror_test.vm.pause() + time.sleep(5) + error.context("Compare original and backup images", logging.info) + mirror_test.vm.resume() + session = mirror_test.get_session() + session.cmd(clean_cmd) + session.cmd("cd %s" % tmp_dir) + qemu_img.compare_images(source_image, target_image) + mirror_test.vm.destroy() + finally: + mirror_test.clean() From 761689aff109dc4c594711227f14d8c6b137d1cb Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 16 Jul 2013 01:37:35 +0800 Subject: [PATCH 182/254] qemu.tests: update drive_mirror test cfg Update drive_mirror test configuration to make it stablly changes from v1: fix some coding style issue Signed-off-by: Xu Tian <xutian@redhat.com> --- qemu/tests/cfg/drive_mirror.cfg | 31 +++++++++++++++++-------------- qemu/tests/drive_mirror.py | 5 ++--- shared/cfg/guest-os/Windows.cfg | 2 +- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/qemu/tests/cfg/drive_mirror.cfg b/qemu/tests/cfg/drive_mirror.cfg index a68a52ea4..7910a54a4 100644 --- a/qemu/tests/cfg/drive_mirror.cfg +++ b/qemu/tests/cfg/drive_mirror.cfg @@ -2,7 +2,7 @@ no Host_RHEL.5 no Host_RHEL.6.1 no Host_RHEL.6.2 - only qcow2 + no raw qed vmdk type = drive_mirror monitor_type = qmp monitors = qmp1 @@ -27,13 +27,14 @@ # default speed unit is B/s, for 10MB/s please set speed to '10M' target_format_image1 = "qcow2" create_mode_image1 = "absolute-paths" - target_image_image1 = "/tmp/target1" + target_image_image1 = "images/target1" check_event = no + tmp_dir = "/tmp" variants: - simple_test: type = drive_mirror_simple repeat_times = 3 - cancel_timeout = 3 + cancel_timeout = 5 variants: - cancel: before_steady = "cancel" @@ -59,13 +60,12 @@ dd_cmd = "dd if=/dev/zero bs=1024 count=1024 of=tmp%s.file" - with_stress: type = drive_mirror_stress - reopen_timeout = 360 + reopen_timeout = 600 variants: - heavyload: - tmp_dir = "/tmp" download_link = http://weather.ou.edu/~apw/projects/stress/stress-1.0.4.tar.gz md5sum = a607afa695a511765b40993a64c6e2f4 - install_cmd = "tar -xzvf %s/stress-1.0.4.tar.gz -C ./ && cd stress-1.0.4 && ./configure --prefix=/usr && make && make install " + install_cmd = "tar -xzvf ${tmp_dir}/stress-1.0.4.tar.gz -C ./ && cd stress-1.0.4 && ./configure --prefix=/usr && make && make install " config_cmd = "" app_check_cmd = "stress --help" start_cmd = "stress --cpu 4 --io 4 --vm 2 --vm-bytes 256M --quiet &" @@ -89,23 +89,26 @@ after_reopen = "reboot verify_alive" - dd: app_check_cmd = "dd --help" - start_cmd = "(dd if=/dev/urandom of=/tmp/tmp.img bs=4k count=500000 oflag=direct &)" + start_cmd = "dd if=/dev/urandom of=/tmp/dd.img bs=4k count=500000" check_cmd = "pidof dd" - stop_cmd = "killall -g dd;rm -f /tmp/tmp.img" + stop_cmd = "pkill -g dd && rm -rf /tmp/dd*" before_start = "load_stress" when_steady = "reopen" after_reopen = "reboot verify_alive" - with_reboot: type = drive_mirror_reboot - when_steady = "reopen stop_reset" + when_steady = "reopen" after_reopen = "reboot verify_alive" - with_powerdown: type = drive_mirror_powerdown - app_check_cmd = "uname" - start_cmd = 'sh -c "wget -c https://www.kernel.org/pub/linux/kernel/v2.6/longterm/v2.6.35/linux-2.6.35.14.tar.gz -O /mnt/Linux.tgz && ' - start_cmd += 'tar -xzvf /mnt/Linux.tgz -C /mnt && cd /mnt/linux-2.6.35.14 && make defconfig && make && make modules"' - check_cmd = 'pidof -s make' - stop_cmd = 'pkill sh;rm -rf /mnt/linux-2.6.35.14' + app_check_cmd = "test -d ${tmp_dir}/linux-2.6.35.14" + download_link = "https://www.kernel.org/pub/linux/kernel/v2.6/longterm/v2.6.35/linux-2.6.35.14.tar.gz" + md5sum = "15e4021ffcb47b93c218083e1f2734a7" + install_cmd = "tar xzvf ${tmp_dir}/linux-2.6.35.14.tar.gz -C ${tmp_dir}/" + config_cmd = "cd ${tmp_dir}/linux-2.6.35.14 && make defconfig" + start_cmd = "cd ${tmp_dir}/linux-2.6.35.14 && make clean && make -j `grep processor /proc/cpuinfo|wc -l` && make modules" + check_cmd = "pidof make" + stop_cmd = "pkill -g make && rm -rf ${tmp_dir}/linux*" before_start = "load_stress" when_steady = "powerdown" after_reopen ="verify_alive" diff --git a/qemu/tests/drive_mirror.py b/qemu/tests/drive_mirror.py index b88f28acb..c7efd0e01 100644 --- a/qemu/tests/drive_mirror.py +++ b/qemu/tests/drive_mirror.py @@ -62,7 +62,6 @@ def reopen(self): reopen target image, then check if image file of the device is target images; """ - params = self.parser_test_args() target_format = params["target_format"] timeout = params["reopen_timeout"] @@ -105,8 +104,8 @@ def wait_for_steady(self): timeout = params.get("wait_timeout") if self.vm.monitor.protocol == "qmp": self.vm.monitor.clear_event("BLOCK_JOB_READY") - steady =utils_misc.wait_for(self.is_steady, step=2.0, - timeout=timeout) + steady = utils_misc.wait_for(self.is_steady, step=2.0, + timeout=timeout) if not steady: raise error.TestFail("Wait mirroring job ready " "timeout in %ss" % timeout) diff --git a/shared/cfg/guest-os/Windows.cfg b/shared/cfg/guest-os/Windows.cfg index 5a972a04e..1938306e8 100644 --- a/shared/cfg/guest-os/Windows.cfg +++ b/shared/cfg/guest-os/Windows.cfg @@ -297,7 +297,7 @@ start_cmd = "heavyload /CPU /MEMORY /START" check_cmd = 'tasklist | findstr /I "heavyload.exe"' stop_cmd = "taskkill /T /F /IM heavyload.exe" - drive_mirror.powerdown: + drive_mirror.with_powerdown: tmp_dir = "C:\" download_link = "http://www.jam-software.com/heavyload/HeavyLoadSetup.exe" md5sum = 5bf187bd914ac8ce7f79361d7b56bc15 From 5375426bd11ef2f7a6c18e7d25dca0d2b3018a4c Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 16 Jul 2013 01:43:09 +0800 Subject: [PATCH 183/254] qemu.tests: add steps to install stress app if not installed Signed-off-by: Xu Tian <xutian@redhat.com> --- qemu/tests/block_stream_stress.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/qemu/tests/block_stream_stress.py b/qemu/tests/block_stream_stress.py index 1b2a96e19..23968efa4 100644 --- a/qemu/tests/block_stream_stress.py +++ b/qemu/tests/block_stream_stress.py @@ -1,5 +1,6 @@ import time, logging from autotest.client.shared import error +from autotest.client import utils from virttest import utils_misc from qemu.tests import blk_stream @@ -19,12 +20,37 @@ def parser_test_args(self): "configuration at first") return params + @error.context_aware + def install_stress_app(self): + params = self.parser_test_args() + session = self.get_session() + if session.cmd_status(params.get("app_check_cmd","true")) == 0: + return True + error.context("install stress app in guest", logging.info) + link = params.get("download_link") + md5sum = params.get("md5sum") + tmp_dir = params.get("tmp_dir") + install_cmd = params.get("install_cmd") + config_cmd = params.get("config_cmd") + logging.info("Fetch package: %s" % link) + pkg = utils.unmap_url_cache(self.test.tmpdir, link, md5sum) + self.vm.copy_files_to(pkg, tmp_dir) + logging.info("Install app: %s" % install_cmd) + s, o = session.cmd_status_output(install_cmd, timeout=300) + if s != 0: + raise error.TestError("Fail to install stress app(%s)" % o) + logging.info("Configure app: %s" % config_cmd) + s, o = session.cmd_status_output(config_cmd, timeout=300) + if s != 0: + raise error.TestError("Fail to conifg stress app(%s)" % o) + @error.context_aware def load_stress(self): """ load IO/CPU/Memoery stress in guest; """ params = self.parser_test_args() + self.install_stress_app() cmd = params.get("start_cmd") session = self.get_session() error.context("Load stress in guest(%s)" % cmd, logging.info) From ea12111502edd6e13e6666d58b26e7ba8fa13ffb Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 16 Jul 2013 01:57:49 +0800 Subject: [PATCH 184/254] qemu.tests: move snapshot image to image dir Signed-off-by: Xu Tian <xutian@redhat.com> --- qemu/tests/block_stream_check_backingfile.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qemu/tests/block_stream_check_backingfile.py b/qemu/tests/block_stream_check_backingfile.py index 974d2e564..845773a0d 100644 --- a/qemu/tests/block_stream_check_backingfile.py +++ b/qemu/tests/block_stream_check_backingfile.py @@ -1,5 +1,6 @@ import logging from autotest.client.shared import error +from virttest import utils_misc from qemu.tests import blk_stream class BlockStreamCheckBackingfile(blk_stream.BlockStream): @@ -40,6 +41,7 @@ def check_imagefile(self): """ params = self.parser_test_args() exp_img_file = params["expected_image_file"] + exp_img_file = utils_misc.get_path(self.data_dir, exp_img_file) error.context("Check image file is '%s'" % exp_img_file, logging.info) img_file = self.get_image_file() if exp_img_file != img_file: From ed13130217dd811932c6e69a754c092d57d571d1 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 16 Jul 2013 02:15:20 +0800 Subject: [PATCH 185/254] qemu.tests: update block copy test configuration Update configuration to make test works stably Signed-off-by: Xu Tian <xutian@redhat.com> --- qemu/tests/cfg/block_stream.cfg | 10 ++++++++-- shared/cfg/guest-os/Windows.cfg | 14 +------------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/qemu/tests/cfg/block_stream.cfg b/qemu/tests/cfg/block_stream.cfg index b516326d5..1798d3f30 100644 --- a/qemu/tests/cfg/block_stream.cfg +++ b/qemu/tests/cfg/block_stream.cfg @@ -2,6 +2,7 @@ # monitor, so suggest to use QMP monitor as default qemu monitor run below test # - block_stream: + no raw qed vmdk backup_image_before_testing = yes restore_image_after_testing = yes wait_finished = yes @@ -54,11 +55,16 @@ snapshot_check_cmd = "lsof -p %s|awk '{print $9}'|grep ^/" - check_backingfile: type = block_stream_check_backingfile - snapshot_chain = "/tmp/sn1" - expected_image_file = "/tmp/sn1" + snapshot_chain = "images/sn1" + expected_image_file = "images/sn1" after_finished = "check_backingfile check_imagefile verify_alive" - with_stress: type = block_stream_stress + download_link = http://weather.ou.edu/~apw/projects/stress/stress-1.0.4.tar.gz + md5sum = a607afa695a511765b40993a64c6e2f4 + install_cmd = "tar -xzvf ${tmp_dir}/stress-1.0.4.tar.gz -C ./ && cd stress-1.0.4 && ./configure --prefix=/usr && make && make install " + config_cmd = "" + app_check_cmd = "stress --help" wait_timeout = 3600 before_start = "load_stress" start_cmd = "stress --cpu 4 --io 4 --vm 2 --vm-bytes 256M --quiet &" diff --git a/shared/cfg/guest-os/Windows.cfg b/shared/cfg/guest-os/Windows.cfg index 1938306e8..1071c6412 100644 --- a/shared/cfg/guest-os/Windows.cfg +++ b/shared/cfg/guest-os/Windows.cfg @@ -54,8 +54,6 @@ guest_path = C:\tmpfile stress_boot: alive_test_cmd = systeminfo - block_stream: - alive_test_cmd = systeminfo timedrift: # Timedrift compensation on Windows with hpet does not happen disable_hpet = yes @@ -287,17 +285,7 @@ start_cmd = "dd if=/dev/random of=c:\test.img bs=4k count=25000" stop_cmd = 'taskkill /F /T /IM dd.exe & del /f /s /q "c:\test.img"' check_cmd = 'tasklist | findstr /I "dd.exe"' - drive_mirror.with_stress.heavyload: - tmp_dir = "C:\" - download_link = "http://www.jam-software.com/heavyload/HeavyLoadSetup.exe" - md5sum = 5bf187bd914ac8ce7f79361d7b56bc15 - install_cmd = 'start /wait %s\HeavyLoadSetup.exe /verysilent' - config_cmd = 'setx path "%path%;C:\Program Files\JAM Software\HeavyLoad" -m' - app_check_cmd = "heavyload" - start_cmd = "heavyload /CPU /MEMORY /START" - check_cmd = 'tasklist | findstr /I "heavyload.exe"' - stop_cmd = "taskkill /T /F /IM heavyload.exe" - drive_mirror.with_powerdown: + drive_mirror.with_stress.heavyload, drive_mirror.with_powerdown, block_stream.with_stress: tmp_dir = "C:\" download_link = "http://www.jam-software.com/heavyload/HeavyLoadSetup.exe" md5sum = 5bf187bd914ac8ce7f79361d7b56bc15 From 479f696a64d798e3de6ee792cebcaccc7dc2808c Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 16 Jul 2013 10:55:21 +0800 Subject: [PATCH 186/254] qemu.tests: update config filter some qemu images case use "no raw qed vmdk" instead "only qcow2" because new image format (eg. qcow3) maybe support in futuer; Signed-off-by: Xu Tian <xutian@redhat.com> --- qemu/tests/cfg/live_snapshot.cfg | 1 + qemu/tests/cfg/live_snapshot_chain.cfg | 2 +- qemu/tests/cfg/qemu_disk_img.cfg | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/qemu/tests/cfg/live_snapshot.cfg b/qemu/tests/cfg/live_snapshot.cfg index 0b7634d92..4cd3298ac 100644 --- a/qemu/tests/cfg/live_snapshot.cfg +++ b/qemu/tests/cfg/live_snapshot.cfg @@ -1,6 +1,7 @@ - live_snapshot: virt_test_type = qemu type = live_snapshot + no raw vmdk qed kill_vm = yes create_sn_cmd = snapshot_blkdev create_cmd = "dd if=/dev/urandom of=%s bs=1M count=1024" diff --git a/qemu/tests/cfg/live_snapshot_chain.cfg b/qemu/tests/cfg/live_snapshot_chain.cfg index 3405f9737..ef4b00bbb 100644 --- a/qemu/tests/cfg/live_snapshot_chain.cfg +++ b/qemu/tests/cfg/live_snapshot_chain.cfg @@ -1,5 +1,5 @@ - live_snapshot_chain: - only qcow2 + no qed vmdk raw virt_test_type = qemu type = live_snapshot_chain snapshot_chain = "image1 sn1" diff --git a/qemu/tests/cfg/qemu_disk_img.cfg b/qemu/tests/cfg/qemu_disk_img.cfg index 9d5b5202f..d21fbe5a9 100644 --- a/qemu/tests/cfg/qemu_disk_img.cfg +++ b/qemu/tests/cfg/qemu_disk_img.cfg @@ -2,7 +2,7 @@ # For windows guest, you can download md5sum.exe from http://www.brothersoft.com/md5sum-81781.html, # then add parents dir to $PATH or config md5sum in share/cfg/guest-os/Windows.cfg; - qemu_disk_img: - only qcow2 + no qed raw vmdk virt_test_type = qemu type = qemu_disk_img image_chain= "image1" From cdb762699c6013d4735f97b911f3a77551637f8c Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 16 Jul 2013 11:22:16 +0800 Subject: [PATCH 187/254] virttest:new interface to clear a kind of events We need to clear a kind of event only before send a monitor command, and jude the command go into effect by check event; This interface used to clear this kinds of events in events list; Signed-off-by: Xu Tian <xutian@redhat.com> --- virttest/qemu_monitor.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/virttest/qemu_monitor.py b/virttest/qemu_monitor.py index 1e3358abc..c8c5a3598 100644 --- a/virttest/qemu_monitor.py +++ b/virttest/qemu_monitor.py @@ -1419,6 +1419,24 @@ def clear_events(self): self._lock.release() + def clear_event(self, name): + """ + Clear a kinds of events in events list only. + + @raise MonitorLockError: Raised if the lock cannot be acquired + """ + if not self._acquire_lock(): + raise MonitorLockError("Could not acquire exclusive lock to clear " + "QMP event list") + while True: + event = self.get_event(name) + if event: + self._events.remove(event) + else: + break + self._lock.release() + + def get_greeting(self): """ Return QMP greeting message. From 91879bcb5952729c052ad8761efa983f2f1505ae Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 16 Jul 2013 15:12:25 +0800 Subject: [PATCH 188/254] qemu.tests: fix incorrect test steps in qemu_img.rebase test qemu-img rebase function used to changes backing_file and backing_file format for an image file; In this case, we create snapshots "base->sn1->sn2", then rebase sn2's backing_file to base, then bootup with sn2 and check sn2's backing_file is base; Signed-off-by: Xu Tian <xutian@redhat.com> --- qemu/tests/qemu_img.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/qemu/tests/qemu_img.py b/qemu/tests/qemu_img.py index 1568f9900..490adf1d1 100644 --- a/qemu/tests/qemu_img.py +++ b/qemu/tests/qemu_img.py @@ -464,14 +464,13 @@ def rebase_test(cmd): os.remove(sn1) _rebase(cmd, sn2, base_img, image_format, mode=rebase_mode) - # Boot base image after rebase - img_suffix = ".%s" % image_format - img_name = base_img.split(img_suffix)[0] - _boot(img_name, image_format) + # Boot snapshot image after rebase + img_name, img_format = sn2.split('.') + _boot(img_name, img_format) # Check sn2's format and backing_file actual_base_img = _info(cmd, sn2, "backing file") - base_img_name = os.path.basename(params.get("image_name")) + base_img_name = os.path.basename(base_img) if not base_img_name in actual_base_img: raise error.TestFail("After rebase the backing_file of 'sn2' is " "'%s' which is not expected as '%s'" From 623e191f10ce3b4ffd9290184a478d07972dd629 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 16 Jul 2013 15:24:38 +0800 Subject: [PATCH 189/254] qemu.tests: correct configuration for qemu_img tests image rebase only support by qcow2 and qed image format; commit is used to commit connect to image's backingfile;And boot from converted qed format image is not support RHEL qemu; Signed-off-by: Xu Tian <xutian@redhat.com> --- qemu/tests/cfg/qemu_img.cfg | 3 +++ 1 file changed, 3 insertions(+) diff --git a/qemu/tests/cfg/qemu_img.cfg b/qemu/tests/cfg/qemu_img.cfg index 4170f45f0..1d7ffd8ae 100644 --- a/qemu/tests/cfg/qemu_img.cfg +++ b/qemu/tests/cfg/qemu_img.cfg @@ -57,6 +57,7 @@ - to_raw: dest_image_format = raw - to_qed: + no Host_RHEL dest_image_format = qed - snapshot: @@ -65,10 +66,12 @@ - info: subcommand = info - rebase: + no raw vmdk qed subcommand = rebase rebase_mode = unsafe image_name_snapshot1 = images/sn1 image_name_snapshot2 = images/sn2 # Commit is the only subtest that does need an installed guest - commit: install setup image_copy unattended_install.cdrom + no vmdk raw qed subcommand = commit From 78613920c53251b61133106b6101a51ee931e9bd Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Sun, 21 Jul 2013 23:15:52 +0800 Subject: [PATCH 190/254] qemu.tests: remove duplicated function in block_copy module Signed-off-by: Xu Tian <xutian@redhat.com> --- qemu/tests/blk_stream.py | 3 ++- qemu/tests/block_copy.py | 27 +++------------------------ 2 files changed, 5 insertions(+), 25 deletions(-) diff --git a/qemu/tests/blk_stream.py b/qemu/tests/blk_stream.py index e3daba285..1222a1bed 100644 --- a/qemu/tests/blk_stream.py +++ b/qemu/tests/blk_stream.py @@ -53,7 +53,7 @@ def create_snapshots(self): error.context("create live snapshots", logging.info) for sn in snapshots: sn = utils_misc.get_path(data_dir.get_data_dir(), sn) - image_file = self.get_block_file() + image_file = self.get_image_file() device = self.vm.live_snapshot(image_file, sn, format) if device != self.device: image_file = self.get_image_file() @@ -86,6 +86,7 @@ def wait_for_finished(self): text="wait job finshed in %ss"% timeout) if not finished: raise error.TestFail("Wait job finished timeout in %s" % timeout) + logging.info("Block stream job done.") def action_before_start(self): diff --git a/qemu/tests/block_copy.py b/qemu/tests/block_copy.py index 66201a51a..d5de8dcc1 100644 --- a/qemu/tests/block_copy.py +++ b/qemu/tests/block_copy.py @@ -20,6 +20,7 @@ class BlockCopy(object): sessions = [] trash = [] + def __init__(self, test, params, env, tag): self.test = test self.env = env @@ -66,28 +67,6 @@ def get_device(self): return device - def get_image_file(self): - """ - return file associated with $device device - """ - blocks = self.vm.monitor.info("block") - image_file = None - if isinstance(blocks, str): - image_file = re.findall('%s: .*file=(\S*) ' % self.device, blocks) - if not image_file: - return None - else: - image_file = image_file[0] - else: - for block in blocks: - if block['device'] == self.device: - try: - image_file = block['inserted']['file'] - except KeyError: - continue - return image_file - - def get_session(self): """ get a session object; @@ -132,7 +111,6 @@ def is_cancelled(): error.context("cancel block copy job", logging.info) params = self.parser_test_args() timeout = params.get("cancel_timeout") - if self.vm.monitor.protocol == "qmp": self.vm.monitor.clear_event("BLOCK_JOB_CANCELLED") self.vm.cancel_block_job(self.device) @@ -237,11 +215,12 @@ def verify_alive(self): return session.cmd(cmd, timeout=120) - def get_block_file(self): + def get_image_file(self): """ return file associated with $device device """ blocks = self.vm.monitor.info("block") + image_file = None if isinstance(blocks, str): image_file = re.findall('%s.*\s+file=(\S*)' % self.device, blocks) if image_file: From 56250962b5f826c5550247cf1efcd21e64ec9835 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Sun, 21 Jul 2013 23:17:29 +0800 Subject: [PATCH 191/254] qemu.tests: refactor block_stream test with exist framework changes from v1: use utils_misc.get_qemu_img_binary() to get qemu-img binary path instead re.search() with re.findall() Signed-off-by: Xu Tian <xutian@redhat.com> --- qemu/tests/block_stream.py | 158 +++++++++++-------------------------- 1 file changed, 46 insertions(+), 112 deletions(-) diff --git a/qemu/tests/block_stream.py b/qemu/tests/block_stream.py index faf2f4474..39d74e46c 100644 --- a/qemu/tests/block_stream.py +++ b/qemu/tests/block_stream.py @@ -1,6 +1,18 @@ -import re, os, logging, time -from autotest.client.shared import utils, error -from virttest import qemu_monitor, env_process, data_dir, storage +import re, logging +from autotest.client.shared import error, utils +from virttest import env_process, utils_misc +from qemu.tests import blk_stream + +class BlockStreamTest(blk_stream.BlockStream): + + def get_image_size(self, image_file): + qemu_img = utils_misc.get_qemu_img_binary(self.params) + cmd = "%s info %s" % (qemu_img, image_file) + info = utils.system_output(cmd) + size = re.findall("(\d+) bytes", info) + if size: + return int(size[0]) + return 0 @error.context_aware @@ -8,121 +20,43 @@ def run_block_stream(test, params, env): """ Test block streaming functionality. - 1) Create a image_bak.img with the backing file image.img - 2) Start the image_bak.img in qemu command line. - 3) Request for block-stream ide0-hd0/virtio0 + 1) create live snapshot image sn1 + 3) Request for block-stream 4) Wait till the block job finishs - 5) Check for backing file in image_bak.img - 6) TODO: Check for the size of the image_bak.img should not exceeds the image.img - 7) TODO(extra): Block job completion can be check in QMP + 5) Check for backing file in sn1 + 6) Check for the size of the sn1 should not exceeds image.img """ - image_format = params["image_format"] - image_name = storage.get_image_filename(params, data_dir.get_data_dir()) - backing_file_name = "%s_bak" % image_name - snapshot_format = params.get("snapshot_format", "qcow2") - qemu_img = params["qemu_img_binary"] - - - def check_block_jobs_info(device_id): - """ - Verify the status of block-jobs reported by monitor command info block-jobs. - @return: parsed output of info block-jobs - """ - fail = 0 - status = {} - try: - status = vm.get_job_status(device_id) - except qemu_monitor.MonitorError, e: - logging.error(e) - fail += 1 - return status - return status - + tag = params.get("source_images", "image1") + stream_test = BlockStreamTest(test, params, env, tag) try: - backing_file = "%s.%s" % (backing_file_name, image_format) - # Remove the existing backing file - if os.path.isfile(backing_file): - os.remove(backing_file) - - # Create the new backing file - create_cmd = "%s create -b %s -f %s %s" % (qemu_img, - image_name, - snapshot_format, - backing_file) - error.context("Creating backing file") - utils.system(create_cmd) - - info_cmd = "%s info %s" % (qemu_img, image_name) - error.context("Image file can not be find") - results = utils.system_output(info_cmd) - logging.info("Infocmd output of basefile: %s" ,results) - - # Set the qemu harddisk to the backing file - logging.info("Original image file is: %s", image_name) - params['image_name'] = backing_file_name - logging.info("Param image_name changed to: %s", params['image_name']) - - # Start virtual machine, using backing file as its harddisk - vm_name = params['main_vm'] - env_process.preprocess_vm(test, params, env, vm_name) - vm = env.get_vm(vm_name) - vm.verify_alive() - timeout = int(params.get("login_timeout", 360)) - session = vm.wait_for_login(timeout=timeout) - - info_cmd = "%s info %s" % (qemu_img, backing_file) - error.context("Image file can not be find") - results = utils.system_output(info_cmd) - logging.info("Infocmd output of backing file before block streaming: " - "%s", results) - - if not re.search("backing file:", str(results)): + image_file = stream_test.get_image_file() + image_size = stream_test.get_image_size(image_file) + stream_test.create_snapshots() + backingfile = stream_test.get_backingfile() + if not backingfile: raise error.TestFail("Backing file is not available in the " "backdrive image") - - device_id = vm.get_block({"file": backing_file}) - vm.block_stream(device_id, speed=0) - - while True: - info = check_block_jobs_info(device_id) - if info.get("type","") == "stream": - logging.info("[(Completed bytes): %s (Total bytes): %s " - "(Speed in bytes/s): %s]", info["len"], - info["offset"], info["speed"]) - time.sleep(10) - continue - if not info: - logging.info("Block job completed") - break - - info_cmd = "%s info %s" % (qemu_img, backing_file) - error.context("Image file can not be find") - results = utils.system_output(info_cmd) - logging.info("Infocmd output of backing file after block streaming: %s", - results) - - if re.search("backing file:", str(results)): - raise error.TestFail(" Backing file is still available in the " + logging.info("Image file: %s" % stream_test.get_image_file()) + logging.info("Backing file: %s" % backingfile) + stream_test.start() + stream_test.wait_for_finished() + backingfile = stream_test.get_backingfile() + if backingfile: + raise error.TestFail("Backing file is still available in the " "backdrive image") - # TODO - # The file size should be more/less equal to the "backing file" size - - # Shutdown the virtual machine - vm.destroy() - # Relogin with the backup-harddrive + target_file = stream_test.get_image_file() + target_size = stream_test.get_image_size(target_file) + error.context("Compare image size", logging.info) + if image_size < target_size: + raise error.TestFail("Compare %s image, size of %s increased" + "(%s -> %s)" % (image_file, target_file, + image_size, target_size)) + stream_test.verify_alive() + stream_test.vm.destroy() + vm_name = params["main_vm"] env_process.preprocess_vm(test, params, env, vm_name) vm = env.get_vm(vm_name) - vm.verify_alive() - timeout = int(params.get("login_timeout", 360)) - session = vm.wait_for_login(timeout=timeout) - logging.info("Checking whether the guest with backup-harddrive boot " - "and respond after block stream completion") - error.context("checking responsiveness of guest") - session.cmd(params["alive_check_cmd"]) - - # Finally shutdown the virtual machine - vm.destroy() + stream_test.vm = vm + stream_test.verify_alive() finally: - # Remove the backing file - if os.path.isfile(backing_file): - os.remove(backing_file) + stream_test.clean() From a1afc65ef55a4b72479331a757b5cac33c8a7966 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Fri, 26 Jul 2013 15:27:39 +0800 Subject: [PATCH 192/254] virttest: enhanced block_stream/drive_mirror related interface since drive_mirror feature still in development, and key commands and options still in changes, so do below enhancement to make script works more stablly: 1). make key commands configurable 2). read supportted options from help info before used it; Signed-off-by: Xu Tian <xutian@redhat.com> --- virttest/qemu_monitor.py | 119 +++++++++++++++++++++++++++++---------- virttest/qemu_vm.py | 13 +++-- 2 files changed, 96 insertions(+), 36 deletions(-) diff --git a/virttest/qemu_monitor.py b/virttest/qemu_monitor.py index c8c5a3598..f998cfa2a 100644 --- a/virttest/qemu_monitor.py +++ b/virttest/qemu_monitor.py @@ -277,6 +277,22 @@ def _log_lines(self, log_str): pass + def correct(self, cmd): + """ + Automatic conversion "-" and "_" in commands if the translate command + is supported commands; + """ + def translate(cmd): + return "-".join( re.split("[_-]", cmd)) + + if not self._has_command(cmd): + for _cmd in self._supported_cmds: + if translate(_cmd) == translate(cmd): + logging.info("Convert command %s -> %s", cmd, _cmd) + return _cmd + return cmd + + def is_responsive(self): """ Return True iff the monitor is responsive. @@ -696,46 +712,61 @@ def live_snapshot(self, device, snapshot_file, snapshot_format="qcow2"): return self.cmd(cmd) - def block_stream(self, device, speed=None, base=None): + def block_stream(self, device, speed=None, base=None, + cmd="block_stream", correct=True): """ Start block-stream job; @param device: device ID @param speed: int type, lmited speed(B/s) @param base: base file + @param correct: auto correct command, correct by default @return: The command's output """ - cmd = "block_stream %s" % device + if correct: + cmd = self.correct(cmd) + self.verify_supported_cmd(cmd) + cmd += " %s" % device if speed is not None: - cmd = "%s %sB" % (cmd, speed) + cmd += " %sB" % speed if base: - cmd = "%s %s" % (cmd, base) + cmd += " %s" % base return self.cmd(cmd) - def set_block_job_speed(self, device, speed=0): + def set_block_job_speed(self, device, speed=0, + cmd="block_job_set_speed", correct=True): """ Set limited speed for runnig job on the device @param device: device ID @param speed: int type, limited speed(B/s) + @param correct: auto correct command, correct by default @return: The command's output """ - cmd = "block-job-set-speed %s %sB" % (device, speed) + if correct: + cmd = self.correct(cmd) + self.verify_supported_cmd(cmd) + cmd += " %s %sB" % (device, speed) return self.cmd(cmd) - def cancel_block_job(self, device): + def cancel_block_job(self, device, cmd="block_job_cancel", correct=True): """ Cancel running block stream/mirror job on the device @param device: device ID + @param correct: auto correct command, correct by default @return: The command's output """ - return self.send_args_cmd("block-job-cancel %s" % device) + if correct: + cmd = self.correct(cmd) + self.verify_supported_cmd(cmd) + cmd += " %s" % device + return self.send_args_cmd(cmd) def query_block_job(self, device): @@ -783,7 +814,7 @@ def get_backingfile(self, device): def block_mirror(self, device, target, speed, sync, format, mode, - cmd="__com.redhat_drive-mirror"): + cmd="drive_mirror", correct=True): """ Start mirror type block device copy job @@ -794,25 +825,27 @@ def block_mirror(self, device, target, speed, sync, format, mode, @param mode: target image create mode, 'absolute-paths' or 'existing' @param format: target image format @param cmd: block mirror command + @param correct: auto correct command, correct by default @return: The command's output """ + if correct: + cmd = self.correct(cmd) self.verify_supported_cmd(cmd) - args = " ".join([device, target, format]) - if cmd.startswith("__com.redhat"): - if mode == "existing": - args = "-n %s" % args - if sync == "full": - args ="-f %s" % args - else: - if speed: - args = "%s %sB" % (args, speed) + args = " %s %s %s" % (device, target, format) + info = str(self.cmd("help %s" % cmd)) + if (mode == "existing") and "-n" in info: + args = "-n %s" % args + if (sync == "full") and "-f" in info: + args ="-f %s" % args + if (speed is not None) and ("speed" in info): + args = "%s %s" % (args, speed) cmd = "%s %s" % (cmd, args) return self.cmd(cmd) def block_reopen(self, device, new_image_file, image_format, - cmd="__com.redhat_drive-reopen"): + cmd="block_job_complete", correct=True): """ Reopen new target image @@ -820,13 +853,17 @@ def block_reopen(self, device, new_image_file, image_format, @param new_image_file: new image file name @param image_format: new image file format @param cmd: image reopen command + @param correct: auto correct command, correct by default @return: The command's output """ + if correct: + cmd = self.correct(cmd) self.verify_supported_cmd(cmd) - args = device - if cmd.startswith("__com.redhat"): - args += " ".join([new_image_file, image_format]) + args = "%s" % device + info = str(self.cmd("help %s" % cmd)) + if "format" in info: + args += " %s %s" % (new_image_file, image_format) cmd = "%s %s" % (cmd, args) return self.cmd(cmd) @@ -1639,48 +1676,62 @@ def live_snapshot(self, device, snapshot_file, snapshot_format="qcow2"): return self.cmd("blockdev-snapshot-sync", args) - def block_stream(self, device, speed=None, base=None): + def block_stream(self, device, speed=None, base=None, + cmd="block-stream", correct=True): """ Start block-stream job; @param device: device ID @param speed: int type, limited speed(B/s) @param base: base file + @param correct: auto correct command, correct by default @return: The command's output """ + if correct: + cmd = self.correct(cmd) + self.verify_supported_cmd(cmd) args = {"device": device} if speed is not None: args["speed"] = speed if base: args["base"] = base - return self.cmd("block-stream", args) + return self.cmd(cmd, args) - def set_block_job_speed(self, device, speed=0): + def set_block_job_speed(self, device, speed=0, + cmd="block-job-set-speed", correct=True): """ Set limited speed for runnig job on the device @param device: device ID @param speed: int type, limited speed(B/s) + @param correct: auto correct command, correct by default @return: The command's output """ + if correct: + cmd = self.correct(cmd) + self.verify_supported_cmd(cmd) args = {"device": device, "speed": speed} - return self.cmd("block-job-set-speed", args) + return self.cmd(cmd, args) - def cancel_block_job(self, device): + def cancel_block_job(self, device, cmd="block-job-cancel", correct=True): """ Cancel running block stream/mirror job on the device @param device: device ID + @param correct: auto correct command, correct by default @return: The command's output """ + if correct: + cmd = self.correct(cmd) + self.verify_supported_cmd(cmd) args = {"device": device} - return self.cmd("block-job-cancel", args) + return self.cmd(cmd, args) def query_block_job(self, device): @@ -1720,7 +1771,7 @@ def get_backingfile(self, device): def block_mirror(self, device, target, speed, sync, format, mode, - cmd="__com.redhat_drive-mirror"): + cmd="drive-mirror", correct=True): """ Start mirror type block device copy job @@ -1732,9 +1783,12 @@ def block_mirror(self, device, target, speed, sync, format, mode, @param mode: 'absolute-paths' or 'existing' @param format: target image format @param cmd: block mirror command + @param correct: auto correct command, correct by default @return: The command's output """ + if correct: + cmd = self.correct(cmd) self.verify_supported_cmd(cmd) args = {"device": device, "target": target} @@ -1752,7 +1806,7 @@ def block_mirror(self, device, target, speed, sync, format, mode, def block_reopen(self, device, new_image_file, image_format, - cmd="__com.redhat_drive-reopen"): + cmd="block-job-complete", correct=True): """ Reopen new target image; @@ -1760,12 +1814,15 @@ def block_reopen(self, device, new_image_file, image_format, @param new_image_file: new image file name @param image_format: new image file format @param cmd: image reopen command + @param correct: auto correct command, correct by default @return: the command's output """ + if correct: + cmd = self.correct(cmd) self.verify_supported_cmd(cmd) args = {"device": device} - if cmd.startswith("__com.redhat"): + if cmd.startswith("__"): args["new-image-file"] = new_image_file args["format"] = image_format return self.cmd(cmd, args) diff --git a/virttest/qemu_vm.py b/virttest/qemu_vm.py index 791adb09c..f3eda2fef 100644 --- a/virttest/qemu_vm.py +++ b/virttest/qemu_vm.py @@ -3586,7 +3586,8 @@ def block_stream(self, device, speed, base=None): @param speed: limited speed, default unit B/s; @param base: base file; """ - return self.monitor.block_stream(device, speed, base) + cmd = self.params.get("block_stream_cmd", "block-stream") + return self.monitor.block_stream(device, speed, base, cmd) def block_mirror(self, device, target, speed, sync, @@ -3602,7 +3603,7 @@ def block_mirror(self, device, target, speed, sync, @param mode: new image open mode @param format: target image format """ - cmd = self.params.get("block_mirror_cmd", "__com.redhat_drive-mirror") + cmd = self.params.get("block_mirror_cmd", "drive-mirror") return self.monitor.block_mirror(device, target, speed, sync, format, mode, cmd) @@ -3615,7 +3616,7 @@ def block_reopen(self, device, new_image, format="qcow2"): @param new_image: new image filename @param format: new image format """ - cmd = self.params.get("block_reopen_cmd", "__com.redhat_drive-reopen") + cmd = self.params.get("block_reopen_cmd", "block-job-complete") return self.monitor.block_reopen(device, new_image, format, cmd) @@ -3626,7 +3627,8 @@ def cancel_block_job(self, device): @param device: device ID @param timeout: seconds wait job cancel timeout, default is 3s """ - return self.monitor.cancel_block_job(device) + cmd = self.params.get("block_job_cancel_cmd", "block-job-cancel") + return self.monitor.cancel_block_job(device, cmd) def set_job_speed(self, device, speed="0"): @@ -3636,7 +3638,8 @@ def set_job_speed(self, device, speed="0"): @param device: device ID @param speed: max speed of block job """ - return self.monitor.set_block_job_speed(device, speed) + cmd = self.params.get("set_block_job_speed", "block-job-set-speed") + return self.monitor.set_block_job_speed(device, speed, cmd) def get_job_status(self, device): From 2e818ed0fb2ac248b02c4b911402a7f7d5ae23f6 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Fri, 26 Jul 2013 16:59:19 +0800 Subject: [PATCH 193/254] virttest: auto correct command before send Auto correct command before send it to monitor, it enable for block copy related commands. It will helpful to compatible testing different distro with human monitor; Signed-off-by: Xu Tian <xutian@redhat.com> --- virttest/qemu_vm.py | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/virttest/qemu_vm.py b/virttest/qemu_vm.py index f3eda2fef..2cb9fecf2 100644 --- a/virttest/qemu_vm.py +++ b/virttest/qemu_vm.py @@ -3578,20 +3578,22 @@ def live_snapshot(self, base_file, snapshot_file, return current_file - def block_stream(self, device, speed, base=None): + def block_stream(self, device, speed, base=None, correct=True): """ start to stream block device, aka merge snapshot; @param device: device ID; @param speed: limited speed, default unit B/s; @param base: base file; + @param correct: auto correct cmd, correct by default """ cmd = self.params.get("block_stream_cmd", "block-stream") - return self.monitor.block_stream(device, speed, base, cmd) + return self.monitor.block_stream(device, speed, base, + cmd, correct=correct) def block_mirror(self, device, target, speed, sync, - format, mode="absolute-paths"): + format, mode="absolute-paths", correct=True): """ Mirror block device to target file; @@ -3602,44 +3604,49 @@ def block_mirror(self, device, target, speed, sync, destination; @param mode: new image open mode @param format: target image format + @param correct: auto correct cmd, correct by default """ cmd = self.params.get("block_mirror_cmd", "drive-mirror") - return self.monitor.block_mirror(device, target, speed, - sync, format, mode, cmd) + return self.monitor.block_mirror(device, target, speed, sync, + format, mode, cmd, correct=correct) - def block_reopen(self, device, new_image, format="qcow2"): + def block_reopen(self, device, new_image, format="qcow2", correct=True): """ Reopen a new image, no need to do this step in rhel7 host @param device: device ID @param new_image: new image filename @param format: new image format + @param correct: auto correct cmd, correct by default """ cmd = self.params.get("block_reopen_cmd", "block-job-complete") - return self.monitor.block_reopen(device, new_image, format, cmd) + return self.monitor.block_reopen(device, new_image, + format, cmd, correct=correct) - def cancel_block_job(self, device): + def cancel_block_job(self, device, correct=True): """ cancel active job on the image_file @param device: device ID - @param timeout: seconds wait job cancel timeout, default is 3s + @param correct: auto correct cmd, correct by default """ cmd = self.params.get("block_job_cancel_cmd", "block-job-cancel") - return self.monitor.cancel_block_job(device, cmd) + return self.monitor.cancel_block_job(device, cmd, correct=correct) - def set_job_speed(self, device, speed="0"): + def set_job_speed(self, device, speed="0", correct=True): """ set max speed of block job; @param device: device ID @param speed: max speed of block job + @param correct: auto correct cmd, correct by default """ cmd = self.params.get("set_block_job_speed", "block-job-set-speed") - return self.monitor.set_block_job_speed(device, speed, cmd) + return self.monitor.set_block_job_speed(device, speed, + cmd, correct=correct) def get_job_status(self, device): From 95c0ae6fc31ee9c2c4162bc757a6b16e8db193ea Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Mon, 29 Jul 2013 11:25:12 +0800 Subject: [PATCH 194/254] qemu.tests: update block stream testing cfg accroding test-case Signed-off-by: Xu Tian <xutian@redhat.com> --- qemu/tests/cfg/block_stream.cfg | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/qemu/tests/cfg/block_stream.cfg b/qemu/tests/cfg/block_stream.cfg index 1798d3f30..90ed2891f 100644 --- a/qemu/tests/cfg/block_stream.cfg +++ b/qemu/tests/cfg/block_stream.cfg @@ -8,7 +8,7 @@ wait_finished = yes source_image = image1 default_speed_image1 = 0 - snapshot_chain = "images/sn1 images/sn2" + snapshot_chain = "images/sn1" wait_timeout = 1800 snapshot_format = qcow2 kill_vm = yes @@ -40,15 +40,11 @@ default_speed_image1 = 8M - when_reboot: type = block_stream_reboot - reboot_method = "shell" + reboot_method = "system_reset" before_start = "reboot" after_finished = "reboot verify_alive" - - when_boot: - type = block_stream_reboot - reboot_method = "shell" - before_start = "bootup" - after_finished = "reboot verify_alive" - drop_backingfile: + snapshot_chain += " images/sn2" type = block_stream_drop_backingfile # set limited_speed to 10MB/s eq 10485760B/s limited_speed = 10485760 From b23a62b16811b8bf28c4f5d87d144a7fefba7ba9 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 30 Jul 2013 15:09:03 +0800 Subject: [PATCH 195/254] shared.unattended: include some autotest requried pkgs Include some sub tests of autotests requried packages in kickstart file; Signed-off-by: Xu Tian <xutian@redhat.com> --- shared/unattended/Debian-6.0.7.preseed | 2 +- shared/unattended/RHEL-5-series.ks | 3 +++ shared/unattended/RHEL-6-series.ks | 3 +++ shared/unattended/SLES-10.xml | 3 +++ shared/unattended/SLES-11-SP2.xml | 3 +++ shared/unattended/SLES-11.xml | 3 +++ shared/unattended/Ubuntu-11-04.preseed | 2 +- shared/unattended/Ubuntu-11-10.preseed | 2 +- shared/unattended/Ubuntu-12-04.preseed | 2 +- shared/unattended/Ubuntu-12-10.preseed | 2 +- shared/unattended/Ubuntu-13-04.preseed | 2 +- 11 files changed, 21 insertions(+), 6 deletions(-) diff --git a/shared/unattended/Debian-6.0.7.preseed b/shared/unattended/Debian-6.0.7.preseed index bfd483e96..1da1b1545 100644 --- a/shared/unattended/Debian-6.0.7.preseed +++ b/shared/unattended/Debian-6.0.7.preseed @@ -32,7 +32,7 @@ d-i mirror/http/proxy string tasksel tasksel/first multiselect standard -d-i pkgsel/include string openssh-server build-essential +d-i pkgsel/include string openssh-server build-essential lvm2 ethtool sg3-utils lsscsi libaio-dev libtime-hires-perl d-i grub-installer/only_debian boolean true d-i grub-installer/with_other_os boolean true diff --git a/shared/unattended/RHEL-5-series.ks b/shared/unattended/RHEL-5-series.ks index dc65ac421..0ff6613cc 100644 --- a/shared/unattended/RHEL-5-series.ks +++ b/shared/unattended/RHEL-5-series.ks @@ -42,6 +42,9 @@ nc ntp redhat-lsb sg3_utils +lsscsi +libaio-devel +perl-Time-HiRes %post echo "OS install is completed" > /dev/ttyS0 diff --git a/shared/unattended/RHEL-6-series.ks b/shared/unattended/RHEL-6-series.ks index 286d05839..19bd48b13 100644 --- a/shared/unattended/RHEL-6-series.ks +++ b/shared/unattended/RHEL-6-series.ks @@ -52,6 +52,9 @@ usbutils qemu-guest-agent sg3_utils xfsprogs +lsscsi +libaio-devel +perl-Time-HiRes %post echo "OS install is completed" > /dev/ttyS0 diff --git a/shared/unattended/SLES-10.xml b/shared/unattended/SLES-10.xml index 9cdf043ea..8a704c62e 100644 --- a/shared/unattended/SLES-10.xml +++ b/shared/unattended/SLES-10.xml @@ -553,6 +553,9 @@ service network restart <packages config:type="list"> <package>dhcp-client</package> <package>sg3_utils</package> + <package>lsscsi</package> + <package>libaio-devel</package> + <package>perl-Time-HiRes</package> </packages> <patterns config:type="list"> <pattern>Basis-Devel</pattern> diff --git a/shared/unattended/SLES-11-SP2.xml b/shared/unattended/SLES-11-SP2.xml index 304da717c..ffbaae6fc 100644 --- a/shared/unattended/SLES-11-SP2.xml +++ b/shared/unattended/SLES-11-SP2.xml @@ -553,6 +553,9 @@ service sshd restart <package>dhcp-client</package> <package>open-iscsi</package> <package>sg3_utils</package> + <package>lsscsi</package> + <package>libaio-devel</package> + <package>perl-Time-HiRes</package> </packages> <patterns config:type="list"> <pattern>Basis-Devel</pattern> diff --git a/shared/unattended/SLES-11.xml b/shared/unattended/SLES-11.xml index fad360f48..0f4dbb739 100644 --- a/shared/unattended/SLES-11.xml +++ b/shared/unattended/SLES-11.xml @@ -582,6 +582,9 @@ ycpc -c Packages.ycp <package>dhcp-client</package> <package>patch</package> <package>sg3_utils</package> + <package>lsscsi</package> + <package>libaio-devel</package> + <package>perl-Time-HiRes</package> </packages> <patterns config:type="list"> <pattern>Basis-Devel</pattern> diff --git a/shared/unattended/Ubuntu-11-04.preseed b/shared/unattended/Ubuntu-11-04.preseed index e846ce0b8..7b153f7fb 100644 --- a/shared/unattended/Ubuntu-11-04.preseed +++ b/shared/unattended/Ubuntu-11-04.preseed @@ -30,7 +30,7 @@ d-i mirror/udeb/components multiselect main, restricted, universe, multiverse tasksel tasksel/first multiselect standard -d-i pkgsel/include string openssh-server build-essential lvm2 ethtool sg3-utils +d-i pkgsel/include string openssh-server build-essential lvm2 ethtool sg3-utils lsscsi libaio-dev libtime-hires-perl d-i grub-installer/only_debian boolean true d-i grub-installer/with_other_os boolean true diff --git a/shared/unattended/Ubuntu-11-10.preseed b/shared/unattended/Ubuntu-11-10.preseed index e846ce0b8..7b153f7fb 100644 --- a/shared/unattended/Ubuntu-11-10.preseed +++ b/shared/unattended/Ubuntu-11-10.preseed @@ -30,7 +30,7 @@ d-i mirror/udeb/components multiselect main, restricted, universe, multiverse tasksel tasksel/first multiselect standard -d-i pkgsel/include string openssh-server build-essential lvm2 ethtool sg3-utils +d-i pkgsel/include string openssh-server build-essential lvm2 ethtool sg3-utils lsscsi libaio-dev libtime-hires-perl d-i grub-installer/only_debian boolean true d-i grub-installer/with_other_os boolean true diff --git a/shared/unattended/Ubuntu-12-04.preseed b/shared/unattended/Ubuntu-12-04.preseed index e846ce0b8..7b153f7fb 100644 --- a/shared/unattended/Ubuntu-12-04.preseed +++ b/shared/unattended/Ubuntu-12-04.preseed @@ -30,7 +30,7 @@ d-i mirror/udeb/components multiselect main, restricted, universe, multiverse tasksel tasksel/first multiselect standard -d-i pkgsel/include string openssh-server build-essential lvm2 ethtool sg3-utils +d-i pkgsel/include string openssh-server build-essential lvm2 ethtool sg3-utils lsscsi libaio-dev libtime-hires-perl d-i grub-installer/only_debian boolean true d-i grub-installer/with_other_os boolean true diff --git a/shared/unattended/Ubuntu-12-10.preseed b/shared/unattended/Ubuntu-12-10.preseed index a4ea2fa5f..f0d78414c 100644 --- a/shared/unattended/Ubuntu-12-10.preseed +++ b/shared/unattended/Ubuntu-12-10.preseed @@ -30,7 +30,7 @@ d-i mirror/udeb/components multiselect main, restricted, universe, multiverse tasksel tasksel/first multiselect standard -d-i pkgsel/include string openssh-server build-essential lvm2 ethtool sg3-utils +d-i pkgsel/include string openssh-server build-essential lvm2 ethtool sg3-utils lsscsi libaio-dev libtime-hires-perl d-i grub-installer/only_debian boolean true d-i grub-installer/with_other_os boolean true diff --git a/shared/unattended/Ubuntu-13-04.preseed b/shared/unattended/Ubuntu-13-04.preseed index a4ea2fa5f..f0d78414c 100644 --- a/shared/unattended/Ubuntu-13-04.preseed +++ b/shared/unattended/Ubuntu-13-04.preseed @@ -30,7 +30,7 @@ d-i mirror/udeb/components multiselect main, restricted, universe, multiverse tasksel tasksel/first multiselect standard -d-i pkgsel/include string openssh-server build-essential lvm2 ethtool sg3-utils +d-i pkgsel/include string openssh-server build-essential lvm2 ethtool sg3-utils lsscsi libaio-dev libtime-hires-perl d-i grub-installer/only_debian boolean true d-i grub-installer/with_other_os boolean true From 5b5dc7381b809bd3c71b1ac194203d5b8dd90f70 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 30 Jul 2013 11:24:02 +0800 Subject: [PATCH 196/254] qemu.tests: disable qemu_iotests for some image format on RHEL host since qcow, qed, vmdk, vpc and vdi not support by qemu-kvm in RHEL so filter out tests on these image format; Signed-off-by: Xu Tian <xutian@redhat.com> --- qemu/tests/cfg/qemu_iotests.cfg | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/qemu/tests/cfg/qemu_iotests.cfg b/qemu/tests/cfg/qemu_iotests.cfg index 4de3f2fad..ef27d3238 100644 --- a/qemu/tests/cfg/qemu_iotests.cfg +++ b/qemu/tests/cfg/qemu_iotests.cfg @@ -13,14 +13,19 @@ - raw_format: qemu_io_image_format = raw - qcow_format: + no Host_RHEL qemu_io_image_format = qcow - qcow2_format: qemu_io_image_format = qcow2 - qed_format: + no Host_RHEL qemu_io_image_format = qed - vdi_format: + no Host_RHEL qemu_io_image_format = vdi - vpc_format: + no Host_RHEL qemu_io_image_format = vpc - vmdk_format: + no Host_RHEL qemu_io_image_format = vmdk From 3779651f676ecb8fbd87e53ed22653778df419f8 Mon Sep 17 00:00:00 2001 From: Yunping Zheng <yunzheng@redhat.com> Date: Thu, 18 Jul 2013 10:52:10 +0800 Subject: [PATCH 197/254] virttest.qemu_vm : Get vcpu threads by funtion get_vcpu_pids Now we can using funtion get_vcpu_pids() to get vcpu thread Signed-off-by: Yunping Zheng <yunzheng@redhat.com> --- virttest/qemu_vm.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/virttest/qemu_vm.py b/virttest/qemu_vm.py index 2cb9fecf2..b9ba36266 100644 --- a/virttest/qemu_vm.py +++ b/virttest/qemu_vm.py @@ -2401,11 +2401,9 @@ def create(self, name=None, params=None, root_dir=None, raise e logging.debug("VM appears to be alive with PID %s", self.get_pid()) - - o = self.monitor.info("cpus") - vcpu_thread_pattern = params.get("vcpu_thread_pattern", - "thread_id=(\d+)") - self.vcpu_threads = re.findall(vcpu_thread_pattern, str(o)) + vcpu_thread_pattern = self.params.get("vcpu_thread_pattern", + r"thread_id.?[:|=]\s*(\d+)") + self.vcpu_threads = self.get_vcpu_pids(vcpu_thread_pattern) o = commands.getoutput("ps aux") self.vhost_threads = re.findall("\w+\s+(\d+)\s.*\[vhost-%s\]" % self.get_pid(), o) @@ -2755,20 +2753,16 @@ def get_vnc_port(self): return self.vnc_port - def get_vcpu_pids(self, params): + def get_vcpu_pids(self, vcpu_thread_pattern): """ Return the list of vcpu PIDs @return: the list of vcpu PIDs """ - vcpu_thread_pattern = params.get("vcpu_thread_pattern", - "thread_id=(\d+)") return [int(_) for _ in re.findall(vcpu_thread_pattern, str(self.monitor.info("cpus")))] - - def get_shared_meminfo(self): """ Returns the VM's shared memory information. From 1e9b2aabbf7f3c5fe9b31efee3ff64db6a12ff87 Mon Sep 17 00:00:00 2001 From: Yunping Zheng <yunzheng@redhat.com> Date: Thu, 18 Jul 2013 10:53:08 +0800 Subject: [PATCH 198/254] Shared/cfg/base.cfg: make 'vcpu_thread_pattern' support both type monitors This patch modify the pattern of 'vcpu_thread_pattern', make the pattern can support both human and qmp monitor. Signed-off-by: Yunping Zheng <yunzheng@redhat.com> --- qemu/tests/cgroup.py | 15 ++++++++++++--- shared/cfg/base.cfg | 6 ++---- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/qemu/tests/cgroup.py b/qemu/tests/cgroup.py index bdbe09898..a75e9e341 100644 --- a/qemu/tests/cgroup.py +++ b/qemu/tests/cgroup.py @@ -606,7 +606,10 @@ def cpu_cfs_util(): timeout = 1.5 * int(params.get("login_timeout", 360)) # First one vms.append(env.get_all_vms()[0]) - cpu_pids = vms[0].get_vcpu_pids(params) + vcpu_thread_pattern = params.get("vcpu_thread_pattern", + r"thread_id.?[:|=]\s*(\d+)") + cpu_pids = vms[0].get_vcpu_pids(vcpu_thread_pattern) + smp = len(cpu_pids) cgroup.mk_cgroup() cgroup.set_property("cpu.cfs_period_us", 100000, 0) @@ -637,7 +640,10 @@ def cpu_cfs_util(): # Total quota is for ALL vCPUs cgroup.set_property("cpu.cfs_quota_us", 50000 * smp, -1) assign_vm_into_cgroup(vms[-1], cgroup, -1) - cpu_pids = vms[-1].get_vcpu_pids(params) + vcpu_thread_pattern = params.get("vcpu_thread_pattern", + r"thread_id.?[:|=]\s*(\d+)") + cpu_pids = vms[-1].get_vcpu_pids(vcpu_thread_pattern) + for j in range(smp): cgroup.mk_cgroup(pwd) cgroup.set_property("cpu.cfs_period_us", 100000, -1) @@ -1081,7 +1087,10 @@ def _generate_verification(cpusets, no_cpus): params['smp'] = vm_cpus vm.create(params=params) # Verify vcpus matches prescription - vcpus = vm.get_vcpu_pids(params) + vcpu_thread_pattern = params.get("vcpu_thread_pattern", + r"thread_id.?[:|=]\s*(\d+)") + vcpus = vm.get_vcpu_pids(vcpu_thread_pattern) + if len(vcpus) != vm_cpus: raise error.TestFail("Incorrect number of vcpu PIDs; smp=%s vcpus=" "%s" % (vm_cpus, vcpus)) diff --git a/shared/cfg/base.cfg b/shared/cfg/base.cfg index 245e09aa5..5f19b954c 100644 --- a/shared/cfg/base.cfg +++ b/shared/cfg/base.cfg @@ -187,10 +187,8 @@ monitors = hmp1 #monitor_type_hmp1 = human # Default monitor type (protocol), if multiple types to be used monitor_type = human -# Pattern to get vcpu threads from monitor. -# human monitor: thread_id=(\d+) -# qmp monitor: u'thread_id':\s+(\d+) -vcpu_thread_pattern = "thread_id=(\d+)" +# Pattern to get vcpu threads from monitor.both support +vcpu_thread_pattern = "thread_id.?[:|=]\s*(\d+)" # Guest Display type (vnc, sdl, spice, or nographic) display = vnc From e2426ae91d416262ac02b16b67f0c74b5b3eca88 Mon Sep 17 00:00:00 2001 From: Qingtang Zhou <qzhou@redhat.com> Date: Tue, 16 Jul 2013 18:52:43 +0800 Subject: [PATCH 199/254] shared.cfg: Check SSDT for both S3/S4 tests The SSDT shows whether the bios set the suspend status correctly, so it's another test point for both S3/S4 tests. Signed-off-by: Qingtang Zhou <qzhou@redhat.com> --- shared/cfg/guest-os/Linux/Fedora.cfg | 18 ++++++++++++ shared/cfg/guest-os/Linux/RHEL/5.4/x86_64.cfg | 29 +++++++++++++++---- shared/cfg/guest-os/Linux/RHEL/5.5/x86_64.cfg | 29 +++++++++++++++---- shared/cfg/guest-os/Linux/RHEL/5.6/x86_64.cfg | 29 +++++++++++++++---- shared/cfg/guest-os/Linux/RHEL/5.7/x86_64.cfg | 29 +++++++++++++++---- shared/cfg/guest-os/Linux/RHEL/5.8/x86_64.cfg | 29 +++++++++++++++---- shared/cfg/guest-os/Linux/RHEL/5.9/x86_64.cfg | 29 +++++++++++++++---- shared/cfg/guest-os/Linux/RHEL/6.0.cfg | 24 +++++++++++++++ shared/cfg/guest-os/Linux/RHEL/6.0/i386.cfg | 5 ---- shared/cfg/guest-os/Linux/RHEL/6.0/x86_64.cfg | 5 ---- shared/cfg/guest-os/Linux/RHEL/6.1.cfg | 24 +++++++++++++++ shared/cfg/guest-os/Linux/RHEL/6.1/i386.cfg | 5 ---- shared/cfg/guest-os/Linux/RHEL/6.2.cfg | 24 +++++++++++++++ shared/cfg/guest-os/Linux/RHEL/6.2/i386.cfg | 5 ---- shared/cfg/guest-os/Linux/RHEL/6.2/x86_64.cfg | 5 ---- shared/cfg/guest-os/Linux/RHEL/6.3.cfg | 24 +++++++++++++++ shared/cfg/guest-os/Linux/RHEL/6.3/i386.cfg | 5 ---- shared/cfg/guest-os/Linux/RHEL/6.3/x86_64.cfg | 5 ---- shared/cfg/guest-os/Linux/RHEL/6.4.cfg | 24 +++++++++++++++ shared/cfg/guest-os/Linux/RHEL/6.4/i386.cfg | 5 ---- shared/cfg/guest-os/Linux/RHEL/6.4/x86_64.cfg | 5 ---- shared/cfg/guest-os/Linux/RHEL/6.devel.cfg | 24 +++++++++++++++ .../cfg/guest-os/Linux/RHEL/6.devel/i386.cfg | 5 ---- .../guest-os/Linux/RHEL/6.devel/x86_64.cfg | 5 ---- 24 files changed, 306 insertions(+), 85 deletions(-) diff --git a/shared/cfg/guest-os/Linux/Fedora.cfg b/shared/cfg/guest-os/Linux/Fedora.cfg index e23b42484..68297c767 100644 --- a/shared/cfg/guest-os/Linux/Fedora.cfg +++ b/shared/cfg/guest-os/Linux/Fedora.cfg @@ -5,9 +5,27 @@ boot_path = "images/pxeboot" kernel_params = "ks=cdrom nicdelay=60 console=ttyS0,115200 console=tty0" anaconda_log = "yes" + guest_s3: + global_enable_s3: + s3_support_chk_cmd = "yum install -y iasl" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + s3_support_chk_cmd += " && dmesg -c > /dev/null && grep -q mem /sys/power/state" + global_disable_s3: + s3_support_chk_cmd = "yum install -y iasl" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" guest_s4: 17, 18: s4_log_chk_cmd = 'dmesg | grep -E "PM: Image restored successfully."' + global_enable_s4: + s4_support_chk_cmd = "yum install -y iasl" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" + s4_support_chk_cmd += " && dmesg -c > /dev/null && grep -q disk /sys/power/state" global_disable_s4: s4_support_chk_cmd = "yum install -y iasl" s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" diff --git a/shared/cfg/guest-os/Linux/RHEL/5.4/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/5.4/x86_64.cfg index ca256065a..dc950dc6c 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.4/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.4/x86_64.cfg @@ -13,8 +13,27 @@ unattended_install..floppy_ks: floppies = "fl" floppy_name = images/rhel54-64/ks.vfd - guest_s4..global_disable_s4: - s4_support_chk_cmd = "rpm --force --nodeps http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" - s4_support_chk_cmd += " && cat cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" - s4_support_chk_cmd += " && iasl -d /tmp/ssdt" - s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" + guest_s3: + global_enable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + s3_support_chk_cmd += " && dmesg -c > /dev/null && grep -q mem /sys/power/state" + global_disable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + guest_s4: + global_enable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" + s4_support_chk_cmd += " && dmesg -c > /dev/null && grep -q disk /sys/power/state" + global_disable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" diff --git a/shared/cfg/guest-os/Linux/RHEL/5.5/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/5.5/x86_64.cfg index f0218ea1d..9291bcc2e 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.5/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.5/x86_64.cfg @@ -13,8 +13,27 @@ unattended_install..floppy_ks: floppies = "fl" floppy_name = images/rhel55-64/ks.vfd - guest_s4..global_disable_s4: - s4_support_chk_cmd = "rpm --force --nodeps http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" - s4_support_chk_cmd += " && cat cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" - s4_support_chk_cmd += " && iasl -d /tmp/ssdt" - s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" + guest_s3: + global_enable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + s3_support_chk_cmd += " && dmesg -c > /dev/null && grep -q mem /sys/power/state" + global_disable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + guest_s4: + global_enable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" + s4_support_chk_cmd += " && dmesg -c > /dev/null && grep -q disk /sys/power/state" + global_disable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" diff --git a/shared/cfg/guest-os/Linux/RHEL/5.6/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/5.6/x86_64.cfg index aafedefbb..c73b99045 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.6/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.6/x86_64.cfg @@ -13,8 +13,27 @@ unattended_install..floppy_ks: floppies = "fl" floppy_name = images/rhel56-64/ks.vfd - guest_s4..global_disable_s4: - s4_support_chk_cmd = "rpm --force --nodeps http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" - s4_support_chk_cmd += " && cat cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" - s4_support_chk_cmd += " && iasl -d /tmp/ssdt" - s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" + guest_s3: + global_enable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + s3_support_chk_cmd += " && dmesg -c > /dev/null && grep -q mem /sys/power/state" + global_disable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + guest_s4: + global_enable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" + s4_support_chk_cmd += " && dmesg -c > /dev/null && grep -q disk /sys/power/state" + global_disable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" diff --git a/shared/cfg/guest-os/Linux/RHEL/5.7/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/5.7/x86_64.cfg index df3b45ddb..a05028b3a 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.7/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.7/x86_64.cfg @@ -13,8 +13,27 @@ unattended_install..floppy_ks: floppies = "fl" floppy_name = images/rhel56-64/ks.vfd - guest_s4..global_disable_s4: - s4_support_chk_cmd = "rpm --force --nodeps http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" - s4_support_chk_cmd += " && cat cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" - s4_support_chk_cmd += " && iasl -d /tmp/ssdt" - s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" + guest_s3: + global_enable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + s3_support_chk_cmd += " && dmesg -c > /dev/null && grep -q mem /sys/power/state" + global_disable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + guest_s4: + global_enable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" + s4_support_chk_cmd += " && dmesg -c > /dev/null && grep -q disk /sys/power/state" + global_disable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" diff --git a/shared/cfg/guest-os/Linux/RHEL/5.8/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/5.8/x86_64.cfg index 0d6308ee3..cc2fcce62 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.8/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.8/x86_64.cfg @@ -13,8 +13,27 @@ unattended_install..floppy_ks: floppies = "fl" floppy_name = images/rhel58-64/ks.vfd - guest_s4..global_disable_s4: - s4_support_chk_cmd = "rpm --force --nodeps http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" - s4_support_chk_cmd += " && cat cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" - s4_support_chk_cmd += " && iasl -d /tmp/ssdt" - s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" + guest_s3: + global_enable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + s3_support_chk_cmd += " && dmesg -c > /dev/null && grep -q mem /sys/power/state" + global_disable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + guest_s4: + global_enable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" + s4_support_chk_cmd += " && dmesg -c > /dev/null && grep -q disk /sys/power/state" + global_disable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" diff --git a/shared/cfg/guest-os/Linux/RHEL/5.9/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/5.9/x86_64.cfg index a38124a70..92a78859a 100644 --- a/shared/cfg/guest-os/Linux/RHEL/5.9/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/5.9/x86_64.cfg @@ -13,8 +13,27 @@ unattended_install..floppy_ks: floppies = "fl" floppy_name = images/rhel59-64/ks.vfd - guest_s4..global_disable_s4: - s4_support_chk_cmd = "rpm --force --nodeps http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" - s4_support_chk_cmd += " && cat cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" - s4_support_chk_cmd += " && iasl -d /tmp/ssdt" - s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" + guest_s3: + global_enable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + s3_support_chk_cmd += " && dmesg -c > /dev/null && grep -q mem /sys/power/state" + global_disable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + guest_s4: + global_enable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" + s4_support_chk_cmd += " && dmesg -c > /dev/null && grep -q disk /sys/power/state" + global_disable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/5/os/x86_64/CentOS/iasl-20090123-1.el5.x86_64.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" diff --git a/shared/cfg/guest-os/Linux/RHEL/6.0.cfg b/shared/cfg/guest-os/Linux/RHEL/6.0.cfg index b4df9fb5f..540b31065 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.0.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.0.cfg @@ -8,3 +8,27 @@ modprobe_module = block_hotplug: modprobe_module = + guest_s3: + global_enable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + s3_support_chk_cmd += " && dmesg -c > /dev/null && grep -q mem /sys/power/state" + global_disable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + guest_s4: + global_enable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" + s4_support_chk_cmd += " && dmesg -c > /dev/null && grep -q disk /sys/power/state" + global_disable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" diff --git a/shared/cfg/guest-os/Linux/RHEL/6.0/i386.cfg b/shared/cfg/guest-os/Linux/RHEL/6.0/i386.cfg index 662941fcc..a8de5acc6 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.0/i386.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.0/i386.cfg @@ -13,8 +13,3 @@ unattended_install..floppy_ks: floppies = "fl" floppy_name = images/rhel60-32/ks.vfd - guest_s4..global_disable_s4: - s4_support_chk_cmd = "rpm --force --nodeps http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" - s4_support_chk_cmd += " && cat cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" - s4_support_chk_cmd += " && iasl -d /tmp/ssdt" - s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" diff --git a/shared/cfg/guest-os/Linux/RHEL/6.0/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/6.0/x86_64.cfg index 74b5a2472..83e240cbb 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.0/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.0/x86_64.cfg @@ -13,8 +13,3 @@ unattended_install..floppy_ks: floppies = "fl" floppy_name = images/rhel60-64/ks.vfd - guest_s4..global_disable_s4: - s4_support_chk_cmd = "rpm --force --nodeps http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" - s4_support_chk_cmd += " && cat cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" - s4_support_chk_cmd += " && iasl -d /tmp/ssdt" - s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" diff --git a/shared/cfg/guest-os/Linux/RHEL/6.1.cfg b/shared/cfg/guest-os/Linux/RHEL/6.1.cfg index d2fcfc2ba..c18f1b395 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.1.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.1.cfg @@ -8,3 +8,27 @@ modprobe_module = block_hotplug: modprobe_module = + guest_s3: + global_enable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + s3_support_chk_cmd += " && dmesg -c > /dev/null && grep -q mem /sys/power/state" + global_disable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + guest_s4: + global_enable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" + s4_support_chk_cmd += " && dmesg -c > /dev/null && grep -q disk /sys/power/state" + global_disable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" diff --git a/shared/cfg/guest-os/Linux/RHEL/6.1/i386.cfg b/shared/cfg/guest-os/Linux/RHEL/6.1/i386.cfg index dec8ab187..29967c17e 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.1/i386.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.1/i386.cfg @@ -13,8 +13,3 @@ unattended_install..floppy_ks: floppies = "fl" floppy_name = images/rhel61-32/ks.vfd - guest_s4..global_disable_s4: - s4_support_chk_cmd = "rpm --force --nodeps http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" - s4_support_chk_cmd += " && cat cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" - s4_support_chk_cmd += " && iasl -d /tmp/ssdt" - s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" diff --git a/shared/cfg/guest-os/Linux/RHEL/6.2.cfg b/shared/cfg/guest-os/Linux/RHEL/6.2.cfg index 6c775b431..1689a66e2 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.2.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.2.cfg @@ -8,3 +8,27 @@ modprobe_module = block_hotplug: modprobe_module = + guest_s3: + global_enable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + s3_support_chk_cmd += " && dmesg -c > /dev/null && grep -q mem /sys/power/state" + global_disable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + guest_s4: + global_enable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" + s4_support_chk_cmd += " && dmesg -c > /dev/null && grep -q disk /sys/power/state" + global_disable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" diff --git a/shared/cfg/guest-os/Linux/RHEL/6.2/i386.cfg b/shared/cfg/guest-os/Linux/RHEL/6.2/i386.cfg index ddaa86977..6989ea40a 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.2/i386.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.2/i386.cfg @@ -13,8 +13,3 @@ unattended_install..floppy_ks: floppies = "fl" floppy_name = images/rhel62-32/ks.vfd - guest_s4..global_disable_s4: - s4_support_chk_cmd = "rpm --force --nodeps http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" - s4_support_chk_cmd += " && cat cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" - s4_support_chk_cmd += " && iasl -d /tmp/ssdt" - s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" diff --git a/shared/cfg/guest-os/Linux/RHEL/6.2/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/6.2/x86_64.cfg index 17201a793..f1b3c940d 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.2/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.2/x86_64.cfg @@ -13,8 +13,3 @@ unattended_install..floppy_ks: floppies = "fl" floppy_name = images/rhel62-64/ks.vfd - guest_s4..global_disable_s4: - s4_support_chk_cmd = "rpm --force --nodeps http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" - s4_support_chk_cmd += " && cat cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" - s4_support_chk_cmd += " && iasl -d /tmp/ssdt" - s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" diff --git a/shared/cfg/guest-os/Linux/RHEL/6.3.cfg b/shared/cfg/guest-os/Linux/RHEL/6.3.cfg index dee5be5cf..92ac83862 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.3.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.3.cfg @@ -8,3 +8,27 @@ modprobe_module = block_hotplug: modprobe_module = + guest_s3: + global_enable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + s3_support_chk_cmd += " && dmesg -c > /dev/null && grep -q mem /sys/power/state" + global_disable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + guest_s4: + global_enable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" + s4_support_chk_cmd += " && dmesg -c > /dev/null && grep -q disk /sys/power/state" + global_disable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" diff --git a/shared/cfg/guest-os/Linux/RHEL/6.3/i386.cfg b/shared/cfg/guest-os/Linux/RHEL/6.3/i386.cfg index e6da796d2..53615b402 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.3/i386.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.3/i386.cfg @@ -13,8 +13,3 @@ unattended_install..floppy_ks: floppies = "fl" floppy_name = images/rhel63-32/ks.vfd - guest_s4..global_disable_s4: - s4_support_chk_cmd = "rpm --force --nodeps http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" - s4_support_chk_cmd += " && cat cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" - s4_support_chk_cmd += " && iasl -d /tmp/ssdt" - s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" diff --git a/shared/cfg/guest-os/Linux/RHEL/6.3/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/6.3/x86_64.cfg index 66bca09bc..76345f83c 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.3/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.3/x86_64.cfg @@ -13,8 +13,3 @@ unattended_install..floppy_ks: floppies = "fl" floppy_name = images/rhel63-64/ks.vfd - guest_s4..global_disable_s4: - s4_support_chk_cmd = "rpm --force --nodeps http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" - s4_support_chk_cmd += " && cat cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" - s4_support_chk_cmd += " && iasl -d /tmp/ssdt" - s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" diff --git a/shared/cfg/guest-os/Linux/RHEL/6.4.cfg b/shared/cfg/guest-os/Linux/RHEL/6.4.cfg index 21dd053b3..610e88153 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.4.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.4.cfg @@ -8,3 +8,27 @@ modprobe_module = block_hotplug: modprobe_module = + guest_s3: + global_enable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + s3_support_chk_cmd += " && dmesg -c > /dev/null && grep -q mem /sys/power/state" + global_disable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + guest_s4: + global_enable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" + s4_support_chk_cmd += " && dmesg -c > /dev/null && grep -q disk /sys/power/state" + global_disable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" diff --git a/shared/cfg/guest-os/Linux/RHEL/6.4/i386.cfg b/shared/cfg/guest-os/Linux/RHEL/6.4/i386.cfg index dc36f411d..1680f80d4 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.4/i386.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.4/i386.cfg @@ -13,8 +13,3 @@ unattended_install..floppy_ks: floppies = "fl" floppy_name = images/rhel64-32/ks.vfd - guest_s4..global_disable_s4: - s4_support_chk_cmd = "rpm --force --nodeps http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" - s4_support_chk_cmd += " && cat cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" - s4_support_chk_cmd += " && iasl -d /tmp/ssdt" - s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" diff --git a/shared/cfg/guest-os/Linux/RHEL/6.4/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/6.4/x86_64.cfg index a750ab665..258639b9f 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.4/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.4/x86_64.cfg @@ -13,8 +13,3 @@ unattended_install..floppy_ks: floppies = "fl" floppy_name = images/rhel64-64/ks.vfd - guest_s4..global_disable_s4: - s4_support_chk_cmd = "rpm --force --nodeps http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" - s4_support_chk_cmd += " && cat cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" - s4_support_chk_cmd += " && iasl -d /tmp/ssdt" - s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" diff --git a/shared/cfg/guest-os/Linux/RHEL/6.devel.cfg b/shared/cfg/guest-os/Linux/RHEL/6.devel.cfg index 74c6d54ac..042031e3c 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.devel.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.devel.cfg @@ -8,3 +8,27 @@ modprobe_module = block_hotplug: modprobe_module = + guest_s3: + global_enable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + s3_support_chk_cmd += " && dmesg -c > /dev/null && grep -q mem /sys/power/state" + global_disable_s3: + s3_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s3_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s3_support_chk_cmd += " && iasl -d /tmp/ssdt" + s3_support_chk_cmd += " && grep "_S3" /tmp/ssdt.dsl" + guest_s4: + global_enable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" + s4_support_chk_cmd += " && dmesg -c > /dev/null && grep -q disk /sys/power/state" + global_disable_s4: + s4_support_chk_cmd = "rpm --force --nodeps -ivh http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" + s4_support_chk_cmd += " && cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" + s4_support_chk_cmd += " && iasl -d /tmp/ssdt" + s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" diff --git a/shared/cfg/guest-os/Linux/RHEL/6.devel/i386.cfg b/shared/cfg/guest-os/Linux/RHEL/6.devel/i386.cfg index 025923443..638d77f60 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.devel/i386.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.devel/i386.cfg @@ -11,8 +11,3 @@ unattended_install..floppy_ks: floppies = "fl" floppy_name = images/rhel63-64/ks.vfd - guest_s4..global_disable_s4: - s4_support_chk_cmd = "rpm --force --nodeps http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" - s4_support_chk_cmd += " && cat cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" - s4_support_chk_cmd += " && iasl -d /tmp/ssdt" - s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" diff --git a/shared/cfg/guest-os/Linux/RHEL/6.devel/x86_64.cfg b/shared/cfg/guest-os/Linux/RHEL/6.devel/x86_64.cfg index 5bfb1da6f..5572861d3 100644 --- a/shared/cfg/guest-os/Linux/RHEL/6.devel/x86_64.cfg +++ b/shared/cfg/guest-os/Linux/RHEL/6.devel/x86_64.cfg @@ -12,8 +12,3 @@ floppies = "fl" floppy_name = images/rhel6-64/ks.vfd cdrom_cd1 = isos/linux/RHEL6-devel-x86_64.iso - guest_s4..global_disable_s4: - s4_support_chk_cmd = "rpm --force --nodeps http://mirrors.sonic.net/centos/6/os/`uname -m`/Packages/iasl-20090123-3.1.el6.`uname -m`.rpm" - s4_support_chk_cmd += " && cat cat /sys/firmware/acpi/tables/SSDT > /tmp/ssdt" - s4_support_chk_cmd += " && iasl -d /tmp/ssdt" - s4_support_chk_cmd += " && grep "_S4" /tmp/ssdt.dsl" From c736b729e2cb2ef1a778f0dc26f1bd17598f0050 Mon Sep 17 00:00:00 2001 From: Yu Mingfei <yumingfei@cn.fujitsu.com> Date: Tue, 6 Aug 2013 12:48:14 +0800 Subject: [PATCH 200/254] virttest.virsh: Fix argument error for vol_create_as. Signed-off-by: Yu Mingfei <yumingfei@cn.fujitsu.com> --- virttest/virsh.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/virttest/virsh.py b/virttest/virsh.py index 43af3caf3..ebd00383f 100644 --- a/virttest/virsh.py +++ b/virttest/virsh.py @@ -1531,8 +1531,8 @@ def pool_undefine(name, extra="", **dargs): return command("pool-undefine %s %s" % (name, extra), **dargs) -def vol_create_as(vol_name, pool_name, capacity, allocation, frmt, \ - extra="", **dargs): +def vol_create_as(vol_name, pool_name, capacity, allocation, + frmt, extra="", **dargs): """ To create the volumes on different available pool @@ -1550,7 +1550,7 @@ def vol_create_as(vol_name, pool_name, capacity, allocation, frmt, \ if allocation: cmd += " --allocation %s" % (allocation) - if format: + if frmt: cmd += " --format %s" % (frmt) if extra: cmd += " %s" % (extra) From 88ec94e757e2cea4cf0c7ff111131aa7663366d4 Mon Sep 17 00:00:00 2001 From: Peter Krempa <pkrempa@redhat.com> Date: Thu, 1 Aug 2013 16:04:56 +0200 Subject: [PATCH 201/254] virsh_managedsave: Fix configuration option virsh_managedsave.status_error_yes.name_option.shut_status failed if it was run as a part of the testsuite and the testing VM was running before. This was due to misconfiguration of the environment, where the test was expecting the machine to be off. Change the status command to kill the VM before the test. --- libvirt/tests/cfg/virsh_cmd/domain/virsh_managedsave.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libvirt/tests/cfg/virsh_cmd/domain/virsh_managedsave.cfg b/libvirt/tests/cfg/virsh_cmd/domain/virsh_managedsave.cfg index b5a434108..0be8db093 100644 --- a/libvirt/tests/cfg/virsh_cmd/domain/virsh_managedsave.cfg +++ b/libvirt/tests/cfg/virsh_cmd/domain/virsh_managedsave.cfg @@ -40,6 +40,6 @@ variants: - shut_status: start_vm = no - kill_vm = yes + kill_vm_before_test = yes - libvirtd_off: managedsave_libvirtd = "off" From d353a501baea606e5e49559b91bb88ae2cbf7daa Mon Sep 17 00:00:00 2001 From: Li Yang <liyang.fnst@cn.fujitsu.com> Date: Mon, 29 Jul 2013 11:41:10 +0800 Subject: [PATCH 202/254] libvirt: Add 'EDITOR' configuration in control Signed-off-by: Li Yang <liyang.fnst@cn.fujitsu.com> --- libvirt/control | 2 ++ libvirt/tests/src/virsh_cmd/domain/virsh_edit.py | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libvirt/control b/libvirt/control index 1252d064c..1cb082eb5 100644 --- a/libvirt/control +++ b/libvirt/control @@ -22,6 +22,8 @@ from virttest import utils_misc, cartesian_config # set English environment (command output might be localized, need to be safe) os.environ['LANG'] = 'en_US.UTF-8' +# set editor environment (some command will use default editor "vi") +os.environ['EDITOR'] = 'vi' libvirt_test_dir = os.path.join(os.environ['AUTODIR'],'tests/virt/libvirt') diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_edit.py b/libvirt/tests/src/virsh_cmd/domain/virsh_edit.py index 508563e51..41d7b3874 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_edit.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_edit.py @@ -35,7 +35,6 @@ def modify_vcpu(source, edit_cmd): """ session = aexpect.ShellSession("sudo -s") try: - session.sendline("export EDITOR=vi") session.sendline("virsh edit %s" % source) session.sendline(edit_cmd) session.send('\x1b') From 3b795a2eb9e61eadb5db206d0d2807b5df117bd0 Mon Sep 17 00:00:00 2001 From: Yiqiao Pu <ypu@redhat.com> Date: Mon, 5 Aug 2013 22:59:59 +0800 Subject: [PATCH 203/254] virttest.staging.utils_memory: Add utils_memory in virttest staging This file is just the same as autotest/client/shared. It can be drop when the utils_memory in autotest package. Signed-off-by: Yiqiao Pu <ypu@redhat.com> --- virttest/staging/__init__.py | 0 virttest/staging/utils_memory.py | 208 +++++++++++++++++++++++++++++++ 2 files changed, 208 insertions(+) create mode 100644 virttest/staging/__init__.py create mode 100644 virttest/staging/utils_memory.py diff --git a/virttest/staging/__init__.py b/virttest/staging/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/virttest/staging/utils_memory.py b/virttest/staging/utils_memory.py new file mode 100644 index 000000000..07c240131 --- /dev/null +++ b/virttest/staging/utils_memory.py @@ -0,0 +1,208 @@ +import re, glob, math +from autotest.client import utils + + +# Returns total memory in kb +def read_from_meminfo(key): + cmd_result = utils.run('grep %s /proc/meminfo' % key, verbose=False) + meminfo = cmd_result.stdout + return int(re.search(r'\d+', meminfo).group(0)) + + +def memtotal(): + return read_from_meminfo('MemTotal') + + +def freememtotal(): + return read_from_meminfo('MemFree') + + +def rounded_memtotal(): + # Get total of all physical mem, in kbytes + usable_kbytes = memtotal() + # usable_kbytes is system's usable DRAM in kbytes, + # as reported by memtotal() from device /proc/meminfo memtotal + # after Linux deducts 1.5% to 5.1% for system table overhead + # Undo the unknown actual deduction by rounding up + # to next small multiple of a big power-of-two + # eg 12GB - 5.1% gets rounded back up to 12GB + mindeduct = 0.015 # 1.5 percent + maxdeduct = 0.055 # 5.5 percent + # deduction range 1.5% .. 5.5% supports physical mem sizes + # 6GB .. 12GB in steps of .5GB + # 12GB .. 24GB in steps of 1 GB + # 24GB .. 48GB in steps of 2 GB ... + # Finer granularity in physical mem sizes would require + # tighter spread between min and max possible deductions + + # increase mem size by at least min deduction, without rounding + min_kbytes = int(usable_kbytes / (1.0 - mindeduct)) + # increase mem size further by 2**n rounding, by 0..roundKb or more + round_kbytes = int(usable_kbytes / (1.0 - maxdeduct)) - min_kbytes + # find least binary roundup 2**n that covers worst-cast roundKb + mod2n = 1 << int(math.ceil(math.log(round_kbytes, 2))) + # have round_kbytes <= mod2n < round_kbytes*2 + # round min_kbytes up to next multiple of mod2n + phys_kbytes = min_kbytes + mod2n - 1 + phys_kbytes = phys_kbytes - (phys_kbytes % mod2n) # clear low bits + return phys_kbytes + + +def numa_nodes(): + node_paths = glob.glob('/sys/devices/system/node/node*') + nodes = [int(re.sub(r'.*node(\d+)', r'\1', x)) for x in node_paths] + return (sorted(nodes)) + + +def node_size(): + nodes = max(len(numa_nodes()), 1) + return ((memtotal() * 1024) / nodes) + + +def get_huge_page_size(): + output = utils.system_output('grep Hugepagesize /proc/meminfo') + return int(output.split()[1]) # Assumes units always in kB. :( + + +def get_num_huge_pages(): + raw_hugepages = utils.system_output('/sbin/sysctl vm.nr_hugepages') + return int(raw_hugepages.split()[2]) + + +def set_num_huge_pages(num): + utils.system('/sbin/sysctl vm.nr_hugepages=%d' % num) + + +def drop_caches(): + """Writes back all dirty pages to disk and clears all the caches.""" + utils.run("sync", verbose=False) + # We ignore failures here as this will fail on 2.6.11 kernels. + utils.run("echo 3 > /proc/sys/vm/drop_caches", ignore_status=True, + verbose=False) + + +def read_from_vmstat(key): + """ + Get specific item value from vmstat + + :param key: The item you want to check from vmstat + :type key: String + :return: The value of the item + :rtype: int + """ + vmstat = open("/proc/vmstat") + vmstat_info = vmstat.read() + vmstat.close() + return int(re.findall("%s\s+(\d+)" % key, vmstat_info)[0]) + + +def read_from_smaps(pid, key): + """ + Get specific item value from the smaps of a process include all sections. + + :param pid: Process id + :type pid: String + :param key: The item you want to check from smaps + :type key: String + :return: The value of the item in kb + :rtype: int + """ + smaps = open("/proc/%s/smaps" % pid) + smaps_info = smaps.read() + smaps.close() + + memory_size = 0 + for each_number in re.findall("%s:\s+(\d+)" % key, smaps_info): + memory_size += int(each_number) + + return memory_size + + +def read_from_numa_maps(pid, key): + """ + Get the process numa related info from numa_maps. This function + only use to get the numbers like anon=1. + + :param pid: Process id + :type pid: String + :param key: The item you want to check from numa_maps + :type key: String + :return: A dict using the address as the keys + :rtype: dict + """ + numa_maps = open("/proc/%s/numa_maps" % pid) + numa_map_info = numa_maps.read() + numa_maps.close() + + + numa_maps_dict = {} + numa_pattern = r"(^[\dabcdfe]+)\s+.*%s[=:](\d+)" % key + for address, number in re.findall(numa_pattern, numa_map_info, re.M): + numa_maps_dict[address] = number + + return numa_maps_dict + + +def get_buddy_info(chunk_sizes, nodes="all", zones="all"): + """ + Get the fragement status of the host. It use the same method + to get the page size in buddyinfo. + 2^chunk_size * page_size + The chunk_sizes can be string make up by all orders that you want to check + splited with blank or a mathematical expression with '>', '<' or '='. + For example: + The input of chunk_size could be: "0 2 4" + And the return will be: {'0': 3, '2': 286, '4': 687} + if you are using expression: ">=9" + the return will be: {'9': 63, '10': 225} + + :param chunk_size: The order number shows in buddyinfo. This is not + the real page size. + :type chunk_size: string + :param nodes: The numa node that you want to check. Default value is all + :type nodes: string + :param zones: The memory zone that you want to check. Default value is all + :type zones: string + :return: A dict using the chunk_size as the keys + :rtype: dict + """ + buddy_info = open("/proc/buddyinfo") + buddy_info_content = buddy_info.read() + buddy_info.close() + + re_buddyinfo = "Node\s+" + if nodes == "all": + re_buddyinfo += "(\d+)" + else: + re_buddyinfo += "(%s)" % "|".join(nodes.split()) + + if not re.findall(re_buddyinfo, buddy_info_content): + logging.warn("Can not find Nodes %s" % nodes) + return None + re_buddyinfo += ".*?zone\s+" + if zones == "all": + re_buddyinfo += "(\w+)" + else: + re_buddyinfo += "(%s)" % "|".join(zones.split()) + if not re.findall(re_buddyinfo, buddy_info_content): + logging.warn("Can not find zones %s" % zones) + return None + re_buddyinfo += "\s+([\s\d]+)" + + buddy_list = re.findall(re_buddyinfo, buddy_info_content) + + if re.findall("[<>=]", chunk_sizes) and buddy_list: + size_list = range(len(buddy_list[-1][-1].strip().split())) + chunk_sizes = [str(_) for _ in size_list if eval("%s %s" % (_, + chunk_sizes))] + + chunk_sizes = ' '.join(chunk_sizes) + + buddyinfo_dict = {} + for chunk_size in chunk_sizes.split(): + buddyinfo_dict[chunk_size] = 0 + for _, _, chunk_info in buddy_list: + chunk_info = chunk_info.strip().split()[int(chunk_size)] + buddyinfo_dict[chunk_size] += int(chunk_info) + + return buddyinfo_dict From c842911182b5c5a6a0e32834cc7033f0e14b9d23 Mon Sep 17 00:00:00 2001 From: Yiqiao Pu <ypu@redhat.com> Date: Wed, 7 Aug 2013 00:01:55 +0800 Subject: [PATCH 204/254] Update memory related calls in scripts Signed-off-by: Yiqiao Pu <ypu@redhat.com> --- .../tests/src/virsh_cmd/domain/virsh_memtune.py | 10 ++++++++-- .../tests/src/virsh_cmd/host/virsh_nodeinfo.py | 7 ++++++- .../src/virsh_cmd/host/virsh_nodememstats.py | 16 +++++++++++----- qemu/tests/boot_time.py | 8 ++++++-- qemu/tests/cgroup.py | 8 +++++++- qemu/tests/ksm_overcommit.py | 17 +++++++++++------ qemu/tests/stress_kernel_compile.py | 8 ++++++-- shared/control/stress_memory_heavy.control | 8 +++++++- tests/trans_hugepage_memory_stress.py | 17 ++++++++++++----- tests/trans_hugepage_relocated.py | 13 +++++++++---- virttest/utils_test.py | 9 +++++++-- 11 files changed, 90 insertions(+), 31 deletions(-) diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_memtune.py b/libvirt/tests/src/virsh_cmd/domain/virsh_memtune.py index 6e285b387..aad7e28b5 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_memtune.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_memtune.py @@ -1,7 +1,13 @@ import logging, re, os, commands, string, math from autotest.client.shared import error from virttest import virsh, libvirt_vm -from autotest.client import utils, cgroup_utils +from autotest.client import cgroup_utils + +try: + from autotest.client.shared import utils_memory +except ImportError: + from virttest.staging import utils_memory + def run_virsh_memtune(test, params, env): """ @@ -151,7 +157,7 @@ def check_hardswaplimit(path, expected_value): # By default set 1GB less than the total memory # In case of total memory is less than 1GB set to 256MB # visit subtests.cfg to change these default values - Memtotal = utils.read_from_meminfo('MemTotal') + Memtotal = utils_memory.read_from_meminfo('MemTotal') base_mem = params.get("memtune_base_mem") if int(Memtotal) < int(base_mem): diff --git a/libvirt/tests/src/virsh_cmd/host/virsh_nodeinfo.py b/libvirt/tests/src/virsh_cmd/host/virsh_nodeinfo.py index de8f9b52d..e25f1eaa3 100644 --- a/libvirt/tests/src/virsh_cmd/host/virsh_nodeinfo.py +++ b/libvirt/tests/src/virsh_cmd/host/virsh_nodeinfo.py @@ -3,6 +3,11 @@ from autotest.client.shared import error from virttest import virsh, utils_libvirtd +try: + from autotest.client.shared import utils_memory +except ImportError: + from virttest.staging import utils_memory + def run_virsh_nodeinfo(test, params, env): """ @@ -66,7 +71,7 @@ def output_check(nodeinfo_output): # Check Memory size memory_size_nodeinfo = int(_check_nodeinfo(nodeinfo_output, 'Memory size', 3)) - memory_size_os = utils.memtotal() + memory_size_os = utils_memory.memtotal() if memory_size_nodeinfo != memory_size_os: raise error.TestFail("Virsh nodeinfo output didn't match " "Memory size") diff --git a/libvirt/tests/src/virsh_cmd/host/virsh_nodememstats.py b/libvirt/tests/src/virsh_cmd/host/virsh_nodememstats.py index 9a3d0d574..8db325ac3 100644 --- a/libvirt/tests/src/virsh_cmd/host/virsh_nodememstats.py +++ b/libvirt/tests/src/virsh_cmd/host/virsh_nodememstats.py @@ -1,8 +1,14 @@ import logging, re from autotest.client.shared import error -from autotest.client import utils from virttest import virsh, utils_libvirtd + +try: + from autotest.client.shared import utils_memory +except ImportError: + from virttest.staging import utils_memory + + def run_virsh_nodememstats(test, params, env): """ Test the command virsh nodememstats @@ -102,10 +108,10 @@ def virsh_check_nodememtats(actual_stats, expected_stats, delta): expected[name] = int(value) / 1024 # Get the actual value from /proc/meminfo and normalise to MBs - actual['total'] = int(utils.memtotal()) / 1024 - actual['free'] = int(utils.freememtotal()) / 1024 - actual['buffers'] = int(utils.read_from_meminfo('Buffers'))/1024 - actual['cached'] = int(utils.read_from_meminfo('Cached')) / 1024 + actual['total'] = int(utils_memory.memtotal()) / 1024 + actual['free'] = int(utils_memory.freememtotal()) / 1024 + actual['buffers'] = int(utils_memory.read_from_meminfo('Buffers'))/1024 + actual['cached'] = int(utils_memory.read_from_meminfo('Cached')) / 1024 # Currently the delta value is kept at 200 MB this can be # tuned based on the accuracy diff --git a/qemu/tests/boot_time.py b/qemu/tests/boot_time.py index 525203a6f..416dd1f5c 100644 --- a/qemu/tests/boot_time.py +++ b/qemu/tests/boot_time.py @@ -1,8 +1,12 @@ import logging, time, re, os from autotest.client.shared import error -from autotest.client import utils from virttest import utils_misc, utils_test, env_process, storage, data_dir +try: + from autotest.client.shared import utils_memory +except ImportError: + from virttest.staging import utils_memory + @error.context_aware def run_boot_time(test, params, env): @@ -34,7 +38,7 @@ def run_boot_time(test, params, env): vm.destroy() error.context("Boot up guest and measure the boot time", logging.info) - utils.drop_caches() + utils_memory.drop_caches() vm.create() vm.verify_alive() session = vm.wait_for_serial_login(timeout=timeout) diff --git a/qemu/tests/cgroup.py b/qemu/tests/cgroup.py index a75e9e341..ae0aa0791 100644 --- a/qemu/tests/cgroup.py +++ b/qemu/tests/cgroup.py @@ -21,6 +21,12 @@ from virttest.utils_cgroup import CgroupModules from virttest.utils_cgroup import get_load_per_cpu +try: + from autotest.client.shared import utils_memory +except ImportError: + from virttest.staging import utils_memory + + @error.context_aware def run_cgroup(test, params, env): """ @@ -1768,7 +1774,7 @@ def memory_limit(memsw=False): err = "Hugepages can't be used in this test." logging.error(err) raise error.TestNAError(err) - if utils.read_from_meminfo('SwapFree') < (mem * 0.1): + if utils_memory.read_from_meminfo('SwapFree') < (mem * 0.1): err = "Not enough free swap space" logging.error(err) raise error.TestNAError(err) diff --git a/qemu/tests/ksm_overcommit.py b/qemu/tests/ksm_overcommit.py index 1d7c5d7a2..074f0d0e7 100644 --- a/qemu/tests/ksm_overcommit.py +++ b/qemu/tests/ksm_overcommit.py @@ -1,8 +1,12 @@ import logging, time, random, math, os from autotest.client.shared import error -from autotest.client import utils from virttest import utils_misc, utils_test, aexpect, env_process, data_dir +try: + from autotest.client.shared import utils_memory +except ImportError: + from virttest.staging import utils_memory + def run_ksm_overcommit(test, params, env): """ @@ -215,10 +219,10 @@ def split_guest(): e_msg = ("VM %d died while executing " "static_random_fill on allocator loop" % i) raise error.TestFail(e_msg) - free_mem = int(utils.read_from_meminfo("MemFree")) + free_mem = int(utils_memory.read_from_meminfo("MemFree")) if (ksm_swap): free_mem = (free_mem + - int(utils.read_from_meminfo("SwapFree"))) + int(utils_memory.read_from_meminfo("SwapFree"))) logging.debug("Free memory on host: %d", free_mem) # We need to keep some memory for python to run. @@ -422,7 +426,8 @@ def split_parallel(): if (host_reserve == -1): # default host_reserve = MemAvailable + one_minimal_guest(128MB) # later we add 64MB per additional guest - host_reserve = ((utils.memtotal() - utils.read_from_meminfo("MemFree")) + host_reserve = ((utils_memory.memtotal() + - utils_memory.read_from_meminfo("MemFree")) / 1024 + 128) # using default reserve _host_reserve = True @@ -455,7 +460,7 @@ def split_parallel(): host_reserve += vmsc * 64 _host_reserve = vmsc - host_mem = (int(utils.memtotal()) / 1024 - host_reserve) + host_mem = (int(utils_memory.memtotal()) / 1024 - host_reserve) ksm_swap = False if params.get("ksm_swap") == "yes": @@ -523,7 +528,7 @@ def split_parallel(): if _guest_reserve: guest_reserve += math.ceil(mem * 0.055) - swap = int(utils.read_from_meminfo("SwapTotal")) / 1024 + swap = int(utils_memory.read_from_meminfo("SwapTotal")) / 1024 logging.debug("Overcommit = %f", overcommit) logging.debug("True overcommit = %f ", (float(vmsc * mem) / diff --git a/qemu/tests/stress_kernel_compile.py b/qemu/tests/stress_kernel_compile.py index dde2436f7..c17f631ae 100644 --- a/qemu/tests/stress_kernel_compile.py +++ b/qemu/tests/stress_kernel_compile.py @@ -1,8 +1,12 @@ import logging, os from autotest.client.shared import error -from autotest.client import utils from virttest import utils_test, utils_misc, env_process +try: + from autotest.client.shared import utils_memory +except ImportError: + from virttest.staging import utils_memory + def run_stress_kernel_compile(tests, params, env): """ @@ -54,7 +58,7 @@ def kernelcompile(session, vm_name): for tag in range(1, guest_number): params["vms"] += " stress_guest_%s" % tag - mem_host = utils.memtotal() / 1024 + mem_host = utils_memory.memtotal() / 1024 vmem = int(mem_host * over_c / guest_number) if vmem < 256: diff --git a/shared/control/stress_memory_heavy.control b/shared/control/stress_memory_heavy.control index c97c535ea..c7ffac56a 100644 --- a/shared/control/stress_memory_heavy.control +++ b/shared/control/stress_memory_heavy.control @@ -13,12 +13,18 @@ to heavily stress a machine's memory. import os from autotest.client import utils +try: + from autotest.client.shared import utils_memory +except ImportError: + from virttest.staging import utils_memory + + # Assemble the parameters specially to stress memory # We will use 2 workers of each type for each CPU detected threads = 2 * utils.count_cpus() -mem = utils.memtotal() / 1024 / 512 +mem = utils_memory.memtotal() / 1024 / 512 memory_per_thread = 256 * 1024 free_disk = utils.freespace(os.getcwd()) diff --git a/tests/trans_hugepage_memory_stress.py b/tests/trans_hugepage_memory_stress.py index 277200533..3da966bb9 100644 --- a/tests/trans_hugepage_memory_stress.py +++ b/tests/trans_hugepage_memory_stress.py @@ -3,6 +3,12 @@ from autotest.client import utils from virttest import utils_test +try: + from autotest.client.shared import utils_memory +except ImportError: + from virttest.staging import utils_memory + + @error.context_aware def run_trans_hugepage_memory_stress(test, params, env): """ @@ -32,9 +38,10 @@ def run_trans_hugepage_memory_stress(test, params, env): try: # Allocated free memory to hugetlbfs - mem_free = int(utils.read_from_meminfo('MemFree')) / 1024 - mem_swap = int(utils.read_from_meminfo('SwapFree')) / 1024 - hugepage_size = int (utils.read_from_meminfo('Hugepagesize')) / 1024 + mem_free = int(utils_memory.read_from_meminfo('MemFree')) / 1024 + mem_swap = int(utils_memory.read_from_meminfo('SwapFree')) / 1024 + hugepage_size = (int (utils_memory.read_from_meminfo('Hugepagesize')) + / 1024) nr_hugetlbfs = (mem_free + mem_swap - mem - qemu_mem) / hugepage_size fd = open(hugetlbfs_path, "w") fd.write(str(nr_hugetlbfs)) @@ -42,7 +49,7 @@ def run_trans_hugepage_memory_stress(test, params, env): error.context("Memory stress test") - nr_ah.append(int(utils.read_from_meminfo('AnonHugePages'))) + nr_ah.append(int(utils_memory.read_from_meminfo('AnonHugePages'))) if nr_ah[0] <= 0: raise error.TestFail("VM is not using transparent hugepage") @@ -51,7 +58,7 @@ def run_trans_hugepage_memory_stress(test, params, env): utils_test.run_virt_sub_test(test, params, env, sub_type=memory_stress_test) - nr_ah.append(int(utils.read_from_meminfo('AnonHugePages'))) + nr_ah.append(int(utils_memory.read_from_meminfo('AnonHugePages'))) logging.debug("The huge page using for guest is: %s" % nr_ah) if nr_ah[1] <= nr_ah[0]: diff --git a/tests/trans_hugepage_relocated.py b/tests/trans_hugepage_relocated.py index d87d9c523..f23c30cdb 100644 --- a/tests/trans_hugepage_relocated.py +++ b/tests/trans_hugepage_relocated.py @@ -1,8 +1,13 @@ import logging, time, commands, os, re from autotest.client.shared import error -from autotest.client import utils from virttest import utils_test +try: + from autotest.client.shared import utils_memory +except ImportError: + from virttest.staging import utils_memory + + def run_trans_hugepage_relocated(test, params, env): """ Transparent hugepage relocated test with quantification. @@ -20,7 +25,7 @@ def run_trans_hugepage_relocated(test, params, env): def nr_hugepage_check(sleep_time, wait_time): time_last = 0 while True: - value = int(utils.read_from_meminfo("AnonHugePages")) + value = int(utils_memory.read_from_meminfo("AnonHugePages")) nr_hugepages.append(value) time_stamp = time.time() if time_last != 0: @@ -39,8 +44,8 @@ def nr_hugepage_check(sleep_time, wait_time): vm.verify_alive() session = vm.wait_for_login(timeout=login_timeout) - free_memory = utils.read_from_meminfo("MemFree") - hugepage_size = utils.read_from_meminfo("Hugepagesize") + free_memory = utils_memory.read_from_meminfo("MemFree") + hugepage_size = utils_memory.read_from_meminfo("Hugepagesize") mem = params.get("mem") vmsm = int(mem) + 128 hugetlbfs_path = params.get("hugetlbfs_path", "/proc/sys/vm/nr_hugepages") diff --git a/virttest/utils_test.py b/virttest/utils_test.py index cf980d44e..95ef78c6f 100644 --- a/virttest/utils_test.py +++ b/virttest/utils_test.py @@ -37,6 +37,11 @@ # TODO: Obsoleted path used prior autotest-0.15.2/virttest-2013.06.24 from virttest import utils_cgroup +try: + from autotest.client.shared import utils_memory +except ImportError: + from virttest.staging import utils_memory + # Handle transition from autotest global_config (0.14.x series) to # settings (0.15.x onwards) try: @@ -1442,9 +1447,9 @@ def get_memory_info(lvms): try: meminfo = "Host: memfree = " - meminfo += str(int(utils.freememtotal()) / 1024) + "M; " + meminfo += str(int(utils_memory.freememtotal()) / 1024) + "M; " meminfo += "swapfree = " - mf = int(utils.read_from_meminfo("SwapFree")) / 1024 + mf = int(utils_system.read_from_meminfo("SwapFree")) / 1024 meminfo += str(mf) + "M; " except Exception, e: raise error.TestFail("Could not fetch host free memory info, " From 49883b79ca9e8ba8234310616d858433b0692614 Mon Sep 17 00:00:00 2001 From: Lucas Meneghel Rodrigues <lmr@redhat.com> Date: Tue, 6 Aug 2013 13:57:29 -0300 Subject: [PATCH 205/254] Add virttest.staging.utils_cgroup Add a new virttest.staging namespace that will hold libraries whose ultimate destination is autotest. Add back utils_cgroup to that namespace, and keep both files in sync until newer versions of autotest shipping this file will be widely available. Signed-off-by: Lucas Meneghel Rodrigues <lmr@redhat.com> --- .../src/virsh_cmd/domain/virsh_numatune.py | 2 +- qemu/tests/cgroup.py | 6 +- qemu/tests/ksm_overcommit.py | 2 + qemu/tests/vhost_with_cgroup.py | 2 +- virttest/staging/utils_cgroup.py | 756 ++++++++++++++++++ virttest/staging/utils_memory.py | 2 +- virttest/utils_test.py | 4 +- 7 files changed, 766 insertions(+), 8 deletions(-) create mode 100755 virttest/staging/utils_cgroup.py diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_numatune.py b/libvirt/tests/src/virsh_cmd/domain/virsh_numatune.py index c9fc0bc22..097b33084 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_numatune.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_numatune.py @@ -5,7 +5,7 @@ from autotest.client.shared import utils_cgroup except ImportError: # TODO: Obsoleted path used prior autotest-0.15.2/virttest-2013.06.24 - from virttest import utils_cgroup + from virttest.staging import utils_cgroup def num_numa_nodes(): diff --git a/qemu/tests/cgroup.py b/qemu/tests/cgroup.py index ae0aa0791..16c950bcf 100644 --- a/qemu/tests/cgroup.py +++ b/qemu/tests/cgroup.py @@ -17,9 +17,9 @@ from autotest.client.shared.utils_cgroup import get_load_per_cpu except ImportError: # TODO: Obsoleted path used prior autotest-0.15.2/virttest-2013.06.24 - from virttest.utils_cgroup import Cgroup - from virttest.utils_cgroup import CgroupModules - from virttest.utils_cgroup import get_load_per_cpu + from virttest.staging.utils_cgroup import Cgroup + from virttest.staging.utils_cgroup import CgroupModules + from virttest.staging.utils_cgroup import get_load_per_cpu try: from autotest.client.shared import utils_memory diff --git a/qemu/tests/ksm_overcommit.py b/qemu/tests/ksm_overcommit.py index 074f0d0e7..030d6603f 100644 --- a/qemu/tests/ksm_overcommit.py +++ b/qemu/tests/ksm_overcommit.py @@ -2,6 +2,8 @@ from autotest.client.shared import error from virttest import utils_misc, utils_test, aexpect, env_process, data_dir +from autotest.client.shared import utils + try: from autotest.client.shared import utils_memory except ImportError: diff --git a/qemu/tests/vhost_with_cgroup.py b/qemu/tests/vhost_with_cgroup.py index 19a151aac..afa5d2aa9 100644 --- a/qemu/tests/vhost_with_cgroup.py +++ b/qemu/tests/vhost_with_cgroup.py @@ -7,7 +7,7 @@ from autotest.client.shared.utils_cgroup import Cgroup, CgroupModules except ImportError: # TODO: Obsoleted path used prior autotest-0.15.2/virttest-2013.06.24 - from virttest.utils_cgroup import Cgroup, CgroupModules + from virttest.staging.utils_cgroup import Cgroup, CgroupModules @error.context_aware diff --git a/virttest/staging/utils_cgroup.py b/virttest/staging/utils_cgroup.py new file mode 100755 index 000000000..28761cac4 --- /dev/null +++ b/virttest/staging/utils_cgroup.py @@ -0,0 +1,756 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +""" +Helpers for cgroup testing. + +@copyright: 2011 Red Hat Inc. +@author: Lukas Doktor <ldoktor@redhat.com> +""" +import logging, os, shutil, subprocess, time, re, random, commands +from tempfile import mkdtemp +from autotest.client import utils +from autotest.client.shared import error + +class Cgroup(object): + """ + Cgroup handling class. + """ + def __init__(self, module, _client): + """ + Constructor + @param module: Name of the cgroup module + @param _client: Test script pwd + name + """ + self.module = module + self._client = _client + self.root = None + self.cgroups = [] + + + def __del__(self): + """ + Destructor + """ + self.cgroups.sort(reverse=True) + for pwd in self.cgroups[:]: + for task in self.get_property("tasks", pwd): + if task: + self.set_root_cgroup(int(task)) + self.rm_cgroup(pwd) + + def initialize(self, modules): + """ + Initializes object for use. + + @param modules: Array of all available cgroup modules. + """ + self.root = modules.get_pwd(self.module) + if not self.root: + raise error.TestError("cg.initialize(): Module %s not found" + % self.module) + + + def __get_cgroup_pwd(self, cgroup): + """ + Get cgroup's full path + + @param: cgroup: cgroup name + @return: cgroup's full path + """ + if not isinstance(cgroup, str): + raise error.TestError("cgroup type isn't string!") + return os.path.join(self.root, cgroup) + '/' + + + def get_cgroup_name(self, pwd=None): + """ + Get cgroup's name + + @param: pwd: cgroup name + @return: cgroup's name + """ + if pwd is None: + # root cgroup + return None + if isinstance(pwd, int): + pwd = self.cgroups[pwd] + # self.root is "/cgroup/blkio," not "/cgroup/blkio/" + # cgroup is "/cgroup/blkio/test" or "/cgroup/blkio/test/test" + # expected cgroup name is test/ or test/test/ + if pwd.startswith(self.root + '/'): + return pwd[len(self.root) + 1:] + return None + + + def get_cgroup_index(self, cgroup): + """ + Get cgroup's index in cgroups + + @param: cgroup: cgroup name + @return: index of cgroup + """ + try: + if self.__get_cgroup_pwd(cgroup) not in self.cgroups: + raise error.TestFail("%s not exists!" % cgroup) + cgroup_pwd = self.__get_cgroup_pwd(cgroup) + return self.cgroups.index(cgroup_pwd) + except error.CmdError: + raise error.TestFail("Find index failed!") + + + def mk_cgroup_cgcreate(self, pwd=None, cgroup=None): + """ + Make a cgroup by cgcreate command + + @params: cgroup: Maked cgroup name + @return: last cgroup index + """ + try: + parent_cgroup = self.get_cgroup_name(pwd) + if cgroup is None: + range = "abcdefghijklmnopqrstuvwxyz0123456789" + sub_cgroup = "cgroup-" + "".join(random.sample(range + + range.upper(), 6)) + else: + sub_cgroup = cgroup + if parent_cgroup is None: + cgroup = sub_cgroup + else: + # Parent cgroup:test. Created cgroup:test1. + # Whole cgroup name is "test/test1" + cgroup = os.path.join(parent_cgroup, sub_cgroup) + if self.__get_cgroup_pwd(cgroup) in self.cgroups: + raise error.TestFail("%s exists!" % cgroup) + cgcreate_cmd = "cgcreate -g %s:%s" % (self.module, cgroup) + utils.run(cgcreate_cmd, ignore_status=False) + pwd = self.__get_cgroup_pwd(cgroup) + self.cgroups.append(pwd) + return len(self.cgroups) - 1 + except error.CmdError: + raise error.TestFail("Make cgroup by cgcreate failed!") + + + def mk_cgroup(self, pwd=None, cgroup=None): + """ + Creates new temporary cgroup + @param pwd: where to create this cgroup (default: self.root) + @param cgroup: desired cgroup name + @return: last cgroup index + """ + if pwd is None: + pwd = self.root + if isinstance(pwd, int): + pwd = self.cgroups[pwd] + try: + if cgroup and self.__get_cgroup_pwd(cgroup) in self.cgroups: + raise error.TestFail("%s exists!" % cgroup) + if not cgroup: + pwd = mkdtemp(prefix='cgroup-', dir=pwd) + '/' + else: + pwd = os.path.join(pwd, cgroup) + '/' + if not os.path.exists(pwd): + os.mkdir(pwd) + except Exception, inst: + raise error.TestError("cg.mk_cgroup(): %s" % inst) + self.cgroups.append(pwd) + return len(self.cgroups) - 1 + + + def cgexec(self, cgroup, cmd, args=""): + """ + Execute command in desired cgroup + + @param: cgroup: Desired cgroup + @param: cmd: Executed command + @param: args: Executed command's parameters + """ + try: + args_str = "" + if len(args): + args_str = " ".join(args) + cgexec_cmd = ("cgexec -g %s:%s %s %s" % + (self.module, cgroup, cmd, args_str)) + status, output = commands.getstatusoutput(cgexec_cmd) + return status, output + except error.CmdError, detail: + raise error.TestFail("Execute %s in cgroup failed!\n%s" % + (cmd, detail)) + + + def rm_cgroup(self, pwd): + """ + Removes cgroup. + + @param pwd: cgroup directory. + """ + if isinstance(pwd, int): + pwd = self.cgroups[pwd] + try: + os.rmdir(pwd) + self.cgroups.remove(pwd) + except ValueError: + logging.warn("cg.rm_cgroup(): Removed cgroup which wasn't created" + "using this Cgroup") + except Exception, inst: + raise error.TestError("cg.rm_cgroup(): %s" % inst) + + + def cgdelete_all_cgroups(self): + """ + Delete all cgroups in the module + """ + try: + for cgroup_pwd in self.cgroups: + # Ignore sub cgroup + cgroup = self.get_cgroup_name(cgroup_pwd) + if cgroup.count("/") > 0: + continue + self.cgdelete_cgroup(cgroup, True) + except error.CmdError: + raise error.TestFail("cgdelete all cgroups in %s failed!" + % self.module) + + + def cgdelete_cgroup(self, cgroup, recursive=False): + """ + Delete desired cgroup. + + @params cgroup: desired cgroup + @params force:If true, sub cgroup can be deleted with parent cgroup + """ + try: + cgroup_pwd = self.__get_cgroup_pwd(cgroup) + if cgroup_pwd not in self.cgroups: + raise error.TestError("%s doesn't exist!" % cgroup) + cmd = "cgdelete %s:%s" % (self.module, cgroup) + if recursive: + cmd += " -r" + utils.run(cmd, ignore_status=False) + self.cgroups.remove(cgroup_pwd) + except error.CmdError, detail: + raise error.TestFail("cgdelete %s failed!\n%s" % + (cgroup, detail)) + + + def cgclassify_cgroup(self, pid, cgroup): + """ + Classify pid into cgroup + + @param pid: pid of the process + @param cgroup: cgroup name + """ + try: + cgroup_pwd = self.__get_cgroup_pwd(cgroup) + if cgroup_pwd not in self.cgroups: + raise error.TestError("%s doesn't exist!" % cgroup) + cgclassify_cmd = ("cgclassify -g %s:%s %d" % + (self.module, cgroup, pid)) + utils.run(cgclassify_cmd, ignore_status=False) + except error.CmdError, detail: + raise error.TestFail("Classify process to tasks file failed!:%s" % + detail) + + + def get_pids(self, pwd=None): + """ + Get all pids in cgroup + + @params: pwd: cgroup directory + @return: all pids(list) + """ + if pwd == None: + pwd = self.root + if isinstance(pwd, int): + pwd = self.cgroups[pwd] + try: + return [_.strip() for _ in open(os.path.join(pwd, 'tasks'), 'r')] + except Exception, inst: + raise error.TestError("cg.get_pids(): %s" % inst) + + + def test(self, cmd): + """ + Executes cgroup_client.py with cmd parameter. + + @param cmd: command to be executed + @return: subprocess.Popen() process + """ + logging.debug("cg.test(): executing paralel process '%s'", cmd) + cmd = self._client + ' ' + cmd + process = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, close_fds=True) + return process + + + def is_cgroup(self, pid, pwd): + """ + Checks if the 'pid' process is in 'pwd' cgroup + @param pid: pid of the process + @param pwd: cgroup directory + @return: 0 when is 'pwd' member + """ + if isinstance(pwd, int): + pwd = self.cgroups[pwd] + if open(os.path.join(pwd, 'tasks')).readlines().count("%d\n" % pid) > 0: + return 0 + else: + return -1 + + + def is_root_cgroup(self, pid): + """ + Checks if the 'pid' process is in root cgroup (WO cgroup) + @param pid: pid of the process + @return: 0 when is 'root' member + """ + return self.is_cgroup(pid, self.root) + + + def set_cgroup(self, pid, pwd=None): + """ + Sets cgroup membership + @param pid: pid of the process + @param pwd: cgroup directory + """ + if pwd is None: + pwd = self.root + if isinstance(pwd, int): + pwd = self.cgroups[pwd] + try: + open(os.path.join(pwd, 'tasks'), 'w').write(str(pid)) + except Exception, inst: + raise error.TestError("cg.set_cgroup(): %s" % inst) + if self.is_cgroup(pid, pwd): + raise error.TestError("cg.set_cgroup(): Setting %d pid into %s " + "cgroup failed" % (pid, pwd)) + + + def set_root_cgroup(self, pid): + """ + Resets the cgroup membership (sets to root) + @param pid: pid of the process + @return: 0 when PASSED + """ + return self.set_cgroup(pid, self.root) + + + def get_property(self, prop, pwd=None): + """ + Gets the property value + @param prop: property name (file) + @param pwd: cgroup directory + @return: [] values or None when FAILED + """ + if pwd is None: + pwd = self.root + if isinstance(pwd, int): + pwd = self.cgroups[pwd] + try: + # Remove tailing '\n' from each line + ret = [_[:-1] for _ in open(os.path.join(pwd, prop), 'r')] + if ret: + return ret + else: + return [""] + except Exception, inst: + raise error.TestError("cg.get_property(): %s" % inst) + + + def set_property_h(self, prop, value, pwd=None, check=True, checkprop=None): + """ + Sets the one-line property value concerning the K,M,G postfix + @param prop: property name (file) + @param value: desired value + @param pwd: cgroup directory + @param check: check the value after setup / override checking value + @param checkprop: override prop when checking the value + """ + _value = value + try: + value = str(value) + human = {'B': 1, + 'K': 1024, + 'M': 1048576, + 'G': 1073741824, + 'T': 1099511627776 + } + if human.has_key(value[-1]): + value = int(value[:-1]) * human[value[-1]] + except Exception: + logging.warn("cg.set_prop() fallback into cg.set_property.") + value = _value + self.set_property(prop, value, pwd, check, checkprop) + + + def set_property(self, prop, value, pwd=None, check=True, checkprop=None): + """ + Sets the property value + @param prop: property name (file) + @param value: desired value + @param pwd: cgroup directory + @param check: check the value after setup / override checking value + @param checkprop: override prop when checking the value + """ + value = str(value) + if pwd is None: + pwd = self.root + if isinstance(pwd, int): + pwd = self.cgroups[pwd] + try: + open(os.path.join(pwd, prop), 'w').write(value) + except Exception, inst: + raise error.TestError("cg.set_property(): %s" % inst) + + if check is not False: + if check is True: + check = value + if checkprop is None: + checkprop = prop + _values = self.get_property(checkprop, pwd) + # Sanitize non printable characters before check + check = " ".join(check.split()) + if check not in _values: + raise error.TestError("cg.set_property(): Setting failed: " + "desired = %s, real values = %s" + % (repr(check), repr(_values))) + + + def cgset_property(self, prop, value, pwd=None, check=True, checkprop=None): + """ + Sets the property value by cgset command + + @param: prop: property name (file) + @param: value: desired value + @param pwd: cgroup directory + @param check: check the value after setup / override checking value + @param checkprop: override prop when checking the value + """ + if pwd is None: + pwd = self.root + if isinstance(pwd, int): + pwd = self.cgroups[pwd] + try: + cgroup = self.get_cgroup_name(pwd) + cgset_cmd = "cgset -r %s='%s' %s" % (prop, value, cgroup) + utils.run(cgset_cmd, ignore_status=False) + except error.CmdError, detail: + raise error.TestFail("Modify %s failed!:\n%s" % (prop, detail)) + + if check is not False: + if check is True: + check = value + if checkprop is None: + checkprop = prop + _values = self.get_property(checkprop, + self.get_cgroup_index(cgroup)) + # Sanitize non printable characters before check + check = " ".join(check.split()) + if check not in _values: + raise error.TestError("cg.set_property(): Setting failed: " + "desired = %s, real values = %s" + % (repr(check), repr(_values))) + + + def smoke_test(self): + """ + Smoke test + Module independent basic tests + """ + pwd = self.mk_cgroup() + + ps = self.test("smoke") + if ps is None: + raise error.TestError("cg.smoke_test: Couldn't create process") + + if (ps.poll() is not None): + raise error.TestError("cg.smoke_test: Process died unexpectidly") + + # New process should be a root member + if self.is_root_cgroup(ps.pid): + raise error.TestError("cg.smoke_test: Process is not a root member") + + # Change the cgroup + self.set_cgroup(ps.pid, pwd) + + # Try to remove used cgroup + try: + self.rm_cgroup(pwd) + except error.TestError: + pass + else: + raise error.TestError("cg.smoke_test: Unexpected successful" + " deletion of the used cgroup") + + # Return the process into the root cgroup + self.set_root_cgroup(ps.pid) + + # It should be safe to remove the cgroup now + self.rm_cgroup(pwd) + + # Finish the process + ps.stdin.write('\n') + time.sleep(2) + if (ps.poll() is None): + raise error.TestError("cg.smoke_test: Process is not finished") + + +class CgroupModules(object): + """ + Handles the list of different cgroup filesystems. + """ + def __init__(self, mountdir=None): + self.modules = [] + self.modules.append([]) + self.modules.append([]) + self.modules.append([]) + if mountdir is None: + self.mountdir = mkdtemp(prefix='cgroup-') + '/' + self.rm_mountdir = True + else: + self.mountdir = mountdir + self.rm_mountdir = False + + + + def __del__(self): + """ + Unmount all cgroups and remove the mountdir + """ + for i in range(len(self.modules[0])): + if self.modules[2][i]: + try: + utils.system('umount %s -l' % self.modules[1][i]) + except Exception, failure_detail: + logging.warn("CGM: Couldn't unmount %s directory: %s", + self.modules[1][i], failure_detail) + try: + if self.rm_mountdir: + # If delete /cgroup/, this action will break cgroup service. + shutil.rmtree(self.mountdir) + except Exception: + logging.warn("CGM: Couldn't remove the %s directory", self.mountdir) + + + def init(self, _modules): + """ + Checks the mounted modules and if necessary mounts them into tmp + mountdir. + @param _modules: Desired modules.'memory','cpu,cpuset'... + @return: Number of initialized modules. + """ + logging.debug("Desired cgroup modules: %s", _modules) + mounts = [] + proc_mounts = open('/proc/mounts', 'r') + line = proc_mounts.readline().split() + while line: + if line[2] == 'cgroup': + mounts.append(line) + line = proc_mounts.readline().split() + proc_mounts.close() + + for module in _modules: + # Is it already mounted? + i = False + _module = set(module.split(',')) + for mount in mounts: + # 'memory' or 'memory,cpuset' + if _module.issubset(mount[3].split(',')): + self.modules[0].append(module) + self.modules[1].append(mount[1] + '/') + self.modules[2].append(False) + i = True + break + if not i: + # Not yet mounted + module_path = os.path.join(self.mountdir, module) + if not os.path.exists(module_path): + os.mkdir(module_path) + cmd = ('mount -t cgroup -o %s %s %s' % + (module, module, module_path)) + try: + utils.run(cmd) + self.modules[0].append(module) + self.modules[1].append(module_path) + self.modules[2].append(True) + except error.CmdError: + logging.info("Cgroup module '%s' not available", module) + + logging.debug("Initialized cgroup modules: %s", self.modules[0]) + return len(self.modules[0]) + + + def get_pwd(self, module): + """ + Returns the mount directory of 'module' + @param module: desired module (memory, ...) + @return: mount directory of 'module' or None + """ + try: + i = self.modules[0].index(module) + except Exception, inst: + logging.error("module %s not found: %s", module, inst) + return None + return self.modules[1][i] + + +def get_load_per_cpu(_stats=None): + """ + Gather load per cpu from /proc/stat + @param _stats: previous values + @return: list of diff/absolute values of CPU times [SUM, CPU1, CPU2, ...] + """ + stats = [] + f_stat = open('/proc/stat', 'r') + if _stats: + for i in range(len(_stats)): + stats.append(int(f_stat.readline().split()[1]) - _stats[i]) + else: + line = f_stat.readline() + while line: + if line.startswith('cpu'): + stats.append(int(line.split()[1])) + else: + break + line = f_stat.readline() + return stats + + +def get_cgroup_mountpoint(controller): + """ + Get desired controller's mountpoint + + @controller: Desired controller + @return: controller's mountpoint + """ + if controller not in get_all_controllers(): + raise error.TestError("Doesn't support controller <%s>" % controller) + f_cgcon = open("/proc/mounts", "rU") + cgconf_txt = f_cgcon.read() + f_cgcon.close() + mntpt = re.findall(r"\s(\S*cgroup/%s)" % controller, cgconf_txt) + return mntpt[0] + + +def get_all_controllers(): + """ + Get all controllers used in system + + @return: all used controllers(controller_list) + """ + try: + result = utils.run("lssubsys", ignore_status=False) + controllers_str = result.stdout.strip() + controller_list = [] + for controller in controllers_str.splitlines(): + controller_sub_list = controller.split(",") + controller_list += controller_sub_list + except error.CmdError: + controller_list = [ 'cpuacct', 'cpu', 'memory', 'cpuset', + 'devices', 'freezer', 'blkio', 'netcls' ] + return controller_list + + +def resolve_task_cgroup_path(pid, controller): + """ + Resolving cgroup mount path of a particular task + + @params: pid : process id of a task for which the cgroup path required + @params: controller: takes one of the controller names in controller list + + @return: resolved path for cgroup controllers of a given pid + """ + if controller not in get_all_controllers(): + raise error.TestError("Doesn't support controller <%s>" % controller) + root_path = get_cgroup_mountpoint(controller) + + proc_cgroup = "/proc/%d/cgroup" % pid + if not os.path.isfile(proc_cgroup): + raise NameError('File %s does not exist\n Check whether cgroup \ + installed in the system' % proc_cgroup) + + try: + proc_file = open(proc_cgroup, 'r') + proc_cgroup_txt = proc_file.read() + finally: + proc_file.close() + + mount_path = re.findall(r":%s:(\S*)\n" % controller, proc_cgroup_txt) + return os.path.join(root_path, mount_path[0]) + + +def service_cgconfig_control(action): + """ + Cgconfig control by action. + + If cmd executes successfully, return True, otherwise return False. + If the action is status, return True when it's running, otherwise return + False. + + @ param action: start|stop|status|restart|condrestart + """ + actions = ['start', 'stop', 'restart', 'condrestart'] + if action in actions: + try: + utils.run("service cgconfig %s" % action) + logging.debug("%s cgconfig successfuly", action) + return True + except error.CmdError, detail: + logging.error("Failed to %s cgconfig:\n%s", action, detail) + return False + elif action == "status": + cmd_result = utils.run("service cgconfig status", ignore_status=True) + if (not cmd_result.exit_status and + cmd_result.stdout.strip()) == "Running": + logging.info("Cgconfig service is running") + return True + else: + return False + else: + raise error.TestError("Unknown action: %s" % action) + + +#Split cgconfig action function, it will be more clear. +def cgconfig_start(): + """ + Stop cgconfig service + """ + return service_cgconfig_control("start") + + +def cgconfig_stop(): + """ + Start cgconfig service + """ + return service_cgconfig_control("stop") + + +def cgconfig_restart(): + """ + Restart cgconfig service + """ + return service_cgconfig_control("restart") + + +def cgconfig_condrestart(): + """ + Condrestart cgconfig service + """ + return service_cgconfig_control("condrestart") + + +def cgconfig_is_running(): + """ + Check cgconfig service status + """ + return service_cgconfig_control("status") + + +def all_cgroup_delete(): + """ + Clear all cgroups in system + """ + try: + utils.run("cgclear", ignore_status=False) + except error.CmdError, detail: + raise error.TestFail("Clear all cgroup failed!:\n%s" % detail) diff --git a/virttest/staging/utils_memory.py b/virttest/staging/utils_memory.py index 07c240131..a9cd28802 100644 --- a/virttest/staging/utils_memory.py +++ b/virttest/staging/utils_memory.py @@ -1,4 +1,4 @@ -import re, glob, math +import re, glob, math, logging from autotest.client import utils diff --git a/virttest/utils_test.py b/virttest/utils_test.py index 95ef78c6f..609417e7e 100644 --- a/virttest/utils_test.py +++ b/virttest/utils_test.py @@ -35,7 +35,7 @@ from autotest.client.shared import utils_cgroup except ImportError: # TODO: Obsoleted path used prior autotest-0.15.2/virttest-2013.06.24 - from virttest import utils_cgroup + from virttest.staging import utils_cgroup try: from autotest.client.shared import utils_memory @@ -1449,7 +1449,7 @@ def get_memory_info(lvms): meminfo = "Host: memfree = " meminfo += str(int(utils_memory.freememtotal()) / 1024) + "M; " meminfo += "swapfree = " - mf = int(utils_system.read_from_meminfo("SwapFree")) / 1024 + mf = int(utils_memory.read_from_meminfo("SwapFree")) / 1024 meminfo += str(mf) + "M; " except Exception, e: raise error.TestFail("Could not fetch host free memory info, " From ffdf619cf817f5788c743ad3a118a2a07807eba8 Mon Sep 17 00:00:00 2001 From: Lucas Meneghel Rodrigues <lmr@redhat.com> Date: Tue, 6 Aug 2013 15:10:14 -0300 Subject: [PATCH 206/254] cgroup: Add CgconfigService class In order to make it more convenient to start/stop the service cgconfig, create a specialized class, built on top of the service API. Signed-off-by: Li Yang <liyang.fnst@cn.fujitsu.com> Signed-off-by: Lucas Meneghel Rodrigues <lmr@redhat.com> --- virttest/staging/service.py | 787 +++++++++++++++++++++++++++++++ virttest/staging/utils_cgroup.py | 101 ++-- 2 files changed, 836 insertions(+), 52 deletions(-) create mode 100644 virttest/staging/service.py diff --git a/virttest/staging/service.py b/virttest/staging/service.py new file mode 100644 index 000000000..e88eb05bb --- /dev/null +++ b/virttest/staging/service.py @@ -0,0 +1,787 @@ +# Copyright(c) 2013 Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# +# The full GNU General Public License is included in this distribution in +# the file called "COPYING". + +import os +import re +import logging + +import common +import error +from tempfile import mktemp +from autotest.client import utils + + +_COMMAND_TABLE_DOC = """ + +Taken from http://fedoraproject.org/wiki/SysVinit_to_Systemd_Cheatsheet + +service frobozz start +systemctl start frobozz.service + Used to start a service (not reboot persistent) + +service frobozz stop +systemctl stop frobozz.service + Used to stop a service (not reboot persistent) + +service frobozz restart +systemctl restart frobozz.service + Used to stop and then start a service + +service frobozz reload +systemctl reload frobozz.service + When supported, reloads the config file without interrupting pending operations. + +service frobozz condrestart +systemctl condrestart frobozz.service + Restarts if the service is already running. + +service frobozz status +systemctl status frobozz.service + Tells whether a service is currently running. + +ls /etc/rc.d/init.d/ +systemctl list-unit-files --type=service (preferred) + Used to list the services that can be started or stopped +ls /lib/systemd/system/*.service /etc/systemd/system/*.service + Used to list all the services and other units + +chkconfig frobozz on +systemctl enable frobozz.service + Turn the service on, for start at next boot, or other trigger. + +chkconfig frobozz off +systemctl disable frobozz.service + Turn the service off for the next reboot, or any other trigger. + +chkconfig frobozz +systemctl is-enabled frobozz.service + Used to check whether a service is configured to start or not in the current environment. + +chkconfig --list +systemctl list-unit-files --type=service(preferred) +ls /etc/systemd/system/*.wants/ + Print a table of services that lists which runlevels each is configured on or off + +chkconfig frobozz --list +ls /etc/systemd/system/*.wants/frobozz.service + Used to list what levels this service is configured on or off + +chkconfig frobozz --add +systemctl daemon-reload + Used when you create a new service file or modify any configuration + + +""" + + +def sys_v_init_result_parser(command): + """ + Parse results from sys_v style commands. + + :param command: command. + :type command: str. + :return: different from the command. + command is status: return true if service is running. + command is is_enabled: return true if service is enalbled. + command is list: return a dict from service name to status. + command is others: return true if operate success. + """ + if command == "status": + def method(cmdResult): + """ + Parse method for service XXX status. + + Returns True if XXX is running. + Returns False if XXX is stopped. + Returns None if XXX is unrecognized. + """ + # If service is stopped, exit_status is also not zero. + # So, we can't use exit_status to check result. + output = cmdResult.stdout.lower() + # Returns None if XXX is unrecognized. + if re.search(r"unrecognized", output): + return None + # Returns False if XXX is stopped. + dead_flags = [r"stopped", r"not running", r"dead"] + for flag in dead_flags: + if re.search(flag, output): + return False + # If output does not contain a dead flag, check it with "running". + return bool(re.search(r"running", output)) + return method + elif command == "list": + def method(cmdResult): + """ + Parse method for service XXX list. + + Return dict from service name to status. + + e.g: + {"sshd": {0: 'off', 1: 'off', 2: 'off', 3: 'off', 4: 'off', 5: 'off', 6: 'off'}, + "vsftpd": {0: 'off', 1: 'off', 2: 'off', 3: 'off', 4: 'off', 5: 'off', 6: 'off'}, + "xinetd": {'discard-dgram:': 'off', 'rsync:': 'off'...'chargen-stream:': 'off'}, + ... + } + """ + if cmdResult.exit_status: + raise error.CmdError(cmdResult.command, cmdResult) + # The final dict to return. + _service2statusOnTarget_dict = {} + # Dict to store status on every target for each service. + _status_on_target = {} + # Dict to store the status for service based on xinetd. + _service2statusOnXinet_dict = {} + lines = cmdResult.stdout.strip().splitlines() + for line in lines: + sublines = line.strip().split() + if len(sublines) == 8: + # Service and status on each target. + service_name = sublines[0] + # Store the status of each target in _status_on_target. + for target in range(7): + status = sublines[target + 1].split(":")[-1] + _status_on_target[target] = status + _service2statusOnTarget_dict[service_name] = _status_on_target.copy() + + elif len(sublines) == 2: + # Service based on xinetd. + service_name = sublines[0].strip(":") + status = sublines[-1] + _service2statusOnXinet_dict[service_name] = status + + else: + # Header or some lines useless. + continue + # Add xinetd based service in the main dict. + _service2statusOnTarget_dict["xinetd"] = _service2statusOnXinet_dict + return _service2statusOnTarget_dict + return method + else: + return _ServiceResultParser.default_method + + +def systemd_result_parser(command): + """ + Parse results from systemd style commands. + + :param command: command. + :type command: str. + :return: different from the command. + command is status: return true if service is running. + command is is_enabled: return true if service is enalbled. + command is list: return a dict from service name to status. + command is others: return true if operate success. + """ + if command == "status": + def method(cmdResult): + """ + Parse method for systemctl status XXX.service. + + Returns True if XXX.service is running. + Returns False if XXX.service is stopped. + Returns None if XXX.service is not loaded. + """ + # If service is stopped, exit_status is also not zero. + # So, we can't use exit_status to check result. + output = cmdResult.stdout + # Returns None if XXX is not loaded. + if not re.search(r"Loaded: loaded", output): + return None + # Check it with Active status. + return (output.count("Active: active") > 0) + return method + elif command == "list": + def method(cmdResult): + """ + Parse method for systemctl list XXX.service. + + Return a dict from service name to status. + + e.g: + {"sshd": "enabled", + "vsftpd": "disabled", + "systemd-sysctl": "static", + ... + } + """ + if cmdResult.exit_status: + raise error.CmdError(cmdResult.command, cmdResult) + # Dict to store service name to status. + _service2status_dict = {} + lines = cmdResult.stdout.strip().splitlines() + for line in lines: + sublines = line.strip().split() + if (not len(sublines) == 2) or (not sublines[0].endswith("service")): + # Some lines useless. + continue + service_name = sublines[0].rstrip(".service") + status = sublines[-1] + _service2status_dict[service_name] = status + return _service2status_dict + return method + else: + return _ServiceResultParser.default_method + + +def sys_v_init_command_generator(command): + """ + Generate lists of command arguments for sys_v style inits. + + :param command: start,stop,restart, etc. + :type command: str + :return: list of commands to pass to utils.run or similar function + :rtype: list + """ + command_name = "service" + if command == "is_enabled": + command_name = "chkconfig" + command = "" + elif command == 'enable': + command_name = "chkconfig" + command = "on" + elif command == 'disable': + command_name = "chkconfig" + command = "off" + elif command == 'list': + # noinspection PyUnusedLocal + def list_command(service_name): + return ["chkconfig", "--list"] + return list_command + elif command == "set_target": + def set_target_command(target): + target = convert_systemd_target_to_runlevel(target) + return ["telinit", target] + return set_target_command + + def method(service_name): + return [command_name, service_name, command] + return method + + +def systemd_command_generator(command): + """ + Generate list of command line argument strings for systemctl. + One argument per string for compatibility Popen + + WARNING: If systemctl detects that it is running on a tty it will use color, + pipe to $PAGER, change column sizes and not truncate unit names. + Use --no-pager to suppress pager output, or set PAGER=cat in the environment. + You may need to take other steps to suppress color output. + See https://bugzilla.redhat.com/show_bug.cgi?id=713567 + + :param command: start,stop,restart, etc. + :type command: str + :return: list of command and arguments to pass to utils.run or similar functions + :rtype: list + """ + command_name = "systemctl" + if command == "is_enabled": + command = "is-enabled" + elif command == "list": + # noinspection PyUnusedLocal + def list_command(service_name): + # systemctl pipes to `less` or $PAGER by default. Workaround this + # add '--full' to avoid systemctl truncates service names. + return [command_name, "list-unit-files", + "--type=service", "--no-pager", "--full"] + return list_command + elif command == "set_target": + def set_target_command(target): + return [command_name, "isolate", target] + return set_target_command + + def method(service_name): + return [command_name, command, "%s.service" % service_name] + return method + + +COMMANDS = ( + "start", + "stop", + "reload", + "restart", + "condrestart", + "status", + "enable", + "disable", + "is_enabled", + "list", + "set_target", +) + + +class _ServiceResultParser(object): + """ + A class that contains staticmethods to parse the result of service command. + """ + + def __init__(self, result_parser, command_list=COMMANDS): + """ + Create staticmethods for each command in command_list using setattr and the + result_parser + + :param result_parser: function that generates functions that parse the result of command. + :type result_parser: function + :param command_list: list of all the commands, e.g. start, stop, restart, etc. + :type command_list: list + """ + self.commands = command_list + for command in self.commands: + setattr(self, command, result_parser(command)) + + @staticmethod + def default_method(cmdResult): + """ + Default method to parse result from command which is not 'list' nor 'status'. + + Returns True if command was executed successfully. + """ + if cmdResult.exit_status: + logging.debug(cmdResult) + return False + else: + return True + + +class _ServiceCommandGenerator(object): + """ + A class that contains staticmethods that generate partial functions that + generate command lists for starting/stopping services. + """ + + def __init__(self, command_generator, command_list=COMMANDS): + """ + Create staticmethods for each command in command_list using setattr and the + command_generator + + :param command_generator: function that generates functions that generate lists of command strings + :type command_generator: function + :param command_list: list of all the commands, e.g. start, stop, restart, etc. + :type command_list: list + """ + self.commands = command_list + for command in self.commands: + setattr(self, command, command_generator(command)) + + +def _get_name_of_init(run=utils.run): + """ + Internal function to determine what executable is PID 1, + aka init by checking /proc/1/exe + :return: executable name for PID 1, aka init + :rtype: str + """ + # /proc/1/comm was added in 2.6.33 and is not in RHEL6.x, so use cmdline + # Non-root can read cmdline + # return os.path.basename(open("/proc/1/cmdline").read().split(chr(0))[0]) + # readlink /proc/1/exe requires root + # inspired by openvswitch.py:ServiceManagerInterface.get_version() + output = run("readlink /proc/1/exe").stdout.strip() + return os.path.basename(output) + + +def get_name_of_init(run=utils.run): + """ + Determine what executable is PID 1, aka init by checking /proc/1/exe + This init detection will only run once and cache the return value. + + :return: executable name for PID 1, aka init + :rtype: str + """ + # _init_name is explicitly undefined so that we get the NameError on first access + # pylint: disable=W0601 + global _init_name + try: + return _init_name + except (NameError, AttributeError): + _init_name = _get_name_of_init(run) + return _init_name + + +class _SpecificServiceManager(object): + + def __init__(self, service_name, service_command_generator, service_result_parser, run=utils.run): + """ + Create staticmethods that call utils.run with the given service_name + for each command in service_command_generator. + + lldpad = SpecificServiceManager("lldpad", + auto_create_specific_service_command_generator()) + lldpad.start() + lldpad.stop() + + :param service_name: init service name or systemd unit name + :type service_name: str + :param service_command_generator: a sys_v_init or systemd command generator + :type service_command_generator: _ServiceCommandGenerator + :param run: function that executes the commands and return CmdResult object, default utils.run + :type run: function + """ + for cmd in service_command_generator.commands: + setattr(self, cmd, + self.generate_run_function(run, + getattr(service_result_parser, cmd), + getattr(service_command_generator, cmd), + service_name)) + + @staticmethod + def generate_run_function(run_func, parse_func, command, service_name): + """ + Generate the wrapped call to utils.run for the given service_name. + + :param run_func: function to execute command and return CmdResult object. + :type run_func: function + :param parse_func: function to parse the result from run. + :type parse_func: function + :param command: partial function that generates the command list + :type command: function + :param service_name: init service name or systemd unit name + :type service_name: str + :return: wrapped utils.run function. + :rtype: function + """ + def run(**kwargs): + """ + Wrapped utils.run invocation that will start, stop, restart, etc. a service. + + :param kwargs: extra arguments to utils.run, .e.g. timeout. But not for ignore_status. + We need a CmdResult to parse and raise a error.TestError if command failed. + We will not let the CmdError out. + :return: result of parse_func. + """ + # If run_func is utils.run by default, we need to set + # ignore_status = True. Otherwise, skip this setting. + if run_func is utils.run: + logging.debug("Setting ignore_status to True.") + kwargs["ignore_status"] = True + result = run_func(" ".join(command(service_name)), **kwargs) + return parse_func(result) + return run + + +class _GenericServiceManager(object): + """ + Base class for SysVInitServiceManager and SystemdServiceManager. + """ + + def __init__(self, service_command_generator, service_result_parser, run=utils.run): + """ + Create staticmethods for each service command, e.g. start, stop, restart. + These staticmethods take as an argument the service to be started or stopped. + + systemd = SpecificServiceManager(auto_create_specific_service_command_generator()) + systemd.start("lldpad") + systemd.stop("lldpad") + + :param service_command_generator: a sys_v_init or systemd command generator + :type service_command_generator: _ServiceCommandGenerator + :param run: function to call the run the commands, default utils.run + :type run: function + """ + #### create staticmethods in class attributes (not used) + # for cmd in service_command_generator.commands: + # setattr(self.__class__, cmd, + # staticmethod(self.generate_run_function(run, getattr(service_command_generator, cmd)))) + #### create functions in instance attributes + for cmd in service_command_generator.commands: + setattr(self, cmd, + self.generate_run_function(run, + getattr(service_result_parser, cmd), + getattr(service_command_generator, cmd))) + + @staticmethod + def generate_run_function(run_func, parse_func, command): + """ + Generate the wrapped call to utils.run for the service command, "service" or "systemctl" + + :param run_func: utils.run + :type run_func: function + :param command: partial function that generates the command list + :type command: function + :return: wrapped utils.run function. + :rtype: function + """ + def run(service="", **kwargs): + """ + Wrapped utils.run invocation that will start, stop, restart, etc. a service. + + :param service: service name, e.g. crond, dbus, etc. + :param kwargs: extra arguments to utils.run, .e.g. timeout. But not for ignore_status. + We need a CmdResult to parse and raise a error.TestError if command failed. + We will not let the CmdError out. + :return: result of parse_func. + """ + # If run_func is utils.run by default, we need to set + # ignore_status = True. Otherwise, skip this setting. + if run_func is utils.run: + logging.debug("Setting ignore_status to True.") + kwargs["ignore_status"] = True + result = run_func(" ".join(command(service)), **kwargs) + return parse_func(result) + return run + + +class _SysVInitServiceManager(_GenericServiceManager): + """ + Concrete class that implements the SysVInitServiceManager + """ + + def __init__(self, service_command_generator, service_result_parser, run=utils.run): + """ + Create the GenericServiceManager for SysV services. + + :param service_command_generator: + :type service_command_generator: _ServiceCommandGenerator + :param run: function to call to run the commands, default utils.run + :type run: function + """ + super(_SysVInitServiceManager, self).__init__(service_command_generator, + service_result_parser, run) + + # @staticmethod + # def change_default_runlevel(runlevel='3'): + # """ + # Set the default sys_v runlevel + # + # :param runlevel: sys_v runlevel to set as default in inittab + # :type runlevel: str + # """ + # raise NotImplemented + + +def convert_sysv_runlevel(level): + """ + Convert runlevel to systemd target. + + :param level: sys_v runlevel + :type level: str or int + :return: systemd target + :rtype: str + :raise ValueError: when runlevel is unknown + """ + runlevel = str(level) + if runlevel == '0': + target = "poweroff.target" + elif runlevel in ['1', "s", "single"]: + target = "rescue.target" + elif runlevel in ['2', '3', '4']: + target = "multi-user.target" + elif runlevel == '5': + target = "graphical.target" + elif runlevel == '6': + target = "reboot.target" + else: + raise ValueError("unknown runlevel %s" % level) + return target + + +def convert_systemd_target_to_runlevel(target): + """ + Convert systemd target to runlevel. + + :param target: systemd target + :type target: str + :return: sys_v runlevel + :rtype: str + :raise ValueError: when systemd target is unknown + """ + if target == "poweroff.target": + runlevel = '0' + elif target == "rescue.target": + runlevel = 's' + elif target == "multi-user.target": + runlevel = '3' + elif target == "graphical.target": + runlevel = '5' + elif target == "reboot.target": + runlevel = '6' + else: + raise ValueError("unknown target %s" % target) + return runlevel + + +class _SystemdServiceManager(_GenericServiceManager): + """ + Concrete class that implements the SystemdServiceManager + """ + + def __init__(self, service_command_generator, service_result_parser, run=utils.run): + """ + Create the GenericServiceManager for systemd services. + + :param service_command_generator: + :type service_command_generator: _ServiceCommandGenerator + :param run: function to call to run the commands, default utils.run + :type run: function + """ + super(_SystemdServiceManager, self).__init__(service_command_generator, + service_result_parser, run) + + @staticmethod + def change_default_runlevel(runlevel='multi-user.target'): + # atomic symlinking, symlink and then rename + """ + Set the default systemd target. + Create the symlink in a temp directory and then use + atomic rename to move the symlink into place. + + :param runlevel: default systemd target + :type runlevel: str + """ + tmp_symlink = mktemp(dir="/etc/systemd/system") + os.symlink("/usr/lib/systemd/system/%s" % runlevel, tmp_symlink) + os.rename(tmp_symlink, "/etc/systemd/system/default.target") + + +_command_generators = {"init": sys_v_init_command_generator, + "systemd": systemd_command_generator} + +_result_parsers = {"init": sys_v_init_result_parser, + "systemd": systemd_result_parser} + +_service_managers = {"init": _SysVInitServiceManager, + "systemd": _SystemdServiceManager} + + +def _get_service_result_parser(run=utils.run): + """ + Get the ServiceResultParser using the auto-detect init command. + + :return: ServiceResultParser fro the current init command. + :rtype: _ServiceResultParser + """ + # pylint: disable=W0601 + global _service_result_parser + try: + return _service_result_parser + except NameError: + result_parser = _result_parsers[get_name_of_init(run)] + _service_result_parser = _ServiceResultParser(result_parser) + return _service_result_parser + + +def _get_service_command_generator(run=utils.run): + """ + Lazy initializer for ServiceCommandGenerator using the auto-detect init command. + + :return: ServiceCommandGenerator for the current init command. + :rtype: _ServiceCommandGenerator + """ + # _service_command_generator is explicitly undefined so that we get the NameError on first access + # pylint: disable=W0601 + global _service_command_generator + try: + return _service_command_generator + except NameError: + command_generator = _command_generators[get_name_of_init(run)] + _service_command_generator = _ServiceCommandGenerator( + command_generator) + return _service_command_generator + + +def ServiceManager(run=utils.run): + """ + Detect which init program is being used, init or systemd and return a + class has methods to start/stop services. + + # Get the system service manager + service_manager = ServiceManager() + + # Stating service/unit "sshd" + service_manager.start("sshd") + + # Getting a list of available units + units = service_manager.list() + + # Disabling and stopping a list of services + services_to_disable = ['ntpd', 'httpd'] + for s in services_to_disable: + service_manager.disable(s) + service_manager.stop(s) + + :return: SysVInitServiceManager or SystemdServiceManager + :rtype: _GenericServiceManager + """ + service_manager = _service_managers[get_name_of_init(run)] + # _service_command_generator is explicitly undefined so that we get the NameError on first access + # pylint: disable=W0601 + global _service_manager + try: + return _service_manager + except NameError: + _service_manager = service_manager(_get_service_command_generator(run), + _get_service_result_parser(run)) + return _service_manager + + +def _auto_create_specific_service_result_parser(run=utils.run): + """ + Create a class that will create partial functions that generate result_parser + for the current init command. + + :return: A ServiceResultParser for the auto-detected init command. + :rtype: _ServiceResultParser + """ + result_parser = _result_parsers[get_name_of_init(run)] + # remove list method + command_list = [c for c in COMMANDS if c not in ["list", "set_target"]] + return _ServiceResultParser(result_parser, command_list) + + +def _auto_create_specific_service_command_generator(run=utils.run): + """ + Create a class that will create partial functions that generate commands + for the current init command. + + lldpad = SpecificServiceManager("lldpad", + auto_create_specific_service_command_generator()) + lldpad.start() + lldpad.stop() + + :return: A ServiceCommandGenerator for the auto-detected init command. + :rtype: _ServiceCommandGenerator + """ + command_generator = _command_generators[get_name_of_init(run)] + # remove list method + command_list = [c for c in COMMANDS if c not in ["list", "set_target"]] + return _ServiceCommandGenerator(command_generator, command_list) + + +def SpecificServiceManager(service_name, run=utils.run): + """ + + # Get the specific service manager for sshd + sshd = SpecificServiceManager("sshd") + sshd.start() + sshd.stop() + sshd.reload() + sshd.restart() + sshd.condrestart() + sshd.status() + sshd.enable() + sshd.disable() + sshd.is_enabled() + + :param service_name: systemd unit or init.d service to manager + :type service_name: str + :return: SpecificServiceManager that has start/stop methods + :rtype: _SpecificServiceManager + """ + return _SpecificServiceManager(service_name, + _auto_create_specific_service_command_generator(run), + _get_service_result_parser(run), run) diff --git a/virttest/staging/utils_cgroup.py b/virttest/staging/utils_cgroup.py index 28761cac4..361279f38 100755 --- a/virttest/staging/utils_cgroup.py +++ b/virttest/staging/utils_cgroup.py @@ -11,6 +11,12 @@ from autotest.client import utils from autotest.client.shared import error +try: + from autotest.client.shared import service +except ImportError: + import service + + class Cgroup(object): """ Cgroup handling class. @@ -679,71 +685,62 @@ def resolve_task_cgroup_path(pid, controller): return os.path.join(root_path, mount_path[0]) -def service_cgconfig_control(action): +class CgconfigService(object): """ - Cgconfig control by action. + Cgconfig service class. + """ + def __init__(self): + self._service_manager = service.SpecificServiceManager("cgconfig") - If cmd executes successfully, return True, otherwise return False. - If the action is status, return True when it's running, otherwise return - False. - @ param action: start|stop|status|restart|condrestart - """ - actions = ['start', 'stop', 'restart', 'condrestart'] - if action in actions: - try: - utils.run("service cgconfig %s" % action) - logging.debug("%s cgconfig successfuly", action) - return True - except error.CmdError, detail: - logging.error("Failed to %s cgconfig:\n%s", action, detail) - return False - elif action == "status": - cmd_result = utils.run("service cgconfig status", ignore_status=True) - if (not cmd_result.exit_status and - cmd_result.stdout.strip()) == "Running": - logging.info("Cgconfig service is running") - return True - else: - return False - else: - raise error.TestError("Unknown action: %s" % action) + def _service_cgconfig_control(self, action): + """ + Cgconfig control by action. + If cmd executes successfully, return True, otherwise return False. + If the action is status, return True when it's running, otherwise return + False. -#Split cgconfig action function, it will be more clear. -def cgconfig_start(): - """ - Stop cgconfig service - """ - return service_cgconfig_control("start") + @param: action: cgconfig service action + """ + if not hasattr(self._service_manager, action): + raise error.TestError("Unknown action: %s" % action) + return getattr(self._service_manager, action)() -def cgconfig_stop(): - """ - Start cgconfig service - """ - return service_cgconfig_control("stop") + def cgconfig_start(self): + """ + Sart cgconfig service + """ + return self._service_cgconfig_control("start") -def cgconfig_restart(): - """ - Restart cgconfig service - """ - return service_cgconfig_control("restart") + def cgconfig_stop(self): + """ + Sop cgconfig service + """ + return self._service_cgconfig_control("stop") -def cgconfig_condrestart(): - """ - Condrestart cgconfig service - """ - return service_cgconfig_control("condrestart") + def cgconfig_restart(self): + """ + Restart cgconfig service + """ + return self._service_cgconfig_control("restart") -def cgconfig_is_running(): - """ - Check cgconfig service status - """ - return service_cgconfig_control("status") + def cgconfig_condrestart(self): + """ + Condrestart cgconfig service + """ + return self._service_cgconfig_control("condrestart") + + + def cgconfig_is_running(self): + """ + Check cgconfig service status + """ + return self._service_cgconfig_control("status") def all_cgroup_delete(): From ff9c6783e92aeb3678fd44443a2709b070d1f66b Mon Sep 17 00:00:00 2001 From: Eduardo Habkost <ehabkost@redhat.com> Date: Fri, 2 Aug 2013 11:40:30 -0300 Subject: [PATCH 207/254] qemu_vm: don't hide TestNAError exceptions We have some code to automatically raise TestNAError (a "SKIP" test result) if a QEMU feature is missing. But that code is being rendered useless by a catch-all exception handling block around the make_create_command() call. Fix this by not hiding TestNAError exceptions from the caller. Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- virttest/qemu_vm.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/virttest/qemu_vm.py b/virttest/qemu_vm.py index b9ba36266..976b8b8f4 100644 --- a/virttest/qemu_vm.py +++ b/virttest/qemu_vm.py @@ -2245,6 +2245,10 @@ def create(self, name=None, params=None, root_dir=None, logging.debug(self.devices.str_short()) logging.debug(self.devices.str_bus_short()) qemu_command = self.devices.cmdline() + except error.TestNAError: + # TestNAErrors should be kept as-is so we generate SKIP + # results instead of bogus FAIL results + raise except Exception: for nic in self.virtnet: self._nic_tap_remove_helper(nic) From 9119da30806cc1ce921a60af90263b9264e3ced1 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost <ehabkost@redhat.com> Date: Mon, 5 Aug 2013 08:54:01 -0300 Subject: [PATCH 208/254] .gitignore: add cpuid_test_kernel binary Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 701f02fd5..f9d09bd06 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ *.so .settings shared/data +shared/deps/cpuid_test_kernel/cpuid_dump_kernel.bin qemu/env logs qemu/unittests From 4e1e0613e9b301c9ab256bb257de8520bad8e342 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost <ehabkost@redhat.com> Date: Mon, 5 Aug 2013 10:50:02 -0300 Subject: [PATCH 209/254] qemu_vm: add comma before CPU flags if necessary Instead of strictly requiring cpu_model_flags to start with ",", add the comma if necessary. The commit that changed the code to always require commas broke most of the "qemu_cpu" test cases. This should make them work again. Cc: Xiaoqing Wei <xwei@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- virttest/qemu_vm.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/virttest/qemu_vm.py b/virttest/qemu_vm.py index 976b8b8f4..97463ad9a 100644 --- a/virttest/qemu_vm.py +++ b/virttest/qemu_vm.py @@ -1164,6 +1164,8 @@ def add_cpu_flags(devices, cpu_model, flags=None, vendor_id=None, if vendor_id: cmd += ",vendor=\"%s\"" % vendor_id if flags: + if not flags.startswith(","): + cmd += "," cmd += "%s" % flags if family is not None: cmd += ",family=%s" % family From 47d77a4c16ddc67ec633737a9b3043a62de53e80 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost <ehabkost@redhat.com> Date: Fri, 2 Aug 2013 11:36:14 -0300 Subject: [PATCH 210/254] qemu_cpu.cfg: create named variants for multiple QEMU versions Keep only the "unknown QEMU version" variant enabled, but allow people to enable other variants if desired. Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- qemu/tests/cfg/qemu_cpu.cfg | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/qemu/tests/cfg/qemu_cpu.cfg b/qemu/tests/cfg/qemu_cpu.cfg index 64e9c4982..3c785c38e 100644 --- a/qemu/tests/cfg/qemu_cpu.cfg +++ b/qemu/tests/cfg/qemu_cpu.cfg @@ -9,15 +9,28 @@ auto_cpu_model = no # QEMU versions: - variants: - - unknown_qemu: - - rhel64: - - qemu13: + variants qemu_flavor: + - @unknown: + - rhel: + variants rhel_version: + - 6_0: + - 6_1: + - 6_2: + - 6_3: + - 6_4: + - upstream: + variants qemu_version: + - 1_0: + - 1_1: + - 1_2: + - 1_3: + - 1_4: + - 1_5: # uncomment the line corresponding to the QEMU version, if you know it: - only unknown_qemu - #only rhel64 - #only qemu13 + only (qemu_flavor = unknown) + #only (qemu_flavor = rhel).(rhel_version = 6_4) + #only (qemu_flavor = upstream).(qemu_version = 1_5) # CPU model lists: variants: @@ -76,10 +89,10 @@ - Opteron_G5: cpu_model = "Opteron_G5" - cpu64_rhel6: - only rhel64 + only (qemu_flavor = rhel) cpu_model = "cpu64-rhel6" - cpu64_rhel4: - only rhel64 + only (qemu_flavor = rhel) cpu_model = "cpu64-rhel5" variants: @@ -96,7 +109,7 @@ only nokvm # we don't know if all models will be available if QEMU # version is unknown: - no unknown_qemu + no (qemu_flavor = unknown) # CPUID data tests: - cpuid: # 486 is excluded due to not supporting cpuid @@ -116,7 +129,7 @@ nokvm: # we don't know if all models will be available if QEMU # version is unknown: - no unknown_qemu + no (qemu_flavor = unknown) only cpu.intel cpu.amd cpu.intel: vendor = "GenuineIntel" From b5189cf970963d07f346d32386c0eba42fe0237a Mon Sep 17 00:00:00 2001 From: Eduardo Habkost <ehabkost@redhat.com> Date: Fri, 2 Aug 2013 11:37:09 -0300 Subject: [PATCH 211/254] cpuid: convenience functions for logging Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- qemu/tests/cpuid.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/qemu/tests/cpuid.py b/qemu/tests/cpuid.py index ce869f3cc..1f7799912 100644 --- a/qemu/tests/cpuid.py +++ b/qemu/tests/cpuid.py @@ -1,11 +1,15 @@ """ Group of cpuid tests for X86 CPU """ -import logging, re, sys, traceback, os, string +import re, sys, traceback, os, string from autotest.client.shared import error, utils from autotest.client.shared import test as test_module from virttest import utils_misc, env_process +import logging +logger = logging.getLogger(__name__) +dbg = logger.debug +info = logger.info def run_cpuid(test, params, env): """ From b8760fb43b63c771a532ae4f4447e65b2f66600a Mon Sep 17 00:00:00 2001 From: Eduardo Habkost <ehabkost@redhat.com> Date: Fri, 2 Aug 2013 11:38:38 -0300 Subject: [PATCH 212/254] cpuid: always parse and convert CPUID dump to a dictionary This will make it easier to analyze the CPUID dump data. Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- qemu/tests/cpuid.py | 112 +++++++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 48 deletions(-) diff --git a/qemu/tests/cpuid.py b/qemu/tests/cpuid.py index 1f7799912..50332a249 100644 --- a/qemu/tests/cpuid.py +++ b/qemu/tests/cpuid.py @@ -117,6 +117,46 @@ def test(self): if added: logging.info("Extra CPU models in QEMU CPU listing: %s", added) + def compare_cpuid_output(a, b): + """ + Generates a list of (register, bit, va, vb) tuples for + each bit that is different between a and b. + """ + for reg in ('eax', 'ebx', 'ecx', 'edx'): + for bit in range(32): + ba = (a[reg] & (1 << bit)) >> bit + bb = (b[reg] & (1 << bit)) >> bit + if ba <> bb: + yield (reg, bit, ba, bb) + + def parse_cpuid_dump(output): + dbg("parsing cpuid dump: %r", output) + cpuid_re = re.compile("^ *(0x[0-9a-f]+) +0x([0-9a-f]+): +eax=0x([0-9a-f]+) ebx=0x([0-9a-f]+) ecx=0x([0-9a-f]+) edx=0x([0-9a-f]+)$") + out_lines = output.splitlines() + if out_lines[0] <> '==START TEST==' or out_lines[-1] <> '==END TEST==': + dbg("cpuid dump doesn't have expected delimiters") + return None + if out_lines[1] <> 'CPU:': + dbg("cpuid dump doesn't start with 'CPU:' line") + return None + result = {} + for l in out_lines[2:-1]: + m = cpuid_re.match(l) + if m is None: + dbg("invalid cpuid dump line: %r", l) + return None + in_eax = int(m.group(1), 16) + in_ecx = int(m.group(2), 16) + out = { + 'eax':int(m.group(3), 16), + 'ebx':int(m.group(4), 16), + 'ecx':int(m.group(5), 16), + 'edx':int(m.group(6), 16), + } + result[(in_eax, in_ecx)] = out + return result + + def get_guest_cpuid(self, cpu_model, feature=None): test_kernel_dir = os.path.join(test.virtdir, "deps", "cpuid_test_kernel") @@ -141,39 +181,15 @@ def get_guest_cpuid(self, cpu_model, feature=None): if not utils_misc.wait_for(f, timeout, 1): raise error.TestFail("Could not get test complete message.") - test_sig = re.compile("==START TEST==\n((?:.*\n)*)\n*==END TEST==") - test_output = test_sig.search(vm.serial_console.get_output()) - if test_output == None: + test_output = parse_cpuid_dump(vm.serial_console.get_output()) + if test_output is None: raise error.TestFail("Test output signature not found in " "output:\n %s", vm.serial_console.get_output()) self.clean() - return test_output.group(1) - - def cpuid_regs_to_dic(level_count, cpuid_dump): - """ - @param level_count: is CPUID level and count string in format - 'LEVEL COUNT', where: - LEVEL - CPUID level in hex format - 8 chracters width - COUNT - input ECX value of cpuid in - hex format 2 charaters width - example: '0x00000001 0x00' - @cpuid_dump: string: output of 'cpuid' utility or provided with - this test simple kernel that dumps cpuid - in a similar format. - @return: dictionary of register values indexed by register name - """ - grp = '\w*=(\w*)\s*' - regs = re.search('\s+%s:.*%s%s%s%s' % (level_count, grp, grp, grp, grp), - cpuid_dump) - if regs == None: - raise error.TestFail("Could not find %s in cpuid output:\n%s", - level_count, cpuid_dump) - return {'eax': int(regs.group(1), 16), 'ebx': int(regs.group(2), 16), - 'ecx': int(regs.group(3), 16), 'edx': int(regs.group(4), 16) } + return test_output def cpuid_to_vendor(cpuid_dump, idx): - r = cpuid_regs_to_dic(idx + ' 0x00', cpuid_dump) + r = cpuid_dump[idx, 0] dst = [] map(lambda i: dst.append((chr(r['ebx'] >> (8 * i) & 0xff))), range(0, 4)) @@ -202,7 +218,7 @@ def test(self): for cpu_model in cpu_models: out = get_guest_cpuid(self, cpu_model) - guest_vendor = cpuid_to_vendor(out, '0x00000000') + guest_vendor = cpuid_to_vendor(out, 0x00000000) logging.debug("Guest's vendor: " + guest_vendor) if guest_vendor != vendor: raise error.TestFail("Guest vendor [%s], doesn't match " @@ -219,8 +235,8 @@ def test(self): try: out = get_guest_cpuid(self, cpu_model, "vendor=" + vendor) - guest_vendor0 = cpuid_to_vendor(out, '0x00000000') - guest_vendor80000000 = cpuid_to_vendor(out, '0x80000000') + guest_vendor0 = cpuid_to_vendor(out, 0x00000000) + guest_vendor80000000 = cpuid_to_vendor(out, 0x80000000) logging.debug("Guest's vendor[0]: " + guest_vendor0) logging.debug("Guest's vendor[0x80000000]: " + guest_vendor80000000) @@ -242,7 +258,7 @@ def test(self): raise error.TestFail("Test was expected to fail, but it didn't") def cpuid_to_level(cpuid_dump): - r = cpuid_regs_to_dic('0x00000000 0x00', cpuid_dump) + r = cpuid_dump[0, 0] return r['eax'] class custom_level(MiniSubtest): @@ -270,7 +286,7 @@ def cpuid_to_family(cpuid_dump): # Intel Processor Identification and the CPUID Instruction # http://www.intel.com/Assets/PDF/appnote/241618.pdf # 5.1.2 Feature Information (Function 01h) - eax = cpuid_regs_to_dic('0x00000001 0x00', cpuid_dump)['eax'] + eax = cpuid_dump[1, 0]['eax'] family = (eax >> 8) & 0xf if family == 0xf: # extract extendend family @@ -302,7 +318,7 @@ def cpuid_to_model(cpuid_dump): # Intel Processor Identification and the CPUID Instruction # http://www.intel.com/Assets/PDF/appnote/241618.pdf # 5.1.2 Feature Information (Function 01h) - eax = cpuid_regs_to_dic('0x00000001 0x00', cpuid_dump)['eax'] + eax = cpuid_dump[1, 0]['eax'] model = (eax >> 4) & 0xf # extended model model |= (eax >> 12) & 0xf0 @@ -333,7 +349,7 @@ def cpuid_to_stepping(cpuid_dump): # Intel Processor Identification and the CPUID Instruction # http://www.intel.com/Assets/PDF/appnote/241618.pdf # 5.1.2 Feature Information (Function 01h) - eax = cpuid_regs_to_dic('0x00000001 0x00', cpuid_dump)['eax'] + eax = cpuid_dump[1, 0]['eax'] stepping = eax & 0xf return stepping @@ -362,7 +378,7 @@ def cpuid_to_xlevel(cpuid_dump): # Intel Processor Identification and the CPUID Instruction # http://www.intel.com/Assets/PDF/appnote/241618.pdf # 5.2.1 Largest Extendend Function # (Function 80000000h) - return cpuid_regs_to_dic('0x80000000 0x00', cpuid_dump)['eax'] + return cpuid_dump[0x80000000, 0x00]['eax'] class custom_xlevel(MiniSubtest): """ @@ -395,8 +411,8 @@ def cpuid_to_model_id(cpuid_dump): # 5.2.3 Processor Brand String (Functions 80000002h, 80000003h, # 80000004h) m_id = "" - for idx in ('0x80000002', '0x80000003', '0x80000004'): - regs = cpuid_regs_to_dic('%s 0x00' % idx, cpuid_dump) + for idx in (0x80000002, 0x80000003, 0x80000004): + regs = cpuid_dump[idx, 0] for name in ('eax', 'ebx', 'ecx', 'edx'): for shift in range(4): c = ((regs[name] >> (shift * 8)) & 0xff) @@ -429,7 +445,7 @@ def test(self): raise error.TestFail("Test was expected to fail, but it didn't") def cpuid_regs_to_string(cpuid_dump, leaf, idx, regs): - r = cpuid_regs_to_dic('%s %s' % (leaf, idx), cpuid_dump) + r = cpuid_dump[leaf, idx] signature = "" for i in regs: for shift in range(0, 4): @@ -449,8 +465,8 @@ class cpuid_signature(MiniSubtest): def test(self): has_error = False flags = params.get("flags","") - leaf = params.get("leaf","0x40000000") - idx = params.get("index","0x00") + leaf = int(params.get("leaf","0x40000000"), 0) + idx = int(params.get("index","0x00"), 0) regs = params.get("regs","ebx ecx edx").split() signature = params["signature"] try: @@ -474,13 +490,13 @@ class cpuid_bit_test(MiniSubtest): def test(self): has_error = False flags = params.get("flags","") - leaf = params.get("leaf","0x40000000") - idx = params.get("index","0x00") + leaf = int(params.get("leaf","0x40000000"), 0) + idx = int(params.get("index","0x00"), 0) reg = params.get("reg","eax") bits = params["bits"].split() try: out = get_guest_cpuid(self, cpu_model, flags) - r = cpuid_regs_to_dic('%s %s' % (leaf, idx), out)[reg] + r = out[leaf, idx][reg] logging.debug("CPUID(%s.%s).%s=0x%08x" % (leaf, idx, reg, r)) for i in bits: if (r & (1 << int(i))) == 0: @@ -500,13 +516,13 @@ class cpuid_reg_test(MiniSubtest): def test(self): has_error = False flags = params.get("flags","") - leaf = params.get("leaf") - idx = params.get("index","0x00") + leaf = int(params.get("leaf", "0x00"), 0) + idx = int(params.get("index","0x00"), 0) reg = params.get("reg","eax") - val = int(params["value"]) + val = int(params["value"], 0) try: out = get_guest_cpuid(self, cpu_model, flags) - r = cpuid_regs_to_dic('%s %s' % (leaf, idx), out)[reg] + r = out[leaf, idx][reg] logging.debug("CPUID(%s.%s).%s=0x%08x" % (leaf, idx, reg, r)) if r != val: raise error.TestFail("CPUID(%s.%s).%s is not 0x%08x" % From fd6c619c5e8de6ce8a946b4409f090e7417e7055 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost <ehabkost@redhat.com> Date: Fri, 2 Aug 2013 11:39:44 -0300 Subject: [PATCH 213/254] cpuid: remove unnecessary exception-catching code There's no need to raise a different exception if a test failed. Simply pass the same exception to the caller and let the test runner take care of it. Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- qemu/tests/cpuid.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/qemu/tests/cpuid.py b/qemu/tests/cpuid.py index 50332a249..f96f10c07 100644 --- a/qemu/tests/cpuid.py +++ b/qemu/tests/cpuid.py @@ -537,18 +537,13 @@ def test(self): # subtests runner test_type = params["test_type"] - failed = [] if test_type in locals(): tests_group = locals()[test_type] try: tests_group() except: print_exception(tests_group) - failed.append(test_type) + raise else: raise error.TestError("Test group '%s' is not defined in" " test" % test_type) - - if failed != []: - raise error.TestFail("Test of cpu models %s failed." % - (str(failed))) From dad4171b45e59e81287d0be29f6df948d53dd2ad Mon Sep 17 00:00:00 2001 From: Eduardo Habkost <ehabkost@redhat.com> Date: Mon, 5 Aug 2013 09:25:19 -0300 Subject: [PATCH 214/254] cpuid: get_guest_cpuid(): allow extra VM creation parameters to be specified Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- qemu/tests/cpuid.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qemu/tests/cpuid.py b/qemu/tests/cpuid.py index f96f10c07..5a1af6285 100644 --- a/qemu/tests/cpuid.py +++ b/qemu/tests/cpuid.py @@ -157,7 +157,7 @@ def parse_cpuid_dump(output): return result - def get_guest_cpuid(self, cpu_model, feature=None): + def get_guest_cpuid(self, cpu_model, feature=None, extra_params=None): test_kernel_dir = os.path.join(test.virtdir, "deps", "cpuid_test_kernel") os.chdir(test_kernel_dir) @@ -170,6 +170,8 @@ def get_guest_cpuid(self, cpu_model, feature=None): params_b["cpu_model_flags"] = feature del params_b["images"] del params_b["nics"] + if extra_params: + params_b.update(extra_params) env_process.preprocess_vm(self, params_b, env, vm_name) vm = env.get_vm(vm_name) vm.create() From 424e44c1ea059f84221553b1eed53892bc881c5a Mon Sep 17 00:00:00 2001 From: Eduardo Habkost <ehabkost@redhat.com> Date: Mon, 5 Aug 2013 09:34:05 -0300 Subject: [PATCH 215/254] cpuid: remove exception traceback code There's nothing special about the cpuid test case that requires special exception-handling code. If somebody needs a traceback from a test exception, the generic virt-test test runner should be able to provide it. Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- qemu/tests/cpuid.py | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/qemu/tests/cpuid.py b/qemu/tests/cpuid.py index 5a1af6285..2acaf3288 100644 --- a/qemu/tests/cpuid.py +++ b/qemu/tests/cpuid.py @@ -1,7 +1,7 @@ """ Group of cpuid tests for X86 CPU """ -import re, sys, traceback, os, string +import re, sys, os, string from autotest.client.shared import error, utils from autotest.client.shared import test as test_module from virttest import utils_misc, env_process @@ -59,19 +59,6 @@ def test(self): """ raise error.TestFail("test() must be redifined in subtest") - def print_exception(called_object): - """ - print error including stack trace - """ - exc_type, exc_value, exc_traceback = sys.exc_info() - logging.error("In function (" + called_object.__name__ + "):") - logging.error("Call from:\n" + - traceback.format_stack()[-2][:-1]) - logging.error("Exception from:\n" + - "".join(traceback.format_exception( - exc_type, exc_value, - exc_traceback.tb_next))) - def cpu_models_to_test(): """Return the list of CPU models to be tested, based on the cpu_models and cpu_model config options. @@ -541,11 +528,7 @@ def test(self): test_type = params["test_type"] if test_type in locals(): tests_group = locals()[test_type] - try: - tests_group() - except: - print_exception(tests_group) - raise + tests_group() else: raise error.TestError("Test group '%s' is not defined in" " test" % test_type) From a072e0fd1ed69b784241a3b7599630138f60960b Mon Sep 17 00:00:00 2001 From: Eduardo Habkost <ehabkost@redhat.com> Date: Mon, 5 Aug 2013 10:36:41 -0300 Subject: [PATCH 216/254] cpuid: eliminate MiniSubtest class There's no reason to create an additional test object and use confusing tricks using __new__(), if we already have a test object as the "test" parameter. With this, we can convert all test classes to simple functions. To make sure we kill the VM after running each test case, add kill_vm=yes and kill_vm_gracefully=no to qemu_cpu.cfg. Cc: Igor Mammedov <imammedo@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- qemu/tests/cfg/qemu_cpu.cfg | 2 + qemu/tests/cpuid.py | 507 +++++++++++++++++------------------- 2 files changed, 234 insertions(+), 275 deletions(-) diff --git a/qemu/tests/cfg/qemu_cpu.cfg b/qemu/tests/cfg/qemu_cpu.cfg index 3c785c38e..2c4689c5b 100644 --- a/qemu/tests/cfg/qemu_cpu.cfg +++ b/qemu/tests/cfg/qemu_cpu.cfg @@ -3,6 +3,8 @@ virt_test_type = qemu type = cpuid start_vm = "no" + kill_vm = yes + kill_vm_gracefully = no smp = 1 # ask autotest to not mess with the cpu_model settings diff --git a/qemu/tests/cpuid.py b/qemu/tests/cpuid.py index 2acaf3288..d0b4ac914 100644 --- a/qemu/tests/cpuid.py +++ b/qemu/tests/cpuid.py @@ -27,38 +27,6 @@ def run_cpuid(test, params, env): if (params.get("xfail") is not None) and (params.get("xfail") == "yes"): xfail = True - class MiniSubtest(test_module.Subtest): - """ - subtest base class for actual tests - """ - def __new__(cls, *args, **kargs): - self = test.__new__(cls) - ret = None - if args is None: - args = [] - try: - ret = self.test(*args, **kargs) - finally: - if hasattr(self, "clean"): - self.clean() - return ret - - def clean(self): - """ - cleans up running VM instance - """ - if (hasattr(self, "vm")): - vm = getattr(self, "vm") - if vm.is_alive(): - vm.pause() - vm.destroy(gracefully=False) - - def test(self): - """ - stub for actual test code - """ - raise error.TestFail("test() must be redifined in subtest") - def cpu_models_to_test(): """Return the list of CPU models to be tested, based on the cpu_models and cpu_model config options. @@ -87,22 +55,21 @@ def cpu_models_to_test(): return cpu_models - class test_qemu_cpu_models_list(MiniSubtest): + def test_qemu_cpu_models_list(self): """ check CPU models returned by <qemu> -cpu '?' are what is expected """ - def test(self): - """ - test method - """ - cpu_models = cpu_models_to_test() - qemu_models = utils_misc.get_qemu_cpu_models(qemu_binary) - missing = set(cpu_models) - set(qemu_models) - if missing: - raise error.TestFail("Some CPU models not in QEMU CPU model list: %s") - added = set(qemu_models) - set(cpu_models) - if added: - logging.info("Extra CPU models in QEMU CPU listing: %s", added) + """ + test method + """ + cpu_models = cpu_models_to_test() + qemu_models = utils_misc.get_qemu_cpu_models(qemu_binary) + missing = set(cpu_models) - set(qemu_models) + if missing: + raise error.TestFail("Some CPU models not in QEMU CPU model list: %s") + added = set(qemu_models) - set(cpu_models) + if added: + logging.info("Extra CPU models in QEMU CPU listing: %s", added) def compare_cpuid_output(a, b): """ @@ -161,6 +128,7 @@ def get_guest_cpuid(self, cpu_model, feature=None, extra_params=None): params_b.update(extra_params) env_process.preprocess_vm(self, params_b, env, vm_name) vm = env.get_vm(vm_name) + dbg('is dead: %r', vm.is_dead()) vm.create() self.vm = vm vm.resume() @@ -174,7 +142,7 @@ def get_guest_cpuid(self, cpu_model, feature=None, extra_params=None): if test_output is None: raise error.TestFail("Test output signature not found in " "output:\n %s", vm.serial_console.get_output()) - self.clean() + vm.destroy(gracefully=False) return test_output def cpuid_to_vendor(cpuid_dump, idx): @@ -188,88 +156,85 @@ def cpuid_to_vendor(cpuid_dump, idx): dst.append((chr(r['ecx'] >> (8 * i) & 0xff))), range(0, 4)) return ''.join(dst) - class default_vendor(MiniSubtest): + def default_vendor(self): """ Boot qemu with specified cpu models and verify that CPU vendor matches requested """ - def test(self): - cpu_models = cpu_models_to_test() - - vendor = params.get("vendor") - if vendor is None or vendor == "host": - cmd = "grep 'vendor_id' /proc/cpuinfo | head -n1 | awk '{print $3}'" - cmd_result = utils.run(cmd, ignore_status=True) - vendor = cmd_result.stdout.strip() - - ignore_cpus = set(params.get("ignore_cpu_models","").split(' ')) - cpu_models = cpu_models - ignore_cpus - - for cpu_model in cpu_models: - out = get_guest_cpuid(self, cpu_model) - guest_vendor = cpuid_to_vendor(out, 0x00000000) - logging.debug("Guest's vendor: " + guest_vendor) - if guest_vendor != vendor: - raise error.TestFail("Guest vendor [%s], doesn't match " - "required vendor [%s] for CPU [%s]" % - (guest_vendor, vendor, cpu_model)) - - class custom_vendor(MiniSubtest): + cpu_models = cpu_models_to_test() + + vendor = params.get("vendor") + if vendor is None or vendor == "host": + cmd = "grep 'vendor_id' /proc/cpuinfo | head -n1 | awk '{print $3}'" + cmd_result = utils.run(cmd, ignore_status=True) + vendor = cmd_result.stdout.strip() + + ignore_cpus = set(params.get("ignore_cpu_models","").split(' ')) + cpu_models = cpu_models - ignore_cpus + + for cpu_model in cpu_models: + out = get_guest_cpuid(self, cpu_model) + guest_vendor = cpuid_to_vendor(out, 0x00000000) + logging.debug("Guest's vendor: " + guest_vendor) + if guest_vendor != vendor: + raise error.TestFail("Guest vendor [%s], doesn't match " + "required vendor [%s] for CPU [%s]" % + (guest_vendor, vendor, cpu_model)) + + def custom_vendor(self): """ Boot qemu with specified vendor """ - def test(self): - has_error = False - vendor = params["vendor"] - - try: - out = get_guest_cpuid(self, cpu_model, "vendor=" + vendor) - guest_vendor0 = cpuid_to_vendor(out, 0x00000000) - guest_vendor80000000 = cpuid_to_vendor(out, 0x80000000) - logging.debug("Guest's vendor[0]: " + guest_vendor0) - logging.debug("Guest's vendor[0x80000000]: " + - guest_vendor80000000) - if guest_vendor0 != vendor: - raise error.TestFail("Guest vendor[0] [%s], doesn't match " - "required vendor [%s] for CPU [%s]" % - (guest_vendor0, vendor, cpu_model)) - if guest_vendor80000000 != vendor: - raise error.TestFail("Guest vendor[0x80000000] [%s], " - "doesn't match required vendor " - "[%s] for CPU [%s]" % - (guest_vendor80000000, vendor, - cpu_model)) - except: - has_error = True - if xfail is False: - raise - if (has_error is False) and (xfail is True): - raise error.TestFail("Test was expected to fail, but it didn't") + has_error = False + vendor = params["vendor"] + + try: + out = get_guest_cpuid(self, cpu_model, "vendor=" + vendor) + guest_vendor0 = cpuid_to_vendor(out, 0x00000000) + guest_vendor80000000 = cpuid_to_vendor(out, 0x80000000) + logging.debug("Guest's vendor[0]: " + guest_vendor0) + logging.debug("Guest's vendor[0x80000000]: " + + guest_vendor80000000) + if guest_vendor0 != vendor: + raise error.TestFail("Guest vendor[0] [%s], doesn't match " + "required vendor [%s] for CPU [%s]" % + (guest_vendor0, vendor, cpu_model)) + if guest_vendor80000000 != vendor: + raise error.TestFail("Guest vendor[0x80000000] [%s], " + "doesn't match required vendor " + "[%s] for CPU [%s]" % + (guest_vendor80000000, vendor, + cpu_model)) + except: + has_error = True + if xfail is False: + raise + if (has_error is False) and (xfail is True): + raise error.TestFail("Test was expected to fail, but it didn't") def cpuid_to_level(cpuid_dump): r = cpuid_dump[0, 0] return r['eax'] - class custom_level(MiniSubtest): + def custom_level(self): """ Boot qemu with specified level """ - def test(self): - has_error = False - level = params["level"] - try: - out = get_guest_cpuid(self, cpu_model, "level=" + level) - guest_level = str(cpuid_to_level(out)) - if guest_level != level: - raise error.TestFail("Guest's level [%s], doesn't match " - "required level [%s]" % - (guest_level, level)) - except: - has_error = True - if xfail is False: - raise - if (has_error is False) and (xfail is True): - raise error.TestFail("Test was expected to fail, but it didn't") + has_error = False + level = params["level"] + try: + out = get_guest_cpuid(self, cpu_model, "level=" + level) + guest_level = str(cpuid_to_level(out)) + if guest_level != level: + raise error.TestFail("Guest's level [%s], doesn't match " + "required level [%s]" % + (guest_level, level)) + except: + has_error = True + if xfail is False: + raise + if (has_error is False) and (xfail is True): + raise error.TestFail("Test was expected to fail, but it didn't") def cpuid_to_family(cpuid_dump): # Intel Processor Identification and the CPUID Instruction @@ -282,26 +247,25 @@ def cpuid_to_family(cpuid_dump): return family + ((eax >> 20) & 0xff) return family - class custom_family(MiniSubtest): + def custom_family(self): """ Boot qemu with specified family """ - def test(self): - has_error = False - family = params["family"] - try: - out = get_guest_cpuid(self, cpu_model, "family=" + family) - guest_family = str(cpuid_to_family(out)) - if guest_family != family: - raise error.TestFail("Guest's family [%s], doesn't match " - "required family [%s]" % - (guest_family, family)) - except: - has_error = True - if xfail is False: - raise - if (has_error is False) and (xfail is True): - raise error.TestFail("Test was expected to fail, but it didn't") + has_error = False + family = params["family"] + try: + out = get_guest_cpuid(self, cpu_model, "family=" + family) + guest_family = str(cpuid_to_family(out)) + if guest_family != family: + raise error.TestFail("Guest's family [%s], doesn't match " + "required family [%s]" % + (guest_family, family)) + except: + has_error = True + if xfail is False: + raise + if (has_error is False) and (xfail is True): + raise error.TestFail("Test was expected to fail, but it didn't") def cpuid_to_model(cpuid_dump): # Intel Processor Identification and the CPUID Instruction @@ -313,26 +277,25 @@ def cpuid_to_model(cpuid_dump): model |= (eax >> 12) & 0xf0 return model - class custom_model(MiniSubtest): + def custom_model(self): """ Boot qemu with specified model """ - def test(self): - has_error = False - model = params["model"] - try: - out = get_guest_cpuid(self, cpu_model, "model=" + model) - guest_model = str(cpuid_to_model(out)) - if guest_model != model: - raise error.TestFail("Guest's model [%s], doesn't match " - "required model [%s]" % - (guest_model, model)) - except: - has_error = True - if xfail is False: - raise - if (has_error is False) and (xfail is True): - raise error.TestFail("Test was expected to fail, but it didn't") + has_error = False + model = params["model"] + try: + out = get_guest_cpuid(self, cpu_model, "model=" + model) + guest_model = str(cpuid_to_model(out)) + if guest_model != model: + raise error.TestFail("Guest's model [%s], doesn't match " + "required model [%s]" % + (guest_model, model)) + except: + has_error = True + if xfail is False: + raise + if (has_error is False) and (xfail is True): + raise error.TestFail("Test was expected to fail, but it didn't") def cpuid_to_stepping(cpuid_dump): # Intel Processor Identification and the CPUID Instruction @@ -342,26 +305,25 @@ def cpuid_to_stepping(cpuid_dump): stepping = eax & 0xf return stepping - class custom_stepping(MiniSubtest): + def custom_stepping(self): """ Boot qemu with specified stepping """ - def test(self): - has_error = False - stepping = params["stepping"] - try: - out = get_guest_cpuid(self, cpu_model, "stepping=" + stepping) - guest_stepping = str(cpuid_to_stepping(out)) - if guest_stepping != stepping: - raise error.TestFail("Guest's stepping [%s], doesn't match " - "required stepping [%s]" % - (guest_stepping, stepping)) - except: - has_error = True - if xfail is False: - raise - if (has_error is False) and (xfail is True): - raise error.TestFail("Test was expected to fail, but it didn't") + has_error = False + stepping = params["stepping"] + try: + out = get_guest_cpuid(self, cpu_model, "stepping=" + stepping) + guest_stepping = str(cpuid_to_stepping(out)) + if guest_stepping != stepping: + raise error.TestFail("Guest's stepping [%s], doesn't match " + "required stepping [%s]" % + (guest_stepping, stepping)) + except: + has_error = True + if xfail is False: + raise + if (has_error is False) and (xfail is True): + raise error.TestFail("Test was expected to fail, but it didn't") def cpuid_to_xlevel(cpuid_dump): # Intel Processor Identification and the CPUID Instruction @@ -369,30 +331,29 @@ def cpuid_to_xlevel(cpuid_dump): # 5.2.1 Largest Extendend Function # (Function 80000000h) return cpuid_dump[0x80000000, 0x00]['eax'] - class custom_xlevel(MiniSubtest): + def custom_xlevel(self): """ Boot qemu with specified xlevel """ - def test(self): - has_error = False - xlevel = params["xlevel"] - if params.get("expect_xlevel") is not None: - xlevel = params.get("expect_xlevel") - - try: - out = get_guest_cpuid(self, cpu_model, "xlevel=" + - params.get("xlevel")) - guest_xlevel = str(cpuid_to_xlevel(out)) - if guest_xlevel != xlevel: - raise error.TestFail("Guest's xlevel [%s], doesn't match " - "required xlevel [%s]" % - (guest_xlevel, xlevel)) - except: - has_error = True - if xfail is False: - raise - if (has_error is False) and (xfail is True): - raise error.TestFail("Test was expected to fail, but it didn't") + has_error = False + xlevel = params["xlevel"] + if params.get("expect_xlevel") is not None: + xlevel = params.get("expect_xlevel") + + try: + out = get_guest_cpuid(self, cpu_model, "xlevel=" + + params.get("xlevel")) + guest_xlevel = str(cpuid_to_xlevel(out)) + if guest_xlevel != xlevel: + raise error.TestFail("Guest's xlevel [%s], doesn't match " + "required xlevel [%s]" % + (guest_xlevel, xlevel)) + except: + has_error = True + if xfail is False: + raise + if (has_error is False) and (xfail is True): + raise error.TestFail("Test was expected to fail, but it didn't") def cpuid_to_model_id(cpuid_dump): # Intel Processor Identification and the CPUID Instruction @@ -410,28 +371,27 @@ def cpuid_to_model_id(cpuid_dump): m_id += chr(c) return m_id - class custom_model_id(MiniSubtest): + def custom_model_id(self): """ Boot qemu with specified model_id """ - def test(self): - has_error = False - model_id = params["model_id"] - - try: - out = get_guest_cpuid(self, cpu_model, "model_id='%s'" % - model_id) - guest_model_id = cpuid_to_model_id(out) - if guest_model_id != model_id: - raise error.TestFail("Guest's model_id [%s], doesn't match " - "required model_id [%s]" % - (guest_model_id, model_id)) - except: - has_error = True - if xfail is False: - raise - if (has_error is False) and (xfail is True): - raise error.TestFail("Test was expected to fail, but it didn't") + has_error = False + model_id = params["model_id"] + + try: + out = get_guest_cpuid(self, cpu_model, "model_id='%s'" % + model_id) + guest_model_id = cpuid_to_model_id(out) + if guest_model_id != model_id: + raise error.TestFail("Guest's model_id [%s], doesn't match " + "required model_id [%s]" % + (guest_model_id, model_id)) + except: + has_error = True + if xfail is False: + raise + if (has_error is False) and (xfail is True): + raise error.TestFail("Test was expected to fail, but it didn't") def cpuid_regs_to_string(cpuid_dump, leaf, idx, regs): r = cpuid_dump[leaf, idx] @@ -447,88 +407,85 @@ def cpuid_regs_to_string(cpuid_dump, leaf, idx, regs): signature)) return signature - class cpuid_signature(MiniSubtest): + def cpuid_signature(self): """ test signature in specified leaf:index:regs """ - def test(self): - has_error = False - flags = params.get("flags","") - leaf = int(params.get("leaf","0x40000000"), 0) - idx = int(params.get("index","0x00"), 0) - regs = params.get("regs","ebx ecx edx").split() - signature = params["signature"] - try: - out = get_guest_cpuid(self, cpu_model, flags) - _signature = cpuid_regs_to_string(out, leaf, idx, regs) - if _signature != signature: - raise error.TestFail("Guest's signature [%s], doesn't" - "match required signature [%s]" % - (_signature, signature)) - except: - has_error = True - if xfail is False: - raise - if (has_error is False) and (xfail is True): - raise error.TestFail("Test was expected to fail, but it didn't") - - class cpuid_bit_test(MiniSubtest): + has_error = False + flags = params.get("flags","") + leaf = int(params.get("leaf","0x40000000"), 0) + idx = int(params.get("index","0x00"), 0) + regs = params.get("regs","ebx ecx edx").split() + signature = params["signature"] + try: + out = get_guest_cpuid(self, cpu_model, flags) + _signature = cpuid_regs_to_string(out, leaf, idx, regs) + if _signature != signature: + raise error.TestFail("Guest's signature [%s], doesn't" + "match required signature [%s]" % + (_signature, signature)) + except: + has_error = True + if xfail is False: + raise + if (has_error is False) and (xfail is True): + raise error.TestFail("Test was expected to fail, but it didn't") + + def cpuid_bit_test(self): """ test bits in specified leaf:func:reg """ - def test(self): - has_error = False - flags = params.get("flags","") - leaf = int(params.get("leaf","0x40000000"), 0) - idx = int(params.get("index","0x00"), 0) - reg = params.get("reg","eax") - bits = params["bits"].split() - try: - out = get_guest_cpuid(self, cpu_model, flags) - r = out[leaf, idx][reg] - logging.debug("CPUID(%s.%s).%s=0x%08x" % (leaf, idx, reg, r)) - for i in bits: - if (r & (1 << int(i))) == 0: - raise error.TestFail("CPUID(%s.%s).%s[%s] is not set" % - (leaf, idx, reg, i)) - except: - has_error = True - if xfail is False: - raise - if (has_error is False) and (xfail is True): - raise error.TestFail("Test was expected to fail, but it didn't") - - class cpuid_reg_test(MiniSubtest): + has_error = False + flags = params.get("flags","") + leaf = int(params.get("leaf","0x40000000"), 0) + idx = int(params.get("index","0x00"), 0) + reg = params.get("reg","eax") + bits = params["bits"].split() + try: + out = get_guest_cpuid(self, cpu_model, flags) + r = out[leaf, idx][reg] + logging.debug("CPUID(%s.%s).%s=0x%08x" % (leaf, idx, reg, r)) + for i in bits: + if (r & (1 << int(i))) == 0: + raise error.TestFail("CPUID(%s.%s).%s[%s] is not set" % + (leaf, idx, reg, i)) + except: + has_error = True + if xfail is False: + raise + if (has_error is False) and (xfail is True): + raise error.TestFail("Test was expected to fail, but it didn't") + + def cpuid_reg_test(self): """ test register value in specified leaf:index:reg """ - def test(self): - has_error = False - flags = params.get("flags","") - leaf = int(params.get("leaf", "0x00"), 0) - idx = int(params.get("index","0x00"), 0) - reg = params.get("reg","eax") - val = int(params["value"], 0) - try: - out = get_guest_cpuid(self, cpu_model, flags) - r = out[leaf, idx][reg] - logging.debug("CPUID(%s.%s).%s=0x%08x" % (leaf, idx, reg, r)) - if r != val: - raise error.TestFail("CPUID(%s.%s).%s is not 0x%08x" % - (leaf, idx, reg, val)) - except: - has_error = True - if xfail is False: - raise - if (has_error is False) and (xfail is True): - raise error.TestFail("Test was expected to fail, but it didn't") + has_error = False + flags = params.get("flags","") + leaf = int(params.get("leaf", "0x00"), 0) + idx = int(params.get("index","0x00"), 0) + reg = params.get("reg","eax") + val = int(params["value"], 0) + try: + out = get_guest_cpuid(self, cpu_model, flags) + r = out[leaf, idx][reg] + logging.debug("CPUID(%s.%s).%s=0x%08x" % (leaf, idx, reg, r)) + if r != val: + raise error.TestFail("CPUID(%s.%s).%s is not 0x%08x" % + (leaf, idx, reg, val)) + except: + has_error = True + if xfail is False: + raise + if (has_error is False) and (xfail is True): + raise error.TestFail("Test was expected to fail, but it didn't") # subtests runner test_type = params["test_type"] - if test_type in locals(): - tests_group = locals()[test_type] - tests_group() - else: - raise error.TestError("Test group '%s' is not defined in" + if test_type not in locals(): + raise error.TestError("Test function '%s' is not defined in" " test" % test_type) + + test_func = locals()[test_type] + return test_func(test) From 1e5a5cee80e8af68e8e5450d9f61586ef8fb03e0 Mon Sep 17 00:00:00 2001 From: Yiqiao Pu <ypu@redhat.com> Date: Thu, 1 Aug 2013 17:53:42 +0800 Subject: [PATCH 217/254] shared.cfg.guest-os: Add serial number check command for Windows guest And the disk driver serial number check command for Windows guests. Signed-off-by: Yiqiao Pu <ypu@redhat.com> --- shared/cfg/guest-os/Windows.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/cfg/guest-os/Windows.cfg b/shared/cfg/guest-os/Windows.cfg index 1071c6412..d2dfcbc58 100644 --- a/shared/cfg/guest-os/Windows.cfg +++ b/shared/cfg/guest-os/Windows.cfg @@ -159,7 +159,7 @@ umount_cmd = "" physical_resources_check: catch_uuid_cmd = - catch_serial_cmd = + catch_serial_cmd = "wmic diskdrive get serialnumber | more +1" cpu_vendor_id_chk_cmd = "wmic cpu get Manufacturer | more +1" #XXX: Since I don't find a reliable way to check the cpu socket # numbers for windows, disable this kind of checking temporarily. From 102b00eb0904860fbf6a6298f8ff9c1806be9817 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Tue, 6 Aug 2013 02:31:46 +0800 Subject: [PATCH 218/254] shared.control: update bonnie control file autotest.bonnie always failed because of not enough free space to create the testing file on a 20G virtual disk. Therefore, update default test command to: "bonnie++ -d xxx -n 500 -s 2048 -r 1024" to avoid this situation. Signed-off-by: Xu Tian <xutian@redhat.com> --- shared/control/bonnie.control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/control/bonnie.control b/shared/control/bonnie.control index 2717a8040..878f559ba 100644 --- a/shared/control/bonnie.control +++ b/shared/control/bonnie.control @@ -18,4 +18,4 @@ throughput, %CPU rand seeks per second. Not sure if the the CPU numbers are trustworthy. """ -job.run_test('bonnie') +job.run_test('bonnie', extra_args="-n 500 -s 2048M -r 1024M") From adfdde2e3b0e570092dadddeadf49e8ce1df7962 Mon Sep 17 00:00:00 2001 From: Yiqiao Pu <ypu@redhat.com> Date: Mon, 5 Aug 2013 23:47:07 +0800 Subject: [PATCH 219/254] qemu: Remove the host kernel file at the beginning of control.kernel-version Remove this file to ignore the problem caused by this file in upgraded system. Signed-off-by: Yiqiao Pu <ypu@redhat.com> --- qemu/control.kernel-version | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qemu/control.kernel-version b/qemu/control.kernel-version index 5c99c3b22..13f2491f0 100644 --- a/qemu/control.kernel-version +++ b/qemu/control.kernel-version @@ -95,6 +95,8 @@ parser.parse_file(os.path.join(qemu_test_dir, "cfg", "tests-example.cfg")) host_kernel_ver_str = "" host_kernel_ver_file = "/tmp/host_kernel_version" +if os.path.isfile(host_kernel_ver_file): + os.remove(host_kernel_ver_file) filter_str = "" for dict_test in parser.get_dicts(): From 6943306f5cfd1c1323546f7bf61feede7ce6638b Mon Sep 17 00:00:00 2001 From: Feng Yang <fyang@redhat.com> Date: Fri, 2 Aug 2013 15:59:12 +0800 Subject: [PATCH 220/254] tests.boot: Create new session for every VM in loop Signed-off-by: Feng Yang <fyang@redhat.com> --- tests/boot.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/boot.py b/tests/boot.py index d27d3685d..870b928f8 100644 --- a/tests/boot.py +++ b/tests/boot.py @@ -22,17 +22,20 @@ def run_boot(test, params, env): for vm in vms: error.context("Try to log into guest '%s'." % vm.name, logging.info) session = vm.wait_for_login(timeout=timeout) + session.close() if params.get("rh_perf_envsetup_script"): for vm in vms: + session = vm.wait_for_login(timeout=timeout) utils_test.service_setup(vm, session, test.virtdir) - + session.close() if params.get("reboot_method"): for vm in vms: error.context("Reboot guest '%s'." % vm.name, logging.info) if params["reboot_method"] == "system_reset": time.sleep(int(params.get("sleep_before_reset", 10))) # Reboot the VM + session = vm.wait_for_login(timeout=timeout) for i in range(int(params.get("reboot_count", 1))): session = vm.reboot(session, params["reboot_method"], From 518e9041dfe481b3190e89efa17c2d26e69b2803 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Doktor?= <ldoktor@redhat.com> Date: Fri, 26 Jul 2013 07:40:08 +0200 Subject: [PATCH 221/254] virttest.qemu_devices: Add parameter to workaround qemu qmp crash bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to avoid qemu crash dump on older qemu you can set "workaround_qemu_qmp_crash = always" in base.cfg and qemu_devices will wait 1 second before using QMP monitor for the first time. By default virt-test will try using QMP directly after qemu startup and in case of failure it still fall backs to the workaround. Still the first attempt generates unnecessarily crashdump which might be stored in the autotest results. Signed-off-by: Lukáš Doktor <ldoktor@redhat.com> --- shared/cfg/base.cfg | 3 +++ virttest/qemu_devices.py | 11 +++++++---- virttest/qemu_vm.py | 3 ++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/shared/cfg/base.cfg b/shared/cfg/base.cfg index 5f19b954c..eff740bc5 100644 --- a/shared/cfg/base.cfg +++ b/shared/cfg/base.cfg @@ -24,6 +24,9 @@ main_vm = virt-tests-vm1 # Always set optional parameters (addr, bus, ...) strict_mode = no +# Uncomment this to always wait 1s before executing QMP command +# (due of bug immediate use of QMP monitor after qemu start causes qemu crash) +# workaround_qemu_qmp_crash = always # List of default network device object names (whitespace seperated) # All VMs get these by default, unless specific vm name references diff --git a/virttest/qemu_devices.py b/virttest/qemu_devices.py index 0eb719211..03d1f5f52 100644 --- a/virttest/qemu_devices.py +++ b/virttest/qemu_devices.py @@ -869,7 +869,8 @@ class DevContainer(object): Device container class """ # General methods - def __init__(self, qemu_binary, vmname, strict_mode=False): + def __init__(self, qemu_binary, vmname, strict_mode=False, + workaround_qemu_qmp_crash=False): """ @param qemu_binary: qemu binary @param vm: related VM @@ -891,9 +892,11 @@ def get_hmp_cmds(qemu_binary): hmp_cmds.extend(cmd.split('|')) return hmp_cmds - def get_qmp_cmds(qemu_binary): + def get_qmp_cmds(qemu_binary, workaround_qemu_qmp_crash=False): """ @return: list of qmp commands """ - cmds = utils.system_output('echo -e \'' + cmds = None + if not workaround_qemu_qmp_crash: + cmds = utils.system_output('echo -e \'' '{ "execute": "qmp_capabilities" }\n' '{ "execute": "query-commands", "id": "RAND91" }\n' '{ "execute": "quit" }\'' @@ -923,7 +926,7 @@ def get_qmp_cmds(qemu_binary): self.__machine_types = utils.system_output("%s -M ?" % qemu_binary, timeout=10, ignore_status=True, verbose=False) self.__hmp_cmds = get_hmp_cmds(qemu_binary) - self.__qmp_cmds = get_qmp_cmds(qemu_binary) + self.__qmp_cmds = get_qmp_cmds(qemu_binary, workaround_qemu_qmp_crash) self.vmname = vmname self.strict_mode = strict_mode == 'yes' self.__devices = [] diff --git a/virttest/qemu_vm.py b/virttest/qemu_vm.py index 97463ad9a..8fbd2100e 100644 --- a/virttest/qemu_vm.py +++ b/virttest/qemu_vm.py @@ -1348,7 +1348,8 @@ def add_option_rom(devices, opt_rom): # Start constructing devices representation devices = qemu_devices.DevContainer(qemu_binary, self.name, - params.get('strict_mode')) + params.get('strict_mode'), + params.get('workaround_qemu_qmp_crash') == "always") StrDev = qemu_devices.QStringDevice QDevice = qemu_devices.QDevice From 36d23bd761e1ddb2b921f6202e9176b219501065 Mon Sep 17 00:00:00 2001 From: Qingtang Zhou <qzhou@redhat.com> Date: Wed, 17 Jul 2013 16:07:53 +0800 Subject: [PATCH 222/254] qemu.tests: Add negative test for usb host Signed-off-by: Qingtang Zhou <qzhou@redhat.com> --- qemu/tests/cfg/usb.cfg | 11 +++++++++++ qemu/tests/usb_host.py | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/qemu/tests/cfg/usb.cfg b/qemu/tests/cfg/usb.cfg index 0a69fd1e3..e5176f68b 100644 --- a/qemu/tests/cfg/usb.cfg +++ b/qemu/tests/cfg/usb.cfg @@ -203,6 +203,17 @@ # must configure which device should be used #usb_host_device = "<vendorid>:<productid>" type = usb_host + #XXX: Now usb_host doesn't support QMP monitor. + # Limit it to human monitor only. + monitor_type = human + monitors = hmp1 + main_monitor = hmp1 + variants: + - usb_normal_test: + - usb_negative_test: + usb_negative_test = "yes" + usb_reply_msg = "Property 'usb-host.productid' doesn't take value" + usb_host_device_list = "aaa:aaa,aaa:111,21231:11231333,21231:1123132233,2123133:1123132233111" - usb_multi_disk: only ehci type = multi_disk diff --git a/qemu/tests/usb_host.py b/qemu/tests/usb_host.py index 8793b9dee..199b4e124 100644 --- a/qemu/tests/usb_host.py +++ b/qemu/tests/usb_host.py @@ -12,6 +12,25 @@ def run_usb_host(test, params, env): @param env: Dictionary with test environment. """ + if params.get("usb_negative_test", "no") != "no": + # Negative test. + vm = env.get_vm(params["main_vm"]) + vm.verify_alive() + session = vm.wait_for_login() + usb_host_device_list = params["usb_host_device_list"].split(",") + for dev in usb_host_device_list: + vid, pid = dev.split(":") + monitor_add = "device_add usb-host,bus=usbtest.0,id=usbhostdev" + monitor_add += ",vendorid=%s" % vid + monitor_add += ",productid=%s" % pid + reply = vm.monitor.cmd(monitor_add) + if params["usb_reply_msg"] not in reply: + raise error.TestFail("Could not get expected warning" + " msg in negative test, monitor" + " returns: '%s'" % reply) + vm.reboot() + return + device = params["usb_host_device"] (vendorid,productid) = device.split(":") From b8b84e912aa96d6edc3c7e41eb6a65b43553968d Mon Sep 17 00:00:00 2001 From: Qingtang Zhou <qzhou@redhat.com> Date: Wed, 17 Jul 2013 16:45:30 +0800 Subject: [PATCH 223/254] qemu.tests: Make usb host test can repeat multiple times Signed-off-by: Qingtang Zhou <qzhou@redhat.com> --- qemu/tests/cfg/usb.cfg | 5 ++++ qemu/tests/usb_host.py | 61 ++++++++++++++++++++++++++---------------- 2 files changed, 43 insertions(+), 23 deletions(-) diff --git a/qemu/tests/cfg/usb.cfg b/qemu/tests/cfg/usb.cfg index e5176f68b..8afab452a 100644 --- a/qemu/tests/cfg/usb.cfg +++ b/qemu/tests/cfg/usb.cfg @@ -214,6 +214,11 @@ usb_negative_test = "yes" usb_reply_msg = "Property 'usb-host.productid' doesn't take value" usb_host_device_list = "aaa:aaa,aaa:111,21231:11231333,21231:1123132233,2123133:1123132233111" + variants: + - usb_one_time: + usb_repeat_times = 1 + - usb_multi_times: + usb_repeat_times = 5000 - usb_multi_disk: only ehci type = multi_disk diff --git a/qemu/tests/usb_host.py b/qemu/tests/usb_host.py index 199b4e124..07e68651f 100644 --- a/qemu/tests/usb_host.py +++ b/qemu/tests/usb_host.py @@ -1,4 +1,4 @@ -import logging, re, uuid +import logging from autotest.client.shared import error from autotest.client import utils @@ -11,6 +11,37 @@ def run_usb_host(test, params, env): @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ + @error.context_aware + def usb_dev_hotplug(): + error.context("Plugin usb device", logging.info) + session.cmd_status("dmesg -c") + vm.monitor.cmd(monitor_add) + session.cmd_status("sleep 1") + session.cmd_status("udevadm settle") + messages_add = session.cmd("dmesg -c") + for line in messages_add.splitlines(): + logging.debug("[dmesg add] %s" % line) + if messages_add.find(match_add) == -1: + raise error.TestFail("kernel didn't detect plugin") + + + @error.context_aware + def usb_dev_verify(): + error.context("Check usb device %s in guest" % device, logging.info) + session.cmd(lsusb_cmd) + + + @error.context_aware + def usb_dev_unplug(): + error.context("Unplug usb device", logging.info) + vm.monitor.cmd(monitor_del) + session.cmd_status("sleep 1") + messages_del = session.cmd("dmesg -c") + for line in messages_del.splitlines(): + logging.debug("[dmesg del] %s" % line) + if messages_del.find(match_del) == -1: + raise error.TestFail("kernel didn't detect unplug") + if params.get("usb_negative_test", "no") != "no": # Negative test. @@ -54,28 +85,12 @@ def run_usb_host(test, params, env): vm = env.get_vm(params["main_vm"]) vm.verify_alive() session = vm.wait_for_login() - session.cmd_status("dmesg -c") - - error.context("Plugin usb device", logging.info) - vm.monitor.cmd(monitor_add) - session.cmd_status("sleep 1") - session.cmd_status("udevadm settle") - messages_add = session.cmd("dmesg -c") - for line in messages_add.splitlines(): - logging.debug("[dmesg add] %s" % line) - if messages_add.find(match_add) == -1: - raise error.TestFail("kernel didn't detect plugin") - - error.context("Check usb device %s in guest" % device, logging.info) - session.cmd(lsusb_cmd) - error.context("Unplug usb device", logging.info) - vm.monitor.cmd(monitor_del) - session.cmd_status("sleep 1") - messages_del = session.cmd("dmesg -c") - for line in messages_del.splitlines(): - logging.debug("[dmesg del] %s" % line) - if messages_del.find(match_del) == -1: - raise error.TestFail("kernel didn't detect unplug") + repeat_times = int(params.get("usb_repeat_times", "1")) + for i in range(repeat_times): + error.context("Hotplug (iteration %i)" % (i + 1), logging.info) + usb_dev_hotplug() + usb_dev_verify() + usb_dev_unplug() session.close() From c1a7e660163000a7b36dd507f8f69aca5a620b88 Mon Sep 17 00:00:00 2001 From: Qingtang Zhou <qzhou@redhat.com> Date: Wed, 17 Jul 2013 16:50:26 +0800 Subject: [PATCH 224/254] qemu.tests: Add a test for checking isobufs option for usb Signed-off-by: Qingtang Zhou <qzhou@redhat.com> --- qemu/tests/cfg/usb.cfg | 2 ++ qemu/tests/usb_host.py | 12 +++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/qemu/tests/cfg/usb.cfg b/qemu/tests/cfg/usb.cfg index 8afab452a..e3d04ddc2 100644 --- a/qemu/tests/cfg/usb.cfg +++ b/qemu/tests/cfg/usb.cfg @@ -214,6 +214,8 @@ usb_negative_test = "yes" usb_reply_msg = "Property 'usb-host.productid' doesn't take value" usb_host_device_list = "aaa:aaa,aaa:111,21231:11231333,21231:1123132233,2123133:1123132233111" + - usb_check_isobufs: + usb_check_isobufs = "yes" variants: - usb_one_time: usb_repeat_times = 1 diff --git a/qemu/tests/usb_host.py b/qemu/tests/usb_host.py index 07e68651f..53f6b3e0c 100644 --- a/qemu/tests/usb_host.py +++ b/qemu/tests/usb_host.py @@ -88,7 +88,17 @@ def usb_dev_unplug(): repeat_times = int(params.get("usb_repeat_times", "1")) for i in range(repeat_times): - error.context("Hotplug (iteration %i)" % (i + 1), logging.info) + if params.get("usb_check_isobufs", "no") == "no": + error.context("Hotplug (iteration %i)" % (i + 1), logging.info) + else: + # The value of isobufs could only be in '4, 8, 16' + isobufs = (2 << (i % 3 + 1)) + monitor_add = "device_add usb-host,bus=usbtest.0,id=usbhostdev" + monitor_add += ",vendorid=%s" % vendorid + monitor_add += ",productid=%s" % productid + monitor_add += ",isobufs=%d" % isobufs + error.context("Hotplug (iteration %i), with 'isobufs' option" + " set to %d" % ((i + 1), isobufs), logging.info) usb_dev_hotplug() usb_dev_verify() usb_dev_unplug() From 33ccd5aba7767f6bd452b944e3ecbb147c278285 Mon Sep 17 00:00:00 2001 From: Vaclav Ehrlich <vehrlich@redhat.com> Date: Thu, 20 Dec 2012 12:30:51 +0100 Subject: [PATCH 225/254] kill_app.py: Kill selected application This test is substitution (successor) for tests like rv_disconnect where the one and only purpose is to kill application and check exit code. Signed-off-by: Vaclav Ehrlich <vehrlich@redhat.com> --- tests/kill_app.py | 57 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 tests/kill_app.py diff --git a/tests/kill_app.py b/tests/kill_app.py new file mode 100644 index 000000000..6f4467ddf --- /dev/null +++ b/tests/kill_app.py @@ -0,0 +1,57 @@ +""" +kill_app.py - Kill specific application. + +This test was created as a successor of almost the same rv_disconnect and +rv_video_close tests. +Simply close selected app. If app is not running, ends with error. Application +could be closed during migration or for any unwanted reason. This test checks +if application is running when it should . + +""" +import logging, os +from autotest.client.shared import error + +def run_kill_app(test, params, env): + """ + Test kills application. Application is given by name kill_app_name in + params. + It has to be defined if application is on guest or client with parameter + kill_on_vms which should contain name(s) of vm(s) (separated with ',') + + @param test: KVM test object. + @param params: Dictionary with the test parameters. + @param env: Dictionary with test environment. + """ + kill_on_vms = params.get("kill_on_vms", "") + vms = kill_on_vms.split(',') + app_name = params.get("kill_app_name", None) + logging.debug("vms %s", vms) + if not vms: + raise error.TestFail("Kill app test launched without any VM parameter") + else: + for vm in vms: + logging.debug("vm %s", vm) + if params.has_key(vm): + kill_app(vm, app_name, params, env) + +def kill_app(vm_name, app_name, params, env): + """ + Kill selected app on selected VM + + @params vm_name - VM name in parameters + @params app_name - name of application + """ + vm = env.get_vm(params[vm_name]) + + vm.verify_alive() + vm_session = vm.wait_for_login( + timeout=int(params.get("login_timeout", 360))) + #get PID of remote-viewer and kill it + logging.info("Get PID of %s", app_name) + vm_session.cmd("pgrep %s" % app_name) + + logging.info("Try to kill %s", app_name) + vm_session.cmd("pkill %s" % app_name \ + .split(os.path.sep)[-1]) + vm.verify_alive() + vm_session.close() From 8ec10a3e0bf9097ee8e6fc86141639d6ba018192 Mon Sep 17 00:00:00 2001 From: Vaclav Ehrlich <vehrlich@redhat.com> Date: Fri, 21 Dec 2012 13:36:31 +0100 Subject: [PATCH 226/254] rv_disconnect: Remove test This test is substituted by kill_application test. Signed-off-by: Vaclav Ehrlich <vehrlich@redhat.com> --- tests/rv_disconnect.py | 38 -------------------------------------- 1 file changed, 38 deletions(-) delete mode 100644 tests/rv_disconnect.py diff --git a/tests/rv_disconnect.py b/tests/rv_disconnect.py deleted file mode 100644 index a72fe7228..000000000 --- a/tests/rv_disconnect.py +++ /dev/null @@ -1,38 +0,0 @@ -""" -rv_disconnect.py - disconnect remote-viewer - -Requires: connected binaries remote-viewer, Xorg, gnome session - -""" -import logging, os - -def run_rv_disconnect(test, params, env): - """ - Tests disconnection of remote-viewer. - - @param test: QEMU test object. @param params: Dictionary with the test parameters. - @param env: Dictionary with test environment. - """ - - guest_vm = env.get_vm(params["guest_vm"]) - guest_vm.verify_alive() - guest_session = guest_vm.wait_for_login( - timeout=int(params.get("login_timeout", 360))) - - client_vm = env.get_vm(params["client_vm"]) - client_vm.verify_alive() - client_session = client_vm.wait_for_login( - timeout=int(params.get("login_timeout", 360))) - - #get PID of remote-viewer and kill it - logging.info("Get PID of remote-viewer") - client_session.cmd("pgrep remote-viewer") - - logging.info("Try to kill remote-viewer") - client_session.cmd("pkill %s" % params.get("rv_binary")\ - .split(os.path.sep)[-1]) - - guest_vm.verify_alive() - - client_session.close() - guest_session.close() From a6ca395ba47a39da6ef1b361eccff2f9d85bbf05 Mon Sep 17 00:00:00 2001 From: Vaclav Ehrlich <vehrlich@redhat.com> Date: Mon, 28 Jan 2013 18:50:13 +0100 Subject: [PATCH 227/254] rv_video.py: Spice video test Test of video playback. Could be played in loop/one time, fullscreen/windowed. Signed-off-by: Vaclav Ehrlich <vehrlich@redhat.com> --- tests/rv_video.py | 82 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 tests/rv_video.py diff --git a/tests/rv_video.py b/tests/rv_video.py new file mode 100644 index 000000000..ca3f788a6 --- /dev/null +++ b/tests/rv_video.py @@ -0,0 +1,82 @@ +""" +rv_video.py - Starts video player +Video is played in a loop, usually kill_app +test should be called later to close totem. + +Requires: binaries Xorg, totem, gnome-session + Test starts video player + +""" +import logging, os +from virttest import utils_misc, remote + + +def launch_totem(guest_session, params): + """ + Launch Totem player + + @param guest_vm - vm object + """ + + totem_version = guest_session.cmd('totem --version') + logging.info("Totem version", totem_version) + + #repeat parameters for totem + logging.info("Set up video repeat to '%s' to the Totem.", + params.get("repeat_video")) + + if params.get("repeat_video") == "yes": + cmd = "gconftool-2 --set /apps/totem/repeat -t bool true" + else: + cmd = "gconftool-2 --set /apps/totem/repeat -t bool false" + + guest_session.cmd(cmd) + + cmd = "export DISPLAY=:0.0" + guest_session.cmd(cmd) + + #fullscreen parameters for totem + if params.get("fullscreen"): + fullscreen = " --fullscreen " + else: + fullscreen = "" + + cmd = "nohup totem %s %s --display=:0.0 --play &> /dev/null &" \ + % (fullscreen, params.get("destination_video_file_path")) + guest_session.cmd(cmd) + +def deploy_video_file(test, vm_obj, params): + """ + Deploy video file into destination on vm + + @param vm_obj - vm object + @param params: Dictionary with the test parameters. + """ + source_video_file = params.get("source_video_file") + video_dir = os.path.join("deps", source_video_file) + video_path = utils_misc.get_path(test.virtdir, video_dir) + + remote.copy_files_to(vm_obj.get_address(), 'scp', + params.get("username"), + params.get("password"), + params.get("shell_port"), + video_path, + params.get("destination_video_file_path")) + +def run_rv_video(test, params, env): + """ + Test of video through spice + + @param test: KVM test object. + @param params: Dictionary with the test parameters. + @param env: Dictionary with test environment. + """ + + guest_vm = env.get_vm(params["guest_vm"]) + guest_vm.verify_alive() + guest_session = guest_vm.wait_for_login( + timeout=int(params.get("login_timeout", 360))) + deploy_video_file(test, guest_vm, params) + + launch_totem(guest_session, params) + guest_session.close() From db216cd1a060a7f33c4ab210b7dab8b9af7a8e65 Mon Sep 17 00:00:00 2001 From: Marian Krcmarik <mkrcmari@redhat.com> Date: Mon, 3 Jun 2013 20:47:55 +0200 Subject: [PATCH 228/254] rv_connect: SSL, audio, smartcard, ipv6, menu updates. - remove kill_all function - support for 4 tests for host subject values for ssl tests Testing: valid explicit host subject value, valid implicit host subject value, invalid explicit host subject value, invalid implicit host subject value. - enable connecting using menu and not cli Done by adding a new parameter (rv_menu) and handling it accordingly Also renames and modifies send_ticket(), as this function is now more generic and allows sending of arbitrary strings; the new function might later be moved to qemu_vm.py or some utils - add support for disable audio option - add support for smartcard options - add possibility to connect to ipv6 address Signed-off-by: Tomas Jamrisko <tjamrisk@redhat.com> Signed-off-by: Vimal Patel <vipatel@redhat.com> Signed-off-by: Marian Krcmarik <mkrcmari@redhat.com> --- tests/rv_connect.py | 131 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 112 insertions(+), 19 deletions(-) diff --git a/tests/rv_connect.py b/tests/rv_connect.py index 4b4d03cf7..a6037e231 100644 --- a/tests/rv_connect.py +++ b/tests/rv_connect.py @@ -5,20 +5,28 @@ Use example kickstart RHEL-6-spice.ks """ -import logging, os +import logging, sys, socket from virttest.aexpect import ShellStatusError from virttest.aexpect import ShellProcessTerminatedError -from virttest import utils_net, utils_spice, remote +from virttest import utils_net, utils_spice, remote, utils_misc from autotest.client.shared import error -def send_ticket(client_vm, ticket): +def str_input(client_vm, ticket): """ sends spice_password trough vm.send_key() @param client_session - vm() object @param ticket - use params.get("spice_password") """ logging.info("Passing ticket '%s' to the remote-viewer.", ticket) + char_mapping = {":": "shift-semicolon", + ",": "comma", + ".": "dot", + "/": "slash", + "?": "shift-slash", + "=": "equal"} for character in ticket: + if character in char_mapping: + character = char_mapping[character] client_vm.send_key(character) client_vm.send_key("kp_enter") # send enter @@ -36,16 +44,6 @@ def print_rv_version(client_session, rv_binary): client_session.cmd(rv_binary + " --spice-gtk-version")) -def killall(client_session, pth): - """ - calls killall execname - @params client_session - @params pth - path or execname - """ - execname = pth.split(os.path.sep)[-1] - client_session.cmd("killall %s &> /dev/null" % execname, ok_status=[0, 1]) - - def launch_rv(client_vm, guest_vm, params): """ Launches rv_binary with args based on spice configuration @@ -58,14 +56,24 @@ def launch_rv(client_vm, guest_vm, params): """ rv_binary = params.get("rv_binary", "remote-viewer") host_ip = utils_net.get_host_ip_address(params) + if guest_vm.get_spice_var("listening_addr") == "ipv6": + host_ip = "[" + utils_misc.convert_ipv4_to_ipv6(host_ip) + "]" + check_spice_info = params.get("spice_info") + ssltype = params.get("ssltype") test_type = params.get("test_type") host_port = None full_screen = params.get("full_screen") + disable_audio = params.get("disable_audio", "no") display = params.get("display") - cmd = rv_binary + " --display=:0.0" ticket = None ticket_send = params.get("spice_password_send") qemu_ticket = params.get("qemu_password") + gencerts = params.get("gencerts") + certdb = params.get("certdb") + smartcard = params.get("smartcard") + menu = params.get("rv_menu", None) + #cmd var keeps final remote-viewer command line to be executed on client + cmd = rv_binary + " --display=:0.0" #If qemu_ticket is set, set the password of the VM using the qemu-monitor if qemu_ticket: @@ -89,9 +97,27 @@ def launch_rv(client_vm, guest_vm, params): #first character (it's '/') host_subj = guest_vm.get_spice_var("spice_x509_server_subj") host_subj = host_subj.replace('/', ',')[1:] + if ssltype == "invalid_explicit_hs": + host_subj = "Invalid Explicit HS" + else: + host_subj += host_ip + + # If it's invalid implicit, a remote-viewer connection + # will be attempted with the hostname, since ssl certs were + # generated with the ip address + hostname = socket.gethostname() + if ssltype == "invalid_implicit_hs": + spice_url = " spice://%s?tls-port=%s\&port=%s" % (hostname, + host_tls_port, host_port) + else: + spice_url = " spice://%s?tls-port=%s\&port=%s" % (host_ip, + host_tls_port, host_port) + + if menu == "yes": + line = spice_url + else: + cmd += spice_url - cmd += " spice://%s?tls-port=%s\&port=%s" % (host_ip, host_tls_port, - host_port) cmd += " --spice-ca-file=%s" % cacert if params.get("spice_client_host_subject") == "yes": @@ -108,7 +134,12 @@ def launch_rv(client_vm, guest_vm, params): cacert, cacert) else: host_port = guest_vm.get_spice_var("spice_port") - cmd += " spice://%s?port=%s" % (host_ip, host_port) + if menu == "yes": + #line to be sent through monitor once r-v is started + #without spice url + line = "spice://%s?port=%s" % (host_ip, host_port) + else: + cmd += " spice://%s?port=%s" % (host_ip, host_port) elif display == "vnc": raise NotImplementedError("remote-viewer vnc") @@ -121,6 +152,24 @@ def launch_rv(client_vm, guest_vm, params): logging.info("Remote Viewer Set to use Full Screen") cmd += " --full-screen" + if disable_audio == "yes": + logging.info("Remote Viewer Set to disable audio") + cmd += " --spice-disable-audio" + + # Check to see if the test is using a smartcard. + if smartcard == "yes": + logging.info("remote viewer Set to use a smartcard") + cmd += " --spice-smartcard" + + if certdb != None: + logging.debug("Remote Viewer set to use the following certificate" + " database: " + certdb) + cmd += " --spice-smartcard-db " + certdb + + if gencerts != None: + logging.debug("Remote Viewer set to use the following certs: " + + gencerts) + cmd += " --spice-smartcard-certificates " + gencerts cmd = "nohup " + cmd + " &> /dev/null &" # Launch it on background @@ -140,27 +189,71 @@ def launch_rv(client_vm, guest_vm, params): logging.debug("Ignoring a status exception, will check connection of" "remote-viewer later") + #Send command line through monitor since r-v was started without spice url + if menu == "yes": + utils_spice.wait_timeout(1) + str_input(client_vm, line) + client_vm.send_key("tab") + client_vm.send_key("tab") + client_vm.send_key("tab") + client_vm.send_key("kp_enter") + # client waits for user entry (authentication) if spice_password is set # use qemu monitor password if set, else check if the normal password is set if qemu_ticket: # Wait for remote-viewer to launch utils_spice.wait_timeout(5) - send_ticket(client_vm, qemu_ticket) + str_input(client_vm, qemu_ticket) elif ticket: if ticket_send: ticket = ticket_send utils_spice.wait_timeout(5) # Wait for remote-viewer to launch - send_ticket(client_vm, ticket) + str_input(client_vm, ticket) + utils_spice.wait_timeout(5) # Wait for conncetion to establish + is_rv_connected = True try: utils_spice.verify_established(client_vm, host_ip, host_port, rv_binary) except utils_spice.RVConnectError: if test_type == "negative": logging.info("remote-viewer connection failed as expected") + if ssltype in ("invalid_implicit_hs", "invalid_explicit_hs"): + #Check the qemu process output to verify what is expected + qemulog = guest_vm.process.get_output() + if "SSL_accept failed" in qemulog: + return + else: + raise error.TestFail("SSL_accept failed not shown in qemu" + + "process as expected.") + is_rv_connected = False else: raise error.TestFail("remote-viewer connection failed") + if test_type == "negative" and is_rv_connected: + raise error.TestFail("remote-viewer connection was established when" + + " it was supposed to be unsuccessful") + + #Get spice info + output = guest_vm.monitor.cmd("info spice") + logging.debug("INFO SPICE") + logging.debug(output) + + # Check to see if ipv6 address is reported back from qemu monitor + if (check_spice_info == "ipv6"): + logging.info("Test to check if ipv6 address is reported" + " back from the qemu monitor") + #Remove brackets from ipv6 host ip + if (host_ip[1:len(host_ip)-1] in output): + logging.info("Reported ipv6 address found in output from" + " 'info spice'") + else: + raise error.TestFail("ipv6 address not found from qemu monitor" + " command: 'info spice'") + else: + logging.info("Not checking the value of 'info spice'" + " from the qemu monitor") + #prevent from kill remote-viewer after test finish cmd = "disown -ar" client_session.cmd(cmd) From 98a3d2c8e0672c12d2d36396d22ca50b13feab8d Mon Sep 17 00:00:00 2001 From: Tomas Jamrisko <tjamrisk@redhat.com> Date: Tue, 26 Feb 2013 17:28:23 -0500 Subject: [PATCH 229/254] virttest/qemu_vm.py: spice related updates. - add support to add the ip address for SSL Host Subject tests. - add support for semicolon - fix used port if VM running Previously, when the VM was already running the spice_port for the VM was automatically generated anyway -> VM had incorrect parameters and connection failed. This patch makes sure, that spice_port with which the VM got created will persist between launches of autotest. - suppport to set VM listening address. Listening address can be none, explicit ipv4 or an explicit ipv6 address. - add getting spice info from the qemu monitor - add devices needed for smartcard support Signed-off-by: Vimal Patel <vipatel@redhat.com> Signed-off-by: Tomas Jamrisko <tjamrisk@redhat.com> --- virttest/qemu_vm.py | 80 +++++++++++++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 20 deletions(-) diff --git a/virttest/qemu_vm.py b/virttest/qemu_vm.py index 8fbd2100e..0a92e270f 100644 --- a/virttest/qemu_vm.py +++ b/virttest/qemu_vm.py @@ -1017,22 +1017,42 @@ def set_value(opt_string, key, fallback=None): spice_opts.append(fallback) s_port = str(utils_misc.find_free_port(*port_range)) if optget("spice_port") == "generate": - self.spice_options['spice_port'] = s_port - spice_opts.append("port=%s" % s_port) + if not self.is_alive(): + self.spice_options['spice_port'] = s_port + spice_opts.append("port=%s" % s_port) + self.spice_port = s_port + else: + self.spice_options['spice_port'] = self.spice_port + spice_opts.append("port=%s" % self.spice_port) else: set_value("port=%s", "spice_port") set_value("password=%s", "spice_password", "disable-ticketing") - set_yes_no_value("disable_copy_paste", - yes_value="disable-copy-paste") + if optget("listening_addr") == "ipv4": + host_ip = utils_net.get_host_ip_address(self.params) + self.spice_options['listening_addr'] = "ipv4" + spice_opts.append("addr=%s" % host_ip) + #set_value("addr=%s", "listening_addr", ) + elif optget("listening_addr") == "ipv6": + host_ip = utils_net.get_host_ip_address(self.params) + host_ip_ipv6 = utils_misc.convert_ipv4_to_ipv6(host_ip) + self.spice_options['listening_addr'] = "ipv6" + spice_opts.append("addr=%s" % host_ip_ipv6) + + set_yes_no_value("disable_copy_paste", yes_value="disable-copy-paste") set_value("addr=%s", "spice_addr") if optget("spice_ssl") == "yes": # SSL only part t_port = str(utils_misc.find_free_port(*tls_port_range)) if optget("spice_tls_port") == "generate": - self.spice_options['spice_tls_port'] = t_port - spice_opts.append("tls-port=%s" % t_port) + if not self.is_alive(): + self.spice_options['spice_tls_port'] = t_port + spice_opts.append("tls-port=%s" % t_port) + self.spice_tls_port = t_port + else: + self.spice_options['spice_tls_port'] = self.spice_tls_port + spice_opts.append("tls-port=%s" % self.spice_tls_port) else: set_value("tls-port=%s", "spice_tls_port") @@ -1044,6 +1064,9 @@ def set_value(opt_string, key, fallback=None): # not longer accessiable via encrypted spice. c_subj = optget("spice_x509_cacert_subj") s_subj = optget("spice_x509_server_subj") + #If CN is not specified, add IP of host + if s_subj[-3:] == "CN=": + s_subj += utils_net.get_host_ip_address(self.params) passwd = optget("spice_x509_key_password") secure = optget("spice_x509_secure") @@ -1276,6 +1299,13 @@ def add_option_rom(devices, opt_rom): return " -option-rom %s" % opt_rom + def add_smartcard(devices, sc_chardev, sc_id): + sc_cmd = " -device usb-ccid,id=ccid0" + sc_cmd += " -chardev " + sc_chardev + sc_cmd += ",id=" + sc_id + ",name=smartcard" + sc_cmd += " -device ccid-card-passthru,chardev=" + sc_id + + return sc_cmd # End of command line option wrappers @@ -1912,15 +1942,16 @@ def add_option_rom(devices, opt_rom): "spice_zlib_glz_wan_compression", "spice_streaming_video", "spice_agent_mouse", "spice_playback_compression", "spice_ipv4", "spice_ipv6", "spice_x509_cert_file", - "disable_copy_paste", "spice_seamless_migration" + "disable_copy_paste", "spice_seamless_migration", + "listening_addr" ) - for skey in spice_keys: - value = params.get(skey, None) - if value: - self.spice_options[skey] = value + for skey in spice_keys: + value = params.get(skey, None) + if value: + self.spice_options[skey] = value - cmd += add_spice() + cmd += add_spice() if cmd: devices.insert(StrDev('display', cmdline=cmd)) @@ -2031,6 +2062,12 @@ def add_option_rom(devices, opt_rom): if params.get("enable_sga") == "yes": devices.insert(StrDev('sga', cmdline=add_sga(devices))) + if params.get("smartcard", "no") == "yes": + sc_chardev = params.get("smartcard_chardev") + sc_id = params.get("smartcard_id") + devices.insert(StrDev('smartcard', + cmdline=add_smartcard(devices, sc_chardev, sc_id))) + if params.get("enable_watchdog", "no") == "yes": cmd = add_watchdog(devices, params.get("watchdog_device_type", None), @@ -3186,7 +3223,9 @@ def migrate(self, timeout=virt_vm.BaseVM.MIGRATE_TIMEOUT, protocol="tcp", "") cert_s = clone.spice_options.get("spice_x509_server_subj", "") - cert_subj = "\"%s\"" % cert_s.replace('/', ',')[1:] + cert_subj = "%s" % cert_s.replace('/',',')[1:] + cert_subj += host_ip + cert_subj = "\"%s\"" % cert_subj else: dest_tls_port = "" cert_subj = "" @@ -3202,17 +3241,17 @@ def migrate(self, timeout=virt_vm.BaseVM.MIGRATE_TIMEOUT, protocol="tcp", continue # spice_migrate_info requires host_ip, dest_port # client_migrate_info also requires protocol - cmdline = "%s hostname=%s" % (command, host_ip) + cmdline = "%s %s" % (command, host_ip) if command == "client_migrate_info": - cmdline += ",protocol=%s" % self.params['display'] + cmdline += " %s" % self.params['display'] if dest_port: - cmdline += ",port=%s" % dest_port + cmdline += " %s" % dest_port if dest_tls_port: - cmdline += ",tls-port=%s" % dest_tls_port + cmdline += " %s" % dest_tls_port if cert_subj: - cmdline += ",cert-subject=%s" % cert_subj + cmdline += " %s" % cert_subj break - self.monitor.send_args_cmd(cmdline) + self.monitor.send_args_cmd(cmdline,convert=False) if protocol in [ "tcp", "rdma", "x-rdma" ]: if local: @@ -3380,7 +3419,8 @@ def send_key(self, keystr): # For compatibility with versions of QEMU that do not recognize all # key names: replace keyname with the hex value from the dict, which # QEMU will definitely accept - key_mapping = {"comma": "0x33", + key_mapping = {"semicolon": "0x27", + "comma": "0x33", "dot": "0x34", "slash": "0x35"} for key, value in key_mapping.items(): From 4107eead0dafee074341361ebe30b8d912aa4085 Mon Sep 17 00:00:00 2001 From: Tomas Jamrisko <tjamrisk@redhat.com> Date: Wed, 27 Mar 2013 17:05:17 +0100 Subject: [PATCH 230/254] tests/rv_audio.py: Adds rv_audio test This tests audio between client and guest Signed-off-by: Tomas Jamrisko <tjamrisk@redhat.com> --- tests/rv_audio.py | 123 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 tests/rv_audio.py diff --git a/tests/rv_audio.py b/tests/rv_audio.py new file mode 100644 index 000000000..4834abb27 --- /dev/null +++ b/tests/rv_audio.py @@ -0,0 +1,123 @@ +""" +rv_audio.py - play audio playback / record on guest +and detect any pauses in the audio stream. + +Requires: rv_connect test + +""" +import logging +from autotest.client.shared import error, utils + +def verify_recording(recording, params): + """Tests whether something was actually recorded + + Threshold is a number of bytes which have to be zeros, in order to + record an unacceptable pause. + 11000 bytes is ~ 0.06236s (at 44100 Hz sampling, 16 bit depth + and stereo) + """ + rec = open(recording).read() + + disable_audio = params.get("disable_audio", "no") + threshold = int(params.get("rv_audio_threshold", "15000")) + config_test = params.get("config_test", None) + + if (len(rec) - rec.count('\0') < 50): + logging.info("Recording is empty") + if disable_audio != "yes": + return False + else: + return True + + pauses = [] + pause = False + try: + for index, value in enumerate(rec): + if value == '\0': + if not pause: + pauses.append([index]) + pause = True + else: + if pause: + pauses[-1].append(index-1) + pause = False + if (pauses[-1][1] - pauses[-1][0]) < threshold: + pauses.pop() + + if len(pauses): + logging.error("%d pauses detected:", len(pauses)) + for i in pauses: + logging.info("start: %10fs duration: %10fs" % ( + (float(i[0]) / (2*2*44100)), + (float(i[1]-i[0]) / (2*2*44100)) + )) + #Two small hiccups are allowed when migrating + if len(pauses) < 3 and config_test == "migration": + return True + else: + return False + else: + logging.info("No pauses detected") + + except IndexError: + #Too long pause, overflow in index + return False + + return True + +def run_rv_audio(test, params, env): + + guest_vm = env.get_vm(params["guest_vm"]) + guest_vm.verify_alive() + guest_session = guest_vm.wait_for_login( + timeout=int(params.get("login_timeout", 360))) + + client_vm = env.get_vm(params["client_vm"]) + client_vm.verify_alive() + client_session = client_vm.wait_for_login( + timeout=int(params.get("login_timeout", 360))) + + if(guest_session.cmd_status("ls %s" % params.get("audio_tgt"))): + print params.get("audio_src") + print params.get("audio_tgt") + guest_vm.copy_files_to( + params.get("audio_src"), + params.get("audio_tgt")) + if(client_session.cmd_status("ls %s" % params.get("audio_tgt"))): + client_vm.copy_files_to( + params.get("audio_src"), + params.get("audio_tgt")) + + if params.get("rv_record") == "yes": + logging.info("rv_record set; Testing recording") + player = client_vm.wait_for_login( + timeout=int(params.get("login_timeout", 360))) + recorder_session = guest_vm.wait_for_login( + timeout=int(params.get("login_timeout", 360))) + recorder_session_vm = guest_vm + else: + logging.info("rv_record not set; Testing playback") + player = guest_vm.wait_for_login( + timeout=int(params.get("login_timeout", 360))) + recorder_session = client_vm.wait_for_login( + timeout=int(params.get("login_timeout", 360))) + recorder_session_vm = client_vm + + player.cmd("aplay %s &> /dev/null &" % #starts playback + params.get("audio_tgt"), timeout = 30) + + if params.get("config_test", "no") == "migration": + bg = utils.InterruptedThread(guest_vm.migrate, kwargs={}) + bg.start() + + recorder_session.cmd("arecord -d %s -f cd -D hw:0,1 %s" % ( #records + params.get("audio_time","200"), #duration + params.get("audio_rec")), #target + timeout = 500) + + if params.get("config_test", "no") == "migration": + bg.join() + + recorder_session_vm.copy_files_from(params.get("audio_rec"),"./recorded.wav") + if not verify_recording("./recorded.wav", params): + raise error.TestFail("Test failed") From 64b656c0c8a42b270d1029bd942f4c7372379741 Mon Sep 17 00:00:00 2001 From: Vimal Patel <vipatel@redhat.com> Date: Thu, 25 Apr 2013 16:15:12 -0400 Subject: [PATCH 231/254] utils_misc.py: Add function to convert ipv4 address to ipv6 format. Signed-off-by: Vimal Patel <vipatel@redhat.com> --- virttest/utils_misc.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/virttest/utils_misc.py b/virttest/utils_misc.py index f9c9a229f..ed84cfaf9 100644 --- a/virttest/utils_misc.py +++ b/virttest/utils_misc.py @@ -1103,6 +1103,39 @@ def create_x509_dir(path, cacert_subj, server_subj, passphrase, utils.run(cmd) logging.info(cmd) +def convert_ipv4_to_ipv6(ipv4): + """ + Translates a passed in string of an ipv4 address to an ipv6 address. + + @param ipv4: a string of an ipv4 address + """ + + converted_ip = "::ffff:" + split_ipaddress = ipv4.split('.') + try: + socket.inet_aton(ipv4) + except socket.error: + raise ValueError("ipv4 to be converted is invalid") + if (len(split_ipaddress) != 4): + raise ValueError("ipv4 address is not in dotted quad format") + + for index, string in enumerate(split_ipaddress): + if index != 1: + test = str(hex(int(string)).split('x')[1]) + if len(test) == 1: + final = "0" + final+=test + test = final + else: + test = str(hex(int(string)).split('x')[1]) + if len(test) == 1: + final = "0" + final+=test+":" + test = final + else: + test += ":" + converted_ip += test + return converted_ip class NumaNode(object): """ From 9ef59f01afb43e24bf44c9dd83f8064f34cf9371 Mon Sep 17 00:00:00 2001 From: Marian Krcmarik <mkrcmari@redhat.com> Date: Sat, 8 Jun 2013 02:00:42 +0200 Subject: [PATCH 232/254] qemu/tests/cfg/spice.cfg: Add spice tests. - migration test - audio test - smartcard test - video test - vdagent test Signed-off-by: Marian Krcmarik <mkrcmari@redhat.com> --- qemu/tests/cfg/spice.cfg | 51 +++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/qemu/tests/cfg/spice.cfg b/qemu/tests/cfg/spice.cfg index 96edbb117..67ee0857b 100644 --- a/qemu/tests/cfg/spice.cfg +++ b/qemu/tests/cfg/spice.cfg @@ -21,15 +21,42 @@ -RHEL.6.devel.i386: image_name_vm2 = images/rhel6devel-32_client variants: - -fullscreen_setup: + - fullscreen_setup: type = fullscreen_setup - -rv_connect: + - smartcard_setup: + type = smartcard_setup + - rv_connect: type = rv_connect - -rv_disconnect: rv_connect - type = rv_disconnect - -rv_fullscreen: fullscreen_setup, rv_connect + - rv_video: + type = rv_video + video_binary = totem + repeat_video = "yes" + source_video_file = video_sample_test.ogv + destination_video_file_path = /tmp/test.ogv + - rv_migrate: + type = migration + main_vm = vm1 + migrate_background = yes + migration_test_command = help + #migration_bg_command = "cd /tmp; nohup tcpdump -q -i any -t ip host localhost" + #migration_bg_check_command = pgrep tcpdump + #migration_bg_kill_command = pkill tcpdump + kill_vm_on_error = yes + iterations = 2 + used_mem = 1024 + mig_timeout = 3600 + migration_protocol = "tcp" + variants: + - @default: + - with_set_speed: + mig_speed = 1G + pre_migrate = "mig_set_speed" + - with_reboot: + iterations = 1 + type = migration_with_reboot + - rv_fullscreen: fullscreen_setup, rv_connect type = rv_fullscreen - -rv_copyandpaste: rv_connect + - rv_copyandpaste: rv_connect type = rv_copyandpaste interpreter = python dst_dir = /tmp @@ -50,6 +77,8 @@ - rv_input: rv_connect type = rv_input guest_script = key_event_form.py + - rv_audio: rv_connect + type = rv_audio - rv_logging: rv_connect type = rv_logging logtest = qxl @@ -60,10 +89,20 @@ guest_script = cb.py script_params = --set text_to_test = Testing_this_text_was_copied + - rv_vdagent: rv_connect + type = rv_vdagent + vdagent_test = start + - rv_smartcard: rv_connect + type = rv_smartcard + - rv_disconnect: rv_connect + type = kill_app - rv_vmshutdown: rv_connect type = rv_vmshutdown cmd_cli_shutdown = "shutdown -h now" cmd_qemu_shutdown = "system_powerdown" + - rv_clearx: + type = rv_clearx + kill_vm = no - client_guest_shutdown: type = client_guest_shutdown shutdown_method = shell From abae4b2c798da80a5f67e6c00729424c6e94431e Mon Sep 17 00:00:00 2001 From: Marian Krcmarik <mkrcmari@redhat.com> Date: Sat, 8 Jun 2013 02:01:06 +0200 Subject: [PATCH 233/254] qemu/cfg/tests-spice.cfg: Add spice test variants - migration tests - smartcard tests - audio tests - r-v connect through menu - SSL subject tests - vdagent restart/start tests - ipv6 connect tests Signed-off-by: Marian Krcmarik <mkrcmari@redhat.com> --- qemu/cfg/tests-spice.cfg | 237 +++++++++++++++++++++++++++++++++------ 1 file changed, 201 insertions(+), 36 deletions(-) diff --git a/qemu/cfg/tests-spice.cfg b/qemu/cfg/tests-spice.cfg index 88030eefb..f3cfb3dd5 100644 --- a/qemu/cfg/tests-spice.cfg +++ b/qemu/cfg/tests-spice.cfg @@ -11,16 +11,20 @@ password=123456 # Use static MAC addresses for spice tests to have # the same IP in all test. -nics = nic1 nic2 -nics_vm1 = nic1 -nics_vm2 = nic2 -mac_nic1 = 9a:96:97:98:99:9a -mac_nic2 = 9a:9b:9c:9d:9e:9f +#nics = nic1 nic2 +#nics_vm1 = nic1 +#nics_vm2 = nic2 +#mac_nic1 = 9a:9a:97:98:99:9a +#mac_nic2 = 9a:9a:9c:9d:9e:9f qemu_binary = /usr/libexec/qemu-kvm qemu_img_binary = /usr/bin/qemu-img qemu_io_binary = /usr/bin/qemu-io rv_binary = /usr/bin/remote-viewer +spice_info = None +listening_addr = None +certdb=None +gencerts=None # Only qcow2 file format only qcow2 @@ -36,6 +40,10 @@ only no_9p_export only no_pci_assignable # No large memory pages only smallpages +# No gluster fs support +only no_glusterfs_support +# Only i440fx pc type +only i440fx variants: - qxl: @@ -56,6 +64,18 @@ variants: vga = qxl display = spice + variants: + - @default_sc: + smartcard = no + - smartcard: + smartcard = yes + smartcard_chardev = "spicevmc" + smartcard_id = "ccid" + usb_type_usb = piix3-usb-uhci + usbs_vm1 = usb + - no_smartcard: + smartcard = no + variants: - 1monitor: qxl_dev_nr = 1 @@ -76,6 +96,7 @@ variants: variants: - @no_password: + spice_password = - password: spice_password = 12456 variants: @@ -97,7 +118,7 @@ variants: spice_x509_cert_file = server-cert.pem spice_x509_key_password = testPassPhrase spice_x509_cacert_subj = /C=CZ/L=BRNO/O=SPICE/CN=my CA - spice_x509_server_subj = /C=CZ/L=BRNO/O=SPICE/CN=my Server + spice_x509_server_subj = /C=CZ/L=BRNO/O=SPICE/CN= spice_secure_channels = main, inputs spice_client_host_subject = yes variants: @@ -185,41 +206,41 @@ variants: - qemu_kvm_rhel6devel_install_client: image_name += "_client" only os.RHEL - only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor.default_sc only unattended_install.cdrom.extra_cdrom_ks # Runs qemu-kvm Windows guest install - @qemu_kvm_windows_install_guest: only os.Windows # Subtest choice. You can modify that line to add more subtests - only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor.default_sc only unattended_install.cdrom - qemu_kvm_rhel6devel_install_guest: only os.RHEL - only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor.default_sc only unattended_install.cdrom.extra_cdrom_ks - @remote_viewer_rhel6develssl: only os.RHEL - only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.ssl.key_password.password.dcp_off.1monitor - only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.client_guest_shutdown.RHEL.6.devel.x86_64 + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.ssl.key_password.password.dcp_off.1monitor.default_sc + only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_clearx.RHEL.6.devel.x86_64 - @remote_viewer_rhel6devel_quick: only os.RHEL - only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor - only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.client_guest_shutdown.RHEL.6.devel.x86_64 + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor.default_sc + only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_clearx.RHEL.6.devel.x86_64 - @remote_viewer_rhel6devel_password: only os.RHEL - only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.password.dcp_off.1monitor.default_sc only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.client_guest_shutdown.RHEL.6.devel.x86_64 - @remote_viewer_win_guest_quick: only os.Windows - only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor.default_sc #rv_connect_win is specifically a test meant for a windows guest and a rhel client, rv_connect cannot be used. - only rv.rw.rv_connect.RHEL.6.devel.x86_64, rv.rr.client_guest_shutdown.RHEL.6.devel.x86_64 + only rv.rw.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_clearx.RHEL.6.devel.x86_64 - @spice_negative_rhel6devel: only os.RHEL @@ -227,38 +248,85 @@ variants: - @rv_disconnect_rhel6devel: only os.RHEL - only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor - only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_disconnect.RHEL.6.devel.x86_64, rv.rr.client_guest_shutdown.RHEL.6.devel.x86_64 + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor.default_sc + only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_disconnect.RHEL.6.devel.x86_64, rv.rr.rv_clearx.RHEL.6.devel.x86_64 + + - @spice_migrate_rhel6devel: + kill_on_vms = "client_vm" + kill_app_name = "remote-viewer" + only os.RHEL + variants: + - no_ssl: + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor.default_sc + only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_migrate.default.RHEL.6.devel.x86_64, rv.rr.rv_disconnect.RHEL.6.devel.x86_64, rv.rr.rv_clearx.RHEL.6.devel.x86_64 + - ssl: + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.ssl.key_password.password.dcp_off.1monitor.default_sc + only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_migrate.default.RHEL.6.devel.x86_64, rv.rr.rv_disconnect.RHEL.6.devel.x86_64, rv.rr.rv_clearx.RHEL.6.devel.x86_64 + - ssl_reboot: + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.ssl.key_password.password.dcp_off.1monitor.default_sc + only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_migrate.with_reboot.RHEL.6.devel.x86_64, rv.rr.rv_disconnect.RHEL.6.devel.x86_64, rv.rr.rv_clearx.RHEL.6.devel.x86_64 + - ssl_video: + kill_app_name = "totem" + kill_on_vms = "guest_vm" + iterations = 1 + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.ssl.key_password.password.dcp_off.1monitor.default_sc + only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_video.RHEL.6.devel.x86_64, rv.rr.rv_migrate.default.RHEL.6.devel.x86_64, rv.rr.rv_disconnect.RHEL.6.devel.x86_64, rv.rr.rv_clearx.RHEL.6.devel.x86_64 + - ssl_vdagent: + config_test = "positive_client_to_guest" + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.ssl.key_password.password.dcp_off.1monitor.default_sc + only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_migrate.default.RHEL.6.devel.x86_64, rv.rr.rv_copyandpaste.RHEL.6.devel.x86_64, rv.rr.rv_disconnect.RHEL.6.devel.x86_64, rv.rr.rv_clearx.RHEL.6.devel.x86_64 - @rv_fullscreen_rhel6devel: spice_port=3000 only os.RHEL - only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor - only rv.rr.fullscreen_setup.RHEL.6.devel.x86_64, rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_fullscreen.RHEL.6.devel.x86_64, rv.rr.client_guest_shutdown.RHEL.6.devel.x86_64 + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor.default_sc + only rv.rr.fullscreen_setup.RHEL.6.devel.x86_64, rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_fullscreen.RHEL.6.devel.x86_64, rv.rr.rv_clearx.RHEL.6.devel.x86_64 + + - @rv_smartcard_rhel6devel: + spice_port=3000 + only os.RHEL + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor.smartcard + only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.smartcard_setup.RHEL.6.devel.x86_64, rv.rr.rv_smartcard.RHEL.6.devel.x86_64, rv.rr.rv_clearx.RHEL.6.devel.x86_64 - @rv_logging_rhel6devel: only os.RHEL - only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor - only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_logging.RHEL.6.devel.x86_64, rv.rr.client_guest_shutdown.RHEL.6.devel.x86_64 + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor.default_sc + only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_logging.RHEL.6.devel.x86_64, rv.rr.rv_clearx.RHEL.6.devel.x86_64 + + - @rv_vdagent_rhel6devel: + only os.RHEL + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor.default_sc + only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_vdagent.RHEL.6.devel.x86_64, rv.rr.rv_clearx.RHEL.6.devel.x86_64 - @rv_copyandpaste_rhel6devel: only os.RHEL - only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor - only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_copyandpaste.RHEL.6.devel.x86_64, rv.rr.client_guest_shutdown.RHEL.6.devel.x86_64 + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor.default_sc + only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_copyandpaste.RHEL.6.devel.x86_64, rv.rr.rv_clearx.RHEL.6.devel.x86_64 - @rv_copyandpaste_dcp_rhel6devel: only os.RHEL - only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_on.1monitor - only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_copyandpaste.RHEL.6.devel.x86_64, rv.rr.client_guest_shutdown.RHEL.6.devel.x86_64 + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_on.1monitor.default_sc + only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_copyandpaste.RHEL.6.devel.x86_64, rv.rr.rv_clearx.RHEL.6.devel.x86_64 - @rv_input_rhel6devel: only os.RHEL - only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor - only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_input.RHEL.6.devel.x86_64, rv.rr.client_guest_shutdown.RHEL.6.devel.x86_64 + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor.default_sc + only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_input.RHEL.6.devel.x86_64, rv.rr.rv_clearx.RHEL.6.devel.x86_64 + + - @rv_audio_rhel6devel: + only os.RHEL + soundcards_vm1 = hda + variants: + - pc: + only spice.default_ipv.pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor.default_sc + only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_audio.RHEL.6.devel.x86_64, rv.rr.rv_clearx.RHEL.6.devel.x86_64 + - no_pc: + only spice.default_ipv.no_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor.default_sc + only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_audio.RHEL.6.devel.x86_64, rv.rr.rv_clearx.RHEL.6.devel.x86_64 - @rv_vmshutdown_rhel6devel: only os.RHEL - only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor.default_sc only rv.rr.rv_connect.RHEL.6.devel.x86_64, rv.rr.rv_vmshutdown.RHEL.6.devel.x86_64, rv.rr.client_guest_shutdown.RHEL.6.devel.x86_64 variants: @@ -268,27 +336,41 @@ variants: - install_win_guest: only qemu_kvm_windows_install_guest - negative_qemu_spice_launch_badport: - only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.bad_port.no_password.dcp_off.1monitor + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.bad_port.no_password.dcp_off.1monitor.default_sc only spice_negative_rhel6devel - negative_qemu_spice_launch_badic: - only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.bad_ic.no_ssl.no_password.dcp_off.1monitor + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.default_jpeg_wc.bad_ic.no_ssl.no_password.dcp_off.1monitor.default_sc only spice_negative_rhel6devel - negative_qemu_spice_launch_badjpegwc: - only spice.default_ipv.default_pc.default_sv.default_zlib_wc.bad_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor + only spice.default_ipv.default_pc.default_sv.default_zlib_wc.bad_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor.default_sc only spice_negative_rhel6devel - negative_qemu_spice_launch_badzlib: - only spice.default_ipv.default_pc.default_sv.bad_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor + only spice.default_ipv.default_pc.default_sv.bad_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor.default_sc only spice_negative_rhel6devel - negative_qemu_spice_launch_badsv: - only spice.default_ipv.default_pc.bad_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor + only spice.default_ipv.default_pc.bad_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor.default_sc only spice_negative_rhel6devel - negative_qemu_spice_launch_badpc: - only spice.default_ipv.bad_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor + only spice.default_ipv.bad_pc.default_sv.default_zlib_wc.default_jpeg_wc.default_ic.no_ssl.no_password.dcp_off.1monitor.default_sc only spice_negative_rhel6devel - remote_viewer_test: only remote_viewer_rhel6devel_quick + #The following ipv6 test is not a true test of ipv6, it is converting an + #ipv4 address to ipv6, and verify the ipv6 format can be accepted. The pure + #ipv6 address cannot be tested because the network is not setup to support + #ipv6 + - remote_viewer_ipv6_addr: + listening_addr = ipv6 + only remote_viewer_rhel6devel_quick + - rv_qemu_report_ipv6: + listening_addr = ipv6 + spice_info = ipv6 + only remote_viewer_rhel6devel_quick - rv_connect_passwd: only remote_viewer_rhel6devel_password + - rv_connect_menu: + rv_menu=yes + only remote_viewer_rhel6devel_quick - rv_connect_wrong_passwd: test_type = negative spice_password_send = incorrectpass @@ -314,9 +396,51 @@ variants: - remote_viewer_winguest_test: only remote_viewer_win_guest_quick - remote_viewer_disconnect_test: + kill_app_name = "remote-viewer" + kill_on_vms = "client_vm" only rv_disconnect_rhel6devel - remote_viewer_ssl_test: + kill_app_name = "remote-viewer" + kill_on_vms = "client_vm" + only remote_viewer_rhel6develssl + - rv_ssl_explicit_hs: + ssltype = "explicit_hs" + only remote_viewer_rhel6develssl + - rv_ssl_implicit_hs: + ssltype = "implicit_hs" + spice_client_host_subject = no + only remote_viewer_rhel6develssl + - rv_ssl_invalid_explicit_hs: + test_type = negative + ssltype = "invalid_explicit_hs" + only remote_viewer_rhel6develssl + - rv_ssl_invalid_implicit_hs: + test_type = negative + spice_client_host_subject = no + ssltype = "invalid_implicit_hs" only remote_viewer_rhel6develssl + - spice_migrate_simple: + only spice_migrate_rhel6devel.no_ssl + - spice_migrate_ssl: + only spice_migrate_rhel6devel.ssl + - spice_migrate_reboot: + only spice_migrate_rhel6devel.ssl_reboot + - spice_migrate_video: + only spice_migrate_rhel6devel.ssl_video + - spice_migrate_vdagent: + only spice_migrate_rhel6devel.ssl_vdagent + - start_vdagent_test: + vdagent_test = start + only rv_vdagent_rhel6devel + - stop_vdagent_test: + vdagent_test = stop + only rv_vdagent_rhel6devel + - restart_start_vdagent_test: + vdagent_test = restart_start + only rv_vdagent_rhel6devel + - restart_stop_vdagent_test: + vdagent_test = restart_stop + only rv_vdagent_rhel6devel - copy_client_to_guest_pos: config_test = "positive_client_to_guest" only rv_copyandpaste_rhel6devel @@ -450,6 +574,47 @@ variants: full_screen = yes config_test = "leds_migration" only rv_input_rhel6devel + - audio_compression: + audio_tgt = "~/tone.wav" + audio_rec = "~/rec.wav" + audio_src = #path to your audio file (recommend generating a square/sine wave) + only rv_audio_rhel6devel.pc + - audio_no_compression: + audio_tgt = "~/tone.wav" + audio_rec = "~/rec.wav" + audio_src = #path to your audio file (recommend generating a square/sine wave) + only rv_audio_rhel6devel.no_pc + - disable_audio: + audio_tgt = "~/tone.wav" + audio_rec = "~/rec.wav" + audio_src = #path to your audio file (recommend generating a square/sine wave) + disable_audio = "yes" + only rv_audio_rhel6devel.pc + - migrate_audio: + audio_tgt = "~/tone.wav" + audio_rec = "~/rec.wav" + audio_src = #path to your audio file (recommend generating a square/sine wave) + config_test = migration + rv_audio_treshold = 529200 + only rv_audio_rhel6devel.pc + - remote_viewer_smartcard_certinfo: + smartcard_testtype = "pkcs11_listcerts" + gencerts = "cert1,cert2,cert3" + certdb = "/etc/pki/nssdb/" + self_sign = True + trustargs = "CT,CT,CT" + only rv_smartcard_rhel6devel + - remote_viewer_smartcard_certdetail: + smartcard_testtype = "pklogin_finder" + gencerts = "cert1,cert2,cert3" + certdb = "/etc/pki/nssdb/" + self_sign = True + trustargs = "CT,CT,CT" + certcheckstr = "Found '3' certificate(s)" + certcheckstr2 = "verifing the certificate #" + certcheck3 = "Couldn't verify Cert: Issuer certificate is invalid." + certcheck4 = "verify_certificate() failed:" + only rv_smartcard_rhel6devel - qxl_logging: only rv_logging_rhel6devel - spice_vdagent_logging: @@ -457,7 +622,7 @@ variants: only rv_logging_rhel6devel #Running all RHEL Client, RHEL Guest Spice Tests -only create_vms, negative_qemu_spice_launch_badport, negative_qemu_spice_launch_badic, negative_qemu_spice_launch_badjpegwc, negative_qemu_spice_launch_badzlib, negative_qemu_spice_launch_badsv, negative_qemu_spice_launch_badpc, remote_viewer_test, remote_viewer_ssl_test, remote_viewer_disconnect_test, guestvmshutdown_cmd, guestvmshutdown_qemu, copy_client_to_guest_largetext_pos, copy_guest_to_client_largetext_pos, copy_client_to_guest_pos, copy_guest_to_client_pos, copy_guest_to_client_neg, copy_client_to_guest_neg, copyimg_client_to_guest_pos, copyimg_client_to_guest_neg, copyimg_guest_to_client_pos, copyimg_guest_to_client_neg, copyimg_client_to_guest_dcp_neg, copyimg_guest_to_client_dcp_neg, copy_guest_to_client_dcp_neg, copy_client_to_guest_dcp_neg, copybmpimg_client_to_guest_pos, copybmpimg_guest_to_client_pos, copy_guest_to_client_largetext_10mb_pos, copy_client_to_guest_largetext_10mb_pos, copyimg_medium_client_to_guest_pos, copyimg_medium_guest_to_client_pos, copyimg_large_client_to_guest_pos, copyimg_large_guest_to_client_pos, restart_vdagent_copy_client_to_guest_pos, restart_vdagent_copy_guest_to_client_pos, restart_vdagent_copyimg_client_to_guest_pos, restart_vdagent_copyimg_guest_to_client_pos, restart_vdagent_copybmpimg_client_to_guest_pos, restart_vdagent_copybmpimg_guest_to_client_pos, restart_vdagent_copy_client_to_guest_largetext_pos, restart_vdagent_copy_guest_to_client_largetext_pos, remote_viewer_fullscreen_test, remote_viewer_fullscreen_test_neg, spice_vdagent_logging, qxl_logging, keyboard_input_leds_and_esc_keys, keyboard_input_non-us_layout, keyboard_input_type_and_func_keys, keyboard_input_leds_migration, rv_connect_passwd, rv_connect_wrong_passwd, rv_qemu_password, rv_qemu_password_overwrite +only create_vms, negative_qemu_spice_launch_badport, negative_qemu_spice_launch_badic, negative_qemu_spice_launch_badjpegwc, negative_qemu_spice_launch_badzlib, negative_qemu_spice_launch_badsv, negative_qemu_spice_launch_badpc, remote_viewer_test, remote_viewer_ssl_test, remote_viewer_disconnect_test, guestvmshutdown_cmd, guestvmshutdown_qemu, copy_client_to_guest_largetext_pos, copy_guest_to_client_largetext_pos, copy_client_to_guest_pos, copy_guest_to_client_pos, copy_guest_to_client_neg, copy_client_to_guest_neg, copyimg_client_to_guest_pos, copyimg_client_to_guest_neg, copyimg_guest_to_client_pos, copyimg_guest_to_client_neg, copyimg_client_to_guest_dcp_neg, copyimg_guest_to_client_dcp_neg, copy_guest_to_client_dcp_neg, copy_client_to_guest_dcp_neg, copybmpimg_client_to_guest_pos, copybmpimg_guest_to_client_pos, copy_guest_to_client_largetext_10mb_pos, copy_client_to_guest_largetext_10mb_pos, copyimg_medium_client_to_guest_pos, copyimg_medium_guest_to_client_pos, copyimg_large_client_to_guest_pos, copyimg_large_guest_to_client_pos, restart_vdagent_copy_client_to_guest_pos, restart_vdagent_copy_guest_to_client_pos, restart_vdagent_copyimg_client_to_guest_pos, restart_vdagent_copyimg_guest_to_client_pos, restart_vdagent_copybmpimg_client_to_guest_pos, restart_vdagent_copybmpimg_guest_to_client_pos, restart_vdagent_copy_client_to_guest_largetext_pos, restart_vdagent_copy_guest_to_client_largetext_pos, remote_viewer_fullscreen_test, remote_viewer_fullscreen_test_neg, spice_vdagent_logging, qxl_logging, keyboard_input_leds_and_esc_keys, keyboard_input_non-us_layout, keyboard_input_type_and_func_keys, keyboard_input_leds_migration, rv_connect_passwd, rv_connect_wrong_passwd, rv_qemu_password, rv_qemu_password_overwrite, spice_migrate_simple, spice_migrate_ssl, spice_migrate_reboot, spice_migrate_video, spice_migrate_vdagent, rv_ssl_invalid_explicit_hs, rv_ssl_invalid_implicit_hs, rv_ssl_implicit_hs, rv_ssl_explicit_hs, rv_connect_menu, audio_compression, audio_no_compression, disable_audio, migrate_audio, remote_viewer_ipv6_addr, rv_qemu_report_ipv6, start_vdagent_test, stop_vdagent_test, restart_start_vdagent_test, restart_stop_vdagent_test, remote_viewer_smartcard_certdetail, remote_viewer_smartcard_certinfo #Running all RHEL Client, Windows Guest Spice Tests #only install_win_guest, remote_viewer_winguest_test From 542a9160ce85c7d34bb82ad5f48edb6f893a3215 Mon Sep 17 00:00:00 2001 From: Vimal Patel <vipatel@redhat.com> Date: Thu, 9 May 2013 14:41:38 -0400 Subject: [PATCH 234/254] tests/rv_vdagent.py:Add basic tests to test the spice vdagent service. Adding 4 tests to test the spice vdagent service (a) starting vdagent, (b) stopping vdagent, (c) restarting vdagent when it is running, and (d) restarting vdagent when it is not running. Signed-off-by: Vimal Patel <vipatel@redhat.com> --- tests/rv_vdagent.py | 97 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 tests/rv_vdagent.py diff --git a/tests/rv_vdagent.py b/tests/rv_vdagent.py new file mode 100644 index 000000000..c4e93d9ce --- /dev/null +++ b/tests/rv_vdagent.py @@ -0,0 +1,97 @@ +""" +rv_vdagent.py - basic tests to verify, vdagent status, starting, stopping, +and restarting correctly. + +Requires: connected binaries remote-viewer, Xorg, gnome session + +""" +from autotest.client.shared import error +from virttest import utils_spice + +def run_rv_vdagent(test, params, env): + """ + Tests spice vdagent (starting, stopping, restarting, and status) + + @param test: QEMU test object. + @param params: Dictionary with the test parameters. + @param env: Dictionary with test environment. + """ + # Get necessary params + test_timeout = float(params.get("test_timeout", 600)) + vdagent_test = params.get("vdagent_test") + + guest_vm = env.get_vm(params["guest_vm"]) + guest_vm.verify_alive() + guest_root_session = guest_vm.wait_for_login( + timeout=int(params.get("login_timeout", 360)), + username="root", password="123456") + + client_vm = env.get_vm(params["client_vm"]) + client_vm.verify_alive() + client_session = client_vm.wait_for_login( + timeout=int(params.get("login_timeout", 360))) + + vdagent_status = utils_spice.get_vdagent_status(guest_root_session, test_timeout) + + #start test + if vdagent_test == "start": + if "running" in vdagent_status: + #stop the service prior to starting + utils_spice.stop_vdagent(guest_root_session, test_timeout) + utils_spice.start_vdagent(guest_root_session, test_timeout) + else: + utils_spice.start_vdagent(guest_root_session, test_timeout) + #Verify the status of vdagent is running + status = utils_spice.get_vdagent_status(guest_root_session, test_timeout) + if "running" in status: + pass + else: + raise error.TestFail("Vdagent status is not running after a start attempt.") + #stop test + elif vdagent_test == "stop": + if "stopped" in vdagent_status: + #start the service prior to stopping the service + utils_spice.start_vdagent(guest_root_session, test_timeout) + utils_spice.stop_vdagent(guest_root_session, test_timeout) + else: + utils_spice.stop_vdagent(guest_root_session, test_timeout) + #Verify the status of vdagent is stopped + status = utils_spice.get_vdagent_status(guest_root_session, test_timeout) + if "stopped" in status: + pass + else: + print "Status: " + status + raise error.TestFail("Vdagent status is not stopped after a stop attempt.") + #restart test when vdagent service is running + elif vdagent_test == "restart_start": + if "stopped" in vdagent_status: + #start the service prior to stopping the service + utils_spice.start_vdagent(guest_root_session, test_timeout) + utils_spice.restart_vdagent(guest_root_session, test_timeout) + else: + utils_spice.restart_vdagent(guest_root_session, test_timeout) + #Verify the status of vdagent is started + status = utils_spice.get_vdagent_status(guest_root_session, test_timeout) + if "running" in status: + pass + else: + raise error.TestFail("Vdagent status is not started after a restart attempt.") + #restart test when vdagent service is stopped + elif vdagent_test == "restart_stop": + if "running" in vdagent_status: + #start the service prior to stopping the service + utils_spice.stop_vdagent(guest_root_session, test_timeout) + utils_spice.restart_vdagent(guest_root_session, test_timeout) + else: + utils_spice.restart_vdagent(guest_root_session, test_timeout) + #Verify the status of vdagent is started + status = utils_spice.get_vdagent_status(guest_root_session, test_timeout) + if "running" in status: + pass + else: + raise error.TestFail("Vdagent status is not started after a restart attempt.") + else: + raise error.TestFail("No test to run, check value of vdagent_test") + + client_session.close() + guest_root_session.close() From 8c8562e8dc5f72890ece3a035f3a11652f1baffb Mon Sep 17 00:00:00 2001 From: Vimal Patel <vipatel@redhat.com> Date: Thu, 9 May 2013 13:12:50 -0400 Subject: [PATCH 235/254] virttest/utils_spice.py: Adding get_vdagent_status method. Signed-off-by: Vimal Patel <vipatel@redhat.com> --- virttest/utils_spice.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/virttest/utils_spice.py b/virttest/utils_spice.py index d113165d2..94718d135 100644 --- a/virttest/utils_spice.py +++ b/virttest/utils_spice.py @@ -2,7 +2,7 @@ Common spice test utility functions. """ -import os, logging, time +import os, logging, time, sys from autotest.client.shared import error from aexpect import ShellCmdError, ShellStatusError, ShellTimeoutError @@ -131,6 +131,26 @@ def verify_vdagent(guest_session, test_timeout): " is available ------------") wait_timeout(3) +def get_vdagent_status(vm_session, test_timeout): + """ + Return the status of vdagent + @param vm_session: ssh session of the VM + @param test_timeout: timeout time for the cmd + """ + output = "" + cmd = "service spice-vdagentd status" + + wait_timeout(3) + try: + output = vm_session.cmd(cmd, print_func=logging.info, timeout=test_timeout) + except ShellCmdError: + #getting the status of vdagent stopped returns 3, which results in a ShellCmdError + return("stopped") + except: + print "Unexpected error:", sys.exc_info()[0] + raise error.TestFail("Failed attempting to get status of spice-vdagentd") + wait_timeout(3) + return(output) def verify_virtio(guest_session, test_timeout): """ From 3f7c82e3222dcfa511be9b1e66cc9fdb5ffeb519 Mon Sep 17 00:00:00 2001 From: Vimal Patel <vipatel@redhat.com> Date: Fri, 24 May 2013 11:37:13 -0400 Subject: [PATCH 236/254] tests/rv_smartcard.py: Adding 2 Smart Card tests. Adding 2 software smart card tests: (1) Verifying the smartcard can be seen and certs in the smartcard can be seen. (2) Verifying the smartcard can be seen and details of the certs in smartcard can be obtained. Signed-off-by: Vimal Patel <vipatel@redhat.com> --- tests/rv_smartcard.py | 167 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 tests/rv_smartcard.py diff --git a/tests/rv_smartcard.py b/tests/rv_smartcard.py new file mode 100644 index 000000000..1b0339b42 --- /dev/null +++ b/tests/rv_smartcard.py @@ -0,0 +1,167 @@ +""" +rv_smartcard.py - Testing software smartcards using remote-viewer + +Requires: connected binaries remote-viewer, Xorg, gnome session + +The test also assumes that the guest is setup with the correct +options to handle smartcards. + +""" +import logging +from virttest import aexpect +from autotest.client.shared import error + + +def run_rv_smartcard(test, params, env): + """ + Tests disconnection of remote-viewer. + + @param test: QEMU test object. + @param params: Dictionary with the test parameters. + @param env: Dictionary with test environment. + """ + #Get the required parameters needed for the tests + cert_list = params.get("gencerts").split(",") + cert_db = params.get("certdb") + smartcard_testtype = params.get("smartcard_testtype") + listcerts_output = "" + certsinfo_output = "" + searchstr = params.get("certcheckstr") + certstr = params.get("certcheckstr2") + certcheck1 = params.get("certcheck3") + certcheck2 = params.get("certcheck4") + + guest_vm = env.get_vm(params["guest_vm"]) + guest_vm.verify_alive() + guest_session = guest_vm.wait_for_login( + timeout=int(params.get("login_timeout", 360)), + username="root", password="123456") + + client_vm = env.get_vm(params["client_vm"]) + client_vm.verify_alive() + + client_session = client_vm.wait_for_login( + timeout=int(params.get("login_timeout", 360)), + username="root", password="123456") + #Verify remote-viewer is running + try: + pid = client_session.cmd("pgrep remote-viewer") + logging.info("remote-viewer is running as PID %s", pid.strip()) + except: + raise error.TestFail("remote-viewer is not running") + + #verify the smart card reader can be seen + output = guest_session.cmd("lsusb") + logging.debug("lsusb output: " + output) + if "Gemplus GemPC433-Swap" in output: + logging.info("Smartcard reader, Gemplus GemPC433-Swap detected.") + else: + raise error.TestFail("No smartcard reader found") + + + if smartcard_testtype == "pkcs11_listcerts": + #pkcs11_listcerts not installed until Smart Card Support is installed + try: + output = guest_session.cmd_output("pkcs11_listcerts") + except aexpect.ShellTimeoutError: + #Expected to get a shell timeout error, + # listing certs prompts for PIN + try: + #Send a carriage return for PIN for token + listcerts_output = guest_session.cmd("") + except: + raise error.TestFail("Test failed trying to get the output" + " of pkcs11_listcerts") + + logging.info("Listing Certs available on the guest: " + + listcerts_output) + + for cert in cert_list: + subj_string = "CN=" + cert + if subj_string in listcerts_output: + logging.debug(subj_string + " has been found" + + " as a listed cert in the guest") + else: + raise error.TestFail("Certificate %s was not found as a listed" + " cert in the guest" % subj_string) + elif smartcard_testtype == "pklogin_finder": + #pkcs11_listcerts not installed until + #Smart Card Support is installed + try: + certsinfo_output = guest_session.cmd("pklogin_finder debug") + except aexpect.ShellTimeoutError: + #Expected to get a shell timeout error, + #listing certs prompts for PIN + try: + #Send a carriage return for PIN for token + certsinfo_output = guest_session.cmd("", ok_status=[0, 1]) + except: + raise error.TestFail("Test failed trying to get the output" + " of pklogin_finder") + testindex = certsinfo_output.find(searchstr) + if testindex >= 0: + string_aftercheck = certsinfo_output[testindex:] + + #Loop through the cert list. and check for the expected data, and + for index, cert in enumerate(cert_list): + subj_string = "CN=" + cert + checkstr = certstr + str(index+1) + testindex = string_aftercheck.find(checkstr) + #print testindex + if testindex >= 0: + logging.debug("Found " + checkstr + "in output of pklogin") + string_aftercheck = string_aftercheck[testindex:] + testindex2 = string_aftercheck.find(subj_string) + if testindex >= 0: + logging.debug("Found " + subj_string + + "in output of pklogin") + string_aftercheck = string_aftercheck[testindex2:] + testindex3 = string_aftercheck.find(certcheck1) + if testindex3 >= 0: + logging.debug("Found " + certcheck1 + + "in output of pklogin") + string_aftercheck = string_aftercheck[testindex3:] + testindex4 = string_aftercheck.find(certcheck2) + if testindex4 >= 0: + logging.debug("Found " + certcheck2 + + "in output of pklogin") + else: + raise error.TestFail(certcheck2 + " not found" + " in output of pklogin " + "on the guest") + else: + raise error.TestFail(certcheck1 + " not found in " + "output of pklogin on the" + " guest") + else: + raise error.TestFail("Common name %s, not found " + "in pkogin_finder after software " + "smartcard was inserted into the " + "guest" % subj_string) + + else: + raise error.TestFail(checkstr + " not found in output of " + "pklogin on the guest") + + else: + raise error.TestFail(searchstr + " not found in output of pklogin" + " on the guest") + + logging.info("Certs Info on the guest: " + certsinfo_output) + else: + raise error.TestFail("Please specify a valid smartcard testype") + + #Do some cleanup, remove the certs on the client + #for each cert listed by the test, create it on the client + for cert in cert_list: + cmd = "certutil " + cmd += "-D -n '" + cert + "' -d " + cert_db + try: + output = client_session.cmd(cmd) + except aexpect.ShellCmdError: + logging.warning("Deleting of %s certificate from the client failed", + cert) + logging.debug("Output of " + cmd + ": " + output) + + client_session.close() + guest_session.close() From 940d51de8290b65156da090005c9420701333380 Mon Sep 17 00:00:00 2001 From: Vimal Patel <vipatel@redhat.com> Date: Fri, 24 May 2013 11:35:57 -0400 Subject: [PATCH 237/254] tests/smartcard_setup.py:Adding a setup test for smartcards. The setup test will create certs on client that will be used by remote-viewer to pass as options to the VM. Signed-off-by: Vimal Patel <vipatel@redhat.com> --- tests/smartcard_setup.py | 73 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 tests/smartcard_setup.py diff --git a/tests/smartcard_setup.py b/tests/smartcard_setup.py new file mode 100644 index 000000000..814bbccfe --- /dev/null +++ b/tests/smartcard_setup.py @@ -0,0 +1,73 @@ +""" +smartcard_setup.py - Used as a setup test for smartcard tests. + +Before doing a remote viewer connection there is some setup required +for smartcard tests: + +On the client, certs that will be put into the smartcard will need +to be generated. + +""" +import logging +from virttest import utils_misc, utils_spice, aexpect +from autotest.client.shared import error + +def run_smartcard_setup(test, params, env): + """ + Simple setup test to create certs on the client to be passed to VM's + smartcard. + + @param test: QEMU test object. + @param params: Dictionary with the test parameters. + @param env: Dictionary with test environment. + """ + # Get necessary params + cert_list = params.get("gencerts").split(",") + cert_db = params.get("certdb") + self_sign = params.get("self_sign") + cert_trustargs = params.get("trustargs") + + logging.debug("Cert List:") + for cert in cert_list: + logging.debug(cert) + logging.debug(cert_trustargs) + logging.debug("CN=" + cert) + logging.debug(cert_db) + + + client_vm = env.get_vm(params["client_vm"]) + client_vm.verify_alive() + + client_session = client_vm.wait_for_login( + timeout=int(params.get("login_timeout", 360)), + username="root", password="123456") + + #generate a random string, used to create a random key for the certs + randomstring = utils_misc.generate_random_string(2048) + cmd = "echo '" + randomstring + "' > /tmp/randomtext.txt" + output = client_session.cmd(cmd) + #output2 = client_session.cmd("cat /tmp/randomtext.txt") + utils_spice.wait_timeout(5) + + #for each cert listed by the test, create it on the client + for cert in cert_list: + cmd = "certutil " + if self_sign: + cmd += " -x " + cmd += "-t '" + cert_trustargs + "' -S -s " + "'CN=" + cert + cmd += "' -n '" + cert + "' -d " + cert_db + cmd += " -z " + "/tmp/randomtext.txt" + logging.debug(cmd) + output = client_session.cmd(cmd) + logging.debug("Cert Created: " + output) + + cmd = "certutil -L -d " + cert_db + output = client_session.cmd(cmd) + logging.info("Listing all certs on the client: " + output) + + #Verify that all the certs have been generated on the client + for cert in cert_list: + if not(cert in output): + raise error.TestFail("Certificate %s not found" % cert) + + client_session.close() From 6d4920812f9c280b361965f393a0f24ef913dbf8 Mon Sep 17 00:00:00 2001 From: Tomas Jamrisko <tjamrisk@redhat.com> Date: Fri, 14 Jun 2013 14:46:55 +0200 Subject: [PATCH 238/254] tests/rv_clearx.py: Restarts X server by killing Xorg Signed-off-by: Tomas Jamrisko <tjamrisk@redhat.com> --- tests/rv_clearx.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 tests/rv_clearx.py diff --git a/tests/rv_clearx.py b/tests/rv_clearx.py new file mode 100644 index 000000000..b57c738c4 --- /dev/null +++ b/tests/rv_clearx.py @@ -0,0 +1,34 @@ +""" +This restarts the x server on all vms by killing gdm in order to eliminate any +side effects and running applications that might interfere with tests. +""" + +import logging +from autotest.client.shared import error +from virttest.aexpect import ShellCmdError +from virttest import utils_misc + +def is_pid_alive(session, pid): + + try: + session.cmd("ps -p %s" % pid) + except ShellCmdError: + return False + + return True + +def run_rv_clearx(test, params, env): + for vm_name in params.get("vms").split(): + vm = env.get_vm(vm_name) + logging.info("restarting X on: %s", vm_name) + session = vm.wait_for_login(username = "root", password = "123456", + timeout=int(params.get("login_timeout", 360))) + pid = session.cmd("pgrep Xorg") + session.cmd("killall Xorg") + + utils_misc.wait_for(lambda: is_pid_alive(session, pid), 10, 5, 0.2) + + try: + session.cmd("ps -C Xorg") + except: + raise error.TestFail("X not running") From aafc6d262dba0203e62ec4340d59ad082071b340 Mon Sep 17 00:00:00 2001 From: Marian Krcmarik <mkrcmari@redhat.com> Date: Mon, 17 Jun 2013 14:39:05 +0200 Subject: [PATCH 239/254] tests/rv_vmshutdown.py: Increase timeout for VM to be dead. Signed-off-by: Marian Krcmarik <mkrcmari@redhat.com> --- tests/rv_vmshutdown.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/rv_vmshutdown.py b/tests/rv_vmshutdown.py index a5ba1c966..7269d258f 100644 --- a/tests/rv_vmshutdown.py +++ b/tests/rv_vmshutdown.py @@ -71,7 +71,7 @@ def run_rv_vmshutdown(test, params, env): #wait for the guest vm to be shutoff logging.info("Waiting for the guest VM to be shutoff") - utils_misc.wait_for(guest_vm.is_dead, 70, 30, 1, "waiting...") + utils_misc.wait_for(guest_vm.is_dead, 90, 30, 1, "waiting...") logging.info("Guest VM is now shutoff") #Verify there was a clean exit by From bda945facb363bf03e30afbf336c19c633a70854 Mon Sep 17 00:00:00 2001 From: Marian Krcmarik <mkrcmari@redhat.com> Date: Mon, 24 Jun 2013 17:30:42 +0200 Subject: [PATCH 240/254] shared/downloads/video-sample.ini: Video file asset Add a video file asset definition which is a requirement for spice video test. Signed-off-by: Marian Krcmarik <mkrcmari@redhat.com> --- shared/downloads/video-sample.ini | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 shared/downloads/video-sample.ini diff --git a/shared/downloads/video-sample.ini b/shared/downloads/video-sample.ini new file mode 100644 index 000000000..5ee913331 --- /dev/null +++ b/shared/downloads/video-sample.ini @@ -0,0 +1,5 @@ +[video-sample] +title = Video sample for Spice tests +url = http://lmr.fedorapeople.org/video_sample/video_sample_test.ogv +sha1_url = http://lmr.fedorapeople.org/video_sample/SHA1SUM +destination = shared/deps/video_sample_test.ogv From bc0d6a6710349a62c0db55127d96846c3180ae00 Mon Sep 17 00:00:00 2001 From: Marian Krcmarik <mkrcmari@redhat.com> Date: Mon, 29 Jul 2013 16:09:11 +0200 Subject: [PATCH 241/254] shared/unattended/RHEL-6.3.ks - testing audio requires a loopback device This loads alsa loopback kernel modules by default at each start of our VMs. Note, that this does not modify the default devices. - add Smart Card support packages to the VMs for testing - add possibility to shutdown VM under test user Signed-off-by: Tomas Jamrisko <tjamrisk@redhat.com> Signed-off-by: Vimal Patel <vipatel@redhat.com> Signed-off-by: Marian Krcmarik <mkrcmari@redhat.com> --- shared/unattended/RHEL-6.3.ks | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/shared/unattended/RHEL-6.3.ks b/shared/unattended/RHEL-6.3.ks index 00cf1d8f3..649250fa0 100644 --- a/shared/unattended/RHEL-6.3.ks +++ b/shared/unattended/RHEL-6.3.ks @@ -29,6 +29,8 @@ KVM_TEST_LOGGING @network-tools @x11 @basic-desktop +@fonts +@Smart Card Support NetworkManager ntpdate watchdog @@ -39,6 +41,7 @@ virt-viewer spice-vdagent usbredir SDL +totem %end %post @@ -52,9 +55,22 @@ chkconfig NetworkManager on sed -i "/^HWADDR/d" /etc/sysconfig/network-scripts/ifcfg-eth0 echo 'Post set up finished' > /dev/ttyS0 echo Post set up finished > /dev/hvc0 -cat > '/mnt/sysimage/etc/gdm/custom.conf' << EOF +cat > '/etc/gdm/custom.conf' << EOF [daemon] AutomaticLogin=test AutomaticLoginEnable=True EOF +cat >> '/etc/sudoers' << EOF +test ALL = NOPASSWD: /sbin/shutdown -r now,/sbin/shutdown -h now +EOF +cat >> '/home/test/.bashrc' << EOF +alias shutdown='sudo shutdown' +EOF +cat >> '/etc/rc.modules' << EOF +modprobe snd-aloop +modprobe snd-pcm-oss +modprobe snd-mixer-oss +modprobe snd-seq-oss +EOF +chmod +x /etc/rc.modules %end From ae2f962f2b405053931b5cf65fa366670b703e70 Mon Sep 17 00:00:00 2001 From: Lucas Meneghel Rodrigues <lmr@redhat.com> Date: Wed, 7 Aug 2013 01:58:35 -0300 Subject: [PATCH 242/254] tests.rv_video: Fix logging parameters --- tests/rv_video.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/rv_video.py b/tests/rv_video.py index ca3f788a6..c2a3670a8 100644 --- a/tests/rv_video.py +++ b/tests/rv_video.py @@ -19,7 +19,7 @@ def launch_totem(guest_session, params): """ totem_version = guest_session.cmd('totem --version') - logging.info("Totem version", totem_version) + logging.info("Totem version: %s", totem_version) #repeat parameters for totem logging.info("Set up video repeat to '%s' to the Totem.", From 5683cdb05aa86047bc095da50a4efa01cdb3ccf7 Mon Sep 17 00:00:00 2001 From: yangdongsheng <yangds.fnst@cn.fujitsu.com> Date: Tue, 6 Aug 2013 20:56:35 +0800 Subject: [PATCH 243/254] libvirt: fix virsh edit test. * we can not assume the guest with 1 vcpu. Change the pattern in sed from `1<\/vcpu>` to `[0-9]*<\/vcpu>` * add a vcpucount function in virsh module. And use it in virsh_edit to get the vcpucount of VM. Signed-off-by: yangdongsheng <yangds.fnst@cn.fujitsu.com> --- libvirt/tests/cfg/virsh_cmd/domain/virsh_edit.cfg | 2 +- libvirt/tests/src/virsh_cmd/domain/virsh_edit.py | 13 +++++++++---- virttest/virsh.py | 12 ++++++++++++ 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/libvirt/tests/cfg/virsh_cmd/domain/virsh_edit.cfg b/libvirt/tests/cfg/virsh_cmd/domain/virsh_edit.cfg index e8a4930df..bf5f2221d 100644 --- a/libvirt/tests/cfg/virsh_cmd/domain/virsh_edit.cfg +++ b/libvirt/tests/cfg/virsh_cmd/domain/virsh_edit.cfg @@ -1,6 +1,6 @@ - virsh_edit: - type = virsh_edit virt_test_type = libvirt + type = virsh_edit take_regular_screendumps = no edit_vm_ref = "name" edit_extra_param = "" diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_edit.py b/libvirt/tests/src/virsh_cmd/domain/virsh_edit.py index 41d7b3874..f707efb61 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_edit.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_edit.py @@ -14,12 +14,17 @@ def run_virsh_edit(test, params, env): 4.Recover test environment. 5.Confirm the test result. """ - vm_name = params.get("main_vm") vm = env.get_vm(vm_name) domid = vm.get_id() domuuid = vm.get_uuid() + vcpucount_result = virsh.vcpucount(vm_name, options="--config") + if vcpucount_result.exit_status: + raise error.TestError("Failed to get vcpucount. Detail:\n%s" + % vcpucount_result) + original_vcpu = vcpucount_result.stdout.strip() + expected_vcpu = str(int(original_vcpu)+1) libvirtd = params.get("libvirtd", "on") vm_ref = params.get("edit_vm_ref") @@ -54,8 +59,8 @@ def edit_vcpu(source, guest_name): @param: guest_name : vm's name. @return: True if edit successed,False if edit failed. """ - dic_mode = {"edit" : ":%s /1<\/vcpu>/2<\/vcpu>", - "recover" : ":%s /2<\/vcpu>/1<\/vcpu>"} + dic_mode = {"edit" : ":%s /[0-9]*<\/vcpu>/"+expected_vcpu+"<\/vcpu>", + "recover" : ":%s /[0-9]*<\/vcpu>/"+original_vcpu+"<\/vcpu>"} status = modify_vcpu(source, dic_mode["edit"]) if not status : return status @@ -67,7 +72,7 @@ def edit_vcpu(source, guest_name): vcpus = vm.dominfo()["CPU(s)"] #Recover cpuinfo status = modify_vcpu(source, dic_mode["recover"]) - if status and vcpus != '2': + if status and vcpus != expected_vcpu: return False return status diff --git a/virttest/virsh.py b/virttest/virsh.py index ebd00383f..480e0532f 100644 --- a/virttest/virsh.py +++ b/virttest/virsh.py @@ -2158,3 +2158,15 @@ def nodedev_reattach(name, options="", **dargs): CmdResult = command(cmd, **dargs) return CmdResult + + +def vcpucount(name, options, **dargs): + """ + Get the vcpu count of guest. + + @param name: name of domain. + @param options: options for vcpucoutn command. + @return: CmdResult object. + """ + cmd = "vcpucount %s %s" % (name, options) + return command(cmd, **dargs) From de39881e557a1b689a5a18794772c9dd9efe28e9 Mon Sep 17 00:00:00 2001 From: yangdongsheng <yangds.fnst@cn.fujitsu.com> Date: Tue, 6 Aug 2013 22:16:41 +0800 Subject: [PATCH 244/254] libvirt: fix virsh_edit.py from pep8 Signed-off-by: yangdongsheng <yangds.fnst@cn.fujitsu.com> --- libvirt/tests/src/virsh_cmd/domain/virsh_edit.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_edit.py b/libvirt/tests/src/virsh_cmd/domain/virsh_edit.py index f707efb61..82d83566d 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_edit.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_edit.py @@ -1,4 +1,6 @@ -import os, time +import os +import time + from autotest.client.shared import error from virttest import virsh, aexpect, utils_libvirtd @@ -59,10 +61,10 @@ def edit_vcpu(source, guest_name): @param: guest_name : vm's name. @return: True if edit successed,False if edit failed. """ - dic_mode = {"edit" : ":%s /[0-9]*<\/vcpu>/"+expected_vcpu+"<\/vcpu>", - "recover" : ":%s /[0-9]*<\/vcpu>/"+original_vcpu+"<\/vcpu>"} + dic_mode = {"edit": ":%s /[0-9]*<\/vcpu>/"+expected_vcpu+"<\/vcpu>", + "recover": ":%s /[0-9]*<\/vcpu>/"+original_vcpu+"<\/vcpu>"} status = modify_vcpu(source, dic_mode["edit"]) - if not status : + if not status: return status if params.get("paused_after_start_vm") == "yes": virsh.resume(guest_name, ignore_status=True) @@ -72,7 +74,7 @@ def edit_vcpu(source, guest_name): vcpus = vm.dominfo()["CPU(s)"] #Recover cpuinfo status = modify_vcpu(source, dic_mode["recover"]) - if status and vcpus != expected_vcpu: + if status and vcpus != expected_vcpu: return False return status From a2fedc742e9b6d7e84c11f67592d4ef0215692c1 Mon Sep 17 00:00:00 2001 From: Xu Tian <xutian@redhat.com> Date: Wed, 7 Aug 2013 17:09:48 +0800 Subject: [PATCH 245/254] virttest.staging: fix module import error Fix ImportError when import "error" module and drop unused module 'common' Signed-off-by: Xu Tian <xutian@redhat.com> --- virttest/staging/service.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/virttest/staging/service.py b/virttest/staging/service.py index e88eb05bb..8f1e35d8f 100644 --- a/virttest/staging/service.py +++ b/virttest/staging/service.py @@ -20,8 +20,7 @@ import re import logging -import common -import error +from autotest.client.shared import error from tempfile import mktemp from autotest.client import utils From d09da62c29d80edbf340ab76100ea55b6cfce565 Mon Sep 17 00:00:00 2001 From: Pavel Hrdina <phrdina@redhat.com> Date: Mon, 5 Aug 2013 14:20:11 +0200 Subject: [PATCH 246/254] virsh-schedinfo-qemu-posix: fix the cgroup path Libvirt has changed the path where cgroups are stored and therefore the tests fails for newer libvirt because it cannot get the value of cgroups. To fix this, we should check if the old path exists and eventualy change the path to new one and for sure also check it. Also, fix incorrect imports used by the modified tests. Signed-off-by: Pavel Hrdina <phrdina@redhat.com> --- .../src/virsh_cmd/domain/virsh_memtune.py | 5 +++-- .../domain/virsh_schedinfo_qemu_posix.py | 20 ++++++++++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_memtune.py b/libvirt/tests/src/virsh_cmd/domain/virsh_memtune.py index aad7e28b5..67bbb1bc8 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_memtune.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_memtune.py @@ -1,12 +1,13 @@ import logging, re, os, commands, string, math from autotest.client.shared import error from virttest import virsh, libvirt_vm -from autotest.client import cgroup_utils try: from autotest.client.shared import utils_memory + from autotest.client.shared import utils_cgroup except ImportError: from virttest.staging import utils_memory + from virttest.staging import utils_cgroup def run_virsh_memtune(test, params, env): @@ -151,7 +152,7 @@ def check_hardswaplimit(path, expected_value): logging.info("Verify valid cgroup path for VM pid: %s", pid) # Resolve the memory cgroup path for a domain - path = cgroup_utils.resolve_task_cgroup_path(int(pid), "memory") + path = utils_cgroup.resolve_task_cgroup_path(int(pid), "memory") # Set the initial memory starting value for test case # By default set 1GB less than the total memory diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_schedinfo_qemu_posix.py b/libvirt/tests/src/virsh_cmd/domain/virsh_schedinfo_qemu_posix.py index 152407e82..2ccd55896 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_schedinfo_qemu_posix.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_schedinfo_qemu_posix.py @@ -1,8 +1,12 @@ -import re, logging -from autotest.client import cgroup_utils +import re, logging, os from autotest.client.shared import utils, error from virttest import virsh +try: + from autotest.client.shared import utils_cgroup +except ImportError: + from virttest.staging import utils_cgroup + def run_virsh_schedinfo_qemu_posix(test, params, env): """ @@ -33,12 +37,18 @@ def get_parameter_in_cgroup(domname, controller="cpu", else return value's result object. """ try: - ctl_mount = cgroup_utils.get_cgroup_mountpoint(controller) + ctl_mount = utils_cgroup.get_cgroup_mountpoint(controller) except IndexError: return None if ctl_mount is not False: - get_value_cmd = "cat %s/%s/%s/%s" % (ctl_mount, - libvirt_cgroup_path, domname, parameter) + cgroup_path = os.path.join(ctl_mount, libvirt_cgroup_path, + domname, parameter) + if not os.path.exists(cgroup_path): + cgroup_path = os.path.join(ctl_mount, "machine", domname + + ".libvirt-qemu", parameter) + if not os.path.exists(cgroup_path): + raise error.TestNAError("Unknown path to cgroups") + get_value_cmd = "cat %s" % cgroup_path result = utils.run(get_value_cmd, ignore_status=True) return result.stdout.strip() else: From 86949bc560880957a680413cbe8fb675ab1bf4cf Mon Sep 17 00:00:00 2001 From: Lucas Meneghel Rodrigues <lmr@redhat.com> Date: Wed, 7 Aug 2013 12:41:22 -0300 Subject: [PATCH 247/254] libvirt: Restrict default test set Signed-off-by: Lucas Meneghel Rodrigues <lmr@redhat.com> --- run | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/run b/run index d20668fd9..35b47d6ce 100755 --- a/run +++ b/run @@ -291,8 +291,10 @@ class VirtTestRunParser(optparse.OptionParser): DEFAULT_MACHINE_TYPE = "i440fx" DEFAULT_GUEST_OS = "JeOS" QEMU_DEFAULT_SET = "migrate..tcp, migrate..unix, migrate..exec, migrate..fd" -LIBVIRT_DEFAULT_SET = ("unattended_install.import.import, virsh_domname, " - "remove_guest.without_disk") +LIBVIRT_DEFAULT_SET = ( + "unattended_install.import.import.default_install.aio_native, " + "virsh_domname, " + "remove_guest.without_disk") class VirtTestApp(object): """ From e3d73013b05fdb2253e3276d851e89923dd90d41 Mon Sep 17 00:00:00 2001 From: Lucas Meneghel Rodrigues <lmr@redhat.com> Date: Wed, 7 Aug 2013 15:39:20 -0300 Subject: [PATCH 248/254] unattended_install: Fix problem with libvirt In the recent unattended install patchset, we referred to a VM attribute, serial_consoles, not present on the libvirt implementation. So add another exception handling to avoid libvirt installs breaking. Signed-off-by: Lucas Meneghel Rodrigues <lmr@redhat.com> --- tests/unattended_install.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/unattended_install.py b/tests/unattended_install.py index 358a534fe..aed4b9349 100644 --- a/tests/unattended_install.py +++ b/tests/unattended_install.py @@ -1053,6 +1053,8 @@ def copy_images(): serial_name = vm.serial_ports[0] except IndexError: raise virt_vm.VMConfigMissingError(vm.name, "isa_serial") + except AttributeError: + serial_name = "libvirt" log_file = utils_misc.get_path(test.debugdir, "serial-%s-%s.log" % (serial_name, From 7b98fc4885eeb42064efa3ad7a54f43411626b69 Mon Sep 17 00:00:00 2001 From: Mike Qiu <qiudayu@linux.vnet.ibm.com> Date: Sun, 4 Aug 2013 23:05:43 -0400 Subject: [PATCH 249/254] add images before image name Some case will try to create images in shared/data/, but it should be in shared/data/images/, update the cfg file of these cases, so that it can create the images in correct directory. Signed-off-by: Mike Qiu <qiudayu@linux.vnet.ibm.com> --- qemu/tests/cfg/systemtap_tracing.cfg | 2 +- qemu/tests/cfg/usb.cfg | 4 ++-- tests/cfg/block_hotplug.cfg | 4 ++-- tests/cfg/dd_test.cfg | 2 +- tests/cfg/lvm.cfg | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/qemu/tests/cfg/systemtap_tracing.cfg b/qemu/tests/cfg/systemtap_tracing.cfg index c6eff2139..9b564177a 100644 --- a/qemu/tests/cfg/systemtap_tracing.cfg +++ b/qemu/tests/cfg/systemtap_tracing.cfg @@ -100,7 +100,7 @@ usb_type_hub = usb-hub usb_max_port_usb2 = 6 images += " stg" - image_name_stg = "usbdevice" + image_name_stg = "images/usbdevice" image_format_stg = "qcow2" create_image_stg = yes index_enable = yes diff --git a/qemu/tests/cfg/usb.cfg b/qemu/tests/cfg/usb.cfg index e3d04ddc2..440676ec5 100644 --- a/qemu/tests/cfg/usb.cfg +++ b/qemu/tests/cfg/usb.cfg @@ -161,7 +161,7 @@ type = usb_storage images += " stg" image_boot_image1 = yes - image_name_stg = "usbdevice" + image_name_stg = "images/usbdevice" image_format_stg = "qcow2" image_boot_stg = no drive_index_stg = 1 @@ -239,7 +239,7 @@ - one_disk_repeat: images += " stg" image_format_stg = qcow2 - image_name_stg = storage + image_name_stg = images/storage image_size_stg = 1G drive_format_stg = usb2 drive_index_stg = 1 diff --git a/tests/cfg/block_hotplug.cfg b/tests/cfg/block_hotplug.cfg index 84d5b0408..364b9f887 100644 --- a/tests/cfg/block_hotplug.cfg +++ b/tests/cfg/block_hotplug.cfg @@ -7,7 +7,7 @@ find_pci_cmd = 'lspci | tail -n1' images += " stg0" boot_drive_stg0 = no - image_name_stg0 = storage0 + image_name_stg0 = images/storage0 image_size_stg0 = 1G remove_image_stg0 = yes force_create_image_stg0 = yes @@ -34,7 +34,7 @@ repeat_times = 2 images += " stg1" boot_drive_stg1 = no - image_name_stg1 = storage1 + image_name_stg1 = images/storage1 image_size_stg1 = 1G remove_image_stg1 = yes force_create_image_stg1 = yes diff --git a/tests/cfg/dd_test.cfg b/tests/cfg/dd_test.cfg index ce02e992c..01c36f6d3 100644 --- a/tests/cfg/dd_test.cfg +++ b/tests/cfg/dd_test.cfg @@ -4,7 +4,7 @@ type = dd_test images += " stg1" create_image_stg1 = yes - image_name_stg1 = stg1 + image_name_stg1 = images/stg1 image_size_stg1 = 1M image_snapshot_stg1 = no drive_index_stg1 = 3 diff --git a/tests/cfg/lvm.cfg b/tests/cfg/lvm.cfg index efdf96240..7b9297051 100644 --- a/tests/cfg/lvm.cfg +++ b/tests/cfg/lvm.cfg @@ -2,11 +2,11 @@ virt_test_type = qemu libvirt only Linux images += ' stg1 stg2' - image_name_stg1 = storage_4k + image_name_stg1 = images/storage_4k image_cluster_size_stg1 = 4096 image_size_stg1 = 1G image_format_stg1 = qcow2 - image_name_stg2 = storage_64k + image_name_stg2 = images/storage_64k image_cluster_size_stg2 = 65536 image_size_stg2 = 1G image_format_stg2 = qcow2 From d2db680e007166601fb69fdc2021b6e033be68de Mon Sep 17 00:00:00 2001 From: Alex Jia <ajia@redhat.com> Date: Mon, 1 Jul 2013 18:34:30 +0800 Subject: [PATCH 250/254] virt-libvirt: Add virsh domiftune commands function wrapper Signed-off-by: Alex Jia <ajia@redhat.com> --- virttest/virsh.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/virttest/virsh.py b/virttest/virsh.py index 480e0532f..00f91ae94 100644 --- a/virttest/virsh.py +++ b/virttest/virsh.py @@ -2052,6 +2052,7 @@ def ttyconsole(name, **dargs): """ return command("ttyconsole %s" % name, **dargs) + def nodedev_dumpxml(name, options="", to_file=None, **dargs): """ Do dumpxml for node device. @@ -2071,6 +2072,7 @@ def nodedev_dumpxml(name, options="", to_file=None, **dargs): return result + def connect(connect_uri="", options="", **dargs): """ Run a connect command to the uri. @@ -2081,6 +2083,7 @@ def connect(connect_uri="", options="", **dargs): """ return command("connect %s %s" % (connect_uri, options), **dargs) + def domif_setlink(name, interface, state, options=None, **dargs): """ Set network interface stats for a running domain. @@ -2098,6 +2101,7 @@ def domif_setlink(name, interface, state, options=None, **dargs): return command(cmd, **dargs) + def domif_getlink(name, interface, options=None, **dargs): """ Get network interface stats for a running domain. @@ -2111,7 +2115,28 @@ def domif_getlink(name, interface, options=None, **dargs): cmd = "domif-getlink %s %s " % (name, interface) if options: cmd += " %s" % options + return command(cmd, **dargs) + +def domiftune(name, interface, options=None, inbound=None, + outbound=None, **dargs): + """ + Set/get parameters of a virtual interface + @param name: name of domain + @param interface: interface device (MAC Address) + @param inbound: control domain's incoming traffics + @param outbound: control domain's outgoing traffics + @param options: options may be live, config and current + @param dargs: standardized virsh function API keywords + @return: CmdResult instance + """ + cmd = "domiftune %s %s" %(name, interface) + if inbound: + cmd += " --inbound %s" % inbound + if outbound: + cmd += " --outbound %s" % outbound + if options: + cmd += " --%s" % options return command(cmd, **dargs) def nodedev_list(options="", **dargs): From 98270669df6cf29910681b0a81eb57908945e1c2 Mon Sep 17 00:00:00 2001 From: Alex Jia <ajia@redhat.com> Date: Mon, 1 Jul 2013 18:34:54 +0800 Subject: [PATCH 251/254] virt-libvirt: Get virtual interface parameters from guest XML Signed-off-by: Alex Jia <ajia@redhat.com> --- virttest/libvirt_xml/vm_xml.py | 71 ++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 17 deletions(-) diff --git a/virttest/libvirt_xml/vm_xml.py b/virttest/libvirt_xml/vm_xml.py index faa02581d..eb5ce04b9 100644 --- a/virttest/libvirt_xml/vm_xml.py +++ b/virttest/libvirt_xml/vm_xml.py @@ -272,7 +272,7 @@ def __init__(self, hypervisor_type='kvm', virsh_instance=base.virsh): @staticmethod # static method (no self) needed b/c calls VMXML.__new__ - def new_from_dumpxml(vm_name, virsh_instance=virsh): + def new_from_dumpxml(vm_name, options="", virsh_instance=virsh): """ Return new VMXML instance from virsh dumpxml command @@ -282,7 +282,7 @@ def new_from_dumpxml(vm_name, virsh_instance=virsh): """ # TODO: Look up hypervisor_type on incoming XML vmxml = VMXML(virsh_instance=virsh_instance) - vmxml['xml'] = virsh_instance.dumpxml(vm_name) + vmxml['xml'] = virsh_instance.dumpxml(vm_name, options=options) return vmxml @@ -506,18 +506,6 @@ def set_primary_serial(vm_name, dev_type, port, path=None, vmxml.define() - def get_iface_all(self): - """ - Get a dict with interface's mac and node. - """ - iface_nodes = self.xmltreefile.find('devices').findall('interface') - interfaces = {} - for node in iface_nodes: - mac_addr = node.find('mac').get('address') - interfaces[mac_addr] = node - return interfaces - - @staticmethod def get_iface_by_mac(vm_name, mac, virsh_instance=base.virsh): """ @@ -545,12 +533,61 @@ def get_iface_by_mac(vm_name, mac, virsh_instance=base.virsh): return None + @staticmethod + def get_iface_dev(vm_name, options="", virsh_instance=base.virsh): + """ + Return VM's interface device from XML definition, None if not set + """ + vmxml = VMXML.new_from_dumpxml(vm_name, virsh_instance=virsh_instance) + ifaces = vmxml.get_iface_all() + if ifaces: + return ifaces.keys() + return None + + + @staticmethod + def get_iftune_params(vm_name, options="", virsh_instance=base.virsh): + """ + Return VM's interface tuning setting from XML definition + """ + vmxml = VMXML.new_from_dumpxml(vm_name, options=options, + virsh_instance=virsh_instance) + xmltreefile = vmxml.dict_get('xml') + iftune_params = {} + bandwidth = None + try: + bandwidth = xmltreefile.find('devices').find( + 'interface').find('bandwidth') + try: + iftune_params['inbound'] = bandwidth.find( + 'inbound').get('average') + iftune_params['outbound'] = bandwidth.find( + 'outbound').get('average') + except AttributeError: + logging.error("Can't find <inbound> or <outbound> element") + except AttributeError: + logging.error("Can't find <bandwidth> element") + + return iftune_params + + + def get_iface_all(self): + """ + Get a dict with interface's mac and node. + """ + iface_nodes = self.xmltreefile.find('devices').findall('interface') + interfaces = {} + for node in iface_nodes: + mac_addr = node.find('mac').get('address') + interfaces[mac_addr] = node + return interfaces + + def get_net_all(self): """ Return VM's net from XML definition, None if not set """ - xmltreefile = self.dict_get('xml') - net_nodes = xmltreefile.find('devices').findall('interface') + net_nodes = self.xmltreefile.find('devices').findall('interface') nets = {} for node in net_nodes: dev = node.find('target').get('dev') @@ -577,7 +614,7 @@ def set_cpu_mode(vm_name, mode='host-model'): """ Set cpu's mode of VM. - @param vm_name: Name of defined vm to set primary serial. + @param vm_name: Name of defined vm @param mode: the mode of cpu:'host-model'... """ vmxml = VMXML.new_from_dumpxml(vm_name) From fa0e33240b38139626637c48ac56c11d7d47bb8e Mon Sep 17 00:00:00 2001 From: Chris Evich <cevich@redhat.com> Date: Fri, 5 Jul 2013 13:39:12 -0400 Subject: [PATCH 252/254] virt-libvirt: Add Deprecate TODOs for VMXML Signed-off-by: Chris Evich <cevich@redhat.com> --- virttest/libvirt_xml/vm_xml.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/virttest/libvirt_xml/vm_xml.py b/virttest/libvirt_xml/vm_xml.py index eb5ce04b9..8dd47c064 100644 --- a/virttest/libvirt_xml/vm_xml.py +++ b/virttest/libvirt_xml/vm_xml.py @@ -474,7 +474,6 @@ def set_primary_serial(vm_name, dev_type, port, path=None, @param dev_type: the type of serial:pty,file... @param port: the port of serial @param path: the path of serial, it is not necessary for pty - # TODO: More features """ vmxml = VMXML.new_from_dumpxml(vm_name, virsh_instance=virsh_instance) xmltreefile = vmxml.dict_get('xml') @@ -506,6 +505,7 @@ def set_primary_serial(vm_name, dev_type, port, path=None, vmxml.define() + #TODO: Deprecate method in favor of VMXML.devices.interface @staticmethod def get_iface_by_mac(vm_name, mac, virsh_instance=base.virsh): """ @@ -533,6 +533,7 @@ def get_iface_by_mac(vm_name, mac, virsh_instance=base.virsh): return None + #TODO: Deprecate method in favor of VMXML.devices.interface @staticmethod def get_iface_dev(vm_name, options="", virsh_instance=base.virsh): """ @@ -545,6 +546,7 @@ def get_iface_dev(vm_name, options="", virsh_instance=base.virsh): return None + #TODO: Deprecate method in favor of VMXML.devices.interface @staticmethod def get_iftune_params(vm_name, options="", virsh_instance=base.virsh): """ @@ -571,6 +573,7 @@ def get_iftune_params(vm_name, options="", virsh_instance=base.virsh): return iftune_params + #TODO: Deprecate method in favor of VMXML.devices.interface def get_iface_all(self): """ Get a dict with interface's mac and node. @@ -583,6 +586,7 @@ def get_iface_all(self): return interfaces + #TODO: Deprecate method in favor of VMXML.devices.interface def get_net_all(self): """ Return VM's net from XML definition, None if not set @@ -594,7 +598,8 @@ def get_net_all(self): nets[dev] = node return nets - #TODO re-visit this method after the libvirt_xml.devices.interface module is implemented + + #TODO: Deprecate method in favor of VMXML.devices.interface @staticmethod def get_net_dev(vm_name): """ @@ -609,6 +614,7 @@ def get_net_dev(vm_name): return None + # TODO: Deprecate method in favor of VMCPUXML.mode @staticmethod def set_cpu_mode(vm_name, mode='host-model'): """ From d3660bb606a7ce9a06a81c6ad211331e4780baa3 Mon Sep 17 00:00:00 2001 From: Alex Jia <ajia@redhat.com> Date: Mon, 1 Jul 2013 18:35:14 +0800 Subject: [PATCH 253/254] virt-libvirt: Add test cases for domain's virtual interface tuning Signed-off-by: Alex Jia <ajia@redhat.com> --- .../src/virsh_cmd/domain/virsh_domiftune.py | 174 ++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 libvirt/tests/src/virsh_cmd/domain/virsh_domiftune.py diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_domiftune.py b/libvirt/tests/src/virsh_cmd/domain/virsh_domiftune.py new file mode 100644 index 000000000..dab892c22 --- /dev/null +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_domiftune.py @@ -0,0 +1,174 @@ +import logging +from autotest.client.shared import error +from virttest import virsh +from virttest.libvirt_xml import vm_xml + + +def check_domiftune(params): + """ + Compare inbound and outbound value with guest XML configuration + and virsh command output. + @params: the parameter dictionary + """ + vm_name = params.get("vms") + vm = params.get("vm") + interface = params.get("iface_dev") + options = params.get("options") + inbound = params.get("inbound", "") + outbound = params.get("outbound", "") + inbound_from_cmd_output = None + outbound_from_cmd_output = None + domiftune_params = {} + if vm and vm.is_alive(): + result = virsh.domiftune(vm_name, interface, options=options) + dicts = {} + o = result.stdout.strip().split("\n") + for l in o: + if l and l.find(':'): + k, v = l.split(':') + dicts[k.strip()] = v.strip() + + logging.debug(dicts) + inbound_from_cmd_output = dicts['inbound.average'] + outbound_from_cmd_output = dicts['outbound.average'] + + virt_xml_obj = vm_xml.VMXML(virsh_instance=virsh) + + if options == "config" and vm and vm.is_alive(): + domiftune_params = virt_xml_obj.get_iftune_params(vm_name, "--inactive") + elif vm and not vm.is_alive(): + logging.debug("The guest %s isn't running!", vm_name) + return True + else: + domiftune_params = virt_xml_obj.get_iftune_params(vm_name) + + inbound_from_xml = domiftune_params.get("inbound") + outbound_from_xml = domiftune_params.get("outbound") + + if vm and vm.is_alive() and options != "config": + if inbound and inbound != inbound_from_cmd_output: + logging.error("To expect inbound %s: %s", (inbound, + inbound_from_cmd_output)) + return False + if outbound and outbound != outbound_from_cmd_output: + logging.error("To expect inbound %s: %s", (outbound, + outbound_from_cmd_output)) + return False + if inbound and inbound_from_xml and inbound != inbound_from_xml: + logging.error("To expect outbound %s: %s", (inbound, + inbound_from_xml)) + return False + if outbound and outbound_from_xml and outbound != outbound_from_xml: + logging.error("To expect outbound %s: %s", (outbound, + outbound_from_xml)) + return False + + return True + +def get_domiftune_parameter(params): + """ + Get the domiftune parameters + @params: the parameter dictionary + """ + vm_name = params.get("vms") + options = params.get("options") + interface = params.get("iface_dev") + + result = virsh.domiftune(vm_name, interface, options=options) + status = result.exit_status + + # Check status_error + status_error = params.get("status_error", "no") + + if status_error == "yes": + if status: + logging.info("It's an expected error: %s", result.stderr) + else: + raise error.TestFail("%d not a expected command " + "return value", status) + elif status_error == "no": + if status: + raise error.TestFail(result.stderr) + else: + logging.info(result.stdout) + +def set_domiftune_parameter(params): + """ + Set the domiftune parameters + @params: the parameter dictionary + """ + vm_name = params.get("vms") + inbound = params.get("inbound") + outbound = params.get("outbound") + options = params.get("options", None) + interface = params.get("iface_dev") + + result = virsh.domiftune(vm_name, interface, options, inbound, outbound) + status = result.exit_status + + # Check status_error + status_error = params.get("status_error", "no") + + if status_error == "yes": + if status: + logging.info("It's an expected error: %s", result.stderr) + else: + raise error.TestFail("%d not a expected command " + "return value", status) + elif status_error == "no": + if status: + raise error.TestFail(result.stderr) + else: + if check_domiftune(params): + logging.info(result.stdout) + else: + error.TestFail("The 'inbound' or/and 'outbound' are" + " inconsistent with domiftune XML" + " and/or virsh command output") + +def run_virsh_domiftune(test, params, env): + """ + Test domiftune tuning + + 1) Positive testing + 1.1) get the current domiftune parameters for a running guest + 1.2) set the current domiftune parameters for a running guest + 2) Negative testing + 2.1) get domiftune parameters + 2.2) set domiftune parameters + """ + + # Run test case + vm_name = params.get("vms") + vm = env.get_vm(vm_name) + status_error = params.get("status_error", "no") + start_vm = params.get("start_vm", "yes") + change_parameters = params.get("change_parameters", "no") + interface = [] + + if vm and vm.is_alive(): + virt_xml_obj = vm_xml.VMXML(virsh_instance=virsh) + interface = virt_xml_obj.get_iface_dev(vm_name) + + test_dict = dict(params) + test_dict['vm'] = vm + if interface: + test_dict['iface_dev'] = interface[0] + + if start_vm == "no" and vm and vm.is_alive(): + vm.destroy() + + ########## positive and negative testing ######### + + if status_error == "no": + if change_parameters == "no": + get_domiftune_parameter(test_dict) + else: + set_domiftune_parameter(test_dict) + + if status_error == "yes": + if change_parameters == "no": + get_domiftune_parameter(test_dict) + else: + set_domiftune_parameter(test_dict) + From 544276403ef7352f357283d2d0e230db5913a07b Mon Sep 17 00:00:00 2001 From: Alex Jia <ajia@redhat.com> Date: Mon, 1 Jul 2013 18:35:33 +0800 Subject: [PATCH 254/254] virt-libvirt: Add domain's virtual interface tuning test configuration Signed-off-by: Alex Jia <ajia@redhat.com> --- .../cfg/virsh_cmd/domain/virsh_domiftune.cfg | 153 ++++++++++++++++++ .../src/virsh_cmd/domain/virsh_domiftune.py | 1 - 2 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 libvirt/tests/cfg/virsh_cmd/domain/virsh_domiftune.cfg diff --git a/libvirt/tests/cfg/virsh_cmd/domain/virsh_domiftune.cfg b/libvirt/tests/cfg/virsh_cmd/domain/virsh_domiftune.cfg new file mode 100644 index 000000000..3bada79f1 --- /dev/null +++ b/libvirt/tests/cfg/virsh_cmd/domain/virsh_domiftune.cfg @@ -0,0 +1,153 @@ +- virsh_domiftune: + type = virsh_domiftune + libvirtd = "on" + variants: + - positive_testing: + status_error = "no" + variants: + - get_domif_parameter: + variants: + - running_guest: + start_vm = "yes" + variants: + - options: + variants: + - none: + options = + - live: + options = "live" + - current: + options = "current" + - set_blkio_parameter: + change_parameters = "yes" + variants: + - running_guest: + start_vm = "yes" + variants: + - change_inbound: + variants: + # the parameters are 32-bit unsigned + # integers and {in,out}bound is in + # range of 1~ 2^32-1 (4294967295) + - minimum_boundary: + inbound = 1 + - inside_boundary: + inbound = 1024 + - maximum_boundary: + inbound = 4294967295 + variants: + - options: + variants: + - live: + options = "live" + - current: + options = "current" + - change_outbound: + variants: + - minimum_boundary: + outbound = 1 + - inside_boundary: + outbound = 65535 + - maximum_boundary: + outbound = 4294967295 + variants: + - options: + variants: + - live: + options = "live" + - current: + options = "current" + + - negative_testing: + status_error = "yes" + variants: + - get_domif_parameter: + variants: + - running_guest: + start_vm = "yes" + variants: + - options: + variants: + - none: + options = "hello" + - shutoff_guest: + start_vm = "no" + variants: + - options: + variants: + - none: + options = "hello" + - live: + options = "live" + - set_domif_parameter: + change_parameters = "yes" + variants: + - running_guest: + start_vm = "yes" + variants: + - change_inbound: + variants: + # inbound average is mandatory + - average: + inbound = 0 + - invalid_format: + inbound = "~@#$%^-=_:,.[]{}" + variants: + - options: + variants: + - live: + options = "live" + - change_outbound: + variants: + - average: + outbound = 0 + - invalid_format: + outbound = "~@#$%^-=_:,.[]{}" + variants: + - options: + variants: + - live: + options = "live" + - config: + options = "config" + - current: + options = "current" + - shutoff_guest: + start_vm = "no" + variants: + - change_inbound: + variants: + - minimum_boundary: + inbound = 1 + - inside_boundary: + inbound = 65535 + - maximum_boundary: + inbound = 4294967295 + variants: + - options: + variants: + - live: + options = "live" + - config: + options = "config" + - current: + options = "current" + + - change_outbound: + variants: + - minimum_boundary: + outbound = 1 + - inside_boundary: + outbound = 65535 + - maximum_boundary: + outbound = 4294967295 + variants: + - options: + variants: + - live: + options = "live" + - config: + options = "config" + - current: + options = "current" + diff --git a/libvirt/tests/src/virsh_cmd/domain/virsh_domiftune.py b/libvirt/tests/src/virsh_cmd/domain/virsh_domiftune.py index dab892c22..ad92c8813 100644 --- a/libvirt/tests/src/virsh_cmd/domain/virsh_domiftune.py +++ b/libvirt/tests/src/virsh_cmd/domain/virsh_domiftune.py @@ -171,4 +171,3 @@ def run_virsh_domiftune(test, params, env): get_domiftune_parameter(test_dict) else: set_domiftune_parameter(test_dict) -