13eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org#!/usr/bin/python
23eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org
33eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org"""
43eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.orgCopyright 2014 Google Inc.
53eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org
63eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.orgUse of this source code is governed by a BSD-style license that can be
73eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.orgfound in the LICENSE file.
83eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org
93eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.orgCompare results of two render_pictures runs.
103eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org"""
113eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org
123eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org# System-level imports
133eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.orgimport logging
143eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.orgimport os
153eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.orgimport re
163eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.orgimport time
173eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org
183eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org# Imports from within Skia
19b144271179aaf82cb1151e9dfd8e866747402594epogerimport fix_pythonpath  # must do this first
20b144271179aaf82cb1151e9dfd8e866747402594epogerfrom pyutils import url_utils
213eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.orgimport gm_json
223eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.orgimport imagediffdb
233eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.orgimport imagepair
243eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.orgimport imagepairset
253eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.orgimport results
263eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org
273eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org# URL under which all render_pictures images can be found in Google Storage.
283eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org# TODO(epoger): Move this default value into
293eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org# https://skia.googlesource.com/buildbot/+/master/site_config/global_variables.json
303eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.orgDEFAULT_IMAGE_BASE_URL = 'http://chromium-skia-gm.commondatastorage.googleapis.com/render_pictures/images'
313eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org
323eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org
333eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.orgclass RenderedPicturesComparisons(results.BaseComparisons):
343eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org  """Loads results from two different render_pictures runs into an ImagePairSet.
353eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org  """
363eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org
373eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org  def __init__(self, subdirs, actuals_root,
383eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org               generated_images_root=results.DEFAULT_GENERATED_IMAGES_ROOT,
393eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org               image_base_url=DEFAULT_IMAGE_BASE_URL,
403eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org               diff_base_url=None):
413eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org    """
423eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org    Args:
433eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org      actuals_root: root directory containing all render_pictures-generated
443eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org          JSON files
453eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org      subdirs: (string, string) tuple; pair of subdirectories within
463eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org          actuals_root to compare
473eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org      generated_images_root: directory within which to create all pixel diffs;
483eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org          if this directory does not yet exist, it will be created
493eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org      image_base_url: URL under which all render_pictures result images can
503eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org          be found; this will be used to read images for comparison within
513eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org          this code, and included in the ImagePairSet so its consumers know
523eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org          where to download the images from
533eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org      diff_base_url: base URL within which the client should look for diff
543eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org          images; if not specified, defaults to a "file:///" URL representation
553eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org          of generated_images_root
563eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org    """
573eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org    time_start = int(time.time())
583eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org    self._image_diff_db = imagediffdb.ImageDiffDB(generated_images_root)
593eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org    self._image_base_url = image_base_url
603eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org    self._diff_base_url = (
613eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org        diff_base_url or
62b144271179aaf82cb1151e9dfd8e866747402594epoger        url_utils.create_filepath_url(generated_images_root))
633eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org    self._load_result_pairs(actuals_root, subdirs)
643eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org    self._timestamp = int(time.time())
653eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org    logging.info('Results complete; took %d seconds.' %
663eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org                 (self._timestamp - time_start))
673eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org
683eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org  def _load_result_pairs(self, actuals_root, subdirs):
693eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org    """Loads all JSON files found within two subdirs in actuals_root,
703eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org    compares across those two subdirs, and stores the summary in self._results.
713eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org
723eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org    Args:
733eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org      actuals_root: root directory containing all render_pictures-generated
743eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org          JSON files
753eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org      subdirs: (string, string) tuple; pair of subdirectories within
763eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org          actuals_root to compare
773eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org    """
783eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org    logging.info(
793eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org        'Reading actual-results JSON files from %s subdirs within %s...' % (
803eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org            subdirs, actuals_root))
813eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org    subdirA, subdirB = subdirs
827418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    subdirA_dicts = self._read_dicts_from_root(
833eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org        os.path.join(actuals_root, subdirA))
847418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    subdirB_dicts = self._read_dicts_from_root(
853eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org        os.path.join(actuals_root, subdirB))
863eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org    logging.info('Comparing subdirs %s and %s...' % (subdirA, subdirB))
873eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org
883eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org    all_image_pairs = imagepairset.ImagePairSet(
893eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org        descriptions=subdirs,
903eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org        diff_base_url=self._diff_base_url)
913eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org    failing_image_pairs = imagepairset.ImagePairSet(
923eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org        descriptions=subdirs,
933eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org        diff_base_url=self._diff_base_url)
943eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org
953eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org    all_image_pairs.ensure_extra_column_values_in_summary(
9668a3815401f461976f76891d0477cb1440fa0abacommit-bot@chromium.org        column_id=results.KEY__EXTRACOLUMNS__RESULT_TYPE, values=[
973eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org            results.KEY__RESULT_TYPE__FAILED,
983eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org            results.KEY__RESULT_TYPE__NOCOMPARISON,
993eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org            results.KEY__RESULT_TYPE__SUCCEEDED,
1003eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org        ])
1013eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org    failing_image_pairs.ensure_extra_column_values_in_summary(
10268a3815401f461976f76891d0477cb1440fa0abacommit-bot@chromium.org        column_id=results.KEY__EXTRACOLUMNS__RESULT_TYPE, values=[
1033eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org            results.KEY__RESULT_TYPE__FAILED,
1043eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org            results.KEY__RESULT_TYPE__NOCOMPARISON,
1053eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org        ])
1063eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org
1077418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    common_dict_paths = sorted(set(subdirA_dicts.keys() + subdirB_dicts.keys()))
1087418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    num_common_dict_paths = len(common_dict_paths)
1097418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    dict_num = 0
1107418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    for dict_path in common_dict_paths:
1117418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      dict_num += 1
1127418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      logging.info('Generating pixel diffs for dict #%d of %d, "%s"...' %
1137418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org                   (dict_num, num_common_dict_paths, dict_path))
1147418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      dictA = subdirA_dicts[dict_path]
1157418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      dictB = subdirB_dicts[dict_path]
1167418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      self._validate_dict_version(dictA)
1177418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      self._validate_dict_version(dictB)
1187418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      dictA_results = dictA[gm_json.JSONKEY_ACTUALRESULTS]
1197418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      dictB_results = dictB[gm_json.JSONKEY_ACTUALRESULTS]
1207418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      skp_names = sorted(set(dictA_results.keys() + dictB_results.keys()))
1217418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      for skp_name in skp_names:
1227418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org        imagepairs_for_this_skp = []
1237418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org
1247418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org        whole_image_A = RenderedPicturesComparisons.get_multilevel(
1257418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org            dictA_results, skp_name, gm_json.JSONKEY_SOURCE_WHOLEIMAGE)
1267418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org        whole_image_B = RenderedPicturesComparisons.get_multilevel(
1277418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org            dictB_results, skp_name, gm_json.JSONKEY_SOURCE_WHOLEIMAGE)
1287418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org        imagepairs_for_this_skp.append(self._create_image_pair(
1297418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org            test=skp_name, config=gm_json.JSONKEY_SOURCE_WHOLEIMAGE,
1307418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org            image_dict_A=whole_image_A, image_dict_B=whole_image_B))
1317418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org
1327418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org        tiled_images_A = RenderedPicturesComparisons.get_multilevel(
1337418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org            dictA_results, skp_name, gm_json.JSONKEY_SOURCE_TILEDIMAGES)
1347418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org        tiled_images_B = RenderedPicturesComparisons.get_multilevel(
1357418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org            dictB_results, skp_name, gm_json.JSONKEY_SOURCE_TILEDIMAGES)
1367418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org        # TODO(epoger): Report an error if we find tiles for A but not B?
1377418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org        if tiled_images_A and tiled_images_B:
1387418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org          # TODO(epoger): Report an error if we find a different number of tiles
1397418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org          # for A and B?
1407418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org          num_tiles = len(tiled_images_A)
1417418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org          for tile_num in range(num_tiles):
1427418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org            imagepairs_for_this_skp.append(self._create_image_pair(
1437418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org                test=skp_name,
1447418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org                config='%s-%d' % (gm_json.JSONKEY_SOURCE_TILEDIMAGES, tile_num),
1457418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org                image_dict_A=tiled_images_A[tile_num],
1467418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org                image_dict_B=tiled_images_B[tile_num]))
1477418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org
1487418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org        for imagepair in imagepairs_for_this_skp:
1497418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org          if imagepair:
1507418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org            all_image_pairs.add_image_pair(imagepair)
1517418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org            result_type = imagepair.extra_columns_dict\
15268a3815401f461976f76891d0477cb1440fa0abacommit-bot@chromium.org                [results.KEY__EXTRACOLUMNS__RESULT_TYPE]
1537418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org            if result_type != results.KEY__RESULT_TYPE__SUCCEEDED:
1547418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org              failing_image_pairs.add_image_pair(imagepair)
1553eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org
1563eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org    self._results = {
1573eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org      results.KEY__HEADER__RESULTS_ALL: all_image_pairs.as_dict(),
1583eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org      results.KEY__HEADER__RESULTS_FAILURES: failing_image_pairs.as_dict(),
1593eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org    }
1603eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org
1617418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org  def _validate_dict_version(self, result_dict):
1627418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    """Raises Exception if the dict is not the type/version we know how to read.
1637418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org
1647418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    Args:
1657418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      result_dict: dictionary holding output of render_pictures
1667418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    """
1677418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    expected_header_type = 'ChecksummedImages'
1687418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    expected_header_revision = 1
1697418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org
1707418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    header = result_dict[gm_json.JSONKEY_HEADER]
1717418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    header_type = header[gm_json.JSONKEY_HEADER_TYPE]
1727418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    if header_type != expected_header_type:
1737418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      raise Exception('expected header_type "%s", but got "%s"' % (
1747418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org          expected_header_type, header_type))
1757418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    header_revision = header[gm_json.JSONKEY_HEADER_REVISION]
1767418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    if header_revision != expected_header_revision:
1777418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      raise Exception('expected header_revision %d, but got %d' % (
1787418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org          expected_header_revision, header_revision))
1797418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org
1807418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org  def _create_image_pair(self, test, config, image_dict_A, image_dict_B):
1817418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    """Creates an ImagePair object for this pair of images.
1827418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org
1837418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    Args:
1847418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      test: string; name of the test
1857418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      config: string; name of the config
1867418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      image_dict_A: dict with JSONKEY_IMAGE_* keys, or None if no image
1877418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      image_dict_B: dict with JSONKEY_IMAGE_* keys, or None if no image
1887418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org
1897418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    Returns:
1907418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      An ImagePair object, or None if both image_dict_A and image_dict_B are
1917418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      None.
1927418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    """
1937418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    if (not image_dict_A) and (not image_dict_B):
1947418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      return None
1957418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org
1967418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    def _checksum_and_relative_url(dic):
1977418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      if dic:
1987418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org        return ((dic[gm_json.JSONKEY_IMAGE_CHECKSUMALGORITHM],
1997418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org                 dic[gm_json.JSONKEY_IMAGE_CHECKSUMVALUE]),
2007418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org                dic[gm_json.JSONKEY_IMAGE_FILEPATH])
2017418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      else:
2027418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org        return None, None
2037418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org
2047418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    imageA_checksum, imageA_relative_url = _checksum_and_relative_url(
2057418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org        image_dict_A)
2067418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    imageB_checksum, imageB_relative_url = _checksum_and_relative_url(
2077418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org        image_dict_B)
2087418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org
2097418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    if not imageA_checksum:
2107418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      result_type = results.KEY__RESULT_TYPE__NOCOMPARISON
2117418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    elif not imageB_checksum:
2127418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      result_type = results.KEY__RESULT_TYPE__NOCOMPARISON
2137418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    elif imageA_checksum == imageB_checksum:
2147418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      result_type = results.KEY__RESULT_TYPE__SUCCEEDED
2157418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    else:
2167418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      result_type = results.KEY__RESULT_TYPE__FAILED
2177418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org
2187418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    extra_columns_dict = {
21968a3815401f461976f76891d0477cb1440fa0abacommit-bot@chromium.org        results.KEY__EXTRACOLUMNS__CONFIG: config,
22068a3815401f461976f76891d0477cb1440fa0abacommit-bot@chromium.org        results.KEY__EXTRACOLUMNS__RESULT_TYPE: result_type,
22168a3815401f461976f76891d0477cb1440fa0abacommit-bot@chromium.org        results.KEY__EXTRACOLUMNS__TEST: test,
2227418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org        # TODO(epoger): Right now, the client UI crashes if it receives
2237418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org        # results that do not include this column.
2247418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org        # Until we fix that, keep the client happy.
22568a3815401f461976f76891d0477cb1440fa0abacommit-bot@chromium.org        results.KEY__EXTRACOLUMNS__BUILDER: 'TODO',
2267418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    }
2277418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org
2287418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    try:
2297418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      return imagepair.ImagePair(
2307418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org          image_diff_db=self._image_diff_db,
2317418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org          base_url=self._image_base_url,
2327418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org          imageA_relative_url=imageA_relative_url,
2337418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org          imageB_relative_url=imageB_relative_url,
2347418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org          extra_columns=extra_columns_dict)
2357418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org    except (KeyError, TypeError):
2367418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      logging.exception(
2377418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org          'got exception while creating ImagePair for'
2387418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org          ' test="%s", config="%s", urlPair=("%s","%s")' % (
2397418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org              test, config, imageA_relative_url, imageB_relative_url))
2407418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org      return None
2417418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org
2423eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org
2433eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org# TODO(epoger): Add main() so this can be called by vm_run_skia_try.sh
244