##// END OF EJS Templates
tests: Use settings dict from fixture instead of grabbing it from the WSGI app stack.
Martin Bornhold -
r603:4f5ebd99 default
parent child Browse files
Show More
@@ -1,305 +1,304 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-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 base64
22 22
23 23 import mock
24 24 import pytest
25 25 import webtest.app
26 26
27 27 from rhodecode.lib.caching_query import FromCache
28 28 from rhodecode.lib.hooks_daemon import DummyHooksCallbackDaemon
29 29 from rhodecode.lib.middleware import simplevcs
30 30 from rhodecode.lib.middleware.https_fixup import HttpsFixup
31 31 from rhodecode.lib.middleware.utils import scm_app
32 32 from rhodecode.model.db import User, _hash_key
33 33 from rhodecode.model.meta import Session
34 34 from rhodecode.tests import (
35 35 HG_REPO, TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS)
36 36 from rhodecode.tests.lib.middleware import mock_scm_app
37 37 from rhodecode.tests.utils import set_anonymous_access
38 38
39 39
40 40 class StubVCSController(simplevcs.SimpleVCS):
41 41
42 42 SCM = 'hg'
43 43 stub_response_body = tuple()
44 44
45 45 def _get_repository_name(self, environ):
46 46 return HG_REPO
47 47
48 48 def _get_action(self, environ):
49 49 return "pull"
50 50
51 51 def _create_wsgi_app(self, repo_path, repo_name, config):
52 52 def fake_app(environ, start_response):
53 53 start_response('200 OK', [])
54 54 return self.stub_response_body
55 55 return fake_app
56 56
57 57 def _create_config(self, extras, repo_name):
58 58 return None
59 59
60 60
61 61 @pytest.fixture
62 62 def vcscontroller(pylonsapp, config_stub):
63 63 config_stub.testing_securitypolicy()
64 64 config_stub.include('rhodecode.authentication')
65 65
66 66 set_anonymous_access(True)
67 67 controller = StubVCSController(pylonsapp, pylonsapp.config, None)
68 68 app = HttpsFixup(controller, pylonsapp.config)
69 69 app = webtest.app.TestApp(app)
70 70
71 71 _remove_default_user_from_query_cache()
72 72
73 73 # Sanity checks that things are set up correctly
74 74 app.get('/' + HG_REPO, status=200)
75 75
76 76 app.controller = controller
77 77 return app
78 78
79 79
80 80 def _remove_default_user_from_query_cache():
81 81 user = User.get_default_user(cache=True)
82 82 query = Session().query(User).filter(User.username == user.username)
83 83 query = query.options(FromCache(
84 84 "sql_cache_short", "get_user_%s" % _hash_key(user.username)))
85 85 query.invalidate()
86 86 Session().expire(user)
87 87
88 88
89 89 @pytest.fixture
90 90 def disable_anonymous_user(request, pylonsapp):
91 91 set_anonymous_access(False)
92 92
93 93 @request.addfinalizer
94 94 def cleanup():
95 95 set_anonymous_access(True)
96 96
97 97
98 98 def test_handles_exceptions_during_permissions_checks(
99 99 vcscontroller, disable_anonymous_user):
100 100 user_and_pass = '%s:%s' % (TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS)
101 101 auth_password = base64.encodestring(user_and_pass).strip()
102 102 extra_environ = {
103 103 'AUTH_TYPE': 'Basic',
104 104 'HTTP_AUTHORIZATION': 'Basic %s' % auth_password,
105 105 'REMOTE_USER': TEST_USER_ADMIN_LOGIN,
106 106 }
107 107
108 108 # Verify that things are hooked up correctly
109 109 vcscontroller.get('/', status=200, extra_environ=extra_environ)
110 110
111 111 # Simulate trouble during permission checks
112 112 with mock.patch('rhodecode.model.db.User.get_by_username',
113 113 side_effect=Exception) as get_user:
114 114 # Verify that a correct 500 is returned and check that the expected
115 115 # code path was hit.
116 116 vcscontroller.get('/', status=500, extra_environ=extra_environ)
117 117 assert get_user.called
118 118
119 119
120 120 def test_returns_forbidden_if_no_anonymous_access(
121 121 vcscontroller, disable_anonymous_user):
122 122 vcscontroller.get('/', status=401)
123 123
124 124
125 125 class StubFailVCSController(simplevcs.SimpleVCS):
126 126 def _handle_request(self, environ, start_response):
127 127 raise Exception("BOOM")
128 128
129 129
130 130 @pytest.fixture(scope='module')
131 131 def fail_controller(pylonsapp):
132 132 controller = StubFailVCSController(pylonsapp, pylonsapp.config, None)
133 133 controller = HttpsFixup(controller, pylonsapp.config)
134 134 controller = webtest.app.TestApp(controller)
135 135 return controller
136 136
137 137
138 138 def test_handles_exceptions_as_internal_server_error(fail_controller):
139 139 fail_controller.get('/', status=500)
140 140
141 141
142 142 def test_provides_traceback_for_appenlight(fail_controller):
143 143 response = fail_controller.get(
144 144 '/', status=500, extra_environ={'appenlight.client': 'fake'})
145 145 assert 'appenlight.__traceback' in response.request.environ
146 146
147 147
148 148 def test_provides_utils_scm_app_as_scm_app_by_default(pylonsapp):
149 149 controller = StubVCSController(pylonsapp, pylonsapp.config, None)
150 150 assert controller.scm_app is scm_app
151 151
152 152
153 153 def test_allows_to_override_scm_app_via_config(pylonsapp):
154 154 config = pylonsapp.config.copy()
155 155 config['vcs.scm_app_implementation'] = (
156 156 'rhodecode.tests.lib.middleware.mock_scm_app')
157 157 controller = StubVCSController(pylonsapp, config, None)
158 158 assert controller.scm_app is mock_scm_app
159 159
160 160
161 161 @pytest.mark.parametrize('query_string, expected', [
162 162 ('cmd=stub_command', True),
163 163 ('cmd=listkeys', False),
164 164 ])
165 165 def test_should_check_locking(query_string, expected):
166 166 result = simplevcs._should_check_locking(query_string)
167 167 assert result == expected
168 168
169 169
170 170 @mock.patch.multiple(
171 171 'Pyro4.config', SERVERTYPE='multiplex', POLLTIMEOUT=0.01)
172 172 class TestGenerateVcsResponse:
173 173
174 174 def test_ensures_that_start_response_is_called_early_enough(self):
175 175 self.call_controller_with_response_body(iter(['a', 'b']))
176 176 assert self.start_response.called
177 177
178 178 def test_invalidates_cache_after_body_is_consumed(self):
179 179 result = self.call_controller_with_response_body(iter(['a', 'b']))
180 180 assert not self.was_cache_invalidated()
181 181 # Consume the result
182 182 list(result)
183 183 assert self.was_cache_invalidated()
184 184
185 185 @mock.patch('rhodecode.lib.middleware.simplevcs.HTTPLockedRC')
186 186 def test_handles_locking_exception(self, http_locked_rc):
187 187 result = self.call_controller_with_response_body(
188 188 self.raise_result_iter(vcs_kind='repo_locked'))
189 189 assert not http_locked_rc.called
190 190 # Consume the result
191 191 list(result)
192 192 assert http_locked_rc.called
193 193
194 194 @mock.patch('rhodecode.lib.middleware.simplevcs.HTTPRequirementError')
195 195 def test_handles_requirement_exception(self, http_requirement):
196 196 result = self.call_controller_with_response_body(
197 197 self.raise_result_iter(vcs_kind='requirement'))
198 198 assert not http_requirement.called
199 199 # Consume the result
200 200 list(result)
201 201 assert http_requirement.called
202 202
203 203 @mock.patch('rhodecode.lib.middleware.simplevcs.HTTPLockedRC')
204 204 def test_handles_locking_exception_in_app_call(self, http_locked_rc):
205 205 app_factory_patcher = mock.patch.object(
206 206 StubVCSController, '_create_wsgi_app')
207 207 with app_factory_patcher as app_factory:
208 208 app_factory().side_effect = self.vcs_exception()
209 209 result = self.call_controller_with_response_body(['a'])
210 210 list(result)
211 211 assert http_locked_rc.called
212 212
213 213 def test_raises_unknown_exceptions(self):
214 214 result = self.call_controller_with_response_body(
215 215 self.raise_result_iter(vcs_kind='unknown'))
216 216 with pytest.raises(Exception):
217 217 list(result)
218 218
219 219 def test_prepare_callback_daemon_is_called(self):
220 220 def side_effect(extras):
221 221 return DummyHooksCallbackDaemon(), extras
222 222
223 223 prepare_patcher = mock.patch.object(
224 224 StubVCSController, '_prepare_callback_daemon')
225 225 with prepare_patcher as prepare_mock:
226 226 prepare_mock.side_effect = side_effect
227 227 self.call_controller_with_response_body(iter(['a', 'b']))
228 228 assert prepare_mock.called
229 229 assert prepare_mock.call_count == 1
230 230
231 231 def call_controller_with_response_body(self, response_body):
232 232 settings = {
233 233 'base_path': 'fake_base_path',
234 234 'vcs.hooks.protocol': 'http',
235 235 'vcs.hooks.direct_calls': False,
236 236 }
237 237 controller = StubVCSController(None, settings, None)
238 238 controller._invalidate_cache = mock.Mock()
239 239 controller.stub_response_body = response_body
240 240 self.start_response = mock.Mock()
241 241 result = controller._generate_vcs_response(
242 242 environ={}, start_response=self.start_response,
243 243 repo_path='fake_repo_path',
244 244 repo_name='fake_repo_name',
245 245 extras={}, action='push')
246 246 self.controller = controller
247 247 return result
248 248
249 249 def raise_result_iter(self, vcs_kind='repo_locked'):
250 250 """
251 251 Simulates an exception due to a vcs raised exception if kind vcs_kind
252 252 """
253 253 raise self.vcs_exception(vcs_kind=vcs_kind)
254 254 yield "never_reached"
255 255
256 256 def vcs_exception(self, vcs_kind='repo_locked'):
257 257 locked_exception = Exception('TEST_MESSAGE')
258 258 locked_exception._vcs_kind = vcs_kind
259 259 return locked_exception
260 260
261 261 def was_cache_invalidated(self):
262 262 return self.controller._invalidate_cache.called
263 263
264 264
265 265 class TestInitializeGenerator:
266 266
267 267 def test_drains_first_element(self):
268 268 gen = self.factory(['__init__', 1, 2])
269 269 result = list(gen)
270 270 assert result == [1, 2]
271 271
272 272 @pytest.mark.parametrize('values', [
273 273 [],
274 274 [1, 2],
275 275 ])
276 276 def test_raises_value_error(self, values):
277 277 with pytest.raises(ValueError):
278 278 self.factory(values)
279 279
280 280 @simplevcs.initialize_generator
281 281 def factory(self, iterable):
282 282 for elem in iterable:
283 283 yield elem
284 284
285 285
286 286 class TestPrepareHooksDaemon(object):
287 def test_calls_imported_prepare_callback_daemon(self, pylonsapp):
288 settings = pylonsapp.application.config
287 def test_calls_imported_prepare_callback_daemon(self, app_settings):
289 288 expected_extras = {'extra1': 'value1'}
290 289 daemon = DummyHooksCallbackDaemon()
291 290
292 controller = StubVCSController(None, settings, None)
291 controller = StubVCSController(None, app_settings, None)
293 292 prepare_patcher = mock.patch.object(
294 293 simplevcs, 'prepare_callback_daemon',
295 294 return_value=(daemon, expected_extras))
296 295 with prepare_patcher as prepare_mock:
297 296 callback_daemon, extras = controller._prepare_callback_daemon(
298 297 expected_extras.copy())
299 298 prepare_mock.assert_called_once_with(
300 299 expected_extras,
301 protocol=settings['vcs.hooks.protocol'],
302 use_direct_calls=settings['vcs.hooks.direct_calls'])
300 protocol=app_settings['vcs.hooks.protocol'],
301 use_direct_calls=app_settings['vcs.hooks.direct_calls'])
303 302
304 303 assert callback_daemon == daemon
305 304 assert extras == extras
General Comments 0
You need to be logged in to leave comments. Login now