Update test documentation. 76/3776/9
authorMatej Klotton <mklotton@cisco.com>
Fri, 11 Nov 2016 10:38:55 +0000 (11:38 +0100)
committerDamjan Marion <dmarion.lists@gmail.com>
Tue, 15 Nov 2016 15:32:48 +0000 (15:32 +0000)
- update IRB, IPv4, ipv6 doc
- revert 778c2765c8ea5c6628f6d668847f0b9ae06dbf3d

Change-Id: I9af5ed9329ce5fe01392cf28d5bf321cfc647e48
Signed-off-by: Matej Klotton <mklotton@cisco.com>
28 files changed:
Makefile
test/doc/Makefile
test/doc/framework.rst [deleted file]
test/doc/hook.rst [deleted file]
test/doc/index.rst
test/doc/log.rst [deleted file]
test/doc/modules.rst [deleted file]
test/doc/run_tests.rst [deleted file]
test/doc/scapy_handlers.rst [deleted file]
test/doc/template_bd.rst [deleted file]
test/doc/test_ip4.rst [deleted file]
test/doc/test_ip6.rst [deleted file]
test/doc/test_l2bd.rst [deleted file]
test/doc/test_l2xc.rst [deleted file]
test/doc/test_lb.rst [deleted file]
test/doc/test_mpls.rst [deleted file]
test/doc/test_vxlan.rst [deleted file]
test/doc/util.rst [deleted file]
test/doc/vpp_interface.rst [deleted file]
test/doc/vpp_papi_provider.rst [deleted file]
test/doc/vpp_pg_interface.rst [deleted file]
test/doc/vpp_sub_interface.rst [deleted file]
test/framework.py
test/test_ip4.py
test/test_ip4_irb.py
test/test_ip6.py
test/vpp_interface.py
test/vpp_lo_interface.py

index 41a45c8..4e084d4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -212,7 +212,7 @@ build-vpp-api: $(BR)/.bootstrap.ok
 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 \
index 3b4c02b..809abef 100644 (file)
@@ -8,13 +8,15 @@ SPHINXBUILD = sphinx-build
 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
