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 os | 9 import os |
10 import StringIO | 10 import StringIO |
(...skipping 30 matching lines...) Expand all Loading... |
41 os_path_dirname = presubmit.os.path.dirname | 41 os_path_dirname = presubmit.os.path.dirname |
42 os_path_normpath = presubmit.os.path.normpath | 42 os_path_normpath = presubmit.os.path.normpath |
43 os_path_splitext = presubmit.os.path.splitext | 43 os_path_splitext = presubmit.os.path.splitext |
44 self.mox.StubOutWithMock(presubmit, 'os') | 44 self.mox.StubOutWithMock(presubmit, 'os') |
45 self.mox.StubOutWithMock(presubmit.os, 'path') | 45 self.mox.StubOutWithMock(presubmit.os, 'path') |
46 presubmit.os.sep = os_sep | 46 presubmit.os.sep = os_sep |
47 presubmit.os.path.join = os_path_join | 47 presubmit.os.path.join = os_path_join |
48 presubmit.os.path.dirname = os_path_dirname | 48 presubmit.os.path.dirname = os_path_dirname |
49 presubmit.os.path.normpath = os_path_normpath | 49 presubmit.os.path.normpath = os_path_normpath |
50 presubmit.os.path.splitext = os_path_splitext | 50 presubmit.os.path.splitext = os_path_splitext |
| 51 self.mox.StubOutWithMock(presubmit, 'random') |
51 self.mox.StubOutWithMock(presubmit, 'sys') | 52 self.mox.StubOutWithMock(presubmit, 'sys') |
| 53 presubmit._ASKED_FOR_FEEDBACK = False |
52 # Special mocks. | 54 # Special mocks. |
53 def MockAbsPath(f): | 55 def MockAbsPath(f): |
54 return f | 56 return f |
55 presubmit.os.path.abspath = MockAbsPath | 57 presubmit.os.path.abspath = MockAbsPath |
56 self.fake_root_dir = self.RootDir() | 58 self.fake_root_dir = self.RootDir() |
57 self.mox.StubOutWithMock(presubmit.gclient, 'CaptureSVNInfo') | 59 self.mox.StubOutWithMock(presubmit.gclient, 'CaptureSVNInfo') |
58 self.mox.StubOutWithMock(presubmit.gcl, 'GetSVNFileProperty') | 60 self.mox.StubOutWithMock(presubmit.gcl, 'GetSVNFileProperty') |
59 self.mox.StubOutWithMock(presubmit.gcl, 'ReadFile') | 61 self.mox.StubOutWithMock(presubmit.gcl, 'ReadFile') |
60 | 62 |
61 | 63 |
62 class PresubmitUnittest(PresubmitTestsBase): | 64 class PresubmitUnittest(PresubmitTestsBase): |
63 """General presubmit_support.py tests (excluding InputApi and OutputApi).""" | 65 """General presubmit_support.py tests (excluding InputApi and OutputApi).""" |
64 def testMembersChanged(self): | 66 def testMembersChanged(self): |
65 self.mox.ReplayAll() | 67 self.mox.ReplayAll() |
66 members = [ | 68 members = [ |
67 'AffectedFile', 'Change', 'DoPresubmitChecks', 'GitChange', | 69 'AffectedFile', 'Change', 'DoPresubmitChecks', 'GitChange', |
68 'GitAffectedFile', 'InputApi', | 70 'GitAffectedFile', 'InputApi', |
69 'ListRelevantPresubmitFiles', 'Main', 'NotImplementedException', | 71 'ListRelevantPresubmitFiles', 'Main', 'NotImplementedException', |
70 'OutputApi', 'ParseFiles', 'PresubmitExecuter', 'ScanSubDirs', | 72 'OutputApi', 'ParseFiles', 'PresubmitExecuter', 'ScanSubDirs', |
71 'SvnAffectedFile', 'SvnChange', | 73 'SvnAffectedFile', 'SvnChange', |
72 'cPickle', 'cStringIO', 'exceptions', | 74 'cPickle', 'cStringIO', 'exceptions', |
73 'fnmatch', 'gcl', 'gclient', 'glob', 'logging', 'marshal', 'normpath', | 75 'fnmatch', 'gcl', 'gclient', 'glob', 'logging', 'marshal', 'normpath', |
74 'optparse', | 76 'optparse', 'os', 'pickle', |
75 'os', 'pickle', 'presubmit_canned_checks', 're', 'subprocess', 'sys', | 77 'presubmit_canned_checks', 'random', 're', 'subprocess', 'sys', |
76 'tempfile', 'traceback', 'types', 'unittest', 'urllib2', 'warnings', | 78 'tempfile', 'traceback', 'types', 'unittest', 'urllib2', 'warnings', |
77 ] | 79 ] |
78 # If this test fails, you should add the relevant test. | 80 # If this test fails, you should add the relevant test. |
79 self.compareMembers(presubmit, members) | 81 self.compareMembers(presubmit, members) |
80 | 82 |
81 def testListRelevantPresubmitFiles(self): | 83 def testListRelevantPresubmitFiles(self): |
82 join = presubmit.os.path.join | 84 join = presubmit.os.path.join |
83 files = [ | 85 files = [ |
84 'blat.cc', | 86 'blat.cc', |
85 join('foo', 'haspresubmit', 'yodle', 'smart.h'), | 87 join('foo', 'haspresubmit', 'yodle', 'smart.h'), |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 ['A', join('haspresubmit', 'blat.cc')], | 290 ['A', join('haspresubmit', 'blat.cc')], |
289 ] | 291 ] |
290 haspresubmit_path = join(self.fake_root_dir, 'haspresubmit', 'PRESUBMIT.py') | 292 haspresubmit_path = join(self.fake_root_dir, 'haspresubmit', 'PRESUBMIT.py') |
291 root_path = join(self.fake_root_dir, 'PRESUBMIT.py') | 293 root_path = join(self.fake_root_dir, 'PRESUBMIT.py') |
292 presubmit.os.path.isfile(root_path).AndReturn(True) | 294 presubmit.os.path.isfile(root_path).AndReturn(True) |
293 presubmit.os.path.isfile(haspresubmit_path).AndReturn(True) | 295 presubmit.os.path.isfile(haspresubmit_path).AndReturn(True) |
294 presubmit.gcl.ReadFile(root_path, | 296 presubmit.gcl.ReadFile(root_path, |
295 'rU').AndReturn(self.presubmit_text) | 297 'rU').AndReturn(self.presubmit_text) |
296 presubmit.gcl.ReadFile(haspresubmit_path, | 298 presubmit.gcl.ReadFile(haspresubmit_path, |
297 'rU').AndReturn(self.presubmit_text) | 299 'rU').AndReturn(self.presubmit_text) |
| 300 presubmit.random.randint(0, 4).AndReturn(1) |
298 self.mox.ReplayAll() | 301 self.mox.ReplayAll() |
299 | 302 |
300 output = StringIO.StringIO() | 303 output = StringIO.StringIO() |
301 input = StringIO.StringIO('y\n') | 304 input = StringIO.StringIO('y\n') |
302 change = presubmit.Change('mychange', '\n'.join(description_lines), | 305 change = presubmit.Change('mychange', '\n'.join(description_lines), |
303 self.fake_root_dir, files, 0, 0) | 306 self.fake_root_dir, files, 0, 0) |
304 self.failIf(presubmit.DoPresubmitChecks(change, False, True, output, input, | 307 self.failIf(presubmit.DoPresubmitChecks(change, False, True, output, input, |
305 None, False)) | 308 None, False)) |
306 self.assertEqual(output.getvalue().count('!!'), 2) | 309 self.assertEqual(output.getvalue().count('!!'), 2) |
307 | 310 |
308 def testDoPresubmitChecksPromptsAfterWarnings(self): | 311 def testDoPresubmitChecksPromptsAfterWarnings(self): |
309 join = presubmit.os.path.join | 312 join = presubmit.os.path.join |
310 description_lines = ('Hello there', | 313 description_lines = ('Hello there', |
311 'this is a change', | 314 'this is a change', |
312 'NOSUCHKEY=http://tracker/123') | 315 'NOSUCHKEY=http://tracker/123') |
313 files = [ | 316 files = [ |
314 ['A', join('haspresubmit', 'blat.cc')], | 317 ['A', join('haspresubmit', 'blat.cc')], |
315 ] | 318 ] |
316 presubmit_path = join(self.fake_root_dir, 'PRESUBMIT.py') | 319 presubmit_path = join(self.fake_root_dir, 'PRESUBMIT.py') |
317 haspresubmit_path = join(self.fake_root_dir, 'haspresubmit', 'PRESUBMIT.py') | 320 haspresubmit_path = join(self.fake_root_dir, 'haspresubmit', 'PRESUBMIT.py') |
318 for i in range(2): | 321 for i in range(2): |
319 presubmit.os.path.isfile(presubmit_path).AndReturn(True) | 322 presubmit.os.path.isfile(presubmit_path).AndReturn(True) |
320 presubmit.os.path.isfile(haspresubmit_path).AndReturn(True) | 323 presubmit.os.path.isfile(haspresubmit_path).AndReturn(True) |
321 presubmit.gcl.ReadFile(presubmit_path, 'rU' | 324 presubmit.gcl.ReadFile(presubmit_path, 'rU' |
322 ).AndReturn(self.presubmit_text) | 325 ).AndReturn(self.presubmit_text) |
323 presubmit.gcl.ReadFile(haspresubmit_path, 'rU' | 326 presubmit.gcl.ReadFile(haspresubmit_path, 'rU' |
324 ).AndReturn(self.presubmit_text) | 327 ).AndReturn(self.presubmit_text) |
| 328 presubmit.random.randint(0, 4).AndReturn(1) |
| 329 presubmit.random.randint(0, 4).AndReturn(1) |
325 self.mox.ReplayAll() | 330 self.mox.ReplayAll() |
326 | 331 |
327 output = StringIO.StringIO() | 332 output = StringIO.StringIO() |
328 input = StringIO.StringIO('n\n') # say no to the warning | 333 input = StringIO.StringIO('n\n') # say no to the warning |
329 change = presubmit.Change('mychange', '\n'.join(description_lines), | 334 change = presubmit.Change('mychange', '\n'.join(description_lines), |
330 self.fake_root_dir, files, 0, 0) | 335 self.fake_root_dir, files, 0, 0) |
331 self.failIf(presubmit.DoPresubmitChecks(change, False, True, output, input, | 336 self.failIf(presubmit.DoPresubmitChecks(change, False, True, output, input, |
332 None, True)) | 337 None, True)) |
333 self.assertEqual(output.getvalue().count('??'), 2) | 338 self.assertEqual(output.getvalue().count('??'), 2) |
334 | 339 |
(...skipping 13 matching lines...) Expand all Loading... |
348 ['A', join('haspresubmit', 'blat.cc')], | 353 ['A', join('haspresubmit', 'blat.cc')], |
349 ] | 354 ] |
350 presubmit_path = join(self.fake_root_dir, 'PRESUBMIT.py') | 355 presubmit_path = join(self.fake_root_dir, 'PRESUBMIT.py') |
351 haspresubmit_path = join(self.fake_root_dir, 'haspresubmit', | 356 haspresubmit_path = join(self.fake_root_dir, 'haspresubmit', |
352 'PRESUBMIT.py') | 357 'PRESUBMIT.py') |
353 presubmit.os.path.isfile(presubmit_path).AndReturn(True) | 358 presubmit.os.path.isfile(presubmit_path).AndReturn(True) |
354 presubmit.os.path.isfile(haspresubmit_path).AndReturn(True) | 359 presubmit.os.path.isfile(haspresubmit_path).AndReturn(True) |
355 presubmit.gcl.ReadFile(presubmit_path, 'rU').AndReturn(self.presubmit_text) | 360 presubmit.gcl.ReadFile(presubmit_path, 'rU').AndReturn(self.presubmit_text) |
356 presubmit.gcl.ReadFile(haspresubmit_path, 'rU').AndReturn( | 361 presubmit.gcl.ReadFile(haspresubmit_path, 'rU').AndReturn( |
357 self.presubmit_text) | 362 self.presubmit_text) |
| 363 presubmit.random.randint(0, 4).AndReturn(1) |
358 self.mox.ReplayAll() | 364 self.mox.ReplayAll() |
359 | 365 |
360 output = StringIO.StringIO() | 366 output = StringIO.StringIO() |
361 input = StringIO.StringIO() # should be unused | 367 input = StringIO.StringIO() # should be unused |
362 change = presubmit.Change('mychange', '\n'.join(description_lines), | 368 change = presubmit.Change('mychange', '\n'.join(description_lines), |
363 self.fake_root_dir, files, 0, 0) | 369 self.fake_root_dir, files, 0, 0) |
364 self.failIf(presubmit.DoPresubmitChecks(change, False, True, output, input, | 370 self.failIf(presubmit.DoPresubmitChecks(change, False, True, output, input, |
365 None, False)) | 371 None, False)) |
366 self.assertEqual(output.getvalue().count('??'), 2) | 372 self.assertEqual(output.getvalue().count('??'), 2) |
367 self.assertEqual(output.getvalue().count('XX!!XX'), 2) | 373 self.assertEqual(output.getvalue().count('XX!!XX'), 2) |
368 self.assertEqual(output.getvalue().count('(y/N)'), 0) | 374 self.assertEqual(output.getvalue().count('(y/N)'), 0) |
369 | 375 |
370 def testDoDefaultPresubmitChecks(self): | 376 def testDoDefaultPresubmitChecksAndFeedback(self): |
371 join = presubmit.os.path.join | 377 join = presubmit.os.path.join |
372 description_lines = ('Hello there', | 378 description_lines = ('Hello there', |
373 'this is a change', | 379 'this is a change', |
374 'STORY=http://tracker/123') | 380 'STORY=http://tracker/123') |
375 files = [ | 381 files = [ |
376 ['A', join('haspresubmit', 'blat.cc')], | 382 ['A', join('haspresubmit', 'blat.cc')], |
377 ] | 383 ] |
378 DEFAULT_SCRIPT = """ | 384 DEFAULT_SCRIPT = """ |
379 def CheckChangeOnUpload(input_api, output_api): | 385 def CheckChangeOnUpload(input_api, output_api): |
380 return [output_api.PresubmitError("!!")] | 386 return [output_api.PresubmitError("!!")] |
381 def CheckChangeOnCommit(input_api, output_api): | 387 def CheckChangeOnCommit(input_api, output_api): |
382 raise Exception("Test error") | 388 raise Exception("Test error") |
383 """ | 389 """ |
384 presubmit.os.path.isfile(join(self.fake_root_dir, 'PRESUBMIT.py') | 390 presubmit.os.path.isfile(join(self.fake_root_dir, 'PRESUBMIT.py') |
385 ).AndReturn(False) | 391 ).AndReturn(False) |
386 presubmit.os.path.isfile(join(self.fake_root_dir, | 392 presubmit.os.path.isfile(join(self.fake_root_dir, |
387 'haspresubmit', | 393 'haspresubmit', |
388 'PRESUBMIT.py')).AndReturn(False) | 394 'PRESUBMIT.py')).AndReturn(False) |
| 395 presubmit.random.randint(0, 4).AndReturn(0) |
389 self.mox.ReplayAll() | 396 self.mox.ReplayAll() |
390 | 397 |
391 output = StringIO.StringIO() | 398 output = StringIO.StringIO() |
392 input = StringIO.StringIO('y\n') | 399 input = StringIO.StringIO('y\n') |
393 # Always fail. | 400 # Always fail. |
394 change = presubmit.Change('mychange', '\n'.join(description_lines), | 401 change = presubmit.Change('mychange', '\n'.join(description_lines), |
395 self.fake_root_dir, files, 0, 0) | 402 self.fake_root_dir, files, 0, 0) |
396 self.failIf(presubmit.DoPresubmitChecks(change, False, True, output, input, | 403 self.failIf(presubmit.DoPresubmitChecks(change, False, True, output, input, |
397 DEFAULT_SCRIPT, False)) | 404 DEFAULT_SCRIPT, False)) |
398 self.assertEquals(output.getvalue().count('!!'), 1) | 405 text = ('Warning, no presubmit.py found.\n' |
| 406 'Running default presubmit script.\n' |
| 407 '** Presubmit ERRORS **\n!!\n\n' |
| 408 'Was the presubmit check useful? Please send feedback & hate mail ' |
| 409 'to maruel@chromium.org!\n') |
| 410 self.assertEquals(output.getvalue(), text) |
399 | 411 |
400 def testDirectoryHandling(self): | 412 def testDirectoryHandling(self): |
401 files = [ | 413 files = [ |
402 ['A', 'isdir'], | 414 ['A', 'isdir'], |
403 ['A', os.path.join('isdir', 'blat.cc')], | 415 ['A', os.path.join('isdir', 'blat.cc')], |
404 ] | 416 ] |
405 isdir = presubmit.os.path.join(self.fake_root_dir, 'isdir') | 417 isdir = presubmit.os.path.join(self.fake_root_dir, 'isdir') |
406 blat = presubmit.os.path.join(isdir, 'blat.cc') | 418 blat = presubmit.os.path.join(isdir, 'blat.cc') |
407 presubmit.os.path.exists(isdir).AndReturn(True) | 419 presubmit.os.path.exists(isdir).AndReturn(True) |
408 presubmit.os.path.isdir(isdir).AndReturn(True) | 420 presubmit.os.path.isdir(isdir).AndReturn(True) |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 return [output_api.PresubmitError('Tag parsing failed. 4 ' + | 454 return [output_api.PresubmitError('Tag parsing failed. 4 ' + |
443 input_api.change.DescriptionText())] | 455 input_api.change.DescriptionText())] |
444 if (input_api.change.FullDescriptionText() != | 456 if (input_api.change.FullDescriptionText() != |
445 'Blah Blah\\n\\nSTORY=http://tracker.com/42\\nBUG=boo\\n'): | 457 'Blah Blah\\n\\nSTORY=http://tracker.com/42\\nBUG=boo\\n'): |
446 return [output_api.PresubmitError('Tag parsing failed. 5 ' + | 458 return [output_api.PresubmitError('Tag parsing failed. 5 ' + |
447 input_api.change.FullDescriptionText())] | 459 input_api.change.FullDescriptionText())] |
448 return [output_api.PresubmitNotifyResult(input_api.change.tags['STORY'])] | 460 return [output_api.PresubmitNotifyResult(input_api.change.tags['STORY'])] |
449 def CheckChangeOnCommit(input_api, output_api): | 461 def CheckChangeOnCommit(input_api, output_api): |
450 raise Exception("Test error") | 462 raise Exception("Test error") |
451 """ | 463 """ |
| 464 presubmit.random.randint(0, 4).AndReturn(1) |
452 self.mox.ReplayAll() | 465 self.mox.ReplayAll() |
453 | 466 |
454 output = StringIO.StringIO() | 467 output = StringIO.StringIO() |
455 input = StringIO.StringIO('y\n') | 468 input = StringIO.StringIO('y\n') |
456 change = presubmit.Change( | 469 change = presubmit.Change( |
457 'foo', "Blah Blah\n\nSTORY=http://tracker.com/42\nBUG=boo\n", | 470 'foo', "Blah Blah\n\nSTORY=http://tracker.com/42\nBUG=boo\n", |
458 self.fake_root_dir, None, 0, 0) | 471 self.fake_root_dir, None, 0, 0) |
459 self.failUnless(presubmit.DoPresubmitChecks(change, False, True, output, | 472 self.failUnless(presubmit.DoPresubmitChecks(change, False, True, output, |
460 input, DEFAULT_SCRIPT, False)) | 473 input, DEFAULT_SCRIPT, False)) |
461 self.assertEquals(output.getvalue(), | 474 self.assertEquals(output.getvalue(), |
(...skipping 895 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1357 process.communicate().AndReturn(('', '')) | 1370 process.communicate().AndReturn(('', '')) |
1358 self.mox.ReplayAll() | 1371 self.mox.ReplayAll() |
1359 | 1372 |
1360 results = presubmit_canned_checks.RunPythonUnitTests( | 1373 results = presubmit_canned_checks.RunPythonUnitTests( |
1361 input_api, presubmit.OutputApi, ['test_module']) | 1374 input_api, presubmit.OutputApi, ['test_module']) |
1362 self.assertEquals(len(results), 0) | 1375 self.assertEquals(len(results), 0) |
1363 | 1376 |
1364 | 1377 |
1365 if __name__ == '__main__': | 1378 if __name__ == '__main__': |
1366 unittest.main() | 1379 unittest.main() |
OLD | NEW |