Attention is currently required from: chugly, flichtenheld, plaisthos, razvanc.

Hello flichtenheld, plaisthos, razvanc,

I'd like you to reexamine a change. Please visit

    http://gerrit.openvpn.net/c/openvpn/+/1946?usp=email

to look at the new patch set (#4).

The following approvals got outdated and were removed:
Code-Review-1 by flichtenheld


Change subject: tests: add unit tests for route.c
......................................................................

tests: add unit tests for route.c

route.c has no unit test coverage at all, so there is nowhere to put a
test when touching it.  Cover the pure helpers it already exports: the
special address predicate, both netmask-to-netbits conversions, and the
IPv6 prefix host-bit masking.

The two conversions disagree on a full-length netmask, where
netmask_to_netbits() reports -1 and netmask_to_netbits2() reports 32.
That is deliberate, callers use the -1 to tell a host route from a
network route, so pin it down rather than leave it to be "fixed" later.

Rather than add a driver of its own, the tests are hosted by
networking_testdriver as case 9, in the way test_misc hosts
test_schedule.  That driver is already gated on HAVE_SITNL, which is
what route.c needs: it reaches the routing table through net_route_* on
Linux and through argv/execve elsewhere, so one set of stubs cannot
link on both.  t_net.sh runs the cases above LAST_AUTO_TEST after it has
removed its dummy interface, so the route tests need no interface and no
particular network state.

route.c links against the real networking_sitnl.c that the driver
already carries.  Only the socket and argv helpers that route.c
references but no test here reaches are stubbed, and those assert rather
than return quietly, so a test straying onto one fails loudly.

Change-Id: I9085c55a7efefd31839b00ec8ec9a6f085574dde
Signed-off-by: Charlie Vigue <[email protected]>
---
M CMakeLists.txt
M tests/t_net.sh
M tests/unit_tests/openvpn/Makefile.am
M tests/unit_tests/openvpn/test_networking.c
A tests/unit_tests/openvpn/test_route.c
A tests/unit_tests/openvpn/test_route.h
6 files changed, 223 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/46/1946/4

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6eb5954..6fd2940 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -961,7 +961,15 @@
     if (TARGET test_networking)
         target_link_options(test_networking PRIVATE -Wl,--wrap=parse_line)
         target_compile_options(test_networking PRIVATE -UNDEBUG)
+        target_link_libraries(test_networking PUBLIC ${RESOLV_LIBRARIES})
         target_sources(test_networking PRIVATE
+            tests/unit_tests/openvpn/test_route.c
+            tests/unit_tests/openvpn/mock_management.c
+            tests/unit_tests/openvpn/mock_win32_execve.c
+            src/openvpn/route.c
+            src/openvpn/env_set.c
+            src/openvpn/run_command.c
+            src/openvpn/socket_util.c
             src/openvpn/networking_sitnl.c
             src/openvpn/crypto_epoch.c
             src/openvpn/crypto_mbedtls.c
diff --git a/tests/t_net.sh b/tests/t_net.sh
index d63f648..fd07277 100755
--- a/tests/t_net.sh
+++ b/tests/t_net.sh
@@ -3,7 +3,7 @@
 IFACE="ovpn-dummy0"
 UNIT_TEST="./unit_tests/openvpn/networking_testdriver"
 LAST_AUTO_TEST=7
-LAST_TEST=8
+LAST_TEST=9

 srcdir="${srcdir:-.}"
 top_builddir="${top_builddir:-..}"
diff --git a/tests/unit_tests/openvpn/Makefile.am 
b/tests/unit_tests/openvpn/Makefile.am
index 5954902..a653311 100644
--- a/tests/unit_tests/openvpn/Makefile.am
+++ b/tests/unit_tests/openvpn/Makefile.am
@@ -212,7 +212,14 @@
 networking_testdriver_LDFLAGS = @TEST_LDFLAGS@ -L$(top_srcdir)/src/openvpn \
        $(OPTIONAL_CRYPTO_LIBS)
 networking_testdriver_SOURCES = test_networking.c mock_msg.c \
+       test_route.c test_route.h test_common.h \
+       mock_management.c \
        $(top_srcdir)/src/openvpn/networking_sitnl.c \
+       $(top_srcdir)/src/openvpn/route.c \
+       $(top_srcdir)/src/openvpn/env_set.c \
+       $(top_srcdir)/src/openvpn/run_command.c \
+       $(top_srcdir)/src/openvpn/socket_util.c \
+       $(top_srcdir)/src/openvpn/win32-util.c \
        $(top_srcdir)/src/openvpn/buffer.c \
        $(top_srcdir)/src/openvpn/crypto.c \
        $(top_srcdir)/src/openvpn/crypto_epoch.c \
diff --git a/tests/unit_tests/openvpn/test_networking.c 
b/tests/unit_tests/openvpn/test_networking.c
index 1c9cac1..849f247 100644
--- a/tests/unit_tests/openvpn/test_networking.c
+++ b/tests/unit_tests/openvpn/test_networking.c
@@ -2,6 +2,8 @@
 #include "syshead.h"
 #include "networking.h"

+#include "test_route.h"
+
 #include <setjmp.h>
 #include <cmocka.h>

@@ -212,7 +214,7 @@
 static void
 usage(char *name)
 {
-    printf("Usage: %s <0-8>\n", name);
+    printf("Usage: %s <0-9>\n", name);
 }

 int
@@ -272,6 +274,9 @@
             assert_int_equal(net__iface_type("dummy0815", NULL), -ENODEV);
             return 0;

+        case 9:
+            return route_tests();
+
         default:
             printf("invalid test: %d\n", test);
             break;
diff --git a/tests/unit_tests/openvpn/test_route.c 
b/tests/unit_tests/openvpn/test_route.c
new file mode 100644
index 0000000..476cfa9
--- /dev/null
+++ b/tests/unit_tests/openvpn/test_route.c
@@ -0,0 +1,174 @@
+/*
+ *  OpenVPN -- An application to securely tunnel IP networks
+ *             over a single UDP port, with support for SSL/TLS-based
+ *             session authentication and key exchange,
+ *             packet encryption, packet authentication, and
+ *             packet compression.
+ *
+ *  Copyright (C) 2002-2026 OpenVPN Inc <[email protected]>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "syshead.h"
+
+#include "test_common.h"
+
+#include "route.h"
+#include "networking.h"
+
+#include "test_route.h"
+
+/* Stubs for functions route.c references but that no test here reaches.
+ * They assert rather than return quietly, so a test straying onto one
+ * fails loudly instead of silently doing nothing.
+ */
+struct argv
+argv_new(void)
+{
+    assert_true(0);
+    struct argv a = { 0 };
+    return a;
+}
+
+void
+argv_free(struct argv *a)
+{
+    assert_true(0);
+}
+
+bool
+get_ipv6_addr(const char *prefix_str, struct in6_addr *network, unsigned int 
*netbits,
+              msglvl_t msglevel)
+{
+    assert_true(0);
+    return false;
+}
+
+in_addr_t
+getaddr(unsigned int flags, const char *hostname, int resolve_retry, bool 
*succeeded,
+        struct signal_info *sig_info)
+{
+    assert_true(0);
+    return 0;
+}
+
+struct signal_info siginfo_static; /* GLOBAL */
+
+int
+signal_reset(struct signal_info *si, int signum)
+{
+    assert_true(0);
+    return 0;
+}
+
+static void
+test_is_special_addr(void **state)
+{
+    assert_true(is_special_addr("net_gateway"));
+    assert_true(is_special_addr("vpn_gateway"));
+    assert_true(is_special_addr("remote_host"));
+
+    assert_false(is_special_addr("10.0.0.1"));
+    assert_false(is_special_addr("default"));
+    assert_false(is_special_addr(NULL));
+}
+
+static void
+test_netmask_to_netbits(void **state)
+{
+    int netbits;
+
+    assert_true(netmask_to_netbits(0x0a000000, 0xff000000, &netbits)); /* 10/8 
*/
+    assert_int_equal(netbits, 8);
+
+    assert_true(netmask_to_netbits(0xc0a80100, 0xffffff00, &netbits)); /* 
192.168.1/24 */
+    assert_int_equal(netbits, 24);
+
+    assert_true(netmask_to_netbits(0x00000000, 0x00000000, &netbits)); /* 
default route */
+    assert_int_equal(netbits, 0);
+
+    /* a full-length mask reports -1 rather than 32, which is what callers
+     * use to tell "host route" from "network route"
+     */
+    assert_true(netmask_to_netbits(0x0a010203, 0xffffffff, &netbits));
+    assert_int_equal(netbits, -1);
+
+    /* host bits set in the network part */
+    assert_false(netmask_to_netbits(0x0a000001, 0xff000000, &netbits));
+
+    /* not a contiguous netmask */
+    assert_false(netmask_to_netbits(0x0a000000, 0xff00ff00, &netbits));
+}
+
+static void
+test_netmask_to_netbits2(void **state)
+{
+    assert_int_equal(netmask_to_netbits2(0xff000000), 8);
+    assert_int_equal(netmask_to_netbits2(0xffffff00), 24);
+    assert_int_equal(netmask_to_netbits2(0x00000000), 0);
+
+    /* unlike netmask_to_netbits(), this one reports a full-length mask as 32 
*/
+    assert_int_equal(netmask_to_netbits2(0xffffffff), 32);
+
+    assert_int_equal(netmask_to_netbits2(0xff00ff00), -1);
+}
+
+static void
+assert_clear_host_bits(const char *addr, unsigned int netbits, const char 
*expected)
+{
+    struct route_ipv6 r6;
+    struct in6_addr want;
+
+    CLEAR(r6);
+    assert_int_equal(inet_pton(AF_INET6, addr, &r6.network), 1);
+    assert_int_equal(inet_pton(AF_INET6, expected, &want), 1);
+    r6.netbits = netbits;
+
+    route_ipv6_clear_host_bits(&r6);
+    assert_memory_equal(&r6.network, &want, sizeof(struct in6_addr));
+}
+
+static void
+test_route_ipv6_clear_host_bits(void **state)
+{
+    /* whole bytes cleared */
+    assert_clear_host_bits("2001:db8::1", 64, "2001:db8::");
+    assert_clear_host_bits("2001:db8:dead:beef::1", 32, "2001:db8::");
+
+    /* a prefix that does not fall on a byte boundary */
+    assert_clear_host_bits("2001:db8:0:00ff::1", 60, "2001:db8:0:00f0::");
+    assert_clear_host_bits("2001:db8::ffff", 121, "2001:db8::ff80");
+
+    /* nothing to clear, and everything to clear */
+    assert_clear_host_bits("2001:db8::1", 128, "2001:db8::1");
+    assert_clear_host_bits("2001:db8::1", 0, "::");
+}
+
+static const struct CMUnitTest route_test_list[] = {
+    cmocka_unit_test(test_is_special_addr),
+    cmocka_unit_test(test_netmask_to_netbits),
+    cmocka_unit_test(test_netmask_to_netbits2),
+    cmocka_unit_test(test_route_ipv6_clear_host_bits),
+};
+
+int
+route_tests(void)
+{
+    openvpn_unit_test_setup();
+    return cmocka_run_group_tests(route_test_list, NULL, NULL);
+}
diff --git a/tests/unit_tests/openvpn/test_route.h 
b/tests/unit_tests/openvpn/test_route.h
new file mode 100644
index 0000000..caa5c3c
--- /dev/null
+++ b/tests/unit_tests/openvpn/test_route.h
@@ -0,0 +1,27 @@
+/*
+ *  OpenVPN -- An application to securely tunnel IP networks
+ *             over a single UDP port, with support for SSL/TLS-based
+ *             session authentication and key exchange,
+ *             packet encryption, packet authentication, and
+ *             packet compression.
+ *
+ *  Copyright (C) 2002-2026 OpenVPN Inc <[email protected]>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <https://www.gnu.org/licenses/>.
+ */
+#ifndef TEST_ROUTE_H
+#define TEST_ROUTE_H
+/** Runs the route.c unit tests, returns the number of failures */
+int
+route_tests(void);
+#endif

--
To view, visit http://gerrit.openvpn.net/c/openvpn/+/1946?usp=email
To unsubscribe, or for help writing mail filters, visit 
http://gerrit.openvpn.net/settings?usp=email

Gerrit-MessageType: newpatchset
Gerrit-Project: openvpn
Gerrit-Branch: master
Gerrit-Change-Id: I9085c55a7efefd31839b00ec8ec9a6f085574dde
Gerrit-Change-Number: 1946
Gerrit-PatchSet: 4
Gerrit-Owner: chugly <[email protected]>
Gerrit-Reviewer: flichtenheld <[email protected]>
Gerrit-Reviewer: plaisthos <[email protected]>
Gerrit-Reviewer: razvanc <[email protected]>
Gerrit-CC: openvpn-devel <[email protected]>
Gerrit-Attention: chugly <[email protected]>
Gerrit-Attention: razvanc <[email protected]>
Gerrit-Attention: plaisthos <[email protected]>
Gerrit-Attention: flichtenheld <[email protected]>
_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

Reply via email to