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 imagepairset.py
     10 """
     11 
     12 # System-level imports
     13 import unittest
     14 
     15 # Local imports
     16 import column
     17 import imagepair
     18 import imagepairset
     19 
     20 
     21 BASE_URL_1 = 'http://base/url/1'
     22 BASE_URL_2 = 'http://base/url/2'
     23 DIFF_BASE_URL = 'http://diff/base/url'
     24 IMAGEPAIR_1_AS_DICT = {
     25     imagepair.KEY__IMAGEPAIRS__EXTRACOLUMNS: {
     26         'builder': 'MyBuilder',
     27         'test': 'test1',
     28     },
     29     imagepair.KEY__IMAGEPAIRS__IMAGE_A_URL: 'test1/1111.png',
     30     imagepair.KEY__IMAGEPAIRS__IMAGE_B_URL: 'test1/1111.png',
     31     imagepair.KEY__IMAGEPAIRS__IS_DIFFERENT: False,
     32 }
     33 IMAGEPAIR_2_AS_DICT = {
     34     imagepair.KEY__IMAGEPAIRS__DIFFERENCES: {
     35         'maxDiffPerChannel': [1, 2, 3],
     36         'numDifferingPixels': 111,
     37         'percentDifferingPixels': 22.222,
     38     },
     39     imagepair.KEY__IMAGEPAIRS__EXTRACOLUMNS: {
     40         'builder': 'MyBuilder',
     41         'test': 'test2',
     42     },
     43     imagepair.KEY__IMAGEPAIRS__IMAGE_A_URL: 'test2/2222.png',
     44     imagepair.KEY__IMAGEPAIRS__IMAGE_B_URL: 'test2/22223.png',
     45     imagepair.KEY__IMAGEPAIRS__IS_DIFFERENT: True,
     46 }
     47 IMAGEPAIR_3_AS_DICT = {
     48     imagepair.KEY__IMAGEPAIRS__DIFFERENCES: {
     49         'maxDiffPerChannel': [4, 5, 6],
     50         'numDifferingPixels': 111,
     51         'percentDifferingPixels': 44.444,
     52     },
     53     imagepair.KEY__IMAGEPAIRS__EXPECTATIONS: {
     54         'bugs': [1001, 1002],
     55         'ignoreFailure': True,
     56     },
     57     imagepair.KEY__IMAGEPAIRS__EXTRACOLUMNS: {
     58         'builder': 'MyBuilder',
     59         'test': 'test3',
     60     },
     61     imagepair.KEY__IMAGEPAIRS__IMAGE_A_URL: 'test3/3333.png',
     62     imagepair.KEY__IMAGEPAIRS__IMAGE_B_URL: 'test3/33334.png',
     63     imagepair.KEY__IMAGEPAIRS__IS_DIFFERENT: True,
     64 }
     65 SET_A_DESCRIPTION = 'expectations'
     66 SET_B_DESCRIPTION = 'actuals'
     67 
     68 
     69 class ImagePairSetTest(unittest.TestCase):
     70 
     71   def setUp(self):
     72     self.maxDiff = None  # do not truncate diffs when tests fail
     73 
     74   def shortDescription(self):
     75     """Tells unittest framework to not print docstrings for test cases."""
     76     return None
     77 
     78   def test_success(self):
     79     """Assembles some ImagePairs into an ImagePairSet, and validates results.
     80     """
     81     image_pairs = [
     82         MockImagePair(base_url=BASE_URL_1, dict_to_return=IMAGEPAIR_1_AS_DICT),
     83         MockImagePair(base_url=BASE_URL_1, dict_to_return=IMAGEPAIR_2_AS_DICT),
     84         MockImagePair(base_url=BASE_URL_1, dict_to_return=IMAGEPAIR_3_AS_DICT),
     85     ]
     86     expected_imageset_dict = {
     87         'extraColumnHeaders': {
     88             'builder': {
     89                 'headerText': 'builder',
     90                 'isFilterable': True,
     91                 'isSortable': True,
     92                 'valuesAndCounts': [('MyBuilder', 3)],
     93             },
     94             'test': {
     95                 'headerText': 'which GM test',
     96                 'headerUrl': 'http://learn/about/gm/tests',
     97                 'isFilterable': True,
     98                 'isSortable': False,
     99             },
    100         },
    101         'imagePairs': [
    102             IMAGEPAIR_1_AS_DICT,
    103             IMAGEPAIR_2_AS_DICT,
    104             IMAGEPAIR_3_AS_DICT,
    105         ],
    106         'imageSets': {
    107             'imageA': {
    108                 'baseUrl': BASE_URL_1,
    109                 'description': SET_A_DESCRIPTION,
    110             },
    111             'imageB': {
    112                 'baseUrl': BASE_URL_1,
    113                 'description': SET_B_DESCRIPTION,
    114             },
    115             'diffs': {
    116                 'baseUrl': DIFF_BASE_URL + '/diffs',
    117                 'description': 'color difference per channel',
    118             },
    119             'whiteDiffs': {
    120                 'baseUrl': DIFF_BASE_URL + '/whitediffs',
    121                 'description': 'differing pixels in white',
    122             },
    123         },
    124     }
    125 
    126     image_pair_set = imagepairset.ImagePairSet(
    127         descriptions=(SET_A_DESCRIPTION, SET_B_DESCRIPTION),
    128         diff_base_url=DIFF_BASE_URL)
    129     for image_pair in image_pairs:
    130       image_pair_set.add_image_pair(image_pair)
    131     # The 'builder' column header uses the default settings,
    132     # but the 'test' column header has manual adjustments.
    133     image_pair_set.set_column_header_factory(
    134         'test',
    135         column.ColumnHeaderFactory(
    136             header_text='which GM test',
    137             header_url='http://learn/about/gm/tests',
    138             is_filterable=True,
    139             is_sortable=False,
    140             include_values_and_counts=False))
    141     self.assertEqual(image_pair_set.as_dict(), expected_imageset_dict)
    142 
    143   def test_mismatched_base_url(self):
    144     """Confirms that mismatched base_urls will cause an exception."""
    145     image_pair_set = imagepairset.ImagePairSet(
    146         diff_base_url=DIFF_BASE_URL)
    147     image_pair_set.add_image_pair(
    148         MockImagePair(base_url=BASE_URL_1, dict_to_return=IMAGEPAIR_1_AS_DICT))
    149     image_pair_set.add_image_pair(
    150         MockImagePair(base_url=BASE_URL_1, dict_to_return=IMAGEPAIR_2_AS_DICT))
    151     with self.assertRaises(Exception):
    152       image_pair_set.add_image_pair(
    153           MockImagePair(base_url=BASE_URL_2,
    154                         dict_to_return=IMAGEPAIR_3_AS_DICT))
    155 
    156 
    157 class MockImagePair(object):
    158   """Mock ImagePair object, which will return canned results."""
    159   def __init__(self, base_url, dict_to_return):
    160     """
    161     Args:
    162       base_url: base_url attribute for this object
    163       dict_to_return: dictionary to return from as_dict()
    164     """
    165     self.base_url = base_url
    166     self.extra_columns_dict = dict_to_return.get(
    167         imagepair.KEY__IMAGEPAIRS__EXTRACOLUMNS, None)
    168     self._dict_to_return = dict_to_return
    169 
    170   def as_dict(self):
    171     return self._dict_to_return
    172 
    173 
    174 def main():
    175   suite = unittest.TestLoader().loadTestsFromTestCase(ImagePairSetTest)
    176   unittest.TextTestRunner(verbosity=2).run(suite)
    177 
    178 
    179 if __name__ == '__main__':
    180   main()
    181