summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2020-09-19 12:33:08 +0200
committerThomas Haller <thaller@redhat.com>2020-09-22 21:05:07 +0200
commit9a698cc5ba2d6074c13b171ae29f6323a162a0e7 (patch)
tree6c5c58673a6db9559b2172e632ffa7fdd27af44c
parent0397faaf8775f4e1aaa030d2aa1f9dfa876b6fcd (diff)
downloadNetworkManager-th/l3cfg-10.tar.gz
l3cfg/tests: add unit test for NML3Cfgth/l3cfg-10
-rw-r--r--.gitignore3
-rw-r--r--Makefile.am19
-rw-r--r--src/tests/meson.build5
-rw-r--r--src/tests/test-l3cfg.c358
-rwxr-xr-xtools/run-nm-test.sh1
5 files changed, 377 insertions, 9 deletions
diff --git a/.gitignore b/.gitignore
index 8c08337548..5cf1beb8d1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -256,11 +256,12 @@ test-*.trs
/src/settings/plugins/ifcfg-rh/tests/network-scripts/tmp/
/src/supplicant/tests/test-supplicant-config
/src/tests/config/test-config
-/src/tests/test-dcb
/src/tests/test-core
/src/tests/test-core-with-expect
+/src/tests/test-dcb
/src/tests/test-ip4-config
/src/tests/test-ip6-config
+/src/tests/test-l3cfg
/src/tests/test-route-manager-fake
/src/tests/test-route-manager-linux
/src/tests/test-systemd
diff --git a/Makefile.am b/Makefile.am
index 741b1e6eb2..0d02d3ff52 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4117,12 +4117,14 @@ src_tests_ldadd = \
check_programs += \
src/tests/test-core \
src/tests/test-core-with-expect \
+ src/tests/test-dcb \
src/tests/test-ip4-config \
src/tests/test-ip6-config \
- src/tests/test-dcb \
+ src/tests/test-l3cfg \
src/tests/test-systemd \
+ src/tests/test-utils \
src/tests/test-wired-defname \
- src/tests/test-utils
+ $(NULL)
src_tests_test_ip4_config_CPPFLAGS = $(src_cppflags_test)
src_tests_test_ip4_config_LDFLAGS = $(src_tests_ldflags)
@@ -4152,13 +4154,18 @@ src_tests_test_utils_CPPFLAGS = $(src_cppflags_test)
src_tests_test_utils_LDFLAGS = $(src_tests_ldflags)
src_tests_test_utils_LDADD = $(src_tests_ldadd)
-$(src_tests_test_ip4_config_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
-$(src_tests_test_ip6_config_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
-$(src_tests_test_dcb_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
+src_tests_test_l3cfg_CPPFLAGS = $(src_cppflags_test)
+src_tests_test_l3cfg_LDFLAGS = $(src_devices_tests_ldflags)
+src_tests_test_l3cfg_LDADD = $(src_tests_ldadd)
+
$(src_tests_test_core_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
$(src_tests_test_core_with_expect_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
-$(src_tests_test_wired_defname_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
+$(src_tests_test_dcb_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
+$(src_tests_test_ip4_config_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
+$(src_tests_test_ip6_config_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
+$(src_tests_test_l3cfg_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
$(src_tests_test_utils_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
+$(src_tests_test_wired_defname_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
src_tests_test_systemd_CPPFLAGS = \
$(src_libnm_systemd_core_la_cppflags) \
diff --git a/src/tests/meson.build b/src/tests/meson.build
index df8d1cf803..8ee8bd936e 100644
--- a/src/tests/meson.build
+++ b/src/tests/meson.build
@@ -5,11 +5,12 @@ subdir('config')
test_units = [
'test-core',
'test-core-with-expect',
+ 'test-dcb',
'test-ip4-config',
'test-ip6-config',
- 'test-dcb',
- 'test-wired-defname',
+ 'test-l3cfg',
'test-utils',
+ 'test-wired-defname',
]
foreach test_unit: test_units
diff --git a/src/tests/test-l3cfg.c b/src/tests/test-l3cfg.c
new file mode 100644
index 0000000000..0bd43799b1
--- /dev/null
+++ b/src/tests/test-l3cfg.c
@@ -0,0 +1,358 @@
+// SPDX-License-Identifier: LGPL-2.1+
+
+#include "nm-default.h"
+
+#include "nm-l3cfg.h"
+#include "nm-netns.h"
+#include "platform/nm-platform.h"
+
+#include "platform/tests/test-common.h"
+
+/*****************************************************************************/
+
+typedef struct {
+ int test_idx;
+ NMPlatform *platform;
+ NMNetns *netns;
+ NMDedupMultiIndex *multiidx;
+ const char *ifname0;
+ const char *ifname1;
+ NMPLinkAddress hwaddr0;
+ NMPLinkAddress hwaddr1;
+ int ifindex0;
+ int ifindex1;
+} TestFixture1;
+
+static const TestFixture1 *
+_test_fixture_1_setup (TestFixture1 *f, int test_idx)
+{
+ const NMPlatformLink *l0;
+ const NMPlatformLink *l1;
+
+ g_assert_cmpint (test_idx, >, 0);
+ g_assert_cmpint (f->test_idx, ==, 0);
+
+ f->test_idx = test_idx;
+
+ f->ifname0 = "nm-test-veth0";
+ f->ifname1 = "nm-test-veth1";
+
+ f->platform = g_object_ref (NM_PLATFORM_GET);
+ f->multiidx = nm_dedup_multi_index_ref (nm_platform_get_multi_idx (f->platform));
+ f->netns = nm_netns_new (f->platform);
+
+ l0 = nmtstp_link_veth_add (f->platform, -1, f->ifname0, f->ifname1);
+ l1 = nmtstp_link_get_typed (f->platform, -1, f->ifname1, NM_LINK_TYPE_VETH);
+
+ f->ifindex0 = l0->ifindex;
+ f->hwaddr0 = l0->l_address;
+
+ f->ifindex1 = l1->ifindex;
+ f->hwaddr1 = l1->l_address;
+
+ g_assert (nm_platform_link_set_up (f->platform, f->ifindex0, NULL));
+ g_assert (nm_platform_link_set_up (f->platform, f->ifindex1, NULL));
+
+ return f;
+}
+
+static void
+_test_fixture_1_teardown (TestFixture1 *f)
+{
+ g_assert (f);
+
+ if (f->test_idx == 0)
+ return;
+
+ _LOGD ("test teatdown");
+
+ nmtstp_link_delete (f->platform, -1, f->ifindex0, f->ifname0, TRUE);
+ g_assert (!nm_platform_link_get (f->platform, f->ifindex0));
+ g_assert (!nm_platform_link_get (f->platform, f->ifindex1));
+ g_assert (!nm_platform_link_get_by_ifname (f->platform, f->ifname0));
+ g_assert (!nm_platform_link_get_by_ifname (f->platform, f->ifname1));
+
+ g_object_unref (f->netns);
+ g_object_unref (f->platform);
+ nm_dedup_multi_index_unref (f->multiidx);
+
+ *f = (TestFixture1) {
+ .test_idx = 0,
+ };
+}
+
+/*****************************************************************************/
+
+typedef enum {
+ TEST_L3CFG_NOTIFY_TYPE_NONE,
+ TEST_L3CFG_NOTIFY_TYPE_IDLE_ASSERT_NO_SIGNAL,
+ TEST_L3CFG_NOTIFY_TYPE_COMMIT_1,
+ TEST_L3CFG_NOTIFY_TYPE_WAIT_FOR_ACD_READY_1,
+} TestL3cfgNotifyType;
+
+typedef struct {
+ const TestFixture1 *f;
+
+ TestL3cfgNotifyType notify_type;
+ guint post_commit_event_count;
+ guint general_event_count;
+ union {
+ struct {
+ int cb_count;
+ bool expected_probe_result:1;
+ } wait_for_acd_ready_1;
+ } notify_data;
+} TestL3cfgData;
+
+static void
+_test_l3cfg_data_set_notify_type (TestL3cfgData *tdata,
+ TestL3cfgNotifyType notify_type)
+{
+ g_assert (tdata);
+
+ tdata->notify_type = notify_type;
+ tdata->post_commit_event_count = 0;
+ tdata->general_event_count = 0;
+ memset (&tdata->notify_data, 0, sizeof (tdata->notify_data));
+}
+
+static void
+_test_l3cfg_signal_notify (NML3Cfg *l3cfg,
+ int notify_type_i,
+ const NML3ConfigNotifyPayload *payload,
+ TestL3cfgData *tdata)
+{
+ NML3ConfigNotifyType l3_notify_type = notify_type_i;
+
+ g_assert (NM_IS_L3CFG (l3cfg));
+ g_assert (tdata);
+ g_assert ((!!payload) == NM_IN_SET (l3_notify_type, NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE_ON_IDLE,
+ NM_L3_CONFIG_NOTIFY_TYPE_ACD_COMPLETED));
+
+ if (l3_notify_type == NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE_ON_IDLE)
+ g_assert (payload->platform_change_on_idle.obj_type_flags != 0u);
+
+ switch (tdata->notify_type) {
+ case TEST_L3CFG_NOTIFY_TYPE_NONE:
+ g_assert_not_reached ();
+ break;
+ case TEST_L3CFG_NOTIFY_TYPE_IDLE_ASSERT_NO_SIGNAL:
+ if (l3_notify_type == NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE_ON_IDLE)
+ return;
+ g_assert_not_reached ();
+ return;
+ case TEST_L3CFG_NOTIFY_TYPE_COMMIT_1:
+ g_assert_cmpint (tdata->post_commit_event_count, ==, 0);
+ switch (l3_notify_type) {
+ case NM_L3_CONFIG_NOTIFY_TYPE_POST_COMMIT:
+ tdata->post_commit_event_count++;
+ return;
+ case NM_L3_CONFIG_NOTIFY_TYPE_ACD_COMPLETED:
+ switch (tdata->f->test_idx) {
+ case 2:
+ nmtst_assert_ip4_address (payload->acd_completed.addr, "192.167.133.45");
+ g_assert (payload->acd_completed.probe_result);
+ g_assert (tdata->general_event_count == 0);
+ tdata->general_event_count++;
+ return;
+ default:
+ g_assert_not_reached ();
+ return;
+ }
+ default:
+ g_assert_not_reached ();
+ return;
+ }
+ case TEST_L3CFG_NOTIFY_TYPE_WAIT_FOR_ACD_READY_1:
+ if (l3_notify_type == NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE_ON_IDLE)
+ return;
+ if (l3_notify_type == NM_L3_CONFIG_NOTIFY_TYPE_ACD_COMPLETED) {
+ g_assert (tdata->notify_data.wait_for_acd_ready_1.cb_count == 0);
+ tdata->notify_data.wait_for_acd_ready_1.cb_count++;
+ return;
+ }
+ if (l3_notify_type == NM_L3_CONFIG_NOTIFY_TYPE_POST_COMMIT) {
+ g_assert (tdata->notify_data.wait_for_acd_ready_1.cb_count == 1);
+ tdata->notify_data.wait_for_acd_ready_1.cb_count++;
+ nmtstp_platform_ip_addresses_assert (tdata->f->platform,
+ tdata->f->ifindex0,
+ TRUE,
+ TRUE,
+ TRUE,
+ "192.167.133.45",
+ "1:2:3:4::45");
+ return;
+ }
+ g_assert_not_reached ();
+ return;
+ }
+
+ g_assert_not_reached ();
+}
+
+static void
+test_l3cfg (gconstpointer test_data)
+{
+ nm_auto (_test_fixture_1_teardown) TestFixture1 test_fixture = { };
+ const TestFixture1 *f;
+ NML3CfgCommitTypeHandle *commit_type_1;
+ NML3CfgCommitTypeHandle *commit_type_2;
+ gs_unref_object NML3Cfg *l3cfg0 = NULL;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd_a = NULL;
+ guint32 acd_timeout_msec = 0;
+ TestL3cfgData tdata_stack = {
+ .f = NULL,
+ };
+ TestL3cfgData *const tdata = &tdata_stack;
+
+ _LOGD ("test start (/l3cfg/%d)", GPOINTER_TO_INT (test_data));
+
+ if (nmtst_test_quick ()) {
+ gs_free char *msg = g_strdup_printf ("Skipping test: don't run long running test %s (NMTST_DEBUG=slow)\n",
+ g_get_prgname () ?: "test-l3cfg");
+
+ g_test_skip (msg);
+ return;
+ }
+
+ f = _test_fixture_1_setup (&test_fixture, GPOINTER_TO_INT (test_data));
+
+ tdata->f = f;
+
+ l3cfg0 = nm_netns_access_l3cfg (f->netns, f->ifindex0);
+ g_assert (NM_IS_L3CFG (l3cfg0));
+
+ g_signal_connect (l3cfg0,
+ NM_L3CFG_SIGNAL_NOTIFY,
+ G_CALLBACK (_test_l3cfg_signal_notify),
+ tdata);
+
+ commit_type_1 = nm_l3cfg_commit_type_register (l3cfg0, NM_L3_CFG_COMMIT_TYPE_UPDATE, NULL);
+
+ if ((nmtst_get_rand_uint32 () % 4u) != 0) {
+ commit_type_2 = nm_l3cfg_commit_type_register (l3cfg0,
+ nmtst_rand_select (NM_L3_CFG_COMMIT_TYPE_NONE,
+ NM_L3_CFG_COMMIT_TYPE_ASSUME,
+ NM_L3_CFG_COMMIT_TYPE_UPDATE),
+ NULL);
+ } else
+ commit_type_2 = NULL;
+
+ switch (f->test_idx) {
+ case 1:
+ break;
+ case 2:
+ case 3: {
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
+
+ l3cd = nm_l3_config_data_new (f->multiidx, f->ifindex0);
+
+ nm_l3_config_data_add_address_4 (l3cd,
+ NM_PLATFORM_IP4_ADDRESS_INIT (
+ .address = nmtst_inet4_from_string ("192.167.133.45"),
+ .peer_address = nmtst_inet4_from_string ("192.167.133.45"),
+ .plen = 24,
+ ));
+
+ nm_l3_config_data_add_address_6 (l3cd,
+ NM_PLATFORM_IP6_ADDRESS_INIT (
+ .address = *nmtst_inet6_from_string ("1:2:3:4::45"),
+ .plen = 64,
+ ));
+
+ if (nmtst_get_rand_bool ())
+ nm_l3_config_data_seal (l3cd);
+ l3cd_a = g_steal_pointer (&l3cd);
+ break;
+ }
+ }
+
+ acd_timeout_msec = (f->test_idx == 3) ? 2000u : 0u;
+
+ if (l3cd_a) {
+ nm_l3cfg_add_config (l3cfg0,
+ GINT_TO_POINTER ('a'),
+ nmtst_get_rand_bool (),
+ l3cd_a,
+ 'a',
+ 0,
+ 0,
+ acd_timeout_msec,
+ NM_L3_CONFIG_MERGE_FLAGS_NONE);
+ }
+
+ nm_l3_config_data_log (nm_l3cfg_get_combined_l3cd (l3cfg0, FALSE),
+ "test",
+ "platform-test: l3cfg0: ",
+ LOGL_DEBUG,
+ LOGD_PLATFORM);
+
+ _test_l3cfg_data_set_notify_type (tdata, TEST_L3CFG_NOTIFY_TYPE_COMMIT_1);
+ nm_l3cfg_platform_commit (l3cfg0,
+ NM_L3_CFG_COMMIT_TYPE_REAPPLY);
+ g_assert_cmpint (tdata->post_commit_event_count, ==, 1);
+ _test_l3cfg_data_set_notify_type (tdata, TEST_L3CFG_NOTIFY_TYPE_NONE);
+
+ nmtstp_platform_ip_addresses_assert (tdata->f->platform,
+ tdata->f->ifindex0,
+ TRUE,
+ TRUE,
+ TRUE,
+ NM_IN_SET (f->test_idx, 2) ? "192.167.133.45" : NULL,
+ NM_IN_SET (f->test_idx, 2, 3) ? "1:2:3:4::45" : NULL);
+
+ if (NM_IN_SET (f->test_idx, 1, 2)) {
+ _test_l3cfg_data_set_notify_type (tdata, TEST_L3CFG_NOTIFY_TYPE_IDLE_ASSERT_NO_SIGNAL);
+ _LOGT ("poll 1 start");
+ nmtst_main_context_iterate_until (NULL, nmtst_get_rand_uint32 () % 5000u, FALSE);
+ _LOGT ("poll 1 end");
+ _test_l3cfg_data_set_notify_type (tdata, TEST_L3CFG_NOTIFY_TYPE_NONE);
+ }
+
+ if (NM_IN_SET (f->test_idx, 3)) {
+ _test_l3cfg_data_set_notify_type (tdata, TEST_L3CFG_NOTIFY_TYPE_WAIT_FOR_ACD_READY_1);
+ tdata->notify_data.wait_for_acd_ready_1.expected_probe_result = TRUE;
+ _LOGT ("poll 2 start");
+ nmtst_main_context_iterate_until (NULL,
+ 2500u + (nmtst_get_rand_uint32 () % 4000u),
+ FALSE);
+ _LOGT ("poll 2 end");
+ g_assert_cmpint (tdata->notify_data.wait_for_acd_ready_1.cb_count, ==, 2);
+ _test_l3cfg_data_set_notify_type (tdata, TEST_L3CFG_NOTIFY_TYPE_NONE);
+ }
+
+ g_signal_handlers_disconnect_by_func (l3cfg0,
+ G_CALLBACK (_test_l3cfg_signal_notify),
+ tdata);
+
+ nm_l3cfg_commit_type_unregister (l3cfg0, commit_type_1);
+ nm_l3cfg_commit_type_unregister (l3cfg0, commit_type_2);
+
+ if ((nmtst_get_rand_uint32 () % 3) == 0)
+ _test_fixture_1_teardown (&test_fixture);
+
+ nm_l3cfg_remove_config_all (l3cfg0, GINT_TO_POINTER ('a'), FALSE);
+
+ if ((nmtst_get_rand_uint32 () % 3) == 0)
+ _test_fixture_1_teardown (&test_fixture);
+
+ _LOGD ("test end (/l3cfg/%d)", f->test_idx);
+}
+
+/*****************************************************************************/
+
+NMTstpSetupFunc const _nmtstp_setup_platform_func = nm_linux_platform_setup;
+
+void
+_nmtstp_init_tests (int *argc, char ***argv)
+{
+ nmtst_init_with_logging (argc, argv, NULL, "ALL");
+}
+
+void
+_nmtstp_setup_tests (void)
+{
+ g_test_add_data_func ("/l3cfg/1", GINT_TO_POINTER (1), test_l3cfg);
+ g_test_add_data_func ("/l3cfg/2", GINT_TO_POINTER (2), test_l3cfg);
+ g_test_add_data_func ("/l3cfg/3", GINT_TO_POINTER (3), test_l3cfg);
+}
diff --git a/tools/run-nm-test.sh b/tools/run-nm-test.sh
index 5a6247cfc9..f452d9d4b8 100755
--- a/tools/run-nm-test.sh
+++ b/tools/run-nm-test.sh
@@ -314,6 +314,7 @@ if [ $HAS_ERRORS -eq 0 ]; then
'test-address-linux' | \
'test-cleanup-linux' | \
'test-config' | \
+ 'test-l3cfg' | \
'test-link-linux' | \
'test-lldp' | \
'test-nm-client' | \