Пример #1
0
 def setdefault(self):
     c = Config({"foo": "bar", "nested": {"leafkey": "leafval"}})
     assert c.setdefault("foo") == "bar"
     assert c.nested.setdefault("leafkey") == "leafval"
     assert c.setdefault("notfoo", "notbar") == "notbar"
     assert c.notfoo == "notbar"
     nested = c.nested.setdefault("otherleaf", "otherval")
     assert nested == "otherval"
     assert c.nested.otherleaf == "otherval"
Пример #2
0
 def runtime_can_skip_merging(self):
     path = join(CONFIGS_PATH, "yaml", "raft.yaml")
     config = Config(runtime_path=path, lazy=True)
     assert "outer" not in config._runtime
     assert "outer" not in config
     config.load_runtime(merge=False)
     # Test that we loaded into the per-level dict, but not the
     # central/merged config.
     assert "outer" in config._runtime
     assert "outer" not in config
Пример #3
0
 def unicode_replaced_with_env_value(self):
     # Python 3 doesn't allow you to put 'bytes' objects into
     # os.environ, so the test makes no sense there.
     if six.PY3:
         return
     os.environ["RAFT_FOO"] = "myunicode"
     c = Config(defaults={"foo": u"myoldvalue"})
     c.load_shell_env()
     assert c.foo == "myunicode"
     assert isinstance(c.foo, str)
Пример #4
0
 def preserves_merged_config(self):
     c = Config(
         defaults={"key": "default"}, overrides={"key": "override"}
     )
     assert c.key == "override"
     assert c._defaults["key"] == "default"
     c2 = c.clone()
     assert c2.key == "override"
     assert c2._defaults["key"] == "default"
     assert c2._overrides["key"] == "override"
Пример #5
0
 def pop(self):
     # Root
     c = Config(defaults={"foo": "bar"})
     assert c.pop("foo") == "bar"
     assert c == {}
     # With the default arg
     assert c.pop("wut", "fine then") == "fine then"
     # Leaf (different key to avoid AmbiguousMergeError)
     c.nested = {"leafkey": "leafval"}
     assert c.nested.pop("leafkey") == "leafval"
     assert c == {"nested": {}}
Пример #6
0
 def nested_dict_values_also_allow_dual_access(self):
     # TODO: ditto
     c = Config({"foo": "bar", "biz": {"baz": "boz"}})
     # Sanity check - nested doesn't somehow kill simple top level
     assert c.foo == "bar"
     assert c["foo"] == "bar"
     # Actual check
     assert c.biz.baz == "boz"
     assert c["biz"]["baz"] == "boz"
     assert c.biz["baz"] == "boz"
     assert c["biz"].baz == "boz"
Пример #7
0
 def project_can_skip_merging(self):
     config = Config(
         project_location=join(CONFIGS_PATH, "yml"), lazy=True
     )
     assert "outer" not in config._project
     assert "outer" not in config
     config.load_project(merge=False)
     # Test that we loaded into the per-level dict, but not the
     # central/merged config.
     assert "outer" in config._project
     assert "outer" not in config
Пример #8
0
            def arbitrary_types_work_too(self):
                os.environ["RAFT_FOO"] = "whatever"

                class Meh(object):
                    def __init__(self, thing=None):
                        pass

                old_obj = Meh()
                c = Config(defaults={"foo": old_obj})
                c.load_shell_env()
                assert isinstance(c.foo, Meh)
                assert c.foo is not old_obj
Пример #9
0
 def booleans(self):
     for input_, result in (
         ("0", False),
         ("1", True),
         ("", False),
         ("meh", True),
         ("false", True),
     ):
         os.environ["RAFT_FOO"] = input_
         c = Config(defaults={"foo": bool()})
         c.load_shell_env()
         assert c.foo == result
Пример #10
0
 def reinstatement_of_deleted_values_works_ok(self):
     # Sounds like a stupid thing to test, but when we have to track
     # deletions and mutations manually...it's an easy thing to overlook
     c = Config(defaults={"foo": "bar"})
     assert c.foo == "bar"
     del c["foo"]
     # Sanity checks
     assert "foo" not in c
     assert len(c) == 0
     # Put it back again...as a different value, for funsies
     c.foo = "formerly bar"
     # And make sure it stuck
     assert c.foo == "formerly bar"
