summary refs log tree commit diff
path: root/src/platform/tests/test-nmp-object.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/platform/tests/test-nmp-object.c')
-rw-r--r--src/platform/tests/test-nmp-object.c987
1 files changed, 510 insertions, 477 deletions
diff --git a/src/platform/tests/test-nmp-object.c b/src/platform/tests/test-nmp-object.c
index 8ecfac8a..e61e6b09 100644
--- a/src/platform/tests/test-nmp-object.c
+++ b/src/platform/tests/test-nmp-object.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2015 - 2017 Red Hat, Inc.
  */
@@ -14,571 +14,604 @@
 #include "nm-test-utils-core.h"
 
 struct {
-	GList *udev_devices;
+    GList *udev_devices;
 } global;
 
 /*****************************************************************************/
 
 static void
-test_obj_base (void)
+test_obj_base(void)
 {
-	static const union {
-		GObject g;
-		NMPObject k;
-	} x = { };
-	static const union {
-		GTypeClass k;
-		NMPClass c;
-	} l = { };
-	static const GObject *g = &x.g;
-	static const GTypeClass *k = &l.k;
-	static const NMPObject *o = &x.k;
-	static const NMPClass *c = &l.c;
-
-	NMObjBaseInst *obj;
-	gs_unref_object GCancellable *obj_cancellable = g_cancellable_new ();
-	nm_auto_nmpobj NMPObject *obj_link = nmp_object_new_link (10);
-
-	g_assert (&g->g_type_instance              == (void *) &o->_class);
-	g_assert (&g->g_type_instance.g_class      == (void *) &o->_class);
-
-	g_assert (sizeof (o->parent.parent)        == sizeof (GTypeInstance));
-
-	g_assert (&c->parent                       == (void *) c);
-	g_assert (&c->parent.parent.g_type_class   == (void *) c);
-	g_assert (&c->parent.parent.g_type         == (void *) c);
-	g_assert (&c->parent.parent.g_type         == &k->g_type);
-
-	g_assert (sizeof (c->parent.parent)        == sizeof (GTypeClass));
-
-	g_assert (&o->parent                       == (void *) o);
-	g_assert (&o->parent.klass                 == (void *) &o->_class);
-
-	obj = (NMObjBaseInst *) obj_cancellable;
-	g_assert (!NMP_CLASS_IS_VALID ((NMPClass *) obj->klass));
-	g_assert (G_TYPE_CHECK_INSTANCE_TYPE (obj, G_TYPE_CANCELLABLE));
-
-	obj = (NMObjBaseInst *) obj_link;
-	g_assert (NMP_CLASS_IS_VALID ((NMPClass *) obj->klass));
-	g_assert (!G_TYPE_CHECK_INSTANCE_TYPE (obj, G_TYPE_CANCELLABLE));
-
+    static const union {
+        GObject   g;
+        NMPObject k;
+    } x = {};
+    static const union {
+        GTypeClass k;
+        NMPClass   c;
+    } l                        = {};
+    static const GObject *   g = &x.g;
+    static const GTypeClass *k = &l.k;
+    static const NMPObject * o = &x.k;
+    static const NMPClass *  c = &l.c;
+
+    NMObjBaseInst * obj;
+    gs_unref_object GCancellable *obj_cancellable = g_cancellable_new();
+    nm_auto_nmpobj NMPObject *obj_link            = nmp_object_new_link(10);
+
+    g_assert(&g->g_type_instance == (void *) &o->_class);
+    g_assert(&g->g_type_instance.g_class == (void *) &o->_class);
+
+    g_assert(sizeof(o->parent.parent) == sizeof(GTypeInstance));
+
+    g_assert(&c->parent == (void *) c);
+    g_assert(&c->parent.parent.g_type_class == (void *) c);
+    g_assert(&c->parent.parent.g_type == (void *) c);
+    g_assert(&c->parent.parent.g_type == &k->g_type);
+
+    g_assert(sizeof(c->parent.parent) == sizeof(GTypeClass));
+
+    g_assert(&o->parent == (void *) o);
+    g_assert(&o->parent.klass == (void *) &o->_class);
+
+    obj = (NMObjBaseInst *) obj_cancellable;
+    g_assert(!NMP_CLASS_IS_VALID((NMPClass *) obj->klass));
+    g_assert(G_TYPE_CHECK_INSTANCE_TYPE(obj, G_TYPE_CANCELLABLE));
+
+    obj = (NMObjBaseInst *) obj_link;
+    g_assert(NMP_CLASS_IS_VALID((NMPClass *) obj->klass));
+    g_assert(!G_TYPE_CHECK_INSTANCE_TYPE(obj, G_TYPE_CANCELLABLE));
 }
 
 /*****************************************************************************/
 
 static gboolean
-_nmp_object_id_equal (const NMPObject *a, const NMPObject *b)
+_nmp_object_id_equal(const NMPObject *a, const NMPObject *b)
 {
-	gboolean a_b = nmp_object_id_equal (a, b);
+    gboolean a_b = nmp_object_id_equal(a, b);
 
-	g_assert (NM_IN_SET (a_b, FALSE, TRUE) && a_b == nmp_object_id_equal (b, a));
-	return a_b;
+    g_assert(NM_IN_SET(a_b, FALSE, TRUE) && a_b == nmp_object_id_equal(b, a));
+    return a_b;
 }
 #define nmp_object_id_equal _nmp_object_id_equal
 
 static gboolean
-_nmp_object_equal (const NMPObject *a, const NMPObject *b)
+_nmp_object_equal(const NMPObject *a, const NMPObject *b)
 {
-	gboolean a_b = nmp_object_equal (a, b);
+    gboolean a_b = nmp_object_equal(a, b);
 
-	g_assert (NM_IN_SET (a_b, FALSE, TRUE) && a_b == nmp_object_equal (b, a));
-	return a_b;
+    g_assert(NM_IN_SET(a_b, FALSE, TRUE) && a_b == nmp_object_equal(b, a));
+    return a_b;
 }
 #define nmp_object_equal _nmp_object_equal
 
 /*****************************************************************************/
 
 static void
-_assert_cache_multi_lookup_contains (const NMPCache *cache, const NMDedupMultiHeadEntry *head_entry, const NMPObject *obj, gboolean visible_only, gboolean contains)
+_assert_cache_multi_lookup_contains(const NMPCache *             cache,
+                                    const NMDedupMultiHeadEntry *head_entry,
+                                    const NMPObject *            obj,
+                                    gboolean                     visible_only,
+                                    gboolean                     contains)
 {
-	NMDedupMultiIter iter;
-	gboolean found;
-	guint i, len;
-	const NMPObject *o;
-
-	g_assert (NMP_OBJECT_IS_VALID (obj));
-
-	g_assert (nmp_cache_lookup_obj (cache, obj) == obj);
-	g_assert (!head_entry || (head_entry->len > 0 && c_list_length (&head_entry->lst_entries_head) == head_entry->len));
-
-	len = head_entry ? head_entry->len : 0;
-
-	found = FALSE;
-	i = 0;
-	nmp_cache_iter_for_each (&iter,
-	                         head_entry,
-	                         &o) {
-		g_assert (NMP_OBJECT_IS_VALID (o));
-		if (obj == o) {
-			if (   !visible_only
-			    || nmp_object_is_visible (o)) {
-				g_assert (!found);
-				found = TRUE;
-			}
-		}
-		i++;
-	}
-
-	g_assert (len == i);
-	g_assert (!!contains == found);
+    NMDedupMultiIter iter;
+    gboolean         found;
+    guint            i, len;
+    const NMPObject *o;
+
+    g_assert(NMP_OBJECT_IS_VALID(obj));
+
+    g_assert(nmp_cache_lookup_obj(cache, obj) == obj);
+    g_assert(!head_entry
+             || (head_entry->len > 0
+                 && c_list_length(&head_entry->lst_entries_head) == head_entry->len));
+
+    len = head_entry ? head_entry->len : 0;
+
+    found = FALSE;
+    i     = 0;
+    nmp_cache_iter_for_each (&iter, head_entry, &o) {
+        g_assert(NMP_OBJECT_IS_VALID(o));
+        if (obj == o) {
+            if (!visible_only || nmp_object_is_visible(o)) {
+                g_assert(!found);
+                found = TRUE;
+            }
+        }
+        i++;
+    }
+
+    g_assert(len == i);
+    g_assert(!!contains == found);
 }
 
 static void
-_assert_cache_multi_lookup_contains_link (const NMPCache *cache,
-                                          gboolean visible_only,
-                                          const NMPObject *obj,
-                                          gboolean contains)
+_assert_cache_multi_lookup_contains_link(const NMPCache * cache,
+                                         gboolean         visible_only,
+                                         const NMPObject *obj,
+                                         gboolean         contains)
 {
-	const NMDedupMultiHeadEntry *head_entry;
-	NMPLookup lookup;
+    const NMDedupMultiHeadEntry *head_entry;
+    NMPLookup                    lookup;
 
-	g_assert (cache);
+    g_assert(cache);
 
-	nmp_lookup_init_obj_type (&lookup, NMP_OBJECT_TYPE_LINK);
-	head_entry = nmp_cache_lookup (cache, &lookup);
-	_assert_cache_multi_lookup_contains (cache, head_entry, obj, visible_only, contains);
+    nmp_lookup_init_obj_type(&lookup, NMP_OBJECT_TYPE_LINK);
+    head_entry = nmp_cache_lookup(cache, &lookup);
+    _assert_cache_multi_lookup_contains(cache, head_entry, obj, visible_only, contains);
 }
 
 /*****************************************************************************/
 
 static void
-ops_post_check (NMPCache *cache,
-                NMPCacheOpsType ops_type,
-                const NMPObject *obj_old,
-                const NMPObject *obj_new,
-                const NMPObject *obj_new_expected,
-                NMPCacheOpsType expected_ops_type)
+ops_post_check(NMPCache *       cache,
+               NMPCacheOpsType  ops_type,
+               const NMPObject *obj_old,
+               const NMPObject *obj_new,
+               const NMPObject *obj_new_expected,
+               NMPCacheOpsType  expected_ops_type)
 {
-	g_assert (cache);
-
-	g_assert_cmpint (expected_ops_type, ==, ops_type);
-
-	switch (ops_type) {
-	case NMP_CACHE_OPS_ADDED:
-		g_assert (!obj_old);
-		g_assert (NMP_OBJECT_IS_VALID (obj_new));
-		g_assert (nmp_object_is_alive (obj_new));
-		g_assert (nmp_object_id_equal (obj_new_expected, obj_new));
-		g_assert (nmp_object_equal (obj_new_expected, obj_new));
-		break;
-	case NMP_CACHE_OPS_UPDATED:
-		g_assert (obj_old != obj_new);
-		g_assert (NMP_OBJECT_IS_VALID (obj_old));
-		g_assert (NMP_OBJECT_IS_VALID (obj_new));
-		g_assert (nmp_object_is_alive (obj_old));
-		g_assert (nmp_object_is_alive (obj_new));
-		g_assert (nmp_object_id_equal (obj_new_expected, obj_new));
-		g_assert (nmp_object_id_equal (obj_new_expected, obj_old));
-		g_assert (nmp_object_id_equal (obj_old, obj_new));
-		g_assert (nmp_object_equal (obj_new_expected, obj_new));
-		g_assert (!nmp_object_equal (obj_new_expected, obj_old));
-		g_assert (!nmp_object_equal (obj_old, obj_new));
-		break;
-	case NMP_CACHE_OPS_REMOVED:
-		g_assert (!obj_new);
-		g_assert (NMP_OBJECT_IS_VALID (obj_old));
-		g_assert (nmp_object_is_alive (obj_old));
-		if (obj_new_expected)
-			g_assert (nmp_object_id_equal (obj_new_expected, obj_old));
-		break;
-	case NMP_CACHE_OPS_UNCHANGED:
-		g_assert (obj_old == obj_new);
-		if (obj_old) {
-			g_assert (NMP_OBJECT_IS_VALID (obj_old));
-			g_assert (nmp_object_is_alive (obj_old));
-			g_assert (nmp_object_equal (obj_old, obj_new));
-			g_assert (nmp_object_id_equal (obj_new_expected, obj_new));
-		} else
-			g_assert (!obj_new_expected);
-		break;
-	default:
-		g_assert_not_reached ();
-	}
+    g_assert(cache);
+
+    g_assert_cmpint(expected_ops_type, ==, ops_type);
+
+    switch (ops_type) {
+    case NMP_CACHE_OPS_ADDED:
+        g_assert(!obj_old);
+        g_assert(NMP_OBJECT_IS_VALID(obj_new));
+        g_assert(nmp_object_is_alive(obj_new));
+        g_assert(nmp_object_id_equal(obj_new_expected, obj_new));
+        g_assert(nmp_object_equal(obj_new_expected, obj_new));
+        break;
+    case NMP_CACHE_OPS_UPDATED:
+        g_assert(obj_old != obj_new);
+        g_assert(NMP_OBJECT_IS_VALID(obj_old));
+        g_assert(NMP_OBJECT_IS_VALID(obj_new));
+        g_assert(nmp_object_is_alive(obj_old));
+        g_assert(nmp_object_is_alive(obj_new));
+        g_assert(nmp_object_id_equal(obj_new_expected, obj_new));
+        g_assert(nmp_object_id_equal(obj_new_expected, obj_old));
+        g_assert(nmp_object_id_equal(obj_old, obj_new));
+        g_assert(nmp_object_equal(obj_new_expected, obj_new));
+        g_assert(!nmp_object_equal(obj_new_expected, obj_old));
+        g_assert(!nmp_object_equal(obj_old, obj_new));
+        break;
+    case NMP_CACHE_OPS_REMOVED:
+        g_assert(!obj_new);
+        g_assert(NMP_OBJECT_IS_VALID(obj_old));
+        g_assert(nmp_object_is_alive(obj_old));
+        if (obj_new_expected)
+            g_assert(nmp_object_id_equal(obj_new_expected, obj_old));
+        break;
+    case NMP_CACHE_OPS_UNCHANGED:
+        g_assert(obj_old == obj_new);
+        if (obj_old) {
+            g_assert(NMP_OBJECT_IS_VALID(obj_old));
+            g_assert(nmp_object_is_alive(obj_old));
+            g_assert(nmp_object_equal(obj_old, obj_new));
+            g_assert(nmp_object_id_equal(obj_new_expected, obj_new));
+        } else
+            g_assert(!obj_new_expected);
+        break;
+    default:
+        g_assert_not_reached();
+    }
 }
 
 static void
