Home | History | Annotate | Download | only in image_comparison
      1 # Copyright 2015 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import base64
      6 import datetime
      7 import glob
      8 import os
      9 import shutil
     10 
     11 from autotest_lib.client.bin import utils
     12 from autotest_lib.client.cros import constants
     13 from string import Template
     14 
     15 class ImageDiffPublisher(object):
     16     """
     17     Class that takes care of creating the HTML file output when a pdiff
     18     comparison fails. It moves each of the three images to a folder in the
     19     results directory. It then writes a html file that references these images.
     20 
     21     """
     22 
     23     VIEWER_FILES = '/usr/local/autotest/cros/image_comparison/diffviewer/*'
     24 
     25 
     26     def __init__(self, results_folder):
     27         """
     28         @param results_folder: path, where to publish to
     29         """
     30         self.results_folder = results_folder
     31         # Copy files needed to the results dir
     32         for diff_viewer_file in glob.glob(self.VIEWER_FILES):
     33             shutil.copy(diff_viewer_file, self.results_folder)
     34 
     35 
     36     def publish(self, golden_image_path, test_image_path, diff_image_path,
     37                 tags):
     38         """
     39         Move viewer files to the results folder and base64 encode the images.
     40         Write tags to HTML file.
     41 
     42         @param golden_image_path: path, complete path to a golden image.
     43         @param test_image_path: path, complete path to a test image.
     44         @param diff_image_path: path, complete path to a diff image.
     45         @param tags: list, run information.
     46         """
     47 
     48         # Encode the images to base64
     49         base64_images = {}
     50         with open(golden_image_path, "rb") as image_file:
     51             base64_images["golden"] = base64.b64encode(image_file.read())
     52         with open(test_image_path, "rb") as image_file:
     53             base64_images["test"] = base64.b64encode(image_file.read())
     54         with open(diff_image_path, "rb") as image_file:
     55             base64_images["diff"] = base64.b64encode(image_file.read())
     56 
     57         # Append all of the things we push to the html template
     58         tags.update(base64_images)
     59 
     60         html_file_fullpath = os.path.join(self.results_folder, 'index.html')
     61         self._write_tags_to_html(tags, html_file_fullpath)
     62 
     63 
     64     def publish_paths(self, image_paths, testname):
     65         """
     66         Creates a results page for an array of images.
     67 
     68         Move viewer files to the results folder and base64 encode the images.
     69         Write tags to HTML file.
     70 
     71         @param image_paths: an array of paths
     72         @param testname: name of current test.
     73         """
     74 
     75         img_tags = []
     76         for img in image_paths:
     77             with open(img, "rb") as image_file:
     78                 b64img = base64.b64encode(image_file.read())
     79                 b64imgsrc = "data:image/png;base64, " + b64img
     80                 img_tags.append(b64imgsrc)
     81 
     82         tags = self._generate_tags(testname)
     83         tags['images'] = img_tags
     84         html_file_fullpath = os.path.join(self.results_folder, 'slideshow.html')
     85         self._write_tags_to_html(tags, html_file_fullpath)
     86 
     87 
     88     def _write_tags_to_html(self, tags, html_filename):
     89         """
     90         Writes tags to the HTML file
     91 
     92         @param tags the tags to write into the html template
     93         @param html_filename the full path to the html template
     94         """
     95 
     96         with open(html_filename, 'r+') as f:
     97             html = Template(f.read())
     98             formatted_html = html.substitute(tags)
     99             f.seek(0)
    100             f.write(formatted_html)
    101 
    102 
    103     def _generate_tags(self, testname):
    104         """
    105         Generate tags for the current test run
    106 
    107         @param testname the name of the current test
    108         @return an array of tags
    109         """
    110         # get chrome version
    111         version_string = utils.system_output(
    112             constants.CHROME_VERSION_COMMAND, ignore_status=True)
    113         version_string = utils.parse_chrome_version(version_string)[0]
    114 
    115         return {
    116             'testname': testname,
    117             'chromeos_version': utils.get_chromeos_release_version(),
    118             'chrome_version': version_string,
    119             'board': utils.get_board(),
    120             'date': datetime.date.today().strftime("%m/%d/%y"),
    121         }
    122