##// END OF EJS Templates
tests: fixed name generation for shadow repos
marcink -
r2890:30b99364 default
parent child Browse files
Show More
@@ -1,183 +1,183 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2016-2018 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 import pytest
22 22
23 23 from mock import call, patch
24 24
25 25 from rhodecode.lib.vcs.backends.base import Reference
26 26
27 27
28 28 class TestMercurialRemoteRepoInvalidation(object):
29 29 """
30 30 If the VCSServer is running with multiple processes or/and instances.
31 31 Operations on repositories are potentially handled by different processes
32 32 in a random fashion. The mercurial repository objects used in the VCSServer
33 33 are caching the commits of the repo. Therefore we have to invalidate the
34 34 VCSServer caching of these objects after a writing operation.
35 35 """
36 36
37 37 # Default reference used as a dummy during tests.
38 38 default_ref = Reference('branch', 'default', None)
39 39
40 40 # Methods of vcsserver.hg.HgRemote that are "writing" operations.
41 41 writing_methods = [
42 42 'bookmark',
43 43 'commit',
44 44 'merge',
45 45 'pull',
46 46 'pull_cmd',
47 47 'rebase',
48 48 'strip',
49 49 'tag',
50 50 ]
51 51
52 52 @pytest.mark.parametrize('method_name, method_args', [
53 53 ('_local_merge', [default_ref, None, None, None, default_ref]),
54 54 ('_local_pull', ['', default_ref]),
55 55 ('bookmark', [None]),
56 56 ('pull', ['', default_ref]),
57 57 ('remove_tag', ['mytag', None]),
58 58 ('strip', [None]),
59 59 ('tag', ['newtag', None]),
60 60 ])
61 61 def test_method_invokes_invalidate_on_remote_repo(
62 62 self, method_name, method_args, backend_hg):
63 63 """
64 64 Check that the listed methods are invalidating the VCSServer cache
65 65 after invoking a writing method of their remote repository object.
66 66 """
67 67 tags = {'mytag': 'mytag-id'}
68 68
69 69 def add_tag(name, raw_id, *args, **kwds):
70 70 tags[name] = raw_id
71 71
72 72 repo = backend_hg.repo.scm_instance()
73 73 with patch.object(repo, '_remote') as remote:
74 74 remote.lookup.return_value = ('commit-id', 'commit-idx')
75 75 remote.tags.return_value = tags
76 76 remote._get_tags.return_value = tags
77 77 remote.tag.side_effect = add_tag
78 78
79 79 # Invoke method.
80 80 method = getattr(repo, method_name)
81 81 method(*method_args)
82 82
83 83 # Assert that every "writing" method is followed by an invocation
84 84 # of the cache invalidation method.
85 85 for counter, method_call in enumerate(remote.method_calls):
86 86 call_name = method_call[0]
87 87 if call_name in self.writing_methods:
88 88 next_call = remote.method_calls[counter + 1]
89 89 assert next_call == call.invalidate_vcs_cache()
90 90
91 91 def _prepare_shadow_repo(self, pull_request):
92 92 """
93 93 Helper that creates a shadow repo that can be used to reproduce the
94 94 CommitDoesNotExistError when pulling in from target and source
95 95 references.
96 96 """
97 97 from rhodecode.model.pull_request import PullRequestModel
98 repo_id = pull_request.target_repo
98 repo_id = pull_request.target_repo.repo_id
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
102 102
103 103 # Create shadow repository.
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 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
111 111 # inside of the VCSServer.
112 112 shadow_repo.get_commit()
113 113
114 114 return shadow_repo, source_ref, target_ref
115 115
116 116 @pytest.mark.backends('hg')
117 117 def test_commit_does_not_exist_error_happens(self, pr_util, app):
118 118 """
119 119 This test is somewhat special. It does not really test the system
120 120 instead it is more or less a precondition for the
121 121 "test_commit_does_not_exist_error_does_not_happen". It deactivates the
122 122 cache invalidation and asserts that the error occurs.
123 123 """
124 124 from rhodecode.lib.vcs.exceptions import CommitDoesNotExistError
125 125
126 126 pull_request = pr_util.create_pull_request()
127 127 target_vcs = pull_request.target_repo.scm_instance()
128 128 source_vcs = pull_request.source_repo.scm_instance()
129 129 shadow_repo, source_ref, target_ref = self._prepare_shadow_repo(
130 130 pull_request)
131 131
132 132 # Pull from target and source references but without invalidation of
133 133 # RemoteRepo objects and without VCSServer caching of mercurial
134 134 # repository objects.
135 135 with patch.object(shadow_repo._remote, 'invalidate_vcs_cache'):
136 136 # NOTE: Do not use patch.dict() to disable the cache because it
137 137 # restores the WHOLE dict and not only the patched keys.
138 138 shadow_repo._remote._wire['cache'] = False
139 139 shadow_repo._local_pull(target_vcs.path, target_ref)
140 140 shadow_repo._local_pull(source_vcs.path, source_ref)
141 141 shadow_repo._remote._wire.pop('cache')
142 142
143 143 # Try to lookup the target_ref in shadow repo. This should work because
144 144 # the shadow repo is a clone of the target and always contains all off
145 145 # it's commits in the initial cache.
146 146 shadow_repo.get_commit(target_ref.commit_id)
147 147
148 148 # If we try to lookup the source_ref it should fail because the shadow
149 149 # repo commit cache doesn't get invalidated. (Due to patched
150 150 # invalidation and caching above).
151 151 with pytest.raises(CommitDoesNotExistError):
152 152 shadow_repo.get_commit(source_ref.commit_id)
153 153
154 154 @pytest.mark.backends('hg')
155 155 def test_commit_does_not_exist_error_does_not_happen(self, pr_util, app):
156 156 """
157 157 This test simulates a pull request merge in which the pull operations
158 158 are handled by a different VCSServer process than all other operations.
159 159 Without correct cache invalidation this leads to an error when
160 160 retrieving the pulled commits afterwards.
161 161 """
162 162
163 163 pull_request = pr_util.create_pull_request()
164 164 target_vcs = pull_request.target_repo.scm_instance()
165 165 source_vcs = pull_request.source_repo.scm_instance()
166 166 shadow_repo, source_ref, target_ref = self._prepare_shadow_repo(
167 167 pull_request)
168 168
169 169 # Pull from target and source references without without VCSServer
170 170 # caching of mercurial repository objects but with active invalidation
171 171 # of RemoteRepo objects.
172 172 # NOTE: Do not use patch.dict() to disable the cache because it
173 173 # restores the WHOLE dict and not only the patched keys.
174 174 shadow_repo._remote._wire['cache'] = False
175 175 shadow_repo._local_pull(target_vcs.path, target_ref)
176 176 shadow_repo._local_pull(source_vcs.path, source_ref)
177 177 shadow_repo._remote._wire.pop('cache')
178 178
179 179 # Try to lookup the target and source references in shadow repo. This
180 180 # should work because the RemoteRepo object gets invalidated during the
181 181 # above pull operations.
182 182 shadow_repo.get_commit(target_ref.commit_id)
183 183 shadow_repo.get_commit(source_ref.commit_id)
General Comments 0
You need to be logged in to leave comments. Login now