-_nmp_cache_update_netlink (NMPCache *cache, NMPObject *obj, const NMPObject **out_obj_old, const NMPObject **out_obj_new, NMPCacheOpsType expected_ops_type)
+_nmp_cache_update_netlink(NMPCache *        cache,
+                          NMPObject *       obj,
+                          const NMPObject **out_obj_old,
+                          const NMPObject **out_obj_new,
+                          NMPCacheOpsType   expected_ops_type)
 {
-	NMPCacheOpsType ops_type;
-	const NMPObject *obj_prev;
-	const NMPObject *obj_old;
-	const NMPObject *obj_new;
-	nm_auto_nmpobj NMPObject *obj_new_expected = NULL;
-
-	g_assert (cache);
-	g_assert (NMP_OBJECT_IS_VALID (obj));
-
-	obj_prev = nmp_cache_lookup_link (cache, NMP_OBJECT_CAST_LINK (obj)->ifindex);
-	obj_new_expected = nmp_object_clone (obj, FALSE);
-	if (obj_prev && obj_prev->_link.udev.device)
-		obj_new_expected->_link.udev.device = udev_device_ref (obj_prev->_link.udev.device);
-	_nmp_object_fixup_link_udev_fields (&obj_new_expected, NULL, nmp_cache_use_udev_get (cache));
-
-	ops_type = nmp_cache_update_netlink (cache, obj, FALSE, &obj_old, &obj_new);
-	ops_post_check (cache, ops_type, obj_old, obj_new,
-	                nmp_object_is_alive (obj_new_expected) ? obj_new_expected : NULL,
-	                expected_ops_type);
-
-	if (out_obj_new)
-		*out_obj_new = obj_new;
-	else
-		nmp_object_unref (obj_new);
-	if (out_obj_old)
-		*out_obj_old = obj_old;
-	else
-		nmp_object_unref (obj_old);
+    NMPCacheOpsType  ops_type;
+    const NMPObject *obj_prev;
+    const NMPObject *obj_old;
+    const NMPObject *obj_new;
+    nm_auto_nmpobj NMPObject *obj_new_expected = NULL;
+
+    g_assert(cache);
+    g_assert(NMP_OBJECT_IS_VALID(obj));
+
+    obj_prev         = nmp_cache_lookup_link(cache, NMP_OBJECT_CAST_LINK(obj)->ifindex);
+    obj_new_expected = nmp_object_clone(obj, FALSE);
+    if (obj_prev && obj_prev->_link.udev.device)
+        obj_new_expected->_link.udev.device = udev_device_ref(obj_prev->_link.udev.device);
+    _nmp_object_fixup_link_udev_fields(&obj_new_expected, NULL, nmp_cache_use_udev_get(cache));
+
+    ops_type = nmp_cache_update_netlink(cache, obj, FALSE, &obj_old, &obj_new);
+    ops_post_check(cache,
+                   ops_type,
+                   obj_old,
+                   obj_new,
+                   nmp_object_is_alive(obj_new_expected) ? obj_new_expected : NULL,
+                   expected_ops_type);
+
+    if (out_obj_new)
+        *out_obj_new = obj_new;
+    else
+        nmp_object_unref(obj_new);
+    if (out_obj_old)
+        *out_obj_old = obj_old;
+    else
+        nmp_object_unref(obj_old);
 }
 
 static const NMPlatformLink pl_link_2 = {
-	.ifindex = 2,
-	.name = "eth0",
-	.type = NM_LINK_TYPE_ETHERNET,
+    .ifindex = 2,
+    .name    = "eth0",
+    .type    = NM_LINK_TYPE_ETHERNET,
 };
 
 static const NMPlatformLink pl_link_3 = {
-	.ifindex = 3,
-	.name = "wlan0",
-	.type = NM_LINK_TYPE_WIFI,
+    .ifindex = 3,
+    .name    = "wlan0",
+    .type    = NM_LINK_TYPE_WIFI,
 };
 
 static void