Пример #11
0
 def merging_does_not_wipe_user_modifications_or_deletions(self):
     c = Config({"foo": {"bar": "biz"}, "error": True})
     c.foo.bar = "notbiz"
     del c["error"]
     assert c["foo"]["bar"] == "notbiz"
     assert "error" not in c
     c.merge()
     # Will be back to 'biz' if user changes don't get saved on their
     # own (previously they are just mutations on the cached central
     # config)
     assert c["foo"]["bar"] == "notbiz"
     # And this would still be here, too
     assert "error" not in c
Пример #12
0
        def attr_access_has_useful_error_msg(self):
            c = Config()
            try:
                c.nope
            except AttributeError as e:
                expected = """
No attribute or config key found for 'nope'

Valid keys: ['run', 'runners', 'sudo', 'tasks', 'timeouts']

Valid real attributes: ['clear', 'clone', 'env_prefix', 'file_prefix', 'from_data', 'global_defaults', 'load_base_conf_files', 'load_collection', 'load_defaults', 'load_overrides', 'load_project', 'load_runtime', 'load_shell_env', 'load_system', 'load_user', 'merge', 'pop', 'popitem', 'prefix', 'set_project_location', 'set_runtime_path', 'setdefault', 'update']
""".strip()  # noqa
                assert str(e) == expected
            else:
                assert False, "Didn't get an AttributeError on bad key!"
Пример #13
0
 def numeric_types_become_casted(self):
     tests = [
         (int, "5", 5),
         (float, "5.5", 5.5),
         # TODO: more?
     ]
     # Can't use '5L' in Python 3, even having it in a branch makes
     # it upset.
     if not six.PY3:
         tests.append((long, "5", long(5)))  # noqa
     for old, new_, result in tests:
         os.environ["RAFT_FOO"] = new_
         c = Config(defaults={"foo": old()})
         c.load_shell_env()
         assert c.foo == result
Пример #14
0
 def does_not_reload_file_data(self, load_yaml):
     path = join(CONFIGS_PATH, "yaml/")
     c = Config(system_prefix=path)
     c2 = c.clone()
     assert c2.outer.inner.hooray == "yaml"
     # Crummy way to say "only got called with this specific invocation
     # one time" (since assert_calls_with gets mad about other
     # invocations w/ different args)
     calls = load_yaml.call_args_list
     my_call = call("{}raft.yaml".format(path))
     try:
         calls.remove(my_call)
         assert my_call not in calls
     except ValueError:
         err = "{} not found in {} even once!"
         assert False, err.format(my_call, calls)
Пример #15
0
            def non_conflicting_values_are_merged(self):
                # NOTE: this is really just basic clone behavior.
                class MyConfig(Config):
                    @staticmethod
                    def global_defaults():
                        orig = Config.global_defaults()
                        orig["new"] = {"data": "ohai"}
                        return orig

                c = Config(defaults={"other": {"data": "hello"}})
                c["runtime"] = {"modification": "sup"}
                c2 = c.clone(into=MyConfig)
                # New default data from MyConfig present
                assert c2.new.data == "ohai"
                # As well as old default data from the cloned instance
                assert c2.other.data == "hello"
                # And runtime user mods from the cloned instance
                assert c2.runtime.modification == "sup"
Пример #16
0
 def update(self):
     c = Config(
         defaults={"foo": "bar", "nested": {"leafkey": "leafval"}}
     )
     # Regular update(dict)
     c.update({"foo": "notbar"})
     assert c.foo == "notbar"
     c.nested.update({"leafkey": "otherval"})
     assert c.nested.leafkey == "otherval"
     # Apparently allowed but wholly useless
     c.update()
     expected = {"foo": "notbar", "nested": {"leafkey": "otherval"}}
     assert c == expected
     # Kwarg edition
     c.update(foo="otherbar")
     assert c.foo == "otherbar"
     # Iterator of 2-tuples edition
     c.nested.update(
         [("leafkey", "yetanotherval"), ("newleaf", "turnt")]
     )
     assert c.nested.leafkey == "yetanotherval"
     assert c.nested.newleaf == "turnt"
