diff options
author | Thomas Haller <thaller@redhat.com> | 2020-09-19 12:33:08 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2020-09-24 09:44:04 +0200 |
commit | 7141537097717d45a39e364d164a14f1883d7c31 (patch) | |
tree | c8562e5cc4b2666437b4c20b1b37607515615649 | |
parent | 36959491516b60381c6941a10517c7b97cd79dea (diff) | |
download | NetworkManager-7141537097717d45a39e364d164a14f1883d7c31.tar.gz |
l3cfg/tests: add unit test for NML3Cfg
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | Makefile.am | 19 | ||||
-rw-r--r-- | src/tests/meson.build | 5 | ||||
-rw-r--r-- | src/tests/test-l3cfg.c | 358 | ||||
-rwxr-xr-x | tools/run-nm-test.sh | 1 |
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' | \ |