Tests ===== Test harness ------------ The test harness is a set of convenience functions used to ease testing of ``bpfilter``. Test ~~~~ .. doxygenfile:: test.h Symbols ~~~~~~~ .. doxygenfile:: sym.h Mocks ~~~~~ .. doxygenfile:: mock.h Process ~~~~~~~ .. doxygenfile:: process.h Daemon ~~~~~~~ .. doxygenfile:: daemon.h Filters ~~~~~~~ .. doxygenfile:: filters.h Program ~~~~~~~ .. doxygenfile:: prog.h Unit tests ---------- .. warning:: In progress. End-to-end tests ---------------- .. note:: The end-to-end test suite is not yet part of the main test suite and won't be build or run by default. To start the end-to-end tests manually, you need to install the Python Scapy module and run ``make e2e``. End-to-end tests are designed to validate the bytecode generated by ``bpfilter`` through the following workflow: - Start the ``bpfilter`` daemon. - Send a chain to the daemon to be translated into a BPF program. - Use ``BPF_PROG_TEST_RUN`` with a dummy packet and validate the program's return code. Run end-to-end tests with ``make e2e``. ``root`` privileges are required to start the daemon and call ``bpf(BPF_PROG_TEST_RUN)``. The test packets are generated using a Python script and Scapy: the scripts creates ``packets.h`` which is included in the end-to-end tests sources. See ``tests/e2e/genpkts.py``. **Adding a new end-to-end test** End-to-end tests are defined in ``tests/e2e`` and use ``cmocka`` as the testing library. To add a new end-to-end test: 1. Add a new ``cmocka`` test in a source file under ``tests/e2e``. 2. Create a chain: use the primitives in :ref:`Filters` to easily create chains, rules, and matchers. :c:struct:`bf_test_chain_get` will automatically disable attachment of the chain and generate a custom name for the BPF program prefixed with ``bf_e2e_``. 3. Get a file descriptor to the generated BPF program with :c:func:`bf_test_prog_get`: the chain will be sent to the daemon, and a dynamically allocated :c:struct:`bf_test_prog` will be returned. This program will be used to run the tests. 4. Send a dummy packet to your program and validate the return value with :c:func:`bf_test_prog_run`. **Example** The example below will create an empty chain with a default ``ACCEPT`` policy. We expect the generated XDP program to return ``XDP_PASS`` (which is ``2``). .. code-block:: c Test(xdp, default_policy) { _cleanup_bf_chain_ struct bf_chain *chain = bf_test_chain_get( BF_HOOK_XDP, BF_VERDICT_ACCEPT, NULL, (struct bf_rule *[]) { NULL, } ); _free_bf_test_prog_ struct bf_test_prog *prog = bf_test_prog_get(chain); assert_non_null(prog); assert_success(bf_test_prog_run(prog, 2, pkt_local_ip6_tcp)); } Benchmarking ------------ .. warning:: In progress.