]> git.feebdaed.xyz Git - 0xmirror/openvpn.git/commitdiff
tests/unit_tests: Port to cmocka 2.0.0 API
authorFrank Lichtenheld <frank@lichtenheld.com>
Thu, 18 Dec 2025 10:40:32 +0000 (11:40 +0100)
committerGert Doering <gert@greenie.muc.de>
Thu, 18 Dec 2025 11:21:28 +0000 (12:21 +0100)
But add compat layer so that we can still build
against older versions of cmocka. Mostly this is
trivial but the custom check function changed its
prototype, so that requires some more work.

Change-Id: Ifb6594700db71d219643a29c581099c778bcbbc6
Signed-off-by: Frank Lichtenheld <frank@lichtenheld.com>
Acked-by: Gert Doering <gert@greenie.muc.de>
Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1449
Message-Id: <20251218104042.5961-1-gert@greenie.muc.de>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg35144.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
CMakeLists.txt
config.h.cmake.in
configure.ac
tests/unit_tests/openvpn/test_common.h
tests/unit_tests/openvpn/test_options_parse.c
tests/unit_tests/openvpn/test_push_update_msg.c
tests/unit_tests/openvpn/test_user_pass.c

index bdb19048e6653a13260a0ae138b67389c8d4aad1..bdad173173f5de61ae0d28218b8a6ca4b1bf96bb 100644 (file)
@@ -379,6 +379,18 @@ add_custom_command(
     )
 set(HAVE_CONFIG_VERSION_H YES)
 
+if (BUILD_TESTING)
+    find_package(cmocka CONFIG)
+    if (TARGET cmocka::cmocka)
+        set(CMOCKA_LIBRARIES cmocka::cmocka)
+    else ()
+        pkg_search_module(cmocka cmocka REQUIRED IMPORTED_TARGET)
+        set(CMOCKA_LIBRARIES PkgConfig::cmocka)
+    endif ()
+    set(CMAKE_REQUIRED_LIBRARIES ${CMOCKA_LIBRARIES})
+    check_include_files(cmocka_version.h HAVE_CMOCKA_VERSION_H)
+endif ()
+
 configure_file(config.h.cmake.in config.h)
 configure_file(include/openvpn-plugin.h.in openvpn-plugin.h)
 # TODO we should remove the need for this, and always include config.h
@@ -636,14 +648,6 @@ endif ()
 option(UT_ALLOW_BIG_ALLOC "Allow unit-tests to use > 1 GB of memory" ON)
 
 if (BUILD_TESTING)
