OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2006-2009 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 import exceptions | 8 import exceptions |
| 9 import random |
| 10 import string |
9 import StringIO | 11 import StringIO |
10 import unittest | 12 import unittest |
11 | 13 |
12 # Local imports | 14 # Local imports |
13 import __init__ | 15 import __init__ |
14 import presubmit_support as presubmit | 16 import presubmit_support as presubmit |
15 import presubmit_canned_checks | 17 import presubmit_canned_checks |
16 mox = __init__.mox | 18 mox = __init__.mox |
17 | 19 |
| 20 def String(max_length): |
| 21 return ''.join([random.choice(string.letters) |
| 22 for x in xrange(random.randint(1, max_length))]) |
| 23 |
| 24 def Strings(max_arg_count, max_arg_length): |
| 25 return [String(max_arg_length) for x in xrange(max_arg_count)] |
| 26 |
| 27 def Args(max_arg_count=8, max_arg_length=16): |
| 28 return Strings(max_arg_count, random.randint(1, max_arg_length)) |
| 29 |
| 30 def _DirElts(max_elt_count=4, max_elt_length=8): |
| 31 return presubmit.os.sep.join(Strings(max_elt_count, max_elt_length)) |
| 32 |
| 33 def Dir(max_elt_count=4, max_elt_length=8): |
| 34 return (random.choice((presubmit_support.os.sep, '')) + |
| 35 _DirElts(max_elt_count, max_elt_length)) |
| 36 |
| 37 def Url(max_elt_count=4, max_elt_length=8): |
| 38 return ('svn://random_host:port/a' + |
| 39 _DirElts(max_elt_count, max_elt_length).replace(os.sep, '/')) |
| 40 |
| 41 def RootDir(max_elt_count=4, max_elt_length=8): |
| 42 return presubmit.os.sep + _DirElts(max_elt_count, max_elt_length) |
| 43 |
18 | 44 |
19 class PresubmitTestsBase(mox.MoxTestBase): | 45 class PresubmitTestsBase(mox.MoxTestBase): |
20 """Setups and tear downs the mocks but doesn't test anything as-is.""" | 46 """Setups and tear downs the mocks but doesn't test anything as-is.""" |
21 presubmit_text = """ | 47 presubmit_text = """ |
22 def CheckChangeOnUpload(input_api, output_api): | 48 def CheckChangeOnUpload(input_api, output_api): |
23 if not input_api.change.NOSUCHKEY: | 49 if not input_api.change.NOSUCHKEY: |
24 return [output_api.PresubmitError("!!")] | 50 return [output_api.PresubmitError("!!")] |
25 elif not input_api.change.REALLYNOSUCHKEY: | 51 elif not input_api.change.REALLYNOSUCHKEY: |
26 return [output_api.PresubmitPromptWarning("??")] | 52 return [output_api.PresubmitPromptWarning("??")] |
27 elif not input_api.change.REALLYABSOLUTELYNOSUCHKEY: | 53 elif not input_api.change.REALLYABSOLUTELYNOSUCHKEY: |
28 return [output_api.PresubmitPromptWarning("??"), | 54 return [output_api.PresubmitPromptWarning("??"), |
29 output_api.PresubmitError("XX!!XX")] | 55 output_api.PresubmitError("XX!!XX")] |
30 else: | 56 else: |
31 return () | 57 return () |
32 """ | 58 """ |
33 | 59 |
34 def setUp(self): | 60 def setUp(self): |
35 mox.MoxTestBase.setUp(self) | 61 mox.MoxTestBase.setUp(self) |
36 self.mox.StubOutWithMock(presubmit, 'warnings') | 62 self.mox.StubOutWithMock(presubmit, 'warnings') |
37 # Stub out 'os' but keep os.path.dirname/join/normpath. | 63 # Stub out 'os' but keep os.path.dirname/join/normpath and os.sep. |
38 path_join = presubmit.os.path.join | 64 os_sep = presubmit.os.sep |
39 path_dirname = presubmit.os.path.dirname | 65 os_path_join = presubmit.os.path.join |
40 path_normpath = presubmit.os.path.normpath | 66 os_path_dirname = presubmit.os.path.dirname |
| 67 os_path_normpath = presubmit.os.path.normpath |
41 self.mox.StubOutWithMock(presubmit, 'os') | 68 self.mox.StubOutWithMock(presubmit, 'os') |
42 self.mox.StubOutWithMock(presubmit.os, 'path') | 69 self.mox.StubOutWithMock(presubmit.os, 'path') |
43 presubmit.os.path.join = path_join | 70 presubmit.os.sep = os_sep |
44 presubmit.os.path.dirname = path_dirname | 71 presubmit.os.path.join = os_path_join |
45 presubmit.os.path.normpath = path_normpath | 72 presubmit.os.path.dirname = os_path_dirname |
| 73 presubmit.os.path.normpath = os_path_normpath |
46 self.mox.StubOutWithMock(presubmit, 'sys') | 74 self.mox.StubOutWithMock(presubmit, 'sys') |
47 # Special mocks. | 75 # Special mocks. |
48 def MockAbsPath(f): | 76 def MockAbsPath(f): |
49 return f | 77 return f |
50 presubmit.os.path.abspath = MockAbsPath | 78 presubmit.os.path.abspath = MockAbsPath |
51 self.mox.StubOutWithMock(presubmit.gcl, 'GetRepositoryRoot') | 79 self.mox.StubOutWithMock(presubmit.gcl, 'GetRepositoryRoot') |
| 80 fake_root_dir = RootDir() |
| 81 self.fake_root_dir = fake_root_dir |
52 def MockGetRepositoryRoot(): | 82 def MockGetRepositoryRoot(): |
53 return '' | 83 return fake_root_dir |
54 presubmit.gcl.GetRepositoryRoot = MockGetRepositoryRoot | 84 presubmit.gcl.GetRepositoryRoot = MockGetRepositoryRoot |
55 self.mox.StubOutWithMock(presubmit.gclient, 'CaptureSVNInfo') | 85 self.mox.StubOutWithMock(presubmit.gclient, 'CaptureSVNInfo') |
56 self.mox.StubOutWithMock(presubmit.gcl, 'GetSVNFileProperty') | 86 self.mox.StubOutWithMock(presubmit.gcl, 'GetSVNFileProperty') |
57 self.mox.StubOutWithMock(presubmit.gcl, 'ReadFile') | 87 self.mox.StubOutWithMock(presubmit.gcl, 'ReadFile') |
58 | 88 |
59 @staticmethod | 89 @staticmethod |
60 def MakeBasicChange(name, description): | 90 def MakeBasicChange(name, description): |
61 ci = presubmit.gcl.ChangeInfo(name=name, description=description) | 91 ci = presubmit.gcl.ChangeInfo(name=name, description=description) |
62 change = presubmit.GclChange(ci) | 92 change = presubmit.GclChange(ci) |
63 return change | 93 return change |
64 | 94 |
65 def compareMembers(self, object, members): | 95 def compareMembers(self, object, members): |
66 """If you add a member, be sure to add the relevant test!""" | 96 """If you add a member, be sure to add the relevant test!""" |
67 # Skip over members starting with '_' since they are usually not meant to | 97 # Skip over members starting with '_' since they are usually not meant to |
68 # be for public use. | 98 # be for public use. |
69 actual_members = [x for x in sorted(dir(object)) | 99 actual_members = [x for x in sorted(dir(object)) |
70 if not x.startswith('_')] | 100 if not x.startswith('_')] |
71 self.assertEqual(actual_members, sorted(members)) | 101 self.assertEqual(actual_members, sorted(members)) |
72 | 102 |
73 | 103 |
74 class PresubmitUnittest(PresubmitTestsBase): | 104 class PresubmitUnittest(PresubmitTestsBase): |
75 """General presubmit_support.py tests (excluding InputApi and OutputApi).""" | 105 """General presubmit_support.py tests (excluding InputApi and OutputApi).""" |
76 def testMembersChanged(self): | 106 def testMembersChanged(self): |
| 107 self.mox.ReplayAll() |
77 members = [ | 108 members = [ |
78 'AffectedFile', 'DoPresubmitChecks', 'GclChange', 'InputApi', | 109 'AffectedFile', 'DoPresubmitChecks', 'GclChange', 'InputApi', |
79 'ListRelevantPresubmitFiles', 'Main', 'NotImplementedException', | 110 'ListRelevantPresubmitFiles', 'Main', 'NotImplementedException', |
80 'OutputApi', 'ParseFiles', 'PresubmitExecuter', | 111 'OutputApi', 'ParseFiles', 'PresubmitExecuter', |
81 'ScanSubDirs', 'SvnAffectedFile', | 112 'ScanSubDirs', 'SvnAffectedFile', |
82 'cPickle', 'cStringIO', 'deprecated', 'exceptions', | 113 'cPickle', 'cStringIO', 'deprecated', 'exceptions', |
83 'fnmatch', 'gcl', 'gclient', 'glob', 'marshal', 'normpath', 'optparse', | 114 'fnmatch', 'gcl', 'gclient', 'glob', 'marshal', 'normpath', 'optparse', |
84 'os', 'pickle', 'presubmit_canned_checks', 're', 'subprocess', 'sys', | 115 'os', 'pickle', 'presubmit_canned_checks', 're', 'subprocess', 'sys', |
85 'tempfile', 'types', 'urllib2', 'warnings', | 116 'tempfile', 'types', 'urllib2', 'warnings', |
86 ] | 117 ] |
87 # If this test fails, you should add the relevant test. | 118 # If this test fails, you should add the relevant test. |
88 self.compareMembers(presubmit, members) | 119 self.compareMembers(presubmit, members) |
89 | 120 |
90 def testListRelevantPresubmitFiles(self): | 121 def testListRelevantPresubmitFiles(self): |
91 presubmit.os.path.isfile('PRESUBMIT.py').AndReturn(True) | 122 join = presubmit.os.path.join |
92 presubmit.os.path.isfile( | 123 files = [ |
93 presubmit.os.path.join('foo/haspresubmit/yodle', | 124 'blat.cc', |
94 'PRESUBMIT.py')).AndReturn(False) | 125 join('foo', 'haspresubmit', 'yodle', 'smart.h'), |
95 presubmit.os.path.isfile( | 126 join('moo', 'mat', 'gat', 'yo.h'), |
96 presubmit.os.path.join('foo/haspresubmit', | 127 join('foo', 'luck.h'), |
97 'PRESUBMIT.py')).AndReturn(True) | 128 ] |
98 presubmit.os.path.isfile( | 129 presubmit.os.path.isfile(join(self.fake_root_dir, |
99 presubmit.os.path.join('foo', 'PRESUBMIT.py')).AndReturn(False) | 130 'PRESUBMIT.py')).AndReturn(True) |
100 presubmit.os.path.isfile( | 131 presubmit.os.path.isfile(join(self.fake_root_dir, 'foo', |
101 presubmit.os.path.join('moo/mat/gat', | 132 'PRESUBMIT.py')).AndReturn(False) |
102 'PRESUBMIT.py')).AndReturn(False) | 133 presubmit.os.path.isfile(join(self.fake_root_dir, 'foo', 'haspresubmit', |
103 presubmit.os.path.isfile( | 134 'PRESUBMIT.py')).AndReturn(True) |
104 presubmit.os.path.join('moo/mat', | 135 presubmit.os.path.isfile(join(self.fake_root_dir, 'foo', 'haspresubmit', |
105 'PRESUBMIT.py')).AndReturn(False) | 136 'yodle', 'PRESUBMIT.py')).AndReturn(True) |
106 presubmit.os.path.isfile( | 137 presubmit.os.path.isfile(join(self.fake_root_dir, 'moo', |
107 presubmit.os.path.join('moo', 'PRESUBMIT.py')).AndReturn(False) | 138 'PRESUBMIT.py')).AndReturn(False) |
| 139 presubmit.os.path.isfile(join(self.fake_root_dir, 'moo', 'mat', |
| 140 'PRESUBMIT.py')).AndReturn(False) |
| 141 presubmit.os.path.isfile(join(self.fake_root_dir, 'moo', 'mat', 'gat', |
| 142 'PRESUBMIT.py')).AndReturn(False) |
| 143 #isfile(join('moo', 'PRESUBMIT.py')).AndReturn(False) |
108 self.mox.ReplayAll() | 144 self.mox.ReplayAll() |
109 presubmit_files = presubmit.ListRelevantPresubmitFiles([ | 145 |
110 'blat.cc', | 146 presubmit_files = presubmit.ListRelevantPresubmitFiles(files, |
111 'foo/haspresubmit/yodle/smart.h', | 147 self.fake_root_dir) |
112 'moo/mat/gat/yo.h', | 148 self.assertEqual(presubmit_files, |
113 'foo/luck.h']) | 149 [ |
114 self.assertEqual(len(presubmit_files), 2) | 150 join(self.fake_root_dir, 'PRESUBMIT.py'), |
115 self.failUnless(presubmit.normpath('PRESUBMIT.py') in presubmit_files) | 151 join(self.fake_root_dir, 'foo', 'haspresubmit', 'PRESUBMIT.py'), |
116 self.failUnless(presubmit.normpath('foo/haspresubmit/PRESUBMIT.py') in | 152 join(self.fake_root_dir, 'foo', 'haspresubmit', 'yodle', |
117 presubmit_files) | 153 'PRESUBMIT.py') |
| 154 ]) |
118 | 155 |
119 def testTagLineRe(self): | 156 def testTagLineRe(self): |
| 157 self.mox.ReplayAll() |
120 m = presubmit.GclChange._tag_line_re.match(' BUG =1223, 1445 \t') | 158 m = presubmit.GclChange._tag_line_re.match(' BUG =1223, 1445 \t') |
121 self.failUnless(m) | 159 self.failUnless(m) |
122 self.failUnlessEqual(m.group('key'), 'BUG') | 160 self.failUnlessEqual(m.group('key'), 'BUG') |
123 self.failUnlessEqual(m.group('value'), '1223, 1445') | 161 self.failUnlessEqual(m.group('value'), '1223, 1445') |
124 | 162 |
125 def testGclChange(self): | 163 def testGclChange(self): |
126 description_lines = ('Hello there', | 164 description_lines = ('Hello there', |
127 'this is a change', | 165 'this is a change', |
128 'BUG=123', | 166 'BUG=123', |
129 ' STORY =http://foo/ \t', | 167 ' STORY =http://foo/ \t', |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 self.assertEquals(rhs_lines[3][1], 2) | 261 self.assertEquals(rhs_lines[3][1], 2) |
224 self.assertEquals(rhs_lines[3][2], 'there?') | 262 self.assertEquals(rhs_lines[3][2], 'there?') |
225 | 263 |
226 def testExecPresubmitScript(self): | 264 def testExecPresubmitScript(self): |
227 description_lines = ('Hello there', | 265 description_lines = ('Hello there', |
228 'this is a change', | 266 'this is a change', |
229 'STORY=http://tracker/123') | 267 'STORY=http://tracker/123') |
230 files = [ | 268 files = [ |
231 ['A', 'foo\\blat.cc'], | 269 ['A', 'foo\\blat.cc'], |
232 ] | 270 ] |
| 271 fake_presubmit = presubmit.os.path.join(self.fake_root_dir, 'PRESUBMIT.py') |
233 self.mox.ReplayAll() | 272 self.mox.ReplayAll() |
234 | 273 |
235 ci = presubmit.gcl.ChangeInfo(name='mychange', | 274 ci = presubmit.gcl.ChangeInfo(name='mychange', |
236 description='\n'.join(description_lines), | 275 description='\n'.join(description_lines), |
237 files=files) | 276 files=files) |
238 | 277 |
239 executer = presubmit.PresubmitExecuter(ci, False) | 278 executer = presubmit.PresubmitExecuter(ci, False) |
240 self.failIf(executer.ExecPresubmitScript('', 'PRESUBMIT.py')) | 279 self.failIf(executer.ExecPresubmitScript('', fake_presubmit)) |
241 # No error if no on-upload entry point | 280 # No error if no on-upload entry point |
242 self.failIf(executer.ExecPresubmitScript( | 281 self.failIf(executer.ExecPresubmitScript( |
243 ('def CheckChangeOnCommit(input_api, output_api):\n' | 282 ('def CheckChangeOnCommit(input_api, output_api):\n' |
244 ' return (output_api.PresubmitError("!!"))\n'), | 283 ' return (output_api.PresubmitError("!!"))\n'), |
245 'PRESUBMIT.py' | 284 fake_presubmit |
246 )) | 285 )) |
247 | 286 |
248 executer = presubmit.PresubmitExecuter(ci, True) | 287 executer = presubmit.PresubmitExecuter(ci, True) |
249 # No error if no on-commit entry point | 288 # No error if no on-commit entry point |
250 self.failIf(executer.ExecPresubmitScript( | 289 self.failIf(executer.ExecPresubmitScript( |
251 ('def CheckChangeOnUpload(input_api, output_api):\n' | 290 ('def CheckChangeOnUpload(input_api, output_api):\n' |
252 ' return (output_api.PresubmitError("!!"))\n'), | 291 ' return (output_api.PresubmitError("!!"))\n'), |
253 'PRESUBMIT.py' | 292 fake_presubmit |
254 )) | 293 )) |
255 | 294 |
256 self.failIf(executer.ExecPresubmitScript( | 295 self.failIf(executer.ExecPresubmitScript( |
257 ('def CheckChangeOnUpload(input_api, output_api):\n' | 296 ('def CheckChangeOnUpload(input_api, output_api):\n' |
258 ' if not input_api.change.STORY:\n' | 297 ' if not input_api.change.STORY:\n' |
259 ' return (output_api.PresubmitError("!!"))\n' | 298 ' return (output_api.PresubmitError("!!"))\n' |
260 ' else:\n' | 299 ' else:\n' |
261 ' return ()'), | 300 ' return ()'), |
262 'PRESUBMIT.py' | 301 fake_presubmit |
263 )) | 302 )) |
264 | 303 |
265 self.failUnless(executer.ExecPresubmitScript( | 304 self.failUnless(executer.ExecPresubmitScript( |
266 ('def CheckChangeOnCommit(input_api, output_api):\n' | 305 ('def CheckChangeOnCommit(input_api, output_api):\n' |
267 ' if not input_api.change.NOSUCHKEY:\n' | 306 ' if not input_api.change.NOSUCHKEY:\n' |
268 ' return [output_api.PresubmitError("!!")]\n' | 307 ' return [output_api.PresubmitError("!!")]\n' |
269 ' else:\n' | 308 ' else:\n' |
270 ' return ()'), | 309 ' return ()'), |
271 'PRESUBMIT.py' | 310 fake_presubmit |
272 )) | 311 )) |
273 | 312 |
274 self.assertRaises(exceptions.RuntimeError, | 313 self.assertRaises(exceptions.RuntimeError, |
275 executer.ExecPresubmitScript, | 314 executer.ExecPresubmitScript, |
276 'def CheckChangeOnCommit(input_api, output_api):\n' | 315 'def CheckChangeOnCommit(input_api, output_api):\n' |
277 ' return "foo"', | 316 ' return "foo"', |
278 'PRESUBMIT.py') | 317 fake_presubmit) |
279 | 318 |
280 self.assertRaises(exceptions.RuntimeError, | 319 self.assertRaises(exceptions.RuntimeError, |
281 executer.ExecPresubmitScript, | 320 executer.ExecPresubmitScript, |
282 'def CheckChangeOnCommit(input_api, output_api):\n' | 321 'def CheckChangeOnCommit(input_api, output_api):\n' |
283 ' return ["foo"]', | 322 ' return ["foo"]', |
284 'PRESUBMIT.py') | 323 fake_presubmit) |
285 | 324 |
286 def testDoPresubmitChecks(self): | 325 def testDoPresubmitChecks(self): |
| 326 join = presubmit.os.path.join |
287 description_lines = ('Hello there', | 327 description_lines = ('Hello there', |
288 'this is a change', | 328 'this is a change', |
289 'STORY=http://tracker/123') | 329 'STORY=http://tracker/123') |
290 files = [ | 330 files = [ |
291 ['A', 'haspresubmit\\blat.cc'], | 331 ['A', join('haspresubmit', 'blat.cc')], |
292 ] | 332 ] |
293 path = presubmit.os.path.join('haspresubmit', 'PRESUBMIT.py') | 333 haspresubmit_path = join(self.fake_root_dir, 'haspresubmit', 'PRESUBMIT.py') |
294 presubmit.os.path.isfile(path).AndReturn(True) | 334 root_path = join(self.fake_root_dir, 'PRESUBMIT.py') |
295 presubmit.os.path.isfile('PRESUBMIT.py').AndReturn(True) | 335 presubmit.os.path.isfile(root_path).AndReturn(True) |
296 presubmit.gcl.ReadFile(path, 'rU').AndReturn(self.presubmit_text) | 336 presubmit.os.path.isfile(haspresubmit_path).AndReturn(True) |
297 presubmit.gcl.ReadFile('PRESUBMIT.py', 'rU').AndReturn(self.presubmit_text) | 337 presubmit.gcl.ReadFile(root_path, |
| 338 'rU').AndReturn(self.presubmit_text) |
| 339 presubmit.gcl.ReadFile(haspresubmit_path, |
| 340 'rU').AndReturn(self.presubmit_text) |
298 self.mox.ReplayAll() | 341 self.mox.ReplayAll() |
299 | 342 |
300 ci = presubmit.gcl.ChangeInfo(name='mychange', | 343 ci = presubmit.gcl.ChangeInfo(name='mychange', |
301 description='\n'.join(description_lines), | 344 description='\n'.join(description_lines), |
302 files=files) | 345 files=files) |
303 | 346 |
304 output = StringIO.StringIO() | 347 output = StringIO.StringIO() |
305 input = StringIO.StringIO('y\n') | 348 input = StringIO.StringIO('y\n') |
306 | 349 |
307 self.failIf(presubmit.DoPresubmitChecks(ci, False, True, output, input, | 350 self.failIf(presubmit.DoPresubmitChecks(ci, False, True, output, input, |
308 None)) | 351 None)) |
309 self.assertEqual(output.getvalue().count('!!'), 2) | 352 self.assertEqual(output.getvalue().count('!!'), 2) |
310 | 353 |
311 def testDoPresubmitChecksPromptsAfterWarnings(self): | 354 def testDoPresubmitChecksPromptsAfterWarnings(self): |
| 355 join = presubmit.os.path.join |
312 description_lines = ('Hello there', | 356 description_lines = ('Hello there', |
313 'this is a change', | 357 'this is a change', |
314 'NOSUCHKEY=http://tracker/123') | 358 'NOSUCHKEY=http://tracker/123') |
315 files = [ | 359 files = [ |
316 ['A', 'haspresubmit\\blat.cc'], | 360 ['A', join('haspresubmit', 'blat.cc')], |
317 ] | 361 ] |
318 path = presubmit.os.path.join('haspresubmit', 'PRESUBMIT.py') | 362 presubmit_path = join(self.fake_root_dir, 'PRESUBMIT.py') |
319 presubmit.os.path.isfile(path).AndReturn(True) | 363 haspresubmit_path = join(self.fake_root_dir, 'haspresubmit', 'PRESUBMIT.py') |
320 presubmit.os.path.isfile('PRESUBMIT.py').AndReturn(True) | 364 for i in range(2): |
321 presubmit.gcl.ReadFile(path, 'rU').AndReturn(self.presubmit_text) | 365 presubmit.os.path.isfile(presubmit_path).AndReturn(True) |
322 presubmit.gcl.ReadFile('PRESUBMIT.py', 'rU').AndReturn(self.presubmit_text) | 366 presubmit.os.path.isfile(haspresubmit_path).AndReturn(True) |
323 presubmit.os.path.isfile(path).AndReturn(True) | 367 presubmit.gcl.ReadFile(presubmit_path, 'rU' |
324 presubmit.os.path.isfile('PRESUBMIT.py').AndReturn(True) | 368 ).AndReturn(self.presubmit_text) |
325 presubmit.gcl.ReadFile(path, 'rU').AndReturn(self.presubmit_text) | 369 presubmit.gcl.ReadFile(haspresubmit_path, 'rU' |
326 presubmit.gcl.ReadFile('PRESUBMIT.py', 'rU').AndReturn(self.presubmit_text) | 370 ).AndReturn(self.presubmit_text) |
327 self.mox.ReplayAll() | 371 self.mox.ReplayAll() |
328 | 372 |
329 ci = presubmit.gcl.ChangeInfo(name='mychange', | 373 ci = presubmit.gcl.ChangeInfo(name='mychange', |
330 description='\n'.join(description_lines), | 374 description='\n'.join(description_lines), |
331 files=files) | 375 files=files) |
332 | 376 |
333 output = StringIO.StringIO() | 377 output = StringIO.StringIO() |
334 input = StringIO.StringIO('n\n') # say no to the warning | 378 input = StringIO.StringIO('n\n') # say no to the warning |
335 self.failIf(presubmit.DoPresubmitChecks(ci, False, True, output, input, | 379 self.failIf(presubmit.DoPresubmitChecks(ci, False, True, output, input, |
336 None)) | 380 None)) |
337 self.assertEqual(output.getvalue().count('??'), 2) | 381 self.assertEqual(output.getvalue().count('??'), 2) |
338 | 382 |
339 output = StringIO.StringIO() | 383 output = StringIO.StringIO() |
340 input = StringIO.StringIO('y\n') # say yes to the warning | 384 input = StringIO.StringIO('y\n') # say yes to the warning |
341 self.failUnless(presubmit.DoPresubmitChecks(ci, | 385 self.failUnless(presubmit.DoPresubmitChecks(ci, |
342 False, | 386 False, |
343 True, | 387 True, |
344 output, | 388 output, |
345 input, | 389 input, |
346 None)) | 390 None)) |
347 self.assertEquals(output.getvalue().count('??'), 2) | 391 self.assertEquals(output.getvalue().count('??'), 2) |
348 | 392 |
349 def testDoPresubmitChecksNoWarningPromptIfErrors(self): | 393 def testDoPresubmitChecksNoWarningPromptIfErrors(self): |
| 394 join = presubmit.os.path.join |
350 description_lines = ('Hello there', | 395 description_lines = ('Hello there', |
351 'this is a change', | 396 'this is a change', |
352 'NOSUCHKEY=http://tracker/123', | 397 'NOSUCHKEY=http://tracker/123', |
353 'REALLYNOSUCHKEY=http://tracker/123') | 398 'REALLYNOSUCHKEY=http://tracker/123') |
354 files = [ | 399 files = [ |
355 ['A', 'haspresubmit\\blat.cc'], | 400 ['A', join('haspresubmit', 'blat.cc')], |
356 ] | 401 ] |
357 path = presubmit.os.path.join('haspresubmit', 'PRESUBMIT.py') | 402 presubmit_path = join(self.fake_root_dir, 'PRESUBMIT.py') |
358 presubmit.os.path.isfile(path).AndReturn(True) | 403 haspresubmit_path = join(self.fake_root_dir, 'haspresubmit', |
359 presubmit.os.path.isfile('PRESUBMIT.py').AndReturn(True) | 404 'PRESUBMIT.py') |
360 presubmit.gcl.ReadFile(path, 'rU').AndReturn(self.presubmit_text) | 405 presubmit.os.path.isfile(presubmit_path).AndReturn(True) |
361 presubmit.gcl.ReadFile('PRESUBMIT.py', 'rU').AndReturn(self.presubmit_text) | 406 presubmit.os.path.isfile(haspresubmit_path).AndReturn(True) |
| 407 presubmit.gcl.ReadFile(presubmit_path, 'rU').AndReturn(self.presubmit_text) |
| 408 presubmit.gcl.ReadFile(haspresubmit_path, 'rU' |
| 409 ).AndReturn(self.presubmit_text) |
362 self.mox.ReplayAll() | 410 self.mox.ReplayAll() |
363 | 411 |
364 ci = presubmit.gcl.ChangeInfo(name='mychange', | 412 ci = presubmit.gcl.ChangeInfo(name='mychange', |
365 description='\n'.join(description_lines), | 413 description='\n'.join(description_lines), |
366 files=files) | 414 files=files) |
367 | |
368 output = StringIO.StringIO() | 415 output = StringIO.StringIO() |
369 input = StringIO.StringIO() # should be unused | 416 input = StringIO.StringIO() # should be unused |
370 | |
371 self.failIf(presubmit.DoPresubmitChecks(ci, False, True, output, input, | 417 self.failIf(presubmit.DoPresubmitChecks(ci, False, True, output, input, |
372 None)) | 418 None)) |
373 self.assertEqual(output.getvalue().count('??'), 2) | 419 self.assertEqual(output.getvalue().count('??'), 2) |
374 self.assertEqual(output.getvalue().count('XX!!XX'), 2) | 420 self.assertEqual(output.getvalue().count('XX!!XX'), 2) |
375 self.assertEqual(output.getvalue().count('(y/N)'), 0) | 421 self.assertEqual(output.getvalue().count('(y/N)'), 0) |
376 | 422 |
377 def testDoDefaultPresubmitChecks(self): | 423 def testDoDefaultPresubmitChecks(self): |
| 424 join = presubmit.os.path.join |
378 description_lines = ('Hello there', | 425 description_lines = ('Hello there', |
379 'this is a change', | 426 'this is a change', |
380 'STORY=http://tracker/123') | 427 'STORY=http://tracker/123') |
381 files = [ | 428 files = [ |
382 ['A', 'haspresubmit\\blat.cc'], | 429 ['A', join('haspresubmit', 'blat.cc')], |
383 ] | 430 ] |
384 DEFAULT_SCRIPT = """ | 431 DEFAULT_SCRIPT = """ |
385 def CheckChangeOnUpload(input_api, output_api): | 432 def CheckChangeOnUpload(input_api, output_api): |
386 return [output_api.PresubmitError("!!")] | 433 return [output_api.PresubmitError("!!")] |
387 def CheckChangeOnCommit(input_api, output_api): | 434 def CheckChangeOnCommit(input_api, output_api): |
388 raise Exception("Test error") | 435 raise Exception("Test error") |
389 """ | 436 """ |
390 path = presubmit.os.path.join('haspresubmit', 'PRESUBMIT.py') | 437 presubmit.os.path.isfile(join(self.fake_root_dir, 'PRESUBMIT.py') |
391 presubmit.os.path.isfile(path).AndReturn(False) | 438 ).AndReturn(False) |
392 presubmit.os.path.isfile('PRESUBMIT.py').AndReturn(False) | 439 presubmit.os.path.isfile(join(self.fake_root_dir, |
| 440 'haspresubmit', |
| 441 'PRESUBMIT.py')).AndReturn(False) |
393 self.mox.ReplayAll() | 442 self.mox.ReplayAll() |
394 | 443 |
395 ci = presubmit.gcl.ChangeInfo(name='mychange', | 444 ci = presubmit.gcl.ChangeInfo(name='mychange', |
396 description='\n'.join(description_lines), | 445 description='\n'.join(description_lines), |
397 files=files) | 446 files=files) |
398 | 447 |
399 | 448 |
400 output = StringIO.StringIO() | 449 output = StringIO.StringIO() |
401 input = StringIO.StringIO('y\n') | 450 input = StringIO.StringIO('y\n') |
402 # Always fail. | 451 # Always fail. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 input_api.change.DescriptionText())] | 490 input_api.change.DescriptionText())] |
442 if (input_api.change.FullDescriptionText() != | 491 if (input_api.change.FullDescriptionText() != |
443 'Blah Blah\\n\\nSTORY=http://tracker.com/42\\nBUG=boo\\n'): | 492 'Blah Blah\\n\\nSTORY=http://tracker.com/42\\nBUG=boo\\n'): |
444 return [output_api.PresubmitError('Tag parsing failed. 5 ' + | 493 return [output_api.PresubmitError('Tag parsing failed. 5 ' + |
445 input_api.change.FullDescriptionText())] | 494 input_api.change.FullDescriptionText())] |
446 return [output_api.PresubmitNotifyResult(input_api.change.tags['STORY'])] | 495 return [output_api.PresubmitNotifyResult(input_api.change.tags['STORY'])] |
447 def CheckChangeOnCommit(input_api, output_api): | 496 def CheckChangeOnCommit(input_api, output_api): |
448 raise Exception("Test error") | 497 raise Exception("Test error") |
449 """ | 498 """ |
450 self.mox.ReplayAll() | 499 self.mox.ReplayAll() |
| 500 |
451 change = presubmit.gcl.ChangeInfo( | 501 change = presubmit.gcl.ChangeInfo( |
452 name='foo', | 502 name='foo', |
453 description="Blah Blah\n\nSTORY=http://tracker.com/42\nBUG=boo\n") | 503 description="Blah Blah\n\nSTORY=http://tracker.com/42\nBUG=boo\n") |
454 output = StringIO.StringIO() | 504 output = StringIO.StringIO() |
455 input = StringIO.StringIO('y\n') | 505 input = StringIO.StringIO('y\n') |
456 self.failUnless(presubmit.DoPresubmitChecks(change, False, True, output, | 506 self.failUnless(presubmit.DoPresubmitChecks(change, False, True, output, |
457 input, DEFAULT_SCRIPT)) | 507 input, DEFAULT_SCRIPT)) |
458 self.assertEquals(output.getvalue(), | 508 self.assertEquals(output.getvalue(), |
459 ('Warning, no presubmit.py found.\n' | 509 ('Warning, no presubmit.py found.\n' |
460 'Running default presubmit script.\n\n' | 510 'Running default presubmit script.\n\n' |
461 '** Presubmit Messages **\n\n' | 511 '** Presubmit Messages **\n\n' |
462 'http://tracker.com/42\n\n')) | 512 'http://tracker.com/42\n\n')) |
463 | 513 |
464 | 514 |
465 class InputApiUnittest(PresubmitTestsBase): | 515 class InputApiUnittest(PresubmitTestsBase): |
466 """Tests presubmit.InputApi.""" | 516 """Tests presubmit.InputApi.""" |
467 def testMembersChanged(self): | 517 def testMembersChanged(self): |
| 518 self.mox.ReplayAll() |
468 members = [ | 519 members = [ |
469 'AbsoluteLocalPaths', 'AffectedFiles', 'AffectedTextFiles', | 520 'AbsoluteLocalPaths', 'AffectedFiles', 'AffectedTextFiles', |
470 'DepotToLocalPath', 'LocalPaths', 'LocalToDepotPath', | 521 'DepotToLocalPath', 'LocalPaths', 'LocalToDepotPath', |
471 'PresubmitLocalPath', 'RightHandSideLines', 'ServerPaths', | 522 'PresubmitLocalPath', 'RightHandSideLines', 'ServerPaths', |
472 'basename', 'cPickle', 'cStringIO', 'canned_checks', 'change', | 523 'basename', 'cPickle', 'cStringIO', 'canned_checks', 'change', |
473 'marshal', 'os_path', 'pickle', 'platform', | 524 'marshal', 'os_path', 'pickle', 'platform', |
474 're', 'subprocess', 'tempfile', 'urllib2', 'version', | 525 're', 'subprocess', 'tempfile', 'urllib2', 'version', |
475 ] | 526 ] |
476 # If this test fails, you should add the relevant test. | 527 # If this test fails, you should add the relevant test. |
477 self.compareMembers(presubmit.InputApi(None, './.'), members) | 528 self.compareMembers(presubmit.InputApi(None, './.'), members) |
478 | 529 |
479 def testDepotToLocalPath(self): | 530 def testDepotToLocalPath(self): |
480 presubmit.gclient.CaptureSVNInfo('svn://foo/smurf').AndReturn( | 531 presubmit.gclient.CaptureSVNInfo('svn://foo/smurf').AndReturn( |
481 {'Path': 'prout'}) | 532 {'Path': 'prout'}) |
482 presubmit.gclient.CaptureSVNInfo('svn:/foo/notfound/burp').AndReturn({}) | 533 presubmit.gclient.CaptureSVNInfo('svn:/foo/notfound/burp').AndReturn({}) |
483 self.mox.ReplayAll() | 534 self.mox.ReplayAll() |
| 535 |
484 path = presubmit.InputApi(None, './p').DepotToLocalPath('svn://foo/smurf') | 536 path = presubmit.InputApi(None, './p').DepotToLocalPath('svn://foo/smurf') |
485 self.failUnless(path == 'prout') | 537 self.failUnless(path == 'prout') |
486 path = presubmit.InputApi(None, './p').DepotToLocalPath( | 538 path = presubmit.InputApi(None, './p').DepotToLocalPath( |
487 'svn:/foo/notfound/burp') | 539 'svn:/foo/notfound/burp') |
488 self.failUnless(path == None) | 540 self.failUnless(path == None) |
489 | 541 |
490 def testLocalToDepotPath(self): | 542 def testLocalToDepotPath(self): |
491 presubmit.gclient.CaptureSVNInfo('smurf').AndReturn({'URL': 'svn://foo'}) | 543 presubmit.gclient.CaptureSVNInfo('smurf').AndReturn({'URL': 'svn://foo'}) |
492 presubmit.gclient.CaptureSVNInfo('notfound-food').AndReturn({}) | 544 presubmit.gclient.CaptureSVNInfo('notfound-food').AndReturn({}) |
493 self.mox.ReplayAll() | 545 self.mox.ReplayAll() |
| 546 |
494 path = presubmit.InputApi(None, './p').LocalToDepotPath('smurf') | 547 path = presubmit.InputApi(None, './p').LocalToDepotPath('smurf') |
495 self.assertEqual(path, 'svn://foo') | 548 self.assertEqual(path, 'svn://foo') |
496 path = presubmit.InputApi(None, './p').LocalToDepotPath('notfound-food') | 549 path = presubmit.InputApi(None, './p').LocalToDepotPath('notfound-food') |
497 self.failUnless(path == None) | 550 self.failUnless(path == None) |
498 | 551 |
499 def testInputApiConstruction(self): | 552 def testInputApiConstruction(self): |
| 553 self.mox.ReplayAll() |
500 # Fudge the change object, it's not used during construction anyway | 554 # Fudge the change object, it's not used during construction anyway |
501 api = presubmit.InputApi(change=42, presubmit_path='foo/path/PRESUBMIT.py') | 555 api = presubmit.InputApi(change=42, presubmit_path='foo/path/PRESUBMIT.py') |
502 self.failUnless(api.PresubmitLocalPath() == 'foo/path') | 556 self.assertEquals(api.PresubmitLocalPath(), 'foo/path') |
503 self.failUnless(api.change == 42) | 557 self.assertEquals(api.change, 42) |
504 | 558 |
505 def testInputApiPresubmitScriptFiltering(self): | 559 def testInputApiPresubmitScriptFiltering(self): |
| 560 join = presubmit.os.path.join |
506 description_lines = ('Hello there', | 561 description_lines = ('Hello there', |
507 'this is a change', | 562 'this is a change', |
508 'BUG=123', | 563 'BUG=123', |
509 ' STORY =http://foo/ \t', | 564 ' STORY =http://foo/ \t', |
510 'and some more regular text') | 565 'and some more regular text') |
511 files = [ | 566 files = [ |
512 ['A', presubmit.os.path.join('foo', 'blat.cc')], | 567 ['A', join('foo', 'blat.cc')], |
513 ['M', presubmit.os.path.join('foo', 'blat', 'binary.dll')], | 568 ['M', join('foo', 'blat', 'binary.dll')], |
514 ['D', 'foo/mat/beingdeleted.txt'], | 569 ['D', 'foo/mat/beingdeleted.txt'], |
515 ['M', 'flop/notfound.txt'], | 570 ['M', 'flop/notfound.txt'], |
516 ['A', 'boo/flap.h'], | 571 ['A', 'boo/flap.h'], |
517 ] | 572 ] |
518 | 573 |
519 blat = presubmit.os.path.join('foo', 'blat.cc') | 574 |
520 binary = presubmit.os.path.join('foo', 'blat', 'binary.dll') | 575 blat = join('foo', 'blat.cc') |
521 beingdeleted = presubmit.os.path.join('foo', 'mat', 'beingdeleted.txt') | 576 binary = join('foo', 'blat', 'binary.dll') |
522 notfound = presubmit.os.path.join('flop', 'notfound.txt') | 577 beingdeleted = join('foo', 'mat', 'beingdeleted.txt') |
523 flap = presubmit.os.path.join('boo', 'flap.h') | 578 notfound = join('flop', 'notfound.txt') |
| 579 flap = join('boo', 'flap.h') |
524 presubmit.os.path.exists(blat).AndReturn(True) | 580 presubmit.os.path.exists(blat).AndReturn(True) |
525 presubmit.os.path.isdir(blat).AndReturn(False) | 581 presubmit.os.path.isdir(blat).AndReturn(False) |
526 presubmit.os.path.exists(binary).AndReturn(True) | 582 presubmit.os.path.exists(binary).AndReturn(True) |
527 presubmit.os.path.isdir(binary).AndReturn(False) | 583 presubmit.os.path.isdir(binary).AndReturn(False) |
528 presubmit.os.path.exists(beingdeleted).AndReturn(False) | 584 presubmit.os.path.exists(beingdeleted).AndReturn(False) |
529 presubmit.os.path.exists(notfound).AndReturn(False) | 585 presubmit.os.path.exists(notfound).AndReturn(False) |
530 presubmit.os.path.exists(flap).AndReturn(True) | 586 presubmit.os.path.exists(flap).AndReturn(True) |
531 presubmit.os.path.isdir(flap).AndReturn(False) | 587 presubmit.os.path.isdir(flap).AndReturn(False) |
532 presubmit.gclient.CaptureSVNInfo(beingdeleted).AndReturn({}) | 588 presubmit.gclient.CaptureSVNInfo(beingdeleted).AndReturn({}) |
533 presubmit.gclient.CaptureSVNInfo(notfound).AndReturn({}) | 589 presubmit.gclient.CaptureSVNInfo(notfound).AndReturn({}) |
534 presubmit.gcl.GetSVNFileProperty(blat, 'svn:mime-type').AndReturn(None) | 590 presubmit.gcl.GetSVNFileProperty(blat, 'svn:mime-type').AndReturn(None) |
535 presubmit.gcl.GetSVNFileProperty(binary, 'svn:mime-type').AndReturn( | 591 presubmit.gcl.GetSVNFileProperty(binary, 'svn:mime-type').AndReturn( |
536 'application/octet-stream') | 592 'application/octet-stream') |
537 presubmit.gcl.ReadFile(blat).AndReturn('whatever\ncookie') | 593 presubmit.gcl.ReadFile(blat).AndReturn('whatever\ncookie') |
538 self.mox.ReplayAll() | 594 self.mox.ReplayAll() |
539 | 595 |
540 ci = presubmit.gcl.ChangeInfo(name='mychange', | 596 ci = presubmit.gcl.ChangeInfo(name='mychange', |
541 description='\n'.join(description_lines), | 597 description='\n'.join(description_lines), |
542 files=files) | 598 files=files) |
543 change = presubmit.GclChange(ci) | 599 change = presubmit.GclChange(ci) |
544 | |
545 api = presubmit.InputApi(change, 'foo/PRESUBMIT.py') | 600 api = presubmit.InputApi(change, 'foo/PRESUBMIT.py') |
546 | |
547 affected_files = api.AffectedFiles() | 601 affected_files = api.AffectedFiles() |
548 self.assertEquals(len(affected_files), 3) | 602 self.assertEquals(len(affected_files), 3) |
549 self.assertEquals(affected_files[0].LocalPath(), | 603 self.assertEquals(affected_files[0].LocalPath(), |
550 presubmit.normpath('foo/blat.cc')) | 604 presubmit.normpath('foo/blat.cc')) |
551 self.assertEquals(affected_files[1].LocalPath(), | 605 self.assertEquals(affected_files[1].LocalPath(), |
552 presubmit.normpath('foo/blat/binary.dll')) | 606 presubmit.normpath('foo/blat/binary.dll')) |
553 self.assertEquals(affected_files[2].LocalPath(), | 607 self.assertEquals(affected_files[2].LocalPath(), |
554 presubmit.normpath('foo/mat/beingdeleted.txt')) | 608 presubmit.normpath('foo/mat/beingdeleted.txt')) |
555 | |
556 rhs_lines = [] | 609 rhs_lines = [] |
557 for line in api.RightHandSideLines(): | 610 for line in api.RightHandSideLines(): |
558 rhs_lines.append(line) | 611 rhs_lines.append(line) |
559 self.assertEquals(len(rhs_lines), 2) | 612 self.assertEquals(len(rhs_lines), 2) |
560 self.assertEqual(rhs_lines[0][0].LocalPath(), | 613 self.assertEqual(rhs_lines[0][0].LocalPath(), |
561 presubmit.normpath('foo/blat.cc')) | 614 presubmit.normpath('foo/blat.cc')) |
562 | 615 |
563 def testGetAbsoluteLocalPath(self): | 616 def testGetAbsoluteLocalPath(self): |
| 617 join = presubmit.os.path.join |
| 618 normpath = presubmit.normpath |
564 # Regression test for bug of presubmit stuff that relies on invoking | 619 # Regression test for bug of presubmit stuff that relies on invoking |
565 # SVN (e.g. to get mime type of file) not working unless gcl invoked | 620 # SVN (e.g. to get mime type of file) not working unless gcl invoked |
566 # from the client root (e.g. if you were at 'src' and did 'cd base' before | 621 # from the client root (e.g. if you were at 'src' and did 'cd base' before |
567 # invoking 'gcl upload' it would fail because svn wouldn't find the files | 622 # invoking 'gcl upload' it would fail because svn wouldn't find the files |
568 # the presubmit script was asking about). | 623 # the presubmit script was asking about). |
569 files = [ | 624 files = [ |
570 ['A', 'isdir'], | 625 ['A', 'isdir'], |
571 ['A', presubmit.os.path.join('isdir', 'blat.cc')] | 626 ['A', join('isdir', 'blat.cc')], |
| 627 ['M', join('elsewhere', 'ouf.cc')], |
572 ] | 628 ] |
573 ci = presubmit.gcl.ChangeInfo(name='mychange', | 629 self.mox.ReplayAll() |
574 description='', | 630 |
575 files=files) | 631 ci = presubmit.gcl.ChangeInfo(name='mychange', description='', files=files) |
576 # It doesn't make sense on non-Windows platform. This is somewhat hacky, | 632 # It doesn't make sense on non-Windows platform. This is somewhat hacky, |
577 # but it is needed since we can't just use os.path.join('c:', 'temp'). | 633 # but it is needed since we can't just use os.path.join('c:', 'temp'). |
578 change = presubmit.GclChange(ci, 'c:' + presubmit.os.sep + 'temp') | 634 change = presubmit.GclChange(ci, self.fake_root_dir) |
579 affected_files = change.AffectedFiles(include_dirs=True) | 635 affected_files = change.AffectedFiles(include_dirs=True) |
580 # Local paths should remain the same | 636 # Local paths should remain the same |
581 self.failUnless(affected_files[0].LocalPath() == | 637 self.assertEquals(affected_files[0].LocalPath(), normpath('isdir')) |
582 presubmit.normpath('isdir')) | 638 self.assertEquals(affected_files[1].LocalPath(), normpath('isdir/blat.cc')) |
583 self.failUnless(affected_files[1].LocalPath() == | |
584 presubmit.normpath('isdir/blat.cc')) | |
585 # Absolute paths should be prefixed | 639 # Absolute paths should be prefixed |
586 self.failUnless(affected_files[0].AbsoluteLocalPath() == | 640 self.assertEquals(affected_files[0].AbsoluteLocalPath(), |
587 presubmit.normpath('c:/temp/isdir')) | 641 normpath(join(self.fake_root_dir, 'isdir'))) |
588 self.failUnless(affected_files[1].AbsoluteLocalPath() == | 642 self.assertEquals(affected_files[1].AbsoluteLocalPath(), |
589 presubmit.normpath('c:/temp/isdir/blat.cc')) | 643 normpath(join(self.fake_root_dir, 'isdir/blat.cc'))) |
590 | 644 |
591 # New helper functions need to work | 645 # New helper functions need to work |
592 absolute_paths_from_change = change.AbsoluteLocalPaths(include_dirs=True) | 646 paths_from_change = change.AbsoluteLocalPaths(include_dirs=True) |
593 api = presubmit.InputApi(change=change, | 647 self.assertEqual(len(paths_from_change), 3) |
594 presubmit_path='isdir/PRESUBMIT.py') | 648 presubmit_path = join(self.fake_root_dir, 'isdir', 'PRESUBMIT.py') |
595 absolute_paths_from_api = api.AbsoluteLocalPaths(include_dirs=True) | 649 api = presubmit.InputApi(change=change, presubmit_path=presubmit_path) |
596 for absolute_paths in [absolute_paths_from_change, | 650 paths_from_api = api.AbsoluteLocalPaths(include_dirs=True) |
597 absolute_paths_from_api]: | 651 self.assertEqual(len(paths_from_api), 2) |
598 self.failUnless(absolute_paths[0] == presubmit.normpath('c:/temp/isdir')) | 652 for absolute_paths in [paths_from_change, paths_from_api]: |
599 self.failUnless(absolute_paths[1] == | 653 self.assertEqual(absolute_paths[0], |
600 presubmit.normpath('c:/temp/isdir/blat.cc')) | 654 normpath(join(self.fake_root_dir, 'isdir'))) |
| 655 self.assertEqual(absolute_paths[1], |
| 656 normpath(join(self.fake_root_dir, 'isdir', 'blat.cc'))) |
601 | 657 |
602 def testDeprecated(self): | 658 def testDeprecated(self): |
603 presubmit.warnings.warn(mox.IgnoreArg(), category=mox.IgnoreArg(), | 659 presubmit.warnings.warn(mox.IgnoreArg(), category=mox.IgnoreArg(), |
604 stacklevel=2) | 660 stacklevel=2) |
605 self.mox.ReplayAll() | 661 self.mox.ReplayAll() |
606 change = presubmit.GclChange( | 662 change = presubmit.GclChange( |
607 presubmit.gcl.ChangeInfo(name='mychange', description='Bleh\n')) | 663 presubmit.gcl.ChangeInfo(name='mychange', description='Bleh\n')) |
608 api = presubmit.InputApi(change, 'foo/PRESUBMIT.py') | 664 api = presubmit.InputApi(change, 'foo/PRESUBMIT.py') |
609 api.AffectedTextFiles(include_deletes=False) | 665 api.AffectedTextFiles(include_deletes=False) |
610 | 666 |
611 | 667 |
612 class OuputApiUnittest(PresubmitTestsBase): | 668 class OuputApiUnittest(PresubmitTestsBase): |
613 """Tests presubmit.OutputApi.""" | 669 """Tests presubmit.OutputApi.""" |
614 def testMembersChanged(self): | 670 def testMembersChanged(self): |
| 671 self.mox.ReplayAll() |
615 members = [ | 672 members = [ |
616 'MailTextResult', 'PresubmitError', 'PresubmitNotifyResult', | 673 'MailTextResult', 'PresubmitError', 'PresubmitNotifyResult', |
617 'PresubmitPromptWarning', 'PresubmitResult', | 674 'PresubmitPromptWarning', 'PresubmitResult', |
618 ] | 675 ] |
619 # If this test fails, you should add the relevant test. | 676 # If this test fails, you should add the relevant test. |
620 self.compareMembers(presubmit.OutputApi(), members) | 677 self.compareMembers(presubmit.OutputApi(), members) |
621 | 678 |
622 def testOutputApiBasics(self): | 679 def testOutputApiBasics(self): |
| 680 self.mox.ReplayAll() |
623 self.failUnless(presubmit.OutputApi.PresubmitError('').IsFatal()) | 681 self.failUnless(presubmit.OutputApi.PresubmitError('').IsFatal()) |
624 self.failIf(presubmit.OutputApi.PresubmitError('').ShouldPrompt()) | 682 self.failIf(presubmit.OutputApi.PresubmitError('').ShouldPrompt()) |
625 | 683 |
626 self.failIf(presubmit.OutputApi.PresubmitPromptWarning('').IsFatal()) | 684 self.failIf(presubmit.OutputApi.PresubmitPromptWarning('').IsFatal()) |
627 self.failUnless( | 685 self.failUnless( |
628 presubmit.OutputApi.PresubmitPromptWarning('').ShouldPrompt()) | 686 presubmit.OutputApi.PresubmitPromptWarning('').ShouldPrompt()) |
629 | 687 |
630 self.failIf(presubmit.OutputApi.PresubmitNotifyResult('').IsFatal()) | 688 self.failIf(presubmit.OutputApi.PresubmitNotifyResult('').IsFatal()) |
631 self.failIf(presubmit.OutputApi.PresubmitNotifyResult('').ShouldPrompt()) | 689 self.failIf(presubmit.OutputApi.PresubmitNotifyResult('').ShouldPrompt()) |
632 | 690 |
633 # TODO(joi) Test MailTextResult once implemented. | 691 # TODO(joi) Test MailTextResult once implemented. |
634 | 692 |
635 def testOutputApiHandling(self): | 693 def testOutputApiHandling(self): |
| 694 self.mox.ReplayAll() |
636 output = StringIO.StringIO() | 695 output = StringIO.StringIO() |
637 unused_input = StringIO.StringIO() | 696 unused_input = StringIO.StringIO() |
638 error = presubmit.OutputApi.PresubmitError('!!!') | 697 error = presubmit.OutputApi.PresubmitError('!!!') |
639 self.failIf(error._Handle(output, unused_input)) | 698 self.failIf(error._Handle(output, unused_input)) |
640 self.failUnless(output.getvalue().count('!!!')) | 699 self.failUnless(output.getvalue().count('!!!')) |
641 | 700 |
642 output = StringIO.StringIO() | 701 output = StringIO.StringIO() |
643 notify = presubmit.OutputApi.PresubmitNotifyResult('?see?') | 702 notify = presubmit.OutputApi.PresubmitNotifyResult('?see?') |
644 self.failUnless(notify._Handle(output, unused_input)) | 703 self.failUnless(notify._Handle(output, unused_input)) |
645 self.failUnless(output.getvalue().count('?see?')) | 704 self.failUnless(output.getvalue().count('?see?')) |
(...skipping 12 matching lines...) Expand all Loading... |
658 | 717 |
659 output = StringIO.StringIO() | 718 output = StringIO.StringIO() |
660 input = StringIO.StringIO('\n') | 719 input = StringIO.StringIO('\n') |
661 warning = presubmit.OutputApi.PresubmitPromptWarning('???') | 720 warning = presubmit.OutputApi.PresubmitPromptWarning('???') |
662 self.failIf(warning._Handle(output, input)) | 721 self.failIf(warning._Handle(output, input)) |
663 self.failUnless(output.getvalue().count('???')) | 722 self.failUnless(output.getvalue().count('???')) |
664 | 723 |
665 | 724 |
666 class AffectedFileUnittest(PresubmitTestsBase): | 725 class AffectedFileUnittest(PresubmitTestsBase): |
667 def testMembersChanged(self): | 726 def testMembersChanged(self): |
| 727 self.mox.ReplayAll() |
668 members = [ | 728 members = [ |
669 'AbsoluteLocalPath', 'Action', 'IsDirectory', 'IsTextFile', 'LocalPath', | 729 'AbsoluteLocalPath', 'Action', 'IsDirectory', 'IsTextFile', 'LocalPath', |
670 'NewContents', 'OldContents', 'OldFileTempPath', 'Property', 'ServerPath', | 730 'NewContents', 'OldContents', 'OldFileTempPath', 'Property', 'ServerPath', |
671 ] | 731 ] |
672 # If this test fails, you should add the relevant test. | 732 # If this test fails, you should add the relevant test. |
673 self.compareMembers(presubmit.AffectedFile('a', 'b'), members) | 733 self.compareMembers(presubmit.AffectedFile('a', 'b'), members) |
674 self.compareMembers(presubmit.SvnAffectedFile('a', 'b'), members) | 734 self.compareMembers(presubmit.SvnAffectedFile('a', 'b'), members) |
675 | 735 |
676 def testAffectedFile(self): | 736 def testAffectedFile(self): |
677 path = presubmit.os.path.join('foo', 'blat.cc') | 737 path = presubmit.os.path.join('foo', 'blat.cc') |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
756 self.lines = lines | 816 self.lines = lines |
757 self.basename = lambda x: x | 817 self.basename = lambda x: x |
758 self.urllib2 = self.MockUrllib2() | 818 self.urllib2 = self.MockUrllib2() |
759 self.re = presubmit.re | 819 self.re = presubmit.re |
760 | 820 |
761 def RightHandSideLines(self): | 821 def RightHandSideLines(self): |
762 for line in self.lines: | 822 for line in self.lines: |
763 yield (presubmit.AffectedFile('bingo', 'M'), 1, line) | 823 yield (presubmit.AffectedFile('bingo', 'M'), 1, line) |
764 | 824 |
765 def testMembersChanged(self): | 825 def testMembersChanged(self): |
| 826 self.mox.ReplayAll() |
766 members = [ | 827 members = [ |
767 'CheckChangeHasBugField', 'CheckChangeHasNoTabs', | 828 'CheckChangeHasBugField', 'CheckChangeHasNoTabs', |
768 'CheckChangeHasQaField', 'CheckChangeHasTestedField', | 829 'CheckChangeHasQaField', 'CheckChangeHasTestedField', |
769 'CheckChangeHasTestField', 'CheckDoNotSubmit', | 830 'CheckChangeHasTestField', 'CheckDoNotSubmit', |
770 'CheckDoNotSubmitInDescription', 'CheckDoNotSubmitInFiles', | 831 'CheckDoNotSubmitInDescription', 'CheckDoNotSubmitInFiles', |
771 'CheckLongLines', 'CheckTreeIsOpen', 'RunPythonUnitTests', | 832 'CheckLongLines', 'CheckTreeIsOpen', 'RunPythonUnitTests', |
772 ] | 833 ] |
773 # If this test fails, you should add the relevant test. | 834 # If this test fails, you should add the relevant test. |
774 self.compareMembers(presubmit_canned_checks, members) | 835 self.compareMembers(presubmit_canned_checks, members) |
775 | 836 |
776 def testCannedCheckChangeHasBugField(self): | 837 def testCannedCheckChangeHasBugField(self): |
| 838 self.mox.ReplayAll() |
777 change = self.MakeBasicChange('foo', | 839 change = self.MakeBasicChange('foo', |
778 'Foo\nBUG=1234') | 840 'Foo\nBUG=1234') |
779 api = presubmit.InputApi(change, './PRESUBMIT.py') | 841 api = presubmit.InputApi(change, './PRESUBMIT.py') |
780 self.failIf(presubmit_canned_checks.CheckChangeHasBugField( | 842 self.failIf(presubmit_canned_checks.CheckChangeHasBugField( |
781 api, presubmit.OutputApi)) | 843 api, presubmit.OutputApi)) |
782 | 844 |
783 change = self.MakeBasicChange('foo', | 845 change = self.MakeBasicChange('foo', |
784 'Foo\nNEVERTESTED=did some stuff') | 846 'Foo\nNEVERTESTED=did some stuff') |
785 api = presubmit.InputApi(change, './PRESUBMIT.py') | 847 api = presubmit.InputApi(change, './PRESUBMIT.py') |
786 self.failUnless(presubmit_canned_checks.CheckChangeHasBugField( | 848 self.failUnless(presubmit_canned_checks.CheckChangeHasBugField( |
787 api, presubmit.OutputApi)) | 849 api, presubmit.OutputApi)) |
788 | 850 |
789 def testCannedCheckChangeHasTestField(self): | 851 def testCannedCheckChangeHasTestField(self): |
| 852 self.mox.ReplayAll() |
790 change = self.MakeBasicChange('foo', | 853 change = self.MakeBasicChange('foo', |
791 'Foo\nTEST=did some stuff') | 854 'Foo\nTEST=did some stuff') |
792 api = presubmit.InputApi(change, './PRESUBMIT.py') | 855 api = presubmit.InputApi(change, './PRESUBMIT.py') |
793 self.failIf(presubmit_canned_checks.CheckChangeHasTestField( | 856 self.failIf(presubmit_canned_checks.CheckChangeHasTestField( |
794 api, presubmit.OutputApi)) | 857 api, presubmit.OutputApi)) |
795 | 858 |
796 change = self.MakeBasicChange('foo', | 859 change = self.MakeBasicChange('foo', |
797 'Foo\nNOTEST=did some stuff') | 860 'Foo\nNOTEST=did some stuff') |
798 api = presubmit.InputApi(change, './PRESUBMIT.py') | 861 api = presubmit.InputApi(change, './PRESUBMIT.py') |
799 self.failUnless(presubmit_canned_checks.CheckChangeHasTestField( | 862 self.failUnless(presubmit_canned_checks.CheckChangeHasTestField( |
800 api, presubmit.OutputApi)) | 863 api, presubmit.OutputApi)) |
801 | 864 |
802 def testCannedCheckChangeHasTestedField(self): | 865 def testCannedCheckChangeHasTestedField(self): |
| 866 self.mox.ReplayAll() |
803 change = self.MakeBasicChange('foo', | 867 change = self.MakeBasicChange('foo', |
804 'Foo\nTESTED=did some stuff') | 868 'Foo\nTESTED=did some stuff') |
805 api = presubmit.InputApi(change, './PRESUBMIT.py') | 869 api = presubmit.InputApi(change, './PRESUBMIT.py') |
806 self.failIf(presubmit_canned_checks.CheckChangeHasTestedField( | 870 self.failIf(presubmit_canned_checks.CheckChangeHasTestedField( |
807 api, presubmit.OutputApi)) | 871 api, presubmit.OutputApi)) |
808 | 872 |
809 change = self.MakeBasicChange('foo', | 873 change = self.MakeBasicChange('foo', |
810 'Foo\nNEVERTESTED=did some stuff') | 874 'Foo\nNEVERTESTED=did some stuff') |
811 api = presubmit.InputApi(change, './PRESUBMIT.py') | 875 api = presubmit.InputApi(change, './PRESUBMIT.py') |
812 self.failUnless(presubmit_canned_checks.CheckChangeHasTestedField( | 876 self.failUnless(presubmit_canned_checks.CheckChangeHasTestedField( |
813 api, presubmit.OutputApi)) | 877 api, presubmit.OutputApi)) |
814 | 878 |
815 def testCannedCheckChangeHasQAField(self): | 879 def testCannedCheckChangeHasQAField(self): |
| 880 self.mox.ReplayAll() |
816 change = self.MakeBasicChange('foo', | 881 change = self.MakeBasicChange('foo', |
817 'Foo\nQA=test floop feature very well') | 882 'Foo\nQA=test floop feature very well') |
818 api = presubmit.InputApi(change, './PRESUBMIT.py') | 883 api = presubmit.InputApi(change, './PRESUBMIT.py') |
819 self.failIf(presubmit_canned_checks.CheckChangeHasQaField( | 884 self.failIf(presubmit_canned_checks.CheckChangeHasQaField( |
820 api, presubmit.OutputApi)) | 885 api, presubmit.OutputApi)) |
821 | 886 |
822 change = self.MakeBasicChange('foo', | 887 change = self.MakeBasicChange('foo', |
823 'Foo\nNOTFORQA=test floop feature very well') | 888 'Foo\nNOTFORQA=test floop feature very well') |
824 api = presubmit.InputApi(change, './PRESUBMIT.py') | 889 api = presubmit.InputApi(change, './PRESUBMIT.py') |
825 self.failUnless(presubmit_canned_checks.CheckChangeHasQaField( | 890 self.failUnless(presubmit_canned_checks.CheckChangeHasQaField( |
826 api, presubmit.OutputApi)) | 891 api, presubmit.OutputApi)) |
827 | 892 |
828 def testCannedCheckDoNotSubmitInDescription(self): | 893 def testCannedCheckDoNotSubmitInDescription(self): |
| 894 self.mox.ReplayAll() |
829 change = self.MakeBasicChange('foo', 'hello') | 895 change = self.MakeBasicChange('foo', 'hello') |
830 api = presubmit.InputApi(change, './PRESUBMIT.py') | 896 api = presubmit.InputApi(change, './PRESUBMIT.py') |
831 self.failIf(presubmit_canned_checks.CheckDoNotSubmitInDescription( | 897 self.failIf(presubmit_canned_checks.CheckDoNotSubmitInDescription( |
832 api, presubmit.OutputApi)) | 898 api, presubmit.OutputApi)) |
833 | 899 |
834 change = self.MakeBasicChange('foo', | 900 change = self.MakeBasicChange('foo', |
835 'DO NOT ' + 'SUBMIT') | 901 'DO NOT ' + 'SUBMIT') |
836 api = presubmit.InputApi(change, './PRESUBMIT.py') | 902 api = presubmit.InputApi(change, './PRESUBMIT.py') |
837 self.failUnless(presubmit_canned_checks.CheckDoNotSubmitInDescription( | 903 self.failUnless(presubmit_canned_checks.CheckDoNotSubmitInDescription( |
838 api, presubmit.OutputApi)) | 904 api, presubmit.OutputApi)) |
839 | 905 |
840 def testCannedCheckDoNotSubmitInFiles(self): | 906 def testCannedCheckDoNotSubmitInFiles(self): |
| 907 self.mox.ReplayAll() |
841 self.failIf(presubmit_canned_checks.CheckDoNotSubmitInFiles( | 908 self.failIf(presubmit_canned_checks.CheckDoNotSubmitInFiles( |
842 self.MockInputApi(['hello', 'there']), presubmit.OutputApi | 909 self.MockInputApi(['hello', 'there']), presubmit.OutputApi |
843 )) | 910 )) |
844 self.failUnless(presubmit_canned_checks.CheckDoNotSubmitInFiles( | 911 self.failUnless(presubmit_canned_checks.CheckDoNotSubmitInFiles( |
845 self.MockInputApi(['hello', 'yo, DO NOT ' + 'SUBMIT']), | 912 self.MockInputApi(['hello', 'yo, DO NOT ' + 'SUBMIT']), |
846 presubmit.OutputApi)) | 913 presubmit.OutputApi)) |
847 | 914 |
848 def testCannedCheckChangeHasNoTabs(self): | 915 def testCannedCheckChangeHasNoTabs(self): |
| 916 self.mox.ReplayAll() |
849 self.failIf(presubmit_canned_checks.CheckChangeHasNoTabs( | 917 self.failIf(presubmit_canned_checks.CheckChangeHasNoTabs( |
850 self.MockInputApi(['hello', 'there']), presubmit.OutputApi | 918 self.MockInputApi(['hello', 'there']), presubmit.OutputApi |
851 )) | 919 )) |
852 self.failUnless(presubmit_canned_checks.CheckChangeHasNoTabs( | 920 self.failUnless(presubmit_canned_checks.CheckChangeHasNoTabs( |
853 self.MockInputApi(['hello', 'there\tit is']), presubmit.OutputApi | 921 self.MockInputApi(['hello', 'there\tit is']), presubmit.OutputApi |
854 )) | 922 )) |
855 | 923 |
856 def testCannedCheckLongLines(self): | 924 def testCannedCheckLongLines(self): |
| 925 self.mox.ReplayAll() |
857 self.failIf(presubmit_canned_checks.CheckLongLines( | 926 self.failIf(presubmit_canned_checks.CheckLongLines( |
858 self.MockInputApi(['hello', 'there']), presubmit.OutputApi, 5 | 927 self.MockInputApi(['hello', 'there']), presubmit.OutputApi, 5 |
859 )) | 928 )) |
860 self.failUnless(presubmit_canned_checks.CheckLongLines( | 929 self.failUnless(presubmit_canned_checks.CheckLongLines( |
861 self.MockInputApi(['hello', 'there!']), presubmit.OutputApi, 5 | 930 self.MockInputApi(['hello', 'there!']), presubmit.OutputApi, 5 |
862 )) | 931 )) |
863 | 932 |
864 def testCannedCheckTreeIsOpen(self): | 933 def testCannedCheckTreeIsOpen(self): |
| 934 self.mox.ReplayAll() |
865 self.failIf(presubmit_canned_checks.CheckTreeIsOpen( | 935 self.failIf(presubmit_canned_checks.CheckTreeIsOpen( |
866 self.MockInputApi(), presubmit.OutputApi, url='url_to_open', closed='0' | 936 self.MockInputApi(), presubmit.OutputApi, url='url_to_open', closed='0' |
867 )) | 937 )) |
868 self.failUnless(presubmit_canned_checks.CheckTreeIsOpen( | 938 self.failUnless(presubmit_canned_checks.CheckTreeIsOpen( |
869 self.MockInputApi(), presubmit.OutputApi, url='url_to_closed', closed='0' | 939 self.MockInputApi(), presubmit.OutputApi, url='url_to_closed', closed='0' |
870 )) | 940 )) |
871 | 941 |
872 def RunPythonUnitTests(self): | 942 def RunPythonUnitTests(self): |
| 943 self.mox.ReplayAll() |
873 # TODO(maruel): Add real tests. | 944 # TODO(maruel): Add real tests. |
874 self.failIf(presubmit_canned_checks.RunPythonUnitTests( | 945 self.failIf(presubmit_canned_checks.RunPythonUnitTests( |
875 self.MockInputApi(), | 946 self.MockInputApi(), |
876 presubmit.OutputApi, [])) | 947 presubmit.OutputApi, [])) |
877 self.failUnless(presubmit_canned_checks.RunPythonUnitTests( | 948 self.failUnless(presubmit_canned_checks.RunPythonUnitTests( |
878 self.MockInputApi(), | 949 self.MockInputApi(), |
879 presubmit.OutputApi, ['non_existent_module'])) | 950 presubmit.OutputApi, ['non_existent_module'])) |
880 | 951 |
881 if __name__ == '__main__': | 952 if __name__ == '__main__': |
882 unittest.main() | 953 unittest.main() |
OLD | NEW |