##// END OF EJS Templates
vcs: Move vcsserver cache invalidation to mercurial backend....
vcs: Move vcsserver cache invalidation to mercurial backend. The invalidation is only needed for "writing" mercurial methods. Previous location covers also "reading" methodas and other vcs backends.

File last commit:

r406:82af2251 default
r407:243d422c default
Show More
test_hg_vcsserver_cache_invalidation.py
135 lines | 5.6 KiB | text/x-python | PythonLexer
/ rhodecode / tests / vcs / test_hg_vcsserver_cache_invalidation.py
# -*- coding: utf-8 -*-
# Copyright (C) 2016-2016 RhodeCode GmbH
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License, version 3
# (only), as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# This program is dual-licensed. If you wish to learn more about the
# RhodeCode Enterprise Edition, including its added features, Support services,
# and proprietary license terms, please see https://rhodecode.com/licenses/
import pytest
from mock import patch
from rhodecode.lib.vcs.backends.base import Reference
class TestMercurialRemoteRepoInvalidation(object):
ref_stub = Reference('branch', 'default', None)
@pytest.mark.parametrize('method_name', [
'bookmark',
'commit',
'pull',
'pull_cmd',
'push',
'rebase',
'strip',
'strip',
])
def test_method_invokes_invalidate_on_remote_repo(
self, method_name, backend_hg):
"""
Check that the listed methods call invalidate_vcs_cache on their remote
repo instance.
"""
from rhodecode.lib.vcs import client_http
repo = backend_hg.repo.scm_instance()
remote = repo._remote
with patch.object(remote, 'invalidate_vcs_cache') as invalidate_cache:
with patch.object(client_http, '_remote_call'):
method = getattr(remote, method_name)
method()
assert invalidate_cache.called
def _prepare_shadow_repo(self, pull_request):
"""
Helper that creates a shadow repo that can be used to reproduce the
CommitDoesNotExistError when pulling in from target and source
references.
"""
from rhodecode.model.pull_request import PullRequestModel
target_vcs = pull_request.target_repo.scm_instance()
target_ref = pull_request.target_ref_parts
source_ref = pull_request.source_ref_parts
# Create shadow repository.
pr = PullRequestModel()
workspace_id = pr._workspace_id(pull_request)
shadow_repository_path = target_vcs._maybe_prepare_merge_workspace(
workspace_id, target_ref)
shadow_repo = target_vcs._get_shadow_instance(shadow_repository_path)
# This will populate the cache of the mercurial repository object
# inside of the VCSServer.
shadow_repo.get_commit()
return shadow_repo, source_ref, target_ref
@pytest.mark.backends('hg')
def test_commit_does_not_exist_error_happens(self, pr_util):
from rhodecode.lib.vcs.exceptions import CommitDoesNotExistError
pull_request = pr_util.create_pull_request()
target_vcs = pull_request.target_repo.scm_instance()
source_vcs = pull_request.source_repo.scm_instance()
shadow_repo, source_ref, target_ref = self._prepare_shadow_repo(
pull_request)
# Pull from target and source references but without invalidation of
# RemoteRepo objects and without VCSServer caching of mercurial
# repository objects.
with patch.object(shadow_repo._remote, 'invalidate_vcs_cache'):
# NOTE: Do not use patch.dict() to disable the cache because it
# restores the WHOLE dict and not only the patched keys.
shadow_repo._remote._wire['cache'] = False
shadow_repo._local_pull(target_vcs.path, target_ref)
shadow_repo._local_pull(source_vcs.path, source_ref)
shadow_repo._remote._wire.pop('cache')
# Try to lookup the target_ref in shadow repo. This should work because
# the shadow repo is a clone of the target and always contains all off
# it's commits in the initial cache.
shadow_repo.get_commit(target_ref.commit_id)
# If we try to lookup the source_ref it should fail because the shadow
# repo commit cache doesn't get invalidated. (Due to patched
# invalidation and caching above).
with pytest.raises(CommitDoesNotExistError):
shadow_repo.get_commit(source_ref.commit_id)
@pytest.mark.backends('hg')
def test_commit_does_not_exist_error_does_not_happen(self, pr_util):
pull_request = pr_util.create_pull_request()
target_vcs = pull_request.target_repo.scm_instance()
source_vcs = pull_request.source_repo.scm_instance()
shadow_repo, source_ref, target_ref = self._prepare_shadow_repo(
pull_request)
# Pull from target and source references without without VCSServer
# caching of mercurial repository objects but with active invalidation
# of RemoteRepo objects.
# NOTE: Do not use patch.dict() to disable the cache because it
# restores the WHOLE dict and not only the patched keys.
shadow_repo._remote._wire['cache'] = False
shadow_repo._local_pull(target_vcs.path, target_ref)
shadow_repo._local_pull(source_vcs.path, source_ref)
shadow_repo._remote._wire.pop('cache')
# Try to lookup the target and source references in shadow repo. This
# should work because the RemoteRepo object gets invalidated during the
# above pull operations.
shadow_repo.get_commit(target_ref.commit_id)
shadow_repo.get_commit(source_ref.commit_id)