Home | History | Annotate | Download | only in checkout
      1 # Copyright (C) 2011 Google Inc. All rights reserved.
      2 #
      3 # Redistribution and use in source and binary forms, with or without
      4 # modification, are permitted provided that the following conditions are
      5 # met:
      6 #
      7 #    * Redistributions of source code must retain the above copyright
      8 # notice, this list of conditions and the following disclaimer.
      9 #    * Redistributions in binary form must reproduce the above
     10 # copyright notice, this list of conditions and the following disclaimer
     11 # in the documentation and/or other materials provided with the
     12 # distribution.
     13 #    * Neither the name of Google Inc. nor the names of its
     14 # contributors may be used to endorse or promote products derived from
     15 # this software without specific prior written permission.
     16 #
     17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28 
     29 import unittest
     30 
     31 from webkitpy.common.checkout.baselineoptimizer import BaselineOptimizer
     32 from webkitpy.common.checkout.scm.scm_mock import MockSCM
     33 from webkitpy.common.host_mock import MockHost
     34 from webkitpy.common.webkit_finder import WebKitFinder
     35 
     36 
     37 class ExcludingMockSCM(MockSCM):
     38     def __init__(self, exclusion_list, filesystem=None, executive=None):
     39         MockSCM.__init__(self, filesystem, executive)
     40         self._exclusion_list = exclusion_list
     41 
     42     def exists(self, path):
     43         if path in self._exclusion_list:
     44             return False
     45         return MockSCM.exists(self, path)
     46 
     47     def delete(self, path):
     48         return self.delete_list([path])
     49 
     50     def delete_list(self, paths):
     51         for path in paths:
     52             if path in self._exclusion_list:
     53                 raise Exception("File is not SCM managed: " + path)
     54         return MockSCM.delete_list(self, paths)
     55 
     56     def move(self, origin, destination):
     57         if origin in self._exclusion_list:
     58             raise Exception("File is not SCM managed: " + origin)
     59         return MockSCM.move(self, origin, destination)
     60 
     61 
     62 class BaselineOptimizerTest(unittest.TestCase):
     63     def test_move_baselines(self):
     64         host = MockHost(scm=ExcludingMockSCM(['/mock-checkout/third_party/WebKit/LayoutTests/platform/mac/another/test-expected.txt']))
     65         host.filesystem.write_text_file('/mock-checkout/third_party/WebKit/LayoutTests/VirtualTestSuites', '[]')
     66         host.filesystem.write_binary_file('/mock-checkout/third_party/WebKit/LayoutTests/platform/win/another/test-expected.txt', 'result A')
     67         host.filesystem.write_binary_file('/mock-checkout/third_party/WebKit/LayoutTests/platform/mac/another/test-expected.txt', 'result A')
     68         host.filesystem.write_binary_file('/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt', 'result B')
     69         baseline_optimizer = BaselineOptimizer(host, host.port_factory.get(), host.port_factory.all_port_names(), skip_scm_commands=False)
     70         baseline_optimizer._move_baselines('another/test-expected.txt', {
     71             '/mock-checkout/third_party/WebKit/LayoutTests/platform/win': 'aaa',
     72             '/mock-checkout/third_party/WebKit/LayoutTests/platform/mac': 'aaa',
     73             '/mock-checkout/third_party/WebKit/LayoutTests': 'bbb',
     74         }, {
     75             '/mock-checkout/third_party/WebKit/LayoutTests': 'aaa',
     76         })
     77         self.assertEqual(host.filesystem.read_binary_file('/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt'), 'result A')
     78 
     79     def test_move_baselines_skip_scm_commands(self):
     80         host = MockHost(scm=ExcludingMockSCM(['/mock-checkout/third_party/WebKit/LayoutTests/platform/mac/another/test-expected.txt']))
     81         host.filesystem.write_text_file('/mock-checkout/third_party/WebKit/LayoutTests/VirtualTestSuites', '[]')
     82         host.filesystem.write_binary_file('/mock-checkout/third_party/WebKit/LayoutTests/platform/win/another/test-expected.txt', 'result A')
     83         host.filesystem.write_binary_file('/mock-checkout/third_party/WebKit/LayoutTests/platform/mac/another/test-expected.txt', 'result A')
     84         host.filesystem.write_binary_file('/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt', 'result B')
     85         baseline_optimizer = BaselineOptimizer(host, host.port_factory.get(), host.port_factory.all_port_names(), skip_scm_commands=True)
     86         baseline_optimizer._move_baselines('another/test-expected.txt', {
     87             '/mock-checkout/third_party/WebKit/LayoutTests/platform/win': 'aaa',
     88             '/mock-checkout/third_party/WebKit/LayoutTests/platform/mac': 'aaa',
     89             '/mock-checkout/third_party/WebKit/LayoutTests': 'bbb',
     90         }, {
     91             '/mock-checkout/third_party/WebKit/LayoutTests/platform/linux': 'bbb',
     92             '/mock-checkout/third_party/WebKit/LayoutTests': 'aaa',
     93         })
     94         self.assertEqual(host.filesystem.read_binary_file('/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt'), 'result A')
     95 
     96         self.assertEqual(baseline_optimizer._files_to_delete, [
     97             '/mock-checkout/third_party/WebKit/LayoutTests/platform/win/another/test-expected.txt',
     98         ])
     99 
    100         self.assertEqual(baseline_optimizer._files_to_add, [
    101             '/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt',
    102             '/mock-checkout/third_party/WebKit/LayoutTests/platform/linux/another/test-expected.txt',
    103         ])
    104 
    105     def _assertOptimization(self, results_by_directory, expected_new_results_by_directory, baseline_dirname='', expected_files_to_delete=None, host=None):
    106         if not host:
    107             host = MockHost()
    108         fs = host.filesystem
    109         webkit_base = WebKitFinder(fs).webkit_base()
    110         baseline_name = 'mock-baseline-expected.txt'
    111         fs.write_text_file(fs.join(webkit_base, 'LayoutTests', 'VirtualTestSuites'),
    112                            '[{"prefix": "gpu", "base": "fast/canvas", "args": ["--foo"]}]')
    113 
    114         for dirname, contents in results_by_directory.items():
    115             path = fs.join(webkit_base, 'LayoutTests', dirname, baseline_name)
    116             fs.write_binary_file(path, contents)
    117 
    118         baseline_optimizer = BaselineOptimizer(host, host.port_factory.get(), host.port_factory.all_port_names(), skip_scm_commands=expected_files_to_delete is not None)
    119         self.assertTrue(baseline_optimizer.optimize(fs.join(baseline_dirname, baseline_name)))
    120 
    121         for dirname, contents in expected_new_results_by_directory.items():
    122             path = fs.join(webkit_base, 'LayoutTests', dirname, baseline_name)
    123             if contents is None:
    124                 self.assertTrue(not fs.exists(path) or path in baseline_optimizer._files_to_delete)
    125             else:
    126                 self.assertEqual(fs.read_binary_file(path), contents)
    127 
    128         # Check that the files that were in the original set have been deleted where necessary.
    129         for dirname in results_by_directory:
    130             path = fs.join(webkit_base, 'LayoutTests', dirname, baseline_name)
    131             if not dirname in expected_new_results_by_directory:
    132                 self.assertTrue(not fs.exists(path) or path in baseline_optimizer._files_to_delete)
    133 
    134         if expected_files_to_delete:
    135             self.assertEqual(sorted(baseline_optimizer._files_to_delete), sorted(expected_files_to_delete))
    136 
    137     def test_linux_redundant_with_win(self):
    138         self._assertOptimization({
    139             'platform/win': '1',
    140             'platform/linux': '1',
    141         }, {
    142             'platform/win': '1',
    143         })
    144 
    145     def test_covers_mac_win_linux(self):
    146         self._assertOptimization({
    147             'platform/mac': '1',
    148             'platform/win': '1',
    149             'platform/linux': '1',
    150             '': None,
    151         }, {
    152             '': '1',
    153         })
    154 
    155     def test_overwrites_root(self):
    156         self._assertOptimization({
    157             'platform/mac': '1',
    158             'platform/win': '1',
    159             'platform/linux': '1',
    160             '': '2',
    161         }, {
    162             '': '1',
    163         })
    164 
    165     def test_no_new_common_directory(self):
    166         self._assertOptimization({
    167             'platform/mac': '1',
    168             'platform/linux': '1',
    169             '': '2',
    170         }, {
    171             'platform/mac': '1',
    172             'platform/linux': '1',
    173             '': '2',
    174         })
    175 
    176 
    177     def test_local_optimization(self):
    178         self._assertOptimization({
    179             'platform/mac': '1',
    180             'platform/linux': '1',
    181             'platform/linux-x86': '1',
    182         }, {
    183             'platform/mac': '1',
    184             'platform/linux': '1',
    185         })
    186 
    187     def test_local_optimization_skipping_a_port_in_the_middle(self):
    188         self._assertOptimization({
    189             'platform/mac-snowleopard': '1',
    190             'platform/win': '1',
    191             'platform/linux-x86': '1',
    192         }, {
    193             'platform/mac-snowleopard': '1',
    194             'platform/win': '1',
    195         })
    196 
    197     def test_baseline_redundant_with_root(self):
    198         self._assertOptimization({
    199             'platform/mac': '1',
    200             'platform/win': '2',
    201             '': '2',
    202         }, {
    203             'platform/mac': '1',
    204             '': '2',
    205         })
    206 
    207     def test_root_baseline_unused(self):
    208         self._assertOptimization({
    209             'platform/mac': '1',
    210             'platform/win': '2',
    211             '': '3',
    212         }, {
    213             'platform/mac': '1',
    214             'platform/win': '2',
    215         })
    216 
    217     def test_root_baseline_unused_and_non_existant(self):
    218         self._assertOptimization({
    219             'platform/mac': '1',
    220             'platform/win': '2',
    221         }, {
    222             'platform/mac': '1',
    223             'platform/win': '2',
    224         })
    225 
    226     def test_virtual_root_redundant_with_actual_root(self):
    227         self._assertOptimization({
    228             'virtual/gpu/fast/canvas': '2',
    229             'fast/canvas': '2',
    230         }, {
    231             'virtual/gpu/fast/canvas': None,
    232             'fast/canvas': '2',
    233         }, baseline_dirname='virtual/gpu/fast/canvas')
    234 
    235     def test_virtual_root_redundant_with_ancestors(self):
    236         self._assertOptimization({
    237             'virtual/gpu/fast/canvas': '2',
    238             'platform/mac/fast/canvas': '2',
    239             'platform/win/fast/canvas': '2',
    240         }, {
    241             'virtual/gpu/fast/canvas': None,
    242             'fast/canvas': '2',
    243         }, baseline_dirname='virtual/gpu/fast/canvas')
    244 
    245     def test_virtual_root_redundant_with_ancestors_skip_scm_commands(self):
    246         self._assertOptimization({
    247             'virtual/gpu/fast/canvas': '2',
    248             'platform/mac/fast/canvas': '2',
    249             'platform/win/fast/canvas': '2',
    250         }, {
    251             'virtual/gpu/fast/canvas': None,
    252             'fast/canvas': '2',
    253         },
    254         baseline_dirname='virtual/gpu/fast/canvas',
    255         expected_files_to_delete=[
    256             '/mock-checkout/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/mock-baseline-expected.txt',
    257             '/mock-checkout/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/mock-baseline-expected.txt',
    258             '/mock-checkout/third_party/WebKit/LayoutTests/platform/win/fast/canvas/mock-baseline-expected.txt',
    259         ])
    260 
    261     def test_virtual_root_redundant_with_ancestors_skip_scm_commands_with_file_not_in_scm(self):
    262         self._assertOptimization({
    263             'virtual/gpu/fast/canvas': '2',
    264             'platform/mac/fast/canvas': '2',
    265             'platform/win/fast/canvas': '2',
    266         }, {
    267             'virtual/gpu/fast/canvas': None,
    268             'fast/canvas': '2',
    269         },
    270         baseline_dirname='virtual/gpu/fast/canvas',
    271         expected_files_to_delete=[
    272             '/mock-checkout/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/mock-baseline-expected.txt',
    273             '/mock-checkout/third_party/WebKit/LayoutTests/platform/win/fast/canvas/mock-baseline-expected.txt',
    274         ],
    275         host=MockHost(scm=ExcludingMockSCM(['/mock-checkout/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/mock-baseline-expected.txt'])))
    276 
    277     def test_virtual_root_not_redundant_with_ancestors(self):
    278         self._assertOptimization({
    279             'virtual/gpu/fast/canvas': '2',
    280             'platform/mac/fast/canvas': '1',
    281         }, {
    282             'virtual/gpu/fast/canvas': '2',
    283             'platform/mac/fast/canvas': '1',
    284         }, baseline_dirname='virtual/gpu/fast/canvas')
    285