| """Tests for git_utils.""" |
| |
| from __future__ import absolute_import |
| import os |
| import sys |
| import unittest |
| |
| # Allow imports from cq/scripts folder |
| sys.path.insert( |
| 0, |
| os.path.realpath(os.path.join(os.path.dirname(__file__), os.pardir))) |
| from helpers import git_utils |
| from helpers import repo_utils |
| |
| |
| # A mock executor that keeps simple git state. |
| class MockExecutor(object): |
| |
| def __init__(self): |
| self.current_branch = 'HEAD' |
| self.remote = '' |
| self.remote_branch = '' |
| self._handlers = [] |
| |
| def add_handler(self, handler): |
| self._handlers.append(handler) |
| |
| def exec_subprocess(self, command, cwd=None, check_output=False): |
| |
| for handler in self._handlers: |
| result = handler(command, cwd) |
| if result: |
| if check_output: |
| # check_output option only cares about stdout |
| return result[1] |
| return result |
| |
| if command[:2] == ['git', 'rev-parse']: |
| return (0, self.current_branch, '') |
| elif command[:2] == ['git', 'checkout']: |
| self.current_branch = command[command.index('-B') + 1] |
| self.remote, self.remote_branch = command[-1].split('/') |
| |
| return (0, '', '') |
| |
| |
| class GitUtilsTest(unittest.TestCase): |
| |
| def testNoFilterFiles(self): |
| """Tests with no filter.""" |
| filenames = [ |
| 'something.py', |
| 'something_else.cc' |
| ] |
| filtered_files = git_utils.filtered_files(filenames) |
| self.assertEquals(filenames, filtered_files) |
| |
| def testNoFilteredFiles(self): |
| """Tests filtering files by extension.""" |
| filenames = [ |
| 'something.py', |
| 'something_else.cc' |
| ] |
| filtered_files = git_utils.filtered_files(filenames, |
| file_extensions=['.py', '.cc']) |
| self.assertEquals(2, len(filtered_files)) |
| self.assertIn('something.py', filtered_files) |
| self.assertIn('something_else.cc', filtered_files) |
| |
| def testFilteredFiles(self): |
| """Tests filtering files by extension.""" |
| filenames = [ |
| 'something.py', |
| 'something_else.cc' |
| ] |
| filtered_files = git_utils.filtered_files(filenames, |
| file_extensions=['.py']) |
| self.assertEquals(1, len(filtered_files)) |
| self.assertIn('something.py', filtered_files) |
| |
| def testFilteredFilesExclusion(self): |
| """Tests filtering files by pattern.""" |
| filenames = [ |
| 'something.py', |
| 'something_foo_pb2.py', |
| 'something_else.cc' |
| ] |
| filtered_files = git_utils.filtered_files( |
| filenames, |
| file_extensions=['.py'], |
| file_exclusion_pattern=r'^.+_pb2.py$') |
| self.assertEquals(1, len(filtered_files)) |
| self.assertIn('something.py', filtered_files) |
| |
| def testGetAllFiles(self): |
| """Test getting all files affected by a group of patches.""" |
| patches = [ |
| {'project': 'chromium/src', 'patchset_number': 12345, |
| 'branch': repo_utils.DEFAULT_REVISION}, |
| {'project': 'chromium/src', 'patchset_number': 67890, |
| 'branch': repo_utils.DEFAULT_REVISION}, |
| {'project': 'chromium/src', 'patchset_number': 95271, |
| 'branch': 'branch1'}, |
| {'project': 'chromecast/internal', 'patchset_number': 34567, |
| 'branch': 'branch2'}, |
| {'project': 'test', 'patchset_number': 89012, |
| 'branch': repo_utils.DEFAULT_REVISION}, |
| {'project': 'project_with_no_path', 'patchset_number': 1, |
| 'branch': repo_utils.DEFAULT_REVISION}] |
| |
| path_lookup = repo_utils._ProjectLookupTable() |
| path_lookup.update({ |
| 'chromium/src': 'chromium/src', |
| ('chromecast/internal', 'branch2'): 'cast/internal', |
| 'test': 'test', |
| }) |
| |
| def handle_git_revlist(cmd, cwd): |
| if cmd == ['git', 'rev-list', '--count', 'HEAD']: |
| return (0, '200', '') |
| return None |
| |
| def handle_git_diff(cmd, cwd): |
| if cmd[:2] != ['git', 'diff'] or '--name-only' not in cmd: |
| return None |
| if cwd == 'chromium/src': |
| self.assertTrue('HEAD~2' in cmd) |
| files = ['base/logging.h', 'media/base/config.cc', 'net/utils.h'] |
| elif cwd == 'cast/internal': |
| self.assertTrue('HEAD~1' in cmd) |
| files = ['receiver/client.h', 'base/logging.h'] |
| elif cwd == 'test': |
| self.assertTrue('HEAD~1' in cmd) |
| files = ['foo.h'] |
| else: |
| return (0, '', '') |
| return (0, '\n'.join(files), '') |
| |
| executor = MockExecutor() |
| executor.add_handler(handle_git_revlist) |
| executor.add_handler(handle_git_diff) |
| all_files = git_utils.get_changed_files_in_all_patches( |
| executor, patches, path_lookup) |
| self.assertEqual(set([ |
| 'chromium/src/base/logging.h', |
| 'chromium/src/media/base/config.cc', |
| 'chromium/src/net/utils.h', |
| 'chromium/src/chromecast/internal/receiver/client.h', |
| 'chromium/src/chromecast/internal/base/logging.h', |
| 'test/foo.h']), set(all_files)) |
| |
| def testIsRevisionASha(self): |
| """Tests cases for git_utils.is_sha.""" |
| self.assertTrue( |
| git_utils.is_sha('2fe8f3b110d8b117698265e18e432f32837247bb')) |
| self.assertFalse(git_utils.is_sha('master')) |
| self.assertFalse(git_utils.is_sha('unfork_m52')) |
| |
| def testGetAllFilesOverwritesWithSymlinks(self): |
| """Test getting all files affected by a group of patches.""" |
| patches = [ |
| {'project': 'chromecast/internal', 'patchset_number': 34567, |
| 'branch': 'branch1'}] |
| |
| path_lookup = repo_utils._ProjectLookupTable() |
| path_lookup.update({ |
| ('chromecast/internal', 'branch1'): 'cast/internal', |
| }) |
| |
| def handle_git_revlist(cmd, unused_cwd): |
| if cmd == ['git', 'rev-list', '--count', 'HEAD']: |
| return (0, '200', '') |
| return None |
| |
| def handle_git_diff(cmd, cwd): |
| if cmd[:2] != ['git', 'diff'] or '--name-only' not in cmd: |
| return None |
| if cwd == 'cast/internal': |
| self.assertTrue('HEAD~1' in cmd) |
| files = ['receiver/client.h', 'base/logging.h'] |
| else: |
| return (0, '', '') |
| return (0, '\n'.join(files), '') |
| |
| executor = MockExecutor() |
| executor.add_handler(handle_git_revlist) |
| executor.add_handler(handle_git_diff) |
| all_files = git_utils.get_changed_files_in_all_patches( |
| executor, patches, path_lookup) |
| self.assertEqual( |
| set(['chromium/src/chromecast/internal/receiver/client.h', |
| 'chromium/src/chromecast/internal/base/logging.h',]), |
| set(all_files)) |
| |
| def testIsRevisionASha(self): |
| """Tests cases for git_utils.is_sha.""" |
| self.assertTrue( |
| git_utils.is_sha('2fe8f3b110d8b117698265e18e432f32837247bb')) |
| self.assertFalse(git_utils.is_sha('master')) |
| self.assertFalse(git_utils.is_sha('unfork_m52')) |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |