platform/test: add test adding IPv4 addresses that only differ by their peer-address

Also do a major cleanup of the tests:

- Have utility functions in "test-common.h" with a new prefix "nmtstp_".
  The prefix indicates that these are test functions for platform.

- Add functions to add/remove IP addresses that either use external
  iproute2 command or platform function itself. These commands also
  assert whether the command had the expected result.

- Randomize, whether we use the external command for adding
  ip-addresses. Both approaches should yield the same result
  for linux-platform.
  I did this now for address-tests, but effectively this doubled
  all our previous tests to use both internal and external ways
  to configure the address.

- Enable all address tests for fake-platform. They now
  automatically don't call external iproute2 but fallback
  to fake-platform implementation. This adds more coverage
  to the fake-platform, which we want to behave identical
  to linux-platform.

- Setup a clean test device before every address-test.
This commit is contained in:
Thomas Haller
2015-10-13 19:49:09 +02:00
parent 0d5428b1bd
commit 06aafabf14
5 changed files with 753 additions and 80 deletions

View File

@@ -908,7 +908,7 @@ ip4_address_add (NMPlatform *platform,
address.source = NM_IP_CONFIG_SOURCE_KERNEL; address.source = NM_IP_CONFIG_SOURCE_KERNEL;
address.ifindex = ifindex; address.ifindex = ifindex;
address.address = addr; address.address = addr;
address.peer_address = peer_addr; address.peer_address = peer_addr && peer_addr != addr ? peer_addr : 0;
address.plen = plen; address.plen = plen;
address.timestamp = nm_utils_get_monotonic_timestamp_s (); address.timestamp = nm_utils_get_monotonic_timestamp_s ();
address.lifetime = lifetime; address.lifetime = lifetime;
@@ -925,6 +925,8 @@ ip4_address_add (NMPlatform *platform,
continue; continue;
if (item->plen != address.plen) if (item->plen != address.plen)
continue; continue;
if (!nm_platform_ip4_address_equal_peer_net (item, &address))
continue;
memcpy (item, &address, sizeof (address)); memcpy (item, &address, sizeof (address));
g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NMP_OBJECT_TYPE_IP4_ADDRESS, ifindex, &address, NM_PLATFORM_SIGNAL_CHANGED, NM_PLATFORM_REASON_INTERNAL); g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NMP_OBJECT_TYPE_IP4_ADDRESS, ifindex, &address, NM_PLATFORM_SIGNAL_CHANGED, NM_PLATFORM_REASON_INTERNAL);
@@ -954,7 +956,7 @@ ip6_address_add (NMPlatform *platform,
address.source = NM_IP_CONFIG_SOURCE_KERNEL; address.source = NM_IP_CONFIG_SOURCE_KERNEL;
address.ifindex = ifindex; address.ifindex = ifindex;
address.address = addr; address.address = addr;
address.peer_address = peer_addr; address.peer_address = (IN6_IS_ADDR_UNSPECIFIED (&peer_addr) || IN6_ARE_ADDR_EQUAL (&addr, &peer_addr)) ? in6addr_any : peer_addr;
address.plen = plen; address.plen = plen;
address.timestamp = nm_utils_get_monotonic_timestamp_s (); address.timestamp = nm_utils_get_monotonic_timestamp_s ();
address.lifetime = lifetime; address.lifetime = lifetime;

View File

@@ -4,10 +4,17 @@
#define DEVICE_NAME "nm-test-device" #define DEVICE_NAME "nm-test-device"
#define IP4_ADDRESS "192.0.2.1" #define IP4_ADDRESS "192.0.2.1"
#define IP4_ADDRESS_PEER "192.0.2.2"
#define IP4_ADDRESS_PEER2 "192.0.3.1"
#define IP4_PLEN 24 #define IP4_PLEN 24
#define IP6_ADDRESS "2001:db8:a:b:1:2:3:4" #define IP6_ADDRESS "2001:db8:a:b:1:2:3:4"
#define IP6_PLEN 64 #define IP6_PLEN 64
static int DEVICE_IFINDEX = -1;
static int EX = -1;
/*****************************************************************************/
static void static void
ip4_address_callback (NMPlatform *platform, NMPObjectType obj_type, int ifindex, NMPlatformIP4Address *received, NMPlatformSignalChangeType change_type, NMPlatformReason reason, SignalData *data) ip4_address_callback (NMPlatform *platform, NMPObjectType obj_type, int ifindex, NMPlatformIP4Address *received, NMPlatformSignalChangeType change_type, NMPlatformReason reason, SignalData *data)
{ {
@@ -48,10 +55,12 @@ ip6_address_callback (NMPlatform *platform, NMPObjectType obj_type, int ifindex,
_LOGD ("Received signal '%s' %dth time.", data->name, data->received_count); _LOGD ("Received signal '%s' %dth time.", data->name, data->received_count);
} }
/*****************************************************************************/
static void static void
test_ip4_address (void) test_ip4_address_general (void)
{ {
int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); const int ifindex = DEVICE_IFINDEX;
SignalData *address_added = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip4_address_callback, ifindex); SignalData *address_added = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip4_address_callback, ifindex);
SignalData *address_changed = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, ip4_address_callback, ifindex); SignalData *address_changed = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, ip4_address_callback, ifindex);
SignalData *address_removed = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip4_address_callback, ifindex); SignalData *address_removed = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip4_address_callback, ifindex);
@@ -65,12 +74,12 @@ test_ip4_address (void)
/* Add address */ /* Add address */
g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0)); g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0));
g_assert (nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0, lifetime, preferred, NULL)); nmtstp_ip4_address_add (EX, ifindex, addr, IP4_PLEN, 0, lifetime, preferred, NULL);
g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0)); g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0));
accept_signal (address_added); accept_signal (address_added);
/* Add address again (aka update) */ /* Add address again (aka update) */
g_assert (nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0, lifetime, preferred, NULL)); nmtstp_ip4_address_add (EX, ifindex, addr, IP4_PLEN, 0, lifetime + 100, preferred + 50, NULL);
accept_signals (address_changed, 0, 1); accept_signals (address_changed, 0, 1);
/* Test address listing */ /* Test address listing */
@@ -84,12 +93,12 @@ test_ip4_address (void)
g_array_unref (addresses); g_array_unref (addresses);
/* Remove address */ /* Remove address */
g_assert (nm_platform_ip4_address_delete (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0)); nmtstp_ip4_address_del (EX, ifindex, addr, IP4_PLEN, 0);
g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0)); g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0));
accept_signal (address_removed); accept_signal (address_removed);
/* Remove address again */ /* Remove address again */
g_assert (nm_platform_ip4_address_delete (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0)); nmtstp_ip4_address_del (EX, ifindex, addr, IP4_PLEN, 0);
free_signal (address_added); free_signal (address_added);
free_signal (address_changed); free_signal (address_changed);
@@ -97,9 +106,9 @@ test_ip4_address (void)
} }
static void static void
test_ip6_address (void) test_ip6_address_general (void)
{ {
int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); const int ifindex = DEVICE_IFINDEX;
SignalData *address_added = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip6_address_callback, ifindex); SignalData *address_added = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip6_address_callback, ifindex);
SignalData *address_changed = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, ip6_address_callback, ifindex); SignalData *address_changed = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, ip6_address_callback, ifindex);
SignalData *address_removed = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip6_address_callback, ifindex); SignalData *address_removed = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip6_address_callback, ifindex);
@@ -114,12 +123,12 @@ test_ip6_address (void)
/* Add address */ /* Add address */
g_assert (!nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN)); g_assert (!nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
g_assert (nm_platform_ip6_address_add (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, flags)); nmtstp_ip6_address_add (EX, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, flags);
g_assert (nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN)); g_assert (nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
accept_signal (address_added); accept_signal (address_added);
/* Add address again (aka update) */ /* Add address again (aka update) */
g_assert (nm_platform_ip6_address_add (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, flags)); nmtstp_ip6_address_add (EX, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, flags);
accept_signals (address_changed, 0, 1); accept_signals (address_changed, 0, 1);
/* Test address listing */ /* Test address listing */
@@ -133,12 +142,12 @@ test_ip6_address (void)
g_array_unref (addresses); g_array_unref (addresses);
/* Remove address */ /* Remove address */
g_assert (nm_platform_ip6_address_delete (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN)); nmtstp_ip6_address_del (EX, ifindex, addr, IP6_PLEN);
g_assert (!nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN)); g_assert (!nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
accept_signal (address_removed); accept_signal (address_removed);
/* Remove address again */ /* Remove address again */
g_assert (nm_platform_ip6_address_delete (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN)); nmtstp_ip6_address_del (EX, ifindex, addr, IP6_PLEN);
free_signal (address_added); free_signal (address_added);
free_signal (address_changed); free_signal (address_changed);
@@ -146,11 +155,11 @@ test_ip6_address (void)
} }
static void static void
test_ip4_address_external (void) test_ip4_address_general_2 (void)
{ {
const int ifindex = DEVICE_IFINDEX;
SignalData *address_added = add_signal (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip4_address_callback); SignalData *address_added = add_signal (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip4_address_callback);
SignalData *address_removed = add_signal (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip4_address_callback); SignalData *address_removed = add_signal (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip4_address_callback);
int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
in_addr_t addr; in_addr_t addr;
guint32 lifetime = 2000; guint32 lifetime = 2000;
guint32 preferred = 1000; guint32 preferred = 1000;
@@ -161,38 +170,31 @@ test_ip4_address_external (void)
/* Looks like addresses are not announced by kerenl when the interface /* Looks like addresses are not announced by kerenl when the interface
* is down. Link-local IPv6 address is automatically added. * is down. Link-local IPv6 address is automatically added.
*/ */
g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME), NULL)); g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, DEVICE_IFINDEX, NULL));
/* Add/delete notification */ /* Add/delete notification */
run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d", nmtstp_ip4_address_add (EX, ifindex, addr, IP4_PLEN, 0, lifetime, preferred, NULL);
IP4_ADDRESS, IP4_PLEN, DEVICE_NAME, lifetime, preferred); accept_signal (address_added);
wait_signal (address_added);
g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0)); g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0));
run_command ("ip address delete %s/%d dev %s", IP4_ADDRESS, IP4_PLEN, DEVICE_NAME); nmtstp_ip4_address_del (EX, ifindex, addr, IP4_PLEN, 0);
wait_signal (address_removed); accept_signal (address_removed);
g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0)); g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0));
/* Add/delete conflict */ /* Add/delete conflict */
run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d", nmtstp_ip4_address_add (EX, ifindex, addr, IP4_PLEN, 0, lifetime, preferred, NULL);
IP4_ADDRESS, IP4_PLEN, DEVICE_NAME, lifetime, preferred);
g_assert (nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0, lifetime, preferred, NULL));
g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0)); g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0));
accept_signal (address_added); accept_signal (address_added);
/*run_command ("ip address delete %s/%d dev %s", IP4_ADDRESS, IP4_PLEN, DEVICE_NAME);
g_assert (nm_platform_ip4_address_delete (ifindex, addr, IP4_PLEN, 0));
g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0));
accept_signal (address_removed);*/
free_signal (address_added); free_signal (address_added);
free_signal (address_removed); free_signal (address_removed);
} }
static void static void
test_ip6_address_external (void) test_ip6_address_general_2 (void)
{ {
const int ifindex = DEVICE_IFINDEX;
SignalData *address_added = add_signal (NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip6_address_callback); SignalData *address_added = add_signal (NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip6_address_callback);
SignalData *address_removed = add_signal (NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip6_address_callback); SignalData *address_removed = add_signal (NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip6_address_callback);
int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
struct in6_addr addr; struct in6_addr addr;
guint32 lifetime = 2000; guint32 lifetime = 2000;
guint32 preferred = 1000; guint32 preferred = 1000;
@@ -201,51 +203,143 @@ test_ip6_address_external (void)
inet_pton (AF_INET6, IP6_ADDRESS, &addr); inet_pton (AF_INET6, IP6_ADDRESS, &addr);
/* Add/delete notification */ /* Add/delete notification */
run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d", nmtstp_ip6_address_add (EX, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, 0);
IP6_ADDRESS, IP6_PLEN, DEVICE_NAME, lifetime, preferred); accept_signal (address_added);
wait_signal (address_added);
g_assert (nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN)); g_assert (nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
run_command ("ip address delete %s/%d dev %s", IP6_ADDRESS, IP6_PLEN, DEVICE_NAME);
wait_signal (address_removed); nmtstp_ip6_address_del (EX, ifindex, addr, IP6_PLEN);
accept_signal (address_removed);
g_assert (!nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN)); g_assert (!nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
/* Add/delete conflict */ /* Add/delete conflict */
run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d", nmtstp_ip6_address_add (EX, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, 0);
IP6_ADDRESS, IP6_PLEN, DEVICE_NAME, lifetime, preferred);
g_assert (nm_platform_ip6_address_add (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, flags));
g_assert (nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
accept_signal (address_added); accept_signal (address_added);
/*run_command ("ip address delete %s/%d dev %s", IP6_ADDRESS, IP6_PLEN, DEVICE_NAME); g_assert (nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
g_assert (nm_platform_ip6_address_delete (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
g_assert (!nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN)); nmtstp_ip6_address_add (EX, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, flags);
wait_signal (address_removed);*/ ensure_no_signal (address_added);
g_assert (nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
free_signal (address_added); free_signal (address_added);
free_signal (address_removed); free_signal (address_removed);
} }
/*****************************************************************************/
static void
test_ip4_address_peer (void)
{
const int ifindex = DEVICE_IFINDEX;
SignalData *address_added = add_signal (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip4_address_callback);
SignalData *address_removed = add_signal (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip4_address_callback);
in_addr_t addr, addr_peer, addr_peer2;
guint32 lifetime = 2000;
guint32 preferred = 1000;
const NMPlatformIP4Address *a;
inet_pton (AF_INET, IP4_ADDRESS, &addr);
inet_pton (AF_INET, IP4_ADDRESS_PEER, &addr_peer);
inet_pton (AF_INET, IP4_ADDRESS_PEER2, &addr_peer2);
g_assert (ifindex > 0);
g_assert (addr != addr_peer);
g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, ifindex, NULL));
accept_signals (address_removed, 0, G_MAXINT);
accept_signals (address_added, 0, G_MAXINT);
/* Add/delete notification */
nmtstp_ip4_address_add (EX, ifindex, addr, IP4_PLEN, addr_peer, lifetime, preferred, NULL);
accept_signal (address_added);
g_assert ((a = nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer)));
g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer2));
nmtstp_ip_address_assert_lifetime ((NMPlatformIPAddress *) a, -1, lifetime, preferred);
nmtstp_ip4_address_add (EX, ifindex, addr, IP4_PLEN, addr_peer2, lifetime, preferred, NULL);
accept_signal (address_added);
g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer));
g_assert ((a = nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer2)));
nmtstp_ip_address_assert_lifetime ((NMPlatformIPAddress *) a, -1, lifetime, preferred);
g_assert (addr != addr_peer);
nmtstp_ip4_address_del (EX, ifindex, addr, IP4_PLEN, addr_peer);
accept_signal (address_removed);
g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer));
g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer2));
free_signal (address_added);
free_signal (address_removed);
}
/*****************************************************************************/
void void
init_tests (int *argc, char ***argv) init_tests (int *argc, char ***argv)
{ {
nmtst_init_with_logging (argc, argv, NULL, "ALL"); nmtst_init_with_logging (argc, argv, NULL, "ALL");
} }
void /*****************************************************************************
setup_tests (void) * SETUP TESTS
*****************************************************************************/
typedef struct {
const char *testpath;
GTestFunc test_func;
} TestSetup;
static void
_g_test_run (gconstpointer user_data)
{ {
SignalData *link_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, DEVICE_NAME); const TestSetup *s = user_data;
int ifindex;
_LOGt ("TEST: start %s", s->testpath);
nm_platform_link_delete (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME)); nm_platform_link_delete (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME));
g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, DEVICE_NAME)); g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, DEVICE_NAME));
g_assert (nm_platform_dummy_add (NM_PLATFORM_GET, DEVICE_NAME, NULL) == NM_PLATFORM_ERROR_SUCCESS); g_assert_cmpint (nm_platform_dummy_add (NM_PLATFORM_GET, DEVICE_NAME, NULL), ==, NM_PLATFORM_ERROR_SUCCESS);
accept_signal (link_added);
free_signal (link_added);
g_test_add_func ("/address/internal/ip4", test_ip4_address); ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
g_test_add_func ("/address/internal/ip6", test_ip6_address); g_assert_cmpint (ifindex, >, 0);
g_assert_cmpint (DEVICE_IFINDEX, ==, -1);
if (strcmp (g_type_name (G_TYPE_FROM_INSTANCE (nm_platform_get ())), "NMFakePlatform")) { DEVICE_IFINDEX = ifindex;
g_test_add_func ("/address/external/ip4", test_ip4_address_external); EX = nmtstp_run_command_check_external_global ();
g_test_add_func ("/address/external/ip6", test_ip6_address_external);
s->test_func ();
g_assert_cmpint (DEVICE_IFINDEX, ==, ifindex);
DEVICE_IFINDEX = -1;
g_assert_cmpint (ifindex, ==, nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME));
g_assert (nm_platform_link_delete (NM_PLATFORM_GET, ifindex));
_LOGt ("TEST: finished %s", s->testpath);
} }
static void
_g_test_add_func (const char *testpath,
GTestFunc test_func)
{
TestSetup *s;
s = g_new0 (TestSetup, 1);
s->testpath = testpath;
s->test_func = test_func;
g_test_add_data_func_full (testpath, s, _g_test_run, g_free);
}
void
setup_tests (void)
{
_g_test_add_func ("/address/ipv4/general", test_ip4_address_general);
_g_test_add_func ("/address/ipv6/general", test_ip6_address_general);
_g_test_add_func ("/address/ipv4/general-2", test_ip4_address_general_2);
_g_test_add_func ("/address/ipv6/general-2", test_ip6_address_general_2);
_g_test_add_func ("/address/ipv4/peer", test_ip4_address_peer);
} }

