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

Side by Side Diff: client/tests/kvm/kvm_preprocessing.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.py ('k') | client/tests/kvm/kvm_scheduler.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 import sys, os, time, commands, re, logging, signal, glob, threading, shutil 1 import sys, os, time, commands, re, logging, signal, glob, threading, shutil
2 from autotest_lib.client.bin import test, utils 2 from autotest_lib.client.bin import test, utils
3 from autotest_lib.client.common_lib import error 3 from autotest_lib.client.common_lib import error
4 import kvm_vm, kvm_utils, kvm_subprocess, kvm_monitor, ppm_utils 4 import kvm_vm, kvm_utils, kvm_subprocess, kvm_monitor, ppm_utils
5 try: 5 try:
6 import PIL.Image 6 import PIL.Image
7 except ImportError: 7 except ImportError:
8 logging.warning('No python imaging library installed. PPM image ' 8 logging.warning('No python imaging library installed. PPM image '
9 'conversion to JPEG disabled. In order to enable it, ' 9 'conversion to JPEG disabled. In order to enable it, '
10 'please install python-imaging or the equivalent for your ' 10 'please install python-imaging or the equivalent for your '
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 """ 43 """
44 Preprocess a single VM object according to the instructions in params. 44 Preprocess a single VM object according to the instructions in params.
45 Start the VM if requested and get a screendump. 45 Start the VM if requested and get a screendump.
46 46
47 @param test: An Autotest test object. 47 @param test: An Autotest test object.
48 @param params: A dict containing VM preprocessing parameters. 48 @param params: A dict containing VM preprocessing parameters.
49 @param env: The environment (a dict-like object). 49 @param env: The environment (a dict-like object).
50 @param name: The name of the VM object. 50 @param name: The name of the VM object.
51 """ 51 """
52 logging.debug("Preprocessing VM '%s'..." % name) 52 logging.debug("Preprocessing VM '%s'..." % name)
53 vm = env.get_vm(name) 53 vm = kvm_utils.env_get_vm(env, name)
54 if vm: 54 if vm:
55 logging.debug("VM object found in environment") 55 logging.debug("VM object found in environment")
56 else: 56 else:
57 logging.debug("VM object does not exist; creating it") 57 logging.debug("VM object does not exist; creating it")
58 vm = kvm_vm.VM(name, params, test.bindir, env.get("address_cache")) 58 vm = kvm_vm.VM(name, params, test.bindir, env.get("address_cache"))
59 env.register_vm(name, vm) 59 kvm_utils.env_register_vm(env, name, vm)
60 60
61 start_vm = False 61 start_vm = False
62 62
63 migration_mode = params.get("migration_mode", None)
64
65 if params.get("restart_vm") == "yes": 63 if params.get("restart_vm") == "yes":
66 logging.debug("'restart_vm' specified; (re)starting VM...") 64 logging.debug("'restart_vm' specified; (re)starting VM...")
67 start_vm = True 65 start_vm = True
68 elif params.get("start_vm") == "yes": 66 elif params.get("start_vm") == "yes":
69 if not vm.is_alive(): 67 if not vm.is_alive():
70 logging.debug("VM is not alive; starting it...") 68 logging.debug("VM is not alive; starting it...")
71 start_vm = True 69 start_vm = True
72 elif vm.make_qemu_command() != vm.make_qemu_command(name, params, 70 elif vm.make_qemu_command() != vm.make_qemu_command(name, params,
73 test.bindir): 71 test.bindir):
74 logging.debug("VM's qemu command differs from requested one; " 72 logging.debug("VM's qemu command differs from requested one; "
75 "restarting it...") 73 "restarting it...")
76 start_vm = True 74 start_vm = True
77 elif migration_mode is not None:
78 logging.debug("Starting VM on migration incoming mode...")
79 start_vm = True
80 75
81 if start_vm: 76 if start_vm:
82 if migration_mode is not None: 77 # Start the VM (or restart it if it's already up)
83 if not vm.create(name, params, test.bindir, 78 if not vm.create(name, params, test.bindir):
84 migration_mode=migration_mode): 79 raise error.TestError("Could not start VM")
85 raise error.TestError("Could not start VM for migration")
86 else:
87 # Start the VM (or restart it if it's already up)
88 if not vm.create(name, params, test.bindir):
89 raise error.TestError("Could not start VM")
90 else: 80 else:
91 # Don't start the VM, just update its params 81 # Don't start the VM, just update its params
92 vm.params = params 82 vm.params = params
93 83
94 scrdump_filename = os.path.join(test.debugdir, "pre_%s.ppm" % name) 84 scrdump_filename = os.path.join(test.debugdir, "pre_%s.ppm" % name)
95 try: 85 try:
96 if vm.monitor: 86 if vm.monitor:
97 vm.monitor.screendump(scrdump_filename) 87 vm.monitor.screendump(scrdump_filename)
98 except kvm_monitor.MonitorError, e: 88 except kvm_monitor.MonitorError, e:
99 logging.warn(e) 89 logging.warn(e)
(...skipping 15 matching lines...) Expand all
115 """ 105 """
116 Postprocess a single VM object according to the instructions in params. 106 Postprocess a single VM object according to the instructions in params.
117 Kill the VM if requested and get a screendump. 107 Kill the VM if requested and get a screendump.
118 108
119 @param test: An Autotest test object. 109 @param test: An Autotest test object.
120 @param params: A dict containing VM postprocessing parameters. 110 @param params: A dict containing VM postprocessing parameters.
121 @param env: The environment (a dict-like object). 111 @param env: The environment (a dict-like object).
122 @param name: The name of the VM object. 112 @param name: The name of the VM object.
123 """ 113 """
124 logging.debug("Postprocessing VM '%s'..." % name) 114 logging.debug("Postprocessing VM '%s'..." % name)
125 vm = env.get_vm(name) 115 vm = kvm_utils.env_get_vm(env, name)
126 if vm: 116 if vm:
127 logging.debug("VM object found in environment") 117 logging.debug("VM object found in environment")
128 else: 118 else:
129 logging.debug("VM object does not exist in environment") 119 logging.debug("VM object does not exist in environment")
130 return 120 return
131 121
132 scrdump_filename = os.path.join(test.debugdir, "post_%s.ppm" % name) 122 scrdump_filename = os.path.join(test.debugdir, "post_%s.ppm" % name)
133 try: 123 try:
134 if vm.monitor: 124 if vm.monitor:
135 vm.monitor.screendump(scrdump_filename) 125 vm.monitor.screendump(scrdump_filename)
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 Pre- or post-process VMs and images according to the instructions in params. 166 Pre- or post-process VMs and images according to the instructions in params.
177 Call image_func for each image listed in params and vm_func for each VM. 167 Call image_func for each image listed in params and vm_func for each VM.
178 168
179 @param test: An Autotest test object. 169 @param test: An Autotest test object.
180 @param params: A dict containing all VM and image parameters. 170 @param params: A dict containing all VM and image parameters.
181 @param env: The environment (a dict-like object). 171 @param env: The environment (a dict-like object).
182 @param image_func: A function to call for each image. 172 @param image_func: A function to call for each image.
183 @param vm_func: A function to call for each VM. 173 @param vm_func: A function to call for each VM.
184 """ 174 """
185 # Get list of VMs specified for this test 175 # Get list of VMs specified for this test
186 for vm_name in params.objects("vms"): 176 vm_names = kvm_utils.get_sub_dict_names(params, "vms")
187 vm_params = params.object_params(vm_name) 177 for vm_name in vm_names:
178 vm_params = kvm_utils.get_sub_dict(params, vm_name)
188 # Get list of images specified for this VM 179 # Get list of images specified for this VM
189 for image_name in vm_params.objects("images"): 180 image_names = kvm_utils.get_sub_dict_names(vm_params, "images")
190 image_params = vm_params.object_params(image_name) 181 for image_name in image_names:
182 image_params = kvm_utils.get_sub_dict(vm_params, image_name)
191 # Call image_func for each image 183 # Call image_func for each image
192 image_func(test, image_params) 184 image_func(test, image_params)
193 # Call vm_func for each vm 185 # Call vm_func for each vm
194 vm_func(test, vm_params, env, vm_name) 186 vm_func(test, vm_params, env, vm_name)
195 187
196 188
197 def preprocess(test, params, env): 189 def preprocess(test, params, env):
198 """ 190 """
199 Preprocess all VMs and images according to the instructions in params. 191 Preprocess all VMs and images according to the instructions in params.
200 Also, collect some host information, such as the KVM version. 192 Also, collect some host information, such as the KVM version.
201 193
202 @param test: An Autotest test object. 194 @param test: An Autotest test object.
203 @param params: A dict containing all VM and image parameters. 195 @param params: A dict containing all VM and image parameters.
204 @param env: The environment (a dict-like object). 196 @param env: The environment (a dict-like object).
205 """ 197 """
206 # Start tcpdump if it isn't already running 198 # Start tcpdump if it isn't already running
207 if "address_cache" not in env: 199 if "address_cache" not in env:
208 env["address_cache"] = {} 200 env["address_cache"] = {}
209 if "tcpdump" in env and not env["tcpdump"].is_alive(): 201 if "tcpdump" in env and not env["tcpdump"].is_alive():
210 env["tcpdump"].close() 202 env["tcpdump"].close()
211 del env["tcpdump"] 203 del env["tcpdump"]
212 if "tcpdump" not in env and params.get("run_tcpdump", "yes") == "yes": 204 if "tcpdump" not in env and params.get("run_tcpdump", "yes") == "yes":
213 cmd = "%s -npvi any 'dst port 68'" % kvm_utils.find_command("tcpdump") 205 cmd = "%s -npvi any 'dst port 68'" % kvm_utils.find_command("tcpdump")
214 logging.debug("Starting tcpdump (%s)...", cmd) 206 logging.debug("Starting tcpdump (%s)...", cmd)
215 env["tcpdump"] = kvm_subprocess.Tail( 207 env["tcpdump"] = kvm_subprocess.kvm_tail(
216 command=cmd, 208 command=cmd,
217 output_func=_update_address_cache, 209 output_func=_update_address_cache,
218 output_params=(env["address_cache"],)) 210 output_params=(env["address_cache"],))
219 if kvm_utils.wait_for(lambda: not env["tcpdump"].is_alive(), 211 if kvm_utils.wait_for(lambda: not env["tcpdump"].is_alive(),
220 0.1, 0.1, 1.0): 212 0.1, 0.1, 1.0):
221 logging.warn("Could not start tcpdump") 213 logging.warn("Could not start tcpdump")
222 logging.warn("Status: %s" % env["tcpdump"].get_status()) 214 logging.warn("Status: %s" % env["tcpdump"].get_status())
223 logging.warn("Output:" + kvm_utils.format_str_for_message( 215 logging.warn("Output:" + kvm_utils.format_str_for_message(
224 env["tcpdump"].get_output())) 216 env["tcpdump"].get_output()))
225 217
226 # Destroy and remove VMs that are no longer needed in the environment 218 # Destroy and remove VMs that are no longer needed in the environment
227 requested_vms = params.objects("vms") 219 requested_vms = kvm_utils.get_sub_dict_names(params, "vms")
228 for key in env.keys(): 220 for key in env.keys():
229 vm = env[key] 221 vm = env[key]
230 if not kvm_utils.is_vm(vm): 222 if not kvm_utils.is_vm(vm):
231 continue 223 continue
232 if not vm.name in requested_vms: 224 if not vm.name in requested_vms:
233 logging.debug("VM '%s' found in environment but not required for " 225 logging.debug("VM '%s' found in environment but not required for "
234 "test; removing it..." % vm.name) 226 "test; removing it..." % vm.name)
235 vm.destroy() 227 vm.destroy()
236 del env[key] 228 del env[key]
237 229
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 logging.debug("'keep_screendumps' not specified; removing screendump " 323 logging.debug("'keep_screendumps' not specified; removing screendump "
332 "dirs...") 324 "dirs...")
333 for d in glob.glob(os.path.join(test.debugdir, "screendumps_*")): 325 for d in glob.glob(os.path.join(test.debugdir, "screendumps_*")):
334 if os.path.isdir(d) and not os.path.islink(d): 326 if os.path.isdir(d) and not os.path.islink(d):
335 shutil.rmtree(d, ignore_errors=True) 327 shutil.rmtree(d, ignore_errors=True)
336 328
337 # Kill all unresponsive VMs 329 # Kill all unresponsive VMs
338 if params.get("kill_unresponsive_vms") == "yes": 330 if params.get("kill_unresponsive_vms") == "yes":
339 logging.debug("'kill_unresponsive_vms' specified; killing all VMs " 331 logging.debug("'kill_unresponsive_vms' specified; killing all VMs "
340 "that fail to respond to a remote login request...") 332 "that fail to respond to a remote login request...")
341 for vm in env.get_all_vms(): 333 for vm in kvm_utils.env_get_all_vms(env):
342 if vm.is_alive(): 334 if vm.is_alive():
343 session = vm.remote_login() 335 session = vm.remote_login()
344 if session: 336 if session:
345 session.close() 337 session.close()
346 else: 338 else:
347 vm.destroy(gracefully=False) 339 vm.destroy(gracefully=False)
348 340
349 # Kill all kvm_subprocess tail threads 341 # Kill all kvm_subprocess tail threads
350 kvm_subprocess.kill_tail_threads() 342 kvm_subprocess.kill_tail_threads()
351 343
352 # Terminate tcpdump if no VMs are alive 344 # Terminate tcpdump if no VMs are alive
353 living_vms = [vm for vm in env.get_all_vms() if vm.is_alive()] 345 living_vms = [vm for vm in kvm_utils.env_get_all_vms(env) if vm.is_alive()]
354 if not living_vms and "tcpdump" in env: 346 if not living_vms and "tcpdump" in env:
355 env["tcpdump"].close() 347 env["tcpdump"].close()
356 del env["tcpdump"] 348 del env["tcpdump"]
357 349
358 # Execute any post_commands 350 # Execute any post_commands
359 if params.get("post_command"): 351 if params.get("post_command"):
360 process_command(test, params, env, params.get("post_command"), 352 process_command(test, params, env, params.get("post_command"),
361 int(params.get("post_command_timeout", "600")), 353 int(params.get("post_command_timeout", "600")),
362 params.get("post_command_noncritical") == "yes") 354 params.get("post_command_noncritical") == "yes")
363 355
364 356
365 def postprocess_on_error(test, params, env): 357 def postprocess_on_error(test, params, env):
366 """ 358 """
367 Perform postprocessing operations required only if the test failed. 359 Perform postprocessing operations required only if the test failed.
368 360
369 @param test: An Autotest test object. 361 @param test: An Autotest test object.
370 @param params: A dict containing all VM and image parameters. 362 @param params: A dict containing all VM and image parameters.
371 @param env: The environment (a dict-like object). 363 @param env: The environment (a dict-like object).
372 """ 364 """
373 params.update(params.object_params("on_error")) 365 params.update(kvm_utils.get_sub_dict(params, "on_error"))
374 366
375 367
376 def _update_address_cache(address_cache, line): 368 def _update_address_cache(address_cache, line):
377 if re.search("Your.IP", line, re.IGNORECASE): 369 if re.search("Your.IP", line, re.IGNORECASE):
378 matches = re.findall(r"\d*\.\d*\.\d*\.\d*", line) 370 matches = re.findall(r"\d*\.\d*\.\d*\.\d*", line)
379 if matches: 371 if matches:
380 address_cache["last_seen"] = matches[0] 372 address_cache["last_seen"] = matches[0]
381 if re.search("Client.Ethernet.Address", line, re.IGNORECASE): 373 if re.search("Client.Ethernet.Address", line, re.IGNORECASE):
382 matches = re.findall(r"\w*:\w*:\w*:\w*:\w*:\w*", line) 374 matches = re.findall(r"\w*:\w*:\w*:\w*:\w*:\w*", line)
383 if matches and address_cache.get("last_seen"): 375 if matches and address_cache.get("last_seen"):
384 mac_address = matches[0].lower() 376 mac_address = matches[0].lower()
385 if time.time() - address_cache.get("time_%s" % mac_address, 0) > 5: 377 logging.debug("(address cache) Adding cache entry: %s ---> %s",
386 logging.debug("(address cache) Adding cache entry: %s ---> %s", 378 mac_address, address_cache.get("last_seen"))
387 mac_address, address_cache.get("last_seen"))
388 address_cache[mac_address] = address_cache.get("last_seen") 379 address_cache[mac_address] = address_cache.get("last_seen")
389 address_cache["time_%s" % mac_address] = time.time()
390 del address_cache["last_seen"] 380 del address_cache["last_seen"]
391 381
392 382
393 def _take_screendumps(test, params, env): 383 def _take_screendumps(test, params, env):
394 global _screendump_thread_termination_event 384 global _screendump_thread_termination_event
395 temp_dir = test.debugdir 385 temp_dir = test.debugdir
396 if params.get("screendump_temp_dir"): 386 if params.get("screendump_temp_dir"):
397 temp_dir = kvm_utils.get_path(test.bindir, 387 temp_dir = kvm_utils.get_path(test.bindir,
398 params.get("screendump_temp_dir")) 388 params.get("screendump_temp_dir"))
399 try: 389 try:
400 os.makedirs(temp_dir) 390 os.makedirs(temp_dir)
401 except OSError: 391 except OSError:
402 pass 392 pass
403 temp_filename = os.path.join(temp_dir, "scrdump-%s.ppm" % 393 temp_filename = os.path.join(temp_dir, "scrdump-%s.ppm" %
404 kvm_utils.generate_random_string(6)) 394 kvm_utils.generate_random_string(6))
405 delay = float(params.get("screendump_delay", 5)) 395 delay = float(params.get("screendump_delay", 5))
406 quality = int(params.get("screendump_quality", 30)) 396 quality = int(params.get("screendump_quality", 30))
407 397
408 cache = {} 398 cache = {}
409 399
410 while True: 400 while True:
411 for vm in env.get_all_vms(): 401 for vm in kvm_utils.env_get_all_vms(env):
412 if not vm.is_alive(): 402 if not vm.is_alive():
413 continue 403 continue
414 try: 404 try:
415 vm.monitor.screendump(temp_filename) 405 vm.monitor.screendump(temp_filename)
416 except kvm_monitor.MonitorError, e: 406 except kvm_monitor.MonitorError, e:
417 logging.warn(e) 407 logging.warn(e)
418 continue 408 continue
419 if not os.path.exists(temp_filename): 409 if not os.path.exists(temp_filename):
420 logging.warn("VM '%s' failed to produce a screendump", vm.name) 410 logging.warn("VM '%s' failed to produce a screendump", vm.name)
421 continue 411 continue
(...skipping 20 matching lines...) Expand all
442 try: 432 try:
443 image = PIL.Image.open(temp_filename) 433 image = PIL.Image.open(temp_filename)
444 image.save(screendump_filename, format="JPEG", quality=quali ty) 434 image.save(screendump_filename, format="JPEG", quality=quali ty)
445 cache[hash] = screendump_filename 435 cache[hash] = screendump_filename
446 except NameError: 436 except NameError:
447 pass 437 pass
448 os.unlink(temp_filename) 438 os.unlink(temp_filename)
449 if _screendump_thread_termination_event.isSet(): 439 if _screendump_thread_termination_event.isSet():
450 break 440 break
451 _screendump_thread_termination_event.wait(delay) 441 _screendump_thread_termination_event.wait(delay)
OLDNEW
« no previous file with comments | « client/tests/kvm/kvm.py ('k') | client/tests/kvm/kvm_scheduler.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698