1#!/usr/bin/python 2 3""" 4Copyright 2014 Google Inc. 5 6Use of this source code is governed by a BSD-style license that can be 7found in the LICENSE file. 8 9Test imagepair.py 10""" 11 12# System-level imports 13import shutil 14import tempfile 15import unittest 16 17# Local imports 18import imagediffdb 19import imagepair 20 21 22IMG_URL_BASE = ('http://chromium-skia-gm.commondatastorage.googleapis.com/' 23 'gm/bitmap-64bitMD5/') 24 25 26class 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 208def main(): 209 suite = unittest.TestLoader().loadTestsFromTestCase(ImagePairTest) 210 unittest.TextTestRunner(verbosity=2).run(suite) 211 212 213if __name__ == '__main__': 214 main() 215