view tests/test.py @ 284:4aaf74858d07

Some links to AWS docu into the aws moduleSome links to AWS docu into the aws moduleSome links to AWS docu into the aws moduleSome links to AWS docu into the aws moduleSome links to AWS docu into the aws moduleSome links to AWS docu into the aws moduleSome links to AWS docu into the aws moduleSome links to AWS docu into the aws module
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 07 Dec 2020 01:59:11 +0100
parents af371f9c016d
children 6a044778371a
line wrap: on
line source

# -*- coding: utf-8 -*-

import sys
import os
import unittest
import platform
import io

sys.path.insert(
    0,
    os.path.abspath(
        os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))))

import configmix
import configmix.ini
import configmix.yaml
import configmix.json
import configmix.py
import configmix.toml
from configmix.compat import u


TESTDATADIR = os.path.join(
    os.path.abspath(os.path.dirname(__file__)),
    "data")


class T01Basic(unittest.TestCase):

    """Check with low-level internal interfaces"""

    def __check_types(self, cfg):
        self.assertEqual(u("the value"),
                         cfg.get("key1"))
        self.assertTrue(isinstance(cfg.get("key1"), type(u(''))))
        self.assertEqual(2, cfg.get("key2"))
        self.assertEqual(5.7, cfg.get("key3"))
        self.assertTrue(isinstance(cfg.get("key1"), type(u(''))))
        self.assertTrue(cfg.get("key4"))
        self.assertTrue(isinstance(cfg.get("key4"), bool))
        self.assertFalse(cfg.get("key5"))
        self.assertTrue(isinstance(cfg.get("key5"), bool))
        self.assertEqual(255, cfg.get("key6"))
        self.assertEqual(u("Umlaute: ÄÖÜäöüß"),
                         cfg.get("key7"))

    def __check_comment(self, cfg):
        # Check comments: low level comments are *not* filtered
        self.assertEqual(u("Comment 1"), cfg.get("__comment1"))
        self.assertEqual(u("Comment no 2"), cfg.get("__comment2"))

    def __check_no_comment(self, cfg):

        def _c(name):
            def _f():
                cfg[u(name)]
            return _f

        # Variables with leading underscores are *not*  imported by default
        self.assertRaises(KeyError, _c("__comment1"))
        self.assertRaises(KeyError, _c("__comment2"))

    def __check_tree(self, cfg):
        self.assertEqual(u("in the root namespace"),
                         cfg.get("key1"))
        self.assertEqual(u("in the root namespace -- too"),
                         cfg.get("key2"))
        self.assertEqual(32,
                         cfg["tree1"]["key3"])
        self.assertEqual(u("get this as `tree1.tree2.key4'"),
                         cfg["tree1"]["tree2"]["key4"])
        self.assertTrue(cfg["tree1"]["tree2"]["key5"])

    def test01_ini_types(self):
        cfg = configmix.ini.load(os.path.join(TESTDATADIR, "conf1.ini"))
        self.__check_types(cfg)
        self.__check_comment(cfg)

    def test01_toml_types(self):
        cfg = configmix.toml.load(os.path.join(TESTDATADIR, "conf1.toml"))
        self.__check_types(cfg)
        self.__check_comment(cfg)

    def test02_py_types(self):
        cfg = configmix.py.load(os.path.join(TESTDATADIR, "conf1.py"))
        self.__check_types(cfg)
        self.__check_no_comment(cfg)

    def test03_yaml_types(self):
        with io.open(os.path.join(TESTDATADIR, "conf1.yml"), "rt",
                     encoding="utf-8") as f:
            cfg = configmix.yaml.safe_load(f)
            if configmix.yaml.OrderedDict:
                self.assertTrue(isinstance(cfg, configmix.yaml.OrderedDict))
            self.__check_types(cfg)
            self.__check_comment(cfg)

    def test04_json_types(self):
        cfg = configmix.json.load(os.path.join(TESTDATADIR, "conf1.json"))
        self.assertTrue(isinstance(cfg, configmix.json.DictImpl))
        self.__check_types(cfg)
        self.__check_comment(cfg)

    def test05_py_export_all(self):
        # When __all__ is given only it's keys are exported
        cfg = configmix.py.load(os.path.join(TESTDATADIR, "conf2.py"))
        self.assertEqual(u("the next value"), cfg.get("key1"))
        self.assertTrue(isinstance(cfg.get("key1"), type(u(''))))
        self.assertTrue(cfg.get("key2") is None)

    def test06_py_hide_private(self):
        # When no __all__ is given all symbols with leading "_" are hidden
        cfg = configmix.py.load(os.path.join(TESTDATADIR, "conf3.py"))
        self.assertEqual(u("the next value "), cfg.get("key1"))
        self.assertTrue(isinstance(cfg.get("key1"), type(u(''))))
        self.assertTrue(cfg.get("_key2") is None)

    def test07_ini_tree(self):
        cfg = configmix.ini.load(os.path.join(TESTDATADIR, "conf10.ini"))
        self.__check_tree(cfg)

    def test08_py_tree(self):
        cfg = configmix.py.load(os.path.join(TESTDATADIR, "conf10.py"))
        self.__check_tree(cfg)

    def test09_yaml_tree(self):
        with io.open(os.path.join(TESTDATADIR, "conf10.yml"), "rt",
                     encoding="utf-8") as f:
            cfg = configmix.yaml.safe_load(f)
            self.__check_tree(cfg)

    def test10_json_tree(self):
        cfg = configmix.json.load(os.path.join(TESTDATADIR, "conf10.json"))
        self.__check_tree(cfg)

    def test11_toml_tree(self):
        cfg = configmix.toml.load(os.path.join(TESTDATADIR, "conf10.toml"))
        self.__check_tree(cfg)


