未验证 提交 989ca0b2 编写于 作者: C Caio Carrara

Merge remote-tracking branch 'clebergnu/yaml_to_mux_unwind_v2'

Signed-off-by: NCaio Carrara <ccarrara@redhat.com>
......@@ -73,20 +73,34 @@ class ListOfNodeObjects(list): # Few methods pylint: disable=R0903
"""
def _create_from_yaml(path, cls_node=mux.MuxTreeNode):
"""Create tree structure from yaml stream"""
def tree_node_from_values(name, values):
"""Create `name` node and add values"""
def handle_control_tag(node, value):
"""Handling of YAML tags (except of !using)"""
def normalize_path(path):
"""End the path with single '/', None when empty path"""
def _normalize_path(path):
"""
End the path with single '/'
:param path: original path
:type path: str
:returns: path with trailing '/', or None when empty path
:rtype: str or None
"""
if not path:
return
if path[-1] != '/':
path += '/'
return path
def _handle_control_tag(path, cls_node, node, value):
"""
Handling of most YAML control tags (all but "!using")
:param path: path on the YAML
:type path: str
:param cls_node: the class of the node
:type cls_node: :class:`avocado.core.tree.TreeNode` or similar
:param node: the node in which to handle control tags
:type node: instance of :class:`avocado.core.tree.TreeNode` or similar
:param value: the value of the node
"""
if value[0].code == YAML_INCLUDE:
# Include file
ypath = value[1]
......@@ -96,25 +110,33 @@ def _create_from_yaml(path, cls_node=mux.MuxTreeNode):
raise ValueError("File '%s' included from '%s' does not "
"exist." % (ypath, path))
node.merge(_create_from_yaml('/:' + ypath, cls_node))
elif value[0].code == YAML_REMOVE_NODE:
elif value[0].code in (YAML_REMOVE_NODE, YAML_REMOVE_VALUE):
value[0].value = value[1] # set the name
node.ctrl.append(value[0]) # add "blue pill" of death
elif value[0].code == YAML_REMOVE_VALUE:
value[0].value = value[1] # set the name
node.ctrl.append(value[0])
elif value[0].code == YAML_MUX:
node.multiplex = True
elif value[0].code == YAML_FILTER_ONLY:
new_value = normalize_path(value[1])
new_value = _normalize_path(value[1])
if new_value:
node.filters[0].append(new_value)
elif value[0].code == YAML_FILTER_OUT:
new_value = normalize_path(value[1])
new_value = _normalize_path(value[1])
if new_value:
node.filters[1].append(new_value)
def handle_control_tag_using(name, using, value):
"""Handling of the !using tag"""
def _handle_control_tag_using(path, name, using, value):
"""
Handling of the "!using" YAML control tag
:param path: path on the YAML
:type path: str
:param name: name to be applied in the "!using" tag
:type name: str
:param using: wether using is already being used
:type using: bool
:param value: the value of the node
"""
if using:
raise ValueError("!using can be used only once per "
"node! (%s:%s)" % (path, name))
......@@ -125,6 +147,39 @@ def _create_from_yaml(path, cls_node=mux.MuxTreeNode):
using = using[:-1]
return using
def _apply_using(name, cls_node, using, node):
"""
Create the structure defined by "!using" and return the new root
:param name: the tag name to have the "!using" applied to
:type name: str
:param cls_node: the class of the node
:type cls_node: :class:`avocado.core.tree.TreeNode` or similar
:param using: the new location to put the tag into
:type using: bool
:param node: the node in which to handle control tags
:type node: instance of :class:`avocado.core.tree.TreeNode` or similar
"""
if name is not '':
for name in using.split('/')[::-1]:
node = cls_node(name, children=[node])
else:
using = using.split('/')[::-1]
node.name = using.pop()
while True:
if not using:
break
name = using.pop() # 'using' is list pylint: disable=E1101
node = cls_node(name, children=[node])
node = cls_node('', children=[node])
return node
def _create_from_yaml(path, cls_node=mux.MuxTreeNode):
"""Create tree structure from yaml stream"""
def tree_node_from_values(name, values):
"""Create `name` node and add values"""
def node_content_from_node(node, values, using):
"""Processes node values into the current node content"""
for value in values:
......@@ -132,9 +187,9 @@ def _create_from_yaml(path, cls_node=mux.MuxTreeNode):
node.add_child(value)
elif isinstance(value[0], mux.Control):
if value[0].code == YAML_USING:
using = handle_control_tag_using(name, using, value[1])
using = _handle_control_tag_using(path, name, using, value[1])
else:
handle_control_tag(node, value)
_handle_control_tag(path, cls_node, node, value)
elif isinstance(value[1], collections.OrderedDict):
node.add_child(tree_node_from_values(str(value[0]),
value[1]))
......@@ -147,9 +202,9 @@ def _create_from_yaml(path, cls_node=mux.MuxTreeNode):
for key, value in iteritems(values):
if isinstance(key, mux.Control):
if key.code == YAML_USING:
using = handle_control_tag_using(name, using, value)
using = _handle_control_tag_using(path, name, using, value)
else:
handle_control_tag(node, [key, value])
_handle_control_tag(path, cls_node, node, [key, value])
elif (isinstance(value, collections.OrderedDict) or
value is None):
node.add_child(tree_node_from_values(key, value))
......@@ -157,22 +212,6 @@ def _create_from_yaml(path, cls_node=mux.MuxTreeNode):
node.value[key] = value
return using
def apply_using(name, using, node):
'''Create the structure defined by using and return the new root'''
if name is not '':
for name in using.split('/')[::-1]:
node = cls_node(name, children=[node])
else:
using = using.split('/')[::-1]
node.name = using.pop()
while True:
if not using:
break
name = using.pop() # 'using' is list pylint: disable=E1101
node = cls_node(name, children=[node])
node = cls_node('', children=[node])
return node
# Initialize the node
node = cls_node(str(name))
if not values:
......@@ -187,7 +226,7 @@ def _create_from_yaml(path, cls_node=mux.MuxTreeNode):
# Prefix nodes if tag "!using" was used
if using:
node = apply_using(name, using, node)
node = _apply_using(name, cls_node, using, node)
return node
def mapping_to_tree_loader(loader, node, looks_like_node=False):
......
......@@ -55,6 +55,13 @@ class MultiplexTests(unittest.TestCase):
result = self.run_and_check(cmd_line, expected_rc)
self.assertIn('No such file or directory', result.stderr_text)
def test_mplex_plugin_using(self):
cmd_line = ('%s variants -m /:optional_plugins/varianter_yaml_to_mux/'
'tests/.data/mux-selftest-using.yaml' % AVOCADO)
expected_rc = exit_codes.AVOCADO_ALL_OK
result = self.run_and_check(cmd_line, expected_rc)
self.assertIn(b' /foo/baz/bar', result.stdout)
@unittest.skipIf(sys.version_info[0] == 3,
"Test currently broken on Python 3")
def test_mplex_debug(self):
......
......@@ -535,6 +535,49 @@ class TestPathParent(unittest.TestCase):
self.assertNotEqual(mux.path_parent('/os/linux'), '/')
class TestCreateFromYaml(unittest.TestCase):
def test_normalize_path(self):
self.assertEqual(yaml_to_mux._normalize_path(''), None)
self.assertEqual(yaml_to_mux._normalize_path('path'), 'path/')
def test_handle_control_path_include_file_does_not_exist(self):
with self.assertRaises(ValueError):
yaml_to_mux._handle_control_tag(
'original_fake_file.yaml',
mux.MuxTreeNode, mux.MuxTreeNode(),
(mux.Control(yaml_to_mux.YAML_INCLUDE),
'unexisting_include.yaml'))
def test_handle_control_path_remove(self):
klass = mux.MuxTreeNode
node = klass()
control = mux.Control(yaml_to_mux.YAML_REMOVE_NODE)
to_be_removed = 'node_to_be_removed'
yaml_to_mux._handle_control_tag('fake_path',
klass, node,
(control, to_be_removed))
self.assertEqual(control.value, to_be_removed)
self.assertIn(control, node.ctrl)
def test_handle_control_tag_using_multiple(self):
with self.assertRaises(ValueError):
yaml_to_mux._handle_control_tag_using('original_fake_file.yaml',
'name', True, 'using')
def test_handle_control_tag_using(self):
using = yaml_to_mux._handle_control_tag_using('fake_path',
'name',
False,
'/using/path/')
self.assertEqual(using, 'using/path')
def test_apply_using(self):
node = yaml_to_mux._apply_using('bar', mux.MuxTreeNode,
'foo', mux.MuxTreeNode())
self.assertEqual(node.path, '/foo')
class TestFingerprint(unittest.TestCase):
def test_fingerprint(self):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册