-test_cache_link (void)
+test_cache_link(void)
 {
-	NMPCache *cache;
-	NMPObject *objm1;
-	const NMPObject *obj_old, *obj_new;
-	NMPObject objs1;
-	struct udev_device *udev_device_2 = g_list_nth_data (global.udev_devices, 0);
-	struct udev_device *udev_device_3 = g_list_nth_data (global.udev_devices, 0);
-	NMPCacheOpsType ops_type;
-	nm_auto_unref_dedup_multi_index NMDedupMultiIndex *multi_idx = NULL;
-	gboolean use_udev = nmtst_get_rand_uint32 () % 2;
-
-	multi_idx = nm_dedup_multi_index_new ();
-
-	cache = nmp_cache_new (multi_idx, use_udev);
-
-	/* if we have a link, and don't set is_in_netlink, adding it has no effect. */
-	objm1 = nmp_object_new (NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2);
-	g_assert (NMP_OBJECT_UP_CAST (&objm1->object) == objm1);
-	g_assert (!nmp_object_is_alive (objm1));
-	_nmp_cache_update_netlink (cache, objm1, &obj_old, &obj_new, NMP_CACHE_OPS_UNCHANGED);
-	ASSERT_nmp_cache_is_consistent (cache);
-	g_assert (!obj_old);
-	g_assert (!obj_new);
-	g_assert (!nmp_cache_lookup_obj (cache, objm1));
-	g_assert (!nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&objs1, pl_link_2.ifindex)));
-	nmp_object_unref (objm1);
-
-	/* Only when setting @is_in_netlink the link is added. */
-	objm1 = nmp_object_new (NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2);
-	objm1->_link.netlink.is_in_netlink = TRUE;
-	g_assert (nmp_object_is_alive (objm1));
-	_nmp_cache_update_netlink (cache, objm1, &obj_old, &obj_new, NMP_CACHE_OPS_ADDED);
-	ASSERT_nmp_cache_is_consistent (cache);
-	g_assert (!obj_old);
-	g_assert (obj_new);
-	g_assert (objm1 == obj_new);
-	g_assert (nmp_object_equal (objm1, obj_new));
-	g_assert (nmp_cache_lookup_obj (cache, objm1) == obj_new);
-	g_assert (nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&objs1, pl_link_2.ifindex)) == obj_new);
-	g_assert (nmp_object_is_visible (obj_new));
-	_assert_cache_multi_lookup_contains_link (cache, FALSE, obj_new, TRUE);
-	_assert_cache_multi_lookup_contains_link (cache, TRUE, obj_new, TRUE);
-	nmp_object_unref (objm1);
-	nmp_object_unref (obj_new);
-
-	/* updating the same link with identical value, has no effect. */
-	objm1 = nmp_object_new (NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2);
-	objm1->_link.netlink.is_in_netlink = TRUE;
-	g_assert (nmp_object_is_alive (objm1));
-	_nmp_cache_update_netlink (cache, objm1, &obj_old, &obj_new, NMP_CACHE_OPS_UNCHANGED);
-	ASSERT_nmp_cache_is_consistent (cache);
-	g_assert (obj_old);
-	g_assert (obj_new);
-	g_assert (obj_new != objm1);
-	g_assert (nmp_object_equal (objm1, obj_new));
-	g_assert (nmp_cache_lookup_obj (cache, objm1) == obj_new);
-	g_assert (nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&objs1, pl_link_2.ifindex)) == obj_new);
-	nmp_object_unref (objm1);
-	nmp_object_unref (obj_new);
-	nmp_object_unref (obj_new);
-
-	/* remove the link from netlink */
-	objm1 = nmp_object_new (NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2);
-	g_assert (!nmp_object_is_alive (objm1));
-	_nmp_cache_update_netlink (cache, objm1, &obj_old, &obj_new, NMP_CACHE_OPS_REMOVED);
-	ASSERT_nmp_cache_is_consistent (cache);
-	g_assert (obj_old);
-	g_assert (!obj_new);
-	g_assert (!nmp_cache_lookup_obj (cache, objm1));
-	g_assert (!nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&objs1, pl_link_2.ifindex)));
-	nmp_object_unref (objm1);
-	nmp_object_unref (obj_old);
-	nmp_object_unref (obj_new);
-
-	if (udev_device_2) {
-		/* now add the link only with aspect UDEV. */
-		ops_type = nmp_cache_update_link_udev (cache, pl_link_2.ifindex, udev_device_2, &obj_old, &obj_new);
-		ASSERT_nmp_cache_is_consistent (cache);
-		g_assert_cmpint (ops_type, ==, NMP_CACHE_OPS_ADDED);
-		g_assert (!obj_old);
-		g_assert (obj_new);
-		g_assert (nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&objs1, pl_link_2.ifindex)) == obj_new);
-		g_assert (!nmp_object_is_visible (obj_new));
-		_assert_cache_multi_lookup_contains_link (cache, TRUE, obj_new, FALSE);
-		_assert_cache_multi_lookup_contains_link (cache, FALSE, obj_new, TRUE);
-		nmp_object_unref (obj_new);
-	}
-
-	/* add it in netlink too. */
-	objm1 = nmp_object_new (NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2);
-	objm1->_link.netlink.is_in_netlink = TRUE;
-	g_assert (nmp_object_is_alive (objm1));
-	_nmp_cache_update_netlink (cache, objm1, &obj_old, &obj_new, udev_device_2 ? NMP_CACHE_OPS_UPDATED : NMP_CACHE_OPS_ADDED);
-	ASSERT_nmp_cache_is_consistent (cache);
-	if (udev_device_2) {
-		g_assert (obj_old);
-		g_assert (!nmp_object_is_visible (obj_old));
-	} else
-		g_assert (!obj_old);
-	g_assert (nmp_object_equal (objm1, obj_new));
-	g_assert (nmp_cache_lookup_obj (cache, objm1) == obj_new);
-	g_assert (nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&objs1, pl_link_2.ifindex)) == obj_new);
-	g_assert (nmp_object_is_visible (obj_new));
-	_assert_cache_multi_lookup_contains_link (cache, TRUE, obj_new, TRUE);
-	_assert_cache_multi_lookup_contains_link (cache, FALSE, obj_new, TRUE);
-	nmp_object_unref (objm1);
-	nmp_object_unref (obj_old);
-	nmp_object_unref (obj_new);
-
-	/* remove again from netlink. */
-	objm1 = nmp_object_new (NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2);
-	objm1->_link.netlink.is_in_netlink = FALSE;
-	g_assert (!nmp_object_is_alive (objm1));
-	_nmp_cache_update_netlink (cache, objm1, &obj_old, &obj_new, udev_device_2 ? NMP_CACHE_OPS_UPDATED : NMP_CACHE_OPS_REMOVED);
-	ASSERT_nmp_cache_is_consistent (cache);
-	if (udev_device_2)
-		g_assert (obj_new == objm1);
-	else
-		g_assert (!obj_new);
-	g_assert (obj_old);
-	g_assert (nmp_object_is_alive (obj_old));
-	if (udev_device_2) {
-		g_assert (nmp_cache_lookup_obj (cache, objm1) == obj_new);
-		g_assert (nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&objs1, pl_link_2.ifindex)) == obj_new);
-		g_assert (!nmp_object_is_visible (obj_new));
-		_assert_cache_multi_lookup_contains_link (cache, TRUE, obj_new, FALSE);
-		_assert_cache_multi_lookup_contains_link (cache, FALSE, obj_new, TRUE);
-	} else {
-		g_assert (nmp_cache_lookup_obj (cache, objm1) == NULL);
-		g_assert (nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&objs1, pl_link_2.ifindex)) == NULL);
-		g_assert (!nmp_object_is_alive (obj_new));
-		g_assert (!nmp_object_is_visible (obj_new));
-	}
-	nmp_object_unref (objm1);
-	nmp_object_unref (obj_old);
-	nmp_object_unref (obj_new);
-
-	/* now another link only with aspect UDEV. */
-	if (udev_device_3) {
-		/* now add the link only with aspect UDEV. */
-		ops_type = nmp_cache_update_link_udev (cache, pl_link_3.ifindex, udev_device_3, &obj_old, &obj_new);
-		g_assert_cmpint (ops_type, ==, NMP_CACHE_OPS_ADDED);
-		ASSERT_nmp_cache_is_consistent (cache);
-		g_assert (NMP_OBJECT_IS_VALID (obj_new));
-		g_assert (!obj_old);
-		g_assert (!nmp_object_is_visible (obj_new));
-		g_assert (nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&objs1, pl_link_3.ifindex)) == obj_new);
-		_assert_cache_multi_lookup_contains_link (cache, TRUE, obj_new, FALSE);
-		_assert_cache_multi_lookup_contains_link (cache, FALSE, obj_new, TRUE);
-		g_assert_cmpint (obj_new->_link.netlink.is_in_netlink, ==, FALSE);
-		g_assert_cmpint (obj_new->link.initialized, ==, FALSE);
-		nmp_object_unref (obj_new);
-
-		/* add it in netlink too. */
-		objm1 = nmp_object_new (NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_3);
-		objm1->_link.netlink.is_in_netlink = TRUE;
-		g_assert (nmp_object_is_alive (objm1));
-		_nmp_cache_update_netlink (cache, objm1, &obj_old, &obj_new, NMP_CACHE_OPS_UPDATED);
-		ASSERT_nmp_cache_is_consistent (cache);
-		g_assert (obj_old);
-		g_assert (obj_new == objm1);
-		g_assert (nmp_object_equal (objm1, obj_new));
-		g_assert (!obj_old || !nmp_object_is_visible (obj_old));
-		g_assert (nmp_cache_lookup_obj (cache, objm1) == obj_new);
-		g_assert (nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&objs1, pl_link_3.ifindex)) == obj_new);
-		g_assert (nmp_object_is_visible (obj_new));
-		_assert_cache_multi_lookup_contains_link (cache, TRUE, obj_new, TRUE);
-		_assert_cache_multi_lookup_contains_link (cache, FALSE, obj_new, TRUE);
-		g_assert_cmpint (obj_new->_link.netlink.is_in_netlink, ==, TRUE);
-		g_assert_cmpint (obj_new->link.initialized, ==, TRUE);
-		nmp_object_unref (objm1);
-		nmp_object_unref (obj_old);
-		nmp_object_unref (obj_new);
-
-		/* remove UDEV. */
-		ops_type = nmp_cache_update_link_udev (cache, pl_link_3.ifindex, NULL, &obj_old, &obj_new);
-		g_assert_cmpint (ops_type, ==, NMP_CACHE_OPS_UPDATED);
-		ASSERT_nmp_cache_is_consistent (cache);
-		g_assert (obj_old && nmp_object_is_visible (obj_old));
-		g_assert (nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&objs1, pl_link_3.ifindex)) == obj_new);
-		g_assert (nmp_object_is_visible (obj_new));
-		_assert_cache_multi_lookup_contains_link (cache, TRUE, obj_new, TRUE);
-		_assert_cache_multi_lookup_contains_link (cache, FALSE, obj_new, TRUE);
-		g_assert_cmpint (obj_new->_link.netlink.is_in_netlink, ==, TRUE);
-		g_assert_cmpint (obj_new->link.initialized, ==, !nmp_cache_use_udev_get (cache));
-		nmp_object_unref (obj_new);
-		nmp_object_unref (obj_old);
-	}
-
-	nmp_cache_free (cache);
+    NMPCache *                      cache;
+    NMPObject *                     objm1;
+    const NMPObject *               obj_old, *obj_new;
+    NMPObject                       objs1;
+    struct udev_device *            udev_device_2 = g_list_nth_data(global.udev_devices, 0);
+    struct udev_device *            udev_device_3 = g_list_nth_data(global.udev_devices, 0);
+    NMPCacheOpsType                 ops_type;
+    nm_auto_unref_dedup_multi_index NMDedupMultiIndex *multi_idx = NULL;
+    gboolean                                           use_udev  = nmtst_get_rand_uint32() % 2;
+
+    multi_idx = nm_dedup_multi_index_new();
+
+    cache = nmp_cache_new(multi_idx, use_udev);
+
+    /* if we have a link, and don't set is_in_netlink, adding it has no effect. */
+    objm1 = nmp_object_new(NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2);
+    g_assert(NMP_OBJECT_UP_CAST(&objm1->object) == objm1);
+    g_assert(!nmp_object_is_alive(objm1));
+    _nmp_cache_update_netlink(cache, objm1, &obj_old, &obj_new, NMP_CACHE_OPS_UNCHANGED);
+    nmtst_assert_nmp_cache_is_consistent(cache);
+    g_assert(!obj_old);
+    g_assert(!obj_new);
+    g_assert(!nmp_cache_lookup_obj(cache, objm1));
+    g_assert(!nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&objs1, pl_link_2.ifindex)));
+    nmp_object_unref(objm1);
+
+    /* Only when setting @is_in_netlink the link is added. */
+    objm1 = nmp_object_new(NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2);
+    objm1->_link.netlink.is_in_netlink = TRUE;
+    g_assert(nmp_object_is_alive(objm1));
+    _nmp_cache_update_netlink(cache, objm1, &obj_old, &obj_new, NMP_CACHE_OPS_ADDED);
+    nmtst_assert_nmp_cache_is_consistent(cache);
+    g_assert(!obj_old);
+    g_assert(obj_new);
+    g_assert(objm1 == obj_new);
+    g_assert(nmp_object_equal(objm1, obj_new));
+    g_assert(nmp_cache_lookup_obj(cache, objm1) == obj_new);
+    g_assert(nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&objs1, pl_link_2.ifindex))
+             == obj_new);
+    g_assert(nmp_object_is_visible(obj_new));
+    _assert_cache_multi_lookup_contains_link(cache, FALSE, obj_new, TRUE);
+    _assert_cache_multi_lookup_contains_link(cache, TRUE, obj_new, TRUE);
+    nmp_object_unref(objm1);
+    nmp_object_unref(obj_new);
+
+    /* updating the same link with identical value, has no effect. */
+    objm1 = nmp_object_new(NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2);
+    objm1->_link.netlink.is_in_netlink = TRUE;
+    g_assert(nmp_object_is_alive(objm1));
+    _nmp_cache_update_netlink(cache, objm1, &obj_old, &obj_new, NMP_CACHE_OPS_UNCHANGED);
+    nmtst_assert_nmp_cache_is_consistent(cache);
+    g_assert(obj_old);
+    g_assert(obj_new);
+    g_assert(obj_new != objm1);
+    g_assert(nmp_object_equal(objm1, obj_new));
+    g_assert(nmp_cache_lookup_obj(cache, objm1) == obj_new);
+    g_assert(nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&objs1, pl_link_2.ifindex))
+             == obj_new);
+    nmp_object_unref(objm1);
+    nmp_object_unref(obj_new);
+    nmp_object_unref(obj_new);
+
+    /* remove the link from netlink */
+    objm1 = nmp_object_new(NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2);
+    g_assert(!nmp_object_is_alive(objm1));
+    _nmp_cache_update_netlink(cache, objm1, &obj_old, &obj_new, NMP_CACHE_OPS_REMOVED);
+    nmtst_assert_nmp_cache_is_consistent(cache);
+    g_assert(obj_old);
+    g_assert(!obj_new);
+    g_assert(!nmp_cache_lookup_obj(cache, objm1));
+    g_assert(!nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&objs1, pl_link_2.ifindex)));
+    nmp_object_unref(objm1);
+    nmp_object_unref(obj_old);
+    nmp_object_unref(obj_new);
+
+    if (udev_device_2) {
+        /* now add the link only with aspect UDEV. */
+        ops_type =
+            nmp_cache_update_link_udev(cache, pl_link_2.ifindex, udev_device_2, &obj_old, &obj_new);
+        nmtst_assert_nmp_cache_is_consistent(cache);
+        g_assert_cmpint(ops_type, ==, NMP_CACHE_OPS_ADDED);
+        g_assert(!obj_old);
+        g_assert(obj_new);
+        g_assert(
+            nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&objs1, pl_link_2.ifindex))
+            == obj_new);
+        g_assert(!nmp_object_is_visible(obj_new));
+        _assert_cache_multi_lookup_contains_link(cache, TRUE, obj_new, FALSE);
+        _assert_cache_multi_lookup_contains_link(cache, FALSE, obj_new, TRUE);
+        nmp_object_unref(obj_new);
+    }
+
+    /* add it in netlink too. */
+    objm1 = nmp_object_new(NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2);
+    objm1->_link.netlink.is_in_netlink = TRUE;
+    g_assert(nmp_object_is_alive(objm1));
+    _nmp_cache_update_netlink(cache,
+                              objm1,
+                              &obj_old,
+                              &obj_new,
+                              udev_device_2 ? NMP_CACHE_OPS_UPDATED : NMP_CACHE_OPS_ADDED);
+    nmtst_assert_nmp_cache_is_consistent(cache);
+    if (udev_device_2) {
+        g_assert(obj_old);
+        g_assert(!nmp_object_is_visible(obj_old));
+    } else
+        g_assert(!obj_old);
+    g_assert(nmp_object_equal(objm1, obj_new));
+    g_assert(nmp_cache_lookup_obj(cache, objm1) == obj_new);
+    g_assert(nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&objs1, pl_link_2.ifindex))
+             == obj_new);
+    g_assert(nmp_object_is_visible(obj_new));
+    _assert_cache_multi_lookup_contains_link(cache, TRUE, obj_new, TRUE);
+    _assert_cache_multi_lookup_contains_link(cache, FALSE, obj_new, TRUE);
+    nmp_object_unref(objm1);
+    nmp_object_unref(obj_old);
+    nmp_object_unref(obj_new);
+
+    /* remove again from netlink. */
+    objm1 = nmp_object_new(NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2);
+    objm1->_link.netlink.is_in_netlink = FALSE;
+    g_assert(!nmp_object_is_alive(objm1));
+    _nmp_cache_update_netlink(cache,
+                              objm1,
+                              &obj_old,
+                              &obj_new,
+                              udev_device_2 ? NMP_CACHE_OPS_UPDATED : NMP_CACHE_OPS_REMOVED);
+    nmtst_assert_nmp_cache_is_consistent(cache);
+    if (udev_device_2)
+        g_assert(obj_new == objm1);
+    else
+        g_assert(!obj_new);
+    g_assert(obj_old);
+    g_assert(nmp_object_is_alive(obj_old));
+    if (udev_device_2) {
+        g_assert(nmp_cache_lookup_obj(cache, objm1) == obj_new);
+        g_assert(
+            nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&objs1, pl_link_2.ifindex))
+            == obj_new);
+        g_assert(!nmp_object_is_visible(obj_new));
+        _assert_cache_multi_lookup_contains_link(cache, TRUE, obj_new, FALSE);
+        _assert_cache_multi_lookup_contains_link(cache, FALSE, obj_new, TRUE);
+    } else {
+        g_assert(nmp_cache_lookup_obj(cache, objm1) == NULL);
+        g_assert(
+            nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&objs1, pl_link_2.ifindex))
+            == NULL);
+        g_assert(!nmp_object_is_alive(obj_new));
+        g_assert(!nmp_object_is_visible(obj_new));
+    }
+    nmp_object_unref(objm1);
+    nmp_object_unref(obj_old);
+    nmp_object_unref(obj_new);
+
+    /* now another link only with aspect UDEV. */
+    if (udev_device_3) {
+        /* now add the link only with aspect UDEV. */
+        ops_type =
+            nmp_cache_update_link_udev(cache, pl_link_3.ifindex, udev_device_3, &obj_old, &obj_new);
+        g_assert_cmpint(ops_type, ==, NMP_CACHE_OPS_ADDED);
+        nmtst_assert_nmp_cache_is_consistent(cache);
+        g_assert(NMP_OBJECT_IS_VALID(obj_new));
+        g_assert(!obj_old);
+        g_assert(!nmp_object_is_visible(obj_new));
+        g_assert(
+            nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&objs1, pl_link_3.ifindex))
+            == obj_new);
+        _assert_cache_multi_lookup_contains_link(cache, TRUE, obj_new, FALSE);
+        _assert_cache_multi_lookup_contains_link(cache, FALSE, obj_new, TRUE);
+        g_assert_cmpint(obj_new->_link.netlink.is_in_netlink, ==, FALSE);
+        g_assert_cmpint(obj_new->link.initialized, ==, FALSE);
+        nmp_object_unref(obj_new);
+
+        /* add it in netlink too. */
+        objm1 = nmp_object_new(NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_3);
+        objm1->_link.netlink.is_in_netlink = TRUE;
+        g_assert(nmp_object_is_alive(objm1));
+        _nmp_cache_update_netlink(cache, objm1, &obj_old, &obj_new, NMP_CACHE_OPS_UPDATED);
+        nmtst_assert_nmp_cache_is_consistent(cache);
+        g_assert(obj_old);
+        g_assert(obj_new == objm1);
+        g_assert(nmp_object_equal(objm1, obj_new));
+        g_assert(!obj_old || !nmp_object_is_visible(obj_old));
+        g_assert(nmp_cache_lookup_obj(cache, objm1) == obj_new);
+        g_assert(
+            nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&objs1, pl_link_3.ifindex))
+            == obj_new);
+        g_assert(nmp_object_is_visible(obj_new));
+        _assert_cache_multi_lookup_contains_link(cache, TRUE, obj_new, TRUE);
+        _assert_cache_multi_lookup_contains_link(cache, FALSE, obj_new, TRUE);
+        g_assert_cmpint(obj_new->_link.netlink.is_in_netlink, ==, TRUE);
+        g_assert_cmpint(obj_new->link.initialized, ==, TRUE);
+        nmp_object_unref(objm1);
+        nmp_object_unref(obj_old);
+        nmp_object_unref(obj_new);
+
+        /* remove UDEV. */
+        ops_type = nmp_cache_update_link_udev(cache, pl_link_3.ifindex, NULL, &obj_old, &obj_new);
+        g_assert_cmpint(ops_type, ==, NMP_CACHE_OPS_UPDATED);
+        nmtst_assert_nmp_cache_is_consistent(cache);
+        g_assert(obj_old && nmp_object_is_visible(obj_old));
+        g_assert(
+            nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&objs1, pl_link_3.ifindex))
+            == obj_new);
+        g_assert(nmp_object_is_visible(obj_new));
+        _assert_cache_multi_lookup_contains_link(cache, TRUE, obj_new, TRUE);
+        _assert_cache_multi_lookup_contains_link(cache, FALSE, obj_new, TRUE);
+        g_assert_cmpint(obj_new->_link.netlink.is_in_netlink, ==, TRUE);
+        g_assert_cmpint(obj_new->link.initialized, ==, !nmp_cache_use_udev_get(cache));
+        nmp_object_unref(obj_new);
+        nmp_object_unref(obj_old);
+    }
+
+    nmp_cache_free(cache);
 }
 