class _T02MixinLoadAndMerge:

    def test01_load(self):
        cfg = self._load(
            os.path.join(TESTDATADIR, "conf20.yml"),
            os.path.join(TESTDATADIR, "conf21.yml"))

        self.assertEqual(u("the_database_user"),
                         cfg.getvar_s("db.user.name"))
        self.assertEqual(u("the-database-password"),
                         cfg.getvar_s("db.user.pwd"))

        tmpdir = cfg.getvar_s("tmpdir")
        if os.name == 'nt':
            self.assertFalse(u('/') in tmpdir)
        self.assertEqual(os.path.normpath(
            os.path.abspath(os.path.join(os.getcwd(), "tmp"))),
                         tmpdir)

        self.assertEqual(u("anotherhost"),
                         cfg.getvar_s("db.locinfo.ro.hostname"))
        self.assertEqual(u("localhost"),
                         cfg.getvar_s("db.locinfo.rw.hostname"))

        self.assertEqual(5432, cfg.getvar_s("db.locinfo.ro.port"))

        url = cfg.getvar_s("db.engines.ro.url")
        self.assertEqual(
            u("postgresql+psycopg2://the_database_user:the-database-password@anotherhost:5432/my_database_catalog"),
            url)

        self.assertEqual(u("not a list any more"),
                         cfg.getvar_s("test.List"))

        self.assertEqual(list(range(0, 3)),
                         cfg.getvar_s("test.Str"))

    def test02_load_with_ini(self):
        cfg = self._load(
            os.path.join(TESTDATADIR, "conf20.yml"),
            os.path.join(TESTDATADIR, "conf21.yml"),
            os.path.join(TESTDATADIR, "conf22.ini"))

        self.assertEqual(u("the_database_user_2"),
                         cfg.getvar_s("db.user.name"))
        self.assertEqual(u("the-database-password-2"),
                         cfg.getvar_s("db.user.pwd"))

        tmpdir = cfg.getvar_s("tmpdir")
        self.assertEqual(u(os.getcwd()) + u("/tmp\\2"), tmpdir)

        self.assertEqual(u("3rd-host"),
                         cfg.getvar_s("db.locinfo.ro.hostname"))
        self.assertEqual(u("localhost"),
                         cfg.getvar_s("db.locinfo.rw.hostname"))

        self.assertEqual(5432, cfg.getvar_s("db.locinfo.ro.port"))

        url = cfg.getvar_s("db.engines.ro.url")
        self.assertEqual(
            u("postgresql+psycopg2://the_database_user_2:the-database-password-2@3rd-host:5432/my_database_catalog"),
            url)

    def test02_load_with_json(self):
        cfg = self._load(
            os.path.join(TESTDATADIR, "conf20.yml"),
            os.path.join(TESTDATADIR, "conf21.yml"),
            # .ini replaced with an equivalent .json
            os.path.join(TESTDATADIR, "conf23.json"))

        self.assertEqual(u("the_database_user_2"),
                         cfg.getvar_s("db.user.name"))
        self.assertEqual(u("the-database-password-2"),
                         cfg.getvar_s("db.user.pwd"))

        tmpdir = cfg.getvar_s("tmpdir")
        self.assertEqual(u(os.getcwd()) + u("/tmp\\3"), tmpdir)

        self.assertEqual(u("3rd-host"),
                         cfg.getvar_s("db.locinfo.ro.hostname"))
        self.assertEqual(u("localhost"),
                         cfg.getvar_s("db.locinfo.rw.hostname"))

        self.assertEqual(5432, cfg.getvar_s("db.locinfo.ro.port"))

        url = cfg.getvar_s("db.engines.ro.url")
        self.assertEqual(
            u("postgresql+psycopg2://the_database_user_2:the-database-password-2@3rd-host:5432/my_database_catalog"),
            url)

    def test02_load_with_toml(self):
        cfg = self._load(
            os.path.join(TESTDATADIR, "conf20.yml"),
            os.path.join(TESTDATADIR, "conf21.yml"),
            # .ini replaced with an equivalent .toml
            os.path.join(TESTDATADIR, "conf24.toml"))

        self.assertEqual(u("the_database_user_2"),
                         cfg.getvar_s("db.user.name"))
        self.assertEqual(u("the-database-password-2"),
                         cfg.getvar_s("db.user.pwd"))

        tmpdir = cfg.getvar_s("tmpdir")
        self.assertEqual(u(os.getcwd()) + u("/tmp\\4"), tmpdir)

        self.assertEqual(u("3rd-host"),
                         cfg.getvar_s("db.locinfo.ro.hostname"))
        self.assertEqual(u("localhost"),
                         cfg.getvar_s("db.locinfo.rw.hostname"))

        self.assertEqual(5432, cfg.getvar_s("db.locinfo.ro.port"))

        url = cfg.getvar_s("db.engines.ro.url")
        self.assertEqual(
            u("postgresql+psycopg2://the_database_user_2:the-database-password-2@3rd-host:5432/my_database_catalog"),
            url)

    def test03_namespace(self):
        cfg = self._load(
            os.path.join(TESTDATADIR, "conf20.yml"),
            os.path.join(TESTDATADIR, "conf21.yml"),
            os.path.join(TESTDATADIR, "conf22.ini"))
        self.assertEqual(u(os.getcwd()), cfg.getvar("OS:cwd"))
        self.assertEqual(u(platform.python_version()),
                         cfg.getvar_s("PY:version"))

    def test04_no_filter(self):
        cfg = self._load(
            os.path.join(TESTDATADIR, "conf20.yml"),
            os.path.join(TESTDATADIR, "conf21.yml"),
            os.path.join(TESTDATADIR, "conf22.ini"))

        def _look():
            return cfg.getvar("OS:cwd|upper")

        self.assertRaises(KeyError, _look)

    def test05_comments(self):
        cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml"),
                         os.path.join(TESTDATADIR, "conf21.yml"),
                         os.path.join(TESTDATADIR, "conf22.ini"),
                         os.path.join(TESTDATADIR, "conf23.json"),
                         os.path.join(TESTDATADIR, "conf24.toml"))

        def _c(name):
            def _f():
                cfg.getvar_s(name)
            return _f

        # Variables with leading underscores are *not*  imported by default
        self.assertEqual(0o0027, int(cfg.getvar_s("process.umask"), 0))
        self.assertRaises(KeyError, _c("process.__doc1"))
        self.assertRaises(KeyError, _c("db.__comment1"))
        self.assertRaises(KeyError, _c("db.user.__doc2"))

    def test06_check_all_comments(self):
        cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml"),
                         os.path.join(TESTDATADIR, "conf21.yml"),
                         os.path.join(TESTDATADIR, "conf22.ini"),
                         os.path.join(TESTDATADIR, "conf23.json"),
                         os.path.join(TESTDATADIR, "conf24.toml"))

        def _check(d):
            for k, v in d.items():
                self.assertFalse(configmix._is_comment(k))
                if isinstance(v, dict):
                    _check(v)

        _check(cfg)

    def test07_deletions(self):
        cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml"),
                         os.path.join(TESTDATADIR, "conf21.yml"),
                         os.path.join(TESTDATADIR, "conf22.ini"),
                         os.path.join(TESTDATADIR, "conf23.json"),
                         os.path.join(TESTDATADIR, "conf24.toml"),
                         os.path.join(TESTDATADIR, "delete-in-dict.yml"))
        # automatic clean-up
        self.assertRaises(KeyError, cfg.getvar_s, "not-deleted")
        # explicit deletion
        self.assertRaises(KeyError, cfg.getvar_s, "to-be-deleted")
        self.assertRaises(KeyError, cfg.getvar_s, "db.user.name")
        self.assertEqual("the-database-password-2",cfg.getvar_s("db.user.pwd"))
        self.assertRaises(KeyError, cfg.getvar_s, "test.Str")
        self.assertEqual("not a list any more", cfg.getvar_s("test.List"))
        self.assertEqual("the last value",
                         cfg.getvar_s("to-be-deleted-but-reassigned"))


