Пример #1
0
 def initDestinations(self):
     """Runs the trac initialization script for each destination trac and applies and config values"""
     for dest_name in self.dests.keys():
         inheritFile = [
             x[2] for x in self.dests[dest_name]['configs']
             if x[0] == 'inherit' and x[1] == 'file'
         ]
         if inheritFile:
             inheritOpt = '--inherit=/var/trac/common/conf/trac.ini'
         else:
             inheritOpt = ''
         initline = "'%s' '%s' '%s' '%s' %s" % (dest_name, \
          self.dests[dest_name]['db'], self.dests[dest_name]['repo_type'], self.dests[dest_name]['repo_dir'], inheritOpt)
         destination = os.path.abspath(self.dests[dest_name]['path'])
         destAdmin = TracAdmin(destination)
         destAdmin.do_initenv(initline)
         self.dests[dest_name]['trac'] = Trac(destination)
         if self.dests[dest_name]['repo_type'] == 'hg':
             self.dests[dest_name]['trac']._env.config.set(
                 'components', 'tracext.hg.*', 'enabled')
         if self.dests[dest_name].has_key('configs'):
             for confSection, confName, confValue in self.dests[dest_name][
                     'configs']:
                 self.dests[dest_name]['trac']._env.config.set(
                     confSection, confName, confValue)
         self.dests[dest_name]['trac']._env.config.save()
Пример #2
0
 def _do_product_admin(self, prefix, *args):
     mgr = self.product_admincmd_mgr(prefix)
     if args and args[0] in self.GLOBAL_COMMANDS:
         raise AdminCommandError('%s command not supported for products' %
                                 (args[0],))
     if args and args[0] == 'help':
         help_args = args[1:]
         if help_args:
             doc = mgr.get_command_help(list(help_args))
             if doc:
                 TracAdmin.print_doc(doc)
             else:
                 printerr(_("No documentation found for '%(cmd)s'."
                            " Use 'help' to see the list of commands.",
                            cmd=' '.join(help_args)))
                 cmds = mgr.get_similar_commands(help_args[0])
                 if cmds:
                     printout('')
                     printout(ngettext("Did you mean this?",
                                       "Did you mean one of these?",
                                       len(cmds)))
                     for cmd in cmds:
                         printout('    ' + cmd)
         else:
             printout(_("trac-admin - The Trac Administration Console "
                        "%(version)s", version=TRAC_VERSION))
             env = mgr.env
             TracAdmin.print_doc(TracAdmin.all_docs(env), short=True)
     else:
         mgr.execute_command(*args)
Пример #3
0
 def _do_product_admin(self, prefix, *args):
     mgr = self.product_admincmd_mgr(prefix)
     if args and args[0] in self.GLOBAL_COMMANDS:
         raise AdminCommandError('%s command not supported for products' %
                                 (args[0], ))
     if args and args[0] == 'help':
         help_args = args[1:]
         if help_args:
             doc = mgr.get_command_help(list(help_args))
             if doc:
                 TracAdmin.print_doc(doc)
             else:
                 printerr(
                     _(
                         "No documentation found for '%(cmd)s'."
                         " Use 'help' to see the list of commands.",
                         cmd=' '.join(help_args)))
                 cmds = mgr.get_similar_commands(help_args[0])
                 if cmds:
                     printout('')
                     printout(
                         ngettext("Did you mean this?",
                                  "Did you mean one of these?", len(cmds)))
                     for cmd in cmds:
                         printout('    ' + cmd)
         else:
             printout(
                 _(
                     "trac-admin - The Trac Administration Console "
                     "%(version)s",
                     version=TRAC_VERSION))
             env = mgr.env
             TracAdmin.print_doc(TracAdmin.all_docs(env), short=True)
     else:
         mgr.execute_command(*args)
Пример #4
0
 def setUp(self):
     self.env = EnvironmentStub(default_data=True,
                                enable=('trac.*', ),
                                disable=('trac.tests.*', ))
     self.admin = TracAdmin()
     self.admin.env_set('', self.env)
     self._test_date = '2004-01-11'  # Set test date to 11th Jan 2004
Пример #5
0
 def setUp(self):
     self.env = EnvironmentStub(default_data=True,
                                enable=('trac.*', ),
                                disable=('trac.tests.*', ))
     self.admin = TracAdmin()
     self.admin.env_set('', self.env)
     self.tempdir = mkdtemp()
Пример #6
0
class TracAdminDeployTestCase(TracAdminTestCaseBase):
    """Tests for the trac-admin deploy command."""

    stdout = None
    stderr = None
    devnull = None

    @classmethod
    def setUpClass(cls):
        cls.stdout = sys.stdout
        cls.stderr = sys.stderr
        cls.devnull = io.open(os.devnull, 'wb')
        sys.stdout = sys.stderr = cls.devnull

    @classmethod
    def tearDownClass(cls):
        cls.devnull.close()
        sys.stdout = cls.stdout
        sys.stderr = cls.stderr

    def setUp(self):
        self.env = Environment(path=mkdtemp(), create=True)
        self.admin = TracAdmin(self.env.path)
        self.admin.env_set('', self.env)

    def tearDown(self):
        self.env.shutdown()
        rmtree(self.env.path)

    def test_deploy(self):
        target = os.path.join(self.env.path, 'www')
        shebang = ('#!' + sys.executable).encode('utf-8')
        rv, output = self.execute('deploy %s' % target)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)
        self.assertTrue(os.path.exists(os.path.join(target, 'cgi-bin')))
        self.assertTrue(os.path.exists(os.path.join(target, 'htdocs')))
        self.assertTrue(os.path.exists(os.path.join(target, 'htdocs',
                                                    'common')))
        self.assertTrue(os.path.exists(os.path.join(target, 'htdocs',
                                                    'site')))
        self.assertTrue(os.path.isfile(os.path.join(
            target, 'htdocs', 'common', 'js', 'trac.js')))
        self.assertTrue(os.path.isfile(os.path.join(
            target, 'htdocs', 'common', 'css', 'trac.css')))
        for ext in ('cgi', 'fcgi', 'wsgi'):
            content = read_file(os.path.join(target, 'cgi-bin',
                                             'trac.%s' % ext), 'rb')
            self.assertIn(shebang, content)
            self.assertEqual(0, content.index(shebang))
            self.assertIn(repr(self.env.path).encode('ascii'), content)

    def test_deploy_to_invalid_target_raises_error(self):
        """Running deploy with target directory equal to or below the source
        directory raises AdminCommandError.
        """
        rv, output = self.execute('deploy %s' % self.env.htdocs_dir)

        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)
Пример #7
0
 def setUp(self):
     self.env = EnvironmentStub(default_data=True, enable=('trac.*',),
                                disable=('trac.tests.*',))
     self.admin = TracAdmin()
     self.admin.env_set('', self.env)
     provider = DbRepositoryProvider(self.env)
     provider.add_repository('mock', '/', 'mock_type')
Пример #8
0
class TracAdminDeployTestCase(TracAdminTestCaseBase):
    """Tests for the trac-admin deploy command."""
    def setUp(self):
        self.env = Environment(path=mkdtemp(), create=True)
        self.admin = TracAdmin(self.env.path)
        self.admin.env_set('', self.env)

    def tearDown(self):
        self.env.shutdown()  # really closes the db connections
        shutil.rmtree(self.env.path)

    def test_deploy(self):
        """Deploy into valid target directory."""
        target = os.path.join(self.env.path, 'www')
        htdocs_dir = os.path.join(target, 'htdocs')

        rv, output = self.execute('deploy %s' % target)

        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)
        self.assertTrue(os.path.exists(os.path.join(target, 'cgi-bin')))
        self.assertTrue(os.path.exists(htdocs_dir))
        self.assertTrue(os.path.exists(os.path.join(htdocs_dir, 'common')))
        self.assertTrue(os.path.exists(os.path.join(htdocs_dir, 'site')))

    def test_deploy_to_invalid_target_raises_error(self):
        """Running deploy with target directory equal to or below the source 
        directory raises AdminCommandError.
        """
        rv, output = self.execute('deploy %s' % self.env.htdocs_dir)

        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)
Пример #9
0
def trac_admin(env_path, *commands):
    admin = TracAdmin(env_path)
    logging.disable(logging.CRITICAL)
    save_stdout, sys.stdout = sys.stdout, StringIO()
    try:
        for command in commands:
            admin.onecmd(command)
    finally:
        sys.stdout = save_stdout
        logging.disable(logging.NOTSET)
Пример #10
0
def trac_admin(env_path, *commands):
    admin = TracAdmin(env_path)
    logging.disable(logging.CRITICAL)
    save_stdout, sys.stdout = sys.stdout, StringIO()
    try:
        for command in commands:
            admin.onecmd(command)
    finally:
        sys.stdout = save_stdout
        logging.disable(logging.NOTSET)
Пример #11
0
def main(trac_env, examples_dir='.'):
    loaded = False
    admin = TracAdmin()
    admin.env_set(trac_env)
    for file in os.listdir(examples_dir):
        if 'GraphvizExamples' in file:
            admin._do_wiki_import(os.path.join(examples_dir, file), 
                                  file.replace('%2F', '/'))
            loaded = True

    if not loaded:
        print 'The %(examples_dir)s does not contain any GrapgvizExamples files.' % locals()
Пример #12
0
class TracAdminTestCase(TracAdminTestCaseBase):
    def setUp(self):
        self.env = EnvironmentStub(default_data=True,
                                   enable=('trac.*', ),
                                   disable=('trac.tests.*', ))
        self.admin = TracAdmin()
        self.admin.env_set('', self.env)
        provider = DbRepositoryProvider(self.env)
        provider.add_repository('mock', '/', 'mock_type')

    def tearDown(self):
        self.env = None

    def test_changeset_add_no_repository_revision(self):
        rv, output = self.execute('changeset added')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_changeset_add_no_revision(self):
        rv, output = self.execute('changeset added mock')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_changeset_modify_no_repository_revision(self):
        rv, output = self.execute('changeset modified')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_changeset_modify_no_revision(self):
        rv, output = self.execute('changeset modified mock')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_changeset_add_invalid_repository(self):
        rv, output = self.execute('changeset added invalid 123')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_changeset_modify_invalid_repository(self):
        rv, output = self.execute('changeset modified invalid 123')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_changeset_add_invalid_changeset(self):
        rv, output = self.execute('changeset added mock invalid')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_changeset_modify_invalid_changeset(self):
        rv, output = self.execute('changeset modified mock invalid')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)
Пример #13
0
 def setUp(self):
     self.env = EnvironmentStub(default_data=True, enable=('trac.*',),
                                disable=('trac.tests.*',))
     self.env.path = mkdtemp()
     self.admin = TracAdmin()
     self.admin.env_set('', self.env)
     self.datetime = datetime(2001, 1, 1, 1, 1, 1, 0, utc)
     with self.env.db_transaction as db:
         db("INSERT INTO wiki (name,version) VALUES ('WikiStart',1)")
         db("INSERT INTO wiki (name,version) VALUES ('SomePage',1)")
         db("INSERT INTO ticket (id) VALUES (42)")
         db("INSERT INTO ticket (id) VALUES (43)")
         db("INSERT INTO attachment VALUES (%s,%s,%s,%s,%s,%s,%s)",
            ('ticket', '43', 'foo.txt', 8, to_utimestamp(self.datetime),
             'A comment', 'joe'))
Пример #14
0
def build_trac_env(request):
    """Create a Trac Environment in a tmp dir
    """
    path = tempfile.mkdtemp()
    ta = TracAdmin()
    ta.env_set(path)
    ta.do_initenv(u'ExampleTracEnv sqlite:db/trac.db')
    env = Environment(path)

    def fin():
        rmtree(path)
    request.addfinalizer(fin)

    if request.cls:
        request.cls.env = env
    return env
Пример #15
0
 def execute(self, cmd, strip_trailing_space=True, input=None):
     if hasattr(self, 'admin'):
         admin = self.admin
     else:
         admin = TracAdmin()
     return execute_cmd(admin, cmd,
                        strip_trailing_space=strip_trailing_space,
                        input=input)
Пример #16
0
class TracAdminComponentTestCase(TracAdminTestCaseBase):
    def setUp(self):
        self.env = EnvironmentStub(default_data=True,
                                   enable=('trac.*', ),
                                   disable=('trac.tests.*', ))
        self.admin = TracAdmin()
        self.admin.env_set('', self.env)
        self._orig = {
            'ComponentMeta._components': ComponentMeta._components,
            'ComponentMeta._registry': ComponentMeta._registry,
            'ConfigSection.registry': ConfigSection.registry,
            'Option.registry': Option.registry,
        }
        ComponentMeta._components = list(ComponentMeta._components)
        ComponentMeta._registry = {
            interface: list(classes)
            for interface, classes in ComponentMeta._registry.iteritems()
        }
        ConfigSection.registry = {}
        Option.registry = {}

        class CompA(Component):
            from trac.config import Option
            opt1 = Option('compa', 'opt1', 1)
            opt2 = Option('compa', 'opt2', 2)

    def tearDown(self):
        self.env = None
        self.admin = None
        ComponentMeta._components = self._orig['ComponentMeta._components']
        ComponentMeta._registry = self._orig['ComponentMeta._registry']
        ConfigSection.registry = self._orig['ConfigSection.registry']
        Option.registry = self._orig['Option.registry']

    def test_config_component_enable(self):
        self.env.config.save()
        initial_file = copy.deepcopy(self.env.config.parser)

        rv, output = self.execute('config set components '
                                  'trac.admin.tests.console.* enabled')

        self.assertEqual(0, rv, output)
        self.assertFalse(initial_file.has_section('compa'))
        self.assertIn('compa', self.env.config)
        self.assertIn('1', self.env.config.parser.get('compa', 'opt1'))
        self.assertIn('2', self.env.config.parser.get('compa', 'opt2'))
Пример #17
0
	def initDestinations(self):
		"""Runs the trac initialization script for each destination trac and applies and config values"""
		for dest_name in self.dests.keys():
			inheritFile = [x[2] for x in self.dests[dest_name]['configs'] if x[0] == 'inherit' and x[1] == 'file']
			if inheritFile:
				inheritOpt = '--inherit=/var/trac/common/conf/trac.ini'
			else:
				inheritOpt = ''
			initline = "'%s' '%s' '%s' '%s' %s" % (dest_name, \
				self.dests[dest_name]['db'], self.dests[dest_name]['repo_type'], self.dests[dest_name]['repo_dir'], inheritOpt)
			destination = os.path.abspath(self.dests[dest_name]['path'])
			destAdmin = TracAdmin(destination)
			destAdmin.do_initenv(initline)
			self.dests[dest_name]['trac'] = Trac(destination)
			if self.dests[dest_name]['repo_type'] == 'hg':
				self.dests[dest_name]['trac']._env.config.set('components', 'tracext.hg.*', 'enabled')
			if self.dests[dest_name].has_key('configs'): 
				for confSection, confName, confValue in self.dests[dest_name]['configs']:
					self.dests[dest_name]['trac']._env.config.set(confSection, confName, confValue)
			self.dests[dest_name]['trac']._env.config.save()
Пример #18
0
    def __init__(self, env):
        TracAdmin.__init__(self, env)
        self.env = open_environment(env)

        # new style, as of trac:changeset:7677
        # see trac:#7770
        # for now, support both use-cases
        if not hasattr(self, 'get_component_list'):
            # TODO: create these functions
            from trac.ticket.admin import ComponentAdminPanel
            from trac.ticket.admin import MilestoneAdminPanel
            from trac.wiki.admin import WikiAdmin

            self.ComponentAdminPanel = ComponentAdminPanel(self.env)
            self.get_component_list = self.ComponentAdminPanel.get_component_list
            self._do_component_remove = self.ComponentAdminPanel._do_remove
            self.MilestoneAdminPanel = MilestoneAdminPanel(self.env)
            self.get_milestone_list = self.MilestoneAdminPanel.get_milestone_list
            self._do_milestone_remove = self.MilestoneAdminPanel._do_remove
            self.WikiAdmin = WikiAdmin(self.env)
            self._do_wiki_load = self.WikiAdmin.load_pages
Пример #19
0
    def __init__(self, env):
        TracAdmin.__init__(self, env)
        self.env = open_environment(env)

        # new style, as of trac:changeset:7677
        # see trac:#7770
        # for now, support both use-cases
        if not hasattr(self, 'get_component_list'):
            # TODO: create these functions
            from trac.ticket.admin import ComponentAdminPanel
            from trac.ticket.admin import MilestoneAdminPanel
            from trac.wiki.admin import WikiAdmin

            self.ComponentAdminPanel = ComponentAdminPanel(self.env)
            self.get_component_list = self.ComponentAdminPanel.get_component_list
            self._do_component_remove = self.ComponentAdminPanel._do_remove
            self.MilestoneAdminPanel = MilestoneAdminPanel(self.env)
            self.get_milestone_list = self.MilestoneAdminPanel.get_milestone_list
            self._do_milestone_remove = self.MilestoneAdminPanel._do_remove
            self.WikiAdmin = WikiAdmin(self.env)
            self._do_wiki_load = self.WikiAdmin.load_pages
Пример #20
0
    def globally_get_command_help(self, *args):
        sys_home_project_name = self.config.get('multiproject', 'sys_home_project_name')
        for env_name, in self.projects_iterator(['env_name'], batch_size=1):
            if env_name == sys_home_project_name:
                continue
            env = None

            try:
                env_path = safe_path(self.config.get('multiproject', 'sys_projects_root'),
                    env_name)
                env = open_environment(env_path, True)
            except TracError as e:
                printout(_('ERROR: Opening environment %(env_name)s failed', env_name=env_name))
                continue

            try:
                command_manager = AdminCommandManager(env)
                helps = command_manager.get_command_help(list(args))
                if not args:
                    TracAdmin.print_doc(helps, short=True)
                elif len(helps) == 1:
                    TracAdmin.print_doc(helps, long=True)
                else:
                    TracAdmin.print_doc(helps)

            except AdminCommandError as e:
                printout(_('ERROR: Getting command help in environment %(env_name)s failed: ',
                    env_name=env_name) + e)
            break
Пример #21
0
    def setUp(self):
        self.env = EnvironmentStub(default_data=True,
                                   enable=('trac.*', ),
                                   disable=('trac.tests.*', ))
        self.admin = TracAdmin()
        self.admin.env_set('', self.env)
        self._orig = {
            'ComponentMeta._components': ComponentMeta._components,
            'ComponentMeta._registry': ComponentMeta._registry,
            'ConfigSection.registry': ConfigSection.registry,
            'Option.registry': Option.registry,
        }
        ComponentMeta._components = list(ComponentMeta._components)
        ComponentMeta._registry = {
            interface: list(classes)
            for interface, classes in ComponentMeta._registry.iteritems()
        }
        ConfigSection.registry = {}
        Option.registry = {}

        class CompA(Component):
            from trac.config import Option
            opt1 = Option('compa', 'opt1', 1)
            opt2 = Option('compa', 'opt2', 2)
Пример #22
0
def main(trac_env, examples_dir='.'):
    loaded = False
    admin = TracAdmin()
    admin.env_set(trac_env)
    for file in os.listdir(examples_dir):
        if 'MetapostExamples' in file:
            admin._do_wiki_import(os.path.join(examples_dir, file),
                                  file.replace('%2F', '/'))
            loaded = True

    if not loaded:
        print 'The %(examples_dir)s does not contain any MetapostExamples files.' % locals(
        )
Пример #23
0
    def install(self):
        options = self.options

        # create our run scripts
        entry_points = [('trac-admin', 'trac.admin.console', 'run'),
                        ('tracd', 'trac.web.standalone', 'main')]

        zc.buildout.easy_install.scripts(
                entry_points, pkg_resources.working_set,
                options['executable'], options['bin-directory']
                )
    
        # create the trac instance
        location = options['location']
        project_name = options.get('project-name', 'trac-project')
        project_name = '"%s"' % project_name
        project_url = options.get('project-url', 'http://example.com')
        if not options.has_key('db-type') or options['db-type'] == 'sqlite':
            db = 'sqlite:%s' % os.path.join('db', 'trac.db')
        elif options['db-type'] == 'postgres':
            db_options = {  'user': options['db-username'], 
                            'pass': options['db-password'], 
                            'host': options.get('db-host', 'localhost'), 
                            'db': options.get('db-name', 'trac'), 
                            'port': options.get('db-port', '5432')
                         }
            db = 'postgres://%(user)s:%(pass)s@%(host)s:%(port)s/%(db)s' % db_options

        repos_type = options.get('repos-type', "")
        repos_path = options.get('repos-path', "")

        if not os.path.exists(location):
            os.makedirs(location)

        print "Creating Trac Instance in: " + location

        
        
        # install the eggs that we need
        self.egg.install()
        
        if self.metamode:
            # put the config file somewhere so we can inherit it
            self._write_ini(os.path.join(location, 'base_trac.ini'), db, {'location': location})
            
            instances = self._get_instances()
            for instance, data in instances.iteritems():
                # we need a new location for each project
                meta_location = os.path.join(self.buildout['buildout']['directory'], 'var', self.name, instance)
                trac = TracAdmin(meta_location)
                if not trac.env_check():
                    repos_type = data.get('repository_type', '')
                    repos_path = data.get('repository-dir', '')
                    
                    # get the database dsn
                    if not data.has_key('db-type') or data['db-type'] == 'sqlite':
                        db = 'sqlite:%s' % os.path.join('db', 'trac.db')
                    elif data['db-type'] == 'postgres':
                        db_options = {  'user': data.get('db-username', 'trac'), 
                                'pass': data.get('db-password', 'trac'), 
                                'host': data.get('db-host', 'localhost'), 
                                'port': data.get('db-port', '5432'),
                                'db': instance
                             }
                        db = 'postgres://%(user)s:%(pass)s@%(host)s:%(port)s/%(db)s' % db_options
                    
                    env = trac.do_initenv('%s %s %s %s' % (instance, db, repos_type, repos_path))
                    data.update({'project_name': instance,
                                 'repository-dir': data.get('repository-dir', '')})
                    
                    data['database_dsn'] = db
                    
                    self.write_custom_config(os.path.join(meta_location, 'conf', 'trac.ini'), 
                                             os.path.join(location, 'base_trac.ini'),
                                             meta = True,
                                             meta_vars = data)
                    
                    # add any repositories
                    repo_provider = DbRepositoryProvider(trac.env)
                    repo_provider.add_repository('default', repos_path, repos_type)
            
        else:
            trac = TracAdmin(location)
            
            if not trac.env_check():
                trac.do_initenv('%s %s %s %s' % (project_name, db, repos_type, repos_path))
        
            self._write_ini(os.path.join(location, 'conf', 'base_trac.ini'), db, self.options)
            self.write_custom_config(os.path.join(location, 'conf', 'trac.ini'), os.path.join(location, 'conf', 'base_trac.ini'))

        if options.has_key('wsgi') and options['wsgi'].lower() == 'true':
            self.install_wsgi(options['location'])
            
        if options.has_key('testrunner') and options['testrunner'].lower() == 'true':
            self.install_testrunner()

        self.install_htpasswd()

        # buildout expects a tuple of paths, but we don't have any to add
        # just return an empty one for now.
        return tuple()
Пример #24
0
    def setup(self, **kwargs):
        """Do the setup. A kwargs dictionary may be passed to override base
        options, potentially allowing for multiple environment creation."""
        
        if has_babel:
            import babel
            try:
                locale = get_negotiated_locale([LANG]) 
                locale = locale or babel.Locale.default()
            except babel.UnknownLocaleError:
                pass
            translation.activate(locale)
        
        options = dict(self.options)
        options.update(kwargs)
        if psycopg2 is None and options.get('dbtype') == 'postgres':
            print "psycopg2 needs to be installed to initialise a postgresql db"
            return False

        environments_path = options['envsdir']
        if not os.path.exists(environments_path):
            os.makedirs(environments_path)

        new_env =  os.path.join(environments_path, options['project'])
        tracini = os.path.abspath(os.path.join(new_env, 'conf', 'trac.ini'))
        baseini = os.path.abspath(os.path.join(new_env, 'conf', 'base.ini'))
        options['inherit'] = baseini

        options['db'] = self._generate_db_str(options)
        if 'repo_type' not in options or options['repo_type'] is None:
            options['repo_type'] = ''
        if 'repo_path' not in options or options['repo_path'] is None:
            options['repo_path'] = ''
        if (len(options['repo_type']) > 0) ^ (len(options['repo_path']) > 0):
            print "Error: Specifying a repository requires both the "\
                  "repository-type and the repository-path options."
            return False

        digestfile = os.path.abspath(os.path.join(new_env,
                                                  options['digestfile']))
        realm =  options['realm']
        adminuser = options['adminuser']
        adminpass = options['adminpass']

        # create base options:
        accounts_config = dict(ACCOUNTS_CONFIG)
        accounts_config['account-manager']['htdigest_file'] = digestfile
        accounts_config['account-manager']['htdigest_realm'] = realm

        trac = TracAdmin(os.path.abspath(new_env))
        if not trac.env_check():
            try:
                trac.do_initenv('%(project)s %(db)s '
                                '%(repo_type)s %(repo_path)s '
                                '--inherit=%(inherit)s '
                                '--nowiki'
                                % options)
            except SystemExit:
                print ("Error: Unable to initialise the database"
                       "Traceback for error is above")
                return False
        else:
            print ("Warning: Environment already exists at %s." % new_env)
            self.writeconfig(tracini, [{'inherit': {'file': baseini},},])

        self.writeconfig(baseini, [BASE_CONFIG, accounts_config])

        if os.path.exists(digestfile):
            backupfile(digestfile)
        htdigest_create(digestfile, adminuser, realm, adminpass)

        print "Adding TRAC_ADMIN permissions to the admin user %s" % adminuser
        trac.onecmd('permission add %s TRAC_ADMIN' % adminuser)

        # get fresh TracAdmin instance (original does not know about base.ini)
        bloodhound = TracAdmin(os.path.abspath(new_env))

        # final upgrade
        print "Running upgrades"
        bloodhound.onecmd('upgrade')
        pages = []
        pages.append(pkg_resources.resource_filename('bhdashboard',
                                                     'default-pages'))
        bloodhound.onecmd('wiki load %s' % " ".join(pages))

        print "Running wiki upgrades"
        bloodhound.onecmd('wiki upgrade')
        
        print "Running wiki bh upgrades"
        bloodhound.onecmd('wiki bh-upgrade')

        print """
You can now start Bloodhound by running:

  tracd --port=8000 %s

And point your browser at http://localhost:8000/%s
""" % (os.path.abspath(new_env), options['project'])
        return True
