summary refs log tree commit diff
path: root/libnm-core/tests
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2020-06-28 18:58:14 +0200
committerMichael Biebl <biebl@debian.org>2020-06-28 18:58:14 +0200
commita54ac63bbf9b2c71026ac9028a8ffaf186cf3c82 (patch)
tree6a32883bd916c4096357b35298beff6db8bcd0b5 /libnm-core/tests
parent45e8e1149027529194982212c804c0468aa01d98 (diff)
New upstream version 1.25.90 upstream/1.25.90
Diffstat (limited to 'libnm-core/tests')
-rw-r--r--libnm-core/tests/test-general.c13
-rw-r--r--libnm-core/tests/test-keyfile.c4
-rw-r--r--libnm-core/tests/test-setting.c319
3 files changed, 302 insertions, 34 deletions
diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c
index 2b1f1e3d..a6fb7007 100644
--- a/libnm-core/tests/test-general.c
+++ b/libnm-core/tests/test-general.c
@@ -3334,6 +3334,7 @@ test_connection_diff_a_only (void)
 			{ NM_SETTING_CONNECTION_AUTH_RETRIES,         NM_SETTING_DIFF_RESULT_IN_A },
 			{ NM_SETTING_CONNECTION_MDNS,                 NM_SETTING_DIFF_RESULT_IN_A },
 			{ NM_SETTING_CONNECTION_LLMNR,                NM_SETTING_DIFF_RESULT_IN_A },
+			{ NM_SETTING_CONNECTION_MUD_URL,              NM_SETTING_DIFF_RESULT_IN_A },
 			{ NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT,  NM_SETTING_DIFF_RESULT_IN_A },
 			{ NULL, NM_SETTING_DIFF_RESULT_UNKNOWN }
 		} },
@@ -7814,7 +7815,7 @@ _do_test_utils_str_utf8safe_unescape (const char *str, const char *expected, gsi
 	gs_free gpointer buf_free_1 = NULL;
 	gs_free char *str_free_1 = NULL;
 
-	s = nm_utils_buf_utf8safe_unescape (str, &l, &buf_free_1);
+	s = nm_utils_buf_utf8safe_unescape (str, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE, &l, &buf_free_1);
 	g_assert_cmpint (expected_len, ==, l);
 	g_assert_cmpstr (s, ==, expected);
 
@@ -7838,7 +7839,7 @@ _do_test_utils_str_utf8safe_unescape (const char *str, const char *expected, gsi
 	if (   expected
 	    && l == strlen (expected)) {
 		/* there are no embeeded NULs. Check that nm_utils_str_utf8safe_unescape() yields the same result. */
-		s = nm_utils_str_utf8safe_unescape (str, &str_free_1);
+		s = nm_utils_str_utf8safe_unescape (str, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE, &str_free_1);
 		g_assert_cmpstr (s, ==, expected);
 		if (strchr (str, '\\')) {
 			g_assert (str_free_1 != str);
@@ -7907,10 +7908,10 @@ _do_test_utils_str_utf8safe (const char *str, gsize str_len, const char *expecte
 			g_assert (g_utf8_validate (str, -1, NULL));
 		}
 
-		g_assert (str == nm_utils_str_utf8safe_unescape (str_safe, &str_free_4));
+		g_assert (str == nm_utils_str_utf8safe_unescape (str_safe, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE, &str_free_4));
 		g_assert (!str_free_4);
 
-		str_free_5 = nm_utils_str_utf8safe_unescape_cp (str_safe);
+		str_free_5 = nm_utils_str_utf8safe_unescape_cp (str_safe, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE);
 		if (str) {
 			g_assert (str_free_5 != str);
 			g_assert_cmpstr (str_free_5, ==, str);
@@ -7934,11 +7935,11 @@ _do_test_utils_str_utf8safe (const char *str, gsize str_len, const char *expecte
 		str_free_6 = g_strcompress (str_safe);
 		g_assert_cmpstr (str, ==, str_free_6);
 
-		str_free_7 = nm_utils_str_utf8safe_unescape_cp (str_safe);
+		str_free_7 = nm_utils_str_utf8safe_unescape_cp (str_safe, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE);
 		g_assert (str_free_7 != str);
 		g_assert_cmpstr (str_free_7, ==, str);
 
-		s = nm_utils_str_utf8safe_unescape (str_safe, &str_free_8);
+		s = nm_utils_str_utf8safe_unescape (str_safe, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE, &str_free_8);
 		g_assert (str_free_8 != str);
 		g_assert (s == str_free_8);
 		g_assert_cmpstr (str_free_8, ==, str);
diff --git a/libnm-core/tests/test-keyfile.c b/libnm-core/tests/test-keyfile.c
index 47a27571..23149b61 100644
--- a/libnm-core/tests/test-keyfile.c
+++ b/libnm-core/tests/test-keyfile.c
@@ -143,7 +143,7 @@ _nm_keyfile_write (NMConnection *connection,
 
 	g_assert (NM_IS_CONNECTION (connection));
 
-	kf = nm_keyfile_write (connection, handler, user_data, &error);
+	kf = nm_keyfile_write (connection, NM_KEYFILE_HANDLER_FLAGS_NONE, handler, user_data, &error);
 	g_assert_no_error (error);
 	g_assert (kf);
 	return kf;
@@ -167,7 +167,7 @@ _nm_keyfile_read (GKeyFile *keyfile,
 	base_dir = g_path_get_dirname (keyfile_name);
 	filename = g_path_get_basename (keyfile_name);
 
-	con = nm_keyfile_read (keyfile, base_dir, read_handler, read_data, &error);
+	con = nm_keyfile_read (keyfile, base_dir, NM_KEYFILE_HANDLER_FLAGS_NONE, read_handler, read_data, &error);
 	g_assert_no_error (error);
 	g_assert (NM_IS_CONNECTION (con));
 
diff --git a/libnm-core/tests/test-setting.c b/libnm-core/tests/test-setting.c
index 072be57a..359c20c4 100644
--- a/libnm-core/tests/test-setting.c
+++ b/libnm-core/tests/test-setting.c
@@ -1499,7 +1499,53 @@ test_team_setting (void)
 /*****************************************************************************/
 
 static void
-test_ethtool_1 (void)
+_setting_ethtool_set_feature (NMSettingEthtool *s_ethtool,
+                              const char *opt_name,
+                              NMTernary value)
+{
+	g_assert (NM_IS_SETTING_ETHTOOL (s_ethtool));
+
+	if (nmtst_get_rand_bool ()) {
+		nm_setting_ethtool_set_feature (s_ethtool, opt_name, value);
+		return;
+	}
+
+	if (value == NM_TERNARY_DEFAULT) {
+		nm_setting_option_set (NM_SETTING (s_ethtool), opt_name, NULL);
+		return;
+	}
+
+	if (nmtst_get_rand_bool ())
+		nm_setting_option_set_boolean (NM_SETTING (s_ethtool), opt_name, value);
+	else
+		nm_setting_option_set (NM_SETTING (s_ethtool), opt_name, g_variant_new_boolean (value));
+}
+
+static NMTernary
+_setting_ethtool_get_feature (NMSettingEthtool *s_ethtool,
+                              const char *opt_name)
+{
+	GVariant *v;
+	gboolean b;
+
+	switch (nmtst_get_rand_uint32 () % 3) {
+	case 0:
+		return nm_setting_ethtool_get_feature (s_ethtool, opt_name);
+	case 1:
+		if (!nm_setting_option_get_boolean (NM_SETTING (s_ethtool), opt_name, &b))
+			return NM_TERNARY_DEFAULT;
+		return b;
+	default:
+		v = nm_setting_option_get (NM_SETTING (s_ethtool), opt_name);
+		if (   !v
+		    || !g_variant_is_of_type (v, G_VARIANT_TYPE_BOOLEAN))
+			return NM_TERNARY_DEFAULT;
+		return g_variant_get_boolean (v);
+	}
+}
+
+static void
+test_ethtool_features (void)
 {
 	gs_unref_object NMConnection *con = NULL;
 	gs_unref_object NMConnection *con2 = NULL;
@@ -1519,16 +1565,87 @@ test_ethtool_1 (void)
 	s_ethtool = NM_SETTING_ETHTOOL (nm_setting_ethtool_new ());
 	nm_connection_add_setting (con, NM_SETTING (s_ethtool));
 
-	nm_setting_ethtool_set_feature (s_ethtool,
-	                                NM_ETHTOOL_OPTNAME_FEATURE_RX,
-	                                NM_TERNARY_TRUE);
-	nm_setting_ethtool_set_feature (s_ethtool,
-	                                NM_ETHTOOL_OPTNAME_FEATURE_LRO,
-	                                NM_TERNARY_FALSE);
+	_setting_ethtool_set_feature (s_ethtool,
+	                              NM_ETHTOOL_OPTNAME_FEATURE_RX,
+	                              NM_TERNARY_TRUE);
+	_setting_ethtool_set_feature (s_ethtool,
+	                              NM_ETHTOOL_OPTNAME_FEATURE_LRO,
+	                              NM_TERNARY_FALSE);
+
+	g_assert_cmpint (_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_RX), ==, NM_TERNARY_TRUE);
+	g_assert_cmpint (_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_LRO), ==, NM_TERNARY_FALSE);
+	g_assert_cmpint (_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_SG),  ==, NM_TERNARY_DEFAULT);
+
+	nmtst_connection_normalize (con);
+
+	variant = nm_connection_to_dbus (con, NM_CONNECTION_SERIALIZE_ALL);
+
+	con2 = nm_simple_connection_new_from_dbus (variant, &error);
+	nmtst_assert_success (con2, error);
+
+	s_ethtool2 = NM_SETTING_ETHTOOL (nm_connection_get_setting (con2, NM_TYPE_SETTING_ETHTOOL));
+
+	g_assert_cmpint (_setting_ethtool_get_feature (s_ethtool2, NM_ETHTOOL_OPTNAME_FEATURE_RX),  ==, NM_TERNARY_TRUE);
+	g_assert_cmpint (_setting_ethtool_get_feature (s_ethtool2, NM_ETHTOOL_OPTNAME_FEATURE_LRO), ==, NM_TERNARY_FALSE);
+	g_assert_cmpint (_setting_ethtool_get_feature (s_ethtool2, NM_ETHTOOL_OPTNAME_FEATURE_SG),  ==, NM_TERNARY_DEFAULT);
+
+	nmtst_assert_connection_verifies_without_normalization (con2);
+
+	nmtst_assert_connection_equals (con, FALSE, con2, FALSE);
+
+	keyfile = nm_keyfile_write (con, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, &error);
+	nmtst_assert_success (keyfile, error);
+
+	con3 = nm_keyfile_read (keyfile,
+	                        "/ignored/current/working/directory/for/loading/relative/paths",
+	                        NM_KEYFILE_HANDLER_FLAGS_NONE,
+	                        NULL,
+	                        NULL,
+	                        &error);
+	nmtst_assert_success (con3, error);
+
+	nm_keyfile_read_ensure_id (con3, "unused-because-already-has-id");
+	nm_keyfile_read_ensure_uuid (con3, "unused-because-already-has-uuid");
+
+	nmtst_connection_normalize (con3);
+
+	nmtst_assert_connection_equals (con, FALSE, con3, FALSE);
+
+	s_ethtool3 = NM_SETTING_ETHTOOL (nm_connection_get_setting (con3, NM_TYPE_SETTING_ETHTOOL));
+
+	g_assert_cmpint (_setting_ethtool_get_feature (s_ethtool3, NM_ETHTOOL_OPTNAME_FEATURE_RX),  ==, NM_TERNARY_TRUE);
+	g_assert_cmpint (_setting_ethtool_get_feature (s_ethtool3, NM_ETHTOOL_OPTNAME_FEATURE_LRO), ==, NM_TERNARY_FALSE);
+	g_assert_cmpint (_setting_ethtool_get_feature (s_ethtool3, NM_ETHTOOL_OPTNAME_FEATURE_SG),  ==, NM_TERNARY_DEFAULT);
+}
+
+static void
+test_ethtool_coalesce (void)
+{
+	gs_unref_object NMConnection *con = NULL;
+	gs_unref_object NMConnection *con2 = NULL;
+	gs_unref_object NMConnection *con3 = NULL;
+	gs_unref_variant GVariant *variant = NULL;
+	gs_free_error GError *error = NULL;
+	gs_unref_keyfile GKeyFile *keyfile = NULL;
+	NMSettingConnection *s_con;
+	NMSettingEthtool *s_ethtool;
+	NMSettingEthtool *s_ethtool2;
+	NMSettingEthtool *s_ethtool3;
+	guint32 u32;
+
+	con = nmtst_create_minimal_connection ("ethtool-coalesce",
+	                                        NULL,
+	                                        NM_SETTING_WIRED_SETTING_NAME,
+	                                        &s_con);
+	s_ethtool = NM_SETTING_ETHTOOL (nm_setting_ethtool_new ());
+	nm_connection_add_setting (con, NM_SETTING (s_ethtool));
+
+	nm_setting_option_set_uint32 (NM_SETTING (s_ethtool),
+	                              NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES,
+	                              4);
 
-	g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_RX), ==, NM_TERNARY_TRUE);
-	g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_LRO), ==, NM_TERNARY_FALSE);
-	g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_SG),  ==, NM_TERNARY_DEFAULT);
+	g_assert_true (nm_setting_option_get_uint32 (NM_SETTING (s_ethtool), NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES, &u32));
+	g_assert_cmpuint (u32, ==, 4);
 
 	nmtst_connection_normalize (con);
 
@@ -1539,19 +1656,19 @@ test_ethtool_1 (void)
 
 	s_ethtool2 = NM_SETTING_ETHTOOL (nm_connection_get_setting (con2, NM_TYPE_SETTING_ETHTOOL));
 
-	g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool2, NM_ETHTOOL_OPTNAME_FEATURE_RX),  ==, NM_TERNARY_TRUE);
-	g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool2, NM_ETHTOOL_OPTNAME_FEATURE_LRO), ==, NM_TERNARY_FALSE);
-	g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool2, NM_ETHTOOL_OPTNAME_FEATURE_SG),  ==, NM_TERNARY_DEFAULT);
+	g_assert_true (nm_setting_option_get_uint32 (NM_SETTING (s_ethtool2), NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES, &u32));
+	g_assert_cmpuint (u32, ==, 4);
 
 	nmtst_assert_connection_verifies_without_normalization (con2);
 
 	nmtst_assert_connection_equals (con, FALSE, con2, FALSE);
 
-	keyfile = nm_keyfile_write (con, NULL, NULL, &error);
+	keyfile = nm_keyfile_write (con, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, &error);
 	nmtst_assert_success (keyfile, error);
 
 	con3 = nm_keyfile_read (keyfile,
 	                        "/ignored/current/working/directory/for/loading/relative/paths",
+	                        NM_KEYFILE_HANDLER_FLAGS_NONE,
 	                        NULL,
 	                        NULL,
 	                        &error);
