Ejemplo n.º 1
0
    def testTimeZone(self):
        config = configuration.CoreConfig()

        self.assertEqual(None,
                config._get_option('TIMEZONE').set("0"))

        # not a valid timezone
        self.assertRaises(configuration.OptionValueError,
                config._get_option('TIMEZONE').set, "Zot")

        # 25 is not a valid UTC offset: -12 - +14 is range
        # possibly +/- 1 for DST. But roundup.date doesn't
        # constrain to this range.
        #self.assertRaises(configuration.OptionValueError,
        #        config._get_option('TIMEZONE').set, "25")

        try:
            import pytz
            self.assertEqual(None,
                    config._get_option('TIMEZONE').set("UTC"))
            self.assertEqual(None,
                    config._get_option('TIMEZONE').set("America/New_York"))

        except ImportError:
            self.assertRaises(configuration.OptionValueError,
                    config._get_option('TIMEZONE').set, "UTC")
            self.assertRaises(configuration.OptionValueError,
                    config._get_option('TIMEZONE').set, "America/New_York")
Ejemplo n.º 2
0
def run_demo(home):
    """Run the demo tracker instance from its ``home`` directory"""
    print("Demo Tracker Home:", home)

    cfg = configuration.CoreConfig(home)
    url = cfg["TRACKER_WEB"]
    hostname, port = urlparse.urlparse(url)[1].split(':')
    port = int(port)
    success_message = '''Server running - connect to:
    %(url)s
1. Log in as "demo"/"demo" or "admin"/"admin".
2. Hit Control-C to stop the server.
3. Re-start the server by running "%(script)s" again.
4. Reset the tracker by running "%(script)s nuke".

By default the demo tracker is set up to be accessed from "localhost".
If you want to run it on a server,
edit "%(datadir)s/config.ini"
and set the "web" option in section "[tracker]" to your host name,
then restart demo. If you want to change backend types, you must use "nuke".

''' % dict(url=url, script=sys.argv[0], datadir=TRACKER_HOME)

    # disable command line processing in roundup_server
    sys.argv = sys.argv[:1] + ['-p', str(port), '-n', hostname, 'demo=' + home]
    roundup_server.run(success_message=success_message)
Ejemplo n.º 3
0
    def testConfigSave(self):

        config = configuration.CoreConfig()
        # make scratch directory to create files in

        self.startdir = os.getcwd()

        self.dirname = os.getcwd() + '_test_config'
        os.mkdir(self.dirname)

        try:
            os.chdir(self.dirname)
            self.assertFalse(os.access("config.ini", os.F_OK))
            self.assertFalse(os.access("config.bak", os.F_OK))
            config.save()
            config.save()  # creates .bak file
            self.assertTrue(os.access("config.ini", os.F_OK))
            self.assertTrue(os.access("config.bak", os.F_OK))

            self.assertFalse(os.access("foo.bar", os.F_OK))
            self.assertFalse(os.access("foo.bak", os.F_OK))
            config.save("foo.bar")
            config.save("foo.bar")  # creates .bak file
            self.assertTrue(os.access("foo.bar", os.F_OK))
            self.assertTrue(os.access("foo.bak", os.F_OK))

        finally:
            # cleanup scratch directory and files
            try:
                os.chdir(self.startdir)
                shutil.rmtree(self.dirname)
            except OSError as error:
                if error.errno not in (errno.ENOENT, errno.ESRCH): raise
Ejemplo n.º 4
0
    def testTimeZone(self):
        config = configuration.CoreConfig()

        self.assertEqual(None, config._get_option('TIMEZONE').set("0"))

        # not a valid timezone
        self.assertRaises(configuration.OptionValueError,
                          config._get_option('TIMEZONE').set, "Zot")

        # 25 is not a valid UTC offset: -12 - +14 is range
        # possibly +/- 1 for DST. But roundup.date doesn't
        # constrain to this range.
        #self.assertRaises(configuration.OptionValueError,
        #        config._get_option('TIMEZONE').set, "25")

        try:
            import pytz
            self.assertEqual(None, config._get_option('TIMEZONE').set("UTC"))
            self.assertEqual(
                None,
                config._get_option('TIMEZONE').set("America/New_York"))
            self.assertEqual(None, config._get_option('TIMEZONE').set("EST"))
            self.assertRaises(configuration.OptionValueError,
                              config._get_option('TIMEZONE').set, "Zool/Zot")

        except ImportError:
            # UTC is a known offset of 0 coded into roundup.date
            # so it works even without pytz.
            self.assertEqual(None, config._get_option('TIMEZONE').set("UTC"))
            # same with EST known timeone offset of 5
            self.assertEqual(None, config._get_option('TIMEZONE').set("EST"))
            self.assertRaises(configuration.OptionValueError,
                              config._get_option('TIMEZONE').set,
                              "America/New_York")
