mirror of
https://github.com/OpenVPN/openvpn.git
synced 2026-06-08 16:35:26 -04:00
test_options_parse: Start new UT for options_parse.c
For now contains one test case for parse_line. Change-Id: I95032d2539d994abf69fc17319ed1a429c3bb948 Signed-off-by: Frank Lichtenheld <frank@lichtenheld.com> Acked-by: Gert Doering <gert@greenie.muc.de> Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1244 Message-Id: <20251008101014.5691-1-gert@greenie.muc.de> URL: https://sourceforge.net/p/openvpn/mailman/message/59243816/ Signed-off-by: Gert Doering <gert@greenie.muc.de>
This commit is contained in:
parent
e0b5ea5db9
commit
80981cf338
3 changed files with 227 additions and 0 deletions
|
|
@ -685,6 +685,7 @@ if (BUILD_TESTING)
|
|||
# Clang-cl (which is also MSVC) is wrongly detected to support wrap
|
||||
if (NOT MSVC AND "${LD_SUPPORTS_WRAP}")
|
||||
list(APPEND unit_tests
|
||||
"test_options_parse"
|
||||
"test_tls_crypt"
|
||||
)
|
||||
endif ()
|
||||
|
|
@ -826,6 +827,20 @@ if (BUILD_TESTING)
|
|||
src/compat/compat-strsep.c
|
||||
)
|
||||
|
||||
if (TARGET test_options_parse)
|
||||
target_link_options(test_options_parse PRIVATE
|
||||
-Wl,--wrap=add_option
|
||||
-Wl,--wrap=remove_option
|
||||
-Wl,--wrap=update_option
|
||||
-Wl,--wrap=usage
|
||||
)
|
||||
target_sources(test_options_parse PRIVATE
|
||||
tests/unit_tests/openvpn/mock_get_random.c
|
||||
src/openvpn/options_parse.c
|
||||
src/openvpn/options_util.c
|
||||
)
|
||||
endif ()
|
||||
|
||||
target_sources(test_packet_id PRIVATE
|
||||
tests/unit_tests/openvpn/mock_get_random.c
|
||||
src/openvpn/otime.c
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ test_binaries = argv_testdriver buffer_testdriver crypto_testdriver packet_id_te
|
|||
user_pass_testdriver push_update_msg_testdriver provider_testdriver socket_testdriver
|
||||
|
||||
if HAVE_LD_WRAP_SUPPORT
|
||||
test_binaries += options_parse_testdriver
|
||||
if !WIN32
|
||||
test_binaries += tls_crypt_testdriver
|
||||
endif
|
||||
|
|
@ -190,6 +191,21 @@ networking_testdriver_SOURCES = test_networking.c mock_msg.c \
|
|||
$(top_srcdir)/src/openvpn/platform.c
|
||||
endif
|
||||
|
||||
options_parse_testdriver_CFLAGS = -I$(top_srcdir)/src/openvpn -I$(top_srcdir)/src/compat @TEST_CFLAGS@
|
||||
options_parse_testdriver_LDFLAGS = @TEST_LDFLAGS@ -L$(top_srcdir)/src/openvpn \
|
||||
-Wl,--wrap=add_option \
|
||||
-Wl,--wrap=update_option \
|
||||
-Wl,--wrap=remove_option \
|
||||
-Wl,--wrap=usage
|
||||
options_parse_testdriver_SOURCES = test_options_parse.c \
|
||||
mock_msg.c mock_msg.h test_common.h \
|
||||
mock_get_random.c \
|
||||
$(top_srcdir)/src/openvpn/options_parse.c \
|
||||
$(top_srcdir)/src/openvpn/options_util.c \
|
||||
$(top_srcdir)/src/openvpn/buffer.c \
|
||||
$(top_srcdir)/src/openvpn/win32-util.c \
|
||||
$(top_srcdir)/src/openvpn/platform.c
|
||||
|
||||
provider_testdriver_CFLAGS = \
|
||||
-I$(top_srcdir)/include -I$(top_srcdir)/src/compat -I$(top_srcdir)/src/openvpn \
|
||||
@TEST_CFLAGS@ $(OPTIONAL_CRYPTO_CFLAGS)
|
||||
|
|
|
|||
196
tests/unit_tests/openvpn/test_options_parse.c
Normal file
196
tests/unit_tests/openvpn/test_options_parse.c
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
* 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) 2025 OpenVPN Inc <sales@openvpn.net>
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <setjmp.h>
|
||||
#include <cmocka.h>
|
||||
|
||||
#include "options.h"
|
||||
#include "test_common.h"
|
||||
#include "mock_msg.h"
|
||||
|
||||
void
|
||||
__wrap_add_option(struct options *options, char *p[], bool is_inline, const char *file,
|
||||
int line, const int level, const msglvl_t msglevel,
|
||||
const unsigned int permission_mask, unsigned int *option_types_found,
|
||||
struct env_set *es)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
__wrap_remove_option(struct context *c, struct options *options, char *p[], bool is_inline,
|
||||
const char *file, int line, const msglvl_t msglevel,
|
||||
const unsigned int permission_mask, unsigned int *option_types_found,
|
||||
struct env_set *es)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
__wrap_update_option(struct context *c, struct options *options, char *p[], bool is_inline,
|
||||
const char *file, int line, const int level, const msglvl_t msglevel,
|
||||
const unsigned int permission_mask, unsigned int *option_types_found,
|
||||
struct env_set *es, unsigned int *update_options_found)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
__wrap_usage(void)
|
||||
{
|
||||
}
|
||||
|
||||
/* for building long texts */
|
||||
#define A_TIMES_256 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO"
|
||||
|
||||
static void
|
||||
test_parse_line(void **state)
|
||||
{
|
||||
char *p[MAX_PARMS + 1] = { 0 };
|
||||
struct gc_arena gc = gc_new();
|
||||
int res = 0;
|
||||
|
||||
#define PARSE_LINE_TST(string) \
|
||||
do \
|
||||
{ \
|
||||
CLEAR(p); \
|
||||
res = parse_line(string, p, SIZE(p) - 1, "test_options_parse", 1, M_INFO, &gc); \
|
||||
} while (0);
|
||||
|
||||
/* basic example */
|
||||
PARSE_LINE_TST("some-opt firstparm second-parm");
|
||||
assert_int_equal(res, 3);
|
||||
assert_string_equal(p[0], "some-opt");
|
||||
assert_string_equal(p[1], "firstparm");
|
||||
assert_string_equal(p[2], "second-parm");
|
||||
assert_null(p[res]);
|
||||
|
||||
/* basic quoting, -- is not handled special */
|
||||
PARSE_LINE_TST("--some-opt 'first parm' \"second' 'parm\"");
|
||||
assert_int_equal(res, 3);
|
||||
assert_string_equal(p[0], "--some-opt");
|
||||
assert_string_equal(p[1], "first parm");
|
||||
assert_string_equal(p[2], "second' 'parm");
|
||||
assert_null(p[res]);
|
||||
|
||||
/* escaped quotes */
|
||||
PARSE_LINE_TST("\"some opt\" 'first\" \"parm' \"second\\\" \\\"parm\"");
|
||||
assert_int_equal(res, 3);
|
||||
assert_string_equal(p[0], "some opt");
|
||||
assert_string_equal(p[1], "first\" \"parm");
|
||||
assert_string_equal(p[2], "second\" \"parm");
|
||||
assert_null(p[res]);
|
||||
|
||||
/* missing closing quote */
|
||||
PARSE_LINE_TST("--some-opt 'first parm \"second parm\"");
|
||||
assert_int_equal(res, 0);
|
||||
|
||||
/* escaped backslash */
|
||||
PARSE_LINE_TST("some\\\\opt C:\\\\directory\\\\file");
|
||||
assert_int_equal(res, 2);
|
||||
assert_string_equal(p[0], "some\\opt");
|
||||
assert_string_equal(p[1], "C:\\directory\\file");
|
||||
assert_null(p[res]);
|
||||
|
||||
/* comment chars are not special inside parameter */
|
||||
PARSE_LINE_TST("some-opt firstparm; second#parm");
|
||||
assert_int_equal(res, 3);
|
||||
assert_string_equal(p[0], "some-opt");
|
||||
assert_string_equal(p[1], "firstparm;");
|
||||
assert_string_equal(p[2], "second#parm");
|
||||
assert_null(p[res]);
|
||||
|
||||
/* comment */
|
||||
PARSE_LINE_TST("some-opt firstparm # secondparm");
|
||||
assert_int_equal(res, 2);
|
||||
assert_string_equal(p[0], "some-opt");
|
||||
assert_string_equal(p[1], "firstparm");
|
||||
assert_null(p[res]);
|
||||
|
||||
/* parameter just long enough */
|
||||
PARSE_LINE_TST("opt " A_TIMES_256);
|
||||
assert_int_equal(res, 2);
|
||||
assert_string_equal(p[0], "opt");
|
||||
assert_string_equal(p[1], A_TIMES_256);
|
||||
assert_null(p[res]);
|
||||
|
||||
/* quoting doesn't count for parameter length */
|
||||
PARSE_LINE_TST("opt \"" A_TIMES_256 "\"");
|
||||
assert_int_equal(res, 2);
|
||||
assert_string_equal(p[0], "opt");
|
||||
assert_string_equal(p[1], A_TIMES_256);
|
||||
assert_null(p[res]);
|
||||
|
||||
/* very long line */
|
||||
PARSE_LINE_TST("opt " A_TIMES_256 " " A_TIMES_256 " " A_TIMES_256 " " A_TIMES_256);
|
||||
assert_int_equal(res, 5);
|
||||
assert_string_equal(p[0], "opt");
|
||||
assert_string_equal(p[1], A_TIMES_256);
|
||||
assert_string_equal(p[2], A_TIMES_256);
|
||||
assert_string_equal(p[3], A_TIMES_256);
|
||||
assert_string_equal(p[4], A_TIMES_256);
|
||||
assert_null(p[res]);
|
||||
|
||||
/* parameter too long */
|
||||
PARSE_LINE_TST("opt " A_TIMES_256 "B");
|
||||
assert_int_equal(res, 0);
|
||||
|
||||
/* max parameters */
|
||||
PARSE_LINE_TST("0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15");
|
||||
assert_int_equal(res, MAX_PARMS);
|
||||
char num[3];
|
||||
for (int i = 0; i < MAX_PARMS; i++)
|
||||
{
|
||||
assert_true(snprintf(num, 3, "%d", i) < 3);
|
||||
assert_string_equal(p[i], num);
|
||||
}
|
||||
assert_null(p[res]);
|
||||
|
||||
/* too many parameters, overflow is ignored */
|
||||
PARSE_LINE_TST("0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16");
|
||||
assert_int_equal(res, MAX_PARMS);
|
||||
for (int i = 0; i < MAX_PARMS; i++)
|
||||
{
|
||||
assert_true(snprintf(num, 3, "%d", i) < 3);
|
||||
assert_string_equal(p[i], num);
|
||||
}
|
||||
assert_null(p[res]);
|
||||
|
||||
gc_free(&gc);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
const struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test(test_parse_line),
|
||||
};
|
||||
|
||||
return cmocka_run_group_tests_name("options_parse", tests, NULL, NULL);
|
||||
}
|
||||
Loading…
Reference in a new issue