summary refs log tree commit diff
path: root/libnm-core/tests
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2019-12-18 18:29:24 +0100
committerMichael Biebl <biebl@debian.org>2019-12-18 18:29:24 +0100
commit28028b26b3371756811e95d894f709f4b1207c00 (patch)
tree6fe7316fd743b51042db47601a8ef8814b3134ac /libnm-core/tests
parente22609983008e1a669196ad64ba3a59ae8c76e0d (diff)
New upstream version 1.22.0 upstream/1.22.0
Diffstat (limited to 'libnm-core/tests')
-rw-r--r--libnm-core/tests/meson.build33
-rw-r--r--libnm-core/tests/test-compare.c20
-rw-r--r--libnm-core/tests/test-crypto.c19
-rw-r--r--libnm-core/tests/test-general-enums.h18
-rw-r--r--libnm-core/tests/test-general.c249
-rw-r--r--libnm-core/tests/test-keyfile.c19
-rw-r--r--libnm-core/tests/test-secrets.c19
-rw-r--r--libnm-core/tests/test-setting.c294
-rw-r--r--libnm-core/tests/test-settings-defaults.c19
9 files changed, 539 insertions, 151 deletions
diff --git a/libnm-core/tests/meson.build b/libnm-core/tests/meson.build
index 1afb9c4b..292eeaa0 100644
--- a/libnm-core/tests/meson.build
+++ b/libnm-core/tests/meson.build
@@ -9,14 +9,24 @@
 
 enum_types = 'nm-core-tests-enum-types'
 
