From patchwork Tue Apr 28 21:48:47 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Huff X-Patchwork-Id: 20529 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n3SLnUnm024169 for ; Tue, 28 Apr 2009 21:49:31 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755197AbZD1Vt3 (ORCPT ); Tue, 28 Apr 2009 17:49:29 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1755101AbZD1Vt3 (ORCPT ); Tue, 28 Apr 2009 17:49:29 -0400 Received: from mx2.redhat.com ([66.187.237.31]:58867 "EHLO mx2.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754793AbZD1VtY (ORCPT ); Tue, 28 Apr 2009 17:49:24 -0400 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n3SLnO7b004207 for ; Tue, 28 Apr 2009 17:49:24 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n3SLnNSw022274; Tue, 28 Apr 2009 17:49:23 -0400 Received: from localhost.localdomain (dhcp231-89.rdu.redhat.com [10.11.231.89]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id n3SLnMrT014937; Tue, 28 Apr 2009 17:49:23 -0400 From: David Huff To: kvm@vger.kernel.org Cc: David Huff Subject: [PATCH] Added "stock" or existing test to ./kvm_tests/ Date: Tue, 28 Apr 2009 17:48:47 -0400 Message-Id: <1240955328-23358-3-git-send-email-dhuff@redhat.com> In-Reply-To: <1240955328-23358-1-git-send-email-dhuff@redhat.com> References: <1240955328-23358-1-git-send-email-dhuff@redhat.com> X-Scanned-By: MIMEDefang 2.58 on 172.16.27.26 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org autotest.py, boot.py, linux_s3.py, migration.py, yum_update.py --- client/tests/kvm_runtest_2/kvm_tests/autotest.py | 145 ++++++++++++++++++++ client/tests/kvm_runtest_2/kvm_tests/boot.py | 45 ++++++ client/tests/kvm_runtest_2/kvm_tests/linux_s3.py | 53 +++++++ client/tests/kvm_runtest_2/kvm_tests/migration.py | 132 ++++++++++++++++++ client/tests/kvm_runtest_2/kvm_tests/yum_update.py | 53 +++++++ 5 files changed, 428 insertions(+), 0 deletions(-) create mode 100644 client/tests/kvm_runtest_2/kvm_tests/autotest.py create mode 100644 client/tests/kvm_runtest_2/kvm_tests/boot.py create mode 100644 client/tests/kvm_runtest_2/kvm_tests/linux_s3.py create mode 100644 client/tests/kvm_runtest_2/kvm_tests/migration.py create mode 100644 client/tests/kvm_runtest_2/kvm_tests/yum_update.py diff --git a/client/tests/kvm_runtest_2/kvm_tests/autotest.py b/client/tests/kvm_runtest_2/kvm_tests/autotest.py new file mode 100644 index 0000000..7497596 --- /dev/null +++ b/client/tests/kvm_runtest_2/kvm_tests/autotest.py @@ -0,0 +1,145 @@ +import time +import os + +#from autotest_lib.client.common_lib import utils, error + +#import kvm_log +#import kvm_utils +#import ppm_utils +#import scan_results + + +def run_autotest(test, params, env): + vm = kvm_utils.env_get_vm(env, params.get("main_vm")) + if not vm: + raise error.TestError, "VM object not found in environment" + if not vm.is_alive(): + raise error.TestError, "VM seems to be dead; Test requires a living VM" + + kvm_log.info("Logging into guest...") + + session = kvm_utils.wait_for(vm.ssh_login, 240, 0, 2) + if not session: + raise error.TestFail, "Could not log into guest" + + kvm_log.info("Logged in") + + # Collect some info + test_name = params.get("test_name") + test_timeout = int(params.get("test_timeout", 300)) + test_control_file = params.get("test_control_file", "control") + tarred_autotest_path = "/tmp/autotest.tar.bz2" + tarred_test_path = "/tmp/%s.tar.bz2" % test_name + + # tar the contents of bindir/autotest + cmd = "cd %s; tar cvjf %s autotest/*" + cmd += " --exclude=autotest/tests" + cmd += " --exclude=autotest/results" + cmd += " --exclude=autotest/tmp" + cmd += " --exclude=autotest/control" + cmd += " --exclude=*.pyc" + cmd += " --exclude=*.svn" + cmd += " --exclude=*.git" + kvm_utils.run_bg(cmd % (test.bindir, tarred_autotest_path), timeout=30) + + # tar the contents of bindir/autotest/tests/ + cmd = "cd %s; tar cvjf %s %s/*" + cmd += " --exclude=*.pyc" + cmd += " --exclude=*.svn" + cmd += " --exclude=*.git" + kvm_utils.run_bg(cmd % (os.path.join(test.bindir, "autotest", "tests"), tarred_test_path, test_name), timeout=30) + + # Check if we need to copy autotest.tar.bz2 + copy = False + output = session.get_command_output("ls -l autotest.tar.bz2") + if "such file" in output: + copy = True + else: + size = int(output.split()[4]) + if size != os.path.getsize(tarred_autotest_path): + copy = True + # Perform the copy + if copy: + kvm_log.info("Copying autotest.tar.bz2 to guest (file is missing or has a different size)...") + if not vm.scp_to_remote(tarred_autotest_path, ""): + raise error.TestFail, "Could not copy autotest.tar.bz2 to guest" + + # Check if we need to copy .tar.bz2 + copy = False + output = session.get_command_output("ls -l %s.tar.bz2" % test_name) + if "such file" in output: + copy = True + else: + size = int(output.split()[4]) + if size != os.path.getsize(tarred_test_path): + copy = True + # Perform the copy + if copy: + kvm_log.info("Copying %s.tar.bz2 to guest (file is missing or has a different size)..." % test_name) + if not vm.scp_to_remote(tarred_test_path, ""): + raise error.TestFail, "Could not copy %s.tar.bz2 to guest" % test_name + + # Extract autotest.tar.bz2 + kvm_log.info("Extracting autotest.tar.bz2...") + status = session.get_command_status("tar xvfj autotest.tar.bz2") + if status != 0: + raise error.TestFail, "Could not extract autotest.tar.bz2" + + # mkdir autotest/tests + session.sendline("mkdir autotest/tests") + + # Extract .tar.bz2 into autotest/tests + kvm_log.info("Extracting %s.tar.bz2..." % test_name) + status = session.get_command_status("tar xvfj %s.tar.bz2 -C autotest/tests" % test_name) + if status != 0: + raise error.TestFail, "Could not extract %s.tar.bz2" % test_name + + # Run the test + kvm_log.info("Running test '%s'..." % test_name) + session.sendline("cd autotest/tests/%s" % test_name) + session.sendline("rm -f ./%s.state" % test_control_file) + session.read_up_to_prompt() + session.sendline("../../bin/autotest ./%s" % test_control_file) + kvm_log.info("---------------- Test output ----------------") + match, output = session.read_up_to_prompt(timeout=test_timeout, print_func=kvm_log.info) + kvm_log.info("---------------- End of test output ----------------") + if not match: + raise error.TestFail, "Timeout elapsed while waiting for test to complete" + + session.close() + + # Parse test results + result_list = scan_results.parse_results(output) + + # Report test results and check for FAIL/ERROR status + kvm_log.info("Results (test, status, duration, info):") + status_error = False + status_fail = False + if result_list == []: + status_fail = True + message_fail = "Test '%s' did not produce any recognizable results" % test_name + for result in result_list: + kvm_log.info(str(result)) + if result[1] == "FAIL": + status_fail = True + message_fail = "Test '%s' ended with FAIL (info: '%s')" % (result[0], result[3]) + if result[1] == "ERROR": + status_error = True + message_error = "Test '%s' ended with ERROR (info: '%s')" % (result[0], result[3]) + if result[1] == "ABORT": + status_error = True + message_error = "Test '%s' ended with ABORT (info: '%s')" % (result[0], result[3]) + + # Copy test results to the local bindir/guest_results + kvm_log.info("Copying results back from guest...") + guest_results_dir = os.path.join(test.outputdir, "guest_results") + if not os.path.exists(guest_results_dir): + os.mkdir(guest_results_dir) + if not vm.scp_from_remote("autotest/results/default/*", guest_results_dir): + kvm_log.error("Could not copy results back from guest") + + # Fail the test if necessary + if status_fail: + raise error.TestFail, message_fail + elif status_error: + raise error.TestError, message_error diff --git a/client/tests/kvm_runtest_2/kvm_tests/boot.py b/client/tests/kvm_runtest_2/kvm_tests/boot.py new file mode 100644 index 0000000..b8ff668 --- /dev/null +++ b/client/tests/kvm_runtest_2/kvm_tests/boot.py @@ -0,0 +1,45 @@ +import time +import os + +from autotest_lib.client.common_lib import utils, error + +import kvm_log +import kvm_utils +import ppm_utils +import scan_results + + +def run_boot(test, params, env): + vm = kvm_utils.env_get_vm(env, params.get("main_vm")) + if not vm: + raise error.TestError, "VM object not found in environment" + if not vm.is_alive(): + raise error.TestError, "VM seems to be dead; Test requires a living VM" + + kvm_log.info("Waiting for guest to be up...") + + session = kvm_utils.wait_for(vm.ssh_login, 240, 0, 2) + if not session: + raise error.TestFail, "Could not log into guest" + + kvm_log.info("Logged in") + + if params.get("reboot") == "yes": + # Send the VM's reboot command + session.sendline(vm.get_params().get("cmd_reboot")) + kvm_log.info("Reboot command sent; waiting for guest to go down...") + + if not kvm_utils.wait_for(lambda: not session.is_responsive(), 120, 0, 1): + raise error.TestFail, "Guest refuses to go down" + + session.close() + + kvm_log.info("Guest is down; waiting for it to go up again...") + + session = kvm_utils.wait_for(vm.ssh_login, 120, 0, 2) + if not session: + raise error.TestFail, "Could not log into guest after reboot" + + kvm_log.info("Guest is up again") + + session.close() diff --git a/client/tests/kvm_runtest_2/kvm_tests/linux_s3.py b/client/tests/kvm_runtest_2/kvm_tests/linux_s3.py new file mode 100644 index 0000000..352f0a9 --- /dev/null +++ b/client/tests/kvm_runtest_2/kvm_tests/linux_s3.py @@ -0,0 +1,53 @@ +import time +import os + +from autotest_lib.client.common_lib import utils, error + +import kvm_log +import kvm_utils +import ppm_utils +import scan_results + +def run_linux_s3(test, params, env): + vm = kvm_utils.env_get_vm(env, params.get("main_vm")) + if not vm: + raise error.TestError, "VM object not found in environment" + if not vm.is_alive(): + raise error.TestError, "VM seems to be dead; Test requires a living VM" + + kvm_log.info("Waiting for guest to be up...") + + session = kvm_utils.wait_for(vm.ssh_login, 240, 0, 2) + if not session: + raise error.TestFail, "Could not log into guest" + + kvm_log.info("Logged in") + kvm_log.info("Checking that VM supports S3") + + status = session.get_command_status("grep -q mem /sys/power/state") + if status == None: + kvm_log.error("Failed to check if S3 exists") + elif status != 0: + raise error.TestFail, "Guest does not support S3" + + kvm_log.info("Waiting for a while for X to start") + time.sleep(10) + + src_tty = session.get_command_output("fgconsole").strip() + kvm_log.info("Current virtual terminal is %s" % src_tty) + if src_tty not in map(str, range(1,10)): + raise error.TestFail, "Got a strange current vt (%s)" % src_tty + + dst_tty = "1" + if src_tty == "1": + dst_tty = "2" + + kvm_log.info("Putting VM into S3") + command = "chvt %s && echo mem > /sys/power/state && chvt %s" % (dst_tty, src_tty) + status = session.get_command_status(command, timeout=120) + if status != 0: + raise error.TestFail, "Suspend to mem failed" + + kvm_log.info("VM resumed after S3") + + session.close() \ No newline at end of file diff --git a/client/tests/kvm_runtest_2/kvm_tests/migration.py b/client/tests/kvm_runtest_2/kvm_tests/migration.py new file mode 100644 index 0000000..1d8899a --- /dev/null +++ b/client/tests/kvm_runtest_2/kvm_tests/migration.py @@ -0,0 +1,132 @@ +import time +import os + +#from autotest_lib.client.common_lib import utils, error + +#import kvm_log +#import kvm_utils +#import ppm_utils +#import scan_results + +def run_migration(test, params, env): + src_vm_name = params.get("migration_src") + vm = kvm_utils.env_get_vm(env, src_vm_name) + if not vm: + raise error.TestError, "VM '%s' not found in environment" % src_vm_name + if not vm.is_alive(): + raise error.TestError, "VM '%s' seems to be dead; Test requires a living VM" % src_vm_name + + dest_vm_name = params.get("migration_dst") + dest_vm = kvm_utils.env_get_vm(env, dest_vm_name) + if not dest_vm: + raise error.TestError, "VM '%s' not found in environment" % dest_vm_name + if not dest_vm.is_alive(): + raise error.TestError, "VM '%s' seems to be dead; Test requires a living VM" % dest_vm_name + + pre_scrdump_filename = os.path.join(test.debugdir, "migration_pre.ppm") + post_scrdump_filename = os.path.join(test.debugdir, "migration_post.ppm") + + # See if migration is supported + s, o = vm.send_monitor_cmd("help info") + if not "info migrate" in o: + raise error.TestError, "Migration is not supported" + + # Log into guest and get the output of migration_test_command + kvm_log.info("Waiting for guest to be up...") + + session = kvm_utils.wait_for(vm.ssh_login, 240, 0, 2) + if not session: + raise error.TestFail, "Could not log into guest" + + kvm_log.info("Logged in") + + reference_output = session.get_command_output(params.get("migration_test_command")) + session.close() + + # Define the migration command + cmd = "migrate -d tcp:localhost:%d" % dest_vm.migration_port + kvm_log.debug("Migration command: %s" % cmd) + + # Migrate + s, o = vm.send_monitor_cmd(cmd) + if s: + kvm_log.error("Migration command failed (command: %r, output: %r)" % (cmd, o)) + raise error.TestFail, "Migration command failed" + + # Define some helper functions + def mig_finished(): + s, o = vm.send_monitor_cmd("info migrate") + if s: + return False + if "Migration status: active" in o: + return False + return True + + def mig_succeeded(): + s, o = vm.send_monitor_cmd("info migrate") + if s == 0 and "Migration status: completed" in o: + return True + return False + + def mig_failed(): + s, o = vm.send_monitor_cmd("info migrate") + if s == 0 and "Migration status: failed" in o: + return True + return False + + # Wait for migration to finish + if not kvm_utils.wait_for(mig_finished, 90, 2, 2, "Waiting for migration to finish..."): + raise error.TestFail, "Timeout elapsed while waiting for migration to finish" + + # Report migration status + if mig_succeeded(): + kvm_log.info("Migration finished successfully") + else: + if mig_failed(): + message = "Migration failed" + else: + message = "Migration ended with unknown status" + raise error.TestFail, message + + # Get 'post' screendump + dest_vm.send_monitor_cmd("screendump %s" % post_scrdump_filename) + + # Get 'pre' screendump + vm.send_monitor_cmd("screendump %s" % pre_scrdump_filename) + + # Kill the source VM + vm.send_monitor_cmd("quit", block=False) + + # Compare 'pre' and 'post' screendumps + # Should work, but disabled for now + #(pre_w, pre_h, pre_data) = ppm_utils.image_read_from_ppm_file(pre_scrdump_filename) + #(post_w, post_h, post_data) = ppm_utils.image_read_from_ppm_file(post_scrdump_filename) + #if pre_w != post_w or pre_h != post_h or ppm_utils.image_fuzzy_compare(pre_w, pre_h, pre_data, post_data) < 0.99: + # message = "Pre- and post-migration screendumps are too different" + # kvm_log.error(message + "\n(see info at %s)" % test.debugdir) + # raise error.TestFail, message + + # Hack: it seems that the first attempt to communicate with the SSH port following migration + # always fails (or succeeds after a very long time). So just connect to the port once so the + # following call to ssh_login succeeds. + dest_vm.is_sshd_running(timeout=0.0) + + # Log into guest and get the output of migration_test_command + kvm_log.info("Logging into guest after migration...") + + session = dest_vm.ssh_login() + if not session: + raise error.TestFail, "Could not log into guest after migration" + + kvm_log.info("Logged in after migration") + + output = session.get_command_output(params.get("migration_test_command")) + session.close() + + # Compare output to reference output + if output != reference_output: + kvm_log.info("Command output before migration differs from command output after migration") + kvm_log.info("Command: %s" % params.get("migration_test_command")) + kvm_log.info("Output before: %s" % reference_output) + kvm_log.info("Output after: %s" % output) + raise error.TestFail, "Command produced different output before and after migration" diff --git a/client/tests/kvm_runtest_2/kvm_tests/yum_update.py b/client/tests/kvm_runtest_2/kvm_tests/yum_update.py new file mode 100644 index 0000000..741c9ef --- /dev/null +++ b/client/tests/kvm_runtest_2/kvm_tests/yum_update.py @@ -0,0 +1,53 @@ +import time +import os + +from autotest_lib.client.common_lib import utils, error + +import kvm_log +import kvm_utils +import ppm_utils +import scan_results + +# I'm not sure if we need these... +def internal_yum_update(session, command, prompt, timeout): + session.sendline(command) + end_time = time.time() + timeout + while time.time() < end_time: + (match, text) = session.read_until_last_line_matches(["[Ii]s this [Oo][Kk]", prompt], timeout=timeout) + if match == 0: + kvm_log.info("Got 'Is this ok'; sending 'y'") + session.sendline("y") + elif match == 1: + kvm_log.info("Got shell prompt") + return True + else: + kvm_log.info("Timeout or process exited") + return False + + +def run_yum_update(test, params, env): + vm = kvm_utils.env_get_vm(env, params.get("main_vm")) + if not vm: + message = "VM object not found in environment" + kvm_log.error(message) + raise error.TestError, message + if not vm.is_alive(): + message = "VM seems to be dead; Test requires a living VM" + kvm_log.error(message) + raise error.TestError, message + + kvm_log.info("Logging into guest...") + + session = kvm_utils.wait_for(vm.ssh_login, 120, 0, 2) + if not session: + message = "Could not log into guest" + kvm_log.error(message) + raise error.TestFail, message + + kvm_log.info("Logged in") + + internal_yum_update(session, "yum update", params.get("ssh_prompt"), 600) + internal_yum_update(session, "yum update kernel", params.get("ssh_prompt"), 600) + + session.close() +