diff options
| author | Michael Biebl <biebl@debian.org> | 2019-04-21 21:09:51 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2019-04-21 21:09:51 +0200 |
| commit | 85563b7fc7ec2cd21e38debb9b28db342e2e8e7c (patch) | |
| tree | cce7b0b02d28fae2df9fdf2c1804cacd1500f2d7 /libnm-core/tests | |
| parent | 9a6dcbf895f9da01768e64b73cec88c16157d91e (diff) | |
New upstream version 1.18.0 upstream/1.18.0
Diffstat (limited to 'libnm-core/tests')
| -rw-r--r-- | libnm-core/tests/meson.build | 2 | ||||
| -rw-r--r-- | libnm-core/tests/test-general.c | 516 | ||||
| -rw-r--r-- | libnm-core/tests/test-keyfile.c | 98 | ||||
| -rw-r--r-- | libnm-core/tests/test-setting.c | 368 |
4 files changed, 884 insertions, 100 deletions
diff --git a/libnm-core/tests/meson.build b/libnm-core/tests/meson.build index 7d772c80..1afb9c4b 100644 --- a/libnm-core/tests/meson.build +++ b/libnm-core/tests/meson.build @@ -34,7 +34,7 @@ foreach test_unit: test_units 'libnm-core-' + test_unit, [test_unit + '.c'] + enum, dependencies: [ - nm_core_dep, + libnm_core_dep, libnm_systemd_shared_no_logging_dep, ], c_args: [ diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index 7d97296a..a6abf391 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -23,8 +23,8 @@ #include "nm-default.h" -#include "nm-utils/c-list-util.h" -#include "nm-utils/nm-enum-utils.h" +#include "nm-std-aux/c-list-util.h" +#include "nm-glib-aux/nm-enum-utils.h" #include "nm-utils.h" #include "nm-setting-private.h" @@ -63,8 +63,8 @@ #include "nm-setting-wpan.h" #include "nm-simple-connection.h" #include "nm-keyfile-internal.h" -#include "nm-utils/nm-dedup-multi.h" -#include "nm-ethtool-utils.h" +#include "nm-glib-aux/nm-dedup-multi.h" +#include "nm-libnm-core-intern/nm-ethtool-utils.h" #include "test-general-enums.h" @@ -80,6 +80,29 @@ G_STATIC_ASSERT (sizeof (bool) <= sizeof (int)); /*****************************************************************************/ +static void +test_nm_ascii_spaces (void) +{ + int i; + const char *const S = NM_ASCII_SPACES; + + for (i = 0; S[i]; i++) + g_assert (!strchr (&S[i + 1], S[i])); + + for (i = 0; S[i] != '\0'; i++) + g_assert (g_ascii_isspace (S[i])); + + g_assert (!g_ascii_isspace ((char) 0)); + for (i = 1; i < 0x100; i++) { + if (g_ascii_isspace ((char) i)) + g_assert (strchr (S, (char) i)); + else + g_assert (!strchr (S, (char) i)); + } +} + +/*****************************************************************************/ + typedef struct _nm_packed { int v0; char v1; @@ -236,51 +259,324 @@ test_nm_g_slice_free_fcn (void) /*****************************************************************************/ static void -_do_test_nm_utils_strsplit_set (gboolean escape, const char *str, ...) +_do_test_nm_utils_strsplit_set_f_one (NMUtilsStrsplitSetFlags flags, + const char *str, + gsize words_len, + const char *const*exp_words) { - gs_unref_ptrarray GPtrArray *args_array = g_ptr_array_new (); - const char *const*args; +#define DELIMITERS " \n" +#define DELIMITERS_C ' ', '\n' + gs_free const char **words = NULL; - const char *arg; - gsize i; - va_list ap; + gsize i, j, k; + const gboolean f_allow_escaping = NM_FLAGS_HAS (flags, NM_UTILS_STRSPLIT_SET_FLAGS_ALLOW_ESCAPING); + const gboolean f_preserve_empty = NM_FLAGS_HAS (flags, NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY); + const char *s1; + gsize initial_offset; + gs_strfreev char **words_g = NULL; + + g_assert (!NM_FLAGS_ANY (flags, ~( NM_UTILS_STRSPLIT_SET_FLAGS_ALLOW_ESCAPING + | NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY))); + + /* assert that the epected words are valid (and don't contain unescaped delimiters). */ + for (i = 0; i < words_len; i++) { + const char *w = exp_words[i]; + + g_assert (w); + if (!f_preserve_empty) + g_assert (w[0]); + for (k = 0; w[k]; ) { + if ( f_allow_escaping + && w[k] == '\\') { + k++; + if (w[k] == '\0') + break; + k++; + continue; + } + g_assert (!NM_IN_SET (w[k], DELIMITERS_C)); + k++; + } + if (!f_allow_escaping) + g_assert (!NM_STRCHAR_ANY (w, ch, NM_IN_SET (ch, DELIMITERS_C))); + } - va_start (ap, str); - while ((arg = va_arg (ap, const char *))) - g_ptr_array_add (args_array, (gpointer) arg); - va_end (ap); - g_ptr_array_add (args_array, NULL); + initial_offset = (f_preserve_empty || !str) + ? 0u + : strspn (str, DELIMITERS); + + /* first compare our expected values with what g_strsplit_set() would + * do. */ + words_g = str ? g_strsplit_set (str, DELIMITERS, -1) : NULL; + if (str == NULL) { + g_assert_cmpint (words_len, ==, 0); + g_assert (!words_g); + } else if (nm_streq0 (str, "")) { + g_assert_cmpint (words_len, ==, 0); + g_assert (words_g); + g_assert (!words_g[0]); + } else { + g_assert (words_g); + g_assert (words_g[0]); + if (!f_allow_escaping) { + if (!f_preserve_empty) { + for (i = 0, j = 0; words_g[i]; i++) { + if (words_g[i][0] == '\0') + g_free (words_g[i]); + else + words_g[j++] = words_g[i]; + } + words_g[j] = NULL; + } + if (f_preserve_empty) + g_assert_cmpint (words_len, >, 0); + for (i = 0; i < words_len; i++) { + g_assert (exp_words[i]); + g_assert_cmpstr (exp_words[i], ==, words_g[i]); + } + g_assert (words_g[words_len] == NULL); + g_assert_cmpint (NM_PTRARRAY_LEN (words_g), ==, words_len); + g_assert (_nm_utils_strv_cmp_n (exp_words, words_len, NM_CAST_STRV_CC (words_g), -1) == 0); + } + } - args = (const char *const*) args_array->pdata; + if ( flags == NM_UTILS_STRSPLIT_SET_FLAGS_NONE + && nmtst_get_rand_bool ()) + words = nm_utils_strsplit_set (str, DELIMITERS); + else if ( flags == NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY + && nmtst_get_rand_bool ()) + words = nm_utils_strsplit_set_with_empty (str, DELIMITERS); + else + words = nm_utils_strsplit_set_full (str, DELIMITERS, flags); - words = nm_utils_strsplit_set (str, " \t\n", escape); + g_assert_cmpint (NM_PTRARRAY_LEN (words), ==, words_len); - if (!args[0]) { + if (words_len == 0) { g_assert (!words); g_assert ( !str - || NM_STRCHAR_ALL (str, ch, NM_IN_SET (ch, ' ', '\t', '\n'))); + || NM_STRCHAR_ALL (str, ch, NM_IN_SET (ch, DELIMITERS_C))); return; } + g_assert (words); - for (i = 0; args[i] || words[i]; i++) { - g_assert (args[i]); - g_assert (words[i]); - g_assert (args[i][0]); - g_assert (escape || NM_STRCHAR_ALL (args[i], ch, !NM_IN_SET (ch, ' ', '\t', '\n'))); - g_assert_cmpstr (args[i], ==, words[i]); + for (i = 0; i < words_len; i++) + g_assert_cmpstr (exp_words[i], ==, words[i]); + g_assert (words[words_len] == NULL); + + g_assert (_nm_utils_strv_cmp_n (exp_words, words_len, words, -1) == 0); + + s1 = words[0]; + g_assert (s1 >= (char *) &words[words_len + 1]); + s1 = &s1[strlen (str)]; + for (i = 1; i < words_len; i++) { + g_assert (&(words[i - 1])[strlen (words[i - 1])] < words[i]); + g_assert (words[i] <= s1); + } + + /* while strsplit removes all delimiters, we can relatively easily find them + * in the original string. Assert that the original string and the pointer offsets + * of words correspond. In particular, find idx_delim_after and idx_delim_before + * to determine which delimiter was after/before a word. */ + { + gsize idx_word_start; + gsize idx_delim_after_old = G_MAXSIZE; + + idx_word_start = initial_offset; + for (i = 0; i < words_len; i++) { + const gsize l_i = strlen (words[i]); + gsize idx_delim_after; + gsize idx_delim_before; + + /* find the delimiter *after* words[i]. We can do that by looking at the next + * word and calculating the pointer difference. + * + * The delimiter after the very last word is '\0' and requires strlen() to find. */ + idx_delim_after = initial_offset + ((words[i] - words[0]) + l_i); + if (idx_delim_after != idx_word_start + l_i) { + g_assert (!f_preserve_empty); + g_assert_cmpint (idx_word_start + l_i, <, idx_delim_after); + idx_word_start = idx_delim_after - l_i; + } + if (i + 1 < words_len) { + gsize x = initial_offset + ((words[i + 1] - words[0]) - 1); + + if (idx_delim_after != x) { + g_assert (!f_preserve_empty); + g_assert_cmpint (idx_delim_after, <, x); + for (k = idx_delim_after; k <= x; k++) + g_assert (NM_IN_SET (str[k], DELIMITERS_C)); + } + g_assert (NM_IN_SET (str[idx_delim_after], DELIMITERS_C)); + } else { + if (f_preserve_empty) + g_assert (NM_IN_SET (str[idx_delim_after], '\0')); + else + g_assert (NM_IN_SET (str[idx_delim_after], '\0', DELIMITERS_C)); + } + + /* find the delimiter *before* words[i]. */ + if (i == 0) { + /* there is only a delimiter *before*, with !f_preserve_empty and leading + * delimiters. */ + idx_delim_before = G_MAXSIZE; + if (initial_offset > 0) { + g_assert (!f_preserve_empty); + idx_delim_before = initial_offset - 1; + } + } else + idx_delim_before = initial_offset + (words[i] - words[0]) - 1; + if (idx_delim_before != G_MAXSIZE) + g_assert (NM_IN_SET (str[idx_delim_before], DELIMITERS_C)); + if (idx_delim_after_old != idx_delim_before) { + g_assert (!f_preserve_empty); + if (i == 0) { + g_assert_cmpint (initial_offset, >, 0); + g_assert_cmpint (idx_delim_before, !=, G_MAXSIZE); + g_assert_cmpint (idx_delim_before, ==, initial_offset - 1); + } else { + g_assert_cmpint (idx_delim_after_old, !=, G_MAXSIZE); + g_assert_cmpint (idx_delim_before, !=, G_MAXSIZE); + g_assert_cmpint (idx_delim_after_old, <, idx_delim_before); + for (k = idx_delim_after_old; k <= idx_delim_before; k++) + g_assert (NM_IN_SET (str[k], DELIMITERS_C)); + } + } + + for (k = 0; k < l_i; ) { + if ( f_allow_escaping + && str[idx_word_start + k] == '\\') { + k++; + if (k >= l_i) + break; + k++; + continue; + } + g_assert (!NM_IN_SET (str[idx_word_start + k], DELIMITERS_C)); + k++; + } + g_assert (strncmp (words[i], &str[idx_word_start], l_i) == 0); + + if (i > 0) { + const char *s = &(words[i - 1])[strlen (words[i - 1]) + 1]; + + if (s != words[i]) { + g_assert (!f_preserve_empty); + g_assert (s < words[i]); + } + } + + idx_word_start += l_i + 1; + idx_delim_after_old = idx_delim_after; + } } } -#define do_test_nm_utils_strsplit_set(str, ...) \ - _do_test_nm_utils_strsplit_set (str, ##__VA_ARGS__, NULL) +static void +_do_test_nm_utils_strsplit_set_f (NMUtilsStrsplitSetFlags flags, + const char *str, + gsize words_len, + const char *const*exp_words) +{ + _do_test_nm_utils_strsplit_set_f_one (flags, str, words_len, exp_words); + + if (NM_FLAGS_HAS (flags, NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY)) { + gs_unref_ptrarray GPtrArray *exp_words2 = NULL; + gsize k; + + exp_words2 = g_ptr_array_new (); + for (k = 0; k < words_len; k++) { + if (exp_words[k][0] != '\0') + g_ptr_array_add (exp_words2, (gpointer) exp_words[k]); + } + + _do_test_nm_utils_strsplit_set_f_one (flags & (~NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY), + str, + exp_words2->len, + (const char *const*) exp_words2->pdata); + } +} + +#define do_test_nm_utils_strsplit_set_f(flags, str, ...) \ + _do_test_nm_utils_strsplit_set_f (flags, \ + str, \ + NM_NARG (__VA_ARGS__), \ + NM_MAKE_STRV (__VA_ARGS__)) + +#define do_test_nm_utils_strsplit_set(allow_escaping, str, ...) \ + do_test_nm_utils_strsplit_set_f ( (allow_escaping) \ + ? NM_UTILS_STRSPLIT_SET_FLAGS_ALLOW_ESCAPING \ + : NM_UTILS_STRSPLIT_SET_FLAGS_NONE, \ + str, \ + ##__VA_ARGS__) + +static void +_do_test_nm_utils_strsplit_set_simple (NMUtilsStrsplitSetFlags flags, + const char *str, + gsize words_len, + const char *const*exp_words) +{ + gs_free const char **tokens = NULL; + gsize n_tokens; + + tokens = nm_utils_strsplit_set_full (str, DELIMITERS, flags); + + if (!tokens) { + g_assert_cmpint (words_len, ==, 0); + return; + } + + g_assert (str && str[0]); + g_assert_cmpint (words_len, >, 0); + n_tokens = NM_PTRARRAY_LEN (tokens); + + if (_nm_utils_strv_cmp_n (exp_words, words_len, tokens, -1) != 0) { + gsize i; + + g_print (">>> split \"%s\" (flags %x) got %zu tokens (%zu expected)\n", str, (guint) flags, n_tokens, words_len); + for (i = 0; i < NM_MAX (n_tokens, words_len); i++) { + const char *s1 = i < n_tokens ? tokens[i] : NULL; + const char *s2 = i < words_len ? exp_words[i] : NULL; + + g_print (">>> [%zu]: %s - %s%s%s vs. %s%s%s\n", + i, + nm_streq0 (s1, s2) ? "same" : "diff", + NM_PRINT_FMT_QUOTE_STRING (s1), + NM_PRINT_FMT_QUOTE_STRING (s2)); + } + g_assert_not_reached (); + } + g_assert_cmpint (words_len, ==, NM_PTRARRAY_LEN (tokens)); +} +#define do_test_nm_utils_strsplit_set_simple(flags, str, ...) \ + _do_test_nm_utils_strsplit_set_simple ((flags), (str), NM_NARG (__VA_ARGS__), NM_MAKE_STRV (__VA_ARGS__)) static void test_nm_utils_strsplit_set (void) { + gs_unref_ptrarray GPtrArray *words_exp = NULL; + guint test_run; + + do_test_nm_utils_strsplit_set_f (NM_UTILS_STRSPLIT_SET_FLAGS_NONE, NULL); + do_test_nm_utils_strsplit_set_f (NM_UTILS_STRSPLIT_SET_FLAGS_NONE, ""); + do_test_nm_utils_strsplit_set_f (NM_UTILS_STRSPLIT_SET_FLAGS_NONE, " "); + do_test_nm_utils_strsplit_set_f (NM_UTILS_STRSPLIT_SET_FLAGS_NONE, "a b", "a", "b"); + + do_test_nm_utils_strsplit_set_f (NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, NULL); + do_test_nm_utils_strsplit_set_f (NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, ""); + do_test_nm_utils_strsplit_set_f (NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, " ", "", ""); + do_test_nm_utils_strsplit_set_f (NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, " ", "", "", ""); + do_test_nm_utils_strsplit_set_f (NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, "a ", "a", "", ""); + do_test_nm_utils_strsplit_set_f (NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, "a b", "a", "", "b"); + do_test_nm_utils_strsplit_set_f (NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, " ab b", "", "ab", "", "b"); + do_test_nm_utils_strsplit_set_f (NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, "ab b", "ab", "", "b"); + do_test_nm_utils_strsplit_set_f (NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, "abb", "abb"); + do_test_nm_utils_strsplit_set_f (NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, "abb bb ", "abb", "", "bb", ""); + do_test_nm_utils_strsplit_set_f (NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, "abb bcb ", "abb", "bcb", ""); + do_test_nm_utils_strsplit_set (FALSE, NULL); do_test_nm_utils_strsplit_set (FALSE, ""); - do_test_nm_utils_strsplit_set (FALSE, "\t"); - do_test_nm_utils_strsplit_set (FALSE, " \t\n"); + do_test_nm_utils_strsplit_set (FALSE, "\n"); + do_test_nm_utils_strsplit_set (TRUE, " \t\n", "\t"); do_test_nm_utils_strsplit_set (FALSE, "a", "a"); do_test_nm_utils_strsplit_set (FALSE, "a b", "a", "b"); do_test_nm_utils_strsplit_set (FALSE, "a\rb", "a\rb"); @@ -300,6 +596,76 @@ test_nm_utils_strsplit_set (void) do_test_nm_utils_strsplit_set (TRUE, "foo\\", "foo\\"); do_test_nm_utils_strsplit_set (TRUE, "bar foo\\", "bar", "foo\\"); do_test_nm_utils_strsplit_set (TRUE, "\\ a b\\ \\ c", "\\ a", "b\\ \\ ", "c"); + + words_exp = g_ptr_array_new_with_free_func (g_free); + for (test_run = 0; test_run < 100; test_run++) { + gboolean f_allow_escaping = nmtst_get_rand_bool (); + guint words_len = nmtst_get_rand_int () % 100; + gs_free char *str = NULL; + guint i; + + g_ptr_array_set_size (words_exp, 0); + for (i = 0; i < words_len; i++) { + guint word_len; + char *word; + guint j; + + word_len = nmtst_get_rand_int (); + if ((word_len % 100) < 30) + word_len = 0; + else + word_len = (word_len >> 10) % 100; + word = g_new (char, word_len + 3); + for (j = 0; j < word_len; ) { + guint32 p = nmtst_get_rand_int (); + static const char delimiters_arr[] = { DELIMITERS_C }; + static const char regular_chars[] = "abcdefghijklmnopqrstuvwxyz"; + + if ( !f_allow_escaping + || (p % 1000) < 700) { + if (((p >> 20) % 100) < 20) + word[j++] = '\\'; + word[j++] = regular_chars[(p >> 11) % (G_N_ELEMENTS (regular_chars) - 1)]; + continue; + } + word[j++] = '\\'; + word[j++] = delimiters_arr[(p >> 11) % G_N_ELEMENTS (delimiters_arr)]; + } + word[j] = '\0'; + g_ptr_array_add (words_exp, word); + } + g_ptr_array_add (words_exp, NULL); + + str = g_strjoinv (" ", (char **) words_exp->pdata); + + if ( str[0] == '\0' + && words_len > 0) { + g_assert (words_len == 1); + g_assert_cmpstr (words_exp->pdata[0], ==, ""); + words_len = 0; + } + + _do_test_nm_utils_strsplit_set_f ( (f_allow_escaping ? NM_UTILS_STRSPLIT_SET_FLAGS_ALLOW_ESCAPING : NM_UTILS_STRSPLIT_SET_FLAGS_NONE) + | NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, + str, + words_len, + (const char *const*) words_exp->pdata); + } + + do_test_nm_utils_strsplit_set_simple (NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED, "\t", "\t"); + do_test_nm_utils_strsplit_set_simple (NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED | NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP, "\t"); + do_test_nm_utils_strsplit_set_simple (NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED | NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP | NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, + "\t", ""); + do_test_nm_utils_strsplit_set_simple (NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED | NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP | NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, + "\t\\\t\t\t\\\t", "\t\t\t\t"); + + do_test_nm_utils_strsplit_set_simple (NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED, "\ta", "\ta"); + do_test_nm_utils_strsplit_set_simple (NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED | NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP, "\ta", "a"); + do_test_nm_utils_strsplit_set_simple (NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED, "\ta\\ b\t\\ ", "\ta b\t "); + do_test_nm_utils_strsplit_set_simple (NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED | NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP, "\ta\\ b\t\\ \t", "a b\t "); + do_test_nm_utils_strsplit_set_simple (NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED, "a\\ b", "a ", "b"); + do_test_nm_utils_strsplit_set_simple (NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED, "\ta\\ b", "\ta ", "b"); + do_test_nm_utils_strsplit_set_simple (NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED | NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP, "\ta\\ b", "a ", "b"); } /*****************************************************************************/ @@ -809,54 +1175,54 @@ test_setting_vpn_items (void) nm_setting_vpn_remove_data_item (s_vpn, "foobar4-flags"); /* Try to add some blank values and make sure they are rejected */ - NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key != NULL)); + NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0])); nm_setting_vpn_add_data_item (s_vpn, NULL, NULL); g_test_assert_expected_messages (); - NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (strlen (key) > 0)); + NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0])); nm_setting_vpn_add_data_item (s_vpn, "", ""); g_test_assert_expected_messages (); - NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (item != NULL)); + NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (item && item[0])); nm_setting_vpn_add_data_item (s_vpn, "foobar1", NULL); g_test_assert_expected_messages (); - NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (strlen (item) > 0)); + NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (item && item[0])); nm_setting_vpn_add_data_item (s_vpn, "foobar1", ""); g_test_assert_expected_messages (); - NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key != NULL)); + NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0])); nm_setting_vpn_add_data_item (s_vpn, NULL, "blahblah1"); g_test_assert_expected_messages (); - NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (strlen (key) > 0)); + NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0])); nm_setting_vpn_add_data_item (s_vpn, "", "blahblah1"); g_test_assert_expected_messages (); nm_setting_vpn_foreach_data_item (s_vpn, vpn_check_empty_func, NULL); /* Try to add some blank secrets and make sure they are rejected */ - NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key != NULL)); + NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0])); nm_setting_vpn_add_secret (s_vpn, NULL, NULL); g_test_assert_expected_messages (); - NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (strlen (key) > 0)); + NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0])); nm_setting_vpn_add_secret (s_vpn, "", ""); g_test_assert_expected_messages (); - NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (secret != NULL)); + NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (secret && secret[0])); nm_setting_vpn_add_secret (s_vpn, "foobar1", NULL); g_test_assert_expected_messages (); - NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (strlen (secret) > 0)); + NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (secret && secret[0])); nm_setting_vpn_add_secret (s_vpn, "foobar1", ""); g_test_assert_expected_messages (); - NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key != NULL)); + NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0])); nm_setting_vpn_add_secret (s_vpn, NULL, "blahblah1"); g_test_assert_expected_messages (); - NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (strlen (key) > 0)); + NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0])); nm_setting_vpn_add_secret (s_vpn, "", "blahblah1"); g_test_assert_expected_messages (); @@ -2347,7 +2713,7 @@ test_setting_connection_permissions_helpers (void) g_assert (!success); /* Ensure a bad [type] is rejected */ - NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (ptype)); + NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (ptype && ptype[0])); success = nm_setting_connection_add_permission (s_con, NULL, "blah", NULL); g_test_assert_expected_messages (); g_assert (!success); @@ -2687,6 +3053,7 @@ test_connection_diff_a_only (void) { NM_SETTING_IP_CONFIG_ROUTES, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_IP_CONFIG_ROUTE_METRIC, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_IP_CONFIG_ROUTE_TABLE, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_ROUTING_RULES, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, NM_SETTING_DIFF_RESULT_IN_A }, @@ -4713,6 +5080,7 @@ test_connection_normalize_infiniband_mtu (void) { gs_unref_object NMConnection *con = NULL; NMSettingInfiniband *s_infini; + guint mtu_regular = nmtst_rand_select (2044, 2045, 65520); con = nmtst_create_minimal_connection ("test_connection_normalize_infiniband_mtu", NULL, NM_SETTING_INFINIBAND_SETTING_NAME, NULL); @@ -4725,26 +5093,26 @@ test_connection_normalize_infiniband_mtu (void) g_object_set (s_infini, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", - NM_SETTING_INFINIBAND_MTU, (guint) 2044, + NM_SETTING_INFINIBAND_MTU, (guint) mtu_regular, NULL); nmtst_assert_connection_verifies_and_normalizable (con); nmtst_connection_normalize (con); - g_assert_cmpint (2044, ==, nm_setting_infiniband_get_mtu (s_infini)); + g_assert_cmpint (mtu_regular, ==, nm_setting_infiniband_get_mtu (s_infini)); g_object_set (s_infini, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", - NM_SETTING_INFINIBAND_MTU, (guint) 2045, + NM_SETTING_INFINIBAND_MTU, (guint) 65521, NULL); nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); nmtst_connection_normalize (con); - g_assert_cmpint (2044, ==, nm_setting_infiniband_get_mtu (s_infini)); + g_assert_cmpint (65520, ==, nm_setting_infiniband_get_mtu (s_infini)); g_object_set (s_infini, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected", - NM_SETTING_INFINIBAND_MTU, (guint) 65520, + NM_SETTING_INFINIBAND_MTU, (guint) mtu_regular, NULL); nmtst_assert_connection_verifies_without_normalization (con); - g_assert_cmpint (65520, ==, nm_setting_infiniband_get_mtu (s_infini)); + g_assert_cmpint (mtu_regular, ==, nm_setting_infiniband_get_mtu (s_infini)); g_object_set (s_infini, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected", @@ -5540,7 +5908,7 @@ _sock_addr_endpoint (const char *endpoint, SockAddrUnion sockaddr = { }; g_assert (endpoint); - g_assert (!host == (port == -1)); + g_assert ((!host) == (port == -1)); g_assert (port >= -1 && port <= G_MAXUINT16); ep = nm_sock_addr_endpoint_new (endpoint); @@ -7706,53 +8074,6 @@ test_ethtool_offload (void) g_assert_cmpstr (d->optname, ==, NM_ETHTOOL_OPTNAME_FEATURE_RXHASH); } -static void -test_nm_utils_escape_spaces (void) -{ - char *to_free; - - g_assert_cmpstr (_nm_utils_escape_spaces (NULL, &to_free), ==, NULL); - g_free (to_free); - - g_assert_cmpstr (_nm_utils_escape_spaces ("", &to_free), ==, ""); - g_free (to_free); - - g_assert_cmpstr (_nm_utils_escape_spaces (" ", &to_free), ==, "\\ "); - g_free (to_free); - - g_assert_cmpstr (_nm_utils_escape_spaces ("\t ", &to_free), ==, "\\\t\\ "); - g_free (to_free); - - g_assert_cmpstr (_nm_utils_escape_spaces ("abc", &to_free), ==, "abc"); - g_free (to_free); - - g_assert_cmpstr (_nm_utils_escape_spaces ("abc def", &to_free), ==, "abc\\ def"); - g_free (to_free); - - g_assert_cmpstr (_nm_utils_escape_spaces ("abc\tdef", &to_free), ==, "abc\\\tdef"); - g_free (to_free); -} - -static void -test_nm_utils_unescape_spaces (void) -{ -#define CHECK_STR(in, out) \ - G_STMT_START { \ - gs_free char *str = g_strdup (in); \ - \ - g_assert_cmpstr (_nm_utils_unescape_spaces (str), ==, out); \ - } G_STMT_END - - CHECK_STR ("\\a", "\\a"); - CHECK_STR ("foobar", "foobar"); - CHECK_STR ("foo bar", "foo bar"); - CHECK_STR ("foo\\ bar", "foo bar"); - CHECK_STR ("foo\\", "foo\\"); - CHECK_STR ("\\\\\t", "\\\t"); - -#undef CHECK_STR -} - /*****************************************************************************/ NMTST_DEFINE (); @@ -7761,6 +8082,7 @@ int main (int argc, char **argv) { nmtst_init (&argc, &argv, TRUE); + g_test_add_func ("/core/general/test_nm_ascii_spaces", test_nm_ascii_spaces); g_test_add_func ("/core/general/test_nm_hash", test_nm_hash); g_test_add_func ("/core/general/test_nm_g_slice_free_fcn", test_nm_g_slice_free_fcn); g_test_add_func ("/core/general/test_c_list_sort", test_c_list_sort); @@ -7905,8 +8227,6 @@ int main (int argc, char **argv) g_test_add_func ("/core/general/_nm_utils_dns_option_find_idx", test_nm_utils_dns_option_find_idx); g_test_add_func ("/core/general/_nm_utils_validate_json", test_nm_utils_check_valid_json); g_test_add_func ("/core/general/_nm_utils_team_config_equal", test_nm_utils_team_config_equal); - g_test_add_func ("/core/general/_nm_utils_escape_spaces", test_nm_utils_escape_spaces); - g_test_add_func ("/core/general/_nm_utils_unescape_spaces", test_nm_utils_unescape_spaces); g_test_add_func ("/core/general/test_nm_utils_enum", test_nm_utils_enum); g_test_add_func ("/core/general/nm-set-out", test_nm_set_out); g_test_add_func ("/core/general/route_attributes/parse", test_route_attributes_parse); diff --git a/libnm-core/tests/test-keyfile.c b/libnm-core/tests/test-keyfile.c index 9b9d1c04..157e8f18 100644 --- a/libnm-core/tests/test-keyfile.c +++ b/libnm-core/tests/test-keyfile.c @@ -744,6 +744,102 @@ test_vpn_1 (void) /*****************************************************************************/ +static void +test_bridge_vlans (void) +{ + gs_unref_keyfile GKeyFile *keyfile = NULL; + gs_unref_object NMConnection *con = NULL; + NMSettingBridge *s_bridge; + NMBridgeVlan *vlan; + guint16 vid, vid_end; + + con = nmtst_create_connection_from_keyfile ( + "[connection]\n" + "id=t\n" + "type=bridge\n" + "interface-name=br4\n" + "\n" + "[bridge]\n" + "vlans=900 , 1 pvid untagged, 100-123 untagged\n" + "", + "/test_bridge_port/vlans"); + s_bridge = NM_SETTING_BRIDGE (nm_connection_get_setting (con, NM_TYPE_SETTING_BRIDGE)); + g_assert (s_bridge); + g_assert_cmpuint (nm_setting_bridge_get_num_vlans (s_bridge), ==, 3); + + vlan = nm_setting_bridge_get_vlan (s_bridge, 0); + g_assert (vlan); + nm_bridge_vlan_get_vid_range (vlan, &vid, &vid_end); + g_assert_cmpuint (vid, ==, 1); + g_assert_cmpuint (vid_end, ==, 1); + g_assert_cmpint (nm_bridge_vlan_is_pvid (vlan), ==, TRUE); + g_assert_cmpint (nm_bridge_vlan_is_untagged (vlan), ==, TRUE); + + vlan = nm_setting_bridge_get_vlan (s_bridge, 1); + g_assert (vlan); + nm_bridge_vlan_get_vid_range (vlan, &vid, &vid_end); + g_assert_cmpuint (vid, ==, 100); + g_assert_cmpuint (vid_end, ==, 123); + g_assert_cmpint (nm_bridge_vlan_is_pvid (vlan), ==, FALSE); + g_assert_cmpint (nm_bridge_vlan_is_untagged (vlan), ==, TRUE); + + vlan = nm_setting_bridge_get_vlan (s_bridge, 2); + g_assert (vlan); + nm_bridge_vlan_get_vid_range (vlan, &vid, &vid_end); + g_assert_cmpuint (vid, ==, 900); + g_assert_cmpuint (vid_end, ==, 900); + g_assert_cmpint (nm_bridge_vlan_is_pvid (vlan), ==, FALSE); + g_assert_cmpint (nm_bridge_vlan_is_untagged (vlan), ==, FALSE); + + CLEAR (&con, &keyfile); +} + +static void +test_bridge_port_vlans (void) +{ + gs_unref_keyfile GKeyFile *keyfile = NULL; + gs_unref_object NMConnection *con = NULL; + NMSettingBridgePort *s_port; + NMBridgeVlan *vlan; + guint16 vid_start, vid_end; + + con = nmtst_create_connection_from_keyfile ( + "[connection]\n" + "id=t\n" + "type=dummy\n" + "interface-name=dummy1\n" + "master=br0\n" + "slave-type=bridge\n" + "\n" + "[bridge-port]\n" + "vlans=4094 pvid , 10-20 untagged\n" + "", + "/test_bridge_port/vlans"); + s_port = NM_SETTING_BRIDGE_PORT (nm_connection_get_setting (con, NM_TYPE_SETTING_BRIDGE_PORT)); + g_assert (s_port); + g_assert_cmpuint (nm_setting_bridge_port_get_num_vlans (s_port), ==, 2); + + vlan = nm_setting_bridge_port_get_vlan (s_port, 0); + g_assert (vlan); + nm_bridge_vlan_get_vid_range (vlan, &vid_start, &vid_end); + g_assert_cmpuint (vid_start, ==, 10); + g_assert_cmpuint (vid_end, ==, 20); + g_assert_cmpint (nm_bridge_vlan_is_pvid (vlan), ==, FALSE); + g_assert_cmpint (nm_bridge_vlan_is_untagged (vlan), ==, TRUE); + + vlan = nm_setting_bridge_port_get_vlan (s_port, 1); + g_assert (vlan); + nm_bridge_vlan_get_vid_range (vlan, &vid_start, &vid_end); + g_assert_cmpuint (vid_start, ==, 4094); + g_assert_cmpuint (vid_end, ==, 4094); + g_assert_cmpint (nm_bridge_vlan_is_pvid (vlan), ==, TRUE); + g_assert_cmpint (nm_bridge_vlan_is_untagged (vlan), ==, FALSE); + + CLEAR (&con, &keyfile); +} + +/*****************************************************************************/ + NMTST_DEFINE (); int main (int argc, char **argv) @@ -757,6 +853,8 @@ int main (int argc, char **argv) g_test_add_func ("/core/keyfile/test_team_conf_read/invalid", test_team_conf_read_invalid); g_test_add_func ("/core/keyfile/test_user/1", test_user_1); g_test_add_func ("/core/keyfile/test_vpn/1", test_vpn_1); + g_test_add_func ("/core/keyfile/bridge/vlans", test_bridge_vlans); + g_test_add_func ("/core/keyfile/bridge-port/vlans", test_bridge_port_vlans); return g_test_run (); } diff --git a/libnm-core/tests/test-setting.c b/libnm-core/tests/test-setting.c index 2011273a..03100a03 100644 --- a/libnm-core/tests/test-setting.c +++ b/libnm-core/tests/test-setting.c @@ -20,6 +20,7 @@ #include "nm-default.h" #include <linux/pkt_sched.h> +#include <net/if.h> #include "nm-utils.h" #include "nm-utils-private.h" @@ -1658,6 +1659,76 @@ test_sriov_parse_vlans (void) test_sriov_parse_vlan_one ("1.2.ad;2.0.q;5;3", TRUE, {1, 2, 1}, {2, 0, 0}, {3, 0, 0}, {5, 0, 0}); } +static void +test_bridge_vlans (void) +{ + NMBridgeVlan *v1, *v2; + GError *error = NULL; + guint16 vid_start, vid_end; + char *str; + + v1 = nm_bridge_vlan_from_str ("1 foobar", &error); + nmtst_assert_no_success (v1, error); + g_clear_error (&error); + + v1 = nm_bridge_vlan_from_str ("4095", &error); + nmtst_assert_no_success (v1, error); + g_clear_error (&error); + + /* test ranges */ + v1 = nm_bridge_vlan_from_str ("2-1000 untagged", &error); + nmtst_assert_success (v1, error); + g_assert_cmpint (nm_bridge_vlan_get_vid_range (v1, &vid_start, &vid_end), ==, TRUE); + g_assert_cmpuint (vid_start, ==, 2); + g_assert_cmpuint (vid_end, ==, 1000); + g_assert_cmpint (nm_bridge_vlan_is_pvid (v1), ==, FALSE); + g_assert_cmpint (nm_bridge_vlan_is_untagged (v1), ==, TRUE); + nm_bridge_vlan_unref (v1); + + /* test comparison (1) */ + v1 = nm_bridge_vlan_from_str ("10 untagged", &error); + nmtst_assert_success (v1, error); + + g_assert_cmpint (nm_bridge_vlan_get_vid_range (v1, &vid_start, &vid_end), ==, FALSE); + g_assert_cmpuint (vid_start, ==, 10); + g_assert_cmpuint (vid_end, ==, 10); + g_assert_cmpint (nm_bridge_vlan_is_sealed (v1), ==, FALSE); + g_assert_cmpint (nm_bridge_vlan_is_pvid (v1), ==, FALSE); + g_assert_cmpint (nm_bridge_vlan_is_untagged (v1), ==, TRUE); + + nm_bridge_vlan_set_pvid (v1, TRUE); + nm_bridge_vlan_set_untagged (v1, FALSE); + nm_bridge_vlan_seal (v1); + + g_assert_cmpint (nm_bridge_vlan_is_sealed (v1), ==, TRUE); + g_assert_cmpint (nm_bridge_vlan_is_pvid (v1), ==, TRUE); + g_assert_cmpint (nm_bridge_vlan_is_untagged (v1), ==, FALSE); + + str = nm_bridge_vlan_to_str (v1, &error); + nmtst_assert_success (str, error); + g_assert_cmpstr (str, ==, "10 pvid"); + g_clear_pointer (&str, g_free); + + v2 = nm_bridge_vlan_from_str (" 10 pvid ", &error); + nmtst_assert_success (v2, error); + + g_assert_cmpint (nm_bridge_vlan_cmp (v1, v2), ==, 0); + + nm_bridge_vlan_unref (v1); + nm_bridge_vlan_unref (v2); + + /* test comparison (2) */ + v1 = nm_bridge_vlan_from_str ("10", &error); + nmtst_assert_success (v1, error); + v2 = nm_bridge_vlan_from_str ("20", &error); + nmtst_assert_success (v2, error); + + g_assert_cmpint (nm_bridge_vlan_cmp (v1, v2), <, 0); + + nm_bridge_vlan_unref (v1); + nm_bridge_vlan_unref (v2); +} + /*****************************************************************************/ static void @@ -2304,7 +2375,16 @@ test_roundtrip_conversion (gconstpointer test_data) NMSettingConnection *s_con = NULL; NMSettingWired *s_eth = NULL; NMSettingWireGuard *s_wg = NULL; + union { + struct { + NMSettingIPConfig *s_6; + NMSettingIPConfig *s_4; + }; + NMSettingIPConfig *s_x[2]; + } s_ip; + int is_ipv4; guint i; + gboolean success; switch (MODE) { case 0: @@ -2491,6 +2571,89 @@ test_roundtrip_conversion (gconstpointer test_data) _rndt_wg_peers_assert_equal (s_wg, wg_peers, TRUE, TRUE, FALSE); break; + case 3: + con = nmtst_create_minimal_connection (ID, UUID, NM_SETTING_WIRED_SETTING_NAME, &s_con); + g_object_set (s_con, + NM_SETTING_CONNECTION_INTERFACE_NAME, + INTERFACE_NAME, + NULL); + nmtst_connection_normalize (con); + + s_eth = NM_SETTING_WIRED (nm_connection_get_setting (con, NM_TYPE_SETTING_WIRED)); + g_assert (NM_IS_SETTING_WIRED (s_eth)); + + g_object_set (s_eth, + NM_SETTING_WIRED_MTU, + ETH_MTU, + NULL); + + s_ip.s_4 = NM_SETTING_IP_CONFIG (nm_connection_get_setting (con, NM_TYPE_SETTING_IP4_CONFIG)); + g_assert (NM_IS_SETTING_IP4_CONFIG (s_ip.s_4)); + + s_ip.s_6 = NM_SETTING_IP_CONFIG (nm_connection_get_setting (con, NM_TYPE_SETTING_IP6_CONFIG)); + g_assert (NM_IS_SETTING_IP6_CONFIG (s_ip.s_6)); + + for (is_ipv4 = 0; is_ipv4 < 2; is_ipv4++) { + g_assert (NM_IS_SETTING_IP_CONFIG (s_ip.s_x[is_ipv4])); + for (i = 0; i < 3; i++) { + char addrstr[NM_UTILS_INET_ADDRSTRLEN]; + + nm_auto_unref_ip_routing_rule NMIPRoutingRule *rr = NULL; + + rr = nm_ip_routing_rule_new (is_ipv4 ? AF_INET : AF_INET6); + nm_ip_routing_rule_set_priority (rr, i + 1); + if (i > 0) { + if (is_ipv4) + nm_sprintf_buf (addrstr, "192.168.%u.0", i); + else + nm_sprintf_buf (addrstr, "1:2:3:%x::", 10 + i); + nm_ip_routing_rule_set_from (rr, addrstr, is_ipv4 ? 24 + i : 64 + i); + } + nm_ip_routing_rule_set_table (rr, 1000 + i); + + success = nm_ip_routing_rule_validate (rr, &error); + nmtst_assert_success (success, error); + + nm_setting_ip_config_add_routing_rule (s_ip.s_x[is_ipv4], rr); + } + } + + g_ptr_array_add (kf_data_arr, + g_strdup_printf ("[connection]\n" + "id=%s\n" + "uuid=%s\n" + "type=ethernet\n" + "interface-name=%s\n" + "permissions=\n" + "\n" + "[ethernet]\n" + "mac-address-blacklist=\n" + "%s" /* mtu */ + "\n" + "[ipv4]\n" + "dns-search=\n" + "method=auto\n" + "routing-rule1=priority 1 from 0.0.0.0/0 table 1000\n" + "routing-rule2=priority 2 from 192.168.1.0/25 table 1001\n" + "routing-rule3=priority 3 from 192.168.2.0/26 table 1002\n" + "\n" + "[ipv6]\n" + "addr-gen-mode=stable-privacy\n" + "dns-search=\n" + "method=auto\n" + "routing-rule1=priority 1 from ::/0 table 1000\n" + "routing-rule2=priority 2 from 1:2:3:b::/65 table 1001\n" + "routing-rule3=priority 3 from 1:2:3:c::/66 table 1002\n" + "", + ID, + UUID, + INTERFACE_NAME, + (ETH_MTU != 0) + ? nm_sprintf_bufa (100, "mtu=%u\n", ETH_MTU) + : "")); + + break; + default: g_assert_not_reached (); } @@ -2618,6 +2781,204 @@ test_roundtrip_conversion (gconstpointer test_data) /*****************************************************************************/ +static NMIPRoutingRule * +_rr_from_str_get_impl (const char *str, const char *const*aliases) +{ + nm_auto_unref_ip_routing_rule NMIPRoutingRule *rr = NULL; + gs_free_error GError *error = NULL; + gboolean vbool; + int addr_family; + int i; + NMIPRoutingRuleAsStringFlags to_string_flags; + + rr = nm_ip_routing_rule_from_string (str, + NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE, + NULL, + &error); + nmtst_assert_success (rr, error); + + addr_family = nm_ip_routing_rule_get_addr_family (rr); + g_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6)); + + if (addr_family == AF_INET) + to_string_flags = NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET; + else + to_string_flags = NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET6; + + for (i = 0; TRUE; i++) { + nm_auto_unref_ip_routing_rule NMIPRoutingRule *rr2 = NULL; + gs_free char *str1 = NULL; + gs_unref_variant GVariant *variant1 = NULL; + const char *cstr1; + + switch (i) { + case 0: + rr2 = nm_ip_routing_rule_ref (rr); + break; + + case 1: + rr2 = nm_ip_routing_rule_from_string (str, + NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE + | (nmtst_get_rand_bool () ? to_string_flags : NM_IP_ROUTING_RULE_AS_STRING_FLAGS_NONE), + NULL, + &error); + nmtst_assert_success (rr, error); + break; + + case 2: + str1 = nm_ip_routing_rule_to_string (rr, + NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE + | (nmtst_get_rand_bool () ? to_string_flags : NM_IP_ROUTING_RULE_AS_STRING_FLAGS_NONE), + NULL, + &error); + nmtst_assert_success (str1 && str1[0], error); + + g_assert_cmpstr (str, ==, str1); + + rr2 = nm_ip_routing_rule_from_string (str1, + NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE + | (nmtst_get_rand_bool () ? to_string_flags : NM_IP_ROUTING_RULE_AS_STRING_FLAGS_NONE), + NULL, + &error); + nmtst_assert_success (rr, error); + break; + + case 3: + variant1 = nm_ip_routing_rule_to_dbus (rr); + g_assert (variant1); + g_assert (g_variant_is_floating (variant1)); + g_assert (g_variant_is_of_type (variant1, G_VARIANT_TYPE_VARDICT)); + + rr2 = nm_ip_routing_rule_from_dbus (variant1, + TRUE, + &error); + nmtst_assert_success (rr, error); + break; + + default: + if (!aliases || !aliases[0]) + goto done; + cstr1 = (aliases++)[0]; + rr2 = nm_ip_routing_rule_from_string (cstr1, + NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE + | (nmtst_get_rand_bool () ? to_string_flags : NM_IP_ROUTING_RULE_AS_STRING_FLAGS_NONE), + NULL, + &error); + nmtst_assert_success (rr, error); + break; + } + + g_assert (rr2); + vbool = nm_ip_routing_rule_validate (rr, &error); + nmtst_assert_success (vbool, error); + vbool = nm_ip_routing_rule_validate (rr2, &error); + nmtst_assert_success (vbool, error); + + g_assert_cmpint (nm_ip_routing_rule_cmp (rr, rr2), ==, 0); + g_assert_cmpint (nm_ip_routing_rule_cmp (rr2, rr), ==, 0); + } + +done: + return g_steal_pointer (&rr); +} +#define _rr_from_str_get(a, ...) _rr_from_str_get_impl (a, &(NM_MAKE_STRV (NULL, ##__VA_ARGS__))[1]) + +#define _rr_from_str(...) \ + G_STMT_START { \ + nm_auto_unref_ip_routing_rule NMIPRoutingRule *_rr = NULL; \ + \ + _rr = _rr_from_str_get (__VA_ARGS__); \ + g_assert (_rr); \ + } G_STMT_END + +static void +test_routing_rule (gconstpointer test_data) +{ + nm_auto_unref_ip_routing_rule NMIPRoutingRule *rr1 = NULL; + gboolean success; + char ifname_buf[16]; + + _rr_from_str ("priority 5 from 0.0.0.0 table 1", + " from 0.0.0.0 priority 5 lookup 1 "); + _rr_from_str ("priority 5 from 0.0.0.0/0 table 4"); + _rr_from_str ("priority 5 to 0.0.0.0 table 6"); + _rr_from_str ("priority 5 to 0.0.0.0 table 254", + "priority 5 to 0.0.0.0/32"); + _rr_from_str ("priority 5 from 1.2.3.4 table 15", + "priority 5 from 1.2.3.4/32 table 0xF ", + "priority 5 from 1.2.3.4/32 to 0.0.0.0/0 lookup 15 "); + _rr_from_str ("priority 5 from 1.2.3.4 to 0.0.0.0 table 8"); + _rr_from_str ("priority 5 to a:b:c:: tos 0x16 table 25", + "priority 5 to a:b:c::/128 table 0x19 tos 16", + "priority 5 to a:b:c::/128 lookup 0x19 dsfield 16", + "priority 5 to a:b:c::/128 lookup 0x19 dsfield 16 fwmark 0/0x00", + "priority 5 to a:b:c:: from all lookup 0x19 dsfield 16 fwmark 0x0/0"); + _rr_from_str ("priority 5 from :: fwmark 0 table 25", + "priority 5 from ::/128 to all table 0x19 fwmark 0/0xFFFFFFFF", + "priority 5 from :: to ::/0 table 0x19 fwmark 0x00/4294967295"); + _rr_from_str ("priority 5 from :: iif aab table 25"); + _rr_from_str ("priority 5 from :: iif aab oif er table 25", + "priority 5 from :: table 0x19 dev aab oif er"); + _rr_from_str ("priority 5 from :: iif a\\\\303b table 25"); + _rr_from_str ("priority 5 to 0.0.0.0 sport 10 table 6", + "priority 5 to 0.0.0.0 sport 10-10 table 6"); + _rr_from_str ("not priority 5 to 0.0.0.0 dport 10-133 table 6", + "priority 5 to 0.0.0.0 not dport 10-133 not table 6", + "priority 5 to 0.0.0.0 not dport 10-\\ 133 not table 6"); + _rr_from_str ("priority 5 to 0.0.0.0 ipproto 10 sport 10 table 6"); + + rr1 = _rr_from_str_get ("priority 5 from :: iif aab table 25"); + g_assert_cmpstr (nm_ip_routing_rule_get_iifname (rr1), ==, "aab"); + success = nm_ip_routing_rule_get_xifname_bin (rr1, FALSE, ifname_buf); + g_assert (!success); + success = nm_ip_routing_rule_get_xifname_bin (rr1, TRUE, ifname_buf); + g_assert_cmpstr (ifname_buf, ==, "aab"); + g_assert (success); + nm_clear_pointer (&rr1, nm_ip_routing_rule_unref); + + rr1 = _rr_from_str_get ("priority 5 from :: iif a\\\\303\\\\261xb table 254"); + g_assert_cmpstr (nm_ip_routing_rule_get_iifname (rr1), ==, "a\\303\\261xb"); + success = nm_ip_routing_rule_get_xifname_bin (rr1, FALSE, ifname_buf); + g_assert (!success); + success = nm_ip_routing_rule_get_xifname_bin (rr1, TRUE, ifname_buf); + g_assert_cmpstr (ifname_buf, ==, "a\303\261xb"); + g_assert (success); + nm_clear_pointer (&rr1, nm_ip_routing_rule_unref); + + rr1 = _rr_from_str_get ("priority 5 from :: oif \\\\101=\\\\303\\\\261xb table 7"); + g_assert_cmpstr (nm_ip_routing_rule_get_oifname (rr1), ==, "\\101=\\303\\261xb"); + success = nm_ip_routing_rule_get_xifname_bin (rr1, FALSE, ifname_buf); + g_assert_cmpstr (ifname_buf, ==, "A=\303\261xb"); + g_assert (success); + success = nm_ip_routing_rule_get_xifname_bin (rr1, TRUE, ifname_buf); + g_assert (!success); + nm_clear_pointer (&rr1, nm_ip_routing_rule_unref); + + rr1 = _rr_from_str_get ("priority 5 to 0.0.0.0 tos 0x10 table 7"); + g_assert_cmpstr (NULL, ==, nm_ip_routing_rule_get_from (rr1)); + g_assert (!nm_ip_routing_rule_get_from_bin (rr1)); + g_assert_cmpint (0, ==, nm_ip_routing_rule_get_from_len (rr1)); + g_assert_cmpstr ("0.0.0.0", ==, nm_ip_routing_rule_get_to (rr1)); + g_assert (nm_ip_addr_is_null (AF_INET, nm_ip_routing_rule_get_to_bin (rr1))); + g_assert_cmpint (32, ==, nm_ip_routing_rule_get_to_len (rr1)); + g_assert_cmpint (7, ==, nm_ip_routing_rule_get_table (rr1)); + g_assert_cmpint (0x10, ==, nm_ip_routing_rule_get_tos (rr1)); + nm_clear_pointer (&rr1, nm_ip_routing_rule_unref); + + rr1 = _rr_from_str_get ("priority 5 from :: iif a\\\\303\\\\261,x;b table 254", + "priority 5 from :: iif a\\\\303\\\\261,x;b table 254"); + g_assert_cmpstr (nm_ip_routing_rule_get_iifname (rr1), ==, "a\\303\\261,x;b"); + success = nm_ip_routing_rule_get_xifname_bin (rr1, FALSE, ifname_buf); + g_assert (!success); + success = nm_ip_routing_rule_get_xifname_bin (rr1, TRUE, ifname_buf); + g_assert_cmpstr (ifname_buf, ==, "a\303\261,x;b"); + g_assert (success); + nm_clear_pointer (&rr1, nm_ip_routing_rule_unref); + +} + +/*****************************************************************************/ + NMTST_DEFINE (); int @@ -2663,6 +3024,8 @@ main (int argc, char **argv) g_test_add_func ("/libnm/settings/tc_config/setting/duplicates", test_tc_config_setting_duplicates); g_test_add_func ("/libnm/settings/tc_config/dbus", test_tc_config_dbus); + g_test_add_func ("/libnm/settings/bridge/vlans", test_bridge_vlans); + #if WITH_JSON_VALIDATION g_test_add_func ("/libnm/settings/team/sync_runner_from_config_roundrobin", test_runner_roundrobin_sync_from_config); @@ -2694,9 +3057,12 @@ main (int argc, char **argv) g_test_add_func ("/libnm/settings/team-port/sycn_from_config_full", test_team_port_full_config); #endif - g_test_add_data_func ("/libnm/settings/roundtrip-conversion/general/0", GINT_TO_POINTER (0), test_roundtrip_conversion); + g_test_add_data_func ("/libnm/settings/roundtrip-conversion/general/0", GINT_TO_POINTER (0), test_roundtrip_conversion); g_test_add_data_func ("/libnm/settings/roundtrip-conversion/wireguard/1", GINT_TO_POINTER (1), test_roundtrip_conversion); g_test_add_data_func ("/libnm/settings/roundtrip-conversion/wireguard/2", GINT_TO_POINTER (2), test_roundtrip_conversion); + g_test_add_data_func ("/libnm/settings/roundtrip-conversion/general/3", GINT_TO_POINTER (3), test_roundtrip_conversion); + + g_test_add_data_func ("/libnm/settings/routing-rule/1", GINT_TO_POINTER (0), test_routing_rule); return g_test_run (); } |