2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-22 09:58:01 +00:00

python: Introduce unit tests.

Use pytest to run unit tests as part of the standard testsuite.

Acked-by: Eelco Chaudron <echaudro@redhat.com>
Signed-off-by: Adrian Moreno <amorenoz@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
This commit is contained in:
Adrian Moreno 2022-07-08 20:03:12 +02:00 committed by Ilya Maximets
parent 6a71bc09bb
commit 445dceb884
9 changed files with 123 additions and 2 deletions

View File

@ -42,6 +42,9 @@ if [ "$M32" ]; then
sudo apt-get install -y $pkgs sudo apt-get install -y $pkgs
fi fi
# Install python test dependencies
pip install -r python/test_requirements.txt
# IPv6 is supported by kernel but disabled in TravisCI images: # IPv6 is supported by kernel but disabled in TravisCI images:
# https://github.com/travis-ci/travis-ci/issues/8891 # https://github.com/travis-ci/travis-ci/issues/8891
# Enable it to avoid skipping of IPv6 related tests. # Enable it to avoid skipping of IPv6 related tests.

View File

@ -181,6 +181,10 @@ following to obtain better warnings:
come from the "hacking" flake8 plugin. If it's not installed, the warnings come from the "hacking" flake8 plugin. If it's not installed, the warnings
just won't occur until it's run on a system with "hacking" installed. just won't occur until it's run on a system with "hacking" installed.
- the python packages listed in "python/test_requirements.txt" (compatible
with pip). If they are installed, the pytest-based Python unit tests will
be run.
You may find the ovs-dev script found in ``utilities/ovs-dev.py`` useful. You may find the ovs-dev script found in ``utilities/ovs-dev.py`` useful.
.. _general-install-reqs: .. _general-install-reqs:

View File

@ -53,6 +53,9 @@ ovs_pyfiles = \
python/ovs/vlog.py \ python/ovs/vlog.py \
python/ovs/winutils.py python/ovs/winutils.py
ovs_pytests = \
python/ovs/tests/test_kv.py
# These python files are used at build time but not runtime, # These python files are used at build time but not runtime,
# so they are not installed. # so they are not installed.
EXTRA_DIST += \ EXTRA_DIST += \
@ -65,12 +68,14 @@ EXTRA_DIST += \
EXTRA_DIST += \ EXTRA_DIST += \
python/ovs/compat/sortedcontainers/LICENSE \ python/ovs/compat/sortedcontainers/LICENSE \
python/README.rst \ python/README.rst \
python/setup.py python/setup.py \
python/test_requirements.txt
# C extension support. # C extension support.
EXTRA_DIST += python/ovs/_json.c EXTRA_DIST += python/ovs/_json.c
PYFILES = $(ovs_pyfiles) python/ovs/dirs.py $(ovstest_pyfiles) PYFILES = $(ovs_pyfiles) python/ovs/dirs.py $(ovstest_pyfiles) $(ovs_pytests)
EXTRA_DIST += $(PYFILES) EXTRA_DIST += $(PYFILES)
PYCOV_CLEAN_FILES += $(PYFILES:.py=.py,cover) PYCOV_CLEAN_FILES += $(PYFILES:.py=.py,cover)

View File