class T02LoadAndMerge(_T02MixinLoadAndMerge, unittest.TestCase):

    def setUp(self):
        self._load = configmix.load

    def test08_identity(self):
        cfg = configmix.ini.load(os.path.join(TESTDATADIR, "conf1.ini"))
        cfg2 = configmix.merge(cfg, None)
        self.assertEqual(id(cfg), id(cfg2))

    def test09_identity(self):
        cfg = configmix.ini.load(os.path.join(TESTDATADIR, "conf1.ini"))
        cfg2 = configmix.merge(cfg, {})
        self.assertEqual(id(cfg), id(cfg2))


class T03SafeLoadAndMerge(_T02MixinLoadAndMerge, unittest.TestCase):

    def setUp(self):
        self._load = configmix.safe_load

    def test08_deepcopy(self):
        cfg = configmix.ini.load(os.path.join(TESTDATADIR, "conf1.ini"))
        cfg2 = configmix.safe_merge(cfg, None)
        self.assertNotEqual(id(cfg), id(cfg2))

    def test09_deepcopy(self):
        cfg = configmix.ini.load(os.path.join(TESTDATADIR, "conf1.ini"))
        cfg2 = configmix.safe_merge(cfg, {})
        self.assertNotEqual(id(cfg), id(cfg2))


