Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
avocado
提交
94cb27dc
A
avocado
项目概览
openeuler
/
avocado
通知
0
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
A
avocado
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
94cb27dc
编写于
12月 19, 2014
作者:
L
Lucas Meneghel Rodrigues
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #315 from ldoktor/multiplexer
avocado.multiplexer: Support for debug run [v3]
上级
9d40978a
e1363982
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
369 addition
and
82 deletion
+369
-82
avocado/core/output.py
avocado/core/output.py
+3
-0
avocado/core/tree.py
avocado/core/tree.py
+134
-60
avocado/core/tree_debug.py
avocado/core/tree_debug.py
+141
-0
avocado/multiplexer.py
avocado/multiplexer.py
+3
-2
avocado/plugins/multiplexer.py
avocado/plugins/multiplexer.py
+14
-4
examples/mux-selftest.yaml
examples/mux-selftest.yaml
+24
-8
selftests/all/functional/avocado/multiplex_tests.py
selftests/all/functional/avocado/multiplex_tests.py
+17
-0
selftests/all/unit/avocado/tree_unittest.py
selftests/all/unit/avocado/tree_unittest.py
+33
-8
未找到文件。
avocado/core/output.py
浏览文件 @
94cb27dc
...
...
@@ -112,6 +112,7 @@ class TermSupport(object):
COLOR_GREEN
=
'
\033
[92m'
COLOR_YELLOW
=
'
\033
[93m'
COLOR_RED
=
'
\033
[91m'
COLOR_DARKGREY
=
'
\033
[90m'
CONTROL_END
=
'
\033
[0m'
...
...
@@ -138,6 +139,7 @@ class TermSupport(object):
self
.
WARN
=
self
.
COLOR_YELLOW
self
.
PARTIAL
=
self
.
COLOR_YELLOW
self
.
ENDC
=
self
.
CONTROL_END
self
.
LOWLIGHT
=
self
.
COLOR_DARKGREY
term
=
os
.
environ
.
get
(
"TERM"
)
if
(
not
os
.
isatty
(
1
))
or
(
term
not
in
self
.
allowed_terms
):
self
.
disable
()
...
...
@@ -155,6 +157,7 @@ class TermSupport(object):
self
.
WARN
=
''
self
.
PARTIAL
=
''
self
.
ENDC
=
''
self
.
LOWLIGHT
=
''
def
header_str
(
self
,
msg
):
"""
...
...
avocado/core/tree.py
浏览文件 @
94cb27dc
...
...
@@ -46,6 +46,10 @@ except ImportError:
class
TreeNode
(
object
):
"""
Class for bounding nodes into tree-structure.
"""
def
__init__
(
self
,
name
=
''
,
value
=
None
,
parent
=
None
,
children
=
None
):
if
value
is
None
:
value
=
{}
...
...
@@ -55,6 +59,7 @@ class TreeNode(object):
self
.
value
=
value
self
.
parent
=
parent
self
.
children
=
[]
self
.
_environment
=
None
for
child
in
children
:
self
.
add_child
(
child
)
...
...
@@ -66,25 +71,30 @@ class TreeNode(object):
return
'%s: %s'
%
(
self
.
path
,
', '
.
join
(
variables
))
def
__len__
(
self
):
""" Return number of descended leaf nodes """
return
len
(
tuple
(
self
.
iter_leaves
()))
def
__iter__
(
self
):
""" Iterate through descended leaf nodes """
return
self
.
iter_leaves
()
def
__eq__
(
self
,
other
):
""" Compares node to other node or string to name of this node """
if
isinstance
(
other
,
str
):
# Compare names
if
self
.
name
==
other
:
return
True
elif
isinstance
(
other
,
self
.
__class__
):
first
=
self
.
__dict__
.
copy
()
first
.
pop
(
'parent'
)
second
=
other
.
__dict__
.
copy
()
second
.
pop
(
'parent'
)
return
first
==
second
return
False
else
:
for
attr
in
(
'name'
,
'value'
,
'children'
):
if
getattr
(
self
,
attr
)
!=
getattr
(
other
,
attr
):
return
False
return
True
def
add_child
(
self
,
node
):
if
isinstance
(
node
,
self
.
__class__
):
"""
Append node as child. Nodes with the same name gets merged into the
existing position.
"""
if
isinstance
(
node
,
TreeNode
):
if
node
.
name
in
self
.
children
:
self
.
children
[
self
.
children
.
index
(
node
.
name
)].
merge
(
node
)
else
:
...
...
@@ -94,26 +104,36 @@ class TreeNode(object):
raise
ValueError
(
'Bad node type.'
)
def
merge
(
self
,
other
):
""" Merges $other node into this one (doesn't check the name) """
"""
Merges `other` node into this one without checking the name of the
other node. New values are appended, existing values overwritten
and unaffected ones are kept. Then all other node children are
added as children (recursively they get either appended at the end
or merged into existing node in the previous position.
"""
self
.
value
.
update
(
other
.
value
)
for
child
in
other
.
children
:
self
.
add_child
(
child
)
@
property
def
is_leaf
(
self
):
return
len
(
self
.
children
)
==
0
""" Is this a leaf node? """
return
not
self
.
children
@
property
def
root
(
self
):
""" Root of this tree """
return
self
.
get_root
()
def
get_root
(
self
):
""" Get root of this tree """
root
=
None
for
root
in
self
.
iter_parents
():
pass
return
root
def
iter_parents
(
self
):
""" Iterate through parent nodes to root """
node
=
self
.
parent
while
True
:
if
node
is
None
:
...
...
@@ -123,16 +143,20 @@ class TreeNode(object):
@
property
def
parents
(
self
):
""" List of parent nodes """
return
self
.
get_parents
()
def
get_parents
(
self
):
""" Get list of parent nodes """
return
list
(
self
.
iter_parents
())
@
property
def
path
(
self
):
""" Node path """
return
self
.
get_path
()
def
get_path
(
self
,
sep
=
'/'
):
""" Get node path """
path
=
[
str
(
self
.
name
)]
for
node
in
self
.
iter_parents
():
path
.
append
(
str
(
node
.
name
))
...
...
@@ -140,86 +164,114 @@ class TreeNode(object):
@
property
def
environment
(
self
):
""" Node environment (values + preceding envs) """
return
self
.
get_environment
()
def
get_environment
(
self
):
def
update_or_extend
(
target
,
source
):
for
k
,
_
in
source
.
items
():
if
k
in
target
and
isinstance
(
target
[
k
],
list
):
target
[
k
].
extend
(
source
[
k
])
else
:
if
isinstance
(
source
[
k
],
list
):
target
[
k
]
=
source
[
k
][:]
""" Get node environment (values + preceding envs) """
if
self
.
_environment
is
None
:
self
.
_environment
=
(
self
.
parent
.
environment
.
copy
()
if
self
.
parent
else
{})
for
key
,
value
in
self
.
value
.
iteritems
():
if
isinstance
(
value
,
list
):
if
(
key
in
self
.
_environment
and
isinstance
(
self
.
_environment
[
key
],
list
)):
self
.
_environment
[
key
]
=
self
.
_environment
[
key
]
+
value
else
:
target
[
k
]
=
source
[
k
]
env
=
{}
rev_parents
=
reversed
(
self
.
get_parents
())
for
parent
in
rev_parents
:
update_or_extend
(
env
,
parent
.
value
)
update_or_extend
(
env
,
self
.
value
)
return
env
def
iter_children_preorder
(
self
,
node
=
None
):
q
=
collections
.
deque
()
self
.
_environment
[
key
]
=
value
else
:
self
.
_environment
[
key
]
=
value
return
self
.
_environment
def
set_environment_dirty
(
self
):
"""
Set the environment cache dirty. You should call this always when
you query for the environment and then change the value or structure.
Otherwise you'll get the old environment instead.
"""
for
child
in
self
.
children
:
child
.
set_environment_dirty
()
self
.
_environment
=
None
def
iter_children_preorder
(
self
):
""" Iterate through children """
queue
=
collections
.
deque
()
node
=
self
while
node
is
not
None
:
yield
node
q
.
extendleft
(
reversed
(
node
.
children
))
q
ueue
.
extendleft
(
reversed
(
node
.
children
))
try
:
node
=
q
.
popleft
()
except
:
node
=
q
ueue
.
popleft
()
except
IndexError
:
node
=
None
def
iter_leaves
(
self
):
""" Iterate throuh leaf nodes """
for
node
in
self
.
iter_children_preorder
():
if
node
.
is_leaf
:
yield
node
def
get_leaves
(
self
):
""" Get list of leaf nodes """
return
list
(
self
.
iter_leaves
())
def
get_ascii
(
self
,
show_internal
=
True
,
compact
=
False
,
attributes
=
None
):
(
lines
,
_
)
=
self
.
_ascii_art
(
show_internal
=
show_internal
,
compact
=
compact
,
attributes
=
attributes
)
"""
Get ascii-art tree structure
:param show_internal: Show intermediary nodes
:param compact: Compress the tree vertically
:param attributes: List of node attributes to be printed out ['name']
:return: string
"""
(
lines
,
_
)
=
self
.
ascii_art
(
show_internal
=
show_internal
,
compact
=
compact
,
attributes
=
attributes
)
return
'
\n
'
+
'
\n
'
.
join
(
lines
)
def
_ascii_art
(
self
,
char1
=
'-'
,
show_internal
=
True
,
compact
=
False
,
attributes
=
None
):
def
ascii_art
(
self
,
char1
=
'-'
,
show_internal
=
True
,
compact
=
False
,
attributes
=
None
):
"""
Generate ascii-art for this node
:param char1: Incomming path character [-]
:param show_internal: Show intermediary nodes
:param compact: Compress the tree vertically
:param attributes: List of node attributes to be printed out ['name']
:return: list of strings
"""
if
attributes
is
None
:
attributes
=
[
"name"
]
node_name
=
', '
.
join
(
map
(
str
,
[
getattr
(
self
,
v
)
for
v
in
attributes
if
hasattr
(
self
,
v
)]))
LEN
=
max
(
3
,
len
(
node_name
)
if
not
self
.
children
or
show_internal
else
3
)
PAD
=
' '
*
LEN
PA
=
' '
*
(
LEN
-
1
)
length
=
max
(
3
,
len
(
node_name
)
if
not
self
.
children
or
show_internal
else
3
)
pad
=
' '
*
length
_pad
=
' '
*
(
length
-
1
)
if
not
self
.
is_leaf
:
mids
=
[]
result
=
[]
for
c
in
self
.
children
:
for
c
har
in
self
.
children
:
if
len
(
self
.
children
)
==
1
:
char2
=
'/'
elif
c
is
self
.
children
[
0
]:
elif
c
har
is
self
.
children
[
0
]:
char2
=
'/'
elif
c
is
self
.
children
[
-
1
]:
elif
c
har
is
self
.
children
[
-
1
]:
char2
=
'
\\
'
else
:
char2
=
'-'
(
clines
,
mid
)
=
c
.
_
ascii_art
(
char2
,
show_internal
,
compact
,
attributes
)
(
clines
,
mid
)
=
c
har
.
ascii_art
(
char2
,
show_internal
,
compact
,
attributes
)
mids
.
append
(
mid
+
len
(
result
))
result
.
extend
(
clines
)
if
not
compact
:
result
.
append
(
''
)
if
not
compact
:
result
.
pop
()
(
lo
,
hi
,
end
)
=
(
mids
[
0
],
mids
[
-
1
],
len
(
result
))
prefixes
=
([
PAD
]
*
(
lo
+
1
)
+
[
PA
+
'|'
]
*
(
hi
-
lo
-
1
)
+
[
PAD
]
*
(
end
-
hi
))
mid
=
(
lo
+
hi
)
/
2
prefixes
[
mid
]
=
char1
+
'-'
*
(
LEN
-
2
)
+
prefixes
[
mid
][
-
1
]
(
lo
w
,
high
,
end
)
=
(
mids
[
0
],
mids
[
-
1
],
len
(
result
))
prefixes
=
([
pad
]
*
(
low
+
1
)
+
[
_pad
+
'|'
]
*
(
high
-
low
-
1
)
+
[
pad
]
*
(
end
-
high
))
mid
=
(
lo
w
+
high
)
/
2
prefixes
[
mid
]
=
char1
+
'-'
*
(
length
-
2
)
+
prefixes
[
mid
][
-
1
]
result
=
[
p
+
l
for
(
p
,
l
)
in
zip
(
prefixes
,
result
)]
if
show_internal
:
stem
=
result
[
mid
]
...
...
@@ -229,21 +281,23 @@ class TreeNode(object):
return
[
char1
+
'-'
+
node_name
],
0
def
detach
(
self
):
""" Detach this node from parent """
if
self
.
parent
:
self
.
parent
.
children
.
remove
(
self
)
self
.
parent
=
None
return
self
def
_create_from_yaml
(
stream
):
""" Create tree structure from yaml stream """
class
Value
(
tuple
):
class
Value
(
tuple
):
# Few methods pylint: disable=R0903
""" Used to mark values to simplify checking for node vs. value """
pass
""" Used to mark values to simplify checking for node vs. value """
pass
def
_create_from_yaml
(
path
,
cls_node
=
TreeNode
):
""" Create tree structure from yaml stream """
def
tree_node_from_values
(
name
,
values
):
""" Create
$name
node and add values """
""" Create
`name`
node and add values """
node_children
=
[]
node_values
=
[]
for
value
in
values
:
...
...
@@ -251,10 +305,12 @@ def _create_from_yaml(stream):
node_children
.
append
(
value
)
else
:
node_values
.
append
(
value
)
return
TreeN
ode
(
name
,
dict
(
node_values
),
children
=
node_children
)
return
cls_n
ode
(
name
,
dict
(
node_values
),
children
=
node_children
)
def
mapping_to_tree_loader
(
loader
,
node
):
""" Maps yaml mapping tag to TreeNode structure """
def
is_node
(
values
):
""" Whether these values represent node or just random values """
if
(
isinstance
(
values
,
list
)
and
values
and
isinstance
(
values
[
0
],
(
Value
,
TreeNode
))):
# When any value is TreeNode or Value, all of them are already
...
...
@@ -267,26 +323,44 @@ def _create_from_yaml(stream):
if
is_node
(
values
):
# New node
objects
.
append
(
tree_node_from_values
(
name
,
values
))
elif
values
is
None
:
# Empty node
objects
.
append
(
TreeN
ode
(
name
))
objects
.
append
(
cls_n
ode
(
name
))
else
:
# Values
objects
.
append
(
Value
((
name
,
values
)))
return
objects
Loader
.
add_constructor
(
yaml
.
resolver
.
BaseResolver
.
DEFAULT_MAPPING_TAG
,
mapping_to_tree_loader
)
return
tree_node_from_values
(
''
,
yaml
.
load
(
stream
,
Loader
))
with
open
(
path
)
as
stream
:
return
tree_node_from_values
(
''
,
yaml
.
load
(
stream
,
Loader
))
def
create_from_yaml
(
paths
):
def
create_from_yaml
(
paths
,
debug
=
False
):
"""
Create tree structure from yaml-like file
:param fileobj: File object to be processed
:raise SyntaxError: When yaml-file is corrupted
:return: Root of the created tree structure
"""
data
=
TreeNode
()
def
_merge
(
data
,
path
):
""" Normal run """
data
.
merge
(
_create_from_yaml
(
path
))
def
_merge_debug
(
data
,
path
):
""" Use NamedTreeNodeDebug magic """
node_cls
=
tree_debug
.
get_named_tree_cls
(
path
)
data
.
merge
(
_create_from_yaml
(
path
,
node_cls
))
if
not
debug
:
data
=
TreeNode
()
merge
=
_merge
else
:
from
avocado.core
import
tree_debug
data
=
tree_debug
.
TreeNodeDebug
()
merge
=
_merge_debug
try
:
for
path
in
paths
:
data
.
merge
(
_create_from_yaml
(
open
(
path
).
read
())
)
merge
(
data
,
path
)
except
(
yaml
.
scanner
.
ScannerError
,
yaml
.
parser
.
ParserError
)
as
err
:
raise
SyntaxError
(
err
)
return
data
...
...
avocado/core/tree_debug.py
0 → 100644
浏览文件 @
94cb27dc
"""
Debug version of the avocado.core.tree.TreeNode with additional utils.
:license: GPLv2
:copyright: Red Hat, Inc. 2014
:author: Lukas Doktor <ldoktor@redhat.com>
"""
import
itertools
import
os
from
avocado.core
import
output
from
avocado.core.tree
import
TreeNode
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
values
.
iteritems
():
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
self
.
iterkeys
():
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'
):
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
):
""" Return TreeNodeDebug class with hardcoded yaml path """
class
NamedTreeNodeDebug
(
TreeNodeDebug
):
# 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
)
return
NamedTreeNodeDebug
avocado/multiplexer.py
浏览文件 @
94cb27dc
...
...
@@ -77,12 +77,13 @@ def multiplex(*args):
yield
tuple
(
prod
)
def
multiplex_yamls
(
input_yamls
,
filter_only
=
None
,
filter_out
=
None
):
def
multiplex_yamls
(
input_yamls
,
filter_only
=
None
,
filter_out
=
None
,
debug
=
False
):
if
filter_only
is
None
:
filter_only
=
[]
if
filter_out
is
None
:
filter_out
=
[]
input_tree
=
tree
.
create_from_yaml
(
input_yamls
)
input_tree
=
tree
.
create_from_yaml
(
input_yamls
,
debug
)
final_tree
=
tree
.
apply_filters
(
input_tree
,
filter_only
,
filter_out
)
leaves
=
(
x
for
x
in
final_tree
.
iter_leaves
()
if
x
.
parent
is
not
None
)
variants
=
multiplex
(
leaves
)
...
...
avocado/plugins/multiplexer.py
浏览文件 @
94cb27dc
...
...
@@ -50,6 +50,9 @@ class Multiplexer(plugin.Plugin):
self
.
parser
.
add_argument
(
'-c'
,
'--contents'
,
action
=
'store_true'
,
default
=
False
,
help
=
"Shows the variant's content (variables)"
)
self
.
parser
.
add_argument
(
'-d'
,
'--debug'
,
action
=
'store_true'
,
default
=
False
,
help
=
"Debug multiplexed "
"files."
)
super
(
Multiplexer
,
self
).
configure
(
self
.
parser
)
def
run
(
self
,
args
):
...
...
@@ -71,15 +74,22 @@ class Multiplexer(plugin.Plugin):
variants
=
multiplexer
.
multiplex_yamls
(
multiplex_files
,
args
.
filter_only
,
args
.
filter_out
)
args
.
filter_out
,
args
.
debug
)
view
.
notify
(
event
=
'message'
,
msg
=
'Variants generated:'
)
for
(
index
,
tpl
)
in
enumerate
(
variants
):
paths
=
', '
.
join
([
x
.
path
for
x
in
tpl
])
view
.
notify
(
event
=
'minor'
,
msg
=
'Variant %s: %s'
%
if
not
args
.
debug
:
paths
=
', '
.
join
([
x
.
path
for
x
in
tpl
])
else
:
color
=
output
.
term_support
.
LOWLIGHT
cend
=
output
.
term_support
.
ENDC
paths
=
', '
.
join
([
"%s%s@%s%s"
%
(
_
.
name
,
color
,
_
.
yaml
,
cend
)
for
_
in
tpl
])
view
.
notify
(
event
=
'minor'
,
msg
=
'
\n
Variant %s: %s'
%
(
index
+
1
,
paths
))
if
args
.
contents
:
env
=
collections
.
OrderedDict
()
env
=
{}
for
node
in
tpl
:
env
.
update
(
node
.
environment
)
for
k
in
sorted
(
env
.
keys
()):
...
...
examples/mux-selftest.yaml
浏览文件 @
94cb27dc
# Special values
# joinlist: list which gets combined while getting environment
# corruptlist: list which is overwritten with string and again by list
# /distro: should be merged from two separated trees into the position of
# the first one. PS: Don't do this in production, it works but
# it's not nice and readable... here it simulates the use of
# multiple files and checks that the node ordering works fine.
# /env/opt_CFLAGS: Should be present in merged node
# /env/prod/opt_CFLAGS: value should be overridden by latter node
hw
:
cpu
:
test_value
:
-
a
joinlist
:
-
first_item
intel
:
cpu_CFLAGS
:
'
-march=core2'
amd
:
test_value
:
-
b
-
c
joinlist
:
[
'
second'
,
'
third'
]
cpu_CFLAGS
:
'
-march=athlon64'
arm
:
cpu_CFLAGS
:
'
-mabi=apcs-gnu
-march=armv8-a
-mtune=arm8'
disk
:
disk_type
:
'
virtio'
corruptlist
:
'
nonlist'
scsi
:
corruptlist
:
[
'
againlist'
]
disk_type
:
'
scsi'
virtio
:
test_value
:
42
corruptlist
:
[
'
upper_node_list'
]
distro
:
fedora
:
init
:
'
systemd'
mint
:
init
:
'
systemv'
env
:
opt_CFLAGS
:
'
-Os'
prod
:
opt_CFLAGS
:
'
THIS
SHOULD
GET
OVERWRITTEN'
env
:
prod
:
opt_CFLAGS
:
'
-O2'
distro
:
mint
:
init
:
'
systemv'
selftests/all/functional/avocado/multiplex_tests.py
浏览文件 @
94cb27dc
...
...
@@ -13,6 +13,15 @@ if os.path.isdir(os.path.join(basedir, 'avocado')):
from
avocado.utils
import
process
DEBUG_OUT
=
"""Variant 16: amd@examples/mux-environment.yaml, virtio@examples/mux-environment.yaml, mint@examples/mux-environment.yaml, debug@examples/mux-environment.yaml
corruptlist: nonlist@examples/mux-selftest.yaml:/hw/disk
cpu_CFLAGS: -march=athlon64@examples/mux-environment.yaml:/hw/cpu/amd
disk_type: virtio@examples/mux-environment.yaml:/hw/disk/virtio
init: systemv@examples/mux-environment.yaml:/distro/mint
joinlist: ['first_item']@examples/mux-selftest.yaml:/hw/cpu + ['second', 'third']@examples/mux-selftest.yaml:/hw/cpu/amd
opt_CFLAGS: -O0 -g@examples/mux-environment.yaml:/env/debug
"""
class
MultiplexTests
(
unittest
.
TestCase
):
...
...
@@ -51,6 +60,14 @@ class MultiplexTests(unittest.TestCase):
expected_rc
=
2
self
.
run_and_check
(
cmd_line
,
expected_rc
)
def
test_mplex_debug
(
self
):
cmd_line
=
(
'./scripts/avocado multiplex -c -d '
'examples/mux-selftest.yaml examples/mux-environment.yaml '
'examples/mux-selftest.yaml examples/mux-environment.yaml'
)
expected_rc
=
0
out
=
self
.
run_and_check
(
cmd_line
,
expected_rc
)
self
.
assertIn
(
DEBUG_OUT
,
out
)
def
test_run_mplex_noid
(
self
):
cmd_line
=
'./scripts/avocado run --multiplex examples/tests/sleeptest.py.data/sleeptest.yaml'
expected_rc
=
2
...
...
selftests/all/unit/avocado/tree_unittest.py
浏览文件 @
94cb27dc
...
...
@@ -17,7 +17,8 @@ class TestTree(unittest.TestCase):
self
.
tree
.
children
[
0
].
children
[
0
].
children
[
0
].
value
)
disk
=
self
.
tree
.
children
[
0
].
children
[
1
]
self
.
assertEqual
(
'scsi'
,
disk
.
children
[
0
])
self
.
assertEqual
({
'disk_type'
:
'scsi'
},
disk
.
children
[
0
].
value
)
self
.
assertEqual
({
'disk_type'
:
'scsi'
,
'corruptlist'
:
[
'againlist'
]},
disk
.
children
[
0
].
value
)
self
.
assertEqual
(
'virtio'
,
disk
.
children
[
1
])
self
.
assertEqual
({},
disk
.
children
[
1
].
value
)
self
.
assertEqual
(
'distro'
,
self
.
tree
.
children
[
1
])
...
...
@@ -54,6 +55,11 @@ class TestTree(unittest.TestCase):
# Add_child incorrect class
self
.
assertRaises
(
ValueError
,
tree3
.
add_child
,
'probably_bad_type'
)
def
test_links
(
self
):
""" Verify child->parent links """
for
leaf
in
self
.
tree
:
self
.
assertEqual
(
leaf
.
root
,
self
.
tree
)
def
test_basic_functions
(
self
):
# repr
self
.
assertEqual
(
"TreeNode(name='hw')"
,
repr
(
self
.
tree
.
children
[
0
]))
...
...
@@ -70,18 +76,36 @@ class TestTree(unittest.TestCase):
)
# .parents
self
.
assertEqual
([
'hw'
,
''
],
self
.
tree
.
children
[
0
].
children
[
0
].
parents
)
# environment
# environment
/ (root)
self
.
assertEqual
({},
self
.
tree
.
environment
)
self
.
assertEqual
({
'test_value'
:
42
},
# environment /hw (nodes first)
self
.
assertEqual
({
'corruptlist'
:
[
'upper_node_list'
]},
self
.
tree
.
children
[
0
].
environment
)
cpu
=
self
.
tree
.
children
[
0
].
children
[
0
]
self
.
assertEqual
({
'test_value'
:
[
'a'
]},
# environment /hw/cpu (mixed env)
self
.
assertEqual
({
'corruptlist'
:
[
'upper_node_list'
],
'joinlist'
:
[
'first_item'
]},
cpu
.
environment
)
vals
=
{
'test_value'
:
[
'a'
,
'b'
,
'c'
],
'cpu_CFLAGS'
:
'-march=athlon64'
}
# environment /hw/cpu/amd (list extension)
vals
=
{
'corruptlist'
:
[
'upper_node_list'
],
'cpu_CFLAGS'
:
'-march=athlon64'
,
'joinlist'
:
[
'first_item'
,
'second'
,
'third'
]}
self
.
assertEqual
(
vals
,
cpu
.
children
[
1
].
environment
)
vals
=
{
'test_value'
:
[
'a'
],
'cpu_CFLAGS'
:
'-mabi=apcs-gnu '
# environment /hw/cpu/arm (deep env)
vals
=
{
'corruptlist'
:
[
'upper_node_list'
],
'joinlist'
:
[
'first_item'
],
'cpu_CFLAGS'
:
'-mabi=apcs-gnu '
'-march=armv8-a -mtune=arm8'
}
self
.
assertEqual
(
vals
,
cpu
.
children
[
2
].
environment
)
# environment /hw/disk (list -> string)
vals
=
{
'corruptlist'
:
'nonlist'
,
'disk_type'
:
'virtio'
}
disk
=
self
.
tree
.
children
[
0
].
children
[
1
]
self
.
assertEqual
(
vals
,
disk
.
environment
)
# environment /hw/disk/scsi (string -> list)
vals
=
{
'corruptlist'
:
[
'againlist'
],
'disk_type'
:
'scsi'
}
self
.
assertEqual
(
vals
,
disk
.
children
[
0
].
environment
)
# environment /env
vals
=
{
'opt_CFLAGS'
:
'-Os'
}
self
.
assertEqual
(
vals
,
self
.
tree
.
children
[
2
].
environment
)
# leaves order
leaves
=
[
'intel'
,
'amd'
,
'arm'
,
'scsi'
,
'virtio'
,
'fedora'
,
'mint'
,
'prod'
]
...
...
@@ -119,9 +143,10 @@ class TestTree(unittest.TestCase):
exp
=
[
'intel'
,
'amd'
,
'arm'
,
'scsi'
,
'virtio'
,
'default'
,
'virtio'
,
'fedora'
,
'mint'
,
'prod'
]
self
.
assertEqual
(
exp
,
tree2
.
get_leaves
())
self
.
assertEqual
({
'test_value'
:
42
,
'another_value'
:
'bbb'
},
self
.
assertEqual
({
'corruptlist'
:
[
'upper_node_list'
],
'another_value'
:
'bbb'
},
tree2
.
children
[
0
].
value
)
self
.
assertEqual
({
'test_value'
:
[
'z'
]},
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'
},
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录