-enum = gnome.mkenums(
+enum_sources = gnome.mkenums_simple(
   enum_types,
   sources: 'test-general-enums.h',
   identifier_prefix: nm_id_prefix,
-  c_template: enum_types + '.c.template',
-  h_template: enum_types + '.h.template',
 )
 
+deps = [
+  libnm_core_dep,
+  libnm_core_nm_default_dep,
+]
+
+c_flags = [
+  '-DNETWORKMANAGER_COMPILATION_TEST',
+  '-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_LIBNM_CORE',
+]
+
+test_cert_dir = join_paths(meson.current_source_dir(), 'certs')
+
 test_units = [
   'test-compare',
   'test-crypto',
@@ -27,22 +37,15 @@ test_units = [
   'test-settings-defaults',
 ]
 
-test_cert_dir = join_paths(meson.current_source_dir(), 'certs')
-
 foreach test_unit: test_units
   exe = executable(
     'libnm-core-' + test_unit,
-    [test_unit + '.c'] + enum,
-    dependencies: [
-      libnm_core_dep,
-      libnm_systemd_shared_no_logging_dep,
-    ],
-    c_args: [
-        '-DNETWORKMANAGER_COMPILATION_TEST',
-        '-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_LIBNM_CORE',
-      ],
-    link_with: libnm_core,
+    [test_unit + '.c'] + enum_sources,
+    dependencies: deps,
+    c_args: c_flags,
+    link_with: libnm_systemd_logging_stub,
   )
+
   test(
     'libnm-core/' + test_unit,
     test_script,
diff --git a/libnm-core/tests/test-compare.c b/libnm-core/tests/test-compare.c
index ec4ca437..77f0ba4f 100644
--- a/libnm-core/tests/test-compare.c
+++ b/libnm-core/tests/test-compare.c
@@ -1,21 +1,7 @@
+// SPDX-License-Identifier: LGPL-2.1+
 /*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * Copyright 2007 - 2014 Red Hat, Inc.
- * Copyright 2007 - 2008 Novell, Inc.
+ * Copyright (C) 2007 - 2014 Red Hat, Inc.
+ * Copyright (C) 2007 - 2008 Novell, Inc.
  */
 
 #include "nm-default.h"
diff --git a/libnm-core/tests/test-crypto.c b/libnm-core/tests/test-crypto.c
index 9eab29d4..538bf858 100644
--- a/libnm-core/tests/test-crypto.c
+++ b/libnm-core/tests/test-crypto.c
@@ -1,22 +1,7 @@
+// SPDX-License-Identifier: LGPL-2.1+
 /*
  * Dan Williams <dcbw@redhat.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * Copyright 2007 - 2011 Red Hat, Inc.
+ * Copyright (C) 2007 - 2011 Red Hat, Inc.
  */
 
 #include "nm-default.h"
diff --git a/libnm-core/tests/test-general-enums.h b/libnm-core/tests/test-general-enums.h
index 72981171..451f1b50 100644
--- a/libnm-core/tests/test-general-enums.h
+++ b/libnm-core/tests/test-general-enums.h
@@ -1,20 +1,6 @@
+// SPDX-License-Identifier: LGPL-2.1+
 /*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * Copyright 2015 Red Hat, Inc.
+ * Copyright (C) 2015 Red Hat, Inc.
  */
 
 #ifndef _NM_TEST_GENERAL_ENUMS_H_
diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c
index 13fed902..c1b7b84a 100644
--- a/libnm-core/tests/test-general.c
+++ b/libnm-core/tests/test-general.c
@@ -1,27 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT SC WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Copyright 2008 - 2018 Red Hat, Inc.
- *
+ * Copyright (C) 2008 - 2018 Red Hat, Inc.
  */
 
 #define NM_GLIB_COMPAT_H_TEST
 
 #include "nm-default.h"
 
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <glib-unix.h>
+
 #include "nm-std-aux/c-list-util.h"
 #include "nm-glib-aux/nm-enum-utils.h"
 
@@ -1755,7 +1745,7 @@ test_setting_gsm_apn_bad_chars (void)
 
 	/* 0 characters long */
 	g_object_set (s_gsm, NM_SETTING_GSM_APN, "", NULL);
-	g_assert (!nm_setting_verify (NM_SETTING (s_gsm), NULL, NULL));
+	g_assert (nm_setting_verify (NM_SETTING (s_gsm), NULL, NULL));
 
 	/* 65-character long */
 	g_object_set (s_gsm, NM_SETTING_GSM_APN, "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl1", NULL);
@@ -3061,11 +3051,13 @@ test_connection_diff_a_only (void)
 			{ NM_SETTING_IP_CONFIG_DHCP_TIMEOUT,       NM_SETTING_DIFF_RESULT_IN_A },
 			{ NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, NM_SETTING_DIFF_RESULT_IN_A },
 			{ NM_SETTING_IP_CONFIG_DHCP_HOSTNAME,      NM_SETTING_DIFF_RESULT_IN_A },
+			{ NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS,NM_SETTING_DIFF_RESULT_IN_A },
 			{ NM_SETTING_IP4_CONFIG_DHCP_FQDN,         NM_SETTING_DIFF_RESULT_IN_A },
 			{ NM_SETTING_IP_CONFIG_NEVER_DEFAULT,      NM_SETTING_DIFF_RESULT_IN_A },
 			{ NM_SETTING_IP_CONFIG_MAY_FAIL,           NM_SETTING_DIFF_RESULT_IN_A },
 			{ NM_SETTING_IP_CONFIG_DAD_TIMEOUT,        NM_SETTING_DIFF_RESULT_IN_A },
 			{ NM_SETTING_IP_CONFIG_DNS_PRIORITY,       NM_SETTING_DIFF_RESULT_IN_A },
+			{ NM_SETTING_IP_CONFIG_DHCP_IAID,          NM_SETTING_DIFF_RESULT_IN_A },
 			{ NULL, NM_SETTING_DIFF_RESULT_UNKNOWN },
 		} },
 	};
@@ -6572,6 +6564,11 @@ test_nm_utils_ascii_str_to_int64 (void)
 	test_nm_utils_ascii_str_to_int64_do ("080",  0, G_MININT64, G_MAXINT64, -1, EINVAL, -1);
 	test_nm_utils_ascii_str_to_int64_do ("070",  0, G_MININT64, G_MAXINT64, -1, 0, 7*8);
 	test_nm_utils_ascii_str_to_int64_do ("0x70",  0, G_MININT64, G_MAXINT64, -1, 0, 0x70);
+
+	g_assert_cmpint (21, ==, _nm_utils_ascii_str_to_int64 ("025", 0, 0, 1000, -1));
+	g_assert_cmpint (21, ==, _nm_utils_ascii_str_to_int64 ("0025", 0, 0, 1000, -1));
+	g_assert_cmpint (25, ==, _nm_utils_ascii_str_to_int64 ("025", 10, 0, 1000, -1));
+	g_assert_cmpint (25, ==, _nm_utils_ascii_str_to_int64 ("0025", 10, 0, 1000, -1));
 }
 
 /*****************************************************************************/
