Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
avocado
提交
bb04ad64
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,发现更多精彩内容 >>
提交
bb04ad64
编写于
10月 01, 2015
作者:
L
Lucas Meneghel Rodrigues
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'ldoktor-loader2'
上级
d1201443
fddbd88c
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
321 addition
and
162 deletion
+321
-162
avocado/core/job.py
avocado/core/job.py
+7
-1
avocado/core/loader.py
avocado/core/loader.py
+197
-26
avocado/core/plugins/inner_runner.py
avocado/core/plugins/inner_runner.py
+0
-96
avocado/core/plugins/runner.py
avocado/core/plugins/runner.py
+3
-0
avocado/core/plugins/test_list.py
avocado/core/plugins/test_list.py
+7
-1
avocado/core/test.py
avocado/core/test.py
+41
-32
docs/source/Loaders.rst
docs/source/Loaders.rst
+54
-0
docs/source/index.rst
docs/source/index.rst
+1
-0
etc/avocado/avocado.conf
etc/avocado/avocado.conf
+7
-3
selftests/functional/test_basic.py
selftests/functional/test_basic.py
+3
-2
selftests/unit/test_loader.py
selftests/unit/test_loader.py
+1
-1
未找到文件。
avocado/core/job.py
浏览文件 @
bb04ad64
...
...
@@ -48,6 +48,7 @@ from ..utils import archive
from
..utils
import
astring
from
..utils
import
path
from
..utils
import
runtime
from
..utils
import
stacktrace
try
:
from
.plugins
import
htmlresult
...
...
@@ -446,7 +447,12 @@ class Job(object):
self
.
view
.
start_file_logging
(
self
.
logfile
,
self
.
loglevel
,
self
.
unique_id
)
test_suite
=
self
.
_make_test_suite
(
urls
)
try
:
test_suite
=
self
.
_make_test_suite
(
urls
)
except
loader
.
LoaderError
,
details
:
stacktrace
.
log_exc_info
(
sys
.
exc_info
(),
'avocado.app.tracebacks'
)
self
.
_remove_job_results
()
raise
exceptions
.
OptionValidationError
(
details
)
if
not
test_suite
:
self
.
_remove_job_results
()
e_msg
=
(
"No tests found for given urls, try 'avocado list -V %s' "
...
...
avocado/core/loader.py
浏览文件 @
bb04ad64
...
...
@@ -17,16 +17,19 @@
Test loader module.
"""
import
collections
import
imp
import
inspect
import
os
import
re
import
sys
import
shlex
import
fnmatch
from
.
import
data_dir
from
.
import
output
from
.
import
test
from
.
import
exceptions
from
.settings
import
settings
from
..utils
import
path
from
..utils
import
stacktrace
...
...
@@ -79,11 +82,20 @@ class TestLoaderProxy(object):
self
.
_initialized_plugins
=
[]
self
.
registered_plugins
=
[]
self
.
url_plugin_mapping
=
{}
self
.
_test_types
=
{}
def
register_plugin
(
self
,
plugin
):
try
:
if
issubclass
(
plugin
,
TestLoader
):
self
.
registered_plugins
.
append
(
plugin
)
for
test_type
in
plugin
.
get_type_label_mapping
().
itervalues
():
if
(
test_type
in
self
.
_test_types
and
self
.
_test_types
[
test_type
]
!=
plugin
):
msg
=
(
"Multiple plugins using the same test_type not "
"yet supported (%s, %s)"
%
(
test_type
,
self
.
_test_types
))
raise
NotImplementedError
(
msg
)
self
.
_test_types
[
test_type
]
=
plugin
else
:
raise
ValueError
except
ValueError
:
...
...
@@ -91,23 +103,45 @@ class TestLoaderProxy(object):
"TestLoader"
%
plugin
)
def
load_plugins
(
self
,
args
):
def
_err_list_loaders
():
return
(
"Loaders: %s
\n
Types: %s"
%
(
names
,
self
.
_test_types
.
keys
()))
self
.
_initialized_plugins
=
[]
# Add (default) file loader if not already registered
if
FileLoader
not
in
self
.
registered_plugins
:
self
.
register
ed_plugins
.
append
(
FileLoader
)
self
.
register
_plugin
(
FileLoader
)
# Load plugin by the priority from settings
names
=
[
_
.
name
for
_
in
self
.
registered_plugins
]
priority
=
settings
.
get_value
(
"plugins"
,
"loader_plugins_priority"
,
list
,
[])
sorted_plugins
=
[
self
.
registered_plugins
[
names
.
index
(
name
)]
for
name
in
priority
if
name
in
names
]
for
plugin
in
sorted_plugins
:
self
.
_initialized_plugins
.
append
(
plugin
(
args
))
for
plugin
in
self
.
registered_plugins
:
if
plugin
in
sorted_plugins
:
continue
self
.
_initialized_plugins
.
append
(
plugin
(
args
))
names
=
[
"@"
+
_
.
name
for
_
in
self
.
registered_plugins
]
loaders
=
getattr
(
args
,
'loaders'
,
None
)
if
not
loaders
:
loaders
=
settings
.
get_value
(
"plugins"
,
"loaders"
,
list
,
[])
if
'?'
in
loaders
:
raise
LoaderError
(
"Loaders: %s
\n
Types: %s"
%
(
names
,
self
.
_test_types
.
keys
()))
if
"DEFAULT"
in
loaders
:
# Replace DEFAULT with unused loaders
idx
=
loaders
.
index
(
"DEFAULT"
)
loaders
=
(
loaders
[:
idx
]
+
[
_
for
_
in
names
if
_
not
in
loaders
]
+
loaders
[
idx
+
1
:])
while
"DEFAULT"
in
loaders
:
# Remove duplicite DEFAULT entries
loaders
.
remove
(
"DEFAULT"
)
loaders
=
[
_
.
split
(
':'
,
1
)
for
_
in
loaders
]
priority
=
[
_
[
0
]
for
_
in
loaders
]
for
i
,
name
in
enumerate
(
priority
):
extra_params
=
{}
if
name
in
names
:
plugin
=
self
.
registered_plugins
[
names
.
index
(
name
)]
elif
name
in
self
.
_test_types
:
plugin
=
self
.
_test_types
[
name
]
extra_params
[
'allowed_test_types'
]
=
name
else
:
raise
InvalidLoaderPlugin
(
"Loader '%s' not available:
\n
"
"Loaders: %s
\n
Types: %s"
%
(
name
,
names
,
self
.
_test_types
.
keys
()))
if
len
(
loaders
[
i
])
==
2
:
extra_params
[
'loader_options'
]
=
loaders
[
i
][
1
]
self
.
_initialized_plugins
.
append
(
plugin
(
args
,
extra_params
))
def
get_extra_listing
(
self
):
for
loader_plugin
in
self
.
_initialized_plugins
:
...
...
@@ -153,8 +187,7 @@ class TestLoaderProxy(object):
if
not
urls
:
for
loader_plugin
in
self
.
_initialized_plugins
:
try
:
tests
.
extend
(
loader_plugin
.
discover
(
None
,
list_tests
))
tests
.
extend
(
loader_plugin
.
discover
(
None
,
list_tests
))
except
Exception
,
details
:
handle_exception
(
loader_plugin
,
details
)
else
:
...
...
@@ -200,13 +233,14 @@ class TestLoader(object):
Base for test loader classes
"""
def
__init__
(
self
,
args
):
def
__init__
(
self
,
args
,
extra_params
):
# pylint: disable=W0613
self
.
args
=
args
def
get_extra_listing
(
self
):
pass
def
get_type_label_mapping
(
self
):
@
staticmethod
def
get_type_label_mapping
():
"""
Get label mapping for display in test listing.
...
...
@@ -214,7 +248,8 @@ class TestLoader(object):
"""
raise
NotImplementedError
def
get_decorator_mapping
(
self
):
@
staticmethod
def
get_decorator_mapping
():
"""
Get label mapping for display in test listing.
...
...
@@ -222,7 +257,7 @@ class TestLoader(object):
"""
raise
NotImplementedError
def
discover
(
self
,
url
,
list_tests
=
False
):
def
discover
(
self
,
url
,
list_tests
=
DEFAULT
):
"""
Discover (possible) tests from an url.
...
...
@@ -254,6 +289,43 @@ class FilteredOut(object):
pass
def
add_file_loader_options
(
parser
):
loader
=
parser
.
add_argument_group
(
'loader options'
)
loader
.
add_argument
(
'--loaders'
,
nargs
=
'*'
,
help
=
"Overrides the priority "
"of the test loaders. You can specify either "
"@loader_name or TEST_TYPE. By default it tries all "
"available loaders according to priority set in "
"settings->plugins.loaders."
)
loader
.
add_argument
(
'--inner-runner'
,
default
=
None
,
metavar
=
'EXECUTABLE'
,
help
=
(
'Path to an specific test runner that '
'allows the use of its own tests. This '
'should be used for running tests that '
'do not conform to Avocado
\'
SIMPLE test'
'interface and can not run standalone'
))
chdir_help
=
(
'Change directory before executing tests. This option '
'may be necessary because of requirements and/or '
'limitations of the inner test runner. If the inner '
'runner requires to be run from its own base directory,'
'use "runner" here. If the inner runner runs tests based'
' on files and requires to be run from the directory '
'where those files are located, use "test" here and '
'specify the test directory with the option '
'"--inner-runner-testdir". Defaults to "%(default)s"'
)
loader
.
add_argument
(
'--inner-runner-chdir'
,
default
=
'off'
,
choices
=
(
'runner'
,
'test'
,
'off'
),
help
=
chdir_help
)
loader
.
add_argument
(
'--inner-runner-testdir'
,
metavar
=
'DIRECTORY'
,
default
=
None
,
help
=
(
'Where test files understood by the inner'
' test runner are located in the '
'filesystem. Obviously this assumes and '
'only applies to inner test runners that '
'run tests from files'
))
class
FileLoader
(
TestLoader
):
"""
...
...
@@ -262,8 +334,67 @@ class FileLoader(TestLoader):
name
=
'file'
def
get_type_label_mapping
(
self
):
def
__init__
(
self
,
args
,
extra_params
):
super
(
FileLoader
,
self
).
__init__
(
args
,
extra_params
)
loader_options
=
extra_params
.
get
(
'loader_options'
)
if
loader_options
==
'?'
:
raise
LoaderError
(
"File loader accept option to sets the "
"inner-runner executable."
)
self
.
_inner_runner
=
self
.
_process_inner_runner
(
args
,
loader_options
)
self
.
test_type
=
extra_params
.
get
(
'allowed_test_types'
)
@
staticmethod
def
_process_inner_runner
(
args
,
extra_params
):
""" Enables the inner_runner when asked for """
runner
=
getattr
(
args
,
'inner_runner'
,
None
)
chdir
=
getattr
(
args
,
'inner_runner_chdir'
,
'off'
)
test_dir
=
getattr
(
args
,
'inner_runner_testdir'
,
None
)
if
extra_params
:
if
runner
:
msg
=
(
"Inner runner specified via booth: --loaders (%s) and "
"--inner-runner (%s). Please use only one of them"
%
(
extra_params
,
runner
))
raise
LoaderError
(
msg
)
runner
=
extra_params
if
runner
:
inner_runner_and_args
=
shlex
.
split
(
runner
)
if
len
(
inner_runner_and_args
)
>
1
:
executable
=
inner_runner_and_args
[
0
]
else
:
executable
=
runner
if
not
os
.
path
.
exists
(
executable
):
msg
=
(
'Could not find the inner runner executable "%s"'
%
executable
)
raise
LoaderError
(
msg
)
if
chdir
==
'test'
:
if
not
test_dir
:
msg
=
(
'Option "--inner-runner-chdir=test" requires '
'"--inner-runner-testdir" to be set.'
)
raise
LoaderError
(
msg
)
elif
test_dir
:
msg
=
(
'Option "--inner-runner-testdir" requires '
'"--inner-runner-chdir=test".'
)
raise
LoaderError
(
msg
)
cls_inner_runner
=
collections
.
namedtuple
(
'InnerRunner'
,
[
'runner'
,
'chdir'
,
'test_dir'
])
return
cls_inner_runner
(
runner
,
chdir
,
test_dir
)
elif
chdir
!=
"off"
:
msg
=
(
'Option "--inner-runner-chdir" requires '
'"--inner-runner" to be set.'
)
raise
LoaderError
(
msg
)
elif
test_dir
:
msg
=
(
'Option "--inner-runner-test-dir" requires '
'"--inner-runner" to be set.'
)
raise
LoaderError
(
msg
)
@
staticmethod
def
get_type_label_mapping
():
return
{
test
.
SimpleTest
:
'SIMPLE'
,
test
.
InnerRunnerTest
:
'INNER_RUNNER'
,
test
.
BuggyTest
:
'BUGGY'
,
test
.
NotATest
:
'NOT_A_TEST'
,
test
.
MissingTest
:
'MISSING'
,
...
...
@@ -272,9 +403,11 @@ class FileLoader(TestLoader):
test
.
Test
:
'INSTRUMENTED'
,
FilteredOut
:
'FILTERED'
}
def
get_decorator_mapping
(
self
):
@
staticmethod
def
get_decorator_mapping
():
term_support
=
output
.
TermSupport
()
return
{
test
.
SimpleTest
:
term_support
.
healthy_str
,
test
.
InnerRunnerTest
:
term_support
.
healthy_str
,
test
.
BuggyTest
:
term_support
.
fail_header_str
,
test
.
NotATest
:
term_support
.
warn_header_str
,
test
.
MissingTest
:
term_support
.
fail_header_str
,
...
...
@@ -290,12 +423,45 @@ class FileLoader(TestLoader):
Recursively walk in a directory and find tests params.
The tests are returned in alphabetic order.
Afterwards when "allowed_test_types" is supplied it verifies if all
found tests are of the allowed type. If not return None (even on
partial match).
:param url: the directory path to inspect.
:param list_tests: list corrupted/invalid tests too
:return: list of matching tests
"""
tests
=
self
.
_discover
(
url
,
list_tests
)
if
self
.
test_type
:
mapping
=
self
.
get_type_label_mapping
()
if
self
.
test_type
==
'INSTRUMENTED'
:
# Instrumented is parent of all of supported tests, we need to
# exclude the rest of the supported tests
filtered_clss
=
tuple
(
_
for
_
in
mapping
.
iterkeys
()
if
_
is
not
test
.
Test
)
for
tst
in
tests
:
if
(
not
issubclass
(
tst
[
0
],
test
.
Test
)
or
issubclass
(
tst
[
0
],
filtered_clss
)):
return
None
else
:
test_class
=
(
key
for
key
,
value
in
mapping
.
iteritems
()
if
value
==
self
.
test_type
).
next
()
for
tst
in
tests
:
if
not
issubclass
(
tst
[
0
],
test_class
):
return
None
return
tests
def
_discover
(
self
,
url
,
list_tests
=
DEFAULT
):
"""
Recursively walk in a directory and find tests params.
The tests are returned in alphabetic order.
:param url: the directory path to inspect.
:param list_tests: list corrupted/invalid tests too
:return: list of matching tests
"""
if
test
.
INNER_RUNNER
is
not
None
:
return
self
.
_make_
tests
(
url
,
[],
[]
)
if
self
.
_inner_runner
:
return
self
.
_make_
inner_runner_test
(
url
)
if
url
is
None
:
if
list_tests
is
DEFAULT
:
...
...
@@ -453,6 +619,14 @@ class FileLoader(TestLoader):
params
.
setdefault
(
'id'
,
uid
)
return
[(
klass
,
{
'name'
:
uid
,
'params'
:
params
})]
def
_make_inner_runner_test
(
self
,
test_path
):
"""
Creates inner-runner test (adds self._inner_runner as test argument)
"""
tst
=
self
.
_make_test
(
test
.
InnerRunnerTest
,
test_path
)
tst
[
0
][
1
][
'inner_runner'
]
=
self
.
_inner_runner
return
tst
def
_make_tests
(
self
,
test_path
,
list_non_tests
,
subtests_filter
=
None
):
"""
Create test templates from given path
...
...
@@ -464,9 +638,6 @@ class FileLoader(TestLoader):
""" Always return empty list """
return
[]
if
test
.
INNER_RUNNER
is
not
None
:
return
self
.
_make_test
(
test
.
SimpleTest
,
test_path
)
if
list_non_tests
:
# return broken test with params
make_broken
=
self
.
_make_test
else
:
# return empty set instead
...
...
avocado/core/plugins/inner_runner.py
已删除
100644 → 0
浏览文件 @
d1201443
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# See LICENSE for more details.
#
# Copyright: Red Hat Inc. 2015
# Author: Cleber Rosa <cleber@redhat.com>
"""Allows the use of an intermediary inner test runner."""
import
os
import
sys
import
shlex
from
.
import
plugin
from
..
import
test
from
..
import
output
from
..
import
exit_codes
class
InnerRunner
(
plugin
.
Plugin
):
"""
Allows the use of an intermediary inner test runner
"""
name
=
'inner_runner'
enabled
=
True
def
configure
(
self
,
parser
):
inner_grp
=
parser
.
runner
.
add_argument_group
(
'inner test runner support'
)
inner_grp
.
add_argument
(
'--inner-runner'
,
default
=
None
,
metavar
=
'EXECUTABLE'
,
help
=
(
'Path to an specific test runner that '
'allows the use of its own tests. This '
'should be used for running tests that '
'do not conform to Avocado
\'
SIMPLE test'
'interface and can not run standalone'
))
chdir_help
=
(
'Change directory before executing tests. This option '
'may be necessary because of requirements and/or '
'limitations of the inner test runner. If the inner '
'runner requires to be run from its own base directory,'
'use "runner" here. If the inner runner runs tests based'
' on files and requires to be run from the directory '
'where those files are located, use "test" here and '
'specify the test directory with the option '
'"--inner-runner-testdir". Defaults to "%(default)s"'
)
inner_grp
.
add_argument
(
'--inner-runner-chdir'
,
default
=
'off'
,
choices
=
(
'runner'
,
'test'
,
'off'
),
help
=
chdir_help
)
inner_grp
.
add_argument
(
'--inner-runner-testdir'
,
metavar
=
'DIRECTORY'
,
default
=
None
,
help
=
(
'Where test files understood by the inner'
' test runner are located in the '
'filesystem. Obviously this assumes and '
'only applies to inner test runners that '
'run tests from files'
))
self
.
configured
=
True
def
activate
(
self
,
app_args
):
self
.
view
=
output
.
View
(
app_args
=
app_args
)
if
hasattr
(
app_args
,
'inner_runner'
):
if
app_args
.
inner_runner
:
inner_runner_and_args
=
shlex
.
split
(
app_args
.
inner_runner
)
if
len
(
inner_runner_and_args
)
>
1
:
executable
=
inner_runner_and_args
[
0
]
else
:
executable
=
app_args
.
inner_runner
if
not
os
.
path
.
exists
(
executable
):
msg
=
'Could not find the inner runner executable "%s"'
%
executable
self
.
view
.
notify
(
event
=
'error'
,
msg
=
msg
)
sys
.
exit
(
exit_codes
.
AVOCADO_FAIL
)
test
.
INNER_RUNNER
=
app_args
.
inner_runner
if
hasattr
(
app_args
,
'inner_runner_testdir'
):
if
app_args
.
inner_runner_testdir
:
test
.
INNER_RUNNER_TESTDIR
=
app_args
.
inner_runner_testdir
if
hasattr
(
app_args
,
'inner_runner_chdir'
):
if
app_args
.
inner_runner_chdir
:
if
app_args
.
inner_runner_chdir
==
'test'
:
if
app_args
.
inner_runner_testdir
is
None
:
msg
=
(
'Option "--inner-runner-testdir" is mandatory '
'when "--inner-runner-chdir=test" is used.'
)
self
.
view
.
notify
(
event
=
'error'
,
msg
=
msg
)
sys
.
exit
(
exit_codes
.
AVOCADO_FAIL
)
test
.
INNER_RUNNER_CHDIR
=
app_args
.
inner_runner_chdir
avocado/core/plugins/runner.py
浏览文件 @
bb04ad64
...
...
@@ -22,6 +22,7 @@ from . import plugin
from
..
import
exit_codes
from
..
import
output
from
..
import
job
from
..
import
loader
from
..
import
multiplexer
from
..settings
import
settings
...
...
@@ -115,6 +116,8 @@ class TestRunner(plugin.Plugin):
'present for the test. '
'Current: on (output check enabled)'
))
loader
.
add_file_loader_options
(
self
.
parser
)
if
multiplexer
.
MULTIPLEX_CAPABLE
:
mux
=
self
.
parser
.
add_argument_group
(
'multiplexer use on test execution'
)
mux
.
add_argument
(
'-m'
,
'--multiplex-files'
,
nargs
=
'*'
,
...
...
avocado/core/plugins/test_list.py
浏览文件 @
bb04ad64
...
...
@@ -32,7 +32,12 @@ class TestLister(object):
use_paginator
=
args
.
paginator
==
'on'
self
.
view
=
output
.
View
(
app_args
=
args
,
use_paginator
=
use_paginator
)
self
.
term_support
=
output
.
TermSupport
()
loader
.
loader
.
load_plugins
(
args
)
try
:
loader
.
loader
.
load_plugins
(
args
)
except
loader
.
LoaderError
,
details
:
sys
.
stderr
.
write
(
str
(
details
))
sys
.
stderr
.
write
(
'
\n
'
)
sys
.
exit
(
exit_codes
.
AVOCADO_FAIL
)
self
.
args
=
args
def
_extra_listing
(
self
):
...
...
@@ -159,6 +164,7 @@ class TestList(plugin.Plugin):
choices
=
(
'on'
,
'off'
),
default
=
'on'
,
help
=
'Turn the paginator on/off. '
'Current: %(default)s'
)
loader
.
add_file_loader_options
(
self
.
parser
)
super
(
TestList
,
self
).
configure
(
self
.
parser
)
parser
.
lister
=
self
.
parser
...
...
avocado/core/test.py
浏览文件 @
bb04ad64
...
...
@@ -43,11 +43,6 @@ from ..utils import stacktrace
from
..utils
import
data_structures
INNER_RUNNER
=
None
INNER_RUNNER_TESTDIR
=
None
INNER_RUNNER_CHDIR
=
None
class
Test
(
unittest
.
TestCase
):
"""
...
...
@@ -563,12 +558,9 @@ class SimpleTest(Test):
r
' \d\d:\d\d:\d\d WARN \|'
)
def
__init__
(
self
,
name
,
params
=
None
,
base_logdir
=
None
,
tag
=
None
,
job
=
None
):
if
INNER_RUNNER
is
None
:
self
.
path
=
os
.
path
.
abspath
(
name
)
else
:
self
.
path
=
name
super
(
SimpleTest
,
self
).
__init__
(
name
=
name
,
base_logdir
=
base_logdir
,
params
=
params
,
tag
=
tag
,
job
=
job
)
self
.
path
=
name
basedir
=
os
.
path
.
dirname
(
self
.
path
)
basename
=
os
.
path
.
basename
(
self
.
path
)
datadirname
=
basename
+
'.data'
...
...
@@ -587,7 +579,7 @@ class SimpleTest(Test):
self
.
log
.
info
(
"Exit status: %s"
,
result
.
exit_status
)
self
.
log
.
info
(
"Duration: %s"
,
result
.
duration
)
def
test
(
self
):
def
test
(
self
,
override_command
=
None
):
"""
Run the executable, and log its detailed execution.
"""
...
...
@@ -595,34 +587,14 @@ class SimpleTest(Test):
test_params
=
dict
([(
str
(
key
),
str
(
val
))
for
key
,
val
in
self
.
params
.
iteritems
()])
pre_cwd
=
os
.
getcwd
()
new_cwd
=
None
if
INNER_RUNNER
is
not
None
:
self
.
log
.
info
(
'Running test with the inner level test '
'runner: "%s"'
,
INNER_RUNNER
)
# Change work directory if needed by the inner runner
if
INNER_RUNNER_CHDIR
==
'runner'
:
new_cwd
=
os
.
path
.
dirname
(
INNER_RUNNER
)
elif
INNER_RUNNER_CHDIR
==
'test'
:
new_cwd
=
INNER_RUNNER_TESTDIR
else
:
new_cwd
=
None
if
new_cwd
is
not
None
:
self
.
log
.
debug
(
'Changing working directory to "%s" '
'because of inner runner requirements '
,
new_cwd
)
os
.
chdir
(
new_cwd
)
command
=
"%s %s"
%
(
INNER_RUNNER
,
self
.
path
)
if
override_command
is
not
None
:
command
=
override_command
else
:
command
=
pipes
.
quote
(
self
.
path
)
# process.run uses shlex.split(), the self.path needs to be escaped
result
=
process
.
run
(
command
,
verbose
=
True
,
env
=
test_params
)
if
new_cwd
is
not
None
:
os
.
chdir
(
pre_cwd
)
self
.
_log_detailed_cmd_info
(
result
)
except
process
.
CmdError
,
details
:
...
...
@@ -638,6 +610,43 @@ class SimpleTest(Test):
"the log for details."
)
class
InnerRunnerTest
(
SimpleTest
):
def
__init__
(
self
,
name
,
params
=
None
,
base_logdir
=
None
,
tag
=
None
,
job
=
None
,
inner_runner
=
None
):
self
.
assertIsNotNone
(
inner_runner
,
"Inner runner test requires "
"inner_runner parameter, got None instead."
)
self
.
inner_runner
=
inner_runner
super
(
InnerRunnerTest
,
self
).
__init__
(
name
,
params
,
base_logdir
,
tag
,
job
)
def
test
(
self
):
pre_cwd
=
os
.
getcwd
()
new_cwd
=
None
try
:
self
.
log
.
info
(
'Running test with the inner level test '
'runner: "%s"'
,
self
.
inner_runner
.
runner
)
# Change work directory if needed by the inner runner
if
self
.
inner_runner
.
chdir
==
'runner'
:
new_cwd
=
os
.
path
.
dirname
(
self
.
inner_runner
.
runner
)
elif
self
.
inner_runner
.
chdir
==
'test'
:
new_cwd
=
self
.
inner_runner
.
test_dir
else
:
new_cwd
=
None
if
new_cwd
is
not
None
:
self
.
log
.
debug
(
'Changing working directory to "%s" '
'because of inner runner requirements '
,
new_cwd
)
os
.
chdir
(
new_cwd
)
command
=
"%s %s"
%
(
self
.
inner_runner
.
runner
,
self
.
path
)
return
super
(
InnerRunnerTest
,
self
).
test
(
command
)
finally
:
if
new_cwd
is
not
None
:
os
.
chdir
(
pre_cwd
)
class
MissingTest
(
Test
):
"""
...
...
docs/source/Loaders.rst
0 → 100644
浏览文件 @
bb04ad64
==============
Test discovery
==============
In this section you can learn how tests are being discovered and how to affect
this process.
The order of test loaders
=========================
Avocado supports different types of test starting with `SIMPLE` tests, which
are simply executable files, then unittest-like tests called `INSTRUMENTED`
up to some tests like the `avocado-vt` ones, which uses complex
matrix of tests from config files that don't directl map to existing files.
Given the number of loaders, the mapping from test names on the command line
to executed tests might not always be unique. Additionally some people might
always (or for given run) want to execute only tests of a single type.
To adjust this behavior you can either tweak ``plugins.loaders`` in avocado
settings (``/etc/avocado/``), or temporarily using ``--loaders``
(option of ``avocado run``) option.
This option allows you to specify order and some params of the available test
loaders. You can specify either ``@`` + loader_name (``@file``),
TEST_TYPE (``SIMPLE``) and for some loaders even additional params passed
after ``:`` (``@file:/bin/echo -e`` or ``INNER_RUNNER:/bin/echo -e``). You can
also supply ``DEFAULT``, which injects into that position all the remaining
unused loaders.
To get help about ``--loaders``::
$ avocado run --loaders ?
$ avocado run --loaders @file:?
Example of how ``--loaders`` affects the produced tests (manually gathered
as some of them result in error)::
$ avocado run passtest boot this_does_not_exist /bin/echo
> INSTRUMENTED passtest.py:PassTest.test
> VT io-github-autotest-qemu.boot
> MISSING this_does_not_exist
> SIMPLE /bin/echo
$ avocado run passtest boot this_does_not_exist /bin/echo --loaders DEFAULT "@file:/bin/echo -e"
> INSTRUMENTED passtest.py:PassTest.test
> VT io-github-autotest-qemu.boot
> INNER_RUNNER this_does_not_exist
> SIMPLE /bin/echo
$ avocado run passtest boot this_does_not_exist /bin/echo --loaders SIMPLE INSTRUMENTED DEFAULT INNER_RUNNER:/bin/echo
> INSTRUMENTED passtest.py:PassTest.test
> VT io-github-autotest-qemu.boot
> INNER_RUNNER this_does_not_exist
> SIMPLE /bin/echo
docs/source/index.rst
浏览文件 @
bb04ad64
...
...
@@ -12,6 +12,7 @@ Contents:
WritingTests
ResultFormats
Configuration
Loaders
MultiplexConfig
RunningTestsRemotely
DebuggingWithGDB
...
...
etc/avocado/avocado.conf
浏览文件 @
bb04ad64
...
...
@@ -56,6 +56,10 @@ password =
# avocado.core.plugins.htmlresult ImportError No module named pystache
# add 'avocado.core.plugins.htmlresult' as an element of the list below.
skip_broken_plugin_notification
= []
# Optionally you can specify the priority of loader plugins. Unspecified
# plugins will be sorted accordingly to the plugin priorities.
loader_plugins_priority
= [
'file'
]
# Optionally you can specify the priority of test loaders (@file) or test
# types (SIMPLE). Some of the plugins even support extra params
# (INNER_RUNNER:/bin/echo -e). Plugins will be used accordingly to the plugin
# priorities. It's possible to list plugins multiple times (with different
# options or just types).
# The type "DEFAULT" will be replaced with all available unused loaders.
loaders
= [
'@file'
,
'DEFAULT'
]
selftests/functional/test_basic.py
浏览文件 @
bb04ad64
...
...
@@ -443,9 +443,10 @@ class InnerRunnerTest(unittest.TestCase):
'--inner-runner-chdir=test %s'
)
cmd_line
%=
(
self
.
tmpdir
,
self
.
pass_script
.
path
)
result
=
process
.
run
(
cmd_line
,
ignore_status
=
True
)
expected_output
=
'Option "--inner-runner-testdir" is mandatory'
expected_output
=
(
'Option "--inner-runner-chdir=test" requires '
'"--inner-runner-testdir" to be set'
)
self
.
assertIn
(
expected_output
,
result
.
stderr
)
expected_rc
=
3
expected_rc
=
2
self
.
assertEqual
(
result
.
exit_status
,
expected_rc
,
"Avocado did not return rc %d:
\n
%s"
%
(
expected_rc
,
result
))
...
...
selftests/unit/test_loader.py
浏览文件 @
bb04ad64
...
...
@@ -81,7 +81,7 @@ class MultipleMethods(Test):
class
LoaderTest
(
unittest
.
TestCase
):
def
setUp
(
self
):
self
.
loader
=
loader
.
FileLoader
({})
self
.
loader
=
loader
.
FileLoader
(
None
,
{})
self
.
queue
=
multiprocessing
.
Queue
()
def
test_load_simple
(
self
):
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录