@ -0,0 +1,76 @@
import pytest
from ovs.flow.kv import KVParser, KeyValue
@pytest.mark.parametrize(
"input_data,expected",
[
(
(
"cookie=0x0, duration=147566.365s, table=0, n_packets=39, n_bytes=2574, idle_age=65534, hard_age=65534", # noqa: E501
None,
),
[
KeyValue("cookie", 0),
KeyValue("duration", "147566.365s"),
KeyValue("table", 0),
KeyValue("n_packets", 39),
KeyValue("n_bytes", 2574),
KeyValue("idle_age", 65534),
KeyValue("hard_age", 65534),
],
),
(
(
"load:0x4->NXM_NX_REG13[],load:0x9->NXM_NX_REG11[],load:0x8->NXM_NX_REG12[],load:0x1->OXM_OF_METADATA[],load:0x1->NXM_NX_REG14[],mod_dl_src:0a:58:a9:fe:00:02,resubmit(,8)", # noqa: E501
None,
),
[
KeyValue("load", "0x4->NXM_NX_REG13[]"),
KeyValue("load", "0x9->NXM_NX_REG11[]"),
KeyValue("load", "0x8->NXM_NX_REG12[]"),
KeyValue("load", "0x1->OXM_OF_METADATA[]"),
KeyValue("load", "0x1->NXM_NX_REG14[]"),
KeyValue("mod_dl_src", "0a:58:a9:fe:00:02"),
KeyValue("resubmit", ",8"),
],
),
(
("l1(l2(l3(l4())))", None),
[KeyValue("l1", "l2(l3(l4()))")]
),
(
("l1(l2(l3(l4()))),foo:bar", None),
[KeyValue("l1", "l2(l3(l4()))"), KeyValue("foo", "bar")],
),
(
("enqueue:1:2,output=2", None),
[KeyValue("enqueue", "1:2"), KeyValue("output", 2)],
),
(
("value_to_reg(100)->someReg[10],foo:bar", None),
[
KeyValue("value_to_reg", "(100)->someReg[10]"),
KeyValue("foo", "bar"),
],
),
],
)
def test_kv_parser(input_data, expected):
input_string = input_data[0]
decoders = input_data[1]
tparser = KVParser(input_string, decoders)
tparser.parse()
result = tparser.kv()
assert len(expected) == len(result)
for i in range(0, len(result)):
assert result[i].key == expected[i].key
assert result[i].value == expected[i].value
kpos = result[i].meta.kpos
kstr = result[i].meta.kstring
vpos = result[i].meta.vpos
vstr = result[i].meta.vstring
assert input_string[kpos : kpos + len(kstr)] == kstr
if vpos != -1:
assert input_string[vpos : vpos + len(vstr)] == vstr

View File

@ -0,0 +1,3 @@
pytest
netaddr
pyparsing

View File

@ -238,3 +238,23 @@ export ASAN_OPTIONS
# for the build. # for the build.
UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=true:log_path=ubsan:$UBSAN_OPTIONS UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=true:log_path=ubsan:$UBSAN_OPTIONS
export UBSAN_OPTIONS export UBSAN_OPTIONS
# Check whether Python test requirements are available.
REQUIREMENT_PATH=$abs_top_srcdir/python/test_requirements.txt $PYTHON3 -c '
import os
import pathlib
import pkg_resources
import sys
with pathlib.Path(os.path.join(os.getenv("REQUIREMENT_PATH"))).open() as reqs:
for req in pkg_resources.parse_requirements(reqs):
try:
pkg_resources.require(str(req))
except pkg_resources.DistributionNotFound:
sys.exit(2)
'
case $? in
0) HAVE_PYTEST=yes ;;
2) HAVE_PYTEST=no ;;
*) echo "$0: unexpected error probing Python unit test requirements" >&2 ;;
esac

View File

@ -100,6 +100,7 @@ TESTSUITE_AT = \
tests/ovsdb-rbac.at \ tests/ovsdb-rbac.at \
tests/ovs-vsctl.at \ tests/ovs-vsctl.at \
tests/ovs-xapi-sync.at \ tests/ovs-xapi-sync.at \
tests/pytest.at \
tests/stp.at \ tests/stp.at \
tests/rstp.at \ tests/rstp.at \
tests/interface-reconfigure.at \ tests/interface-reconfigure.at \

8
tests/pytest.at Normal file
View File

@ -0,0 +1,8 @@
AT_BANNER([Python unit tests])
# Run pytest unit tests.
AT_SETUP([Pytest unit tests - Python3])
AT_KEYWORDS([python])
AT_SKIP_IF([test "$HAVE_PYTEST" = "no"])
AT_CHECK([$PYTHON3 -m pytest $top_srcdir/python/ovs],[0], [ignore], [ignore])
AT_CLEANUP()

View File

@ -78,3 +78,4 @@ m4_include([tests/mcast-snooping.at])
m4_include([tests/packet-type-aware.at]) m4_include([tests/packet-type-aware.at])
m4_include([tests/nsh.at]) m4_include([tests/nsh.at])
m4_include([tests/drop-stats.at]) m4_include([tests/drop-stats.at])
m4_include([tests/pytest.at])