##// END OF EJS Templates
release: Finish preparation for 4.20.0
release: Finish preparation for 4.20.0

File last commit:

r4306:09801de9 default
r4459:3e635489 v4.20.0 stable
Show More
test_hooks_base.py
152 lines | 4.9 KiB | text/x-python | PythonLexer
project: added all source files and assets
r1 # -*- coding: utf-8 -*-
code: update copyrights to 2020
r4306 # Copyright (C) 2010-2020 RhodeCode GmbH
project: added all source files and assets
r1 #
# 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 mock
Martin Bornhold
tests: Add some tests to check that events/extensions are triggered on hook execution....
r910 import pytest
hooks: deprecate old action_logger
r1754 from rhodecode.model.db import Session, UserLog
project: added all source files and assets
r1 from rhodecode.lib import hooks_base, utils2
dan
events: add event system for RepoEvents
r375 def test_post_push_truncates_commits(user_regular, repo_stub):
project: added all source files and assets
r1 extras = {
'ip': '127.0.0.1',
dan
events: add event system for RepoEvents
r375 'username': user_regular.username,
vcs-ops: store user_id inside the extras for vcs context operations....
r2411 'user_id': user_regular.user_id,
project: added all source files and assets
r1 'action': 'push_local',
dan
events: add event system for RepoEvents
r375 'repository': repo_stub.repo_name,
project: added all source files and assets
r1 'scm': 'git',
'config': '',
'server_url': 'http://example.com',
'make_lock': None,
hooks: expose user agent in the variables submitted to pull/push hooks.
r1710 'user_agent': 'some-client',
project: added all source files and assets
r1 'locked_by': [None],
'commit_ids': ['abcde12345' * 4] * 30000,
rcextensions: new builtin rcextensions....
r3133 'hook_type': 'large_push_test_type',
Martin Bornhold
tests: Add new attribute `is_shadow_repo` to test dummy extra data.
r909 'is_shadow_repo': False,
project: added all source files and assets
r1 }
extras = utils2.AttributeDict(extras)
hooks_base.post_push(extras)
# Calculate appropriate action string here
audit-logs: use stricter limit on how much data the commits key can hold....
r1964 commit_ids = extras.commit_ids[:400]
project: added all source files and assets
r1
db: use more consistent sorting using real objects, strings are deprecated in laters sqlalchemy query syntax.
r3949 entry = UserLog.query().order_by(UserLog.user_log_id.desc()).first()
hooks: deprecate old action_logger
r1754 assert entry.action == 'user.push'
assert entry.action_data['commit_ids'] == commit_ids
Session().delete(entry)
Session().commit()
Martin Bornhold
tests: Add some tests to check that events/extensions are triggered on hook execution....
r910
def assert_called_with_mock(callable_, expected_mock_name):
mock_obj = callable_.call_args[0][0]
mock_name = mock_obj._mock_new_parent._mock_new_name
assert mock_name == expected_mock_name
pytest: use consistent way of creating a fixture by using pytest.fixture()
r3946 @pytest.fixture()
Martin Bornhold
tests: Add some tests to check that events/extensions are triggered on hook execution....
r910 def hook_extras(user_regular, repo_stub):
extras = utils2.AttributeDict({
'ip': '127.0.0.1',
'username': user_regular.username,
vcs-ops: store user_id inside the extras for vcs context operations....
r2411 'user_id': user_regular.user_id,
Martin Bornhold
tests: Add some tests to check that events/extensions are triggered on hook execution....
r910 'action': 'push',
'repository': repo_stub.repo_name,
'scm': '',
'config': '',
hooks: pass in store_path into env for hooks.
r3094 'repo_store': '',
Martin Bornhold
tests: Add some tests to check that events/extensions are triggered on hook execution....
r910 'server_url': 'http://example.com',
'make_lock': None,
hooks: expose user agent in the variables submitted to pull/push hooks.
r1710 'user_agent': 'some-client',
Martin Bornhold
tests: Add some tests to check that events/extensions are triggered on hook execution....
r910 'locked_by': [None],
'commit_ids': [],
rcextensions: new builtin rcextensions....
r3133 'hook_type': 'test_type',
Martin Bornhold
tests: Add some tests to check that events/extensions are triggered on hook execution....
r910 'is_shadow_repo': False,
})
return extras
@pytest.mark.parametrize('func, extension, event', [
(hooks_base.pre_push, 'pre_push_extension', 'RepoPrePushEvent'),
(hooks_base.post_push, 'post_pull_extension', 'RepoPushEvent'),
(hooks_base.pre_pull, 'pre_pull_extension', 'RepoPrePullEvent'),
(hooks_base.post_pull, 'post_push_extension', 'RepoPullEvent'),
])
def test_hooks_propagate(func, extension, event, hook_extras):
"""
Tests that our hook code propagates to rhodecode extensions and triggers
the appropriate event.
"""
rcextensions: new builtin rcextensions....
r3133 class ExtensionMock(mock.Mock):
@property
def output(self):
return 'MOCK'
extension_mock = ExtensionMock()
Martin Bornhold
tests: Add some tests to check that events/extensions are triggered on hook execution....
r910 events_mock = mock.Mock()
patches = {
'Repository': mock.Mock(),
'events': events_mock,
extension: extension_mock,
}
# Clear shadow repo flag.
hook_extras.is_shadow_repo = False
# Execute hook function.
with mock.patch.multiple(hooks_base, **patches):
func(hook_extras)
# Assert that extensions are called and event was fired.
extension_mock.called_once()
assert_called_with_mock(events_mock.trigger, event)
@pytest.mark.parametrize('func, extension, event', [
(hooks_base.pre_push, 'pre_push_extension', 'RepoPrePushEvent'),
(hooks_base.post_push, 'post_pull_extension', 'RepoPushEvent'),
(hooks_base.pre_pull, 'pre_pull_extension', 'RepoPrePullEvent'),
(hooks_base.post_pull, 'post_push_extension', 'RepoPullEvent'),
])
def test_hooks_propagates_not_on_shadow(func, extension, event, hook_extras):
"""
If hooks are called by a request to a shadow repo we only want to run our
internal hooks code but not external ones like rhodecode extensions or
trigger an event.
"""
extension_mock = mock.Mock()
events_mock = mock.Mock()
patches = {
'Repository': mock.Mock(),
'events': events_mock,
extension: extension_mock,
}
# Set shadow repo flag.
hook_extras.is_shadow_repo = True
# Execute hook function.
with mock.patch.multiple(hooks_base, **patches):
func(hook_extras)
# Assert that extensions are *not* called and event was *not* fired.
assert not extension_mock.called
assert not events_mock.trigger.called
db: use more consistent sorting using real objects, strings are deprecated in laters sqlalchemy query syntax.
r3949