Beispiel #1
0
 def test_eq(self):
     # Copy
     tree2 = copy.deepcopy(self.tree)
     self.assertEqual(self.tree, tree2)
     # Additional node
     child = mux.MuxTreeNode("20", {'name': 'Heisenbug'})
     tree2.children[1].children[1].add_child(child)
     self.assertNotEqual(self.tree, tree2)
     # Should match again
     child.detach()
     self.assertEqual(self.tree, tree2)
     # Missing node
     tree2.children[1].children[1].detach()
     self.assertNotEqual(self.tree, tree2)
     self.assertEqual(self.tree.children[0], tree2.children[0])
     # Different value
     tree2.children[0].children[0].children[0].value = {'something': 'else'}
     self.assertNotEqual(self.tree.children[0], tree2.children[0])
     tree3 = mux.MuxTreeNode()
     self.assertNotEqual(tree3, tree2)
     # Merge
     tree3.merge(tree2)
     self.assertEqual(tree3, tree2)
     # Add_child existing
     tree3.add_child(tree2.children[0])
     self.assertEqual(tree3, tree2)
Beispiel #2
0
 def test_tree_mux_node(self):
     """
     Check the extension of fingerprint in MuxTreeNode
     """
     node1 = tree.TreeNode("node1", {"foo": "bar"})
     node1m = mux.MuxTreeNode("node1", {"foo": "bar"})
     node1m_fingerprint = node1m.fingerprint()
     self.assertNotEqual(node1.fingerprint(), node1m_fingerprint)
     node1mduplicate = mux.MuxTreeNode("node1", {"foo": "bar"})
     self.assertEqual(node1m_fingerprint, node1mduplicate.fingerprint())
     node1mb_ctrl = mux.MuxTreeNode("node1", {"foo": "bar"})
     node1mb_ctrl.ctrl = [mux.Control(0, 0)]
     self.assertNotEqual(node1m_fingerprint, node1mb_ctrl.fingerprint())
Beispiel #3
0
def _mapping_to_tree_loader(loader, node, looks_like_node=False):
    """Maps yaml mapping tag to TreeNode structure"""
    _value = []
    for key_node, value_node in node.value:
        # Allow only strings as dict keys
        if key_node.tag.startswith('!'):    # reflect tags everywhere
            key = loader.construct_object(key_node)
        else:
            key = loader.construct_scalar(key_node)
        # If we are to keep them, use following, but we lose the control
        # for both, nodes and dicts
        # key = loader.construct_object(key_node)
        if isinstance(key, mux.Control):
            looks_like_node = True
        value = loader.construct_object(value_node)
        if isinstance(value, ListOfNodeObjects):
            looks_like_node = True
        _value.append((key, value))

    if not looks_like_node:
        return collections.OrderedDict(_value)

    objects = ListOfNodeObjects()
    for name, values in _value:
        if isinstance(values, ListOfNodeObjects):   # New node from list
            objects.append(_tree_node_from_values(loader.path, name,
                                                  values, loader.using))
        elif values is None:            # Empty node
            objects.append(mux.MuxTreeNode(astring.to_text(name)))
        elif values == 'null':
            objects.append((name, None))
        else:                           # Values
            objects.append((name, values))
    return objects
Beispiel #4
0
def create_from_yaml(paths):
    """Create tree structure from yaml-like file.

    :param paths: File object to be processed
    :raise SyntaxError: When yaml-file is corrupted
    :return: Root of the created tree structure
    """
    def _merge(data, path):
        """Normal run"""
        tmp = _create_from_yaml(path)
        if tmp:
            data.merge(tmp)

    data = mux.MuxTreeNode()
    path = None
    try:
        for path in paths:
            _merge(data, path)
    # Yaml can raise IndexError on some files
    except (yaml.YAMLError, IndexError) as details:
        if ('mapping values are not allowed in this context' in
                astring.to_text(details)):
            details = ("%s\nMake sure !tags and colons are separated by a "
                       "space (eg. !include :)" % details)
        msg = "Invalid multiplex file '%s': %s" % (path, details)
        raise IOError(2, msg, path)
    return data
Beispiel #5
0
 def test_handle_control_path_include_file_does_not_exist(self):
     with self.assertRaises(ValueError):
         # pylint: disable=W0212
         yaml_to_mux._handle_control_tag(
             'original_fake_file.yaml', mux.MuxTreeNode, mux.MuxTreeNode(),
             (mux.Control(
                 yaml_to_mux.YAML_INCLUDE), 'unexisting_include.yaml'))
Beispiel #6
0
 def test_handle_control_path_remove(self):
     node = mux.MuxTreeNode()
     control = mux.Control(yaml_to_mux.YAML_REMOVE_NODE)
     to_be_removed = 'node_to_be_removed'
     # pylint: disable=W0212
     yaml_to_mux._handle_control_tag('fake_path', node,
                                     (control, to_be_removed))
     self.assertEqual(control.value, to_be_removed)
     self.assertIn(control, node.ctrl)