-const char noqueue[] = "noqueue";
+const char noqueue[]  = "noqueue";
 const char fq_codel[] = "fq_codel";
-const char ingress[] = "ingress";
+const char ingress[]  = "ingress";
 
 static const NMPlatformQdisc pl_qdisc_1a = {
-	.ifindex = 1,
-	.kind = noqueue,
-	.addr_family = AF_UNSPEC,
-	.handle = 0,
-	.parent = TC_H_ROOT,
-	.info = 0,
+    .ifindex     = 1,
+    .kind        = noqueue,
+    .addr_family = AF_UNSPEC,
+    .handle      = 0,
+    .parent      = TC_H_ROOT,
+    .info        = 0,
 };
 
 static const NMPlatformQdisc pl_qdisc_1b = {
-	.ifindex = 1,
-	.kind = fq_codel,
-	.addr_family = AF_UNSPEC,
-	.handle = 0,
-	.parent = TC_H_ROOT,
-	.info = 0,
+    .ifindex     = 1,
+    .kind        = fq_codel,
+    .addr_family = AF_UNSPEC,
+    .handle      = 0,
+    .parent      = TC_H_ROOT,
+    .info        = 0,
 };
 
 static const NMPlatformQdisc pl_qdisc_1c = {
-	.ifindex = 1,
-	.kind = ingress,
-	.addr_family = AF_UNSPEC,
-	.handle = TC_H_MAKE(TC_H_INGRESS, 0),
-	.parent = TC_H_INGRESS,
-	.info = 0,
+    .ifindex     = 1,
+    .kind        = ingress,
+    .addr_family = AF_UNSPEC,
+    .handle      = TC_H_MAKE(TC_H_INGRESS, 0),
+    .parent      = TC_H_INGRESS,
+    .info        = 0,
 };
 
 static const NMPlatformQdisc pl_qdisc_2 = {
-	.ifindex = 2,
-	.kind = fq_codel,
-	.addr_family = AF_UNSPEC,
-	.handle = 0,
-	.parent = TC_H_ROOT,
-	.info = 0,
+    .ifindex     = 2,
+    .kind        = fq_codel,
+    .addr_family = AF_UNSPEC,
+    .handle      = 0,
+    .parent      = TC_H_ROOT,
+    .info        = 0,
 };
 
 static void
