From patchwork Fri Jul 8 18:03:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Adri=C3=A1n_Moreno?= X-Patchwork-Id: 1654339 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=DWwXtYCT; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4Lfh4F3LCdz9ryY for ; Sat, 9 Jul 2022 04:04:13 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 421B342725; Fri, 8 Jul 2022 18:04:11 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 421B342725 Authentication-Results: smtp4.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=DWwXtYCT X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id uBRlWJ9gUZ6R; Fri, 8 Jul 2022 18:04:09 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp4.osuosl.org (Postfix) with ESMTPS id 904AF426C9; Fri, 8 Jul 2022 18:03:57 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 904AF426C9 Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 9F8EEC0086; Fri, 8 Jul 2022 18:03:50 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 1A556C0095 for ; Fri, 8 Jul 2022 18:03:48 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 7D19741655 for ; Fri, 8 Jul 2022 18:03:44 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 7D19741655 Authentication-Results: smtp2.osuosl.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=DWwXtYCT X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id eiMAWnU8zYiS for ; Fri, 8 Jul 2022 18:03:43 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org C858141665 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by smtp2.osuosl.org (Postfix) with ESMTPS id C858141665 for ; Fri, 8 Jul 2022 18:03:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1657303421; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=v5c4Hq427uksW07EJF0A5mYQ1Y52vaAHThOmG0+X9iU=; b=DWwXtYCT613zM5p2n/4Dw5PBu7fSHDK1mjWdz+ANDUG6QPDHayKCs5pxjPL1s70+rjOWJy mihDEK7V3cybRFxgMJo8pP/golN5hQuruzOe+iVO/+HwKxHxReu/3CcHieGr6gywptX6gd 8X92viYMlRTh5UFerwR+rqwF7370yc0= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-531-STUqFu3UOgaGMWIHdQeqXg-1; Fri, 08 Jul 2022 14:03:40 -0400 X-MC-Unique: STUqFu3UOgaGMWIHdQeqXg-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 360F484818B; Fri, 8 Jul 2022 18:03:40 +0000 (UTC) Received: from amorenoz.users.ipa.redhat.com (unknown [10.39.192.174]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0B15A2024CB9; Fri, 8 Jul 2022 18:03:38 +0000 (UTC) From: Adrian Moreno To: dev@openvswitch.org Date: Fri, 8 Jul 2022 20:03:12 +0200 Message-Id: <20220708180316.2852046-14-amorenoz@redhat.com> In-Reply-To: <20220708180316.2852046-1-amorenoz@redhat.com> References: <20220708180316.2852046-1-amorenoz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=amorenoz@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Cc: i.maximets@ovn.org Subject: [ovs-dev] [PATCH v5 13/17] python: introduce unit tests X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Use pytest to run unit tests as part of the standard testsuite. Acked-by: Eelco Chaudron Signed-off-by: Adrian Moreno --- .ci/linux-prepare.sh | 3 + Documentation/intro/install/general.rst | 4 ++ python/automake.mk | 9 ++- python/ovs/tests/test_kv.py | 76 +++++++++++++++++++++++++ python/test_requirements.txt | 3 + tests/atlocal.in | 20 +++++++ tests/automake.mk | 1 + tests/pytest.at | 8 +++ tests/testsuite.at | 1 + 9 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 python/ovs/tests/test_kv.py create mode 100644 python/test_requirements.txt create mode 100644 tests/pytest.at diff --git a/.ci/linux-prepare.sh b/.ci/linux-prepare.sh index a0635cf56..de741c6b4 100755 --- a/.ci/linux-prepare.sh +++ b/.ci/linux-prepare.sh @@ -45,6 +45,9 @@ if [ "$M32" ]; then sudo apt-get install -y $pkgs fi +# Install python test dependencies +pip install -r python/test_requirements.txt + # IPv6 is supported by kernel but disabled in TravisCI images: # https://github.com/travis-ci/travis-ci/issues/8891 # Enable it to avoid skipping of IPv6 related tests. diff --git a/Documentation/intro/install/general.rst b/Documentation/intro/install/general.rst index a297aadac..e2c15a620 100644 --- a/Documentation/intro/install/general.rst +++ b/Documentation/intro/install/general.rst @@ -181,6 +181,10 @@ following to obtain better 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. +- 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. .. _general-install-reqs: diff --git a/python/automake.mk b/python/automake.mk index aa3adb703..3a9246fe2 100644 --- a/python/automake.mk +++ b/python/automake.mk @@ -52,6 +52,9 @@ ovs_pyfiles = \ python/ovs/vlog.py \ python/ovs/winutils.py +ovs_pytests = \ + python/ovs/tests/test_kv.py + # These python files are used at build time but not runtime, # so they are not installed. EXTRA_DIST += \ @@ -64,12 +67,14 @@ EXTRA_DIST += \ EXTRA_DIST += \ python/ovs/compat/sortedcontainers/LICENSE \ python/README.rst \ - python/setup.py + python/setup.py \ + python/test_requirements.txt # C extension support. 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) PYCOV_CLEAN_FILES += $(PYFILES:.py=.py,cover) diff --git a/python/ovs/tests/test_kv.py b/python/ovs/tests/test_kv.py new file mode 100644 index 000000000..c5b66de88 --- /dev/null +++ b/python/ovs/tests/test_kv.py @@ -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 diff --git a/python/test_requirements.txt b/python/test_requirements.txt new file mode 100644 index 000000000..6aaee13e3 --- /dev/null +++ b/python/test_requirements.txt @@ -0,0 +1,3 @@ +pytest +netaddr +pyparsing diff --git a/tests/atlocal.in b/tests/atlocal.in index 142ea2090..e02248f6f 100644 --- a/tests/atlocal.in +++ b/tests/atlocal.in @@ -238,3 +238,23 @@ export ASAN_OPTIONS # for the build. UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=true:log_path=ubsan:$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 diff --git a/tests/automake.mk b/tests/automake.mk index 49b639c3c..fee3d2328 100644 --- a/tests/automake.mk +++ b/tests/automake.mk @@ -102,6 +102,7 @@ TESTSUITE_AT = \ tests/ovsdb-rbac.at \ tests/ovs-vsctl.at \ tests/ovs-xapi-sync.at \ + tests/pytest.at \ tests/stp.at \ tests/rstp.at \ tests/interface-reconfigure.at \ diff --git a/tests/pytest.at b/tests/pytest.at new file mode 100644 index 000000000..0e75da4c4 --- /dev/null +++ b/tests/pytest.at @@ -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() diff --git a/tests/testsuite.at b/tests/testsuite.at index 58adfa09c..14a28b517 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -78,3 +78,4 @@ m4_include([tests/mcast-snooping.at]) m4_include([tests/packet-type-aware.at]) m4_include([tests/nsh.at]) m4_include([tests/drop-stats.at]) +m4_include([tests/pytest.at])