Update test documentation.
- update IRB, IPv4, ipv6 doc
- revert 778c2765c8
Change-Id: I9af5ed9329ce5fe01392cf28d5bf321cfc647e48
Signed-off-by: Matej Klotton <mklotton@cisco.com>
This commit is contained in:

committed by
Damjan Marion

parent
b7c3f2c61c
commit
86d87c40dd
2
Makefile
2
Makefile
@ -212,7 +212,7 @@ build-vpp-api: $(BR)/.bootstrap.ok
|
||||
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 \
|
||||
|
@ -8,13 +8,15 @@ SPHINXBUILD = sphinx-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
|
||||
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) .
|
||||
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
|
||||
@ -23,6 +25,13 @@ ifeq ($(IN_VENV),0)
|
||||
$(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"
|
||||
@ -58,44 +67,44 @@ wipe:
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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" \
|
||||
@ -105,7 +114,7 @@ qthelp: verify-virtualenv
|
||||
@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."
|
||||
@ -114,7 +123,7 @@ applehelp: verify-virtualenv
|
||||
"bundle."
|
||||
|
||||
.PHONY: devhelp
|
||||
devhelp: verify-virtualenv
|
||||
devhelp: regen-api-doc verify-virtualenv
|
||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILD_DOC_DIR)/devhelp
|
||||
@echo
|
||||
@echo "Build finished."
|
||||
@ -124,7 +133,7 @@ devhelp: verify-virtualenv
|
||||
@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."
|
||||
@ -136,7 +145,7 @@ epub3:
|
||||
@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."
|
||||
@ -144,33 +153,33 @@ latex: verify-virtualenv
|
||||
"(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
|
||||
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
|
||||
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
|
||||
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
|
||||
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."
|
||||
@ -178,57 +187,57 @@ texinfo: verify-virtualenv
|
||||
"(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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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."
|
||||
|
@ -1,7 +0,0 @@
|
||||
framework module
|
||||
================
|
||||
|
||||
.. automodule:: framework
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
@ -1,7 +0,0 @@
|
||||
hook module
|
||||
===========
|
||||
|
||||
.. automodule:: hook
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
@ -22,7 +22,7 @@ Anatomy of a test case
|
||||
######################
|
||||
|
||||
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.
|
||||
|
||||
@ -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>`:
|
||||
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
|
||||
################################################
|
||||
###########################################
|
||||
|
||||
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
|
||||
###################
|
||||
|
||||
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
|
||||
@ -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
|
||||
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.
|
||||
|
@ -1,7 +0,0 @@
|
||||
log module
|
||||
==========
|
||||
|
||||
.. automodule:: log
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
@ -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
|
@ -1,7 +0,0 @@
|
||||
run_tests module
|
||||
================
|
||||
|
||||
.. automodule:: run_tests
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
@ -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:
|
@ -1,7 +0,0 @@
|
||||
template_bd module
|
||||
==================
|
||||
|
||||
.. automodule:: template_bd
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
@ -1,7 +0,0 @@
|
||||
test_ip module
|
||||
==============
|
||||
|
||||
.. automodule:: test_ip4
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
@ -1,7 +0,0 @@
|
||||
test_ip6 module
|
||||
===============
|
||||
|
||||
.. automodule:: test_ip6
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
@ -1,7 +0,0 @@
|
||||
test_l2bd module
|
||||
================
|
||||
|
||||
.. automodule:: test_l2bd
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
@ -1,7 +0,0 @@
|
||||
test_l2xc module
|
||||
================
|
||||
|
||||
.. automodule:: test_l2xc
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
@ -1,7 +0,0 @@
|
||||
test_lb module
|
||||
==============
|
||||
|
||||
.. automodule:: test_lb
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
@ -1,7 +0,0 @@
|
||||
test_mpls module
|
||||
================
|
||||
|
||||
.. automodule:: test_mpls
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
@ -1,7 +0,0 @@
|
||||
test_vxlan module
|
||||
=================
|
||||
|
||||
.. automodule:: test_vxlan
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
@ -1,7 +0,0 @@
|
||||
util module
|
||||
===========
|
||||
|
||||
.. automodule:: util
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
@ -1,7 +0,0 @@
|
||||
vpp_interface module
|
||||
====================
|
||||
|
||||
.. automodule:: vpp_interface
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
@ -1,7 +0,0 @@
|
||||
vpp_papi_provider module
|
||||
========================
|
||||
|
||||
.. automodule:: vpp_papi_provider
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
@ -1,7 +0,0 @@
|
||||
vpp_pg_interface module
|
||||
=======================
|
||||
|
||||
.. automodule:: vpp_pg_interface
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
@ -1,7 +0,0 @@
|
||||
vpp_sub_interface module
|
||||
========================
|
||||
|
||||
.. automodule:: vpp_sub_interface
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
@ -29,22 +29,15 @@ class _PacketInfo(object):
|
||||
|
||||
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
|
||||
#: Store the index of the source packet generator interface of the packet.
|
||||
src = -1
|
||||
#: Store the index of the destination packet generator interface
|
||||
#: of the packet.
|
||||
dst = -1
|
||||
#: Store the copy of the former packet.
|
||||
data = None
|
||||
|
||||
|
||||
@ -54,12 +47,8 @@ def pump_output(out, queue):
|
||||
|
||||
|
||||
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
|
||||
@ -189,7 +178,7 @@ class VppTestCase(unittest.TestCase):
|
||||
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
|
||||
|
@ -2,24 +2,38 @@
|
||||
|
||||
import unittest
|
||||
import socket
|
||||
from logging import *
|
||||
|
||||
from framework import VppTestCase, VppTestRunner
|
||||
from vpp_interface import VppInterface
|
||||
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 """
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestIPv4, 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 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
|
||||
@ -49,16 +63,26 @@ class TestIPv4(VppTestCase):
|
||||
i.config_ip4()
|
||||
i.resolve_arp()
|
||||
|
||||
# config 2M FIB enries
|
||||
# config 2M FIB entries
|
||||
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:
|
||||
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):
|
||||
"""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
|
||||
@ -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)
|
||||
counter = counter + 1
|
||||
counter += 1
|
||||
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):
|
||||
"""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]
|
||||
@ -95,7 +124,13 @@ class TestIPv4(VppTestCase):
|
||||
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
|
||||
@ -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)
|
||||
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])
|
||||
@ -129,8 +164,8 @@ class TestIPv4(VppTestCase):
|
||||
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(
|
||||
@ -141,7 +176,14 @@ class TestIPv4(VppTestCase):
|
||||
(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)
|
||||
|
@ -1,39 +1,51 @@
|
||||
#!/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
|
||||
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 logging import *
|
||||
|
||||
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):
|
||||
""" IRB Test Case """
|
||||
"""IRB Test Case"""
|
||||
|
||||
@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
|
||||
@ -58,27 +70,34 @@ class TestIpIrb(VppTestCase):
|
||||
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()
|
||||
|
||||
# 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.configure_extend_ipv4_mac_binding()
|
||||
cls.loop0.configure_ipv4_neighbors()
|
||||
# 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):
|
||||
"""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:
|
||||
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 = []
|
||||
@ -200,8 +219,8 @@ class TestIpIrb(VppTestCase):
|
||||
""" 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
|
||||
"""
|
||||
|
||||
@ -224,7 +243,7 @@ class TestIpIrb(VppTestCase):
|
||||
""" 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(
|
||||
|
@ -2,14 +2,13 @@
|
||||
|
||||
import unittest
|
||||
import socket
|
||||
from logging import *
|
||||
|
||||
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.layers.inet6 import ICMPv6ND_NS, IPv6, UDP
|
||||
from scapy.layers.inet6 import IPv6, UDP
|
||||
|
||||
|
||||
class TestIPv6(VppTestCase):
|
||||
@ -20,6 +19,26 @@ class TestIPv6(VppTestCase):
|
||||
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
|
||||
@ -28,8 +47,9 @@ class TestIPv6(VppTestCase):
|
||||
# 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)
|
||||
]
|
||||
|
||||
# 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()
|
||||
|
||||
# config 2M FIB enries
|
||||
# config 2M FIB entries
|
||||
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:
|
||||
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):
|
||||
"""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
|
||||
@ -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)
|
||||
counter = counter + 1
|
||||
counter += 1
|
||||
if counter / count * 100 > percent:
|
||||
info("Configure %d FIB entries .. %d%% done" %
|
||||
self.logger.info("Configure %d FIB entries .. %d%% done" %
|
||||
(count, percent))
|
||||
percent = percent + 1
|
||||
percent += 1
|
||||
|
||||
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]
|
||||
@ -96,7 +131,13 @@ class TestIPv6(VppTestCase):
|
||||
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
|
||||
@ -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)
|
||||
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])
|
||||
@ -130,8 +171,8 @@ class TestIPv6(VppTestCase):
|
||||
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(
|
||||
@ -142,7 +183,13 @@ class TestIPv6(VppTestCase):
|
||||
(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)
|
||||
|
@ -6,59 +6,57 @@ from util import Host
|
||||
|
||||
|
||||
class VppInterface(object):
|
||||
"""
|
||||
Generic VPP interface
|
||||
"""
|
||||
"""Generic VPP interface."""
|
||||
__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):
|
||||
"""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):
|
||||
"""MAC-address of the VPP interface"""
|
||||
"""MAC-address of the VPP interface."""
|
||||
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):
|
||||
"""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):
|
||||
"""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):
|
||||
"""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):
|
||||
"""Local IPv6 address on VPP interface (string)"""
|
||||
"""Local IPv6 address on VPP interface (string)."""
|
||||
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):
|
||||
"""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
|
||||
@ -68,17 +66,17 @@ class VppInterface(object):
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Name of the interface"""
|
||||
"""Name of the interface."""
|
||||
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):
|
||||
"""Test case creating this interface"""
|
||||
"""Test case creating this interface."""
|
||||
return self._test
|
||||
|
||||
@property
|
||||
@ -88,20 +86,44 @@ class VppInterface(object):
|
||||
|
||||
@remote_hosts.setter
|
||||
def remote_hosts(self, value):
|
||||
"""
|
||||
:param list value: List of remote hosts.
|
||||
"""
|
||||
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):
|
||||
"""
|
||||
: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):
|
||||
"""
|
||||
: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):
|
||||
"""
|
||||
: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):
|
||||
"""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 = {}
|
||||
@ -117,7 +139,7 @@ class VppInterface(object):
|
||||
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()
|
||||
|
||||
@ -149,21 +171,21 @@ class VppInterface(object):
|
||||
(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)
|
||||
|
||||
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):
|
||||
"""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(
|
||||
@ -171,30 +193,31 @@ class VppInterface(object):
|
||||
|
||||
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.
|
||||
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):
|
||||
"""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):
|
||||
""" 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):
|
||||
"""
|
||||
Register a sub-interface with this interface
|
||||
"""Register a sub-interface with this interface.
|
||||
|
||||
:param sub_if: sub-interface
|
||||
|
||||
"""
|
||||
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):
|
||||
"""Enable MPLS on the VPP interface"""
|
||||
"""Enable MPLS on the VPP interface."""
|
||||
self.test.vapi.sw_interface_enable_disable_mpls(
|
||||
self.sw_if_index)
|
||||
|
@ -3,9 +3,7 @@ from vpp_interface import VppInterface
|
||||
|
||||
|
||||
class VppLoInterface(VppInterface):
|
||||
"""
|
||||
VPP loopback interface
|
||||
"""
|
||||
"""VPP loopback interface."""
|
||||
|
||||
def __init__(self, test, lo_index):
|
||||
""" Create VPP loopback interface """
|
||||
|
Reference in New Issue
Block a user