| 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 |