OLD | NEW |
| (Empty) |
1 #!/usr/bin/python | |
2 | |
3 """ | |
4 Copyright 2014 Google Inc. | |
5 | |
6 Use of this source code is governed by a BSD-style license that can be | |
7 found in the LICENSE file. | |
8 | |
9 Test imagepair.py | |
10 """ | |
11 | |
12 # System-level imports | |
13 import shutil | |
14 import tempfile | |
15 import unittest | |
16 | |
17 # Local imports | |
18 import imagediffdb | |
19 import imagepair | |
20 | |
21 | |
22 IMG_URL_BASE = ('http://chromium-skia-gm.commondatastorage.googleapis.com/' | |
23 'gm/bitmap-64bitMD5/') | |
24 | |
25 | |
26 class ImagePairTest(unittest.TestCase): | |
27 | |
28 def setUp(self): | |
29 self.temp_dir = tempfile.mkdtemp() | |
30 self.maxDiff = None | |
31 | |
32 def tearDown(self): | |
33 shutil.rmtree(self.temp_dir) | |
34 | |
35 def shortDescription(self): | |
36 """Tells unittest framework to not print docstrings for test cases.""" | |
37 return None | |
38 | |
39 def test_endToEnd(self): | |
40 """Tests ImagePair, using a real ImageDiffDB to download real images. | |
41 | |
42 TODO(epoger): Either in addition to or instead of this end-to-end test, | |
43 we should perform some tests using either: | |
44 1. a mock ImageDiffDB, or | |
45 2. a real ImageDiffDB that doesn't hit Google Storage looking for input | |
46 image files (maybe a file:// IMG_URL_BASE) | |
47 """ | |
48 # params for each self-test: | |
49 # | |
50 # inputs: | |
51 # 0. imageA_relative_URL | |
52 # 1. imageB_relative_URL | |
53 # 2. expectations dict | |
54 # 3. extra_columns dict | |
55 # expected output: | |
56 # 4. expected result of ImagePair.as_dict() | |
57 selftests = [ | |
58 [ | |
59 # inputs: | |
60 'arcofzorro/16206093933823793653.png', | |
61 'arcofzorro/16206093933823793653.png', | |
62 None, | |
63 { | |
64 'builder': 'MyBuilder', | |
65 'test': 'MyTest', | |
66 }, | |
67 # expected output: | |
68 { | |
69 'extraColumns': { | |
70 'builder': 'MyBuilder', | |
71 'test': 'MyTest', | |
72 }, | |
73 'imageAUrl': 'arcofzorro/16206093933823793653.png', | |
74 'imageBUrl': 'arcofzorro/16206093933823793653.png', | |
75 'isDifferent': False, | |
76 }, | |
77 ], | |
78 | |
79 [ | |
80 # inputs: | |
81 'arcofzorro/16206093933823793653.png', | |
82 'arcofzorro/13786535001616823825.png', | |
83 None, | |
84 None, | |
85 # expected output: | |
86 { | |
87 'differenceData': { | |
88 'maxDiffPerChannel': [255, 255, 247], | |
89 'numDifferingPixels': 662, | |
90 'percentDifferingPixels': 0.0662, | |
91 'perceptualDifference': 0.06620300000000157, | |
92 'diffUrl': 'arcofzorro_16206093933823793653_png_png-vs-' + | |
93 'arcofzorro_13786535001616823825_png_png.png', | |
94 'whiteDiffUrl': 'arcofzorro_16206093933823793653_png_png' + | |
95 '-vs-arcofzorro_13786535001616823825_png_png.png', | |
96 }, | |
97 'imageAUrl': 'arcofzorro/16206093933823793653.png', | |
98 'imageBUrl': 'arcofzorro/13786535001616823825.png', | |
99 'isDifferent': True, | |
100 }, | |
101 ], | |
102 | |
103 [ | |
104 # inputs: | |
105 'gradients_degenerate_2pt/10552995703607727960.png', | |
106 'gradients_degenerate_2pt/11198253335583713230.png', | |
107 { | |
108 'ignoreFailure': True, | |
109 'bugs': [1001, 1002], | |
110 }, | |
111 { | |
112 'builder': 'MyBuilder', | |
113 'test': 'MyTest', | |
114 }, | |
115 # expected output: | |
116 { | |
117 'differenceData': { | |
118 'maxDiffPerChannel': [255, 0, 255], | |
119 'numDifferingPixels': 102400, | |
120 'percentDifferingPixels': 100.00, | |
121 'perceptualDifference': 100.00, | |
122 'diffUrl': 'gradients_degenerate_2pt_10552995703607727960' + | |
123 '_png_png-vs-gradients_degenerate_2pt_' + | |
124 '11198253335583713230_png_png.png', | |
125 'whiteDiffUrl': 'gradients_degenerate_2pt_' + | |
126 '10552995703607727960_png_png-vs-' + | |
127 'gradients_degenerate_2pt_11198253335583713230' + | |
128 '_png_png.png' | |
129 }, | |
130 'expectations': { | |
131 'bugs': [1001, 1002], | |
132 'ignoreFailure': True, | |
133 }, | |
134 'extraColumns': { | |
135 'builder': 'MyBuilder', | |
136 'test': 'MyTest', | |
137 }, | |
138 'imageAUrl': | |
139 'gradients_degenerate_2pt/10552995703607727960.png', | |
140 'imageBUrl': | |
141 'gradients_degenerate_2pt/11198253335583713230.png', | |
142 'isDifferent': True, | |
143 }, | |
144 ], | |
145 | |
146 # Test fix for http://skbug.com/2368 -- how do we handle an ImagePair | |
147 # missing one of its images? | |
148 [ | |
149 # inputs: | |
150 'arcofzorro/16206093933823793653.png', | |
151 'nonexistentDir/111111.png', | |
152 { | |
153 'ignoreFailure': True, | |
154 'bugs': [1001, 1002], | |
155 }, | |
156 { | |
157 'builder': 'MyBuilder', | |
158 'test': 'MyTest', | |
159 }, | |
160 # expected output: | |
161 { | |
162 'expectations': { | |
163 'bugs': [1001, 1002], | |
164 'ignoreFailure': True, | |
165 }, | |
166 'extraColumns': { | |
167 'builder': 'MyBuilder', | |
168 'test': 'MyTest', | |
169 }, | |
170 'imageAUrl': 'arcofzorro/16206093933823793653.png', | |
171 'imageBUrl': 'nonexistentDir/111111.png', | |
172 'isDifferent': True, | |
173 }, | |
174 ], | |
175 | |
176 # One of the two images is missing, but download_all_images=True so we | |
177 # should download it anyway. | |
178 [ | |
179 # inputs: | |
180 None, | |
181 'arcofzorro/13786535001616823825.png', | |
182 None, | |
183 None, | |
184 # expected output: | |
185 { | |
186 'imageAUrl': None, | |
187 'imageBUrl': 'arcofzorro/13786535001616823825.png', | |
188 'isDifferent': True, | |
189 }, | |
190 ], | |
191 | |
192 ] | |
193 | |
194 db = imagediffdb.ImageDiffDB(self.temp_dir) | |
195 for selftest in selftests: | |
196 image_pair = imagepair.ImagePair( | |
197 image_diff_db=db, | |
198 imageA_base_url=IMG_URL_BASE, | |
199 imageB_base_url=IMG_URL_BASE, | |
200 imageA_relative_url=selftest[0], | |
201 imageB_relative_url=selftest[1], | |
202 expectations=selftest[2], | |
203 extra_columns=selftest[3], | |
204 download_all_images=True) | |
205 self.assertEqual(image_pair.as_dict(), selftest[4]) | |
206 | |
207 | |
208 def main(): | |
209 suite = unittest.TestLoader().loadTestsFromTestCase(ImagePairTest) | |
210 unittest.TextTestRunner(verbosity=2).run(suite) | |
211 | |
212 | |
213 if __name__ == '__main__': | |
214 main() | |
OLD | NEW |