Ejemplo n.º 5
0
    def testWebSecretKey(self):
        config = configuration.CoreConfig()

        self.assertEqual(None,
                         config._get_option('WEB_SECRET_KEY').set("skskskd"))

        self.assertRaises(configuration.OptionValueError,
                          config._get_option('WEB_SECRET_KEY').set, "")
Ejemplo n.º 6
0
    def testOctalNumberOption(self):

        config = configuration.CoreConfig()

        with self.assertRaises(configuration.OptionValueError) as cm:
            config._get_option('UMASK').set("xyzzy")

        print(type(config._get_option('UMASK')))
Ejemplo n.º 7
0
    def testStaticFiles(self):
        config = configuration.CoreConfig()

        self.assertEqual(
            None,
            config._get_option('STATIC_FILES').set("foo /tmp/bar"))

        self.assertEqual(config.STATIC_FILES, ["./foo", "/tmp/bar"])

        self.assertEqual(config['STATIC_FILES'], ["./foo", "/tmp/bar"])
Ejemplo n.º 8
0
def new_config(debug=False):
    config = configuration.CoreConfig()
    config.DATABASE = "db"
    #config.logging = MockNull()
    # these TRACKER_WEB and MAIL_DOMAIN values are used in mailgw tests
    if debug:
        config.LOGGING_LEVEL = "DEBUG"
    config.MAIL_DOMAIN = "your.tracker.email.domain.example"
    config.TRACKER_WEB = "http://tracker.example/cgi-bin/roundup.cgi/bugs/"
    return config
Ejemplo n.º 9
0
    def testUnsetMailPassword_with_unset_username(self):
        """ Set [mail] username but don't set the 
            [mail] password. Should get an OptionValueError. 
        """
        config = configuration.CoreConfig()

        config.load(self.dirname)

        self.assertEqual(config['MAIL_USERNAME'], '')

        with self.assertRaises(configuration.OptionUnsetError) as cm:
            self.assertEqual(config['MAIL_PASSWORD'], 'NO DEFAULT')
Ejemplo n.º 10
0
    def testFloatAndInt_with_update_option(self):

        config = configuration.CoreConfig()

        # Update existing IntegerNumberGeqZeroOption to IntegerNumberOption
        config.update_option('WEB_LOGIN_ATTEMPTS_MIN',
                             configuration.IntegerNumberOption,
                             "0",
                             description="new desc")

        # -1 is allowed now that it is an int.
        self.assertEqual(
            None,
            config._get_option('WEB_LOGIN_ATTEMPTS_MIN').set("-1"))

        # but can't float this
        self.assertRaises(configuration.OptionValueError,
                          config._get_option('WEB_LOGIN_ATTEMPTS_MIN').set,
                          "2.4")

        # but fred is still an issue
        self.assertRaises(configuration.OptionValueError,
                          config._get_option('WEB_LOGIN_ATTEMPTS_MIN').set,
                          "fred")

        # Update existing IntegerNumberOption to FloatNumberOption
        config.update_option('WEB_LOGIN_ATTEMPTS_MIN',
                             configuration.FloatNumberOption, "0.0")

        self.assertEqual(config['WEB_LOGIN_ATTEMPTS_MIN'], -1)

        # can float this
        self.assertEqual(
            None,
            config._get_option('WEB_LOGIN_ATTEMPTS_MIN').set("3.1415926"))

        # but fred is still an issue
        self.assertRaises(configuration.OptionValueError,
                          config._get_option('WEB_LOGIN_ATTEMPTS_MIN').set,
                          "fred")

        self.assertAlmostEqual(config['WEB_LOGIN_ATTEMPTS_MIN'],
                               3.1415926,
                               places=6)

        # test removal of .0 on floats that are integers
        self.assertEqual(
            None,
            config._get_option('WEB_LOGIN_ATTEMPTS_MIN').set("3.0"))

        self.assertEqual(
            "3",
            config._get_option('WEB_LOGIN_ATTEMPTS_MIN')._value2str(3.00))