-    find_package(cmocka CONFIG)
-    if (TARGET cmocka::cmocka)
-        set(CMOCKA_LIBRARIES cmocka::cmocka)
-    else ()
-        pkg_search_module(cmocka cmocka REQUIRED IMPORTED_TARGET)
-        set(CMOCKA_LIBRARIES PkgConfig::cmocka)
-    endif ()
-
     set(unit_tests
         "test_argv"
         "test_auth_token"
index 53c3598a39426918a2d04a1e8024abcddaa5577c..01bbadc63d7a832b41cf743d0c3674f3eb284d1d 100644 (file)
@@ -86,6 +86,9 @@
 /* git version information in config-version.h */
 #cmakedefine HAVE_CONFIG_VERSION_H
 
+/* cmocka version information available in cmocka_version.h (>= 2.0.0) */
+#cmakedefine HAVE_CMOCKA_VERSION_H
+
 /* Define to 1 if you have the `daemon' function. */
 #cmakedefine HAVE_DAEMON
 
index d5a0c707f014e727ee9440a5bac4b760cde4f169..f363e0f2f6f88468fd2c721a93e6fc2fb214e844 100644 (file)
@@ -1415,7 +1415,16 @@ PKG_CHECK_MODULES(
        [have_cmocka="yes"],
        [AC_MSG_WARN([cmocka.pc not found on the system using pkg-config ${pkg_config_found}.  Unit tests disabled])]
 )
-AM_CONDITIONAL([ENABLE_UNITTESTS], [test "${enable_unit_tests}" = "yes" -a "${have_cmocka}" = "yes" ])
+AM_CONDITIONAL([ENABLE_UNITTESTS], [false])
+if test "${enable_unit_tests}" = "yes" -a "${have_cmocka}" = "yes"; then
+   AM_CONDITIONAL([ENABLE_UNITTESTS], [true])
+
+   saved_CFLAGS="${CFLAGS}"
+   CFLAGS="${CFLAGS} ${CMOCKA_CFLAGS}"
+   # detect cmocka < 2.0.0 that had no cmocka_version.h
+   AC_CHECK_HEADERS([cmocka_version.h])
+   CFLAGS="${saved_CFLAGS}"
+fi
 AC_SUBST([ENABLE_UNITTESTS])
 
 TEST_LDFLAGS="${OPTIONAL_CRYPTO_LIBS} ${OPTIONAL_PKCS11_HELPER_LIBS} ${OPTIONAL_LIBCAPNG_LIBS}"
index da98531de6effd557a26bdaf0eb887e5f90cc476..3a0598db188ab2fd64aee1e0b77b49814472a480 100644 (file)
 #include <setjmp.h>
 #include <cmocka.h>
 
+/* Do we use cmocka < 2.0.0? */
+#ifndef HAVE_CMOCKA_VERSION_H
+#define HAVE_OLD_CMOCKA_API 1
+/* compat with various versions of cmocka.h
+ * Older versions have LargestIntegralType. Newer
+ * versions use uintmax_t. But LargestIntegralType
+ * is not guaranteed to be equal to uintmax_t, so
+ * we can't use that unconditionally. So we only use
+ * it if cmocka.h does not define LargestIntegralType.
+ */
+#ifndef LargestIntegralType
+#define LargestIntegralType uintmax_t
+#endif
+/* redefine 2.x API in terms of 1.x API */
+#define CMockaValueData             LargestIntegralType
+#define check_expected_uint         check_expected
+#define expect_uint_value           expect_value
+#define expect_check_data           expect_check
+#define cast_ptr_to_cmocka_value(x) (x)
+#endif
+
 /**
  * Sets up the environment for unit tests like making both stderr and stdout
  * non-buffered to avoid messages getting lost if the program exits early.
index adf3e5ba8b4cc8756e10ead4df273a4866ebeb7e..5af84f523685883981942b855fb3cd4f241abc82 100644 (file)
@@ -44,8 +44,8 @@ add_option(struct options *options, char *p[], bool is_inline, const char *file,
            struct env_set *es)
 {
     function_called();
-    check_expected(p);
-    check_expected(is_inline);
+    check_expected_ptr(p);
+    check_expected_uint(is_inline);
 }
 
 void
@@ -198,31 +198,27 @@ read_single_config(struct options *options, const char *config)
                        &option_types_found, &es);
 }
 
-/* compat with various versions of cmocka.h
- * Older versions have LargestIntegralType. Newer
- * versions use uintmax_t. But LargestIntegralType
- * is not guaranteed to be equal to uintmax_t, so
- * we can't use that unconditionally. So we only use
- * it if cmocka.h does not define LargestIntegralType.
- */
-#ifndef LargestIntegralType
-#define LargestIntegralType uintmax_t
-#endif
-
-union tokens_parameter
+#if HAVE_OLD_CMOCKA_API
+union token_parameter
 {
-    LargestIntegralType as_int;
-    void *as_pointer;
+    LargestIntegralType int_val;
+    void *ptr;
 };
+#endif
 
 static int
-check_tokens(const LargestIntegralType value, const LargestIntegralType expected)
+check_tokens(const CMockaValueData value, const CMockaValueData expected)
 {
-    union tokens_parameter temp;
-    temp.as_int = value;
-    const char **p = (const char **)temp.as_pointer;
-    temp.as_int = expected;
-    const char **expected_p = (const char **)temp.as_pointer;
+#if HAVE_OLD_CMOCKA_API
+    union token_parameter temp;
+    temp.int_val = value;
+    const char **p = (const char **)temp.ptr;
+    temp.int_val = expected;
+    const char **expected_p = (const char **)temp.ptr;
+#else
+    const char **p = (const char **)value.ptr;
+    const char **expected_p = (const char **)expected.ptr;
+#endif
     for (int i = 0; i < MAX_PARMS; i++)
     {
         if (!p[i] && !expected_p[i])
@@ -271,33 +267,33 @@ test_read_config(void **state)
 
     /* basic test */
     expect_function_call(add_option);
-    expect_check(add_option, p, check_tokens, p_expect_someopt);
-    expect_value(add_option, is_inline, 0);
+    expect_check_data(add_option, p, check_tokens, cast_ptr_to_cmocka_value(p_expect_someopt));
+    expect_uint_value(add_option, is_inline, 0);
     expect_function_call(add_option);
-    expect_check(add_option, p, check_tokens, p_expect_otheropt);
-    expect_value(add_option, is_inline, 0);
+    expect_check_data(add_option, p, check_tokens, cast_ptr_to_cmocka_value(p_expect_otheropt));
+    expect_uint_value(add_option, is_inline, 0);
     read_single_config(&o, "someopt parm1 parm2\n  otheropt 1 2");
 
     /* -- gets stripped */
     expect_function_call(add_option);
-    expect_check(add_option, p, check_tokens, p_expect_someopt);
-    expect_value(add_option, is_inline, 0);
+    expect_check_data(add_option, p, check_tokens, cast_ptr_to_cmocka_value(p_expect_someopt));
+    expect_uint_value(add_option, is_inline, 0);
     expect_function_call(add_option);
-    expect_check(add_option, p, check_tokens, p_expect_otheropt);
-    expect_value(add_option, is_inline, 0);
+    expect_check_data(add_option, p, check_tokens, cast_ptr_to_cmocka_value(p_expect_otheropt));
+    expect_uint_value(add_option, is_inline, 0);
     read_single_config(&o, "someopt parm1 parm2\n\t--otheropt 1 2");
 
     /* inline options */
     expect_function_call(add_option);
-    expect_check(add_option, p, check_tokens, p_expect_inlineopt);
-    expect_value(add_option, is_inline, 1);
+    expect_check_data(add_option, p, check_tokens, cast_ptr_to_cmocka_value(p_expect_inlineopt));
+    expect_uint_value(add_option, is_inline, 1);
     read_single_config(&o, "<inlineopt>\nsome text\nother text\n</inlineopt>");
 
     p_expect_inlineopt[0] = "inlineopt";
     p_expect_inlineopt[1] = A_TIMES_256 A_TIMES_256 A_TIMES_256 A_TIMES_256 A_TIMES_256 "\n";
     expect_function_call(add_option);
-    expect_check(add_option, p, check_tokens, p_expect_inlineopt);
-    expect_value(add_option, is_inline, 1);
+    expect_check_data(add_option, p, check_tokens, cast_ptr_to_cmocka_value(p_expect_inlineopt));
+    expect_uint_value(add_option, is_inline, 1);
     read_single_config(&o, "<inlineopt>\n" A_TIMES_256 A_TIMES_256 A_TIMES_256 A_TIMES_256 A_TIMES_256 "\n</inlineopt>");
 
     gc_free(&o.gc);
index 5c16001b6ef47334b140a2c2187a37e81ca03222..9b7978e51e217d9c87ca2984e5493cda0469b8dd 100644 (file)
@@ -171,7 +171,7 @@ send_control_channel_string(struct context *c, const char *str, msglvl_t msgleve
 bool
 send_control_channel_string(struct context *c, const char *str, msglvl_t msglevel)
 {
-    check_expected(str);
+    check_expected_ptr(str);
     return true;
 }
 
index abe223c94d41d76b553f69adadcfa68d8bd408f1..a109201a6f183c733b4578546038e1d88fcfd833 100644 (file)
@@ -52,7 +52,7 @@ query_user_exec_builtin(void)
     /* Loop through configured query_user slots */
     for (int i = 0; i < QUERY_USER_NUMSLOTS && query_user[i].response != NULL; i++)
     {
-        check_expected(query_user[i].prompt);
+        check_expected_ptr(query_user[i].prompt);
         strncpy(query_user[i].response, mock_ptr_type(char *), query_user[i].response_len);
     }