git: 65f065ec7131 - stable/13 - netlink: connect netlink tests to the build

From: Alexander V. Chernikov <melifaro_at_FreeBSD.org>
Date: Mon, 23 Jan 2023 22:12:08 UTC
The branch stable/13 has been updated by melifaro:

URL: https://cgit.FreeBSD.org/src/commit/?id=65f065ec7131db4028ed37d951d94d905298bc31

commit 65f065ec7131db4028ed37d951d94d905298bc31
Author:     Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2022-12-16 12:02:17 +0000
Commit:     Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2023-01-23 22:04:03 +0000

    netlink: connect netlink tests to the build
    
    Reviewed By: ngie
    Differential Revision: https://reviews.freebsd.org/D37708
    
    (cherry picked from commit 3873bdc2f28f6aab6b426ccb6c85ab2a41483264)
---
 tests/atf_python/Makefile            |  2 +-
 tests/atf_python/sys/net/tools.py    |  7 ------
 tests/atf_python/sys/net/vnet.py     | 20 ++++++----------
 tests/atf_python/utils.py            | 46 ++++++++++++++++++++++++++++++++++++
 tests/sys/Makefile                   |  1 +
 tests/sys/netlink/test_rtnl_iface.py |  2 ++
 6 files changed, 57 insertions(+), 21 deletions(-)

diff --git a/tests/atf_python/Makefile b/tests/atf_python/Makefile
index 26d419743257..1a2fec387eda 100644
--- a/tests/atf_python/Makefile
+++ b/tests/atf_python/Makefile
@@ -2,7 +2,7 @@
 
 .PATH:	${.CURDIR}
 
-FILES=	__init__.py atf_pytest.py
+FILES=	__init__.py atf_pytest.py utils.py
 SUBDIR=	sys
 
 .include <bsd.own.mk>
diff --git a/tests/atf_python/sys/net/tools.py b/tests/atf_python/sys/net/tools.py
index 23bb5f4b4128..567d9d4b21ac 100644
--- a/tests/atf_python/sys/net/tools.py
+++ b/tests/atf_python/sys/net/tools.py
@@ -1,13 +1,6 @@
 #!/usr/local/bin/python3
 import json
 import os
-import socket
-import time
-from ctypes import cdll
-from ctypes import get_errno
-from ctypes.util import find_library
-from typing import List
-from typing import Optional
 
 
 class ToolsHelper(object):
diff --git a/tests/atf_python/sys/net/vnet.py b/tests/atf_python/sys/net/vnet.py
index 0d9f969b28d9..faae58e95b6f 100644
--- a/tests/atf_python/sys/net/vnet.py
+++ b/tests/atf_python/sys/net/vnet.py
@@ -5,17 +5,14 @@ import os
 import socket
 import sys
 import time
-from ctypes import cdll
-from ctypes import get_errno
-from ctypes.util import find_library
 from multiprocessing import Pipe
 from multiprocessing import Process
 from typing import Dict
 from typing import List
 from typing import NamedTuple
-from typing import Optional
 
 from atf_python.sys.net.tools import ToolsHelper
+from atf_python.utils import libc, BaseTest
 
 
 def run_cmd(cmd: str, verbose=True) -> str:
@@ -145,7 +142,7 @@ class IfaceFactory(object):
 
     def __init__(self, test_name: str):
         self.test_name = test_name
-        test_id = convert_test_name(test_name)
+        self.test_id = convert_test_name(test_name)
         self.file_name = self.INTERFACES_FNAME
 
     def _register_iface(self, iface_name: str):
@@ -204,13 +201,9 @@ class VnetInstance(object):
 
     @staticmethod
     def attach_jid(jid: int):
