OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Unit tests for presubmit_support.py and presubmit_canned_checks.py.""" | 6 """Unit tests for presubmit_support.py and presubmit_canned_checks.py.""" |
7 | 7 |
8 # pylint is too confused. | 8 # pylint is too confused. |
9 # pylint: disable=E1101,E1103,R0201,W0212,W0403 | 9 # pylint: disable=E1101,E1103,R0201,W0212,W0403 |
10 | 10 |
11 import StringIO | 11 import StringIO |
12 import sys | 12 import sys |
13 | 13 |
14 # Fixes include path. | 14 # Fixes include path. |
15 from super_mox import mox, SuperMoxTestBase | 15 from super_mox import mox, SuperMoxTestBase |
16 | 16 |
17 import owners | 17 import owners |
18 import presubmit_support as presubmit | 18 import presubmit_support as presubmit |
| 19 import rietveld |
19 # Shortcut. | 20 # Shortcut. |
20 presubmit_canned_checks = presubmit.presubmit_canned_checks | 21 presubmit_canned_checks = presubmit.presubmit_canned_checks |
21 | 22 |
22 | 23 |
23 class PresubmitTestsBase(SuperMoxTestBase): | 24 class PresubmitTestsBase(SuperMoxTestBase): |
24 """Setups and tear downs the mocks but doesn't test anything as-is.""" | 25 """Setups and tear downs the mocks but doesn't test anything as-is.""" |
25 presubmit_text = """ | 26 presubmit_text = """ |
26 def CheckChangeOnUpload(input_api, output_api): | 27 def CheckChangeOnUpload(input_api, output_api): |
27 if not input_api.change.NOSUCHKEY: | 28 if not input_api.change.NOSUCHKEY: |
28 return [output_api.PresubmitError("!!")] | 29 return [output_api.PresubmitError("!!")] |
(...skipping 1302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1331 | 1332 |
1332 class CannedChecksUnittest(PresubmitTestsBase): | 1333 class CannedChecksUnittest(PresubmitTestsBase): |
1333 """Tests presubmit_canned_checks.py.""" | 1334 """Tests presubmit_canned_checks.py.""" |
1334 | 1335 |
1335 def setUp(self): | 1336 def setUp(self): |
1336 PresubmitTestsBase.setUp(self) | 1337 PresubmitTestsBase.setUp(self) |
1337 | 1338 |
1338 def MockInputApi(self, change, committing): | 1339 def MockInputApi(self, change, committing): |
1339 input_api = self.mox.CreateMock(presubmit.InputApi) | 1340 input_api = self.mox.CreateMock(presubmit.InputApi) |
1340 input_api.cStringIO = presubmit.cStringIO | 1341 input_api.cStringIO = presubmit.cStringIO |
| 1342 input_api.json = presubmit.json |
1341 input_api.os_listdir = self.mox.CreateMockAnything() | 1343 input_api.os_listdir = self.mox.CreateMockAnything() |
1342 input_api.os_walk = self.mox.CreateMockAnything() | 1344 input_api.os_walk = self.mox.CreateMockAnything() |
1343 input_api.os_path = presubmit.os.path | 1345 input_api.os_path = presubmit.os.path |
1344 input_api.re = presubmit.re | 1346 input_api.re = presubmit.re |
| 1347 input_api.rietveld = self.mox.CreateMock(rietveld.Rietveld) |
1345 input_api.traceback = presubmit.traceback | 1348 input_api.traceback = presubmit.traceback |
1346 input_api.urllib2 = self.mox.CreateMock(presubmit.urllib2) | 1349 input_api.urllib2 = self.mox.CreateMock(presubmit.urllib2) |
1347 input_api.unittest = unittest | 1350 input_api.unittest = unittest |
1348 input_api.subprocess = self.mox.CreateMock(presubmit.subprocess) | 1351 input_api.subprocess = self.mox.CreateMock(presubmit.subprocess) |
1349 class fake_CalledProcessError(Exception): | 1352 class fake_CalledProcessError(Exception): |
1350 def __str__(self): | 1353 def __str__(self): |
1351 return 'foo' | 1354 return 'foo' |
1352 input_api.subprocess.CalledProcessError = fake_CalledProcessError | 1355 input_api.subprocess.CalledProcessError = fake_CalledProcessError |
1353 | 1356 |
1354 input_api.change = change | 1357 input_api.change = change |
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1808 self.mox.ReplayAll() | 1811 self.mox.ReplayAll() |
1809 results = presubmit_canned_checks.CheckTreeIsOpen( | 1812 results = presubmit_canned_checks.CheckTreeIsOpen( |
1810 input_api, presubmit.OutputApi, | 1813 input_api, presubmit.OutputApi, |
1811 url='url_to_closed', closed='.*closed.*') | 1814 url='url_to_closed', closed='.*closed.*') |
1812 self.assertEquals(len(results), 1) | 1815 self.assertEquals(len(results), 1) |
1813 self.assertEquals(results[0].__class__, | 1816 self.assertEquals(results[0].__class__, |
1814 presubmit.OutputApi.PresubmitError) | 1817 presubmit.OutputApi.PresubmitError) |
1815 | 1818 |
1816 def testCannedCheckJsonTreeIsOpenOpen(self): | 1819 def testCannedCheckJsonTreeIsOpenOpen(self): |
1817 input_api = self.MockInputApi(None, True) | 1820 input_api = self.MockInputApi(None, True) |
1818 input_api.json = presubmit.json | |
1819 connection = self.mox.CreateMockAnything() | 1821 connection = self.mox.CreateMockAnything() |
1820 input_api.urllib2.urlopen('url_to_open').AndReturn(connection) | 1822 input_api.urllib2.urlopen('url_to_open').AndReturn(connection) |
1821 status = { | 1823 status = { |
1822 'can_commit_freely': True, | 1824 'can_commit_freely': True, |
1823 'general_state': 'open', | 1825 'general_state': 'open', |
1824 'message': 'The tree is open' | 1826 'message': 'The tree is open' |
1825 } | 1827 } |
1826 connection.read().AndReturn(input_api.json.dumps(status)) | 1828 connection.read().AndReturn(input_api.json.dumps(status)) |
1827 connection.close() | 1829 connection.close() |
1828 self.mox.ReplayAll() | 1830 self.mox.ReplayAll() |
1829 results = presubmit_canned_checks.CheckTreeIsOpen( | 1831 results = presubmit_canned_checks.CheckTreeIsOpen( |
1830 input_api, presubmit.OutputApi, json_url='url_to_open') | 1832 input_api, presubmit.OutputApi, json_url='url_to_open') |
1831 self.assertEquals(results, []) | 1833 self.assertEquals(results, []) |
1832 | 1834 |
1833 def testCannedCheckJsonTreeIsOpenClosed(self): | 1835 def testCannedCheckJsonTreeIsOpenClosed(self): |
1834 input_api = self.MockInputApi(None, True) | 1836 input_api = self.MockInputApi(None, True) |
1835 input_api.json = presubmit.json | |
1836 connection = self.mox.CreateMockAnything() | 1837 connection = self.mox.CreateMockAnything() |
1837 input_api.urllib2.urlopen('url_to_closed').AndReturn(connection) | 1838 input_api.urllib2.urlopen('url_to_closed').AndReturn(connection) |
1838 status = { | 1839 status = { |
1839 'can_commit_freely': False, | 1840 'can_commit_freely': False, |
1840 'general_state': 'closed', | 1841 'general_state': 'closed', |
1841 'message': 'The tree is close', | 1842 'message': 'The tree is close', |
1842 } | 1843 } |
1843 connection.read().AndReturn(input_api.json.dumps(status)) | 1844 connection.read().AndReturn(input_api.json.dumps(status)) |
1844 connection.close() | 1845 connection.close() |
1845 self.mox.ReplayAll() | 1846 self.mox.ReplayAll() |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1961 | 1962 |
1962 results = presubmit_canned_checks.CheckRietveldTryJobExecution( | 1963 results = presubmit_canned_checks.CheckRietveldTryJobExecution( |
1963 input_api, presubmit.OutputApi, 'uurl', ('mac', 'linux', 'amiga'), | 1964 input_api, presubmit.OutputApi, 'uurl', ('mac', 'linux', 'amiga'), |
1964 'georges') | 1965 'georges') |
1965 self.assertEquals(len(results), 1) | 1966 self.assertEquals(len(results), 1) |
1966 self.assertEquals(results[0].__class__, | 1967 self.assertEquals(results[0].__class__, |
1967 presubmit.OutputApi.PresubmitPromptWarning) | 1968 presubmit.OutputApi.PresubmitPromptWarning) |
1968 | 1969 |
1969 def testCheckBuildbotPendingBuildsBad(self): | 1970 def testCheckBuildbotPendingBuildsBad(self): |
1970 input_api = self.MockInputApi(None, True) | 1971 input_api = self.MockInputApi(None, True) |
1971 input_api.json = presubmit.json | |
1972 connection = self.mox.CreateMockAnything() | 1972 connection = self.mox.CreateMockAnything() |
1973 input_api.urllib2.urlopen('uurl').AndReturn(connection) | 1973 input_api.urllib2.urlopen('uurl').AndReturn(connection) |
1974 connection.read().AndReturn('foo') | 1974 connection.read().AndReturn('foo') |
1975 connection.close() | 1975 connection.close() |
1976 self.mox.ReplayAll() | 1976 self.mox.ReplayAll() |
1977 | 1977 |
1978 results = presubmit_canned_checks.CheckBuildbotPendingBuilds( | 1978 results = presubmit_canned_checks.CheckBuildbotPendingBuilds( |
1979 input_api, presubmit.OutputApi, 'uurl', 2, ('foo')) | 1979 input_api, presubmit.OutputApi, 'uurl', 2, ('foo')) |
1980 self.assertEquals(len(results), 1) | 1980 self.assertEquals(len(results), 1) |
1981 self.assertEquals(results[0].__class__, | 1981 self.assertEquals(results[0].__class__, |
1982 presubmit.OutputApi.PresubmitNotifyResult) | 1982 presubmit.OutputApi.PresubmitNotifyResult) |
1983 | 1983 |
1984 def testCheckBuildbotPendingBuildsGood(self): | 1984 def testCheckBuildbotPendingBuildsGood(self): |
1985 input_api = self.MockInputApi(None, True) | 1985 input_api = self.MockInputApi(None, True) |
1986 input_api.json = presubmit.json | |
1987 connection = self.mox.CreateMockAnything() | 1986 connection = self.mox.CreateMockAnything() |
1988 input_api.urllib2.urlopen('uurl').AndReturn(connection) | 1987 input_api.urllib2.urlopen('uurl').AndReturn(connection) |
1989 connection.read().AndReturn(""" | 1988 connection.read().AndReturn(""" |
1990 { | 1989 { |
1991 'b1': { 'pending_builds': [0, 1, 2, 3, 4, 5, 6, 7] }, | 1990 'b1': { 'pending_builds': [0, 1, 2, 3, 4, 5, 6, 7] }, |
1992 'foo': { 'pending_builds': [0, 1, 2, 3, 4, 5, 6, 7] }, | 1991 'foo': { 'pending_builds': [0, 1, 2, 3, 4, 5, 6, 7] }, |
1993 'b2': { 'pending_builds': [0] } | 1992 'b2': { 'pending_builds': [0] } |
1994 }""") | 1993 }""") |
1995 connection.close() | 1994 connection.close() |
1996 self.mox.ReplayAll() | 1995 self.mox.ReplayAll() |
1997 | 1996 |
1998 results = presubmit_canned_checks.CheckBuildbotPendingBuilds( | 1997 results = presubmit_canned_checks.CheckBuildbotPendingBuilds( |
1999 input_api, presubmit.OutputApi, 'uurl', 2, ('foo')) | 1998 input_api, presubmit.OutputApi, 'uurl', 2, ('foo')) |
2000 self.assertEquals(len(results), 1) | 1999 self.assertEquals(len(results), 1) |
2001 self.assertEquals(results[0].__class__, | 2000 self.assertEquals(results[0].__class__, |
2002 presubmit.OutputApi.PresubmitNotifyResult) | 2001 presubmit.OutputApi.PresubmitNotifyResult) |
2003 | 2002 |
2004 def AssertOwnersWorks(self, tbr=False, issue='1', approvers=None, | 2003 def AssertOwnersWorks(self, tbr=False, issue='1', approvers=None, |
2005 rietveld_response=None, host_url=None, | 2004 rietveld_response=None, uncovered_files=None, expected_output=''): |
2006 uncovered_files=None, expected_output=''): | |
2007 if approvers is None: | 2005 if approvers is None: |
2008 approvers = set() | 2006 approvers = set() |
2009 if uncovered_files is None: | 2007 if uncovered_files is None: |
2010 uncovered_files = set() | 2008 uncovered_files = set() |
2011 | 2009 |
2012 change = self.mox.CreateMock(presubmit.Change) | 2010 change = self.mox.CreateMock(presubmit.Change) |
2013 change.issue = issue | 2011 change.issue = issue |
2014 affected_file = self.mox.CreateMock(presubmit.SvnAffectedFile) | 2012 affected_file = self.mox.CreateMock(presubmit.SvnAffectedFile) |
2015 input_api = self.MockInputApi(change, False) | 2013 input_api = self.MockInputApi(change, False) |
2016 fake_db = self.mox.CreateMock(owners.Database) | 2014 fake_db = self.mox.CreateMock(owners.Database) |
2017 fake_db.email_regexp = input_api.re.compile(owners.BASIC_EMAIL_REGEXP) | 2015 fake_db.email_regexp = input_api.re.compile(owners.BASIC_EMAIL_REGEXP) |
2018 input_api.owners_db = fake_db | 2016 input_api.owners_db = fake_db |
2019 input_api.is_committing = True | 2017 input_api.is_committing = True |
2020 input_api.tbr = tbr | 2018 input_api.tbr = tbr |
2021 | 2019 |
2022 if not tbr and issue: | 2020 if not tbr and issue: |
2023 affected_file.LocalPath().AndReturn('foo.cc') | 2021 affected_file.LocalPath().AndReturn('foo.cc') |
2024 change.AffectedFiles(file_filter=None).AndReturn([affected_file]) | 2022 change.AffectedFiles(file_filter=None).AndReturn([affected_file]) |
2025 | |
2026 expected_host = 'http://localhost' | |
2027 if host_url: | |
2028 input_api.host_url = host_url | |
2029 if host_url.startswith('https'): | |
2030 expected_host = host_url | |
2031 | |
2032 owner_email = 'john@example.com' | 2023 owner_email = 'john@example.com' |
2033 if not rietveld_response: | 2024 if not rietveld_response: |
2034 messages = ( | 2025 rietveld_response = { |
2035 '{"sender": "%s", "text": "I approve", "approval": true}' % a | 2026 "owner_email": owner_email, |
2036 for a in approvers) | 2027 "messages": [ |
2037 rietveld_response = '{"owner_email": "%s", "messages": [%s]}' % ( | 2028 {"sender": a, "text": "I approve", "approval": True} |
2038 owner_email, ','.join(messages)) | 2029 for a in approvers |
2039 input_api.urllib2.urlopen( | 2030 ], |
2040 expected_host + '/api/1?messages=true').AndReturn( | 2031 } |
2041 StringIO.StringIO(rietveld_response)) | 2032 input_api.rietveld.get_issue_properties( |
2042 input_api.json = presubmit.json | 2033 int(input_api.change.issue), True).AndReturn(rietveld_response) |
2043 fake_db.files_not_covered_by(set(['foo.cc']), | 2034 fake_db.files_not_covered_by(set(['foo.cc']), |
2044 approvers.union(set([owner_email]))).AndReturn(uncovered_files) | 2035 approvers.union(set([owner_email]))).AndReturn(uncovered_files) |
2045 | 2036 |
2046 self.mox.ReplayAll() | 2037 self.mox.ReplayAll() |
2047 output = presubmit.PresubmitOutput() | 2038 output = presubmit.PresubmitOutput() |
2048 results = presubmit_canned_checks.CheckOwners(input_api, | 2039 results = presubmit_canned_checks.CheckOwners(input_api, |
2049 presubmit.OutputApi) | 2040 presubmit.OutputApi) |
2050 if results: | 2041 if results: |
2051 results[0].handle(output) | 2042 results[0].handle(output) |
2052 self.assertEquals(output.getvalue(), expected_output) | 2043 self.assertEquals(output.getvalue(), expected_output) |
2053 | 2044 |
2054 def testCannedCheckOwners_LGTMPhrases(self): | 2045 def testCannedCheckOwners_Approved(self): |
2055 def phrase_test(approval, approvers=None, expected_output=''): | 2046 response = { |
2056 if approvers is None: | 2047 "owner_email": "john@example.com", |
2057 approvers = set(['ben@example.com']) | 2048 "messages": [ |
2058 self.AssertOwnersWorks(approvers=approvers, | 2049 { |
2059 rietveld_response=( | 2050 "sender": "ben@example.com", "text": "foo", "approval": True, |
2060 '{"owner_email": "john@example.com",' | 2051 }, |
2061 '"messages": [{"sender": "ben@example.com",' | 2052 ], |
2062 ' "text": "foo", "approval": %s}]}') % approval, | 2053 } |
2063 expected_output=expected_output) | 2054 self.AssertOwnersWorks(approvers=set(['ben@example.com']), |
| 2055 rietveld_response=response, |
| 2056 expected_output='') |
2064 | 2057 |
2065 phrase_test('true') | 2058 def testCannedCheckOwners_NotApproved(self): |
2066 phrase_test('false', approvers=set(), | 2059 response = { |
2067 expected_output='Missing LGTM from someone other than ' | 2060 "owner_email": "john@example.com", |
2068 'john@example.com\n') | 2061 "messages": [ |
2069 | 2062 { |
2070 def testCannedCheckOwners_HTTPS_HostURL(self): | 2063 "sender": "ben@example.com", "text": "foo", "approval": False, |
2071 self.AssertOwnersWorks(approvers=set(['ben@example.com']), | 2064 }, |
2072 host_url='https://localhost') | 2065 ], |
2073 | 2066 } |
2074 def testCannedCheckOwners_MissingSchemeInHostURL(self): | 2067 self.AssertOwnersWorks( |
2075 self.AssertOwnersWorks(approvers=set(['ben@example.com']), | 2068 approvers=set(), |
2076 host_url='localhost') | 2069 rietveld_response=response, |
| 2070 expected_output= |
| 2071 'Missing LGTM from someone other than john@example.com\n') |
2077 | 2072 |
2078 def testCannedCheckOwners_NoIssue(self): | 2073 def testCannedCheckOwners_NoIssue(self): |
2079 self.AssertOwnersWorks(issue=None, | 2074 self.AssertOwnersWorks(issue=None, |
2080 expected_output="OWNERS check failed: this change has no Rietveld " | 2075 expected_output="OWNERS check failed: this change has no Rietveld " |
2081 "issue number, so we can't check it for approvals.\n") | 2076 "issue number, so we can't check it for approvals.\n") |
2082 | 2077 |
2083 def testCannedCheckOwners_NoLGTM(self): | 2078 def testCannedCheckOwners_NoLGTM(self): |
2084 self.AssertOwnersWorks(expected_output='Missing LGTM from someone ' | 2079 self.AssertOwnersWorks(expected_output='Missing LGTM from someone ' |
2085 'other than john@example.com\n') | 2080 'other than john@example.com\n') |
2086 | 2081 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2158 whitelist=['^a$', '^b$'], | 2153 whitelist=['^a$', '^b$'], |
2159 blacklist=['a']) | 2154 blacklist=['a']) |
2160 self.assertEqual(results, []) | 2155 self.assertEqual(results, []) |
2161 self.checkstdout( | 2156 self.checkstdout( |
2162 'Running %s\n' % presubmit.os.path.join('random_directory', 'b')) | 2157 'Running %s\n' % presubmit.os.path.join('random_directory', 'b')) |
2163 | 2158 |
2164 | 2159 |
2165 if __name__ == '__main__': | 2160 if __name__ == '__main__': |
2166 import unittest | 2161 import unittest |
2167 unittest.main() | 2162 unittest.main() |
OLD | NEW |