##// END OF EJS Templates
tests: Skip test for Pyro4 connection and added doc strings.
Martin Bornhold -
r434:e4f441e2 default
parent child Browse files
Show More
@@ -1,159 +1,189 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2016-2016 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 """
30 If the VCSServer is running with multiple processes or/and instances.
31 Operations on repositories are potentially handled by different processes
32 in a random fashion. The mercurial repository objects used in the VCSServer
33 are caching the commits of the repo. Therefore we have to invalidate the
34 VCSServer caching of these objects after a writing operation.
35 """
36
37 # Default reference used as a dummy during tests.
29 38 default_ref = Reference('branch', 'default', None)
39
40 # Methods of vcsserver.hg.HgRemote that are "writing" operations.
30 41 writing_methods = [
31 42 'bookmark',
32 43 'commit',
33 44 'merge',
34 45 'pull',
35 46 'pull_cmd',
36 47 'rebase',
37 48 'strip',
38 49 'tag',
39 50 ]
40 51
41 52 @pytest.mark.parametrize('method_name, method_args', [
42 53 ('_local_merge', [default_ref, None, None, None, default_ref]),
43 54 ('_local_pull', ['', default_ref]),
44 55 ('bookmark', [None]),
45 56 ('pull', ['', default_ref]),
46 57 ('remove_tag', ['mytag', None]),
47 58 ('strip', [None]),
48 59 ('tag', ['newtag', None]),
49 60 ])
50 61 def test_method_invokes_invalidate_on_remote_repo(
51 62 self, method_name, method_args, backend_hg):
52 63 """
53 64 Check that the listed methods are invalidating the VCSServer cache
54 65 after invoking a writing method of their remote repository object.
55 66 """
56 67 tags = {'mytag': 'mytag-id'}
57 68
58 69 def add_tag(name, raw_id, *args, **kwds):
59 70 tags[name] = raw_id
60 71
61 72 repo = backend_hg.repo.scm_instance()
62 73 with patch.object(repo, '_remote') as remote:
63 74 remote.lookup.return_value = ('commit-id', 'commit-idx')
64 75 remote.tags.return_value = tags
65 76 remote._get_tags.return_value = tags
66 77 remote.tag.side_effect = add_tag
67 78
68 79 # Invoke method.
69 80 method = getattr(repo, method_name)
70 81 method(*method_args)
71 82
72 83 # Assert that every "writing" method is followed by an invocation
73 84 # of the cache invalidation method.
74 85 for counter, method_call in enumerate(remote.method_calls):
75 86 call_name = method_call[0]
76 87 if call_name in self.writing_methods:
77 88 next_call = remote.method_calls[counter + 1]
78 89 assert next_call == call.invalidate_vcs_cache()
79 90
80 91 def _prepare_shadow_repo(self, pull_request):
81 92 """
82 93 Helper that creates a shadow repo that can be used to reproduce the
83 94 CommitDoesNotExistError when pulling in from target and source
84 95 references.
85 96 """
86 97 from rhodecode.model.pull_request import PullRequestModel
87 98
88 99 target_vcs = pull_request.target_repo.scm_instance()
89 100 target_ref = pull_request.target_ref_parts
90 101 source_ref = pull_request.source_ref_parts
91 102
92 103 # Create shadow repository.
93 104 pr = PullRequestModel()
94 105 workspace_id = pr._workspace_id(pull_request)
95 106 shadow_repository_path = target_vcs._maybe_prepare_merge_workspace(
96 107 workspace_id, target_ref)
97 108 shadow_repo = target_vcs._get_shadow_instance(shadow_repository_path)
98 109
99 110 # This will populate the cache of the mercurial repository object
100 111 # inside of the VCSServer.
101 112 shadow_repo.get_commit()
102 113
103 114 return shadow_repo, source_ref, target_ref
104 115
105 116 @pytest.mark.backends('hg')
106 def test_commit_does_not_exist_error_happens(self, pr_util):
117 def test_commit_does_not_exist_error_happens(self, pr_util, pylonsapp):
118 """
119 This test is somewhat special. It does not really test the system
120 instead it is more or less a precondition for the
121 "test_commit_does_not_exist_error_does_not_happen". It deactivates the
122 cache invalidation and asserts that the error occurs.
123 """
107 124 from rhodecode.lib.vcs.exceptions import CommitDoesNotExistError
108 125
126 if pylonsapp.config['vcs.server.protocol'] != 'http':
127 pytest.skip('Test is intended for the HTTP protocol only.')
128
109 129 pull_request = pr_util.create_pull_request()
110 130 target_vcs = pull_request.target_repo.scm_instance()
111 131 source_vcs = pull_request.source_repo.scm_instance()
112 132 shadow_repo, source_ref, target_ref = self._prepare_shadow_repo(
113 133 pull_request)
114 134
115 135 # Pull from target and source references but without invalidation of
116 136 # RemoteRepo objects and without VCSServer caching of mercurial
117 137 # repository objects.
118 138 with patch.object(shadow_repo._remote, 'invalidate_vcs_cache'):
119 139 # NOTE: Do not use patch.dict() to disable the cache because it
120 140 # restores the WHOLE dict and not only the patched keys.
121 141 shadow_repo._remote._wire['cache'] = False
122 142 shadow_repo._local_pull(target_vcs.path, target_ref)
123 143 shadow_repo._local_pull(source_vcs.path, source_ref)
124 144 shadow_repo._remote._wire.pop('cache')
125 145
126 146 # Try to lookup the target_ref in shadow repo. This should work because
127 147 # the shadow repo is a clone of the target and always contains all off
128 148 # it's commits in the initial cache.
129 149 shadow_repo.get_commit(target_ref.commit_id)
130 150
131 151 # If we try to lookup the source_ref it should fail because the shadow
132 152 # repo commit cache doesn't get invalidated. (Due to patched
133 153 # invalidation and caching above).
134 154 with pytest.raises(CommitDoesNotExistError):
135 155 shadow_repo.get_commit(source_ref.commit_id)
136 156
137 157 @pytest.mark.backends('hg')
138 def test_commit_does_not_exist_error_does_not_happen(self, pr_util):
158 def test_commit_does_not_exist_error_does_not_happen(
159 self, pr_util, pylonsapp):
160 """
161 This test simulates a pull request merge in which the pull operations
162 are handled by a different VCSServer process than all other operations.
163 Without correct cache invalidation this leads to an error when
164 retrieving the pulled commits afterwards.
165 """
166 if pylonsapp.config['vcs.server.protocol'] != 'http':
167 pytest.skip('Test is intended for the HTTP protocol only.')
168
139 169 pull_request = pr_util.create_pull_request()
140 170 target_vcs = pull_request.target_repo.scm_instance()
141 171 source_vcs = pull_request.source_repo.scm_instance()
142 172 shadow_repo, source_ref, target_ref = self._prepare_shadow_repo(
143 173 pull_request)
144 174
145 175 # Pull from target and source references without without VCSServer
146 176 # caching of mercurial repository objects but with active invalidation
147 177 # of RemoteRepo objects.
148 178 # NOTE: Do not use patch.dict() to disable the cache because it
149 179 # restores the WHOLE dict and not only the patched keys.
150 180 shadow_repo._remote._wire['cache'] = False
151 181 shadow_repo._local_pull(target_vcs.path, target_ref)
152 182 shadow_repo._local_pull(source_vcs.path, source_ref)
153 183 shadow_repo._remote._wire.pop('cache')
154 184
155 185 # Try to lookup the target and source references in shadow repo. This
156 186 # should work because the RemoteRepo object gets invalidated during the
157 187 # above pull operations.
158 188 shadow_repo.get_commit(target_ref.commit_id)
159 189 shadow_repo.get_commit(source_ref.commit_id)
General Comments 0
You need to be logged in to leave comments. Login now