@@ -1566,9 +1683,109 @@ test_ethtool_1 (void)
 
 	s_ethtool3 = NM_SETTING_ETHTOOL (nm_connection_get_setting (con3, NM_TYPE_SETTING_ETHTOOL));
 
-	g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool3, NM_ETHTOOL_OPTNAME_FEATURE_RX),  ==, NM_TERNARY_TRUE);
-	g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool3, NM_ETHTOOL_OPTNAME_FEATURE_LRO), ==, NM_TERNARY_FALSE);
-	g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool3, NM_ETHTOOL_OPTNAME_FEATURE_SG),  ==, NM_TERNARY_DEFAULT);
+	g_assert_true (nm_setting_option_get_uint32 (NM_SETTING (s_ethtool3), NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES, &u32));
+	g_assert_cmpuint (u32, ==, 4);
+
+
+	nm_setting_option_set (NM_SETTING (s_ethtool), NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES, NULL);
+	g_assert_false (nm_setting_option_get_uint32 (NM_SETTING (s_ethtool), NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES, NULL));
+
+	nm_setting_option_set_uint32 (NM_SETTING (s_ethtool),
+	                              NM_ETHTOOL_OPTNAME_COALESCE_TX_FRAMES,
+	                              8);
+
+	g_assert_true (nm_setting_option_get_uint32 (NM_SETTING (s_ethtool), NM_ETHTOOL_OPTNAME_COALESCE_TX_FRAMES, &u32));
+	g_assert_cmpuint (u32, ==, 8);
+
+	nm_setting_option_clear_by_name (NM_SETTING (s_ethtool), nm_ethtool_optname_is_coalesce);
+	g_assert_false (nm_setting_option_get_uint32 (NM_SETTING (s_ethtool), NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES, NULL));
+	g_assert_false (nm_setting_option_get_uint32 (NM_SETTING (s_ethtool), NM_ETHTOOL_OPTNAME_COALESCE_TX_FRAMES, NULL));
+	g_assert_false (nm_setting_option_get_uint32 (NM_SETTING (s_ethtool), NM_ETHTOOL_OPTNAME_COALESCE_TX_USECS, NULL));
+}
+
+static void
+test_ethtool_ring (void)
+{
+	gs_unref_object NMConnection *con = NULL;
+	gs_unref_object NMConnection *con2 = NULL;
+	gs_unref_object NMConnection *con3 = NULL;
+	gs_unref_variant GVariant *variant = NULL;
+	gs_free_error GError *error = NULL;
+	gs_unref_keyfile GKeyFile *keyfile = NULL;
+	NMSettingConnection *s_con;
+	NMSettingEthtool *s_ethtool;
+	NMSettingEthtool *s_ethtool2;
+	NMSettingEthtool *s_ethtool3;
+	guint32 out_value;
+
+	con = nmtst_create_minimal_connection ("ethtool-ring",
+	                                        NULL,
+	                                        NM_SETTING_WIRED_SETTING_NAME,
+	                                        &s_con);
+	s_ethtool = NM_SETTING_ETHTOOL (nm_setting_ethtool_new ());
+	nm_connection_add_setting (con, NM_SETTING (s_ethtool));
+
+	nm_setting_option_set_uint32 (NM_SETTING (s_ethtool),
+	                              NM_ETHTOOL_OPTNAME_RING_RX_JUMBO,
+	                              4);
+
+	g_assert_true (nm_setting_option_get_uint32 (NM_SETTING (s_ethtool), NM_ETHTOOL_OPTNAME_RING_RX_JUMBO, &out_value));
+	g_assert_cmpuint (out_value, ==, 4);
+
+	nmtst_connection_normalize (con);
+
+	variant = nm_connection_to_dbus (con, NM_CONNECTION_SERIALIZE_ALL);
+
+	con2 = nm_simple_connection_new_from_dbus (variant, &error);
+	nmtst_assert_success (con2, error);
+
+	s_ethtool2 = NM_SETTING_ETHTOOL (nm_connection_get_setting (con2, NM_TYPE_SETTING_ETHTOOL));
+
+	g_assert_true (nm_setting_option_get_uint32 (NM_SETTING (s_ethtool2), NM_ETHTOOL_OPTNAME_RING_RX_JUMBO, &out_value));
+	g_assert_cmpuint (out_value, ==, 4);
+
+	nmtst_assert_connection_verifies_without_normalization (con2);
+
+	nmtst_assert_connection_equals (con, FALSE, con2, FALSE);
+
+	keyfile = nm_keyfile_write (con, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, &error);
+	nmtst_assert_success (keyfile, error);
+
+	con3 = nm_keyfile_read (keyfile,
+	                        "/ignored/current/working/directory/for/loading/relative/paths",
+	                        NM_KEYFILE_HANDLER_FLAGS_NONE,
+	                        NULL,
+	                        NULL,
+	                        &error);
+	nmtst_assert_success (con3, error);
+
+	nm_keyfile_read_ensure_id (con3, "unused-because-already-has-id");
+	nm_keyfile_read_ensure_uuid (con3, "unused-because-already-has-uuid");
+
+	nmtst_connection_normalize (con3);
+
+	nmtst_assert_connection_equals (con, FALSE, con3, FALSE);
+
+	s_ethtool3 = NM_SETTING_ETHTOOL (nm_connection_get_setting (con3, NM_TYPE_SETTING_ETHTOOL));
+
+	g_assert_true (nm_setting_option_get_uint32 (NM_SETTING (s_ethtool3), NM_ETHTOOL_OPTNAME_RING_RX_JUMBO, &out_value));
+	g_assert_cmpuint (out_value, ==, 4);
+
+
+	nm_setting_option_set (NM_SETTING (s_ethtool), NM_ETHTOOL_OPTNAME_RING_RX_JUMBO, NULL);
+	g_assert_false (nm_setting_option_get_uint32 (NM_SETTING (s_ethtool), NM_ETHTOOL_OPTNAME_RING_RX_JUMBO, NULL));
+
+	nm_setting_option_set_uint32 (NM_SETTING (s_ethtool),
+	                              NM_ETHTOOL_OPTNAME_RING_RX_JUMBO,
+	                              8);
+
+	g_assert_true (nm_setting_option_get_uint32 (NM_SETTING (s_ethtool), NM_ETHTOOL_OPTNAME_RING_RX_JUMBO, &out_value));
+	g_assert_cmpuint (out_value, ==, 8);
+
+	nm_setting_option_clear_by_name (NM_SETTING (s_ethtool), nm_ethtool_optname_is_ring);
+	g_assert_false (nm_setting_option_get_uint32 (NM_SETTING (s_ethtool), NM_ETHTOOL_OPTNAME_RING_RX_JUMBO, NULL));
+	g_assert_false (nm_setting_option_get_uint32 (NM_SETTING (s_ethtool), NM_ETHTOOL_OPTNAME_RING_RX, NULL));
+	g_assert_false (nm_setting_option_get_uint32 (NM_SETTING (s_ethtool), NM_ETHTOOL_OPTNAME_RING_TX, NULL));
 }
 
 /*****************************************************************************/
