##// END OF EJS Templates
shadow-repos: use numeric repo id for creation of shadow repos....
marcink -
r2810:a15bd3a8 default
parent child Browse files
Show More
@@ -302,7 +302,7 b' def merge_pull_request('
302 302 request.environ, repo_name=target_repo.repo_name,
303 303 username=apiuser.username, action='push',
304 304 scm=target_repo.repo_type)
305 merge_response = PullRequestModel().merge(
305 merge_response = PullRequestModel().merge_repo(
306 306 pull_request, apiuser, extras=extras)
307 307 if merge_response.executed:
308 308 PullRequestModel().close_pull_request(
@@ -618,7 +618,7 b' class TestPullrequestsView(object):'
618 618
619 619 model_patcher = mock.patch.multiple(
620 620 PullRequestModel,
621 merge=mock.Mock(return_value=MergeResponse(
621 merge_repo=mock.Mock(return_value=MergeResponse(
622 622 True, False, 'STUB_COMMIT_ID', MergeFailureReason.PUSH_FAILED)),
623 623 merge_status=mock.Mock(return_value=(True, 'WRONG_MESSAGE')))
624 624
@@ -340,7 +340,8 b' class RepoPullRequestsView(RepoAppView, '
340 340 # check merge capabilities
341 341 _merge_check = MergeCheck.validate(
342 342 pull_request_latest, user=self._rhodecode_user,
343 translator=self.request.translate, force_shadow_repo_refresh=force_refresh)
343 translator=self.request.translate,
344 force_shadow_repo_refresh=force_refresh)
344 345 c.pr_merge_errors = _merge_check.error_details
345 346 c.pr_merge_possible = not _merge_check.failed
346 347 c.pr_merge_message = _merge_check.merge_msg
@@ -1063,7 +1064,7 b' class RepoPullRequestsView(RepoAppView, '
1063 1064
1064 1065 def _merge_pull_request(self, pull_request, user, extras):
1065 1066 _ = self.request.translate
1066 merge_resp = PullRequestModel().merge(pull_request, user, extras=extras)
1067 merge_resp = PullRequestModel().merge_repo(pull_request, user, extras=extras)
1067 1068
1068 1069 if merge_resp.executed:
1069 1070 log.debug("The merge was successful, closing the pull request.")
@@ -204,13 +204,14 b' class SimpleVCS(object):'
204 204
205 205 # Only proceed if we got a pull request and if acl repo name from
206 206 # URL equals the target repo name of the pull request.
207 if pull_request and (acl_repo_name ==
208 pull_request.target_repo.repo_name):
207 if pull_request and \
208 (acl_repo_name == pull_request.target_repo.repo_name):
209 repo_id = pull_request.target_repo.repo_id
209 210 # Get file system path to shadow repository.
210 211 workspace_id = PullRequestModel()._workspace_id(pull_request)
211 212 target_vcs = pull_request.target_repo.scm_instance()
212 213 vcs_repo_name = target_vcs._get_shadow_repository_path(
213 workspace_id)
214 repo_id, workspace_id)
214 215
215 216 # Store names for later usage.
216 217 self.vcs_repo_name = vcs_repo_name
@@ -451,7 +451,7 b' class BaseRepository(object):'
451 451 """
452 452 raise NotImplementedError
453 453
454 def merge(self, target_ref, source_repo, source_ref, workspace_id,
454 def merge(self, repo_id, workspace_id, target_ref, source_repo, source_ref,
455 455 user_name='', user_email='', message='', dry_run=False,
456 456 use_rebase=False, close_branch=False):
457 457 """
@@ -465,13 +465,14 b' class BaseRepository(object):'
465 465 'possible', 'executed', 'source_commit', 'target_commit',
466 466 'merge_commit'.
467 467
468 :param repo_id: `repo_id` target repo id.
469 :param workspace_id: `workspace_id` unique identifier.
468 470 :param target_ref: `target_ref` points to the commit on top of which
469 471 the `source_ref` should be merged.
470 472 :param source_repo: The repository that contains the commits to be
471 473 merged.
472 474 :param source_ref: `source_ref` points to the topmost commit from
473 475 the `source_repo` which should be merged.
474 :param workspace_id: `workspace_id` unique identifier.
475 476 :param user_name: Merge commit `user_name`.
476 477 :param user_email: Merge commit `user_email`.
477 478 :param message: Merge commit `message`.
@@ -492,12 +493,9 b' class BaseRepository(object):'
492 493 if not message:
493 494 raise ValueError('message cannot be empty')
494 495
495 shadow_repository_path = self._maybe_prepare_merge_workspace(
496 workspace_id, target_ref, source_ref)
497
498 496 try:
499 497 return self._merge_repo(
500 shadow_repository_path, target_ref, source_repo,
498 repo_id, workspace_id, target_ref, source_repo,
501 499 source_ref, message, user_name, user_email, dry_run=dry_run,
502 500 use_rebase=use_rebase, close_branch=close_branch)
503 501 except RepositoryError:
@@ -507,14 +505,15 b' class BaseRepository(object):'
507 505 return MergeResponse(
508 506 False, False, None, MergeFailureReason.UNKNOWN)
509 507
510 def _merge_repo(self, shadow_repository_path, target_ref,
508 def _merge_repo(self, repo_id, workspace_id, target_ref,
511 509 source_repo, source_ref, merge_message,
512 510 merger_name, merger_email, dry_run=False,
513 511 use_rebase=False, close_branch=False):
514 512 """Internal implementation of merge."""
515 513 raise NotImplementedError
516 514
517 def _maybe_prepare_merge_workspace(self, workspace_id, target_ref, source_ref):
515 def _maybe_prepare_merge_workspace(
516 self, repo_id, workspace_id, target_ref, source_ref):
518 517 """
519 518 Create the merge workspace.
520 519
@@ -522,10 +521,27 b' class BaseRepository(object):'
522 521 """
523 522 raise NotImplementedError
524 523
525 def _get_shadow_repository_path(self, workspace_id):
526 raise NotImplementedError
524 def _get_legacy_shadow_repository_path(self, workspace_id):
525 """
526 Legacy version that was used before. We still need it for
527 backward compat
528 """
529 return os.path.join(
530 os.path.dirname(self.path),
531 '.__shadow_%s_%s' % (os.path.basename(self.path), workspace_id))
527 532
528 def cleanup_merge_workspace(self, workspace_id):
533 def _get_shadow_repository_path(self, repo_id, workspace_id):
534 # The name of the shadow repository must start with '.', so it is
535 # skipped by 'rhodecode.lib.utils.get_filesystem_repos'.
536 legacy_repository_path = self._get_legacy_shadow_repository_path(workspace_id)
537 if os.path.exists(legacy_repository_path):
538 return legacy_repository_path
539 else:
540 return os.path.join(
541 os.path.dirname(self.path),
542 '.__shadow_repo_%s_%s' % (repo_id, workspace_id))
543
544 def cleanup_merge_workspace(self, repo_id, workspace_id):
529 545 """
530 546 Remove merge workspace.
531 547
@@ -534,7 +550,7 b' class BaseRepository(object):'
534 550
535 551 :param workspace_id: `workspace_id` unique identifier.
536 552 """
537 shadow_repository_path = self._get_shadow_repository_path(workspace_id)
553 shadow_repository_path = self._get_shadow_repository_path(repo_id, workspace_id)
538 554 shadow_repository_path_del = '{}.{}.delete'.format(
539 555 shadow_repository_path, time.time())
540 556
@@ -902,7 +902,19 b' class GitRepository(BaseRepository):'
902 902
903 903 return '%s%d' % (prefix, branch_id)
904 904
905 def _merge_repo(self, shadow_repository_path, target_ref,
905 def _maybe_prepare_merge_workspace(
906 self, repo_id, workspace_id, target_ref, source_ref):
907 shadow_repository_path = self._get_shadow_repository_path(
908 repo_id, workspace_id)
909 if not os.path.exists(shadow_repository_path):
910 self._local_clone(
911 shadow_repository_path, target_ref.name, source_ref.name)
912 log.debug(
913 'Prepared shadow repository in %s', shadow_repository_path)
914
915 return shadow_repository_path
916
917 def _merge_repo(self, repo_id, workspace_id, target_ref,
906 918 source_repo, source_ref, merge_message,
907 919 merger_name, merger_email, dry_run=False,
908 920 use_rebase=False, close_branch=False):
@@ -912,7 +924,10 b' class GitRepository(BaseRepository):'
912 924 return MergeResponse(
913 925 False, False, None, MergeFailureReason.TARGET_IS_NOT_HEAD)
914 926
915 shadow_repo = GitRepository(shadow_repository_path)
927 shadow_repository_path = self._maybe_prepare_merge_workspace(
928 repo_id, workspace_id, target_ref, source_ref)
929 shadow_repo = self._get_shadow_instance(shadow_repository_path)
930
916 931 # checkout source, if it's different. Otherwise we could not
917 932 # fetch proper commits for merge testing
918 933 if source_ref.name != target_ref.name:
@@ -929,7 +944,7 b' class GitRepository(BaseRepository):'
929 944
930 945 # Need to reload repo to invalidate the cache, or otherwise we cannot
931 946 # retrieve the last target commit.
932 shadow_repo = GitRepository(shadow_repository_path)
947 shadow_repo = self._get_shadow_instance(shadow_repository_path)
933 948 if target_ref.commit_id != shadow_repo.branches[target_ref.name]:
934 949 log.warning('Shadow Target ref %s commit mismatch %s vs %s',
935 950 target_ref, target_ref.commit_id,
@@ -989,18 +1004,3 b' class GitRepository(BaseRepository):'
989 1004 return MergeResponse(
990 1005 merge_possible, merge_succeeded, merge_ref,
991 1006 merge_failure_reason)
992
993 def _get_shadow_repository_path(self, workspace_id):
994 # The name of the shadow repository must start with '.', so it is
995 # skipped by 'rhodecode.lib.utils.get_filesystem_repos'.
996 return os.path.join(
997 os.path.dirname(self.path),
998 '.__shadow_%s_%s' % (os.path.basename(self.path), workspace_id))
999
1000 def _maybe_prepare_merge_workspace(self, workspace_id, target_ref, source_ref):
1001 shadow_repository_path = self._get_shadow_repository_path(workspace_id)
1002 if not os.path.exists(shadow_repository_path):
1003 self._local_clone(
1004 shadow_repository_path, target_ref.name, source_ref.name)
1005
1006 return shadow_repository_path
@@ -681,15 +681,10 b' class MercurialRepository(BaseRepository'
681 681 return ref.name
682 682 return self._remote.ctx_branch(ref.commit_id)
683 683
684 def _get_shadow_repository_path(self, workspace_id):
685 # The name of the shadow repository must start with '.', so it is
686 # skipped by 'rhodecode.lib.utils.get_filesystem_repos'.
687 return os.path.join(
688 os.path.dirname(self.path),
689 '.__shadow_%s_%s' % (os.path.basename(self.path), workspace_id))
690
691 def _maybe_prepare_merge_workspace(self, workspace_id, unused_target_ref, unused_source_ref):
692 shadow_repository_path = self._get_shadow_repository_path(workspace_id)
684 def _maybe_prepare_merge_workspace(
685 self, repo_id, workspace_id, unused_target_ref, unused_source_ref):
686 shadow_repository_path = self._get_shadow_repository_path(
687 repo_id, workspace_id)
693 688 if not os.path.exists(shadow_repository_path):
694 689 self._local_clone(shadow_repository_path)
695 690 log.debug(
@@ -697,7 +692,7 b' class MercurialRepository(BaseRepository'
697 692
698 693 return shadow_repository_path
699 694
700 def _merge_repo(self, shadow_repository_path, target_ref,
695 def _merge_repo(self, repo_id, workspace_id, target_ref,
701 696 source_repo, source_ref, merge_message,
702 697 merger_name, merger_email, dry_run=False,
703 698 use_rebase=False, close_branch=False):
@@ -719,6 +714,8 b' class MercurialRepository(BaseRepository'
719 714 return MergeResponse(
720 715 False, False, None, MergeFailureReason.MISSING_TARGET_REF)
721 716
717 shadow_repository_path = self._maybe_prepare_merge_workspace(
718 repo_id, workspace_id, target_ref, source_ref)
722 719 shadow_repo = self._get_shadow_instance(shadow_repository_path)
723 720
724 721 log.debug('Pulling in target reference %s', target_ref)
@@ -1883,6 +1883,12 b' class Repository(Base, BaseModel):'
1883 1883 return os.listdir(diff_cache_dir)
1884 1884 return []
1885 1885
1886 def shadow_repos(self):
1887 shadow_repos_pattern = '.__shadow_repo_{}'.format(self.repo_id)
1888 return [
1889 x for x in os.listdir(os.path.dirname(self.repo_full_path))
1890 if x.startswith(shadow_repos_pattern)]
1891
1886 1892 def get_new_name(self, repo_name):
1887 1893 """
1888 1894 returns new full repository name based on assigned group and new new
@@ -3762,7 +3768,7 b' class PullRequest(Base, _PullRequestBase'
3762 3768 workspace_id = self.workspace_id
3763 3769 vcs_obj = self.target_repo.scm_instance()
3764 3770 shadow_repository_path = vcs_obj._get_shadow_repository_path(
3765 workspace_id)
3771 self.target_repo.repo_id, workspace_id)
3766 3772 if os.path.isdir(shadow_repository_path):
3767 3773 return vcs_obj._get_shadow_instance(shadow_repository_path)
3768 3774
@@ -583,7 +583,7 b' class PullRequestModel(BaseModel):'
583 583
584 584 return commit_ids
585 585
586 def merge(self, pull_request, user, extras):
586 def merge_repo(self, pull_request, user, extras):
587 587 log.debug("Merging pull request %s", pull_request.pull_request_id)
588 588 merge_state = self._merge_pull_request(pull_request, user, extras)
589 589 if merge_state.executed:
@@ -616,6 +616,7 b' class PullRequestModel(BaseModel):'
616 616 }
617 617
618 618 workspace_id = self._workspace_id(pull_request)
619 repo_id = pull_request.target_repo.repo_id
619 620 use_rebase = self._use_rebase_for_merging(pull_request)
620 621 close_branch = self._close_branch_before_merging(pull_request)
621 622
@@ -629,9 +630,10 b' class PullRequestModel(BaseModel):'
629 630 target_vcs.config.set(
630 631 'rhodecode', 'RC_SCM_DATA', json.dumps(extras))
631 632 merge_state = target_vcs.merge(
632 target_ref, source_vcs, pull_request.source_ref_parts,
633 workspace_id, user_name=user.username,
634 user_email=user.email, message=message, use_rebase=use_rebase,
633 repo_id, workspace_id, target_ref, source_vcs,
634 pull_request.source_ref_parts,
635 user_name=user.username, user_email=user.email,
636 message=message, use_rebase=use_rebase,
635 637 close_branch=close_branch)
636 638 return merge_state
637 639
@@ -1328,11 +1330,13 b' class PullRequestModel(BaseModel):'
1328 1330 def _refresh_merge_state(self, pull_request, target_vcs, target_reference):
1329 1331 workspace_id = self._workspace_id(pull_request)
1330 1332 source_vcs = pull_request.source_repo.scm_instance()
1333 repo_id = pull_request.target_repo.repo_id
1331 1334 use_rebase = self._use_rebase_for_merging(pull_request)
1332 1335 close_branch = self._close_branch_before_merging(pull_request)
1333 1336 merge_state = target_vcs.merge(
1337 repo_id, workspace_id,
1334 1338 target_reference, source_vcs, pull_request.source_ref_parts,
1335 workspace_id, dry_run=True, use_rebase=use_rebase,
1339 dry_run=True, use_rebase=use_rebase,
1336 1340 close_branch=close_branch)
1337 1341
1338 1342 # Do not store the response if there was an unknown error.
@@ -1398,11 +1402,12 b' class PullRequestModel(BaseModel):'
1398 1402
1399 1403 def _cleanup_merge_workspace(self, pull_request):
1400 1404 # Merging related cleanup
1405 repo_id = pull_request.target_repo.repo_id
1401 1406 target_scm = pull_request.target_repo.scm_instance()
1402 workspace_id = 'pr-%s' % pull_request.pull_request_id
1407 workspace_id = self._workspace_id(pull_request)
1403 1408
1404 1409 try:
1405 target_scm.cleanup_merge_workspace(workspace_id)
1410 target_scm.cleanup_merge_workspace(repo_id, workspace_id)
1406 1411 except NotImplementedError:
1407 1412 pass
1408 1413
@@ -116,6 +116,13 b' def get_new_dir(title):'
116 116 return get_normalized_path(path)
117 117
118 118
119 def repo_id_generator(name):
120 numeric_hash = 0
121 for char in name:
122 numeric_hash += (ord(char))
123 return numeric_hash
124
125
119 126 @pytest.mark.usefixtures('app', 'index_location')
120 127 class TestController(object):
121 128
@@ -333,7 +333,7 b' class TestShadowRepoExposure(object):'
333 333 workspace_id = PullRequestModel()._workspace_id(pull_request)
334 334 target_vcs = pull_request.target_repo.scm_instance()
335 335 vcs_repo_name = target_vcs._get_shadow_repository_path(
336 workspace_id)
336 pull_request.target_repo.repo_id, workspace_id)
337 337
338 338 assert controller.vcs_repo_name == vcs_repo_name
339 339 assert controller.url_repo_name == shadow_url
@@ -81,6 +81,7 b' class TestPullRequestModel(object):'
81 81 self.source_commit = self.pull_request.source_ref_parts.commit_id
82 82 self.target_commit = self.pull_request.target_ref_parts.commit_id
83 83 self.workspace_id = 'pr-%s' % self.pull_request.pull_request_id
84 self.repo_id = self.pull_request.target_repo.repo_id
84 85
85 86 @request.addfinalizer
86 87 def cleanup_pull_request():
@@ -135,17 +136,19 b' class TestPullRequestModel(object):'
135 136 assert pr_count == 1
136 137
137 138 def test_delete_calls_cleanup_merge(self, pull_request):
139 repo_id = pull_request.target_repo.repo_id
138 140 PullRequestModel().delete(pull_request, pull_request.author)
139 141
140 142 self.workspace_remove_mock.assert_called_once_with(
141 self.workspace_id)
143 repo_id, self.workspace_id)
142 144
143 145 def test_close_calls_cleanup_and_hook(self, pull_request):
144 146 PullRequestModel().close_pull_request(
145 147 pull_request, pull_request.author)
148 repo_id = pull_request.target_repo.repo_id
146 149
147 150 self.workspace_remove_mock.assert_called_once_with(
148 self.workspace_id)
151 repo_id, self.workspace_id)
149 152 self.hook_mock.assert_called_with(
150 153 self.pull_request, self.pull_request.author, 'close')
151 154
@@ -161,9 +164,10 b' class TestPullRequestModel(object):'
161 164 assert status is True
162 165 assert msg.eval() == 'This pull request can be automatically merged.'
163 166 self.merge_mock.assert_called_with(
167 self.repo_id, self.workspace_id,
164 168 pull_request.target_ref_parts,
165 169 pull_request.source_repo.scm_instance(),
166 pull_request.source_ref_parts, self.workspace_id, dry_run=True,
170 pull_request.source_ref_parts, dry_run=True,
167 171 use_rebase=False, close_branch=False)
168 172
169 173 assert pull_request._last_merge_source_rev == self.source_commit
@@ -190,9 +194,10 b' class TestPullRequestModel(object):'
190 194 msg.eval() ==
191 195 'This pull request cannot be merged because of merge conflicts.')
192 196 self.merge_mock.assert_called_with(
197 self.repo_id, self.workspace_id,
193 198 pull_request.target_ref_parts,
194 199 pull_request.source_repo.scm_instance(),
195 pull_request.source_ref_parts, self.workspace_id, dry_run=True,
200 pull_request.source_ref_parts, dry_run=True,
196 201 use_rebase=False, close_branch=False)
197 202
198 203 assert pull_request._last_merge_source_rev == self.source_commit
@@ -222,9 +227,10 b' class TestPullRequestModel(object):'
222 227 'This pull request cannot be merged because of an unhandled'
223 228 ' exception.')
224 229 self.merge_mock.assert_called_with(
230 self.repo_id, self.workspace_id,
225 231 pull_request.target_ref_parts,
226 232 pull_request.source_repo.scm_instance(),
227 pull_request.source_ref_parts, self.workspace_id, dry_run=True,
233 pull_request.source_ref_parts, dry_run=True,
228 234 use_rebase=False, close_branch=False)
229 235
230 236 assert pull_request._last_merge_source_rev is None
@@ -281,7 +287,7 b' class TestPullRequestModel(object):'
281 287 True, True, merge_ref, MergeFailureReason.NONE)
282 288
283 289 merge_extras['repository'] = pull_request.target_repo.repo_name
284 PullRequestModel().merge(
290 PullRequestModel().merge_repo(
285 291 pull_request, pull_request.author, extras=merge_extras)
286 292
287 293 message = (
@@ -295,9 +301,10 b' class TestPullRequestModel(object):'
295 301 )
296 302 )
297 303 self.merge_mock.assert_called_with(
304 self.repo_id, self.workspace_id,
298 305 pull_request.target_ref_parts,
299 306 pull_request.source_repo.scm_instance(),
300 pull_request.source_ref_parts, self.workspace_id,
307 pull_request.source_ref_parts,
301 308 user_name=user.username, user_email=user.email, message=message,
302 309 use_rebase=False, close_branch=False
303 310 )
@@ -320,7 +327,7 b' class TestPullRequestModel(object):'
320 327 False, False, merge_ref, MergeFailureReason.MERGE_FAILED)
321 328
322 329 merge_extras['repository'] = pull_request.target_repo.repo_name
323 PullRequestModel().merge(
330 PullRequestModel().merge_repo(
324 331 pull_request, pull_request.author, extras=merge_extras)
325 332
326 333 message = (
@@ -334,9 +341,10 b' class TestPullRequestModel(object):'
334 341 )
335 342 )
336 343 self.merge_mock.assert_called_with(
344 self.repo_id, self.workspace_id,
337 345 pull_request.target_ref_parts,
338 346 pull_request.source_repo.scm_instance(),
339 pull_request.source_ref_parts, self.workspace_id,
347 pull_request.source_ref_parts,
340 348 user_name=user.username, user_email=user.email, message=message,
341 349 use_rebase=False, close_branch=False
342 350 )
@@ -392,7 +400,7 b' class TestIntegrationMerge(object):'
392 400 Session().commit()
393 401
394 402 with mock.patch.dict(rhodecode.CONFIG, extra_config, clear=False):
395 merge_state = PullRequestModel().merge(
403 merge_state = PullRequestModel().merge_repo(
396 404 pull_request, user_admin, extras=merge_extras)
397 405
398 406 assert merge_state.executed
@@ -409,7 +417,7 b' class TestIntegrationMerge(object):'
409 417
410 418 with mock.patch('rhodecode.EXTENSIONS.PRE_PUSH_HOOK') as pre_pull:
411 419 pre_pull.side_effect = RepositoryError("Disallow push!")
412 merge_status = PullRequestModel().merge(
420 merge_status = PullRequestModel().merge_repo(
413 421 pull_request, user_admin, extras=merge_extras)
414 422
415 423 assert not merge_status.executed
@@ -429,7 +437,7 b' class TestIntegrationMerge(object):'
429 437 merge_extras['repository'] = pull_request.target_repo.repo_name
430 438 # TODO: johbo: Needed for sqlite, try to find an automatic way for it
431 439 Session().commit()
432 merge_status = PullRequestModel().merge(
440 merge_status = PullRequestModel().merge_repo(
433 441 pull_request, user_regular, extras=merge_extras)
434 442 assert not merge_status.executed
435 443
@@ -566,7 +566,7 b' TODO: To be written...'
566 566
567 567 def test_maybe_prepare_merge_workspace(self):
568 568 workspace = self.repo._maybe_prepare_merge_workspace(
569 'pr2', Reference('branch', 'master', 'unused'),
569 2, 'pr2', Reference('branch', 'master', 'unused'),
570 570 Reference('branch', 'master', 'unused'))
571 571
572 572 assert os.path.isdir(workspace)
@@ -575,13 +575,13 b' TODO: To be written...'
575 575
576 576 # Calling it a second time should also succeed
577 577 workspace = self.repo._maybe_prepare_merge_workspace(
578 'pr2', Reference('branch', 'master', 'unused'),
578 2, 'pr2', Reference('branch', 'master', 'unused'),
579 579 Reference('branch', 'master', 'unused'))
580 580 assert os.path.isdir(workspace)
581 581
582 582 def test_maybe_prepare_merge_workspace_different_refs(self):
583 583 workspace = self.repo._maybe_prepare_merge_workspace(
584 'pr2', Reference('branch', 'master', 'unused'),
584 2, 'pr2', Reference('branch', 'master', 'unused'),
585 585 Reference('branch', 'develop', 'unused'))
586 586
587 587 assert os.path.isdir(workspace)
@@ -590,22 +590,22 b' TODO: To be written...'
590 590
591 591 # Calling it a second time should also succeed
592 592 workspace = self.repo._maybe_prepare_merge_workspace(
593 'pr2', Reference('branch', 'master', 'unused'),
593 2, 'pr2', Reference('branch', 'master', 'unused'),
594 594 Reference('branch', 'develop', 'unused'))
595 595 assert os.path.isdir(workspace)
596 596
597 597 def test_cleanup_merge_workspace(self):
598 598 workspace = self.repo._maybe_prepare_merge_workspace(
599 'pr3', Reference('branch', 'master', 'unused'),
599 2, 'pr3', Reference('branch', 'master', 'unused'),
600 600 Reference('branch', 'master', 'unused'))
601 self.repo.cleanup_merge_workspace('pr3')
601 self.repo.cleanup_merge_workspace(2, 'pr3')
602 602
603 603 assert not os.path.exists(workspace)
604 604
605 605 def test_cleanup_merge_workspace_invalid_workspace_id(self):
606 606 # No assert: because in case of an inexistent workspace this function
607 607 # should still succeed.
608 self.repo.cleanup_merge_workspace('pr4')
608 self.repo.cleanup_merge_workspace(1, 'pr4')
609 609
610 610 def test_set_refs(self):
611 611 test_ref = 'refs/test-refs/abcde'
@@ -31,7 +31,7 b' from rhodecode.lib.vcs.backends.hg impor'
31 31 from rhodecode.lib.vcs.exceptions import (
32 32 RepositoryError, VCSError, NodeDoesNotExistError, CommitDoesNotExistError)
33 33 from rhodecode.lib.vcs.nodes import FileNode, NodeKind, NodeState
34 from rhodecode.tests import TEST_HG_REPO, TEST_HG_REPO_CLONE
34 from rhodecode.tests import TEST_HG_REPO, TEST_HG_REPO_CLONE, repo_id_generator
35 35
36 36
37 37 pytestmark = pytest.mark.backends("hg")
@@ -46,7 +46,6 b' def repo_path_generator():'
46 46 i += 1
47 47 yield '%s-%d' % (TEST_HG_REPO_CLONE, i)
48 48
49
50 49 REPO_PATH_GENERATOR = repo_path_generator()
51 50
52 51
@@ -553,7 +552,7 b' TODO: To be written...'
553 552
554 553 def test_maybe_prepare_merge_workspace(self):
555 554 workspace = self.repo._maybe_prepare_merge_workspace(
556 'pr2', 'unused', 'unused2')
555 1, 'pr2', 'unused', 'unused2')
557 556
558 557 assert os.path.isdir(workspace)
559 558 workspace_repo = MercurialRepository(workspace)
@@ -561,20 +560,22 b' TODO: To be written...'
561 560
562 561 # Calling it a second time should also succeed
563 562 workspace = self.repo._maybe_prepare_merge_workspace(
564 'pr2', 'unused', 'unused2')
563 1, 'pr2', 'unused', 'unused2')
565 564 assert os.path.isdir(workspace)
566 565
567 566 def test_cleanup_merge_workspace(self):
568 567 workspace = self.repo._maybe_prepare_merge_workspace(
569 'pr3', 'unused', 'unused2')
570 self.repo.cleanup_merge_workspace('pr3')
568 1, 'pr3', 'unused', 'unused2')
569
570 assert os.path.isdir(workspace)
571 self.repo.cleanup_merge_workspace(1, 'pr3')
571 572
572 573 assert not os.path.exists(workspace)
573 574
574 575 def test_cleanup_merge_workspace_invalid_workspace_id(self):
575 576 # No assert: because in case of an inexistent workspace this function
576 577 # should still succeed.
577 self.repo.cleanup_merge_workspace('pr4')
578 self.repo.cleanup_merge_workspace(1, 'pr4')
578 579
579 580 def test_merge_target_is_bookmark(self, vcsbackend_hg):
580 581 target_repo = vcsbackend_hg.create_repo(number_of_commits=1)
@@ -594,10 +595,10 b' TODO: To be written...'
594 595 target_repo.bookmark(bookmark_name)
595 596 target_ref = Reference('book', bookmark_name, target_commit.raw_id)
596 597 source_ref = Reference('branch', default_branch, source_commit.raw_id)
597 workspace = 'test-merge'
598
598 workspace_id = 'test-merge'
599 repo_id = repo_id_generator(target_repo.path)
599 600 merge_response = target_repo.merge(
600 target_ref, source_repo, source_ref, workspace,
601 repo_id, workspace_id, target_ref, source_repo, source_ref,
601 602 'test user', 'test@rhodecode.com', 'merge message 1',
602 603 dry_run=False)
603 604 expected_merge_response = MergeResponse(
@@ -638,10 +639,10 b' TODO: To be written...'
638 639 source_repo._update(default_branch)
639 640 source_repo.bookmark(bookmark_name)
640 641 source_ref = Reference('book', bookmark_name, source_commit.raw_id)
641 workspace = 'test-merge'
642
642 workspace_id = 'test-merge'
643 repo_id = repo_id_generator(target_repo.path)
643 644 merge_response = target_repo.merge(
644 target_ref, source_repo, source_ref, workspace,
645 repo_id, workspace_id, target_ref, source_repo, source_ref,
645 646 'test user', 'test@rhodecode.com', 'merge message 1',
646 647 dry_run=False)
647 648 expected_merge_response = MergeResponse(
@@ -677,14 +678,15 b' TODO: To be written...'
677 678
678 679 target_ref = Reference('branch', default_branch, target_commit.raw_id)
679 680 source_ref = Reference('branch', default_branch, source_commit.raw_id)
680 workspace = 'test-merge'
681 workspace_id = 'test-merge'
681 682
682 683 assert len(target_repo._heads(branch='default')) == 2
683 684 expected_merge_response = MergeResponse(
684 685 False, False, None,
685 686 MergeFailureReason.HG_TARGET_HAS_MULTIPLE_HEADS)
687 repo_id = repo_id_generator(target_repo.path)
686 688 merge_response = target_repo.merge(
687 target_ref, source_repo, source_ref, workspace,
689 repo_id, workspace_id, target_ref, source_repo, source_ref,
688 690 'test user', 'test@rhodecode.com', 'merge message 1',
689 691 dry_run=False)
690 692 assert merge_response == expected_merge_response
@@ -711,10 +713,11 b' TODO: To be written...'
711 713
712 714 target_ref = Reference('branch', default_branch, target_commit.raw_id)
713 715 source_ref = Reference('book', bookmark_name, source_commit.raw_id)
714 workspace = 'test-merge'
716 repo_id = repo_id_generator(target_repo.path)
717 workspace_id = 'test-merge'
715 718
716 719 merge_response = target_repo.merge(
717 target_ref, source_repo, source_ref, workspace,
720 repo_id, workspace_id, target_ref, source_repo, source_ref,
718 721 'test user', 'test@rhodecode.com', 'merge message 1',
719 722 dry_run=False, use_rebase=True)
720 723
@@ -95,7 +95,7 b' class TestMercurialRemoteRepoInvalidatio'
95 95 references.
96 96 """
97 97 from rhodecode.model.pull_request import PullRequestModel
98
98 repo_id = pull_request.target_repo
99 99 target_vcs = pull_request.target_repo.scm_instance()
100 100 target_ref = pull_request.target_ref_parts
101 101 source_ref = pull_request.source_ref_parts
@@ -104,7 +104,7 b' class TestMercurialRemoteRepoInvalidatio'
104 104 pr = PullRequestModel()
105 105 workspace_id = pr._workspace_id(pull_request)
106 106 shadow_repository_path = target_vcs._maybe_prepare_merge_workspace(
107 workspace_id, target_ref, source_ref)
107 repo_id, workspace_id, target_ref, source_ref)
108 108 shadow_repo = target_vcs._get_shadow_instance(shadow_repository_path)
109 109
110 110 # This will populate the cache of the mercurial repository object
@@ -30,6 +30,7 b' from rhodecode.lib.vcs.backends.base imp'
30 30 from rhodecode.lib.vcs.exceptions import VCSError, RepositoryError
31 31 from rhodecode.lib.vcs.nodes import FileNode
32 32 from rhodecode.tests.vcs.conftest import BackendTestMixin
33 from rhodecode.tests import repo_id_generator
33 34
34 35
35 36 @pytest.mark.usefixtures("vcs_repository_support")
@@ -268,7 +269,7 b' class TestRepositoryGetCommonAncestor:'
268 269
269 270
270 271 @pytest.mark.backends("git", "hg")
271 class TestRepositoryMerge:
272 class TestRepositoryMerge(object):
272 273 def prepare_for_success(self, vcsbackend):
273 274 self.target_repo = vcsbackend.create_repo(number_of_commits=1)
274 275 self.source_repo = vcsbackend.clone_repo(self.target_repo)
@@ -287,7 +288,8 b' class TestRepositoryMerge:'
287 288 'branch', default_branch, self.target_commit.raw_id)
288 289 self.source_ref = Reference(
289 290 'branch', default_branch, self.source_commit.raw_id)
290 self.workspace = 'test-merge'
291 self.workspace_id = 'test-merge'
292 self.repo_id = repo_id_generator(self.target_repo.path)
291 293
292 294 def prepare_for_conflict(self, vcsbackend):
293 295 self.target_repo = vcsbackend.create_repo(number_of_commits=1)
@@ -302,13 +304,15 b' class TestRepositoryMerge:'
302 304 'branch', default_branch, self.target_commit.raw_id)
303 305 self.source_ref = Reference(
304 306 'branch', default_branch, self.source_commit.raw_id)
305 self.workspace = 'test-merge'
307 self.workspace_id = 'test-merge'
308 self.repo_id = repo_id_generator(self.target_repo.path)
306 309
307 310 def test_merge_success(self, vcsbackend):
308 311 self.prepare_for_success(vcsbackend)
309 312
310 313 merge_response = self.target_repo.merge(
311 self.target_ref, self.source_repo, self.source_ref, self.workspace,
314 self.repo_id, self.workspace_id, self.target_ref, self.source_repo,
315 self.source_ref,
312 316 'test user', 'test@rhodecode.com', 'merge message 1',
313 317 dry_run=False)
314 318 expected_merge_response = MergeResponse(
@@ -334,7 +338,7 b' class TestRepositoryMerge:'
334 338 merge_response.merge_ref.commit_id)
335 339
336 340 merge_response = target_repo.merge(
337 target_ref, self.source_repo, self.source_ref, self.workspace,
341 self.repo_id, self.workspace_id, target_ref, self.source_repo, self.source_ref,
338 342 'test user', 'test@rhodecode.com', 'merge message 2',
339 343 dry_run=False)
340 344 expected_merge_response = MergeResponse(
@@ -353,13 +357,13 b' class TestRepositoryMerge:'
353 357 self.prepare_for_success(vcsbackend)
354 358
355 359 merge_response = self.target_repo.merge(
356 self.target_ref, self.source_repo, self.source_ref, self.workspace,
357 dry_run=True)
360 self.repo_id, self.workspace_id, self.target_ref, self.source_repo,
361 self.source_ref, dry_run=True)
358 362
359 363 # We call it twice so to make sure we can handle updates
360 364 merge_response_update = self.target_repo.merge(
361 self.target_ref, self.source_repo, self.source_ref, self.workspace,
362 dry_run=True)
365 self.repo_id, self.workspace_id, self.target_ref, self.source_repo,
366 self.source_ref, dry_run=True)
363 367
364 368 # Multiple merges may differ in their commit id. Therefore we set the
365 369 # commit id to `None` before comparing the merge responses.
@@ -381,13 +385,15 b' class TestRepositoryMerge:'
381 385 False, False, None, MergeFailureReason.MERGE_FAILED)
382 386
383 387 merge_response = self.target_repo.merge(
384 self.target_ref, self.source_repo, self.source_ref, self.workspace,
388 self.repo_id, self.workspace_id, self.target_ref,
389 self.source_repo, self.source_ref,
385 390 'test_user', 'test@rhodecode.com', 'test message', dry_run=dry_run)
386 391 assert merge_response == expected_merge_response
387 392
388 393 # We call it twice so to make sure we can handle updates
389 394 merge_response = self.target_repo.merge(
390 self.target_ref, self.source_repo, self.source_ref, self.workspace,
395 self.repo_id, self.workspace_id, self.target_ref, self.source_repo,
396 self.source_ref,
391 397 'test_user', 'test@rhodecode.com', 'test message', dry_run=dry_run)
392 398 assert merge_response == expected_merge_response
393 399
@@ -400,8 +406,8 b' class TestRepositoryMerge:'
400 406 self.target_ref.type, self.target_ref.name, '0' * 40)
401 407
402 408 merge_response = self.target_repo.merge(
403 target_ref, self.source_repo, self.source_ref, self.workspace,
404 dry_run=True)
409 self.repo_id, self.workspace_id, target_ref, self.source_repo,
410 self.source_ref, dry_run=True)
405 411
406 412 assert merge_response == expected_merge_response
407 413
@@ -414,7 +420,8 b' class TestRepositoryMerge:'
414 420 self.source_ref.type, 'not_existing', self.source_ref.commit_id)
415 421
416 422 merge_response = self.target_repo.merge(
417 self.target_ref, self.source_repo, source_ref, self.workspace,
423 self.repo_id, self.workspace_id, self.target_ref,
424 self.source_repo, source_ref,
418 425 dry_run=True)
419 426
420 427 assert merge_response == expected_merge_response
@@ -427,29 +434,38 b' class TestRepositoryMerge:'
427 434 with mock.patch.object(self.target_repo, '_merge_repo',
428 435 side_effect=RepositoryError()):
429 436 merge_response = self.target_repo.merge(
430 self.target_ref, self.source_repo, self.source_ref,
431 self.workspace, dry_run=True)
437 self.repo_id, self.workspace_id, self.target_ref,
438 self.source_repo, self.source_ref,
439 dry_run=True)
432 440
433 441 assert merge_response == expected_merge_response
434 442
435 443 def test_merge_invalid_user_name(self, vcsbackend):
436 444 repo = vcsbackend.create_repo(number_of_commits=1)
437 445 ref = Reference('branch', 'master', 'not_used')
446 workspace_id = 'test-errors-in-merge'
447 repo_id = repo_id_generator(workspace_id)
438 448 with pytest.raises(ValueError):
439 repo.merge(ref, self, ref, 'workspace_id')
449 repo.merge(repo_id, workspace_id, ref, self, ref)
440 450
441 451 def test_merge_invalid_user_email(self, vcsbackend):
442 452 repo = vcsbackend.create_repo(number_of_commits=1)
443 453 ref = Reference('branch', 'master', 'not_used')
454 workspace_id = 'test-errors-in-merge'
455 repo_id = repo_id_generator(workspace_id)
444 456 with pytest.raises(ValueError):
445 repo.merge(ref, self, ref, 'workspace_id', 'user name')
457 repo.merge(
458 repo_id, workspace_id, ref, self, ref, 'user name')
446 459
447 460 def test_merge_invalid_message(self, vcsbackend):
448 461 repo = vcsbackend.create_repo(number_of_commits=1)
449 462 ref = Reference('branch', 'master', 'not_used')
463 workspace_id = 'test-errors-in-merge'
464 repo_id = repo_id_generator(workspace_id)
450 465 with pytest.raises(ValueError):
451 466 repo.merge(
452 ref, self, ref, 'workspace_id', 'user name', 'user@email.com')
467 repo_id, workspace_id, ref, self, ref,
468 'user name', 'user@email.com')
453 469
454 470
455 471 @pytest.mark.usefixtures("vcs_repository_support")
@@ -505,7 +521,7 b' class TestRepositoryStrip(BackendTestMix'
505 521
506 522
507 523 @pytest.mark.backends('hg', 'git')
508 class TestRepositoryPull:
524 class TestRepositoryPull(object):
509 525
510 526 def test_pull(self, vcsbackend):
511 527 source_repo = vcsbackend.repo
General Comments 0
You need to be logged in to leave comments. Login now