| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2016 The LUCI Authors. All rights reserved. | 2 # Copyright 2016 The LUCI Authors. All rights reserved. |
| 3 # Use of this source code is governed under the Apache License, Version 2.0 | 3 # Use of this source code is governed under the Apache License, Version 2.0 |
| 4 # that can be found in the LICENSE file. | 4 # that can be found in the LICENSE file. |
| 5 | 5 |
| 6 import base64 | 6 import base64 |
| 7 import io | 7 import io |
| 8 import os | 8 import os |
| 9 import sys | 9 import sys |
| 10 import unittest | 10 import unittest |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 | 25 |
| 26 class TestGit(unittest.TestCase): | 26 class TestGit(unittest.TestCase): |
| 27 @mock.patch('recipe_engine.fetch._run_git') | 27 @mock.patch('recipe_engine.fetch._run_git') |
| 28 def test_fresh_clone(self, run_git): | 28 def test_fresh_clone(self, run_git): |
| 29 run_git.side_effect = [ | 29 run_git.side_effect = [ |
| 30 None, | 30 None, |
| 31 'repo\n', | 31 'repo\n', |
| 32 None, | 32 None, |
| 33 None, | 33 None, |
| 34 ] | 34 ] |
| 35 fetch.ensure_git_checkout('repo', 'revision', 'dir', allow_fetch=True) | 35 fetch.LocalGitBackend().checkout( |
| 36 'repo', 'revision', 'dir', allow_fetch=True) |
| 36 run_git.assert_has_calls([ | 37 run_git.assert_has_calls([ |
| 37 mock.call(None, 'clone', '-q', 'repo', 'dir'), | 38 mock.call(None, 'clone', '-q', 'repo', 'dir'), |
| 38 mock.call('dir', 'config', 'remote.origin.url'), | 39 mock.call('dir', 'config', 'remote.origin.url'), |
| 39 mock.call('dir', 'rev-parse', '-q', '--verify', 'revision^{commit}'), | 40 mock.call('dir', 'rev-parse', '-q', '--verify', 'revision^{commit}'), |
| 40 mock.call('dir', 'reset', '-q', '--hard', 'revision'), | 41 mock.call('dir', 'reset', '-q', '--hard', 'revision'), |
| 41 ]) | 42 ]) |
| 42 | 43 |
| 43 @mock.patch('os.path.isdir') | 44 @mock.patch('os.path.isdir') |
| 44 @mock.patch('recipe_engine.fetch._run_git') | 45 @mock.patch('recipe_engine.fetch._run_git') |
| 45 def test_existing_checkout(self, run_git, isdir): | 46 def test_existing_checkout(self, run_git, isdir): |
| 46 run_git.side_effect = [ | 47 run_git.side_effect = [ |
| 47 'repo\n', | 48 'repo\n', |
| 48 None, | 49 None, |
| 49 None, | 50 None, |
| 50 ] | 51 ] |
| 51 isdir.return_value = True | 52 isdir.return_value = True |
| 52 fetch.ensure_git_checkout('repo', 'revision', 'dir', allow_fetch=True) | 53 fetch.LocalGitBackend().checkout( |
| 54 'repo', 'revision', 'dir', allow_fetch=True) |
| 53 isdir.assert_has_calls([ | 55 isdir.assert_has_calls([ |
| 54 mock.call('dir'), | 56 mock.call('dir'), |
| 55 mock.call('dir/.git'), | 57 mock.call('dir/.git'), |
| 56 ]) | 58 ]) |
| 57 run_git.assert_has_calls([ | 59 run_git.assert_has_calls([ |
| 58 mock.call('dir', 'config', 'remote.origin.url'), | 60 mock.call('dir', 'config', 'remote.origin.url'), |
| 59 mock.call('dir', 'rev-parse', '-q', '--verify', 'revision^{commit}'), | 61 mock.call('dir', 'rev-parse', '-q', '--verify', 'revision^{commit}'), |
| 60 mock.call('dir', 'reset', '-q', '--hard', 'revision'), | 62 mock.call('dir', 'reset', '-q', '--hard', 'revision'), |
| 61 ]) | 63 ]) |
| 62 | 64 |
| 63 @mock.patch('recipe_engine.fetch._run_git') | 65 @mock.patch('recipe_engine.fetch._run_git') |
| 64 def test_clone_not_allowed(self, run_git): | 66 def test_clone_not_allowed(self, run_git): |
| 65 with self.assertRaises(fetch.FetchNotAllowedError): | 67 with self.assertRaises(fetch.FetchNotAllowedError): |
| 66 fetch.ensure_git_checkout('repo', 'revision', 'dir', allow_fetch=False) | 68 fetch.LocalGitBackend().checkout( |
| 69 'repo', 'revision', 'dir', allow_fetch=False) |
| 67 | 70 |
| 68 @mock.patch('os.path.isdir') | 71 @mock.patch('os.path.isdir') |
| 69 @mock.patch('recipe_engine.fetch._run_git') | 72 @mock.patch('recipe_engine.fetch._run_git') |
| 70 def test_unclean_filesystem(self, run_git, isdir): | 73 def test_unclean_filesystem(self, run_git, isdir): |
| 71 isdir.side_effect = [True, False] | 74 isdir.side_effect = [True, False] |
| 72 with self.assertRaises(fetch.UncleanFilesystemError): | 75 with self.assertRaises(fetch.UncleanFilesystemError): |
| 73 fetch.ensure_git_checkout('repo', 'revision', 'dir', allow_fetch=False) | 76 fetch.LocalGitBackend().checkout( |
| 77 'repo', 'revision', 'dir', allow_fetch=False) |
| 74 isdir.assert_has_calls([ | 78 isdir.assert_has_calls([ |
| 75 mock.call('dir'), | 79 mock.call('dir'), |
| 76 mock.call('dir/.git'), | 80 mock.call('dir/.git'), |
| 77 ]) | 81 ]) |
| 78 | 82 |
| 79 @mock.patch('os.path.isdir') | 83 @mock.patch('os.path.isdir') |
| 80 @mock.patch('recipe_engine.fetch._run_git') | 84 @mock.patch('recipe_engine.fetch._run_git') |
| 81 def test_origin_mismatch(self, run_git, isdir): | 85 def test_origin_mismatch(self, run_git, isdir): |
| 82 run_git.return_value = 'not-repo' | 86 run_git.return_value = 'not-repo' |
| 83 isdir.return_value = True | 87 isdir.return_value = True |
| 84 with self.assertRaises(fetch.UncleanFilesystemError): | 88 with self.assertRaises(fetch.UncleanFilesystemError): |
| 85 fetch.ensure_git_checkout('repo', 'revision', 'dir', allow_fetch=False) | 89 fetch.LocalGitBackend().checkout( |
| 90 'repo', 'revision', 'dir', allow_fetch=False) |
| 86 isdir.assert_has_calls([ | 91 isdir.assert_has_calls([ |
| 87 mock.call('dir'), | 92 mock.call('dir'), |
| 88 mock.call('dir/.git'), | 93 mock.call('dir/.git'), |
| 89 ]) | 94 ]) |
| 90 run_git.assert_has_calls([ | 95 run_git.assert_has_calls([ |
| 91 mock.call('dir', 'config', 'remote.origin.url'), | 96 mock.call('dir', 'config', 'remote.origin.url'), |
| 92 ]) | 97 ]) |
| 93 | 98 |
| 94 @mock.patch('os.path.isdir') | 99 @mock.patch('os.path.isdir') |
| 95 @mock.patch('recipe_engine.fetch._run_git') | 100 @mock.patch('recipe_engine.fetch._run_git') |
| 96 def test_rev_parse_fail(self, run_git, isdir): | 101 def test_rev_parse_fail(self, run_git, isdir): |
| 97 run_git.side_effect = [ | 102 run_git.side_effect = [ |
| 98 'repo', | 103 'repo', |
| 99 subprocess42.CalledProcessError(1, ['fakecmd']), | 104 subprocess42.CalledProcessError(1, ['fakecmd']), |
| 100 None, | 105 None, |
| 101 None, | 106 None, |
| 102 ] | 107 ] |
| 103 isdir.return_value = True | 108 isdir.return_value = True |
| 104 fetch.ensure_git_checkout('repo', 'revision', 'dir', allow_fetch=True) | 109 fetch.LocalGitBackend().checkout( |
| 110 'repo', 'revision', 'dir', allow_fetch=True) |
| 105 isdir.assert_has_calls([ | 111 isdir.assert_has_calls([ |
| 106 mock.call('dir'), | 112 mock.call('dir'), |
| 107 mock.call('dir/.git'), | 113 mock.call('dir/.git'), |
| 108 ]) | 114 ]) |
| 109 run_git.assert_has_calls([ | 115 run_git.assert_has_calls([ |
| 110 mock.call('dir', 'config', 'remote.origin.url'), | 116 mock.call('dir', 'config', 'remote.origin.url'), |
| 111 mock.call('dir', 'rev-parse', '-q', '--verify', 'revision^{commit}'), | 117 mock.call('dir', 'rev-parse', '-q', '--verify', 'revision^{commit}'), |
| 112 mock.call('dir', 'fetch'), | 118 mock.call('dir', 'fetch'), |
| 113 mock.call('dir', 'reset', '-q', '--hard', 'revision'), | 119 mock.call('dir', 'reset', '-q', '--hard', 'revision'), |
| 114 ]) | 120 ]) |
| 115 | 121 |
| 116 @mock.patch('os.path.isdir') | 122 @mock.patch('os.path.isdir') |
| 117 @mock.patch('recipe_engine.fetch._run_git') | 123 @mock.patch('recipe_engine.fetch._run_git') |
| 118 def test_rev_parse_fetch_not_allowed(self, run_git, isdir): | 124 def test_rev_parse_fetch_not_allowed(self, run_git, isdir): |
| 119 run_git.side_effect = [ | 125 run_git.side_effect = [ |
| 120 'repo', | 126 'repo', |
| 121 subprocess42.CalledProcessError(1, ['fakecmd']), | 127 subprocess42.CalledProcessError(1, ['fakecmd']), |
| 122 ] | 128 ] |
| 123 isdir.return_value = True | 129 isdir.return_value = True |
| 124 with self.assertRaises(fetch.FetchNotAllowedError): | 130 with self.assertRaises(fetch.FetchNotAllowedError): |
| 125 fetch.ensure_git_checkout('repo', 'revision', 'dir', allow_fetch=False) | 131 fetch.LocalGitBackend().checkout( |
| 132 'repo', 'revision', 'dir', allow_fetch=False) |
| 126 isdir.assert_has_calls([ | 133 isdir.assert_has_calls([ |
| 127 mock.call('dir'), | 134 mock.call('dir'), |
| 128 mock.call('dir/.git'), | 135 mock.call('dir/.git'), |
| 129 ]) | 136 ]) |
| 130 run_git.assert_has_calls([ | 137 run_git.assert_has_calls([ |
| 131 mock.call('dir', 'config', 'remote.origin.url'), | 138 mock.call('dir', 'config', 'remote.origin.url'), |
| 132 mock.call('dir', 'rev-parse', '-q', '--verify', 'revision^{commit}'), | 139 mock.call('dir', 'rev-parse', '-q', '--verify', 'revision^{commit}'), |
| 133 ]) | 140 ]) |
| 134 | 141 |
| 135 | 142 |
| 136 class TestGitiles(unittest.TestCase): | 143 class TestGitiles(unittest.TestCase): |
| 137 @mock.patch('__builtin__.open', mock.mock_open()) | 144 @mock.patch('__builtin__.open', mock.mock_open()) |
| 138 @mock.patch('shutil.rmtree') | 145 @mock.patch('shutil.rmtree') |
| 139 @mock.patch('os.makedirs') | 146 @mock.patch('os.makedirs') |
| 140 @mock.patch('tarfile.open') | 147 @mock.patch('tarfile.open') |
| 141 @mock.patch('requests.get') | 148 @mock.patch('requests.get') |
| 142 def test_basic(self, requests_get, tarfile_open, makedirs, rmtree): | 149 def test_basic(self, requests_get, tarfile_open, makedirs, rmtree): |
| 143 proto_text = u""" | 150 proto_text = u""" |
| 144 api_version: 1 | 151 api_version: 1 |
| 145 project_id: "foo" | 152 project_id: "foo" |
| 146 recipes_path: "path/to/recipes" | 153 recipes_path: "path/to/recipes" |
| 147 """.lstrip() | 154 """.lstrip() |
| 148 requests_get.side_effect = [ | 155 requests_get.side_effect = [ |
| 149 mock.Mock(text=u')]}\'\n{ "commit": "abc123" }'), | 156 mock.Mock(text=u')]}\'\n{ "commit": "abc123" }'), |
| 150 mock.Mock(text=base64.b64encode(proto_text)), | 157 mock.Mock(text=base64.b64encode(proto_text)), |
| 151 mock.Mock(content=''), | 158 mock.Mock(content=''), |
| 152 ] | 159 ] |
| 153 | 160 |
| 154 fetch.ensure_gitiles_checkout('repo', 'revision', 'dir', allow_fetch=True) | 161 fetch.GitilesGitBackend().checkout( |
| 162 'repo', 'revision', 'dir', allow_fetch=True) |
| 155 | 163 |
| 156 requests_get.assert_has_calls([ | 164 requests_get.assert_has_calls([ |
| 157 mock.call('repo/+/revision?format=JSON'), | 165 mock.call('repo/+/revision?format=JSON'), |
| 158 mock.call('repo/+/abc123/infra/config/recipes.cfg?format=TEXT'), | 166 mock.call('repo/+/abc123/infra/config/recipes.cfg?format=TEXT'), |
| 159 mock.call('repo/+archive/abc123/path/to/recipes.tar.gz'), | 167 mock.call('repo/+archive/abc123/path/to/recipes.tar.gz'), |
| 160 ]) | 168 ]) |
| 161 | 169 |
| 162 makedirs.assert_has_calls([ | 170 makedirs.assert_has_calls([ |
| 163 mock.call('dir/infra/config'), | 171 mock.call('dir/infra/config'), |
| 164 mock.call('dir/path/to/recipes'), | 172 mock.call('dir/path/to/recipes'), |
| 165 ]) | 173 ]) |
| 166 | 174 |
| 167 rmtree.assert_called_once_with('dir', ignore_errors=True) | 175 rmtree.assert_called_once_with('dir', ignore_errors=True) |
| 168 | 176 |
| 169 | 177 |
| 170 if __name__ == '__main__': | 178 if __name__ == '__main__': |
| 171 unittest.main() | 179 unittest.main() |
| OLD | NEW |