Index: client/tests/kvm/kvm_test_utils.py |
diff --git a/client/tests/kvm/kvm_test_utils.py b/client/tests/kvm/kvm_test_utils.py |
index 7ed33300a1f03f308d970a88125be1ce17ee7a80..014f26573eaf077905ad7064480b8eaddd8fdc89 100644 |
--- a/client/tests/kvm/kvm_test_utils.py |
+++ b/client/tests/kvm/kvm_test_utils.py |
@@ -21,7 +21,7 @@ More specifically: |
@copyright: 2008-2009 Red Hat Inc. |
""" |
-import time, os, logging, re, commands, signal, threading |
+import time, os, logging, re, commands, signal |
from autotest_lib.client.common_lib import error |
from autotest_lib.client.bin import utils |
import kvm_utils, kvm_vm, kvm_subprocess, scan_results |
@@ -35,7 +35,7 @@ def get_living_vm(env, vm_name): |
@param vm_name: Name of the desired VM object. |
@return: A VM object. |
""" |
- vm = env.get_vm(vm_name) |
+ vm = kvm_utils.env_get_vm(env, vm_name) |
if not vm: |
raise error.TestError("VM '%s' not found in environment" % vm_name) |
if not vm.is_alive(): |
@@ -44,33 +44,21 @@ def get_living_vm(env, vm_name): |
return vm |
-def wait_for_login(vm, nic_index=0, timeout=240, start=0, step=2, serial=None): |
+def wait_for_login(vm, nic_index=0, timeout=240, start=0, step=2): |
""" |
Try logging into a VM repeatedly. Stop on success or when timeout expires. |
@param vm: VM object. |
@param nic_index: Index of NIC to access in the VM. |
@param timeout: Time to wait before giving up. |
- @param serial: Whether to use a serial connection instead of a remote |
- (ssh, rss) one. |
@return: A shell session object. |
""" |
- type = 'remote' |
- if serial: |
- type = 'serial' |
- logging.info("Trying to log into guest %s using serial connection," |
- " timeout %ds", vm.name, timeout) |
- session = kvm_utils.wait_for(lambda: vm.serial_login(), timeout, |
- start, step) |
- else: |
- logging.info("Trying to log into guest %s using remote connection," |
- " timeout %ds", vm.name, timeout) |
- session = kvm_utils.wait_for(lambda: vm.remote_login( |
- nic_index=nic_index), timeout, start, step) |
+ logging.info("Trying to log into guest '%s', timeout %ds", vm.name, timeout) |
+ session = kvm_utils.wait_for(lambda: vm.remote_login(nic_index=nic_index), |
+ timeout, start, step) |
if not session: |
- raise error.TestFail("Could not log into guest %s using %s connection" % |
- (vm.name, type)) |
- logging.info("Logged into guest %s using %s connection", vm.name, type) |
+ raise error.TestFail("Could not log into guest '%s'" % vm.name) |
+ logging.info("Logged into guest '%s'" % vm.name) |
return session |
@@ -133,8 +121,7 @@ def reboot(vm, session, method="shell", sleep_before_reset=10, nic_index=0, |
def migrate(vm, env=None, mig_timeout=3600, mig_protocol="tcp", |
- mig_cancel=False, offline=False, stable_check=False, |
- clean=False, save_path=None, dest_host='localhost', mig_port=None): |
+ mig_cancel=False): |
""" |
Migrate a VM locally and re-register it in the environment. |
@@ -144,10 +131,7 @@ def migrate(vm, env=None, mig_timeout=3600, mig_protocol="tcp", |
@param mig_timeout: timeout value for migration. |
@param mig_protocol: migration protocol |
@param mig_cancel: Test migrate_cancel or not when protocol is tcp. |
- @param dest_host: Destination host (defaults to 'localhost'). |
- @param mig_port: Port that will be used for migration. |
- @return: The post-migration VM, in case of same host migration, True in |
- case of multi-host migration. |
+ @return: The post-migration VM. |
""" |
def mig_finished(): |
o = vm.monitor.info("migrate") |
@@ -185,32 +169,38 @@ def migrate(vm, env=None, mig_timeout=3600, mig_protocol="tcp", |
raise error.TestFail("Timeout expired while waiting for migration " |
"to finish") |
- if dest_host == 'localhost': |
- dest_vm = vm.clone() |
+ dest_vm = vm.clone() |
- if (dest_host == 'localhost') and stable_check: |
- # Pause the dest vm after creation |
- dest_vm.params['extra_params'] = (dest_vm.params.get('extra_params','') |
- + ' -S') |
+ if mig_protocol == "exec": |
+ # Exec is a little different from other migrate methods - first we |
+ # ask the monitor the migration, then the vm state is dumped to a |
+ # compressed file, then we start the dest vm with -incoming pointing |
+ # to it |
+ try: |
+ exec_file = "/tmp/exec-%s.gz" % kvm_utils.generate_random_string(8) |
+ exec_cmd = "gzip -c -d %s" % exec_file |
+ uri = '"exec:gzip -c > %s"' % exec_file |
+ vm.monitor.cmd("stop") |
+ vm.monitor.migrate(uri) |
+ wait_for_migration() |
- if dest_host == 'localhost': |
+ if not dest_vm.create(migration_mode=mig_protocol, |
+ migration_exec_cmd=exec_cmd, mac_source=vm): |
+ raise error.TestError("Could not create dest VM") |
+ finally: |
+ logging.debug("Removing migration file %s", exec_file) |
+ try: |
+ os.remove(exec_file) |
+ except OSError: |
+ pass |
+ else: |
if not dest_vm.create(migration_mode=mig_protocol, mac_source=vm): |
raise error.TestError("Could not create dest VM") |
- |
- try: |
try: |
if mig_protocol == "tcp": |
- if dest_host == 'localhost': |
- uri = "tcp:localhost:%d" % dest_vm.migration_port |
- else: |
- uri = 'tcp:%s:%d' % (dest_host, mig_port) |
+ uri = "tcp:localhost:%d" % dest_vm.migration_port |
elif mig_protocol == "unix": |
uri = "unix:%s" % dest_vm.migration_file |
- elif mig_protocol == "exec": |
- uri = '"exec:nc localhost %s"' % dest_vm.migration_port |
- |
- if offline: |
- vm.monitor.cmd("stop") |
vm.monitor.migrate(uri) |
if mig_cancel: |
@@ -220,43 +210,14 @@ def migrate(vm, env=None, mig_timeout=3600, mig_protocol="tcp", |
"Waiting for migration " |
"cancellation"): |
raise error.TestFail("Failed to cancel migration") |
- if offline: |
- vm.monitor.cmd("cont") |
- if dest_host == 'localhost': |
- dest_vm.destroy(gracefully=False) |
+ dest_vm.destroy(gracefully=False) |
return vm |
else: |
wait_for_migration() |
- if (dest_host == 'localhost') and stable_check: |
- save_path = None or "/tmp" |
- save1 = os.path.join(save_path, "src") |
- save2 = os.path.join(save_path, "dst") |
- |
- vm.save_to_file(save1) |
- dest_vm.save_to_file(save2) |
- |
- # Fail if we see deltas |
- md5_save1 = utils.hash_file(save1) |
- md5_save2 = utils.hash_file(save2) |
- if md5_save1 != md5_save2: |
- raise error.TestFail("Mismatch of VM state before " |
- "and after migration") |
- |
- if (dest_host == 'localhost') and offline: |
- dest_vm.monitor.cmd("cont") |
except: |
- if dest_host == 'localhost': |
- dest_vm.destroy() |
+ dest_vm.destroy() |
raise |
- finally: |
- if (dest_host == 'localhost') and stable_check and clean: |
- logging.debug("Cleaning the state files") |
- if os.path.isfile(save1): |
- os.remove(save1) |
- if os.path.isfile(save2): |
- os.remove(save2) |
- |
# Report migration status |
if mig_succeeded(): |
logging.info("Migration finished successfully") |
@@ -265,23 +226,19 @@ def migrate(vm, env=None, mig_timeout=3600, mig_protocol="tcp", |
else: |
raise error.TestFail("Migration ended with unknown status") |
- if dest_host == 'localhost': |
- if "paused" in dest_vm.monitor.info("status"): |
- logging.debug("Destination VM is paused, resuming it...") |
- dest_vm.monitor.cmd("cont") |
+ if "paused" in dest_vm.monitor.info("status"): |
+ logging.debug("Destination VM is paused, resuming it...") |
+ dest_vm.monitor.cmd("cont") |
# Kill the source VM |
vm.destroy(gracefully=False) |
# Replace the source VM with the new cloned VM |
- if (dest_host == 'localhost') and (env is not None): |
- env.register_vm(vm.name, dest_vm) |
+ if env is not None: |
+ kvm_utils.env_register_vm(env, vm.name, dest_vm) |
# Return the new cloned VM |
- if dest_host == 'localhost': |
- return dest_vm |
- else: |
- return vm |
+ return dest_vm |
def stop_windows_service(session, service, timeout=120): |
@@ -295,7 +252,7 @@ def stop_windows_service(session, service, timeout=120): |
""" |
end_time = time.time() + timeout |
while time.time() < end_time: |
- o = session.cmd_output("sc stop %s" % service, timeout=60) |
+ o = session.get_command_output("sc stop %s" % service, timeout=60) |
# FAILED 1060 means the service isn't installed. |
# FAILED 1062 means the service hasn't been started. |
if re.search(r"\bFAILED (1060|1062)\b", o, re.I): |
@@ -317,7 +274,7 @@ def start_windows_service(session, service, timeout=120): |
""" |
end_time = time.time() + timeout |
while time.time() < end_time: |
- o = session.cmd_output("sc start %s" % service, timeout=60) |
+ o = session.get_command_output("sc start %s" % service, timeout=60) |
# FAILED 1060 means the service isn't installed. |
if re.search(r"\bFAILED 1060\b", o, re.I): |
raise error.TestError("Could not start service '%s' " |
@@ -349,7 +306,10 @@ def get_time(session, time_command, time_filter_re, time_format): |
""" |
if len(re.findall("ntpdate|w32tm", time_command)) == 0: |
host_time = time.time() |
- s = session.cmd_output(time_command) |
+ session.sendline(time_command) |
+ (match, s) = session.read_up_to_prompt() |
+ if not match: |
+ raise error.TestError("Could not get guest time") |
try: |
s = re.findall(time_filter_re, s)[0] |
@@ -363,7 +323,9 @@ def get_time(session, time_command, time_filter_re, time_format): |
guest_time = time.mktime(time.strptime(s, time_format)) |
else: |
- o = session.cmd(time_command) |
+ s , o = session.get_command_status_output(time_command) |
+ if s != 0: |
+ raise error.TestError("Could not get guest time") |
if re.match('ntpdate', time_command): |
offset = re.findall('offset (.*) sec',o)[0] |
host_main, host_mantissa = re.findall(time_filter_re, o)[0] |
@@ -441,7 +403,7 @@ def run_autotest(vm, session, control_path, timeout, outputdir): |
copy = False |
local_hash = utils.hash_file(local_path) |
basename = os.path.basename(local_path) |
- output = session.cmd_output("md5sum %s" % remote_path) |
+ output = session.get_command_output("md5sum %s" % remote_path) |
if "such file" in output: |
remote_hash = "0" |
elif output: |
@@ -473,7 +435,10 @@ def run_autotest(vm, session, control_path, timeout, outputdir): |
basename = os.path.basename(remote_path) |
logging.info("Extracting %s...", basename) |
e_cmd = "tar xjvf %s -C %s" % (remote_path, dest_dir) |
- session.cmd(e_cmd, timeout=120) |
+ s, o = session.get_command_status_output(e_cmd, timeout=120) |
+ if s != 0: |
+ logging.error("Uncompress output:\n%s", o) |
+ raise error.TestFail("Failed to extract %s on guest" % basename) |
def get_results(): |
@@ -494,7 +459,7 @@ def run_autotest(vm, session, control_path, timeout, outputdir): |
Get the status of the tests that were executed on the host and close |
the session where autotest was being executed. |
""" |
- output = session.cmd_output("cat results/*/status") |
+ output = session.get_command_output("cat results/*/status") |
try: |
results = scan_results.parse_results(output) |
# Report test results |
@@ -543,32 +508,26 @@ def run_autotest(vm, session, control_path, timeout, outputdir): |
# Run the test |
logging.info("Running autotest control file %s on guest, timeout %ss", |
os.path.basename(control_path), timeout) |
- session.cmd("cd %s" % autotest_path) |
- try: |
- session.cmd("rm -f control.state") |
- session.cmd("rm -rf results/*") |
- except kvm_subprocess.ShellError: |
- pass |
- try: |
- try: |
- logging.info("---------------- Test output ----------------") |
- session.cmd_output("bin/autotest control", timeout=timeout, |
- print_func=logging.info) |
- finally: |
- logging.info("------------- End of test output ------------") |
- except kvm_subprocess.ShellTimeoutError: |
- if vm.is_alive(): |
- get_results() |
- get_results_summary() |
- raise error.TestError("Timeout elapsed while waiting for job to " |
- "complete") |
- else: |
+ session.get_command_output("cd %s" % autotest_path) |
+ session.get_command_output("rm -f control.state") |
+ session.get_command_output("rm -rf results/*") |
+ logging.info("---------------- Test output ----------------") |
+ status = session.get_command_status("bin/autotest control", |
+ timeout=timeout, |
+ print_func=logging.info) |
+ logging.info("------------- End of test output ------------") |
+ if status is None: |
+ if not vm.is_alive(): |
raise error.TestError("Autotest job on guest failed " |
"(VM terminated during job)") |
- except kvm_subprocess.ShellProcessTerminatedError: |
+ if not session.is_alive(): |
+ get_results() |
+ raise error.TestError("Autotest job on guest failed " |
+ "(Remote session terminated during job)") |
get_results() |
- raise error.TestError("Autotest job on guest failed " |
- "(Remote session terminated during job)") |
+ get_results_summary() |
+ raise error.TestError("Timeout elapsed while waiting for job to " |
+ "complete") |
results = get_results_summary() |
get_results() |
@@ -630,24 +589,21 @@ def raw_ping(command, timeout, session, output_func): |
process.close() |
return status, output |
else: |
- try: |
- output = session.cmd_output(command, timeout=timeout, |
- print_func=output_func) |
- except kvm_subprocess.ShellTimeoutError: |
+ session.sendline(command) |
+ status, output = session.read_up_to_prompt(timeout=timeout, |
+ print_func=output_func) |
+ if not status: |
# Send ctrl+c (SIGINT) through ssh session |
session.send("\003") |
- try: |
- output2 = session.read_up_to_prompt(print_func=output_func) |
- output += output2 |
- except kvm_subprocess.ExpectTimeoutError, e: |
- output += e.output |
+ status, output2 = session.read_up_to_prompt(print_func=output_func) |
+ output += output2 |
+ if not status: |
# We also need to use this session to query the return value |
session.send("\003") |
session.sendline(session.status_test_command) |
- try: |
- o2 = session.read_up_to_prompt() |
- except kvm_subprocess.ExpectError: |
+ s2, o2 = session.read_up_to_prompt() |
+ if not s2: |
status = -1 |
else: |
try: |
@@ -714,7 +670,7 @@ def get_linux_ifname(session, mac_address): |
@mac_address: the macaddress of nic |
""" |
- output = session.cmd_output("ifconfig -a") |
+ output = session.get_command_output("ifconfig -a") |
try: |
ethname = re.findall("(\w+)\s+Link.*%s" % mac_address, output, |