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()
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)
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)
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 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()
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)
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')
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)
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)
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()
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)
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 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
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)
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'))
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()
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
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
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 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( )
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()
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
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)
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()
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)
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
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()
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
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)
def setUp(self): self.env = Environment(path=mkdtemp(), create=True) self.admin = TracAdmin(self.env.path) self.admin.env_set('', self.env)
def setUp(self): self.parent_dir = mkdtemp() self.env_path = os.path.join(self.parent_dir, 'trac') self.admin = TracAdmin(self.env_path)
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)
def setUp(self): self.env = EnvironmentStub() self.admin = TracAdmin() self.admin.env_set('', self.env)
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)
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)
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
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)
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
def setUp(self): self.env = EnvironmentStub(default_data=True) self.admin = TracAdmin() self.admin.env_set('', self.env)
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()