Пример #25
0
class TracadminTestCase(TracAdminTestCaseBase):
    """
    Tests the output of trac-admin and is meant to be used with
    .../trac/tests.py.
    """
    def setUp(self):
        self.env = EnvironmentStub(default_data=True,
                                   enable=('trac.*', ),
                                   disable=('trac.tests.*', ))
        self.admin = TracAdmin()
        self.admin.env_set('', self.env)

    def tearDown(self):
        self.env = None

    @property
    def datetime_format_hint(self):
        return get_datetime_format_hint(get_console_locale(self.env))

    def test_python_with_optimizations_returns_error(self):
        """Error is returned when a command is executed in interpreter
        with optimizations enabled.
        """
        with Popen((sys.executable, '-O', '-m', 'trac.admin.console', 'help'),
                   stdin=PIPE,
                   stdout=PIPE,
                   stderr=PIPE,
                   close_fds=close_fds) as proc:
            stdout, stderr = proc.communicate(input='')
        self.assertEqual(2, proc.returncode)
        self.assertEqual("Python with optimizations is not supported.",
                         stderr.strip())

    # Help test

    def test_help_ok(self):
        """
        Tests the 'help' command in trac-admin.  Since the 'help' command
        has no command arguments, it is hard to call it incorrectly.  As
        a result, there is only this one test.
        """
        rv, output = self.execute('help')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(
            output, {
                'version': self.env.trac_version,
                'date_format_hint': get_date_format_hint()
            })
        self.assertTrue(all(len(line) < 80 for line in output.split('\n')),
                        "Lines should be less than 80 characters in length.")

    # Locale test

    def _test_get_console_locale_with_babel(self):
        from babel.core import Locale, UnknownLocaleError
        locales = get_available_locales()
        en_US = Locale.parse('en_US')
        de = Locale.parse('de')

        def unset_locale_envs():
            for name in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'):
                if name in os.environ:
                    del os.environ[name]

        if 'de' in locales:
            unset_locale_envs()
            self.assertIsNone(get_console_locale(None, None))
            self.assertEqual(de, get_console_locale(None, 'de_DE.UTF8'))
            self.env.config.set('trac', 'default_language', 'de')
            self.assertEqual(de, get_console_locale(self.env, None))
            self.assertEqual(de, get_console_locale(self.env, 'C'))
            self.env.config.set('trac', 'default_language', 'en_US')
            self.assertEqual(en_US, get_console_locale(self.env, None))
            self.assertEqual(en_US, get_console_locale(self.env, 'C'))
            self.assertEqual(de, get_console_locale(self.env, 'de_DE.UTF8'))

            self.env.config.set('trac', 'default_language', 'de')
            os.environ['LANG'] = 'POSIX'  # unavailable locale in Trac
            self.assertIsNone(get_console_locale())
            self.assertEqual(de, get_console_locale(self.env))
            os.environ['LANG'] = '****'  # invalid locale
            self.assertIsNone(get_console_locale())
            self.assertEqual(de, get_console_locale(self.env))
            os.environ['LANG'] = 'en_US.utf-8'
            self.assertEqual(en_US, get_console_locale())
            self.assertEqual(en_US, get_console_locale(self.env))
            os.environ['LC_MESSAGES'] = 'de_DE.utf-8'
            self.assertEqual(de, get_console_locale())
            self.assertEqual(de, get_console_locale(self.env))
            os.environ['LC_ALL'] = 'en_US.utf-8'
            self.assertEqual(en_US, get_console_locale())
            self.assertEqual(en_US, get_console_locale(self.env))
            os.environ['LANGUAGE'] = 'de_DE:en_US:en'
            self.assertEqual(de, get_console_locale())
            self.assertEqual(de, get_console_locale(self.env))

        if not locales:  # compiled catalog is missing
            unset_locale_envs()
            self.assertIsNone(get_console_locale(None, 'de_DE.UTF8'))
            self.env.config.set('trac', 'default_language', 'de')
            self.assertIsNone(get_console_locale(self.env, None))
            self.assertIsNone(get_console_locale(self.env, 'C'))
            self.assertIsNone(get_console_locale(self.env, 'de_DE.UTF8'))
            os.environ['LANG'] = 'en_US.utf-8'
            os.environ['LC_MESSAGES'] = 'de_DE.utf-8'
            os.environ['LC_ALL'] = 'en_US.utf-8'
            os.environ['LANGUAGE'] = 'de_DE:en_US'
            self.assertEqual(en_US, get_console_locale())
            self.assertEqual(en_US, get_console_locale(self.env))

    def _test_get_console_locale_without_babel(self):
        os.environ['LANG'] = 'en_US.utf-8'
        os.environ['LC_MESSAGES'] = 'de_DE.utf-8'
        os.environ['LC_ALL'] = 'en_US.utf-8'
        os.environ['LANGUAGE'] = 'de_DE:en_US'
        self.assertIsNone(get_console_locale(None, 'en_US.UTF8'))
        self.env.config.set('trac', 'default_language', '')
        self.assertIsNone(get_console_locale(self.env, 'en_US.UTF8'))
        self.assertIsNone(get_console_locale(self.env))
        self.env.config.set('trac', 'default_language', 'en_US')
        self.assertIsNone(get_console_locale(self.env, 'en_US.UTF8'))
        self.assertIsNone(get_console_locale(self.env))

    if has_babel:
        test_get_console_locale = _test_get_console_locale_with_babel
    else:
        test_get_console_locale = _test_get_console_locale_without_babel

    # Attachment tests

    def test_attachment_list_empty(self):
        """
        Tests the 'attachment list' command in trac-admin, on a wiki page that
        doesn't have any attachments.
        """
        # FIXME: Additional tests should be written for the other 'attachment'
        #        commands. This requires being able to control the current
        #        time, which in turn would require centralizing the time
        #        provider, for example in the environment object.
        rv, output = self.execute('attachment list wiki:WikiStart')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_attachment_add_nonexistent_resource(self):
        """Tests the 'attachment add' command in trac-admin, on a non-existent
        resource."""
        rv, output = self.execute('attachment add wiki:NonExistentPage "%s"' %
                                  __file__)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    # Config tests

    def test_config_get(self):
        """
        Tests the 'config get' command in trac-admin.  This particular
        test gets the project name from the config.
        """
        self.env.config.set('project', 'name', 'Test project')
        rv, output = self.execute('config get project name')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_config_set(self):
        """
        Tests the 'config set' command in trac-admin.  This particular
        test sets the project name using an option value containing a space.
        """
        rv, output = self.execute('config set project name "Test project"')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)
        self.assertEqual('Test project',
                         self.env.config.get('project', 'name'))

    def test_config_remove(self):
        """
        Tests the 'config remove' command in trac-admin.  This particular
        test removes the project name from the config, therefore reverting
        the option to the default value.
        """
        self.env.config.set('project', 'name', 'Test project')
        rv, output = self.execute('config remove project name')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)
        self.assertEqual('My Project', self.env.config.get('project', 'name'))

    # Permission tests

    def test_permission_list_ok(self):
        """Tests the 'permission list' command in trac-admin."""
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_list_includes_undefined_actions(self):
        """Undefined actions are included in the User Action table,
        but not in the Available Actions list.
        """
        self.env.disable_component(trac.search.web_ui.SearchModule)
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_add_one_action_ok(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test passes valid arguments to add one permission and checks for
        success.
        """
        self.execute('permission add test_user WIKI_VIEW')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_add_multiple_actions_ok(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test passes valid arguments to add multiple permissions and checks for
        success.
        """
        self.execute('permission add test_user LOG_VIEW FILE_VIEW')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_add_already_exists(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test passes a permission that already exists and checks for the
        message. Other permissions passed are added.
        """
        rv, output = self.execute('permission add anonymous WIKI_CREATE '
                                  'WIKI_VIEW WIKI_MODIFY')
        self.assertEqual(0, rv, output)
        rv, output2 = self.execute('permission list')
        self.assertEqual(0, rv, output2)
        self.assertExpectedResult(output + output2)

    def test_permission_add_subject_already_in_group(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test passes a group that the subject is already a member of and
        checks for the message. Other permissions passed are added.
        """
        rv, output1 = self.execute('permission add user1 group2')
        self.assertEqual(0, rv, output1)
        rv, output2 = self.execute('permission add user1 group1 group2 '
                                   'group3')
        self.assertEqual(0, rv, output2)
        rv, output3 = self.execute('permission list')
        self.assertEqual(0, rv, output3)
        self.assertExpectedResult(output2 + output3)

    def test_permission_add_differs_from_action_by_casing(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test passes a permission that differs from an action by casing and
        checks for the message. None of the permissions in the list are
        granted.
        """
        rv, output = self.execute('permission add joe WIKI_CREATE '
                                  'Trac_Admin WIKI_MODIFY')
        self.assertEqual(2, rv, output)
        rv, output2 = self.execute('permission list')
        self.assertEqual(0, rv, output2)
        self.assertExpectedResult(output + output2)

    def test_permission_add_unknown_action(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test tries granting NOT_A_PERM to a user. NOT_A_PERM does not exist
        in the system. None of the permissions in the list are granted.
        """
        rv, output = self.execute('permission add joe WIKI_CREATE '
                                  'NOT_A_PERM WIKI_MODIFY')
        self.assertEqual(2, rv, output)
        rv, output2 = self.execute('permission list')
        self.assertEqual(0, rv, output2)
        self.assertExpectedResult(output + output2)

    def test_permission_remove_one_action_ok(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test passes valid arguments to remove one permission and checks for
        success.
        """
        self.execute('permission remove anonymous TICKET_MODIFY')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_multiple_actions_ok(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test passes valid arguments to remove multiple permission and checks
        for success.
        """
        self.execute('permission remove anonymous WIKI_CREATE WIKI_MODIFY')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_all_actions_for_user(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test removes all permissions for anonymous.
        """
        self.execute('permission remove anonymous *')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_action_for_all_users(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test removes the TICKET_CREATE permission from all users.
        """
        self.execute('permission add anonymous TICKET_CREATE')
        self.execute('permission remove * TICKET_CREATE')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_unknown_user(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test tries removing a permission from an unknown user.
        """
        rv, output = self.execute('permission remove joe TICKET_VIEW')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_action_not_granted(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test tries removing TICKET_CREATE from user anonymous, who doesn't
        have that permission.
        """
        rv, output = self.execute('permission remove anonymous TICKET_CREATE')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_action_granted_through_meta_permission(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test tries removing WIKI_VIEW from a user. WIKI_VIEW has been granted
        through user anonymous."""
        self.execute('permission add joe TICKET_VIEW')
        rv, output = self.execute('permission remove joe WIKI_VIEW')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_unknown_action(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test tries removing NOT_A_PERM from a user. NOT_A_PERM does not exist
        in the system."""
        rv, output = self.execute('permission remove joe NOT_A_PERM')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_unknown_action_granted(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test tries removing NOT_A_PERM from a user. NOT_A_PERM does not exist
        in the system, but the user possesses the permission."""
        self.env.db_transaction(
            """
            INSERT INTO permission VALUES (%s, %s)
        """, ('joe', 'NOT_A_PERM'))
        rv, output = self.execute('permission remove joe NOT_A_PERM')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_export_ok(self):
        """
        Tests the 'permission export' command in trac-admin.  This particular
        test exports the default permissions to stdout.
        """
        rv, output = self.execute('permission export')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_import_ok(self):
        """
        Tests the 'permission import' command in trac-admin.  This particular
        test exports additional permissions, removes them and imports them back.
        """
        user = u'test_user\u0250'
        self.execute('permission add ' + user + ' WIKI_VIEW')
        self.execute('permission add ' + user + ' TICKET_VIEW')
        rv, output = self.execute('permission export')
        self.execute('permission remove ' + user + ' *')
        rv, output = self.execute('permission import', input=output)
        self.assertEqual(0, rv, output)
        self.assertEqual('', output)
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_backslash_use_ok(self):
        if self.admin.interactive:
            self.execute('version add \\')
        else:
            self.execute(r"version add '\'")
        rv, output = self.execute('version list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_no_sessions(self):
        rv, output = self.execute('session list authenticated')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_authenticated(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session list authenticated')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_anonymous(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session list anonymous')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_all(self):
        _prep_session_table(self.env)
        if self.admin.interactive:
            rv, output = self.execute("session list *")
        else:
            rv, output = self.execute("session list '*'")
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_authenticated_sid(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session list name00')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_anonymous_sid(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session list name10:0')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_missing_sid(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session list thisdoesntexist')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_add_missing_sid(self):
        rv, output = self.execute('session add')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_add_duplicate_sid(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session add name00')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_add_sid_all(self):
        rv, output = self.execute('session add john John [email protected]')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list john')
        self.assertExpectedResult(
            output, {'today': format_date(None, console_date_format)})

    def test_session_add_sid(self):
        rv, output = self.execute('session add john')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list john')
        self.assertExpectedResult(
            output, {'today': format_date(None, console_date_format)})

    def test_session_add_sid_name(self):
        rv, output = self.execute('session add john John')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list john')
        self.assertExpectedResult(
            output, {'today': format_date(None, console_date_format)})

    def test_session_set_attr_name(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session set name name00 JOHN')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list name00')
        self.assertExpectedResult(output)

    def test_session_set_attr_email(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session set email name00 [email protected]')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list name00')
        self.assertExpectedResult(output)

    def test_session_set_attr_default_handler(self):
        _prep_session_table(self.env)
        rv, output = \
            self.execute('session set default_handler name00 SearchModule')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list name00')
        self.assertExpectedResult(output)

    def test_session_set_attr_default_handler_invalid(self):
        _prep_session_table(self.env)
        rv, output = \
            self.execute('session set default_handler name00 InvalidModule')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_set_attr_missing_attr(self):
        rv, output = self.execute('session set')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_set_attr_missing_value(self):
        rv, output = self.execute('session set name john')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_set_attr_missing_sid(self):
        rv, output = self.execute('session set name')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_set_attr_nonexistent_sid(self):
        rv, output = self.execute('session set name john foo')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_delete_sid(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session delete name00')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list nam00')
        self.assertExpectedResult(output)

    def test_session_delete_missing_params(self):
        rv, output = self.execute('session delete')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_delete_anonymous(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session delete anonymous')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list *')
        self.assertExpectedResult(output)

    def test_session_delete_multiple_sids(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session delete name00 name01 name02 '
                                  'name03')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list *')
        self.assertExpectedResult(output)

    def test_session_purge_age(self):
        _prep_session_table(self.env, spread_visits=True)
        rv, output = self.execute('session purge 20100112')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list *')
        self.assertExpectedResult(output)

    def test_session_purge_invalid_date(self):
        rv, output = self.execute('session purge <purge>')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(
            output, {
                'hint': self.datetime_format_hint,
                'isohint': get_datetime_format_hint('iso8601')
            })

    def test_help_session_purge(self):
        doc = self.get_command_help('session', 'purge')
        self.assertIn(u'"YYYY-MM-DDThh:mm:ss±hh:mm"', doc)
Пример #26
0
    def install(self):
        """Installer"""

        # Utility function to interpreted boolean option value
        getBool = lambda s: s.strip().lower() in ['true', 'yes']

        # Utility function to parse a multi-line/multi-value parameter
        def cleanMultiParams(v):
            params = [s.split('|') for s in [l.strip() for l in v.split('\n')] if len(s) > 0]
            cleaned_params = []
            for line in params:
                cleaned_params.append([row.strip() for row in line])
            return cleaned_params

        # Utility function to transform any string to an ID
        getId = lambda s: ''.join([c for c in s if c.isalnum()]).lower()

        options = self.options

        #################
        # eggs from the config options
        ################

        requirements, ws = self.egg.working_set()
        
        for dist in pkg_resources.working_set:
            ws.add(dist)

        # Add command line scripts trac-admin and tracd into bin
        entry_points = [('trac-admin', 'trac.admin.console', 'run'),
                        ('tracd', 'trac.web.standalone', 'main')]
        zc.buildout.easy_install.scripts(
                entry_points, ws,
                options['executable'], options['bin-directory']
                )


        ####################
        # Init Trac instance
        ####################

        # Generate the trac instance, if required
        location = options['location']
        project_name = options.get('project-name', 'My project')
        project_url = options.get('project-url', 'http://example.com')
        db = 'sqlite:%s' % os.path.join('db', 'trac.db')
        if not os.path.exists(location):
            os.mkdir(location)
        trac = TracAdmin(location)
        if not trac.env_check():
            trac.do_initenv('"%s" %s' % (project_name, db))
        env = trac.env

        # Remove Trac default example data
        clean_up = getBool(options.get('remove-examples', 'True'))
        if clean_up:
            # Remove default milestones
            for mil in Milestone.select(env):
                if mil.name in ['milestone1', 'milestone2', 'milestone3', 'milestone4']:
                    mil.delete()
            # Remove default components
            for comp in Component.select(env):
                if comp.name in ['component1', 'component2']:
                    comp.delete()

        # Add custom milestones
        for mil_data in cleanMultiParams(options.get('milestones', '')):
            mil_name = mil_data[0]
            try:
                mil = Milestone(env, name=mil_name)
            except ResourceNotFound:
                mil = Milestone(env)
                mil.name = mil_name
                mil.insert()

        # Add custom components
        for comp_data in cleanMultiParams(options.get('components', '')):
            comp_name = comp_data[0]
            try:
                comp = Component(env, name=comp_name)
            except ResourceNotFound:
                comp = Component(env)
                comp.name = comp_name
                if len(comp_data) == 2 and comp_data[1] not in [None, '']:
                    comp.owner = comp_data[1]
                comp.insert()


        #######################
        # Generate the trac.ini
        #######################

        # Read the trac.ini config file
        trac_ini = os.path.join(location, 'conf', 'trac.ini')
        parser = ConfigParser.ConfigParser()
        parser.read([trac_ini])

        # Clean-up trac.ini: add missing stuff
        if 'components' not in parser.sections():
            parser.add_section('components')

        # Force upgrade of informations used during initialization
        parser.set('project', 'name', project_name)

        # Set all repositories
        repos = cleanMultiParams(options.get('repos', None))
        repo_names = [getId(r[0]) for r in repos]
        repo_types = {}.fromkeys([r[1].lower() for r in repos]).keys()
        if 'repositories' not in parser.sections():
            parser.add_section('repositories')
        for repo in repos:
            repo_name = getId(repo[0])
            repo_type = repo[1]
            repo_dir  = repo[2]
            repo_url  = repo[3]
            parser.set('repositories', '%s.type' % repo_name, repo_type)
            parser.set('repositories', '%s.dir'  % repo_name, repo_dir)
            if repo_url not in ['', None]:
                parser.set('repositories', '%s.url'  % repo_name, repo_url)

        # Set default repository
        default_repo = getId(options.get('default-repo', None))
        if default_repo and default_repo in repo_names:
            parser.set('repositories', '.alias', default_repo)
            parser.set('repositories', '.hidden', 'true')

        # Set repository sync method
        sync_method = options.get('repos-sync', 'request').strip().lower()
        svn_repos = [getId(r[0]) for r in repos if r[1] == 'svn']
        if sync_method == 'request':
          parser.set('trac', 'repository_sync_per_request', ', '.join(svn_repos))
        # TODO
        # elif sync_method == 'hook':
        #   do stuff...

        # Set project description
        project_descr = options.get('project-description', None)
        if project_descr:
            parser.set('project', 'descr', project_descr)
            parser.set('header_logo', 'alt', project_descr)

        # Setup logo
        header_logo = options.get('header-logo', '')
        header_logo = os.path.realpath(header_logo)
        if os.path.exists(header_logo):
            shutil.copyfile(header_logo, os.path.join(location, 'htdocs', 'logo'))
        parser.set('header_logo', 'src', 'site/logo')
        parser.set('header_logo', 'link', project_url)

        # Set footer message
        parser.set('project', 'footer', options.get('footer-message', 'This Trac instance was generated by <a href="http://pypi.python.org/pypi/pbp.recipe.trac">pbp.recipe.trac</a>.'))

        # SMTP parameters
        for name in ('always-bcc', 'always-cc', 'default-domain', 'enabled',
                     'from', 'from-name', 'password', 'port', 'replyto',
                     'server', 'subject-prefix', 'user'):
            param_name = "smtp-%s" % name
            default_value = None
            if param_name == "smtp-from-name":
                default_value = project_name
            value = options.get(param_name, default_value)
            if value is not None:
                parser.set('notification', param_name.replace('-', '_'), value)


        ###############
        # Plugins setup
        ###############

        # If one repository use Mercurial, hook its plugin
        if 'hg' in repo_types:
            parser.set('components', 'tracext.hg.*', 'enabled')

        # Configure the NavAdd plugin
        menu_items = cleanMultiParams(options.get('additional-menu-items', ''))
        item_list = []
        for item in menu_items:
            item_title = item[0]
            item_url = item[1]
            item_id = getId(item_title)
            item_list.append((item_id, item_title, item_url))
        if item_list > 0:
            parser.set('components', 'navadd.*', 'enabled')
            if 'navadd' not in parser.sections():
                parser.add_section('navadd')
            parser.set('navadd', 'add_items', ','.join([i[0] for i in item_list]))
            for (uid, title, url) in item_list:
                parser.set('navadd', '%s.target' % uid, 'mainnav')
                parser.set('navadd', '%s.title'  % uid, title)
                parser.set('navadd', '%s.url'    % uid, url)

        # Enable and setup time tracking
        time_tracking = options.get('time-tracking-plugin', 'disabled').strip().lower() == 'enabled'
        if time_tracking:
            parser.set('components', 'timingandestimationplugin.*', 'enabled')

        # Enable and setup the stat plugin
        stats = options.get('stats-plugin', 'disabled').strip().lower() == 'enabled'
        if stats:
            parser.set('components', 'tracstats.*', 'enabled')


        #######################
        # Final upgrades & sync
        #######################

        # Apply custom parameters defined by the user
        custom_params = cleanMultiParams(options.get('trac-ini-additional', ''))
        for param in custom_params:
            if len(param) == 3:
                section = param[0]
                if section not in parser.sections():
                    parser.add_section(section)
                parser.set(section, param[1], param[2])

        # Write the final trac.ini
        parser.write(open(trac_ini, 'w'))

        # Reload the environment
        env.shutdown()
        trac = TracAdmin(location)
        env = trac.env

        # Set custom permissions
        perm_sys = PermissionSystem(env)
        for cperm in cleanMultiParams(options.get('permissions', '')):
            if len(cperm) == 2:
                user = cperm[0]
                current_user_perms = perm_sys.get_user_permissions(user)
                perm_list = [p.upper() for p in cperm[1].split(' ') if len(p)]
                for perm in perm_list:
                    if perm not in current_user_perms:
                        perm_sys.grant_permission(user, perm)

        # Upgrade Trac instance to keep it fresh
        needs_upgrade = env.needs_upgrade()
        force_upgrade = getBool(options.get('force-instance-upgrade', 'False'))
        if needs_upgrade or force_upgrade:
            env.upgrade(backup=True)

        # Force repository resync
        repo_resync = getBool(options.get('force-repos-resync', 'False'))
        if repo_resync:
            rm = RepositoryManager(env)
            repositories = rm.get_real_repositories()
            for repos in sorted(repositories, key=lambda r: r.reponame):
                repos.sync(clean=True)

        # Upgrade default wiki pages embedded in Trac instance
        wiki_upgrade = getBool(options.get('wiki-doc-upgrade', 'False'))
        if wiki_upgrade:
            # Got the command below from trac/admin/console.py
            pages_dir = pkg_resources.resource_filename('trac.wiki',
                                                        'default-pages')
            WikiAdmin(env).load_pages( pages_dir
                                     , ignore=['WikiStart', 'checkwiki.py']
                                     , create_only=['InterMapTxt']
                                     )

        # Return files that were created by the recipe. The buildout
        # will remove all returned files upon reinstall.
        return tuple()
Пример #27
0
class TracAdminTestCase(TracAdminTestCaseBase):

    request_handlers = []

    @classmethod
    def setUpClass(cls):
        class DefaultHandlerStub(Component):
            implements(IRequestHandler)

            def match_request(self, req):
                pass

            def process_request(req):
                pass

        cls.request_handlers = [DefaultHandlerStub]

    @classmethod
    def tearDownClass(cls):
        for component in cls.request_handlers:
            ComponentMeta.deregister(component)

    def setUp(self):
        self.env = EnvironmentStub()
        self.admin = TracAdmin()
        self.admin.env_set('', self.env)

    def tearDown(self):
        self.env = None

    @property
    def datetime_format_hint(self):
        return get_datetime_format_hint(get_console_locale(self.env))

    def test_session_list_no_sessions(self):
        rv, output = self.execute('session list authenticated')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_authenticated(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session list authenticated')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_anonymous(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session list anonymous')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_all(self):
        _prep_session_table(self.env)
        if self.admin.interactive:
            rv, output = self.execute("session list *")
        else:
            rv, output = self.execute("session list '*'")
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_authenticated_sid(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session list name00')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_anonymous_sid(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session list name10:0')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_missing_sid(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session list thisdoesntexist')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_add_missing_sid(self):
        rv, output = self.execute('session add')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_add_duplicate_sid(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session add name00')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_add_sid_all(self):
        rv, output = self.execute('session add john John [email protected]')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list john')
        self.assertExpectedResult(
            output, {'today': format_date(None, console_date_format)})

    def test_session_add_sid(self):
        rv, output = self.execute('session add john')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list john')
        self.assertExpectedResult(
            output, {'today': format_date(None, console_date_format)})

    def test_session_add_sid_name(self):
        rv, output = self.execute('session add john John')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list john')
        self.assertExpectedResult(
            output, {'today': format_date(None, console_date_format)})

    def test_session_set_attr_name(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session set name name00 JOHN')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list name00')
        self.assertExpectedResult(output)

    def test_session_set_attr_email(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session set email name00 [email protected]')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list name00')
        self.assertExpectedResult(output)

    def test_session_set_attr_default_handler(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session set default_handler name00 '
                                  'DefaultHandlerStub')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list name00')
        self.assertExpectedResult(output)

    def test_session_set_attr_default_handler_invalid(self):
        _prep_session_table(self.env)
        rv, output = \
            self.execute('session set default_handler name00 InvalidModule')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_set_attr_missing_attr(self):
        rv, output = self.execute('session set')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_set_attr_missing_value(self):
        rv, output = self.execute('session set name john')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_set_attr_missing_sid(self):
        rv, output = self.execute('session set name')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_set_attr_nonexistent_sid(self):
        rv, output = self.execute('session set name john foo')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_delete_sid(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session delete name00')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list nam00')
        self.assertExpectedResult(output)

    def test_session_delete_missing_params(self):
        rv, output = self.execute('session delete')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_delete_anonymous(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session delete anonymous')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list *')
        self.assertExpectedResult(output)

    def test_session_delete_multiple_sids(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session delete name00 name01 name02 '
                                  'name03')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list *')
        self.assertExpectedResult(output)

    def test_session_purge_age(self):
        _prep_session_table(self.env, spread_visits=True)
        rv, output = self.execute('session purge 20100112')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list *')
        self.assertExpectedResult(output)

    def test_session_purge_invalid_date(self):
        rv, output = self.execute('session purge <purge>')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(
            output, {
                'hint': self.datetime_format_hint,
                'isohint': get_datetime_format_hint('iso8601')
            })

    def test_help_session_purge(self):
        doc = self.get_command_help('session', 'purge')
        self.assertIn(u'"YYYY-MM-DDThh:mm:ss±hh:mm"', doc)
Пример #28
0
from trac.admin.console import TracAdmin
from trac.util.text import printout, printerr
import sys

if __name__ == "__main__":
    if len(sys.argv) != 2:
        printerr(
            "Usage: %s <path>\nSupply the path where to create the test environment"
            % (sys.argv[0]))
        sys.exit(-1)

    admin = TracAdmin(sys.argv[1])
    admin.onecmd(
        "initenv \"trac-subcomponents test environment\" sqlite:db/trac.db")
    admin.onecmd("permission add anonymous TRAC_ADMIN")

    components = ("NoSubcomponents", "SuperComponent",
                  "SuperComponent/SubComponent1",
                  "SuperComponent/SubComponent2",
                  "ForcedSubcomponent/ForcedSub1/ForcedSubSub", "LeafTest",
                  "LeafTest/HasEmptyLeaf", "LeafTest/HasEmptyLeaf/Sub1",
                  "LeafTest/HasEmptyLeaf/Sub2", "LeafTest/NoEmptyLeaf/Sub1",
                  "LeafTest/NoEmptyLeaf/Sub2",
                  "SixSubLevels/s1/s2/s3/s4/s5/s6")
    for component in components:
        admin.onecmd("component add %s nobody" % (component, ))

    printout("""
The test environment is set up at %s. You can run tracd to test this
environment. Please make sure that the trac-subcomponents plugin is loaded,
either by putting the plugin in %s/plugins, by making it available in general
Пример #29
0
    def install(self):
        options = self.options

        # create our run scripts
        entry_points = [('trac-admin', 'trac.admin.console', 'run'),
                        ('tracd', 'trac.web.standalone', 'main')]

        zc.buildout.easy_install.scripts(
                entry_points, pkg_resources.working_set,
                options['executable'], options['bin-directory']
                )
    
        # create the trac instance
        location = options['location']
        project_name = options.get('project-name', 'trac-project')
        project_name = '"%s"' % project_name
        project_url = options.get('project-url', 'http://example.com')
        if not options.has_key('db-type') or options['db-type'] == 'sqlite':
            db = 'sqlite:%s' % os.path.join('db', 'trac.db')
        elif options['db-type'] == 'postgres':
            db_options = {  'user': options['db-username'], 
                            'pass': options['db-password'], 
                            'host': options.get('db-host', 'localhost'), 
                            'port': options.get('db-port', '5432')
                         }
            db = 'postgres://%(user)s:%(pass)s@%(host)s:%(port)s' % db_options

        repos_type = options.get('repos-type', "")
        repos_path = options.get('repos-path', "")

        if not os.path.exists(location):
            os.makedirs(location)

        trac = TracAdmin(location)
    
        if not trac.env_check():
            trac.do_initenv('%s %s %s %s' % (project_name, db, repos_type, repos_path))
        
        # install the eggs that we need
        self.egg.install()
        
        # move the generated config out of the way so we can inherit it
        trac_ini = os.path.join(location, 'conf', 'trac.ini')

        # parse the options to pass into our template
        template_options = self.options['config-template-options']
        template_options = json.loads(template_options)
        
        template_options['site_url'] = self.options.get('site-url', "")
        template_options['log_directory'] = self.options.get('log-directory', "")
        template_options['trac_location'] = self.options['location']
   
        template_options['database_dsn'] = db

        self.write_config(trac_ini, self.options['base-config'], template_options)

        if options.has_key('wsgi') and options['wsgi'].lower() == 'true':
            self.install_wsgi()
            
        if options.has_key('testrunner') and options['testrunner'].lower() == 'true':
            self.install_testrunner()

        self.install_htpasswd()

        # buildout expects a tuple of paths, but we don't have any to add
        # just return an empty one for now.
        return tuple()
Пример #30
0
    def setup(self, **kwargs):
        """Do the setup. A kwargs dictionary may be passed to override base
        options, potentially allowing for multiple environment creation."""

        if has_babel:
            import babel
            try:
                locale = get_negotiated_locale([LANG])
                locale = locale or babel.Locale.default()
            except babel.UnknownLocaleError:
                pass
            translation.activate(locale)

        options = dict(self.options)
        options.update(kwargs)
        if psycopg2 is None and options.get('dbtype') == 'postgres':
            print "psycopg2 needs to be installed to initialise a postgresql db"
            return False
        elif mysqldb is None and options.get('dbtype') == 'mysql':
            print "MySQLdb needs to be installed to initialise a mysql db"
            return False

        environments_path = options['envsdir']
        if not os.path.exists(environments_path):
            os.makedirs(environments_path)

        new_env =  os.path.join(environments_path, options['project'])
        tracini = os.path.abspath(os.path.join(new_env, 'conf', 'trac.ini'))
        baseini = os.path.abspath(os.path.join(new_env, 'conf', 'base.ini'))
        options['inherit'] = '"' + baseini + '"'

        options['db'] = self._generate_db_str(options)
        if 'repo_type' not in options or options['repo_type'] is None:
            options['repo_type'] = ''
        if 'repo_path' not in options or options['repo_path'] is None:
            options['repo_path'] = ''
        if (len(options['repo_type']) > 0) ^ (len(options['repo_path']) > 0):
            print "Error: Specifying a repository requires both the "\
                  "repository-type and the repository-path options."
            return False

        custom_prefix = 'default_product_prefix'
        if custom_prefix in options and options[custom_prefix]:
            default_product_prefix = options[custom_prefix]
        else:
            default_product_prefix = '@'

        digestfile = os.path.abspath(os.path.join(new_env,
                                                  options['digestfile']))
        realm =  options['realm']
        adminuser = options['adminuser']
        adminpass = options['adminpass']

        # create base options:
        accounts_config = dict(ACCOUNTS_CONFIG)
        accounts_config['account-manager']['htdigest_file'] = digestfile
        accounts_config['account-manager']['htdigest_realm'] = realm

        trac = TracAdmin(os.path.abspath(new_env))
        if not trac.env_check():
            try:
                rv = trac.do_initenv('%(project)s %(db)s '
                                     '%(repo_type)s %(repo_path)s '
                                     '--inherit=%(inherit)s '
                                     '--nowiki'
                                     % options)
                if rv == 2:
                    raise SystemExit
            except SystemExit:
                print ("Error: Unable to initialise the environment.")
                return False
        else:
            print ("Warning: Environment already exists at %s." % new_env)
            self.writeconfig(tracini, [{'inherit': {'file': baseini},},])

        base_config = dict(BASE_CONFIG)
        base_config['trac']['environment_factory'] = \
            'multiproduct.hooks.MultiProductEnvironmentFactory'
        base_config['trac']['request_factory'] = \
            'multiproduct.hooks.ProductRequestFactory'
        if default_product_prefix != '@':
            base_config['multiproduct'] = dict(
                default_product_prefix=default_product_prefix
            )

        self.writeconfig(baseini, [base_config, accounts_config])

        if os.path.exists(digestfile):
            backupfile(digestfile)
        htdigest_create(digestfile, adminuser, realm, adminpass)

        print "Adding TRAC_ADMIN permissions to the admin user %s" % adminuser
        trac.onecmd('permission add %s TRAC_ADMIN' % adminuser)

        # get fresh TracAdmin instance (original does not know about base.ini)
        bloodhound = TracAdmin(os.path.abspath(new_env))

        # final upgrade
        print "Running upgrades"
        bloodhound.onecmd('upgrade')
        pages = []
        pages.append(pkg_resources.resource_filename('bhdashboard',
                                                 'default-pages'))
        pages.append(pkg_resources.resource_filename('bhsearch',
                                                 'default-pages'))
        bloodhound.onecmd('wiki load %s' % " ".join(pages))

        print "Running wiki upgrades"
        bloodhound.onecmd('wiki upgrade')

        if self.apply_bhwiki_upgrades:
            print "Running wiki Bloodhound upgrades"
            bloodhound.onecmd('wiki bh-upgrade')
        else:
            print "Skipping Bloodhound wiki upgrades"

        print "Loading default product wiki"
        bloodhound.onecmd('product admin %s wiki load %s' %
                          (default_product_prefix,
                           " ".join(pages)))

        print "Running default product wiki upgrades"
        bloodhound.onecmd('product admin %s wiki upgrade' %
                          default_product_prefix)

        if self.apply_bhwiki_upgrades:
            print "Running default product Bloodhound wiki upgrades"
            bloodhound.onecmd('product admin %s wiki bh-upgrade' %
                              default_product_prefix)
        else:
            print "Skipping default product Bloodhound wiki upgrades"

        print """
You can now start Bloodhound by running:

  tracd --port=8000 %s

And point your browser at http://localhost:8000/%s
""" % (os.path.abspath(new_env), options['project'])
        return True
Пример #31
0
from trac.admin.console import TracAdmin
from trac.util.text import printout, printerr
import sys

if __name__ == "__main__":
    if len(sys.argv) != 2:
        printerr("Usage: %s <path>\nSupply the path where to create the test environment"
                 % (sys.argv[0]))
        sys.exit(-1)

    admin = TracAdmin(sys.argv[1])
    admin.onecmd("initenv \"trac-subcomponents test environment\" sqlite:db/trac.db")
    admin.onecmd("permission add anonymous TRAC_ADMIN")
    
    components = ("NoSubcomponents", 
        "SuperComponent", "SuperComponent/SubComponent1", 
        "SuperComponent/SubComponent2", 
        "ForcedSubcomponent/ForcedSub1/ForcedSubSub",
        "LeafTest", "LeafTest/HasEmptyLeaf", "LeafTest/HasEmptyLeaf/Sub1",
        "LeafTest/HasEmptyLeaf/Sub2", "LeafTest/NoEmptyLeaf/Sub1",
        "LeafTest/NoEmptyLeaf/Sub2", "SixSubLevels/s1/s2/s3/s4/s5/s6")
    for component in components:
        admin.onecmd("component add %s nobody" % (component,))
    
    printout("""
The test environment is set up at %s. You can run tracd to test this
environment. Please make sure that the trac-subcomponents plugin is loaded,
either by putting the plugin in %s/plugins, by making it available in general
or by manipulation PYTHON_PATH. """ % (sys.argv[1], sys.argv[1]))

    sys.exit(0)
Пример #32
0
 def setUp(self):
     self.env = Environment(path=mkdtemp(), create=True)
     self.admin = TracAdmin(self.env.path)
     self.admin.env_set('', self.env)
Пример #33
0
 def setUp(self):
     self.parent_dir = mkdtemp()
     self.env_path = os.path.join(self.parent_dir, 'trac')
     self.admin = TracAdmin(self.env_path)
Пример #34
0
class TracAdminTestCase(TracAdminTestCaseBase):
    def setUp(self):
        self.env = EnvironmentStub(default_data=True,
                                   enable=('trac.*', ),
                                   disable=('trac.tests.*', ))
        self.admin = TracAdmin()
        self.admin.env_set('', self.env)
        self.tempdir = mkdtemp()

    def tearDown(self):
        self.env = None

    def _insert_page(self, name=None):
        page = WikiPage(self.env)
        if name is None:
            name = random_unique_camel()
        page.name = name
        page.text = random_paragraph()
        page.save('user1', 'Page created.')
        return name

    def _insert_pages(self, int_or_names):
        if isinstance(int_or_names, int):
            names = sorted(random_unique_camel()
                           for _ in range(0, int_or_names))
        else:
            names = sorted(int_or_names)
        return [self._insert_page(n) for n in names]

    def _change_page(self, name):
        page = WikiPage(self.env, name)
        page.text = random_paragraph()
        page.save('user2', 'Page changed.')

    def _file_content(self, dir_or_path, name=None):
        path = dir_or_path if name is None else os.path.join(dir_or_path, name)
        with open(path, 'r') as f:
            return f.read()

    def _write_file(self, path, content=None):
        if content is None:
            content = random_paragraph()
        with open(path, 'w') as f:
            f.write(content)
        return content

    def execute(self, cmd, *args):
        argstr = ' '.join('"%s"' % a for a in args)
        return super(TracAdminTestCase, self) \
               .execute('wiki {} {}'.format(cmd, argstr))

    def assertFileContentMatchesPage(self, names):
        for n in names:
            self.assertEqual(
                WikiPage(self.env, n).text,
                self._file_content(self.tempdir, n))

    def test_wiki_dump(self):
        names = self._insert_pages(2)
        rv, output = self.execute('dump', self.tempdir, *names)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(
            output, {
                'name1': names[0],
                'name2': names[1],
                'path1': os.path.join(self.tempdir, names[0]),
                'path2': os.path.join(self.tempdir, names[1]),
            })
        self.assertFileContentMatchesPage(names)

    def test_wiki_dump_all(self):
        names = self._insert_pages(2)
        rv, output = self.execute('dump', self.tempdir)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(
            output, {
                'name1': names[0],
                'name2': names[1],
                'path1': os.path.join(self.tempdir, names[0]),
                'path2': os.path.join(self.tempdir, names[1]),
            })
        self.assertEquals(names, sorted(os.listdir(self.tempdir)))
        self.assertFileContentMatchesPage(names)

    def test_wiki_dump_all_create_dst_dir(self):
        names = self._insert_pages(2)
        dstdir = os.path.join(self.tempdir, 'subdir')
        rv, output = self.execute('dump', dstdir)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(
            output, {
                'name1': names[0],
                'name2': names[1],
                'path1': os.path.join(dstdir, names[0]),
                'path2': os.path.join(dstdir, names[1]),
            })
        self.assertEquals(names, sorted(os.listdir(dstdir)))

    def test_wiki_dump_all_glob(self):
        names = self._insert_pages(['PageOne', 'PageTwo', 'ThreePage'])
        rv, output = self.execute('dump', self.tempdir, 'Page*')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(
            output, {
                'name1': names[0],
                'name2': names[1],
                'path1': os.path.join(self.tempdir, names[0]),
                'path2': os.path.join(self.tempdir, names[1]),
            })
        self.assertEquals(names[0:2], sorted(os.listdir(self.tempdir)))
        self.assertFileContentMatchesPage(names[0:2])

    def test_wiki_dump_all_dst_is_file(self):
        tempdir = os.path.join(self.tempdir, 'dst')
        create_file(tempdir)
        rv, output = self.execute('dump', tempdir)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output, {
            'dstdir': tempdir,
        })

    def test_wiki_export(self):
        name = self._insert_page()
        export_path = os.path.join(self.tempdir, name)
        rv, output = self.execute('export', name, export_path)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'name': name,
            'path': export_path,
        })
        self.assertFileContentMatchesPage([name])

    def test_wiki_export_page_not_found(self):
        name = random_unique_camel()
        export_path = os.path.join(self.tempdir, name)
        rv, output = self.execute('export', name, export_path)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output, {
            'name': name,
        })

    def test_wiki_export_file_exists(self):
        name = self._insert_page()
        export_path = os.path.join(self.tempdir, name)
        create_file(export_path)
        rv, output = self.execute('export', name, export_path)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output, {
            'export_path': export_path,
        })

    def test_wiki_export_print_to_stdout(self):
        name = self._insert_page()
        rv, output = self.execute('export', name)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'content': WikiPage(self.env, name).text,
        })

    def test_wiki_import(self):
        name = random_unique_camel()
        import_path = os.path.join(self.tempdir, name)
        content = self._write_file(import_path)
        rv, output = self.execute('import', name, import_path)
        page = WikiPage(self.env, name)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'name': name,
            'path': import_path,
        })
        self.assertIn(('INFO', '%s imported from %s' % (name, import_path)),
                      self.env.log_messages)
        self.assertEqual(content, page.text)

    def test_wiki_import_page_exists(self):
        name = self._insert_page()
        import_path = os.path.join(self.tempdir, name)
        self._write_file(import_path)
        rv, output = self.execute('import', name, import_path)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'name': name,
            'path': import_path,
        })
        self.assertEqual(2, WikiPage(self.env, name).version)

    def test_wiki_import_page_up_to_date(self):
        name = self._insert_page()
        import_path = os.path.join(self.tempdir, name)
        self._write_file(import_path, WikiPage(self.env, name).text)
        rv, output = self.execute('import', name, import_path)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'tempdir': self.tempdir,
            'name': name,
        })
        self.assertIn(('INFO', '%s is already up to date' % name),
                      self.env.log_messages)
        self.assertEqual(1, WikiPage(self.env, name).version)

    def test_wiki_import_page_name_invalid(self):
        name = 'PageOne/../PageTwo'
        import_path = os.path.join(self.tempdir, 'PageOne')
        self._write_file(import_path)
        rv, output = self.execute('import', name, import_path)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output, {
            'tempdir': self.tempdir,
            'name': name
        })
        self.assertFalse(WikiPage(self.env, name).exists)

    def test_wiki_import_file_not_found(self):
        name = random_unique_camel()
        import_path = os.path.join(self.tempdir, name)
        rv, output = self.execute('import', name, import_path)
        page = WikiPage(self.env, name)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output, {
            'import_path': import_path,
        })

    def test_wiki_list(self):
        name1 = self._insert_page('PageOne')
        name2 = self._insert_page('PageTwo')
        self._change_page(name2)
        rv, output = self.execute('list')
        self.assertEqual(0, rv, output)
        fmt = lambda m: format_datetime(m, console_datetime_format)
        self.assertExpectedResult(
            output, {
                'page1_modified': fmt(WikiPage(self.env, name1).time),
                'page2_modified': fmt(WikiPage(self.env, name2).time),
            })

    def test_wiki_list_no_pages(self):
        rv, output = self.execute('list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_wiki_load(self):
        name1 = 'PageOne'
        name2 = 'PageTwo'
        path1 = os.path.join(self.tempdir, name1)
        path2 = os.path.join(self.tempdir, name2)
        content1 = random_paragraph()
        content2 = random_paragraph()
        with open(path1, 'w') as f:
            f.write(content1)
        with open(path2, 'w') as f:
            f.write(content2)
        rv, output = self.execute('load', path1, path2)
        page1 = WikiPage(self.env, name1)
        page2 = WikiPage(self.env, name2)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'name1': name1,
            'name2': name2,
            'path1': path1,
            'path2': path2,
        })
        self.assertIn(('INFO', '%s imported from %s' % (name1, path1)),
                      self.env.log_messages)
        self.assertIn(('INFO', '%s imported from %s' % (name2, path2)),
                      self.env.log_messages)
        self.assertEqual(content1, page1.text)
        self.assertEqual(content2, page2.text)
        self.assertEqual(1, page1.version)
        self.assertEqual(1, page2.version)

    def test_wiki_load_page_exists(self):
        name = self._insert_page()
        path = os.path.join(self.tempdir, name)
        content = self._write_file(path)
        rv, output = self.execute('load', path)
        page = WikiPage(self.env, name)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'name': name,
            'path': path,
        })
        self.assertEqual(content, page.text)
        self.assertEqual(2, page.version)

    def test_wiki_load_pages_from_dir(self):
        name1 = 'PageOne'
        name2 = 'PageTwo'
        path1 = os.path.join(self.tempdir, name1)
        path2 = os.path.join(self.tempdir, name2)
        content1 = random_paragraph()
        content2 = random_paragraph()
        with open(path1, 'w') as f:
            f.write(content1)
        with open(path2, 'w') as f:
            f.write(content2)
        os.mkdir(os.path.join(self.tempdir, 'subdir'))
        rv, output = self.execute('load', self.tempdir)
        page1 = WikiPage(self.env, name1)
        page2 = WikiPage(self.env, name2)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'name1': name1,
            'name2': name2,
            'path1': path1,
            'path2': path2,
        })
        self.assertEqual(content1, page1.text)
        self.assertEqual(content2, page2.text)
        self.assertEqual(1, page1.version)
        self.assertEqual(1, page2.version)

    def test_wiki_load_from_invalid_path(self):
        name = random_unique_camel()
        path = os.path.join(self.tempdir, name)
        rv, output = self.execute('load', path)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output, {
            'path': path,
        })
        self.assertFalse(WikiPage(self.env, name).exists)

    def test_wiki_remove(self):
        name = self._insert_page()

        rv, output = self.execute('remove', name)
        self.assertIn(('INFO', 'Deleted page %s' % name),
                      self.env.log_messages)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'name': name,
        })
        self.assertFalse(WikiPage(self.env, name).exists)

    def test_wiki_remove_glob(self):
        names = self._insert_pages(['PageOne', 'PageTwo', 'PageThree'])

        rv, output = self.execute('remove', 'Page*')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)
        for n in names:
            self.assertIn(('INFO', 'Deleted page %s' % n),
                          self.env.log_messages)
            self.assertFalse(WikiPage(self.env, n).exists)

    def test_wiki_rename(self):
        name1 = self._insert_page()
        name2 = random_unique_camel()

        rv, output = self.execute('rename', name1, name2)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'name1': name1,
            'name2': name2,
        })
        self.assertIn(('INFO', 'Renamed page %s to %s' % (name1, name2)),
                      self.env.log_messages)
        self.assertFalse(WikiPage(self.env, name1).exists)
        self.assertTrue(WikiPage(self.env, name2).exists)

    def test_wiki_rename_name_unchanged(self):
        name = self._insert_page()

        rv, output = self.execute('rename', name, name)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)
        self.assertTrue(WikiPage(self.env, name).exists)

    def test_wiki_rename_name_not_specified(self):
        name = self._insert_page()

        rv, output = self.execute('rename', name)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_wiki_rename_new_name_invalid(self):
        name = self._insert_page()
        new_name = 'PageOne/../PageTwo'

        rv, output = self.execute('rename', name, new_name)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output, {
            'name': new_name,
        })
        self.assertTrue(WikiPage(self.env, name).exists)

    def test_wiki_rename_new_page_exists(self):
        names = self._insert_pages(['PageOne', 'PageTwo'])
        page1_content = WikiPage(self.env, names[0]).text
        page2_content = WikiPage(self.env, names[1]).text

        rv, output = self.execute('rename', *names)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)
        page1 = WikiPage(self.env, names[0])
        page2 = WikiPage(self.env, names[1])
        self.assertTrue(page1.exists)
        self.assertTrue(page2.exists)
        self.assertEqual(page1_content, page1.text)
        self.assertEqual(page2_content, page2.text)

    def test_wiki_replace(self):
        name1 = random_unique_camel()
        name2 = random_unique_camel()
        path1 = os.path.join(self.tempdir, name1)
        path2 = os.path.join(self.tempdir, name2)
        content1 = random_paragraph()
        content2 = random_paragraph()
        self._insert_page(name1)
        self._insert_page(name2)
        with open(path1, 'w') as f:
            f.write(content1)
        with open(path2, 'w') as f:
            f.write(content2)
        rv, output = self.execute('replace', path1, path2)
        page1 = WikiPage(self.env, name1)
        page2 = WikiPage(self.env, name2)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'name1': name1,
            'name2': name2,
            'path1': path1,
            'path2': path2,
        })
        self.assertIn(('INFO', '%s imported from %s' % (name1, path1)),
                      self.env.log_messages)
        self.assertIn(('INFO', '%s imported from %s' % (name2, path2)),
                      self.env.log_messages)
        self.assertEqual(content1, page1.text)
        self.assertEqual(content2, page2.text)
        self.assertEqual(1, page1.version)
        self.assertEqual(1, page2.version)

    def test_wiki_replace_new_page(self):
        name = random_unique_camel()
        path = os.path.join(self.tempdir, name)
        content = self._write_file(path)
        rv, output = self.execute('replace', path)
        page = WikiPage(self.env, name)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'name': name,
            'path': path,
        })
        self.assertEqual(1, page.version)
        self.assertEqual(content, page.text)

    def test_wiki_replace_pages_from_dir(self):
        names = self._insert_pages(2)
        path1 = os.path.join(self.tempdir, names[0])
        path2 = os.path.join(self.tempdir, names[1])
        content1 = random_paragraph()
        content2 = random_paragraph()
        with open(path1, 'w') as f:
            f.write(content1)
        with open(path2, 'w') as f:
            f.write(content2)
        os.mkdir(os.path.join(self.tempdir, 'subdir'))
        rv, output = self.execute('replace', self.tempdir)
        page1 = WikiPage(self.env, names[0])
        page2 = WikiPage(self.env, names[1])
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'name1': names[0],
            'name2': names[1],
            'path1': path1,
            'path2': path2,
        })
        self.assertEqual(content1, page1.text)
        self.assertEqual(content2, page2.text)
        self.assertEqual(1, page1.version)
        self.assertEqual(1, page2.version)

    def test_wiki_replace_from_invalid_path(self):
        name = random_unique_camel()
        path = os.path.join(self.tempdir, name)
        rv, output = self.execute('replace', path)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output, {
            'path': path,
        })
        self.assertFalse(WikiPage(self.env, name).exists)

    def test_wiki_upgrade(self):
        rv, output = self.execute('upgrade')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_wiki_upgrade_up_to_date(self):
        self.execute('upgrade')
        rv, output = self.execute('upgrade')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)
