Esempio n. 1
0
def test_bind_non_extensions():
    dut = DictMentor()
    with pytest.raises(
        ValueError, 
        match='Cannot bind extension due to missing interface requirements'
    ):
        dut.bind("Not an extension")
Esempio n. 2
0
def test_load_yaml_with_stream():
    import os
    fn = os.path.join(os.path.dirname(__file__), 'resources/simple.yaml')
    dut = DictMentor()
    with open(fn, 'r') as fp:
        dct = dut.load_yaml(fp)

    expected = dict(root=dict(a=1, b=2, c=dict(ca=31, cb=32)))
    assert dct == expected
Esempio n. 3
0
def test_bind_extensions_via_init():
    env = ext.Environment()
    extres = ext.ExternalResource()

    dut = DictMentor(env, extres)
    assert len(dut._extensions) == 2
    assert dut._extensions[0] == env
    assert dut._extensions[1] == extres

    dut = DictMentor(env)
    assert len(dut._extensions) == 1
    assert dut._extensions[0] == env
Esempio n. 4
0
    def _augment(self, configuration: PartialConfig, base_path: str) -> Any:
        """Augments the configuration by using dictmentor with `Environment`,
        `ExternalResource` and `ExternalYamlResource` plguins."""
        _ = self  # Fake usage
        assert isinstance(base_path, str)

        # pnp configuration is probably of list of tasks. dictmentor needs a dict ...
        # ... let's fake it ;-)
        cfg = dict(fake_root=configuration)

        mentor = DictMentor(ext.Environment(fail_on_unset=True),
                            ext.ExternalResource(base_path=base_path),
                            ext.ExternalYamlResource(base_path=base_path))

        # Remove the faked dictionary as root level
        return mentor.augment(cfg)['fake_root']
Esempio n. 5
0
def make_mentor(config_path):
    """Creates an instance of the dictmentor with configured plugins."""
    from dictmentor import DictMentor, ext  # type: ignore
    return DictMentor(
        ext.Environment(fail_on_unset=True),
        ext.ExternalResource(base_path=os.path.dirname(config_path)),
        ext.ExternalYamlResource(base_path=os.path.dirname(config_path)))
Esempio n. 6
0
File: mqtt.py Progetto: nagu4dwh/pnp
 def _configure(self, object_id, node_id):
     configure_key = str(object_id) + str(node_id)
     if configure_key not in self.configured:
         base_topic, config_topic, state_topic = self._topics(
             object_id, node_id)
         mentor = DictMentor(
             ext.Variables(fail_on_unset=True,
                           discovery_prefix=self.discovery_prefix,
                           component=self.component,
                           object_id=object_id,
                           node_id=node_id,
                           base_topic=base_topic,
                           config_topic=config_topic,
                           state_topic=state_topic))
         config_augmented = mentor.augment(self.config)
         self._publish(config_augmented, config_topic, retain=True)
         self.configured[configure_key] = True
Esempio n. 7
0
    def _configure(self, object_id, node_id):
        configure_key = str(object_id) + str(node_id)
        if configure_key not in self.configured:
            base_topic, config_topic, state_topic, attr_topic = self._topics(object_id, node_id)
            mentor = DictMentor(
                ext.Variables(
                    fail_on_unset=True,
                    discovery_prefix=self.discovery_prefix,
                    component=self.component,
                    object_id=object_id,
                    node_id=node_id,
                    base_topic=base_topic,
                    config_topic=config_topic,
                    **{
                        self.CONST_STATE_TOPIC: state_topic,
                        self.CONST_JSON_ATTRIBUTES_TOPIC: attr_topic
                    }
                )
            )
            config_augmented = mentor.augment(self.config)
            if self.CONST_STATE_TOPIC in config_augmented:
                self.logger.warning(
                    "%s is part of your config, but will be ignored",
                    self.CONST_STATE_TOPIC
                )
            if self.CONST_JSON_ATTRIBUTES_TOPIC in config_augmented:
                self.logger.warning(
                    "%s is part of your config, but will be ignored",
                    self.CONST_JSON_ATTRIBUTES_TOPIC
                )

            config_augmented[self.CONST_STATE_TOPIC] = state_topic
            config_augmented[self.CONST_JSON_ATTRIBUTES_TOPIC] = attr_topic

            self._publish(config_augmented, config_topic, retain=True)
            self.configured[configure_key] = True
Esempio n. 8
0
def test_environment_with_multiple_patterns():
    jstr = '{"a": 1, "file_path": "{{var::a}}-{{var::b}}-{{var::c}}"}'
    res = DictMentor().bind(Variables(a='aval', b='bval',
                                      c='cval')).load_yaml(jstr)

    assert res == {'a': 1, 'file_path': 'aval-bval-cval'}