Beispiel #7
0
    def initialize(self, config):
        subcommand = config.get('subcommand')
        data = None

        # Merge the multiplex
        multiplex_files = config.get("yaml_to_mux.files")
        if multiplex_files:
            data = mux.MuxTreeNode()
            try:
                data.merge(create_from_yaml(multiplex_files))
            except IOError as details:
                error_msg = "%s : %s" % (details.strerror, details.filename)
                LOG_UI.error(error_msg)
                if subcommand == 'run':
                    sys.exit(exit_codes.AVOCADO_JOB_FAIL)
                else:
                    sys.exit(exit_codes.AVOCADO_FAIL)

        # Extend default multiplex tree of --mux-inject values
        for inject in config.get("yaml_to_mux.inject"):
            entry = inject.split(':', 2)
            if len(entry) < 2:
                raise ValueError("key:entry pairs required, found only %s"
                                 % (entry))
            elif len(entry) == 2:   # key, entry
                entry.insert(0, '')  # add path='' (root)
            # We try to maintain the data type of the provided value
            try:
                entry[2] = ast.literal_eval(entry[2])
            except (ValueError, SyntaxError, NameError, RecursionError):
                pass
            if data is None:
                data = mux.MuxTreeNode()
            data.get_node(entry[0], True).value[entry[1]] = entry[2]

        if data is not None:
            mux_filter_only = config.get('yaml_to_mux.filter_only')
            mux_filter_out = config.get('yaml_to_mux.filter_out')
            data = mux.apply_filters(data, mux_filter_only, mux_filter_out)
            paths = config.get("yaml_to_mux.parameter_paths")
            self.initialize_mux(data, paths)
Beispiel #8
0
 def test_merge_trees(self):
     tree2 = copy.deepcopy(self.tree)
     tree3 = mux.MuxTreeNode()
     tree3.add_child(mux.MuxTreeNode('hw', {'another_value': 'bbb'}))
     tree3.children[0].add_child(mux.MuxTreeNode('nic'))
     tree3.children[0].children[0].add_child(mux.MuxTreeNode('default'))
     tree3.children[0].children[0].add_child(
         mux.MuxTreeNode('virtio', {'nic': 'virtio'}))
     tree3.children[0].add_child(
         mux.MuxTreeNode('cpu', {'test_value': ['z']}))
     tree2.merge(tree3)
     exp = [
         'intel', 'amd', 'arm', 'scsi', 'virtio', 'default', 'virtio',
         'fedora', u'\u0161mint', 'prod'
     ]
     self.assertEqual(exp, tree2.get_leaves())
     self.assertEqual(
         {
             'corruptlist': ['upper_node_list'],
             'another_value': 'bbb'
         }, tree2.children[0].value)
     self.assertEqual({
         'joinlist': ['first_item'],
         'test_value': ['z']
     }, tree2.children[0].children[0].value)
     self.assertFalse(tree2.children[0].children[2].children[0].value)
     self.assertEqual({'nic': 'virtio'},
                      tree2.children[0].children[2].children[1].value)
Beispiel #9
0
def _create_from_yaml(path):
    """Create tree structure from yaml stream"""

    # Parse file name ([$using:]$path)
    path = __RE_FILE_SPLIT.split(path, 1)
    if len(path) == 1:
        path = __RE_FILE_SUBS.sub(':', path[0])
        using = ["run"]
    else:
        nodes = __RE_FILE_SUBS.sub(':', path[0]).strip('/').split('/')
        using = [node for node in nodes if node]
        if not path[0].startswith('/'):  # relative path, put into /run
            using.insert(0, 'run')
        path = __RE_FILE_SUBS.sub(':', path[1])

    # For loader instance needs different "path" and "using" values
    class Loader(_BaseLoader):
        _BaseLoader.path = path
        _BaseLoader.using = using

    # Load the tree
    with open(path, encoding='utf-8') as stream:
        loaded_tree = yaml.load(stream, Loader)  # nosec
        if loaded_tree is None:
            return

        loaded_tree = _tree_node_from_values(path, '', loaded_tree, using)

    # Add prefix
    if using:
        loaded_tree.name = using.pop()
        while True:
            if not using:
                break
            loaded_tree = mux.MuxTreeNode(using.pop(), children=[loaded_tree])
        loaded_tree = mux.MuxTreeNode('', children=[loaded_tree])
    return loaded_tree
Beispiel #10
0
def _apply_using(name, 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 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 != '':
        for name in using.split('/')[::-1]:
            node = mux.MuxTreeNode(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 = mux.MuxTreeNode(name, children=[node])
        node = mux.MuxTreeNode('', children=[node])
    return node
Beispiel #11
0
def _tree_node_from_values(path, name, values, using):
    """Create `name` node and add values"""
    # Initialize the node
    node = mux.MuxTreeNode(astring.to_text(name))
    if not values:
        return node
    using = ''

    # Fill the node content from parsed values
    if isinstance(values, dict):
        using = _node_content_from_dict(path, node, values, using)
    else:
        using = _node_content_from_node(path, node, values, using)

    # Prefix nodes if tag "!using" was used
    if using:
        node = _apply_using(name, using, node)
    return node
Beispiel #12
0
 def test_apply_using(self):
     # pylint: disable=W0212
     node = yaml_to_mux._apply_using('bar', 'foo', mux.MuxTreeNode())
     self.assertEqual(node.path, '/foo')
Beispiel #13
0
 def test_empty(self):
     act = tuple(mux.MuxTree(mux.MuxTreeNode()))
     self.assertEqual(act, ([
         '',
     ], ))
Beispiel #14
0
 def test_apply_using(self):
     node = yaml_to_mux._apply_using('bar', mux.MuxTreeNode,
                                     'foo', mux.MuxTreeNode())
     self.assertEqual(node.path, '/foo')