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