Esempio n. 9
0
def test_load_yaml_invalid():
    with pytest.raises(
        TypeError, 
        match="Argument '_yaml' is whether a stream, nor a file, nor a string"
    ):
        DictMentor().load_yaml(5)
Esempio n. 10
0
def test_init_extensions_with_non_iterable():
    dut = DictMentor()
    env = ext.Environment()
    dut._init_extensions(env)
    assert len(dut._extensions) == 1
    assert dut._extensions[0] == env
Esempio n. 11
0
def test_environment_with_nested_inline_default():
    jstr = '{"a": 1, "file_path": "my_file.{{env::ENVIRONMENT:={{env::DEFAULT}}.cfg}}"}'
    with modified_environ('ENVIRONMENT', DEFAULT='the_default'):
        res = DictMentor().bind(Environment()).load_yaml(jstr)

    assert res == {'a': 1, 'file_path': 'my_file.the_default.cfg'}
Esempio n. 12
0
# Import DictMentor and extensions
import dictmentor.extensions as ext
from dictmentor import DictMentor, utils

yml = """
statements:
  my_env: "{{var::my_env}}"
  home: "{{var::home}}"
  unknown: "{{var::unknown}}"
  combined: "{{var::my_env}}@{{var::home}}"
"""

var_ext = ext.Variables(
    my_env='development',
    home="/home/pi",
)
result = DictMentor().bind(var_ext).load_yaml(yml)

from pprint import pprint
pprint(result)

# Result:
# {'statements': {'combined': 'development@/home/pi',
#                 'home': '/home/pi',
#                 'my_env': 'development',
#                 'unknown': 'none'}}
Esempio n. 13
0
def test_environment_with_inline_default():
    jstr = '{"a": 1, "file_path": "my_file.{{env::ENVIRONMENT:=local}}.cfg"}'
    with modified_environ('ENVIRONMENT'):
        res = DictMentor().bind(Environment()).load_yaml(jstr)

    assert res == {'a': 1, 'file_path': 'my_file.local.cfg'}
Esempio n. 14
0
def test_environment_with_multiple_patterns():
    jstr = '{"a": 1, "file_path": "{{env::A}}-{{env::B}}-{{env::C}}"}'
    with modified_environ(A='aval', B='bval', C='cval'):
        res = DictMentor().bind(Environment()).load_yaml(jstr)

    assert res == {'a': 1, 'file_path': 'aval-bval-cval'}
Esempio n. 15
0
import os
from dictmentor import DictMentor, extensions as ext, utils


base_path = os.path.dirname(__file__)
dm = DictMentor(
    ext.Environment(),
    ext.ExternalResource(base_path=base_path),
    ext.ExternalYamlResource(base_path=base_path)
)

yml = """
products:
    - external: item1.yaml
    - external: item2.yaml
home_directory: "{{env::HOME}}"
extraction_sql: "{{external::products.sql}}"
"""

with utils.modified_environ(HOME="/home/pi"):
    res = dm.load_yaml(yml)

from pprint import pprint
pprint(res)

# Result:
# {'extraction_sql': '-- Contents of products.sql\nSELECT *\nFROM products\n;',
#  'home_directory': '/home/pi',
#  'products': [{'item1': {'price': 50, 'stock': 100}},
#               {'item2': {'price': 99, 'stock': 10}}]}
Esempio n. 16
0
# Import DictMentor and extensions
import dictmentor.extensions as ext
from dictmentor import DictMentor

import os

base_path = os.path.dirname(__file__)

yml = """
statements:
  external: "inner.yaml"
"""

result = DictMentor().bind(
    ext.ExternalYamlResource(base_path=base_path)).load_yaml(yml)

from pprint import pprint

pprint(result)

# Result:
# {'statements': {'inner': {'item1': None,
#                           'item2': {'price': 50},
#                           'item3': {'count': 5, 'price': 100, 'sold': 200}}}}
Esempio n. 17
0
# Import DictMentor and extensions
import dictmentor.extensions as ext
from dictmentor import DictMentor, utils

yml = """
statements:
  my_env: "{{env::MY_ENV}}"
  home: "{{env::HOME}}"
  unknown: "{{env::UNKNOWN}}"
  with_default: "{{env::UNKNOWN:=the_default}}"
"""

# Make sure that MY_ENV is set and that UNKNOWN is unset
with utils.modified_environ("UNKNOWN", MY_ENV='development'):
    result = DictMentor().bind(ext.Environment()).load_yaml(yml)

from pprint import pprint
pprint(result)

# Result:
# {'statements': {'home': '/home/pi',
#                 'my_env': 'development',
#                 'unknown': 'none'
#                 'with_default': 'the_default'}}