# Copyright (c) 2012 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """Touch firmware test report in html format.""" import os import urllib import common_util import firmware_log import test_conf as conf from firmware_utils import get_fw_and_date from string import Template from validators import get_base_name_and_segment class TemplateHtml: """An html Template.""" def __init__(self, image_width, image_height, score_colors): self.score_colors = score_colors # Define the template of the doc self.doc = Template('$head $test_version $logs $tail') self.table = Template(' $gestures ' '
') self.gestures = [] # Define a template to show a gesture information including # the gesture name, variation, prompt, image, and test results. self.gesture_template = Template('''

$gesture_name.$variation

$prompt
$filename
$vlogs
''' % (image_width, image_height)) self.criteria_string = ' criteria: %s' self.validator_template = Template('''
$name
$details
$criteria
''') self.detail_template = Template('
$detail
') self._fill_doc() def _html_head(self): """Fill the head of an html document.""" head = '\n'.join(['', '', '']) return head def _html_tail(self): """Fill the tail of an html document.""" tail = '\n'.join(['', '']) return tail def _fill_doc(self): """Fill in fields into the doc.""" self.doc = Template(self.doc.safe_substitute(head=self._html_head(), tail=self._html_tail())) def get_score_color(self, score): """Present the score in different colors.""" for s, c in self.score_colors: if score >= s: return c def _insert_details(self, details): details_content = [] for detail in details: details_content.append(' ' * 2 + detail.strip()) return '
'.join(details_content) def _insert_vlog(self, vlog): """Insert a single vlog.""" base_name, _ = get_base_name_and_segment(vlog.name) criteria_string = self.criteria_string % vlog.criteria vlog_content = self.validator_template.safe_substitute( name=vlog.name, details=self._insert_details(vlog.details), criteria=criteria_string, color='blue', score=vlog.score) return vlog_content def _insert_vlogs(self, vlogs): """Insert multiple vlogs.""" vlogs_content = [] for vlog in vlogs: vlogs_content.append(self._insert_vlog(vlog)) return '
'.join(vlogs_content) def insert_gesture(self, glog, image, image_filename): """Insert glog, image, and vlogs.""" vlogs_content = self._insert_vlogs(glog.vlogs) gesture = self.gesture_template.safe_substitute( gesture_name=glog.name, variation=glog.variation, prompt=glog.prompt, image=image, filename=image_filename, vlogs=vlogs_content) self.gestures.append(gesture) def get_doc(self, test_version): gestures = ''.join(self.gestures) new_table = self.table.safe_substitute(gestures=gestures) new_doc = self.doc.safe_substitute(test_version=test_version, logs=new_table) return new_doc class ReportHtml: """Firmware Report in html format.""" def __init__(self, filename, screen_size, touch_device_window_size, score_colors, test_version): self.html_filename = filename self.screen_size = screen_size self.image_width = self.screen_size[0] * 0.5 touch_width, touch_height = touch_device_window_size self.image_height = self.image_width / touch_width * touch_height self.doc = TemplateHtml(self.image_width, self.image_height, score_colors) self._reset_content() self.test_version = test_version fw_and_date = get_fw_and_date(filename) self.rlog = firmware_log.RoundLog(test_version, *fw_and_date) def __del__(self): self.stop() def stop(self): """Close the file.""" with open(self.html_filename, 'w') as report_file: report_file.write(self.doc.get_doc(self.test_version)) # Make a copy to /tmp so that it could be viewed in Chrome. tmp_copy = os.path.join(conf.docroot, os.path.basename(self.html_filename)) copy_cmd = 'cp %s %s' % (self.html_filename, tmp_copy) common_util.simple_system(copy_cmd) # Dump the logs to a byte stream file log_file_root = os.path.splitext(self.html_filename)[0] log_filename = os.extsep.join([log_file_root, 'log']) self.rlog.dump(log_filename) def _reset_content(self): self.glog = firmware_log.GestureLog() self.encoded_image='' self.image_filename='' def _get_content(self): return [self.glog, self.encoded_image, self.image_filename] def _encode_base64(self, filename): """Encode a file in base 64 format.""" if (filename is None) or (not os.path.isfile(filename)): return None encoded = urllib.quote(open(filename, "rb").read().encode("base64")) return encoded def flush(self): """Flush the current gesture including gesture log, image and validator logs. """ content = self._get_content() # It is ok to flush the gesture log even when there are no mtplot images if self.glog: # Write the content to the html file. self.doc.insert_gesture(*content) # Write the logs to the round log. self.rlog.insert_glog(self.glog) self._reset_content() def insert_image(self, filename): """Insert an image into the document.""" self.encoded_image = self._encode_base64(filename) self.image_filename = filename def insert_result(self, text): """Insert the text into the document.""" self.result += text def insert_gesture_log(self, glog): """Update the gesture log.""" self.glog = glog def insert_validator_logs(self, vlogs): """Update the validator logs.""" self.glog.vlogs = vlogs