diff options
Diffstat (limited to 'src/tests/test-general.c')
| -rw-r--r-- | src/tests/test-general.c | 437 |
1 files changed, 389 insertions, 48 deletions
diff --git a/src/tests/test-general.c b/src/tests/test-general.c index 1e7329d1..f065d127 100644 --- a/src/tests/test-general.c +++ b/src/tests/test-general.c @@ -22,12 +22,19 @@ #include <string.h> #include <errno.h> +#include <net/if.h> +#include <byteswap.h> /* need math.h for isinf() and INFINITY. No need to link with -lm */ #include <math.h> #include "NetworkManagerUtils.h" #include "nm-core-internal.h" +#include "nm-core-utils.h" +#include "systemd/nm-sd-utils-core.h" + +#include "dns/nm-dns-manager.h" +#include "nm-connectivity.h" #include "nm-test-utils-core.h" @@ -345,13 +352,13 @@ _match_connection (GSList *connections, gint64 default_v4_metric, gint64 default_v6_metric) { - NMConnection **list; + gs_free NMConnection **list = NULL; guint i, len; len = g_slist_length (connections); g_assert (len < 10); - list = g_alloca ((len + 1) * sizeof (NMConnection *)); + list = g_malloc ((len + 1) * sizeof (NMConnection *)); for (i = 0; i < len; i++, connections = connections->next) { g_assert (connections); g_assert (connections->data); @@ -1093,7 +1100,7 @@ static NMMatchSpecMatchType _test_match_spec_device (const GSList *specs, const char *match_str) { if (match_str && g_str_has_prefix (match_str, MATCH_S390)) - return nm_match_spec_device (specs, NULL, NULL, NULL, NULL, NULL, &match_str[NM_STRLEN (MATCH_S390)]); + return nm_match_spec_device (specs, NULL, NULL, NULL, NULL, NULL, &match_str[NM_STRLEN (MATCH_S390)], NULL); if (match_str && g_str_has_prefix (match_str, MATCH_DRIVER)) { gs_free char *s = g_strdup (&match_str[NM_STRLEN (MATCH_DRIVER)]); char *t; @@ -1103,13 +1110,16 @@ _test_match_spec_device (const GSList *specs, const char *match_str) t[0] = '\0'; t++; } - return nm_match_spec_device (specs, NULL, NULL, s, t, NULL, NULL); + return nm_match_spec_device (specs, NULL, NULL, s, t, NULL, NULL, NULL); } - return nm_match_spec_device (specs, match_str, NULL, NULL, NULL, NULL, NULL); + return nm_match_spec_device (specs, match_str, NULL, NULL, NULL, NULL, NULL, NULL); } static void -_do_test_match_spec_device (const char *spec_str, const char **matches, const char **no_matches, const char **neg_matches) +_do_test_match_spec_device (const char *spec_str, + const char *const *matches, + const char *const *no_matches, + const char *const *neg_matches) { GSList *specs, *specs_randperm = NULL, *specs_resplit, *specs_i, *specs_j; guint i; @@ -1181,98 +1191,100 @@ _do_test_match_spec_device (const char *spec_str, const char **matches, const ch static void test_match_spec_device (void) { -#define S(...) ((const char *[]) { __VA_ARGS__, NULL } ) _do_test_match_spec_device ("em1", - S ("em1"), + NM_MAKE_STRV ("em1"), NULL, NULL); _do_test_match_spec_device ("em1,em2", - S ("em1", "em2"), + NM_MAKE_STRV ("em1", "em2"), NULL, NULL); _do_test_match_spec_device ("em1,em2,interface-name:em2", - S ("em1", "em2"), + NM_MAKE_STRV ("em1", "em2"), NULL, NULL); _do_test_match_spec_device ("interface-name:em1", - S ("em1"), + NM_MAKE_STRV ("em1"), NULL, NULL); _do_test_match_spec_device ("interface-name:em*", - S ("em", "em*", "em\\", "em\\*", "em\\1", "em\\11", "em\\2", "em1", "em11", "em2", "em3"), + NM_MAKE_STRV ("em", "em*", "em\\", "em\\*", "em\\1", "em\\11", "em\\2", "em1", "em11", "em2", "em3"), NULL, NULL); _do_test_match_spec_device ("interface-name:em\\*", - S ("em\\", "em\\*", "em\\1", "em\\11", "em\\2"), + NM_MAKE_STRV ("em\\", "em\\*", "em\\1", "em\\11", "em\\2"), NULL, NULL); _do_test_match_spec_device ("interface-name:~em\\*", - S ("em\\", "em\\*", "em\\1", "em\\11", "em\\2"), + NM_MAKE_STRV ("em\\", "em\\*", "em\\1", "em\\11", "em\\2"), NULL, NULL); _do_test_match_spec_device ("except:*", NULL, - S (NULL), - S ("a")); + NM_MAKE_STRV (NULL), + NM_MAKE_STRV ("a")); _do_test_match_spec_device ("interface-name:=em*", - S ("em*"), + NM_MAKE_STRV ("em*"), NULL, NULL); _do_test_match_spec_device ("interface-name:em*,except:interface-name:em1*", - S ("em", "em*", "em\\", "em\\*", "em\\1", "em\\11", "em\\2", "em2", "em3"), + NM_MAKE_STRV ("em", "em*", "em\\", "em\\*", "em\\1", "em\\11", "em\\2", "em2", "em3"), NULL, - S ("em1", "em11")); + NM_MAKE_STRV ("em1", "em11")); _do_test_match_spec_device ("interface-name:em*,except:interface-name:=em*", - S ("em", "em\\", "em\\*", "em\\1", "em\\11", "em\\2", "em1", "em11", "em2", "em3"), + NM_MAKE_STRV ("em", "em\\", "em\\*", "em\\1", "em\\11", "em\\2", "em1", "em11", "em2", "em3"), NULL, - S ("em*")); + NM_MAKE_STRV ("em*")); + _do_test_match_spec_device ("except:interface-name:em*", + NM_MAKE_STRV ("", "eth", "eth1", "e1"), + NM_MAKE_STRV (NULL), + NM_MAKE_STRV ("em", "em\\", "em\\*", "em\\1", "em\\11", "em\\2", "em1", "em11", "em2", "em3")); _do_test_match_spec_device ("aa,bb,cc\\,dd,e,,", - S ("aa", "bb", "cc,dd", "e"), + NM_MAKE_STRV ("aa", "bb", "cc,dd", "e"), NULL, NULL); _do_test_match_spec_device ("aa;bb;cc\\;dd;e,;", - S ("aa", "bb", "cc;dd", "e"), + NM_MAKE_STRV ("aa", "bb", "cc;dd", "e"), NULL, NULL); _do_test_match_spec_device ("interface-name:em\\;1,em\\,2,\\,,\\\\,,em\\\\x", - S ("em;1", "em,2", ",", "\\", "em\\x"), + NM_MAKE_STRV ("em;1", "em,2", ",", "\\", "em\\x"), NULL, NULL); _do_test_match_spec_device ("\\s\\s,\\sinterface-name:a,\\s,", - S (" ", " ", " interface-name:a"), + NM_MAKE_STRV (" ", " ", " interface-name:a"), NULL, NULL); _do_test_match_spec_device (" aa ; bb ; cc\\;dd ;e , ; \t\\t , ", - S ("aa", "bb", "cc;dd", "e", "\t"), + NM_MAKE_STRV ("aa", "bb", "cc;dd", "e", "\t"), NULL, NULL); _do_test_match_spec_device ("s390-subchannels:0.0.1000\\,0.0.1001", - S (MATCH_S390"0.0.1000", MATCH_S390"0.0.1000,deadbeef", MATCH_S390"0.0.1000,0.0.1001", MATCH_S390"0.0.1000,0.0.1002"), - S (MATCH_S390"0.0.1001"), + NM_MAKE_STRV (MATCH_S390"0.0.1000", MATCH_S390"0.0.1000,deadbeef", MATCH_S390"0.0.1000,0.0.1001", MATCH_S390"0.0.1000,0.0.1002"), + NM_MAKE_STRV (MATCH_S390"0.0.1001"), NULL); _do_test_match_spec_device ("*,except:s390-subchannels:0.0.1000\\,0.0.1001", NULL, - S (NULL), - S (MATCH_S390"0.0.1000", MATCH_S390"0.0.1000,deadbeef", MATCH_S390"0.0.1000,0.0.1001", MATCH_S390"0.0.1000,0.0.1002")); + NM_MAKE_STRV (NULL), + NM_MAKE_STRV (MATCH_S390"0.0.1000", MATCH_S390"0.0.1000,deadbeef", MATCH_S390"0.0.1000,0.0.1001", MATCH_S390"0.0.1000,0.0.1002")); _do_test_match_spec_device ("driver:DRV", - S (MATCH_DRIVER"DRV", MATCH_DRIVER"DRV|1.6"), - S (MATCH_DRIVER"DR", MATCH_DRIVER"DR*"), + NM_MAKE_STRV (MATCH_DRIVER"DRV", MATCH_DRIVER"DRV|1.6"), + NM_MAKE_STRV (MATCH_DRIVER"DR", MATCH_DRIVER"DR*"), NULL); _do_test_match_spec_device ("driver:DRV//", - S (MATCH_DRIVER"DRV/"), - S (MATCH_DRIVER"DRV/|1.6", MATCH_DRIVER"DR", MATCH_DRIVER"DR*"), + NM_MAKE_STRV (MATCH_DRIVER"DRV/"), + NM_MAKE_STRV (MATCH_DRIVER"DRV/|1.6", MATCH_DRIVER"DR", MATCH_DRIVER"DR*"), NULL); _do_test_match_spec_device ("driver:DRV//*", - S (MATCH_DRIVER"DRV/", MATCH_DRIVER"DRV/|1.6"), - S (MATCH_DRIVER"DR", MATCH_DRIVER"DR*"), + NM_MAKE_STRV (MATCH_DRIVER"DRV/", MATCH_DRIVER"DRV/|1.6"), + NM_MAKE_STRV (MATCH_DRIVER"DR", MATCH_DRIVER"DR*"), NULL); _do_test_match_spec_device ("driver:DRV//1.5*", - S (MATCH_DRIVER"DRV/|1.5", MATCH_DRIVER"DRV/|1.5.2"), - S (MATCH_DRIVER"DRV/", MATCH_DRIVER"DRV/|1.6", MATCH_DRIVER"DR", MATCH_DRIVER"DR*"), + NM_MAKE_STRV (MATCH_DRIVER"DRV/|1.5", MATCH_DRIVER"DRV/|1.5.2"), + NM_MAKE_STRV (MATCH_DRIVER"DRV/", MATCH_DRIVER"DRV/|1.6", MATCH_DRIVER"DR", MATCH_DRIVER"DR*"), NULL); -#undef S } /*****************************************************************************/ @@ -1296,9 +1308,10 @@ _do_test_match_spec_config (const char *file, int line, const char *spec_str, gu match_result = nm_match_spec_config (specs, version, NULL); if (expected != match_result) - g_error ("%s:%d: faild comparing \"%s\" with %u.%u.%u. Expected %d, but got %d", file, line, spec_str, v_maj, v_min, v_mic, (int) expected, (int) match_result); + g_error ("%s:%d: failed comparing \"%s\" with %u.%u.%u. Expected %d, but got %d", file, line, spec_str, v_maj, v_min, v_mic, (int) expected, (int) match_result); - if (g_slist_length (specs) == 1 && match_result != NM_MATCH_SPEC_NEG_MATCH) { + if ( g_slist_length (specs) == 1 + && !g_str_has_prefix (specs->data, "except:")) { /* there is only one spec in the list... test that we match except: */ char *sss = g_strdup_printf ("except:%s", (char *) specs->data); GSList *specs2 = g_slist_append (NULL, sss); @@ -1306,7 +1319,7 @@ _do_test_match_spec_config (const char *file, int line, const char *spec_str, gu match_result2 = nm_match_spec_config (specs2, version, NULL); if (match_result == NM_MATCH_SPEC_NO_MATCH) - g_assert_cmpint (match_result2, ==, NM_MATCH_SPEC_NO_MATCH); + g_assert_cmpint (match_result2, ==, NM_MATCH_SPEC_MATCH); else g_assert_cmpint (match_result2, ==, NM_MATCH_SPEC_NEG_MATCH); @@ -1390,7 +1403,7 @@ test_match_spec_config (void) do_test_match_spec_config ("nm-version-max:1", 1, 4, 30, NM_MATCH_SPEC_MATCH); do_test_match_spec_config ("nm-version-max:1", 2, 4, 30, NM_MATCH_SPEC_NO_MATCH); - do_test_match_spec_config ("except:nm-version:1.4.8", 1, 6, 0, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_config ("except:nm-version:1.4.8", 1, 6, 0, NM_MATCH_SPEC_MATCH); do_test_match_spec_config ("nm-version-min:1.6,except:nm-version:1.4.8", 1, 6, 0, NM_MATCH_SPEC_MATCH); do_test_match_spec_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 2, 0, NM_MATCH_SPEC_NO_MATCH); @@ -1427,6 +1440,82 @@ test_nm_utils_strbuf_append (void) char buf[NM_STRLEN (BUF_ORIG) + 1]; char str[NM_STRLEN (BUF_ORIG) + 1]; +#define _strbuf_append(buf, len, format, ...) \ + G_STMT_START { \ + char **_buf = (buf); \ + gsize *_len = (len); \ + const char *_str_iter; \ + gs_free char *_str = NULL; \ + \ + switch (nmtst_get_rand_int () % 4) { \ + case 0: \ + nm_utils_strbuf_append (_buf, _len, (format), __VA_ARGS__); \ + break; \ + case 1: \ + _str = g_strdup_printf ((format), __VA_ARGS__); \ + nm_utils_strbuf_append_str (_buf, _len, _str); \ + break; \ + case 2: \ + _str = g_strdup_printf ((format), __VA_ARGS__); \ + nm_utils_strbuf_append_bin (_buf, _len, _str, strlen (_str)); \ + break; \ + case 3: \ + _str = g_strdup_printf ((format), __VA_ARGS__); \ + if (!_str[0]) \ + nm_utils_strbuf_append_str (_buf, _len, _str); \ + for (_str_iter = _str; _str_iter[0]; _str_iter++) \ + nm_utils_strbuf_append_c (_buf, _len, _str_iter[0]); \ + break; \ + } \ + } G_STMT_END + +#define _strbuf_append_str(buf, len, str) \ + G_STMT_START { \ + char **_buf = (buf); \ + gsize *_len = (len); \ + const char *_str = (str); \ + \ + switch (nmtst_get_rand_int () % 4) { \ + case 0: \ + nm_utils_strbuf_append (_buf, _len, "%s", _str ?: ""); \ + break; \ + case 1: \ + nm_utils_strbuf_append_str (_buf, _len, _str); \ + break; \ + case 2: \ + nm_utils_strbuf_append_bin (_buf, _len, _str, _str ? strlen (_str) : 0); \ + break; \ + case 3: \ + if (!_str || !_str[0]) \ + nm_utils_strbuf_append_str (_buf, _len, _str); \ + for (; _str && _str[0]; _str++) \ + nm_utils_strbuf_append_c (_buf, _len, _str[0]); \ + break; \ + } \ + } G_STMT_END + +#define _strbuf_append_c(buf, len, ch) \ + G_STMT_START { \ + char **_buf = (buf); \ + gsize *_len = (len); \ + char _ch = (ch); \ + \ + switch (nmtst_get_rand_int () % 4) { \ + case 0: \ + nm_utils_strbuf_append (_buf, _len, "%c", _ch); \ + break; \ + case 1: \ + nm_utils_strbuf_append_str (_buf, _len, ((char[2]) { _ch, 0 })); \ + break; \ + case 2: \ + nm_utils_strbuf_append_bin (_buf, _len, &_ch, 1); \ + break; \ + case 3: \ + nm_utils_strbuf_append_c (_buf, _len, _ch); \ + break; \ + } \ + } G_STMT_END + for (buf_len = 0; buf_len < 10; buf_len++) { for (rep = 0; rep < 50; rep++) { const int s_len = nmtst_get_rand_int () % (sizeof (str) - 5); @@ -1450,21 +1539,21 @@ test_nm_utils_strbuf_append (void) switch (test_mode) { case 0: if (s_len == 1) { - nm_utils_strbuf_append_c (&t_buf, &t_len, str[0]); + _strbuf_append_c (&t_buf, &t_len, str[0]); break; } /* fall through */ case 1: - nm_utils_strbuf_append_str (&t_buf, &t_len, str); + _strbuf_append_str (&t_buf, &t_len, str); break; case 2: if (s_len == 1) { - nm_utils_strbuf_append (&t_buf, &t_len, "%c", str[0]); + _strbuf_append (&t_buf, &t_len, "%c", str[0]); break; } /* fall through */ case 3: - nm_utils_strbuf_append (&t_buf, &t_len, "%s", str); + _strbuf_append (&t_buf, &t_len, "%s", str); break; case 4: g_snprintf (t_buf, t_len, "%s", str); @@ -1733,7 +1822,7 @@ do_test_stable_id_parse (const char *stable_id, else g_assert (stable_id); - stable_type = nm_utils_stable_id_parse (stable_id, "_DEVICE", "_BOOT", "_CONNECTION", &generated); + stable_type = nm_utils_stable_id_parse (stable_id, "_DEVICE", "_MAC", "_BOOT", "_CONNECTION", &generated); g_assert_cmpint (expected_stable_type, ==, stable_type); @@ -1772,6 +1861,7 @@ test_stable_id_parse (void) _parse_generated ("x${BOOT}", "x${BOOT}=5{_BOOT}"); _parse_generated ("x${BOOT}${CONNECTION}", "x${BOOT}=5{_BOOT}${CONNECTION}=11{_CONNECTION}"); _parse_generated ("xX${BOOT}yY${CONNECTION}zZ", "xX${BOOT}=5{_BOOT}yY${CONNECTION}=11{_CONNECTION}zZ"); + _parse_generated ("${MAC}x", "${MAC}=4{_MAC}x"); _parse_random ("${RANDOM}"); _parse_random (" ${RANDOM}"); _parse_random ("${BOOT}${RANDOM}"); @@ -1845,6 +1935,246 @@ test_nm_utils_exp10 (void) /*****************************************************************************/ +static void +test_utils_file_is_in_path (void) +{ + g_assert (!nm_utils_file_is_in_path ("/", "/")); + g_assert (!nm_utils_file_is_in_path ("//", "/")); + g_assert (!nm_utils_file_is_in_path ("/a/", "/")); + g_assert ( nm_utils_file_is_in_path ("/a", "/")); + g_assert ( nm_utils_file_is_in_path ("///a", "/")); + g_assert ( nm_utils_file_is_in_path ("//b/a", "/b//")); + g_assert ( nm_utils_file_is_in_path ("//b///a", "/b//")); + g_assert (!nm_utils_file_is_in_path ("//b///a/", "/b//")); + g_assert (!nm_utils_file_is_in_path ("//b///a/", "/b/a/")); + g_assert (!nm_utils_file_is_in_path ("//b///a", "/b/a/")); + g_assert ( nm_utils_file_is_in_path ("//b///a/.", "/b/a/")); + g_assert ( nm_utils_file_is_in_path ("//b///a/..", "/b/a/")); +} + +/*****************************************************************************/ + +#define _TEST_RC(searches, nameservers, options, expected) \ + G_STMT_START { \ + const char *const*const _searches = (searches); \ + const char *const*const _nameservers = (nameservers); \ + const char *const*const _options = (options); \ + gs_free char *_content = NULL; \ + \ + _content = nmtst_dns_create_resolv_conf (_searches, _nameservers, _options); \ + g_assert_cmpstr (_content, ==, expected); \ + } G_STMT_END + +static void +test_dns_create_resolv_conf (void) +{ + _TEST_RC (NM_MAKE_STRV ("a"), + NULL, + NULL, + "# Generated by NetworkManager\n" + "search a\n" + ""); + + _TEST_RC (NM_MAKE_STRV ("a", "b.com"), + NM_MAKE_STRV ("192.168.55.1", "192.168.56.1"), + NM_MAKE_STRV ("opt1", "opt2"), + "# Generated by NetworkManager\n" + "search a b.com\n" + "nameserver 192.168.55.1\n" + "nameserver 192.168.56.1\n" + "options opt1 opt2\n" + ""); + + _TEST_RC (NM_MAKE_STRV ("a2x456789.b2x456789.c2x456789.d2x456789.e2x456789.f2x456789.g2x456789.h2x456789.i2x456789.j2x4567890", + "a2y456789.b2y456789.c2y456789.d2y456789.e2y456789.f2y456789.g2y456789.h2y456789.i2y456789.j2y4567890", + "a2z456789.b2z456789.c2z456789.d2z456789.e2z456789.f2z456789.g2z456789.h2z456789.i2z456789.j2z4567890"), + NULL, + NULL, + "# Generated by NetworkManager\n" + "search a2x456789.b2x456789.c2x456789.d2x456789.e2x456789.f2x456789.g2x456789.h2x456789.i2x456789.j2x4567890 a2y456789.b2y456789.c2y456789.d2y456789.e2y456789.f2y456789.g2y456789.h2y456789.i2y456789.j2y4567890 a2z456789.b2z456789.c2z456789.d2z456789.e2z456789.f2z456789.g2z456789.h2z456789.i2z456789.j2z4567890\n" + ""); + +} + +/*****************************************************************************/ + +static void +test_machine_id_read (void) +{ + NMUuid machine_id_sd; + const NMUuid *machine_id; + char machine_id_str[33]; + gpointer logstate; + + logstate = nmtst_logging_disable (FALSE); + /* If you run this test as root, without a valid /etc/machine-id, + * the code will try to get the secret-key. That is a bit ugly, + * but no real problem. */ + machine_id = nm_utils_machine_id_bin (); + nmtst_logging_reenable (logstate); + + g_assert (machine_id); + g_assert (_nm_utils_bin2hexstr_full (machine_id, + sizeof (NMUuid), + '\0', + FALSE, + machine_id_str) == machine_id_str); + g_assert (strlen (machine_id_str) == 32); + g_assert_cmpstr (machine_id_str, ==, nm_utils_machine_id_str ()); + + /* double check with systemd's implementation... */ + if (!nm_sd_utils_id128_get_machine (&machine_id_sd)) { + /* if systemd failed to read /etc/machine-id, the file likely + * is invalid. Our machine-id is fake, and we have nothing to + * compare against. */ + + /* NOTE: this test will fail, if you don't have /etc/machine-id, + * but a valid "LOCALSTATEDIR/lib/dbus/machine-id" file. + * Just don't do that. */ + g_assert (nm_utils_machine_id_is_fake ()); + } else { + g_assert (!nm_utils_machine_id_is_fake ()); + g_assert_cmpmem (&machine_id_sd, sizeof (NMUuid), machine_id, 16); + } +} + +/*****************************************************************************/ + +static void +test_nm_utils_dhcp_client_id_systemd_node_specific (gconstpointer test_data) +{ + const int TEST_IDX = GPOINTER_TO_INT (test_data); + const guint8 HASH_KEY[16] = { 0x80, 0x11, 0x8c, 0xc2, 0xfe, 0x4a, 0x03, 0xee, 0x3e, 0xd6, 0x0c, 0x6f, 0x36, 0x39, 0x14, 0x09 }; + const guint16 duid_type_en = htons (2); + const guint32 systemd_pen = htonl (43793); + const struct { + NMUuid machine_id; + const char *ifname; + guint64 ifname_hash_1; + guint32 iaid_ifname; + guint64 duid_id; + } d_array[] = { + [0] = { + .machine_id = { 0xcb, 0xc2, 0x2e, 0x47, 0x41, 0x8e, 0x40, 0x2a, 0xa7, 0xb3, 0x0d, 0xea, 0x92, 0x83, 0x94, 0xef }, + .ifname = "lo", + .ifname_hash_1 = 0x7297085c2b12c911llu, + .iaid_ifname = htobe32 (0x5985c14du), + .duid_id = htobe64 (0x3d769bb2c14d29e1u), + }, + [1] = { + .machine_id = { 0x11, 0x4e, 0xb4, 0xda, 0xd3, 0x22, 0x4a, 0xff, 0x9f, 0xc3, 0x30, 0x83, 0x38, 0xa0, 0xeb, 0xb7 }, + .ifname = "eth0", + .ifname_hash_1 = 0x9e1cb083b54cd7b6llu, + .iaid_ifname = htobe32 (0x2b506735u), + .duid_id = htobe64 (0x551572e0f2a2a10fu), + }, + }; + int i; + typeof (d_array[0]) *d = &d_array[TEST_IDX]; + gint64 u64; + gint32 u32; + + /* the test already hard-codes the expected values iaid_ifname and duid_id + * above. Still, redo the steps to derive them from the ifname/machine-id + * and double check. */ + u64 = c_siphash_hash (HASH_KEY, (const guint8 *) d->ifname, strlen (d->ifname)); + g_assert_cmpint (u64, ==, d->ifname_hash_1); + u32 = be32toh ((u64 & 0xffffffffu) ^ (u64 >> 32)); + g_assert_cmpint (u32, ==, d->iaid_ifname); + + u64 = htole64 (c_siphash_hash (HASH_KEY, (const guint8 *) &d->machine_id, sizeof (d->machine_id))); + g_assert_cmpint (u64, ==, d->duid_id); + + for (i = 0; i < 2; i++) { + const gboolean legacy_unstable_byteorder = (i != 0); + gs_unref_bytes GBytes *client_id = NULL; + const guint8 *cid; + guint32 iaid = d->iaid_ifname; + + client_id = nm_utils_dhcp_client_id_systemd_node_specific_full (legacy_unstable_byteorder, + (const guint8 *) d->ifname, + strlen (d->ifname), + (const guint8 *) &d->machine_id, + sizeof (d->machine_id)); + + g_assert (client_id); + g_assert_cmpint (g_bytes_get_size (client_id), ==, 19); + cid = g_bytes_get_data (client_id, NULL); + g_assert_cmpint (cid[0], ==, 255); +#if __BYTE_ORDER == __BIG_ENDIAN + if (legacy_unstable_byteorder) { + /* on non-little endian, the legacy behavior is to have the bytes + * swapped. */ + iaid = bswap_32 (iaid); + } +#endif + g_assert_cmpmem (&cid[1], 4, &iaid, sizeof (iaid)); + g_assert_cmpmem (&cid[5], 2, &duid_type_en, sizeof (duid_type_en)); + g_assert_cmpmem (&cid[7], 4, &systemd_pen, sizeof (systemd_pen)); + g_assert_cmpmem (&cid[11], 8, &d->duid_id, sizeof (d->duid_id)); + + g_assert_cmpint (iaid, ==, htonl (nm_utils_create_dhcp_iaid (legacy_unstable_byteorder, + (const guint8 *) d->ifname, + strlen (d->ifname)))); + } +} + +/*****************************************************************************/ + +static void +test_connectivity_state_cmp (void) +{ + NMConnectivityState a; + +#define _cmp(a, b, cmp) \ + G_STMT_START { \ + const NMConnectivityState _a = (a); \ + const NMConnectivityState _b = (b); \ + const int _cmp = (cmp); \ + \ + g_assert (NM_IN_SET (_cmp, -1, 0, 1)); \ + g_assert_cmpint (nm_connectivity_state_cmp (_a, _b), ==, _cmp); \ + g_assert_cmpint (nm_connectivity_state_cmp (_b, _a), ==, -_cmp); \ + } G_STMT_END + + for (a = NM_CONNECTIVITY_UNKNOWN; a <= NM_CONNECTIVITY_FULL; a++) + _cmp (a, a, 0); + + _cmp (NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_UNKNOWN, 0); + _cmp (NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_NONE, -1); + _cmp (NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_LIMITED, -1); + _cmp (NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_PORTAL, -1); + _cmp (NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_FULL, -1); + + _cmp (NM_CONNECTIVITY_NONE, NM_CONNECTIVITY_UNKNOWN, 1); + _cmp (NM_CONNECTIVITY_NONE, NM_CONNECTIVITY_NONE, 0); + _cmp (NM_CONNECTIVITY_NONE, NM_CONNECTIVITY_LIMITED, -1); + _cmp (NM_CONNECTIVITY_NONE, NM_CONNECTIVITY_PORTAL, -1); + _cmp (NM_CONNECTIVITY_NONE, NM_CONNECTIVITY_FULL, -1); + + _cmp (NM_CONNECTIVITY_LIMITED, NM_CONNECTIVITY_UNKNOWN, 1); + _cmp (NM_CONNECTIVITY_LIMITED, NM_CONNECTIVITY_NONE, 1); + _cmp (NM_CONNECTIVITY_LIMITED, NM_CONNECTIVITY_LIMITED, 0); + _cmp (NM_CONNECTIVITY_LIMITED, NM_CONNECTIVITY_PORTAL, -1); + _cmp (NM_CONNECTIVITY_LIMITED, NM_CONNECTIVITY_FULL, -1); + + _cmp (NM_CONNECTIVITY_PORTAL, NM_CONNECTIVITY_UNKNOWN, 1); + _cmp (NM_CONNECTIVITY_PORTAL, NM_CONNECTIVITY_NONE, 1); + _cmp (NM_CONNECTIVITY_PORTAL, NM_CONNECTIVITY_LIMITED, 1); + _cmp (NM_CONNECTIVITY_PORTAL, NM_CONNECTIVITY_PORTAL, 0); + _cmp (NM_CONNECTIVITY_PORTAL, NM_CONNECTIVITY_FULL, -1); + + _cmp (NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_UNKNOWN, 1); + _cmp (NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_NONE, 1); + _cmp (NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_LIMITED, 1); + _cmp (NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_PORTAL, 1); + _cmp (NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_FULL, 0); + +#undef _cmp +} + +/*****************************************************************************/ + NMTST_DEFINE (); int @@ -1891,6 +2221,17 @@ main (int argc, char **argv) g_test_add_func ("/general/stable-id/parse", test_stable_id_parse); g_test_add_func ("/general/stable-id/generated-complete", test_stable_id_generated_complete); + g_test_add_func ("/general/machine-id/read", test_machine_id_read); + + g_test_add_func ("/general/test_utils_file_is_in_path", test_utils_file_is_in_path); + + g_test_add_func ("/general/test_dns_create_resolv_conf", test_dns_create_resolv_conf); + + g_test_add_data_func ("/general/nm_utils_dhcp_client_id_systemd_node_specific/0", GINT_TO_POINTER (0), test_nm_utils_dhcp_client_id_systemd_node_specific); + g_test_add_data_func ("/general/nm_utils_dhcp_client_id_systemd_node_specific/1", GINT_TO_POINTER (1), test_nm_utils_dhcp_client_id_systemd_node_specific); + + g_test_add_func ("/core/general/test_connectivity_state_cmp", test_connectivity_state_cmp); + return g_test_run (); } |