Пример #35
0
 def setUp(self):
     self.env = EnvironmentStub()
     self.admin = TracAdmin()
     self.admin.env_set('', self.env)
Пример #36
0
class TracAdminTestCase(TracAdminTestCaseBase):
    def setUp(self):
        self.env = EnvironmentStub(default_data=True)
        self.admin = TracAdmin()
        self.admin.env_set('', self.env)

    def tearDown(self):
        self.env.reset_db()
        self.env = None

    def test_permission_list_ok(self):
        """Tests the 'permission list' command in trac-admin."""
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_list_includes_undefined_actions(self):
        """Undefined actions are included in the User Action table,
        but not in the Available Actions list.
        """
        self.env.disable_component(trac.search.web_ui.SearchModule)
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_add_one_action_ok(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test passes valid arguments to add one permission and checks for
        success.
        """
        self.execute('permission add test_user WIKI_VIEW')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_add_multiple_actions_ok(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test passes valid arguments to add multiple permissions and checks for
        success.
        """
        self.execute('permission add test_user LOG_VIEW FILE_VIEW')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_add_already_exists(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test passes a permission that already exists and checks for the
        message. Other permissions passed are added.
        """
        rv, output = self.execute('permission add anonymous WIKI_CREATE '
                                  'WIKI_VIEW WIKI_MODIFY')
        self.assertEqual(0, rv, output)
        rv, output2 = self.execute('permission list')
        self.assertEqual(0, rv, output2)
        self.assertExpectedResult(output + output2)

    def test_permission_add_subject_already_in_group(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test passes a group that the subject is already a member of and
        checks for the message. Other permissions passed are added.
        """
        rv, output1 = self.execute('permission add user1 group2')
        self.assertEqual(0, rv, output1)
        rv, output2 = self.execute('permission add user1 group1 group2 '
                                   'group3')
        self.assertEqual(0, rv, output2)
        rv, output3 = self.execute('permission list')
        self.assertEqual(0, rv, output3)
        self.assertExpectedResult(output2 + output3)

    def test_permission_add_differs_from_action_by_casing(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test passes a permission that differs from an action by casing and
        checks for the message. None of the permissions in the list are
        granted.
        """
        rv, output = self.execute('permission add joe WIKI_CREATE '
                                  'Trac_Admin WIKI_MODIFY')
        self.assertEqual(2, rv, output)
        rv, output2 = self.execute('permission list')
        self.assertEqual(0, rv, output2)
        self.assertExpectedResult(output + output2)

    def test_permission_add_unknown_action(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test tries granting NOT_A_PERM to a user. NOT_A_PERM does not exist
        in the system. None of the permissions in the list are granted.
        """
        rv, output = self.execute('permission add joe WIKI_CREATE '
                                  'NOT_A_PERM WIKI_MODIFY')
        self.assertEqual(2, rv, output)
        rv, output2 = self.execute('permission list')
        self.assertEqual(0, rv, output2)
        self.assertExpectedResult(output + output2)

    def test_permission_remove_one_action_ok(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test passes valid arguments to remove one permission and checks for
        success.
        """
        self.execute('permission remove anonymous TICKET_MODIFY')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_multiple_actions_ok(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test passes valid arguments to remove multiple permission and checks
        for success.
        """
        self.execute('permission remove anonymous WIKI_CREATE WIKI_MODIFY')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_all_actions_for_user(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test removes all permissions for anonymous.
        """
        self.execute('permission remove anonymous *')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_action_for_all_users(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test removes the TICKET_CREATE permission from all users.
        """
        self.execute('permission add anonymous TICKET_CREATE')
        self.execute('permission remove * TICKET_CREATE')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_unknown_user(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test tries removing a permission from an unknown user.
        """
        rv, output = self.execute('permission remove joe TICKET_VIEW')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_action_not_granted(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test tries removing TICKET_CREATE from user anonymous, who doesn't
        have that permission.
        """
        rv, output = self.execute('permission remove anonymous TICKET_CREATE')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_action_granted_through_meta_permission(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test tries removing WIKI_VIEW from a user. WIKI_VIEW has been granted
        through user anonymous."""
        self.execute('permission add joe TICKET_VIEW')
        rv, output = self.execute('permission remove joe WIKI_VIEW')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_unknown_action(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test tries removing NOT_A_PERM from a user. NOT_A_PERM does not exist
        in the system."""
        rv, output = self.execute('permission remove joe NOT_A_PERM')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_unknown_action_granted(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test tries removing NOT_A_PERM from a user. NOT_A_PERM does not exist
        in the system, but the user possesses the permission."""
        self.env.db_transaction(
            """
            INSERT INTO permission VALUES (%s, %s)
        """, ('joe', 'NOT_A_PERM'))
        rv, output = self.execute('permission remove joe NOT_A_PERM')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_export_ok(self):
        """
        Tests the 'permission export' command in trac-admin.  This particular
        test exports the default permissions to stdout.
        """
        rv, output = self.execute('permission export')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_import_ok(self):
        """
        Tests the 'permission import' command in trac-admin.  This particular
        test exports additional permissions, removes them and imports them back.
        """
        user = u'test_user\u0250'
        self.execute('permission add ' + user + ' WIKI_VIEW')
        self.execute('permission add ' + user + ' TICKET_VIEW')
        rv, output = self.execute('permission export')
        self.execute('permission remove ' + user + ' *')
        rv, output = self.execute('permission import', input=output)
        self.assertEqual(0, rv, output)
        self.assertEqual('', output)
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)
Пример #37
0
class TracAdminTestCase(TracAdminTestCaseBase):
    """
    Tests the output of trac-admin and is meant to be used with
    .../trac/tests.py.
    """

    expected_results_filename = 'attachment-console-tests.txt'

    def setUp(self):
        self.env = EnvironmentStub(default_data=True, enable=('trac.*',),
                                   disable=('trac.tests.*',))
        self.env.path = mkdtemp()
        self.admin = TracAdmin()
        self.admin.env_set('', self.env)
        self.datetime = datetime(2001, 1, 1, 1, 1, 1, 0, utc)
        with self.env.db_transaction as db:
            db("INSERT INTO wiki (name,version) VALUES ('WikiStart',1)")
            db("INSERT INTO wiki (name,version) VALUES ('SomePage',1)")
            db("INSERT INTO ticket (id) VALUES (42)")
            db("INSERT INTO ticket (id) VALUES (43)")
            db("INSERT INTO attachment VALUES (%s,%s,%s,%s,%s,%s,%s)",
               ('ticket', '43', 'foo.txt', 8, to_utimestamp(self.datetime),
                'A comment', 'joe'))

    def tearDown(self):
        self.env.reset_db_and_disk()

    def test_attachment_list(self):
        """Attachment list command."""
        attachment = Attachment(self.env, 'wiki', 'SomePage')
        attachment.insert('foo.txt', io.BytesIO(), 0)
        rv, output = self.execute('attachment list wiki:SomePage')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'date': format_datetime(attachment.date, console_datetime_format)
        })

    def test_attachment_list_empty(self):
        """Attachment list command with no output."""
        rv, output = self.execute('attachment list wiki:WikiStart')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_attachment_add_nonexistent_resource(self):
        """Error raised when adding an attachment to a non-existent resource.
        """
        rv, output = self.execute('attachment add wiki:NonExistentPage "%s"'
                                  % __file__)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_attachment_rename(self):
        """Rename attachment."""
        attachment = Attachment(self.env, 'wiki', 'SomePage')
        attachment.insert('foo.txt', io.BytesIO(), 0)

        rv, output = self.execute('attachment move wiki:SomePage foo.txt '
                                  'wiki:SomePage bar.txt')
        self.assertEqual(0, rv, output)
        self.assertEqual('', output)
        rv, output = self.execute('attachment list wiki:SomePage')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'date': format_datetime(attachment.date, console_datetime_format)
        })

    def test_attachment_reparent(self):
        """Reparent attachment to another resource."""
        attachment = Attachment(self.env, 'wiki', 'SomePage')
        attachment.insert('foo.txt', io.BytesIO(), 0)

        rv, output = self.execute('attachment move wiki:SomePage foo.txt '
                                  'wiki:WikiStart foo.txt')
        self.assertEqual(0, rv, output)
        self.assertEqual('', output)
        rv, output = self.execute('attachment list wiki:SomePage')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('attachment list wiki:WikiStart')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'date': format_datetime(attachment.date, console_datetime_format)
        })

    def test_attachment_move_nonexistent_resource(self):
        """Error raised when reparenting attachment to another resource."""
        attachment = Attachment(self.env, 'wiki', 'SomePage')
        attachment.insert('foo.txt', io.BytesIO(), 0)

        rv, output = self.execute('attachment move wiki:SomePage foo.txt '
                                  'wiki:NonExistentPage foo.txt')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)
Пример #38
0
    def setup(self, **kwargs):
        """Do the setup. A kwargs dictionary may be passed to override base
        options, potentially allowing for multiple environment creation."""
        options = dict(self.options)
        options.update(kwargs)
        if psycopg2 is None and options.get('dbtype') == 'postgres':
            print "psycopg2 needs to be installed to initialise a postgresql db"
            return False

        environments_path = options['envsdir']
        if not os.path.exists(environments_path):
            os.makedirs(environments_path)

        new_env = os.path.join(environments_path, options['project'])
        tracini = os.path.abspath(os.path.join(new_env, 'conf', 'trac.ini'))
        baseini = os.path.abspath(os.path.join(new_env, 'conf', 'base.ini'))
        options['inherit'] = baseini

        options['db'] = self._generate_db_str(options)
        if 'repo_type' not in options or options['repo_type'] is None:
            options['repo_type'] = ''
        if 'repo_path' not in options or options['repo_path'] is None:
            options['repo_path'] = ''

        digestfile = os.path.abspath(
            os.path.join(new_env, options['digestfile']))
        realm = options['realm']
        adminuser = options['adminuser']
        adminpass = options['adminpass']

        # create base options:
        accounts_config = dict(ACCOUNTS_CONFIG)
        accounts_config['account-manager']['htdigest_file'] = digestfile
        accounts_config['account-manager']['htdigest_realm'] = realm
        accounts_config['account-manager']['password_file'] = digestfile

        trac = TracAdmin(os.path.abspath(new_env))
        if not trac.env_check():
            try:
                trac.do_initenv('%(project)s %(db)s '
                                '%(repo_type)s %(repo_path)s '
                                '--inherit=%(inherit)s '
                                '--nowiki' % options)
            except SystemExit:
                print(
                    "Error: Unable to initialise the database"
                    "Traceback for error is above")
                return False
        else:
            print("Warning: Environment already exists at %s." % new_env)
            self.writeconfig(tracini, [
                {
                    'inherit': {
                        'file': baseini
                    },
                },
            ])

        self.writeconfig(baseini, [BASE_CONFIG, accounts_config])

        if os.path.exists(digestfile):
            backupfile(digestfile)
        htdigest_create(digestfile, adminuser, realm, adminpass)

        print "Adding TRAC_ADMIN permissions to the admin user %s" % adminuser
        trac.onecmd('permission add %s TRAC_ADMIN' % adminuser)

        # get fresh TracAdmin instance (original does not know about base.ini)
        bloodhound = TracAdmin(os.path.abspath(new_env))

        # final upgrade
        print "Running upgrades"
        bloodhound.onecmd('upgrade')
        pages = pkg_resources.resource_filename('bhdashboard', 'default-pages')
        bloodhound.onecmd('wiki load %s' % pages)

        print "Running wiki upgrades"
        bloodhound.onecmd('wiki upgrade')

        print """
You can now start Bloodhound by running:

  tracd --port=8000 %s

And point your browser at http://localhost:8000/%s
""" % (os.path.abspath(new_env), options['project'])
        return True
Пример #39
0
class TracAdminTestCase(TracAdminTestCaseBase):

    def setUp(self):
        self.env = EnvironmentStub(default_data=True, enable=('trac.*',),
                                   disable=('trac.tests.*',))
        self.admin = TracAdmin()
        self.admin.env_set('', self.env)
        self._test_date = '2004-01-11'  # Set test date to 11th Jan 2004

    def tearDown(self):
        self.env = None

    @property
    def datetime_format_hint(self):
        return get_datetime_format_hint(get_console_locale(self.env))

    def test_component_help(self):
        rv, output = self.execute('help component')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_component_list_ok(self):
        """
        Tests the 'component list' command in trac-admin.  Since this command
        has no command arguments, it is hard to call it incorrectly.  As
        a result, there is only this one test.
        """
        rv, output = self.execute('component list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_component_add_ok(self):
        """
        Tests the 'component add' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('component add new_component')
        rv, output = self.execute('component list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_component_add_optional_owner_ok(self):
        """
        Tests the 'component add' command in trac-admin with the optional
        'owner' argument.  This particular test passes valid arguments and
        checks for success.
        """
        self.execute('component add new_component new_user')
        rv, output = self.execute('component list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_component_add_complete_optional_owner_restrict_owner_false(self):
        """Tests completion of the 'component add <component>' command with
        [ticket] restrict_owner = false.
        """
        self.execute('config set ticket restrict_owner false')
        self.execute('session add user1')
        self.execute('session add user3')
        self.execute('permission add user1 TICKET_MODIFY')
        self.execute('permission add user2 TICKET_VIEW')
        self.execute('permission add user3 TICKET_MODIFY')
        output = self.complete_command('component', 'add',
                                        'new_component', '')
        self.assertEqual([], output)

    def test_component_add_complete_optional_owner_restrict_owner_true(self):
        """Tests completion of the 'component add <component>' command with
        [ticket] restrict_owner = true.
        """
        self.execute('config set ticket restrict_owner true')
        self.execute('session add user1')
        self.execute('session add user3')
        self.execute('permission add user1 TICKET_MODIFY')
        self.execute('permission add user2 TICKET_VIEW')
        self.execute('permission add user3 TICKET_MODIFY')
        output = self.complete_command('component', 'add',
                                        'new_component', '')
        self.assertEqual(['user1', 'user3'], output)

    def test_component_add_error_already_exists(self):
        """
        Tests the 'component add' command in trac-admin.  This particular
        test passes a component name that already exists and checks for an
        error message.
        """
        rv, output = self.execute('component add component1 new_user')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_component_rename_ok(self):
        """
        Tests the 'component rename' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('component rename component1 changed_name')
        rv, output = self.execute('component list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_component_rename_error_bad_component(self):
        """
        Tests the 'component rename' command in trac-admin.  This particular
        test tries to rename a component that does not exist.
        """
        rv, output = self.execute('component rename bad_component changed_name')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_component_rename_error_bad_new_name(self):
        """
        Tests the 'component rename' command in trac-admin.  This particular
        test tries to rename a component to a name that already exists.
        """
        rv, output = self.execute('component rename component1 component2')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_component_chown_ok(self):
        """
        Tests the 'component chown' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('component chown component2 changed_owner')
        rv, output = self.execute('component list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_component_chown_complete_component(self):
        """Tests completion of the 'component chown' command.
        """
        output = self.complete_command('component', 'chown', '')
        self.assertEqual(['component1', 'component2'], output)

    def test_component_chown_complete_owner_restrict_owner_false(self):
        """Tests completion of the 'component chown <component>' command with
        [ticket] restrict_owner = false.
        """
        self.execute('config set ticket restrict_owner false')
        self.execute('session add user1')
        self.execute('session add user3')
        self.execute('permission add user1 TICKET_MODIFY')
        self.execute('permission add user2 TICKET_VIEW')
        self.execute('permission add user3 TICKET_MODIFY')
        output = self.complete_command('component', 'chown', 'component1', '')
        self.assertEqual([], output)

    def test_component_chown_complete_owner_restrict_owner_true(self):
        """Tests completion of the 'component chown <component>' command with
        [ticket] restrict_owner = true.
        """
        self.execute('config set ticket restrict_owner true')
        self.execute('session add user1')
        self.execute('session add user3')
        self.execute('permission add user1 TICKET_MODIFY')
        self.execute('permission add user2 TICKET_VIEW')
        self.execute('permission add user3 TICKET_MODIFY')
        output = self.complete_command('component', 'chown', 'component1', '')
        self.assertEqual(['user1', 'user3'], output)

    def test_component_chown_error_bad_component(self):
        """
        Tests the 'component chown' command in trac-admin.  This particular
        test tries to change the owner of a component that does not
        exist.
        """
        rv, output = self.execute('component chown bad_component changed_owner')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_component_remove_ok(self):
        """
        Tests the 'component remove' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('component remove component1')
        rv, output = self.execute('component list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_component_remove_error_bad_component(self):
        """
        Tests the 'component remove' command in trac-admin.  This particular
        test tries to remove a component that does not exist.
        """
        rv, output = self.execute('component remove bad_component')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_help(self):
        rv, output = self.execute('help ticket')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_remove_ok(self):
        """Ticket is successfully deleted."""
        insert_ticket(self.env)
        rv, output = self.execute('ticket remove 1')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_remove_error_no_ticket_argument(self):
        """Error reported when ticket# argument is missing."""
        rv, output = self.execute('ticket remove')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_remove_error_ticket_id_not_an_int(self):
        """Error reported when ticket id is not an int."""
        insert_ticket(self.env)
        rv, output = self.execute('ticket remove a')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_remove_error_invalid_ticket_id(self):
        """ResourceNotFound error reported when ticket does not exist."""
        insert_ticket(self.env)
        rv, output = self.execute('ticket remove 2')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_comment_remove_ok(self):
        """Ticket comment is successfully deleted."""
        ticket = insert_ticket(self.env)
        ticket.save_changes('user1', 'the comment')
        rv, output = self.execute('ticket remove_comment 1 1')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_comment_remove_error_no_ticket_argument(self):
        """Error reported when ticket# argument is missing."""
        rv, output = self.execute('ticket remove_comment')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_comment_remove_error_no_comment_argument(self):
        """Error reported when comment# argument is missing."""
        ticket = insert_ticket(self.env)
        rv, output = self.execute('ticket remove_comment 1')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_comment_remove_error_ticket_id_not_an_int(self):
        """ResourceNotFound error reported when comment does not exist."""
        ticket = insert_ticket(self.env)
        ticket.save_changes('user1', 'the comment')
        rv, output = self.execute('ticket remove_comment a 1')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_comment_remove_error_comment_id_not_an_int(self):
        """ResourceNotFound error reported when comment does not exist."""
        ticket = insert_ticket(self.env)
        ticket.save_changes('user1', 'the comment')
        rv, output = self.execute('ticket remove_comment 1 a')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_comment_remove_error_invalid_ticket_id(self):
        """ResourceNotFound error reported when ticket does not exist."""
        ticket = insert_ticket(self.env)
        ticket.save_changes('user1', 'the comment')
        rv, output = self.execute('ticket remove_comment 2 1')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_comment_remove_error_invalid_comment_id(self):
        """ResourceNotFound error reported when comment does not exist."""
        ticket = insert_ticket(self.env)
        ticket.save_changes('user1', 'the comment')
        rv, output = self.execute('ticket remove_comment 1 2')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_type_list_ok(self):
        """
        Tests the 'ticket_type list' command in trac-admin.  Since this command
        has no command arguments, it is hard to call it incorrectly.  As
        a result, there is only this one test.
        """
        rv, output = self.execute('ticket_type list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_type_add_ok(self):
        """
        Tests the 'ticket_type add' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('ticket_type add new_type')
        rv, output = self.execute('ticket_type list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_type_add_error_already_exists(self):
        """
        Tests the 'ticket_type add' command in trac-admin.  This particular
        test passes a ticket type that already exists and checks for an error
        message.
        """
        rv, output = self.execute('ticket_type add defect')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_type_change_ok(self):
        """
        Tests the 'ticket_type change' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('ticket_type change defect bug')
        rv, output = self.execute('ticket_type list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_type_change_error_bad_type(self):
        """
        Tests the 'ticket_type change' command in trac-admin.  This particular
        test tries to change a priority that does not exist.
        """
        rv, output = self.execute('ticket_type change bad_type changed_type')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_type_change_error_bad_new_name(self):
        """
        Tests the 'ticket_type change' command in trac-admin.  This particular
        test tries to change a ticket type to another type that already exists.
        """
        rv, output = self.execute('ticket_type change defect task')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_type_remove_ok(self):
        """
        Tests the 'ticket_type remove' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('ticket_type remove task')
        rv, output = self.execute('ticket_type list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_type_remove_error_bad_type(self):
        """
        Tests the 'ticket_type remove' command in trac-admin.  This particular
        test tries to remove a ticket type that does not exist.
        """
        rv, output = self.execute('ticket_type remove bad_type')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_type_order_down_ok(self):
        """
        Tests the 'ticket_type order' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('ticket_type order defect down')
        rv, output = self.execute('ticket_type list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_type_order_up_ok(self):
        """
        Tests the 'ticket_type order' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('ticket_type order enhancement up')
        rv, output = self.execute('ticket_type list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_type_order_error_bad_type(self):
        """
        Tests the 'priority order' command in trac-admin.  This particular
        test tries to reorder a priority that does not exist.
        """
        rv, output = self.execute('ticket_type order bad_type up')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_priority_help(self):
        rv, output = self.execute('help priority')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_priority_list_ok(self):
        """
        Tests the 'priority list' command in trac-admin.  Since this command
        has no command arguments, it is hard to call it incorrectly.  As
        a result, there is only this one test.
        """
        rv, output = self.execute('priority list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_priority_add_ok(self):
        """
        Tests the 'priority add' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('priority add new_priority')
        rv, output = self.execute('priority list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_priority_add_many_ok(self):
        """
        Tests adding more than 10 priority values.  This makes sure that
        ordering is preserved when adding more than 10 values.
        """
        for i in xrange(11):
            self.execute('priority add p%s' % i)
        rv, output = self.execute('priority list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_priority_add_error_already_exists(self):
        """
        Tests the 'priority add' command in trac-admin.  This particular
        test passes a priority name that already exists and checks for an
        error message.
        """
        rv, output = self.execute('priority add blocker')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_priority_change_ok(self):
        """
        Tests the 'priority change' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('priority change major normal')
        rv, output = self.execute('priority list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_priority_change_error_bad_priority(self):
        """
        Tests the 'priority change' command in trac-admin.  This particular
        test tries to change a priority that does not exist.
        """
        rv, output = self.execute('priority change bad_priority changed_name')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_priority_change_error_bad_new_name(self):
        """
        Tests the 'priority change' command in trac-admin.  This particular
        test tries to change a priority to a name that already exists.
        """
        rv, output = self.execute('priority change major minor')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_priority_remove_ok(self):
        """
        Tests the 'priority remove' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('priority remove major')
        rv, output = self.execute('priority list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_priority_remove_error_bad_priority(self):
        """
        Tests the 'priority remove' command in trac-admin.  This particular
        test tries to remove a priority that does not exist.
        """
        rv, output = self.execute('priority remove bad_priority')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_priority_order_down_ok(self):
        """
        Tests the 'priority order' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('priority order blocker down')
        rv, output = self.execute('priority list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_priority_order_up_ok(self):
        """
        Tests the 'priority order' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('priority order critical up')
        rv, output = self.execute('priority list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_priority_order_error_bad_priority(self):
        """
        Tests the 'priority order' command in trac-admin.  This particular
        test tries to reorder a priority that does not exist.
        """
        rv, output = self.execute('priority remove bad_priority')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_severity_help(self):
        rv, output = self.execute('help severity')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_severity_list_ok(self):
        """
        Tests the 'severity list' command in trac-admin.  Since this command
        has no command arguments, it is hard to call it incorrectly.  As
        a result, there is only this one test.
        """
        rv, output = self.execute('severity list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_severity_add_ok(self):
        """
        Tests the 'severity add' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('severity add new_severity')
        rv, output = self.execute('severity list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_severity_add_error_already_exists(self):
        """
        Tests the 'severity add' command in trac-admin.  This particular
        test passes a severity name that already exists and checks for an
        error message.
        """
        self.execute('severity add blocker')
        rv, output = self.execute('severity add blocker')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_severity_change_ok(self):
        """
        Tests the 'severity add' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('severity add critical')
        self.execute('severity change critical "end-of-the-world"')
        rv, output = self.execute('severity list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_severity_change_error_bad_severity(self):
        """
        Tests the 'severity change' command in trac-admin.  This particular
        test tries to change a severity that does not exist.
        """
        rv, output = self.execute(
            'severity change bad_severity changed_name')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_severity_change_error_bad_new_name(self):
        """
        Tests the 'severity change' command in trac-admin.  This particular
        test tries to change a severity to a name that already exists.
        """
        self.execute('severity add major')
        self.execute('severity add critical')
        rv, output = self.execute('severity change critical major')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_severity_remove_ok(self):
        """
        Tests the 'severity add' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('severity remove trivial')
        rv, output = self.execute('severity list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_severity_remove_error_bad_severity(self):
        """
        Tests the 'severity remove' command in trac-admin.  This particular
        test tries to remove a severity that does not exist.
        """
        rv, output = self.execute('severity remove bad_severity')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_severity_order_down_ok(self):
        """
        Tests the 'severity order' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('severity add foo')
        self.execute('severity add bar')
        self.execute('severity order foo down')
        rv, output = self.execute('severity list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_severity_order_up_ok(self):
        """
        Tests the 'severity order' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('severity add foo')
        self.execute('severity add bar')
        self.execute('severity order bar up')
        rv, output = self.execute('severity list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_severity_order_error_bad_severity(self):
        """
        Tests the 'severity order' command in trac-admin.  This particular
        test tries to reorder a priority that does not exist.
        """
        rv, output = self.execute('severity remove bad_severity')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_help_version_time(self):
        doc = self.get_command_help('version', 'time')
        self.assertIn(self.datetime_format_hint, doc)
        self.assertIn(u'"YYYY-MM-DDThh:mm:ss±hh:mm"', doc)

    def test_version_help(self):
        rv, output = self.execute('help version')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_version_list_ok(self):
        """
        Tests the 'version list' command in trac-admin.  Since this command
        has no command arguments, it is hard to call it incorrectly.  As
        a result, there is only this one test.
        """
        rv, output = self.execute('version list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_version_add_ok(self):
        """
        Tests the 'version add' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('version add 9.9 "%s"' % self._test_date)
        rv, output = self.execute('version list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_version_add_too_many_arguments(self):
        rv, output = self.execute('version add 7.7 8.8 9.9')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_version_add_error_already_exists(self):
        """
        Tests the 'version add' command in trac-admin.  This particular
        test passes a version name that already exists and checks for an
        error message.
        """
        rv, output = self.execute(
            'version add 1.0 "%s"' % self._test_date)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_version_rename_ok(self):
        """
        Tests the 'version rename' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('version rename 1.0 9.9')
        rv, output = self.execute('version list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_version_rename_error_bad_version(self):
        """
        Tests the 'version rename' command in trac-admin.  This particular
        test tries to rename a version that does not exist.
        """
        rv, output = self.execute(
            'version rename bad_version changed_name')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_version_rename_error_bad_new_name(self):
        """
        Tests the 'version rename' command in trac-admin.  This particular
        test tries to rename a version to a name that already exists.
        """
        rv, output = self.execute('version rename 1.0 2.0')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_version_time_ok(self):
        """
        Tests the 'version time' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('version time 2.0 "%s"' % self._test_date)
        rv, output = self.execute('version list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_version_time_unset_ok(self):
        """
        Tests the 'version time' command in trac-admin.  This particular
        test passes valid arguments for unsetting the date.
        """
        self.execute('version time 2.0 "%s"' % self._test_date)
        self.execute('version time 2.0 ""')
        rv, output = self.execute('version list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_version_time_error_bad_version(self):
        """
        Tests the 'version time' command in trac-admin.  This particular
        test tries to change the time on a version that does not exist.
        """
        rv, output = self.execute('version time bad_version "%s"'
                                  % self._test_date)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_version_remove_ok(self):
        """
        Tests the 'version remove' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('version remove 1.0')
        rv, output = self.execute('version list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_version_remove_error_bad_version(self):
        """
        Tests the 'version remove' command in trac-admin.  This particular
        test tries to remove a version that does not exist.
        """
        rv, output = self.execute('version remove bad_version')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_backslash_use_ok(self):
        if self.admin.interactive:
            self.execute('version add \\')
        else:
            self.execute(r"version add '\'")
        rv, output = self.execute('version list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_help(self):
        rv, output = self.execute('help milestone')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_help_milestone_due(self):
        doc = self.get_command_help('milestone', 'due')
        self.assertIn(self.datetime_format_hint, doc)
        self.assertIn(u'"YYYY-MM-DDThh:mm:ss±hh:mm"', doc)

    def test_help_milestone_completed(self):
        doc = self.get_command_help('milestone', 'completed')
        self.assertIn(self.datetime_format_hint, doc)
        self.assertIn(u'"YYYY-MM-DDThh:mm:ss±hh:mm"', doc)

    def test_milestone_list_ok(self):
        """
        Tests the 'milestone list' command in trac-admin.  Since this command
        has no command arguments, it is hard to call it incorrectly.  As
        a result, there is only this one test.
        """
        rv, output = self.execute('milestone list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_add_ok(self):
        """
        Tests the 'milestone add' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('milestone add new_milestone "%s"' % self._test_date)
        rv, output = self.execute('milestone list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_add_utf8_ok(self):
        """
        Tests the 'milestone add' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute(u'milestone add \xa9tat_final "%s"'  # \xc2\xa9
                     % self._test_date)
        rv, output = self.execute('milestone list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_add_error_already_exists(self):
        """
        Tests the 'milestone add' command in trac-admin.  This particular
        test passes a milestone name that already exists and checks for an
        error message.
        """
        rv, output = self.execute('milestone add milestone1 "%s"'
                                  % self._test_date)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_add_invalid_date(self):
        rv, output = self.execute('milestone add new_milestone <add>')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output, {
            'hint': self.datetime_format_hint,
            'isohint': get_datetime_format_hint('iso8601')
        })

    def test_milestone_rename_ok(self):
        """
        Tests the 'milestone rename' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('milestone rename milestone1 changed_milestone')
        rv, output = self.execute('milestone list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_rename_error_bad_milestone(self):
        """
        Tests the 'milestone rename' command in trac-admin.  This particular
        test tries to rename a milestone that does not exist.
        """
        rv, output = self.execute(
            'milestone rename bad_milestone changed_name')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_due_ok(self):
        """
        Tests the 'milestone due' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('milestone due milestone2 "%s"' % self._test_date)
        rv, output = self.execute('milestone list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_due_unset_ok(self):
        """
        Tests the 'milestone due' command in trac-admin.  This particular
        test passes valid arguments for unsetting the due date.
        """
        self.execute('milestone due milestone2 "%s"' % self._test_date)
        self.execute('milestone due milestone2 ""')
        rv, output = self.execute('milestone list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_due_error_bad_milestone(self):
        """
        Tests the 'milestone due' command in trac-admin.  This particular
        test tries to change the due date on a milestone that does not exist.
        """
        rv, output = self.execute('milestone due bad_milestone "%s"'
                                  % self._test_date)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_due_invalid_date(self):
        rv, output = self.execute('milestone due milestone1 <due>')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output, {
            'hint': self.datetime_format_hint,
            'isohint': get_datetime_format_hint('iso8601')
        })

    def test_milestone_completed_ok(self):
        """
        Tests the 'milestone completed' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute(
            'milestone completed milestone2 "%s"' % self._test_date)
        rv, output = self.execute('milestone list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_completed_error_bad_milestone(self):
        """
        Tests the 'milestone completed' command in trac-admin.  This particular
        test tries to change the completed date on a milestone that does not
        exist.
        """
        rv, output = self.execute('milestone completed bad_milestone "%s"'
                                  % self._test_date)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_completed_invalid_date(self):
        rv, output = self.execute('milestone completed milestone1 <com>')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output, {
            'hint': self.datetime_format_hint,
            'isohint': get_datetime_format_hint('iso8601')
        })

    def test_milestone_remove_ok(self):
        """
        Tests the 'milestone remove' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('milestone remove milestone3')
        rv, output = self.execute('milestone list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_remove_error_bad_milestone(self):
        """
        Tests the 'milestone remove' command in trac-admin.  This particular
        test tries to remove a milestone that does not exist.
        """
        rv, output = self.execute('milestone remove bad_milestone')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)
Пример #40
0
class TracadminTestCase(TracAdminTestCaseBase):
    """
    Tests the output of trac-admin and is meant to be used with
    .../trac/tests.py.
    """
    def setUp(self):
        self.env = EnvironmentStub()
        self.admin = TracAdmin()
        self.admin.env_set('', self.env)

    def tearDown(self):
        self.env = None

    def test_help_ok(self):
        """
        Tests the 'help' command in trac-admin.  Since the 'help' command
        has no command arguments, it is hard to call it incorrectly.  As
        a result, there is only this one test.
        """
        rv, output = self.execute('help')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(
            output, {
                'version': self.env.trac_version,
                'date_format_hint': get_date_format_hint()
            })
        self.assertTrue(all(len(line) < 80 for line in output.split('\n')),
                        "Lines should be less than 80 characters in length.")

    def _test_get_console_locale_with_babel(self):
        locales = get_available_locales()
        en_US = Locale.parse('en_US')
        de = Locale.parse('de')

        def unset_locale_envs():
            for name in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'):
                if name in os.environ:
                    del os.environ[name]

        if 'de' in locales:
            unset_locale_envs()
            self.assertIsNone(get_console_locale(None, None))
            self.assertEqual(de, get_console_locale(None, 'de_DE.UTF8'))
            self.env.config.set('trac', 'default_language', 'de')
            self.assertEqual(de, get_console_locale(self.env, None))
            self.assertEqual(de, get_console_locale(self.env, 'C'))
            self.env.config.set('trac', 'default_language', 'en_US')
            self.assertEqual(en_US, get_console_locale(self.env, None))
            self.assertEqual(en_US, get_console_locale(self.env, 'C'))
            self.assertEqual(de, get_console_locale(self.env, 'de_DE.UTF8'))

            self.env.config.set('trac', 'default_language', 'de')
            os.environ['LANG'] = 'POSIX'  # unavailable locale in Trac
            self.assertIsNone(get_console_locale())
            self.assertEqual(de, get_console_locale(self.env))
            os.environ['LANG'] = '****'  # invalid locale
            self.assertIsNone(get_console_locale())
            self.assertEqual(de, get_console_locale(self.env))
            os.environ['LANG'] = 'en_US.utf-8'
            self.assertEqual(en_US, get_console_locale())
            self.assertEqual(en_US, get_console_locale(self.env))
            os.environ['LC_MESSAGES'] = 'de_DE.utf-8'
            self.assertEqual(de, get_console_locale())
            self.assertEqual(de, get_console_locale(self.env))
            os.environ['LC_ALL'] = 'en_US.utf-8'
            self.assertEqual(en_US, get_console_locale())
            self.assertEqual(en_US, get_console_locale(self.env))
            os.environ['LANGUAGE'] = 'de_DE:en_US:en'
            self.assertEqual(de, get_console_locale())
            self.assertEqual(de, get_console_locale(self.env))

        if not locales:  # compiled catalog is missing
            unset_locale_envs()
            self.assertIsNone(get_console_locale(None, 'de_DE.UTF8'))
            self.env.config.set('trac', 'default_language', 'de')
            self.assertIsNone(get_console_locale(self.env, None))
            self.assertIsNone(get_console_locale(self.env, 'C'))
            self.assertIsNone(get_console_locale(self.env, 'de_DE.UTF8'))
            os.environ['LANG'] = 'en_US.utf-8'
            os.environ['LC_MESSAGES'] = 'de_DE.utf-8'
            os.environ['LC_ALL'] = 'en_US.utf-8'
            os.environ['LANGUAGE'] = 'de_DE:en_US'
            self.assertEqual(en_US, get_console_locale())
            self.assertEqual(en_US, get_console_locale(self.env))

    def _test_get_console_locale_without_babel(self):
        os.environ['LANG'] = 'en_US.utf-8'
        os.environ['LC_MESSAGES'] = 'de_DE.utf-8'
        os.environ['LC_ALL'] = 'en_US.utf-8'
        os.environ['LANGUAGE'] = 'de_DE:en_US'
        self.assertIsNone(get_console_locale(None, 'en_US.UTF8'))
        self.env.config.set('trac', 'default_language', '')
        self.assertIsNone(get_console_locale(self.env, 'en_US.UTF8'))
        self.assertIsNone(get_console_locale(self.env))
        self.env.config.set('trac', 'default_language', 'en_US')
        self.assertIsNone(get_console_locale(self.env, 'en_US.UTF8'))
        self.assertIsNone(get_console_locale(self.env))

    if has_babel:
        test_get_console_locale = _test_get_console_locale_with_babel
    else:
        test_get_console_locale = _test_get_console_locale_without_babel
Пример #41
0
 def setUp(self):
     self.env = EnvironmentStub(default_data=True)
     self.admin = TracAdmin()
     self.admin.env_set('', self.env)
Пример #42
0
    def install(self):
        """Installer"""

        # Utility function to interpreted boolean option value
        getBool = lambda s: s.strip().lower() in ['true', 'yes']

        # Utility function to parse a multi-line/multi-value parameter
        def cleanMultiParams(v):
            params = [
                s.split('|') for s in [l.strip() for l in v.split('\n')]
                if len(s) > 0
            ]
            cleaned_params = []
            for line in params:
                cleaned_params.append([row.strip() for row in line])
            return cleaned_params

        # Utility function to transform any string to an ID
        getId = lambda s: ''.join([c for c in s if c.isalnum()]).lower()

        options = self.options

        # Add command line scripts trac-admin and tracd into bin
        entry_points = [('trac-admin', 'trac.admin.console', 'run'),
                        ('tracd', 'trac.web.standalone', 'main')]
        zc.buildout.easy_install.scripts(entry_points,
                                         pkg_resources.working_set,
                                         options['executable'],
                                         options['bin-directory'])

        ####################
        # Init Trac instance
        ####################

        # Generate the trac instance, if required
        location = options['location']
        project_name = options.get('project-name', 'My project')
        project_url = options.get('project-url', 'http://example.com')
        db = 'sqlite:%s' % os.path.join('db', 'trac.db')
        if not os.path.exists(location):
            os.mkdir(location)
        trac = TracAdmin(location)
        if not trac.env_check():
            trac.do_initenv('"%s" %s' % (project_name, db))
        env = trac.env

        # Remove Trac default example data
        clean_up = getBool(options.get('remove-examples', 'True'))
        if clean_up:
            # Remove default milestones
            for mil in Milestone.select(env):
                if mil.name in [
                        'milestone1', 'milestone2', 'milestone3', 'milestone4'
                ]:
                    mil.delete()
            # Remove default components
            for comp in Component.select(env):
                if comp.name in ['component1', 'component2']:
                    comp.delete()

        # Add custom milestones
        for mil_data in cleanMultiParams(options.get('milestones', '')):
            mil_name = mil_data[0]
            try:
                mil = Milestone(env, name=mil_name)
            except ResourceNotFound:
                mil = Milestone(env)
                mil.name = mil_name
                mil.insert()

        # Add custom components
        for comp_data in cleanMultiParams(options.get('components', '')):
            comp_name = comp_data[0]
            try:
                comp = Component(env, name=comp_name)
            except ResourceNotFound:
                comp = Component(env)
                comp.name = comp_name
                if len(comp_data) == 2 and comp_data[1] not in [None, '']:
                    comp.owner = comp_data[1]
                comp.insert()

        #######################
        # Generate the trac.ini
        #######################

        # Read the trac.ini config file
        trac_ini = os.path.join(location, 'conf', 'trac.ini')
        parser = ConfigParser.ConfigParser()
        parser.read([trac_ini])

        # Clean-up trac.ini: add missing stuff
        if 'components' not in parser.sections():
            parser.add_section('components')

        # Force upgrade of informations used during initialization
        parser.set('project', 'name', project_name)

        # Set all repositories
        repos = cleanMultiParams(options.get('repos', None))
        repo_names = [getId(r[0]) for r in repos]
        repo_types = {}.fromkeys([r[1].lower() for r in repos]).keys()
        if 'repositories' not in parser.sections():
            parser.add_section('repositories')
        for repo in repos:
            repo_name = getId(repo[0])
            repo_type = repo[1]
            repo_dir = repo[2]
            repo_url = repo[3]
            parser.set('repositories', '%s.type' % repo_name, repo_type)
            parser.set('repositories', '%s.dir' % repo_name, repo_dir)
            if repo_url not in ['', None]:
                parser.set('repositories', '%s.url' % repo_name, repo_url)

        # Set default repository
        default_repo = getId(options.get('default-repo', None))
        if default_repo and default_repo in repo_names:
            parser.set('repositories', '.alias', default_repo)
            parser.set('repositories', '.hidden', 'true')

        # Set repository sync method
        sync_method = options.get('repos-sync', 'request').strip().lower()
        svn_repos = [getId(r[0]) for r in repos if r[1] == 'svn']
        if sync_method == 'request':
            parser.set('trac', 'repository_sync_per_request',
                       ', '.join(svn_repos))
        # TODO
        # elif sync_method == 'hook':
        #   do stuff...

        # Set project description
        project_descr = options.get('project-description', None)
        if project_descr:
            parser.set('project', 'descr', project_descr)
            parser.set('header_logo', 'alt', project_descr)

        # Setup logo
        header_logo = options.get('header-logo', '')
        header_logo = os.path.realpath(header_logo)
        if os.path.exists(header_logo):
            shutil.copyfile(header_logo,
                            os.path.join(location, 'htdocs', 'logo'))
        parser.set('header_logo', 'src', 'site/logo')
        parser.set('header_logo', 'link', project_url)

        # Set footer message
        parser.set(
            'project', 'footer',
            options.get(
                'footer-message',
                'This Trac instance was generated by <a href="http://pypi.python.org/pypi/pbp.recipe.trac">pbp.recipe.trac</a>.'
            ))

        # SMTP parameters
        for name in ('always-bcc', 'always-cc', 'default-domain', 'enabled',
                     'from', 'from-name', 'password', 'port', 'replyto',
                     'server', 'subject-prefix', 'user'):
            param_name = "smtp-%s" % name
            default_value = None
            if param_name == "smtp-from-name":
                default_value = project_name
            value = options.get(param_name, default_value)
            if value is not None:
                parser.set('notification', param_name.replace('-', '_'), value)

        ###############
        # Plugins setup
        ###############

        # If one repository use Mercurial, hook its plugin
        if 'hg' in repo_types:
            parser.set('components', 'tracext.hg.*', 'enabled')

        # Configure the NavAdd plugin
        menu_items = cleanMultiParams(options.get('additional-menu-items', ''))
        item_list = []
        for item in menu_items:
            item_title = item[0]
            item_url = item[1]
            item_id = getId(item_title)
            item_list.append((item_id, item_title, item_url))
        if item_list > 0:
            parser.set('components', 'navadd.*', 'enabled')
            if 'navadd' not in parser.sections():
                parser.add_section('navadd')
            parser.set('navadd', 'add_items',
                       ','.join([i[0] for i in item_list]))
            for (uid, title, url) in item_list:
                parser.set('navadd', '%s.target' % uid, 'mainnav')
                parser.set('navadd', '%s.title' % uid, title)
                parser.set('navadd', '%s.url' % uid, url)

        # Enable and setup time tracking
        time_tracking = options.get('time-tracking-plugin',
                                    'disabled').strip().lower() == 'enabled'
        if time_tracking:
            parser.set('components', 'timingandestimationplugin.*', 'enabled')

        # Enable and setup the stat plugin
        stats = options.get('stats-plugin',
                            'disabled').strip().lower() == 'enabled'
        if stats:
            parser.set('components', 'tracstats.*', 'enabled')

        #######################
        # Final upgrades & sync
        #######################

        # Apply custom parameters defined by the user
        custom_params = cleanMultiParams(options.get('trac-ini-additional',
                                                     ''))
        for param in custom_params:
            if len(param) == 3:
                section = param[0]
                if section not in parser.sections():
                    parser.add_section(section)
                parser.set(section, param[1], param[2])

        # Write the final trac.ini
        parser.write(open(trac_ini, 'w'))

        # Reload the environment
        env.shutdown()
        trac = TracAdmin(location)
        env = trac.env

        # Set custom permissions
        perm_sys = PermissionSystem(env)
        for cperm in cleanMultiParams(options.get('permissions', '')):
            if len(cperm) == 2:
                user = cperm[0]
                current_user_perms = perm_sys.get_user_permissions(user)
                perm_list = [p.upper() for p in cperm[1].split(' ') if len(p)]
                for perm in perm_list:
                    if perm not in current_user_perms:
                        perm_sys.grant_permission(user, perm)

        # Upgrade Trac instance to keep it fresh
        needs_upgrade = env.needs_upgrade()
        force_upgrade = getBool(options.get('force-instance-upgrade', 'False'))
        if needs_upgrade or force_upgrade:
            env.upgrade(backup=True)

        # Force repository resync
        repo_resync = getBool(options.get('force-repos-resync', 'False'))
        if repo_resync:
            rm = RepositoryManager(env)
            repositories = rm.get_real_repositories()
            for repos in sorted(repositories, key=lambda r: r.reponame):
                repos.sync(clean=True)

        # Upgrade default wiki pages embedded in Trac instance
        wiki_upgrade = getBool(options.get('wiki-doc-upgrade', 'False'))
        if wiki_upgrade:
            # Got the command below from trac/admin/console.py
            pages_dir = pkg_resources.resource_filename(
                'trac.wiki', 'default-pages')
            WikiAdmin(env).load_pages(pages_dir,
                                      ignore=['WikiStart', 'checkwiki.py'],
                                      create_only=['InterMapTxt'])

        # Return files that were created by the recipe. The buildout
        # will remove all returned files upon reinstall.
        return tuple()