# HG changeset patch # User Marcin Kuzminski # Date 2011-11-26 00:16:21 # Node ID 64e91067b9969ab91f2a177288935e8c415a1271 # Parent e7eef7a1db6a3c3f29ad73e9c400b3e740c60b60 - refactoring to overcome poor usage of global pylons config - db transaction fixes - fixed tests - garden diff --git a/rhodecode/__init__.py b/rhodecode/__init__.py --- a/rhodecode/__init__.py +++ b/rhodecode/__init__.py @@ -54,3 +54,10 @@ BACKENDS = { 'hg': 'Mercurial repository', #'git': 'Git repository', } + +CELERY_ON = False + +# link to config for pylons +CONFIG = None + + diff --git a/rhodecode/config/environment.py b/rhodecode/config/environment.py --- a/rhodecode/config/environment.py +++ b/rhodecode/config/environment.py @@ -7,13 +7,14 @@ from mako.lookup import TemplateLookup from pylons.configuration import PylonsConfig from pylons.error import handle_mako_error +import rhodecode import rhodecode.lib.app_globals as app_globals import rhodecode.lib.helpers from rhodecode.config.routing import make_map -from rhodecode.lib import celerypylons +# don't remove this import it does magic for celery +from rhodecode.lib import celerypylons, str2bool from rhodecode.lib import engine_from_config -from rhodecode.lib.timerproxy import TimerProxy from rhodecode.lib.auth import set_available_permissions from rhodecode.lib.utils import repo2db_mapper, make_ui, set_rhodecode_config from rhodecode.model import init_model @@ -38,6 +39,10 @@ def load_environment(global_conf, app_co # Initialize config with the basic options config.init_app(global_conf, app_conf, package='rhodecode', paths=paths) + # store some globals into our main isntance + rhodecode.CELERY_ON = str2bool(config['app_conf'].get('use_celery')) + rhodecode.CONFIG = config + config['routes.map'] = make_map(config) config['pylons.app_globals'] = app_globals.Globals(config) config['pylons.h'] = rhodecode.lib.helpers @@ -61,7 +66,7 @@ def load_environment(global_conf, app_co from rhodecode.lib.utils import create_test_env, create_test_index from rhodecode.tests import TESTS_TMP_PATH create_test_env(TESTS_TMP_PATH, config) - create_test_index(TESTS_TMP_PATH, config, True) + #create_test_index(TESTS_TMP_PATH, config, True) #MULTIPLE DB configs # Setup the SQLAlchemy database engine diff --git a/rhodecode/controllers/admin/notifications.py b/rhodecode/controllers/admin/notifications.py --- a/rhodecode/controllers/admin/notifications.py +++ b/rhodecode/controllers/admin/notifications.py @@ -2,6 +2,7 @@ import logging import traceback from pylons import tmpl_context as c, url +from pylons.controllers.util import redirect from rhodecode.lib.base import BaseController, render from rhodecode.model.db import Notification @@ -10,7 +11,7 @@ from rhodecode.model.notification import from rhodecode.lib.auth import LoginRequired from rhodecode.lib import helpers as h from rhodecode.model.meta import Session -from pylons.controllers.util import redirect + log = logging.getLogger(__name__) diff --git a/rhodecode/lib/celerylib/__init__.py b/rhodecode/lib/celerylib/__init__.py --- a/rhodecode/lib/celerylib/__init__.py +++ b/rhodecode/lib/celerylib/__init__.py @@ -32,10 +32,9 @@ from os.path import dirname as dn, join from hashlib import md5 from decorator import decorator -from pylons import config from vcs.utils.lazy import LazyProperty - +from rhodecode import CELERY_ON from rhodecode.lib import str2bool, safe_str from rhodecode.lib.pidlock import DaemonLock, LockHeld @@ -44,10 +43,7 @@ from celery.messaging import establish_c log = logging.getLogger(__name__) -try: - CELERY_ON = str2bool(config['app_conf'].get('use_celery')) -except KeyError: - CELERY_ON = False + class ResultWrapper(object): diff --git a/rhodecode/lib/celerylib/tasks.py b/rhodecode/lib/celerylib/tasks.py --- a/rhodecode/lib/celerylib/tasks.py +++ b/rhodecode/lib/celerylib/tasks.py @@ -39,6 +39,7 @@ from pylons.i18n.translation import _ from vcs import get_backend +from rhodecode import CELERY_ON from rhodecode.lib import LANGUAGES_EXTENSIONS_MAP, safe_str from rhodecode.lib.celerylib import run_task, locked_task, str2bool, \ __get_lockkey, LockHeld, DaemonLock @@ -59,9 +60,6 @@ add_cache(config) 'reset_user_password', 'send_email'] -CELERY_ON = str2bool(config['app_conf'].get('use_celery')) - - def get_session(): if CELERY_ON: engine = engine_from_config(config, 'sqlalchemy.db1.') diff --git a/rhodecode/lib/utils.py b/rhodecode/lib/utils.py --- a/rhodecode/lib/utils.py +++ b/rhodecode/lib/utils.py @@ -414,7 +414,7 @@ def repo2db_mapper(initial_repo_list, re 'group_id': getattr(group, 'group_id', None) } rm.create(form_data, user, just_db=True) - + sa.commit() removed = [] if remove_obsolete: #remove from database those repositories that are not in the filesystem diff --git a/rhodecode/model/db.py b/rhodecode/model/db.py --- a/rhodecode/model/db.py +++ b/rhodecode/model/db.py @@ -27,10 +27,8 @@ import os import logging import datetime import traceback -from datetime import date from sqlalchemy import * -from sqlalchemy.exc import DatabaseError from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.orm import relationship, joinedload, class_mapper, validates from beaker.cache import cache_region, region_invalidate @@ -40,8 +38,7 @@ from vcs.utils.helpers import get_scm from vcs.exceptions import VCSError from vcs.utils.lazy import LazyProperty -from rhodecode.lib import str2bool, safe_str, get_changeset_safe, \ - generate_api_key, safe_unicode +from rhodecode.lib import str2bool, safe_str, get_changeset_safe, safe_unicode from rhodecode.lib.exceptions import UsersGroupsAssignedException from rhodecode.lib.compat import json from rhodecode.lib.caching_query import FromCache @@ -354,7 +351,7 @@ class UserLog(Base, BaseModel): @property def action_as_day(self): - return date(*self.action_date.timetuple()[:3]) + return datetime.date(*self.action_date.timetuple()[:3]) user = relationship('User') repository = relationship('Repository') diff --git a/rhodecode/model/notification.py b/rhodecode/model/notification.py --- a/rhodecode/model/notification.py +++ b/rhodecode/model/notification.py @@ -29,9 +29,9 @@ import logging import traceback import datetime -from pylons import config from pylons.i18n.translation import _ +import rhodecode from rhodecode.lib import helpers as h from rhodecode.model import BaseModel from rhodecode.model.db import Notification, User, UserNotification @@ -41,7 +41,6 @@ log = logging.getLogger(__name__) class NotificationModel(BaseModel): - def __get_user(self, user): if isinstance(user, basestring): return User.get_by_username(username=user) @@ -58,7 +57,6 @@ class NotificationModel(BaseModel): raise Exception('notification must be int or Instance' ' of Notification got %s' % type(notification)) - def create(self, created_by, subject, body, recipients, type_=Notification.TYPE_MESSAGE): """ @@ -90,7 +88,6 @@ class NotificationModel(BaseModel): body=body, recipients=recipients_objs, type_=type_) - # send email with notification for rec in recipients_objs: email_subject = NotificationModel().make_description(notif, False) @@ -176,7 +173,8 @@ class EmailNotificationModel(BaseModel): TYPE_DEFAULT = 'default' def __init__(self): - self._template_root = config['pylons.paths']['templates'][0] + self._template_root = rhodecode.CONFIG['pylons.paths']['templates'][0] + self._tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup self.email_types = { self.TYPE_CHANGESET_COMMENT:'email_templates/changeset_comment.html', @@ -191,10 +189,9 @@ class EmailNotificationModel(BaseModel): :param type_: """ + base = self.email_types.get(type_, self.TYPE_DEFAULT) - - lookup = config['pylons.app_globals'].mako_lookup - email_template = lookup.get_template(base) + email_template = self._tmpl_lookup.get_template(base) # translator inject _kwargs = {'_':_} _kwargs.update(kwargs) diff --git a/rhodecode/tests/__init__.py b/rhodecode/tests/__init__.py --- a/rhodecode/tests/__init__.py +++ b/rhodecode/tests/__init__.py @@ -13,6 +13,7 @@ import logging from os.path import join as jn from unittest import TestCase +from tempfile import _RandomNameSequence from paste.deploy import loadapp from paste.script.appinstall import SetupCommand @@ -20,7 +21,7 @@ from pylons import config, url from routes.util import URLGenerator from webtest import TestApp -from rhodecode.model import meta +from rhodecode.model.meta import Session from rhodecode.model.db import User import pylons.test @@ -43,7 +44,7 @@ log = logging.getLogger(__name__) environ = {} #SOME GLOBALS FOR TESTS -from tempfile import _RandomNameSequence + TESTS_TMP_PATH = jn('/', 'tmp', 'rc_test_%s' % _RandomNameSequence().next()) TEST_USER_ADMIN_LOGIN = 'test_admin' TEST_USER_ADMIN_PASS = 'test12' @@ -64,7 +65,7 @@ class TestController(TestCase): self.app = TestApp(wsgiapp) url._push_object(URLGenerator(config['routes.map'], environ)) - self.Session = meta.Session + self.Session = Session self.index_location = config['app_conf']['index_dir'] TestCase.__init__(self, *args, **kwargs) @@ -79,14 +80,16 @@ class TestController(TestCase): self.fail('could not login using %s %s' % (username, password)) self.assertEqual(response.status, '302 Found') - self.assertEqual(response.session['rhodecode_user'].get('username'), - username) - return response.follow() + ses = response.session['rhodecode_user'] + self.assertEqual(ses.get('username'), username) + response = response.follow() + self.assertEqual(ses.get('is_authenticated'), True) + + return response.session['rhodecode_user'] def _get_logged_user(self): return User.get_by_username(self._logged_username) - def checkSessionFlash(self, response, msg): self.assertTrue('flash' in response.session) self.assertTrue(msg in response.session['flash'][0][1]) diff --git a/rhodecode/tests/functional/test_admin_notifications.py b/rhodecode/tests/functional/test_admin_notifications.py --- a/rhodecode/tests/functional/test_admin_notifications.py +++ b/rhodecode/tests/functional/test_admin_notifications.py @@ -102,7 +102,7 @@ class TestNotificationsController(TestCo name='u2', lastname='u2') notification = NotificationModel().create(created_by=cur_user, - subject='test', + subject=u'test', body=u'hi there', recipients=[cur_user, u1, u2]) diff --git a/rhodecode/tests/functional/test_branches.py b/rhodecode/tests/functional/test_branches.py --- a/rhodecode/tests/functional/test_branches.py +++ b/rhodecode/tests/functional/test_branches.py @@ -4,15 +4,15 @@ class TestBranchesController(TestControl def test_index(self): self.log_user() - response = self.app.get(url(controller='branches', action='index', repo_name=HG_REPO)) + response = self.app.get(url(controller='branches', + action='index', repo_name=HG_REPO)) - assert """default""" % HG_REPO in response.body, 'wrong info about default branch' - assert """git""" % HG_REPO in response.body, 'wrong info about default git' - assert """web""" % HG_REPO in response.body, 'wrong info about default web' + self.assertTrue("""default""" % HG_REPO in response.body) + self.assertTrue("""git""" % HG_REPO in response.body) + self.assertTrue("""web""" % HG_REPO in response.body) - # Test response... diff --git a/rhodecode/tests/functional/test_changeset_comments.py b/rhodecode/tests/functional/test_changeset_comments.py --- a/rhodecode/tests/functional/test_changeset_comments.py +++ b/rhodecode/tests/functional/test_changeset_comments.py @@ -108,7 +108,7 @@ class TestChangeSetCommentrController(Te users = [x.user.username for x in UserNotification.query().all()] # test_regular get's notification by @mention - self.assertEqual(users, [u'test_admin', u'test_regular']) + self.assertEqual(sorted(users), [u'test_admin', u'test_regular']) def test_delete(self): self.log_user() @@ -128,7 +128,7 @@ class TestChangeSetCommentrController(Te self.app.delete(url(controller='changeset', action='delete_comment', repo_name=HG_REPO, - comment_id = comment_id)) + comment_id=comment_id)) comments = ChangesetComment.query().all() self.assertEqual(len(comments), 0) diff --git a/rhodecode/tests/functional/test_forks.py b/rhodecode/tests/functional/test_forks.py --- a/rhodecode/tests/functional/test_forks.py +++ b/rhodecode/tests/functional/test_forks.py @@ -20,10 +20,13 @@ class TestForksController(TestController fork_name = HG_FORK description = 'fork of vcs test' repo_name = HG_REPO - response = self.app.post(url(controller='settings', + org_repo = Repository.get_by_repo_name(repo_name) + response = self.app.post(url(controller='forks', action='fork_create', repo_name=repo_name), - {'fork_name':fork_name, + {'repo_name':fork_name, + 'repo_group':'', + 'fork_parent_id':org_repo.repo_id, 'repo_type':'hg', 'description':description, 'private':'False'}) @@ -39,3 +42,42 @@ class TestForksController(TestController #remove this fork response = self.app.delete(url('repo', repo_name=fork_name)) + + + + def test_z_fork_create(self): + self.log_user() + fork_name = HG_FORK + description = 'fork of vcs test' + repo_name = HG_REPO + org_repo = Repository.get_by_repo_name(repo_name) + response = self.app.post(url(controller='forks', action='fork_create', + repo_name=repo_name), + {'repo_name':fork_name, + 'repo_group':'', + 'fork_parent_id':org_repo.repo_id, + 'repo_type':'hg', + 'description':description, + 'private':'False'}) + + #test if we have a message that fork is ok + self.assertTrue('forked %s repository as %s' \ + % (repo_name, fork_name) in response.session['flash'][0]) + + #test if the fork was created in the database + fork_repo = self.Session().query(Repository)\ + .filter(Repository.repo_name == fork_name).one() + + self.assertEqual(fork_repo.repo_name, fork_name) + self.assertEqual(fork_repo.fork.repo_name, repo_name) + + + #test if fork is visible in the list ? + response = response.follow() + + + #check if fork is marked as fork + response = self.app.get(url(controller='summary', action='index', + repo_name=fork_name)) + + self.assertTrue('Fork of %s' % repo_name in response.body) diff --git a/rhodecode/tests/functional/test_settings.py b/rhodecode/tests/functional/test_settings.py --- a/rhodecode/tests/functional/test_settings.py +++ b/rhodecode/tests/functional/test_settings.py @@ -8,42 +8,3 @@ class TestSettingsController(TestControl response = self.app.get(url(controller='settings', action='index', repo_name=HG_REPO)) # Test response... - - def test_fork(self): - self.log_user() - response = self.app.get(url(controller='settings', action='fork', - repo_name=HG_REPO)) - - - def test_fork_create(self): - self.log_user() - fork_name = HG_FORK - description = 'fork of vcs test' - repo_name = HG_REPO - response = self.app.post(url(controller='settings', action='fork_create', - repo_name=repo_name), - {'fork_name':fork_name, - 'repo_type':'hg', - 'description':description, - 'private':'False'}) - - #test if we have a message that fork is ok - assert 'forked %s repository as %s' \ - % (repo_name, fork_name) in response.session['flash'][0], 'No flash message about fork' - - #test if the fork was created in the database - fork_repo = self.Session().query(Repository).filter(Repository.repo_name == fork_name).one() - - assert fork_repo.repo_name == fork_name, 'wrong name of repo name in new db fork repo' - assert fork_repo.fork.repo_name == repo_name, 'wrong fork parrent' - - - #test if fork is visible in the list ? - response = response.follow() - - - #check if fork is marked as fork - response = self.app.get(url(controller='summary', action='index', - repo_name=fork_name)) - - assert 'Fork of %s' % repo_name in response.body, 'no message about that this repo is a fork'