Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(141)

Side by Side Diff: client/tests/kvm/kvm_test_utils.py

Issue 6124004: Revert "Merge remote branch 'cros/upstream' into autotest-rebase" (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/autotest.git@master
Patch Set: Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « client/tests/kvm/kvm_subprocess.py ('k') | client/tests/kvm/kvm_utils.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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, commands, signal, threading 24 import time, os, logging, re, commands, 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 import kvm_utils, kvm_vm, kvm_subprocess, scan_results
28 28
29 29
30 def get_living_vm(env, vm_name): 30 def get_living_vm(env, vm_name):
31 """ 31 """
32 Get a VM object from the environment and make sure it's alive. 32 Get a VM object from the environment and make sure it's alive.
33 33
34 @param env: Dictionary with test environment. 34 @param env: Dictionary with test environment.
35 @param vm_name: Name of the desired VM object. 35 @param vm_name: Name of the desired VM object.
36 @return: A VM object. 36 @return: A VM object.
37 """ 37 """
38 vm = env.get_vm(vm_name) 38 vm = kvm_utils.env_get_vm(env, vm_name)
39 if not vm: 39 if not vm:
40 raise error.TestError("VM '%s' not found in environment" % vm_name) 40 raise error.TestError("VM '%s' not found in environment" % vm_name)
41 if not vm.is_alive(): 41 if not vm.is_alive():
42 raise error.TestError("VM '%s' seems to be dead; test requires a " 42 raise error.TestError("VM '%s' seems to be dead; test requires a "
43 "living VM" % vm_name) 43 "living VM" % vm_name)
44 return vm 44 return vm
45 45
46 46
47 def wait_for_login(vm, nic_index=0, timeout=240, start=0, step=2, serial=None): 47 def wait_for_login(vm, nic_index=0, timeout=240, start=0, step=2):
48 """ 48 """
49 Try logging into a VM repeatedly. Stop on success or when timeout expires. 49 Try logging into a VM repeatedly. Stop on success or when timeout expires.
50 50
51 @param vm: VM object. 51 @param vm: VM object.
52 @param nic_index: Index of NIC to access in the VM. 52 @param nic_index: Index of NIC to access in the VM.
53 @param timeout: Time to wait before giving up. 53 @param timeout: Time to wait before giving up.
54 @param serial: Whether to use a serial connection instead of a remote
55 (ssh, rss) one.
56 @return: A shell session object. 54 @return: A shell session object.
57 """ 55 """
58 type = 'remote' 56 logging.info("Trying to log into guest '%s', timeout %ds", vm.name, timeout)
59 if serial: 57 session = kvm_utils.wait_for(lambda: vm.remote_login(nic_index=nic_index),
60 type = 'serial' 58 timeout, start, step)
61 logging.info("Trying to log into guest %s using serial connection,"
62 " timeout %ds", vm.name, timeout)
63 session = kvm_utils.wait_for(lambda: vm.serial_login(), timeout,
64 start, step)
65 else:
66 logging.info("Trying to log into guest %s using remote connection,"
67 " timeout %ds", vm.name, timeout)
68 session = kvm_utils.wait_for(lambda: vm.remote_login(
69 nic_index=nic_index), timeout, start, step)
70 if not session: 59 if not session:
71 raise error.TestFail("Could not log into guest %s using %s connection" % 60 raise error.TestFail("Could not log into guest '%s'" % vm.name)
72 (vm.name, type)) 61 logging.info("Logged into guest '%s'" % vm.name)
73 logging.info("Logged into guest %s using %s connection", vm.name, type)
74 return session 62 return session
75 63
76 64
77 def reboot(vm, session, method="shell", sleep_before_reset=10, nic_index=0, 65 def reboot(vm, session, method="shell", sleep_before_reset=10, nic_index=0,
78 timeout=240): 66 timeout=240):
79 """ 67 """
80 Reboot the VM and wait for it to come back up by trying to log in until 68 Reboot the VM and wait for it to come back up by trying to log in until
81 timeout expires. 69 timeout expires.
82 70
83 @param vm: VM object. 71 @param vm: VM object.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 timeout) 114 timeout)
127 session = kvm_utils.wait_for(lambda: vm.remote_login(nic_index=nic_index), 115 session = kvm_utils.wait_for(lambda: vm.remote_login(nic_index=nic_index),
128 timeout, 0, 2) 116 timeout, 0, 2)
129 if not session: 117 if not session:
130 raise error.TestFail("Could not log into guest after reboot") 118 raise error.TestFail("Could not log into guest after reboot")
131 logging.info("Guest is up again") 119 logging.info("Guest is up again")
132 return session 120 return session
133 121
134 122
135 def migrate(vm, env=None, mig_timeout=3600, mig_protocol="tcp", 123 def migrate(vm, env=None, mig_timeout=3600, mig_protocol="tcp",
136 mig_cancel=False, offline=False, stable_check=False, 124 mig_cancel=False):
137 clean=False, save_path=None, dest_host='localhost', mig_port=None):
138 """ 125 """
139 Migrate a VM locally and re-register it in the environment. 126 Migrate a VM locally and re-register it in the environment.
140 127
141 @param vm: The VM to migrate. 128 @param vm: The VM to migrate.
142 @param env: The environment dictionary. If omitted, the migrated VM will 129 @param env: The environment dictionary. If omitted, the migrated VM will
143 not be registered. 130 not be registered.
144 @param mig_timeout: timeout value for migration. 131 @param mig_timeout: timeout value for migration.
145 @param mig_protocol: migration protocol 132 @param mig_protocol: migration protocol
146 @param mig_cancel: Test migrate_cancel or not when protocol is tcp. 133 @param mig_cancel: Test migrate_cancel or not when protocol is tcp.
147 @param dest_host: Destination host (defaults to 'localhost'). 134 @return: The post-migration VM.
148 @param mig_port: Port that will be used for migration.
149 @return: The post-migration VM, in case of same host migration, True in
150 case of multi-host migration.
151 """ 135 """
152 def mig_finished(): 136 def mig_finished():
153 o = vm.monitor.info("migrate") 137 o = vm.monitor.info("migrate")
154 if isinstance(o, str): 138 if isinstance(o, str):
155 return "status: active" not in o 139 return "status: active" not in o
156 else: 140 else:
157 return o.get("status") != "active" 141 return o.get("status") != "active"
158 142
159 def mig_succeeded(): 143 def mig_succeeded():
160 o = vm.monitor.info("migrate") 144 o = vm.monitor.info("migrate")
(...skipping 17 matching lines...) Expand all
178 else: 162 else:
179 return (o.get("status") == "cancelled" or 163 return (o.get("status") == "cancelled" or
180 o.get("status") == "canceled") 164 o.get("status") == "canceled")
181 165
182 def wait_for_migration(): 166 def wait_for_migration():
183 if not kvm_utils.wait_for(mig_finished, mig_timeout, 2, 2, 167 if not kvm_utils.wait_for(mig_finished, mig_timeout, 2, 2,
184 "Waiting for migration to finish..."): 168 "Waiting for migration to finish..."):
185 raise error.TestFail("Timeout expired while waiting for migration " 169 raise error.TestFail("Timeout expired while waiting for migration "
186 "to finish") 170 "to finish")
187 171
188 if dest_host == 'localhost': 172 dest_vm = vm.clone()
189 dest_vm = vm.clone()
190 173
191 if (dest_host == 'localhost') and stable_check: 174 if mig_protocol == "exec":
192 # Pause the dest vm after creation 175 # Exec is a little different from other migrate methods - first we
193 dest_vm.params['extra_params'] = (dest_vm.params.get('extra_params','') 176 # ask the monitor the migration, then the vm state is dumped to a
194 + ' -S') 177 # compressed file, then we start the dest vm with -incoming pointing
178 # to it
179 try:
180 exec_file = "/tmp/exec-%s.gz" % kvm_utils.generate_random_string(8)
181 exec_cmd = "gzip -c -d %s" % exec_file
182 uri = '"exec:gzip -c > %s"' % exec_file
183 vm.monitor.cmd("stop")
184 vm.monitor.migrate(uri)
185 wait_for_migration()
195 186
196 if dest_host == 'localhost': 187 if not dest_vm.create(migration_mode=mig_protocol,
188 migration_exec_cmd=exec_cmd, mac_source=vm):
189 raise error.TestError("Could not create dest VM")
190 finally:
191 logging.debug("Removing migration file %s", exec_file)
192 try:
193 os.remove(exec_file)
194 except OSError:
195 pass
196 else:
197 if not dest_vm.create(migration_mode=mig_protocol, mac_source=vm): 197 if not dest_vm.create(migration_mode=mig_protocol, mac_source=vm):
198 raise error.TestError("Could not create dest VM") 198 raise error.TestError("Could not create dest VM")
199
200 try:
201 try: 199 try:
202 if mig_protocol == "tcp": 200 if mig_protocol == "tcp":
203 if dest_host == 'localhost': 201 uri = "tcp:localhost:%d" % dest_vm.migration_port
204 uri = "tcp:localhost:%d" % dest_vm.migration_port
205 else:
206 uri = 'tcp:%s:%d' % (dest_host, mig_port)
207 elif mig_protocol == "unix": 202 elif mig_protocol == "unix":
208 uri = "unix:%s" % dest_vm.migration_file 203 uri = "unix:%s" % dest_vm.migration_file
209 elif mig_protocol == "exec":
210 uri = '"exec:nc localhost %s"' % dest_vm.migration_port
211
212 if offline:
213 vm.monitor.cmd("stop")
214 vm.monitor.migrate(uri) 204 vm.monitor.migrate(uri)
215 205
216 if mig_cancel: 206 if mig_cancel:
217 time.sleep(2) 207 time.sleep(2)
218 vm.monitor.cmd("migrate_cancel") 208 vm.monitor.cmd("migrate_cancel")
219 if not kvm_utils.wait_for(mig_cancelled, 60, 2, 2, 209 if not kvm_utils.wait_for(mig_cancelled, 60, 2, 2,
220 "Waiting for migration " 210 "Waiting for migration "
221 "cancellation"): 211 "cancellation"):
222 raise error.TestFail("Failed to cancel migration") 212 raise error.TestFail("Failed to cancel migration")
223 if offline: 213 dest_vm.destroy(gracefully=False)
224 vm.monitor.cmd("cont")
225 if dest_host == 'localhost':
226 dest_vm.destroy(gracefully=False)
227 return vm 214 return vm
228 else: 215 else:
229 wait_for_migration() 216 wait_for_migration()
230 if (dest_host == 'localhost') and stable_check:
231 save_path = None or "/tmp"
232 save1 = os.path.join(save_path, "src")
233 save2 = os.path.join(save_path, "dst")
234
235 vm.save_to_file(save1)
236 dest_vm.save_to_file(save2)
237
238 # Fail if we see deltas
239 md5_save1 = utils.hash_file(save1)
240 md5_save2 = utils.hash_file(save2)
241 if md5_save1 != md5_save2:
242 raise error.TestFail("Mismatch of VM state before "
243 "and after migration")
244
245 if (dest_host == 'localhost') and offline:
246 dest_vm.monitor.cmd("cont")
247 except: 217 except:
248 if dest_host == 'localhost': 218 dest_vm.destroy()
249 dest_vm.destroy()
250 raise 219 raise
251 220
252 finally:
253 if (dest_host == 'localhost') and stable_check and clean:
254 logging.debug("Cleaning the state files")
255 if os.path.isfile(save1):
256 os.remove(save1)
257 if os.path.isfile(save2):
258 os.remove(save2)
259
260 # Report migration status 221 # Report migration status
261 if mig_succeeded(): 222 if mig_succeeded():
262 logging.info("Migration finished successfully") 223 logging.info("Migration finished successfully")
263 elif mig_failed(): 224 elif mig_failed():
264 raise error.TestFail("Migration failed") 225 raise error.TestFail("Migration failed")
265 else: 226 else:
266 raise error.TestFail("Migration ended with unknown status") 227 raise error.TestFail("Migration ended with unknown status")
267 228
268 if dest_host == 'localhost': 229 if "paused" in dest_vm.monitor.info("status"):
269 if "paused" in dest_vm.monitor.info("status"): 230 logging.debug("Destination VM is paused, resuming it...")
270 logging.debug("Destination VM is paused, resuming it...") 231 dest_vm.monitor.cmd("cont")
271 dest_vm.monitor.cmd("cont")
272 232
273 # Kill the source VM 233 # Kill the source VM
274 vm.destroy(gracefully=False) 234 vm.destroy(gracefully=False)
275 235
276 # Replace the source VM with the new cloned VM 236 # Replace the source VM with the new cloned VM
277 if (dest_host == 'localhost') and (env is not None): 237 if env is not None:
278 env.register_vm(vm.name, dest_vm) 238 kvm_utils.env_register_vm(env, vm.name, dest_vm)
279 239
280 # Return the new cloned VM 240 # Return the new cloned VM
281 if dest_host == 'localhost': 241 return dest_vm
282 return dest_vm
283 else:
284 return vm
285 242
286 243
287 def stop_windows_service(session, service, timeout=120): 244 def stop_windows_service(session, service, timeout=120):
288 """ 245 """
289 Stop a Windows service using sc. 246 Stop a Windows service using sc.
290 If the service is already stopped or is not installed, do nothing. 247 If the service is already stopped or is not installed, do nothing.
291 248
292 @param service: The name of the service 249 @param service: The name of the service
293 @param timeout: Time duration to wait for service to stop 250 @param timeout: Time duration to wait for service to stop
294 @raise error.TestError: Raised if the service can't be stopped 251 @raise error.TestError: Raised if the service can't be stopped
295 """ 252 """
296 end_time = time.time() + timeout 253 end_time = time.time() + timeout
297 while time.time() < end_time: 254 while time.time() < end_time:
298 o = session.cmd_output("sc stop %s" % service, timeout=60) 255 o = session.get_command_output("sc stop %s" % service, timeout=60)
299 # FAILED 1060 means the service isn't installed. 256 # FAILED 1060 means the service isn't installed.
300 # FAILED 1062 means the service hasn't been started. 257 # FAILED 1062 means the service hasn't been started.
301 if re.search(r"\bFAILED (1060|1062)\b", o, re.I): 258 if re.search(r"\bFAILED (1060|1062)\b", o, re.I):
302 break 259 break
303 time.sleep(1) 260 time.sleep(1)
304 else: 261 else:
305 raise error.TestError("Could not stop service '%s'" % service) 262 raise error.TestError("Could not stop service '%s'" % service)
306 263
307 264
308 def start_windows_service(session, service, timeout=120): 265 def start_windows_service(session, service, timeout=120):
309 """ 266 """
310 Start a Windows service using sc. 267 Start a Windows service using sc.
311 If the service is already running, do nothing. 268 If the service is already running, do nothing.
312 If the service isn't installed, fail. 269 If the service isn't installed, fail.
313 270
314 @param service: The name of the service 271 @param service: The name of the service
315 @param timeout: Time duration to wait for service to start 272 @param timeout: Time duration to wait for service to start
316 @raise error.TestError: Raised if the service can't be started 273 @raise error.TestError: Raised if the service can't be started
317 """ 274 """
318 end_time = time.time() + timeout 275 end_time = time.time() + timeout
319 while time.time() < end_time: 276 while time.time() < end_time:
320 o = session.cmd_output("sc start %s" % service, timeout=60) 277 o = session.get_command_output("sc start %s" % service, timeout=60)
321 # FAILED 1060 means the service isn't installed. 278 # FAILED 1060 means the service isn't installed.
322 if re.search(r"\bFAILED 1060\b", o, re.I): 279 if re.search(r"\bFAILED 1060\b", o, re.I):
323 raise error.TestError("Could not start service '%s' " 280 raise error.TestError("Could not start service '%s' "
324 "(service not installed)" % service) 281 "(service not installed)" % service)
325 # FAILED 1056 means the service is already running. 282 # FAILED 1056 means the service is already running.
326 if re.search(r"\bFAILED 1056\b", o, re.I): 283 if re.search(r"\bFAILED 1056\b", o, re.I):
327 break 284 break
328 time.sleep(1) 285 time.sleep(1)
329 else: 286 else:
330 raise error.TestError("Could not start service '%s'" % service) 287 raise error.TestError("Could not start service '%s'" % service)
(...skipping 11 matching lines...) Expand all
342 @param session: A shell session. 299 @param session: A shell session.
343 @param time_command: Command to issue to get the current guest time. 300 @param time_command: Command to issue to get the current guest time.
344 @param time_filter_re: Regex filter to apply on the output of 301 @param time_filter_re: Regex filter to apply on the output of
345 time_command in order to get the current time. 302 time_command in order to get the current time.
346 @param time_format: Format string to pass to time.strptime() with the 303 @param time_format: Format string to pass to time.strptime() with the
347 result of the regex filter. 304 result of the regex filter.
348 @return: A tuple containing the host time and guest time. 305 @return: A tuple containing the host time and guest time.
349 """ 306 """
350 if len(re.findall("ntpdate|w32tm", time_command)) == 0: 307 if len(re.findall("ntpdate|w32tm", time_command)) == 0:
351 host_time = time.time() 308 host_time = time.time()
352 s = session.cmd_output(time_command) 309 session.sendline(time_command)
310 (match, s) = session.read_up_to_prompt()
311 if not match:
312 raise error.TestError("Could not get guest time")
353 313
354 try: 314 try:
355 s = re.findall(time_filter_re, s)[0] 315 s = re.findall(time_filter_re, s)[0]
356 except IndexError: 316 except IndexError:
357 logging.debug("The time string from guest is:\n%s" % s) 317 logging.debug("The time string from guest is:\n%s" % s)
358 raise error.TestError("The time string from guest is unexpected.") 318 raise error.TestError("The time string from guest is unexpected.")
359 except Exception, e: 319 except Exception, e:
360 logging.debug("(time_filter_re, time_string): (%s, %s)" % 320 logging.debug("(time_filter_re, time_string): (%s, %s)" %
361 (time_filter_re, s)) 321 (time_filter_re, s))
362 raise e 322 raise e
363 323
364 guest_time = time.mktime(time.strptime(s, time_format)) 324 guest_time = time.mktime(time.strptime(s, time_format))
365 else: 325 else:
366 o = session.cmd(time_command) 326 s , o = session.get_command_status_output(time_command)
327 if s != 0:
328 raise error.TestError("Could not get guest time")
367 if re.match('ntpdate', time_command): 329 if re.match('ntpdate', time_command):
368 offset = re.findall('offset (.*) sec',o)[0] 330 offset = re.findall('offset (.*) sec',o)[0]
369 host_main, host_mantissa = re.findall(time_filter_re, o)[0] 331 host_main, host_mantissa = re.findall(time_filter_re, o)[0]
370 host_time = time.mktime(time.strptime(host_main, time_format)) \ 332 host_time = time.mktime(time.strptime(host_main, time_format)) \
371 + float("0.%s" % host_mantissa) 333 + float("0.%s" % host_mantissa)
372 guest_time = host_time + float(offset) 334 guest_time = host_time + float(offset)
373 else: 335 else:
374 guest_time = re.findall(time_filter_re, o)[0] 336 guest_time = re.findall(time_filter_re, o)[0]
375 offset = re.findall("o:(.*)s", o)[0] 337 offset = re.findall("o:(.*)s", o)[0]
376 if re.match('PM', guest_time): 338 if re.match('PM', guest_time):
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 """ 396 """
435 Copy a file to a guest if it doesn't exist or if its MD5sum differs. 397 Copy a file to a guest if it doesn't exist or if its MD5sum differs.
436 398
437 @param vm: VM object. 399 @param vm: VM object.
438 @param local_path: Local path. 400 @param local_path: Local path.
439 @param remote_path: Remote path. 401 @param remote_path: Remote path.
440 """ 402 """
441 copy = False 403 copy = False
442 local_hash = utils.hash_file(local_path) 404 local_hash = utils.hash_file(local_path)
443 basename = os.path.basename(local_path) 405 basename = os.path.basename(local_path)
444 output = session.cmd_output("md5sum %s" % remote_path) 406 output = session.get_command_output("md5sum %s" % remote_path)
445 if "such file" in output: 407 if "such file" in output:
446 remote_hash = "0" 408 remote_hash = "0"
447 elif output: 409 elif output:
448 remote_hash = output.split()[0] 410 remote_hash = output.split()[0]
449 else: 411 else:
450 logging.warning("MD5 check for remote path %s did not return.", 412 logging.warning("MD5 check for remote path %s did not return.",
451 remote_path) 413 remote_path)
452 # Let's be a little more lenient here and see if it wasn't a 414 # Let's be a little more lenient here and see if it wasn't a
453 # temporary problem 415 # temporary problem
454 remote_hash = "0" 416 remote_hash = "0"
(...skipping 11 matching lines...) Expand all
466 """ 428 """
467 Extract a .tar.bz2 file on the guest. 429 Extract a .tar.bz2 file on the guest.
468 430
469 @param vm: VM object 431 @param vm: VM object
470 @param remote_path: Remote file path 432 @param remote_path: Remote file path
471 @param dest_dir: Destination dir for the contents 433 @param dest_dir: Destination dir for the contents
472 """ 434 """
473 basename = os.path.basename(remote_path) 435 basename = os.path.basename(remote_path)
474 logging.info("Extracting %s...", basename) 436 logging.info("Extracting %s...", basename)
475 e_cmd = "tar xjvf %s -C %s" % (remote_path, dest_dir) 437 e_cmd = "tar xjvf %s -C %s" % (remote_path, dest_dir)
476 session.cmd(e_cmd, timeout=120) 438 s, o = session.get_command_status_output(e_cmd, timeout=120)
439 if s != 0:
440 logging.error("Uncompress output:\n%s", o)
441 raise error.TestFail("Failed to extract %s on guest" % basename)
477 442
478 443
479 def get_results(): 444 def get_results():
480 """ 445 """
481 Copy autotest results present on the guest back to the host. 446 Copy autotest results present on the guest back to the host.
482 """ 447 """
483 logging.info("Trying to copy autotest results from guest") 448 logging.info("Trying to copy autotest results from guest")
484 guest_results_dir = os.path.join(outputdir, "guest_autotest_results") 449 guest_results_dir = os.path.join(outputdir, "guest_autotest_results")
485 if not os.path.exists(guest_results_dir): 450 if not os.path.exists(guest_results_dir):
486 os.mkdir(guest_results_dir) 451 os.mkdir(guest_results_dir)
487 if not vm.copy_files_from("%s/results/default/*" % autotest_path, 452 if not vm.copy_files_from("%s/results/default/*" % autotest_path,
488 guest_results_dir): 453 guest_results_dir):
489 logging.error("Could not copy autotest results from guest") 454 logging.error("Could not copy autotest results from guest")
490 455
491 456
492 def get_results_summary(): 457 def get_results_summary():
493 """ 458 """
494 Get the status of the tests that were executed on the host and close 459 Get the status of the tests that were executed on the host and close
495 the session where autotest was being executed. 460 the session where autotest was being executed.
496 """ 461 """
497 output = session.cmd_output("cat results/*/status") 462 output = session.get_command_output("cat results/*/status")
498 try: 463 try:
499 results = scan_results.parse_results(output) 464 results = scan_results.parse_results(output)
500 # Report test results 465 # Report test results
501 logging.info("Results (test, status, duration, info):") 466 logging.info("Results (test, status, duration, info):")
502 for result in results: 467 for result in results:
503 logging.info(str(result)) 468 logging.info(str(result))
504 session.close() 469 session.close()
505 return results 470 return results
506 except Exception, e: 471 except Exception, e:
507 logging.error("Error processing guest autotest results: %s", e) 472 logging.error("Error processing guest autotest results: %s", e)
(...skipping 28 matching lines...) Expand all
536 # Extract autotest.tar.bz2 501 # Extract autotest.tar.bz2
537 extract(vm, compressed_autotest_path, "/") 502 extract(vm, compressed_autotest_path, "/")
538 503
539 if not vm.copy_files_to(control_path, 504 if not vm.copy_files_to(control_path,
540 os.path.join(autotest_path, 'control')): 505 os.path.join(autotest_path, 'control')):
541 raise error.TestFail("Could not copy the test control file to guest") 506 raise error.TestFail("Could not copy the test control file to guest")
542 507
543 # Run the test 508 # Run the test
544 logging.info("Running autotest control file %s on guest, timeout %ss", 509 logging.info("Running autotest control file %s on guest, timeout %ss",
545 os.path.basename(control_path), timeout) 510 os.path.basename(control_path), timeout)
546 session.cmd("cd %s" % autotest_path) 511 session.get_command_output("cd %s" % autotest_path)
547 try: 512 session.get_command_output("rm -f control.state")
548 session.cmd("rm -f control.state") 513 session.get_command_output("rm -rf results/*")
549 session.cmd("rm -rf results/*") 514 logging.info("---------------- Test output ----------------")
550 except kvm_subprocess.ShellError: 515 status = session.get_command_status("bin/autotest control",
551 pass 516 timeout=timeout,
552 try: 517 print_func=logging.info)
553 try: 518 logging.info("------------- End of test output ------------")
554 logging.info("---------------- Test output ----------------") 519 if status is None:
555 session.cmd_output("bin/autotest control", timeout=timeout, 520 if not vm.is_alive():
556 print_func=logging.info)
557 finally:
558 logging.info("------------- End of test output ------------")
559 except kvm_subprocess.ShellTimeoutError:
560 if vm.is_alive():
561 get_results()
562 get_results_summary()
563 raise error.TestError("Timeout elapsed while waiting for job to "
564 "complete")
565 else:
566 raise error.TestError("Autotest job on guest failed " 521 raise error.TestError("Autotest job on guest failed "
567 "(VM terminated during job)") 522 "(VM terminated during job)")
568 except kvm_subprocess.ShellProcessTerminatedError: 523 if not session.is_alive():
524 get_results()
525 raise error.TestError("Autotest job on guest failed "
526 "(Remote session terminated during job)")
569 get_results() 527 get_results()
570 raise error.TestError("Autotest job on guest failed " 528 get_results_summary()
571 "(Remote session terminated during job)") 529 raise error.TestError("Timeout elapsed while waiting for job to "
530 "complete")
572 531
573 results = get_results_summary() 532 results = get_results_summary()
574 get_results() 533 get_results()
575 534
576 # Make a list of FAIL/ERROR/ABORT results (make sure FAIL results appear 535 # Make a list of FAIL/ERROR/ABORT results (make sure FAIL results appear
577 # before ERROR results, and ERROR results appear before ABORT results) 536 # before ERROR results, and ERROR results appear before ABORT results)
578 bad_results = [r[0] for r in results if r[1] == "FAIL"] 537 bad_results = [r[0] for r in results if r[1] == "FAIL"]
579 bad_results += [r[0] for r in results if r[1] == "ERROR"] 538 bad_results += [r[0] for r in results if r[1] == "ERROR"]
580 bad_results += [r[0] for r in results if r[1] == "ABORT"] 539 bad_results += [r[0] for r in results if r[1] == "ABORT"]
581 540
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 # always get the packet loss ratio even if timeout. 582 # always get the packet loss ratio even if timeout.
624 if process.is_alive(): 583 if process.is_alive():
625 kvm_utils.kill_process_tree(process.get_pid(), signal.SIGINT) 584 kvm_utils.kill_process_tree(process.get_pid(), signal.SIGINT)
626 585
627 status = process.get_status() 586 status = process.get_status()
628 output = process.get_output() 587 output = process.get_output()
629 588
630 process.close() 589 process.close()
631 return status, output 590 return status, output
632 else: 591 else:
633 try: 592 session.sendline(command)
634 output = session.cmd_output(command, timeout=timeout, 593 status, output = session.read_up_to_prompt(timeout=timeout,
635 print_func=output_func) 594 print_func=output_func)
636 except kvm_subprocess.ShellTimeoutError: 595 if not status:
637 # Send ctrl+c (SIGINT) through ssh session 596 # Send ctrl+c (SIGINT) through ssh session
638 session.send("\003") 597 session.send("\003")
639 try: 598 status, output2 = session.read_up_to_prompt(print_func=output_func)
640 output2 = session.read_up_to_prompt(print_func=output_func) 599 output += output2
641 output += output2 600 if not status:
642 except kvm_subprocess.ExpectTimeoutError, e:
643 output += e.output
644 # We also need to use this session to query the return value 601 # We also need to use this session to query the return value
645 session.send("\003") 602 session.send("\003")
646 603
647 session.sendline(session.status_test_command) 604 session.sendline(session.status_test_command)
648 try: 605 s2, o2 = session.read_up_to_prompt()
649 o2 = session.read_up_to_prompt() 606 if not s2:
650 except kvm_subprocess.ExpectError:
651 status = -1 607 status = -1
652 else: 608 else:
653 try: 609 try:
654 status = int(re.findall("\d+", o2)[0]) 610 status = int(re.findall("\d+", o2)[0])
655 except: 611 except:
656 status = -1 612 status = -1
657 613
658 return status, output 614 return status, output
659 615
660 616
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
707 663
708 664
709 def get_linux_ifname(session, mac_address): 665 def get_linux_ifname(session, mac_address):
710 """ 666 """
711 Get the interface name through the mac address. 667 Get the interface name through the mac address.
712 668
713 @param session: session to the virtual machine 669 @param session: session to the virtual machine
714 @mac_address: the macaddress of nic 670 @mac_address: the macaddress of nic
715 """ 671 """
716 672
717 output = session.cmd_output("ifconfig -a") 673 output = session.get_command_output("ifconfig -a")
718 674
719 try: 675 try:
720 ethname = re.findall("(\w+)\s+Link.*%s" % mac_address, output, 676 ethname = re.findall("(\w+)\s+Link.*%s" % mac_address, output,
721 re.IGNORECASE)[0] 677 re.IGNORECASE)[0]
722 return ethname 678 return ethname
723 except: 679 except:
724 return None 680 return None
OLDNEW
« no previous file with comments | « client/tests/kvm/kvm_subprocess.py ('k') | client/tests/kvm/kvm_utils.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698