@@ -7990,6 +7987,33 @@ test_route_attributes_format (void)
 
 /*****************************************************************************/
 
+static void
+test_variant_attribute_spec (void)
+{
+	const NMVariantAttributeSpec *const *const specs_list[] = {
+		nm_ip_route_get_variant_attribute_spec (),
+	};
+	int i_specs;
+
+	for (i_specs = 0; i_specs < G_N_ELEMENTS (specs_list); i_specs++) {
+		const NMVariantAttributeSpec *const *const specs = specs_list[i_specs];
+		gsize len;
+		gsize i;
+
+		g_assert (specs);
+
+		len = NM_PTRARRAY_LEN (specs);
+		g_assert_cmpint (len, >, 0u);
+
+		_nmtst_variant_attribute_spec_assert_sorted (specs, len);
+		for (i = 0; i < len; i++)
+			g_assert (specs[i] == _nm_variant_attribute_spec_find_binary_search (specs, len, specs[i]->name));
+		g_assert (!_nm_variant_attribute_spec_find_binary_search (specs, len, "bogus"));
+	}
+}
+
+/*****************************************************************************/
+
 static gboolean
 do_test_nm_set_out_called (int *call_count)
 {
@@ -8112,6 +8136,191 @@ test_ethtool_offload (void)
 
 /*****************************************************************************/
 
+typedef struct {
+	GMainLoop *loop1;
+	GMainContext *c2;
+	GSource *extra_sources[2];
+	bool got_signal[5];
+	int fd_2;
+} IntegData;
+
+static gboolean
+_test_integrate_cb_handle (IntegData *d, int signal)
+{
+	int i;
+
+	g_assert (d);
+	g_assert (signal >= 0);
+	g_assert (signal < G_N_ELEMENTS (d->got_signal));
+
+	g_assert (!d->got_signal[signal]);
+	d->got_signal[signal] = TRUE;
+
+	for (i = 0; i < G_N_ELEMENTS (d->got_signal); i++) {
+		if (!d->got_signal[i])
+			break;
+	}
+	if (i == G_N_ELEMENTS (d->got_signal))
+		g_main_loop_quit (d->loop1);
+	return G_SOURCE_REMOVE;
+}
+
+static gboolean
+_test_integrate_cb_timeout_1 (gpointer user_data)
+{
+	return _test_integrate_cb_handle (user_data, 0);
+}
+
+static gboolean
+_test_integrate_cb_fd_2 (int fd,
+                         GIOCondition condition,
+                         gpointer user_data)
+
+{
+	IntegData *d = user_data;
+
+	g_assert (d->got_signal[1]);
+	g_assert (d->got_signal[2]);
+	g_assert (d->got_signal[3]);
+	g_assert (d->extra_sources[0]);
+	g_assert (d->extra_sources[1]);
+
+	return _test_integrate_cb_handle (d, 4);
+}
+
+static gboolean
+_test_integrate_cb_idle_2 (gpointer user_data)
+{
+	IntegData *d = user_data;
+	GSource *extra_source;
+
+	g_assert (d->got_signal[1]);
+	g_assert (d->got_signal[2]);
+	g_assert (d->extra_sources[0]);
+	g_assert (!d->extra_sources[1]);
+
+	extra_source = g_unix_fd_source_new (d->fd_2, G_IO_IN);
+	g_source_set_callback (extra_source, G_SOURCE_FUNC (_test_integrate_cb_fd_2), d, NULL);
+	g_source_attach (extra_source, d->c2);
+
+	d->extra_sources[1] = extra_source;
+
+	return _test_integrate_cb_handle (d, 3);
+}
+
+static gboolean
+_test_integrate_cb_idle_1 (gpointer user_data)
+{
+	IntegData *d = user_data;
+	GSource *extra_source;
+
+	g_assert (d->got_signal[2]);
+	g_assert (!d->extra_sources[0]);
+
+	extra_source = g_idle_source_new ();
+	g_source_set_callback (extra_source, _test_integrate_cb_idle_2, d, NULL);
+	g_source_attach (extra_source, d->c2);
+
+	d->extra_sources[0] = extra_source;
+
+	return _test_integrate_cb_handle (d, 1);
+}
+
+static gboolean
+_test_integrate_cb_fd_1 (int fd,
+                         GIOCondition condition,
+                         gpointer user_data)
+
+{
+	IntegData *d = user_data;
+
+	g_assert (!d->got_signal[1]);
+	return _test_integrate_cb_handle (d, 2);
+}
+
+static gboolean
+_test_integrate_maincontext_cb_idle1 (gpointer user_data)
+{
+	guint32 *p_count = user_data;
+
+	g_assert (*p_count < 5);
+	(*p_count)++;
+	return G_SOURCE_CONTINUE;
+}
+
+static void
+test_integrate_maincontext (gconstpointer test_data)
+{
+	const guint TEST_IDX = GPOINTER_TO_UINT (test_data);
+	GMainContext *c1 = g_main_context_default ();
+	nm_auto_unref_gmaincontext GMainContext *c2 = g_main_context_new ();
+	nm_auto_destroy_and_unref_gsource GSource *integ_source = NULL;
+
+	integ_source = nm_utils_g_main_context_create_integrate_source (c2);
+	g_source_attach (integ_source, c1);
+
+	if (TEST_IDX == 1) {
+		nm_auto_destroy_and_unref_gsource GSource *idle_source_1 = NULL;
+		guint32 count = 0;
+
+		idle_source_1 = g_idle_source_new ();
+		g_source_set_callback (idle_source_1, _test_integrate_maincontext_cb_idle1, &count, NULL);
+		g_source_attach (idle_source_1, c2);
+
+		nmtst_main_context_iterate_until (c1, 2000, count == 5);
+	}
+
+	if (TEST_IDX == 2) {
+		nm_auto_destroy_and_unref_gsource GSource *main_timeout_source = NULL;
+		nm_auto_destroy_and_unref_gsource GSource *timeout_source_1 = NULL;
+		nm_auto_destroy_and_unref_gsource GSource *idle_source_1 = NULL;
+		nm_auto_destroy_and_unref_gsource GSource *fd_source_1 = NULL;
+		nm_auto_unref_gmainloop GMainLoop *loop1 = NULL;
+		nm_auto_close int fd_1 = -1;
+		nm_auto_close int fd_2 = -1;
+		IntegData d;
+		int i;
+
+		main_timeout_source = g_timeout_source_new (3000);
+		g_source_set_callback (main_timeout_source, nmtst_g_source_assert_not_called, NULL, NULL);
+		g_source_attach (main_timeout_source, c1);
+
+		loop1 = g_main_loop_new (c1, FALSE);
+
+		d = (IntegData) {
+			.loop1 = loop1,
+			.c2    = c2,
+		};
+
+		fd_1 = open ("/dev/null", O_RDONLY | O_CLOEXEC);
+		g_assert (fd_1 >= 0);
+		fd_source_1 = g_unix_fd_source_new (fd_1, G_IO_IN);
+		g_source_set_callback (fd_source_1, G_SOURCE_FUNC (_test_integrate_cb_fd_1), &d, NULL);
+		g_source_attach (fd_source_1, c2);
+
+		fd_2 = open ("/dev/null", O_RDONLY | O_CLOEXEC);
+		g_assert (fd_2 >= 0);
+		d.fd_2 = fd_2;
+
+		idle_source_1 = g_idle_source_new ();
+		g_source_set_callback (idle_source_1, _test_integrate_cb_idle_1, &d, NULL);
+		g_source_attach (idle_source_1, c2);
+
+		timeout_source_1 = g_timeout_source_new (5);
+		g_source_set_callback (timeout_source_1, _test_integrate_cb_timeout_1, &d, NULL);
+		g_source_attach (timeout_source_1, c2);
+
+		g_main_loop_run (loop1);
+
+		for (i = 0; i < G_N_ELEMENTS (d.extra_sources); i++) {
+			g_assert (d.extra_sources[i]);
+			nm_clear_pointer (&d.extra_sources[i], nm_g_source_destroy_and_unref);
+		}
+	}
+}
+
+/*****************************************************************************/
+
 NMTST_DEFINE ();
 
 int main (int argc, char **argv)
@@ -8267,10 +8476,14 @@ int main (int argc, char **argv)
 	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);
 	g_test_add_func ("/core/general/route_attributes/format", test_route_attributes_format);