-test_cache_qdisc (void)
+test_cache_qdisc(void)
 {
-	NMPCache *cache;
-	nm_auto_unref_dedup_multi_index NMDedupMultiIndex *multi_idx = NULL;
-	NMPLookup lookup;
-	const NMDedupMultiHeadEntry *head_entry;
-	nm_auto_nmpobj NMPObject *obj1a = nmp_object_new (NMP_OBJECT_TYPE_QDISC, (NMPlatformObject *) &pl_qdisc_1a);
-	nm_auto_nmpobj NMPObject *obj1b = nmp_object_new (NMP_OBJECT_TYPE_QDISC, (NMPlatformObject *) &pl_qdisc_1b);
-	nm_auto_nmpobj NMPObject *obj1c = nmp_object_new (NMP_OBJECT_TYPE_QDISC, (NMPlatformObject *) &pl_qdisc_1c);
-	nm_auto_nmpobj NMPObject *obj2 = nmp_object_new (NMP_OBJECT_TYPE_QDISC, (NMPlatformObject *) &pl_qdisc_2);
-
-	multi_idx = nm_dedup_multi_index_new ();
-	cache = nmp_cache_new (multi_idx, nmtst_get_rand_uint32 () % 2);
-
-	g_assert (nmp_cache_lookup_obj (cache, obj1a) == NULL);
-
-	g_assert (nmp_cache_update_netlink (cache, obj1a, FALSE, NULL, NULL) == NMP_CACHE_OPS_ADDED);
-	g_assert (nmp_cache_lookup_obj (cache, obj1a) == obj1a);
-	g_assert (nmp_cache_lookup_obj (cache, obj1b) == obj1a);
-	g_assert (nmp_cache_lookup_obj (cache, obj2) == NULL);
-
-	g_assert (nmp_cache_update_netlink (cache, obj1b, FALSE, NULL, NULL) == NMP_CACHE_OPS_UPDATED);
-	g_assert (nmp_cache_lookup_obj (cache, obj1a) == obj1b);
-	g_assert (nmp_cache_lookup_obj (cache, obj1b) == obj1b);
-	g_assert (nmp_cache_lookup_obj (cache, obj2) == NULL);
-
-	g_assert (nmp_cache_update_netlink (cache, obj1c, FALSE, NULL, NULL) == NMP_CACHE_OPS_ADDED);
-	g_assert (nmp_cache_lookup_obj (cache, obj1a) == obj1b);
-	g_assert (nmp_cache_lookup_obj (cache, obj1b) == obj1b);
-	g_assert (nmp_cache_lookup_obj (cache, obj1c) == obj1c);
-	g_assert (nmp_cache_lookup_obj (cache, obj2) == NULL);
-
-	g_assert (nmp_cache_update_netlink (cache, obj2, FALSE, NULL, NULL) == NMP_CACHE_OPS_ADDED);
-	g_assert (nmp_cache_lookup_obj (cache, obj1a) == obj1b);
-	g_assert (nmp_cache_lookup_obj (cache, obj1b) == obj1b);
-	g_assert (nmp_cache_lookup_obj (cache, obj2) == obj2);
-
-	head_entry = nmp_cache_lookup (cache,
-	                               nmp_lookup_init_object (&lookup,
-	                                                       NMP_OBJECT_TYPE_QDISC,
-	                                                       1));
-	g_assert (head_entry->len == 2);
-
-	nmp_cache_free (cache);
+    NMPCache *                      cache;
+    nm_auto_unref_dedup_multi_index NMDedupMultiIndex *multi_idx = NULL;
+    NMPLookup                                          lookup;
+    const NMDedupMultiHeadEntry *                      head_entry;
+    nm_auto_nmpobj NMPObject *obj1a =
+        nmp_object_new(NMP_OBJECT_TYPE_QDISC, (NMPlatformObject *) &pl_qdisc_1a);
+    nm_auto_nmpobj NMPObject *obj1b =
+        nmp_object_new(NMP_OBJECT_TYPE_QDISC, (NMPlatformObject *) &pl_qdisc_1b);
+    nm_auto_nmpobj NMPObject *obj1c =
+        nmp_object_new(NMP_OBJECT_TYPE_QDISC, (NMPlatformObject *) &pl_qdisc_1c);
+    nm_auto_nmpobj NMPObject *obj2 =
+        nmp_object_new(NMP_OBJECT_TYPE_QDISC, (NMPlatformObject *) &pl_qdisc_2);
+
+    multi_idx = nm_dedup_multi_index_new();
+    cache     = nmp_cache_new(multi_idx, nmtst_get_rand_uint32() % 2);
+
+    g_assert(nmp_cache_lookup_obj(cache, obj1a) == NULL);
+
+    g_assert(nmp_cache_update_netlink(cache, obj1a, FALSE, NULL, NULL) == NMP_CACHE_OPS_ADDED);
+    g_assert(nmp_cache_lookup_obj(cache, obj1a) == obj1a);
+    g_assert(nmp_cache_lookup_obj(cache, obj1b) == obj1a);
+    g_assert(nmp_cache_lookup_obj(cache, obj2) == NULL);
+
+    g_assert(nmp_cache_update_netlink(cache, obj1b, FALSE, NULL, NULL) == NMP_CACHE_OPS_UPDATED);
+    g_assert(nmp_cache_lookup_obj(cache, obj1a) == obj1b);
+    g_assert(nmp_cache_lookup_obj(cache, obj1b) == obj1b);
+    g_assert(nmp_cache_lookup_obj(cache, obj2) == NULL);
+
+    g_assert(nmp_cache_update_netlink(cache, obj1c, FALSE, NULL, NULL) == NMP_CACHE_OPS_ADDED);
+    g_assert(nmp_cache_lookup_obj(cache, obj1a) == obj1b);
+    g_assert(nmp_cache_lookup_obj(cache, obj1b) == obj1b);
+    g_assert(nmp_cache_lookup_obj(cache, obj1c) == obj1c);
+    g_assert(nmp_cache_lookup_obj(cache, obj2) == NULL);
+
+    g_assert(nmp_cache_update_netlink(cache, obj2, FALSE, NULL, NULL) == NMP_CACHE_OPS_ADDED);
+    g_assert(nmp_cache_lookup_obj(cache, obj1a) == obj1b);
+    g_assert(nmp_cache_lookup_obj(cache, obj1b) == obj1b);
+    g_assert(nmp_cache_lookup_obj(cache, obj2) == obj2);
+
+    head_entry = nmp_cache_lookup(cache, nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_QDISC, 1));
+    g_assert(head_entry->len == 2);
+
+    nmp_cache_free(cache);
 }
 
 /*****************************************************************************/
 