class T04CustomExtension(unittest.TestCase):

    def setUp(self):
        self._reset()

    def tearDown(self):
        self._reset()

    def _reset(self):
        configmix.clear_assoc()
        for pat, fmode in configmix.DEFAULT_ASSOC:
            configmix.set_assoc(pat, fmode)

    def test01_additional(self):
        configmix.set_assoc("*.conf", configmix.get_default_assoc("*.yml"))
        cfg = configmix.load(
            os.path.join(TESTDATADIR, "conf1.ini"),
            os.path.join(TESTDATADIR, "conf30.conf"))
        self.assertEqual(u("Umlaute: ÄÖÜäöüß"), cfg.getvar_s("key7"))
        self.assertEqual(u("new value"), cfg.getvar_s("key-new"))

    def test02_only_style_wrong_style(self):
        configmix.clear_assoc()
        configmix.set_assoc("*.conf", configmix.get_default_assoc("*.yml"))

        def _ld():
            return configmix.load(os.path.join(TESTDATADIR, "conf1.ini"),
                                  os.path.join(TESTDATADIR, "conf30.conf"))

        self.assertRaises(ValueError, _ld)

    def test02_ignore_one_style(self):
        configmix.clear_assoc()
        configmix.set_assoc("*.conf", configmix.get_default_assoc("*.yml"))
        configmix.set_assoc("*", "-*-ignore-*-", append=True)

        cfg = configmix.load(os.path.join(TESTDATADIR, "conf1.ini"),
                             os.path.join(TESTDATADIR, "conf30.conf"))
        self.assertEqual(u("new value"), cfg.getvar_s("key-new"))
        self.assertRaises(KeyError, cfg.getvar_s, "key1")

    def test02_ignore_all(self):
        configmix.clear_assoc()
        configmix.set_assoc("*.conf", configmix.get_default_assoc("*.yml"))
        # This inserts at index 0 effectively ignoring all configuration files!
        configmix.set_assoc("*", "-*-ignore-*-")

        cfg = configmix.load(os.path.join(TESTDATADIR, "conf1.ini"),
                             os.path.join(TESTDATADIR, "conf30.conf"))
        self.assertRaises(KeyError, cfg.getvar_s, "key-new")
        self.assertRaises(KeyError, cfg.getvar_s, "key1")

    def test03_only_style_corrrect_style(self):
        configmix.clear_assoc()
        configmix.set_assoc("*.conf", configmix.get_default_assoc("*.yml"))
        cfg = configmix.load(os.path.join(TESTDATADIR, "conf30.conf"))
        self.assertEqual(u("new value"), cfg.getvar_s("key-new"))

        def _g():
            return cfg.getvar_s("key7")

        self.assertRaises(KeyError, _g)

    def test04_determine_mode(self):
        configmix.clear_assoc()
        configmix.set_assoc("*.conf", configmix.try_determine_filemode)
        cfg = configmix.load(os.path.join(TESTDATADIR, "conf30.conf"))
        self.assertEqual(u("new value"), cfg.getvar_s("key-new"))

        self.assertRaises(KeyError, cfg.getvar_s, "key7")

    def test05_try_determine_mode_none(self):
        configmix.clear_assoc()
        configmix.set_assoc("*.conf", configmix.try_determine_filemode)

        def _ld():
            return configmix.load(os.path.join(TESTDATADIR, "no-mode.conf"))

        self.assertRaises(ValueError, _ld)

    def test06_try_determine_mode_unknown(self):
        configmix.clear_assoc()
        configmix.set_assoc("*.conf", configmix.try_determine_filemode)

        def _ld():
            return configmix.load(os.path.join(TESTDATADIR, "unknown-mode.conf"))

        self.assertRaises(KeyError, _ld)


class T05SubstituteExpand(unittest.TestCase):

    def setUp(self):
        self._reset()

    def tearDown(self):
        self._reset()

    def _reset(self):
        configmix.clear_assoc()
        for pat, fmode in configmix.DEFAULT_ASSOC:
            configmix.set_assoc(pat, fmode)

    def test01_expand_int_ini(self):
        cfg = configmix.load(os.path.join(TESTDATADIR, "conf1.ini"))
        self.assertEqual(2, cfg.getvar_s("key100"))

    def test02_expand_int_indirect_ini(self):
        cfg = configmix.load(os.path.join(TESTDATADIR, "conf1.ini"))
        self.assertEqual(2, cfg.getvar_s("key102"))

    def test03_expand_int2str_ini(self):
        cfg = configmix.load(os.path.join(TESTDATADIR, "conf1.ini"))
        self.assertEqual("the 2 value", cfg.getvar_s("key101"))

    def test04_expand_intint2str_ini(self):
        cfg = configmix.load(os.path.join(TESTDATADIR, "conf1.ini"))
        self.assertEqual("22", cfg.getvar_s("key103"))


if __name__ == "__main__":
    unittest.main()