| Index: client/tests/kvm/kvm_vm.py
|
| diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
|
| index 41f7491f90a0ae20098517c1a228b419025e52b1..f0b81528d2e69cc0384e2f6d69815d9e9e4381a3 100755
|
| --- a/client/tests/kvm/kvm_vm.py
|
| +++ b/client/tests/kvm/kvm_vm.py
|
| @@ -105,6 +105,15 @@ class VMDeadError(VMError):
|
| (self.status, self.output))
|
|
|
|
|
| +class VMDeadKernelCrashError(VMError):
|
| + def __init__(self, kernel_crash):
|
| + VMError.__init__(self, kernel_crash)
|
| + self.kernel_crash = kernel_crash
|
| +
|
| + def __str__(self):
|
| + return ("VM is dead due to a kernel crash:\n%s" % self.kernel_crash)
|
| +
|
| +
|
| class VMAddressError(VMError):
|
| pass
|
|
|
| @@ -285,10 +294,31 @@ def check_image(params, root_dir):
|
| except error.CmdError:
|
| logging.error("Error getting info from image %s",
|
| image_filename)
|
| - try:
|
| - utils.system("%s check %s" % (qemu_img_cmd, image_filename))
|
| - except error.CmdError:
|
| +
|
| + cmd_result = utils.run("%s check %s" %
|
| + (qemu_img_cmd, image_filename),
|
| + ignore_status=True)
|
| + # Error check, large chances of a non-fatal problem.
|
| + # There are chances that bad data was skipped though
|
| + if cmd_result.exit_status == 1:
|
| + for e_line in cmd_result.stdout.splitlines():
|
| + logging.error("[stdout] %s", e_line)
|
| + for e_line in cmd_result.stderr.splitlines():
|
| + logging.error("[stderr] %s", e_line)
|
| + raise error.TestWarn("qemu-img check error. Some bad data in "
|
| + "the image may have gone unnoticed")
|
| + # Exit status 2 is data corruption for sure, so fail the test
|
| + elif cmd_result.exit_status == 2:
|
| + for e_line in cmd_result.stdout.splitlines():
|
| + logging.error("[stdout] %s", e_line)
|
| + for e_line in cmd_result.stderr.splitlines():
|
| + logging.error("[stderr] %s", e_line)
|
| raise VMImageCheckError(image_filename)
|
| + # Leaked clusters, they are known to be harmless to data integrity
|
| + elif cmd_result.exit_status == 3:
|
| + raise error.TestWarn("Leaked clusters were noticed during "
|
| + "image check. No data integrity problem "
|
| + "was found though.")
|
|
|
| else:
|
| if not os.path.exists(image_filename):
|
| @@ -335,6 +365,7 @@ class VM:
|
| if not glob.glob("/tmp/*%s" % self.instance):
|
| break
|
|
|
| + self.spice_port = 8000
|
| self.name = name
|
| self.params = params
|
| self.root_dir = root_dir
|
| @@ -553,6 +584,26 @@ class VM:
|
| def add_pcidevice(help, host):
|
| return " -pcidevice host='%s'" % host
|
|
|
| + def add_spice(help, port, param):
|
| + if has_option(help,"spice"):
|
| + return " -spice port=%s,%s" % (port, param)
|
| + else:
|
| + return ""
|
| +
|
| + def add_qxl_vga(help, qxl, vga, qxl_dev_nr=None):
|
| + str = ""
|
| + if has_option(help, "qxl"):
|
| + if qxl and qxl_dev_nr is not None:
|
| + str += " -qxl %s" % qxl_dev_nr
|
| + if has_option(help, "vga") and vga and vga != "qxl":
|
| + str += " -vga %s" % vga
|
| + elif has_option(help, "vga"):
|
| + if qxl:
|
| + str += " -vga qxl"
|
| + elif vga:
|
| + str += " -vga %s" % vga
|
| + return str
|
| +
|
| def add_kernel(help, filename):
|
| return " -kernel '%s'" % filename
|
|
|
| @@ -720,6 +771,19 @@ class VM:
|
| qemu_cmd += add_sdl(help)
|
| elif params.get("display") == "nographic":
|
| qemu_cmd += add_nographic(help)
|
| + elif params.get("display") == "spice":
|
| + qemu_cmd += add_spice(help, self.spice_port, params.get("spice"))
|
| +
|
| + qxl = ""
|
| + vga = ""
|
| + if params.get("qxl"):
|
| + qxl = params.get("qxl")
|
| + if params.get("vga"):
|
| + vga = params.get("vga")
|
| + if qxl or vga:
|
| + if params.get("display") == "spice":
|
| + qxl_dev_nr = params.get("qxl_dev_nr", None)
|
| + qemu_cmd += add_qxl_vga(help, qxl, vga, qxl_dev_nr)
|
|
|
| if params.get("uuid") == "random":
|
| qemu_cmd += add_uuid(help, vm.uuid)
|
| @@ -845,6 +909,10 @@ class VM:
|
| if params.get("display") == "vnc":
|
| self.vnc_port = kvm_utils.find_free_port(5900, 6100)
|
|
|
| + # Find available spice port
|
| + if params.get("spice"):
|
| + self.spice_port = kvm_utils.find_free_port(8000, 8100)
|
| +
|
| # Find random UUID if specified 'uuid = random' in config file
|
| if params.get("uuid") == "random":
|
| f = open("/proc/sys/kernel/random/uuid")
|
| @@ -1120,6 +1188,20 @@ class VM:
|
| return not self.process or not self.process.is_alive()
|
|
|
|
|
| + def verify_kernel_crash(self):
|
| + """
|
| + Find kernel crash message on the VM serial console.
|
| +
|
| + @raise: VMDeadKernelCrashError, in case a kernel crash message was
|
| + found.
|
| + """
|
| + data = self.serial_console.get_output()
|
| + match = re.search(r"BUG:.*---\[ end trace .* \]---", data,
|
| + re.DOTALL|re.MULTILINE)
|
| + if match is not None:
|
| + raise VMDeadKernelCrashError(match.group(0))
|
| +
|
| +
|
| def get_params(self):
|
| """
|
| Return the VM's params dict. Most modified params take effect only
|
| @@ -1596,6 +1678,7 @@ class VM:
|
| if local:
|
| time.sleep(1)
|
| self.verify_alive()
|
| + self.verify_kernel_crash()
|
|
|
| if local and stable_check:
|
| try:
|
|
|