• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# Copyright (C) 2010 Google Inc. All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions
6# are met:
7#
8# 1.  Redistributions of source code must retain the above copyright
9#     notice, this list of conditions and the following disclaimer.
10# 2.  Redistributions in binary form must reproduce the above copyright
11#     notice, this list of conditions and the following disclaimer in the
12#     documentation and/or other materials provided with the distribution.
13#
14# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
25"""Unit tests for deduplicate_tests.py."""
26
27import deduplicate_tests
28import os
29import unittest
30import webkitpy.common.checkout.scm as scm
31
32
33class MockExecutive(object):
34    last_run_command = []
35    response = ''
36
37    class Executive(object):
38        def run_command(self,
39                        args,
40                        cwd=None,
41                        input=None,
42                        error_handler=None,
43                        return_exit_code=False,
44                        return_stderr=True,
45                        decode_output=True):
46            MockExecutive.last_run_command += [args]
47            return MockExecutive.response
48
49
50class ListDuplicatesTest(unittest.TestCase):
51    def setUp(self):
52        MockExecutive.last_run_command = []
53        MockExecutive.response = ''
54        deduplicate_tests.executive = MockExecutive
55        self._original_cwd = os.getcwd()
56        checkout_root = scm.find_checkout_root()
57        self.assertNotEqual(checkout_root, None)
58        os.chdir(checkout_root)
59
60    def tearDown(self):
61        os.chdir(self._original_cwd)
62
63    def test_parse_git_output(self):
64        git_output = (
65            '100644 blob 5053240b3353f6eb39f7cb00259785f16d121df2\tLayoutTests/mac/foo-expected.txt\n'
66            '100644 blob a004548d107ecc4e1ea08019daf0a14e8634a1ff\tLayoutTests/platform/chromium/foo-expected.txt\n'
67            '100644 blob d6bb0bc762e3aec5df03b5c04485b2cb3b65ffb1\tLayoutTests/platform/chromium-linux/foo-expected.txt\n'
68            '100644 blob abcdebc762e3aec5df03b5c04485b2cb3b65ffb1\tLayoutTests/platform/chromium-linux/animage.png\n'
69            '100644 blob d6bb0bc762e3aec5df03b5c04485b2cb3b65ffb1\tLayoutTests/platform/chromium-win/foo-expected.txt\n'
70            '100644 blob abcdebc762e3aec5df03b5c04485b2cb3b65ffb1\tLayoutTests/platform/chromium-win/animage.png\n'
71            '100644 blob 4303df5389ca87cae83dd3236b8dd84e16606517\tLayoutTests/platform/mac/foo-expected.txt\n')
72        hashes = deduplicate_tests.parse_git_output(git_output, '*')
73        expected = {('mac/foo-expected.txt', '5053240b3353f6eb39f7cb00259785f16d121df2'): set(['mac/foo-expected.txt']),
74                    ('animage.png', 'abcdebc762e3aec5df03b5c04485b2cb3b65ffb1'): set(['platform/chromium-linux/animage.png', 'platform/chromium-win/animage.png']),
75                    ('foo-expected.txt', '4303df5389ca87cae83dd3236b8dd84e16606517'): set(['platform/mac/foo-expected.txt']),
76                    ('foo-expected.txt', 'd6bb0bc762e3aec5df03b5c04485b2cb3b65ffb1'): set(['platform/chromium-linux/foo-expected.txt', 'platform/chromium-win/foo-expected.txt']),
77                    ('foo-expected.txt', 'a004548d107ecc4e1ea08019daf0a14e8634a1ff'): set(['platform/chromium/foo-expected.txt'])}
78        self.assertEquals(expected, hashes)
79
80        hashes = deduplicate_tests.parse_git_output(git_output, '*.png')
81        expected = {('animage.png', 'abcdebc762e3aec5df03b5c04485b2cb3b65ffb1'): set(['platform/chromium-linux/animage.png', 'platform/chromium-win/animage.png'])}
82        self.assertEquals(expected, hashes)
83
84    def test_extract_platforms(self):
85        self.assertEquals({'foo': 'platform/foo/bar',
86                           'zoo': 'platform/zoo/com'},
87                           deduplicate_tests.extract_platforms(['platform/foo/bar', 'platform/zoo/com']))
88        self.assertEquals({'foo': 'platform/foo/bar',
89                           deduplicate_tests._BASE_PLATFORM: 'what/'},
90                           deduplicate_tests.extract_platforms(['platform/foo/bar', 'what/']))
91
92    def test_has_intermediate_results(self):
93        test_cases = (
94            # If we found a duplicate in our first fallback, we have no
95            # intermediate results.
96            (False, ('fast/foo-expected.txt',
97                     ['chromium-win', 'chromium', 'base'],
98                     'chromium-win-win7',
99                     lambda path: True)),
100            # Since chromium-win has a result, we have an intermediate result.
101            (True,  ('fast/foo-expected.txt',
102                     ['chromium-win', 'chromium', 'base'],
103                     'chromium',
104                     lambda path: True)),
105            # There are no intermediate results.
106            (False, ('fast/foo-expected.txt',
107                     ['chromium-win', 'chromium', 'base'],
108                     'chromium',
109                     lambda path: False)),
110            # There are no intermediate results since a result for chromium is
111            # our duplicate file.
112            (False, ('fast/foo-expected.txt',
113                     ['chromium-win', 'chromium', 'base'],
114                     'chromium',
115                     lambda path: path == 'LayoutTests/platform/chromium/fast/foo-expected.txt')),
116            # We have an intermediate result in 'chromium' even though our
117            # duplicate is with the file in 'base'.
118            (True,  ('fast/foo-expected.txt',
119                     ['chromium-win', 'chromium', 'base'],
120                     'base',
121                     lambda path: path == 'LayoutTests/platform/chromium/fast/foo-expected.txt')),
122            # We have an intermediate result in 'chromium-win' even though our
123            # duplicate is in 'base'.
124            (True,  ('fast/foo-expected.txt',
125                     ['chromium-win', 'chromium', 'base'],
126                     'base',
127                     lambda path: path == 'LayoutTests/platform/chromium-win/fast/foo-expected.txt')),
128        )
129        for expected, inputs in test_cases:
130            self.assertEquals(expected,
131                deduplicate_tests.has_intermediate_results(*inputs))
132
133    def test_unique(self):
134        MockExecutive.response = (
135            '100644 blob 5053240b3353f6eb39f7cb00259785f16d121df2\tLayoutTests/mac/foo-expected.txt\n'
136            '100644 blob a004548d107ecc4e1ea08019daf0a14e8634a1ff\tLayoutTests/platform/chromium/foo-expected.txt\n'
137            '100644 blob abcd0bc762e3aec5df03b5c04485b2cb3b65ffb1\tLayoutTests/platform/chromium-linux/foo-expected.txt\n'
138            '100644 blob d6bb0bc762e3aec5df03b5c04485b2cb3b65ffb1\tLayoutTests/platform/chromium-win/foo-expected.txt\n'
139            '100644 blob 4303df5389ca87cae83dd3236b8dd84e16606517\tLayoutTests/platform/mac/foo-expected.txt\n')
140        result = deduplicate_tests.deduplicate('*')
141        self.assertEquals(1, len(MockExecutive.last_run_command))
142        self.assertEquals(('git', 'ls-tree', '-r', 'HEAD', 'LayoutTests'), MockExecutive.last_run_command[-1])
143        self.assertEquals(0, len(result))
144
145    def test_duplicates(self):
146        MockExecutive.response = (
147            '100644 blob 5053240b3353f6eb39f7cb00259785f16d121df2\tLayoutTests/mac/foo-expected.txt\n'
148            '100644 blob a004548d107ecc4e1ea08019daf0a14e8634a1ff\tLayoutTests/platform/chromium/foo-expected.txt\n'
149            '100644 blob d6bb0bc762e3aec5df03b5c04485b2cb3b65ffb1\tLayoutTests/platform/chromium-linux/foo-expected.txt\n'
150            '100644 blob abcdebc762e3aec5df03b5c04485b2cb3b65ffb1\tLayoutTests/platform/chromium-linux/animage.png\n'
151            '100644 blob d6bb0bc762e3aec5df03b5c04485b2cb3b65ffb1\tLayoutTests/platform/chromium-win/foo-expected.txt\n'
152            '100644 blob abcdebc762e3aec5df03b5c04485b2cb3b65ffb1\tLayoutTests/platform/chromium-win/animage.png\n'
153            '100644 blob 4303df5389ca87cae83dd3236b8dd84e16606517\tLayoutTests/platform/mac/foo-expected.txt\n')
154
155        result = deduplicate_tests.deduplicate('*')
156        self.assertEquals(1, len(MockExecutive.last_run_command))
157        self.assertEquals(('git', 'ls-tree', '-r', 'HEAD', 'LayoutTests'), MockExecutive.last_run_command[-1])
158        self.assertEquals(2, len(result))
159        self.assertEquals({'test': 'animage.png',
160                           'path': 'LayoutTests/platform/chromium-linux/animage.png',
161                           'fallback': 'chromium-win',
162                           'platform': 'chromium-linux-x86'},
163                          result[0])
164        self.assertEquals({'test': 'foo-expected.txt',
165                           'path': 'LayoutTests/platform/chromium-linux/foo-expected.txt',
166                           'fallback': 'chromium-win',
167                           'platform': 'chromium-linux-x86'},
168                          result[1])
169
170        result = deduplicate_tests.deduplicate('*.txt')
171        self.assertEquals(2, len(MockExecutive.last_run_command))
172        self.assertEquals(('git', 'ls-tree', '-r', 'HEAD', 'LayoutTests'), MockExecutive.last_run_command[-1])
173        self.assertEquals(1, len(result))
174        self.assertEquals({'test': 'foo-expected.txt',
175                           'path': 'LayoutTests/platform/chromium-linux/foo-expected.txt',
176                           'fallback': 'chromium-win',
177                           'platform': 'chromium-linux-x86'},
178                          result[0])
179
180        result = deduplicate_tests.deduplicate('*.png')
181        self.assertEquals(3, len(MockExecutive.last_run_command))
182        self.assertEquals(('git', 'ls-tree', '-r', 'HEAD', 'LayoutTests'), MockExecutive.last_run_command[-1])
183        self.assertEquals(1, len(result))
184        self.assertEquals({'test': 'animage.png',
185                           'path': 'LayoutTests/platform/chromium-linux/animage.png',
186                           'fallback': 'chromium-win',
187                           'platform': 'chromium-linux-x86'},
188                          result[0])
189
190    def test_get_relative_test_path(self):
191        checkout_root = scm.find_checkout_root()
192        layout_test_dir = os.path.join(checkout_root, 'LayoutTests')
193        test_cases = (
194            ('platform/mac/test.html',
195             ('platform/mac/test.html', layout_test_dir)),
196            ('LayoutTests/platform/mac/test.html',
197             ('platform/mac/test.html', checkout_root)),
198            (None,
199             ('platform/mac/test.html', os.path.join(checkout_root, 'Source', 'WebCore'))),
200            ('test.html',
201             ('platform/mac/test.html', os.path.join(layout_test_dir, 'platform/mac'))),
202            (None,
203             ('platform/mac/test.html', os.path.join(layout_test_dir, 'platform/win'))),
204        )
205        for expected, inputs in test_cases:
206            self.assertEquals(expected,
207                              deduplicate_tests.get_relative_test_path(*inputs))
208
209if __name__ == '__main__':
210    unittest.main()
211