lmr | 5c226e3 | 2009-07-27 13:13:01 +0000 | [diff] [blame] | 1 | import time, os, logging, re, commands |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 2 | from autotest_lib.client.common_lib import utils, error |
lmr | d85c55b | 2009-07-23 01:42:10 +0000 | [diff] [blame] | 3 | import kvm_utils, kvm_subprocess, ppm_utils, scan_results |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 4 | |
| 5 | """ |
| 6 | KVM test definitions. |
| 7 | |
| 8 | @copyright: 2008-2009 Red Hat Inc. |
| 9 | """ |
| 10 | |
| 11 | |
| 12 | def run_boot(test, params, env): |
| 13 | """ |
| 14 | KVM reboot test: |
| 15 | 1) Log into a guest |
lmr | 9ce347d | 2009-09-09 22:26:53 +0000 | [diff] [blame] | 16 | 2) Send a reboot command or a system_reset monitor command (optional) |
| 17 | 3) Wait until the guest is up again |
| 18 | 4) Log into the guest to verify it's up again |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 19 | |
| 20 | @param test: kvm test object |
| 21 | @param params: Dictionary with the test parameters |
| 22 | @param env: Dictionary with test environment. |
| 23 | """ |
| 24 | vm = kvm_utils.env_get_vm(env, params.get("main_vm")) |
| 25 | if not vm: |
| 26 | raise error.TestError("VM object not found in environment") |
| 27 | if not vm.is_alive(): |
| 28 | raise error.TestError("VM seems to be dead; Test requires a living VM") |
| 29 | |
| 30 | logging.info("Waiting for guest to be up...") |
| 31 | |
lmr | 912c74b | 2009-08-17 20:43:27 +0000 | [diff] [blame] | 32 | session = kvm_utils.wait_for(vm.remote_login, 240, 0, 2) |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 33 | if not session: |
| 34 | raise error.TestFail("Could not log into guest") |
| 35 | |
lmr | 9ce347d | 2009-09-09 22:26:53 +0000 | [diff] [blame] | 36 | try: |
| 37 | logging.info("Logged in") |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 38 | |
lmr | 9ce347d | 2009-09-09 22:26:53 +0000 | [diff] [blame] | 39 | if params.get("reboot_method") == "shell": |
| 40 | # Send a reboot command to the guest's shell |
| 41 | session.sendline(vm.get_params().get("reboot_command")) |
| 42 | logging.info("Reboot command sent; waiting for guest to go " |
| 43 | "down...") |
| 44 | elif params.get("reboot_method") == "system_reset": |
| 45 | # Sleep for a while -- give the guest a chance to finish booting |
| 46 | time.sleep(float(params.get("sleep_before_reset", 10))) |
| 47 | # Send a system_reset monitor command |
| 48 | vm.send_monitor_cmd("system_reset") |
| 49 | logging.info("system_reset monitor command sent; waiting for " |
| 50 | "guest to go down...") |
| 51 | else: return |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 52 | |
lmr | 9ce347d | 2009-09-09 22:26:53 +0000 | [diff] [blame] | 53 | # Wait for the session to become unresponsive |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 54 | if not kvm_utils.wait_for(lambda: not session.is_responsive(), |
| 55 | 120, 0, 1): |
| 56 | raise error.TestFail("Guest refuses to go down") |
| 57 | |
| 58 | session.close() |
| 59 | |
| 60 | logging.info("Guest is down; waiting for it to go up again...") |
| 61 | |
lmr | 912c74b | 2009-08-17 20:43:27 +0000 | [diff] [blame] | 62 | session = kvm_utils.wait_for(vm.remote_login, 240, 0, 2) |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 63 | if not session: |
| 64 | raise error.TestFail("Could not log into guest after reboot") |
| 65 | |
| 66 | logging.info("Guest is up again") |
| 67 | |
lmr | 9ce347d | 2009-09-09 22:26:53 +0000 | [diff] [blame] | 68 | finally: |
| 69 | session.close() |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 70 | |
| 71 | |
lmr | 6faadb2 | 2009-06-18 14:57:45 +0000 | [diff] [blame] | 72 | def run_shutdown(test, params, env): |
| 73 | """ |
| 74 | KVM shutdown test: |
| 75 | 1) Log into a guest |
lmr | 6e840e3 | 2009-09-09 22:38:07 +0000 | [diff] [blame] | 76 | 2) Send a shutdown command to the guest, or issue a system_powerdown |
| 77 | monitor command (depending on the value of shutdown_method) |
| 78 | 3) Wait until the guest is down |
lmr | 6faadb2 | 2009-06-18 14:57:45 +0000 | [diff] [blame] | 79 | |
| 80 | @param test: kvm test object |
| 81 | @param params: Dictionary with the test parameters |
| 82 | @param env: Dictionary with test environment |
| 83 | """ |
| 84 | vm = kvm_utils.env_get_vm(env, params.get("main_vm")) |
| 85 | if not vm: |
| 86 | raise error.TestError("VM object not found in environment") |
| 87 | if not vm.is_alive(): |
| 88 | raise error.TestError("VM seems to be dead; Test requires a living VM") |
| 89 | |
| 90 | logging.info("Waiting for guest to be up...") |
| 91 | |
lmr | 912c74b | 2009-08-17 20:43:27 +0000 | [diff] [blame] | 92 | session = kvm_utils.wait_for(vm.remote_login, 240, 0, 2) |
lmr | 6faadb2 | 2009-06-18 14:57:45 +0000 | [diff] [blame] | 93 | if not session: |
| 94 | raise error.TestFail("Could not log into guest") |
| 95 | |
lmr | 2077374 | 2009-08-13 04:43:45 +0000 | [diff] [blame] | 96 | try: |
| 97 | logging.info("Logged in") |
lmr | 6faadb2 | 2009-06-18 14:57:45 +0000 | [diff] [blame] | 98 | |
lmr | 6e840e3 | 2009-09-09 22:38:07 +0000 | [diff] [blame] | 99 | if params.get("shutdown_method") == "shell": |
| 100 | # Send a shutdown command to the guest's shell |
| 101 | session.sendline(vm.get_params().get("shutdown_command")) |
| 102 | logging.info("Shutdown command sent; waiting for guest to go " |
| 103 | "down...") |
| 104 | elif params.get("shutdown_method") == "system_powerdown": |
| 105 | # Sleep for a while -- give the guest a chance to finish booting |
| 106 | time.sleep(float(params.get("sleep_before_powerdown", 10))) |
| 107 | # Send a system_powerdown monitor command |
| 108 | vm.send_monitor_cmd("system_powerdown") |
| 109 | logging.info("system_powerdown monitor command sent; waiting for " |
| 110 | "guest to go down...") |
lmr | 6faadb2 | 2009-06-18 14:57:45 +0000 | [diff] [blame] | 111 | |
lmr | 2077374 | 2009-08-13 04:43:45 +0000 | [diff] [blame] | 112 | if not kvm_utils.wait_for(vm.is_dead, 240, 0, 1): |
| 113 | raise error.TestFail("Guest refuses to go down") |
lmr | 6faadb2 | 2009-06-18 14:57:45 +0000 | [diff] [blame] | 114 | |
lmr | 2077374 | 2009-08-13 04:43:45 +0000 | [diff] [blame] | 115 | logging.info("Guest is down") |
lmr | 6e840e3 | 2009-09-09 22:38:07 +0000 | [diff] [blame] | 116 | |
lmr | 2077374 | 2009-08-13 04:43:45 +0000 | [diff] [blame] | 117 | finally: |
| 118 | session.close() |
lmr | 6faadb2 | 2009-06-18 14:57:45 +0000 | [diff] [blame] | 119 | |
| 120 | |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 121 | def run_migration(test, params, env): |
| 122 | """ |
| 123 | KVM migration test: |
lmr | 4d5cc79 | 2009-09-09 22:01:57 +0000 | [diff] [blame] | 124 | 1) Get a live VM and clone it. |
| 125 | 2) Verify that the source VM supports migration. If it does, proceed with |
| 126 | the test. |
| 127 | 3) Send a migration command to the source VM and wait until it's finished. |
| 128 | 4) Kill off the source VM. |
| 129 | 3) Log into the destination VM after the migration is finished. |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 130 | 4) Compare the output of a reference command executed on the source with |
lmr | 4d5cc79 | 2009-09-09 22:01:57 +0000 | [diff] [blame] | 131 | the output of the same command on the destination machine. |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 132 | |
| 133 | @param test: kvm test object. |
| 134 | @param params: Dictionary with test parameters. |
| 135 | @param env: Dictionary with the test environment. |
| 136 | """ |
lmr | 4d5cc79 | 2009-09-09 22:01:57 +0000 | [diff] [blame] | 137 | vm = kvm_utils.env_get_vm(env, params.get("main_vm")) |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 138 | if not vm: |
lmr | 4d5cc79 | 2009-09-09 22:01:57 +0000 | [diff] [blame] | 139 | raise error.TestError("VM object not found in environment") |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 140 | if not vm.is_alive(): |
lmr | 4d5cc79 | 2009-09-09 22:01:57 +0000 | [diff] [blame] | 141 | raise error.TestError("VM seems to be dead; Test requires a living VM") |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 142 | |
| 143 | # See if migration is supported |
| 144 | s, o = vm.send_monitor_cmd("help info") |
| 145 | if not "info migrate" in o: |
| 146 | raise error.TestError("Migration is not supported") |
| 147 | |
lmr | 4d5cc79 | 2009-09-09 22:01:57 +0000 | [diff] [blame] | 148 | dest_vm = vm.clone() |
| 149 | dest_vm.create(for_migration=True) |
| 150 | |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 151 | # Log into guest and get the output of migration_test_command |
| 152 | logging.info("Waiting for guest to be up...") |
| 153 | |
lmr | 912c74b | 2009-08-17 20:43:27 +0000 | [diff] [blame] | 154 | session = kvm_utils.wait_for(vm.remote_login, 240, 0, 2) |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 155 | if not session: |
| 156 | raise error.TestFail("Could not log into guest") |
| 157 | |
| 158 | logging.info("Logged in") |
| 159 | |
| 160 | reference_output = session.get_command_output(params.get("migration_test_" |
| 161 | "command")) |
| 162 | session.close() |
| 163 | |
| 164 | # Define the migration command |
| 165 | cmd = "migrate -d tcp:localhost:%d" % dest_vm.migration_port |
| 166 | logging.debug("Migration command: %s" % cmd) |
| 167 | |
| 168 | # Migrate |
| 169 | s, o = vm.send_monitor_cmd(cmd) |
| 170 | if s: |
| 171 | logging.error("Migration command failed (command: %r, output: %r)" % |
| 172 | (cmd, o)) |
| 173 | raise error.TestFail("Migration command failed") |
| 174 | |
| 175 | # Define some helper functions |
| 176 | def mig_finished(): |
| 177 | s, o = vm.send_monitor_cmd("info migrate") |
lmr | 4d5cc79 | 2009-09-09 22:01:57 +0000 | [diff] [blame] | 178 | return s == 0 and not "Migration status: active" in o |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 179 | |
| 180 | def mig_succeeded(): |
| 181 | s, o = vm.send_monitor_cmd("info migrate") |
lmr | 4d5cc79 | 2009-09-09 22:01:57 +0000 | [diff] [blame] | 182 | return s == 0 and "Migration status: completed" in o |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 183 | |
| 184 | def mig_failed(): |
| 185 | s, o = vm.send_monitor_cmd("info migrate") |
lmr | 4d5cc79 | 2009-09-09 22:01:57 +0000 | [diff] [blame] | 186 | return s == 0 and "Migration status: failed" in o |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 187 | |
| 188 | # Wait for migration to finish |
| 189 | if not kvm_utils.wait_for(mig_finished, 90, 2, 2, |
| 190 | "Waiting for migration to finish..."): |
lmr | 4d5cc79 | 2009-09-09 22:01:57 +0000 | [diff] [blame] | 191 | raise error.TestFail("Timeout elapsed while waiting for migration to " |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 192 | "finish") |
| 193 | |
| 194 | # Report migration status |
| 195 | if mig_succeeded(): |
| 196 | logging.info("Migration finished successfully") |
lmr | 4d5cc79 | 2009-09-09 22:01:57 +0000 | [diff] [blame] | 197 | elif mig_failed(): |
| 198 | raise error.TestFail("Migration failed") |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 199 | else: |
lmr | 4d5cc79 | 2009-09-09 22:01:57 +0000 | [diff] [blame] | 200 | raise error.TestFail("Migration ended with unknown status") |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 201 | |
| 202 | # Kill the source VM |
lmr | 4d5cc79 | 2009-09-09 22:01:57 +0000 | [diff] [blame] | 203 | vm.destroy(gracefully=False) |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 204 | |
| 205 | # Log into guest and get the output of migration_test_command |
| 206 | logging.info("Logging into guest after migration...") |
| 207 | |
lmr | 912c74b | 2009-08-17 20:43:27 +0000 | [diff] [blame] | 208 | session = dest_vm.remote_login() |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 209 | if not session: |
| 210 | raise error.TestFail("Could not log into guest after migration") |
| 211 | |
| 212 | logging.info("Logged in after migration") |
| 213 | |
| 214 | output = session.get_command_output(params.get("migration_test_command")) |
| 215 | session.close() |
| 216 | |
| 217 | # Compare output to reference output |
| 218 | if output != reference_output: |
lmr | 4d5cc79 | 2009-09-09 22:01:57 +0000 | [diff] [blame] | 219 | logging.info("Command output before migration differs from command " |
| 220 | "output after migration") |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 221 | logging.info("Command: %s" % params.get("migration_test_command")) |
| 222 | logging.info("Output before:" + |
| 223 | kvm_utils.format_str_for_message(reference_output)) |
| 224 | logging.info("Output after:" + kvm_utils.format_str_for_message(output)) |
lmr | 4d5cc79 | 2009-09-09 22:01:57 +0000 | [diff] [blame] | 225 | raise error.TestFail("Command produced different output before and " |
| 226 | "after migration") |
| 227 | |
| 228 | kvm_utils.env_register_vm(env, params.get("main_vm"), dest_vm) |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 229 | |
| 230 | |
| 231 | def run_autotest(test, params, env): |
| 232 | """ |
| 233 | Run an autotest test inside a guest. |
| 234 | |
| 235 | @param test: kvm test object. |
| 236 | @param params: Dictionary with test parameters. |
| 237 | @param env: Dictionary with the test environment. |
| 238 | """ |
| 239 | vm = kvm_utils.env_get_vm(env, params.get("main_vm")) |
| 240 | if not vm: |
| 241 | raise error.TestError("VM object not found in environment") |
| 242 | if not vm.is_alive(): |
| 243 | raise error.TestError("VM seems to be dead; Test requires a living VM") |
| 244 | |
| 245 | logging.info("Logging into guest...") |
| 246 | |
lmr | 912c74b | 2009-08-17 20:43:27 +0000 | [diff] [blame] | 247 | session = kvm_utils.wait_for(vm.remote_login, 240, 0, 2) |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 248 | if not session: |
| 249 | raise error.TestFail("Could not log into guest") |
| 250 | |
| 251 | logging.info("Logged in") |
| 252 | |
| 253 | # Collect some info |
| 254 | test_name = params.get("test_name") |
| 255 | test_timeout = int(params.get("test_timeout", 300)) |
| 256 | test_control_file = params.get("test_control_file", "control") |
| 257 | tarred_autotest_path = "/tmp/autotest.tar.bz2" |
| 258 | tarred_test_path = "/tmp/%s.tar.bz2" % test_name |
| 259 | |
| 260 | # tar the contents of bindir/autotest |
| 261 | cmd = "cd %s; tar cvjf %s autotest/*" |
| 262 | cmd += " --exclude=autotest/tests" |
| 263 | cmd += " --exclude=autotest/results" |
| 264 | cmd += " --exclude=autotest/tmp" |
| 265 | cmd += " --exclude=autotest/control" |
| 266 | cmd += " --exclude=*.pyc" |
| 267 | cmd += " --exclude=*.svn" |
| 268 | cmd += " --exclude=*.git" |
lmr | d85c55b | 2009-07-23 01:42:10 +0000 | [diff] [blame] | 269 | kvm_subprocess.run_fg(cmd % (test.bindir, tarred_autotest_path), timeout=30) |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 270 | |
| 271 | # tar the contents of bindir/autotest/tests/<test_name> |
| 272 | cmd = "cd %s; tar cvjf %s %s/*" |
| 273 | cmd += " --exclude=*.pyc" |
| 274 | cmd += " --exclude=*.svn" |
| 275 | cmd += " --exclude=*.git" |
lmr | d85c55b | 2009-07-23 01:42:10 +0000 | [diff] [blame] | 276 | kvm_subprocess.run_fg(cmd % |
| 277 | (os.path.join(test.bindir, "autotest", "tests"), |
| 278 | tarred_test_path, test_name), timeout=30) |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 279 | |
| 280 | # Check if we need to copy autotest.tar.bz2 |
| 281 | copy = False |
| 282 | output = session.get_command_output("ls -l autotest.tar.bz2") |
| 283 | if "such file" in output: |
| 284 | copy = True |
| 285 | else: |
| 286 | size = int(output.split()[4]) |
| 287 | if size != os.path.getsize(tarred_autotest_path): |
| 288 | copy = True |
| 289 | # Perform the copy |
| 290 | if copy: |
| 291 | logging.info("Copying autotest.tar.bz2 to guest" |
| 292 | " (file is missing or has a different size)...") |
lmr | 912c74b | 2009-08-17 20:43:27 +0000 | [diff] [blame] | 293 | if not vm.copy_files_to(tarred_autotest_path, ""): |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 294 | raise error.TestFail("Could not copy autotest.tar.bz2 to guest") |
| 295 | |
| 296 | # Check if we need to copy <test_name>.tar.bz2 |
| 297 | copy = False |
| 298 | output = session.get_command_output("ls -l %s.tar.bz2" % test_name) |
| 299 | if "such file" in output: |
| 300 | copy = True |
| 301 | else: |
| 302 | size = int(output.split()[4]) |
| 303 | if size != os.path.getsize(tarred_test_path): |
| 304 | copy = True |
| 305 | # Perform the copy |
| 306 | if copy: |
| 307 | logging.info("Copying %s.tar.bz2 to guest (file is missing or has a" |
| 308 | " different size)..." % test_name) |
lmr | 912c74b | 2009-08-17 20:43:27 +0000 | [diff] [blame] | 309 | if not vm.copy_files_to(tarred_test_path, ""): |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 310 | raise error.TestFail("Could not copy %s.tar.bz2 to guest" % |
| 311 | test_name) |
| 312 | |
| 313 | # Extract autotest.tar.bz2 |
| 314 | logging.info("Extracting autotest.tar.bz2...") |
| 315 | status = session.get_command_status("tar xvfj autotest.tar.bz2") |
| 316 | if status != 0: |
| 317 | raise error.TestFail("Could not extract autotest.tar.bz2") |
| 318 | |
| 319 | # mkdir autotest/tests |
| 320 | session.sendline("mkdir autotest/tests") |
| 321 | |
| 322 | # Extract <test_name>.tar.bz2 into autotest/tests |
| 323 | logging.info("Extracting %s.tar.bz2..." % test_name) |
| 324 | status = session.get_command_status("tar xvfj %s.tar.bz2 -C " |
| 325 | "autotest/tests" % test_name) |
| 326 | if status != 0: |
| 327 | raise error.TestFail("Could not extract %s.tar.bz2" % test_name) |
| 328 | |
lmr | 16cf165 | 2009-06-15 21:32:49 +0000 | [diff] [blame] | 329 | # Cleaning up old remaining results |
| 330 | session.sendline("rm -rf autotest/results/*") |
| 331 | # Copying the selected control file (located inside |
| 332 | # test.bindir/autotest_control to the autotest dir |
| 333 | control_file_path = os.path.join(test.bindir, "autotest_control", |
| 334 | test_control_file) |
lmr | 912c74b | 2009-08-17 20:43:27 +0000 | [diff] [blame] | 335 | if not vm.copy_files_to(control_file_path, "autotest/control"): |
lmr | 16cf165 | 2009-06-15 21:32:49 +0000 | [diff] [blame] | 336 | raise error.TestFail("Could not copy the test control file to guest") |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 337 | # Run the test |
| 338 | logging.info("Running test '%s'..." % test_name) |
lmr | 16cf165 | 2009-06-15 21:32:49 +0000 | [diff] [blame] | 339 | session.sendline("cd autotest") |
| 340 | session.sendline("rm -f control.state") |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 341 | session.read_up_to_prompt() |
lmr | 16cf165 | 2009-06-15 21:32:49 +0000 | [diff] [blame] | 342 | session.sendline("bin/autotest control") |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 343 | logging.info("---------------- Test output ----------------") |
lmr | 16cf165 | 2009-06-15 21:32:49 +0000 | [diff] [blame] | 344 | match = session.read_up_to_prompt(timeout=test_timeout, |
| 345 | print_func=logging.info)[0] |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 346 | logging.info("---------------- End of test output ----------------") |
| 347 | if not match: |
lmr | 16cf165 | 2009-06-15 21:32:49 +0000 | [diff] [blame] | 348 | raise error.TestFail("Timeout elapsed while waiting for test to " |
| 349 | "complete") |
| 350 | # Get the results generated by autotest |
| 351 | output = session.get_command_output("cat results/*/status") |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 352 | |
| 353 | # Parse test results |
| 354 | result_list = scan_results.parse_results(output) |
| 355 | |
| 356 | # Report test results and check for FAIL/ERROR status |
| 357 | logging.info("Results (test, status, duration, info):") |
| 358 | status_error = False |
| 359 | status_fail = False |
| 360 | if result_list == []: |
| 361 | status_fail = True |
lmr | d16a67d | 2009-06-10 19:52:59 +0000 | [diff] [blame] | 362 | message_fail = ("Test '%s' did not produce any recognizable " |
| 363 | "results" % test_name) |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 364 | for result in result_list: |
| 365 | logging.info(str(result)) |
| 366 | if result[1] == "FAIL": |
| 367 | status_fail = True |
lmr | 50bece4 | 2009-06-15 20:54:43 +0000 | [diff] [blame] | 368 | message_fail = ("Test '%s' ended with FAIL " |
| 369 | "(info: '%s')" % (result[0], result[3])) |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 370 | if result[1] == "ERROR": |
| 371 | status_error = True |
lmr | 50bece4 | 2009-06-15 20:54:43 +0000 | [diff] [blame] | 372 | message_error = ("Test '%s' ended with ERROR " |
| 373 | "(info: '%s')" % (result[0], result[3])) |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 374 | if result[1] == "ABORT": |
| 375 | status_error = True |
lmr | 50bece4 | 2009-06-15 20:54:43 +0000 | [diff] [blame] | 376 | message_error = ("Test '%s' ended with ABORT " |
| 377 | "(info: '%s')" % (result[0], result[3])) |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 378 | |
| 379 | # Copy test results to the local bindir/guest_results |
| 380 | logging.info("Copying results back from guest...") |
| 381 | guest_results_dir = os.path.join(test.outputdir, "guest_results") |
| 382 | if not os.path.exists(guest_results_dir): |
| 383 | os.mkdir(guest_results_dir) |
lmr | 912c74b | 2009-08-17 20:43:27 +0000 | [diff] [blame] | 384 | if not vm.copy_files_from("autotest/results/default/*", guest_results_dir): |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 385 | logging.error("Could not copy results back from guest") |
| 386 | |
| 387 | # Fail the test if necessary |
| 388 | if status_fail: |
| 389 | raise error.TestFail(message_fail) |
| 390 | elif status_error: |
| 391 | raise error.TestError(message_error) |
| 392 | |
| 393 | |
| 394 | def internal_yum_update(session, command, prompt, timeout): |
| 395 | """ |
| 396 | Helper function to perform the yum update test. |
| 397 | |
lmr | 912c74b | 2009-08-17 20:43:27 +0000 | [diff] [blame] | 398 | @param session: shell session stablished to the host |
| 399 | @param command: Command to be sent to the shell session |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 400 | @param prompt: Machine prompt |
| 401 | @param timeout: How long to wait until we get an appropriate output from |
lmr | 912c74b | 2009-08-17 20:43:27 +0000 | [diff] [blame] | 402 | the shell session. |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 403 | """ |
| 404 | session.sendline(command) |
| 405 | end_time = time.time() + timeout |
| 406 | while time.time() < end_time: |
| 407 | (match, text) = session.read_until_last_line_matches( |
| 408 | ["[Ii]s this [Oo][Kk]", prompt], timeout=timeout) |
| 409 | if match == 0: |
| 410 | logging.info("Got 'Is this ok'; sending 'y'") |
| 411 | session.sendline("y") |
| 412 | elif match == 1: |
| 413 | logging.info("Got shell prompt") |
| 414 | return True |
| 415 | else: |
| 416 | logging.info("Timeout or process exited") |
| 417 | return False |
| 418 | |
| 419 | |
| 420 | def run_yum_update(test, params, env): |
| 421 | """ |
| 422 | Runs yum update and yum update kernel on the remote host (yum enabled |
| 423 | hosts only). |
| 424 | |
| 425 | @param test: kvm test object. |
| 426 | @param params: Dictionary with test parameters. |
| 427 | @param env: Dictionary with the test environment. |
| 428 | """ |
| 429 | vm = kvm_utils.env_get_vm(env, params.get("main_vm")) |
| 430 | if not vm: |
| 431 | message = "VM object not found in environment" |
| 432 | logging.error(message) |
| 433 | raise error.TestError(message) |
| 434 | if not vm.is_alive(): |
| 435 | message = "VM seems to be dead; Test requires a living VM" |
| 436 | logging.error(message) |
| 437 | raise error.TestError(message) |
| 438 | |
| 439 | logging.info("Logging into guest...") |
| 440 | |
lmr | 912c74b | 2009-08-17 20:43:27 +0000 | [diff] [blame] | 441 | session = kvm_utils.wait_for(vm.remote_login, 240, 0, 2) |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 442 | if not session: |
| 443 | message = "Could not log into guest" |
| 444 | logging.error(message) |
| 445 | raise error.TestFail(message) |
| 446 | |
| 447 | logging.info("Logged in") |
| 448 | |
lmr | 912c74b | 2009-08-17 20:43:27 +0000 | [diff] [blame] | 449 | internal_yum_update(session, "yum update", params.get("shell_prompt"), 600) |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 450 | internal_yum_update(session, "yum update kernel", |
lmr | 912c74b | 2009-08-17 20:43:27 +0000 | [diff] [blame] | 451 | params.get("shell_prompt"), 600) |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 452 | |
| 453 | session.close() |
| 454 | |
| 455 | |
| 456 | def run_linux_s3(test, params, env): |
| 457 | """ |
| 458 | Suspend a guest Linux OS to memory. |
| 459 | |
| 460 | @param test: kvm test object. |
| 461 | @param params: Dictionary with test parameters. |
| 462 | @param env: Dictionary with the test environment. |
| 463 | """ |
| 464 | vm = kvm_utils.env_get_vm(env, params.get("main_vm")) |
| 465 | if not vm: |
| 466 | raise error.TestError("VM object not found in environment") |
| 467 | if not vm.is_alive(): |
| 468 | raise error.TestError("VM seems to be dead; Test requires a living VM") |
| 469 | |
| 470 | logging.info("Waiting for guest to be up...") |
| 471 | |
lmr | 912c74b | 2009-08-17 20:43:27 +0000 | [diff] [blame] | 472 | session = kvm_utils.wait_for(vm.remote_login, 240, 0, 2) |
lmr | 6f669ce | 2009-05-31 19:02:42 +0000 | [diff] [blame] | 473 | if not session: |
| 474 | raise error.TestFail("Could not log into guest") |
| 475 | |
| 476 | logging.info("Logged in") |
| 477 | logging.info("Checking that VM supports S3") |
| 478 | |
| 479 | status = session.get_command_status("grep -q mem /sys/power/state") |
| 480 | if status == None: |
| 481 | logging.error("Failed to check if S3 exists") |
| 482 | elif status != 0: |
| 483 | raise error.TestFail("Guest does not support S3") |
| 484 | |
| 485 | logging.info("Waiting for a while for X to start") |
| 486 | time.sleep(10) |
| 487 | |
| 488 | src_tty = session.get_command_output("fgconsole").strip() |
| 489 | logging.info("Current virtual terminal is %s" % src_tty) |
| 490 | if src_tty not in map(str, range(1,10)): |
| 491 | raise error.TestFail("Got a strange current vt (%s)" % src_tty) |
| 492 | |
| 493 | dst_tty = "1" |
| 494 | if src_tty == "1": |
| 495 | dst_tty = "2" |
| 496 | |
| 497 | logging.info("Putting VM into S3") |
| 498 | command = "chvt %s && echo mem > /sys/power/state && chvt %s" % (dst_tty, |
| 499 | src_tty) |
| 500 | status = session.get_command_status(command, timeout=120) |
| 501 | if status != 0: |
| 502 | raise error.TestFail("Suspend to mem failed") |
| 503 | |
| 504 | logging.info("VM resumed after S3") |
| 505 | |
| 506 | session.close() |
lmr | a04d7c9 | 2009-06-19 13:05:39 +0000 | [diff] [blame] | 507 | |
| 508 | |
| 509 | def run_stress_boot(tests, params, env): |
| 510 | """ |
| 511 | Boots VMs until one of them becomes unresponsive, and records the maximum |
| 512 | number of VMs successfully started: |
| 513 | 1) boot the first vm |
| 514 | 2) boot the second vm cloned from the first vm, check whether it boots up |
lmr | 912c74b | 2009-08-17 20:43:27 +0000 | [diff] [blame] | 515 | and all booted vms respond to shell commands |
lmr | a04d7c9 | 2009-06-19 13:05:39 +0000 | [diff] [blame] | 516 | 3) go on until cannot create VM anymore or cannot allocate memory for VM |
| 517 | |
| 518 | @param test: kvm test object |
| 519 | @param params: Dictionary with the test parameters |
| 520 | @param env: Dictionary with test environment. |
| 521 | """ |
| 522 | # boot the first vm |
| 523 | vm = kvm_utils.env_get_vm(env, params.get("main_vm")) |
lmr | a04d7c9 | 2009-06-19 13:05:39 +0000 | [diff] [blame] | 524 | if not vm: |
| 525 | raise error.TestError("VM object not found in environment") |
| 526 | if not vm.is_alive(): |
| 527 | raise error.TestError("VM seems to be dead; Test requires a living VM") |
| 528 | |
| 529 | logging.info("Waiting for first guest to be up...") |
| 530 | |
lmr | 912c74b | 2009-08-17 20:43:27 +0000 | [diff] [blame] | 531 | session = kvm_utils.wait_for(vm.remote_login, 240, 0, 2) |
lmr | a04d7c9 | 2009-06-19 13:05:39 +0000 | [diff] [blame] | 532 | if not session: |
| 533 | raise error.TestFail("Could not log into first guest") |
| 534 | |
| 535 | num = 2 |
lmr | a04d7c9 | 2009-06-19 13:05:39 +0000 | [diff] [blame] | 536 | sessions = [session] |
lmr | 26bac24 | 2009-08-13 04:14:24 +0000 | [diff] [blame] | 537 | address_index = int(params.get("clone_address_index_base", 10)) |
lmr | a04d7c9 | 2009-06-19 13:05:39 +0000 | [diff] [blame] | 538 | |
| 539 | # boot the VMs |
| 540 | while num <= int(params.get("max_vms")): |
| 541 | try: |
| 542 | vm_name = "vm" + str(num) |
| 543 | |
| 544 | # clone vm according to the first one |
lmr | 26bac24 | 2009-08-13 04:14:24 +0000 | [diff] [blame] | 545 | vm_params = vm.get_params().copy() |
| 546 | vm_params["address_index"] = str(address_index) |
lmr | a04d7c9 | 2009-06-19 13:05:39 +0000 | [diff] [blame] | 547 | curr_vm = vm.clone(vm_name, vm_params) |
| 548 | kvm_utils.env_register_vm(env, vm_name, curr_vm) |
| 549 | params['vms'] += " " + vm_name |
| 550 | |
lmr | a04d7c9 | 2009-06-19 13:05:39 +0000 | [diff] [blame] | 551 | logging.info("Booting guest #%d" % num) |
| 552 | if not curr_vm.create(): |
| 553 | raise error.TestFail("Cannot create VM #%d" % num) |
| 554 | |
lmr | 912c74b | 2009-08-17 20:43:27 +0000 | [diff] [blame] | 555 | curr_vm_session = kvm_utils.wait_for(curr_vm.remote_login, 240, 0, 2) |
lmr | a04d7c9 | 2009-06-19 13:05:39 +0000 | [diff] [blame] | 556 | if not curr_vm_session: |
| 557 | raise error.TestFail("Could not log into guest #%d" % num) |
| 558 | |
| 559 | logging.info("Guest #%d boots up successfully" % num) |
| 560 | sessions.append(curr_vm_session) |
| 561 | |
lmr | 912c74b | 2009-08-17 20:43:27 +0000 | [diff] [blame] | 562 | # check whether all previous shell sessions are responsive |
lmr | 26bac24 | 2009-08-13 04:14:24 +0000 | [diff] [blame] | 563 | for i, se in enumerate(sessions): |
| 564 | if se.get_command_status(params.get("alive_test_cmd")) != 0: |
lmr | a04d7c9 | 2009-06-19 13:05:39 +0000 | [diff] [blame] | 565 | raise error.TestFail("Session #%d is not responsive" % i) |
| 566 | num += 1 |
lmr | 26bac24 | 2009-08-13 04:14:24 +0000 | [diff] [blame] | 567 | address_index += 1 |
lmr | a04d7c9 | 2009-06-19 13:05:39 +0000 | [diff] [blame] | 568 | |
| 569 | except (error.TestFail, OSError): |
| 570 | for se in sessions: |
| 571 | se.close() |
| 572 | logging.info("Total number booted: %d" % (num - 1)) |
| 573 | raise |
| 574 | else: |
| 575 | for se in sessions: |
| 576 | se.close() |
| 577 | logging.info("Total number booted: %d" % (num -1)) |
lmr | 5c226e3 | 2009-07-27 13:13:01 +0000 | [diff] [blame] | 578 | |
| 579 | |
| 580 | def run_timedrift(test, params, env): |
| 581 | """ |
| 582 | Time drift test (mainly for Windows guests): |
| 583 | |
| 584 | 1) Log into a guest. |
| 585 | 2) Take a time reading from the guest and host. |
| 586 | 3) Run load on the guest and host. |
| 587 | 4) Take a second time reading. |
| 588 | 5) Stop the load and rest for a while. |
| 589 | 6) Take a third time reading. |
| 590 | 7) If the drift immediately after load is higher than a user- |
| 591 | specified value (in %), fail. |
| 592 | If the drift after the rest period is higher than a user-specified value, |
| 593 | fail. |
| 594 | |
| 595 | @param test: KVM test object. |
| 596 | @param params: Dictionary with test parameters. |
| 597 | @param env: Dictionary with the test environment. |
| 598 | """ |
lmr | 25e89fc | 2009-08-07 20:29:16 +0000 | [diff] [blame] | 599 | # Helper functions |
| 600 | def set_cpu_affinity(pid, mask): |
| 601 | """ |
| 602 | Set the CPU affinity of all threads of the process with PID pid. |
lmr | 152da2d | 2009-09-09 22:16:21 +0000 | [diff] [blame] | 603 | Do this recursively for all child processes as well. |
lmr | 25e89fc | 2009-08-07 20:29:16 +0000 | [diff] [blame] | 604 | |
| 605 | @param pid: The process ID. |
| 606 | @param mask: The CPU affinity mask. |
| 607 | @return: A dict containing the previous mask for each thread. |
| 608 | """ |
| 609 | tids = commands.getoutput("ps -L --pid=%s -o lwp=" % pid).split() |
| 610 | prev_masks = {} |
| 611 | for tid in tids: |
| 612 | prev_mask = commands.getoutput("taskset -p %s" % tid).split()[-1] |
| 613 | prev_masks[tid] = prev_mask |
| 614 | commands.getoutput("taskset -p %s %s" % (mask, tid)) |
lmr | 152da2d | 2009-09-09 22:16:21 +0000 | [diff] [blame] | 615 | children = commands.getoutput("ps --ppid=%s -o pid=" % pid).split() |
| 616 | for child in children: |
| 617 | prev_masks.update(set_cpu_affinity(child, mask)) |
lmr | 25e89fc | 2009-08-07 20:29:16 +0000 | [diff] [blame] | 618 | return prev_masks |
| 619 | |
| 620 | def restore_cpu_affinity(prev_masks): |
| 621 | """ |
| 622 | Restore the CPU affinity of several threads. |
| 623 | |
| 624 | @param prev_masks: A dict containing TIDs as keys and masks as values. |
| 625 | """ |
| 626 | for tid, mask in prev_masks.items(): |
| 627 | commands.getoutput("taskset -p %s %s" % (mask, tid)) |
| 628 | |
lmr | ff2a7c5 | 2009-08-10 00:09:22 +0000 | [diff] [blame] | 629 | def get_time(session, time_command, time_filter_re, time_format): |
lmr | 25e89fc | 2009-08-07 20:29:16 +0000 | [diff] [blame] | 630 | """ |
| 631 | Returns the host time and guest time. |
| 632 | |
lmr | ff2a7c5 | 2009-08-10 00:09:22 +0000 | [diff] [blame] | 633 | @param session: A shell session. |
| 634 | @param time_command: Command to issue to get the current guest time. |
| 635 | @param time_filter_re: Regex filter to apply on the output of |
| 636 | time_command in order to get the current time. |
| 637 | @param time_format: Format string to pass to time.strptime() with the |
| 638 | result of the regex filter. |
lmr | 25e89fc | 2009-08-07 20:29:16 +0000 | [diff] [blame] | 639 | @return: A tuple containing the host time and guest time. |
| 640 | """ |
| 641 | host_time = time.time() |
| 642 | session.sendline(time_command) |
| 643 | (match, s) = session.read_up_to_prompt() |
| 644 | s = re.findall(time_filter_re, s)[0] |
| 645 | guest_time = time.mktime(time.strptime(s, time_format)) |
| 646 | return (host_time, guest_time) |
| 647 | |
lmr | 5c226e3 | 2009-07-27 13:13:01 +0000 | [diff] [blame] | 648 | vm = kvm_utils.env_get_vm(env, params.get("main_vm")) |
| 649 | if not vm: |
| 650 | raise error.TestError("VM object not found in environment") |
| 651 | if not vm.is_alive(): |
| 652 | raise error.TestError("VM seems to be dead; Test requires a living VM") |
| 653 | |
| 654 | logging.info("Waiting for guest to be up...") |
| 655 | |
lmr | 912c74b | 2009-08-17 20:43:27 +0000 | [diff] [blame] | 656 | session = kvm_utils.wait_for(vm.remote_login, 240, 0, 2) |
lmr | 5c226e3 | 2009-07-27 13:13:01 +0000 | [diff] [blame] | 657 | if not session: |
| 658 | raise error.TestFail("Could not log into guest") |
| 659 | |
| 660 | logging.info("Logged in") |
| 661 | |
| 662 | # Collect test parameters: |
| 663 | # Command to run to get the current time |
| 664 | time_command = params.get("time_command") |
| 665 | # Filter which should match a string to be passed to time.strptime() |
| 666 | time_filter_re = params.get("time_filter_re") |
| 667 | # Time format for time.strptime() |
| 668 | time_format = params.get("time_format") |
| 669 | guest_load_command = params.get("guest_load_command") |
| 670 | guest_load_stop_command = params.get("guest_load_stop_command") |
| 671 | host_load_command = params.get("host_load_command") |
| 672 | guest_load_instances = int(params.get("guest_load_instances", "1")) |
| 673 | host_load_instances = int(params.get("host_load_instances", "0")) |
| 674 | # CPU affinity mask for taskset |
| 675 | cpu_mask = params.get("cpu_mask", "0xFF") |
| 676 | load_duration = float(params.get("load_duration", "30")) |
| 677 | rest_duration = float(params.get("rest_duration", "10")) |
| 678 | drift_threshold = float(params.get("drift_threshold", "200")) |
| 679 | drift_threshold_after_rest = float(params.get("drift_threshold_after_rest", |
| 680 | "200")) |
| 681 | |
| 682 | guest_load_sessions = [] |
| 683 | host_load_sessions = [] |
| 684 | |
lmr | 5c226e3 | 2009-07-27 13:13:01 +0000 | [diff] [blame] | 685 | # Set the VM's CPU affinity |
lmr | 25e89fc | 2009-08-07 20:29:16 +0000 | [diff] [blame] | 686 | prev_affinity = set_cpu_affinity(vm.get_pid(), cpu_mask) |
lmr | 5c226e3 | 2009-07-27 13:13:01 +0000 | [diff] [blame] | 687 | |
| 688 | try: |
| 689 | # Get time before load |
lmr | ff2a7c5 | 2009-08-10 00:09:22 +0000 | [diff] [blame] | 690 | (host_time_0, guest_time_0) = get_time(session, time_command, |
| 691 | time_filter_re, time_format) |
lmr | 5c226e3 | 2009-07-27 13:13:01 +0000 | [diff] [blame] | 692 | |
| 693 | # Run some load on the guest |
| 694 | logging.info("Starting load on guest...") |
| 695 | for i in range(guest_load_instances): |
lmr | 912c74b | 2009-08-17 20:43:27 +0000 | [diff] [blame] | 696 | load_session = vm.remote_login() |
lmr | 5c226e3 | 2009-07-27 13:13:01 +0000 | [diff] [blame] | 697 | if not load_session: |
| 698 | raise error.TestFail("Could not log into guest") |
| 699 | load_session.set_output_prefix("(guest load %d) " % i) |
| 700 | load_session.set_output_func(logging.debug) |
| 701 | load_session.sendline(guest_load_command) |
| 702 | guest_load_sessions.append(load_session) |
| 703 | |
| 704 | # Run some load on the host |
| 705 | logging.info("Starting load on host...") |
| 706 | for i in range(host_load_instances): |
| 707 | host_load_sessions.append( |
| 708 | kvm_subprocess.run_bg(host_load_command, |
| 709 | output_func=logging.debug, |
| 710 | output_prefix="(host load %d) " % i, |
| 711 | timeout=0.5)) |
lmr | 152da2d | 2009-09-09 22:16:21 +0000 | [diff] [blame] | 712 | # Set the CPU affinity of the load process |
lmr | fb151b5 | 2009-09-09 22:19:11 +0000 | [diff] [blame] | 713 | pid = host_load_sessions[-1].get_pid() |
lmr | 25e89fc | 2009-08-07 20:29:16 +0000 | [diff] [blame] | 714 | set_cpu_affinity(pid, cpu_mask) |
lmr | 5c226e3 | 2009-07-27 13:13:01 +0000 | [diff] [blame] | 715 | |
| 716 | # Sleep for a while (during load) |
| 717 | logging.info("Sleeping for %s seconds..." % load_duration) |
| 718 | time.sleep(load_duration) |
| 719 | |
| 720 | # Get time delta after load |
lmr | ff2a7c5 | 2009-08-10 00:09:22 +0000 | [diff] [blame] | 721 | (host_time_1, guest_time_1) = get_time(session, time_command, |
| 722 | time_filter_re, time_format) |
lmr | 5c226e3 | 2009-07-27 13:13:01 +0000 | [diff] [blame] | 723 | |
| 724 | # Report results |
| 725 | host_delta = host_time_1 - host_time_0 |
| 726 | guest_delta = guest_time_1 - guest_time_0 |
| 727 | drift = 100.0 * (host_delta - guest_delta) / host_delta |
| 728 | logging.info("Host duration: %.2f" % host_delta) |
| 729 | logging.info("Guest duration: %.2f" % guest_delta) |
| 730 | logging.info("Drift: %.2f%%" % drift) |
| 731 | |
| 732 | finally: |
| 733 | logging.info("Cleaning up...") |
| 734 | # Restore the VM's CPU affinity |
lmr | 25e89fc | 2009-08-07 20:29:16 +0000 | [diff] [blame] | 735 | restore_cpu_affinity(prev_affinity) |
lmr | 5c226e3 | 2009-07-27 13:13:01 +0000 | [diff] [blame] | 736 | # Stop the guest load |
| 737 | if guest_load_stop_command: |
| 738 | session.get_command_output(guest_load_stop_command) |
| 739 | # Close all load shell sessions |
| 740 | for load_session in guest_load_sessions: |
| 741 | load_session.close() |
| 742 | for load_session in host_load_sessions: |
| 743 | load_session.close() |
| 744 | |
| 745 | # Sleep again (rest) |
| 746 | logging.info("Sleeping for %s seconds..." % rest_duration) |
| 747 | time.sleep(rest_duration) |
| 748 | |
| 749 | # Get time after rest |
lmr | ff2a7c5 | 2009-08-10 00:09:22 +0000 | [diff] [blame] | 750 | (host_time_2, guest_time_2) = get_time(session, time_command, |
| 751 | time_filter_re, time_format) |
lmr | 5c226e3 | 2009-07-27 13:13:01 +0000 | [diff] [blame] | 752 | |
| 753 | # Report results |
| 754 | host_delta_total = host_time_2 - host_time_0 |
| 755 | guest_delta_total = guest_time_2 - guest_time_0 |
| 756 | drift_total = 100.0 * (host_delta_total - guest_delta_total) / host_delta |
| 757 | logging.info("Total host duration including rest: %.2f" % host_delta_total) |
| 758 | logging.info("Total guest duration including rest: %.2f" % guest_delta_total) |
| 759 | logging.info("Total drift after rest: %.2f%%" % drift_total) |
| 760 | |
lmr | 5b82960 | 2009-08-07 20:36:06 +0000 | [diff] [blame] | 761 | session.close() |
| 762 | |
lmr | 5c226e3 | 2009-07-27 13:13:01 +0000 | [diff] [blame] | 763 | # Fail the test if necessary |
| 764 | if drift > drift_threshold: |
| 765 | raise error.TestFail("Time drift too large: %.2f%%" % drift) |
lmr | 67bf444 | 2009-08-28 17:29:45 +0000 | [diff] [blame] | 766 | if drift_total > drift_threshold_after_rest: |
lmr | 5c226e3 | 2009-07-27 13:13:01 +0000 | [diff] [blame] | 767 | raise error.TestFail("Time drift too large after rest period: %.2f%%" |
| 768 | % drift_total) |
lmr | 3efa0bd | 2009-08-18 20:00:56 +0000 | [diff] [blame] | 769 | |
| 770 | |
| 771 | def run_autoit(test, params, env): |
| 772 | """ |
| 773 | A wrapper for AutoIt scripts. |
| 774 | |
| 775 | 1) Log into a guest. |
| 776 | 2) Run AutoIt script. |
| 777 | 3) Wait for script execution to complete. |
| 778 | 4) Pass/fail according to exit status of script. |
| 779 | |
| 780 | @param test: KVM test object. |
| 781 | @param params: Dictionary with test parameters. |
| 782 | @param env: Dictionary with the test environment. |
| 783 | """ |
| 784 | vm = kvm_utils.env_get_vm(env, params.get("main_vm")) |
| 785 | if not vm: |
| 786 | raise error.TestError("VM object not found in environment") |
| 787 | if not vm.is_alive(): |
| 788 | raise error.TestError("VM seems to be dead; Test requires a living VM") |
| 789 | |
| 790 | logging.info("Waiting for guest to be up...") |
| 791 | |
| 792 | session = kvm_utils.wait_for(vm.remote_login, 240, 0, 2) |
| 793 | if not session: |
| 794 | raise error.TestFail("Could not log into guest") |
| 795 | |
| 796 | try: |
| 797 | logging.info("Logged in; starting script...") |
| 798 | |
| 799 | # Collect test parameters |
| 800 | binary = params.get("autoit_binary") |
| 801 | script = params.get("autoit_script") |
| 802 | script_params = params.get("autoit_script_params", "") |
| 803 | timeout = float(params.get("autoit_script_timeout", 600)) |
| 804 | |
| 805 | # Send AutoIt script to guest (this code will be replaced once we |
| 806 | # support sending files to Windows guests) |
| 807 | session.sendline("del script.au3") |
| 808 | file = open(kvm_utils.get_path(test.bindir, script)) |
| 809 | for line in file.readlines(): |
| 810 | # Insert a '^' before each character |
| 811 | line = "".join("^" + c for c in line.rstrip()) |
| 812 | if line: |
| 813 | # Append line to the file |
| 814 | session.sendline("echo %s>>script.au3" % line) |
| 815 | file.close() |
| 816 | |
| 817 | session.read_up_to_prompt() |
| 818 | |
| 819 | command = "cmd /c %s script.au3 %s" % (binary, script_params) |
| 820 | |
| 821 | logging.info("---------------- Script output ----------------") |
| 822 | status = session.get_command_status(command, |
| 823 | print_func=logging.info, |
| 824 | timeout=timeout) |
| 825 | logging.info("---------------- End of script output ----------------") |
| 826 | |
| 827 | if status is None: |
| 828 | raise error.TestFail("Timeout expired before script execution " |
| 829 | "completed (or something weird happened)") |
| 830 | if status != 0: |
| 831 | raise error.TestFail("Script execution failed") |
| 832 | |
| 833 | finally: |
| 834 | session.close() |