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 |