Ejemplo n.º 11
0
    def testIsolationLevel(self):
        config = configuration.CoreConfig()

        self.assertEqual(None,
            config._get_option('RDBMS_ISOLATION_LEVEL').set("read uncommitted"))
        self.assertEqual(None,
            config._get_option('RDBMS_ISOLATION_LEVEL').set("read committed"))
        self.assertEqual(None,
            config._get_option('RDBMS_ISOLATION_LEVEL').set("repeatable read"))


        self.assertRaises(configuration.OptionValueError,
            config._get_option('RDBMS_ISOLATION_LEVEL').set, "not a level")
Ejemplo n.º 12
0
    def testNullableSecret_with_value(self):

        self.munge_configini(mods=[
            ("password = "******"test"),
        ])

        config = configuration.CoreConfig()

        config.load(self.dirname)

        v = config['RDBMS_PASSWORD']

        self.assertEqual(v, "test")
Ejemplo n.º 13
0
    def testOptionAsString(self):

        config = configuration.CoreConfig()

        config._get_option('WEB_LOGIN_ATTEMPTS_MIN').set("2552")

        v = config._get_option('WEB_LOGIN_ATTEMPTS_MIN').__str__()
        print(v)
        self.assertIn("55", v)

        v = config._get_option('WEB_LOGIN_ATTEMPTS_MIN').__repr__()
        print(v)
        self.assertIn("55", v)
Ejemplo n.º 14
0
def new_config(debug=False):
    config = configuration.CoreConfig()
    config.detectors = configuration.UserConfig(
        "share/roundup/templates/classic/detectors/config.ini")
    config.ext = configuration.UserConfig(
        "share/roundup/templates/classic/extensions/config.ini")
    config.DATABASE = "db"
    #config.logging = MockNull()
    # these TRACKER_WEB and MAIL_DOMAIN values are used in mailgw tests
    if debug:
        config.LOGGING_LEVEL = "DEBUG"
    config.MAIL_DOMAIN = "your.tracker.email.domain.example"
    config.TRACKER_WEB = "http://tracker.example/cgi-bin/roundup.cgi/bugs/"
    return config
Ejemplo n.º 15
0
    def testOriginHeader(self):
        config = configuration.CoreConfig()

        with self.assertRaises(configuration.OptionValueError) as cm:
            config._get_option('WEB_ALLOWED_API_ORIGINS').set(
                "* https://foo.edu")

        config._get_option('WEB_ALLOWED_API_ORIGINS').set(
            "https://foo.edu HTTP://baR.edu")

        self.assertEqual(config['WEB_ALLOWED_API_ORIGINS'][0],
                         'https://foo.edu')
        self.assertEqual(config['WEB_ALLOWED_API_ORIGINS'][1],
                         'HTTP://baR.edu')
Ejemplo n.º 16
0
    def open(self, tracker_home, optimize=0):
        """Open the tracker.

        Parameters:
            tracker_home:
                tracker home directory
            optimize:
                if set, precompile html templates

        Raise ValueError if the tracker home doesn't exist.

        """
        import imp
        # sanity check existence of tracker home
        if not os.path.exists(tracker_home):
            raise ValueError('no such directory: "%s"' % tracker_home)

        # sanity check tracker home contents
        for reqd in 'config dbinit select_db interfaces'.split():
            if not os.path.exists(os.path.join(tracker_home, '%s.py' % reqd)):
                raise TrackerError('File "%s.py" missing from tracker '\
                    'home "%s"'%(reqd, tracker_home))

        if tracker_home in self.trackers:
            return imp.load_package(self.trackers[tracker_home], tracker_home)
        # register all available backend modules
        backends.list_backends()
        self.number = self.number + 1
        modname = '_roundup_tracker_%s' % self.number
        self.trackers[tracker_home] = modname

        # load the tracker
        tracker = imp.load_package(modname, tracker_home)

        # ensure the tracker has all the required bits
        for required in 'open init Client MailGW'.split():
            if not hasattr(tracker, required):
                raise TrackerError('Required tracker attribute "%s" missing' %
                                   required)

        # load and apply the config
        tracker.config = configuration.CoreConfig(tracker_home)
        tracker.dbinit.config = tracker.config

        tracker.optimize = optimize
        tracker.templates = templating.get_loader(tracker.config["TEMPLATES"])
        if optimize:
            tracker.templates.precompile()

        return tracker
Ejemplo n.º 17
0
    def testSecretMandatory_missing_file(self):

        # SETUP:
        self.munge_configini(mods=[
            ("secret_key = ", "file://secret_key"),
        ])

        config = configuration.CoreConfig()

        with self.assertRaises(configuration.OptionValueError) as cm:
            config.load(self.dirname)

        print(cm.exception)
        self.assertEqual(cm.exception.args[0].setting, "secret_key")
