| OLD | NEW |
| 1 """ | 1 """ |
| 2 High-level KVM test utility functions. | 2 High-level KVM test utility functions. |
| 3 | 3 |
| 4 This module is meant to reduce code size by performing common test procedures. | 4 This module is meant to reduce code size by performing common test procedures. |
| 5 Generally, code here should look like test code. | 5 Generally, code here should look like test code. |
| 6 More specifically: | 6 More specifically: |
| 7 - Functions in this module should raise exceptions if things go wrong | 7 - Functions in this module should raise exceptions if things go wrong |
| 8 (unlike functions in kvm_utils.py and kvm_vm.py which report failure via | 8 (unlike functions in kvm_utils.py and kvm_vm.py which report failure via |
| 9 their returned values). | 9 their returned values). |
| 10 - Functions in this module may use logging.info(), in addition to | 10 - Functions in this module may use logging.info(), in addition to |
| 11 logging.debug() and logging.error(), to log messages the user may be | 11 logging.debug() and logging.error(), to log messages the user may be |
| 12 interested in (unlike kvm_utils.py and kvm_vm.py which use | 12 interested in (unlike kvm_utils.py and kvm_vm.py which use |
| 13 logging.debug() for anything that isn't an error). | 13 logging.debug() for anything that isn't an error). |
| 14 - Functions in this module typically use functions and classes from | 14 - Functions in this module typically use functions and classes from |
| 15 lower-level modules (e.g. kvm_utils.py, kvm_vm.py, kvm_subprocess.py). | 15 lower-level modules (e.g. kvm_utils.py, kvm_vm.py, kvm_subprocess.py). |
| 16 - Functions in this module should not be used by lower-level modules. | 16 - Functions in this module should not be used by lower-level modules. |
| 17 - Functions in this module should be used in the right context. | 17 - Functions in this module should be used in the right context. |
| 18 For example, a function should not be used where it may display | 18 For example, a function should not be used where it may display |
| 19 misleading or inaccurate info or debug messages. | 19 misleading or inaccurate info or debug messages. |
| 20 | 20 |
| 21 @copyright: 2008-2009 Red Hat Inc. | 21 @copyright: 2008-2009 Red Hat Inc. |
| 22 """ | 22 """ |
| 23 | 23 |
| 24 import time, os, logging, re, signal | 24 import time, os, logging, re, signal |
| 25 from autotest_lib.client.common_lib import error | 25 from autotest_lib.client.common_lib import error |
| 26 from autotest_lib.client.bin import utils | 26 from autotest_lib.client.bin import utils |
| 27 import kvm_utils, kvm_vm, kvm_subprocess, scan_results | 27 from autotest_lib.client.tools import scan_results |
| 28 import aexpect, virt_utils, virt_vm |
| 28 | 29 |
| 29 | 30 |
| 30 def get_living_vm(env, vm_name): | 31 def get_living_vm(env, vm_name): |
| 31 """ | 32 """ |
| 32 Get a VM object from the environment and make sure it's alive. | 33 Get a VM object from the environment and make sure it's alive. |
| 33 | 34 |
| 34 @param env: Dictionary with test environment. | 35 @param env: Dictionary with test environment. |
| 35 @param vm_name: Name of the desired VM object. | 36 @param vm_name: Name of the desired VM object. |
| 36 @return: A VM object. | 37 @return: A VM object. |
| 37 """ | 38 """ |
| (...skipping 21 matching lines...) Expand all Loading... |
| 59 session = None | 60 session = None |
| 60 if serial: | 61 if serial: |
| 61 type = 'serial' | 62 type = 'serial' |
| 62 logging.info("Trying to log into guest %s using serial connection," | 63 logging.info("Trying to log into guest %s using serial connection," |
| 63 " timeout %ds", vm.name, timeout) | 64 " timeout %ds", vm.name, timeout) |
| 64 time.sleep(start) | 65 time.sleep(start) |
| 65 while time.time() < end_time: | 66 while time.time() < end_time: |
| 66 try: | 67 try: |
| 67 session = vm.serial_login() | 68 session = vm.serial_login() |
| 68 break | 69 break |
| 69 except kvm_utils.LoginError, e: | 70 except virt_utils.LoginError, e: |
| 70 logging.debug(e) | 71 logging.debug(e) |
| 71 time.sleep(step) | 72 time.sleep(step) |
| 72 else: | 73 else: |
| 73 type = 'remote' | 74 type = 'remote' |
| 74 logging.info("Trying to log into guest %s using remote connection," | 75 logging.info("Trying to log into guest %s using remote connection," |
| 75 " timeout %ds", vm.name, timeout) | 76 " timeout %ds", vm.name, timeout) |
| 76 time.sleep(start) | 77 time.sleep(start) |
| 77 while time.time() < end_time: | 78 while time.time() < end_time: |
| 78 try: | 79 try: |
| 79 session = vm.login(nic_index=nic_index) | 80 session = vm.login(nic_index=nic_index) |
| 80 break | 81 break |
| 81 except (kvm_utils.LoginError, kvm_vm.VMError), e: | 82 except (virt_utils.LoginError, virt_vm.VMError), e: |
| 82 logging.debug(e) | 83 logging.debug(e) |
| 83 time.sleep(step) | 84 time.sleep(step) |
| 84 if not session: | 85 if not session: |
| 85 raise error.TestFail("Could not log into guest %s using %s connection" % | 86 raise error.TestFail("Could not log into guest %s using %s connection" % |
| 86 (vm.name, type)) | 87 (vm.name, type)) |
| 87 logging.info("Logged into guest %s using %s connection", vm.name, type) | 88 logging.info("Logged into guest %s using %s connection", vm.name, type) |
| 88 return session | 89 return session |
| 89 | 90 |
| 90 | 91 |
| 91 def reboot(vm, session, method="shell", sleep_before_reset=10, nic_index=0, | 92 def reboot(vm, session, method="shell", sleep_before_reset=10, nic_index=0, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 for m in monitors: | 124 for m in monitors: |
| 124 if not m.get_event("RESET"): | 125 if not m.get_event("RESET"): |
| 125 raise error.TestFail("RESET QMP event not received after " | 126 raise error.TestFail("RESET QMP event not received after " |
| 126 "system_reset (monitor '%s')" % m.name) | 127 "system_reset (monitor '%s')" % m.name) |
| 127 else: | 128 else: |
| 128 logging.info("RESET QMP event received") | 129 logging.info("RESET QMP event received") |
| 129 else: | 130 else: |
| 130 logging.error("Unknown reboot method: %s", method) | 131 logging.error("Unknown reboot method: %s", method) |
| 131 | 132 |
| 132 # Wait for the session to become unresponsive and close it | 133 # Wait for the session to become unresponsive and close it |
| 133 if not kvm_utils.wait_for(lambda: not session.is_responsive(timeout=30), | 134 if not virt_utils.wait_for(lambda: not session.is_responsive(timeout=30), |
| 134 120, 0, 1): | 135 120, 0, 1): |
| 135 raise error.TestFail("Guest refuses to go down") | 136 raise error.TestFail("Guest refuses to go down") |
| 136 session.close() | 137 session.close() |
| 137 | 138 |
| 138 # Try logging into the guest until timeout expires | 139 # Try logging into the guest until timeout expires |
| 139 logging.info("Guest is down. Waiting for it to go up again, timeout %ds", | 140 logging.info("Guest is down. Waiting for it to go up again, timeout %ds", |
| 140 timeout) | 141 timeout) |
| 141 session = vm.wait_for_login(nic_index, timeout=timeout) | 142 session = vm.wait_for_login(nic_index, timeout=timeout) |
| 142 logging.info("Guest is up again") | 143 logging.info("Guest is up again") |
| 143 return session | 144 return session |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 def mig_cancelled(): | 185 def mig_cancelled(): |
| 185 o = vm.monitor.info("migrate") | 186 o = vm.monitor.info("migrate") |
| 186 if isinstance(o, str): | 187 if isinstance(o, str): |
| 187 return ("Migration status: cancelled" in o or | 188 return ("Migration status: cancelled" in o or |
| 188 "Migration status: canceled" in o) | 189 "Migration status: canceled" in o) |
| 189 else: | 190 else: |
| 190 return (o.get("status") == "cancelled" or | 191 return (o.get("status") == "cancelled" or |
| 191 o.get("status") == "canceled") | 192 o.get("status") == "canceled") |
| 192 | 193 |
| 193 def wait_for_migration(): | 194 def wait_for_migration(): |
| 194 if not kvm_utils.wait_for(mig_finished, mig_timeout, 2, 2, | 195 if not virt_utils.wait_for(mig_finished, mig_timeout, 2, 2, |
| 195 "Waiting for migration to finish..."): | 196 "Waiting for migration to finish..."): |
| 196 raise error.TestFail("Timeout expired while waiting for migration " | 197 raise error.TestFail("Timeout expired while waiting for migration " |
| 197 "to finish") | 198 "to finish") |
| 198 | 199 |
| 199 if dest_host == 'localhost': | 200 if dest_host == 'localhost': |
| 200 dest_vm = vm.clone() | 201 dest_vm = vm.clone() |
| 201 | 202 |
| 202 if (dest_host == 'localhost') and stable_check: | 203 if (dest_host == 'localhost') and stable_check: |
| 203 # Pause the dest vm after creation | 204 # Pause the dest vm after creation |
| 204 dest_vm.params['extra_params'] = (dest_vm.params.get('extra_params','') | 205 dest_vm.params['extra_params'] = (dest_vm.params.get('extra_params','') |
| (...skipping 14 matching lines...) Expand all Loading... |
| 219 elif mig_protocol == "exec": | 220 elif mig_protocol == "exec": |
| 220 uri = '"exec:nc localhost %s"' % dest_vm.migration_port | 221 uri = '"exec:nc localhost %s"' % dest_vm.migration_port |
| 221 | 222 |
| 222 if offline: | 223 if offline: |
| 223 vm.monitor.cmd("stop") | 224 vm.monitor.cmd("stop") |
| 224 vm.monitor.migrate(uri) | 225 vm.monitor.migrate(uri) |
| 225 | 226 |
| 226 if mig_cancel: | 227 if mig_cancel: |
| 227 time.sleep(2) | 228 time.sleep(2) |
| 228 vm.monitor.cmd("migrate_cancel") | 229 vm.monitor.cmd("migrate_cancel") |
| 229 if not kvm_utils.wait_for(mig_cancelled, 60, 2, 2, | 230 if not virt_utils.wait_for(mig_cancelled, 60, 2, 2, |
| 230 "Waiting for migration " | 231 "Waiting for migration " |
| 231 "cancellation"): | 232 "cancellation"): |
| 232 raise error.TestFail("Failed to cancel migration") | 233 raise error.TestFail("Failed to cancel migration") |
| 233 if offline: | 234 if offline: |
| 234 vm.monitor.cmd("cont") | 235 vm.monitor.cmd("cont") |
| 235 if dest_host == 'localhost': | 236 if dest_host == 'localhost': |
| 236 dest_vm.destroy(gracefully=False) | 237 dest_vm.destroy(gracefully=False) |
| 237 return vm | 238 return vm |
| 238 else: | 239 else: |
| 239 wait_for_migration() | 240 wait_for_migration() |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 549 | 550 |
| 550 vm.copy_files_to(control_path, os.path.join(autotest_path, 'control')) | 551 vm.copy_files_to(control_path, os.path.join(autotest_path, 'control')) |
| 551 | 552 |
| 552 # Run the test | 553 # Run the test |
| 553 logging.info("Running autotest control file %s on guest, timeout %ss", | 554 logging.info("Running autotest control file %s on guest, timeout %ss", |
| 554 os.path.basename(control_path), timeout) | 555 os.path.basename(control_path), timeout) |
| 555 session.cmd("cd %s" % autotest_path) | 556 session.cmd("cd %s" % autotest_path) |
| 556 try: | 557 try: |
| 557 session.cmd("rm -f control.state") | 558 session.cmd("rm -f control.state") |
| 558 session.cmd("rm -rf results/*") | 559 session.cmd("rm -rf results/*") |
| 559 except kvm_subprocess.ShellError: | 560 except aexpect.ShellError: |
| 560 pass | 561 pass |
| 561 try: | 562 try: |
| 562 bg = None | 563 bg = None |
| 563 try: | 564 try: |
| 564 logging.info("---------------- Test output ----------------") | 565 logging.info("---------------- Test output ----------------") |
| 565 if migrate_background: | 566 if migrate_background: |
| 566 mig_timeout = float(params.get("mig_timeout", "3600")) | 567 mig_timeout = float(params.get("mig_timeout", "3600")) |
| 567 mig_protocol = params.get("migration_protocol", "tcp") | 568 mig_protocol = params.get("migration_protocol", "tcp") |
| 568 | 569 |
| 569 bg = kvm_utils.Thread(session.cmd_output, | 570 bg = virt_utils.Thread(session.cmd_output, |
| 570 kwargs={'cmd': "bin/autotest control", | 571 kwargs={'cmd': "bin/autotest control", |
| 571 'timeout': timeout, | 572 'timeout': timeout, |
| 572 'print_func': logging.info}) | 573 'print_func': logging.info}) |
| 573 | 574 |
| 574 bg.start() | 575 bg.start() |
| 575 | 576 |
| 576 while bg.is_alive(): | 577 while bg.is_alive(): |
| 577 logging.info("Tests is not ended, start a round of" | 578 logging.info("Tests is not ended, start a round of" |
| 578 "migration ...") | 579 "migration ...") |
| 579 vm.migrate(timeout=mig_timeout, protocol=mig_protocol) | 580 vm.migrate(timeout=mig_timeout, protocol=mig_protocol) |
| 580 else: | 581 else: |
| 581 session.cmd_output("bin/autotest control", timeout=timeout, | 582 session.cmd_output("bin/autotest control", timeout=timeout, |
| 582 print_func=logging.info) | 583 print_func=logging.info) |
| 583 finally: | 584 finally: |
| 584 logging.info("------------- End of test output ------------") | 585 logging.info("------------- End of test output ------------") |
| 585 if migrate_background and bg: | 586 if migrate_background and bg: |
| 586 bg.join() | 587 bg.join() |
| 587 except kvm_subprocess.ShellTimeoutError: | 588 except aexpect.ShellTimeoutError: |
| 588 if vm.is_alive(): | 589 if vm.is_alive(): |
| 589 get_results() | 590 get_results() |
| 590 get_results_summary() | 591 get_results_summary() |
| 591 raise error.TestError("Timeout elapsed while waiting for job to " | 592 raise error.TestError("Timeout elapsed while waiting for job to " |
| 592 "complete") | 593 "complete") |
| 593 else: | 594 else: |
| 594 raise error.TestError("Autotest job on guest failed " | 595 raise error.TestError("Autotest job on guest failed " |
| 595 "(VM terminated during job)") | 596 "(VM terminated during job)") |
| 596 except kvm_subprocess.ShellProcessTerminatedError: | 597 except aexpect.ShellProcessTerminatedError: |
| 597 get_results() | 598 get_results() |
| 598 raise error.TestError("Autotest job on guest failed " | 599 raise error.TestError("Autotest job on guest failed " |
| 599 "(Remote session terminated during job)") | 600 "(Remote session terminated during job)") |
| 600 | 601 |
| 601 results = get_results_summary() | 602 results = get_results_summary() |
| 602 get_results() | 603 get_results() |
| 603 | 604 |
| 604 # Make a list of FAIL/ERROR/ABORT results (make sure FAIL results appear | 605 # Make a list of FAIL/ERROR/ABORT results (make sure FAIL results appear |
| 605 # before ERROR results, and ERROR results appear before ABORT results) | 606 # before ERROR results, and ERROR results appear before ABORT results) |
| 606 bad_results = [r[0] for r in results if r[1] == "FAIL"] | 607 bad_results = [r[0] for r in results if r[1] == "FAIL"] |
| (...skipping 29 matching lines...) Expand all Loading... |
| 636 | 637 |
| 637 def raw_ping(command, timeout, session, output_func): | 638 def raw_ping(command, timeout, session, output_func): |
| 638 """ | 639 """ |
| 639 Low-level ping command execution. | 640 Low-level ping command execution. |
| 640 | 641 |
| 641 @param command: Ping command. | 642 @param command: Ping command. |
| 642 @param timeout: Timeout of the ping command. | 643 @param timeout: Timeout of the ping command. |
| 643 @param session: Local executon hint or session to execute the ping command. | 644 @param session: Local executon hint or session to execute the ping command. |
| 644 """ | 645 """ |
| 645 if session is None: | 646 if session is None: |
| 646 process = kvm_subprocess.run_bg(command, output_func=output_func, | 647 process = aexpect.run_bg(command, output_func=output_func, |
| 647 timeout=timeout) | 648 timeout=timeout) |
| 648 | 649 |
| 649 # Send SIGINT signal to notify the timeout of running ping process, | 650 # Send SIGINT signal to notify the timeout of running ping process, |
| 650 # Because ping have the ability to catch the SIGINT signal so we can | 651 # Because ping have the ability to catch the SIGINT signal so we can |
| 651 # always get the packet loss ratio even if timeout. | 652 # always get the packet loss ratio even if timeout. |
| 652 if process.is_alive(): | 653 if process.is_alive(): |
| 653 kvm_utils.kill_process_tree(process.get_pid(), signal.SIGINT) | 654 virt_utils.kill_process_tree(process.get_pid(), signal.SIGINT) |
| 654 | 655 |
| 655 status = process.get_status() | 656 status = process.get_status() |
| 656 output = process.get_output() | 657 output = process.get_output() |
| 657 | 658 |
| 658 process.close() | 659 process.close() |
| 659 return status, output | 660 return status, output |
| 660 else: | 661 else: |
| 661 output = "" | 662 output = "" |
| 662 try: | 663 try: |
| 663 output = session.cmd_output(command, timeout=timeout, | 664 output = session.cmd_output(command, timeout=timeout, |
| 664 print_func=output_func) | 665 print_func=output_func) |
| 665 except kvm_subprocess.ShellTimeoutError: | 666 except aexpect.ShellTimeoutError: |
| 666 # Send ctrl+c (SIGINT) through ssh session | 667 # Send ctrl+c (SIGINT) through ssh session |
| 667 session.send("\003") | 668 session.send("\003") |
| 668 try: | 669 try: |
| 669 output2 = session.read_up_to_prompt(print_func=output_func) | 670 output2 = session.read_up_to_prompt(print_func=output_func) |
| 670 output += output2 | 671 output += output2 |
| 671 except kvm_subprocess.ExpectTimeoutError, e: | 672 except aexpect.ExpectTimeoutError, e: |
| 672 output += e.output | 673 output += e.output |
| 673 # We also need to use this session to query the return value | 674 # We also need to use this session to query the return value |
| 674 session.send("\003") | 675 session.send("\003") |
| 675 | 676 |
| 676 session.sendline(session.status_test_command) | 677 session.sendline(session.status_test_command) |
| 677 try: | 678 try: |
| 678 o2 = session.read_up_to_prompt() | 679 o2 = session.read_up_to_prompt() |
| 679 except kvm_subprocess.ExpectError: | 680 except aexpect.ExpectError: |
| 680 status = -1 | 681 status = -1 |
| 681 else: | 682 else: |
| 682 try: | 683 try: |
| 683 status = int(re.findall("\d+", o2)[0]) | 684 status = int(re.findall("\d+", o2)[0]) |
| 684 except: | 685 except: |
| 685 status = -1 | 686 status = -1 |
| 686 | 687 |
| 687 return status, output | 688 return status, output |
| 688 | 689 |
| 689 | 690 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 744 """ | 745 """ |
| 745 | 746 |
| 746 output = session.cmd_output("ifconfig -a") | 747 output = session.cmd_output("ifconfig -a") |
| 747 | 748 |
| 748 try: | 749 try: |
| 749 ethname = re.findall("(\w+)\s+Link.*%s" % mac_address, output, | 750 ethname = re.findall("(\w+)\s+Link.*%s" % mac_address, output, |
| 750 re.IGNORECASE)[0] | 751 re.IGNORECASE)[0] |
| 751 return ethname | 752 return ethname |
| 752 except: | 753 except: |
| 753 return None | 754 return None |
| OLD | NEW |