From 5f4d8ffa79d574c86b108a83735e58e6f1bb6ab5 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 24 Oct 2018 10:52:42 +0200 Subject: [PATCH] core/tests: allow to reset singleton instantiations for testing Most singletons can only be instantiated once (unless NM_DEFINE_SINGLETON_ALLOW_MULTIPLE is defined). Otherwise, an assertion will be triggered if the singleton is destroyed and another instance is requested. For testing, we want to create multiple singleton instances and being able to reset the singleton getter. Add a function for that. --- src/nm-core-utils.h | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h index 2591fd28bb..79bef0a870 100644 --- a/src/nm-core-utils.h +++ b/src/nm-core-utils.h @@ -63,20 +63,35 @@ void _nm_singleton_instance_register_destruction (GObject *instance); #define NM_DEFINE_SINGLETON_GETTER(TYPE, GETTER, GTYPE, ...) \ NM_DEFINE_SINGLETON_INSTANCE (TYPE); \ NM_DEFINE_SINGLETON_REGISTER (TYPE); \ +static char _already_created_##GETTER = FALSE; \ TYPE * \ GETTER (void) \ { \ if (G_UNLIKELY (!singleton_instance)) { \ - static char _already_created = FALSE; \ -\ - g_assert (!_already_created || (NM_DEFINE_SINGLETON_ALLOW_MULTIPLE)); \ - _already_created = TRUE;\ + g_assert (!(_already_created_##GETTER) || (NM_DEFINE_SINGLETON_ALLOW_MULTIPLE)); \ + (_already_created_##GETTER) = TRUE;\ singleton_instance = (g_object_new (GTYPE, ##__VA_ARGS__, NULL)); \ g_assert (singleton_instance); \ nm_singleton_instance_register (); \ nm_log_dbg (LOGD_CORE, "create %s singleton (%p)", G_STRINGIFY (TYPE), singleton_instance); \ } \ return singleton_instance; \ +} \ +_nm_unused static void \ +_nmtst_##GETTER##_reset (TYPE *instance) \ +{ \ + /* usually, the singleton can only be created once (and further instantiations + * are guarded by an assert). For testing, we need to reset the singleton to + * allow multiple instantiations. */ \ + g_assert (G_IS_OBJECT (instance)); \ + g_assert (instance == singleton_instance); \ + g_assert (_already_created_##GETTER); \ + g_object_unref (instance); \ + \ + /* require that the last unref also destroyed the singleton. If this fails, + * somebody still keeps a reference. Fix your test! */ \ + g_assert (!singleton_instance); \ + _already_created_##GETTER = FALSE; \ } /* attach @instance to the data or @owner. @owner owns a reference