Пример #17
0
 def user_overrides_systemwide(self):
     c = Config(
         system_prefix=join(CONFIGS_PATH, "yaml/"),
         user_prefix=join(CONFIGS_PATH, "json/"),
     )
     assert c.outer.inner.hooray == "json"
Пример #18
0
 def json_prevents_python(self):
     c = Config(system_prefix=join(CONFIGS_PATH, "json-and-python/"))
     assert "python_only" not in c
     assert "json-only" in c
     assert c.shared == "json-value"
Пример #19
0
 def yml_prevents_json_or_python(self):
     c = Config(system_prefix=join(CONFIGS_PATH, "three-of-em/"))
     assert "json-only" not in c
     assert "python_only" not in c
     assert "yml-only" in c
     assert c.shared == "yml-value"
Пример #20
0
 def runtime_overrides_collection(self):
     c = Config(runtime_path=join(CONFIGS_PATH, "json", "raft.json"))
     c.load_collection({"outer": {"inner": {"hooray": "defaults"}}})
     c.load_runtime()
     assert c.outer.inner.hooray == "json"
Пример #21
0
 def runtime_overrides_env_vars(self):
     os.environ["RAFT_OUTER_INNER_HOORAY"] = "env"
     c = Config(runtime_path=join(CONFIGS_PATH, "json", "raft.json"))
     c.load_runtime()
     c.load_shell_env()
     assert c.outer.inner.hooray == "json"
Пример #22
0
 def env_vars_override_collection(self):
     os.environ["RAFT_OUTER_INNER_HOORAY"] = "env"
     c = Config()
     c.load_collection({"outer": {"inner": {"hooray": "defaults"}}})
     c.load_shell_env()
     assert c.outer.inner.hooray == "env"
Пример #23
0
 def env_vars_override_systemwide(self):
     os.environ["RAFT_OUTER_INNER_HOORAY"] = "env"
     c = Config(system_prefix=join(CONFIGS_PATH, "yaml/"))
     c.load_shell_env()
     assert c.outer.inner.hooray == "env"
Пример #24
0
 def env_vars_override_project(self):
     os.environ["RAFT_OUTER_INNER_HOORAY"] = "env"
     c = Config(project_location=join(CONFIGS_PATH, "yaml"))
     c.load_project()
     c.load_shell_env()
     assert c.outer.inner.hooray == "env"
Пример #25
0
 def project_overrides_collection(self):
     c = Config(project_location=join(CONFIGS_PATH, "yaml"))
     c.load_project()
     c.load_collection({"outer": {"inner": {"hooray": "defaults"}}})
     assert c.outer.inner.hooray == "yaml"
Пример #26
0
 def user_overrides_collection(self):
     c = Config(user_prefix=join(CONFIGS_PATH, "json/"))
     c.load_collection({"outer": {"inner": {"hooray": "defaults"}}})
     assert c.outer.inner.hooray == "json"
Пример #27
0
 def systemwide_overrides_collection(self):
     c = Config(system_prefix=join(CONFIGS_PATH, "yaml/"))
     c.load_collection({"outer": {"inner": {"hooray": "defaults"}}})
     assert c.outer.inner.hooray == "yaml"
Пример #28
0
 def collection_overrides_defaults(self):
     c = Config(defaults={"nested": {"setting": "default"}})
     c.load_collection({"nested": {"setting": "collection"}})
     assert c.nested.setting == "collection"
Пример #29
0
 def _uncastable_type(self, default):
     os.environ["RAFT_FOO"] = "stuff"
     c = Config(defaults={"foo": default})
     c.load_shell_env()
Пример #30
0
 def boolean_type_inputs_with_non_boolean_defaults(self):
     for input_ in ("0", "1", "", "meh", "false"):
         os.environ["RAFT_FOO"] = input_
         c = Config(defaults={"foo": "bar"})
         c.load_shell_env()
         assert c.foo == input_