Home | History | Annotate | Download | only in rebaseline_server
      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()
    215