@@ -1917,14 +2134,16 @@ _test_verify_options_bridge (gboolean expected_result,
 		case G_TYPE_UINT: {
 				guint uvalue;
 
-				uvalue = _nm_utils_ascii_str_to_uint64 (option_val, 10, 0, G_MAXUINT, 0);
+				uvalue = _nm_utils_ascii_str_to_uint64 (option_val, 10, 0, G_MAXUINT, -1);
+				g_assert (errno == 0);
 				g_object_set (s_bridge, option_key, uvalue, NULL);
 			}
 			break;
 		case G_TYPE_BOOLEAN: {
-				gboolean bvalue;
+				int bvalue;
 
-				bvalue = _nm_utils_ascii_str_to_bool (option_val, FALSE);
+				bvalue = _nm_utils_ascii_str_to_bool (option_val, -1);
+				g_assert (bvalue != -1);
 				g_object_set (s_bridge, option_key, bvalue, NULL);
 			}
 			break;
@@ -1980,10 +2199,10 @@ test_bridge_verify (void)
 	/* multicast-router */
 	test_verify_options_bridge (FALSE,
 	                            "multicast-router",   "nonsense");
-	test_verify_options_bridge (FALSE,
+	test_verify_options_bridge (TRUE,
 	                            "multicast-snooping", "no",
 	                            "multicast-router",   "auto");
-	test_verify_options_bridge (FALSE,
+	test_verify_options_bridge (TRUE,
 	                            "multicast-snooping", "no",
 	                            "multicast-router",   "enabled");
 	test_verify_options_bridge (TRUE,
@@ -1998,6 +2217,13 @@ test_bridge_verify (void)
 	test_verify_options_bridge (TRUE,
 	                            "multicast-snooping", "yes",
 	                            "multicast-router",   "disabled");
+	/* multicast-hash-max */
+	test_verify_options_bridge (TRUE,
+	                            "multicast-hash-max",   "1024");
+	test_verify_options_bridge (TRUE,
+	                            "multicast-hash-max",   "8192");
+	test_verify_options_bridge (FALSE,
+	                            "multicast-hash-max",   "3");
 }
 
 /*****************************************************************************/
@@ -2008,6 +2234,7 @@ test_tc_config_qdisc (void)
 	NMTCQdisc *qdisc1, *qdisc2;
 	char *str;
 	GError *error = NULL;
+	GVariant *variant;
 
 	qdisc1 = nm_tc_qdisc_new ("fq_codel", TC_H_ROOT, &error);
 	nmtst_assert_success (qdisc1, error);
@@ -2070,6 +2297,43 @@ test_tc_config_qdisc (void)
 
 	nm_tc_qdisc_unref (qdisc1);
 	nm_tc_qdisc_unref (qdisc2);
+
+#define CHECK_ATTRIBUTE(qdisc, name, vtype, type, value) \
+	variant = nm_tc_qdisc_get_attribute (qdisc, name); \
+	g_assert (variant); \
+	g_assert (g_variant_is_of_type (variant, vtype)); \
+	g_assert_cmpint (g_variant_get_ ## type(variant), ==, value);
+
+	qdisc1 = nm_utils_tc_qdisc_from_str ("handle 1235 root sfq perturb 10 quantum 1480 "
+	                                     "limit 9000 flows 1024 divisor 500 depth 12",
+	                                     &error);
+	nmtst_assert_success (qdisc1, error);
+
+	g_assert_cmpstr (nm_tc_qdisc_get_kind (qdisc1), ==, "sfq");
+	g_assert (nm_tc_qdisc_get_handle (qdisc1) == TC_H_MAKE (0x1235u << 16, 0x0000u));
+	g_assert (nm_tc_qdisc_get_parent (qdisc1) == TC_H_ROOT);
+	CHECK_ATTRIBUTE (qdisc1, "perturb", G_VARIANT_TYPE_INT32,  int32,  10);
+	CHECK_ATTRIBUTE (qdisc1, "quantum", G_VARIANT_TYPE_UINT32, uint32, 1480);
+	CHECK_ATTRIBUTE (qdisc1, "limit",   G_VARIANT_TYPE_UINT32, uint32, 9000);
+	CHECK_ATTRIBUTE (qdisc1, "flows",   G_VARIANT_TYPE_UINT32, uint32, 1024);
+	CHECK_ATTRIBUTE (qdisc1, "divisor", G_VARIANT_TYPE_UINT32, uint32, 500);
+	CHECK_ATTRIBUTE (qdisc1, "depth",   G_VARIANT_TYPE_UINT32, uint32, 12);
+	nm_tc_qdisc_unref (qdisc1);
+
+	qdisc1 = nm_utils_tc_qdisc_from_str ("handle 1235 root tbf rate 1000000 burst 5000 limit 10000",
+	                                     &error);
+	nmtst_assert_success (qdisc1, error);
+
+	g_assert_cmpstr (nm_tc_qdisc_get_kind (qdisc1), ==, "tbf");
+	g_assert (nm_tc_qdisc_get_handle (qdisc1) == TC_H_MAKE (0x1235u << 16, 0x0000u));
+	g_assert (nm_tc_qdisc_get_parent (qdisc1) == TC_H_ROOT);
+	CHECK_ATTRIBUTE (qdisc1, "rate",  G_VARIANT_TYPE_UINT64, uint64, 1000000);
+	CHECK_ATTRIBUTE (qdisc1, "burst", G_VARIANT_TYPE_UINT32, uint32, 5000);
+	CHECK_ATTRIBUTE (qdisc1, "limit", G_VARIANT_TYPE_UINT32, uint32, 10000);
+	nm_tc_qdisc_unref (qdisc1);
+
+
+#undef CHECK_ATTRIBUTE
 }
 
 static void
@@ -3045,7 +3309,7 @@ test_roundtrip_conversion (gconstpointer test_data)
 	{
 		gs_unref_keyfile GKeyFile *kf = NULL;
 
-		kf = nm_keyfile_write (con, NULL, NULL, &error);
+		kf = nm_keyfile_write (con, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, &error);
 		nmtst_assert_success (kf, error);
 
 		/* the first kf_data_arr entry is special: it must be what the writer would
@@ -3140,7 +3404,7 @@ test_roundtrip_conversion (gconstpointer test_data)
 			{
 				gs_unref_keyfile GKeyFile *kf = NULL;
 
-				kf = nm_keyfile_write (con2, NULL, NULL, &error);
+				kf = nm_keyfile_write (con2, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, &error);
 				nmtst_assert_success (kf, error);
 				nmtst_keyfile_assert_data (kf, kf_data_arr->pdata[0], -1);
 			}
@@ -3444,7 +3708,7 @@ test_empty_setting (void)
 
 	nmtst_assert_connection_verifies_without_normalization (con);
 
-	kf = nm_keyfile_write (con, NULL, NULL, &error);
+	kf = nm_keyfile_write (con, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, &error);
 	nmtst_assert_success (kf, error);
 
 	g_assert (g_key_file_has_group (kf, "gsm"));
@@ -3452,6 +3716,7 @@ test_empty_setting (void)
 
 	con2 = nm_keyfile_read (kf,
 	                        "/ignored/current/working/directory/for/loading/relative/paths",
+	                        NM_KEYFILE_HANDLER_FLAGS_NONE,
 	                        NULL,
 	                        NULL,
 	                        &error);
@@ -3763,7 +4028,9 @@ main (int argc, char **argv)
 	g_test_add_func ("/libnm/settings/dcb/priorities", test_dcb_priorities_valid);
 	g_test_add_func ("/libnm/settings/dcb/bandwidth-sums", test_dcb_bandwidth_sums);
 
-	g_test_add_func ("/libnm/settings/ethtool/1", test_ethtool_1);
+	g_test_add_func ("/libnm/settings/ethtool/features", test_ethtool_features);
+	g_test_add_func ("/libnm/settings/ethtool/coalesce", test_ethtool_coalesce);
+	g_test_add_func ("/libnm/settings/ethtool/ring", test_ethtool_ring);
 
 	g_test_add_func ("/libnm/settings/sriov/vf", test_sriov_vf);
 	g_test_add_func ("/libnm/settings/sriov/vf-dup", test_sriov_vf_dup);