def set_image_from_file(self, filename): if not ppm_utils.image_verify_ppm_file(filename): logging.warning("set_image_from_file: Warning: received invalid" "screendump file") return self.clear_image() (w, h, data) = ppm_utils.image_read_from_ppm_file(filename) self.set_image(w, h, data)
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 env.get_all_vms(): 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(): _screendump_thread_termination_event = None break _screendump_thread_termination_event.wait(delay)
def event_replace_clicked(self, widget): if not self.steps: return # Let the user choose a screendump file current_filename = os.path.join(self.steps_data_dir, self.entry_screendump.get_text()) filename = self.filedialog("Choose PPM image file", default_filename=current_filename) if not filename: return if not ppm_utils.image_verify_ppm_file(filename): self.message("Not a valid PPM image file.", "Error") return self.clear_image() self.clear_barrier_state() self.set_image_from_file(filename) self.update_screendump_id(self.steps_data_dir)
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 _take_screendumps(test, params, env): global _screendump_thread_termination_event temp_dir = test.debugdir if params.get("screendump_temp_dir"): temp_dir = utils_misc.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" % utils_misc.generate_random_string(6)) delay = float(params.get("screendump_delay", 5)) quality = int(params.get("screendump_quality", 30)) inactivity_treshold = float(params.get("inactivity_treshold", 1800)) inactivity_watcher = params.get("inactivity_watcher", "log") cache = {} counter = {} inactivity = {} while True: for vm in env.get_all_vms(): if vm not in counter.keys(): counter[vm] = 0 if vm not in inactivity.keys(): inactivity[vm] = time.time() if not vm.is_alive(): continue try: vm.screendump(filename=temp_filename, debug=False) except qemu_monitor.MonitorError, e: logging.warn(e) continue except AttributeError, 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 counter[vm] += 1 screendump_filename = os.path.join(screendump_dir, "%04d.jpg" % counter[vm]) image_hash = utils.hash_file(temp_filename) if image_hash in cache: time_inactive = time.time() - inactivity[vm] if time_inactive > inactivity_treshold: msg = ("%s screen is inactive for more than %d s (%d min)" % (vm.name, time_inactive, time_inactive/60)) if inactivity_watcher == "error": try: raise virt_vm.VMScreenInactiveError(vm, time_inactive) except virt_vm.VMScreenInactiveError: logging.error(msg) # Let's reset the counter inactivity[vm] = time.time() test.background_errors.put(sys.exc_info()) elif inactivity_watcher == 'log': logging.debug(msg) try: os.link(cache[image_hash], screendump_filename) except OSError: pass else: inactivity[vm] = time.time() try: try: image = PIL.Image.open(temp_filename) image.save(screendump_filename, format="JPEG", quality=quality) cache[image_hash] = screendump_filename except IOError, error_detail: logging.warning("VM '%s' failed to produce a " "screendump: %s", vm.name, error_detail) # Decrement the counter as we in fact failed to # produce a converted screendump counter[vm] -= 1 except NameError: pass os.unlink(temp_filename)
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). """ error.context("postprocessing") # Postprocess all VMs and images process(test, params, env, postprocess_image, postprocess_vm, vm_first=True) # Terminate the screendump thread global _screendump_thread, _screendump_thread_termination_event if _screendump_thread is not None: _screendump_thread_termination_event.set() _screendump_thread.join(10) _screendump_thread = 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": 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", "no") != "yes": 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", "no") != "yes": 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) # Should we keep the video files? if params.get("keep_video_files", "yes") != "yes": for f in (glob.glob(os.path.join(test.debugdir, '*.ogg')) + glob.glob(os.path.join(test.debugdir, '*.webm'))): os.unlink(f) # Kill all unresponsive VMs if params.get("kill_unresponsive_vms") == "yes": for vm in env.get_all_vms(): if vm.is_alive(): try: session = vm.login() session.close() except (remote.LoginError, virt_vm.VMError), e: logging.warn(e) vm.destroy(gracefully=False)
def _take_screendumps(test, params, env): global _screendump_thread_termination_event temp_dir = test.debugdir if params.get("screendump_temp_dir"): temp_dir = utils_misc.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" % utils_misc.generate_random_string(6)) delay = float(params.get("screendump_delay", 5)) quality = int(params.get("screendump_quality", 30)) inactivity_treshold = float(params.get("inactivity_treshold", 1800)) inactivity_watcher = params.get("inactivity_watcher", "log") cache = {} counter = {} inactivity = {} while True: for vm in env.get_all_vms(): if vm.instance not in counter.keys(): counter[vm.instance] = 0 if vm.instance not in inactivity.keys(): inactivity[vm.instance] = time.time() if not vm.is_alive(): continue vm_pid = vm.get_pid() try: vm.screendump(filename=temp_filename, debug=False) except qemu_monitor.MonitorError, e: logging.warn(e) continue except AttributeError, 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_%s" % (vm.name, vm_pid)) try: os.makedirs(screendump_dir) except OSError: pass counter[vm.instance] += 1 screendump_filename = os.path.join( screendump_dir, "%04d.jpg" % counter[vm.instance]) vm.verify_bsod(screendump_filename) image_hash = utils.hash_file(temp_filename) if image_hash in cache: time_inactive = time.time() - inactivity[vm.instance] if time_inactive > inactivity_treshold: msg = ( "%s screen is inactive for more than %d s (%d min)" % (vm.name, time_inactive, time_inactive / 60)) if inactivity_watcher == "error": try: raise virt_vm.VMScreenInactiveError( vm, time_inactive) except virt_vm.VMScreenInactiveError: logging.error(msg) # Let's reset the counter inactivity[vm.instance] = time.time() test.background_errors.put(sys.exc_info()) elif inactivity_watcher == 'log': logging.debug(msg) try: os.link(cache[image_hash], screendump_filename) except OSError: pass else: inactivity[vm.instance] = time.time() try: try: image = PIL.Image.open(temp_filename) image.save(screendump_filename, format="JPEG", quality=quality) cache[image_hash] = screendump_filename except IOError, error_detail: logging.warning( "VM '%s' failed to produce a " "screendump: %s", vm.name, error_detail) # Decrement the counter as we in fact failed to # produce a converted screendump counter[vm.instance] -= 1 except NameError: pass os.unlink(temp_filename)
test.debugdir, "%s-%s.webm" % (screendump_dir, test.iteration)) else: video_file = os.path.join( test.debugdir, "%s-%s.ogg" % (screendump_dir, test.iteration)) logging.debug("Encoding video file %s", video_file) video.start(screendump_dir, video_file) except Exception, detail: logging.info("Video creation failed for %s: %s", screendump_dir, detail) # 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", "no") == "yes": 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", "no") != "yes":
def _take_screendumps(test, params, env): global _screendump_thread_termination_event temp_dir = test.debugdir if params.get("screendump_temp_dir"): temp_dir = utils_misc.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" % utils_misc.generate_random_string(6)) delay = float(params.get("screendump_delay", 5)) quality = int(params.get("screendump_quality", 30)) cache = {} counter = {} while True: for vm in env.get_all_vms(): if vm not in counter.keys(): counter[vm] = 0 if not vm.is_alive(): continue try: vm.screendump(filename=temp_filename, debug=False) except kvm_monitor.MonitorError, e: logging.warn(e) continue except AttributeError, 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 counter[vm] += 1 screendump_filename = os.path.join(screendump_dir, "%04d.jpg" % counter[vm]) hsh = utils.hash_file(temp_filename) if hsh in cache: try: os.link(cache[hsh], screendump_filename) except OSError: pass else: try: try: image = PIL.Image.open(temp_filename) image.save(screendump_filename, format="JPEG", quality=quality) cache[hsh] = screendump_filename except IOError, error_detail: logging.warning( "VM '%s' failed to produce a " "screendump: %s", vm.name, error_detail) # Decrement the counter as we in fact failed to # produce a converted screendump counter[vm] -= 1 except NameError: pass os.unlink(temp_filename)
def _take_screendumps(test, params, env): global _screendump_thread_termination_event temp_dir = test.debugdir if params.get("screendump_temp_dir"): temp_dir = virt_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" % virt_utils.generate_random_string(6)) delay = float(params.get("screendump_delay", 5)) quality = int(params.get("screendump_quality", 30)) cache = {} counter = {} while True: for vm in env.get_all_vms(): if vm not in counter.keys(): counter[vm] = 0 if not vm.is_alive(): continue try: vm.screendump(filename=temp_filename, debug=False) except kvm_monitor.MonitorError, e: logging.warn(e) continue except AttributeError, 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 counter[vm] += 1 screendump_filename = os.path.join(screendump_dir, "%04d.jpg" % counter[vm]) hash = utils.hash_file(temp_filename) if hash in cache: try: os.link(cache[hash], screendump_filename) except OSError: pass else: try: try: image = PIL.Image.open(temp_filename) image.save(screendump_filename, format="JPEG", quality=quality) cache[hash] = screendump_filename except IOError, error_detail: logging.warning("VM '%s' failed to produce a " "screendump: %s", vm.name, error_detail) # Decrement the counter as we in fact failed to # produce a converted screendump counter[vm] -= 1 except NameError: pass os.unlink(temp_filename)
def barrier_2(vm, words, params, debug_dir, data_scrdump_filename, current_step_num): if len(words) < 7: logging.error("Bad barrier_2 command line") return False # Parse barrier command line cmd, dx, dy, x1, y1, md5sum, timeout = words[:7] dx, dy, x1, y1, timeout = map(int, [dx, dy, x1, y1, timeout]) # Define some paths scrdump_filename = os.path.join(debug_dir, "scrdump.ppm") cropped_scrdump_filename = os.path.join(debug_dir, "cropped_scrdump.ppm") expected_scrdump_filename = os.path.join(debug_dir, "scrdump_expected.ppm") expected_cropped_scrdump_filename = os.path.join(debug_dir, "cropped_scrdump_expected.ppm") comparison_filename = os.path.join(debug_dir, "comparison.ppm") history_dir = os.path.join(debug_dir, "barrier_history") # Collect a few parameters timeout_multiplier = float(params.get("timeout_multiplier") or 1) fail_if_stuck_for = float(params.get("fail_if_stuck_for") or 1e308) stuck_detection_history = int(params.get("stuck_detection_history") or 2) keep_screendump_history = params.get("keep_screendump_history") == "yes" keep_all_history = params.get("keep_all_history") == "yes" # Multiply timeout by the timeout multiplier timeout *= timeout_multiplier # Timeout/5 is the time it took stepmaker to complete this step. # Divide that number by 10 to poll 10 times, just in case # current machine is stronger then the "stepmaker machine". # Limit to 1 (min) and 10 (max) seconds between polls. sleep_duration = float(timeout) / 50.0 if sleep_duration < 1.0: sleep_duration = 1.0 if sleep_duration > 10.0: sleep_duration = 10.0 end_time = time.time() + timeout end_time_stuck = time.time() + fail_if_stuck_for start_time = time.time() prev_whole_image_md5sums = [] failure_message = None # Main loop while True: # Check for timeouts if time.time() > end_time: failure_message = "regular timeout" break if time.time() > end_time_stuck: failure_message = "guest is stuck" break # Make sure vm is alive if not vm.is_alive(): failure_message = "VM is dead" break # Request screendump try: vm.monitor.screendump(scrdump_filename) except kvm_monitor.MonitorError, e: logging.warn(e) continue # Read image file (w, h, data) = ppm_utils.image_read_from_ppm_file(scrdump_filename) # Make sure image is valid if not ppm_utils.image_verify_ppm_file(scrdump_filename): logging.warn("Got invalid screendump: dimensions: %dx%d, " "data size: %d", w, h, len(data)) continue # Compute md5sum of whole image whole_image_md5sum = ppm_utils.image_md5sum(w, h, data) # Write screendump to history_dir (as JPG) if requested # and if the screendump differs from the previous one if (keep_screendump_history and whole_image_md5sum not in prev_whole_image_md5sums[:1]): try: os.makedirs(history_dir) except: pass history_scrdump_filename = os.path.join(history_dir, "scrdump-step_%s-%s.jpg" % (current_step_num, time.strftime("%Y%m%d-%H%M%S"))) try: image = PIL.Image.open(scrdump_filename) image.save(history_scrdump_filename, format = 'JPEG', quality = 30) except NameError: pass # Compare md5sum of barrier region with the expected md5sum calced_md5sum = ppm_utils.get_region_md5sum(w, h, data, x1, y1, dx, dy, cropped_scrdump_filename) if calced_md5sum == md5sum: # Success -- remove screendump history unless requested not to if keep_screendump_history and not keep_all_history: shutil.rmtree(history_dir) # Report success return True # Insert image md5sum into queue of last seen images: # If md5sum is already in queue... if whole_image_md5sum in prev_whole_image_md5sums: # Remove md5sum from queue prev_whole_image_md5sums.remove(whole_image_md5sum) else: # Otherwise extend 'stuck' timeout end_time_stuck = time.time() + fail_if_stuck_for # Insert md5sum at beginning of queue prev_whole_image_md5sums.insert(0, whole_image_md5sum) # Limit queue length to stuck_detection_history prev_whole_image_md5sums = \ prev_whole_image_md5sums[:stuck_detection_history] # Sleep for a while time.sleep(sleep_duration)
def barrier_2(vm, words, params, debug_dir, data_scrdump_filename, current_step_num): if len(words) < 7: logging.error("Bad barrier_2 command line") return False cmd, dx, dy, x1, y1, md5sum, timeout = words[:7] dx, dy, x1, y1, timeout = map(int, [dx, dy, x1, y1, timeout]) # Timeout/5 is the time it took stepmaker to complete this step. # Divide that number by 10 to poll 10 times, just in case # current machine is stronger then the "stepmaker machine". # Limit to 1 (min) and 10 (max) seconds between polls. sleep_duration = float(timeout) / 50.0 if sleep_duration < 1.0: sleep_duration = 1.0 if sleep_duration > 10.0: sleep_duration = 10.0 scrdump_filename = os.path.join(debug_dir, "scrdump.ppm") cropped_scrdump_filename = os.path.join(debug_dir, "cropped_scrdump.ppm") expected_scrdump_filename = os.path.join(debug_dir, "scrdump_expected.ppm") expected_cropped_scrdump_filename = os.path.join(debug_dir, "cropped_scrdump_expected.ppm") comparison_filename = os.path.join(debug_dir, "comparison.ppm") fail_if_stuck_for = params.get("fail_if_stuck_for") if fail_if_stuck_for: fail_if_stuck_for = float(fail_if_stuck_for) else: fail_if_stuck_for = 1e308 stuck_detection_history = params.get("stuck_detection_history") if stuck_detection_history: stuck_detection_history = int(stuck_detection_history) else: stuck_detection_history = 2 keep_screendump_history = params.get("keep_screendump_history") == "yes" if keep_screendump_history: keep_all_history = params.get("keep_all_history") == "yes" history_dir = os.path.join(debug_dir, "barrier_history") end_time = time.time() + timeout end_time_stuck = time.time() + fail_if_stuck_for start_time = time.time() prev_whole_image_md5sums = [] failure_message = None # Main loop while True: # Check for timeouts if time.time() > end_time: failure_message = "regular timeout" break if time.time() > end_time_stuck: failure_message = "guest is stuck" break # Make sure vm is alive if not vm.is_alive(): failure_message = "VM is dead" break # Request screendump (status, output) = vm.send_monitor_cmd("screendump %s" % scrdump_filename) if status: logging.error("Could not fetch screendump") continue # Make sure image is valid if not ppm_utils.image_verify_ppm_file(scrdump_filename): failure_message = "got invalid screendump" break # Read image file (w, h, data) = ppm_utils.image_read_from_ppm_file(scrdump_filename) # Compute md5sum of whole image whole_image_md5sum = ppm_utils.image_md5sum(w, h, data) # Write screendump to history_dir (as JPG) if requested # and if the screendump differs from the previous one if (keep_screendump_history and whole_image_md5sum not in prev_whole_image_md5sums[:1]): try: os.makedirs(history_dir) except: pass history_scrdump_filename = os.path.join(history_dir, "scrdump-step_%s-%s.jpg" % (current_step_num, time.strftime("%Y%m%d-%H%M%S"))) kvm_subprocess.run_fg("convert -quality 30 %s %s" % (scrdump_filename, history_scrdump_filename), logging.debug, "(convert) ", timeout=30) # Compare md5sum of barrier region with the expected md5sum calced_md5sum = ppm_utils.get_region_md5sum(w, h, data, x1, y1, dx, dy, cropped_scrdump_filename) if calced_md5sum == md5sum: # Success -- remove screendump history unless requested not to if keep_screendump_history and not keep_all_history: kvm_subprocess.run_fg("rm -rvf %s" % history_dir, logging.debug, "(rm) ", timeout=30) # Report success return True # Insert image md5sum into queue of last seen images: # If md5sum is already in queue... if whole_image_md5sum in prev_whole_image_md5sums: # Remove md5sum from queue prev_whole_image_md5sums.remove(whole_image_md5sum) else: # Otherwise extend 'stuck' timeout end_time_stuck = time.time() + fail_if_stuck_for # Insert md5sum at beginning of queue prev_whole_image_md5sums.insert(0, whole_image_md5sum) # Limit queue length to stuck_detection_history prev_whole_image_md5sums = \ prev_whole_image_md5sums[:stuck_detection_history] # Sleep for a while time.sleep(sleep_duration) # Failure message = ("Barrier failed at step %s after %.2f seconds (%s)" % (current_step_num, time.time() - start_time, failure_message)) # What should we do with this failure? if words[-1] == "optional": logging.info(message) return False else: # Collect information and put it in debug_dir if data_scrdump_filename and os.path.exists(data_scrdump_filename): # Read expected screendump image (ew, eh, edata) = \ ppm_utils.image_read_from_ppm_file(data_scrdump_filename) # Write it in debug_dir ppm_utils.image_write_to_ppm_file(expected_scrdump_filename, ew, eh, edata) # Write the cropped version as well ppm_utils.get_region_md5sum(ew, eh, edata, x1, y1, dx, dy, expected_cropped_scrdump_filename) # Perform comparison (w, h, data) = ppm_utils.image_read_from_ppm_file(scrdump_filename) if w == ew and h == eh: (w, h, data) = ppm_utils.image_comparison(w, h, data, edata) ppm_utils.image_write_to_ppm_file(comparison_filename, w, h, data) # Print error messages and fail the test long_message = message + "\n(see analysis at %s)" % debug_dir logging.error(long_message) raise error.TestFail, message
def barrier_2(vm, words, params, debug_dir, data_scrdump_filename, current_step_num): if len(words) < 7: logging.error("Bad barrier_2 command line") return False # Parse barrier command line cmd, dx, dy, x1, y1, md5sum, timeout = words[:7] dx, dy, x1, y1, timeout = map(int, [dx, dy, x1, y1, timeout]) # Define some paths scrdump_filename = os.path.join(debug_dir, "scrdump.ppm") cropped_scrdump_filename = os.path.join(debug_dir, "cropped_scrdump.ppm") expected_scrdump_filename = os.path.join(debug_dir, "scrdump_expected.ppm") expected_cropped_scrdump_filename = os.path.join( debug_dir, "cropped_scrdump_expected.ppm") comparison_filename = os.path.join(debug_dir, "comparison.ppm") history_dir = os.path.join(debug_dir, "barrier_history") # Collect a few parameters timeout_multiplier = float(params.get("timeout_multiplier") or 1) fail_if_stuck_for = float(params.get("fail_if_stuck_for") or 1e308) stuck_detection_history = int(params.get("stuck_detection_history") or 2) keep_screendump_history = params.get("keep_screendump_history") == "yes" keep_all_history = params.get("keep_all_history") == "yes" # Multiply timeout by the timeout multiplier timeout *= timeout_multiplier # Timeout/5 is the time it took stepmaker to complete this step. # Divide that number by 10 to poll 10 times, just in case # current machine is stronger then the "stepmaker machine". # Limit to 1 (min) and 10 (max) seconds between polls. sleep_duration = float(timeout) / 50.0 if sleep_duration < 1.0: sleep_duration = 1.0 if sleep_duration > 10.0: sleep_duration = 10.0 end_time = time.time() + timeout end_time_stuck = time.time() + fail_if_stuck_for start_time = time.time() prev_whole_image_md5sums = [] failure_message = None # Main loop while True: # Check for timeouts if time.time() > end_time: failure_message = "regular timeout" break if time.time() > end_time_stuck: failure_message = "guest is stuck" break # Make sure vm is alive if not vm.is_alive(): failure_message = "VM is dead" break # Request screendump try: vm.monitor.screendump(scrdump_filename) except kvm_monitor.MonitorError, e: logging.warn(e) continue # Read image file (w, h, data) = ppm_utils.image_read_from_ppm_file(scrdump_filename) # Make sure image is valid if not ppm_utils.image_verify_ppm_file(scrdump_filename): logging.warn( "Got invalid screendump: dimensions: %dx%d, " "data size: %d", w, h, len(data)) continue # Compute md5sum of whole image whole_image_md5sum = ppm_utils.image_md5sum(w, h, data) # Write screendump to history_dir (as JPG) if requested # and if the screendump differs from the previous one if (keep_screendump_history and whole_image_md5sum not in prev_whole_image_md5sums[:1]): try: os.makedirs(history_dir) except: pass history_scrdump_filename = os.path.join( history_dir, "scrdump-step_%s-%s.jpg" % (current_step_num, time.strftime("%Y%m%d-%H%M%S"))) try: image = PIL.Image.open(scrdump_filename) image.save(history_scrdump_filename, format='JPEG', quality=30) except NameError: pass # Compare md5sum of barrier region with the expected md5sum calced_md5sum = ppm_utils.get_region_md5sum(w, h, data, x1, y1, dx, dy, cropped_scrdump_filename) if calced_md5sum == md5sum: # Success -- remove screendump history unless requested not to if keep_screendump_history and not keep_all_history: shutil.rmtree(history_dir) # Report success return True # Insert image md5sum into queue of last seen images: # If md5sum is already in queue... if whole_image_md5sum in prev_whole_image_md5sums: # Remove md5sum from queue prev_whole_image_md5sums.remove(whole_image_md5sum) else: # Otherwise extend 'stuck' timeout end_time_stuck = time.time() + fail_if_stuck_for # Insert md5sum at beginning of queue prev_whole_image_md5sums.insert(0, whole_image_md5sum) # Limit queue length to stuck_detection_history prev_whole_image_md5sums = \ prev_whole_image_md5sums[:stuck_detection_history] # Sleep for a while time.sleep(sleep_duration)
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")
process(test, params, env, postprocess_image, postprocess_vm, vm_first=True) except Exception, details: err += "\nPostprocess: %s" % str(details).replace('\\n', '\n ') logging.error(details) # Terminate the screendump thread global _screendump_thread, _screendump_thread_termination_event if _screendump_thread is not None: _screendump_thread_termination_event.set() _screendump_thread.join(10) _screendump_thread = 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": 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", "no") != "yes":
def _take_screendumps(test, params, env): global _screendump_thread_termination_event temp_dir = test.debugdir if params.get("screendump_temp_dir"): temp_dir = virt_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" % virt_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 env.get_all_vms(): if not vm.is_alive(): continue try: vm.monitor.screendump(filename=temp_filename, debug=False) except kvm_monitor.MonitorError, e: logging.warning(e) continue except AttributeError, e: continue if not os.path.exists(temp_filename): logging.warning("VM '%s' failed to produce a screendump", vm.name) continue if not ppm_utils.image_verify_ppm_file(temp_filename): logging.warning("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)