##// END OF EJS Templates
Tests rewrite for 1.2 added some globals configs to make tests easier....
marcink -
r688:8acbfa83 beta
parent child Browse files
Show More
1 NO CONTENT: new file 100644, binary diff hidden
@@ -1,80 +1,81 b''
1 1 """Pylons environment configuration"""
2 2 from mako.lookup import TemplateLookup
3 3 from pylons.configuration import PylonsConfig
4 4 from pylons.error import handle_mako_error
5 5 from rhodecode.config.routing import make_map
6 6 from rhodecode.lib.auth import set_available_permissions, set_base_path
7 7 from rhodecode.lib.utils import repo2db_mapper, make_ui, set_rhodecode_config
8 8 from rhodecode.model import init_model
9 9 from rhodecode.model.hg import HgModel
10 10 from sqlalchemy import engine_from_config
11 11 import logging
12 12 import os
13 13 import rhodecode.lib.app_globals as app_globals
14 14 import rhodecode.lib.helpers
15 15
16 16 log = logging.getLogger(__name__)
17 17
18 18 def load_environment(global_conf, app_conf, initial=False):
19 19 """Configure the Pylons environment via the ``pylons.config``
20 20 object
21 21 """
22 22 config = PylonsConfig()
23 23
24 24 # Pylons paths
25 25 root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
26 26 paths = dict(root=root,
27 27 controllers=os.path.join(root, 'controllers'),
28 28 static_files=os.path.join(root, 'public'),
29 29 templates=[os.path.join(root, 'templates')])
30 30
31 31 # Initialize config with the basic options
32 32 config.init_app(global_conf, app_conf, package='rhodecode', paths=paths)
33 33
34 34 config['routes.map'] = make_map(config)
35 35 config['pylons.app_globals'] = app_globals.Globals(config)
36 36 config['pylons.h'] = rhodecode.lib.helpers
37 37
38 38 # Setup cache object as early as possible
39 39 import pylons
40 40 pylons.cache._push_object(config['pylons.app_globals'].cache)
41 41
42 42 # Create the Mako TemplateLookup, with the default auto-escaping
43 43 config['pylons.app_globals'].mako_lookup = TemplateLookup(
44 44 directories=paths['templates'],
45 45 error_handler=handle_mako_error,
46 46 module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
47 47 input_encoding='utf-8', default_filters=['escape'],
48 48 imports=['from webhelpers.html import escape'])
49 49
50 50 #sets the c attribute access when don't existing attribute are accessed
51 51 config['pylons.strict_tmpl_context'] = True
52 52 test = os.path.split(config['__file__'])[-1] == 'test.ini'
53 53 if test:
54 54 from rhodecode.lib.utils import create_test_env, create_test_index
55 create_test_env('/tmp', config)
56 create_test_index('/tmp', True)
55 from rhodecode.tests import TESTS_TMP_PATH
56 create_test_env(TESTS_TMP_PATH, config)
57 create_test_index(TESTS_TMP_PATH, True)
57 58
58 59 #MULTIPLE DB configs
59 60 # Setup the SQLAlchemy database engine
60 61 if config['debug'] and not test:
61 62 #use query time debugging.
62 63 from rhodecode.lib.timerproxy import TimerProxy
63 64 sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.',
64 65 proxy=TimerProxy())
65 66 else:
66 67 sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.')
67 68
68 69 init_model(sa_engine_db1)
69 70 #init baseui
70 71 config['pylons.app_globals'].baseui = make_ui('db')
71 72
72 73 g = config['pylons.app_globals']
73 74 repo2db_mapper(HgModel().repo_scan(g.paths[0][1], g.baseui, initial))
74 75 set_available_permissions(config)
75 76 set_base_path(config)
76 77 set_rhodecode_config(config)
77 78 # CONFIGURATION OPTIONS HERE (note: all config options will override
78 79 # any Pylons config options)
79 80
80 81 return config
@@ -1,112 +1,113 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 # search controller for pylons
4 4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5 5 #
6 6 # This program is free software; you can redistribute it and/or
7 7 # modify it under the terms of the GNU General Public License
8 8 # as published by the Free Software Foundation; version 2
9 9 # of the License or (at your opinion) any later version of the license.
10 10 #
11 11 # This program is distributed in the hope that it will be useful,
12 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 14 # GNU General Public License for more details.
15 15 #
16 16 # You should have received a copy of the GNU General Public License
17 17 # along with this program; if not, write to the Free Software
18 18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 19 # MA 02110-1301, USA.
20 20 """
21 21 Created on Aug 7, 2010
22 22 search controller for pylons
23 23 @author: marcink
24 24 """
25 from pylons import request, response, session, tmpl_context as c, url
25 from pylons import request, response, config, session, tmpl_context as c, url
26 26 from pylons.controllers.util import abort, redirect
27 27 from rhodecode.lib.auth import LoginRequired
28 28 from rhodecode.lib.base import BaseController, render
29 from rhodecode.lib.indexers import IDX_LOCATION, SCHEMA, IDX_NAME, ResultWrapper
29 from rhodecode.lib.indexers import SCHEMA, IDX_NAME, ResultWrapper
30 30 from webhelpers.paginate import Page
31 31 from webhelpers.util import update_params
32 32 from pylons.i18n.translation import _
33 33 from whoosh.index import open_dir, EmptyIndexError
34 34 from whoosh.qparser import QueryParser, QueryParserError
35 35 from whoosh.query import Phrase
36 36 import logging
37 37 import traceback
38 38
39 39 log = logging.getLogger(__name__)
40 40
41 41 class SearchController(BaseController):
42 42
43 43 @LoginRequired()
44 44 def __before__(self):
45 super(SearchController, self).__before__()
45 super(SearchController, self).__before__()
46 46
47 47 def index(self, search_repo=None):
48 48 c.repo_name = search_repo
49 49 c.formated_results = []
50 50 c.runtime = ''
51 51 c.cur_query = request.GET.get('q', None)
52 52 c.cur_type = request.GET.get('type', 'source')
53 53 c.cur_search = search_type = {'content':'content',
54 54 'commit':'content',
55 55 'path':'path',
56 56 'repository':'repository'}\
57 57 .get(c.cur_type, 'content')
58 58
59
59
60 60 if c.cur_query:
61 61 cur_query = c.cur_query.lower()
62
62
63 63 if c.cur_query:
64 64 p = int(request.params.get('page', 1))
65 65 highlight_items = set()
66 66 try:
67 idx = open_dir(IDX_LOCATION, indexname=IDX_NAME)
67 idx = open_dir(config['app_conf']['index_dir']
68 , indexname=IDX_NAME)
68 69 searcher = idx.searcher()
69 70
70 71 qp = QueryParser(search_type, schema=SCHEMA)
71 72 if c.repo_name:
72 73 cur_query = u'repository:%s %s' % (c.repo_name, cur_query)
73 74 try:
74 75 query = qp.parse(unicode(cur_query))
75
76
76 77 if isinstance(query, Phrase):
77 78 highlight_items.update(query.words)
78 79 else:
79 80 for i in query.all_terms():
80 81 if i[0] == 'content':
81 82 highlight_items.add(i[1])
82 83
83 84 matcher = query.matcher(searcher)
84
85
85 86 log.debug(query)
86 87 log.debug(highlight_items)
87 88 results = searcher.search(query)
88 89 res_ln = len(results)
89 90 c.runtime = '%s results (%.3f seconds)' \
90 91 % (res_ln, results.runtime)
91
92
92 93 def url_generator(**kw):
93 94 return update_params("?q=%s&type=%s" \
94 95 % (c.cur_query, c.cur_search), **kw)
95 96
96 97 c.formated_results = Page(
97 98 ResultWrapper(search_type, searcher, matcher,
98 99 highlight_items),
99 100 page=p, item_count=res_ln,
100 101 items_per_page=10, url=url_generator)
101
102
102
103
103 104 except QueryParserError:
104 105 c.runtime = _('Invalid search query. Try quoting it.')
105 106 searcher.close()
106 107 except (EmptyIndexError, IOError):
107 108 log.error(traceback.format_exc())
108 109 log.error('Empty Index data')
109 110 c.runtime = _('There is no index to search in. Please run whoosh indexer')
110
111
111 112 # Return a rendered template
112 113 return render('/search/search.html')
@@ -1,544 +1,553 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 # Utilities for RhodeCode
4 4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5 5 # This program is free software; you can redistribute it and/or
6 6 # modify it under the terms of the GNU General Public License
7 7 # as published by the Free Software Foundation; version 2
8 8 # of the License or (at your opinion) any later version of the license.
9 9 #
10 10 # This program is distributed in the hope that it will be useful,
11 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 # GNU General Public License for more details.
14 14 #
15 15 # You should have received a copy of the GNU General Public License
16 16 # along with this program; if not, write to the Free Software
17 17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 18 # MA 02110-1301, USA.
19 19 """
20 20 Created on April 18, 2010
21 21 Utilities for RhodeCode
22 22 @author: marcink
23 23 """
24 24
25 25 from UserDict import DictMixin
26 26 from mercurial import ui, config, hg
27 27 from mercurial.error import RepoError
28 28 from rhodecode.model import meta
29 29 from rhodecode.model.caching_query import FromCache
30 30 from rhodecode.model.db import Repository, User, RhodeCodeUi, RhodeCodeSettings, \
31 31 UserLog
32 32 from rhodecode.model.repo import RepoModel
33 33 from rhodecode.model.user import UserModel
34 34 from vcs.backends.base import BaseChangeset
35 35 from paste.script import command
36 36 import ConfigParser
37 37 from vcs.utils.lazy import LazyProperty
38 38 import traceback
39 39 import datetime
40 40 import logging
41 41 import os
42 42
43 43 log = logging.getLogger(__name__)
44 44
45 45
46 46 def get_repo_slug(request):
47 47 return request.environ['pylons.routes_dict'].get('repo_name')
48 48
49 49 def is_mercurial(environ):
50 50 """
51 51 Returns True if request's target is mercurial server - header
52 52 ``HTTP_ACCEPT`` of such request would start with ``application/mercurial``.
53 53 """
54 54 http_accept = environ.get('HTTP_ACCEPT')
55 55 if http_accept and http_accept.startswith('application/mercurial'):
56 56 return True
57 57 return False
58 58
59 59 def is_git(environ):
60 60 """
61 61 Returns True if request's target is git server. ``HTTP_USER_AGENT`` would
62 62 then have git client version given.
63 63
64 64 :param environ:
65 65 """
66 66 http_user_agent = environ.get('HTTP_USER_AGENT')
67 if http_user_agent.startswith('git'):
67 if http_user_agent and http_user_agent.startswith('git'):
68 68 return True
69 69 return False
70 70
71 71 def action_logger(user, action, repo, ipaddr, sa=None):
72 72 """
73 73 Action logger for various action made by users
74 74 """
75 75
76 76 if not sa:
77 77 sa = meta.Session()
78 78
79 79 try:
80 80 if hasattr(user, 'user_id'):
81 81 user_obj = user
82 82 elif isinstance(user, basestring):
83 83 user_obj = UserModel(sa).get_by_username(user, cache=False)
84 84 else:
85 85 raise Exception('You have to provide user object or username')
86 86
87 87 repo_name = repo.lstrip('/')
88 88 user_log = UserLog()
89 89 user_log.user_id = user_obj.user_id
90 90 user_log.action = action
91 91 user_log.repository_name = repo_name
92 92 user_log.repository = RepoModel(sa).get(repo_name, cache=False)
93 93 user_log.action_date = datetime.datetime.now()
94 94 user_log.user_ip = ipaddr
95 95 sa.add(user_log)
96 96 sa.commit()
97 97
98 98 log.info('Adding user %s, action %s on %s',
99 99 user_obj.username, action, repo)
100 100 except:
101 101 log.error(traceback.format_exc())
102 102 sa.rollback()
103 103
104 104 def get_repos(path, recursive=False, initial=False):
105 105 """
106 106 Scans given path for repos and return (name,(type,path)) tuple
107 107 :param prefix:
108 108 :param path:
109 109 :param recursive:
110 110 :param initial:
111 111 """
112 112 from vcs.utils.helpers import get_scm
113 113 from vcs.exceptions import VCSError
114 114
115 115 try:
116 116 scm = get_scm(path)
117 117 except:
118 118 pass
119 119 else:
120 120 raise Exception('The given path %s should not be a repository got %s',
121 121 path, scm)
122 122
123 123 for dirpath in os.listdir(path):
124 124 try:
125 125 yield dirpath, get_scm(os.path.join(path, dirpath))
126 126 except VCSError:
127 127 pass
128 128
129 129 if __name__ == '__main__':
130 130 get_repos('', '/home/marcink/workspace-python')
131 131
132 132
133 133 def check_repo_fast(repo_name, base_path):
134 134 if os.path.isdir(os.path.join(base_path, repo_name)):return False
135 135 return True
136 136
137 137 def check_repo(repo_name, base_path, verify=True):
138 138
139 139 repo_path = os.path.join(base_path, repo_name)
140 140
141 141 try:
142 142 if not check_repo_fast(repo_name, base_path):
143 143 return False
144 144 r = hg.repository(ui.ui(), repo_path)
145 145 if verify:
146 146 hg.verify(r)
147 147 #here we hnow that repo exists it was verified
148 148 log.info('%s repo is already created', repo_name)
149 149 return False
150 150 except RepoError:
151 151 #it means that there is no valid repo there...
152 152 log.info('%s repo is free for creation', repo_name)
153 153 return True
154 154
155 155 def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
156 156 while True:
157 157 ok = raw_input(prompt)
158 158 if ok in ('y', 'ye', 'yes'): return True
159 159 if ok in ('n', 'no', 'nop', 'nope'): return False
160 160 retries = retries - 1
161 161 if retries < 0: raise IOError
162 162 print complaint
163 163
164 164 def get_hg_ui_cached():
165 165 try:
166 166 sa = meta.Session
167 167 ret = sa.query(RhodeCodeUi)\
168 168 .options(FromCache("sql_cache_short", "get_hg_ui_settings"))\
169 169 .all()
170 170 except:
171 171 pass
172 172 finally:
173 173 meta.Session.remove()
174 174 return ret
175 175
176 176
177 177 def get_hg_settings():
178 178 try:
179 179 sa = meta.Session()
180 180 ret = sa.query(RhodeCodeSettings)\
181 181 .options(FromCache("sql_cache_short", "get_hg_settings"))\
182 182 .all()
183 183 except:
184 184 pass
185 185 finally:
186 186 meta.Session.remove()
187 187
188 188 if not ret:
189 189 raise Exception('Could not get application settings !')
190 190 settings = {}
191 191 for each in ret:
192 192 settings['rhodecode_' + each.app_settings_name] = each.app_settings_value
193 193
194 194 return settings
195 195
196 196 def get_hg_ui_settings():
197 197 try:
198 198 sa = meta.Session()
199 199 ret = sa.query(RhodeCodeUi).all()
200 200 except:
201 201 pass
202 202 finally:
203 203 meta.Session.remove()
204 204
205 205 if not ret:
206 206 raise Exception('Could not get application ui settings !')
207 207 settings = {}
208 208 for each in ret:
209 209 k = each.ui_key
210 210 v = each.ui_value
211 211 if k == '/':
212 212 k = 'root_path'
213 213
214 214 if k.find('.') != -1:
215 215 k = k.replace('.', '_')
216 216
217 217 if each.ui_section == 'hooks':
218 218 v = each.ui_active
219 219
220 220 settings[each.ui_section + '_' + k] = v
221 221
222 222 return settings
223 223
224 224 #propagated from mercurial documentation
225 225 ui_sections = ['alias', 'auth',
226 226 'decode/encode', 'defaults',
227 227 'diff', 'email',
228 228 'extensions', 'format',
229 229 'merge-patterns', 'merge-tools',
230 230 'hooks', 'http_proxy',
231 231 'smtp', 'patch',
232 232 'paths', 'profiling',
233 233 'server', 'trusted',
234 234 'ui', 'web', ]
235 235
236 236 def make_ui(read_from='file', path=None, checkpaths=True):
237 237 """
238 238 A function that will read python rc files or database
239 239 and make an mercurial ui object from read options
240 240
241 241 :param path: path to mercurial config file
242 242 :param checkpaths: check the path
243 243 :param read_from: read from 'file' or 'db'
244 244 """
245 245
246 246 baseui = ui.ui()
247 247
248 248 if read_from == 'file':
249 249 if not os.path.isfile(path):
250 250 log.warning('Unable to read config file %s' % path)
251 251 return False
252 252 log.debug('reading hgrc from %s', path)
253 253 cfg = config.config()
254 254 cfg.read(path)
255 255 for section in ui_sections:
256 256 for k, v in cfg.items(section):
257 257 baseui.setconfig(section, k, v)
258 258 log.debug('settings ui from file[%s]%s:%s', section, k, v)
259 259
260 260 elif read_from == 'db':
261 261 hg_ui = get_hg_ui_cached()
262 262 for ui_ in hg_ui:
263 263 if ui_.ui_active:
264 264 log.debug('settings ui from db[%s]%s:%s', ui_.ui_section, ui_.ui_key, ui_.ui_value)
265 265 baseui.setconfig(ui_.ui_section, ui_.ui_key, ui_.ui_value)
266 266
267 267
268 268 return baseui
269 269
270 270
271 271 def set_rhodecode_config(config):
272 272 hgsettings = get_hg_settings()
273 273
274 274 for k, v in hgsettings.items():
275 275 config[k] = v
276 276
277 277 def invalidate_cache(name, *args):
278 278 """
279 279 Puts cache invalidation task into db for
280 280 further global cache invalidation
281 281 """
282 282 pass
283 283
284 284 class EmptyChangeset(BaseChangeset):
285 285 """
286 286 An dummy empty changeset. It's possible to pass hash when creating
287 287 an EmptyChangeset
288 288 """
289 289
290 290 def __init__(self, cs='0' * 40):
291 291 self._empty_cs = cs
292 292 self.revision = -1
293 293 self.message = ''
294 294 self.author = ''
295 295 self.date = ''
296 296
297 297 @LazyProperty
298 298 def raw_id(self):
299 299 """
300 300 Returns raw string identifying this changeset, useful for web
301 301 representation.
302 302 """
303 303 return self._empty_cs
304 304
305 305 @LazyProperty
306 306 def short_id(self):
307 307 return self.raw_id[:12]
308 308
309 309 def get_file_changeset(self, path):
310 310 return self
311 311
312 312 def get_file_content(self, path):
313 313 return u''
314 314
315 315 def get_file_size(self, path):
316 316 return 0
317 317
318 318 def repo2db_mapper(initial_repo_list, remove_obsolete=False):
319 319 """
320 320 maps all found repositories into db
321 321 """
322 322
323 323 sa = meta.Session()
324 324 rm = RepoModel(sa)
325 325 user = sa.query(User).filter(User.admin == True).first()
326 326
327 327 for name, repo in initial_repo_list.items():
328 328 if not rm.get(name, cache=False):
329 329 log.info('repository %s not found creating default', name)
330 330
331 331 form_data = {
332 332 'repo_name':name,
333 333 'repo_type':repo.alias,
334 334 'description':repo.description \
335 335 if repo.description != 'unknown' else \
336 336 '%s repository' % name,
337 337 'private':False
338 338 }
339 339 rm.create(form_data, user, just_db=True)
340 340
341 341 if remove_obsolete:
342 342 #remove from database those repositories that are not in the filesystem
343 343 for repo in sa.query(Repository).all():
344 344 if repo.repo_name not in initial_repo_list.keys():
345 345 sa.delete(repo)
346 346 sa.commit()
347 347
348 348 class OrderedDict(dict, DictMixin):
349 349
350 350 def __init__(self, *args, **kwds):
351 351 if len(args) > 1:
352 352 raise TypeError('expected at most 1 arguments, got %d' % len(args))
353 353 try:
354 354 self.__end
355 355 except AttributeError:
356 356 self.clear()
357 357 self.update(*args, **kwds)
358 358
359 359 def clear(self):
360 360 self.__end = end = []
361 361 end += [None, end, end] # sentinel node for doubly linked list
362 362 self.__map = {} # key --> [key, prev, next]
363 363 dict.clear(self)
364 364
365 365 def __setitem__(self, key, value):
366 366 if key not in self:
367 367 end = self.__end
368 368 curr = end[1]
369 369 curr[2] = end[1] = self.__map[key] = [key, curr, end]
370 370 dict.__setitem__(self, key, value)
371 371
372 372 def __delitem__(self, key):
373 373 dict.__delitem__(self, key)
374 374 key, prev, next = self.__map.pop(key)
375 375 prev[2] = next
376 376 next[1] = prev
377 377
378 378 def __iter__(self):
379 379 end = self.__end
380 380 curr = end[2]
381 381 while curr is not end:
382 382 yield curr[0]
383 383 curr = curr[2]
384 384
385 385 def __reversed__(self):
386 386 end = self.__end
387 387 curr = end[1]
388 388 while curr is not end:
389 389 yield curr[0]
390 390 curr = curr[1]
391 391
392 392 def popitem(self, last=True):
393 393 if not self:
394 394 raise KeyError('dictionary is empty')
395 395 if last:
396 396 key = reversed(self).next()
397 397 else:
398 398 key = iter(self).next()
399 399 value = self.pop(key)
400 400 return key, value
401 401
402 402 def __reduce__(self):
403 403 items = [[k, self[k]] for k in self]
404 404 tmp = self.__map, self.__end
405 405 del self.__map, self.__end
406 406 inst_dict = vars(self).copy()
407 407 self.__map, self.__end = tmp
408 408 if inst_dict:
409 409 return (self.__class__, (items,), inst_dict)
410 410 return self.__class__, (items,)
411 411
412 412 def keys(self):
413 413 return list(self)
414 414
415 415 setdefault = DictMixin.setdefault
416 416 update = DictMixin.update
417 417 pop = DictMixin.pop
418 418 values = DictMixin.values
419 419 items = DictMixin.items
420 420 iterkeys = DictMixin.iterkeys
421 421 itervalues = DictMixin.itervalues
422 422 iteritems = DictMixin.iteritems
423 423
424 424 def __repr__(self):
425 425 if not self:
426 426 return '%s()' % (self.__class__.__name__,)
427 427 return '%s(%r)' % (self.__class__.__name__, self.items())
428 428
429 429 def copy(self):
430 430 return self.__class__(self)
431 431
432 432 @classmethod
433 433 def fromkeys(cls, iterable, value=None):
434 434 d = cls()
435 435 for key in iterable:
436 436 d[key] = value
437 437 return d
438 438
439 439 def __eq__(self, other):
440 440 if isinstance(other, OrderedDict):
441 441 return len(self) == len(other) and self.items() == other.items()
442 442 return dict.__eq__(self, other)
443 443
444 444 def __ne__(self, other):
445 445 return not self == other
446 446
447 447
448 448 #===============================================================================
449 449 # TEST FUNCTIONS AND CREATORS
450 450 #===============================================================================
451 451 def create_test_index(repo_location, full_index):
452 452 """Makes default test index
453 453 :param repo_location:
454 454 :param full_index:
455 455 """
456 456 from rhodecode.lib.indexers.daemon import WhooshIndexingDaemon
457 457 from rhodecode.lib.pidlock import DaemonLock, LockHeld
458 from rhodecode.lib.indexers import IDX_LOCATION
459 458 import shutil
460 459
461 if os.path.exists(IDX_LOCATION):
462 shutil.rmtree(IDX_LOCATION)
460 index_location = os.path.join(repo_location, 'index')
461 if os.path.exists(index_location):
462 shutil.rmtree(index_location)
463 463
464 464 try:
465 465 l = DaemonLock()
466 WhooshIndexingDaemon(repo_location=repo_location)\
466 WhooshIndexingDaemon(index_location=index_location,
467 repo_location=repo_location)\
467 468 .run(full_index=full_index)
468 469 l.release()
469 470 except LockHeld:
470 471 pass
471 472
472 473 def create_test_env(repos_test_path, config):
473 474 """Makes a fresh database and
474 475 install test repository into tmp dir
475 476 """
476 477 from rhodecode.lib.db_manage import DbManage
478 from rhodecode.tests import HG_REPO, GIT_REPO, NEW_HG_REPO, NEW_GIT_REPO, \
479 HG_FORK, GIT_FORK, TESTS_TMP_PATH
477 480 import tarfile
478 481 import shutil
479 482 from os.path import dirname as dn, join as jn, abspath
480 483
481 484 log = logging.getLogger('TestEnvCreator')
482 485 # create logger
483 486 log.setLevel(logging.DEBUG)
484 487 log.propagate = True
485 488 # create console handler and set level to debug
486 489 ch = logging.StreamHandler()
487 490 ch.setLevel(logging.DEBUG)
488 491
489 492 # create formatter
490 493 formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
491 494
492 495 # add formatter to ch
493 496 ch.setFormatter(formatter)
494 497
495 498 # add ch to logger
496 499 log.addHandler(ch)
497 500
498 501 #PART ONE create db
499 502 dbname = config['sqlalchemy.db1.url'].split('/')[-1]
500 503 log.debug('making test db %s', dbname)
501 504
502 505 dbmanage = DbManage(log_sql=True, dbname=dbname, root=config['here'],
503 506 tests=True)
504 507 dbmanage.create_tables(override=True)
505 508 dbmanage.config_prompt(repos_test_path)
506 509 dbmanage.create_default_user()
507 510 dbmanage.admin_prompt()
508 511 dbmanage.create_permissions()
509 512 dbmanage.populate_default_permissions()
510 513
511 514 #PART TWO make test repo
512 log.debug('making test vcs repo')
513 if os.path.isdir('/tmp/vcs_test'):
514 shutil.rmtree('/tmp/vcs_test')
515 log.debug('making test vcs repositories')
516
517 #remove old one from previos tests
518 for r in [HG_REPO, GIT_REPO, NEW_HG_REPO, NEW_GIT_REPO, HG_FORK, GIT_FORK]:
515 519
520 if os.path.isdir(jn(TESTS_TMP_PATH, r)):
521 log.debug('removing %s', r)
522 shutil.rmtree(jn(TESTS_TMP_PATH, r))
523
524 #CREATE DEFAULT HG REPOSITORY
516 525 cur_dir = dn(dn(abspath(__file__)))
517 tar = tarfile.open(jn(cur_dir, 'tests', "vcs_test.tar.gz"))
518 tar.extractall('/tmp')
526 tar = tarfile.open(jn(cur_dir, 'tests', "vcs_test_hg.tar.gz"))
527 tar.extractall(jn(TESTS_TMP_PATH, HG_REPO))
519 528 tar.close()
520 529
521 530 class UpgradeDb(command.Command):
522 531 """Command used for paster to upgrade our database to newer version
523 532 """
524 533
525 534 max_args = 1
526 535 min_args = 1
527 536
528 537 usage = "CONFIG_FILE"
529 538 summary = "Upgrades current db to newer version given configuration file"
530 539 group_name = "RhodeCode"
531 540
532 541 parser = command.Command.standard_parser(verbose=True)
533 542
534 543 parser.add_option('--sql',
535 544 action='store_true',
536 545 dest='just_sql',
537 546 help="Prints upgrade sql for further investigation",
538 547 default=False)
539 548 def command(self):
540 549 config_name = self.args[0]
541 550 p = config_name.split('/')
542 551 root = '.' if len(p) == 1 else '/'.join(p[:-1])
543 552 config = ConfigParser.ConfigParser({'here':root})
544 553 config.read(config_name)
@@ -1,58 +1,72 b''
1 1 """Pylons application test package
2 2
3 3 This package assumes the Pylons environment is already loaded, such as
4 4 when this script is imported from the `nosetests --with-pylons=test.ini`
5 5 command.
6 6
7 7 This module initializes the application via ``websetup`` (`paster
8 8 setup-app`) and provides the base testing objects.
9 9 """
10 10 from unittest import TestCase
11 11
12 12 from paste.deploy import loadapp
13 13 from paste.script.appinstall import SetupCommand
14 14 from pylons import config, url
15 15 from routes.util import URLGenerator
16 16 from webtest import TestApp
17 17 import os
18 18 from rhodecode.model import meta
19 19 import logging
20 20
21 21
22 log = logging.getLogger(__name__)
22 log = logging.getLogger(__name__)
23 23
24 24 import pylons.test
25 25
26 __all__ = ['environ', 'url', 'TestController']
26 __all__ = ['environ', 'url', 'TestController', 'TESTS_TMP_PATH', 'HG_REPO',
27 'GIT_REPO', 'NEW_HG_REPO', 'NEW_GIT_REPO', 'HG_FORK', 'GIT_FORK', ]
27 28
28 29 # Invoke websetup with the current config file
29 30 #SetupCommand('setup-app').run([config_file])
30 31
31 32 ##RUNNING DESIRED TESTS
32 33 #nosetests rhodecode.tests.functional.test_admin_settings:TestSettingsController.test_my_account
33 34
34 35 environ = {}
35 36
37 #SOME GLOBALS FOR TESTS
38 TESTS_TMP_PATH = '/tmp'
39
40 HG_REPO = 'vcs_test_hg'
41 GIT_REPO = 'vcs_test_git'
42
43 NEW_HG_REPO = 'vcs_test_hg_new'
44 NEW_GIT_REPO = 'vcs_test_git_new'
45
46 HG_FORK = 'vcs_test_hg_fork'
47 GIT_FORK = 'vcs_test_git_fork'
48
36 49 class TestController(TestCase):
37 50
38 51 def __init__(self, *args, **kwargs):
39 52 wsgiapp = pylons.test.pylonsapp
40 53 config = wsgiapp.config
54
41 55 self.app = TestApp(wsgiapp)
42 56 url._push_object(URLGenerator(config['routes.map'], environ))
43 57 self.sa = meta.Session
44
58 self.index_location = config['app_conf']['index_dir']
45 59 TestCase.__init__(self, *args, **kwargs)
46
60
47 61 def log_user(self, username='test_admin', password='test12'):
48 62 response = self.app.post(url(controller='login', action='index'),
49 63 {'username':username,
50 64 'password':password})
51 65 print response
52
66
53 67 if 'invalid user name' in response.body:
54 68 assert False, 'could not login using %s %s' % (username, password)
55
69
56 70 assert response.status == '302 Found', 'Wrong response code from login got %s' % response.status
57 71 assert response.session['rhodecode_user'].username == username, 'wrong logged in user got %s expected %s' % (response.session['rhodecode_user'].username, username)
58 72 return response.follow()
@@ -1,8 +1,18 b''
1 1 from rhodecode.tests import *
2 2
3 3 class TestBranchesController(TestController):
4 4
5 5 def test_index(self):
6 6 self.log_user()
7 response = self.app.get(url(controller='branches', action='index',repo_name='vcs_test'))
7 response = self.app.get(url(controller='branches', action='index', repo_name=HG_REPO))
8
9 assert """<a href="/%s/changeset/27cd5cce30c96924232dffcd24178a07ffeb5dfc">default</a>""" % HG_REPO in response.body, 'wrong info about default branch'
10 assert """<a href="/%s/changeset/97e8b885c04894463c51898e14387d80c30ed1ee">git</a>""" % HG_REPO in response.body, 'wrong info about default git'
11 assert """<a href="/%s/changeset/2e6a2bf9356ca56df08807f4ad86d480da72a8f4">web</a>""" % HG_REPO in response.body, 'wrong info about default web'
12
13
14
15
16
17
8 18 # Test response...
@@ -1,31 +1,36 b''
1 1 from rhodecode.tests import *
2 2
3 3 class TestChangelogController(TestController):
4 4
5 def test_index(self):
5 def test_index_hg(self):
6 6 self.log_user()
7 response = self.app.get(url(controller='changelog', action='index', repo_name='vcs_test'))
8
9 print response
10 assert """<div id="chg_20" class="container">""" in response.body, 'wrong info about number ofchanges'
7 response = self.app.get(url(controller='changelog', action='index', repo_name=HG_REPO))
8
9 assert """<div id="chg_20" class="container">""" in response.body, 'wrong info about number of changes'
11 10 assert """Small update at simplevcs app""" in response.body, 'missing info about commit message'
12 assert """<span class="removed" title="removed">0</span>""" in response.body, 'wrong info about removed nodes'
13 assert """<span class="changed" title="changed">2</span>""" in response.body, 'wrong info about changed nodes'
14 assert """<span class="added" title="added">1</span>""" in response.body, 'wrong info about added nodes'
15
11 assert """<span class="removed" title="removed: ">0</span>""" in response.body, 'wrong info about removed nodes'
12 assert """<span class="changed" title="changed: hg.py | models.py">2</span>""" in response.body, 'wrong info about changed nodes'
13 assert """<span class="added" title="added: managers.py">1</span>""" in response.body, 'wrong info about added nodes'
14
16 15 #pagination
17
18 response = self.app.get(url(controller='changelog', action='index', repo_name='vcs_test'), {'page':1})
19 response = self.app.get(url(controller='changelog', action='index', repo_name='vcs_test'), {'page':2})
20 response = self.app.get(url(controller='changelog', action='index', repo_name='vcs_test'), {'page':3})
21 response = self.app.get(url(controller='changelog', action='index', repo_name='vcs_test'), {'page':4})
22 response = self.app.get(url(controller='changelog', action='index', repo_name='vcs_test'), {'page':5})
23 response = self.app.get(url(controller='changelog', action='index', repo_name='vcs_test'), {'page':6})
16
17 response = self.app.get(url(controller='changelog', action='index', repo_name=HG_REPO), {'page':1})
18 response = self.app.get(url(controller='changelog', action='index', repo_name=HG_REPO), {'page':2})
19 response = self.app.get(url(controller='changelog', action='index', repo_name=HG_REPO), {'page':3})
20 response = self.app.get(url(controller='changelog', action='index', repo_name=HG_REPO), {'page':4})
21 response = self.app.get(url(controller='changelog', action='index', repo_name=HG_REPO), {'page':5})
22 response = self.app.get(url(controller='changelog', action='index', repo_name=HG_REPO), {'page':6})
23
24 24 # Test response after pagination...
25 25
26 assert """<span class="removed" title="removed">20</span>"""in response.body, 'wrong info about number of removed'
27 assert """<span class="changed" title="changed">1</span>"""in response.body, 'wrong info about number of changes'
28 assert """<span class="added" title="added">0</span>"""in response.body, 'wrong info about number of added'
29 26 assert """<div class="date">commit 64: 46ad32a4f974@2010-04-20 00:33:21</div>"""in response.body, 'wrong info about commit 64'
30 assert """<div class="message"><a href="/vcs_test/changeset/46ad32a4f974">Merge with 2e6a2bf9356ca56df08807f4ad86d480da72a8f4</a></div>"""in response.body, 'wrong info about commit 64 is a merge'
31
27 assert """<span class="removed" title="removed: api.rst">1</span>"""in response.body, 'wrong info about number of removed'
28 assert """<span class="changed" title="changed: .hgignore | README.rst | conf.py | index.rst | setup.py | test_hg.py | test_nodes.py | __init__.py | __init__.py | base.py | hg.py | nodes.py | __init__.py">13</span>"""in response.body, 'wrong info about number of changes'
29 assert """<span class="added" title="added: hg.rst | index.rst | index.rst | nodes.rst | index.rst | simplevcs.rst | installation.rst | quickstart.rst | setup.cfg | baseui_config.py | web.py | __init__.py | exceptions.py | __init__.py | exceptions.py | middleware.py | models.py | settings.py | utils.py | views.py">20</span>"""in response.body, 'wrong info about number of added'
30 assert """<div class="message"><a href="/%s/changeset/46ad32a4f974e45472a898c6b0acb600320579b1">Merge with 2e6a2bf9356ca56df08807f4ad86d480da72a8f4</a></div>""" % HG_REPO in response.body, 'wrong info about commit 64 is a merge'
31
32
33
34 #def test_index_git(self):
35 # self.log_user()
36 # response = self.app.get(url(controller='changelog', action='index', repo_name=GIT_REPO))
@@ -1,8 +1,8 b''
1 1 from rhodecode.tests import *
2 2
3 3 class TestChangesetController(TestController):
4 4
5 5 def test_index(self):
6 6 response = self.app.get(url(controller='changeset', action='index',
7 repo_name='vcs_test',revision='tip'))
7 repo_name=HG_REPO,revision='tip'))
8 8 # Test response...
@@ -1,15 +1,15 b''
1 1 from rhodecode.tests import *
2 2
3 3 class TestFeedController(TestController):
4 4
5 5 def test_rss(self):
6 6 self.log_user()
7 7 response = self.app.get(url(controller='feed', action='rss',
8 repo_name='vcs_test'))
8 repo_name=HG_REPO))
9 9 # Test response...
10 10
11 11 def test_atom(self):
12 12 self.log_user()
13 13 response = self.app.get(url(controller='feed', action='atom',
14 repo_name='vcs_test'))
14 repo_name=HG_REPO))
15 15 # Test response... No newline at end of file
@@ -1,11 +1,11 b''
1 1 from rhodecode.tests import *
2 2
3 3 class TestFilesController(TestController):
4 4
5 5 def test_index(self):
6 6 self.log_user()
7 7 response = self.app.get(url(controller='files', action='index',
8 repo_name='vcs_test',
8 repo_name=HG_REPO,
9 9 revision='tip',
10 10 f_path='/'))
11 11 # Test response...
@@ -1,11 +1,11 b''
1 1 from rhodecode.tests import *
2 2
3 3 class TestAdminController(TestController):
4 4
5 5 def test_index(self):
6 6 self.log_user()
7 response = self.app.get(url(controller='hg', action='index'))
7 response = self.app.get(url(controller='home', action='index'))
8 8 #if global permission is set
9 9 assert 'ADD NEW REPOSITORY' in response.body, 'Wrong main page'
10 assert 'href="/vcs_test/summary"' in response.body, ' mising repository in list'
10 assert 'href="/%s/summary"' % HG_REPO in response.body, ' mising repository in list'
11 11 # Test response...
@@ -1,147 +1,147 b''
1 1 from rhodecode.tests import *
2 2 from rhodecode.model.db import User
3 3 from rhodecode.lib.auth import check_password
4 4
5 5
6 6 class TestLoginController(TestController):
7 7
8 8 def test_index(self):
9 9 response = self.app.get(url(controller='login', action='index'))
10 10 assert response.status == '200 OK', 'Wrong response from login page got %s' % response.status
11 11 # Test response...
12 12
13 13 def test_login_admin_ok(self):
14 14 response = self.app.post(url(controller='login', action='index'),
15 15 {'username':'test_admin',
16 16 'password':'test12'})
17 17 assert response.status == '302 Found', 'Wrong response code from login got %s' % response.status
18 18 assert response.session['rhodecode_user'].username == 'test_admin', 'wrong logged in user'
19 19 response = response.follow()
20 assert 'vcs_test repository' in response.body
20 assert '%s repository' % HG_REPO in response.body
21 21
22 22 def test_login_regular_ok(self):
23 23 response = self.app.post(url(controller='login', action='index'),
24 24 {'username':'test_regular',
25 25 'password':'test12'})
26 26 print response
27 27 assert response.status == '302 Found', 'Wrong response code from login got %s' % response.status
28 28 assert response.session['rhodecode_user'].username == 'test_regular', 'wrong logged in user'
29 29 response = response.follow()
30 assert 'vcs_test repository' in response.body
30 assert '%s repository' % HG_REPO in response.body
31 31 assert '<a title="Admin" href="/_admin">' not in response.body
32 32
33 33 def test_login_ok_came_from(self):
34 34 test_came_from = '/_admin/users'
35 35 response = self.app.post(url(controller='login', action='index', came_from=test_came_from),
36 36 {'username':'test_admin',
37 37 'password':'test12'})
38 38 assert response.status == '302 Found', 'Wrong response code from came from redirection'
39 39 response = response.follow()
40 40
41 41 assert response.status == '200 OK', 'Wrong response from login page got %s' % response.status
42 42 assert 'Users administration' in response.body, 'No proper title in response'
43 43
44 44
45 45 def test_login_short_password(self):
46 46 response = self.app.post(url(controller='login', action='index'),
47 47 {'username':'error',
48 48 'password':'test'})
49 49 assert response.status == '200 OK', 'Wrong response from login page'
50 50 print response.body
51 51 assert 'Enter 6 characters or more' in response.body, 'No error password message in response'
52 52
53 53 def test_login_wrong_username_password(self):
54 54 response = self.app.post(url(controller='login', action='index'),
55 55 {'username':'error',
56 56 'password':'test12'})
57 57 assert response.status == '200 OK', 'Wrong response from login page'
58 58
59 59 assert 'invalid user name' in response.body, 'No error username message in response'
60 60 assert 'invalid password' in response.body, 'No error password message in response'
61 61
62 62
63 63 def test_register(self):
64 64 response = self.app.get(url(controller='login', action='register'))
65 65 assert 'Sign Up to rhodecode' in response.body, 'wrong page for user registration'
66 66
67 67 def test_register_err_same_username(self):
68 68 response = self.app.post(url(controller='login', action='register'),
69 69 {'username':'test_admin',
70 70 'password':'test',
71 71 'email':'goodmail@domain.com',
72 72 'name':'test',
73 73 'lastname':'test'})
74 74
75 75 assert response.status == '200 OK', 'Wrong response from register page got %s' % response.status
76 76 assert 'This username already exists' in response.body
77 77
78 78 def test_register_err_wrong_data(self):
79 79 response = self.app.post(url(controller='login', action='register'),
80 80 {'username':'xs',
81 81 'password':'',
82 82 'email':'goodmailm',
83 83 'name':'test',
84 84 'lastname':'test'})
85 85
86 86 assert response.status == '200 OK', 'Wrong response from register page got %s' % response.status
87 87 assert 'An email address must contain a single @' in response.body
88 88 assert 'Please enter a value' in response.body
89 89
90 90
91 91
92 92 def test_register_ok(self):
93 93 username = 'test_regular4'
94 94 password = 'qweqwe'
95 95 email = 'marcin@test.com'
96 96 name = 'testname'
97 97 lastname = 'testlastname'
98 98
99 99 response = self.app.post(url(controller='login', action='register'),
100 100 {'username':username,
101 101 'password':password,
102 102 'email':email,
103 103 'name':name,
104 104 'lastname':lastname})
105 105 print response.body
106 106 assert response.status == '302 Found', 'Wrong response from register page got %s' % response.status
107 107 assert 'You have successfully registered into rhodecode' in response.session['flash'][0], 'No flash message about user registration'
108 108
109 109 ret = self.sa.query(User).filter(User.username == 'test_regular4').one()
110 110 assert ret.username == username , 'field mismatch %s %s' % (ret.username, username)
111 111 assert check_password(password, ret.password) == True , 'password mismatch'
112 112 assert ret.email == email , 'field mismatch %s %s' % (ret.email, email)
113 113 assert ret.name == name , 'field mismatch %s %s' % (ret.name, name)
114 114 assert ret.lastname == lastname , 'field mismatch %s %s' % (ret.lastname, lastname)
115 115
116 116
117 117 def test_forgot_password_wrong_mail(self):
118 118 response = self.app.post(url(controller='login', action='password_reset'),
119 119 {'email':'marcin@wrongmail.org', })
120 120
121 121 assert "That e-mail address doesn't exist" in response.body, 'Missing error message about wrong email'
122 122
123 123 def test_forgot_password(self):
124 124 response = self.app.get(url(controller='login', action='password_reset'))
125 125 assert response.status == '200 OK', 'Wrong response from login page got %s' % response.status
126 126
127 127 username = 'test_password_reset_1'
128 128 password = 'qweqwe'
129 129 email = 'marcin@python-works.com'
130 130 name = 'passwd'
131 131 lastname = 'reset'
132 132
133 133 response = self.app.post(url(controller='login', action='register'),
134 134 {'username':username,
135 135 'password':password,
136 136 'email':email,
137 137 'name':name,
138 138 'lastname':lastname})
139 139 #register new user for email test
140 140 response = self.app.post(url(controller='login', action='password_reset'),
141 141 {'email':email, })
142 142 print response.session['flash']
143 143 assert 'You have successfully registered into rhodecode' in response.session['flash'][0], 'No flash message about user registration'
144 144 assert 'Your new password was sent' in response.session['flash'][1], 'No flash message about password reset'
145 145
146 146
147 147
@@ -1,113 +1,141 b''
1 1 from rhodecode.model.db import Repository
2 2 from rhodecode.tests import *
3 3
4 4 class TestReposController(TestController):
5 5
6 6 def test_index(self):
7 7 self.log_user()
8 8 response = self.app.get(url('repos'))
9 9 # Test response...
10 10
11 11 def test_index_as_xml(self):
12 12 response = self.app.get(url('formatted_repos', format='xml'))
13 13
14 def test_create(self):
14 def test_create_hg(self):
15 15 self.log_user()
16 repo_name = 'vcs_test_new'
16 repo_name = NEW_HG_REPO
17 17 description = 'description for newly created repo'
18 18 private = False
19 19 response = self.app.post(url('repos'), {'repo_name':repo_name,
20 'description':description,
21 'private':private})
20 'repo_type':'hg',
21 'description':description,
22 'private':private})
22 23
23 24 print response
24
25
25 26 #test if we have a message for that repository
26 27 print '-' * 100
27 28 print response.session
28 29 assert '''created repository %s''' % (repo_name) in response.session['flash'][0], 'No flash message about new repo'
29
30
30 31 #test if the fork was created in the database
31 32 new_repo = self.sa.query(Repository).filter(Repository.repo_name == repo_name).one()
32
33
33 34 assert new_repo.repo_name == repo_name, 'wrong name of repo name in db'
34 35 assert new_repo.description == description, 'wrong description'
35
36
36 37 #test if repository is visible in the list ?
37 38 response = response.follow()
38
39
39 40 assert repo_name in response.body, 'missing new repo from the main repos list'
40
41
41
42 def test_create_git(self):
43 self.log_user()
44 repo_name = NEW_GIT_REPO
45 description = 'description for newly created repo'
46 private = False
47 response = self.app.post(url('repos'), {'repo_name':repo_name,
48 'repo_type':'git',
49 'description':description,
50 'private':private})
51
52 print response
53
54 #test if we have a message for that repository
55 print '-' * 100
56 print response.session
57 assert '''created repository %s''' % (repo_name) in response.session['flash'][0], 'No flash message about new repo'
58
59 #test if the fork was created in the database
60 new_repo = self.sa.query(Repository).filter(Repository.repo_name == repo_name).one()
61
62 assert new_repo.repo_name == repo_name, 'wrong name of repo name in db'
63 assert new_repo.description == description, 'wrong description'
64
65 #test if repository is visible in the list ?
66 response = response.follow()
67
68 assert repo_name in response.body, 'missing new repo from the main repos list'
42 69
43 70
44 71 def test_new(self):
45 72 self.log_user()
46 73 response = self.app.get(url('new_repo'))
47 74
48 75 def test_new_as_xml(self):
49 76 response = self.app.get(url('formatted_new_repo', format='xml'))
50 77
51 78 def test_update(self):
52 response = self.app.put(url('repo', repo_name='vcs_test'))
79 response = self.app.put(url('repo', repo_name=HG_REPO))
53 80
54 81 def test_update_browser_fakeout(self):
55 response = self.app.post(url('repo', repo_name='vcs_test'), params=dict(_method='put'))
82 response = self.app.post(url('repo', repo_name=HG_REPO), params=dict(_method='put'))
56 83
57 84 def test_delete(self):
58 85 self.log_user()
59 86 repo_name = 'vcs_test_new_to_delete'
60 87 description = 'description for newly created repo'
61 88 private = False
62 89 response = self.app.post(url('repos'), {'repo_name':repo_name,
90 'repo_type':'hg',
63 91 'description':description,
64 92 'private':private})
65 93
66 94 print response
67
95
68 96 #test if we have a message for that repository
69 97 print '-' * 100
70 98 print response.session
71 99 assert '''created repository %s''' % (repo_name) in response.session['flash'][0], 'No flash message about new repo'
72
100
73 101 #test if the repo was created in the database
74 102 new_repo = self.sa.query(Repository).filter(Repository.repo_name == repo_name).one()
75
103
76 104 assert new_repo.repo_name == repo_name, 'wrong name of repo name in db'
77 105 assert new_repo.description == description, 'wrong description'
78
106
79 107 #test if repository is visible in the list ?
80 108 response = response.follow()
81
109
82 110 assert repo_name in response.body, 'missing new repo from the main repos list'
83
84
111
112
85 113 response = self.app.delete(url('repo', repo_name=repo_name))
86
114
87 115 print '-' * 100
88 116 print response.session
89 117 assert '''deleted repository %s''' % (repo_name) in response.session['flash'][0], 'No flash message about delete repo'
90
118
91 119 response.follow()
92
120
93 121 #check if repo was deleted from db
94 122 deleted_repo = self.sa.query(Repository).filter(Repository.repo_name == repo_name).scalar()
95
123
96 124 assert deleted_repo is None, 'Deleted repository was found in db'
97
125
98 126
99 127 def test_delete_browser_fakeout(self):
100 response = self.app.post(url('repo', repo_name='vcs_test'), params=dict(_method='delete'))
128 response = self.app.post(url('repo', repo_name=HG_REPO), params=dict(_method='delete'))
101 129
102 130 def test_show(self):
103 131 self.log_user()
104 response = self.app.get(url('repo', repo_name='vcs_test'))
132 response = self.app.get(url('repo', repo_name=HG_REPO))
105 133
106 134 def test_show_as_xml(self):
107 response = self.app.get(url('formatted_repo', repo_name='vcs_test', format='xml'))
135 response = self.app.get(url('formatted_repo', repo_name=HG_REPO, format='xml'))
108 136
109 137 def test_edit(self):
110 response = self.app.get(url('edit_repo', repo_name='vcs_test'))
138 response = self.app.get(url('edit_repo', repo_name=HG_REPO))
111 139
112 140 def test_edit_as_xml(self):
113 response = self.app.get(url('formatted_edit_repo', repo_name='vcs_test', format='xml'))
141 response = self.app.get(url('formatted_edit_repo', repo_name=HG_REPO, format='xml'))
@@ -1,38 +1,36 b''
1 1 from rhodecode.tests import *
2 from rhodecode.lib.indexers import IDX_LOCATION
3 2 import os
4 3 from nose.plugins.skip import SkipTest
5 4
6 5 class TestSearchController(TestController):
7 6
8 7 def test_index(self):
9 8 self.log_user()
10 9 response = self.app.get(url(controller='search', action='index'))
11 10 print response.body
12 11 assert 'class="small" id="q" name="q" type="text"' in response.body, 'Search box content error'
13 12 # Test response...
14 13
15 14 def test_empty_search(self):
16
17 if os.path.isdir(IDX_LOCATION):
15 if os.path.isdir(self.index_location):
18 16 raise SkipTest('skipped due to existing index')
19 17 else:
20 18 self.log_user()
21 response = self.app.get(url(controller='search', action='index'), {'q':'vcs_test'})
19 response = self.app.get(url(controller='search', action='index'), {'q':HG_REPO})
22 20 assert 'There is no index to search in. Please run whoosh indexer' in response.body, 'No error message about empty index'
23
21
24 22 def test_normal_search(self):
25 23 self.log_user()
26 24 response = self.app.get(url(controller='search', action='index'), {'q':'def repo'})
27 25 print response.body
28 26 assert '10 results' in response.body, 'no message about proper search results'
29 27 assert 'Permission denied' not in response.body, 'Wrong permissions settings for that repo and user'
30
31
28
29
32 30 def test_repo_search(self):
33 31 self.log_user()
34 response = self.app.get(url(controller='search', action='index'), {'q':'repository:vcs_test def test'})
32 response = self.app.get(url(controller='search', action='index'), {'q':'repository:%s def test' % HG_REPO})
35 33 print response.body
36 34 assert '4 results' in response.body, 'no message about proper search results'
37 35 assert 'Permission denied' not in response.body, 'Wrong permissions settings for that repo and user'
38
36
@@ -1,55 +1,50 b''
1 1 from rhodecode.model.db import Repository
2 2 from rhodecode.tests import *
3 3
4 4 class TestSettingsController(TestController):
5 5
6 6 def test_index(self):
7 7 self.log_user()
8 8 response = self.app.get(url(controller='settings', action='index',
9 repo_name='vcs_test'))
9 repo_name=HG_REPO))
10 10 # Test response...
11
11
12 12 def test_fork(self):
13 13 self.log_user()
14 14 response = self.app.get(url(controller='settings', action='fork',
15 repo_name='vcs_test'))
16
15 repo_name=HG_REPO))
16
17 17
18 18 def test_fork_create(self):
19 19 self.log_user()
20 fork_name = 'vcs_test_fork'
20 fork_name = HG_FORK
21 21 description = 'fork of vcs test'
22 repo_name = 'vcs_test'
22 repo_name = HG_REPO
23 23 response = self.app.post(url(controller='settings', action='fork_create',
24 24 repo_name=repo_name),
25 25 {'fork_name':fork_name,
26 'repo_type':'hg',
26 27 'description':description,
27 28 'private':'False'})
28
29
30 print response
31
29
32 30 #test if we have a message that fork is ok
33 31 assert 'fork %s repository as %s task added' \
34 32 % (repo_name, fork_name) in response.session['flash'][0], 'No flash message about fork'
35
33
36 34 #test if the fork was created in the database
37 35 fork_repo = self.sa.query(Repository).filter(Repository.repo_name == fork_name).one()
38
36
39 37 assert fork_repo.repo_name == fork_name, 'wrong name of repo name in new db fork repo'
40 38 assert fork_repo.fork.repo_name == repo_name, 'wrong fork parrent'
41
42
39
40
43 41 #test if fork is visible in the list ?
44 42 response = response.follow()
45 43
46 44
47 45 #check if fork is marked as fork
48 46 response = self.app.get(url(controller='summary', action='index',
49 47 repo_name=fork_name))
50
51
52 print response
53
48
54 49 assert 'Fork of %s' % repo_name in response.body, 'no message about that this repo is a fork'
55
50
@@ -1,8 +1,8 b''
1 1 from rhodecode.tests import *
2 2
3 3 class TestShortlogController(TestController):
4 4
5 5 def test_index(self):
6 6 self.log_user()
7 response = self.app.get(url(controller='shortlog', action='index',repo_name='vcs_test'))
7 response = self.app.get(url(controller='shortlog', action='index',repo_name=HG_REPO))
8 8 # Test response...
@@ -1,11 +1,17 b''
1 1 from rhodecode.tests import *
2 2
3 3 class TestSummaryController(TestController):
4 4
5 5 def test_index(self):
6 6 self.log_user()
7 response = self.app.get(url(controller='summary', action='index', repo_name='vcs_test'))
8 print response
9 assert """<img style="margin-bottom:2px" class="icon" title="public repository" alt="public" src="/images/icons/lock_open.png"/>""" in response.body
10
11 # Test response...
7 response = self.app.get(url(controller='summary', action='index', repo_name=HG_REPO))
8
9 #repo type
10 assert """<img style="margin-bottom:2px" class="icon" title="Mercurial repository" alt="Mercurial repository" src="/images/icons/hgicon.png"/>""" in response.body
11 assert """<img style="margin-bottom:2px" class="icon" title="public repository" alt="public repository" src="/images/icons/lock_open.png"/>""" in response.body
12
13 #codes stats
14 assert """var data = {"text/x-python": 42, "text/plain": 12};""" in response.body, 'wrong info about % of codes stats'
15
16 # clone url...
17 assert """<input type="text" id="clone_url" readonly="readonly" value="hg clone http://test_admin@localhost:80/%s" size="70"/>""" % HG_REPO in response.body
@@ -1,8 +1,13 b''
1 1 from rhodecode.tests import *
2 2
3 3 class TestTagsController(TestController):
4 4
5 5 def test_index(self):
6 6 self.log_user()
7 response = self.app.get(url(controller='tags', action='index',repo_name='vcs_test'))
7 response = self.app.get(url(controller='tags', action='index', repo_name=HG_REPO))
8 assert """<a href="/%s/changeset/27cd5cce30c96924232dffcd24178a07ffeb5dfc">tip</a>""" % HG_REPO, 'wrong info about tip tag'
9 assert """<a href="/%s/changeset/fd4bdb5e9b2a29b4393a4ac6caef48c17ee1a200">0.1.4</a>""" % HG_REPO, 'wrong info about 0.1.4 tag'
10 assert """<a href="/%s/changeset/17544fbfcd33ffb439e2b728b5d526b1ef30bfcf">0.1.3</a>""" % HG_REPO, 'wrong info about 0.1.3 tag'
11 assert """<a href="/%s/changeset/a7e60bff65d57ac3a1a1ce3b12a70f8a9e8a7720">0.1.2</a>""" % HG_REPO, 'wrong info about 0.1.2 tag'
12 assert """<a href="/%s/changeset/eb3a60fc964309c1a318b8dfe26aa2d1586c85ae">0.1.1</a>""" % HG_REPO, 'wrong info about 0.1.1 tag'
8 13 # Test response...
@@ -1,43 +1,49 b''
1 1 from rhodecode.tests import *
2 2
3 3 class TestUsersController(TestController):
4 4
5 5 def test_index(self):
6 6 response = self.app.get(url('users'))
7 7 # Test response...
8 8
9 9 def test_index_as_xml(self):
10 10 response = self.app.get(url('formatted_users', format='xml'))
11 11
12 12 def test_create(self):
13 response = self.app.post(url('users'))
13 self.log_user()
14 # user_name = 'new_user'
15 # response = self.app.post(url('users'),{'repo_name':user_name,
16 # 'repo_type':'hg',
17 # 'description':description,
18 # 'private':private})
19
14 20
15 21 def test_new(self):
16 22 response = self.app.get(url('new_user'))
17 23
18 24 def test_new_as_xml(self):
19 25 response = self.app.get(url('formatted_new_user', format='xml'))
20 26
21 27 def test_update(self):
22 28 response = self.app.put(url('user', id=1))
23 29
24 30 def test_update_browser_fakeout(self):
25 31 response = self.app.post(url('user', id=1), params=dict(_method='put'))
26 32
27 33 def test_delete(self):
28 34 response = self.app.delete(url('user', id=1))
29 35
30 36 def test_delete_browser_fakeout(self):
31 37 response = self.app.post(url('user', id=1), params=dict(_method='delete'))
32 38
33 39 def test_show(self):
34 40 response = self.app.get(url('user', id=1))
35 41
36 42 def test_show_as_xml(self):
37 43 response = self.app.get(url('formatted_user', id=1, format='xml'))
38 44
39 45 def test_edit(self):
40 46 response = self.app.get(url('edit_user', id=1))
41 47
42 48 def test_edit_as_xml(self):
43 49 response = self.app.get(url('formatted_edit_user', id=1, format='xml'))
@@ -1,173 +1,174 b''
1 1 ################################################################################
2 2 ################################################################################
3 3 # rhodecode - Pylons environment configuration #
4 4 # #
5 5 # The %(here)s variable will be replaced with the parent directory of this file#
6 6 ################################################################################
7 7
8 8 [DEFAULT]
9 9 debug = true
10 10 ################################################################################
11 11 ## Uncomment and replace with the address which should receive ##
12 12 ## any error reports after application crash ##
13 13 ## Additionally those settings will be used by rhodecode mailing system ##
14 14 ################################################################################
15 15 #email_to = admin@localhost
16 16 #error_email_from = paste_error@localhost
17 17 #app_email_from = rhodecode-noreply@localhost
18 18 #error_message =
19 19
20 20 #smtp_server = mail.server.com
21 21 #smtp_username =
22 22 #smtp_password =
23 23 #smtp_port =
24 24 #smtp_use_tls = false
25 25
26 26 [server:main]
27 27 ##nr of threads to spawn
28 28 threadpool_workers = 5
29 29
30 30 ##max request before thread respawn
31 31 threadpool_max_requests = 2
32 32
33 33 ##option to use threads of process
34 34 use_threadpool = true
35 35
36 36 use = egg:Paste#http
37 37 host = 127.0.0.1
38 38 port = 5000
39 39
40 40 [app:main]
41 41 use = egg:rhodecode
42 42 full_stack = true
43 43 static_files = true
44 44 lang=en
45 45 cache_dir = %(here)s/data
46 index_dir = /tmp/index
46 47
47 48 ####################################
48 49 ### BEAKER CACHE ####
49 50 ####################################
50 51 beaker.cache.data_dir=/%(here)s/data/cache/data
51 52 beaker.cache.lock_dir=/%(here)s/data/cache/lock
52 53 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
53 54
54 55 beaker.cache.super_short_term.type=memory
55 56 beaker.cache.super_short_term.expire=10
56 57
57 58 beaker.cache.short_term.type=memory
58 59 beaker.cache.short_term.expire=60
59 60
60 61 beaker.cache.long_term.type=memory
61 62 beaker.cache.long_term.expire=36000
62 63
63 64
64 65 beaker.cache.sql_cache_short.type=memory
65 66 beaker.cache.sql_cache_short.expire=5
66 67
67 68 beaker.cache.sql_cache_med.type=memory
68 69 beaker.cache.sql_cache_med.expire=360
69 70
70 71 beaker.cache.sql_cache_long.type=file
71 72 beaker.cache.sql_cache_long.expire=3600
72 73
73 74 ####################################
74 75 ### BEAKER SESSION ####
75 76 ####################################
76 77 ## Type of storage used for the session, current types are
77 78 ## dbm, file, memcached, database, and memory.
78 79 ## The storage uses the Container API
79 80 ##that is also used by the cache system.
80 81 beaker.session.type = file
81 82
82 83 beaker.session.key = rhodecode
83 84 beaker.session.secret = g654dcno0-9873jhgfreyu
84 85 beaker.session.timeout = 36000
85 86
86 87 ##auto save the session to not to use .save()
87 88 beaker.session.auto = False
88 89
89 90 ##true exire at browser close
90 91 #beaker.session.cookie_expires = 3600
91 92
92 93
93 94 ################################################################################
94 95 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
95 96 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
96 97 ## execute malicious code after an exception is raised. ##
97 98 ################################################################################
98 99 #set debug = false
99 100
100 101 ##################################
101 102 ### LOGVIEW CONFIG ###
102 103 ##################################
103 104 logview.sqlalchemy = #faa
104 105 logview.pylons.templating = #bfb
105 106 logview.pylons.util = #eee
106 107
107 108 #########################################################
108 109 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
109 110 #########################################################
110 111 sqlalchemy.db1.url = sqlite:///%(here)s/test.db
111 112 #sqlalchemy.db1.echo = False
112 113 #sqlalchemy.db1.pool_recycle = 3600
113 114 sqlalchemy.convert_unicode = true
114 115
115 116 ################################
116 117 ### LOGGING CONFIGURATION ####
117 118 ################################
118 119 [loggers]
119 120 keys = root, routes, rhodecode, sqlalchemy
120 121
121 122 [handlers]
122 123 keys = console
123 124
124 125 [formatters]
125 126 keys = generic,color_formatter
126 127
127 128 #############
128 129 ## LOGGERS ##
129 130 #############
130 131 [logger_root]
131 132 level = ERROR
132 133 handlers = console
133 134
134 135 [logger_routes]
135 136 level = ERROR
136 137 handlers = console
137 138 qualname = routes.middleware
138 139 # "level = DEBUG" logs the route matched and routing variables.
139 140
140 141 [logger_rhodecode]
141 142 level = ERROR
142 143 handlers = console
143 144 qualname = rhodecode
144 145 propagate = 0
145 146
146 147 [logger_sqlalchemy]
147 148 level = ERROR
148 149 handlers = console
149 150 qualname = sqlalchemy.engine
150 151 propagate = 0
151 152
152 153 ##############
153 154 ## HANDLERS ##
154 155 ##############
155 156
156 157 [handler_console]
157 158 class = StreamHandler
158 159 args = (sys.stderr,)
159 160 level = NOTSET
160 161 formatter = color_formatter
161 162
162 163 ################
163 164 ## FORMATTERS ##
164 165 ################
165 166
166 167 [formatter_generic]
167 168 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
168 169 datefmt = %Y-%m-%d %H:%M:%S
169 170
170 171 [formatter_color_formatter]
171 172 class=rhodecode.lib.colored_formatter.ColorFormatter
172 173 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
173 174 datefmt = %Y-%m-%d %H:%M:%S No newline at end of file
1 NO CONTENT: file was removed, binary diff hidden
General Comments 0
You need to be logged in to leave comments. Login now