+	g_test_add_func ("/core/general/test_variant_attribute_spec", test_variant_attribute_spec);
 
 	g_test_add_func ("/core/general/get_start_time_for_pid", test_get_start_time_for_pid);
 	g_test_add_func ("/core/general/test_nm_va_args_macros", test_nm_va_args_macros);
 	g_test_add_func ("/core/general/test_ethtool_offload", test_ethtool_offload);
 
+	g_test_add_data_func ("/core/general/test_integrate_maincontext/1", GUINT_TO_POINTER (1), test_integrate_maincontext);
+	g_test_add_data_func ("/core/general/test_integrate_maincontext/2", GUINT_TO_POINTER (2), test_integrate_maincontext);
+
 	return g_test_run ();
 }
diff --git a/libnm-core/tests/test-keyfile.c b/libnm-core/tests/test-keyfile.c
index 195f3797..574d671f 100644
--- a/libnm-core/tests/test-keyfile.c
+++ b/libnm-core/tests/test-keyfile.c
@@ -1,21 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Copyright 2015 Red Hat, Inc.
- *
+ * Copyright (C) 2015 Red Hat, Inc.
  */
 
 #include "nm-default.h"
diff --git a/libnm-core/tests/test-secrets.c b/libnm-core/tests/test-secrets.c
index d657a43c..63335669 100644
--- a/libnm-core/tests/test-secrets.c
+++ b/libnm-core/tests/test-secrets.c
@@ -1,21 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Copyright 2008 - 2011 Red Hat, Inc.
- *
+ * Copyright (C) 2008 - 2011 Red Hat, Inc.
  */
 
 #include "nm-default.h"