@@ -23,6 +25,13 @@ ifeq ($(IN_VENV),0)
        $(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"
@@ -58,44 +67,44 @@ wipe:
        rm -rf $(BUILD_DOC_ROOT)
 
 .PHONY: html
        rm -rf $(BUILD_DOC_ROOT)
 
 .PHONY: html
-html: verify-virtualenv
+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: verify-virtualenv
+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" \
@@ -105,7 +114,7 @@ qthelp: verify-virtualenv
        @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."
@@ -114,7 +123,7 @@ applehelp: verify-virtualenv
              "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."
@@ -124,7 +133,7 @@ devhelp: verify-virtualenv
        @echo "# devhelp"
 
 .PHONY: epub
        @echo "# devhelp"
 
 .PHONY: epub
-epub: verify-virtualenv
+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."
@@ -136,7 +145,7 @@ epub3:
        @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."
@@ -144,33 +153,33 @@ latex: verify-virtualenv
              "(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: verify-virtualenv
+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: verify-virtualenv
+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."
@@ -178,57 +187,57 @@ texinfo: verify-virtualenv
              "(use \`make info' here to do that automatically)."
 
 .PHONY: info
              "(use \`make info' here to do that automatically)."
 
 .PHONY: info
-info: verify-virtualenv
+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: verify-virtualenv
+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."
diff --git a/test/doc/framework.rst b/test/doc/framework.rst
deleted file mode 100644 (file)
index ce5e16e..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-framework module
-================
-
-.. automodule:: framework
-    :members:
-    :undoc-members:
-    :show-inheritance:
diff --git a/test/doc/hook.rst b/test/doc/hook.rst
deleted file mode 100644 (file)
index f856e51..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-hook module
-===========
-
-.. automodule:: hook
-    :members:
-    :undoc-members:
-    :show-inheritance:
index 323b608..8cbe961 100644 (file)
@@ -22,7 +22,7 @@ Anatomy of a test case
 ######################
 
 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.
 
@@ -44,11 +44,11 @@ Function flow when running a test case is:
    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
@@ -60,7 +60,7 @@ are stored in this temporary test directory.
 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
@@ -72,7 +72,7 @@ Naming conventions
 
 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.
diff --git a/test/doc/log.rst b/test/doc/log.rst
deleted file mode 100644 (file)
index 5965d5a..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-log module
-==========
-
-.. automodule:: log
-    :members:
-    :undoc-members:
-    :show-inheritance:
diff --git a/test/doc/modules.rst b/test/doc/modules.rst
deleted file mode 100644 (file)
index 773283e..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-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
diff --git a/test/doc/run_tests.rst b/test/doc/run_tests.rst
deleted file mode 100644 (file)
index 30cec4e..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-run_tests module
-================
-
-.. automodule:: run_tests
-    :members:
-    :undoc-members:
-    :show-inheritance:
diff --git a/test/doc/scapy_handlers.rst b/test/doc/scapy_handlers.rst
deleted file mode 100644 (file)
index 6717326..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-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:
diff --git a/test/doc/template_bd.rst b/test/doc/template_bd.rst
deleted file mode 100644 (file)
index e173d27..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-template_bd module
-==================
-
-.. automodule:: template_bd
-    :members:
-    :undoc-members:
-    :show-inheritance:
diff --git a/test/doc/test_ip4.rst b/test/doc/test_ip4.rst
deleted file mode 100644 (file)
index c3c3a23..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-test_ip module
-==============
-
-.. automodule:: test_ip4
-    :members:
-    :undoc-members:
-    :show-inheritance:
diff --git a/test/doc/test_ip6.rst b/test/doc/test_ip6.rst
deleted file mode 100644 (file)
index 63461c3..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-test_ip6 module
-===============
-
-.. automodule:: test_ip6
-    :members:
-    :undoc-members:
-    :show-inheritance:
diff --git a/test/doc/test_l2bd.rst b/test/doc/test_l2bd.rst
deleted file mode 100644 (file)
index 8a80dfe..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-test_l2bd module
-================
-
-.. automodule:: test_l2bd
-    :members:
-    :undoc-members:
-    :show-inheritance:
diff --git a/test/doc/test_l2xc.rst b/test/doc/test_l2xc.rst
deleted file mode 100644 (file)
index caf99ba..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-test_l2xc module
-================
-
-.. automodule:: test_l2xc
-    :members:
-    :undoc-members:
-    :show-inheritance:
diff --git a/test/doc/test_lb.rst b/test/doc/test_lb.rst
deleted file mode 100644 (file)
index e134b29..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-test_lb module
-==============
-
-.. automodule:: test_lb
-    :members:
-    :undoc-members:
-    :show-inheritance:
diff --git a/test/doc/test_mpls.rst b/test/doc/test_mpls.rst
deleted file mode 100644 (file)
index e4c8ce0..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-test_mpls module
-================
-
-.. automodule:: test_mpls
-    :members:
-    :undoc-members:
-    :show-inheritance:
diff --git a/test/doc/test_vxlan.rst b/test/doc/test_vxlan.rst
deleted file mode 100644 (file)
index 7f40c31..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-test_vxlan module
-=================
-
-.. automodule:: test_vxlan
-    :members:
-    :undoc-members:
-    :show-inheritance:
diff --git a/test/doc/util.rst b/test/doc/util.rst
deleted file mode 100644 (file)
index d8ad0d1..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-util module
-===========
-
-.. automodule:: util
-    :members:
-    :undoc-members:
-    :show-inheritance:
diff --git a/test/doc/vpp_interface.rst b/test/doc/vpp_interface.rst
deleted file mode 100644 (file)
index 32bb009..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-vpp_interface module
-====================
-
-.. automodule:: vpp_interface
-    :members:
-    :undoc-members:
-    :show-inheritance:
diff --git a/test/doc/vpp_papi_provider.rst b/test/doc/vpp_papi_provider.rst
deleted file mode 100644 (file)
index c9efe85..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-vpp_papi_provider module
-========================
-
-.. automodule:: vpp_papi_provider
-    :members:
-    :undoc-members:
-    :show-inheritance:
diff --git a/test/doc/vpp_pg_interface.rst b/test/doc/vpp_pg_interface.rst
deleted file mode 100644 (file)
index 85f54f6..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-vpp_pg_interface module
-=======================
-
-.. automodule:: vpp_pg_interface
-    :members:
-    :undoc-members:
-    :show-inheritance:
diff --git a/test/doc/vpp_sub_interface.rst b/test/doc/vpp_sub_interface.rst
deleted file mode 100644 (file)
index 5ff5300..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-vpp_sub_interface module
-========================
-
-.. automodule:: vpp_sub_interface
-    :members:
-    :undoc-members:
-    :show-inheritance:
index fdb600c..227428e 100644 (file)
@@ -29,22 +29,15 @@ class _PacketInfo(object):
 
     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.
     index = -1
     index = -1
+    #: Store the index of the source packet generator interface of the packet.
     src = -1
     src = -1
+    #: Store the index of the destination packet generator interface
+    #: of the packet.
     dst = -1
     dst = -1
+    #: Store the copy of the former packet.
     data = None
 
 
     data = None
 
 
@@ -54,12 +47,8 @@ def pump_output(out, queue):
 
 
 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.
     """
 
     @property
     """
 
     @property
@@ -189,7 +178,7 @@ class VppTestCase(unittest.TestCase):
         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
index 48155a5..36a907a 100644 (file)
@@ -2,24 +2,38 @@
 
 import unittest
 import socket
 
 import unittest
 import socket
-from logging import *
 
 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()
-
     def setUp(self):
     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 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
@@ -49,16 +63,26 @@ class TestIPv4(VppTestCase):
             i.config_ip4()
             i.resolve_arp()
 
             i.config_ip4()
             i.resolve_arp()
 
-        # config 2M FIB enries
+        # 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
@@ -69,13 +93,18 @@ class TestIPv4(VppTestCase):
             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)
