def _take_screendumps(test, params, env): global _screendump_thread_termination_event temp_dir = test.debugdir if params.get("screendump_temp_dir"): temp_dir = kvm_utils.get_path(test.bindir, params.get("screendump_temp_dir")) try: os.makedirs(temp_dir) except OSError: pass temp_filename = os.path.join(temp_dir, "scrdump-%s.ppm" % kvm_utils.generate_random_string(6)) delay = float(params.get("screendump_delay", 5)) quality = int(params.get("screendump_quality", 30)) cache = {} while True: for vm in kvm_utils.env_get_all_vms(env): if not vm.is_alive(): continue try: vm.monitor.screendump(temp_filename) except kvm_monitor.MonitorError, e: logging.warn(e) continue if not os.path.exists(temp_filename): logging.warn("VM '%s' failed to produce a screendump", vm.name) continue if not ppm_utils.image_verify_ppm_file(temp_filename): logging.warn("VM '%s' produced an invalid screendump", vm.name) os.unlink(temp_filename) continue screendump_dir = os.path.join(test.debugdir, "screendumps_%s" % vm.name) try: os.makedirs(screendump_dir) except OSError: pass screendump_filename = os.path.join(screendump_dir, "%s_%s.jpg" % (vm.name, time.strftime("%Y-%m-%d_%H-%M-%S"))) hash = utils.hash_file(temp_filename) if hash in cache: try: os.link(cache[hash], screendump_filename) except OSError: pass else: try: image = PIL.Image.open(temp_filename) image.save(screendump_filename, format="JPEG", quality=quality) cache[hash] = screendump_filename except NameError: pass os.unlink(temp_filename) if _screendump_thread_termination_event.isSet(): break _screendump_thread_termination_event.wait(delay)
def postprocess(test, params, env): """ Postprocess all VMs and images according to the instructions in params. @param test: An Autotest test object. @param params: Dict containing all VM and image parameters. @param env: The environment (a dict-like object). """ process(test, params, env, postprocess_image, postprocess_vm) # Should we convert PPM files to PNG format? if params.get("convert_ppm_files_to_png") == "yes": logging.debug("'convert_ppm_files_to_png' specified; converting PPM" " files to PNG format...") try: for f in glob.glob(os.path.join(test.debugdir, "*.ppm")): if ppm_utils.image_verify_ppm_file(f): new_path = f.replace(".ppm", ".png") image = PIL.Image.open(f) image.save(new_path, format='PNG') except NameError: pass # Should we keep the PPM files? if params.get("keep_ppm_files") != "yes": logging.debug("'keep_ppm_files' not specified; removing all PPM files" " from debug dir...") for f in glob.glob(os.path.join(test.debugdir, '*.ppm')): os.unlink(f) # Execute any post_commands if params.get("post_command"): process_command(test, params, env, params.get("post_command"), int(params.get("post_command_timeout", "600")), params.get("post_command_noncritical") == "yes") # Kill the tailing threads of all VMs for vm in kvm_utils.env_get_all_vms(env): vm.kill_tail_thread() # Terminate tcpdump if no VMs are alive living_vms = [vm for vm in kvm_utils.env_get_all_vms(env) if vm.is_alive()] if not living_vms and env.has_key("tcpdump"): env["tcpdump"].close() del env["tcpdump"]
def postprocess(test, params, env): """ Postprocess all VMs and images according to the instructions in params. @param test: An Autotest test object. @param params: Dict containing all VM and image parameters. @param env: The environment (a dict-like object). """ # Postprocess all VMs and images process(test, params, env, postprocess_image, postprocess_vm) # Terminate the screendump thread global _screendump_thread, _screendump_thread_termination_event if _screendump_thread: logging.debug("Terminating screendump thread...") _screendump_thread_termination_event.set() _screendump_thread.join(10) _screendump_thread = None _screendump_thread_termination_event = None # Warn about corrupt PPM files for f in glob.glob(os.path.join(test.debugdir, "*.ppm")): if not ppm_utils.image_verify_ppm_file(f): logging.warn("Found corrupt PPM file: %s", f) # Should we convert PPM files to PNG format? if params.get("convert_ppm_files_to_png") == "yes": logging.debug("'convert_ppm_files_to_png' specified; converting PPM " "files to PNG format...") try: for f in glob.glob(os.path.join(test.debugdir, "*.ppm")): if ppm_utils.image_verify_ppm_file(f): new_path = f.replace(".ppm", ".png") image = PIL.Image.open(f) image.save(new_path, format='PNG') except NameError: pass # Should we keep the PPM files? if params.get("keep_ppm_files") != "yes": logging.debug("'keep_ppm_files' not specified; removing all PPM files " "from debug dir...") for f in glob.glob(os.path.join(test.debugdir, '*.ppm')): os.unlink(f) # Should we keep the screendump dirs? if params.get("keep_screendumps") != "yes": logging.debug("'keep_screendumps' not specified; removing screendump " "dirs...") for d in glob.glob(os.path.join(test.debugdir, "screendumps_*")): if os.path.isdir(d) and not os.path.islink(d): shutil.rmtree(d, ignore_errors=True) # Kill all unresponsive VMs if params.get("kill_unresponsive_vms") == "yes": logging.debug("'kill_unresponsive_vms' specified; killing all VMs " "that fail to respond to a remote login request...") for vm in kvm_utils.env_get_all_vms(env): if vm.is_alive(): session = vm.remote_login() if session: session.close() else: vm.destroy(gracefully=False) # Kill all kvm_subprocess tail threads kvm_subprocess.kill_tail_threads() # Terminate tcpdump if no VMs are alive living_vms = [vm for vm in kvm_utils.env_get_all_vms(env) if vm.is_alive()] if not living_vms and "tcpdump" in env: env["tcpdump"].close() del env["tcpdump"] # Execute any post_commands if params.get("post_command"): process_command(test, params, env, params.get("post_command"), int(params.get("post_command_timeout", "600")), params.get("post_command_noncritical") == "yes")
def run_once(self, params): # Report the parameters we've received and write them as keyvals logging.debug("Test parameters:") keys = params.keys() keys.sort() for key in keys: logging.debug(" %s = %s", key, params[key]) self.write_test_keyval({key: params[key]}) # Set the log file dir for the logging mechanism used by kvm_subprocess # (this must be done before unpickling env) kvm_utils.set_log_file_dir(self.debugdir) # Open the environment file logging.info("Unpickling env. You may see some harmless error " "messages.") env_filename = os.path.join(self.bindir, params.get("env", "env")) env = kvm_utils.load_env(env_filename, self.env_version) logging.debug("Contents of environment: %s", env) test_passed = False try: try: try: # Get the test routine corresponding to the specified # test type t_type = params.get("type") # Verify if we have the correspondent source file for it subtest_dir = os.path.join(self.bindir, "tests") module_path = os.path.join(subtest_dir, "%s.py" % t_type) if not os.path.isfile(module_path): raise error.TestError("No %s.py test file found" % t_type) # Load the test module f, p, d = imp.find_module(t_type, [subtest_dir]) test_module = imp.load_module(t_type, f, p, d) f.close() # Preprocess try: kvm_preprocessing.preprocess(self, params, env) finally: kvm_utils.dump_env(env, env_filename) # Run the test function run_func = getattr(test_module, "run_%s" % t_type) try: run_func(self, params, env) finally: kvm_utils.dump_env(env, env_filename) test_passed = True except Exception, e: logging.error("Test failed: %s: %s", e.__class__.__name__, e) try: kvm_preprocessing.postprocess_on_error( self, params, env) finally: kvm_utils.dump_env(env, env_filename) raise finally: # Postprocess try: try: kvm_preprocessing.postprocess(self, params, env) except Exception, e: if test_passed: raise logging.error("Exception raised during " "postprocessing: %s", e) finally: kvm_utils.dump_env(env, env_filename) logging.debug("Contents of environment: %s", env) except Exception, e: if params.get("abort_on_error") != "yes": raise # Abort on error logging.info("Aborting job (%s)", e) for vm in kvm_utils.env_get_all_vms(env): if vm.is_dead(): continue logging.info("VM '%s' is alive.", vm.name) for m in vm.monitors: logging.info("'%s' has a %s monitor unix socket at: %s", vm.name, m.protocol, m.filename) logging.info("The command line used to start '%s' was:\n%s", vm.name, vm.make_qemu_command()) raise error.JobError("Abort requested (%s)" % e)