| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 | 2 |
| 3 """ | 3 """ |
| 4 Copyright 2014 Google Inc. | 4 Copyright 2014 Google Inc. |
| 5 | 5 |
| 6 Use of this source code is governed by a BSD-style license that can be | 6 Use of this source code is governed by a BSD-style license that can be |
| 7 found in the LICENSE file. | 7 found in the LICENSE file. |
| 8 | 8 |
| 9 ImagePair class (see class docstring for details) | 9 ImagePair class (see class docstring for details) |
| 10 """ | 10 """ |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 # image diff details yet. | 25 # image diff details yet. |
| 26 _DIFF_RECORD_STILL_LOADING = 'still_loading' | 26 _DIFF_RECORD_STILL_LOADING = 'still_loading' |
| 27 | 27 |
| 28 | 28 |
| 29 class ImagePair(object): | 29 class ImagePair(object): |
| 30 """Describes a pair of images, pixel difference info, and optional metadata. | 30 """Describes a pair of images, pixel difference info, and optional metadata. |
| 31 """ | 31 """ |
| 32 | 32 |
| 33 def __init__(self, image_diff_db, | 33 def __init__(self, image_diff_db, |
| 34 base_url, imageA_relative_url, imageB_relative_url, | 34 base_url, imageA_relative_url, imageB_relative_url, |
| 35 expectations=None, extra_columns=None): | 35 expectations=None, extra_columns=None, |
| 36 download_all_images=False): |
| 36 """ | 37 """ |
| 37 Args: | 38 Args: |
| 38 image_diff_db: ImageDiffDB instance we use to generate/store image diffs | 39 image_diff_db: ImageDiffDB instance we use to generate/store image diffs |
| 39 base_url: base of all image URLs | 40 base_url: base of all image URLs |
| 40 imageA_relative_url: string; URL pointing at an image, relative to | 41 imageA_relative_url: string; URL pointing at an image, relative to |
| 41 base_url; or None, if this image is missing | 42 base_url; or None, if this image is missing |
| 42 imageB_relative_url: string; URL pointing at an image, relative to | 43 imageB_relative_url: string; URL pointing at an image, relative to |
| 43 base_url; or None, if this image is missing | 44 base_url; or None, if this image is missing |
| 44 expectations: optional dictionary containing expectations-specific | 45 expectations: optional dictionary containing expectations-specific |
| 45 metadata (ignore-failure, bug numbers, etc.) | 46 metadata (ignore-failure, bug numbers, etc.) |
| 46 extra_columns: optional dictionary containing more metadata (test name, | 47 extra_columns: optional dictionary containing more metadata (test name, |
| 47 builder name, etc.) | 48 builder name, etc.) |
| 49 download_all_images: if True, download any images associated with this |
| 50 image pair, even if we don't need them to generate diffs |
| 51 (imageA == imageB, or one of them is missing) |
| 48 """ | 52 """ |
| 49 self._image_diff_db = image_diff_db | 53 self._image_diff_db = image_diff_db |
| 50 self.base_url = base_url | 54 self.base_url = base_url |
| 51 self.imageA_relative_url = imageA_relative_url | 55 self.imageA_relative_url = imageA_relative_url |
| 52 self.imageB_relative_url = imageB_relative_url | 56 self.imageB_relative_url = imageB_relative_url |
| 53 self.expectations_dict = expectations | 57 self.expectations_dict = expectations |
| 54 self.extra_columns_dict = extra_columns | 58 self.extra_columns_dict = extra_columns |
| 55 if not imageA_relative_url or not imageB_relative_url: | 59 if not imageA_relative_url or not imageB_relative_url: |
| 56 self._is_different = True | 60 self._is_different = True |
| 57 self._diff_record = None | 61 self._diff_record = None |
| 58 elif imageA_relative_url == imageB_relative_url: | 62 elif imageA_relative_url == imageB_relative_url: |
| 59 self._is_different = False | 63 self._is_different = False |
| 60 self._diff_record = None | 64 self._diff_record = None |
| 61 else: | 65 else: |
| 62 # Tell image_diff_db to add an entry for this diff asynchronously. | 66 # Tell image_diff_db to add an entry for this diff asynchronously. |
| 63 # Later on, we will call image_diff_db.get_diff_record() to find it. | 67 # Later on, we will call image_diff_db.get_diff_record() to find it. |
| 64 self._is_different = True | 68 self._is_different = True |
| 65 self._diff_record = _DIFF_RECORD_STILL_LOADING | 69 self._diff_record = _DIFF_RECORD_STILL_LOADING |
| 70 |
| 71 if self._diff_record != None or download_all_images: |
| 66 image_diff_db.add_image_pair( | 72 image_diff_db.add_image_pair( |
| 67 expected_image_locator=imageA_relative_url, | 73 expected_image_locator=imageA_relative_url, |
| 68 expected_image_url=posixpath.join(base_url, imageA_relative_url), | 74 expected_image_url=self.posixpath_join(base_url, imageA_relative_url), |
| 69 actual_image_locator=imageB_relative_url, | 75 actual_image_locator=imageB_relative_url, |
| 70 actual_image_url=posixpath.join(base_url, imageB_relative_url)) | 76 actual_image_url=self.posixpath_join(base_url, imageB_relative_url)) |
| 71 | 77 |
| 72 def as_dict(self): | 78 def as_dict(self): |
| 73 """Returns a dictionary describing this ImagePair. | 79 """Returns a dictionary describing this ImagePair. |
| 74 | 80 |
| 75 Uses the KEY__IMAGEPAIRS__* constants as keys. | 81 Uses the KEY__IMAGEPAIRS__* constants as keys. |
| 76 """ | 82 """ |
| 77 asdict = { | 83 asdict = { |
| 78 KEY__IMAGEPAIRS__IMAGE_A_URL: self.imageA_relative_url, | 84 KEY__IMAGEPAIRS__IMAGE_A_URL: self.imageA_relative_url, |
| 79 KEY__IMAGEPAIRS__IMAGE_B_URL: self.imageB_relative_url, | 85 KEY__IMAGEPAIRS__IMAGE_B_URL: self.imageB_relative_url, |
| 80 } | 86 } |
| 81 asdict[KEY__IMAGEPAIRS__IS_DIFFERENT] = self._is_different | 87 asdict[KEY__IMAGEPAIRS__IS_DIFFERENT] = self._is_different |
| 82 if self.expectations_dict: | 88 if self.expectations_dict: |
| 83 asdict[KEY__IMAGEPAIRS__EXPECTATIONS] = self.expectations_dict | 89 asdict[KEY__IMAGEPAIRS__EXPECTATIONS] = self.expectations_dict |
| 84 if self.extra_columns_dict: | 90 if self.extra_columns_dict: |
| 85 asdict[KEY__IMAGEPAIRS__EXTRACOLUMNS] = self.extra_columns_dict | 91 asdict[KEY__IMAGEPAIRS__EXTRACOLUMNS] = self.extra_columns_dict |
| 86 if self._diff_record is _DIFF_RECORD_STILL_LOADING: | 92 if self._diff_record is _DIFF_RECORD_STILL_LOADING: |
| 87 # We have waited as long as we can to ask ImageDiffDB for details of | 93 # We have waited as long as we can to ask ImageDiffDB for details of |
| 88 # this image diff. Now we must block until ImageDiffDB can provide | 94 # this image diff. Now we must block until ImageDiffDB can provide |
| 89 # those details. | 95 # those details. |
| 90 # | 96 # |
| 91 # TODO(epoger): Is it wasteful for every imagepair to have its own | 97 # TODO(epoger): Is it wasteful for every imagepair to have its own |
| 92 # reference to image_diff_db? If so, we could pass an image_diff_db | 98 # reference to image_diff_db? If so, we could pass an image_diff_db |
| 93 # reference into this method call instead... | 99 # reference into this method call instead... |
| 94 self._diff_record = self._image_diff_db.get_diff_record( | 100 self._diff_record = self._image_diff_db.get_diff_record( |
| 95 expected_image_locator=self.imageA_relative_url, | 101 expected_image_locator=self.imageA_relative_url, |
| 96 actual_image_locator=self.imageB_relative_url) | 102 actual_image_locator=self.imageB_relative_url) |
| 97 if self._diff_record != None: | 103 if self._diff_record != None: |
| 98 asdict[KEY__IMAGEPAIRS__DIFFERENCES] = self._diff_record.as_dict() | 104 asdict[KEY__IMAGEPAIRS__DIFFERENCES] = self._diff_record.as_dict() |
| 99 return asdict | 105 return asdict |
| 106 |
| 107 @staticmethod |
| 108 def posixpath_join(*args): |
| 109 """Wrapper around posixpath.join(). |
| 110 |
| 111 Returns posixpath.join(*args), or None if any arg is None. |
| 112 """ |
| 113 for arg in args: |
| 114 if arg == None: |
| 115 return None |
| 116 return posixpath.join(*args) |
| OLD | NEW |