##// END OF EJS Templates
pytest: Use http as default backend in pytest configuration.
Martin Bornhold -
r969:63a8933a default
parent child Browse files
Show More
@@ -1,12 +1,12 b''
1 [pytest]
1 [pytest]
2 testpaths = ./rhodecode
2 testpaths = ./rhodecode
3 pylons_config = test.ini
3 pylons_config = test.ini
4 vcsserver_protocol = pyro4
4 vcsserver_protocol = http
5 vcsserver_config = rhodecode/tests/vcsserver.ini
5 vcsserver_config_pyro4 = rhodecode/tests/vcsserver_pyro4.ini
6 vcsserver_config_http = rhodecode/tests/vcsserver_pyramid.ini
6 vcsserver_config_http = rhodecode/tests/vcsserver_http.ini
7 norecursedirs = tests/scripts
7 norecursedirs = tests/scripts
8 addopts = -k "not _BaseTest"
8 addopts = -k "not _BaseTest"
9 markers =
9 markers =
10 vcs_operations: Mark tests depending on a running RhodeCode instance.
10 vcs_operations: Mark tests depending on a running RhodeCode instance.
11 xfail_backends: Mark tests as xfail for given backends.
11 xfail_backends: Mark tests as xfail for given backends.
12 skip_backends: Mark tests as skipped for given backends.
12 skip_backends: Mark tests as skipped for given backends.
@@ -1,440 +1,440 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 RhodeCode GmbH
3 # Copyright (C) 2010-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 json
21 import json
22 import logging.config
22 import logging.config
23 import os
23 import os
24 import platform
24 import platform
25 import socket
25 import socket
26 import subprocess
26 import subprocess
27 import time
27 import time
28 from urllib2 import urlopen, URLError
28 from urllib2 import urlopen, URLError
29
29
30 import configobj
30 import configobj
31 import pylons
31 import pylons
32 import pytest
32 import pytest
33 import webob
33 import webob
34 from beaker.session import SessionObject
34 from beaker.session import SessionObject
35 from paste.deploy import loadapp
35 from paste.deploy import loadapp
36 from pylons.i18n.translation import _get_translator
36 from pylons.i18n.translation import _get_translator
37 from pylons.util import ContextObj
37 from pylons.util import ContextObj
38 from Pyro4.errors import CommunicationError
38 from Pyro4.errors import CommunicationError
39 from routes.util import URLGenerator
39 from routes.util import URLGenerator
40
40
41 from rhodecode.lib import vcs
41 from rhodecode.lib import vcs
42 from rhodecode.tests.fixture import TestINI
42 from rhodecode.tests.fixture import TestINI
43 import rhodecode
43 import rhodecode
44
44
45
45
46 def _parse_json(value):
46 def _parse_json(value):
47 return json.loads(value) if value else None
47 return json.loads(value) if value else None
48
48
49
49
50 def pytest_addoption(parser):
50 def pytest_addoption(parser):
51 group = parser.getgroup('pylons')
51 group = parser.getgroup('pylons')
52 group.addoption(
52 group.addoption(
53 '--with-pylons', dest='pylons_config',
53 '--with-pylons', dest='pylons_config',
54 help="Set up a Pylons environment with the specified config file.")
54 help="Set up a Pylons environment with the specified config file.")
55 group.addoption(
55 group.addoption(
56 '--pylons-config-override', action='store', type=_parse_json,
56 '--pylons-config-override', action='store', type=_parse_json,
57 default=None, dest='pylons_config_override', help=(
57 default=None, dest='pylons_config_override', help=(
58 "Overrides the .ini file settings. Should be specified in JSON"
58 "Overrides the .ini file settings. Should be specified in JSON"
59 " format, e.g. '{\"section\": {\"parameter\": \"value\", ...}}'"
59 " format, e.g. '{\"section\": {\"parameter\": \"value\", ...}}'"
60 )
60 )
61 )
61 )
62 parser.addini(
62 parser.addini(
63 'pylons_config',
63 'pylons_config',
64 "Set up a Pylons environment with the specified config file.")
64 "Set up a Pylons environment with the specified config file.")
65
65
66 vcsgroup = parser.getgroup('vcs')
66 vcsgroup = parser.getgroup('vcs')
67 vcsgroup.addoption(
67 vcsgroup.addoption(
68 '--without-vcsserver', dest='with_vcsserver', action='store_false',
68 '--without-vcsserver', dest='with_vcsserver', action='store_false',
69 help="Do not start the VCSServer in a background process.")
69 help="Do not start the VCSServer in a background process.")
70 vcsgroup.addoption(
70 vcsgroup.addoption(
71 '--with-vcsserver', dest='vcsserver_config',
71 '--with-vcsserver', dest='vcsserver_config_pyro4',
72 help="Start the VCSServer with the specified config file.")
72 help="Start the VCSServer with the specified config file.")
73 vcsgroup.addoption(
73 vcsgroup.addoption(
74 '--with-vcsserver-http', dest='vcsserver_config_http',
74 '--with-vcsserver-http', dest='vcsserver_config_http',
75 help="Start the HTTP VCSServer with the specified config file.")
75 help="Start the HTTP VCSServer with the specified config file.")
76 vcsgroup.addoption(
76 vcsgroup.addoption(
77 '--vcsserver-protocol', dest='vcsserver_protocol',
77 '--vcsserver-protocol', dest='vcsserver_protocol',
78 help="Start the VCSServer with HTTP / Pyro4 protocol support.")
78 help="Start the VCSServer with HTTP / Pyro4 protocol support.")
79 vcsgroup.addoption(
79 vcsgroup.addoption(
80 '--vcsserver-config-override', action='store', type=_parse_json,
80 '--vcsserver-config-override', action='store', type=_parse_json,
81 default=None, dest='vcsserver_config_override', help=(
81 default=None, dest='vcsserver_config_override', help=(
82 "Overrides the .ini file settings for the VCSServer. "
82 "Overrides the .ini file settings for the VCSServer. "
83 "Should be specified in JSON "
83 "Should be specified in JSON "
84 "format, e.g. '{\"section\": {\"parameter\": \"value\", ...}}'"
84 "format, e.g. '{\"section\": {\"parameter\": \"value\", ...}}'"
85 )
85 )
86 )
86 )
87 vcsgroup.addoption(
87 vcsgroup.addoption(
88 '--vcsserver-port', action='store', type=int,
88 '--vcsserver-port', action='store', type=int,
89 default=None, help=(
89 default=None, help=(
90 "Allows to set the port of the vcsserver. Useful when testing "
90 "Allows to set the port of the vcsserver. Useful when testing "
91 "against an already running server and random ports cause "
91 "against an already running server and random ports cause "
92 "trouble."))
92 "trouble."))
93 parser.addini(
93 parser.addini(
94 'vcsserver_config',
94 'vcsserver_config_pyro4',
95 "Start the VCSServer with the specified config file.")
95 "Start the VCSServer with the specified config file.")
96 parser.addini(
96 parser.addini(
97 'vcsserver_config_http',
97 'vcsserver_config_http',
98 "Start the HTTP VCSServer with the specified config file.")
98 "Start the HTTP VCSServer with the specified config file.")
99 parser.addini(
99 parser.addini(
100 'vcsserver_protocol',
100 'vcsserver_protocol',
101 "Start the VCSServer with HTTP / Pyro4 protocol support.")
101 "Start the VCSServer with HTTP / Pyro4 protocol support.")
102
102
103
103
104 @pytest.fixture(scope='session')
104 @pytest.fixture(scope='session')
105 def vcsserver(request, vcsserver_port, vcsserver_factory):
105 def vcsserver(request, vcsserver_port, vcsserver_factory):
106 """
106 """
107 Session scope VCSServer.
107 Session scope VCSServer.
108
108
109 Tests wich need the VCSServer have to rely on this fixture in order
109 Tests wich need the VCSServer have to rely on this fixture in order
110 to ensure it will be running.
110 to ensure it will be running.
111
111
112 For specific needs, the fixture vcsserver_factory can be used. It allows to
112 For specific needs, the fixture vcsserver_factory can be used. It allows to
113 adjust the configuration file for the test run.
113 adjust the configuration file for the test run.
114
114
115 Command line args:
115 Command line args:
116
116
117 --without-vcsserver: Allows to switch this fixture off. You have to
117 --without-vcsserver: Allows to switch this fixture off. You have to
118 manually start the server.
118 manually start the server.
119
119
120 --vcsserver-port: Will expect the VCSServer to listen on this port.
120 --vcsserver-port: Will expect the VCSServer to listen on this port.
121 """
121 """
122
122
123 if not request.config.getoption('with_vcsserver'):
123 if not request.config.getoption('with_vcsserver'):
124 return None
124 return None
125
125
126 use_http = _use_vcs_http_server(request.config)
126 use_http = _use_vcs_http_server(request.config)
127 return vcsserver_factory(
127 return vcsserver_factory(
128 request, use_http=use_http, vcsserver_port=vcsserver_port)
128 request, use_http=use_http, vcsserver_port=vcsserver_port)
129
129
130
130
131 @pytest.fixture(scope='session')
131 @pytest.fixture(scope='session')
132 def vcsserver_factory(tmpdir_factory):
132 def vcsserver_factory(tmpdir_factory):
133 """
133 """
134 Use this if you need a running vcsserver with a special configuration.
134 Use this if you need a running vcsserver with a special configuration.
135 """
135 """
136
136
137 def factory(request, use_http=False, overrides=(), vcsserver_port=None):
137 def factory(request, use_http=False, overrides=(), vcsserver_port=None):
138
138
139 if vcsserver_port is None:
139 if vcsserver_port is None:
140 vcsserver_port = get_available_port()
140 vcsserver_port = get_available_port()
141
141
142 overrides = list(overrides)
142 overrides = list(overrides)
143 if use_http:
143 if use_http:
144 overrides.append({'server:main': {'port': vcsserver_port}})
144 overrides.append({'server:main': {'port': vcsserver_port}})
145 else:
145 else:
146 overrides.append({'DEFAULT': {'port': vcsserver_port}})
146 overrides.append({'DEFAULT': {'port': vcsserver_port}})
147
147
148 if is_cygwin():
148 if is_cygwin():
149 platform_override = {'DEFAULT': {
149 platform_override = {'DEFAULT': {
150 'beaker.cache.repo_object.type': 'nocache'}}
150 'beaker.cache.repo_object.type': 'nocache'}}
151 overrides.append(platform_override)
151 overrides.append(platform_override)
152
152
153 option_name = (
153 option_name = (
154 'vcsserver_config_http' if use_http else 'vcsserver_config')
154 'vcsserver_config_http' if use_http else 'vcsserver_config_pyro4')
155 override_option_name = 'vcsserver_config_override'
155 override_option_name = 'vcsserver_config_override'
156 config_file = get_config(
156 config_file = get_config(
157 request.config, option_name=option_name,
157 request.config, option_name=option_name,
158 override_option_name=override_option_name, overrides=overrides,
158 override_option_name=override_option_name, overrides=overrides,
159 basetemp=tmpdir_factory.getbasetemp().strpath,
159 basetemp=tmpdir_factory.getbasetemp().strpath,
160 prefix='test_vcs_')
160 prefix='test_vcs_')
161
161
162 print "Using the VCSServer configuration", config_file
162 print "Using the VCSServer configuration", config_file
163 ServerClass = HttpVCSServer if use_http else Pyro4VCSServer
163 ServerClass = HttpVCSServer if use_http else Pyro4VCSServer
164 server = ServerClass(config_file)
164 server = ServerClass(config_file)
165 server.start()
165 server.start()
166
166
167 @request.addfinalizer
167 @request.addfinalizer
168 def cleanup():
168 def cleanup():
169 server.shutdown()
169 server.shutdown()
170
170
171 server.wait_until_ready()
171 server.wait_until_ready()
172 return server
172 return server
173
173
174 return factory
174 return factory
175
175
176
176
177 def is_cygwin():
177 def is_cygwin():
178 return 'cygwin' in platform.system().lower()
178 return 'cygwin' in platform.system().lower()
179
179
180
180
181 def _use_vcs_http_server(config):
181 def _use_vcs_http_server(config):
182 protocol_option = 'vcsserver_protocol'
182 protocol_option = 'vcsserver_protocol'
183 protocol = (
183 protocol = (
184 config.getoption(protocol_option) or
184 config.getoption(protocol_option) or
185 config.getini(protocol_option) or
185 config.getini(protocol_option) or
186 'pyro4')
186 'http')
187 return protocol == 'http'
187 return protocol == 'http'
188
188
189
189
190 class VCSServer(object):
190 class VCSServer(object):
191 """
191 """
192 Represents a running VCSServer instance.
192 Represents a running VCSServer instance.
193 """
193 """
194
194
195 _args = []
195 _args = []
196
196
197 def start(self):
197 def start(self):
198 print("Starting the VCSServer: {}".format(self._args))
198 print("Starting the VCSServer: {}".format(self._args))
199 self.process = subprocess.Popen(self._args)
199 self.process = subprocess.Popen(self._args)
200
200
201 def wait_until_ready(self, timeout=30):
201 def wait_until_ready(self, timeout=30):
202 raise NotImplementedError()
202 raise NotImplementedError()
203
203
204 def shutdown(self):
204 def shutdown(self):
205 self.process.kill()
205 self.process.kill()
206
206
207
207
208 class Pyro4VCSServer(VCSServer):
208 class Pyro4VCSServer(VCSServer):
209 def __init__(self, config_file):
209 def __init__(self, config_file):
210 """
210 """
211 :param config_file: The config file to start the server with
211 :param config_file: The config file to start the server with
212 """
212 """
213
213
214 config_data = configobj.ConfigObj(config_file)
214 config_data = configobj.ConfigObj(config_file)
215 self._config = config_data['DEFAULT']
215 self._config = config_data['DEFAULT']
216
216
217 args = ['vcsserver', '--config', config_file]
217 args = ['vcsserver', '--config', config_file]
218 self._args = args
218 self._args = args
219
219
220 def wait_until_ready(self, timeout=30):
220 def wait_until_ready(self, timeout=30):
221 remote_server = vcs.create_vcsserver_proxy(
221 remote_server = vcs.create_vcsserver_proxy(
222 self.server_and_port, 'pyro4')
222 self.server_and_port, 'pyro4')
223 start = time.time()
223 start = time.time()
224 with remote_server:
224 with remote_server:
225 while time.time() - start < timeout:
225 while time.time() - start < timeout:
226 try:
226 try:
227 remote_server.ping()
227 remote_server.ping()
228 break
228 break
229 except CommunicationError:
229 except CommunicationError:
230 time.sleep(0.2)
230 time.sleep(0.2)
231 else:
231 else:
232 pytest.exit(
232 pytest.exit(
233 "Starting the VCSServer failed or took more than {} "
233 "Starting the VCSServer failed or took more than {} "
234 "seconds.".format(timeout))
234 "seconds.".format(timeout))
235
235
236 @property
236 @property
237 def server_and_port(self):
237 def server_and_port(self):
238 return '{host}:{port}'.format(**self._config)
238 return '{host}:{port}'.format(**self._config)
239
239
240
240
241 class HttpVCSServer(VCSServer):
241 class HttpVCSServer(VCSServer):
242 """
242 """
243 Represents a running VCSServer instance.
243 Represents a running VCSServer instance.
244 """
244 """
245 def __init__(self, config_file):
245 def __init__(self, config_file):
246 config_data = configobj.ConfigObj(config_file)
246 config_data = configobj.ConfigObj(config_file)
247 self._config = config_data['server:main']
247 self._config = config_data['server:main']
248
248
249 args = ['pserve', config_file, 'http_host=0.0.0.0']
249 args = ['pserve', config_file, 'http_host=0.0.0.0']
250 self._args = args
250 self._args = args
251
251
252 @property
252 @property
253 def http_url(self):
253 def http_url(self):
254 template = 'http://{host}:{port}/'
254 template = 'http://{host}:{port}/'
255 return template.format(**self._config)
255 return template.format(**self._config)
256
256
257 def start(self):
257 def start(self):
258 self.process = subprocess.Popen(self._args)
258 self.process = subprocess.Popen(self._args)
259
259
260 def wait_until_ready(self, timeout=30):
260 def wait_until_ready(self, timeout=30):
261 host = self._config['host']
261 host = self._config['host']
262 port = self._config['port']
262 port = self._config['port']
263 status_url = 'http://{host}:{port}/status'.format(host=host, port=port)
263 status_url = 'http://{host}:{port}/status'.format(host=host, port=port)
264 start = time.time()
264 start = time.time()
265
265
266 while time.time() - start < timeout:
266 while time.time() - start < timeout:
267 try:
267 try:
268 urlopen(status_url)
268 urlopen(status_url)
269 break
269 break
270 except URLError:
270 except URLError:
271 time.sleep(0.2)
271 time.sleep(0.2)
272 else:
272 else:
273 pytest.exit(
273 pytest.exit(
274 "Starting the VCSServer failed or took more than {} "
274 "Starting the VCSServer failed or took more than {} "
275 "seconds.".format(timeout))
275 "seconds.".format(timeout))
276
276
277 def shutdown(self):
277 def shutdown(self):
278 self.process.kill()
278 self.process.kill()
279
279
280
280
281 @pytest.fixture(scope='session')
281 @pytest.fixture(scope='session')
282 def pylons_config(request, tmpdir_factory, rcserver_port, vcsserver_port):
282 def pylons_config(request, tmpdir_factory, rcserver_port, vcsserver_port):
283 option_name = 'pylons_config'
283 option_name = 'pylons_config'
284
284
285 overrides = [
285 overrides = [
286 {'server:main': {'port': rcserver_port}},
286 {'server:main': {'port': rcserver_port}},
287 {'app:main': {
287 {'app:main': {
288 'vcs.server': 'localhost:%s' % vcsserver_port,
288 'vcs.server': 'localhost:%s' % vcsserver_port,
289 # johbo: We will always start the VCSServer on our own based on the
289 # johbo: We will always start the VCSServer on our own based on the
290 # fixtures of the test cases. For the test run it must always be
290 # fixtures of the test cases. For the test run it must always be
291 # off in the INI file.
291 # off in the INI file.
292 'vcs.start_server': 'false',
292 'vcs.start_server': 'false',
293 }},
293 }},
294 ]
294 ]
295 if _use_vcs_http_server(request.config):
295 if _use_vcs_http_server(request.config):
296 overrides.append({'app:main': {'vcs.server.protocol': 'http'}})
296 overrides.append({'app:main': {'vcs.server.protocol': 'http'}})
297
297
298 filename = get_config(
298 filename = get_config(
299 request.config, option_name=option_name,
299 request.config, option_name=option_name,
300 override_option_name='{}_override'.format(option_name),
300 override_option_name='{}_override'.format(option_name),
301 overrides=overrides,
301 overrides=overrides,
302 basetemp=tmpdir_factory.getbasetemp().strpath,
302 basetemp=tmpdir_factory.getbasetemp().strpath,
303 prefix='test_rce_')
303 prefix='test_rce_')
304 return filename
304 return filename
305
305
306
306
307 @pytest.fixture(scope='session')
307 @pytest.fixture(scope='session')
308 def rcserver_port(request):
308 def rcserver_port(request):
309 port = get_available_port()
309 port = get_available_port()
310 print 'Using rcserver port %s' % (port, )
310 print 'Using rcserver port %s' % (port, )
311 return port
311 return port
312
312
313
313
314 @pytest.fixture(scope='session')
314 @pytest.fixture(scope='session')
315 def vcsserver_port(request):
315 def vcsserver_port(request):
316 port = request.config.getoption('--vcsserver-port')
316 port = request.config.getoption('--vcsserver-port')
317 if port is None:
317 if port is None:
318 port = get_available_port()
318 port = get_available_port()
319 print 'Using vcsserver port %s' % (port, )
319 print 'Using vcsserver port %s' % (port, )
320 return port
320 return port
321
321
322
322
323 def get_available_port():
323 def get_available_port():
324 family = socket.AF_INET
324 family = socket.AF_INET
325 socktype = socket.SOCK_STREAM
325 socktype = socket.SOCK_STREAM
326 host = '127.0.0.1'
326 host = '127.0.0.1'
327
327
328 mysocket = socket.socket(family, socktype)
328 mysocket = socket.socket(family, socktype)
329 mysocket.bind((host, 0))
329 mysocket.bind((host, 0))
330 port = mysocket.getsockname()[1]
330 port = mysocket.getsockname()[1]
331 mysocket.close()
331 mysocket.close()
332 del mysocket
332 del mysocket
333 return port
333 return port
334
334
335
335
336 @pytest.fixture(scope='session')
336 @pytest.fixture(scope='session')
337 def available_port_factory():
337 def available_port_factory():
338 """
338 """
339 Returns a callable which returns free port numbers.
339 Returns a callable which returns free port numbers.
340 """
340 """
341 return get_available_port
341 return get_available_port
342
342
343
343
344 @pytest.fixture
344 @pytest.fixture
345 def available_port(available_port_factory):
345 def available_port(available_port_factory):
346 """
346 """
347 Gives you one free port for the current test.
347 Gives you one free port for the current test.
348
348
349 Uses "available_port_factory" to retrieve the port.
349 Uses "available_port_factory" to retrieve the port.
350 """
350 """
351 return available_port_factory()
351 return available_port_factory()
352
352
353
353
354 @pytest.fixture(scope='session')
354 @pytest.fixture(scope='session')
355 def pylonsapp(pylons_config, vcsserver, http_environ_session):
355 def pylonsapp(pylons_config, vcsserver, http_environ_session):
356 logging.config.fileConfig(
356 logging.config.fileConfig(
357 pylons_config, disable_existing_loggers=False)
357 pylons_config, disable_existing_loggers=False)
358 app = _setup_pylons_environment(pylons_config, http_environ_session)
358 app = _setup_pylons_environment(pylons_config, http_environ_session)
359 return app
359 return app
360
360
361
361
362 @pytest.fixture(scope='session')
362 @pytest.fixture(scope='session')
363 def testini_factory(tmpdir_factory, pylons_config):
363 def testini_factory(tmpdir_factory, pylons_config):
364 """
364 """
365 Factory to create an INI file based on TestINI.
365 Factory to create an INI file based on TestINI.
366
366
367 It will make sure to place the INI file in the correct directory.
367 It will make sure to place the INI file in the correct directory.
368 """
368 """
369 basetemp = tmpdir_factory.getbasetemp().strpath
369 basetemp = tmpdir_factory.getbasetemp().strpath
370 return TestIniFactory(basetemp, pylons_config)
370 return TestIniFactory(basetemp, pylons_config)
371
371
372
372
373 class TestIniFactory(object):
373 class TestIniFactory(object):
374
374
375 def __init__(self, basetemp, template_ini):
375 def __init__(self, basetemp, template_ini):
376 self._basetemp = basetemp
376 self._basetemp = basetemp
377 self._template_ini = template_ini
377 self._template_ini = template_ini
378
378
379 def __call__(self, ini_params, new_file_prefix='test'):
379 def __call__(self, ini_params, new_file_prefix='test'):
380 ini_file = TestINI(
380 ini_file = TestINI(
381 self._template_ini, ini_params=ini_params,
381 self._template_ini, ini_params=ini_params,
382 new_file_prefix=new_file_prefix, dir=self._basetemp)
382 new_file_prefix=new_file_prefix, dir=self._basetemp)
383 result = ini_file.create()
383 result = ini_file.create()
384 return result
384 return result
385
385
386
386
387 def get_config(
387 def get_config(
388 config, option_name, override_option_name, overrides=None,
388 config, option_name, override_option_name, overrides=None,
389 basetemp=None, prefix='test'):
389 basetemp=None, prefix='test'):
390 """
390 """
391 Find a configuration file and apply overrides for the given `prefix`.
391 Find a configuration file and apply overrides for the given `prefix`.
392 """
392 """
393 config_file = (
393 config_file = (
394 config.getoption(option_name) or config.getini(option_name))
394 config.getoption(option_name) or config.getini(option_name))
395 if not config_file:
395 if not config_file:
396 pytest.exit(
396 pytest.exit(
397 "Configuration error, could not extract {}.".format(option_name))
397 "Configuration error, could not extract {}.".format(option_name))
398
398
399 overrides = overrides or []
399 overrides = overrides or []
400 config_override = config.getoption(override_option_name)
400 config_override = config.getoption(override_option_name)
401 if config_override:
401 if config_override:
402 overrides.append(config_override)
402 overrides.append(config_override)
403 temp_ini_file = TestINI(
403 temp_ini_file = TestINI(
404 config_file, ini_params=overrides, new_file_prefix=prefix,
404 config_file, ini_params=overrides, new_file_prefix=prefix,
405 dir=basetemp)
405 dir=basetemp)
406
406
407 return temp_ini_file.create()
407 return temp_ini_file.create()
408
408
409
409
410 def _setup_pylons_environment(pylons_config, http_environ):
410 def _setup_pylons_environment(pylons_config, http_environ):
411 current_path = os.getcwd()
411 current_path = os.getcwd()
412 pylonsapp = loadapp(
412 pylonsapp = loadapp(
413 'config:' + pylons_config, relative_to=current_path)
413 'config:' + pylons_config, relative_to=current_path)
414
414
415 # Using rhodecode.CONFIG which is assigned during "load_environment".
415 # Using rhodecode.CONFIG which is assigned during "load_environment".
416 # The indirect approach is used, because "pylonsapp" may actually be
416 # The indirect approach is used, because "pylonsapp" may actually be
417 # the Pyramid application.
417 # the Pyramid application.
418 pylonsapp_config = rhodecode.CONFIG
418 pylonsapp_config = rhodecode.CONFIG
419 _init_stack(pylonsapp_config, environ=http_environ)
419 _init_stack(pylonsapp_config, environ=http_environ)
420
420
421 # For compatibility add the attribute "config" which would be
421 # For compatibility add the attribute "config" which would be
422 # present on the Pylons application.
422 # present on the Pylons application.
423 pylonsapp.config = pylonsapp_config
423 pylonsapp.config = pylonsapp_config
424 return pylonsapp
424 return pylonsapp
425
425
426
426
427 def _init_stack(config=None, environ=None):
427 def _init_stack(config=None, environ=None):
428 if not config:
428 if not config:
429 config = pylons.test.pylonsapp.config
429 config = pylons.test.pylonsapp.config
430 if not environ:
430 if not environ:
431 environ = {}
431 environ = {}
432 pylons.url._push_object(URLGenerator(config['routes.map'], environ or {}))
432 pylons.url._push_object(URLGenerator(config['routes.map'], environ or {}))
433 pylons.app_globals._push_object(config['pylons.app_globals'])
433 pylons.app_globals._push_object(config['pylons.app_globals'])
434 pylons.config._push_object(config)
434 pylons.config._push_object(config)
435 pylons.tmpl_context._push_object(ContextObj())
435 pylons.tmpl_context._push_object(ContextObj())
436 # Initialize a translator for tests that utilize i18n
436 # Initialize a translator for tests that utilize i18n
437 translator = _get_translator(pylons.config.get('lang'))
437 translator = _get_translator(pylons.config.get('lang'))
438 pylons.translator._push_object(translator)
438 pylons.translator._push_object(translator)
439 pylons.session._push_object(SessionObject(environ or {}))
439 pylons.session._push_object(SessionObject(environ or {}))
440 pylons.request._push_object(webob.Request.blank('', environ=environ))
440 pylons.request._push_object(webob.Request.blank('', environ=environ))
General Comments 0
You need to be logged in to leave comments. Login now