##// END OF EJS Templates
tests: use safer test id generator....
marcink -
r3095:09380574 default
parent child Browse files
Show More
@@ -1,245 +1,245 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2018 RhodeCode GmbH
3 # Copyright (C) 2010-2018 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 os
21 import os
22 import time
22 import time
23 import logging
23 import logging
24 import datetime
24 import datetime
25 import hashlib
25 import hashlib
26 import tempfile
26 import tempfile
27 from os.path import join as jn
27 from os.path import join as jn
28
28
29 from tempfile import _RandomNameSequence
29 from tempfile import _RandomNameSequence
30
30
31 import pytest
31 import pytest
32
32
33 from rhodecode.model.db import User
33 from rhodecode.model.db import User
34 from rhodecode.lib import auth
34 from rhodecode.lib import auth
35 from rhodecode.lib import helpers as h
35 from rhodecode.lib import helpers as h
36 from rhodecode.lib.helpers import flash, link_to
36 from rhodecode.lib.helpers import flash, link_to
37 from rhodecode.lib.utils2 import safe_str
37 from rhodecode.lib.utils2 import safe_str
38
38
39
39
40 log = logging.getLogger(__name__)
40 log = logging.getLogger(__name__)
41
41
42 __all__ = [
42 __all__ = [
43 'get_new_dir', 'TestController',
43 'get_new_dir', 'TestController',
44 'link_to', 'clear_cache_regions',
44 'link_to', 'clear_cache_regions',
45 'assert_session_flash', 'login_user', 'no_newline_id_generator',
45 'assert_session_flash', 'login_user', 'no_newline_id_generator',
46 'TESTS_TMP_PATH', 'HG_REPO', 'GIT_REPO', 'SVN_REPO',
46 'TESTS_TMP_PATH', 'HG_REPO', 'GIT_REPO', 'SVN_REPO',
47 'NEW_HG_REPO', 'NEW_GIT_REPO',
47 'NEW_HG_REPO', 'NEW_GIT_REPO',
48 'HG_FORK', 'GIT_FORK', 'TEST_USER_ADMIN_LOGIN', 'TEST_USER_ADMIN_PASS',
48 'HG_FORK', 'GIT_FORK', 'TEST_USER_ADMIN_LOGIN', 'TEST_USER_ADMIN_PASS',
49 'TEST_USER_REGULAR_LOGIN', 'TEST_USER_REGULAR_PASS',
49 'TEST_USER_REGULAR_LOGIN', 'TEST_USER_REGULAR_PASS',
50 'TEST_USER_REGULAR_EMAIL', 'TEST_USER_REGULAR2_LOGIN',
50 'TEST_USER_REGULAR_EMAIL', 'TEST_USER_REGULAR2_LOGIN',
51 'TEST_USER_REGULAR2_PASS', 'TEST_USER_REGULAR2_EMAIL', 'TEST_HG_REPO',
51 'TEST_USER_REGULAR2_PASS', 'TEST_USER_REGULAR2_EMAIL', 'TEST_HG_REPO',
52 'TEST_HG_REPO_CLONE', 'TEST_HG_REPO_PULL', 'TEST_GIT_REPO',
52 'TEST_HG_REPO_CLONE', 'TEST_HG_REPO_PULL', 'TEST_GIT_REPO',
53 'TEST_GIT_REPO_CLONE', 'TEST_GIT_REPO_PULL', 'SCM_TESTS',
53 'TEST_GIT_REPO_CLONE', 'TEST_GIT_REPO_PULL', 'SCM_TESTS',
54 ]
54 ]
55
55
56
56
57 # SOME GLOBALS FOR TESTS
57 # SOME GLOBALS FOR TESTS
58 TEST_DIR = tempfile.gettempdir()
58 TEST_DIR = tempfile.gettempdir()
59
59
60 TESTS_TMP_PATH = jn(TEST_DIR, 'rc_test_%s' % _RandomNameSequence().next())
60 TESTS_TMP_PATH = jn(TEST_DIR, 'rc_test_%s' % _RandomNameSequence().next())
61 TEST_USER_ADMIN_LOGIN = 'test_admin'
61 TEST_USER_ADMIN_LOGIN = 'test_admin'
62 TEST_USER_ADMIN_PASS = 'test12'
62 TEST_USER_ADMIN_PASS = 'test12'
63 TEST_USER_ADMIN_EMAIL = 'test_admin@mail.com'
63 TEST_USER_ADMIN_EMAIL = 'test_admin@mail.com'
64
64
65 TEST_USER_REGULAR_LOGIN = 'test_regular'
65 TEST_USER_REGULAR_LOGIN = 'test_regular'
66 TEST_USER_REGULAR_PASS = 'test12'
66 TEST_USER_REGULAR_PASS = 'test12'
67 TEST_USER_REGULAR_EMAIL = 'test_regular@mail.com'
67 TEST_USER_REGULAR_EMAIL = 'test_regular@mail.com'
68
68
69 TEST_USER_REGULAR2_LOGIN = 'test_regular2'
69 TEST_USER_REGULAR2_LOGIN = 'test_regular2'
70 TEST_USER_REGULAR2_PASS = 'test12'
70 TEST_USER_REGULAR2_PASS = 'test12'
71 TEST_USER_REGULAR2_EMAIL = 'test_regular2@mail.com'
71 TEST_USER_REGULAR2_EMAIL = 'test_regular2@mail.com'
72
72
73 HG_REPO = 'vcs_test_hg'
73 HG_REPO = 'vcs_test_hg'
74 GIT_REPO = 'vcs_test_git'
74 GIT_REPO = 'vcs_test_git'
75 SVN_REPO = 'vcs_test_svn'
75 SVN_REPO = 'vcs_test_svn'
76
76
77 NEW_HG_REPO = 'vcs_test_hg_new'
77 NEW_HG_REPO = 'vcs_test_hg_new'
78 NEW_GIT_REPO = 'vcs_test_git_new'
78 NEW_GIT_REPO = 'vcs_test_git_new'
79
79
80 HG_FORK = 'vcs_test_hg_fork'
80 HG_FORK = 'vcs_test_hg_fork'
81 GIT_FORK = 'vcs_test_git_fork'
81 GIT_FORK = 'vcs_test_git_fork'
82
82
83 ## VCS
83 ## VCS
84 SCM_TESTS = ['hg', 'git']
84 SCM_TESTS = ['hg', 'git']
85 uniq_suffix = str(int(time.mktime(datetime.datetime.now().timetuple())))
85 uniq_suffix = str(int(time.mktime(datetime.datetime.now().timetuple())))
86
86
87 TEST_GIT_REPO = jn(TESTS_TMP_PATH, GIT_REPO)
87 TEST_GIT_REPO = jn(TESTS_TMP_PATH, GIT_REPO)
88 TEST_GIT_REPO_CLONE = jn(TESTS_TMP_PATH, 'vcsgitclone%s' % uniq_suffix)
88 TEST_GIT_REPO_CLONE = jn(TESTS_TMP_PATH, 'vcsgitclone%s' % uniq_suffix)
89 TEST_GIT_REPO_PULL = jn(TESTS_TMP_PATH, 'vcsgitpull%s' % uniq_suffix)
89 TEST_GIT_REPO_PULL = jn(TESTS_TMP_PATH, 'vcsgitpull%s' % uniq_suffix)
90
90
91 TEST_HG_REPO = jn(TESTS_TMP_PATH, HG_REPO)
91 TEST_HG_REPO = jn(TESTS_TMP_PATH, HG_REPO)
92 TEST_HG_REPO_CLONE = jn(TESTS_TMP_PATH, 'vcshgclone%s' % uniq_suffix)
92 TEST_HG_REPO_CLONE = jn(TESTS_TMP_PATH, 'vcshgclone%s' % uniq_suffix)
93 TEST_HG_REPO_PULL = jn(TESTS_TMP_PATH, 'vcshgpull%s' % uniq_suffix)
93 TEST_HG_REPO_PULL = jn(TESTS_TMP_PATH, 'vcshgpull%s' % uniq_suffix)
94
94
95 TEST_REPO_PREFIX = 'vcs-test'
95 TEST_REPO_PREFIX = 'vcs-test'
96
96
97
97
98 def clear_cache_regions(regions=None):
98 def clear_cache_regions(regions=None):
99 # dogpile
99 # dogpile
100 from rhodecode.lib.rc_cache import region_meta
100 from rhodecode.lib.rc_cache import region_meta
101 for region_name, region in region_meta.dogpile_cache_regions.items():
101 for region_name, region in region_meta.dogpile_cache_regions.items():
102 if not regions or region_name in regions:
102 if not regions or region_name in regions:
103 region.invalidate()
103 region.invalidate()
104
104
105
105
106 def get_new_dir(title):
106 def get_new_dir(title):
107 """
107 """
108 Returns always new directory path.
108 Returns always new directory path.
109 """
109 """
110 from rhodecode.tests.vcs.utils import get_normalized_path
110 from rhodecode.tests.vcs.utils import get_normalized_path
111 name_parts = [TEST_REPO_PREFIX]
111 name_parts = [TEST_REPO_PREFIX]
112 if title:
112 if title:
113 name_parts.append(title)
113 name_parts.append(title)
114 hex_str = hashlib.sha1('%s %s' % (os.getpid(), time.time())).hexdigest()
114 hex_str = hashlib.sha1('%s %s' % (os.getpid(), time.time())).hexdigest()
115 name_parts.append(hex_str)
115 name_parts.append(hex_str)
116 name = '-'.join(name_parts)
116 name = '-'.join(name_parts)
117 path = os.path.join(TEST_DIR, name)
117 path = os.path.join(TEST_DIR, name)
118 return get_normalized_path(path)
118 return get_normalized_path(path)
119
119
120
120
121 def repo_id_generator(name):
121 def repo_id_generator(name):
122 numeric_hash = 0
122 numeric_hash = 0
123 for char in name:
123 for char in name:
124 numeric_hash += (ord(char))
124 numeric_hash += (ord(char))
125 return numeric_hash
125 return numeric_hash
126
126
127
127
128 @pytest.mark.usefixtures('app', 'index_location')
128 @pytest.mark.usefixtures('app', 'index_location')
129 class TestController(object):
129 class TestController(object):
130
130
131 maxDiff = None
131 maxDiff = None
132
132
133 def log_user(self, username=TEST_USER_ADMIN_LOGIN,
133 def log_user(self, username=TEST_USER_ADMIN_LOGIN,
134 password=TEST_USER_ADMIN_PASS):
134 password=TEST_USER_ADMIN_PASS):
135 self._logged_username = username
135 self._logged_username = username
136 self._session = login_user_session(self.app, username, password)
136 self._session = login_user_session(self.app, username, password)
137 self.csrf_token = auth.get_csrf_token(self._session)
137 self.csrf_token = auth.get_csrf_token(self._session)
138
138
139 return self._session['rhodecode_user']
139 return self._session['rhodecode_user']
140
140
141 def logout_user(self):
141 def logout_user(self):
142 logout_user_session(self.app, auth.get_csrf_token(self._session))
142 logout_user_session(self.app, auth.get_csrf_token(self._session))
143 self.csrf_token = None
143 self.csrf_token = None
144 self._logged_username = None
144 self._logged_username = None
145 self._session = None
145 self._session = None
146
146
147 def _get_logged_user(self):
147 def _get_logged_user(self):
148 return User.get_by_username(self._logged_username)
148 return User.get_by_username(self._logged_username)
149
149
150
150
151 def login_user_session(
151 def login_user_session(
152 app, username=TEST_USER_ADMIN_LOGIN, password=TEST_USER_ADMIN_PASS):
152 app, username=TEST_USER_ADMIN_LOGIN, password=TEST_USER_ADMIN_PASS):
153
153
154 response = app.post(
154 response = app.post(
155 h.route_path('login'),
155 h.route_path('login'),
156 {'username': username, 'password': password})
156 {'username': username, 'password': password})
157 if 'invalid user name' in response.body:
157 if 'invalid user name' in response.body:
158 pytest.fail('could not login using %s %s' % (username, password))
158 pytest.fail('could not login using %s %s' % (username, password))
159
159
160 assert response.status == '302 Found'
160 assert response.status == '302 Found'
161 response = response.follow()
161 response = response.follow()
162 assert response.status == '200 OK'
162 assert response.status == '200 OK'
163
163
164 session = response.get_session_from_response()
164 session = response.get_session_from_response()
165 assert 'rhodecode_user' in session
165 assert 'rhodecode_user' in session
166 rc_user = session['rhodecode_user']
166 rc_user = session['rhodecode_user']
167 assert rc_user.get('username') == username
167 assert rc_user.get('username') == username
168 assert rc_user.get('is_authenticated')
168 assert rc_user.get('is_authenticated')
169
169
170 return session
170 return session
171
171
172
172
173 def logout_user_session(app, csrf_token):
173 def logout_user_session(app, csrf_token):
174 app.post(h.route_path('logout'), {'csrf_token': csrf_token}, status=302)
174 app.post(h.route_path('logout'), {'csrf_token': csrf_token}, status=302)
175
175
176
176
177 def login_user(app, username=TEST_USER_ADMIN_LOGIN,
177 def login_user(app, username=TEST_USER_ADMIN_LOGIN,
178 password=TEST_USER_ADMIN_PASS):
178 password=TEST_USER_ADMIN_PASS):
179 return login_user_session(app, username, password)['rhodecode_user']
179 return login_user_session(app, username, password)['rhodecode_user']
180
180
181
181
182 def assert_session_flash(response, msg=None, category=None, no_=None):
182 def assert_session_flash(response, msg=None, category=None, no_=None):
183 """
183 """
184 Assert on a flash message in the current session.
184 Assert on a flash message in the current session.
185
185
186 :param response: Response from give calll, it will contain flash
186 :param response: Response from give calll, it will contain flash
187 messages or bound session with them.
187 messages or bound session with them.
188 :param msg: The expected message. Will be evaluated if a
188 :param msg: The expected message. Will be evaluated if a
189 :class:`LazyString` is passed in.
189 :class:`LazyString` is passed in.
190 :param category: Optional. If passed, the message category will be
190 :param category: Optional. If passed, the message category will be
191 checked as well.
191 checked as well.
192 :param no_: Optional. If passed, the message will be checked to NOT
192 :param no_: Optional. If passed, the message will be checked to NOT
193 be in the flash session
193 be in the flash session
194 """
194 """
195 if msg is None and no_ is None:
195 if msg is None and no_ is None:
196 raise ValueError("Parameter msg or no_ is required.")
196 raise ValueError("Parameter msg or no_ is required.")
197
197
198 if msg and no_:
198 if msg and no_:
199 raise ValueError("Please specify either msg or no_, but not both")
199 raise ValueError("Please specify either msg or no_, but not both")
200
200
201 session = response.get_session_from_response()
201 session = response.get_session_from_response()
202 messages = flash.pop_messages(session=session)
202 messages = flash.pop_messages(session=session)
203 msg = _eval_if_lazy(msg)
203 msg = _eval_if_lazy(msg)
204
204
205 if no_:
205 if no_:
206 error_msg = 'unable to detect no_ message `%s` in empty flash list' % no_
206 error_msg = 'unable to detect no_ message `%s` in empty flash list' % no_
207 else:
207 else:
208 error_msg = 'unable to find message `%s` in empty flash list' % msg
208 error_msg = 'unable to find message `%s` in empty flash list' % msg
209 assert messages, error_msg
209 assert messages, error_msg
210 message = messages[0]
210 message = messages[0]
211
211
212 message_text = _eval_if_lazy(message.message) or ''
212 message_text = _eval_if_lazy(message.message) or ''
213
213
214 if no_:
214 if no_:
215 if no_ in message_text:
215 if no_ in message_text:
216 msg = u'msg `%s` found in session flash.' % (no_,)
216 msg = u'msg `%s` found in session flash.' % (no_,)
217 pytest.fail(safe_str(msg))
217 pytest.fail(safe_str(msg))
218 else:
218 else:
219 if msg not in message_text:
219 if msg not in message_text:
220 fail_msg = u'msg `%s` not found in session ' \
220 fail_msg = u'msg `%s` not found in session ' \
221 u'flash: got `%s` (type:%s) instead' % (
221 u'flash: got `%s` (type:%s) instead' % (
222 msg, message_text, type(message_text))
222 msg, message_text, type(message_text))
223
223
224 pytest.fail(safe_str(fail_msg))
224 pytest.fail(safe_str(fail_msg))
225 if category:
225 if category:
226 assert category == message.category
226 assert category == message.category
227
227
228
228
229 def _eval_if_lazy(value):
229 def _eval_if_lazy(value):
230 return value.eval() if hasattr(value, 'eval') else value
230 return value.eval() if hasattr(value, 'eval') else value
231
231
232
232
233 def no_newline_id_generator(test_name):
233 def no_newline_id_generator(test_name):
234 """
234 """
235 Generates a test name without spaces or newlines characters. Used for
235 Generates a test name without spaces or newlines characters. Used for
236 nicer output of progress of test
236 nicer output of progress of test
237 """
237 """
238 org_name = test_name
238 org_name = test_name
239 test_name = test_name\
239 test_name = str(test_name)\
240 .replace('\n', '_N') \
240 .replace('\n', '_N') \
241 .replace('\r', '_N') \
241 .replace('\r', '_N') \
242 .replace('\t', '_T') \
242 .replace('\t', '_T') \
243 .replace(' ', '_S')
243 .replace(' ', '_S')
244
244
245 return test_name or 'test-with-empty-name'
245 return test_name or 'test-with-empty-name'
General Comments 0
You need to be logged in to leave comments. Login now