blob: 948151bed663c7af7f313cb3956e1478106595cc [file] [log] [blame]
import os
import pytest
from collections import Mapping
from buildstream import _yaml
from buildstream import LoadError, LoadErrorReason
from buildstream._yaml import CompositePolicy
DATA_DIR = os.path.join(
os.path.dirname(os.path.realpath(__file__)),
'data',
)
@pytest.mark.datafiles(os.path.join(DATA_DIR))
def test_load_yaml(datafiles):
filename = os.path.join(datafiles.dirname,
datafiles.basename,
'basics.yaml')
loaded = _yaml.load(filename)
assert(loaded.get('kind') == 'pony')
def assert_provenance(filename, line, col, node, key=None, indices=[]):
provenance = _yaml.node_get_provenance(node, key=key, indices=indices)
if key:
if indices:
assert(isinstance(provenance, _yaml.ElementProvenance))
else:
assert(isinstance(provenance, _yaml.MemberProvenance))
else:
assert(isinstance(provenance, _yaml.DictProvenance))
assert(provenance.filename == filename)
assert(provenance.line == line)
assert(provenance.col == col)
@pytest.mark.datafiles(os.path.join(DATA_DIR))
def test_basic_provenance(datafiles):
filename = os.path.join(datafiles.dirname,
datafiles.basename,
'basics.yaml')
loaded = _yaml.load(filename)
assert(loaded.get('kind') == 'pony')
assert_provenance(filename, 1, 0, loaded)
@pytest.mark.datafiles(os.path.join(DATA_DIR))
def test_member_provenance(datafiles):
filename = os.path.join(datafiles.dirname,
datafiles.basename,
'basics.yaml')
loaded = _yaml.load(filename)
assert(loaded.get('kind') == 'pony')
assert_provenance(filename, 2, 13, loaded, 'description')
@pytest.mark.datafiles(os.path.join(DATA_DIR))
def test_element_provenance(datafiles):
filename = os.path.join(datafiles.dirname,
datafiles.basename,
'basics.yaml')
loaded = _yaml.load(filename)
assert(loaded.get('kind') == 'pony')
assert_provenance(filename, 5, 2, loaded, 'moods', [1])
@pytest.mark.datafiles(os.path.join(DATA_DIR))
def test_composited_overwrite_provenance(datafiles):
filename = os.path.join(datafiles.dirname,
datafiles.basename,
'basics.yaml')
overlayfile = os.path.join(datafiles.dirname,
datafiles.basename,
'composite.yaml')
base = _yaml.load(filename)
assert(base.get('kind') == 'pony')
assert_provenance(filename, 1, 0, base)
overlay = _yaml.load(overlayfile)
assert(overlay.get('kind') == 'horse')
assert_provenance(overlayfile, 1, 0, overlay)
_yaml.composite_dict(base, overlay,
policy=CompositePolicy.OVERWRITE, typesafe=True)
assert(base.get('kind') == 'horse')
children = base.get('children')
assert(isinstance(children, list))
assert(len(children) == 1)
assert_provenance(filename, 1, 0, base)
# The entire children member is overwritten with the overlay
assert_provenance(overlayfile, 4, 0, base, 'children')
assert_provenance(overlayfile, 4, 2, base, 'children', [0])
# The child dict itself has the overlay provenance
child = children[0]
assert_provenance(overlayfile, 5, 8, child, 'mood')
@pytest.mark.datafiles(os.path.join(DATA_DIR))
def test_composited_array_append_provenance(datafiles):
filename = os.path.join(datafiles.dirname,
datafiles.basename,
'basics.yaml')
overlayfile = os.path.join(datafiles.dirname,
datafiles.basename,
'composite.yaml')
base = _yaml.load(filename)
assert(base.get('kind') == 'pony')
assert_provenance(filename, 1, 0, base)
overlay = _yaml.load(overlayfile)
assert(overlay.get('kind') == 'horse')
assert_provenance(overlayfile, 1, 0, overlay)
_yaml.composite_dict(base, overlay,
policy=CompositePolicy.ARRAY_APPEND, typesafe=True)
assert(base.get('kind') == 'horse')
children = base.get('children')
assert(isinstance(children, list))
assert(len(children) == 8)
assert_provenance(filename, 1, 0, base)
assert_provenance(filename, 7, 0, base, 'children')
# The newly added element has the overlay provenance
assert_provenance(overlayfile, 4, 2, base, 'children', [7])
# The child dict itself has the overlay provenance
child = children[7]
assert_provenance(overlayfile, 5, 8, child, 'mood')
extra = base.get('extra')
assert(isinstance(extra, dict))
another = extra.get('another')
assert(isinstance(another, dict))
assert_provenance(filename, 22, 2, base, 'extra')
assert_provenance(filename, 22, 2, extra)
assert_provenance(filename, 22, 8, extra, 'this')
assert_provenance(overlayfile, 9, 4, extra, 'another')
assert_provenance(overlayfile, 9, 4, another)
@pytest.mark.datafiles(os.path.join(DATA_DIR))
def test_node_validate(datafiles):
valid = os.path.join(datafiles.dirname,
datafiles.basename,
'basics.yaml')
invalid = os.path.join(datafiles.dirname,
datafiles.basename,
'invalid.yaml')
base = _yaml.load(valid)
_yaml.node_validate(base, ['kind', 'description', 'moods', 'children', 'extra'])
base = _yaml.load(invalid)
with pytest.raises(LoadError) as exc:
_yaml.node_validate(base, ['kind', 'description', 'moods', 'children', 'extra'])
assert (exc.value.reason == LoadErrorReason.INVALID_DATA)
@pytest.mark.datafiles(os.path.join(DATA_DIR))
def test_node_get(datafiles):
filename = os.path.join(datafiles.dirname,
datafiles.basename,
'basics.yaml')
overlayfile = os.path.join(datafiles.dirname,
datafiles.basename,
'composite.yaml')
base = _yaml.load(filename)
assert(base.get('kind') == 'pony')
overlay = _yaml.load(overlayfile)
assert(overlay.get('kind') == 'horse')
_yaml.composite_dict(base, overlay,
policy=CompositePolicy.ARRAY_APPEND,
typesafe=True)
assert(base.get('kind') == 'horse')
children = _yaml.node_get(base, list, 'children')
assert(isinstance(children, list))
assert(len(children) == 8)
child = _yaml.node_get(base, Mapping, 'children', indices=[7])
assert_provenance(overlayfile, 5, 8, child, 'mood')
extra = _yaml.node_get(base, Mapping, 'extra')
another = _yaml.node_get(extra, Mapping, 'another')
with pytest.raises(LoadError) as exc:
wrong = _yaml.node_get(another, Mapping, 'five')
assert (exc.value.reason == LoadErrorReason.INVALID_DATA)
# Really this is testing _yaml.node_chain_copy(), we want to
# be sure that when using a ChainMap copy, compositing values
# still preserves the original values in the copied dict.
#
@pytest.mark.datafiles(os.path.join(DATA_DIR))
def test_composite_preserve_originals(datafiles):
filename = os.path.join(datafiles.dirname,
datafiles.basename,
'basics.yaml')
overlayfile = os.path.join(datafiles.dirname,
datafiles.basename,
'composite.yaml')
base = _yaml.load(filename)
overlay = _yaml.load(overlayfile)
base_copy = _yaml.node_chain_copy(base)
_yaml.composite_dict(base_copy, overlay,
policy=CompositePolicy.OVERWRITE, typesafe=True)
copy_extra = _yaml.node_get(base_copy, Mapping, 'extra')
orig_extra = _yaml.node_get(base, Mapping, 'extra')
# Test that the node copy has the overridden value...
assert(_yaml.node_get(copy_extra, str, 'old') == 'override')
# But the original node is not effected by the override.
assert(_yaml.node_get(orig_extra, str, 'old') == 'new')