View File

@@ -10,9 +10,16 @@
#define SIGNAL_DATA_FMT "'%s-%s' ifindex %d%s%s%s (%d times received)" #define SIGNAL_DATA_FMT "'%s-%s' ifindex %d%s%s%s (%d times received)"
#define SIGNAL_DATA_ARG(data) (data)->name, nm_platform_signal_change_type_to_string ((data)->change_type), (data)->ifindex, (data)->ifname ? " ifname '" : "", (data)->ifname ? (data)->ifname : "", (data)->ifname ? "'" : "", (data)->received_count #define SIGNAL_DATA_ARG(data) (data)->name, nm_platform_signal_change_type_to_string ((data)->change_type), (data)->ifindex, (data)->ifname ? " ifname '" : "", (data)->ifname ? (data)->ifname : "", (data)->ifname ? "'" : "", (data)->received_count
typedef struct {
union {
guint8 addr_ptr[1];
in_addr_t addr4;
struct in6_addr addr6;
};
} IPAddr;
gboolean gboolean
nmtst_platform_is_root_test (void) nmtstp_is_root_test (void)
{ {
NM_PRAGMA_WARNING_DISABLE("-Wtautological-compare") NM_PRAGMA_WARNING_DISABLE("-Wtautological-compare")
return (SETUP == nm_linux_platform_setup); return (SETUP == nm_linux_platform_setup);
@@ -20,9 +27,9 @@ nmtst_platform_is_root_test (void)
} }
gboolean gboolean
nmtst_platform_is_sysfs_writable (void) nmtstp_is_sysfs_writable (void)
{ {
return !nmtst_platform_is_root_test () return !nmtstp_is_root_test ()
|| (access ("/sys/devices", W_OK) == 0); || (access ("/sys/devices", W_OK) == 0);
} }
@@ -69,6 +76,19 @@ _ensure_no_signal (const char *file, int line, const char *func, SignalData *dat
g_error ("NMPlatformSignalAssert: %s:%d, %s(): failure to accept signal 0 times: "SIGNAL_DATA_FMT, file, line, func, SIGNAL_DATA_ARG (data)); g_error ("NMPlatformSignalAssert: %s:%d, %s(): failure to accept signal 0 times: "SIGNAL_DATA_FMT, file, line, func, SIGNAL_DATA_ARG (data));
} }
void
_accept_or_wait_signal (const char *file, int line, const char *func, SignalData *data)
{
_LOGD ("NMPlatformSignalAssert: %s:%d, %s(): accept-or-wait signal: "SIGNAL_DATA_FMT, file, line, func, SIGNAL_DATA_ARG (data));
if (data->received_count == 0) {
data->loop = g_main_loop_new (NULL, FALSE);
g_main_loop_run (data->loop);
g_clear_pointer (&data->loop, g_main_loop_unref);
}
_accept_signal (file, line, func, data);
}
void void
_wait_signal (const char *file, int line, const char *func, SignalData *data) _wait_signal (const char *file, int line, const char *func, SignalData *data)
{ {
@@ -253,21 +273,534 @@ _assert_ip4_route_exists (const char *file, guint line, const char *func, gboole
} }
} }
void int
run_command (const char *format, ...) nmtstp_run_command (const char *format, ...)
{ {
char *command; int result;
gs_free char *command = NULL;
va_list ap; va_list ap;
va_start (ap, format); va_start (ap, format);
command = g_strdup_vprintf (format, ap); command = g_strdup_vprintf (format, ap);
va_end (ap); va_end (ap);
_LOGD ("Running command: %s", command); _LOGD ("Running command: %s", command);
g_assert (!system (command)); result = system (command);
_LOGD ("Command finished."); _LOGD ("Command finished: result=%d", result);
g_free (command);
return result;
} }
/*****************************************************************************/
typedef struct {
GMainLoop *loop;
gboolean timeout;
guint id;
} WaitForSignalData;
static void
_wait_for_signal_cb (NMPlatform *platform,
NMPObjectType obj_type,
int ifindex,
NMPlatformLink *plink,
NMPlatformSignalChangeType change_type,
NMPlatformReason reason,
gpointer user_data)
{
WaitForSignalData *data = user_data;
g_main_loop_quit (data->loop);
}
static gboolean
_wait_for_signal_timeout (gpointer user_data)
{
WaitForSignalData *data = user_data;
data->timeout = TRUE;
data->id = 0;
g_main_loop_quit (data->loop);
return G_SOURCE_REMOVE;
}
gboolean
nmtstp_wait_for_signal (guint timeout_ms)
{
WaitForSignalData data = { 0 };
guint id_link, id_ip4_address, id_ip6_address, id_ip4_route, id_ip6_route;
data.loop = g_main_loop_new (NULL, FALSE);
id_link = g_signal_connect (NM_PLATFORM_GET, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data);
id_ip4_address = g_signal_connect (NM_PLATFORM_GET, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data);
id_ip6_address = g_signal_connect (NM_PLATFORM_GET, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data);
id_ip4_route = g_signal_connect (NM_PLATFORM_GET, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data);
id_ip6_route = g_signal_connect (NM_PLATFORM_GET, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data);
if (timeout_ms != 0)
data.id = g_timeout_add (timeout_ms, _wait_for_signal_timeout, &data);
g_main_loop_run (data.loop);
g_assert (nm_clear_g_signal_handler (NM_PLATFORM_GET, &id_link));
g_assert (nm_clear_g_signal_handler (NM_PLATFORM_GET, &id_ip4_address));
g_assert (nm_clear_g_signal_handler (NM_PLATFORM_GET, &id_ip6_address));
g_assert (nm_clear_g_signal_handler (NM_PLATFORM_GET, &id_ip4_route));
g_assert (nm_clear_g_signal_handler (NM_PLATFORM_GET, &id_ip6_route));
if (nm_clear_g_source (&data.id))
g_assert (timeout_ms != 0 && !data.timeout);
g_clear_pointer (&data.loop, g_main_loop_unref);
return !data.timeout;
}
gboolean
nmtstp_wait_for_signal_until (gint64 until_ms)
{
gint64 now;
while (TRUE) {
now = nm_utils_get_monotonic_timestamp_ms ();
if (until_ms < now)
return FALSE;
if (nmtstp_wait_for_signal (MAX (1, until_ms - now)))
return TRUE;
}
}
int
nmtstp_run_command_check_external_global (void)
{
if (!nmtstp_is_root_test ())
return FALSE;
switch (nmtst_get_rand_int () % 3) {
case 0:
return -1;
case 1:
return FALSE;
default:
return TRUE;
}
}
gboolean
nmtstp_run_command_check_external (int external_command)
{
if (external_command != -1) {
g_assert (NM_IN_SET (external_command, FALSE, TRUE));
g_assert (!external_command || nmtstp_is_root_test ());
return !!external_command;
}
if (!nmtstp_is_root_test ())
return FALSE;
return (nmtst_get_rand_int () % 2) == 0;
}
#define CHECK_LIFETIME_MAX_DIFF 2
gboolean
nmtstp_ip_address_check_lifetime (const NMPlatformIPAddress *addr,
gint64 now,
guint32 expected_lifetime,
guint32 expected_preferred)
{
gint64 offset;
int i;
g_assert (addr);
if (now == -1)
now = nm_utils_get_monotonic_timestamp_s ();
g_assert (now > 0);
g_assert (expected_preferred <= expected_lifetime);
if ( expected_lifetime == NM_PLATFORM_LIFETIME_PERMANENT
&& expected_lifetime == NM_PLATFORM_LIFETIME_PERMANENT) {
return addr->timestamp == 0
&& addr->lifetime == NM_PLATFORM_LIFETIME_PERMANENT
&& addr->preferred == NM_PLATFORM_LIFETIME_PERMANENT;
}
if (addr->timestamp == 0)
return FALSE;
offset = (gint64) now - addr->timestamp;
for (i = 0; i < 2; i++) {
guint32 lft = i ? expected_lifetime : expected_preferred;
guint32 adr = i ? addr->lifetime : addr->preferred;
if (lft == NM_PLATFORM_LIFETIME_PERMANENT) {
if (adr != NM_PLATFORM_LIFETIME_PERMANENT)
return FALSE;
} else {
if ( adr - offset <= lft - CHECK_LIFETIME_MAX_DIFF
|| adr - offset >= lft + CHECK_LIFETIME_MAX_DIFF)
return FALSE;
}
}
return TRUE;
}
void
nmtstp_ip_address_assert_lifetime (const NMPlatformIPAddress *addr,
gint64 now,
guint32 expected_lifetime,
guint32 expected_preferred)
{
gint64 n = now;
gint64 offset;
int i;
g_assert (addr);
if (now == -1)
now = nm_utils_get_monotonic_timestamp_s ();
g_assert (now > 0);
g_assert (expected_preferred <= expected_lifetime);
if ( expected_lifetime == NM_PLATFORM_LIFETIME_PERMANENT
&& expected_lifetime == NM_PLATFORM_LIFETIME_PERMANENT) {
g_assert_cmpint (addr->timestamp, ==, 0);
g_assert_cmpint (addr->lifetime, ==, NM_PLATFORM_LIFETIME_PERMANENT);
g_assert_cmpint (addr->preferred, ==, NM_PLATFORM_LIFETIME_PERMANENT);
return;
}
g_assert_cmpint (addr->timestamp, >, 0);
g_assert_cmpint (addr->timestamp, <=, now);
offset = (gint64) now - addr->timestamp;
g_assert_cmpint (offset, >=, 0);
for (i = 0; i < 2; i++) {
guint32 lft = i ? expected_lifetime : expected_preferred;
guint32 adr = i ? addr->lifetime : addr->preferred;
if (lft == NM_PLATFORM_LIFETIME_PERMANENT)
g_assert_cmpint (adr, ==, NM_PLATFORM_LIFETIME_PERMANENT);
else {
g_assert_cmpint (adr, <=, lft);
g_assert_cmpint (offset, <=, adr);
g_assert_cmpint (adr - offset, <=, lft + CHECK_LIFETIME_MAX_DIFF);
g_assert_cmpint (adr - offset, >=, lft - CHECK_LIFETIME_MAX_DIFF);
}
}
g_assert (nmtstp_ip_address_check_lifetime (addr, n, expected_lifetime, expected_preferred));
}
static void
_ip_address_add (gboolean external_command,
gboolean is_v4,
int ifindex,
const IPAddr *address,
int plen,
const IPAddr *peer_address,
guint32 lifetime,
guint32 preferred,
const char *label,
guint flags)
{
gint64 end_time;
external_command = nmtstp_run_command_check_external (external_command);
if (external_command) {
const char *ifname;
gs_free char *s_valid = NULL;
gs_free char *s_preferred = NULL;
gs_free char *s_label = NULL;
char b1[NM_UTILS_INET_ADDRSTRLEN], b2[NM_UTILS_INET_ADDRSTRLEN];
ifname = nm_platform_link_get_name (NM_PLATFORM_GET, ifindex);
g_assert (ifname);
if (peer_address == address)
peer_address = 0;
if (lifetime != NM_PLATFORM_LIFETIME_PERMANENT)
s_valid = g_strdup_printf (" valid_lft %d", lifetime);
if (preferred != NM_PLATFORM_LIFETIME_PERMANENT)
s_preferred = g_strdup_printf (" preferred_lft %d", preferred);
if (label)
s_label = g_strdup_printf ("%s:%s", ifname, label);
if (is_v4) {
g_assert (flags == 0);
nmtstp_run_command_check ("ip address change %s%s%s/%d dev %s%s%s%s",
nm_utils_inet4_ntop (address->addr4, b1),
peer_address->addr4 ? " peer " : "",
peer_address->addr4 ? nm_utils_inet4_ntop (peer_address->addr4, b2) : "",
plen,
ifname,
s_valid ?: "",
s_preferred ?: "",
s_label ?: "");
} else {
g_assert (label == NULL);
/* flags not implemented (yet) */
g_assert (flags == 0);
nmtstp_run_command_check ("ip address change %s%s%s/%d dev %s%s%s%s",
nm_utils_inet6_ntop (&address->addr6, b1),
!IN6_IS_ADDR_UNSPECIFIED (&peer_address->addr6) ? " peer " : "",
!IN6_IS_ADDR_UNSPECIFIED (&peer_address->addr6) ? nm_utils_inet6_ntop (&peer_address->addr6, b2) : "",
plen,
ifname,
s_valid ?: "",
s_preferred ?: "",
s_label ?: "");
}
} else {
gboolean success;
if (is_v4) {
g_assert (flags == 0);
success = nm_platform_ip4_address_add (NM_PLATFORM_GET,
ifindex,
address->addr4,
plen,
peer_address->addr4,
lifetime,
preferred,
label);
} else {
g_assert (label == NULL);
success = nm_platform_ip6_address_add (NM_PLATFORM_GET,
ifindex,
address->addr6,
plen,
peer_address->addr6,
lifetime,
preferred,
flags);
}
g_assert (success);
}
/* Let's wait until we see the address. */
end_time = nm_utils_get_monotonic_timestamp_ms () + 250;
do {
if (external_command)
nm_platform_process_events (NM_PLATFORM_GET);
/* let's wait until we see the address as we added it. */
if (is_v4) {
const NMPlatformIP4Address *a;
g_assert (flags == 0);
a = nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, address->addr4, plen, peer_address->addr4);
if ( a
&& nm_platform_ip4_address_get_peer (a) == (peer_address->addr4 ? peer_address->addr4 : address->addr4)
&& nmtstp_ip_address_check_lifetime ((NMPlatformIPAddress*) a, -1, lifetime, preferred)
&& strcmp (a->label, label ?: "") == 0)
break;
} else {
const NMPlatformIP6Address *a;
g_assert (label == NULL);
g_assert (flags == 0);
a = nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, address->addr6, plen);
if ( a
&& !memcmp (nm_platform_ip6_address_get_peer (a),
(IN6_IS_ADDR_UNSPECIFIED (&peer_address->addr6) || IN6_ARE_ADDR_EQUAL (&address->addr6, &peer_address->addr6))
? &address->addr6 : &peer_address->addr6,
sizeof (struct in6_addr))
&& nmtstp_ip_address_check_lifetime ((NMPlatformIPAddress*) a, -1, lifetime, preferred))
break;
}
/* for internal command, we expect not to reach this line.*/
g_assert (external_command);
/* timeout? */
g_assert (nm_utils_get_monotonic_timestamp_ms () < end_time);
g_assert (nmtstp_wait_for_signal_until (end_time));
} while (TRUE);
}
void
nmtstp_ip4_address_add (gboolean external_command,
int ifindex,
in_addr_t address,
int plen,
in_addr_t peer_address,
guint32 lifetime,
guint32 preferred,
const char *label)
{
_ip_address_add (external_command,
TRUE,
ifindex,
(IPAddr *) &address,
plen,
(IPAddr *) &peer_address,
lifetime,
preferred,
label,
0);
}
void
nmtstp_ip6_address_add (gboolean external_command,
int ifindex,
struct in6_addr address,
int plen,
struct in6_addr peer_address,
guint32 lifetime,
guint32 preferred,
guint flags)
{
_ip_address_add (external_command,
FALSE,
ifindex,
(IPAddr *) &address,
plen,
(IPAddr *) &peer_address,
lifetime,
preferred,
NULL,
flags);
}
static void
_ip_address_del (gboolean external_command,
gboolean is_v4,
int ifindex,
const IPAddr *address,
int plen,
const IPAddr *peer_address)
{
gint64 end_time;
external_command = nmtstp_run_command_check_external (external_command);
if (external_command) {
const char *ifname;
char b1[NM_UTILS_INET_ADDRSTRLEN], b2[NM_UTILS_INET_ADDRSTRLEN];
int success;
gboolean had_address;
ifname = nm_platform_link_get_name (NM_PLATFORM_GET, ifindex);
g_assert (ifname);
if (peer_address == address)
peer_address = 0;
/* let's wait until we see the address as we added it. */
if (is_v4)
had_address = !!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, address->addr4, plen, peer_address->addr4);
else
had_address = !!nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, address->addr6, plen);
if (is_v4) {
success = nmtstp_run_command ("ip address delete %s%s%s/%d dev %s",
nm_utils_inet4_ntop (address->addr4, b1),
peer_address->addr4 ? " peer " : "",
peer_address->addr4 ? nm_utils_inet4_ntop (peer_address->addr4, b2) : "",
plen,
ifname);
} else {
g_assert (!peer_address);
success = nmtstp_run_command ("ip address delete %s/%d dev %s",
nm_utils_inet6_ntop (&address->addr6, b1),
plen,
ifname);
}
g_assert (success == 0 || !had_address);
} else {
gboolean success;
if (is_v4) {
success = nm_platform_ip4_address_delete (NM_PLATFORM_GET,
ifindex,
address->addr4,
plen,
peer_address->addr4);
} else {
g_assert (!peer_address);
success = nm_platform_ip6_address_delete (NM_PLATFORM_GET,
ifindex,
address->addr6,
plen);
}
g_assert (success);
}
/* Let's wait until we get the result */
end_time = nm_utils_get_monotonic_timestamp_ms () + 250;
do {
if (external_command)
nm_platform_process_events (NM_PLATFORM_GET);
/* let's wait until we see the address as we added it. */
if (is_v4) {
const NMPlatformIP4Address *a;
a = nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, address->addr4, plen, peer_address->addr4);
if (!a)
break;
} else {
const NMPlatformIP6Address *a;
a = nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, address->addr6, plen);
if (!a)
break;
}
/* for internal command, we expect not to reach this line.*/
g_assert (external_command);
/* timeout? */
g_assert (nm_utils_get_monotonic_timestamp_ms () < end_time);
g_assert (nmtstp_wait_for_signal_until (end_time));
} while (TRUE);
}
void
nmtstp_ip4_address_del (gboolean external_command,
int ifindex,
in_addr_t address,
int plen,
in_addr_t peer_address)
{
_ip_address_del (external_command,
TRUE,
ifindex,
(IPAddr *) &address,
plen,
(IPAddr *) &peer_address);
}
void
nmtstp_ip6_address_del (gboolean external_command,
int ifindex,
struct in6_addr address,
int plen)
{
_ip_address_del (external_command,
FALSE,
ifindex,
(IPAddr *) &address,
plen,
NULL);
}
/*****************************************************************************/
NMTST_DEFINE(); NMTST_DEFINE();
static gboolean static gboolean
@@ -318,7 +851,7 @@ main (int argc, char **argv)
init_tests (&argc, &argv); init_tests (&argc, &argv);
if ( nmtst_platform_is_root_test () if ( nmtstp_is_root_test ()
&& (geteuid () != 0 || getegid () != 0)) { && (geteuid () != 0 || getegid () != 0)) {
if ( g_getenv ("NMTST_FORCE_REAL_ROOT") if ( g_getenv ("NMTST_FORCE_REAL_ROOT")
|| !unshare_user ()) { || !unshare_user ()) {
@@ -335,7 +868,7 @@ main (int argc, char **argv)
} }
} }
if (nmtst_platform_is_root_test () && !g_getenv ("NMTST_NO_UNSHARE")) { if (nmtstp_is_root_test () && !g_getenv ("NMTST_NO_UNSHARE")) {
int errsv; int errsv;
if (unshare (CLONE_NEWNET | CLONE_NEWNS) != 0) { if (unshare (CLONE_NEWNET | CLONE_NEWNS) != 0) {

View File

@@ -43,8 +43,8 @@ typedef struct {
const char *ifname; const char *ifname;
} SignalData; } SignalData;
gboolean nmtst_platform_is_root_test (void); gboolean nmtstp_is_root_test (void);
gboolean nmtst_platform_is_sysfs_writable (void); gboolean nmtstp_is_sysfs_writable (void);
SignalData *add_signal_full (const char *name, NMPlatformSignalChangeType change_type, GCallback callback, int ifindex, const char *ifname); SignalData *add_signal_full (const char *name, NMPlatformSignalChangeType change_type, GCallback callback, int ifindex, const char *ifname);
#define add_signal(name, change_type, callback) add_signal_full (name, change_type, (GCallback) callback, 0, NULL) #define add_signal(name, change_type, callback) add_signal_full (name, change_type, (GCallback) callback, 0, NULL)
@@ -53,11 +53,13 @@ SignalData *add_signal_full (const char *name, NMPlatformSignalChangeType change
void _accept_signal (const char *file, int line, const char *func, SignalData *data); void _accept_signal (const char *file, int line, const char *func, SignalData *data);
void _accept_signals (const char *file, int line, const char *func, SignalData *data, int min, int max); void _accept_signals (const char *file, int line, const char *func, SignalData *data, int min, int max);
void _wait_signal (const char *file, int line, const char *func, SignalData *data); void _wait_signal (const char *file, int line, const char *func, SignalData *data);
void _accept_or_wait_signal (const char *file, int line, const char *func, SignalData *data);
void _ensure_no_signal (const char *file, int line, const char *func, SignalData *data); void _ensure_no_signal (const char *file, int line, const char *func, SignalData *data);
void _free_signal (const char *file, int line, const char *func, SignalData *data); void _free_signal (const char *file, int line, const char *func, SignalData *data);
#define accept_signal(data) _accept_signal(__FILE__, __LINE__, G_STRFUNC, data) #define accept_signal(data) _accept_signal(__FILE__, __LINE__, G_STRFUNC, data)
#define accept_signals(data, min, max) _accept_signals(__FILE__, __LINE__, G_STRFUNC, data, min, max) #define accept_signals(data, min, max) _accept_signals(__FILE__, __LINE__, G_STRFUNC, data, min, max)
#define wait_signal(data) _wait_signal(__FILE__, __LINE__, G_STRFUNC, data) #define wait_signal(data) _wait_signal(__FILE__, __LINE__, G_STRFUNC, data)
#define accept_or_wait_signal(data) _accept_or_wait_signal(__FILE__, __LINE__, G_STRFUNC, data)
#define ensure_no_signal(data) _ensure_no_signal(__FILE__, __LINE__, G_STRFUNC, data) #define ensure_no_signal(data) _ensure_no_signal(__FILE__, __LINE__, G_STRFUNC, data)
#define free_signal(data) _free_signal(__FILE__, __LINE__, G_STRFUNC, data) #define free_signal(data) _free_signal(__FILE__, __LINE__, G_STRFUNC, data)
@@ -68,7 +70,49 @@ void _assert_ip4_route_exists (const char *file, guint line, const char *func, g
void link_callback (NMPlatform *platform, NMPObjectType obj_type, int ifindex, NMPlatformLink *received, NMPlatformSignalChangeType change_type, NMPlatformReason reason, SignalData *data); void link_callback (NMPlatform *platform, NMPObjectType obj_type, int ifindex, NMPlatformLink *received, NMPlatformSignalChangeType change_type, NMPlatformReason reason, SignalData *data);
void run_command (const char *format, ...); int nmtstp_run_command (const char *format, ...) __attribute__((__format__ (__printf__, 1, 2)));
#define nmtstp_run_command_check(format, ...) do { g_assert_cmpint (nmtstp_run_command (format, __VA_ARGS__), ==, 0); } while (0)
gboolean nmtstp_wait_for_signal (guint timeout_ms);
gboolean nmtstp_wait_for_signal_until (gint64 until_ms);
int nmtstp_run_command_check_external_global (void);
gboolean nmtstp_run_command_check_external (int external_command);
gboolean nmtstp_ip_address_check_lifetime (const NMPlatformIPAddress *addr,
gint64 now,
guint32 expected_lifetime,
guint32 expected_preferred);
void nmtstp_ip_address_assert_lifetime (const NMPlatformIPAddress *addr,
gint64 now,
guint32 expected_lifetime,
guint32 expected_preferred);
void nmtstp_ip4_address_add (gboolean external_command,
int ifindex,
in_addr_t address,
int plen,
in_addr_t peer_address,
guint32 lifetime,
guint32 preferred,
const char *label);
void nmtstp_ip6_address_add (gboolean external_command,
int ifindex,
struct in6_addr address,
int plen,
struct in6_addr peer_address,
guint32 lifetime,
guint32 preferred,
guint flags);
void nmtstp_ip4_address_del (gboolean external_command,
int ifindex,
in_addr_t address,
int plen,
in_addr_t peer_address);
void nmtstp_ip6_address_del (gboolean external_command,
int ifindex,
struct in6_addr address,
int plen);
void init_tests (int *argc, char ***argv); void init_tests (int *argc, char ***argv);
void setup_tests (void); void setup_tests (void);

View File

@@ -262,7 +262,7 @@ test_slave (int master, int type, SignalData *master_changed)
/* Set slave option */ /* Set slave option */
switch (type) { switch (type) {
case NM_LINK_TYPE_BRIDGE: case NM_LINK_TYPE_BRIDGE:
if (nmtst_platform_is_sysfs_writable ()) { if (nmtstp_is_sysfs_writable ()) {
g_assert (nm_platform_slave_set_option (NM_PLATFORM_GET, ifindex, "priority", "789")); g_assert (nm_platform_slave_set_option (NM_PLATFORM_GET, ifindex, "priority", "789"));
value = nm_platform_slave_get_option (NM_PLATFORM_GET, ifindex, "priority"); value = nm_platform_slave_get_option (NM_PLATFORM_GET, ifindex, "priority");
g_assert_cmpstr (value, ==, "789"); g_assert_cmpstr (value, ==, "789");
@@ -341,7 +341,7 @@ test_software (NMLinkType link_type, const char *link_typename)
/* Set master option */ /* Set master option */
switch (link_type) { switch (link_type) {
case NM_LINK_TYPE_BRIDGE: case NM_LINK_TYPE_BRIDGE:
if (nmtst_platform_is_sysfs_writable ()) { if (nmtstp_is_sysfs_writable ()) {
g_assert (nm_platform_master_set_option (NM_PLATFORM_GET, ifindex, "forward_delay", "789")); g_assert (nm_platform_master_set_option (NM_PLATFORM_GET, ifindex, "forward_delay", "789"));
value = nm_platform_master_get_option (NM_PLATFORM_GET, ifindex, "forward_delay"); value = nm_platform_master_get_option (NM_PLATFORM_GET, ifindex, "forward_delay");
g_assert_cmpstr (value, ==, "789"); g_assert_cmpstr (value, ==, "789");
@@ -349,7 +349,7 @@ test_software (NMLinkType link_type, const char *link_typename)
} }
break; break;
case NM_LINK_TYPE_BOND: case NM_LINK_TYPE_BOND:
if (nmtst_platform_is_sysfs_writable ()) { if (nmtstp_is_sysfs_writable ()) {
g_assert (nm_platform_master_set_option (NM_PLATFORM_GET, ifindex, "mode", "active-backup")); g_assert (nm_platform_master_set_option (NM_PLATFORM_GET, ifindex, "mode", "active-backup"));
value = nm_platform_master_get_option (NM_PLATFORM_GET, ifindex, "mode"); value = nm_platform_master_get_option (NM_PLATFORM_GET, ifindex, "mode");
/* When reading back, the output looks slightly different. */ /* When reading back, the output looks slightly different. */
@@ -408,7 +408,7 @@ test_bridge (void)
static void static void
test_bond (void) test_bond (void)
{ {
if (nmtst_platform_is_root_test () && if (nmtstp_is_root_test () &&
!g_file_test ("/proc/1/net/bonding", G_FILE_TEST_IS_DIR) && !g_file_test ("/proc/1/net/bonding", G_FILE_TEST_IS_DIR) &&
system("modprobe --show bonding") != 0) { system("modprobe --show bonding") != 0) {
g_test_skip ("Skipping test for bonding: bonding module not available"); g_test_skip ("Skipping test for bonding: bonding module not available");
@@ -519,7 +519,7 @@ test_external (void)
SignalData *link_changed, *link_removed; SignalData *link_changed, *link_removed;
int ifindex; int ifindex;
run_command ("ip link add %s type %s", DEVICE_NAME, "dummy"); nmtstp_run_command_check ("ip link add %s type %s", DEVICE_NAME, "dummy");
wait_signal (link_added); wait_signal (link_added);
g_assert (nm_platform_link_get_by_ifname (NM_PLATFORM_GET, DEVICE_NAME)); g_assert (nm_platform_link_get_by_ifname (NM_PLATFORM_GET, DEVICE_NAME));
@@ -543,24 +543,24 @@ test_external (void)
g_assert (!nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex)); g_assert (!nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex));
g_assert (!nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex)); g_assert (!nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex));
run_command ("ip link set %s up", DEVICE_NAME); nmtstp_run_command_check ("ip link set %s up", DEVICE_NAME);
wait_signal (link_changed); wait_signal (link_changed);
g_assert (nm_platform_link_is_up (NM_PLATFORM_GET, ifindex)); g_assert (nm_platform_link_is_up (NM_PLATFORM_GET, ifindex));
g_assert (nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex)); g_assert (nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex));
run_command ("ip link set %s down", DEVICE_NAME); nmtstp_run_command_check ("ip link set %s down", DEVICE_NAME);
wait_signal (link_changed); wait_signal (link_changed);
g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex)); g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex));
g_assert (!nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex)); g_assert (!nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex));
run_command ("ip link set %s arp on", DEVICE_NAME); nmtstp_run_command_check ("ip link set %s arp on", DEVICE_NAME);
wait_signal (link_changed); wait_signal (link_changed);
g_assert (nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex)); g_assert (nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex));
run_command ("ip link set %s arp off", DEVICE_NAME); nmtstp_run_command_check ("ip link set %s arp off", DEVICE_NAME);
wait_signal (link_changed); wait_signal (link_changed);
g_assert (!nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex)); g_assert (!nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex));
run_command ("ip link del %s", DEVICE_NAME); nmtstp_run_command_check ("ip link del %s", DEVICE_NAME);
wait_signal (link_removed); wait_signal (link_removed);
accept_signals (link_changed, 0, 1); accept_signals (link_changed, 0, 1);
g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, DEVICE_NAME)); g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, DEVICE_NAME));