Ejemplo n.º 18
0
    def testLoadConfigNoConfig(self):
        """ run load on a directory missing config.ini """

        c = os.path.join(self.dirname, configuration.Config.INI_FILE)
        if os.path.exists(c):
            os.remove(c)
        else:
            self.assertFalse("setup failed missing config.ini")

        config = configuration.CoreConfig()

        with self.assertRaises(configuration.NoConfigError) as cm:
            config.load(self.dirname)

        print(cm.exception)
        self.assertEqual(cm.exception.args[0], self.dirname)
Ejemplo n.º 19
0
    def testSetMailPassword_with_set_username(self):
        """ Set [mail] username and set the password.
            Should have both values set.
        """
        # SETUP: set mail username
        self.munge_configini(mods=[("username = "******"foo"),
                                   ("#password = "******"passwordfoo",
                                    "password = "******"[mail]")

        config = configuration.CoreConfig()

        config.load(self.dirname)

        self.assertEqual(config['MAIL_USERNAME'], 'foo')
        self.assertEqual(config['MAIL_PASSWORD'], 'passwordfoo')
Ejemplo n.º 20
0
def new_config(debug=False, prefix=default_prefix):
    if not prefix.startswith('/'):
        prefix = os.path.join(os.path.dirname(__file__), prefix)
    config = configuration.CoreConfig()
    config.detectors = configuration.UserConfig(
        os.path.join(prefix, "detectors/config.ini"))
    config.ext = configuration.UserConfig(
        os.path.join(prefix, "extensions/config.ini"))
    config.DATABASE = "db"
    #config.logging = MockNull()
    # these TRACKER_WEB and MAIL_DOMAIN values are used in mailgw tests
    if debug:
        config.LOGGING_LEVEL = "DEBUG"
    config.MAIL_DOMAIN = "your.tracker.email.domain.example"
    config.TRACKER_WEB = "http://tracker.example/cgi-bin/roundup.cgi/bugs/"
    return config
Ejemplo n.º 21
0
    def testSecretMandatory_load_from_file(self):

        # SETUP:
        self.munge_configini(mods=[
            ("secret_key = ", "file://secret_key"),
        ])

        secret = "ASDQWEZXCRFVBGTYHNMJU"
        with open(self.dirname + "/secret_key", "w") as f:
            f.write(secret + "\n")

        config = configuration.CoreConfig()

        config.load(self.dirname)

        self.assertEqual(config['WEB_SECRET_KEY'], secret)
Ejemplo n.º 22
0
    def testLoginAttemptsMin(self):
        config = configuration.CoreConfig()

        self.assertEqual(None,
                   config._get_option('WEB_LOGIN_ATTEMPTS_MIN').set("0"))
        self.assertEqual(None,
                    config._get_option('WEB_LOGIN_ATTEMPTS_MIN').set("200"))

        self.assertRaises(configuration.OptionValueError,
                   config._get_option('WEB_LOGIN_ATTEMPTS_MIN').set, "fred")

        self.assertRaises(configuration.OptionValueError,
                   config._get_option('WEB_LOGIN_ATTEMPTS_MIN').set, "-1")

        self.assertRaises(configuration.OptionValueError,
                   config._get_option('WEB_LOGIN_ATTEMPTS_MIN').set, "")
Ejemplo n.º 23
0
    def testNullableSecret_with_file_value(self):

        self.munge_configini(mods=[
            ("password = "******"file://db_password"),
        ])

        # file with no value just newline.
        with open(self.dirname + "/db_password", "w") as f:
            f.write("test\n")

        config = configuration.CoreConfig()

        config.load(self.dirname)

        v = config['RDBMS_PASSWORD']

        self.assertEqual(v, "test")
Ejemplo n.º 24
0
    def testInvalidIndexerLanguage_w_empty_no_xapian(self):
        """ Test case for empty indexer if xapian really isn't installed

            This should behave like testInvalidIndexerLanguage_xapian_missing
            but without all the sys.modules mangling.
        """
        print("Testing when xapian is not installed")

        # SETUP: set indexer_language value to an invalid value.
        self.munge_configini(mods=[("indexer = ",
                                    ""), ("indexer_language = ", "NO_LANG")])

        config = configuration.CoreConfig()

        config.load(self.dirname)

        self.assertEqual(config['INDEXER_LANGUAGE'], 'NO_LANG')
Ejemplo n.º 25
0
    def testSecretMandatory_empty_file(self):

        self.munge_configini(mods=[
            ("secret_key = ", "file:// secret_key"),
        ])

        # file with no value just newline.
        with open(self.dirname + "/secret_key", "w") as f:
            f.write("\n")

        config = configuration.CoreConfig()

        with self.assertRaises(configuration.OptionValueError) as cm:
            config.load(self.dirname)

        print(cm.exception.args)
        self.assertEqual(cm.exception.args[2], "Value must not be empty.")
Ejemplo n.º 26
0
    def testTrackerWeb(self):
        config = configuration.CoreConfig()

        self.assertEqual(None,
             config._get_option('TRACKER_WEB').set("http://foo.example/bar/"))
        self.assertEqual(None,
             config._get_option('TRACKER_WEB').set("https://foo.example/bar/"))

        self.assertRaises(configuration.OptionValueError,
             config._get_option('TRACKER_WEB').set, "https://foo.example/bar")

        self.assertRaises(configuration.OptionValueError,
             config._get_option('TRACKER_WEB').set, "htt://foo.example/bar/")

        self.assertRaises(configuration.OptionValueError,
             config._get_option('TRACKER_WEB').set, "htt://foo.example/bar")

        self.assertRaises(configuration.OptionValueError,
             config._get_option('TRACKER_WEB').set, "")
Ejemplo n.º 27
0
    def testUnsetMailPassword_with_set_username(self):
        """ Set [mail] username but don't set the 
            [mail] password. Should get an OptionValueError. 
        """
        # SETUP: set mail username
        self.munge_configini(mods=[
            ("username = "******"foo"),
        ], section="[mail]")

        config = configuration.CoreConfig()

        with self.assertRaises(configuration.OptionValueError) as cm:
            config.load(self.dirname)

        print(cm.exception)
        # test repr. The type is right since it passed assertRaises.
        self.assertIn("OptionValueError", repr(cm.exception))
        # look for 'not defined'
        self.assertEqual("not defined", cm.exception.args[1])
Ejemplo n.º 28
0
    def __init__(self, tracker_home, optimize=0):
        """New-style tracker instance constructor

        Parameters:
            tracker_home:
                tracker home directory
            optimize:
                if set, precompile html templates

        """
        self.tracker_home = tracker_home
        self.optimize = optimize
        # if set, call schema_hook after executing schema.py will get
        # same variables (in particular db) as schema.py main purpose is
        # for regression tests
        self.schema_hook = None
        self.config = configuration.CoreConfig(tracker_home)
        self.actions = {}
        self.cgi_actions = {}
        self.templating_utils = {}

        libdir = os.path.join(self.tracker_home, 'lib')
        self.libdir = os.path.isdir(libdir) and libdir or ''

        self.load_interfaces()
        self.templates = templating.get_loader(self.config["TEMPLATES"],
                                               self.config["TEMPLATE_ENGINE"])

        rdbms_backend = self.config.RDBMS_BACKEND

        self.backend = backends.get_backend(rdbms_backend)

        if self.optimize:
            self.templates.precompile()
            # initialize tracker extensions
            for extension in self.get_extensions('extensions'):
                extension(self)
            # load database schema
            self.schema = self._compile('schema.py')
            # load database detectors
            self.detectors = self.get_extensions('detectors')
            # db_open is set to True after first open()
            self.db_open = 0
Ejemplo n.º 29
0
    def testCopyConfig(self):

        self.munge_configini(mods=[("html_version = ", "xhtml")])

        config = configuration.CoreConfig()

        # verify config is initalized to defaults
        self.assertEqual(config['HTML_VERSION'], 'html4')

        # load config
        config.load(self.dirname)

        # loaded new option
        self.assertEqual(config['HTML_VERSION'], 'xhtml')

        # copy config
        config_copy = config.copy()

        # this should work
        self.assertEqual(config_copy['HTML_VERSION'], 'xhtml')
Ejemplo n.º 30
0
    def testSecretMandatory_load_from_abs_file(self):

        abs_file = "/tmp/secret_key.%s" % os.getpid()

        # SETUP:
        self.munge_configini(mods=[
            ("secret_key = ", "file://%s" % abs_file),
        ])

        secret = "ASDQWEZXCRFVBGTYHNMJU"
        with open(abs_file, "w") as f:
            f.write(secret + "\n")

        config = configuration.CoreConfig()

        config.load(self.dirname)

        self.assertEqual(config['WEB_SECRET_KEY'], secret)

        os.remove(abs_file)