提交 592721e3 编写于 作者: C Cleber Rosa

YAML to Mux: move all related classes to plugin

These classes and methods have knowledge about the YAML files, and the
YAML to Mux plugin is the only user of those.  this plugin.  So it
makes sense to move it to the plugin module.
Signed-off-by: NCleber Rosa <crosa@redhat.com>
上级 41ad170d
......@@ -36,11 +36,8 @@ original base tree code and re-license under GPLv2+, given that GPLv3 and GPLv2
import collections
import itertools
import locale
import os
from six import string_types, iterkeys, iteritems
from . import output
from six import string_types, iteritems
class FilterSet(set):
......@@ -355,141 +352,6 @@ class TreeNode(object):
return self
#
# Debug version of TreeNode with additional utilities.
#
class OutputValue(object): # only container pylint: disable=R0903
""" Ordinary value with some debug info """
def __init__(self, value, node, srcyaml):
self.value = value
self.node = node
self.yaml = srcyaml
def __str__(self):
return "%s%s@%s:%s%s" % (self.value,
output.TERM_SUPPORT.LOWLIGHT,
self.yaml, self.node.path,
output.TERM_SUPPORT.ENDC)
class OutputList(list): # only container pylint: disable=R0903
""" List with some debug info """
def __init__(self, values, nodes, yamls):
super(OutputList, self).__init__(values)
self.nodes = nodes
self.yamls = yamls
def __add__(self, other):
""" Keep attrs separate in order to print the origins """
value = super(OutputList, self).__add__(other)
return OutputList(value,
self.nodes + other.nodes,
self.yamls + other.yamls)
def __str__(self):
color = output.TERM_SUPPORT.LOWLIGHT
cend = output.TERM_SUPPORT.ENDC
return ' + '.join("%s%s@%s:%s%s"
% (_[0], color, _[1], _[2].path, cend)
for _ in itertools.izip(self, self.yamls,
self.nodes))
class ValueDict(dict): # only container pylint: disable=R0903
""" Dict which stores the origin of the items """
def __init__(self, srcyaml, node, values):
super(ValueDict, self).__init__()
self.yaml = srcyaml
self.node = node
self.yaml_per_key = {}
for key, value in iteritems(values):
self[key] = value
def __setitem__(self, key, value):
""" Store yaml_per_key and value """
# Merge is responsible to set `self.yaml` to current file
self.yaml_per_key[key] = self.yaml
return super(ValueDict, self).__setitem__(key, value)
def __getitem__(self, key):
"""
This is debug run. Fake the results and return either
OutputValue (let's call it string) and OutputList. These
overrides the `__str__` and return string with origin.
:warning: Returned values are unusable in tests!
"""
value = super(ValueDict, self).__getitem__(key)
origin = self.yaml_per_key.get(key)
if isinstance(value, list):
value = OutputList([value], [self.node], [origin])
else:
value = OutputValue(value, self.node, origin)
return value
def iteritems(self):
""" Slower implementation with the use of __getitem__ """
for key in iterkeys(self):
yield key, self[key]
raise StopIteration
class TreeNodeDebug(TreeNode): # only container pylint: disable=R0903
"""
Debug version of TreeNodeDebug
:warning: Origin of the value is appended to all values thus it's not
suitable for running tests.
"""
def __init__(self, name='', value=None, parent=None, children=None,
srcyaml=None):
if value is None:
value = {}
if srcyaml:
srcyaml = os.path.relpath(srcyaml)
super(TreeNodeDebug, self).__init__(name,
ValueDict(srcyaml, self, value),
parent, children)
self.yaml = srcyaml
def merge(self, other):
"""
Override origin with the one from other tree. Updated/Newly set values
are going to use this location as origin.
"""
if hasattr(other, 'yaml') and other.yaml:
srcyaml = os.path.relpath(other.yaml)
# when we use TreeNodeDebug, value is always ValueDict
self.value.yaml_per_key.update(other.value.yaml_per_key) # pylint: disable=E1101
else:
srcyaml = "Unknown"
self.yaml = srcyaml
self.value.yaml = srcyaml
return super(TreeNodeDebug, self).merge(other)
def get_named_tree_cls(path, klass=TreeNodeDebug):
""" Return TreeNodeDebug class with hardcoded yaml path """
class NamedTreeNodeDebug(klass): # pylint: disable=R0903
""" Fake class with hardcoded yaml path """
def __init__(self, name='', value=None, parent=None,
children=None):
super(NamedTreeNodeDebug, self).__init__(name, value, parent,
children,
path.split(':', 1)[-1])
return NamedTreeNodeDebug
def tree_view(root, verbose=None, use_utf8=None):
"""
Generate tree-view of the given node
......
......@@ -28,7 +28,7 @@ except ImportError:
from six import iteritems
from avocado.core import tree, exit_codes
from avocado.core import exit_codes
from avocado.core.output import LOG_UI
from avocado.core.plugin_interfaces import CLI, Varianter
......@@ -282,6 +282,20 @@ def _create_from_yaml(path, cls_node=mux.MuxTreeNode):
return loaded_tree
def get_named_tree_cls(path, klass):
""" Return TreeNodeDebug class with hardcoded yaml path """
class NamedTreeNodeDebug(klass): # pylint: disable=R0903
""" Fake class with hardcoded yaml path """
def __init__(self, name='', value=None, parent=None,
children=None):
super(NamedTreeNodeDebug, self).__init__(name, value, parent,
children,
path.split(':', 1)[-1])
return NamedTreeNodeDebug
def create_from_yaml(paths, debug=False):
"""
Create tree structure from yaml-like file
......@@ -297,7 +311,7 @@ def create_from_yaml(paths, debug=False):
def _merge_debug(data, path):
"""Use NamedTreeNodeDebug magic"""
node_cls = tree.get_named_tree_cls(path, mux.MuxTreeNodeDebug)
node_cls = get_named_tree_cls(path, mux.MuxTreeNodeDebug)
tmp = _create_from_yaml(path, node_cls)
if tmp:
data.merge(tmp)
......
......@@ -24,11 +24,14 @@ a custom Varianter plugin.
import collections
import itertools
import re
import os
from six import iterkeys, iteritems
from six.moves import xrange as range
from avocado.core import tree
from avocado.core import varianter
from avocado.core import output
#
......@@ -233,6 +236,87 @@ class MuxPlugin(object):
return sum(1 for _ in self)
class OutputValue(object): # only container pylint: disable=R0903
""" Ordinary value with some debug info """
def __init__(self, value, node, srcyaml):
self.value = value
self.node = node
self.yaml = srcyaml
def __str__(self):
return "%s%s@%s:%s%s" % (self.value,
output.TERM_SUPPORT.LOWLIGHT,
self.yaml, self.node.path,
output.TERM_SUPPORT.ENDC)
class OutputList(list): # only container pylint: disable=R0903
""" List with some debug info """
def __init__(self, values, nodes, yamls):
super(OutputList, self).__init__(values)
self.nodes = nodes
self.yamls = yamls
def __add__(self, other):
""" Keep attrs separate in order to print the origins """
value = super(OutputList, self).__add__(other)
return OutputList(value,
self.nodes + other.nodes,
self.yamls + other.yamls)
def __str__(self):
color = output.TERM_SUPPORT.LOWLIGHT
cend = output.TERM_SUPPORT.ENDC
return ' + '.join("%s%s@%s:%s%s"
% (_[0], color, _[1], _[2].path, cend)
for _ in itertools.izip(self, self.yamls,
self.nodes))
class ValueDict(dict): # only container pylint: disable=R0903
""" Dict which stores the origin of the items """
def __init__(self, srcyaml, node, values):
super(ValueDict, self).__init__()
self.yaml = srcyaml
self.node = node
self.yaml_per_key = {}
for key, value in iteritems(values):
self[key] = value
def __setitem__(self, key, value):
""" Store yaml_per_key and value """
# Merge is responsible to set `self.yaml` to current file
self.yaml_per_key[key] = self.yaml
return super(ValueDict, self).__setitem__(key, value)
def __getitem__(self, key):
"""
This is debug run. Fake the results and return either
OutputValue (let's call it string) and OutputList. These
overrides the `__str__` and return string with origin.
:warning: Returned values are unusable in tests!
"""
value = super(ValueDict, self).__getitem__(key)
origin = self.yaml_per_key.get(key)
if isinstance(value, list):
value = OutputList([value], [self.node], [origin])
else:
value = OutputValue(value, self.node, origin)
return value
def iteritems(self):
""" Slower implementation with the use of __getitem__ """
for key in iterkeys(self):
yield key, self[key]
raise StopIteration
class Control(object): # Few methods pylint: disable=R0903
""" Container used to identify node vs. control sequence """
......@@ -293,7 +377,42 @@ class MuxTreeNode(tree.TreeNode):
self.multiplex = False
class MuxTreeNodeDebug(MuxTreeNode, tree.TreeNodeDebug):
class TreeNodeDebug(tree.TreeNode): # only container pylint: disable=R0903
"""
Debug version of TreeNodeDebug
:warning: Origin of the value is appended to all values thus it's not
suitable for running tests.
"""
def __init__(self, name='', value=None, parent=None, children=None,
srcyaml=None):
if value is None:
value = {}
if srcyaml:
srcyaml = os.path.relpath(srcyaml)
super(TreeNodeDebug, self).__init__(name,
ValueDict(srcyaml, self, value),
parent, children)
self.yaml = srcyaml
def merge(self, other):
"""
Override origin with the one from other tree. Updated/Newly set values
are going to use this location as origin.
"""
if hasattr(other, 'yaml') and other.yaml:
srcyaml = os.path.relpath(other.yaml)
# when we use TreeNodeDebug, value is always ValueDict
self.value.yaml_per_key.update(other.value.yaml_per_key) # pylint: disable=E1101
else:
srcyaml = "Unknown"
self.yaml = srcyaml
self.value.yaml = srcyaml
return super(TreeNodeDebug, self).merge(other)
class MuxTreeNodeDebug(MuxTreeNode, TreeNodeDebug):
"""
Debug version of TreeNodeDebug
......@@ -304,12 +423,12 @@ class MuxTreeNodeDebug(MuxTreeNode, tree.TreeNodeDebug):
def __init__(self, name='', value=None, parent=None, children=None,
srcyaml=None):
MuxTreeNode.__init__(self, name, value, parent, children)
tree.TreeNodeDebug.__init__(self, name, value, parent, children,
srcyaml)
TreeNodeDebug.__init__(self, name, value, parent, children,
srcyaml)
def merge(self, other):
MuxTreeNode.merge(self, other)
tree.TreeNodeDebug.merge(self, other)
TreeNodeDebug.merge(self, other)
#
......
......@@ -420,7 +420,7 @@ class TestMultipleLoaders(unittest.TestCase):
debug = yaml_to_mux.create_from_yaml([yaml_url], debug=True)
self.assertEqual(type(debug), mux.MuxTreeNodeDebug)
# Debug nodes are of generated "NamedTreeNodeDebug" type
self.assertEqual("<class 'avocado.core.tree.NamedTreeNodeDebug'>",
self.assertEqual("<class 'avocado_varianter_yaml_to_mux.NamedTreeNodeDebug'>",
str(type(debug.children[0])))
plain = yaml.load("foo: bar")
self.assertEqual(type(plain), dict)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册