-        _path: Optional[str] = find_library("c")
-        if _path is None:
-            raise Exception("libc not found")
-        path: str = _path
-        libc = cdll.LoadLibrary(path)
-        if libc.jail_attach(jid) != 0:
-            raise Exception("jail_attach() failed: errno {}".format(get_errno()))
+        error_code = libc.jail_attach(jid)
+        if error_code != 0:
+            raise Exception("jail_attach() failed: errno {}".format(error_code))
 
     def attach(self):
         self.attach_jid(self.jid)
@@ -290,7 +283,7 @@ class SingleInterfaceMap(NamedTuple):
     vnet_aliases: List[str]
 
 
-class VnetTestTemplate(object):
+class VnetTestTemplate(BaseTest):
     TOPOLOGY = {}
 
     def _get_vnet_handler(self, vnet_alias: str):
@@ -395,6 +388,7 @@ class VnetTestTemplate(object):
         # 'test_ip6_output.py::TestIP6Output::test_output6_pktinfo[ipandif] (setup)'
         test_id = os.environ.get("PYTEST_CURRENT_TEST").split(" ")[0]
         test_name = test_id.split("::")[-1]
+        self.check_constraints()
         topology = self.TOPOLOGY
         # First, setup kernel objects - interfaces & vnets
         obj_map = self.setup_topology(topology, test_name)
diff --git a/tests/atf_python/utils.py b/tests/atf_python/utils.py
new file mode 100644
index 000000000000..12cd56c10149
--- /dev/null
+++ b/tests/atf_python/utils.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python3
+import os
+from ctypes import CDLL
+from ctypes import get_errno
+from ctypes.util import find_library
+from typing import List
+from typing import Optional
+
+import pytest
+
+
+class LibCWrapper(object):
+    def __init__(self):
+        path: Optional[str] = find_library("c")
+        if path is None:
+            raise RuntimeError("libc not found")
+        self._libc = CDLL(path, use_errno=True)
+
+    def modfind(self, mod_name: str) -> int:
+        if self._libc.modfind(bytes(mod_name, encoding="ascii")) == -1:
+            return get_errno()
+        return 0
+
+    def jail_attach(self, jid: int) -> int:
+        if self._libc.jail_attach(jid) != 0:
+            return get_errno()
+        return 0
+
+
+libc = LibCWrapper()
+
+
+class BaseTest(object):
+    REQUIRED_MODULES: List[str] = []
+
+    def _check_modules(self):
+        for mod_name in self.REQUIRED_MODULES:
+            error_code = libc.modfind(mod_name)
+            if error_code != 0:
+                err_str = os.strerror(error_code)
+                pytest.skip(
+                    "kernel module '{}' not available: {}".format(mod_name, err_str)
+                )
+
+    def check_constraints(self):
+        self._check_modules()
diff --git a/tests/sys/Makefile b/tests/sys/Makefile
index 2ba60f41b76c..14d96e053b64 100644
--- a/tests/sys/Makefile
+++ b/tests/sys/Makefile
@@ -24,6 +24,7 @@ TESTS_SUBDIRS+=		${_netgraph}
 TESTS_SUBDIRS+=		netinet
 TESTS_SUBDIRS+=		netinet6
 TESTS_SUBDIRS+=		netipsec
+TESTS_SUBDIRS+=		netlink
 TESTS_SUBDIRS+=		netmap
 TESTS_SUBDIRS+=		netpfil
 TESTS_SUBDIRS+=		opencrypto
diff --git a/tests/sys/netlink/test_rtnl_iface.py b/tests/sys/netlink/test_rtnl_iface.py
index 38a3075f09c9..3340eaa4d16d 100644
--- a/tests/sys/netlink/test_rtnl_iface.py
+++ b/tests/sys/netlink/test_rtnl_iface.py
@@ -22,6 +22,8 @@ from atf_python.sys.net.vnet import SingleVnetTestTemplate
 
 
 class TestRtNlIface(SingleVnetTestTemplate):
+    REQUIRED_MODULES = ["netlink"]
+
     def setup_method(self, method):
         super().setup_method(method)
         self.helper = NlHelper()