diff options
| author | Michael Biebl <biebl@debian.org> | 2020-04-11 21:28:04 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2020-04-11 21:28:04 +0200 |
| commit | 1e5977b62f896e844b548c3007ace9e1dfa7f9ed (patch) | |
| tree | 7a7416ed410e72b6200f3d860fd315ec11cc106b /shared/nm-utils | |
| parent | b012fa6e1d808e0736c009799c62d835cbfcc1dd (diff) | |
New upstream version 1.23.90 upstream/1.23.90
Diffstat (limited to 'shared/nm-utils')
| -rw-r--r-- | shared/nm-utils/nm-test-utils.h | 277 | ||||
| -rw-r--r-- | shared/nm-utils/nm-vpn-editor-plugin-call.h | 2 | ||||
| -rw-r--r-- | shared/nm-utils/tests/meson.build | 21 | ||||
| -rw-r--r-- | shared/nm-utils/tests/test-shared-general.c | 577 |
4 files changed, 233 insertions, 644 deletions
diff --git a/shared/nm-utils/nm-test-utils.h b/shared/nm-utils/nm-test-utils.h index f0ea1179..96e36135 100644 --- a/shared/nm-utils/nm-test-utils.h +++ b/shared/nm-utils/nm-test-utils.h @@ -622,7 +622,7 @@ __nmtst_init (int *argc, char ***argv, gboolean assert_logging, const char *log_ #ifdef __NETWORKMANAGER_UTILS_H__ /* ensure that monotonic timestamp is called (because it initially logs a line) */ - nm_utils_get_monotonic_timestamp_s (); + nm_utils_get_monotonic_timestamp_sec (); #endif #ifdef NM_UTILS_H @@ -848,6 +848,15 @@ nmtst_get_rand_uint32 (void) return g_rand_int (nmtst_get_rand ()); } +static inline guint64 +nmtst_get_rand_uint64 (void) +{ + GRand *rand = nmtst_get_rand (); + + return (((guint64) g_rand_int (rand)) ) + | (((guint64) g_rand_int (rand)) << 32); +} + static inline guint nmtst_get_rand_uint (void) { @@ -855,6 +864,16 @@ nmtst_get_rand_uint (void) return nmtst_get_rand_uint32 (); } +static inline gsize +nmtst_get_rand_size (void) +{ + G_STATIC_ASSERT_EXPR ( sizeof (gsize) == sizeof (guint32) + || sizeof (gsize) == sizeof (guint64)); + if (sizeof (gsize) == sizeof (guint32)) + return nmtst_get_rand_uint32 (); + return nmtst_get_rand_uint64 (); +} + static inline gboolean nmtst_get_rand_bool (void) { @@ -967,6 +986,89 @@ nmtst_rand_perm_gslist (GRand *rand, GSList *list) /*****************************************************************************/ +/** + * nmtst_get_rand_word_length: + * @rand: (allow-none): #GRand instance or %NULL to use the singleton. + * + * Returns: a random integer >= 0, that most frequently is somewhere between + * 0 and 16, but (with decreasing) probability, it can be larger. This can + * be used when we generate random input for unit tests. + */ +static inline guint +nmtst_get_rand_word_length (GRand *rand) +{ + guint n; + + if (!rand) + rand = nmtst_get_rand (); + + n = 0; + while (TRUE) { + guint32 rnd = g_rand_int (rand); + guint probability; + + /* The following python code implements a random sample with this + * distribution: + * + * def random_histogram(n_tries, scale = None): + * def probability(n_tok): + * import math + * return max(2, math.floor(100 / (2*(n_tok+1)))) + * def n_tokens(): + * import random + * n_tok = 0 + * while True: + * if random.randint(0, 0xFFFFFFFF) % probability(n_tok) == 0: + * return n_tok + * n_tok += 1 + * hist = [] + * i = 0; + * while i < n_tries: + * n_tok = n_tokens() + * while n_tok >= len(hist): + * hist.append(0) + * hist[n_tok] = hist[n_tok] + 1 + * i += 1 + * if scale is not None: + * hist = list([round(x / n_tries * scale) for x in hist]) + * return hist + * + * For example, random_histogram(n_tries = 1000000, scale = 1000) may give + * + * IDX: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29] + * SEEN: [20, 39, 59, 73, 80, 91, 92, 90, 91, 73, 73, 54, 55, 36, 24, 16, 16, 8, 4, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0] + * + * which give a sense of the probability with this individual results are returned. + */ + probability = NM_MAX (2u, (100u / (2u * (n + 1u)))); + if ((rnd % probability) == 0) + return n; + n++; + } +} + +/*****************************************************************************/ + +static inline gboolean +nmtst_g_source_assert_not_called (gpointer user_data) +{ + g_assert_not_reached (); + return G_SOURCE_CONTINUE; +} + +static inline gboolean +nmtst_g_source_set_boolean_true (gpointer user_data) +{ + gboolean *ptr = user_data; + + g_assert (ptr); + g_assert (!*ptr); + *ptr = TRUE; + return G_SOURCE_CONTINUE; +} + +/*****************************************************************************/ + static inline gboolean _nmtst_main_loop_run_timeout (gpointer user_data) { @@ -978,13 +1080,13 @@ _nmtst_main_loop_run_timeout (gpointer user_data) } static inline gboolean -nmtst_main_loop_run (GMainLoop *loop, guint timeout_ms) +nmtst_main_loop_run (GMainLoop *loop, guint timeout_msec) { nm_auto_unref_gsource GSource *source = NULL; GMainLoop *loopx = loop; - if (timeout_ms > 0) { - source = g_timeout_source_new (timeout_ms); + if (timeout_msec > 0) { + source = g_timeout_source_new (timeout_msec); g_source_set_callback (source, _nmtst_main_loop_run_timeout, &loopx, NULL); g_source_attach (source, g_main_loop_get_context (loop)); } @@ -1010,36 +1112,123 @@ _nmtst_main_loop_quit_on_notify (GObject *object, GParamSpec *pspec, gpointer us } #define nmtst_main_loop_quit_on_notify ((GCallback) _nmtst_main_loop_quit_on_notify) -static inline gboolean -_nmtst_main_context_iterate_until_timeout (gpointer user_data) -{ - gboolean *p_had_pointer = user_data; - - g_assert (!*p_had_pointer); - *p_had_pointer = TRUE; - return G_SOURCE_CONTINUE; -} - -#define nmtst_main_context_iterate_until(context, timeout_ms, condition) \ - G_STMT_START { \ +#define nmtst_main_context_iterate_until(context, timeout_msec, condition) \ + ({ \ nm_auto_destroy_and_unref_gsource GSource *_source = NULL; \ GMainContext *_context = (context); \ gboolean _had_timeout = FALSE; \ \ - _source = g_timeout_source_new (timeout_ms); \ - g_source_set_callback (_source, _nmtst_main_context_iterate_until_timeout, &_had_timeout, NULL); \ + _source = g_timeout_source_new (timeout_msec); \ + g_source_set_callback (_source, nmtst_g_source_set_boolean_true, &_had_timeout, NULL); \ g_source_attach (_source, _context); \ \ while (TRUE) { \ if (condition) \ break; \ g_main_context_iteration (_context, TRUE); \ - g_assert (!_had_timeout && #condition); \ + if (_had_timeout) \ + break; \ } \ + \ + !_had_timeout; \ + }) + +#define nmtst_main_context_iterate_until_assert(context, timeout_msec, condition) \ + G_STMT_START { \ + if (!nmtst_main_context_iterate_until (context, timeout_msec, condition)) \ + g_assert (FALSE && #condition); \ } G_STMT_END /*****************************************************************************/ +static inline void +nmtst_main_context_assert_no_dispatch (GMainContext *context, + guint timeout_msec) +{ + nm_auto_destroy_and_unref_gsource GSource *source = NULL; + gboolean timeout_hit = FALSE; + + source = g_timeout_source_new (timeout_msec); + g_source_set_callback (source, nmtst_g_source_set_boolean_true, &timeout_hit, NULL); + g_source_attach (source, context); + + while (g_main_context_iteration (context, TRUE)) { + if (timeout_hit) + return; + g_assert_not_reached (); + } +} + +/*****************************************************************************/ + +typedef struct { + GMainLoop *_main_loop; + union { + GSList *_list; + const void *const is_waiting; + }; +} NMTstContextBusyWatcherData; + +static inline void +_nmtst_context_busy_watcher_add_cb (gpointer data, + GObject *where_the_object_was) +{ + NMTstContextBusyWatcherData *watcher_data = data; + GSList *l; + + g_assert (watcher_data); + + l = g_slist_find (watcher_data->_list, where_the_object_was); + g_assert (l); + + watcher_data->_list = g_slist_delete_link (watcher_data->_list, l); + if (!watcher_data->_list) + g_main_loop_quit (watcher_data->_main_loop); +} + +static inline void +nmtst_context_busy_watcher_add (NMTstContextBusyWatcherData *watcher_data, + GObject *object) +{ + g_assert (watcher_data); + g_assert (G_IS_OBJECT (object)); + + if (!watcher_data->_main_loop) { + watcher_data->_main_loop = g_main_loop_new (g_main_context_get_thread_default (), + FALSE); + g_assert (!watcher_data->_list); + } else { + g_assert ( g_main_loop_get_context (watcher_data->_main_loop) + == (g_main_context_get_thread_default () ?: g_main_context_default ())); + } + + g_object_weak_ref (object, + _nmtst_context_busy_watcher_add_cb, + watcher_data); + watcher_data->_list = g_slist_prepend (watcher_data->_list, object); +} + +static inline void +nmtst_context_busy_watcher_wait (NMTstContextBusyWatcherData *watcher_data) +{ + g_assert (watcher_data); + + if (!watcher_data->_main_loop) { + g_assert (!watcher_data->_list); + return; + } + + if (watcher_data->_list) { + if (!nmtst_main_loop_run (watcher_data->_main_loop, 5000)) + g_error ("timeout running mainloop waiting for GObject to destruct"); + } + + g_assert (!watcher_data->_list); + nm_clear_pointer (&watcher_data->_main_loop, g_main_loop_unref); +} + +/*****************************************************************************/ + static inline const char * nmtst_get_sudo_cmd (void) { @@ -1156,15 +1345,6 @@ nmtst_uuid_generate (void) #endif -#define NMTST_SWAP(x, y) \ - G_STMT_START { \ - char __nmtst_swap_temp[sizeof((x)) == sizeof((y)) ? (signed) sizeof((x)) : -1]; \ - \ - memcpy(__nmtst_swap_temp, &(y), sizeof (__nmtst_swap_temp)); \ - memcpy(&(y), &(x), sizeof (__nmtst_swap_temp)); \ - memcpy(&(x), __nmtst_swap_temp, sizeof (__nmtst_swap_temp)); \ - } G_STMT_END - #define nmtst_assert_str_has_substr(str, substr) \ G_STMT_START { \ const char *__str = (str); \ @@ -1362,15 +1542,27 @@ nmtst_file_get_contents (const char *filename) return contents; } -#define nmtst_file_set_contents(filename, content) \ +#define nmtst_file_set_contents_size(filename, content, size) \ G_STMT_START { \ GError *_error = NULL; \ gboolean _success; \ + const char *_content = (content); \ + gssize _size = (size); \ + \ + g_assert (_content); \ \ - _success = g_file_set_contents ((filename), (content), -1, &_error); \ + if (_size < 0) { \ + g_assert (_size == -1); \ + _size = strlen (_content); \ + } \ + \ + _success = g_file_set_contents ((filename), _content, _size, &_error); \ nmtst_assert_success (_success, _error); \ } G_STMT_END +#define nmtst_file_set_contents(filename, content) \ + nmtst_file_set_contents_size (filename, content, -1) + /*****************************************************************************/ static inline void @@ -1478,9 +1670,9 @@ nmtst_setting_ip_config_add_address (NMSettingIPConfig *s_ip, g_assert (s_ip); - if (nm_utils_ipaddr_valid (AF_INET, address)) + if (nm_utils_ipaddr_is_valid (AF_INET, address)) family = AF_INET; - else if (nm_utils_ipaddr_valid (AF_INET6, address)) + else if (nm_utils_ipaddr_is_valid (AF_INET6, address)) family = AF_INET6; else g_assert_not_reached (); @@ -1503,9 +1695,9 @@ nmtst_setting_ip_config_add_route (NMSettingIPConfig *s_ip, g_assert (s_ip); - if (nm_utils_ipaddr_valid (AF_INET, dest)) + if (nm_utils_ipaddr_is_valid (AF_INET, dest)) family = AF_INET; - else if (nm_utils_ipaddr_valid (AF_INET6, dest)) + else if (nm_utils_ipaddr_is_valid (AF_INET6, dest)) family = AF_INET6; else g_assert_not_reached (); @@ -1611,8 +1803,12 @@ nmtst_create_minimal_connection (const char *id, const char *uuid, const char *t con = nm_connection_new (); #endif + g_assert (con); + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + g_assert (s_con); + g_object_set (s_con, NM_SETTING_CONNECTION_ID, id, NM_SETTING_CONNECTION_UUID, uuid, @@ -1959,14 +2155,14 @@ nmtst_assert_setting_is_equal (gconstpointer /* const NMSetting * */ a, g_assert (NM_IS_SETTING (b)); if (NM_FLAGS_HAS (r, 0x4)) - NMTST_SWAP (a, b); + NM_SWAP (a, b); g_assert (nm_setting_compare ((NMSetting *) a, (NMSetting *) b, flags)); if (NM_FLAGS_HAS (r, 0x8)) - NMTST_SWAP (a, b); + NM_SWAP (a, b); g_assert (nm_setting_diff ((NMSetting *) a, (NMSetting *) b, @@ -2311,13 +2507,4 @@ nmtst_keyfile_get_num_keys (GKeyFile *keyfile, /*****************************************************************************/ -static inline gboolean -nmtst_g_source_assert_not_called (gpointer user_data) -{ - g_assert_not_reached (); - return G_SOURCE_CONTINUE; -} - -/*****************************************************************************/ - #endif /* __NM_TEST_UTILS_H__ */ diff --git a/shared/nm-utils/nm-vpn-editor-plugin-call.h b/shared/nm-utils/nm-vpn-editor-plugin-call.h index ab473083..b2c39e29 100644 --- a/shared/nm-utils/nm-vpn-editor-plugin-call.h +++ b/shared/nm-utils/nm-vpn-editor-plugin-call.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +// SPDX-License-Identifier: LGPL-2.1+ /* * Copyright (C) 2016 Red Hat, Inc. */ diff --git a/shared/nm-utils/tests/meson.build b/shared/nm-utils/tests/meson.build deleted file mode 100644 index 1ee5efff..00000000 --- a/shared/nm-utils/tests/meson.build +++ /dev/null @@ -1,21 +0,0 @@ -test_unit = 'test-shared-general' - -c_flags = [ - '-DNETWORKMANAGER_COMPILATION_TEST', - '-DNETWORKMANAGER_COMPILATION=(NM_NETWORKMANAGER_COMPILATION_GLIB|NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_PROG)', -] - -exe = executable( - test_unit, - test_unit + '.c', - c_args: c_flags, - dependencies: libnm_utils_base_dep, - link_with: libnm_systemd_logging_stub, -) - -test( - 'shared/nm-utils/' + test_unit, - test_script, - args: test_args + [exe.full_path()], - timeout: default_test_timeout, -) diff --git a/shared/nm-utils/tests/test-shared-general.c b/shared/nm-utils/tests/test-shared-general.c deleted file mode 100644 index 34da19b3..00000000 --- a/shared/nm-utils/tests/test-shared-general.c +++ /dev/null @@ -1,577 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1+ -/* - * Copyright (C) 2018 Red Hat, Inc. - */ - -#define NM_TEST_UTILS_NO_LIBNM 1 - -#include "nm-default.h" - -#include "nm-std-aux/unaligned.h" -#include "nm-glib-aux/nm-random-utils.h" -#include "nm-glib-aux/nm-time-utils.h" -#include "nm-glib-aux/nm-ref-string.h" - -#include "nm-utils/nm-test-utils.h" - -/*****************************************************************************/ - -static void -test_gpid (void) -{ - const int *int_ptr; - GPid pid = 42; - - /* We redefine G_PID_FORMAT, because it's only available since glib 2.53.5. - * - * Also, this is the format for GPid, which for glib is always a typedef - * for "int". Add a check for that here. - * - * G_PID_FORMAT is not about pid_t, which might be a smaller int, and which we would - * check with SIZEOF_PID_T. */ - G_STATIC_ASSERT (sizeof (GPid) == sizeof (int)); - - g_assert_cmpstr (""G_PID_FORMAT, ==, "i"); - - /* check that it's really "int". We will get a compiler warning, if that's not - * the case. */ - int_ptr = &pid; - g_assert_cmpint (*int_ptr, ==, 42); -} - -/*****************************************************************************/ - -static void -test_monotonic_timestamp (void) -{ - g_assert (nm_utils_get_monotonic_timestamp_s () > 0); -} - -/*****************************************************************************/ - -static void -test_nmhash (void) -{ - int rnd; - - nm_utils_random_bytes (&rnd, sizeof (rnd)); - - g_assert (nm_hash_val (555, 4) != 0); -} - -/*****************************************************************************/ - -static const char * -_make_strv_foo (void) -{ - return "foo"; -} - -static const char *const*const _tst_make_strv_1 = NM_MAKE_STRV ("1", "2"); - -static void -test_make_strv (void) -{ - const char *const*v1a = NM_MAKE_STRV ("a"); - const char *const*v1b = NM_MAKE_STRV ("a", ); - const char *const*v2a = NM_MAKE_STRV ("a", "b"); - const char *const*v2b = NM_MAKE_STRV ("a", "b", ); - const char *const v3[] = { "a", "b", }; - const char *const*v4b = NM_MAKE_STRV ("a", _make_strv_foo (), ); - - g_assert (NM_PTRARRAY_LEN (v1a) == 1); - g_assert (NM_PTRARRAY_LEN (v1b) == 1); - g_assert (NM_PTRARRAY_LEN (v2a) == 2); - g_assert (NM_PTRARRAY_LEN (v2b) == 2); - - g_assert (NM_PTRARRAY_LEN (_tst_make_strv_1) == 2); - g_assert_cmpstr (_tst_make_strv_1[0], ==, "1"); - g_assert_cmpstr (_tst_make_strv_1[1], ==, "2"); - /* writing the static read-only variable leads to crash .*/ - //((char **) _tst_make_strv_1)[0] = NULL; - //((char **) _tst_make_strv_1)[2] = "c"; - - G_STATIC_ASSERT_EXPR (G_N_ELEMENTS (v3) == 2); - - g_assert (NM_PTRARRAY_LEN (v4b) == 2); - - G_STATIC_ASSERT_EXPR (G_N_ELEMENTS (NM_MAKE_STRV ("a", "b" )) == 3); - G_STATIC_ASSERT_EXPR (G_N_ELEMENTS (NM_MAKE_STRV ("a", "b", )) == 3); - - nm_strquote_a (300, ""); -} - -/*****************************************************************************/ - -typedef enum { - TEST_NM_STRDUP_ENUM_m1 = -1, - TEST_NM_STRDUP_ENUM_3 = 3, -} TestNMStrdupIntEnum; - -static void -test_nm_strdup_int (void) -{ -#define _NM_STRDUP_INT_TEST(num, str) \ - G_STMT_START { \ - gs_free char *_s1 = NULL; \ - \ - _s1 = nm_strdup_int ((num)); \ - \ - g_assert (_s1); \ - g_assert_cmpstr (_s1, ==, str); \ - } G_STMT_END - -#define _NM_STRDUP_INT_TEST_TYPED(type, num) \ - G_STMT_START { \ - type _num = ((type) num); \ - \ - _NM_STRDUP_INT_TEST (_num, G_STRINGIFY (num)); \ - } G_STMT_END - - _NM_STRDUP_INT_TEST_TYPED (char, 0); - _NM_STRDUP_INT_TEST_TYPED (char, 1); - _NM_STRDUP_INT_TEST_TYPED (guint8, 0); - _NM_STRDUP_INT_TEST_TYPED (gint8, 25); - _NM_STRDUP_INT_TEST_TYPED (char, 47); - _NM_STRDUP_INT_TEST_TYPED (short, 47); - _NM_STRDUP_INT_TEST_TYPED (int, 47); - _NM_STRDUP_INT_TEST_TYPED (long, 47); - _NM_STRDUP_INT_TEST_TYPED (unsigned char, 47); - _NM_STRDUP_INT_TEST_TYPED (unsigned short, 47); - _NM_STRDUP_INT_TEST_TYPED (unsigned, 47); - _NM_STRDUP_INT_TEST_TYPED (unsigned long, 47); - _NM_STRDUP_INT_TEST_TYPED (gint64, 9223372036854775807); - _NM_STRDUP_INT_TEST_TYPED (gint64, -9223372036854775807); - _NM_STRDUP_INT_TEST_TYPED (guint64, 0); - _NM_STRDUP_INT_TEST_TYPED (guint64, 9223372036854775807); - - _NM_STRDUP_INT_TEST (TEST_NM_STRDUP_ENUM_m1, "-1"); - _NM_STRDUP_INT_TEST (TEST_NM_STRDUP_ENUM_3, "3"); -} - -/*****************************************************************************/ - -static void -test_nm_strndup_a (void) -{ - int run; - - for (run = 0; run < 20; run++) { - gs_free char *input = NULL; - char ch; - gsize i, l; - - input = g_strnfill (nmtst_get_rand_uint32 () % 20, 'x'); - - for (i = 0; input[i]; i++) { - while ((ch = ((char) nmtst_get_rand_uint32 ())) == '\0') { - /* repeat. */ - } - input[i] = ch; - } - - { - gs_free char *dup_free = NULL; - const char *dup; - - l = strlen (input) + 1; - dup = nm_strndup_a (10, input, l - 1, &dup_free); - g_assert_cmpstr (dup, ==, input); - if (strlen (dup) < 10) - g_assert (!dup_free); - else - g_assert (dup == dup_free); - } - - { - gs_free char *dup_free = NULL; - const char *dup; - - l = nmtst_get_rand_uint32 () % 23; - dup = nm_strndup_a (10, input, l, &dup_free); - g_assert (strncmp (dup, input, l) == 0); - g_assert (strlen (dup) <= l); - if (l < 10) - g_assert (!dup_free); - else - g_assert (dup == dup_free); - if (strlen (input) < l) - g_assert (nm_utils_memeqzero (&dup[strlen (input)], l - strlen (input))); - } - } -} - -/*****************************************************************************/ - -static void -test_nm_ip4_addr_is_localhost (void) -{ - g_assert ( nm_ip4_addr_is_localhost (nmtst_inet4_from_string ("127.0.0.0"))); - g_assert ( nm_ip4_addr_is_localhost (nmtst_inet4_from_string ("127.0.0.1"))); - g_assert ( nm_ip4_addr_is_localhost (nmtst_inet4_from_string ("127.5.0.1"))); - g_assert (!nm_ip4_addr_is_localhost (nmtst_inet4_from_string ("126.5.0.1"))); - g_assert (!nm_ip4_addr_is_localhost (nmtst_inet4_from_string ("128.5.0.1"))); - g_assert (!nm_ip4_addr_is_localhost (nmtst_inet4_from_string ("129.5.0.1"))); -} - -/*****************************************************************************/ - -static void -test_unaligned (void) -{ - int shift; - - for (shift = 0; shift <= 32; shift++) { - guint8 buf[100] = { }; - guint8 val = 0; - - while (val == 0) - val = nmtst_get_rand_uint32 () % 256; - - buf[shift] = val; - - g_assert_cmpint (unaligned_read_le64 (&buf[shift]), ==, (guint64) val); - g_assert_cmpint (unaligned_read_be64 (&buf[shift]), ==, ((guint64) val) << 56); - g_assert_cmpint (unaligned_read_ne64 (&buf[shift]), !=, 0); - - g_assert_cmpint (unaligned_read_le32 (&buf[shift]), ==, (guint32) val); - g_assert_cmpint (unaligned_read_be32 (&buf[shift]), ==, ((guint32) val) << 24); - g_assert_cmpint (unaligned_read_ne32 (&buf[shift]), !=, 0); - - g_assert_cmpint (unaligned_read_le16 (&buf[shift]), ==, (guint16) val); - g_assert_cmpint (unaligned_read_be16 (&buf[shift]), ==, ((guint16) val) << 8); - g_assert_cmpint (unaligned_read_ne16 (&buf[shift]), !=, 0); - } -} - -/*****************************************************************************/ - -static void -_strv_cmp_fuzz_input (const char *const*in, - gssize l, - const char ***out_strv_free_shallow, - char ***out_strv_free_deep, - const char *const* *out_s1, - const char *const* *out_s2) -{ - const char **strv; - gsize i; - - /* Fuzz the input argument. It will return two output arrays that are semantically - * equal the input. */ - - if (nmtst_get_rand_bool ()) { - char **ss; - - if (l < 0) - ss = g_strdupv ((char **) in); - else if (l == 0) { - ss = nmtst_get_rand_bool () - ? NULL - : g_new0 (char *, 1); - } else { - ss = nm_memdup (in, sizeof (const char *) * l); - for (i = 0; i < (gsize) l; i++) - ss[i] = g_strdup (ss[i]); - } - strv = (const char **) ss; - *out_strv_free_deep = ss; - } else { - if (l < 0) { - strv = in - ? nm_memdup (in, sizeof (const char *) * (NM_PTRARRAY_LEN (in) + 1)) - : NULL; - } else if (l == 0) { - strv = nmtst_get_rand_bool () - ? NULL - : g_new0 (const char *, 1); - } else - strv = nm_memdup (in, sizeof (const char *) * l); - *out_strv_free_shallow = strv; - } - - *out_s1 = in; - *out_s2 = strv; - - if (nmtst_get_rand_bool ()) { - /* randomly swap the original and the clone. That means, out_s1 is either - * the input argument (as-is) or the sementically equal clone. */ - NMTST_SWAP (*out_s1, *out_s2); - } - if (nmtst_get_rand_bool ()) { - /* randomly make s1 and s2 the same. This is for testing that - * comparing two identical pointers yields the same result. */ - *out_s2 = *out_s1; - } -} - -static void -_strv_cmp_free_deep (char **strv, - gssize len) -{ - gssize i; - - if (strv) { - if (len < 0) - g_strfreev (strv); - else { - for (i = 0; i < len; i++) - g_free (strv[i]); - g_free (strv); - } - } -} - -static void -test_strv_cmp (void) -{ - const char *const strv0[1] = { }; - const char *const strv1[2] = { "", }; - -#define _STRV_CMP(a1, l1, a2, l2, equal) \ - G_STMT_START { \ - gssize _l1 = (l1); \ - gssize _l2 = (l2); \ - const char *const*_a1; \ - const char *const*_a2; \ - const char *const*_a1x; \ - const char *const*_a2x; \ - char **_a1_free_deep = NULL; \ - char **_a2_free_deep = NULL; \ - gs_free const char **_a1_free_shallow = NULL; \ - gs_free const char **_a2_free_shallow = NULL; \ - int _c1, _c2; \ - \ - _strv_cmp_fuzz_input ((a1), _l1, &_a1_free_shallow, &_a1_free_deep, &_a1, &_a1x); \ - _strv_cmp_fuzz_input ((a2), _l2, &_a2_free_shallow, &_a2_free_deep, &_a2, &_a2x); \ - \ - _c1 = _nm_utils_strv_cmp_n (_a1, _l1, _a2, _l2); \ - _c2 = _nm_utils_strv_cmp_n (_a2, _l2, _a1, _l1); \ - if (equal) { \ - g_assert_cmpint (_c1, ==, 0); \ - g_assert_cmpint (_c2, ==, 0); \ - } else { \ - g_assert_cmpint (_c1, ==, -1); \ - g_assert_cmpint (_c2, ==, 1); \ - } \ - \ - /* Compare with self. _strv_cmp_fuzz_input() randomly swapped the arguments (_a1 and _a1x). - * Either way, the arrays must compare equal to their semantically equal alternative. */ \ - g_assert_cmpint (_nm_utils_strv_cmp_n (_a1, _l1, _a1x, _l1), ==, 0); \ - g_assert_cmpint (_nm_utils_strv_cmp_n (_a2, _l2, _a2x, _l2), ==, 0); \ - \ - _strv_cmp_free_deep (_a1_free_deep, _l1); \ - _strv_cmp_free_deep (_a2_free_deep, _l2); \ - } G_STMT_END - - _STRV_CMP (NULL, -1, NULL, -1, TRUE); - - _STRV_CMP (NULL, -1, NULL, 0, FALSE); - _STRV_CMP (NULL, -1, strv0, 0, FALSE); - _STRV_CMP (NULL, -1, strv0, -1, FALSE); - - _STRV_CMP (NULL, 0, NULL, 0, TRUE); - _STRV_CMP (NULL, 0, strv0, 0, TRUE); - _STRV_CMP (NULL, 0, strv0, -1, TRUE); - _STRV_CMP (strv0, 0, strv0, 0, TRUE); - _STRV_CMP (strv0, 0, strv0, -1, TRUE); - _STRV_CMP (strv0, -1, strv0, -1, TRUE); - - _STRV_CMP (NULL, 0, strv1, -1, FALSE); - _STRV_CMP (NULL, 0, strv1, 1, FALSE); - _STRV_CMP (strv0, 0, strv1, -1, FALSE); - _STRV_CMP (strv0, 0, strv1, 1, FALSE); - _STRV_CMP (strv0, -1, strv1, -1, FALSE); - _STRV_CMP (strv0, -1, strv1, 1, FALSE); - - _STRV_CMP (strv1, -1, strv1, 1, TRUE); - _STRV_CMP (strv1, 1, strv1, 1, TRUE); -} - -/*****************************************************************************/ - -static void -_do_strstrip_avoid_copy (const char *str) -{ - gs_free char *str1 = g_strdup (str); - gs_free char *str2 = g_strdup (str); - gs_free char *str3 = NULL; - gs_free char *str4 = NULL; - const char *s3; - const char *s4; - - if (str1) - g_strstrip (str1); - - nm_strstrip (str2); - - g_assert_cmpstr (str1, ==, str2); - - s3 = nm_strstrip_avoid_copy (str, &str3); - g_assert_cmpstr (str1, ==, s3); - - s4 = nm_strstrip_avoid_copy_a (10, str, &str4); - g_assert_cmpstr (str1, ==, s4); - g_assert (!str == !s4); - g_assert (!s4 || strlen (s4) <= strlen (str)); - if (s4 && s4 == &str[strlen (str) - strlen (s4)]) { - g_assert (!str4); - g_assert (s3 == s4); - } else if (s4 && strlen (s4) >= 10) { - g_assert (str4); - g_assert (s4 == str4); - } else - g_assert (!str4); - - if (!nm_streq0 (str1, str)) - _do_strstrip_avoid_copy (str1); -} - -static void -test_strstrip_avoid_copy (void) -{ - _do_strstrip_avoid_copy (NULL); - _do_strstrip_avoid_copy (""); - _do_strstrip_avoid_copy (" "); - _do_strstrip_avoid_copy (" a "); - _do_strstrip_avoid_copy (" 012345678 "); - _do_strstrip_avoid_copy (" 0123456789 "); - _do_strstrip_avoid_copy (" 01234567890 "); - _do_strstrip_avoid_copy (" 012345678901 "); -} - -/*****************************************************************************/ - -static void -test_nm_utils_bin2hexstr (void) -{ - int n_run; - - for (n_run = 0; n_run < 100; n_run++) { - guint8 buf[100]; - guint8 buf2[G_N_ELEMENTS (buf) + 1]; - gsize len = nmtst_get_rand_uint32 () % (G_N_ELEMENTS (buf) + 1); - char strbuf1[G_N_ELEMENTS (buf) * 3]; - gboolean allocate = nmtst_get_rand_bool (); - char delimiter = nmtst_get_rand_bool () ? ':' : '\0'; - gboolean upper_case = nmtst_get_rand_bool (); - gsize expected_strlen; - char *str_hex; - gsize required_len; - gboolean outlen_set; - gsize outlen; - guint8 *bin2; - - nmtst_rand_buf (NULL, buf, len); - - if (len == 0) - expected_strlen = 0; - else if (delimiter != '\0') - expected_strlen = (len * 3u) - 1; - else - expected_strlen = len * 2u; - - g_assert_cmpint (expected_strlen, <, G_N_ELEMENTS (strbuf1)); - - str_hex = nm_utils_bin2hexstr_full (buf, len, delimiter, upper_case, !allocate ? strbuf1 : NULL); - - g_assert (str_hex); - if (!allocate) - g_assert (str_hex == strbuf1); - g_assert_cmpint (strlen (str_hex), ==, expected_strlen); - - g_assert (NM_STRCHAR_ALL (str_hex, ch, (ch >= '0' && ch <= '9') - || ch == delimiter - || ( upper_case - ? (ch >= 'A' && ch <= 'F') - : (ch >= 'a' && ch <= 'f')))); - - required_len = nmtst_get_rand_bool () ? len : 0u; - - outlen_set = required_len == 0 || nmtst_get_rand_bool (); - - memset (buf2, 0, sizeof (buf2)); - - bin2 = nm_utils_hexstr2bin_full (str_hex, - nmtst_get_rand_bool (), - delimiter != '\0' && nmtst_get_rand_bool (), - delimiter != '\0' - ? nmtst_rand_select ((const char *) ":", ":-") - : nmtst_rand_select ((const char *) ":", ":-", "", NULL), - required_len, - buf2, - len, - outlen_set ? &outlen : NULL); - if (len > 0) { - g_assert (bin2); - g_assert (bin2 == buf2); - } else - g_assert (!bin2); - - if (outlen_set) - g_assert_cmpint (outlen, ==, len); - - g_assert_cmpmem (buf, len, buf2, len); - - g_assert (buf2[len] == '\0'); - - if (allocate) - g_free (str_hex); - } -} - -/*****************************************************************************/ - -static void -test_nm_ref_string (void) -{ - nm_auto_ref_string NMRefString *s1 = NULL; - NMRefString *s2; - - s1 = nm_ref_string_new ("hallo"); - g_assert (s1); - g_assert_cmpstr (s1->str, ==, "hallo"); - g_assert_cmpint (s1->len, ==, strlen ("hallo")); - - s2 = nm_ref_string_new ("hallo"); - g_assert (s2 == s1); - nm_ref_string_unref (s2); - - s2 = nm_ref_string_new (NULL); - g_assert (!s2); - nm_ref_string_unref (s2); - -#define STR_WITH_NUL "hallo\0test\0" - s2 = nm_ref_string_new_len (STR_WITH_NUL, NM_STRLEN (STR_WITH_NUL)); - g_assert (s2); - g_assert_cmpstr (s2->str, ==, "hallo"); - g_assert_cmpint (s2->len, ==, NM_STRLEN (STR_WITH_NUL)); - g_assert_cmpint (s2->len, >, strlen (s2->str)); - g_assert_cmpmem (s2->str, s2->len, STR_WITH_NUL, NM_STRLEN (STR_WITH_NUL)); - g_assert (s2->str[s2->len] == '\0'); - nm_ref_string_unref (s2); -} - -/*****************************************************************************/ - -NMTST_DEFINE (); - -int main (int argc, char **argv) -{ - nmtst_init (&argc, &argv, TRUE); - - g_test_add_func ("/general/test_gpid", test_gpid); - g_test_add_func ("/general/test_monotonic_timestamp", test_monotonic_timestamp); - g_test_add_func ("/general/test_nmhash", test_nmhash); - g_test_add_func ("/general/test_nm_make_strv", test_make_strv); - g_test_add_func ("/general/test_nm_strdup_int", test_nm_strdup_int); - g_test_add_func ("/general/test_nm_strndup_a", test_nm_strndup_a); - g_test_add_func ("/general/test_nm_ip4_addr_is_localhost", test_nm_ip4_addr_is_localhost); - g_test_add_func ("/general/test_unaligned", test_unaligned); - g_test_add_func ("/general/test_strv_cmp", test_strv_cmp); - g_test_add_func ("/general/test_strstrip_avoid_copy", test_strstrip_avoid_copy); - g_test_add_func ("/general/test_nm_utils_bin2hexstr", test_nm_utils_bin2hexstr); - g_test_add_func ("/general/test_nm_ref_string", test_nm_ref_string); - - return g_test_run (); -} |