diff --git a/libnm-core/tests/test-setting.c b/libnm-core/tests/test-setting.c
index 0ddf3e8e..40852277 100644
--- a/libnm-core/tests/test-setting.c
+++ b/libnm-core/tests/test-setting.c
@@ -1,20 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Copyright 2008 - 2017 Red Hat, Inc.
- *
+ * Copyright (C) 2008 - 2017 Red Hat, Inc.
  */
 
 #include "nm-default.h"
@@ -22,6 +8,7 @@
 #include <linux/pkt_sched.h>
 #include <net/if.h>
 
+#include "nm-core-internal.h"
 #include "nm-utils.h"
 #include "nm-utils-private.h"
 #include "nm-core-internal.h"
@@ -3172,7 +3159,9 @@ test_routing_rule (gconstpointer test_data)
 	_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",
+	_rr_from_str ("priority 5 not to 0.0.0.0 dport 10-133 table 6",
+	              "not priority 5 to 0.0.0.0 dport 10-133 table 6",
+	              "not priority 5 not 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");
@@ -3328,6 +3317,275 @@ test_empty_setting (void)
 
 /*****************************************************************************/
 
+static guint
+_PROP_IDX_PACK (NMMetaSettingType meta_type,
+                guint idx)
+{
+	return   (((guint) meta_type) & 0xFFu)
+	       | (idx << 8);
+}
+
+static const char *
+_PROP_IDX_OWNER (GHashTable *h_property_types,
+                 const NMSettInfoPropertType *property_type)
+{
+	const NMSettInfoSetting *sett_info_settings = nmtst_sett_info_settings ();
+	const NMSettInfoSetting *sis;
+	const NMMetaSettingInfo *msi;
+	GArray *arr;
+	guint idx;
+	NMMetaSettingType meta_type;
+	guint prop_idx;
+	char sbuf[300];
+
+	g_assert (h_property_types);
+	g_assert (property_type);
+
+	arr = g_hash_table_lookup (h_property_types, property_type);
+
+	g_assert (arr);
+	g_assert (arr->len > 0);
+
+	idx = g_array_index (arr, guint, 0);
+
+	meta_type = (idx & 0xFFu);
+	prop_idx = idx >> 8;
+
+	g_assert (meta_type < _NM_META_SETTING_TYPE_NUM);
+
+	sis = &sett_info_settings[meta_type];
+	msi = &nm_meta_setting_infos[meta_type];
+
+	g_assert (prop_idx < sis->property_infos_len);
+
+	nm_sprintf_buf (sbuf, "%s.%s", msi->setting_name, sis->property_infos[prop_idx].name);
+
+	return g_intern_string (sbuf);
+}
+
+static void
+test_setting_metadata (void)
+{
+	const NMSettInfoSetting *sett_info_settings = nmtst_sett_info_settings ();
+	NMMetaSettingType meta_type;
+	gs_unref_hashtable GHashTable *h_property_types = NULL;
+
+	G_STATIC_ASSERT (_NM_META_SETTING_TYPE_NUM == NM_META_SETTING_TYPE_UNKNOWN);
+
+	h_property_types = g_hash_table_new_full (nm_direct_hash, NULL, NULL, (GDestroyNotify) g_array_unref);
+
+	for (meta_type = 0; meta_type < _NM_META_SETTING_TYPE_NUM; meta_type++) {
+		const NMMetaSettingInfo *msi = &nm_meta_setting_infos[meta_type];
+		nm_auto_unref_gtypeclass NMSettingClass *klass = NULL;
+		GType gtype;
+
+		g_assert (msi->setting_name);
+		g_assert (msi->get_setting_gtype);
+		g_assert (msi->meta_type == meta_type);
+		g_assert (msi->setting_priority >= NM_SETTING_PRIORITY_CONNECTION);
+		g_assert (msi->setting_priority <= NM_SETTING_PRIORITY_USER);
+
+		if (meta_type > 0)
+			g_assert_cmpint (strcmp (nm_meta_setting_infos[meta_type - 1].setting_name, msi->setting_name), <, 0);
+
+		gtype = msi->get_setting_gtype ();
+
+		g_assert (g_type_is_a (gtype, NM_TYPE_SETTING));
+		g_assert (gtype != NM_TYPE_SETTING);
+
+		klass = g_type_class_ref (gtype);
+		g_assert (klass);
+		g_assert (NM_IS_SETTING_CLASS (klass));
+
+		g_assert (msi == klass->setting_info);
+	}
+
+	g_assert (sett_info_settings);
+
+	for (meta_type = 0; meta_type < _NM_META_SETTING_TYPE_NUM; meta_type++) {
+		const NMSettInfoSetting *sis = &sett_info_settings[meta_type];
+		const NMMetaSettingInfo *msi = &nm_meta_setting_infos[meta_type];
+		gs_unref_hashtable GHashTable *h_properties = NULL;
+		GType gtype;
+		gs_unref_object NMSetting *setting = NULL;
+		guint prop_idx;
+		gs_free GParamSpec **property_specs = NULL;
+		guint n_property_specs;
+
+		g_assert (sis);
+
+		g_assert (NM_IS_SETTING_CLASS (sis->setting_class));
+
+		gtype = msi->get_setting_gtype ();
+
+		g_assert (G_TYPE_FROM_CLASS (sis->setting_class) == gtype);
+
+		setting = g_object_new (gtype, NULL);
+
+		g_assert (NM_IS_SETTING (setting));
+
+		g_assert_cmpint (sis->property_infos_len, >, 0);
+		g_assert (sis->property_infos);
+
+		h_properties = g_hash_table_new (nm_str_hash, g_str_equal);
+
+		for (prop_idx = 0; prop_idx < sis->property_infos_len; prop_idx++) {
+			const NMSettInfoProperty *sip = &sis->property_infos[prop_idx];
+			GArray *property_types_data;
+			guint prop_idx_val;
+
+			g_assert (sip->name);
+
+			if (prop_idx > 0)
+				g_assert_cmpint (strcmp (sis->property_infos[prop_idx - 1].name, sip->name), <, 0);
+
+			g_assert (sip->property_type);
+			g_assert (sip->property_type->dbus_type);
+			g_assert (g_variant_type_string_is_valid ((const char *) sip->property_type->dbus_type));
+
+			g_assert (!sip->property_type->to_dbus_fcn || !sip->property_type->gprop_to_dbus_fcn);
+			g_assert (!sip->property_type->from_dbus_fcn || !sip->property_type->gprop_from_dbus_fcn);
+
+			if (!g_hash_table_insert (h_properties, (char *) sip->name, sip->param_spec))
+				g_assert_not_reached ();
+
+			property_types_data = g_hash_table_lookup (h_property_types, sip->property_type);
+			if (!property_types_data) {
+				property_types_data = g_array_new (FALSE, FALSE, sizeof (guint));
+				if (!g_hash_table_insert (h_property_types, (gpointer) sip->property_type, property_types_data))
+					g_assert_not_reached ();
+			}
+			prop_idx_val = _PROP_IDX_PACK (meta_type, prop_idx);
+			g_array_append_val (property_types_data, prop_idx_val);
+
+			if (sip->param_spec) {
+				nm_auto_unset_gvalue GValue val = G_VALUE_INIT;
+
+				g_assert_cmpstr (sip->name, ==, sip->param_spec->name);
+
+				g_value_init (&val, sip->param_spec->value_type);
+				g_object_get_property (G_OBJECT (setting), sip->name, &val);
+
+				if (sip->param_spec->value_type == G_TYPE_STRING) {
+					const char *default_value;
+
+					default_value = ((const GParamSpecString *) sip->param_spec)->default_value;
+					if (default_value) {
+						/* having a string property with a default != NULL is really ugly. They
+						 * should be best avoided... */
+						if (   meta_type == NM_META_SETTING_TYPE_DCB
+						    && nm_streq (sip->name, NM_SETTING_DCB_APP_FCOE_MODE)) {
+							/* Whitelist the properties that have a non-NULL default value. */
+							g_assert_cmpstr (default_value, ==, NM_SETTING_DCB_FCOE_MODE_FABRIC);
+						} else
+							g_assert_not_reached ();
+					}
+
+					if (nm_streq (sip->name, NM_SETTING_NAME))
+						g_assert_cmpstr (g_value_get_string (&val), ==, msi->setting_name);
+					else
+						g_assert_cmpstr (g_value_get_string (&val), ==, default_value);
+				}
+
+				if (NM_FLAGS_HAS (sip->param_spec->flags, NM_SETTING_PARAM_TO_DBUS_IGNORE_FLAGS))
+					g_assert (sip->property_type->to_dbus_fcn);
+			}
+		}
+
+		/* check that all GObject based properties are tracked by the settings. */
+		property_specs = g_object_class_list_properties (G_OBJECT_CLASS (sis->setting_class),
+		                                                 &n_property_specs);
+		g_assert (property_specs);
+		g_assert_cmpint (n_property_specs, >, 0);
+		for (prop_idx = 0; prop_idx < n_property_specs; prop_idx++) {
+			const GParamSpec *pip = property_specs[prop_idx];
+
+			g_assert (g_hash_table_lookup (h_properties, pip->name) == pip);
+		}
+
+		/* check that property_infos_sorted is as expected. */
+		if (sis->property_infos_sorted) {
+			gs_unref_hashtable GHashTable *h = g_hash_table_new (nm_direct_hash, NULL);
+
+			/* property_infos_sorted is only implemented for [connection] type */
+			g_assert_cmpint (meta_type, ==, NM_META_SETTING_TYPE_CONNECTION);
+
+			/* ensure that there are no duplicates, and that all properties are also
+			 * tracked by sis->property_infos. */
+			for (prop_idx = 0; prop_idx < sis->property_infos_len; prop_idx++) {
+				const NMSettInfoProperty *sip = sis->property_infos_sorted[prop_idx];
+
+				if (!g_hash_table_add (h, (gpointer) sip))
+					g_assert_not_reached ();
+			}
+			for (prop_idx = 0; prop_idx < sis->property_infos_len; prop_idx++) {
+				const NMSettInfoProperty *sip = &sis->property_infos[prop_idx];
+
+				g_assert (g_hash_table_contains (h, sip));
+			}
+		} else
+			g_assert_cmpint (meta_type, !=, NM_META_SETTING_TYPE_CONNECTION);
+
+		/* consistency check for gendata-info. */
+		if (sis->detail.gendata_info) {
+			g_assert_cmpint (meta_type, ==, NM_META_SETTING_TYPE_ETHTOOL);
+			g_assert (sis->detail.gendata_info->get_variant_type);
+
+			/* the gendata info based setting has only one regular property: the "name". */
+			g_assert_cmpint (sis->property_infos_len, ==, 1);
+			g_assert_cmpstr (sis->property_infos[0].name, ==, NM_SETTING_NAME);
+		} else
+			g_assert_cmpint (meta_type, !=, NM_META_SETTING_TYPE_ETHTOOL);
+	}
+
+	{
+		gs_free NMSettInfoPropertType **a_property_types = NULL;
+		guint a_property_types_len;
+		guint prop_idx;
+		guint prop_idx_2;
+
+		a_property_types = (NMSettInfoPropertType **) g_hash_table_get_keys_as_array (h_property_types, &a_property_types_len);
+
+		for (prop_idx = 0; prop_idx < a_property_types_len; prop_idx++) {
+			const NMSettInfoPropertType *pt = a_property_types[prop_idx];
+
+			for (prop_idx_2 = prop_idx + 1; prop_idx_2 < a_property_types_len; prop_idx_2++) {
+				const NMSettInfoPropertType *pt_2 = a_property_types[prop_idx_2];
+
+				if (   !g_variant_type_equal (pt->dbus_type, pt_2->dbus_type)
+				    || pt->to_dbus_fcn != pt_2->to_dbus_fcn
+				    || pt->from_dbus_fcn != pt_2->from_dbus_fcn
+				    || pt->missing_from_dbus_fcn != pt_2->missing_from_dbus_fcn
+				    || pt->gprop_to_dbus_fcn != pt_2->gprop_to_dbus_fcn
+				    || pt->gprop_from_dbus_fcn != pt_2->gprop_from_dbus_fcn)
+					continue;
+
+				if (   (pt   == &nm_sett_info_propert_type_plain_i && pt_2 == &nm_sett_info_propert_type_deprecated_ignore_i)
+				    || (pt_2 == &nm_sett_info_propert_type_plain_i && pt   == &nm_sett_info_propert_type_deprecated_ignore_i)
+				    || (pt   == &nm_sett_info_propert_type_plain_u && pt_2 == &nm_sett_info_propert_type_deprecated_ignore_u)
+				    || (pt_2 == &nm_sett_info_propert_type_plain_u && pt   == &nm_sett_info_propert_type_deprecated_ignore_u)) {
+					/* These are known to be duplicated. This is the case for
+					 *   "gsm.network-type"  and plain properies like "802-11-wireless-security.fils" ("i" D-Bus type)
+					 *   "gsm.allowed-bands" and plain properies like "802-11-olpc-mesh.channel" ("u" D-Bus type)
+					 * While the content/behaviour of the property types are identical, their purpose
+					 * is different. So allowe them.
+					 */
+					continue;
+				}
+
+				/* the property-types with same content should all be shared. Here we have two that
+				 * are the same content, but different instances. Bug. */
+				g_error ("The identical property type for D-Bus type \"%s\" is used by: %s and %s",
+				         (const char *) pt->dbus_type,
+				         _PROP_IDX_OWNER (h_property_types, pt),
+				         _PROP_IDX_OWNER (h_property_types, pt_2));
+			}
+		}
+	}
+}
+
+/*****************************************************************************/
+
 NMTST_DEFINE ();
 
 int
@@ -3417,5 +3675,7 @@ main (int argc, char **argv)
 
 	g_test_add_func ("/libnm/test_empty_setting", test_empty_setting);
 
+	g_test_add_func ("/libnm/test_setting_metadata", test_setting_metadata);
+
 	return g_test_run ();
 }
diff --git a/libnm-core/tests/test-settings-defaults.c b/libnm-core/tests/test-settings-defaults.c
index c5156fc9..7cba245c 100644
--- a/libnm-core/tests/test-settings-defaults.c
+++ b/libnm-core/tests/test-settings-defaults.c
@@ -1,21 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Copyright 2008 - 2011 Red Hat, Inc.
- *
+ * Copyright (C) 2008 - 2011 Red Hat, Inc.
  */
 
 #include "nm-default.h"