Repository: PolyJIT/benchbuild (language: python)

Issue:
BB commands don't get the correct environment from the config
We use this env config inside the container, however, the PATH is not correctly injected into the benchbuild.util.cmd s. Further checking showed that the env values cannot be loaded from the config as usual.

```
BB_ENV={LD_LIBRARY_PATH: [/varats_root/libs], PATH [/varats_root/tools/VaRA/bin]}
```

Printing the BB config env shows this result:
```
print(bb_cfg()["env"].value)
{'default': {}, 'desc': "The environment benchbuild's commands should operate in.", 'value': {}}
```


Discussion / hints:
The initial definition of ``CFG['env'] = {'default': {}, 'desc': '...'}`` triggers this bug, because it fails validation and is converted into a leaf node in the configuration.

The problem goes away when there is a config file with an ``env`` entry present. This way we load a configuration object from the file (a correct one) and load the value for it from the environment.

Fix patch:
diff --git a/benchbuild/utils/settings.py b/benchbuild/utils/settings.py
index 48dd348ad..8cf0f5411 100644
--- a/benchbuild/utils/settings.py
+++ b/benchbuild/utils/settings.py
@@ -201,7 +201,10 @@ def to_env_var(env_var: str, value: tp.Any) -> str:
 #  CFG['container']['strategy']['polyjit'] = {
 #    'sync': { 'default': True', 'desc': '...' }
 #  }
-_INNER_NODE_VALUE = schema.Schema({schema.Or('default', 'value'): object})
+_INNER_NODE_VALUE = schema.Schema({
+    schema.Or('default', 'value'): object,
+    schema.Optional('desc'): str
+})
 _INNER_NODE_SCHEMA = schema.Schema({
     schema.And(str, len): {
         schema.Or('default', 'value'): object,


Test patch:
diff --git a/tests/settings/test_configuration.py b/tests/settings/test_configuration.py
index 836215ddb..b8a1b19e7 100644
--- a/tests/settings/test_configuration.py
+++ b/tests/settings/test_configuration.py
@@ -2,7 +2,11 @@
 
 import pytest
 
-from benchbuild.utils.settings import Configuration
+from benchbuild.utils.settings import (
+    Configuration,
+    _INNER_NODE_SCHEMA,
+    _INNER_NODE_VALUE,
+)
 
 
 @pytest.fixture
@@ -10,6 +14,28 @@ def bb():
     yield Configuration('bb')
 
 
+def describe_inner_nodes():
+
+    def dict_can_be_inner_node():
+        assert _INNER_NODE_VALUE.is_valid({'default': 0, 'desc': 'a'})
+
+    def dict_can_be_nested_once():
+        assert _INNER_NODE_SCHEMA.is_valid({'a': {'default': 0, 'desc': 'a'}})
+
+    def inner_node_value_can_be_assigned(bb):
+        bb['a'] = {'default': 0, 'desc': 'a'}
+        assert _INNER_NODE_SCHEMA.is_valid(bb.node)
+
+    def inner_node_needs_to_be_initialized():
+        cfg = Configuration('fresh')
+        cfg['a'] = {'default': 0, 'desc': 'a'}
+
+        assert not hasattr(cfg['a'].node, 'value')
+
+        cfg.init_from_env()
+        assert hasattr(cfg['a'], 'value')
+
+
 def test_simple_construction(bb):
     """Test simple construction."""