##// END OF EJS Templates
tests: Adapt tests to changes in mercurial vcs backend.
Martin Bornhold -
r408:71302d46 default
parent child Browse files
Show More
@@ -1,135 +1,159 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2016 RhodeCode GmbH
3 # Copyright (C) 2016-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 pytest
21 import pytest
22
22
23 from mock import patch
23 from mock import call, patch
24
24
25 from rhodecode.lib.vcs.backends.base import Reference
25 from rhodecode.lib.vcs.backends.base import Reference
26
26
27
27
28 class TestMercurialRemoteRepoInvalidation(object):
28 class TestMercurialRemoteRepoInvalidation(object):
29 ref_stub = Reference('branch', 'default', None)
29 default_ref = Reference('branch', 'default', None)
30
30 writing_methods = [
31 @pytest.mark.parametrize('method_name', [
32 'bookmark',
31 'bookmark',
33 'commit',
32 'commit',
33 'merge',
34 'pull',
34 'pull',
35 'pull_cmd',
35 'pull_cmd',
36 'push',
37 'rebase',
36 'rebase',
38 'strip',
37 'strip',
39 'strip',
38 'tag',
39 ]
40
41 @pytest.mark.parametrize('method_name, method_args', [
42 ('_local_merge', [default_ref, None, None, None, default_ref]),
43 ('_local_pull', ['', default_ref]),
44 ('bookmark', [None]),
45 ('pull', ['', default_ref]),
46 ('remove_tag', ['mytag', None]),
47 ('strip', [None]),
48 ('tag', ['newtag', None]),
40 ])
49 ])
41 def test_method_invokes_invalidate_on_remote_repo(
50 def test_method_invokes_invalidate_on_remote_repo(
42 self, method_name, backend_hg):
51 self, method_name, method_args, backend_hg):
52 """
53 Check that the listed methods are invalidating the VCSServer cache
54 after invoking a writing method of their remote repository object.
43 """
55 """
44 Check that the listed methods call invalidate_vcs_cache on their remote
56 tags = {'mytag': 'mytag-id'}
45 repo instance.
57
46 """
58 def add_tag(name, raw_id, *args, **kwds):
47 from rhodecode.lib.vcs import client_http
59 tags[name] = raw_id
60
48 repo = backend_hg.repo.scm_instance()
61 repo = backend_hg.repo.scm_instance()
49 remote = repo._remote
62 with patch.object(repo, '_remote') as remote:
50 with patch.object(remote, 'invalidate_vcs_cache') as invalidate_cache:
63 remote.lookup.return_value = ('commit-id', 'commit-idx')
51 with patch.object(client_http, '_remote_call'):
64 remote.tags.return_value = tags
52 method = getattr(remote, method_name)
65 remote._get_tags.return_value = tags
53 method()
66 remote.tag.side_effect = add_tag
54 assert invalidate_cache.called
67
68 # Invoke method.
69 method = getattr(repo, method_name)
70 method(*method_args)
71
72 # Assert that every "writing" method is followed by an invocation
73 # of the cache invalidation method.
74 for counter, method_call in enumerate(remote.method_calls):
75 call_name = method_call[0]
76 if call_name in self.writing_methods:
77 next_call = remote.method_calls[counter + 1]
78 assert next_call == call.invalidate_vcs_cache()
55
79
56 def _prepare_shadow_repo(self, pull_request):
80 def _prepare_shadow_repo(self, pull_request):
57 """
81 """
58 Helper that creates a shadow repo that can be used to reproduce the
82 Helper that creates a shadow repo that can be used to reproduce the
59 CommitDoesNotExistError when pulling in from target and source
83 CommitDoesNotExistError when pulling in from target and source
60 references.
84 references.
61 """
85 """
62 from rhodecode.model.pull_request import PullRequestModel
86 from rhodecode.model.pull_request import PullRequestModel
63
87
64 target_vcs = pull_request.target_repo.scm_instance()
88 target_vcs = pull_request.target_repo.scm_instance()
65 target_ref = pull_request.target_ref_parts
89 target_ref = pull_request.target_ref_parts
66 source_ref = pull_request.source_ref_parts
90 source_ref = pull_request.source_ref_parts
67
91
68 # Create shadow repository.
92 # Create shadow repository.
69 pr = PullRequestModel()
93 pr = PullRequestModel()
70 workspace_id = pr._workspace_id(pull_request)
94 workspace_id = pr._workspace_id(pull_request)
71 shadow_repository_path = target_vcs._maybe_prepare_merge_workspace(
95 shadow_repository_path = target_vcs._maybe_prepare_merge_workspace(
72 workspace_id, target_ref)
96 workspace_id, target_ref)
73 shadow_repo = target_vcs._get_shadow_instance(shadow_repository_path)
97 shadow_repo = target_vcs._get_shadow_instance(shadow_repository_path)
74
98
75 # This will populate the cache of the mercurial repository object
99 # This will populate the cache of the mercurial repository object
76 # inside of the VCSServer.
100 # inside of the VCSServer.
77 shadow_repo.get_commit()
101 shadow_repo.get_commit()
78
102
79 return shadow_repo, source_ref, target_ref
103 return shadow_repo, source_ref, target_ref
80
104
81 @pytest.mark.backends('hg')
105 @pytest.mark.backends('hg')
82 def test_commit_does_not_exist_error_happens(self, pr_util):
106 def test_commit_does_not_exist_error_happens(self, pr_util):
83 from rhodecode.lib.vcs.exceptions import CommitDoesNotExistError
107 from rhodecode.lib.vcs.exceptions import CommitDoesNotExistError
84
108
85 pull_request = pr_util.create_pull_request()
109 pull_request = pr_util.create_pull_request()
86 target_vcs = pull_request.target_repo.scm_instance()
110 target_vcs = pull_request.target_repo.scm_instance()
87 source_vcs = pull_request.source_repo.scm_instance()
111 source_vcs = pull_request.source_repo.scm_instance()
88 shadow_repo, source_ref, target_ref = self._prepare_shadow_repo(
112 shadow_repo, source_ref, target_ref = self._prepare_shadow_repo(
89 pull_request)
113 pull_request)
90
114
91 # Pull from target and source references but without invalidation of
115 # Pull from target and source references but without invalidation of
92 # RemoteRepo objects and without VCSServer caching of mercurial
116 # RemoteRepo objects and without VCSServer caching of mercurial
93 # repository objects.
117 # repository objects.
94 with patch.object(shadow_repo._remote, 'invalidate_vcs_cache'):
118 with patch.object(shadow_repo._remote, 'invalidate_vcs_cache'):
95 # NOTE: Do not use patch.dict() to disable the cache because it
119 # NOTE: Do not use patch.dict() to disable the cache because it
96 # restores the WHOLE dict and not only the patched keys.
120 # restores the WHOLE dict and not only the patched keys.
97 shadow_repo._remote._wire['cache'] = False
121 shadow_repo._remote._wire['cache'] = False
98 shadow_repo._local_pull(target_vcs.path, target_ref)
122 shadow_repo._local_pull(target_vcs.path, target_ref)
99 shadow_repo._local_pull(source_vcs.path, source_ref)
123 shadow_repo._local_pull(source_vcs.path, source_ref)
100 shadow_repo._remote._wire.pop('cache')
124 shadow_repo._remote._wire.pop('cache')
101
125
102 # Try to lookup the target_ref in shadow repo. This should work because
126 # Try to lookup the target_ref in shadow repo. This should work because
103 # the shadow repo is a clone of the target and always contains all off
127 # the shadow repo is a clone of the target and always contains all off
104 # it's commits in the initial cache.
128 # it's commits in the initial cache.
105 shadow_repo.get_commit(target_ref.commit_id)
129 shadow_repo.get_commit(target_ref.commit_id)
106
130
107 # If we try to lookup the source_ref it should fail because the shadow
131 # If we try to lookup the source_ref it should fail because the shadow
108 # repo commit cache doesn't get invalidated. (Due to patched
132 # repo commit cache doesn't get invalidated. (Due to patched
109 # invalidation and caching above).
133 # invalidation and caching above).
110 with pytest.raises(CommitDoesNotExistError):
134 with pytest.raises(CommitDoesNotExistError):
111 shadow_repo.get_commit(source_ref.commit_id)
135 shadow_repo.get_commit(source_ref.commit_id)
112
136
113 @pytest.mark.backends('hg')
137 @pytest.mark.backends('hg')
114 def test_commit_does_not_exist_error_does_not_happen(self, pr_util):
138 def test_commit_does_not_exist_error_does_not_happen(self, pr_util):
115 pull_request = pr_util.create_pull_request()
139 pull_request = pr_util.create_pull_request()
116 target_vcs = pull_request.target_repo.scm_instance()
140 target_vcs = pull_request.target_repo.scm_instance()
117 source_vcs = pull_request.source_repo.scm_instance()
141 source_vcs = pull_request.source_repo.scm_instance()
118 shadow_repo, source_ref, target_ref = self._prepare_shadow_repo(
142 shadow_repo, source_ref, target_ref = self._prepare_shadow_repo(
119 pull_request)
143 pull_request)
120
144
121 # Pull from target and source references without without VCSServer
145 # Pull from target and source references without without VCSServer
122 # caching of mercurial repository objects but with active invalidation
146 # caching of mercurial repository objects but with active invalidation
123 # of RemoteRepo objects.
147 # of RemoteRepo objects.
124 # NOTE: Do not use patch.dict() to disable the cache because it
148 # NOTE: Do not use patch.dict() to disable the cache because it
125 # restores the WHOLE dict and not only the patched keys.
149 # restores the WHOLE dict and not only the patched keys.
126 shadow_repo._remote._wire['cache'] = False
150 shadow_repo._remote._wire['cache'] = False
127 shadow_repo._local_pull(target_vcs.path, target_ref)
151 shadow_repo._local_pull(target_vcs.path, target_ref)
128 shadow_repo._local_pull(source_vcs.path, source_ref)
152 shadow_repo._local_pull(source_vcs.path, source_ref)
129 shadow_repo._remote._wire.pop('cache')
153 shadow_repo._remote._wire.pop('cache')
130
154
131 # Try to lookup the target and source references in shadow repo. This
155 # Try to lookup the target and source references in shadow repo. This
132 # should work because the RemoteRepo object gets invalidated during the
156 # should work because the RemoteRepo object gets invalidated during the
133 # above pull operations.
157 # above pull operations.
134 shadow_repo.get_commit(target_ref.commit_id)
158 shadow_repo.get_commit(target_ref.commit_id)
135 shadow_repo.get_commit(source_ref.commit_id)
159 shadow_repo.get_commit(source_ref.commit_id)
General Comments 0
You need to be logged in to leave comments. Login now