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.GitBackend().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.GitBackend().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.GitBackend().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.GitBackend().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.GitBackend().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.GitBackend().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.GitBackend().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.GitilesBackend().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 |