提交 b6488cce 编写于 作者: L Lucas Meneghel Rodrigues

Merge pull request #629 from ldoktor/mux-paths2

avocado.multiplexer: Inject YAML files into /run [v2]
......@@ -370,7 +370,7 @@ def _create_from_yaml(path, cls_node=TreeNode):
ypath = value[1]
if not os.path.isabs(ypath):
ypath = os.path.join(os.path.dirname(path), ypath)
node.merge(_create_from_yaml(ypath, cls_node))
node.merge(_create_from_yaml('/:' + ypath, cls_node))
elif value[0].code == YAML_USING:
if using:
raise ValueError("!using can be used only once per "
......@@ -445,10 +445,12 @@ def _create_from_yaml(path, cls_node=TreeNode):
path = __RE_FILE_SPLIT.split(path, 1)
if len(path) == 1:
path = __RE_FILE_SUBS.sub(':', path[0])
using = None
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])
# Load the tree
......@@ -688,5 +690,6 @@ def get_named_tree_cls(path):
def __init__(self, name='', value=None, parent=None,
children=None):
super(NamedTreeNodeDebug, self).__init__(name, value, parent,
children, path)
children,
path.split(':', 1)[-1])
return NamedTreeNodeDebug
......@@ -401,7 +401,7 @@ class Mux(object):
self.variants = None
self._mux_entry = getattr(args, 'mux_entry', None)
if self._mux_entry is None:
self._mux_entry = ['/test/*']
self._mux_entry = ['/run/*']
def get_number_of_tests(self, test_suite):
"""
......
......@@ -192,7 +192,7 @@ possible and commonly desirable to use non-unique names. But always keep those p
in mind and provide sensible paths.
Multiplexer also supports something called "multiplex entry points" or
"resolution order". By default it's ``/tests/*`` but it can be overridden by
"resolution order". By default it's ``/run/*`` but it can be overridden by
``--mux-entry``, which accepts multiple arguments. What it does it splits
leaves by the provided paths. Each query goes one by one through those
sub-trees and first one to hit the match returns the result. It might not solve
......@@ -216,6 +216,53 @@ Keep in mind that only slices defined in mux-entry are taken into account for
relative paths (the ones starting with ``*``)
Injecting files
===============
You can run any test with any YAML file by::
avocado run sleeptest --multiplex file.yaml
This puts the content of ``file.yaml`` into ``/run``
location, which as mentioned in previous section, is the default ``mux-entry``
path. For most simple cases this is the expected behavior as your files
are available in the default path and you can safely use ``params.get(key)``.
When you need to put a file into a different location, for example
when you have two files and you don't want the content to be merged into
a single place becomming effectively a single blob, you can do that by
giving a name to your yaml file::
avocado run sleeptest --multiplex duration:duration.yaml
The content of ``duration.yaml`` is injected into ``/run/duration``. Still when
keys from other files don't clash, you can use ``params.get(key)`` and retrieve
from this location as it's in the default path, only extended by the
``duration`` intermediary node. Another benefit is you can merge or separate
multiple files by using the same or different name, or even a complex
(relative) path.
Last but not least, advanced users can inject the file into whatever location
they prefer by::
avocado run sleeptest --multiplex /my/variants/duration:duration.yaml
Simple ``params.get(key)`` won't look in this location, which might be the
intention of the test writer. There are several ways to access the values:
* absolute location ``params.get(key, '/my/variants/duration')``
* absolute location with wildcards ``params.get(key, '/my/*)``
(or ``/*/duration/*``...)
* set the mux-entry ``avocado run ... --mux-entry /my/*`` and use relative path
It's recommended to use the simple injection for single YAML files, relative
injection for multiple simple YAML files and the last option is for very
advanced setups when you either can't modify the YAML files and you need to
specify custom resoltion order or you are specifying non-test parameters, for
example parameters for your plugin, which you need to separate from the test
parameters.
Multiple files
==============
......
......@@ -116,22 +116,23 @@ Avocado finds and populates ``self.params`` with all parameters you define on
a Multiplex Config file (see :doc:`MultiplexConfig`). As an example, consider
the following multiplex file for sleeptest::
test:
sleeptest:
type: "builtin"
short:
sleep_length: 0.5
medium:
sleep_length: 1
long:
sleep_length: 5
In this example 3 variants are executed (see :doc:`MultiplexConfig` for
details). All of them contain variable "type" and "sleep_length". To obtain
current value, you need the name ("sleep_length") and its path. The path
differs for each variant so it's needed to use the most suitable portion
of the path, in this example: "/test/sleeptest/*" or perhaps "sleeptest/*"
might be enough. It depends on how your setups looks like.
sleeptest:
type: "builtin"
short:
sleep_length: 0.5
medium:
sleep_length: 1
long:
sleep_length: 5
When running this example by ``avocado run $test --multiplex $file.yaml``
three variants are executed and the content is injected into ``/run`` namespace
(see :doc:`MultiplexConfig` for details). Every variant contains variables
"type" and "sleep_length". To obtain the current value, you need the name
("sleep_length") and its path. The path differs for each variant so it's
needed to use the most suitable portion of the path, in this example:
"/run/sleeptest/*" or perhaps "sleeptest/*" might be enough. It depends on how
your setup looks like.
The default value is optional, but always keep in mind to handle them nicely.
Someone might be executing your test with different params or without any
......@@ -164,8 +165,8 @@ clearer and easier to follow.
When thinking of the path always think about users. It's common to extend
default config with additional variants or combine them with different
ones to generate just the right scenarios they need. People might
simply inject the values elsewhere (eg. `/test/sleeptest` =>
`/upstream/test/sleeptest`) or they can merge other clashing file into the
simply inject the values elsewhere (eg. `/run/sleeptest` =>
`/upstream/sleeptest`) or they can merge other clashing file into the
default path, which won't generate clash, but would return their values
instead. Then you need to clarify the path (eg. `'*'` => `sleeptest/*`)
......@@ -177,7 +178,7 @@ Using a multiplex file
You may use the avocado runner with a multiplex file to provide params and matrix
generation for sleeptest just like::
$ avocado run sleeptest --multiplex /test:examples/tests/sleeptest.py.data/sleeptest.yaml
$ avocado run sleeptest --multiplex examples/tests/sleeptest.py.data/sleeptest.yaml
JOB ID : d565e8dec576d6040f894841f32a836c751f968f
JOB LOG : $HOME/avocado/job-results/job-2014-08-12T15.44-d565e8de/job.log
JOB HTML : $HOME/avocado/job-results/job-2014-08-12T15.44-d565e8de/html/results.html
......@@ -194,18 +195,22 @@ generation for sleeptest just like::
TIME : 6.52 s
The ``--multiplex`` accepts either only ``$FILE_LOCATION`` or ``$INJECT_TO:$FILE_LOCATION``.
By later you can combine multiple simple YAML files and inject them into a specific location
as shown in the example above. As you learned in previous section the ``/test`` location
is part of default ``mux-entry`` path thus sleeptest can access the values without specifying
the path. To understand the difference execute those commands::
As explained in :doc:`MultiplexConfig` without any path the content gets
injected into ``/run`` in order to be in the default relative path location.
The ``$INJECT_TO`` can be either relative path, then it's injected into
``/run/$INJECT_TO`` location, or absolute path (starting with ``'/'``), then
it's injected directly into the specified path and it's up to the test/framework
developer to get the value from this location (using path or adding the path to
``mux-entry``). To understand the difference execute those commands::
$ avocado multiplex -t examples/tests/sleeptest.py.data/sleeptest.yaml
$ avocado multiplex -t /test:examples/tests/sleeptest.py.data/sleeptest.yaml
$ avocado multiplex -t duration:examples/tests/sleeptest.py.data/sleeptest.yaml
$ avocado multiplex -t /my/location:examples/tests/sleeptest.py.data/sleeptest.yaml
Note that, as your multiplex file specifies all parameters for sleeptest, you
can't leave the test ID empty::
$ scripts/avocado run --multiplex /test:examples/tests/sleeptest/sleeptest.yaml
$ scripts/avocado run --multiplex examples/tests/sleeptest/sleeptest.yaml
Empty test ID. A test path or alias must be provided
You can also execute multiple tests with the same multiplex file::
......@@ -594,7 +599,7 @@ impact your test grid. You can account for that possibility and set up a
::
$ avocado run sleeptest --multiplex /test:/tmp/sleeptest-example.yaml
$ avocado run sleeptest --multiplex /tmp/sleeptest-example.yaml
JOB ID : 6d5a2ff16bb92395100fbc3945b8d253308728c9
JOB LOG : $HOME/avocado/job-results/job-2014-08-12T15.52-6d5a2ff1/job.log
JOB HTML : $HOME/avocado/job-results/job-2014-08-12T15.52-6d5a2ff1/html/results.html
......
......@@ -71,8 +71,10 @@ class MultiplexTests(unittest.TestCase):
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')
'/:examples/mux-selftest.yaml '
'/:examples/mux-environment.yaml '
'/:examples/mux-selftest.yaml '
'/:examples/mux-environment.yaml')
expected_rc = 0
result = self.run_and_check(cmd_line, expected_rc)
self.assertIn(DEBUG_OUT, result.stdout)
......
......@@ -14,7 +14,8 @@ if __name__ == "__main__":
else:
PATH_PREFIX = ""
TREE = tree.create_from_yaml([PATH_PREFIX + 'examples/mux-selftest.yaml'])
TREE = tree.create_from_yaml(['/:' + PATH_PREFIX +
'examples/mux-selftest.yaml'])
def combine(leaves_pools):
......@@ -42,20 +43,20 @@ class TestMultiplex(unittest.TestCase):
self.assertEqual(len(self.mux_full), 12)
def test_create_variants(self):
from_file = multiplexer.multiplex_yamls([PATH_PREFIX + 'examples/mux-selftest.yaml'])
from_file = multiplexer.multiplex_yamls(['/:' + PATH_PREFIX + 'examples/mux-selftest.yaml'])
self.assertEqual(self.mux_full, tuple(from_file))
# Filters are tested in tree_unittests, only verify `multiplex_yamls` calls
def test_filter_only(self):
exp = (['intel', 'scsi'], ['intel', 'virtio'])
act = tuple(multiplexer.multiplex_yamls([PATH_PREFIX + 'examples/mux-selftest.yaml'],
act = tuple(multiplexer.multiplex_yamls(['/:' + PATH_PREFIX + 'examples/mux-selftest.yaml'],
('/hw/cpu/intel',
'/distro/fedora',
'/hw')))
self.assertEqual(act, exp)
def test_filter_out(self):
act = tuple(multiplexer.multiplex_yamls([PATH_PREFIX + 'examples/mux-selftest.yaml'],
act = tuple(multiplexer.multiplex_yamls(['/:' + PATH_PREFIX + 'examples/mux-selftest.yaml'],
None,
('/hw/cpu/intel',
'/distro/fedora',
......@@ -70,7 +71,7 @@ class TestMultiplex(unittest.TestCase):
class TestAvocadoParams(unittest.TestCase):
yamls = iter(multiplexer.multiplex_yamls([PATH_PREFIX + 'examples/mux-selftest-params.'
yamls = iter(multiplexer.multiplex_yamls(['/:' + PATH_PREFIX + 'examples/mux-selftest-params.'
'yaml']))
params1 = multiplexer.AvocadoParams(yamls.next(), 'Unittest1', 1,
['/ch0/*', '/ch1/*'], {})
......
......@@ -11,7 +11,7 @@ from avocado.core import tree
class TestTree(unittest.TestCase):
# Share tree with all tests
tree = tree.create_from_yaml(['examples/mux-selftest.yaml'])
tree = tree.create_from_yaml(['/:examples/mux-selftest.yaml'])
def test_node_order(self):
self.assertIsInstance(self.tree, tree.TreeNode)
......@@ -154,7 +154,8 @@ class TestTree(unittest.TestCase):
tree2.children[0].children[2].children[1].value)
def test_advanced_yaml(self):
tree2 = tree.create_from_yaml(['examples/mux-selftest-advanced.yaml'])
tree2 = tree.create_from_yaml(['/:examples/mux-selftest-advanced.'
'yaml'])
exp = ['intel', 'amd', 'arm', 'scsi', 'virtio', 'fedora', '6',
'7', 'gentoo', 'mint', 'prod', 'new_node']
act = tree2.get_leaves()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册