##// END OF EJS Templates
tests: conftests needs to be in the root of package for proper test collection
super-admin -
r4987:f5111bba default
parent child Browse files
Show More
@@ -1,199 +1,200 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2020 RhodeCode GmbH
3 # Copyright (C) 2010-2020 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 from rhodecode.lib import ext_json
22 from rhodecode.lib import ext_json
23
23
24
24
25 pytest_plugins = [
25 pytest_plugins = [
26 "rhodecode.tests.fixture_mods.fixture_pyramid",
26 "rhodecode.tests.fixture_mods.fixture_pyramid",
27 "rhodecode.tests.fixture_mods.fixture_utils",
27 "rhodecode.tests.fixture_mods.fixture_utils",
28 ]
28 ]
29
29
30
30
31 def pytest_configure(config):
31 def pytest_configure(config):
32 from rhodecode.config import patches
32 from rhodecode.config import patches
33
33
34
34
35 def pytest_addoption(parser):
35 def pytest_addoption(parser):
36
36
37 def _parse_json(value):
37 def _parse_json(value):
38 return ext_json.str_json(value) if value else None
38 return ext_json.str_json(value) if value else None
39
39
40 def _split_comma(value):
40 def _split_comma(value):
41 return value.split(',')
41 return value.split(',')
42
42
43 parser.addoption(
43 parser.addoption(
44 '--keep-tmp-path', action='store_true',
44 '--keep-tmp-path', action='store_true',
45 help="Keep the test temporary directories")
45 help="Keep the test temporary directories")
46 parser.addoption(
46 parser.addoption(
47 '--backends', action='store', type=_split_comma,
47 '--backends', action='store', type=_split_comma,
48 default=['git', 'hg', 'svn'],
48 default=['git', 'hg', 'svn'],
49 help="Select which backends to test for backend specific tests.")
49 help="Select which backends to test for backend specific tests.")
50 parser.addoption(
50 parser.addoption(
51 '--dbs', action='store', type=_split_comma,
51 '--dbs', action='store', type=_split_comma,
52 default=['sqlite'],
52 default=['sqlite'],
53 help="Select which database to test for database specific tests. "
53 help="Select which database to test for database specific tests. "
54 "Possible options are sqlite,postgres,mysql")
54 "Possible options are sqlite,postgres,mysql")
55 parser.addoption(
55 parser.addoption(
56 '--appenlight', '--ae', action='store_true',
56 '--appenlight', '--ae', action='store_true',
57 help="Track statistics in appenlight.")
57 help="Track statistics in appenlight.")
58 parser.addoption(
58 parser.addoption(
59 '--appenlight-api-key', '--ae-key',
59 '--appenlight-api-key', '--ae-key',
60 help="API key for Appenlight.")
60 help="API key for Appenlight.")
61 parser.addoption(
61 parser.addoption(
62 '--appenlight-url', '--ae-url',
62 '--appenlight-url', '--ae-url',
63 default="https://ae.rhodecode.com",
63 default="https://ae.rhodecode.com",
64 help="Appenlight service URL, defaults to https://ae.rhodecode.com")
64 help="Appenlight service URL, defaults to https://ae.rhodecode.com")
65 parser.addoption(
65 parser.addoption(
66 '--sqlite-connection-string', action='store',
66 '--sqlite-connection-string', action='store',
67 default='', help="Connection string for the dbs tests with SQLite")
67 default='', help="Connection string for the dbs tests with SQLite")
68 parser.addoption(
68 parser.addoption(
69 '--postgres-connection-string', action='store',
69 '--postgres-connection-string', action='store',
70 default='', help="Connection string for the dbs tests with Postgres")
70 default='', help="Connection string for the dbs tests with Postgres")
71 parser.addoption(
71 parser.addoption(
72 '--mysql-connection-string', action='store',
72 '--mysql-connection-string', action='store',
73 default='', help="Connection string for the dbs tests with MySQL")
73 default='', help="Connection string for the dbs tests with MySQL")
74 parser.addoption(
74 parser.addoption(
75 '--repeat', type=int, default=100,
75 '--repeat', type=int, default=100,
76 help="Number of repetitions in performance tests.")
76 help="Number of repetitions in performance tests.")
77
77
78 parser.addoption(
78 parser.addoption(
79 '--test-loglevel', dest='test_loglevel',
79 '--test-loglevel', dest='test_loglevel',
80 help="Set default Logging level for tests, critical(default), error, warn , info, debug")
80 help="Set default Logging level for tests, critical(default), error, warn , info, debug")
81 group = parser.getgroup('pylons')
81 group = parser.getgroup('pylons')
82 group.addoption(
82 group.addoption(
83 '--with-pylons', dest='pyramid_config',
83 '--with-pylons', dest='pyramid_config',
84 help="Set up a Pylons environment with the specified config file.")
84 help="Set up a Pylons environment with the specified config file.")
85 group.addoption(
85 group.addoption(
86 '--ini-config-override', action='store', type=_parse_json,
86 '--ini-config-override', action='store', type=_parse_json,
87 default=None, dest='pyramid_config_override', help=(
87 default=None, dest='pyramid_config_override', help=(
88 "Overrides the .ini file settings. Should be specified in JSON"
88 "Overrides the .ini file settings. Should be specified in JSON"
89 " format, e.g. '{\"section\": {\"parameter\": \"value\", ...}}'"
89 " format, e.g. '{\"section\": {\"parameter\": \"value\", ...}}'"
90 )
90 )
91 )
91 )
92 parser.addini(
92 parser.addini(
93 'pyramid_config',
93 'pyramid_config',
94 "Set up a Pyramid environment with the specified config file.")
94 "Set up a Pyramid environment with the specified config file.")
95
95
96 vcsgroup = parser.getgroup('vcs')
96 vcsgroup = parser.getgroup('vcs')
97 vcsgroup.addoption(
97 vcsgroup.addoption(
98 '--without-vcsserver', dest='with_vcsserver', action='store_false',
98 '--without-vcsserver', dest='with_vcsserver', action='store_false',
99 help="Do not start the VCSServer in a background process.")
99 help="Do not start the VCSServer in a background process.")
100 vcsgroup.addoption(
100 vcsgroup.addoption(
101 '--with-vcsserver-http', dest='vcsserver_config_http',
101 '--with-vcsserver-http', dest='vcsserver_config_http',
102 help="Start the HTTP VCSServer with the specified config file.")
102 help="Start the HTTP VCSServer with the specified config file.")
103 vcsgroup.addoption(
103 vcsgroup.addoption(
104 '--vcsserver-protocol', dest='vcsserver_protocol',
104 '--vcsserver-protocol', dest='vcsserver_protocol',
105 help="Start the VCSServer with HTTP protocol support.")
105 help="Start the VCSServer with HTTP protocol support.")
106 vcsgroup.addoption(
106 vcsgroup.addoption(
107 '--vcsserver-config-override', action='store', type=_parse_json,
107 '--vcsserver-config-override', action='store', type=_parse_json,
108 default=None, dest='vcsserver_config_override', help=(
108 default=None, dest='vcsserver_config_override', help=(
109 "Overrides the .ini file settings for the VCSServer. "
109 "Overrides the .ini file settings for the VCSServer. "
110 "Should be specified in JSON "
110 "Should be specified in JSON "
111 "format, e.g. '{\"section\": {\"parameter\": \"value\", ...}}'"
111 "format, e.g. '{\"section\": {\"parameter\": \"value\", ...}}'"
112 )
112 )
113 )
113 )
114 vcsgroup.addoption(
114 vcsgroup.addoption(
115 '--vcsserver-port', action='store', type=int,
115 '--vcsserver-port', action='store', type=int,
116 default=None, help=(
116 default=None, help=(
117 "Allows to set the port of the vcsserver. Useful when testing "
117 "Allows to set the port of the vcsserver. Useful when testing "
118 "against an already running server and random ports cause "
118 "against an already running server and random ports cause "
119 "trouble."))
119 "trouble."))
120 parser.addini(
120 parser.addini(
121 'vcsserver_config_http',
121 'vcsserver_config_http',
122 "Start the HTTP VCSServer with the specified config file.")
122 "Start the HTTP VCSServer with the specified config file.")
123 parser.addini(
123 parser.addini(
124 'vcsserver_protocol',
124 'vcsserver_protocol',
125 "Start the VCSServer with HTTP protocol support.")
125 "Start the VCSServer with HTTP protocol support.")
126
126
127
127
128 @pytest.hookimpl(tryfirst=True, hookwrapper=True)
128 @pytest.hookimpl(tryfirst=True, hookwrapper=True)
129 def pytest_runtest_makereport(item, call):
129 def pytest_runtest_makereport(item, call):
130 """
130 """
131 Adding the remote traceback if the exception has this information.
131 Adding the remote traceback if the exception has this information.
132
132
133 VCSServer attaches this information as the attribute `_vcs_server_traceback`
133 VCSServer attaches this information as the attribute `_vcs_server_traceback`
134 to the exception instance.
134 to the exception instance.
135 """
135 """
136 outcome = yield
136 outcome = yield
137 report = outcome.get_result()
137 report = outcome.get_result()
138
138 if call.excinfo:
139 if call.excinfo:
139 exc = call.excinfo.value
140 exc = call.excinfo.value
140 vcsserver_traceback = getattr(exc, '_vcs_server_traceback', None)
141 vcsserver_traceback = getattr(exc, '_vcs_server_traceback', None)
141
142
142 if vcsserver_traceback:
143 if vcsserver_traceback:
143 section = 'VCSServer remote traceback ' + report.when
144 section = f'VCSServer remote traceback {report.when}'
144 report.sections.append((section, vcsserver_traceback))
145 report.sections.append((section, vcsserver_traceback))
145
146
146
147
147 def pytest_collection_modifyitems(session, config, items):
148 def pytest_collection_modifyitems(session, config, items):
148 # nottest marked, compare nose, used for transition from nose to pytest
149 # nottest marked, compare nose, used for transition from nose to pytest
149 remaining = [
150 remaining = [
150 i for i in items if getattr(i.obj, '__test__', True)]
151 i for i in items if getattr(i.obj, '__test__', True)]
151 items[:] = remaining
152 items[:] = remaining
152
153
153 # NOTE(marcink): custom test ordering, db tests and vcstests are slowes and should
154 # NOTE(marcink): custom test ordering, db tests and vcstests are slowes and should
154 # be executed at the end for faster test feedback
155 # be executed at the end for faster test feedback
155 def sorter(item):
156 def sorter(item):
156 pos = 0
157 pos = 0
157 key = item._nodeid
158 key = item._nodeid
158 if key.startswith('rhodecode/tests/database'):
159 if key.startswith('rhodecode/tests/database'):
159 pos = 1
160 pos = 1
160 elif key.startswith('rhodecode/tests/vcs_operations'):
161 elif key.startswith('rhodecode/tests/vcs_operations'):
161 pos = 2
162 pos = 2
162
163
163 return pos
164 return pos
164
165
165 items.sort(key=sorter)
166 items.sort(key=sorter)
166
167
167
168
168 def get_backends_from_metafunc(metafunc):
169 def get_backends_from_metafunc(metafunc):
169 requested_backends = set(metafunc.config.getoption('--backends'))
170 requested_backends = set(metafunc.config.getoption('--backends'))
170 backend_mark = metafunc.definition.get_closest_marker('backends')
171 backend_mark = metafunc.definition.get_closest_marker('backends')
171 if backend_mark:
172 if backend_mark:
172 # Supported backends by this test function, created from
173 # Supported backends by this test function, created from
173 # pytest.mark.backends
174 # pytest.mark.backends
174 backends = backend_mark.args
175 backends = backend_mark.args
175 elif hasattr(metafunc.cls, 'backend_alias'):
176 elif hasattr(metafunc.cls, 'backend_alias'):
176 # Support class attribute "backend_alias", this is mainly
177 # Support class attribute "backend_alias", this is mainly
177 # for legacy reasons for tests not yet using pytest.mark.backends
178 # for legacy reasons for tests not yet using pytest.mark.backends
178 backends = [metafunc.cls.backend_alias]
179 backends = [metafunc.cls.backend_alias]
179 else:
180 else:
180 backends = metafunc.config.getoption('--backends')
181 backends = metafunc.config.getoption('--backends')
181 return requested_backends.intersection(backends)
182 return requested_backends.intersection(backends)
182
183
183
184
184 def pytest_generate_tests(metafunc):
185 def pytest_generate_tests(metafunc):
185
186
186 # Support test generation based on --backend parameter
187 # Support test generation based on --backend parameter
187 if 'backend_alias' in metafunc.fixturenames:
188 if 'backend_alias' in metafunc.fixturenames:
188 backends = get_backends_from_metafunc(metafunc)
189 backends = get_backends_from_metafunc(metafunc)
189 scope = None
190 scope = None
190 if not backends:
191 if not backends:
191 pytest.skip("Not enabled for any of selected backends")
192 pytest.skip("Not enabled for any of selected backends")
192
193
193 metafunc.parametrize('backend_alias', backends, scope=scope)
194 metafunc.parametrize('backend_alias', backends, scope=scope)
194
195
195 backend_mark = metafunc.definition.get_closest_marker('backends')
196 backend_mark = metafunc.definition.get_closest_marker('backends')
196 if backend_mark:
197 if backend_mark:
197 backends = get_backends_from_metafunc(metafunc)
198 backends = get_backends_from_metafunc(metafunc)
198 if not backends:
199 if not backends:
199 pytest.skip("Not enabled for any of selected backends")
200 pytest.skip("Not enabled for any of selected backends")
General Comments 0
You need to be logged in to leave comments. Login now