-                counter = counter + 1
+                counter += 1
                 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]
@@ -95,7 +124,13 @@ class TestIPv4(VppTestCase):
         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
@@ -114,8 +149,8 @@ class TestIPv4(VppTestCase):
                 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])
@@ -129,8 +164,8 @@ class TestIPv4(VppTestCase):
                 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(
@@ -141,7 +176,14 @@ class TestIPv4(VppTestCase):
                 (dst_if.name, i.name))
 
     def test_fib(self):
                 (dst_if.name, i.name))
 
     def test_fib(self):
-        """ IPv4 FIB test """
+        """ 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)
index 412575d..cf2bb15 100644 (file)
@@ -1,39 +1,51 @@
 #!/usr/bin/env python
 #!/usr/bin/env python
+"""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
+
+"""
+
 import unittest
 import unittest
-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 logging import *
 
 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):
-    """ IRB Test Case """
+    """IRB Test Case"""
 
     @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
@@ -58,27 +70,34 @@ class TestIpIrb(VppTestCase):
         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 = []
@@ -200,8 +219,8 @@ class TestIpIrb(VppTestCase):
         """ 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
         """
 
@@ -224,7 +243,7 @@ class TestIpIrb(VppTestCase):
         """ 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(
index 92bb350..bff829b 100644 (file)
@@ -2,14 +2,13 @@
 
 import unittest
 import socket
 
 import unittest
 import socket
-from logging import *
 
 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):
@@ -20,6 +19,26 @@ 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
@@ -28,8 +47,9 @@ class TestIPv6(VppTestCase):
         # 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()
@@ -50,16 +70,26 @@ class TestIPv6(VppTestCase):
             i.config_ip6()
             i.resolve_ndp()
 
             i.config_ip6()
             i.resolve_ndp()
 
-        # config 2M FIB enries
+        # 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
@@ -70,13 +100,18 @@ class TestIPv6(VppTestCase):
             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)
-                counter = counter + 1
+                counter += 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" %
                          (count, percent))
                          (count, percent))
-                    percent = percent + 1
+                    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]
@@ -96,7 +131,13 @@ class TestIPv6(VppTestCase):
         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
@@ -115,8 +156,8 @@ class TestIPv6(VppTestCase):
                 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])
@@ -130,8 +171,8 @@ class TestIPv6(VppTestCase):
                 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(
@@ -142,7 +183,13 @@ class TestIPv6(VppTestCase):
                 (dst_if.name, i.name))
 
     def test_fib(self):
                 (dst_if.name, i.name))
 
     def test_fib(self):
-        """ IPv6 FIB test """
+        """ 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)
index d74248a..30ef8ae 100644 (file)
@@ -6,59 +6,57 @@ from util import Host
 
 
 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
@@ -68,17 +66,17 @@ class VppInterface(object):
 
     @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
@@ -88,20 +86,44 @@ class VppInterface(object):
 
     @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 = {}
@@ -117,7 +139,7 @@ class VppInterface(object):
             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()
 
@@ -149,21 +171,21 @@ class VppInterface(object):
              (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(
@@ -171,30 +193,31 @@ class VppInterface(object):
 
     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
@@ -205,6 +228,6 @@ class VppInterface(object):
                 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)
index ed9ac72..ef81525 100644 (file)
@@ -3,9 +3,7 @@ from vpp_interface import VppInterface
 
 
 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 """