diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist index 7724138d3298..f473995400ae 100644 --- a/etc/mtree/BSD.tests.dist +++ b/etc/mtree/BSD.tests.dist @@ -1,1160 +1,1162 @@ # $FreeBSD$ # # Please see the file src/etc/mtree/README before making changes to this file. # /set type=dir uname=root gname=wheel mode=0755 tags=package=tests . bin cat .. chflags .. chmod .. cp .. date .. dd .. echo .. expr .. ln .. ls .. mkdir .. mv .. pax .. pkill .. pwait .. rm .. rmdir .. sh builtins .. errors .. execution .. expansion .. invocation .. parameters .. parser .. set-e .. .. sleep .. test .. .. cddl lib .. sbin .. usr.bin ctfconvert .. ztest .. .. usr.sbin dtrace common aggs .. arithmetic .. arrays .. assocs .. begin .. bitfields .. buffering .. builtinvar .. cg .. clauses .. cpc .. decls .. drops .. dtraceUtil .. end .. env .. enum .. error .. exit .. fbtprovider .. funcs .. grammar .. include .. inline .. io .. ip .. java_api .. json .. lexer .. llquantize .. mdb .. mib .. misc .. multiaggs .. offsetof .. operators .. pid .. plockstat .. pointers .. pragma .. predicates .. preprocessor .. print .. printa .. printf .. privs .. probes .. proc .. profile-n .. providers .. raise .. rates .. safety .. scalars .. sched .. scripting .. sdt .. sizeof .. speculation .. stability .. stack .. stackdepth .. stop .. strlen .. strtoll .. struct .. sugar .. syscall .. sysevent .. tick-n .. trace .. tracemem .. translators .. typedef .. types .. uctf .. union .. usdt .. ustack .. vars .. version .. .. i386 arrays .. funcs .. pid .. ustack .. .. amd64 arrays .. kinst .. .. .. zfsd .. .. .. etc rc.d .. .. + examples + .. games .. gnu lib .. usr.bin diff .. .. .. lib atf libatf-c detail .. .. libatf-c++ detail .. .. test-programs .. .. csu dynamic .. dynamiclib .. static .. .. googletest gmock .. gmock_main .. gtest .. gtest_main .. .. libarchive .. libbe .. libc c063 .. db .. gen execve .. posix_spawn .. .. hash data .. .. iconv .. inet .. locale .. net getaddrinfo data .. .. .. nss .. regex data .. .. resolv .. rpc .. ssp .. setjmp .. stdio .. stdlib .. string .. sys .. time .. tls dso .. .. termios .. ttyio .. .. libcam .. libcasper services cap_dns .. cap_grp .. cap_pwd .. cap_sysctl .. .. .. libcrypt .. libdevdctl .. libexecinfo .. libkvm .. libmp .. libnv .. libproc .. libregex data .. .. librt .. libsbuf .. libsysdecode .. libthr dlopen .. .. libutil .. libxo .. msun .. .. libexec atf atf-check .. atf-pytest-wrapper .. atf-sh .. .. rc .. rtld-elf .. tftpd .. .. sbin bectl .. dhclient .. devd .. growfs .. ifconfig .. md5 .. mdconfig .. newfs_msdos .. nvmecontrol .. pfctl files .. .. ping .. route .. .. secure lib .. libexec .. usr.bin .. usr.sbin .. .. share examples tests atf .. googletest .. plain .. tap .. .. .. zoneinfo .. .. sys acl .. aio .. audit .. auditpipe .. capsicum .. cddl zfs bin .. include .. tests acl cifs .. nontrivial .. trivial .. .. atime .. bootfs .. cache .. cachefile .. clean_mirror .. cli_root zfs_upgrade .. zfs_promote .. zfs_clone .. zfs_property .. zfs_destroy .. zpool_create .. zpool_history .. zpool_expand .. zpool_remove .. zfs_mount .. zfs_unshare .. zdb .. zpool_online .. zpool_get .. zpool_export .. zfs_copies .. zfs_get .. zfs .. zpool_clear .. zpool_import blockfiles .. .. zpool .. zpool_offline .. zpool_replace .. zfs_rollback .. zpool_set .. zfs_send .. zfs_set .. zpool_detach .. zfs_diff .. zpool_scrub .. zfs_inherit .. zfs_snapshot .. zfs_share .. zpool_destroy .. zpool_status .. zfs_unmount .. zfs_receive .. zfs_create .. zpool_upgrade blockfiles .. .. zpool_add .. zfs_rename .. zpool_attach .. zfs_reservation .. .. cli_user misc .. zfs_list .. zpool_iostat .. zpool_list .. .. compression .. ctime .. delegate .. devices .. exec .. grow_pool .. grow_replicas .. history .. hotplug .. hotspare .. inheritance .. interop .. inuse .. iscsi .. large_files .. largest_pool .. link_count .. migration .. mmap .. mount .. mv_files .. nestedfs .. no_space .. online_offline .. pool_names .. poolversion .. quota .. redundancy .. refquota .. refreserv .. rename_dirs .. replacement .. reservation .. rootpool .. rsend .. scrub_mirror .. slog .. snapshot .. snapused .. sparse .. threadsappend .. truncate .. txg_integrity .. userquota .. utils_test .. write_dirs .. xattr .. zfsd .. zil .. zinject .. zones .. zvol zvol_ENOSPC .. zvol_cli .. zvol_misc .. zvol_swap .. .. zvol_thrash .. .. .. .. devrandom .. dtrace .. fifo .. file .. fs fusefs .. tmpfs .. .. geom class concat .. eli .. gate .. gpt .. mirror .. multipath .. nop .. part .. raid3 .. shsec .. stripe .. uzip etalon .. .. .. .. kern acct .. execve .. pipe .. .. kqueue libkqueue .. .. mac bsdextended .. portacl .. .. mqueue .. net if_ovpn .. routing .. .. netgraph .. netinet .. netinet6 frag6 .. .. netipsec tunnel .. .. netlink .. netmap .. netpfil common .. pf ioctl .. .. .. opencrypto .. pjdfstest chflags .. chmod .. chown .. ftruncate .. granular .. link .. mkdir .. mkfifo .. mknod .. open .. rename .. rmdir .. symlink .. truncate .. unlink .. utimensat .. .. posixshm .. sys .. vfs .. vm .. vmm .. .. usr.bin apply .. awk bugs-fixed .. netbsd .. .. basename .. bintrans .. bmake archives fmt_44bsd .. fmt_44bsd_mod .. fmt_oldbsd .. .. basic t0 .. t1 .. t2 .. t3 .. .. execution ellipsis .. empty .. joberr .. plus .. .. shell builtin .. meta .. path .. path_select .. replace .. select .. .. suffixes basic .. src_wild1 .. src_wild2 .. .. syntax directive-t0 .. enl .. funny-targets .. semi .. .. sysmk t0 2 1 .. .. mk .. .. t1 2 1 .. .. mk .. .. t2 2 1 .. .. mk .. .. .. variables modifier_M .. modifier_t .. opt_V .. t0 .. .. .. bsdcat .. calendar .. cmp .. compress .. cpio .. col .. comm .. csplit .. cut .. dc .. diff .. diff3 .. dirname .. du .. file2c .. file .. find .. fold .. getconf .. gh-bc .. grep .. gzip .. head .. hexdump .. ident .. indent .. join .. jot .. lastcomm .. limits .. locale .. m4 .. mkimg .. mktemp .. ncal .. opensm .. patch .. pr .. printf .. procstat .. renice .. rs .. sdiff .. sed regress.multitest.out .. .. seq .. soelim .. sort .. split .. stat .. tail .. tar .. timeout .. tr .. truncate .. units .. unifdef .. uniq .. vmstat .. xargs .. xinstall .. xo .. yacc yacc .. .. .. usr.sbin chown .. daemon .. etcupdate .. extattr .. fstyp .. jail .. makefs .. mixer .. newsyslog .. nmtree .. praudit .. pw .. rpcbind .. sa .. .. .. # vim: set expandtab ts=4 sw=4: diff --git a/tests/Makefile b/tests/Makefile index b406b8dc6c17..47fc9488f772 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,23 +1,24 @@ # $FreeBSD$ PACKAGE= tests TESTSDIR= ${TESTSBASE} ${PACKAGE}FILES+= README __init__.py conftest.py KYUAFILE= yes SUBDIR+= etc +SUBDIR+= examples SUBDIR+= sys SUBDIR+= atf_python SUBDIR_PARALLEL= afterinstall: install-tests-local install-tests-local: .PHONY ${INSTALL_SYMLINK} -T 'package=tests' \ ../local/tests ${DESTDIR}${TESTSDIR}/local .include "Makefile.inc0" .include diff --git a/tests/examples/Makefile b/tests/examples/Makefile new file mode 100644 index 000000000000..7a5d84a98dfe --- /dev/null +++ b/tests/examples/Makefile @@ -0,0 +1,10 @@ +# $FreeBSD$ + +PACKAGE= tests + +TESTSDIR= ${TESTSBASE}/examples + +ATF_TESTS_PYTEST += test_examples.py + +.include + diff --git a/tests/examples/test_examples.py b/tests/examples/test_examples.py new file mode 100644 index 000000000000..13fdcc420f0e --- /dev/null +++ b/tests/examples/test_examples.py @@ -0,0 +1,198 @@ +import pytest +from atf_python.utils import BaseTest +from atf_python.sys.net.tools import ToolsHelper +from atf_python.sys.net.vnet import SingleVnetTestTemplate +from atf_python.sys.net.vnet import VnetTestTemplate +from atf_python.sys.net.vnet import VnetInstance + +import errno +import socket +import subprocess +import json + +from typing import List + + +# Test classes should be inherited +# from the BaseTest + + +class TestExampleSimplest(BaseTest): + @pytest.mark.skip(reason="comment me to run the test") + def test_one(self): + assert ToolsHelper.get_output("uname -s").strip() == "FreeBSD" + + +class TestExampleSimple(BaseTest): + # List of required kernel modules (kldstat -v) + # that needs to be present for the tests to run + REQUIRED_MODULES = ["null"] + + @pytest.mark.skip(reason="comment me to run the test") + def test_one(self): + """Optional test description + This and the following lines are not propagated + to the ATF test description. + """ + pass + + @pytest.mark.skip(reason="comment me to run the test") + # List of all requirements supported by an atf runner + # See atf-test-case(4) for the detailed description + @pytest.mark.require_user("root") + @pytest.mark.require_arch(["amd64", "i386"]) + @pytest.mark.require_files(["/path/file1", "/path/file2"]) + @pytest.mark.require_machine(["amd64", "i386"]) + @pytest.mark.require_memory("200M") + @pytest.mark.require_progs(["prog1", "prog2"]) + @pytest.mark.timeout(300) + def test_two(self): + pass + + @pytest.mark.skip(reason="comment me to run the test") + @pytest.mark.require_user("unprivileged") + def test_syscall_failure(self): + s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) + with pytest.raises(OSError) as exc_info: + s.bind(("::1", 42)) + assert exc_info.value.errno == errno.EACCES + + @pytest.mark.skip(reason="comment me to run the test") + @pytest.mark.parametrize( + "family_tuple", + [ + pytest.param([socket.AF_INET, None], id="AF_INET"), + pytest.param([socket.AF_INET6, None], id="AF_INET6"), + pytest.param([39, errno.EAFNOSUPPORT], id="FAMILY_39"), + ], + ) + def test_parametrize(self, family_tuple): + family, error = family_tuple + try: + s = socket.socket(family, socket.SOCK_STREAM) + s.close() + except OSError as e: + if error is None or error != e.errno: + raise + + # @pytest.mark.skip(reason="comment me to run the test") + def test_with_cleanup(self): + print("TEST BODY") + + def cleanup_test_with_cleanup(self, test_id): + print("CLEANUP HANDLER") + + +class TestVnetSimple(SingleVnetTestTemplate): + """ + SingleVnetTestTemplate creates a topology with a single + vnet and a single epair between this vnet and the host system. + Additionally, lo0 interface is created inside the vnet. + + Both vnets and interfaces are aliased as vnetX and ifY. + They can be accessed via maps: + vnet: VnetInstance = self.vnet_map["vnet1"] + iface: VnetInterface = vnet.iface_alias_map["if1"] + + All prefixes from IPV4_PREFIXES and IPV6_PREFIXES are + assigned to the single epair interface inside the jail. + + One can rely on the fact that there are no IPv6 prefixes + in the tentative state when the test method is called. + """ + + IPV6_PREFIXES: List[str] = ["2001:db8::1/64"] + IPV4_PREFIXES: List[str] = ["192.0.2.1/24"] + + def setup_method(self, method): + """ + Optional pre-setup for all of the tests inside the class + """ + # Code to run before vnet setup + # + super().setup_method(method) + # + # Code to run after vnet setup + # Executed inside the vnet + + @pytest.mark.skip(reason="comment me to run the test") + @pytest.mark.require_user("root") + def test_ping(self): + assert subprocess.run("ping -c1 192.0.2.1".split()).returncode == 0 + assert subprocess.run("ping -c1 2001:db8::1".split()).returncode == 0 + + @pytest.mark.skip(reason="comment me to run the test") + def test_topology(self): + vnet = self.vnet_map["vnet1"] + iface = vnet.iface_alias_map["if1"] + print("Iface {} inside vnet {}".format(iface.name, vnet.name)) + + +class TestVnetDual1(VnetTestTemplate): + """ + VnetTestTemplate creates topology described in the self.TOPOLOGY + + Each vnet (except vnet1) can have a handler function, named + vnetX_handler. This function will be run in a separate process + inside vnetX jail. The framework automatically creates a pipe + to allow communication between the main test and the vnet handler. + + This topology contains 2 VNETs connected with 2 epairs: + + [ VNET1 ] [ VNET2 ] + if1(epair) 2001:db8:a::1/64 <-> 2001:db8:a::2/64 if1(epair) + if2(epair) 2001:db8:b::1/64 <-> 2001:db8:b::2/64 if2(epair) + lo0 lo0 + + """ + + TOPOLOGY = { + "vnet1": {"ifaces": ["if1", "if2"]}, + "vnet2": {"ifaces": ["if1", "if2"]}, + "if1": {"prefixes6": [("2001:db8:a::1/64", "2001:db8:a::2/64")]}, + "if2": {"prefixes6": [("2001:db8:b::1/64", "2001:db8:b::2/64")]}, + } + + def _get_iface_stat(self, os_ifname: str): + out = ToolsHelper.get_output( + "{} -I {} --libxo json".format(ToolsHelper.NETSTAT_PATH, os_ifname) + ) + js = json.loads(out) + return js["statistics"]["interface"][0] + + def vnet2_handler(self, vnet: VnetInstance): + """ + Test handler that runs in the vnet2 as a separate process. + + This handler receives an interface name, fetches received/sent packets + and returns this data back to the parent process. + """ + while True: + # receives 'ifX' with an infinite timeout + iface_alias = self.wait_object(vnet.pipe, None) + # Translates topology interface name to the actual OS-assigned name + os_ifname = vnet.iface_alias_map[iface_alias].name + self.send_object(vnet.pipe, self._get_iface_stat(os_ifname)) + + @pytest.mark.skip(reason="comment me to run the test") + @pytest.mark.require_user("root") + def test_ifstat(self): + """Checks that RX interface packets are properly accounted for""" + second_vnet = self.vnet_map["vnet2"] + pipe = second_vnet.pipe + + # Ping neighbor IP on if1 and verify that the counter was incremented + self.send_object(pipe, "if1") + old_stat = self.wait_object(pipe) + assert subprocess.run("ping -c5 2001:db8:a::2".split()).returncode == 0 + self.send_object(pipe, "if1") + new_stat = self.wait_object(pipe) + assert new_stat["received-packets"] - old_stat["received-packets"] >= 5 + + # Ping neighbor IP on if2 and verify that the counter was incremented + self.send_object(pipe, "if2") + old_stat = self.wait_object(pipe) + assert subprocess.run("ping -c5 2001:db8:b::2".split()).returncode == 0 + self.send_object(pipe, "if2") + new_stat = self.wait_object(pipe) + assert new_stat["received-packets"] - old_stat["received-packets"] >= 5