summary |
shortlog |
log |
commit | commitdiff |
review |
tree
raw |
patch |
inline | side by side (from parent 1:
b7c3f2c)
28 files changed:
VPP_PYTHON_PREFIX=$(BR)/python
define test
VPP_PYTHON_PREFIX=$(BR)/python
define test
- $(if $(filter-out $(3),retest),make -C $(BR) PLATFORM=$(1) TAG=$(2) vpp-api-install plugins-install vpp-install vpp-api-test-install,)
+ $(if $(filter-out $(3),retest),make -C $(BR) PLATFORM=$(1) TAG=$(2) vpp-api-install plugins-install vpp-install,)
make -C test \
VPP_TEST_BIN=$(BR)/install-$(2)-native/vpp/bin/vpp \
VPP_TEST_API_TEST_BIN=$(BR)/install-$(2)-native/vpp-api-test/bin/vpp_api_test \
make -C test \
VPP_TEST_BIN=$(BR)/install-$(2)-native/vpp/bin/vpp \
VPP_TEST_API_TEST_BIN=$(BR)/install-$(2)-native/vpp-api-test/bin/vpp_api_test \
PAPER =
BUILD_DOC_ROOT = $(BR)/test-doc
BUILD_DOC_DIR = $(BUILD_DOC_ROOT)/build
PAPER =
BUILD_DOC_ROOT = $(BR)/test-doc
BUILD_DOC_DIR = $(BUILD_DOC_ROOT)/build
+API_DOC_GEN_DIR = $(BUILD_DOC_ROOT)/apidoc
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS = -d $(BUILD_DOC_DIR)/.sphinx-cache $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SRC_DOC_DIR)
+ALLSPHINXOPTS = -d $(BUILD_DOC_DIR)/.sphinx-cache $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(API_DOC_GEN_DIR) -c $(SRC_DOC_DIR)
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+INDEX_REL_PATH:=$(shell realpath --relative-to=$(API_DOC_GEN_DIR) $(SRC_DOC_DIR)/index.rst)
IN_VENV:=$(shell if pip -V | grep "virtualenv" 2>&1 > /dev/null; then echo 1; else echo 0; fi)
.PHONY: verify-virtualenv
IN_VENV:=$(shell if pip -V | grep "virtualenv" 2>&1 > /dev/null; then echo 1; else echo 0; fi)
.PHONY: verify-virtualenv
$(error "Not running inside virtualenv (are you running 'make test-doc' from root?)")
endif
$(error "Not running inside virtualenv (are you running 'make test-doc' from root?)")
endif
+.PHONY: regen-api-doc
+regen-api-doc: verify-virtualenv
+ @mkdir -p $(API_DOC_GEN_DIR)
+ #@echo ".. include:: $(INDEX_REL_PATH)" > $(API_DOC_GEN_DIR)/index.rst
+ @cp $(SRC_DOC_DIR)/index.rst $(API_DOC_GEN_DIR)
+ sphinx-apidoc -o $(API_DOC_GEN_DIR) ..
+
.PHONY: help
help:
@echo "Please use \`make <target>' where <target> is one of"
.PHONY: help
help:
@echo "Please use \`make <target>' where <target> is one of"
rm -rf $(BUILD_DOC_ROOT)
.PHONY: html
rm -rf $(BUILD_DOC_ROOT)
.PHONY: html
+html: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILD_DOC_DIR)/html."
.PHONY: dirhtml
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILD_DOC_DIR)/html."
.PHONY: dirhtml
-dirhtml: verify-virtualenv
+dirhtml: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILD_DOC_DIR)/dirhtml."
.PHONY: singlehtml
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILD_DOC_DIR)/dirhtml."
.PHONY: singlehtml
-singlehtml: verify-virtualenv
+singlehtml: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILD_DOC_DIR)/singlehtml."
.PHONY: pickle
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILD_DOC_DIR)/singlehtml."
.PHONY: pickle
-pickle: verify-virtualenv
+pickle: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
.PHONY: json
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
.PHONY: json
+json: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
.PHONY: htmlhelp
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
.PHONY: htmlhelp
-htmlhelp: verify-virtualenv
+htmlhelp: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILD_DOC_DIR)/htmlhelp."
.PHONY: qthelp
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILD_DOC_DIR)/htmlhelp."
.PHONY: qthelp
-qthelp: verify-virtualenv
+qthelp: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
@echo "# assistant -collectionFile $(BUILD_DOC_DIR)/qthelp/VPPtestframework.qhc"
.PHONY: applehelp
@echo "# assistant -collectionFile $(BUILD_DOC_DIR)/qthelp/VPPtestframework.qhc"
.PHONY: applehelp
-applehelp: verify-virtualenv
+applehelp: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/applehelp
@echo
@echo "Build finished. The help book is in $(BUILD_DOC_DIR)/applehelp."
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/applehelp
@echo
@echo "Build finished. The help book is in $(BUILD_DOC_DIR)/applehelp."
"bundle."
.PHONY: devhelp
"bundle."
.PHONY: devhelp
-devhelp: verify-virtualenv
+devhelp: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/devhelp
@echo
@echo "Build finished."
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/devhelp
@echo
@echo "Build finished."
@echo "# devhelp"
.PHONY: epub
@echo "# devhelp"
.PHONY: epub
+epub: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILD_DOC_DIR)/epub."
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILD_DOC_DIR)/epub."
@echo "Build finished. The epub3 file is in $(BUILD_DOC_DIR)/epub3."
.PHONY: latex
@echo "Build finished. The epub3 file is in $(BUILD_DOC_DIR)/epub3."
.PHONY: latex
-latex: verify-virtualenv
+latex: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILD_DOC_DIR)/latex."
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILD_DOC_DIR)/latex."
"(use \`make latexpdf' here to do that automatically)."
.PHONY: latexpdf
"(use \`make latexpdf' here to do that automatically)."
.PHONY: latexpdf
-latexpdf: verify-virtualenv
+latexpdf: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILD_DOC_DIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILD_DOC_DIR)/latex."
.PHONY: latexpdfja
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILD_DOC_DIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILD_DOC_DIR)/latex."
.PHONY: latexpdfja
-latexpdfja: verify-virtualenv
+latexpdfja: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILD_DOC_DIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILD_DOC_DIR)/latex."
.PHONY: text
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILD_DOC_DIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILD_DOC_DIR)/latex."
.PHONY: text
+text: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/text
@echo
@echo "Build finished. The text files are in $(BUILD_DOC_DIR)/text."
.PHONY: man
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/text
@echo
@echo "Build finished. The text files are in $(BUILD_DOC_DIR)/text."
.PHONY: man
+man: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILD_DOC_DIR)/man."
.PHONY: texinfo
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILD_DOC_DIR)/man."
.PHONY: texinfo
-texinfo: verify-virtualenv
+texinfo: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILD_DOC_DIR)/texinfo."
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILD_DOC_DIR)/texinfo."
"(use \`make info' here to do that automatically)."
.PHONY: info
"(use \`make info' here to do that automatically)."
.PHONY: info
+info: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILD_DOC_DIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILD_DOC_DIR)/texinfo."
.PHONY: gettext
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILD_DOC_DIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILD_DOC_DIR)/texinfo."
.PHONY: gettext
-gettext: verify-virtualenv
+gettext: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILD_DOC_DIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILD_DOC_DIR)/locale."
.PHONY: changes
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILD_DOC_DIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILD_DOC_DIR)/locale."
.PHONY: changes
-changes: verify-virtualenv
+changes: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/changes
@echo
@echo "The overview file is in $(BUILD_DOC_DIR)/changes."
.PHONY: linkcheck
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/changes
@echo
@echo "The overview file is in $(BUILD_DOC_DIR)/changes."
.PHONY: linkcheck
-linkcheck: verify-virtualenv
+linkcheck: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILD_DOC_DIR)/linkcheck/output.txt."
.PHONY: doctest
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILD_DOC_DIR)/linkcheck/output.txt."
.PHONY: doctest
-doctest: verify-virtualenv
+doctest: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILD_DOC_DIR)/doctest/output.txt."
.PHONY: coverage
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILD_DOC_DIR)/doctest/output.txt."
.PHONY: coverage
-coverage: verify-virtualenv
+coverage: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/coverage
@echo "Testing of coverage in the sources finished, look at the " \
"results in $(BUILD_DOC_DIR)/coverage/python.txt."
.PHONY: xml
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/coverage
@echo "Testing of coverage in the sources finished, look at the " \
"results in $(BUILD_DOC_DIR)/coverage/python.txt."
.PHONY: xml
+xml: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILD_DOC_DIR)/xml."
.PHONY: pseudoxml
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILD_DOC_DIR)/xml."
.PHONY: pseudoxml
-pseudoxml: verify-virtualenv
+pseudoxml: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILD_DOC_DIR)/pseudoxml."
.PHONY: dummy
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILD_DOC_DIR)/pseudoxml."
.PHONY: dummy
-dummy: verify-virtualenv
+dummy: regen-api-doc verify-virtualenv
$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/dummy
@echo
@echo "Build finished. Dummy builder generates no files."
$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/dummy
@echo
@echo "Build finished. Dummy builder generates no files."
+++ /dev/null
-framework module
-================
-
-.. automodule:: framework
- :members:
- :undoc-members:
- :show-inheritance:
+++ /dev/null
-hook module
-===========
-
-.. automodule:: hook
- :members:
- :undoc-members:
- :show-inheritance:
######################
Python's unittest_ is used as the base framework upon which the VPP test
######################
Python's unittest_ is used as the base framework upon which the VPP test
-framework is built. A test suite in the |vtf| constists of multiple classes
+framework is built. A test suite in the |vtf| consists of multiple classes
derived from `VppTestCase`, which is itself derived from TestCase_.
The test class defines one or more test functions, which act as test cases.
derived from `VppTestCase`, which is itself derived from TestCase_.
The test class defines one or more test functions, which act as test cases.
The tearDown function is called after each test function with the purpose
of doing partial cleanup.
5. `tearDownClass <VppTestCase.tearDownClass>`:
The tearDown function is called after each test function with the purpose
of doing partial cleanup.
5. `tearDownClass <VppTestCase.tearDownClass>`:
- Method called once after running all of the test funnctions to perform
+ Method called once after running all of the test functions to perform
the final cleanup.
Test temporary directory and VPP life cycle
the final cleanup.
Test temporary directory and VPP life cycle
-################################################
+###########################################
Test separation is achieved by separating the test files and vpp instances.
Each test creates a temporary directory and it's name is used to create
Test separation is achieved by separating the test files and vpp instances.
Each test creates a temporary directory and it's name is used to create
Virtual environment
###################
Virtual environment
###################
-Virtualenv_ is a python module which provides a means to crate an environment
+Virtualenv_ is a python module which provides a means to create an environment
containing the dependencies required by the |vtf|, allowing a separation
from any existing system-wide packages. |vtf|'s Makefile automatically
creates a virtualenv_ inside build-root and installs the required packages
containing the dependencies required by the |vtf|, allowing a separation
from any existing system-wide packages. |vtf|'s Makefile automatically
creates a virtualenv_ inside build-root and installs the required packages
Most unit tests do some kind of packet manipulation - sending and receiving
packets between VPP and virtual hosts connected to the VPP. Referring
Most unit tests do some kind of packet manipulation - sending and receiving
packets between VPP and virtual hosts connected to the VPP. Referring
-to the sides, addresses, etc.. is always done as if looking from the VPP side,
+to the sides, addresses, etc. is always done as if looking from the VPP side,
thus:
* *local_* prefix is used for the VPP side.
thus:
* *local_* prefix is used for the VPP side.
+++ /dev/null
-log module
-==========
-
-.. automodule:: log
- :members:
- :undoc-members:
- :show-inheritance:
+++ /dev/null
-test
-====
-
-.. toctree::
- :maxdepth: 4
-
- framework
- hook
- log
- run_tests
- scapy_handlers
- template_bd
- test_ip4
- test_ip6
- test_l2bd
- test_l2xc
- test_lb
- test_mpls
- test_vxlan
- util
- vpp_interface
- vpp_papi_provider
- vpp_pg_interface
- vpp_sub_interface
+++ /dev/null
-run_tests module
-================
-
-.. automodule:: run_tests
- :members:
- :undoc-members:
- :show-inheritance:
+++ /dev/null
-scapy_handlers package
-======================
-
-Submodules
-----------
-
-scapy_handlers.vxlan module
----------------------------
-
-.. automodule:: scapy_handlers.vxlan
- :members:
- :undoc-members:
- :show-inheritance:
-
-
-Module contents
----------------
-
-.. automodule:: scapy_handlers
- :members:
- :undoc-members:
- :show-inheritance:
+++ /dev/null
-template_bd module
-==================
-
-.. automodule:: template_bd
- :members:
- :undoc-members:
- :show-inheritance:
+++ /dev/null
-test_ip module
-==============
-
-.. automodule:: test_ip4
- :members:
- :undoc-members:
- :show-inheritance:
+++ /dev/null
-test_ip6 module
-===============
-
-.. automodule:: test_ip6
- :members:
- :undoc-members:
- :show-inheritance:
+++ /dev/null
-test_l2bd module
-================
-
-.. automodule:: test_l2bd
- :members:
- :undoc-members:
- :show-inheritance:
+++ /dev/null
-test_l2xc module
-================
-
-.. automodule:: test_l2xc
- :members:
- :undoc-members:
- :show-inheritance:
+++ /dev/null
-test_lb module
-==============
-
-.. automodule:: test_lb
- :members:
- :undoc-members:
- :show-inheritance:
+++ /dev/null
-test_mpls module
-================
-
-.. automodule:: test_mpls
- :members:
- :undoc-members:
- :show-inheritance:
+++ /dev/null
-test_vxlan module
-=================
-
-.. automodule:: test_vxlan
- :members:
- :undoc-members:
- :show-inheritance:
+++ /dev/null
-util module
-===========
-
-.. automodule:: util
- :members:
- :undoc-members:
- :show-inheritance:
+++ /dev/null
-vpp_interface module
-====================
-
-.. automodule:: vpp_interface
- :members:
- :undoc-members:
- :show-inheritance:
+++ /dev/null
-vpp_papi_provider module
-========================
-
-.. automodule:: vpp_papi_provider
- :members:
- :undoc-members:
- :show-inheritance:
+++ /dev/null
-vpp_pg_interface module
-=======================
-
-.. automodule:: vpp_pg_interface
- :members:
- :undoc-members:
- :show-inheritance:
+++ /dev/null
-vpp_sub_interface module
-========================
-
-.. automodule:: vpp_sub_interface
- :members:
- :undoc-members:
- :show-inheritance:
Help process information about the next packet.
Set variables to default values.
Help process information about the next packet.
Set variables to default values.
- @property index
- Integer variable to store the index of the packet.
- @property src
- Integer variable to store the index of the source packet generator
- interface of the packet.
- @property dst
- Integer variable to store the index of the destination packet generator
- interface of the packet.
- @property data
- Object variable to store the copy of the former packet.
-
-
+ #: Store the index of the packet.
+ #: Store the index of the source packet generator interface of the packet.
+ #: Store the index of the destination packet generator interface
+ #: of the packet.
+ #: Store the copy of the former packet.
class VppTestCase(unittest.TestCase):
class VppTestCase(unittest.TestCase):
- """
- Subclass of the python unittest.TestCase class.
-
- This subclass is a base class for test cases that are implemented as classes
- It provides methods to create and run test case.
-
+ """This subclass is a base class for VPP test cases that are implemented as
+ classes. It provides methods to create and run test case.
cls.packet_infos = {}
cls.verbose = 0
print(double_line_delim)
cls.packet_infos = {}
cls.verbose = 0
print(double_line_delim)
- print(colorize(getdoc(cls), YELLOW))
+ print(colorize(getdoc(cls).splitlines()[0], YELLOW))
print(double_line_delim)
# need to catch exceptions here because if we raise, then the cleanup
# doesn't get called and we might end with a zombie vpp
print(double_line_delim)
# need to catch exceptions here because if we raise, then the cleanup
# doesn't get called and we might end with a zombie vpp
import unittest
import socket
import unittest
import socket
from framework import VppTestCase, VppTestRunner
from framework import VppTestCase, VppTestRunner
+from vpp_interface import VppInterface
from vpp_sub_interface import VppSubInterface, VppDot1QSubint, VppDot1ADSubint
from scapy.packet import Raw
from vpp_sub_interface import VppSubInterface, VppDot1QSubint, VppDot1ADSubint
from scapy.packet import Raw
-from scapy.layers.l2 import Ether, Dot1Q, ARP
+from scapy.layers.l2 import Ether, Dot1Q
from scapy.layers.inet import IP, UDP
class TestIPv4(VppTestCase):
""" IPv4 Test Case """
from scapy.layers.inet import IP, UDP
class TestIPv4(VppTestCase):
""" IPv4 Test Case """
- @classmethod
- def setUpClass(cls):
- super(TestIPv4, cls).setUpClass()
-
+ """
+ Perform test setup before test case.
+
+ **Config:**
+ - create 3 pg interfaces
+ - untagged pg0 interface
+ - Dot1Q subinterface on pg1
+ - Dot1AD subinterface on pg2
+ - setup interfaces:
+ - put it into UP state
+ - set IPv4 addresses
+ - resolve neighbor address using ARP
+ - configure 200 fib entries
+
+ :ivar list interfaces: pg interfaces and subinterfaces.
+ :ivar dict flows: IPv4 packet flows in test.
+ :ivar list pg_if_packet_sizes: packet sizes in test.
+ """
super(TestIPv4, self).setUp()
# create 3 pg interfaces
super(TestIPv4, self).setUp()
# create 3 pg interfaces
i.config_ip4()
i.resolve_arp()
i.config_ip4()
i.resolve_arp()
+ # config 2M FIB entries
self.config_fib_entries(200)
def tearDown(self):
self.config_fib_entries(200)
def tearDown(self):
+ """Run standard test teardown and log ``show ip arp``."""
super(TestIPv4, self).tearDown()
if not self.vpp_dead:
super(TestIPv4, self).tearDown()
if not self.vpp_dead:
- info(self.vapi.cli("show ip arp"))
+ self.logger.info(self.vapi.cli("show ip arp"))
# info(self.vapi.cli("show ip fib")) # many entries
def config_fib_entries(self, count):
# info(self.vapi.cli("show ip fib")) # many entries
def config_fib_entries(self, count):
+ """For each interface add to the FIB table *count* routes to
+ "10.0.0.1/32" destination with interface's local address as next-hop
+ address.
+
+ :param int count: Number of FIB entries.
+
+ - *TODO:* check if the next-hop address shouldn't be remote address
+ instead of local address.
+ """
n_int = len(self.interfaces)
percent = 0
counter = 0.0
n_int = len(self.interfaces)
percent = 0
counter = 0.0
for j in range(count / n_int):
self.vapi.ip_add_del_route(
dest_addr, dest_addr_len, next_hop_address)
for j in range(count / n_int):
self.vapi.ip_add_del_route(
dest_addr, dest_addr_len, next_hop_address)
if counter / count * 100 > percent:
if counter / count * 100 > percent:
- info("Configure %d FIB entries .. %d%% done" %
- (count, percent))
- percent = percent + 1
+ self.logger.info("Configure %d FIB entries .. %d%% done" %
+ (count, percent))
+ percent += 1
def create_stream(self, src_if, packet_sizes):
def create_stream(self, src_if, packet_sizes):
+ """Create input packet stream for defined interface.
+
+ :param VppInterface src_if: Interface to create packet stream for.
+ :param list packet_sizes: Required packet sizes.
+ """
pkts = []
for i in range(0, 257):
dst_if = self.flows[src_if][i % 2]
pkts = []
for i in range(0, 257):
dst_if = self.flows[src_if][i % 2]
return pkts
def verify_capture(self, dst_if, capture):
return pkts
def verify_capture(self, dst_if, capture):
- info("Verifying capture on interface %s" % dst_if.name)
+ """Verify captured input packet stream for defined interface.
+
+ :param VppInterface dst_if: Interface to verify captured packet stream
+ for.
+ :param list capture: Captured packet stream.
+ """
+ self.logger.info("Verifying capture on interface %s" % dst_if.name)
last_info = dict()
for i in self.interfaces:
last_info[i.sw_if_index] = None
last_info = dict()
for i in self.interfaces:
last_info[i.sw_if_index] = None
payload_info = self.payload_to_info(str(packet[Raw]))
packet_index = payload_info.index
self.assertEqual(payload_info.dst, dst_sw_if_index)
payload_info = self.payload_to_info(str(packet[Raw]))
packet_index = payload_info.index
self.assertEqual(payload_info.dst, dst_sw_if_index)
- debug("Got packet on port %s: src=%u (id=%u)" %
- (dst_if.name, payload_info.src, packet_index))
+ self.logger.debug("Got packet on port %s: src=%u (id=%u)" %
+ (dst_if.name, payload_info.src, packet_index))
next_info = self.get_next_packet_info_for_interface2(
payload_info.src, dst_sw_if_index,
last_info[payload_info.src])
next_info = self.get_next_packet_info_for_interface2(
payload_info.src, dst_sw_if_index,
last_info[payload_info.src])
self.assertEqual(udp.sport, saved_packet[UDP].sport)
self.assertEqual(udp.dport, saved_packet[UDP].dport)
except:
self.assertEqual(udp.sport, saved_packet[UDP].sport)
self.assertEqual(udp.dport, saved_packet[UDP].dport)
except:
- error("Unexpected or invalid packet:")
- error(packet.show())
+ self.logger.error("Unexpected or invalid packet:")
+ self.logger.error(packet.show())
raise
for i in self.interfaces:
remaining_packet = self.get_next_packet_info_for_interface2(
raise
for i in self.interfaces:
remaining_packet = self.get_next_packet_info_for_interface2(
(dst_if.name, i.name))
def test_fib(self):
(dst_if.name, i.name))
def test_fib(self):
+ """ IPv4 FIB test
+
+ Test scenario:
+
+ - Create IPv4 stream for pg0 interface
+ - Create IPv4 tagged streams for pg1's and pg2's subinterface.
+ - Send and verify received packets on each interface.
+ """
pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes)
self.pg0.add_stream(pkts)
pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes)
self.pg0.add_stream(pkts)
+"""IRB Test Case HLD:
+
+**config**
+ - L2 MAC learning enabled in l2bd
+ - 2 routed interfaces untagged, bvi (Bridge Virtual Interface)
+ - 2 bridged interfaces in l2bd with bvi
+
+**test**
+ - sending ip4 eth pkts between routed interfaces
+ - 2 routed interfaces
+ - 2 bridged interfaces
+
+ - 64B, 512B, 1518B, 9200B (ether_size)
+
+ - burst of pkts per interface
+ - 257pkts per burst
+ - routed pkts hitting different FIB entries
+ - bridged pkts hitting different MAC entries
+
+**verify**
+ - all packets received correctly
+
+"""
+
-from random import choice, randint
+from random import choice
from scapy.packet import Raw
from scapy.layers.l2 import Ether
from scapy.layers.inet import IP, UDP
from scapy.packet import Raw
from scapy.layers.l2 import Ether
from scapy.layers.inet import IP, UDP
from framework import VppTestCase, VppTestRunner
from framework import VppTestCase, VppTestRunner
-""" IRB Test Case
-
-config
- L2 MAC learning enabled in l2bd
- 2 routed interfaces untagged, bvi
- 2 bridged interfaces in l2bd with bvi
-test
- sending ip4 eth pkts between routed interfaces
- 2 routed interfaces
- 2 bridged interfaces
- 64B, 512B, 1518B, 9200B (ether_size)
- burst of pkts per interface
- 257pkts per burst
- routed pkts hitting different FIB entries
- bridged pkts hitting different MAC entries
-verify
- all packets received correctly
-"""
-
class TestIpIrb(VppTestCase):
class TestIpIrb(VppTestCase):
@classmethod
def setUpClass(cls):
@classmethod
def setUpClass(cls):
+ """
+ #. Create BD with MAC learning enabled and put interfaces to this BD.
+ #. Configure IPv4 addresses on loopback interface and routed interface.
+ #. Configure MAC address binding to IPv4 neighbors on loop0.
+ #. Configure MAC address on pg2.
+ #. Loopback BVI interface has remote hosts, one half of hosts are
+ behind pg0 second behind pg1.
+ """
super(TestIpIrb, cls).setUpClass()
cls.pg_if_packet_sizes = [64, 512, 1518, 9018] # packet sizes
super(TestIpIrb, cls).setUpClass()
cls.pg_if_packet_sizes = [64, 512, 1518, 9018] # packet sizes
cls.vapi.sw_interface_set_l2_bridge(
cls.pg1.sw_if_index, bd_id=cls.bd_id)
cls.vapi.sw_interface_set_l2_bridge(
cls.pg1.sw_if_index, bd_id=cls.bd_id)
+ # Configure IPv4 addresses on loopback interface and routed interface
cls.loop0.config_ip4()
cls.pg2.config_ip4()
cls.loop0.config_ip4()
cls.pg2.config_ip4()
- # configure MAC address binding to IPv4 neighbors on loop0
+ # Configure MAC address binding to IPv4 neighbors on loop0
cls.loop0.generate_remote_hosts(cls.remote_hosts_count)
cls.loop0.generate_remote_hosts(cls.remote_hosts_count)
- cls.loop0.configure_extend_ipv4_mac_binding()
+ cls.loop0.configure_ipv4_neighbors()
# configure MAC address on pg2
cls.pg2.resolve_arp()
# configure MAC address on pg2
cls.pg2.resolve_arp()
- # one half of hosts are behind pg0 second behind pg1
+ # Loopback BVI interface has remote hosts, one half of hosts are behind
+ # pg0 second behind pg1
half = cls.remote_hosts_count // 2
cls.pg0.remote_hosts = cls.loop0.remote_hosts[:half]
cls.pg1.remote_hosts = cls.loop0.remote_hosts[half:]
def tearDown(self):
half = cls.remote_hosts_count // 2
cls.pg0.remote_hosts = cls.loop0.remote_hosts[:half]
cls.pg1.remote_hosts = cls.loop0.remote_hosts[half:]
def tearDown(self):
+ """Run standard test teardown and log ``show l2patch``,
+ ``show l2fib verbose``,``show bridge-domain <bd_id> detail``,
+ ``show ip arp``.
+ """
super(TestIpIrb, self).tearDown()
if not self.vpp_dead:
super(TestIpIrb, self).tearDown()
if not self.vpp_dead:
- info(self.vapi.cli("show l2patch"))
- info(self.vapi.cli("show l2fib verbose"))
- info(self.vapi.cli("show bridge-domain %s detail" % self.bd_id))
- info(self.vapi.cli("show ip arp"))
+ self.logger.info(self.vapi.cli("show l2patch"))
+ self.logger.info(self.vapi.cli("show l2fib verbose"))
+ self.logger.info(self.vapi.cli("show bridge-domain %s detail" %
+ self.bd_id))
+ self.logger.info(self.vapi.cli("show ip arp"))
def create_stream(self, src_ip_if, dst_ip_if, packet_sizes):
pkts = []
def create_stream(self, src_ip_if, dst_ip_if, packet_sizes):
pkts = []
""" IPv4 IRB test 1
Test scenario:
""" IPv4 IRB test 1
Test scenario:
- ip traffic from pg2 interface must ends in both pg0 and pg1
- - arp entry present in loop0 interface for dst IP
+ - ip traffic from pg2 interface must ends in both pg0 and pg1
+ - arp entry present in loop0 interface for destination IP
- no l2 entree configured, pg0 and pg1 are same
"""
- no l2 entree configured, pg0 and pg1 are same
"""
""" IPv4 IRB test 2
Test scenario:
""" IPv4 IRB test 2
Test scenario:
- ip traffic from pg0 and pg1 ends on pg2
+ - ip traffic from pg0 and pg1 ends on pg2
"""
stream1 = self.create_stream_l2_to_ip(
"""
stream1 = self.create_stream_l2_to_ip(
import unittest
import socket
import unittest
import socket
from framework import VppTestCase, VppTestRunner
from framework import VppTestCase, VppTestRunner
-from vpp_sub_interface import VppSubInterface, VppDot1QSubint, VppDot1ADSubint
+from vpp_sub_interface import VppSubInterface, VppDot1QSubint
from scapy.packet import Raw
from scapy.layers.l2 import Ether, Dot1Q
from scapy.packet import Raw
from scapy.layers.l2 import Ether, Dot1Q
-from scapy.layers.inet6 import ICMPv6ND_NS, IPv6, UDP
+from scapy.layers.inet6 import IPv6, UDP
class TestIPv6(VppTestCase):
class TestIPv6(VppTestCase):
super(TestIPv6, cls).setUpClass()
def setUp(self):
super(TestIPv6, cls).setUpClass()
def setUp(self):
+ """
+ Perform test setup before test case.
+
+ **Config:**
+ - create 3 pg interfaces
+ - untagged pg0 interface
+ - Dot1Q subinterface on pg1
+ - Dot1AD subinterface on pg2
+ - setup interfaces:
+ - put it into UP state
+ - set IPv6 addresses
+ - resolve neighbor address using NDP
+ - configure 200 fib entries
+
+ :ivar list interfaces: pg interfaces and subinterfaces.
+ :ivar dict flows: IPv4 packet flows in test.
+ :ivar list pg_if_packet_sizes: packet sizes in test.
+
+ *TODO:* Create AD sub interface
+ """
super(TestIPv6, self).setUp()
# create 3 pg interfaces
super(TestIPv6, self).setUp()
# create 3 pg interfaces
# create 2 subinterfaces for p1 and pg2
self.sub_interfaces = [
VppDot1QSubint(self, self.pg1, 100),
# create 2 subinterfaces for p1 and pg2
self.sub_interfaces = [
VppDot1QSubint(self, self.pg1, 100),
- VppDot1QSubint(self, self.pg2, 200)]
+ VppDot1QSubint(self, self.pg2, 200)
# TODO: VppDot1ADSubint(self, self.pg2, 200, 300, 400)
# TODO: VppDot1ADSubint(self, self.pg2, 200, 300, 400)
# packet flows mapping pg0 -> pg1.sub, pg2.sub, etc.
self.flows = dict()
# packet flows mapping pg0 -> pg1.sub, pg2.sub, etc.
self.flows = dict()
i.config_ip6()
i.resolve_ndp()
i.config_ip6()
i.resolve_ndp()
+ # config 2M FIB entries
self.config_fib_entries(200)
def tearDown(self):
self.config_fib_entries(200)
def tearDown(self):
+ """Run standard test teardown and log ``show ip6 neighbors``."""
super(TestIPv6, self).tearDown()
if not self.vpp_dead:
super(TestIPv6, self).tearDown()
if not self.vpp_dead:
- info(self.vapi.cli("show ip6 neighbors"))
+ self.logger.info(self.vapi.cli("show ip6 neighbors"))
# info(self.vapi.cli("show ip6 fib")) # many entries
def config_fib_entries(self, count):
# info(self.vapi.cli("show ip6 fib")) # many entries
def config_fib_entries(self, count):
+ """For each interface add to the FIB table *count* routes to
+ "fd02::1/128" destination with interface's local address as next-hop
+ address.
+
+ :param int count: Number of FIB entries.
+
+ - *TODO:* check if the next-hop address shouldn't be remote address
+ instead of local address.
+ """
n_int = len(self.interfaces)
percent = 0
counter = 0.0
n_int = len(self.interfaces)
percent = 0
counter = 0.0
for j in range(count / n_int):
self.vapi.ip_add_del_route(
dest_addr, dest_addr_len, next_hop_address, is_ipv6=1)
for j in range(count / n_int):
self.vapi.ip_add_del_route(
dest_addr, dest_addr_len, next_hop_address, is_ipv6=1)
if counter / count * 100 > percent:
if counter / count * 100 > percent:
- info("Configure %d FIB entries .. %d%% done" %
+ self.logger.info("Configure %d FIB entries .. %d%% done" %
def create_stream(self, src_if, packet_sizes):
def create_stream(self, src_if, packet_sizes):
+ """Create input packet stream for defined interface.
+
+ :param VppInterface src_if: Interface to create packet stream for.
+ :param list packet_sizes: Required packet sizes.
+ """
pkts = []
for i in range(0, 257):
dst_if = self.flows[src_if][i % 2]
pkts = []
for i in range(0, 257):
dst_if = self.flows[src_if][i % 2]
return pkts
def verify_capture(self, dst_if, capture):
return pkts
def verify_capture(self, dst_if, capture):
- info("Verifying capture on interface %s" % dst_if.name)
+ """Verify captured input packet stream for defined interface.
+
+ :param VppInterface dst_if: Interface to verify captured packet stream
+ for.
+ :param list capture: Captured packet stream.
+ """
+ self.logger.info("Verifying capture on interface %s" % dst_if.name)
last_info = dict()
for i in self.interfaces:
last_info[i.sw_if_index] = None
last_info = dict()
for i in self.interfaces:
last_info[i.sw_if_index] = None
payload_info = self.payload_to_info(str(packet[Raw]))
packet_index = payload_info.index
self.assertEqual(payload_info.dst, dst_sw_if_index)
payload_info = self.payload_to_info(str(packet[Raw]))
packet_index = payload_info.index
self.assertEqual(payload_info.dst, dst_sw_if_index)
- debug("Got packet on port %s: src=%u (id=%u)" %
- (dst_if.name, payload_info.src, packet_index))
+ self.logger.debug("Got packet on port %s: src=%u (id=%u)" %
+ (dst_if.name, payload_info.src, packet_index))
next_info = self.get_next_packet_info_for_interface2(
payload_info.src, dst_sw_if_index,
last_info[payload_info.src])
next_info = self.get_next_packet_info_for_interface2(
payload_info.src, dst_sw_if_index,
last_info[payload_info.src])
self.assertEqual(udp.sport, saved_packet[UDP].sport)
self.assertEqual(udp.dport, saved_packet[UDP].dport)
except:
self.assertEqual(udp.sport, saved_packet[UDP].sport)
self.assertEqual(udp.dport, saved_packet[UDP].dport)
except:
- error("Unexpected or invalid packet:")
- error(packet.show())
+ self.logger.error("Unexpected or invalid packet:")
+ self.logger.error(packet.show())
raise
for i in self.interfaces:
remaining_packet = self.get_next_packet_info_for_interface2(
raise
for i in self.interfaces:
remaining_packet = self.get_next_packet_info_for_interface2(
(dst_if.name, i.name))
def test_fib(self):
(dst_if.name, i.name))
def test_fib(self):
+ """ IPv6 FIB test
+
+ Test scenario:
+ - Create IPv6 stream for pg0 interface
+ - Create IPv6 tagged streams for pg1's and pg2's subinterface.
+ - Send and verify received packets on each interface.
+ """
pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes)
self.pg0.add_stream(pkts)
pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes)
self.pg0.add_stream(pkts)
class VppInterface(object):
class VppInterface(object):
- """
- Generic VPP interface
- """
+ """Generic VPP interface."""
__metaclass__ = ABCMeta
@property
def sw_if_index(self):
__metaclass__ = ABCMeta
@property
def sw_if_index(self):
- """Interface index assigned by VPP"""
+ """Interface index assigned by VPP."""
return self._sw_if_index
@property
def remote_mac(self):
return self._sw_if_index
@property
def remote_mac(self):
- """MAC-address of the remote interface "connected" to this interface"""
+ """MAC-address of the remote interface "connected" to this interface."""
return self._remote_hosts[0].mac
@property
def local_mac(self):
return self._remote_hosts[0].mac
@property
def local_mac(self):
- """MAC-address of the VPP interface"""
+ """MAC-address of the VPP interface."""
return self._local_mac
@property
def local_ip4(self):
return self._local_mac
@property
def local_ip4(self):
- """Local IPv4 address on VPP interface (string)"""
+ """Local IPv4 address on VPP interface (string)."""
return self._local_ip4
@property
def local_ip4n(self):
return self._local_ip4
@property
def local_ip4n(self):
- """Local IPv4 address - raw, suitable as API parameter"""
+ """Local IPv4 address - raw, suitable as API parameter."""
return socket.inet_pton(socket.AF_INET, self._local_ip4)
@property
def remote_ip4(self):
return socket.inet_pton(socket.AF_INET, self._local_ip4)
@property
def remote_ip4(self):
- """IPv4 address of remote peer "connected" to this interface"""
+ """IPv4 address of remote peer "connected" to this interface."""
return self._remote_hosts[0].ip4
@property
def remote_ip4n(self):
return self._remote_hosts[0].ip4
@property
def remote_ip4n(self):
- """IPv4 address of remote peer - raw, suitable as API parameter"""
+ """IPv4 address of remote peer - raw, suitable as API parameter."""
return socket.inet_pton(socket.AF_INET, self.remote_ip4)
@property
def local_ip6(self):
return socket.inet_pton(socket.AF_INET, self.remote_ip4)
@property
def local_ip6(self):
- """Local IPv6 address on VPP interface (string)"""
+ """Local IPv6 address on VPP interface (string)."""
return self._local_ip6
@property
def local_ip6n(self):
return self._local_ip6
@property
def local_ip6n(self):
- """Local IPv6 address - raw, suitable as API parameter"""
+ """Local IPv6 address - raw, suitable as API parameter."""
return socket.inet_pton(socket.AF_INET6, self.local_ip6)
@property
def remote_ip6(self):
return socket.inet_pton(socket.AF_INET6, self.local_ip6)
@property
def remote_ip6(self):
- """IPv6 address of remote peer "connected" to this interface"""
+ """IPv6 address of remote peer "connected" to this interface."""
return self._remote_hosts[0].ip6
@property
return self._remote_hosts[0].ip6
@property
@property
def name(self):
@property
def name(self):
- """Name of the interface"""
+ """Name of the interface."""
return self._name
@property
def dump(self):
return self._name
@property
def dump(self):
- """Raw result of sw_interface_dump for this interface"""
+ """RAW result of sw_interface_dump for this interface."""
return self._dump
@property
def test(self):
return self._dump
@property
def test(self):
- """Test case creating this interface"""
+ """Test case creating this interface."""
return self._test
@property
return self._test
@property
@remote_hosts.setter
def remote_hosts(self, value):
@remote_hosts.setter
def remote_hosts(self, value):
+ """
+ :param list value: List of remote hosts.
+ """
self._remote_hosts = value
self._remote_hosts = value
- #TODO: set hosts_by dicts
+ self._hosts_by_mac = {}
+ self._hosts_by_ip4 = {}
+ self._hosts_by_ip6 = {}
+ for host in self._remote_hosts:
+ self._hosts_by_mac[host.mac] = host
+ self._hosts_by_ip4[host.ip4] = host
+ self._hosts_by_ip6[host.ip6] = host
def host_by_mac(self, mac):
def host_by_mac(self, mac):
+ """
+ :param ip: MAC address to find host by.
+ :return: Host object assigned to interface.
+ """
return self._hosts_by_mac[mac]
def host_by_ip4(self, ip):
return self._hosts_by_mac[mac]
def host_by_ip4(self, ip):
+ """
+ :param ip: IPv4 address to find host by.
+ :return: Host object assigned to interface.
+ """
return self._hosts_by_ip4[ip]
def host_by_ip6(self, ip):
return self._hosts_by_ip4[ip]
def host_by_ip6(self, ip):
+ """
+ :param ip: IPv6 address to find host by.
+ :return: Host object assigned to interface.
+ """
return self._hosts_by_ip6[ip]
def generate_remote_hosts(self, count=1):
return self._hosts_by_ip6[ip]
def generate_remote_hosts(self, count=1):
- """Generate and add remote hosts for the interface."""
+ """Generate and add remote hosts for the interface.
+
+ :param int count: Number of generated remote hosts.
+ """
self._remote_hosts = []
self._hosts_by_mac = {}
self._hosts_by_ip4 = {}
self._remote_hosts = []
self._hosts_by_mac = {}
self._hosts_by_ip4 = {}
self._hosts_by_ip6[ip6] = host
def post_init_setup(self):
self._hosts_by_ip6[ip6] = host
def post_init_setup(self):
- """Additional setup run after creating an interface object"""
+ """Additional setup run after creating an interface object."""
self.generate_remote_hosts()
self.generate_remote_hosts()
(self.__name__, self.remote_mac, self.remote_ip4, self.local_ip4))
def config_ip4(self):
(self.__name__, self.remote_mac, self.remote_ip4, self.local_ip4))
def config_ip4(self):
- """Configure IPv4 address on the VPP interface"""
+ """Configure IPv4 address on the VPP interface."""
addr = self.local_ip4n
addr_len = 24
self.test.vapi.sw_interface_add_del_address(
self.sw_if_index, addr, addr_len)
addr = self.local_ip4n
addr_len = 24
self.test.vapi.sw_interface_add_del_address(
self.sw_if_index, addr, addr_len)
- def configure_extend_ipv4_mac_binding(self):
- """Configure neighbor MAC to IPv4 addresses."""
+ def configure_ipv4_neighbors(self):
+ """For every remote host assign neighbor's MAC to IPv4 addresses."""
for host in self._remote_hosts:
macn = host.mac.replace(":", "").decode('hex')
ipn = host.ip4n
self.test.vapi.ip_neighbor_add_del(self.sw_if_index, macn, ipn)
def config_ip6(self):
for host in self._remote_hosts:
macn = host.mac.replace(":", "").decode('hex')
ipn = host.ip4n
self.test.vapi.ip_neighbor_add_del(self.sw_if_index, macn, ipn)
def config_ip6(self):
- """Configure IPv6 address on the VPP interface"""
+ """Configure IPv6 address on the VPP interface."""
addr = self._local_ip6n
addr_len = 64
self.test.vapi.sw_interface_add_del_address(
addr = self._local_ip6n
addr_len = 64
self.test.vapi.sw_interface_add_del_address(
def set_table_ip4(self, table_id):
"""Set the interface in a IPv4 Table.
def set_table_ip4(self, table_id):
"""Set the interface in a IPv4 Table.
- Must be called before configuring IP4 addresses"""
+
+ .. note:: Must be called before configuring IP4 addresses."""
self.test.vapi.sw_interface_set_table(
self.sw_if_index, 0, table_id)
def set_table_ip6(self, table_id):
"""Set the interface in a IPv6 Table.
self.test.vapi.sw_interface_set_table(
self.sw_if_index, 0, table_id)
def set_table_ip6(self, table_id):
"""Set the interface in a IPv6 Table.
- Must be called before configuring IP6 addresses"""
+
+ .. note:: Must be called before configuring IP6 addresses.
+ """
self.test.vapi.sw_interface_set_table(
self.sw_if_index, 1, table_id)
def disable_ipv6_ra(self):
self.test.vapi.sw_interface_set_table(
self.sw_if_index, 1, table_id)
def disable_ipv6_ra(self):
- """Configure IPv6 RA suppress on the VPP interface"""
+ """Configure IPv6 RA suppress on the VPP interface."""
self.test.vapi.sw_interface_ra_suppress(self.sw_if_index)
def admin_up(self):
self.test.vapi.sw_interface_ra_suppress(self.sw_if_index)
def admin_up(self):
- """ Put interface ADMIN-UP """
+ """Put interface ADMIN-UP."""
self.test.vapi.sw_interface_set_flags(self.sw_if_index, admin_up_down=1)
def add_sub_if(self, sub_if):
self.test.vapi.sw_interface_set_flags(self.sw_if_index, admin_up_down=1)
def add_sub_if(self, sub_if):
- """
- Register a sub-interface with this interface
+ """Register a sub-interface with this interface.
:param sub_if: sub-interface
:param sub_if: sub-interface
"""
if not hasattr(self, 'sub_if'):
self.sub_if = sub_if
"""
if not hasattr(self, 'sub_if'):
self.sub_if = sub_if
self.sub_if = sub_if
def enable_mpls(self):
self.sub_if = sub_if
def enable_mpls(self):
- """Enable MPLS on the VPP interface"""
+ """Enable MPLS on the VPP interface."""
self.test.vapi.sw_interface_enable_disable_mpls(
self.sw_if_index)
self.test.vapi.sw_interface_enable_disable_mpls(
self.sw_if_index)
class VppLoInterface(VppInterface):
class VppLoInterface(VppInterface):
- """
- VPP loopback interface
- """
+ """VPP loopback interface."""
def __init__(self, test, lo_index):
""" Create VPP loopback interface """
def __init__(self, test, lo_index):
""" Create VPP loopback interface """