##// END OF EJS Templates
tests: Ignore merge commit id on camparison of merge responses.
Martin Bornhold -
r1060:64559657 default
parent child Browse files
Show More
@@ -1,525 +1,532 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 RhodeCode GmbH
3 # Copyright (C) 2010-2016 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import datetime
21 import datetime
22 from urllib2 import URLError
22 from urllib2 import URLError
23
23
24 import mock
24 import mock
25 import pytest
25 import pytest
26
26
27 from rhodecode.lib.vcs import backends
27 from rhodecode.lib.vcs import backends
28 from rhodecode.lib.vcs.backends.base import (
28 from rhodecode.lib.vcs.backends.base import (
29 Config, BaseInMemoryCommit, Reference, MergeResponse, MergeFailureReason)
29 Config, BaseInMemoryCommit, Reference, MergeResponse, MergeFailureReason)
30 from rhodecode.lib.vcs.exceptions import VCSError, RepositoryError
30 from rhodecode.lib.vcs.exceptions import VCSError, RepositoryError
31 from rhodecode.lib.vcs.nodes import FileNode
31 from rhodecode.lib.vcs.nodes import FileNode
32 from rhodecode.tests.vcs.base import BackendTestMixin
32 from rhodecode.tests.vcs.base import BackendTestMixin
33
33
34
34
35 class TestRepositoryBase(BackendTestMixin):
35 class TestRepositoryBase(BackendTestMixin):
36 recreate_repo_per_test = False
36 recreate_repo_per_test = False
37
37
38 def test_init_accepts_unicode_path(self, tmpdir):
38 def test_init_accepts_unicode_path(self, tmpdir):
39 path = unicode(tmpdir.join(u'unicode Γ€'))
39 path = unicode(tmpdir.join(u'unicode Γ€'))
40 self.Backend(path, create=True)
40 self.Backend(path, create=True)
41
41
42 def test_init_accepts_str_path(self, tmpdir):
42 def test_init_accepts_str_path(self, tmpdir):
43 path = str(tmpdir.join('str Γ€'))
43 path = str(tmpdir.join('str Γ€'))
44 self.Backend(path, create=True)
44 self.Backend(path, create=True)
45
45
46 def test_init_fails_if_path_does_not_exist(self, tmpdir):
46 def test_init_fails_if_path_does_not_exist(self, tmpdir):
47 path = unicode(tmpdir.join('i-do-not-exist'))
47 path = unicode(tmpdir.join('i-do-not-exist'))
48 with pytest.raises(VCSError):
48 with pytest.raises(VCSError):
49 self.Backend(path)
49 self.Backend(path)
50
50
51 def test_init_fails_if_path_is_not_a_valid_repository(self, tmpdir):
51 def test_init_fails_if_path_is_not_a_valid_repository(self, tmpdir):
52 path = unicode(tmpdir.mkdir(u'unicode Γ€'))
52 path = unicode(tmpdir.mkdir(u'unicode Γ€'))
53 with pytest.raises(VCSError):
53 with pytest.raises(VCSError):
54 self.Backend(path)
54 self.Backend(path)
55
55
56 def test_has_commits_attribute(self):
56 def test_has_commits_attribute(self):
57 self.repo.commit_ids
57 self.repo.commit_ids
58
58
59 def test_name(self):
59 def test_name(self):
60 assert self.repo.name.startswith('vcs-test')
60 assert self.repo.name.startswith('vcs-test')
61
61
62 @pytest.mark.backends("hg", "git")
62 @pytest.mark.backends("hg", "git")
63 def test_has_default_branch_name(self):
63 def test_has_default_branch_name(self):
64 assert self.repo.DEFAULT_BRANCH_NAME is not None
64 assert self.repo.DEFAULT_BRANCH_NAME is not None
65
65
66 @pytest.mark.backends("svn")
66 @pytest.mark.backends("svn")
67 def test_has_no_default_branch_name(self):
67 def test_has_no_default_branch_name(self):
68 assert self.repo.DEFAULT_BRANCH_NAME is None
68 assert self.repo.DEFAULT_BRANCH_NAME is None
69
69
70 def test_has_empty_commit(self):
70 def test_has_empty_commit(self):
71 assert self.repo.EMPTY_COMMIT_ID is not None
71 assert self.repo.EMPTY_COMMIT_ID is not None
72 assert self.repo.EMPTY_COMMIT is not None
72 assert self.repo.EMPTY_COMMIT is not None
73
73
74 def test_empty_changeset_is_deprecated(self):
74 def test_empty_changeset_is_deprecated(self):
75 def get_empty_changeset(repo):
75 def get_empty_changeset(repo):
76 return repo.EMPTY_CHANGESET
76 return repo.EMPTY_CHANGESET
77 pytest.deprecated_call(get_empty_changeset, self.repo)
77 pytest.deprecated_call(get_empty_changeset, self.repo)
78
78
79 def test_bookmarks(self):
79 def test_bookmarks(self):
80 assert len(self.repo.bookmarks) == 0
80 assert len(self.repo.bookmarks) == 0
81
81
82 # TODO: Cover two cases: Local repo path, remote URL
82 # TODO: Cover two cases: Local repo path, remote URL
83 def test_check_url(self):
83 def test_check_url(self):
84 config = Config()
84 config = Config()
85 assert self.Backend.check_url(self.repo.path, config)
85 assert self.Backend.check_url(self.repo.path, config)
86
86
87 def test_check_url_invalid(self):
87 def test_check_url_invalid(self):
88 config = Config()
88 config = Config()
89 with pytest.raises(URLError):
89 with pytest.raises(URLError):
90 self.Backend.check_url(self.repo.path + "invalid", config)
90 self.Backend.check_url(self.repo.path + "invalid", config)
91
91
92 def test_get_contact(self):
92 def test_get_contact(self):
93 self.repo.contact
93 self.repo.contact
94
94
95 def test_get_description(self):
95 def test_get_description(self):
96 self.repo.description
96 self.repo.description
97
97
98 def test_get_hook_location(self):
98 def test_get_hook_location(self):
99 assert len(self.repo.get_hook_location()) != 0
99 assert len(self.repo.get_hook_location()) != 0
100
100
101 def test_last_change(self):
101 def test_last_change(self):
102 assert self.repo.last_change >= datetime.datetime(2010, 1, 1, 21, 0)
102 assert self.repo.last_change >= datetime.datetime(2010, 1, 1, 21, 0)
103
103
104 def test_last_change_in_empty_repository(self, vcsbackend):
104 def test_last_change_in_empty_repository(self, vcsbackend):
105 delta = datetime.timedelta(seconds=1)
105 delta = datetime.timedelta(seconds=1)
106 start = datetime.datetime.now()
106 start = datetime.datetime.now()
107 empty_repo = vcsbackend.create_repo()
107 empty_repo = vcsbackend.create_repo()
108 now = datetime.datetime.now()
108 now = datetime.datetime.now()
109 assert empty_repo.last_change >= start - delta
109 assert empty_repo.last_change >= start - delta
110 assert empty_repo.last_change <= now + delta
110 assert empty_repo.last_change <= now + delta
111
111
112 def test_repo_equality(self):
112 def test_repo_equality(self):
113 assert self.repo == self.repo
113 assert self.repo == self.repo
114
114
115 def test_repo_equality_broken_object(self):
115 def test_repo_equality_broken_object(self):
116 import copy
116 import copy
117 _repo = copy.copy(self.repo)
117 _repo = copy.copy(self.repo)
118 delattr(_repo, 'path')
118 delattr(_repo, 'path')
119 assert self.repo != _repo
119 assert self.repo != _repo
120
120
121 def test_repo_equality_other_object(self):
121 def test_repo_equality_other_object(self):
122 class dummy(object):
122 class dummy(object):
123 path = self.repo.path
123 path = self.repo.path
124 assert self.repo != dummy()
124 assert self.repo != dummy()
125
125
126 def test_get_commit_is_implemented(self):
126 def test_get_commit_is_implemented(self):
127 self.repo.get_commit()
127 self.repo.get_commit()
128
128
129 def test_get_commits_is_implemented(self):
129 def test_get_commits_is_implemented(self):
130 commit_iter = iter(self.repo.get_commits())
130 commit_iter = iter(self.repo.get_commits())
131 commit = next(commit_iter)
131 commit = next(commit_iter)
132 assert commit.idx == 0
132 assert commit.idx == 0
133
133
134 def test_supports_iteration(self):
134 def test_supports_iteration(self):
135 repo_iter = iter(self.repo)
135 repo_iter = iter(self.repo)
136 commit = next(repo_iter)
136 commit = next(repo_iter)
137 assert commit.idx == 0
137 assert commit.idx == 0
138
138
139 def test_in_memory_commit(self):
139 def test_in_memory_commit(self):
140 imc = self.repo.in_memory_commit
140 imc = self.repo.in_memory_commit
141 assert isinstance(imc, BaseInMemoryCommit)
141 assert isinstance(imc, BaseInMemoryCommit)
142
142
143 @pytest.mark.backends("hg")
143 @pytest.mark.backends("hg")
144 def test__get_url_unicode(self):
144 def test__get_url_unicode(self):
145 url = u'/home/repos/malmΓΆ'
145 url = u'/home/repos/malmΓΆ'
146 assert self.repo._get_url(url)
146 assert self.repo._get_url(url)
147
147
148
148
149 class TestDeprecatedRepositoryAPI(BackendTestMixin):
149 class TestDeprecatedRepositoryAPI(BackendTestMixin):
150 recreate_repo_per_test = False
150 recreate_repo_per_test = False
151
151
152 def test_revisions_is_deprecated(self):
152 def test_revisions_is_deprecated(self):
153 def get_revisions(repo):
153 def get_revisions(repo):
154 return repo.revisions
154 return repo.revisions
155 pytest.deprecated_call(get_revisions, self.repo)
155 pytest.deprecated_call(get_revisions, self.repo)
156
156
157 def test_get_changeset_is_deprecated(self):
157 def test_get_changeset_is_deprecated(self):
158 pytest.deprecated_call(self.repo.get_changeset)
158 pytest.deprecated_call(self.repo.get_changeset)
159
159
160 def test_get_changesets_is_deprecated(self):
160 def test_get_changesets_is_deprecated(self):
161 pytest.deprecated_call(self.repo.get_changesets)
161 pytest.deprecated_call(self.repo.get_changesets)
162
162
163 def test_in_memory_changeset_is_deprecated(self):
163 def test_in_memory_changeset_is_deprecated(self):
164 def get_imc(repo):
164 def get_imc(repo):
165 return repo.in_memory_changeset
165 return repo.in_memory_changeset
166 pytest.deprecated_call(get_imc, self.repo)
166 pytest.deprecated_call(get_imc, self.repo)
167
167
168
168
169 # TODO: these tests are incomplete, must check the resulting compare result for
169 # TODO: these tests are incomplete, must check the resulting compare result for
170 # correcteness
170 # correcteness
171 class TestRepositoryCompare:
171 class TestRepositoryCompare:
172
172
173 @pytest.mark.parametrize('merge', [True, False])
173 @pytest.mark.parametrize('merge', [True, False])
174 def test_compare_commits_of_same_repository(self, vcsbackend, merge):
174 def test_compare_commits_of_same_repository(self, vcsbackend, merge):
175 target_repo = vcsbackend.create_repo(number_of_commits=5)
175 target_repo = vcsbackend.create_repo(number_of_commits=5)
176 target_repo.compare(
176 target_repo.compare(
177 target_repo[1].raw_id, target_repo[3].raw_id, target_repo,
177 target_repo[1].raw_id, target_repo[3].raw_id, target_repo,
178 merge=merge)
178 merge=merge)
179
179
180 @pytest.mark.xfail_backends('svn')
180 @pytest.mark.xfail_backends('svn')
181 @pytest.mark.parametrize('merge', [True, False])
181 @pytest.mark.parametrize('merge', [True, False])
182 def test_compare_cloned_repositories(self, vcsbackend, merge):
182 def test_compare_cloned_repositories(self, vcsbackend, merge):
183 target_repo = vcsbackend.create_repo(number_of_commits=5)
183 target_repo = vcsbackend.create_repo(number_of_commits=5)
184 source_repo = vcsbackend.clone_repo(target_repo)
184 source_repo = vcsbackend.clone_repo(target_repo)
185 assert target_repo != source_repo
185 assert target_repo != source_repo
186
186
187 vcsbackend.add_file(source_repo, 'newfile', 'somecontent')
187 vcsbackend.add_file(source_repo, 'newfile', 'somecontent')
188 source_commit = source_repo.get_commit()
188 source_commit = source_repo.get_commit()
189
189
190 target_repo.compare(
190 target_repo.compare(
191 target_repo[1].raw_id, source_repo[3].raw_id, source_repo,
191 target_repo[1].raw_id, source_repo[3].raw_id, source_repo,
192 merge=merge)
192 merge=merge)
193
193
194 @pytest.mark.xfail_backends('svn')
194 @pytest.mark.xfail_backends('svn')
195 @pytest.mark.parametrize('merge', [True, False])
195 @pytest.mark.parametrize('merge', [True, False])
196 def test_compare_unrelated_repositories(self, vcsbackend, merge):
196 def test_compare_unrelated_repositories(self, vcsbackend, merge):
197 orig = vcsbackend.create_repo(number_of_commits=5)
197 orig = vcsbackend.create_repo(number_of_commits=5)
198 unrelated = vcsbackend.create_repo(number_of_commits=5)
198 unrelated = vcsbackend.create_repo(number_of_commits=5)
199 assert orig != unrelated
199 assert orig != unrelated
200
200
201 orig.compare(
201 orig.compare(
202 orig[1].raw_id, unrelated[3].raw_id, unrelated, merge=merge)
202 orig[1].raw_id, unrelated[3].raw_id, unrelated, merge=merge)
203
203
204
204
205 class TestRepositoryGetCommonAncestor:
205 class TestRepositoryGetCommonAncestor:
206
206
207 def test_get_common_ancestor_from_same_repo_existing(self, vcsbackend):
207 def test_get_common_ancestor_from_same_repo_existing(self, vcsbackend):
208 target_repo = vcsbackend.create_repo(number_of_commits=5)
208 target_repo = vcsbackend.create_repo(number_of_commits=5)
209
209
210 expected_ancestor = target_repo[2].raw_id
210 expected_ancestor = target_repo[2].raw_id
211
211
212 assert target_repo.get_common_ancestor(
212 assert target_repo.get_common_ancestor(
213 commit_id1=target_repo[2].raw_id,
213 commit_id1=target_repo[2].raw_id,
214 commit_id2=target_repo[4].raw_id,
214 commit_id2=target_repo[4].raw_id,
215 repo2=target_repo
215 repo2=target_repo
216 ) == expected_ancestor
216 ) == expected_ancestor
217
217
218 assert target_repo.get_common_ancestor(
218 assert target_repo.get_common_ancestor(
219 commit_id1=target_repo[4].raw_id,
219 commit_id1=target_repo[4].raw_id,
220 commit_id2=target_repo[2].raw_id,
220 commit_id2=target_repo[2].raw_id,
221 repo2=target_repo
221 repo2=target_repo
222 ) == expected_ancestor
222 ) == expected_ancestor
223
223
224 @pytest.mark.xfail_backends("svn")
224 @pytest.mark.xfail_backends("svn")
225 def test_get_common_ancestor_from_cloned_repo_existing(self, vcsbackend):
225 def test_get_common_ancestor_from_cloned_repo_existing(self, vcsbackend):
226 target_repo = vcsbackend.create_repo(number_of_commits=5)
226 target_repo = vcsbackend.create_repo(number_of_commits=5)
227 source_repo = vcsbackend.clone_repo(target_repo)
227 source_repo = vcsbackend.clone_repo(target_repo)
228 assert target_repo != source_repo
228 assert target_repo != source_repo
229
229
230 vcsbackend.add_file(source_repo, 'newfile', 'somecontent')
230 vcsbackend.add_file(source_repo, 'newfile', 'somecontent')
231 source_commit = source_repo.get_commit()
231 source_commit = source_repo.get_commit()
232
232
233 expected_ancestor = target_repo[4].raw_id
233 expected_ancestor = target_repo[4].raw_id
234
234
235 assert target_repo.get_common_ancestor(
235 assert target_repo.get_common_ancestor(
236 commit_id1=target_repo[4].raw_id,
236 commit_id1=target_repo[4].raw_id,
237 commit_id2=source_commit.raw_id,
237 commit_id2=source_commit.raw_id,
238 repo2=source_repo
238 repo2=source_repo
239 ) == expected_ancestor
239 ) == expected_ancestor
240
240
241 assert target_repo.get_common_ancestor(
241 assert target_repo.get_common_ancestor(
242 commit_id1=source_commit.raw_id,
242 commit_id1=source_commit.raw_id,
243 commit_id2=target_repo[4].raw_id,
243 commit_id2=target_repo[4].raw_id,
244 repo2=target_repo
244 repo2=target_repo
245 ) == expected_ancestor
245 ) == expected_ancestor
246
246
247 @pytest.mark.xfail_backends("svn")
247 @pytest.mark.xfail_backends("svn")
248 def test_get_common_ancestor_from_unrelated_repo_missing(self, vcsbackend):
248 def test_get_common_ancestor_from_unrelated_repo_missing(self, vcsbackend):
249 original = vcsbackend.create_repo(number_of_commits=5)
249 original = vcsbackend.create_repo(number_of_commits=5)
250 unrelated = vcsbackend.create_repo(number_of_commits=5)
250 unrelated = vcsbackend.create_repo(number_of_commits=5)
251 assert original != unrelated
251 assert original != unrelated
252
252
253 assert original.get_common_ancestor(
253 assert original.get_common_ancestor(
254 commit_id1=original[0].raw_id,
254 commit_id1=original[0].raw_id,
255 commit_id2=unrelated[0].raw_id,
255 commit_id2=unrelated[0].raw_id,
256 repo2=unrelated
256 repo2=unrelated
257 ) == None
257 ) == None
258
258
259 assert original.get_common_ancestor(
259 assert original.get_common_ancestor(
260 commit_id1=original[-1].raw_id,
260 commit_id1=original[-1].raw_id,
261 commit_id2=unrelated[-1].raw_id,
261 commit_id2=unrelated[-1].raw_id,
262 repo2=unrelated
262 repo2=unrelated
263 ) == None
263 ) == None
264
264
265
265
266 @pytest.mark.backends("git", "hg")
266 @pytest.mark.backends("git", "hg")
267 class TestRepositoryMerge:
267 class TestRepositoryMerge:
268 def prepare_for_success(self, vcsbackend):
268 def prepare_for_success(self, vcsbackend):
269 self.target_repo = vcsbackend.create_repo(number_of_commits=1)
269 self.target_repo = vcsbackend.create_repo(number_of_commits=1)
270 self.source_repo = vcsbackend.clone_repo(self.target_repo)
270 self.source_repo = vcsbackend.clone_repo(self.target_repo)
271 vcsbackend.add_file(self.target_repo, 'README_MERGE1', 'Version 1')
271 vcsbackend.add_file(self.target_repo, 'README_MERGE1', 'Version 1')
272 vcsbackend.add_file(self.source_repo, 'README_MERGE2', 'Version 2')
272 vcsbackend.add_file(self.source_repo, 'README_MERGE2', 'Version 2')
273 imc = self.source_repo.in_memory_commit
273 imc = self.source_repo.in_memory_commit
274 imc.add(FileNode('file_x', content=self.source_repo.name))
274 imc.add(FileNode('file_x', content=self.source_repo.name))
275 imc.commit(
275 imc.commit(
276 message=u'Automatic commit from repo merge test',
276 message=u'Automatic commit from repo merge test',
277 author=u'Automatic')
277 author=u'Automatic')
278 self.target_commit = self.target_repo.get_commit()
278 self.target_commit = self.target_repo.get_commit()
279 self.source_commit = self.source_repo.get_commit()
279 self.source_commit = self.source_repo.get_commit()
280 # This only works for Git and Mercurial
280 # This only works for Git and Mercurial
281 default_branch = self.target_repo.DEFAULT_BRANCH_NAME
281 default_branch = self.target_repo.DEFAULT_BRANCH_NAME
282 self.target_ref = Reference(
282 self.target_ref = Reference(
283 'branch', default_branch, self.target_commit.raw_id)
283 'branch', default_branch, self.target_commit.raw_id)
284 self.source_ref = Reference(
284 self.source_ref = Reference(
285 'branch', default_branch, self.source_commit.raw_id)
285 'branch', default_branch, self.source_commit.raw_id)
286 self.workspace = 'test-merge'
286 self.workspace = 'test-merge'
287
287
288 def prepare_for_conflict(self, vcsbackend):
288 def prepare_for_conflict(self, vcsbackend):
289 self.target_repo = vcsbackend.create_repo(number_of_commits=1)
289 self.target_repo = vcsbackend.create_repo(number_of_commits=1)
290 self.source_repo = vcsbackend.clone_repo(self.target_repo)
290 self.source_repo = vcsbackend.clone_repo(self.target_repo)
291 vcsbackend.add_file(self.target_repo, 'README_MERGE', 'Version 1')
291 vcsbackend.add_file(self.target_repo, 'README_MERGE', 'Version 1')
292 vcsbackend.add_file(self.source_repo, 'README_MERGE', 'Version 2')
292 vcsbackend.add_file(self.source_repo, 'README_MERGE', 'Version 2')
293 self.target_commit = self.target_repo.get_commit()
293 self.target_commit = self.target_repo.get_commit()
294 self.source_commit = self.source_repo.get_commit()
294 self.source_commit = self.source_repo.get_commit()
295 # This only works for Git and Mercurial
295 # This only works for Git and Mercurial
296 default_branch = self.target_repo.DEFAULT_BRANCH_NAME
296 default_branch = self.target_repo.DEFAULT_BRANCH_NAME
297 self.target_ref = Reference(
297 self.target_ref = Reference(
298 'branch', default_branch, self.target_commit.raw_id)
298 'branch', default_branch, self.target_commit.raw_id)
299 self.source_ref = Reference(
299 self.source_ref = Reference(
300 'branch', default_branch, self.source_commit.raw_id)
300 'branch', default_branch, self.source_commit.raw_id)
301 self.workspace = 'test-merge'
301 self.workspace = 'test-merge'
302
302
303 def test_merge_success(self, vcsbackend):
303 def test_merge_success(self, vcsbackend):
304 self.prepare_for_success(vcsbackend)
304 self.prepare_for_success(vcsbackend)
305
305
306 merge_response = self.target_repo.merge(
306 merge_response = self.target_repo.merge(
307 self.target_ref, self.source_repo, self.source_ref, self.workspace,
307 self.target_ref, self.source_repo, self.source_ref, self.workspace,
308 'test user', 'test@rhodecode.com', 'merge message 1',
308 'test user', 'test@rhodecode.com', 'merge message 1',
309 dry_run=False)
309 dry_run=False)
310 expected_merge_response = MergeResponse(
310 expected_merge_response = MergeResponse(
311 True, True, merge_response.merge_ref,
311 True, True, merge_response.merge_ref,
312 MergeFailureReason.NONE)
312 MergeFailureReason.NONE)
313 assert merge_response == expected_merge_response
313 assert merge_response == expected_merge_response
314
314
315 target_repo = backends.get_backend(vcsbackend.alias)(
315 target_repo = backends.get_backend(vcsbackend.alias)(
316 self.target_repo.path)
316 self.target_repo.path)
317 target_commits = list(target_repo.get_commits())
317 target_commits = list(target_repo.get_commits())
318 commit_ids = [c.raw_id for c in target_commits[:-1]]
318 commit_ids = [c.raw_id for c in target_commits[:-1]]
319 assert self.source_ref.commit_id in commit_ids
319 assert self.source_ref.commit_id in commit_ids
320 assert self.target_ref.commit_id in commit_ids
320 assert self.target_ref.commit_id in commit_ids
321
321
322 merge_commit = target_commits[-1]
322 merge_commit = target_commits[-1]
323 assert merge_commit.raw_id == merge_response.merge_ref.commit_id
323 assert merge_commit.raw_id == merge_response.merge_ref.commit_id
324 assert merge_commit.message.strip() == 'merge message 1'
324 assert merge_commit.message.strip() == 'merge message 1'
325 assert merge_commit.author == 'test user <test@rhodecode.com>'
325 assert merge_commit.author == 'test user <test@rhodecode.com>'
326
326
327 # We call it twice so to make sure we can handle updates
327 # We call it twice so to make sure we can handle updates
328 target_ref = Reference(
328 target_ref = Reference(
329 self.target_ref.type, self.target_ref.name,
329 self.target_ref.type, self.target_ref.name,
330 merge_response.merge_ref.commit_id)
330 merge_response.merge_ref.commit_id)
331
331
332 merge_response = target_repo.merge(
332 merge_response = target_repo.merge(
333 target_ref, self.source_repo, self.source_ref, self.workspace,
333 target_ref, self.source_repo, self.source_ref, self.workspace,
334 'test user', 'test@rhodecode.com', 'merge message 2',
334 'test user', 'test@rhodecode.com', 'merge message 2',
335 dry_run=False)
335 dry_run=False)
336 expected_merge_response = MergeResponse(
336 expected_merge_response = MergeResponse(
337 True, True, merge_response.merge_ref,
337 True, True, merge_response.merge_ref,
338 MergeFailureReason.NONE)
338 MergeFailureReason.NONE)
339 assert merge_response == expected_merge_response
339 assert merge_response == expected_merge_response
340
340
341 target_repo = backends.get_backend(
341 target_repo = backends.get_backend(
342 vcsbackend.alias)(self.target_repo.path)
342 vcsbackend.alias)(self.target_repo.path)
343 merge_commit = target_repo.get_commit(
343 merge_commit = target_repo.get_commit(
344 merge_response.merge_ref.commit_id)
344 merge_response.merge_ref.commit_id)
345 assert merge_commit.message.strip() == 'merge message 1'
345 assert merge_commit.message.strip() == 'merge message 1'
346 assert merge_commit.author == 'test user <test@rhodecode.com>'
346 assert merge_commit.author == 'test user <test@rhodecode.com>'
347
347
348 def test_merge_success_dry_run(self, vcsbackend):
348 def test_merge_success_dry_run(self, vcsbackend):
349 self.prepare_for_success(vcsbackend)
349 self.prepare_for_success(vcsbackend)
350
350
351 merge_response = self.target_repo.merge(
351 merge_response = self.target_repo.merge(
352 self.target_ref, self.source_repo, self.source_ref, self.workspace,
352 self.target_ref, self.source_repo, self.source_ref, self.workspace,
353 dry_run=True)
353 dry_run=True)
354
354
355 # We call it twice so to make sure we can handle updates
355 # We call it twice so to make sure we can handle updates
356 merge_response_update = self.target_repo.merge(
356 merge_response_update = self.target_repo.merge(
357 self.target_ref, self.source_repo, self.source_ref, self.workspace,
357 self.target_ref, self.source_repo, self.source_ref, self.workspace,
358 dry_run=True)
358 dry_run=True)
359
359
360 # Multiple merges may differ in their commit id. Therefore we set the
361 # commit id to `None` before comparing the merge responses.
362 merge_response = merge_response._replace(
363 merge_ref=merge_response.merge_ref._replace(commit_id=None))
364 merge_response_update = merge_response_update._replace(
365 merge_ref=merge_response_update.merge_ref._replace(commit_id=None))
366
360 assert merge_response == merge_response_update
367 assert merge_response == merge_response_update
361 assert merge_response.possible is True
368 assert merge_response.possible is True
362 assert merge_response.executed is False
369 assert merge_response.executed is False
363 assert merge_response.merge_ref
370 assert merge_response.merge_ref
364 assert merge_response.failure_reason is MergeFailureReason.NONE
371 assert merge_response.failure_reason is MergeFailureReason.NONE
365
372
366 @pytest.mark.parametrize('dry_run', [True, False])
373 @pytest.mark.parametrize('dry_run', [True, False])
367 def test_merge_conflict(self, vcsbackend, dry_run):
374 def test_merge_conflict(self, vcsbackend, dry_run):
368 self.prepare_for_conflict(vcsbackend)
375 self.prepare_for_conflict(vcsbackend)
369 expected_merge_response = MergeResponse(
376 expected_merge_response = MergeResponse(
370 False, False, None, MergeFailureReason.MERGE_FAILED)
377 False, False, None, MergeFailureReason.MERGE_FAILED)
371
378
372 merge_response = self.target_repo.merge(
379 merge_response = self.target_repo.merge(
373 self.target_ref, self.source_repo, self.source_ref, self.workspace,
380 self.target_ref, self.source_repo, self.source_ref, self.workspace,
374 'test_user', 'test@rhodecode.com', 'test message', dry_run=dry_run)
381 'test_user', 'test@rhodecode.com', 'test message', dry_run=dry_run)
375 assert merge_response == expected_merge_response
382 assert merge_response == expected_merge_response
376
383
377 # We call it twice so to make sure we can handle updates
384 # We call it twice so to make sure we can handle updates
378 merge_response = self.target_repo.merge(
385 merge_response = self.target_repo.merge(
379 self.target_ref, self.source_repo, self.source_ref, self.workspace,
386 self.target_ref, self.source_repo, self.source_ref, self.workspace,
380 'test_user', 'test@rhodecode.com', 'test message', dry_run=dry_run)
387 'test_user', 'test@rhodecode.com', 'test message', dry_run=dry_run)
381 assert merge_response == expected_merge_response
388 assert merge_response == expected_merge_response
382
389
383 def test_merge_target_is_not_head(self, vcsbackend):
390 def test_merge_target_is_not_head(self, vcsbackend):
384 self.prepare_for_success(vcsbackend)
391 self.prepare_for_success(vcsbackend)
385 expected_merge_response = MergeResponse(
392 expected_merge_response = MergeResponse(
386 False, False, None, MergeFailureReason.TARGET_IS_NOT_HEAD)
393 False, False, None, MergeFailureReason.TARGET_IS_NOT_HEAD)
387
394
388 target_ref = Reference(
395 target_ref = Reference(
389 self.target_ref.type, self.target_ref.name, '0' * 40)
396 self.target_ref.type, self.target_ref.name, '0' * 40)
390
397
391 merge_response = self.target_repo.merge(
398 merge_response = self.target_repo.merge(
392 target_ref, self.source_repo, self.source_ref, self.workspace,
399 target_ref, self.source_repo, self.source_ref, self.workspace,
393 dry_run=True)
400 dry_run=True)
394
401
395 assert merge_response == expected_merge_response
402 assert merge_response == expected_merge_response
396
403
397 def test_merge_missing_commit(self, vcsbackend):
404 def test_merge_missing_commit(self, vcsbackend):
398 self.prepare_for_success(vcsbackend)
405 self.prepare_for_success(vcsbackend)
399 expected_merge_response = MergeResponse(
406 expected_merge_response = MergeResponse(
400 False, False, None, MergeFailureReason.MISSING_COMMIT)
407 False, False, None, MergeFailureReason.MISSING_COMMIT)
401
408
402 source_ref = Reference(
409 source_ref = Reference(
403 self.source_ref.type, 'not_existing', self.source_ref.commit_id)
410 self.source_ref.type, 'not_existing', self.source_ref.commit_id)
404
411
405 merge_response = self.target_repo.merge(
412 merge_response = self.target_repo.merge(
406 self.target_ref, self.source_repo, source_ref, self.workspace,
413 self.target_ref, self.source_repo, source_ref, self.workspace,
407 dry_run=True)
414 dry_run=True)
408
415
409 assert merge_response == expected_merge_response
416 assert merge_response == expected_merge_response
410
417
411 def test_merge_raises_exception(self, vcsbackend):
418 def test_merge_raises_exception(self, vcsbackend):
412 self.prepare_for_success(vcsbackend)
419 self.prepare_for_success(vcsbackend)
413 expected_merge_response = MergeResponse(
420 expected_merge_response = MergeResponse(
414 False, False, None, MergeFailureReason.UNKNOWN)
421 False, False, None, MergeFailureReason.UNKNOWN)
415
422
416 with mock.patch.object(self.target_repo, '_merge_repo',
423 with mock.patch.object(self.target_repo, '_merge_repo',
417 side_effect=RepositoryError()):
424 side_effect=RepositoryError()):
418 merge_response = self.target_repo.merge(
425 merge_response = self.target_repo.merge(
419 self.target_ref, self.source_repo, self.source_ref,
426 self.target_ref, self.source_repo, self.source_ref,
420 self.workspace, dry_run=True)
427 self.workspace, dry_run=True)
421
428
422 assert merge_response == expected_merge_response
429 assert merge_response == expected_merge_response
423
430
424 def test_merge_invalid_user_name(self, vcsbackend):
431 def test_merge_invalid_user_name(self, vcsbackend):
425 repo = vcsbackend.create_repo(number_of_commits=1)
432 repo = vcsbackend.create_repo(number_of_commits=1)
426 ref = Reference('branch', 'master', 'not_used')
433 ref = Reference('branch', 'master', 'not_used')
427 with pytest.raises(ValueError):
434 with pytest.raises(ValueError):
428 repo.merge(ref, self, ref, 'workspace_id')
435 repo.merge(ref, self, ref, 'workspace_id')
429
436
430 def test_merge_invalid_user_email(self, vcsbackend):
437 def test_merge_invalid_user_email(self, vcsbackend):
431 repo = vcsbackend.create_repo(number_of_commits=1)
438 repo = vcsbackend.create_repo(number_of_commits=1)
432 ref = Reference('branch', 'master', 'not_used')
439 ref = Reference('branch', 'master', 'not_used')
433 with pytest.raises(ValueError):
440 with pytest.raises(ValueError):
434 repo.merge(ref, self, ref, 'workspace_id', 'user name')
441 repo.merge(ref, self, ref, 'workspace_id', 'user name')
435
442
436 def test_merge_invalid_message(self, vcsbackend):
443 def test_merge_invalid_message(self, vcsbackend):
437 repo = vcsbackend.create_repo(number_of_commits=1)
444 repo = vcsbackend.create_repo(number_of_commits=1)
438 ref = Reference('branch', 'master', 'not_used')
445 ref = Reference('branch', 'master', 'not_used')
439 with pytest.raises(ValueError):
446 with pytest.raises(ValueError):
440 repo.merge(
447 repo.merge(
441 ref, self, ref, 'workspace_id', 'user name', 'user@email.com')
448 ref, self, ref, 'workspace_id', 'user name', 'user@email.com')
442
449
443
450
444 class TestRepositoryStrip(BackendTestMixin):
451 class TestRepositoryStrip(BackendTestMixin):
445 recreate_repo_per_test = True
452 recreate_repo_per_test = True
446
453
447 @classmethod
454 @classmethod
448 def _get_commits(cls):
455 def _get_commits(cls):
449 commits = [
456 commits = [
450 {
457 {
451 'message': 'Initial commit',
458 'message': 'Initial commit',
452 'author': 'Joe Doe <joe.doe@example.com>',
459 'author': 'Joe Doe <joe.doe@example.com>',
453 'date': datetime.datetime(2010, 1, 1, 20),
460 'date': datetime.datetime(2010, 1, 1, 20),
454 'branch': 'master',
461 'branch': 'master',
455 'added': [
462 'added': [
456 FileNode('foobar', content='foobar'),
463 FileNode('foobar', content='foobar'),
457 FileNode('foobar2', content='foobar2'),
464 FileNode('foobar2', content='foobar2'),
458 ],
465 ],
459 },
466 },
460 ]
467 ]
461 for x in xrange(10):
468 for x in xrange(10):
462 commit_data = {
469 commit_data = {
463 'message': 'Changed foobar - commit%s' % x,
470 'message': 'Changed foobar - commit%s' % x,
464 'author': 'Jane Doe <jane.doe@example.com>',
471 'author': 'Jane Doe <jane.doe@example.com>',
465 'date': datetime.datetime(2010, 1, 1, 21, x),
472 'date': datetime.datetime(2010, 1, 1, 21, x),
466 'branch': 'master',
473 'branch': 'master',
467 'changed': [
474 'changed': [
468 FileNode('foobar', 'FOOBAR - %s' % x),
475 FileNode('foobar', 'FOOBAR - %s' % x),
469 ],
476 ],
470 }
477 }
471 commits.append(commit_data)
478 commits.append(commit_data)
472 return commits
479 return commits
473
480
474 @pytest.mark.backends("git", "hg")
481 @pytest.mark.backends("git", "hg")
475 def test_strip_commit(self):
482 def test_strip_commit(self):
476 tip = self.repo.get_commit()
483 tip = self.repo.get_commit()
477 assert tip.idx == 10
484 assert tip.idx == 10
478 self.repo.strip(tip.raw_id, self.repo.DEFAULT_BRANCH_NAME)
485 self.repo.strip(tip.raw_id, self.repo.DEFAULT_BRANCH_NAME)
479
486
480 tip = self.repo.get_commit()
487 tip = self.repo.get_commit()
481 assert tip.idx == 9
488 assert tip.idx == 9
482
489
483 @pytest.mark.backends("git", "hg")
490 @pytest.mark.backends("git", "hg")
484 def test_strip_multiple_commits(self):
491 def test_strip_multiple_commits(self):
485 tip = self.repo.get_commit()
492 tip = self.repo.get_commit()
486 assert tip.idx == 10
493 assert tip.idx == 10
487
494
488 old = self.repo.get_commit(commit_idx=5)
495 old = self.repo.get_commit(commit_idx=5)
489 self.repo.strip(old.raw_id, self.repo.DEFAULT_BRANCH_NAME)
496 self.repo.strip(old.raw_id, self.repo.DEFAULT_BRANCH_NAME)
490
497
491 tip = self.repo.get_commit()
498 tip = self.repo.get_commit()
492 assert tip.idx == 4
499 assert tip.idx == 4
493
500
494
501
495 @pytest.mark.backends('hg', 'git')
502 @pytest.mark.backends('hg', 'git')
496 class TestRepositoryPull:
503 class TestRepositoryPull:
497
504
498 def test_pull(self, vcsbackend):
505 def test_pull(self, vcsbackend):
499 source_repo = vcsbackend.repo
506 source_repo = vcsbackend.repo
500 target_repo = vcsbackend.create_repo()
507 target_repo = vcsbackend.create_repo()
501 assert len(source_repo.commit_ids) > len(target_repo.commit_ids)
508 assert len(source_repo.commit_ids) > len(target_repo.commit_ids)
502
509
503 target_repo.pull(source_repo.path)
510 target_repo.pull(source_repo.path)
504 # Note: Get a fresh instance, avoids caching trouble
511 # Note: Get a fresh instance, avoids caching trouble
505 target_repo = vcsbackend.backend(target_repo.path)
512 target_repo = vcsbackend.backend(target_repo.path)
506 assert len(source_repo.commit_ids) == len(target_repo.commit_ids)
513 assert len(source_repo.commit_ids) == len(target_repo.commit_ids)
507
514
508 def test_pull_wrong_path(self, vcsbackend):
515 def test_pull_wrong_path(self, vcsbackend):
509 target_repo = vcsbackend.create_repo()
516 target_repo = vcsbackend.create_repo()
510 with pytest.raises(RepositoryError):
517 with pytest.raises(RepositoryError):
511 target_repo.pull(target_repo.path + "wrong")
518 target_repo.pull(target_repo.path + "wrong")
512
519
513 def test_pull_specific_commits(self, vcsbackend):
520 def test_pull_specific_commits(self, vcsbackend):
514 source_repo = vcsbackend.repo
521 source_repo = vcsbackend.repo
515 target_repo = vcsbackend.create_repo()
522 target_repo = vcsbackend.create_repo()
516
523
517 second_commit = source_repo[1].raw_id
524 second_commit = source_repo[1].raw_id
518 if vcsbackend.alias == 'git':
525 if vcsbackend.alias == 'git':
519 second_commit_ref = 'refs/test-refs/a'
526 second_commit_ref = 'refs/test-refs/a'
520 source_repo.set_refs(second_commit_ref, second_commit)
527 source_repo.set_refs(second_commit_ref, second_commit)
521
528
522 target_repo.pull(source_repo.path, commit_ids=[second_commit])
529 target_repo.pull(source_repo.path, commit_ids=[second_commit])
523 target_repo = vcsbackend.backend(target_repo.path)
530 target_repo = vcsbackend.backend(target_repo.path)
524 assert 2 == len(target_repo.commit_ids)
531 assert 2 == len(target_repo.commit_ids)
525 assert second_commit == target_repo.get_commit().raw_id
532 assert second_commit == target_repo.get_commit().raw_id
General Comments 0
You need to be logged in to leave comments. Login now