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 webkitpy.thirdparty.unittest2 as 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_binary_file('/mock-checkout/third_party/WebKit/LayoutTests/platform/win/another/test-expected.txt', 'result A')
     66         host.filesystem.write_binary_file('/mock-checkout/third_party/WebKit/LayoutTests/platform/mac/another/test-expected.txt', 'result A')
     67         host.filesystem.write_binary_file('/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt', 'result B')
     68         baseline_optimizer = BaselineOptimizer(host, host.port_factory.all_port_names(), skip_scm_commands=False)
     69         baseline_optimizer._move_baselines('another/test-expected.txt', {
     70             '/mock-checkout/third_party/WebKit/LayoutTests/platform/win': 'aaa',
     71             '/mock-checkout/third_party/WebKit/LayoutTests/platform/mac': 'aaa',
     72             '/mock-checkout/third_party/WebKit/LayoutTests': 'bbb',
     73         }, {
     74             '/mock-checkout/third_party/WebKit/LayoutTests': 'aaa',
     75         })
     76         self.assertEqual(host.filesystem.read_binary_file('/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt'), 'result A')
     77 
     78     def test_move_baselines_skip_scm_commands(self):
     79         host = MockHost(scm=ExcludingMockSCM(['/mock-checkout/third_party/WebKit/LayoutTests/platform/mac/another/test-expected.txt']))
     80         host.filesystem.write_binary_file('/mock-checkout/third_party/WebKit/LayoutTests/platform/win/another/test-expected.txt', 'result A')
     81         host.filesystem.write_binary_file('/mock-checkout/third_party/WebKit/LayoutTests/platform/mac/another/test-expected.txt', 'result A')
     82         host.filesystem.write_binary_file('/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt', 'result B')
     83         baseline_optimizer = BaselineOptimizer(host, host.port_factory.all_port_names(), skip_scm_commands=True)
     84         baseline_optimizer._move_baselines('another/test-expected.txt', {
     85             '/mock-checkout/third_party/WebKit/LayoutTests/platform/win': 'aaa',
     86             '/mock-checkout/third_party/WebKit/LayoutTests/platform/mac': 'aaa',
     87             '/mock-checkout/third_party/WebKit/LayoutTests': 'bbb',
     88         }, {
     89             '/mock-checkout/third_party/WebKit/LayoutTests/platform/linux': 'bbb',
     90             '/mock-checkout/third_party/WebKit/LayoutTests': 'aaa',
     91         })
     92         self.assertEqual(host.filesystem.read_binary_file('/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt'), 'result A')
     93 
     94         self.assertEqual(baseline_optimizer._files_to_delete, [
     95             '/mock-checkout/third_party/WebKit/LayoutTests/platform/win/another/test-expected.txt',
     96         ])
     97 
     98         self.assertEqual(baseline_optimizer._files_to_add, [
     99             '/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt',
    100             '/mock-checkout/third_party/WebKit/LayoutTests/platform/linux/another/test-expected.txt',
    101         ])
    102 
    103     def _assertOptimization(self, results_by_directory, expected_new_results_by_directory, baseline_dirname='', expected_files_to_delete=None):
    104         host = MockHost()
    105         fs = host.filesystem
    106         webkit_base = WebKitFinder(fs).webkit_base()
    107         baseline_name = 'mock-baseline-expected.txt'
    108 
    109         for dirname, contents in results_by_directory.items():
    110             path = fs.join(webkit_base, 'LayoutTests', dirname, baseline_name)
    111             fs.write_binary_file(path, contents)
    112 
    113         baseline_optimizer = BaselineOptimizer(host, host.port_factory.all_port_names(), skip_scm_commands=expected_files_to_delete is not None)
    114         self.assertTrue(baseline_optimizer.optimize(fs.join(baseline_dirname, baseline_name)))
    115 
    116         for dirname, contents in expected_new_results_by_directory.items():
    117             path = fs.join(webkit_base, 'LayoutTests', dirname, baseline_name)
    118             if contents is None:
    119                 self.assertTrue(not fs.exists(path) or path in baseline_optimizer._files_to_delete)
    120             else:
    121                 self.assertEqual(fs.read_binary_file(path), contents)
    122 
    123         # Check that the files that were in the original set have been deleted where necessary.
    124         for dirname in results_by_directory:
    125             path = fs.join(webkit_base, 'LayoutTests', dirname, baseline_name)
    126             if not dirname in expected_new_results_by_directory:
    127                 self.assertTrue(not fs.exists(path) or path in baseline_optimizer._files_to_delete)
    128 
    129         if expected_files_to_delete:
    130             self.assertEqual(baseline_optimizer._files_to_delete, expected_files_to_delete)
    131 
    132     def test_linux_redundant_with_win(self):
    133         self._assertOptimization({
    134             'platform/win': '1',
    135             'platform/linux': '1',
    136         }, {
    137             'platform/win': '1',
    138         })
    139 
    140     def test_covers_mac_win_linux(self):
    141         self._assertOptimization({
    142             'platform/mac': '1',
    143             'platform/win': '1',
    144             'platform/linux': '1',
    145             '': None,
    146         }, {
    147             '': '1',
    148         })
    149 
    150     def test_overwrites_root(self):
    151         self._assertOptimization({
    152             'platform/mac': '1',
    153             'platform/win': '1',
    154             'platform/linux': '1',
    155             '': '2',
    156         }, {
    157             '': '1',
    158         })
    159 
    160     def test_no_new_common_directory(self):
    161         self._assertOptimization({
    162             'platform/mac': '1',
    163             'platform/linux': '1',
    164             '': '2',
    165         }, {
    166             'platform/mac': '1',
    167             'platform/linux': '1',
    168             '': '2',
    169         })
    170 
    171 
    172     def test_local_optimization(self):
    173         self._assertOptimization({
    174             'platform/mac': '1',
    175             'platform/linux': '1',
    176             'platform/linux-x86': '1',
    177         }, {
    178             'platform/mac': '1',
    179             'platform/linux': '1',
    180         })
    181 
    182     def test_local_optimization_skipping_a_port_in_the_middle(self):
    183         self._assertOptimization({
    184             'platform/mac-snowleopard': '1',
    185             'platform/win': '1',
    186             'platform/linux-x86': '1',
    187         }, {
    188             'platform/mac-snowleopard': '1',
    189             'platform/win': '1',
    190         })
    191 
    192     def test_baseline_redundant_with_root(self):
    193         self._assertOptimization({
    194             'platform/mac': '1',
    195             'platform/win': '2',
    196             '': '2',
    197         }, {
    198             'platform/mac': '1',
    199             '': '2',
    200         })
    201 
    202     def test_root_baseline_unused(self):
    203         self._assertOptimization({
    204             'platform/mac': '1',
    205             'platform/win': '2',
    206             '': '3',
    207         }, {
    208             'platform/mac': '1',
    209             'platform/win': '2',
    210         })
    211 
    212     def test_root_baseline_unused_and_non_existant(self):
    213         self._assertOptimization({
    214             'platform/mac': '1',
    215             'platform/win': '2',
    216         }, {
    217             'platform/mac': '1',
    218             'platform/win': '2',
    219         })
    220 
    221     def test_virtual_root_redundant_with_actual_root(self):
    222         self._assertOptimization({
    223             'virtual/softwarecompositing': '2',
    224             'compositing': '2',
    225         }, {
    226             'virtual/softwarecompositing': None,
    227             'compositing': '2',
    228         }, baseline_dirname='virtual/softwarecompositing')
    229 
    230     def test_virtual_root_redundant_with_ancestors(self):
    231         self._assertOptimization({
    232             'virtual/softwarecompositing': '2',
    233             'platform/mac/compositing': '2',
    234             'platform/win/compositing': '2',
    235         }, {
    236             'virtual/softwarecompositing': None,
    237             'compositing': '2',
    238         }, baseline_dirname='virtual/softwarecompositing')
    239 
    240     def test_virtual_root_redundant_with_ancestors_skip_scm_commands(self):
    241         self._assertOptimization({
    242             'virtual/softwarecompositing': '2',
    243             'platform/mac/compositing': '2',
    244             'platform/win/compositing': '2',
    245         }, {
    246             'virtual/softwarecompositing': None,
    247             'compositing': '2',
    248         },
    249         baseline_dirname='virtual/softwarecompositing',
    250         expected_files_to_delete=[
    251             '/mock-checkout/third_party/WebKit/LayoutTests/virtual/softwarecompositing/mock-baseline-expected.txt',
    252             '/mock-checkout/third_party/WebKit/LayoutTests/platform/mac/compositing/mock-baseline-expected.txt',
    253             '/mock-checkout/third_party/WebKit/LayoutTests/platform/win/compositing/mock-baseline-expected.txt',
    254         ])
    255 
    256     def test_virtual_root_not_redundant_with_ancestors(self):
    257         self._assertOptimization({
    258             'virtual/softwarecompositing': '2',
    259             'platform/mac/compositing': '1',
    260         }, {
    261             'virtual/softwarecompositing': '2',
    262             'platform/mac/compositing': '1',
    263         }, baseline_dirname='virtual/softwarecompositing')
    264