-NMTST_DEFINE ();
+NMTST_DEFINE();
 
 int
-main (int argc, char **argv)
+main(int argc, char **argv)
 {
-	int result;
-	NMUdevClient *udev_client;
+    int           result;
+    NMUdevClient *udev_client;
 
-	nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT");
+    nmtst_init_assert_logging(&argc, &argv, "INFO", "DEFAULT");
 
-	udev_client = nm_udev_client_new ((const char *[]) { "net", NULL },
-	                                  NULL, NULL);
-	{
-		struct udev_enumerate *enumerator;
-		struct udev_list_entry *devices, *l;
+    udev_client = nm_udev_client_new((const char *[]){"net", NULL}, NULL, NULL);
+    {
+        struct udev_enumerate * enumerator;
+        struct udev_list_entry *devices, *l;
 
-		enumerator = nm_udev_client_enumerate_new (udev_client);
+        enumerator = nm_udev_client_enumerate_new(udev_client);
 
-		/* Demand that the device is initialized (udev rules ran,
-		 * device has a stable name now) in case udev is running
-		 * (not in a container). */
-		if (access ("/sys", W_OK) == 0)
-			udev_enumerate_add_match_is_initialized (enumerator);
+        /* Demand that the device is initialized (udev rules ran,
+         * device has a stable name now) in case udev is running
+         * (not in a container). */
+        if (access("/sys", W_OK) == 0)
+            udev_enumerate_add_match_is_initialized(enumerator);
 
-		udev_enumerate_scan_devices (enumerator);
+        udev_enumerate_scan_devices(enumerator);
 
-		devices = udev_enumerate_get_list_entry (enumerator);
-		for (l = devices; l != NULL; l = udev_list_entry_get_next (l)) {
-			struct udev_device *udevice;
+        devices = udev_enumerate_get_list_entry(enumerator);
+        for (l = devices; l != NULL; l = udev_list_entry_get_next(l)) {
+            struct udev_device *udevice;
 
-			udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerator),
-			                                        udev_list_entry_get_name (l));
-			if (udevice == NULL)
-				continue;
+            udevice = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerator),
+                                                   udev_list_entry_get_name(l));
+            if (udevice == NULL)
+                continue;
 
-			global.udev_devices = g_list_prepend (global.udev_devices, udevice);
-		}
-		global.udev_devices = g_list_reverse (global.udev_devices);
+            global.udev_devices = g_list_prepend(global.udev_devices, udevice);
+        }
+        global.udev_devices = g_list_reverse(global.udev_devices);
 
-		udev_enumerate_unref (enumerator);
-	}
+        udev_enumerate_unref(enumerator);
+    }
 
-	g_test_add_func ("/nmp-object/obj-base", test_obj_base);
-	g_test_add_func ("/nmp-object/cache_link", test_cache_link);
-	g_test_add_func ("/nmp-object/cache_qdisc", test_cache_qdisc);
+    g_test_add_func("/nmp-object/obj-base", test_obj_base);
+    g_test_add_func("/nmp-object/cache_link", test_cache_link);
+    g_test_add_func("/nmp-object/cache_qdisc", test_cache_qdisc);
 
-	result = g_test_run ();
+    result = g_test_run();
 
-	while (global.udev_devices) {
-		udev_device_unref (global.udev_devices->data);
-		global.udev_devices = g_list_delete_link (global.udev_devices, global.udev_devices);
-	}
+    while (global.udev_devices) {
+        udev_device_unref(global.udev_devices->data);
+        global.udev_devices = g_list_delete_link(global.udev_devices, global.udev_devices);
+    }
 
-	nm_udev_client_unref (udev_client);
+    nm_udev_client_unref(udev_client);
 
-	return result;
+    return result;
 }
-