[PATCH v3 00/17] Refactor RecipeCommon.Ping
by Jan Tluka
This is a series of patches that attempts to remove the duplicated code
in Recipes/ENRT in case of cross-vlan ping runs.
The changes include:
* split of ping command execution and evaluation of results
* introducing two basic Ping evaluators
* replacing the duplicated code in Recipes/ENRT with the new reusable code
v2:
* fixed a whitespace error
* moved Perf BaseEvaluator to BaseResultEvaluator
* used plural for ping_confing argument in ping_test()
* instead of overriding the do_ping_tests base class method I added few
mixin classes that do the same thing in even more reusable way
* be aware of additional patches compared to previous v1
v3:
* renamed get_ping_evaluators to generate_ping_evaluators
* added PingEndpoints class that holds the information whether the
endpoints are reachable
* removed PingConditionMixin because PingEndpoints provides the needed
information about endpoint reachability
Jan Tluka (17):
RecipeCommon.Ping: rename running_ping to ping
RecipeCommon.Ping: move prepare_job to ping_init
RecipeCommon.Ping: remove ping_config from ping_evaluate_and_report
Tests.Ping: update failure logic
Tests.Ping: do not check rtt data if no packets were received
RecipeCommon.Ping: rename ping_evaluate_and_report method
lnst.RecipeCommon: move Ping Recipe to separate directory
lnst.RecipeCommon: rename Perf BaseEvaluator to BaseResultEvaluator
lnst.RecipeCommon.Ping: add Ping evaluators
RecipeCommon.Ping.Recipe: add evaluators to PingConf object
lnst.RecipeCommon.Ping: add PingEndpoints class
Recipes.ENRT.BaseEnrtRecipe: use PingEndpoints in
generate_ping_configurations
Recipes.ENRT.BaseEnrtRecipe: register default PingEvaluator
RecipeCommon.Ping.Recipe: split report and evaluate
lnst.Recipes.ENRT: add PingMixins
lnst.Recipes.ENRT: use PingMixins to override Ping evaluators
lnst.RecipeCommon.Ping.Recipe: use plural for ping_config in ping_test
...aseEvaluator.py => BaseResultEvaluator.py} | 2 +-
.../Perf/Evaluators/BaselineEvaluator.py | 4 +-
.../Perf/Evaluators/NonzeroFlowEvaluator.py | 4 +-
.../Ping/Evaluators/RatePingEvaluator.py | 59 +++++++++++++
.../Ping/Evaluators/ZeroPassPingEvaluator.py | 21 +++++
lnst/RecipeCommon/Ping/Evaluators/__init__.py | 2 +
lnst/RecipeCommon/Ping/PingEndpoints.py | 20 +++++
lnst/RecipeCommon/{Ping.py => Ping/Recipe.py} | 55 +++++++-----
lnst/RecipeCommon/Ping/__init__.py | 0
lnst/Recipes/ENRT/BaseEnrtRecipe.py | 19 ++--
lnst/Recipes/ENRT/BasePvPRecipe.py | 2 +-
lnst/Recipes/ENRT/BondRecipe.py | 3 +-
lnst/Recipes/ENRT/DoubleBondRecipe.py | 3 +-
lnst/Recipes/ENRT/DoubleTeamRecipe.py | 7 +-
lnst/Recipes/ENRT/IpsecEspAeadRecipe.py | 16 ++--
lnst/Recipes/ENRT/IpsecEspAhCompRecipe.py | 26 +++---
lnst/Recipes/ENRT/NoVirtOvsVxlanRecipe.py | 3 +-
lnst/Recipes/ENRT/OvS_DPDK_PvP.py | 2 +-
lnst/Recipes/ENRT/PingFloodRecipe.py | 4 +-
.../ENRT/PingMixins/PingEvaluatorMixins.py | 13 +++
lnst/Recipes/ENRT/PingMixins/__init__.py | 3 +
lnst/Recipes/ENRT/SimpleNetworkRecipe.py | 3 +-
lnst/Recipes/ENRT/TeamRecipe.py | 7 +-
lnst/Recipes/ENRT/TeamVsBondRecipe.py | 7 +-
lnst/Recipes/ENRT/VirtOvsVxlanRecipe.py | 77 +++--------------
.../VirtualBridgeVlanInGuestMirroredRecipe.py | 3 +-
.../ENRT/VirtualBridgeVlanInGuestRecipe.py | 3 +-
.../VirtualBridgeVlanInHostMirroredRecipe.py | 3 +-
.../ENRT/VirtualBridgeVlanInHostRecipe.py | 3 +-
.../ENRT/VirtualBridgeVlansOverBondRecipe.py | 86 ++++---------------
...rtualOvsBridgeVlanInGuestMirroredRecipe.py | 3 +-
.../ENRT/VirtualOvsBridgeVlanInGuestRecipe.py | 3 +-
...irtualOvsBridgeVlanInHostMirroredRecipe.py | 3 +-
.../ENRT/VirtualOvsBridgeVlanInHostRecipe.py | 3 +-
.../VirtualOvsBridgeVlansOverBondRecipe.py | 86 ++++---------------
lnst/Recipes/ENRT/VlansOverBondRecipe.py | 63 ++------------
lnst/Recipes/ENRT/VlansOverTeamRecipe.py | 64 ++------------
lnst/Recipes/ENRT/VlansRecipe.py | 63 ++------------
lnst/Recipes/ENRT/VxlanMulticastRecipe.py | 5 +-
lnst/Recipes/ENRT/VxlanRemoteRecipe.py | 3 +-
lnst/Tests/Ping.py | 20 ++---
41 files changed, 317 insertions(+), 459 deletions(-)
rename lnst/RecipeCommon/{Perf/Evaluators/BaseEvaluator.py => BaseResultEvaluator.py} (70%)
create mode 100644 lnst/RecipeCommon/Ping/Evaluators/RatePingEvaluator.py
create mode 100644 lnst/RecipeCommon/Ping/Evaluators/ZeroPassPingEvaluator.py
create mode 100644 lnst/RecipeCommon/Ping/Evaluators/__init__.py
create mode 100644 lnst/RecipeCommon/Ping/PingEndpoints.py
rename lnst/RecipeCommon/{Ping.py => Ping/Recipe.py} (63%)
create mode 100644 lnst/RecipeCommon/Ping/__init__.py
create mode 100644 lnst/Recipes/ENRT/PingMixins/PingEvaluatorMixins.py
create mode 100644 lnst/Recipes/ENRT/PingMixins/__init__.py
--
2.21.1
3 years, 8 months
[PATCH] lnst.Recipes.ENRT.BaseEnrtRecipe: add missing FloatParam import
by olichtne@redhat.com
From: Ondrej Lichtner <olichtne(a)redhat.com>
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Recipes/ENRT/BaseEnrtRecipe.py | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/lnst/Recipes/ENRT/BaseEnrtRecipe.py b/lnst/Recipes/ENRT/BaseEnrtRecipe.py
index a90c837..54e38bc 100644
--- a/lnst/Recipes/ENRT/BaseEnrtRecipe.py
+++ b/lnst/Recipes/ENRT/BaseEnrtRecipe.py
@@ -2,7 +2,14 @@ import pprint
from contextlib import contextmanager
from lnst.Common.LnstError import LnstError
-from lnst.Common.Parameters import Param, IntParam, StrParam, BoolParam, ListParam
+from lnst.Common.Parameters import (
+ Param,
+ IntParam,
+ StrParam,
+ BoolParam,
+ ListParam,
+ FloatParam,
+)
from lnst.Common.IpAddress import AF_INET, AF_INET6
from lnst.Recipes.ENRT.ConfigMixins.BaseSubConfigMixin import BaseSubConfigMixin
--
2.25.2
3 years, 8 months
[PATCH v2 00/15] Refactor RecipeCommon.Ping
by Jan Tluka
This is a series of patches that attempts to remove the duplicated code
in Recipes/ENRT in case of cross-vlan ping runs.
The changes include:
* split of ping command execution and evaluation of results
* introducing two basic Ping evaluators
* replacing the duplicated code in Recipes/ENRT with the new reusable code
v2:
* fixed a whitespace error
* moved Perf BaseEvaluator to BaseResultEvaluator
* used plural for ping_confing argument in ping_test()
* instead of overriding the do_ping_tests base class method I added few
mixin classes that do the same thing in even more reusable way
* be aware of additional patches compared to previous v1
Jan Tluka (15):
RecipeCommon.Ping: rename running_ping to ping
RecipeCommon.Ping: move prepare_job to ping_init
RecipeCommon.Ping: remove ping_config from ping_evaluate_and_report
Tests.Ping: update failure logic
Tests.Ping: do not check rtt data if no packets were received
RecipeCommon.Ping: rename ping_evaluate_and_report method
lnst.RecipeCommon: move Ping Recipe to separate directory
lnst.RecipeCommon: rename Perf BaseEvaluator to BaseResultEvaluator
lnst.RecipeCommon.Ping: add Ping evaluators
RecipeCommon.Ping.Recipe: add evaluators to PingConf object
Recipes.ENRT.BaseEnrtRecipe: register default PingEvaluator
RecipeCommon.Ping.Recipe: split report and evaluate
lnst.Recipes.ENRT: add PingMixins
lnst.Recipes.ENRT: use PingMixins to override Ping evaluators
lnst.RecipeCommon.Ping.Recipe: use plural for ping_config in ping_test
...aseEvaluator.py => BaseResultEvaluator.py} | 2 +-
.../Perf/Evaluators/BaselineEvaluator.py | 4 +-
.../Perf/Evaluators/NonzeroFlowEvaluator.py | 4 +-
.../Ping/Evaluators/RatePingEvaluator.py | 59 +++++++++++++++
.../Ping/Evaluators/ZeroPassPingEvaluator.py | 21 ++++++
lnst/RecipeCommon/Ping/Evaluators/__init__.py | 2 +
lnst/RecipeCommon/{Ping.py => Ping/Recipe.py} | 55 ++++++++------
lnst/RecipeCommon/Ping/__init__.py | 0
lnst/Recipes/ENRT/BaseEnrtRecipe.py | 15 ++--
lnst/Recipes/ENRT/BasePvPRecipe.py | 2 +-
lnst/Recipes/ENRT/IpsecEspAeadRecipe.py | 16 ++---
lnst/Recipes/ENRT/IpsecEspAhCompRecipe.py | 26 +++----
lnst/Recipes/ENRT/OvS_DPDK_PvP.py | 2 +-
lnst/Recipes/ENRT/PingFloodRecipe.py | 4 +-
.../ENRT/PingMixins/PingConditionMixins.py | 34 +++++++++
.../ENRT/PingMixins/PingEvaluatorMixins.py | 15 ++++
lnst/Recipes/ENRT/PingMixins/__init__.py | 9 +++
lnst/Recipes/ENRT/VirtOvsVxlanRecipe.py | 69 ++----------------
.../ENRT/VirtualBridgeVlansOverBondRecipe.py | 71 ++-----------------
.../VirtualOvsBridgeVlansOverBondRecipe.py | 71 ++-----------------
lnst/Recipes/ENRT/VlansOverBondRecipe.py | 63 ++--------------
lnst/Recipes/ENRT/VlansOverTeamRecipe.py | 63 ++--------------
lnst/Recipes/ENRT/VlansRecipe.py | 63 ++--------------
lnst/Tests/Ping.py | 20 +++---
24 files changed, 260 insertions(+), 430 deletions(-)
rename lnst/RecipeCommon/{Perf/Evaluators/BaseEvaluator.py => BaseResultEvaluator.py} (70%)
create mode 100644 lnst/RecipeCommon/Ping/Evaluators/RatePingEvaluator.py
create mode 100644 lnst/RecipeCommon/Ping/Evaluators/ZeroPassPingEvaluator.py
create mode 100644 lnst/RecipeCommon/Ping/Evaluators/__init__.py
rename lnst/RecipeCommon/{Ping.py => Ping/Recipe.py} (63%)
create mode 100644 lnst/RecipeCommon/Ping/__init__.py
create mode 100644 lnst/Recipes/ENRT/PingMixins/PingConditionMixins.py
create mode 100644 lnst/Recipes/ENRT/PingMixins/PingEvaluatorMixins.py
create mode 100644 lnst/Recipes/ENRT/PingMixins/__init__.py
--
2.21.1
3 years, 8 months
[PATCH v2 1/4] lnst.Recipes.ENRT.BaseEnrtRecipe: ping_interval should be FloatParam
by olichtne@redhat.com
From: Ondrej Lichtner <olichtne(a)redhat.com>
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Recipes/ENRT/BaseEnrtRecipe.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lnst/Recipes/ENRT/BaseEnrtRecipe.py b/lnst/Recipes/ENRT/BaseEnrtRecipe.py
index 5862311..fb3aae4 100644
--- a/lnst/Recipes/ENRT/BaseEnrtRecipe.py
+++ b/lnst/Recipes/ENRT/BaseEnrtRecipe.py
@@ -29,7 +29,7 @@ class BaseEnrtRecipe(BaseSubConfigMixin, PingTestAndEvaluate, PerfRecipe):
ping_parallel = BoolParam(default=False)
ping_bidirect = BoolParam(default=False)
ping_count = IntParam(default=100)
- ping_interval = StrParam(default=0.2)
+ ping_interval = FloatParam(default=0.2)
ping_psize = IntParam(default=None)
#common perf test params
--
2.25.2
3 years, 8 months
[PATCH 00/12] Refactor RecipeCommon.Ping
by Jan Tluka
This is a series of patches that attempts to remove the duplicated code
in Recipes/ENRT in case of cross-vlan ping runs.
The changes include:
* split of ping command execution and evaluation of results
* introducing two basic Ping evaluators
* replacing the duplicated code in Recipes/ENRT with the new reusable code
Jan Tluka (12):
RecipeCommon.Ping: rename running_ping to ping
RecipeCommon.Ping: move prepare_job to ping_init
RecipeCommon.Ping: remove ping_config from ping_evaluate_and_report
Tests.Ping: update failure logic
Tests.Ping: do not check rtt data if no packets were received
RecipeCommon.Ping: rename ping_evaluate_and_report method
lnst.RecipeCommon: move Ping Recipe to separate directory
lnst.RecipeCommon.Ping: add Ping evaluators
RecipeCommon.Ping.Recipe: add evaluators to PingConf object
Recipes.ENRT.BaseEnrtRecipe: register default PingEvaluator
RecipeCommon.Ping.Recipe: split report and evaluate
Recipes.ENRT: use Ping evaluators to remove code duplicity
.../Ping/Evaluators/RatePingEvaluator.py | 59 +++++++++++++++++++
.../Ping/Evaluators/ZeroPassPingEvaluator.py | 22 +++++++
lnst/RecipeCommon/Ping/Evaluators/__init__.py | 2 +
lnst/RecipeCommon/{Ping.py => Ping/Recipe.py} | 51 ++++++++++------
lnst/RecipeCommon/Ping/__init__.py | 0
lnst/Recipes/ENRT/BaseEnrtRecipe.py | 8 ++-
lnst/Recipes/ENRT/BasePvPRecipe.py | 2 +-
lnst/Recipes/ENRT/IpsecEspAeadRecipe.py | 2 +-
lnst/Recipes/ENRT/IpsecEspAhCompRecipe.py | 2 +-
lnst/Recipes/ENRT/OvS_DPDK_PvP.py | 2 +-
lnst/Recipes/ENRT/PingFloodRecipe.py | 4 +-
lnst/Recipes/ENRT/VirtOvsVxlanRecipe.py | 46 +++------------
.../ENRT/VirtualBridgeVlansOverBondRecipe.py | 49 +++------------
.../VirtualOvsBridgeVlansOverBondRecipe.py | 49 +++------------
lnst/Recipes/ENRT/VlansOverBondRecipe.py | 49 +++------------
lnst/Recipes/ENRT/VlansOverTeamRecipe.py | 49 +++------------
lnst/Recipes/ENRT/VlansRecipe.py | 49 +++------------
lnst/Tests/Ping.py | 20 +++----
18 files changed, 189 insertions(+), 276 deletions(-)
create mode 100644 lnst/RecipeCommon/Ping/Evaluators/RatePingEvaluator.py
create mode 100644 lnst/RecipeCommon/Ping/Evaluators/ZeroPassPingEvaluator.py
create mode 100644 lnst/RecipeCommon/Ping/Evaluators/__init__.py
rename lnst/RecipeCommon/{Ping.py => Ping/Recipe.py} (65%)
create mode 100644 lnst/RecipeCommon/Ping/__init__.py
--
2.21.1
3 years, 8 months
[PATCH v2] Sphinx based documentation
by olichtne@redhat.com
From: Ondrej Lichtner <olichtne(a)redhat.com>
Creating the docs/ directory where we should work on creating
documentation. The standard for Python projects is to use "Sphinx" to
generate various formats (e.g. pdf, html or others) of documentation
from ReStructuredText (rst) source. The source is either stored as
".rst" standalone files or as docstrings with Python source code.
This is the first version that should cover some of the major topics and
exported APIs available for the tester. It is by no means complete yet
but should be enough to get a feel for how the overall structure should
look like.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
v2:
* add master_doc to conf.py
* renamed docs source files for consistency
* fixed SlavePoolManager reference
* added 'none' to ascii art code-block
* simplified wording for sub configuration explanation
* swapped sentences for net_perf_tool and cpu_perf_tool parameters
* updated docs for describe_test_wide_configuration method
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
README.md | 25 +-
docs/Makefile | 20 ++
docs/source/base_enrt_class.rst | 8 +
docs/source/conf.py | 66 +++++
docs/source/config_mixins.rst | 3 +
docs/source/controller_api.rst | 5 +
docs/source/enrt_recipes.rst | 12 +
docs/source/index.rst | 25 ++
docs/source/installation.rst | 133 +++++++++
docs/source/parameters.rst | 5 +
docs/source/recipe_api.rst | 5 +
docs/source/recipe_packages.rst | 7 +
docs/source/recipe_requirements_api.rst | 5 +
docs/source/simple_network_recipe.rst | 6 +
docs/source/specific_scenarios.rst | 5 +
docs/source/tester_api.rst | 10 +
lnst/Common/Parameters.py | 23 +-
lnst/Controller/Controller.py | 98 ++++---
lnst/Controller/Recipe.py | 71 ++---
lnst/Controller/Requirements.py | 80 +++---
lnst/Controller/__init__.py | 7 +
lnst/Recipes/ENRT/BaseEnrtRecipe.py | 310 ++++++++++++++++++++-
lnst/Recipes/ENRT/ConfigMixins/README.md | 3 +
lnst/Recipes/ENRT/ConfigMixins/__init__.py | 9 +
lnst/Recipes/ENRT/README.md | 47 ++++
lnst/Recipes/ENRT/SimpleNetworkRecipe.py | 49 ++++
lnst/Recipes/ENRT/__init__.py | 52 ++++
27 files changed, 971 insertions(+), 118 deletions(-)
create mode 100644 docs/Makefile
create mode 100644 docs/source/base_enrt_class.rst
create mode 100644 docs/source/conf.py
create mode 100644 docs/source/config_mixins.rst
create mode 100644 docs/source/controller_api.rst
create mode 100644 docs/source/enrt_recipes.rst
create mode 100644 docs/source/index.rst
create mode 100644 docs/source/installation.rst
create mode 100644 docs/source/parameters.rst
create mode 100644 docs/source/recipe_api.rst
create mode 100644 docs/source/recipe_packages.rst
create mode 100644 docs/source/recipe_requirements_api.rst
create mode 100644 docs/source/simple_network_recipe.rst
create mode 100644 docs/source/specific_scenarios.rst
create mode 100644 docs/source/tester_api.rst
create mode 100644 lnst/Recipes/ENRT/ConfigMixins/README.md
create mode 100644 lnst/Recipes/ENRT/README.md
diff --git a/README.md b/README.md
index 256f79e..dec9aba 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@ backwards compatibility are yet in place.
This also means that many of our documentation resources outlining how to write
recipes on the wiki are also out of date. We'll soon start working on these but
-please be paitent with us.
+please be patient with us.
If you're interested in helping out we accept code contributions via Patches
submitted to our mailing list <lnst-developers(a)lists.fedorahosted.org>.
@@ -33,13 +33,13 @@ Internet Resources bellow).
## Install
-LNST can be installed using python's distutils.
+Installation and a simple Hello world example is available at
+[Installation](docs/source/installation.rst)
-```bash
-su
-./setup.py install
-```
+## Documentation
+Documentation is available in the `docs/` directory, you can build it with
+`make html` using *Sphinx*.
## Authors/Contributors
@@ -53,18 +53,15 @@ su
* Jiri Zupka (not active anymore)
* Radek Pazdera (not active anymore)
+## How to contact us
-## Internet Resources
-
-* Project Wiki: https://github.com/jpirko/lnst/wiki (currently out of date)
-* Documentation: https://github.com/jpirko/lnst/wiki#learn (currently out of date)
-* Git Source Tree: https://github.com/jpirko/lnst
-* Mailing List: <lnst-developers(a)lists.fedorahosted.org>
-
+* Git Source Tree: https://github.com/jpirko/lnst
+* Mailing List: <lnst-developers(a)lists.fedorahosted.org>
+* IRC channel: #lnst @ freenode.net
## License
-**Copyright (C) 2011-2019 Red Hat, Inc.**
+**Copyright (C) 2011-2020 Red Hat, Inc.**
LNST is distributed under GNU General Public License version 2. See the file
"COPYING" in the source distribution for information on terms & conditions
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000..d0c3cbf
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,20 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line, and also
+# from the environment for the first two.
+SPHINXOPTS ?=
+SPHINXBUILD ?= sphinx-build
+SOURCEDIR = source
+BUILDDIR = build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/source/base_enrt_class.rst b/docs/source/base_enrt_class.rst
new file mode 100644
index 0000000..32dd6fd
--- /dev/null
+++ b/docs/source/base_enrt_class.rst
@@ -0,0 +1,8 @@
+BaseEnrtRecipe class
+====================
+
+.. autoclass:: lnst.Recipes.ENRT.BaseEnrtRecipe.BaseEnrtRecipe
+ :members:
+ :show-inheritance:
+
+.. autoclass:: lnst.Recipes.ENRT.BaseEnrtRecipe.EnrtConfiguration
diff --git a/docs/source/conf.py b/docs/source/conf.py
new file mode 100644
index 0000000..2f228ba
--- /dev/null
+++ b/docs/source/conf.py
@@ -0,0 +1,66 @@
+# Configuration file for the Sphinx documentation builder.
+#
+# This file only contains a selection of the most common options. For a full
+# list see the documentation:
+# https://www.sphinx-doc.org/en/master/usage/configuration.html
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+# import os
+# import sys
+# sys.path.insert(0, os.path.abspath('.'))
+
+
+# -- Project information -----------------------------------------------------
+
+project = 'lnst'
+copyright = '2020, Jiri Pirko'
+author = 'Jiri Pirko'
+
+
+# -- General configuration ---------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+ 'sphinx.ext.autodoc',
+]
+
+import sys
+sys.path = ['../'] + sys.path
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path.
+exclude_patterns = []
+
+
+# -- Options for HTML output -------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+#
+html_theme = 'classic'
+html_theme_options = {
+ #"body_min_width": "100%",
+ "body_max_width": "100%",
+}
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+autodoc_default_options = {
+ 'member-order': 'bysource',
+}
+
+master_doc = "index"
diff --git a/docs/source/config_mixins.rst b/docs/source/config_mixins.rst
new file mode 100644
index 0000000..66119b6
--- /dev/null
+++ b/docs/source/config_mixins.rst
@@ -0,0 +1,3 @@
+.. ENRT Config Mixins
+
+.. automodule:: lnst.Recipes.ENRT.ConfigMixins
diff --git a/docs/source/controller_api.rst b/docs/source/controller_api.rst
new file mode 100644
index 0000000..f80d840
--- /dev/null
+++ b/docs/source/controller_api.rst
@@ -0,0 +1,5 @@
+Controller API
+^^^^^^^^^^^^^^
+
+.. automodule:: lnst.Controller.Controller
+ :members: Controller
diff --git a/docs/source/enrt_recipes.rst b/docs/source/enrt_recipes.rst
new file mode 100644
index 0000000..af8935a
--- /dev/null
+++ b/docs/source/enrt_recipes.rst
@@ -0,0 +1,12 @@
+Early Network Regression Testing (ENRT)
+=======================================
+
+.. automodule:: lnst.Recipes.ENRT
+
+.. toctree::
+ :maxdepth: 2
+ :caption: ENRT Components
+
+ base_enrt_class
+ config_mixins
+ specific_scenarios
diff --git a/docs/source/index.rst b/docs/source/index.rst
new file mode 100644
index 0000000..1b1600f
--- /dev/null
+++ b/docs/source/index.rst
@@ -0,0 +1,25 @@
+LNST - Linux Network Stack Test
+===============================
+
+Linux Network Stack Test is a framework that supports development and execution
+of automated and portable network tests which usually involve multiple test
+systems. This repository contains the implementation of the library to write
+:any:`Recipes<BaseRecipe>`, library functions to implement executable script
+files which run your tests as well as the code for the "LNST Slave"
+application.
+
+.. toctree::
+ :maxdepth: 2
+ :caption: General topics:
+
+ installation
+ tester_api
+ recipe_packages
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
diff --git a/docs/source/installation.rst b/docs/source/installation.rst
new file mode 100644
index 0000000..ede73a2
--- /dev/null
+++ b/docs/source/installation.rst
@@ -0,0 +1,133 @@
+Install LNST and Hello world
+============================
+
+LNST is logically split into two separate application use cases:
+
+* Controller - something that controlls the execution of your :any:`Test
+ Recipes<BaseRecipe>`
+* Slave - a server application running on all hosts available for testing,
+ executes remote procedure calls from the Controller to either run tests or
+ configure the test machine
+
+Codebases for both use cases are developed in this repository and as we
+currently don't have a stable release yet, the recommended method of
+installation involves the following steps:
+
+.. code-block:: bash
+
+ git clone https://github.com/jpirko/lnst
+ cd lnst
+ pip3 install --requirements requirements.txt
+ pip3 install .
+
+
+This installs both the Controller and the Slave code, and you'll need to run
+this on all the test machines that you want to use as well as the machine which
+you want to use as the Controller. Optionally a Controller and a Slave CAN run
+on the same machine.
+
+You can start your Slave application immediatelly by running::
+
+ lnst-slave
+
+Because the lnst-slave application takes care of network configuration, it
+**requires** to be executed with root privileges. This is **A BIG SECURITY
+RISK** so make sure you only run this application on test machines that are not
+publicly accessible or don't contain any sensitive data.
+
+The Controller is a bit more complicated and requires you to:
+
+* create an executable test script
+* create a slave machine pool
+
+Creating an executable "HelloWorld" test script
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+LNST currently doesn't come with a CLI application for the Controller, instead
+we need to create an executable python script ourselves that takes care of
+creating an instance of a Controller class and an instance of the Test Recipe
+that we want to run and calling the Controller.run() method to execute it.
+
+A minimal "hello world" example of an executable test script looks like this:
+
+.. code-block:: python
+
+ from lnst.Controller import Controller, HostReq, DeviceReq, BaseRecipe
+
+ class HelloWorldRecipe(BaseRecipe):
+ machine1 = HostReq()
+ machine1.nic1 = DeviceReq(label="net1")
+
+ machine2 = HostReq()
+ machine2.nic1 = DeviceReq(label="net1")
+
+ def test(self):
+ self.matched.m1.nic1.ip_add("192.168.1.1/24")
+ self.matched.m1.nic1.up()
+ self.matched.m2.nic1.ip_add("192.168.1.2/24")
+ self.matched.m2.nic1.up()
+
+ self.matched.m1.run("ping 192.168.1.2")
+
+ ctl = Controller()
+ recipe_instance = HelloWorldRecipe()
+ ctl.run(recipe_instance)
+
+
+This test requires that you have 2 test machines that are directly connected to
+each other.
+If you write this into a ``hello_world.py`` file you should now be able to
+execute this script by running::
+
+ python3 hello_world.py
+
+And you'll end up receiving an error about being unable to find a match in your
+configured pools, since we didn't configure any yet, this is quite expected. But
+running this script did take care of creating a default configuration file and
+directory where we'll now be able to create our machine pool.
+
+Creating a simple machine pool
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The default location for the Controller config file is ``~/.lnst/lnst-ctl.conf``.
+At this point in time, you don't need to change anything inside this file.
+
+At the same time, the default location for a machine pool is ``~/.lnst/pool/``,
+to create a pool you'll need to put XML files that describe your test machines
+where the ``lnst-slave`` application is running, and how they're connected. You
+need to create one file per test machine, so to satisfy the
+**HelloWorldRecipe** requirements, we need to create two files:
+
+.. code-block:: bash
+
+ touch ~/.lnst/pool/test_machine1.xml
+ touch ~/.lnst/pool/test_machine2.xml
+
+For the contents of the files you can use the following template:
+
+.. code-block:: xml
+
+ <slavemachine>
+ <params>
+ <param name="hostname" value="HOSTNAME"/>
+ <param name="rpc_port" value="9999"/>
+ </params>
+ <interfaces>
+ <eth label="A" id="1">
+ <params>
+ <param name="hwaddr" value="MAC_ADDRESS"/>
+ </params>
+ </eth>
+ </interfaces>
+ </slavemachine>
+
+You'll need to edit the template and replace the **HOSTNAME** and
+**MAC_ADDRESS** strings with values that correspond to the hostname which the
+controller can use to connet to the slave, and the mac address of a network
+interface usable for testing. This **MUST** be a different interface than the
+one used for the Controller-Slave connection, as it's configuration will change
+during test execution, the Controller-Slave connection would break if you used
+the same interface.
+
+After creating your pool, you should now be able to run the ``hello_world.py``
+script successfully and receive back some logs about what happened.
diff --git a/docs/source/parameters.rst b/docs/source/parameters.rst
new file mode 100644
index 0000000..9646b01
--- /dev/null
+++ b/docs/source/parameters.rst
@@ -0,0 +1,5 @@
+Parameters
+^^^^^^^^^^
+
+.. automodule:: lnst.Common.Parameters
+ :members:
diff --git a/docs/source/recipe_api.rst b/docs/source/recipe_api.rst
new file mode 100644
index 0000000..32e7b4c
--- /dev/null
+++ b/docs/source/recipe_api.rst
@@ -0,0 +1,5 @@
+Recipe API
+^^^^^^^^^^
+
+.. automodule:: lnst.Controller.Recipe
+ :members: BaseRecipe, RecipeRun
diff --git a/docs/source/recipe_packages.rst b/docs/source/recipe_packages.rst
new file mode 100644
index 0000000..ccd6269
--- /dev/null
+++ b/docs/source/recipe_packages.rst
@@ -0,0 +1,7 @@
+Supported Recipe packages
+=========================
+
+.. toctree::
+ :maxdepth: 2
+
+ enrt_recipes
diff --git a/docs/source/recipe_requirements_api.rst b/docs/source/recipe_requirements_api.rst
new file mode 100644
index 0000000..4cf1c59
--- /dev/null
+++ b/docs/source/recipe_requirements_api.rst
@@ -0,0 +1,5 @@
+Recipe Requirements
+^^^^^^^^^^^^^^^^^^^
+
+.. automodule:: lnst.Controller.Requirements
+ :members: HostReq, DeviceReq
diff --git a/docs/source/simple_network_recipe.rst b/docs/source/simple_network_recipe.rst
new file mode 100644
index 0000000..1f08feb
--- /dev/null
+++ b/docs/source/simple_network_recipe.rst
@@ -0,0 +1,6 @@
+SimpleNetworkRecipe
+^^^^^^^^^^^^^^^^^^^
+
+.. autoclass:: lnst.Recipes.ENRT.SimpleNetworkRecipe.SimpleNetworkRecipe
+ :members:
+ :show-inheritance:
diff --git a/docs/source/specific_scenarios.rst b/docs/source/specific_scenarios.rst
new file mode 100644
index 0000000..aea3230
--- /dev/null
+++ b/docs/source/specific_scenarios.rst
@@ -0,0 +1,5 @@
+Specific ENRT scenarios
+=======================
+
+.. toctree::
+ simple_network_recipe
diff --git a/docs/source/tester_api.rst b/docs/source/tester_api.rst
new file mode 100644
index 0000000..e7cf743
--- /dev/null
+++ b/docs/source/tester_api.rst
@@ -0,0 +1,10 @@
+Test developer API
+==================
+
+.. toctree::
+ :maxdepth: 2
+
+ recipe_requirements_api
+ recipe_api
+ controller_api
+ parameters
diff --git a/lnst/Common/Parameters.py b/lnst/Common/Parameters.py
index e56c32d..f73fd3a 100644
--- a/lnst/Common/Parameters.py
+++ b/lnst/Common/Parameters.py
@@ -4,10 +4,6 @@ This module defines the Param class, it's type specific derivatives
Param instances. This can be used by a BaseRecipe class to specify
optional/mandatory parameters for the entire test, or by HostReq and DeviceReq
classes to define specific parameters needed for the matching algorithm.
-
-Copyright 2017 Red Hat, Inc.
-Licensed under the GNU General Public License, version 2 as
-published by the Free Software Foundation; see COPYING for details.
"""
__author__ = """
@@ -24,12 +20,31 @@ class ParamError(LnstError):
pass
class Param(object):
+ """Base Parameter class
+
+ Can beused to define your own specific parameter type. Param derived classes
+ serve as *type checkers* to enable earlier failure of the recipe.
+
+ :param mandatory: if `True`, marks the parameter as mandatory
+ :type mandatory: bool
+
+ :param default: the default value for the parameter, is also type-checked,
+ immediately at Param object creation
+ """
def __init__(self, mandatory=False, **kwargs):
self.mandatory = mandatory
if "default" in kwargs:
self.default = self.type_check(kwargs["default"])
def type_check(self, value):
+ """The type check method
+
+ Implementation depends on the specific Param derived class.
+
+ :return: the type checked or converted value
+
+ :raises: :any:`ParamError` if the type check or conversion is invalid
+ """
return value
class IntParam(Param):
diff --git a/lnst/Controller/Controller.py b/lnst/Controller/Controller.py
index ace0caf..160e8b7 100644
--- a/lnst/Controller/Controller.py
+++ b/lnst/Controller/Controller.py
@@ -2,10 +2,6 @@
This module defines the Controller class that brings together individual
implementation parts of an LNST Controller. When instantiated, it allows the
tester to configure and run his own recipes with the LNST 'infrastructure'.
-
-Copyright 2017 Red Hat, Inc.
-Licensed under the GNU General Public License, version 2 as
-published by the Free Software Foundation; see COPYING for details.
"""
__author__ = """
@@ -33,34 +29,65 @@ from lnst.Controller.Recipe import BaseRecipe, RecipeRun
from lnst.Controller.RecipeControl import RecipeControl
class Controller(object):
- """The LNST Controller class
-
- Most importantly allows the tester to run instantiated Recipe tests using
- the LNST infrastructure.
-
- Can be configured with custom implementation of several objects used for
- setting up the infrastructure.
+ """Allows to run LNST Recipe instances
+
+ This is the main mechanism that allows users to create their own executable
+ test scripts that execute LNST Recipes.
+
+ The Controller class implementation provides the most common default values
+ for various parameters that can significantly change the way that Recipes
+ are executed. This includes custom implementations of classes that are used
+ for setting up the testing infrastructure such as the PoolManager or the
+ MachineMapper.
+
+ :param poolMgr:
+ class that implements the
+ :py:class:`lnst.Controller.SlavePoolManager.SlavePoolManager` interface
+ will be instantiated by the Controller to provide the mapper with pools
+ available for matching, also handles the creation of
+ :py:class:`Machine` objects (internal LNST class used to access the
+ slave hosts)
+ :type poolMgr:
+ :py:class:`lnst.Controller.SlavePoolManager.SlavePoolManager`
+ (this is also the default class)
+
+ :param mapper:
+ class that implements the
+ :py:class:`lnst.Controller.MachineMapper.MachineMapper` interface will
+ be instantiated by the Controller to match Recipe requirements to the
+ available pools
+ :type mapper: :py:class:`lnst.Controller.MachineMapper.MachineMapper`
+ (this is also the default class)
+
+ :param config:
+ optional LNST configuration object, if None the Controller will
+ load it's own configuration from default paths. If not provided, the
+ Controller init method will create a CtlConfig object instance
+ automatically and load it with values from default configuration file
+ paths.
+ :type config: :py:class:`lnst.Controller.Config.CtlConfig`
+
+ :param pools:
+ a list of pool names to restrict the used pool directories
+ :type pools: List[str] (default [])
+
+ :param pool_checks:
+ if False, will disable checking the online status of Slaves
+ :type pool_checks: boolean (default True)
+
+ :param debug:
+ sets the debug level of LNST
+ :type debug: integer (default 0)
+
+ Example::
+
+ lnst_controller = Controller()
+ recipe_instance = MyRecipe(test_parameter=123)
+ lnst_controller.run(recipe_instance)
"""
def __init__(self, poolMgr=SlavePoolManager, mapper=MachineMapper,
config=None, pools=[], pool_checks=True, debug=0):
- """
- Args:
- poolMgr -- class that implements the SlavePoolManager interface
- will be instantiated by the Controller to provide the mapper
- with pools available for matching, also handles the creation
- of Machine objects (internal LNST class used to access the
- slave hosts)
- mapper -- class that implements the MachineMapper interface
- will be instantiated by the Controller to match Recipe
- requirements to the available pools
- config -- optional LNST configuration object, if None the
- Controller will load it's own configuration from default paths
- pools -- a list of pool names to restrict the used pool directories
- pool_checks -- boolean (default True), if False will disable
- checking online status of Slaves
- debug -- integer (default 0), sets debug level of LNST
- """
self._config = self._load_ctl_config(config)
config = self._config
@@ -96,13 +123,17 @@ class Controller(object):
def run(self, recipe, **kwargs):
"""Execute the provided Recipe
- This method takes care of both finding a Slave hosts matching the Recipe
- requirements, provisioning them and calling the 'test' method of the
+ This method takes care of both finding Slave hosts matching the Recipe
+ requirements, provisioning them and calling the *test* method of the
Recipe object with proper references to the mapped Hosts
- Args:
- recipe -- an instantiated Recipe object (isinstance BaseRecipe)
- kwargs -- optional keyword arguments passed to the configured Mapper
+ :param recipe:
+ an instantiated Recipe object
+ :type recipe: :py:class:`lnst.Controller.Recipe.BaseRecipe`
+
+ :param kwargs:
+ optional keyword arguments passed to the configured Mapper
+ :type kwargs: Dict[str, Any]
"""
if not isinstance(recipe, BaseRecipe):
raise ControllerError("recipe argument must be a BaseRecipe instance.")
@@ -134,7 +165,6 @@ class Controller(object):
finally:
self._cleanup_slaves()
-
def _map_match(self, match, requested, recipe):
self._machines = {}
self._hosts = Hosts()
diff --git a/lnst/Controller/Recipe.py b/lnst/Controller/Recipe.py
index 42f4e3d..26e0737 100644
--- a/lnst/Controller/Recipe.py
+++ b/lnst/Controller/Recipe.py
@@ -1,9 +1,5 @@
"""
Module implementing the BaseRecipe class.
-
-Copyright 2017 Red Hat, Inc.
-Licensed under the GNU General Public License, version 2 as
-published by the Free Software Foundation; see COPYING for details.
"""
__author__ = """
@@ -23,27 +19,30 @@ class RecipeError(ControllerError):
pass
class BaseRecipe(object):
- """BaseRecipe class
+ """Base class for LNST Recipe definition.
Every LNST Recipe written by testers should be inherited from this class.
An LNST Recipe is composed of several parts:
+
* Requirements definition - you define recipe requirements in a derived
- class by defining class attributes of the HostReq type. You can further
- specify Ethernet Device requirements by defining DeviceReq attributes
- of the HostReq object.
- Example:
- m1 = HostReq(arch="x86_64")
- m1.eth0 = DeviceReq(driver="ixgbe")
- * Parameter definition (optional) - you can define paramaters of your Recipe
- by defining class attributes of the Param type (or inherited). These
- parameters can then be accessed from the test() method to change it's
- behaviour. Parameter validity (type) is checked during the
- instantiation of the Recipe object by the base __init__ method.
- You can define your own __init__ method to implement more complex
- Parameter checking if needed, but you MUST call the base __init__
- method first.
- Example:
- MyRecipe(BaseRecipe):
+ class by defining class attributes of the HostReq type. You can further
+ specify Ethernet Device requirements by defining DeviceReq attributes of
+ the :py:class:`lnst.Controller.Requirements.HostReq` object. Example::
+
+ class MyRecipe(BaseRecipe):
+ m1 = HostReq(arch="x86_64")
+ m1.eth0 = DeviceReq(driver="ixgbe")
+
+ * Parameter definition (optional) - you can define paramaters of your
+ Recipe by defining class attributes of the :any:`Param` type (or
+ inherited). These parameters can then be accessed from the test() method
+ to change it's behaviour. Parameter validity (type) is checked during the
+ instantiation of the Recipe object by the base __init__ method. You can
+ define your own __init__ method to implement more complex Parameter
+ checking if needed, but you MUST call the base __init__ method first.
+ Example::
+
+ class MyRecipe(BaseRecipe):
int_param = IntParam(mandatory=True)
optional_param = IntParam()
@@ -55,18 +54,24 @@ class BaseRecipe(object):
MyRecipe(int_param = 2, optional_param = 3)
* Test definition - this is done by defining the test() method, in this
- method the tester has direct access to mapped LNST slave Hosts, can
- manipulate them and implement his tests.
-
- Attributes:
- matched -- when running the Recipe the Controller will fill this
- attribute with a Hosts object after the Mapper finds suitable slave
- hosts.
- req -- instantiated Requirements object, you can optionally change the
- Recipe requirements through this object during runtime (e.g.
- variable number of hosts or devices of a host based on a Parameter)
- params -- instantiated Parameters object, can be used to access the
- calculated parameters during Recipe initialization/execution
+ method the tester has direct access to mapped LNST slave Hosts, can
+ manipulate them and implement his tests.
+
+ :ivar matched:
+ When running the Recipe the Controller will fill this attribute with a
+ Hosts object after the Mapper finds suitable slave hosts.
+ :type matched: :py:class:`lnst.Controller.Host.Hosts`
+
+ :ivar req:
+ Instantiated Requirements object, you can optionally change the Recipe
+ requirements through this object during runtime (e.g. variable number
+ of hosts or devices of a host based on a Parameter)
+ :type req: :py:class:`lnst.Controller.Requirements._Requirements`
+
+ :ivar params:
+ Instantiated Parameters object, can be used to access the calculated
+ parameters during Recipe initialization/execution
+ :type params: :py:class:`lnst.Common.Parameters.Parameters`
"""
def __init__(self, **kwargs):
"""
diff --git a/lnst/Controller/Requirements.py b/lnst/Controller/Requirements.py
index 342454f..ed61996 100644
--- a/lnst/Controller/Requirements.py
+++ b/lnst/Controller/Requirements.py
@@ -1,19 +1,19 @@
"""
-This module defines the DeviceReq and HostReq classes, which can be used to
+This module defines the :py:class:`lnst.Controller.Requirements.DeviceReq` and
+:py:class:`lnst.Controller.Requirements.HostReq` classes, which can be used to
create a global description of Requirements for a network test. You can use
-these to define class attributes of a BaseRecipe derived class to specify
+these to define class attributes of a
+:py:class:`lnst.Controller.Recipe.BaseRecipe` derived class to specify
"general" requirements for that Recipe, or you can add them to an instance of a
Recipe derived class based on it's parameters to define requirements "specific"
for that single test run.
-The module also specifies a Requirements class which serves as a container for
-HostReq objects, while HostReq classes also serve as containers for DeviceReq
-objects. The object tree created this way is translated to a dictionary used by
-the internal LNST matching algorithm against available machines.
-
-Copyright 2017 Red Hat, Inc.
-Licensed under the GNU General Public License, version 2 as
-published by the Free Software Foundation; see COPYING for details.
+The module also specifies a
+:py:class:`lnst.Controller.Requirements._Requirements` class (currently for
+internal use only) which serves as a container for HostReq objects, while
+HostReq classes also serve as containers for DeviceReq objects. The object tree
+created this way is translated to a dictionary used by the internal LNST
+matching algorithm against available machines.
"""
__author__ = """
@@ -63,15 +63,22 @@ class HostReq(BaseReq):
To define a Host requirement you assign a HostReq instance to a class
attribute of a BaseRecipe derived class.
- Example:
- class MyRecipe(BaseRecipe):
- m1 = HostReq()
-
- Args:
- kwargs -- any other arguments will be treated as arbitrary string
- parameters that will be matched to parameters of Slave machines
- which can define their parameter values based on the implementation
- of the SlaveMachineParser
+
+ :param kwargs:
+ any argument will be treated as arbitrary string parameters that will
+ be matched to parameters of Slave machines which can define their
+ parameter values based on the implementation of the SlaveMachineParser
+
+ A special case is the use of a
+ :py:mod:`lnst.Controller.Requirements.RecipeParam` instance as value.
+ This is used to link to a value provided as a Parameter to the Recipe.
+ :type kwargs: Dict[str, Any]
+
+ Example::
+
+ class MyRecipe(BaseRecipe):
+ m1 = HostReq()
+ m2 = HostReq(architecture="x86_64")
"""
def reinit_with_params(self, recipe_params):
super(HostReq, self).reinit_with_params(recipe_params)
@@ -93,21 +100,32 @@ class HostReq(BaseReq):
return res
class DeviceReq(BaseReq):
- """Specifies an Ethernet Device requirement
+ """Specifies a static test network Device requirement
+
+ This will be used to find a matching test machine in the configured slave
+ machine pools, specifically this will be used to match against a test
+ device on a slave machine that is "statically" present on the machine. In
+ other words an actual REAL network device connected to a network usable for
+ testing.
To define a Device requirement you assign a DeviceReq instance to a HostReq
instance in a BaseRecipe derived class.
- Example:
- class MyRecipe(BaseRecipe):
- m1 = HostReq()
- m1.eth0 = DeviceReq(label="net1")
-
- Args:
- label -- string value indicating the network the Device is connected to
- kwargs -- any other arguments will be treated as arbitrary string
- parameters that will be matched to parameters of Slave machines
- which can define their parameter values based on the implementation
- of the SlaveMachineParser
+
+ :param label:
+ string value indicating the network the Device is connected to
+ :type label: string
+
+ :param kwargs:
+ any other arguments will be treated as arbitrary string parameters that
+ will be matched to parameters of Slave machines which can define their
+ parameter values based on the implementation of the SlaveMachineParser
+ :type kwargs: Dict[str, Any]
+
+ Example::
+
+ class MyRecipe(BaseRecipe):
+ m1 = HostReq()
+ m1.eth0 = DeviceReq(label="net1")
"""
def __init__(self, label, **kwargs):
self.label = label
diff --git a/lnst/Controller/__init__.py b/lnst/Controller/__init__.py
index 106bb91..cb0392d 100644
--- a/lnst/Controller/__init__.py
+++ b/lnst/Controller/__init__.py
@@ -1,3 +1,10 @@
+"""
+Controller package
+==================
+
+This package exposes public facing APIs that can be used to create Recipes, as
+well as executable test scripts.
+"""
from lnst.Controller.Controller import Controller
from lnst.Controller.Recipe import BaseRecipe
from lnst.Controller.Requirements import HostReq, DeviceReq, RecipeParam
diff --git a/lnst/Recipes/ENRT/BaseEnrtRecipe.py b/lnst/Recipes/ENRT/BaseEnrtRecipe.py
index a90c837..ea371a3 100644
--- a/lnst/Recipes/ENRT/BaseEnrtRecipe.py
+++ b/lnst/Recipes/ENRT/BaseEnrtRecipe.py
@@ -2,7 +2,7 @@ import pprint
from contextlib import contextmanager
from lnst.Common.LnstError import LnstError
-from lnst.Common.Parameters import Param, IntParam, StrParam, BoolParam, ListParam
+from lnst.Common.Parameters import Param, IntParam, StrParam, BoolParam, ListParam, FloatParam
from lnst.Common.IpAddress import AF_INET, AF_INET6
from lnst.Recipes.ENRT.ConfigMixins.BaseSubConfigMixin import BaseSubConfigMixin
@@ -16,10 +16,148 @@ from lnst.RecipeCommon.Perf.Measurements import StatCPUMeasurement
from lnst.RecipeCommon.Perf.Evaluators import NonzeroFlowEvaluator
class EnrtConfiguration(object):
+ """Container object for configuration
+
+ Intentionally left empty as it is intended to be used as a container to
+ store any values relevant to configuration being applied during the lifetime
+ of the Recipe.
+ """
pass
class BaseEnrtRecipe(BaseSubConfigMixin, PingTestAndEvaluate, PerfRecipe):
- #common requirements parameters
+ """Base Recipe class for the ENRT recipe package
+
+ This class defines the shared *test* method defining the common test
+ procedure in a very generic way. This common test procedure involves a
+ single main *test_wide* configuration that is different for every specific
+ scenario. After the main configuration there is usually a loop of several
+ minor *sub* configrations types that can take different values to slightly
+ change the tested use cases.
+
+ Finally, for each combination of a **test_wide** + **sub** configuration we
+ do a several ping connection test and several performance measurement tests.
+
+ **test_wide** and **sub** configurations are implemented with **context
+ manager** methods which ensure that if any exceptions are raised (for
+ example because of a bug in the recipe) that deconfiguration is called.
+
+ Both **test_wide** and **sub** configurations are to be implemented in
+ different classes, the BaseEnrtRecipe class only defines the common API and
+ the base versions of the relevant methods.
+
+ Test wide configuration is implemented via the following methods:
+
+ * :any:`test_wide_configuration`
+ * :any:`test_wide_deconfiguration`
+ * :any:`generate_test_wide_description`
+
+ Sub configurations are **mixed into** classes defining the specific
+ scenario that is being tested. Various sub configurations are implemented as
+ individual Python **Mixin** classes in the
+ :any:`ConfigMixins<config_mixins>` package. These make use of Pythons
+ collaborative inheritance by calling the `super` function in a specific way.
+ The "machinery" for that is defined in the :any:`BaseSubConfigMixin` class.
+ It is then used in this class from the `test` method loop.
+
+ :param driver:
+ The driver parameter is used to modify the hw network requirements,
+ specifically to request Devices using the specified driver. This is
+ common enough in the Enrt recipes that it can be part of the Base class.
+
+ :type driver: :any:`StrParam` (default "ixgbe")
+
+ :param ip_versions:
+ Parameter that determines which IP protocol versions will be tested.
+ :type ip_versions: Tuple[Str] (default ("ipv4", "ipv6"))
+
+ :param ping_parallel:
+ Parameter used by the :any:`generate_ping_configurations` generator.
+ Tells the generator method to create :any:`PingConf` objects that will
+ be run in parallel.
+ :type ping_parallel: :any:`BoolParam` (default False)
+
+ :param ping_bidirect:
+ Parameter used by the :any:`generate_ping_configurations` generator.
+ Tells the generator method to create :any:`PingConf` objects for both
+ directions between the ping endpoints.
+ :type ping_bidirect: :any:`BoolParam` (default False)
+
+ :param ping_count:
+ Parameter used by the :any:`generate_ping_configurations` generator.
+ Tells the generator how many pings should be sent for each ping test.
+ :type ping_count: :any:`IntParam` (default 100)
+
+ :param ping_interval:
+ Parameter used by the :any:`generate_ping_configurations` generator.
+ Tells the generator how fast should the pings be sent in each ping test.
+ :type ping_interval: :any:`FloatParam` (default 0.2)
+
+ :param ping_psize:
+ Parameter used by the :any:`generate_ping_configurations` generator.
+ Tells the generator how big should the pings packets be in each ping
+ test.
+ :type ping_psize: :any:`IntParam` (default None)
+
+ :param perf_tests:
+ Parameter used by the :any:`generate_flow_combinations` generator.
+ Tells the generator what types of network flow measurements to generate
+ perf test configurations for.
+ :type perf_tests: Tuple[str] (default ("tcp_stream", "udp_stream",
+ "sctp_stream"))
+
+ :param perf_tool_cpu:
+ Parameter used by the :any:`generate_flow_combinations` generator. To
+ indicate that the flow measurement should be pinned to a specific CPU
+ core.
+ :type perf_tool_cpu: :any:`IntParam` (optional parameter)
+
+ :param perf_duration:
+ Parameter used by the :any:`generate_perf_configurations` generator. To
+ specify the duration of the performance measurements, in seconds.
+ :type perf_duration: :any:`IntParam` (default 60)
+
+ :param perf_iterations:
+ Parameter used by the :any:`generate_perf_configurations` generator. To
+ specify how many times should each performance measurement be repeated
+ to generate cumulative results which can be statistically analyzed.
+ :type perf_iterations: :any:`IntParam` (default 5)
+
+ :param perf_parallel_streams:
+ Parameter used by the :any:`generate_flow_combinations` generator. To
+ specify how many parallel streams of the same network flow should be
+ measured at the same time.
+ :type perf_parallel_streams: :any:`IntParam` (default 1)
+
+ :param perf_msg_sizes:
+ Parameter used by the :any:`generate_flow_combinations` generator. To
+ specify what different message sizes (in bytes) used generated for the
+ network flow should be tested - each message size resulting in a
+ separate performance measurement.
+ :type perf_msg_sizes: List[Int] (default [123])
+
+ :param perf_reverse:
+ Parameter used by the :any:`generate_flow_combinations` generator. To
+ specify that both directions between the endpoints of a network flow
+ should be measured for the same test.
+ :type perf_reverse: :any:`BoolParam` (default False)
+
+
+ :param net_perf_tool:
+ Parameter used by the :any:`generate_perf_configurations` generator to
+ create a PerfRecipeConf object.
+ Specifies a network flow measurement class that accepts :any:`PerfFlow`
+ objects and can be used to measure those specified flows
+ :type net_perf_tool: :any:`BaseFlowMeasurement` (default
+ IperfFlowMeasurement)
+
+ :param cpu_perf_tool:
+ Parameter used by the :any:`generate_perf_configurations` generator to
+ create a PerfRecipeConf object.
+ Specifies a cpu measurement class that can be used to measure CPU
+ utilization on specified hosts.
+ :type cpu_perf_tool: :any:`BaseCPUMeasurement` (default StatCPUMeasurement)
+ """
+
driver = StrParam(default="ixgbe")
#common test parameters
@@ -45,6 +183,20 @@ class BaseEnrtRecipe(BaseSubConfigMixin, PingTestAndEvaluate, PerfRecipe):
cpu_perf_tool = Param(default=StatCPUMeasurement)
def test(self):
+ """Main test loop shared by all the Enrt recipes
+
+ The test loop involves a single application of a **test_wide**
+ configuration, then a loop over multiple **sub** configurations that
+ involves:
+
+ * creating the combined sub configuration of all available SubConfig
+ Mixin classes via :any:`generate_sub_configurations`
+ * applying the generated sub configuration via the :any:`_sub_context`
+ context manager method
+ * running tests
+ * removing the current sub configuration via the :any:`_sub_context`
+ context manager method
+ """
with self._test_wide_context() as main_config:
for sub_config in self.generate_sub_configurations(main_config):
with self._sub_context(sub_config) as recipe_config:
@@ -60,19 +212,90 @@ class BaseEnrtRecipe(BaseSubConfigMixin, PingTestAndEvaluate, PerfRecipe):
self.test_wide_deconfiguration(config)
def test_wide_configuration(self):
+ """Creates an empty :any:`EnrtConfiguration` object
+
+ This is again used in potential collaborative inheritance design that
+ may potentially be useful for Enrt recipes. Derived classes will each
+ individually add their own values to the instance created here. This way
+ the complete test wide configuration is tracked in a single object.
+
+ :return: returns a config object that tracks the applied configuration
+ that can be used during testing to inspect the current state and
+ make test decisions based on it.
+ :rtype: :any:`EnrtConfiguration`
+
+ Example::
+
+ class Derived:
+ def test_wide_configuration():
+ config = super().test_wide_configuration()
+
+ # ... configure something
+ config.something = what_was_configured
+
+ return config
+ """
return EnrtConfiguration()
def test_wide_deconfiguration(self, config):
+ """Base deconfiguration method.
+
+ In the base class this should maybe only check if there's any leftover
+ configuration and warn about it. In derived classes this can be
+ overriden to take care of deconfiguring what was configured in the
+ respective test_wide_configuration method.
+
+ Example::
+
+ class Derived:
+ def test_wide_deconfiguration(config):
+ # ... deconfigure something
+ del config.something #cleanup tracking
+
+ return super().test_wide_deconfiguration()
+ """
#TODO check if anything is still applied and throw exception?
return
def describe_test_wide_configuration(self, config):
+ """Describes the current test wide configuration
+
+ Creates a new result object that contains the description of the full
+ test wide configuration applied by all the
+ :any:`test_wide_configuration` methods in the class hierarchy.
+
+ The description needs to be generated by the
+ :any:`generate_test_wide_description` method. Additionally the
+ description contains the state of all the parameters and their values
+ passed to the recipe class instance during initialization.
+ """
description = self.generate_test_wide_description(config)
self.add_result(True, "Summary of used Recipe parameters:\n{}".format(
pprint.pformat(self.params._to_dict())))
self.add_result(True, "\n".join(description))
def generate_test_wide_description(self, config):
+ """Generates the test wide configuration description
+
+ Another class inteded to be used with the collaborative version of the
+ `super` method to cumulatively desribe the full test wide configuration
+ that was applied through multiple classes.
+
+ The base class version of this method creates the initial list of
+ strings containing just the header line. Each string added to this list
+ will later be printed on its own line.
+
+ :return: list of strings, each representing a single line
+ :rtype: List[str]
+
+ Example::
+
+ class Derived:
+ def generate_sub_configuration_description(config):
+ desc = super().generate_sub_configuration_description(config)
+ desc.append("Configured something: {}".format(config.something))
+ return desc
+ """
return [
"Testwide configuration for recipe {} description:".format(
self.__class__.__name__
@@ -93,20 +316,47 @@ class BaseEnrtRecipe(BaseSubConfigMixin, PingTestAndEvaluate, PerfRecipe):
self.add_result(True, "\n".join(description))
def do_tests(self, recipe_config):
+ """Entry point for actual tests
+
+ The common scenario is to do ping and performance tests, however the
+ method can be overriden to add more tests if needed.
+ """
self.do_ping_tests(recipe_config)
self.do_perf_tests(recipe_config)
def do_ping_tests(self, recipe_config):
+ """Ping testing loop
+
+ Loops over all various ping configurations generated by the
+ :any:`generate_ping_configurations` method, then uses the PingRecipe
+ methods to execute, report and evaluate the results.
+ """
for ping_config in self.generate_ping_configurations(recipe_config):
result = self.ping_test(ping_config)
self.ping_evaluate_and_report(ping_config, result)
def do_perf_tests(self, recipe_config):
+ """Performance testing loop
+
+ Loops over all various perf configurations generated by the
+ :any:`generate_perf_configurations` method, then uses the PerfRecipe
+ methods to execute, report and evaluate the results.
+ """
for perf_config in self.generate_perf_configurations(recipe_config):
result = self.perf_test(perf_config)
self.perf_report_and_evaluate(result)
def generate_ping_configurations(self, config):
+ """Base ping test configuration generator
+
+ The generator loops over all endpoint pairs to test ping between
+ (generated by the :any:`generate_ping_endpoints` method) then over all
+ the selected :any:`ip_versions` and finally over all the IP addresses
+ that fit those criteria.
+
+ :return: list of Ping configurations to test in parallel
+ :rtype: List[:any:`PingConf`]
+ """
for endpoint1, endpoint2 in self.generate_ping_endpoints(config):
for ipv in self.params.ip_versions:
ip_filter = {}
@@ -144,9 +394,30 @@ class BaseEnrtRecipe(BaseSubConfigMixin, PingTestAndEvaluate, PerfRecipe):
yield ping_conf_list
def generate_ping_endpoints(self, config):
+ """Generator for ping endpoints
+
+ To be overriden by a derived class.
+
+ :return: list of device pairs
+ :rtype: List[Tuple[:any:`Device`, :any:`Device`]]
+ """
return []
def generate_perf_configurations(self, config):
+ """Base perf test configuration generator
+
+ The generator loops over all flow combinations to measure performance
+ for (generated by the :any:`generate_flow_combinations` method). In
+ addition to that during each flow combination measurement we add CPU
+ utilization measurement to run on the background.
+
+ Finally for each generated perf test configuration we register
+ measurement evaluators based on the :any:`cpu_perf_evaluators` and
+ :any:`net_perf_evaluators` properties.
+
+ :return: list of Perf test configurations
+ :rtype: List[:any:`PerfRecipeConf`]
+ """
for flows in self.generate_flow_combinations(config):
perf_recipe_conf=dict(
recipe_config=config,
@@ -183,6 +454,18 @@ class BaseEnrtRecipe(BaseSubConfigMixin, PingTestAndEvaluate, PerfRecipe):
yield perf_conf
def generate_flow_combinations(self, config):
+ """Base flow combination generator
+
+ The generator loops over all endpoint pairs to test performance between
+ (generated by the :any:`generate_perf_endpoints` method) then over all
+ the selected :any:`ip_versions` and uses the first IP address fitting
+ these criteria. Then the generator loops over the selected performance
+ tests as selected via :any:`perf_tests`, then message sizes from
+ :any:`msg_sizes`.
+
+ :return: list of Flow combinations to measure in parallel
+ :rtype: List[:any:`PerfFlow`]
+ """
for client_nic, server_nic in self.generate_perf_endpoints(config):
for ipv in self.params.ip_versions:
if ipv == "ipv4":
@@ -213,14 +496,37 @@ class BaseEnrtRecipe(BaseSubConfigMixin, PingTestAndEvaluate, PerfRecipe):
yield [reverse_flow]
def generate_perf_endpoints(self, config):
+ """Generator for perf endpoints
+
+ To be overriden by a derived class.
+
+ :return: list of device pairs
+ :rtype: List[Tuple[:any:`Device`, :any:`Device`]]
+ """
return []
@property
def cpu_perf_evaluators(self):
+ """CPU measurement evaluators
+
+ To be overriden by a derived class. Returns the list of evaluators to
+ use for CPU utilization measurement evaluation.
+
+ :return: a list of cpu evaluator objects
+ :rtype: List[BaseEvaluator]
+ """
return []
@property
def net_perf_evaluators(self):
+ """Network flow measurement evaluators
+
+ To be overriden bby a derived class. Returns the list of evaluators to
+ use for Network flow measurement evaluation.
+
+ :return: a list of flow evaluator objects
+ :rtype: List[BaseEvaluator]
+ """
return [NonzeroFlowEvaluator()]
def _create_reverse_flow(self, flow):
diff --git a/lnst/Recipes/ENRT/ConfigMixins/README.md b/lnst/Recipes/ENRT/ConfigMixins/README.md
new file mode 100644
index 0000000..0472be0
--- /dev/null
+++ b/lnst/Recipes/ENRT/ConfigMixins/README.md
@@ -0,0 +1,3 @@
+# SubConfig Mixins
+
+TODO
diff --git a/lnst/Recipes/ENRT/ConfigMixins/__init__.py b/lnst/Recipes/ENRT/ConfigMixins/__init__.py
index e69de29..7ae6450 100644
--- a/lnst/Recipes/ENRT/ConfigMixins/__init__.py
+++ b/lnst/Recipes/ENRT/ConfigMixins/__init__.py
@@ -0,0 +1,9 @@
+"""
+ENRT Config Mixins
+==================
+
+.. autoclass:: lnst.Recipes.ENRT.ConfigMixins.BaseSubConfigMixin.BaseSubConfigMixin
+
+"""
+
+from lnst.Recipes.ENRT.ConfigMixins.BaseSubConfigMixin import BaseSubConfigMixin
diff --git a/lnst/Recipes/ENRT/README.md b/lnst/Recipes/ENRT/README.md
new file mode 100644
index 0000000..3500cdc
--- /dev/null
+++ b/lnst/Recipes/ENRT/README.md
@@ -0,0 +1,47 @@
+# ENRT Recipes
+
+ENRT stands for Early Network Regression Testing, which was the name of the
+project a couple of years back when we started developing this set of tests
+when we were still using the Legacy LNST API.
+
+This package aims to reimplement the same set of tests, using the new LNST-next
+APIs, while fully utilizing Python to address the largest problems with the old
+implementation:
+* large amounts of code duplication
+* copy paste errors caused by code duplication
+* very hard to maintain the test set and fix bugs
+* very hard to add new tests due to limitations of the old LNST Framework
+
+With that in mind, the main goals for this reimplementation were as follows:
+* reduce code duplication as much as possible by utilizing class inheritance
+* separate individual types of configurations into smaller Mixin classes that
+ can be mixed and matched based on what a specific Test scenario requires
+* writing new test scenarios should be very quick because it should be possible
+ to reuse most of the functionality already defined
+* it should be possible to very easily extend the recipes with new features such
+ as more types of parallel or sequential measurements, more types of
+ Evaluations for different types of measurements, or to be able to switch out
+ and use different measurement tools
+
+The resulting design is split into several parts that interact with each other
+in a specific way:
+
+* [BaseEnrtRecipe](BaseEnrtRecipe.py) serves as the base class for all the
+ specific test scenarios we want to test. Defines the common test loop and the
+ default implementation for configuration generators used in this common test
+ loop.
+* [ConfigMixins](ConfigMixins/README.md) package contains the various types of
+ "SubConfig" mixin classes, these are classes that implement some form of
+ configuration on test machine(s) which can be reused between mutliple recipes,
+ but can often times be looped over to try different variations of the
+ configuration. A good example is configuration of hardware offloads, it's
+ relevant to test it for many different test scenarios, but only some
+ combinations of offloads make sense based on the scenario and we often time
+ want to test more than one combination
+* Specific test scenario implementation that defines the requirements and the
+ main configuration for the specific scenario that we want to test. It also
+ defines the combination of various "SubConfig" configurations that we want to
+ include by adding them to it's inheritance tree. If required the recipe can
+ also override any of the default functionality defined by it's parent classes,
+ a good example could be the generator method for creating various
+ configurations for flow performance measurement.
diff --git a/lnst/Recipes/ENRT/SimpleNetworkRecipe.py b/lnst/Recipes/ENRT/SimpleNetworkRecipe.py
index 911a996..89828c0 100644
--- a/lnst/Recipes/ENRT/SimpleNetworkRecipe.py
+++ b/lnst/Recipes/ENRT/SimpleNetworkRecipe.py
@@ -12,6 +12,25 @@ from lnst.Recipes.ENRT.ConfigMixins.CommonHWSubConfigMixin import (
class SimpleNetworkRecipe(
CommonHWSubConfigMixin, OffloadSubConfigMixin, BaseEnrtRecipe
):
+ """
+ This recipe implements Enrt testing for a simple network scenario that looks
+ as follows
+
+ .. code-block:: none
+
+ +--------+
+ +------+ switch +-----+
+ | +--------+ |
+ +--+-+ +-+--+
+ +-|eth0|-+ +-|eth0|-+
+ | +----+ | | +----+ |
+ | host1 | | host2 |
+ +--------+ +--------+
+
+ All sub configurations are included via Mixin classes.
+
+ The actual test machinery is implemented in the :any:`BaseEnrtRecipe` class.
+ """
host1 = HostReq()
host1.eth0 = DeviceReq(label="net1", driver=RecipeParam("driver"))
@@ -26,6 +45,14 @@ class SimpleNetworkRecipe(
dict(gro="on", gso="on", tso="on", tx="on", rx="off")))
def test_wide_configuration(self):
+ """
+ Test wide configuration for this recipe involves just adding an IPv4 and
+ IPv6 address to the matched eth0 nics on both hosts.
+
+ host1.eth0 = 192.168.101.1/24 and fc00::1/64
+
+ host2.eth0 = 192.168.101.2/24 and fc00::2/64
+ """
host1, host2 = self.matched.host1, self.matched.host2
configuration = super().test_wide_configuration()
configuration.test_wide_devices = []
@@ -41,6 +68,9 @@ class SimpleNetworkRecipe(
return configuration
def generate_test_wide_description(self, config):
+ """
+ Test wide description is extended with the configured addresses
+ """
desc = super().generate_test_wide_description(config)
desc += [
"Configured {}.{}.ips = {}".format(
@@ -51,14 +81,33 @@ class SimpleNetworkRecipe(
return desc
def test_wide_deconfiguration(self, config):
+ "" # overriding the parent docstring
del config.test_wide_devices
super().test_wide_deconfiguration(config)
def generate_ping_endpoints(self, config):
+ """
+ The ping endpoints for this recipe are simply the two matched NICs:
+
+ host1.eth0 and host2.eth0
+
+ Returned as::
+
+ [(self.matched.host1.eth0, self.matched.host2.eth0)]
+ """
return [(self.matched.host1.eth0, self.matched.host2.eth0)]
def generate_perf_endpoints(self, config):
+ """
+ The perf endpoints for this recipe are simply the two matched NICs:
+
+ host1.eth0 and host2.eth0
+
+ Returned as::
+
+ [(self.matched.host1.eth0, self.matched.host2.eth0)]
+ """
return [(self.matched.host1.eth0, self.matched.host2.eth0)]
def wait_tentative_ips(self, devices):
diff --git a/lnst/Recipes/ENRT/__init__.py b/lnst/Recipes/ENRT/__init__.py
index ea5aaf0..a591ef2 100644
--- a/lnst/Recipes/ENRT/__init__.py
+++ b/lnst/Recipes/ENRT/__init__.py
@@ -1,3 +1,55 @@
+'''
+ENRT Recipes
+------------
+
+ENRT stands for Early Network Regression Testing, which was the name of the
+project a couple of years back when we started developing this set of tests
+when we were still using the Legacy LNST API.
+
+This package aims to reimplement the same set of tests, using the new LNST-next
+APIs, while fully utilizing Python to address the largest problems with the old
+implementation:
+
+* large amounts of code duplication
+* copy paste errors caused by code duplication
+* very hard to maintain the test set and fix bugs
+* very hard to add new tests due to limitations of the old LNST Framework
+
+With that in mind, the main goals for this reimplementation were as follows:
+
+* reduce code duplication as much as possible by utilizing class inheritance
+* separate individual types of configurations into smaller Mixin classes that
+ can be mixed and matched based on what a specific Test scenario requires
+* writing new test scenarios should be very quick because it should be possible
+ to reuse most of the functionality already defined
+* it should be possible to very easily extend the recipes with new features
+ such as more types of parallel or sequential measurements, more types of
+ Evaluations for different types of measurements, or to be able to switch out
+ and use different measurement tools
+
+The resulting design is split into several parts that interact with each other
+in a specific way:
+
+* BaseEnrtRecipe serves as the base class for all the specific test scenarios
+ we want to test. Defines the common test loop and the default implementation
+ for configuration generators used in this common test loop.
+* ConfigMixins package contains the various types of "SubConfig" mixin classes,
+ these are classes that implement some form of configuration on test
+ machine(s) which can be reused between mutliple recipes, but can often times
+ be looped over to try different variations of the configuration. A good
+ example is configuration of hardware offloads, it's relevant to test it for
+ many different test scenarios, but only some combinations of offloads make
+ sense based on the scenario and we often time want to test more than one
+ combination
+* Specific test scenario implementation that defines the requirements and the
+ main configuration for the specific scenario that we want to test. It also
+ defines the combination of various "SubConfig" configurations that we want to
+ include by adding them to it's inheritance tree. If required the recipe can
+ also override any of the default functionality defined by it's parent
+ classes, a good example could be the generator method for creating various
+ configurations for flow performance measurement.
+
+'''
from lnst.Recipes.ENRT.SimpleNetworkRecipe import SimpleNetworkRecipe
from lnst.Recipes.ENRT.BondRecipe import BondRecipe
from lnst.Recipes.ENRT.DoubleBondRecipe import DoubleBondRecipe
--
2.25.2
3 years, 8 months
[PATCH 0/1] LNST-next documentation proposal
by olichtne@redhat.com
From: Ondrej Lichtner <olichtne(a)redhat.com>
Hi all,
the following patch is a proposal for how to do documentation for
LNST-next. To review there are two parts:
* review the patch source code changes as usual, if there's something
that doesn't make sense code wise or similar...
* please also apply the patch locally and generate the documentation as
follows:
cd docs/
make html
Then open the generated html index file located at build/html/index.html
with your favourite browser.
To generate the documentation you will need "sphinx" installed, for me
that is provided by the python-sphinx package on Arch Linux, there
should be an equivalent package on other distrubutions or you can
install it via PyPI:
pip install -U sphinx
Thanks,
-Ondrej
Ondrej Lichtner (1):
Sphinx based documentation
README.md | 25 +-
docs/Makefile | 20 ++
docs/source/ControllerAPI.rst | 5 +
docs/source/Parameters.rst | 5 +
docs/source/RecipeAPI.rst | 5 +
docs/source/RecipeRequirementsAPI.rst | 5 +
docs/source/SimpleNetworkRecipe.rst | 6 +
docs/source/TesterAPI.rst | 10 +
docs/source/base_enrt_class.rst | 8 +
docs/source/conf.py | 64 +++++
docs/source/config_mixins.rst | 3 +
docs/source/enrt_recipes.rst | 12 +
docs/source/index.rst | 25 ++
docs/source/installation.rst | 133 +++++++++
docs/source/recipe_packages.rst | 7 +
docs/source/specific_scenarios.rst | 5 +
lnst/Common/Parameters.py | 23 +-
lnst/Controller/Controller.py | 92 +++---
lnst/Controller/Recipe.py | 71 ++---
lnst/Controller/Requirements.py | 80 ++++--
lnst/Controller/__init__.py | 7 +
lnst/Recipes/ENRT/BaseEnrtRecipe.py | 312 ++++++++++++++++++++-
lnst/Recipes/ENRT/ConfigMixins/README.md | 3 +
lnst/Recipes/ENRT/ConfigMixins/__init__.py | 9 +
lnst/Recipes/ENRT/README.md | 47 ++++
lnst/Recipes/ENRT/SimpleNetworkRecipe.py | 49 ++++
lnst/Recipes/ENRT/__init__.py | 52 ++++
27 files changed, 965 insertions(+), 118 deletions(-)
create mode 100644 docs/Makefile
create mode 100644 docs/source/ControllerAPI.rst
create mode 100644 docs/source/Parameters.rst
create mode 100644 docs/source/RecipeAPI.rst
create mode 100644 docs/source/RecipeRequirementsAPI.rst
create mode 100644 docs/source/SimpleNetworkRecipe.rst
create mode 100644 docs/source/TesterAPI.rst
create mode 100644 docs/source/base_enrt_class.rst
create mode 100644 docs/source/conf.py
create mode 100644 docs/source/config_mixins.rst
create mode 100644 docs/source/enrt_recipes.rst
create mode 100644 docs/source/index.rst
create mode 100644 docs/source/installation.rst
create mode 100644 docs/source/recipe_packages.rst
create mode 100644 docs/source/specific_scenarios.rst
create mode 100644 lnst/Recipes/ENRT/ConfigMixins/README.md
create mode 100644 lnst/Recipes/ENRT/README.md
--
2.25.1
3 years, 8 months
Как будет вводиться электронная трудовая книжка?
by Anton D
Для руководителей и специалистов кадров служб. Обязательныепереход
на электронные книжки. Цифровизация кадрового делопроизводства. Новая
отчетность по трудовым договорам с 2020 года
Группа до 20 человек.
14 апреля 2020 г.
Семинар Трудовое право и кадровое делопроизводство:
исправляем ошибки.Электронные трудовые книжки в 2020 г. Цифровизация
кадрового делопроизводства Новыйотчет в ПФР: как заполнять СЗВ-ТД в 2020
год АНДРЕЕВА Валентина Ивановна - ведущийспециалист в сфере документационного обеспечения, профессор
кафедры трудового права исоциального обеспечения Российского государственного университета правосудия
(учредитель - Верховный Суд РФ, автор книг по делопроизводству, к.и.н. Главное изменение- начало
перехода к
цифровизации кадрового делопроизводства. Мероприятия кадровойслужбы в 2020 г. Уведомление
работников о переходе на электронные трудовые книжки и ихправе на продолжение ведения бумажных
трудовых книжек Внесение изменений в правилавнутреннего трудового распорядка Когда выдавать
работникам на руки трудовые книжки,если они отказались от их ведения: в 2020 или 2021 годах
Выдача работникам трудовыхкнижек на руки при отказе от продолжения их ведения Новые статьи в
Трудовом кодексеРФ.
7 апреля 2020 г.
Семинар Электронные трудовые книжки: всё о переходе,
обязанности работодателя впереходный период, что необходимо знать.
Блок 1. Электронные трудовые книжки.
Законодательные акты о переходе на Электронные трудовые книжки с 1 Января 2020 года,разъяснения от
государственных служб по вопросам перехода и внедрения. Прекратят лисуществовать бумажные
трудовые книжки? Предварительный Аудит трудовых книжек набумажном носителе и другой кадровой
документации для перехода на электронную версию,полный алгоритм. Новые правила заполнения
бумажной трудовой книжки в связи с переходомна электронные. Как будет вводиться электронная
трудовая книжка? Как часто придетсяподавать электронные сведения? Появятся ли новые штрафы?
Кто будет привлекать кответственности и за что? Перспективы принятия и последствия для
Работодателя. Новыестатьи, устанавливающие повышенную ответственность для Работодателя.
ПредоставлениеРаботнику доступа к информационным системам Работодателя. Работа с персональными
данными Работника при переходе на электронную трудовую книжку. Расшифровка трех! новыхотчетов от
Пенсионного фонда и детальный разбор заполнения. Как вынудить Работникаперейти на электронную
трудовую книжку или как сохранить бумажную. Пошаговаяинструкция!
20 апреля 2020 г.
ВЕБИНАР Электронные трудовые книжки: всё о переходе,
обязанности работодателя впереходный период, что необходимо знать.
23 марта 2020 г и 14 апреля 2020
День решений. Иностранные работники в 2020 г.:
экспертныйанализ кадровых, правовых и налоговых сторон вопроса Порядок привлечения к работе
иностранных работников Упрощенный порядок привлечения иностранцев граждан - Договор о
ЕВРАЗЭС: Россия, Беларусь, Казахстан, Армения, Киргизия Миграционный учет Особенности
привлечения отдельных категорий граждан (ВКС и студенты) Дополнительный контроль состороны
проверяющих органов и ответственность работодателя за нарушениязаконодательства Порядок
увольнения иностранных работников, дополнительные основаниядля увольнения Поправки в
законодательство, вступающие в силу в 2020 году.
Запись и подробная информация о программе по телефону в Москве:
8 код города 495 тел.: 518-41-39
8 код города 495 тел.: 518-42-97
3 years, 8 months
[PATCH 1/3] lnst.Recipes.ENRT.BaseEnrtRecipe: ping_interval should be FloatParam
by olichtne@redhat.com
From: Ondrej Lichtner <olichtne(a)redhat.com>
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Recipes/ENRT/BaseEnrtRecipe.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lnst/Recipes/ENRT/BaseEnrtRecipe.py b/lnst/Recipes/ENRT/BaseEnrtRecipe.py
index 5862311..fb3aae4 100644
--- a/lnst/Recipes/ENRT/BaseEnrtRecipe.py
+++ b/lnst/Recipes/ENRT/BaseEnrtRecipe.py
@@ -29,7 +29,7 @@ class BaseEnrtRecipe(BaseSubConfigMixin, PingTestAndEvaluate, PerfRecipe):
ping_parallel = BoolParam(default=False)
ping_bidirect = BoolParam(default=False)
ping_count = IntParam(default=100)
- ping_interval = StrParam(default=0.2)
+ ping_interval = FloatParam(default=0.2)
ping_psize = IntParam(default=None)
#common perf test params
--
2.25.1
3 years, 8 months
[PATCH] RecipeCommon..BaseFlowMeasurement: use fixed point format
for rx tput report
by Jan Tluka
Signed-off-by: Jan Tluka <jtluka(a)redhat.com>
---
lnst/RecipeCommon/Perf/Measurements/BaseFlowMeasurement.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lnst/RecipeCommon/Perf/Measurements/BaseFlowMeasurement.py b/lnst/RecipeCommon/Perf/Measurements/BaseFlowMeasurement.py
index 9890ed2c..8c74c610 100644
--- a/lnst/RecipeCommon/Perf/Measurements/BaseFlowMeasurement.py
+++ b/lnst/RecipeCommon/Perf/Measurements/BaseFlowMeasurement.py
@@ -204,7 +204,7 @@ class BaseFlowMeasurement(BaseMeasurement):
.format(cpu=generator_cpu.average,
cpu_deviation=generator_cpu.std_deviation,
cpu_unit=generator_cpu.unit))
- desc.append("Receiver measured throughput: {tput:.2f} +-{deviation:.2f}({percentage:.2}%) {unit} per second."
+ desc.append("Receiver measured throughput: {tput:.2f} +-{deviation:.2f}({percentage:.2f}%) {unit} per second."
.format(tput=receiver.average,
deviation=receiver.std_deviation,
percentage=cls._deviation_percentage(receiver),
--
2.21.1
3 years, 8 months