mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-01 20:00:12 +01:00
tests: add nmtstc_client_new() helper
This commit is contained in:
parent
ec39498fc6
commit
8def37dd65
2 changed files with 149 additions and 0 deletions
|
|
@ -67,3 +67,4 @@ void nmtstc_service_update_connection_variant (NMTstcServiceInfo *sinfo,
|
|||
GVariant *connection,
|
||||
gboolean verify_connection);
|
||||
|
||||
NMClient *nmtstc_client_new (gboolean allow_iterate_main_context);
|
||||
|
|
|
|||
|
|
@ -406,3 +406,151 @@ nmtstc_service_update_connection_variant (NMTstcServiceInfo *sinfo,
|
|||
g_assert (g_variant_is_of_type (result, G_VARIANT_TYPE ("()")));
|
||||
g_variant_unref (result);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
GMainLoop *loop;
|
||||
NMClient *client;
|
||||
} NMTstcClientNewData;
|
||||
|
||||
static void
|
||||
_nmtstc_client_new_cb (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMTstcClientNewData *d = user_data;
|
||||
gs_free_error GError *error = NULL;
|
||||
|
||||
g_assert (!d->client);
|
||||
|
||||
d->client = nm_client_new_finish (res,
|
||||
nmtst_get_rand_bool () ? &error : NULL);
|
||||
|
||||
nmtst_assert_success (NM_IS_CLIENT (d->client), error);
|
||||
|
||||
g_main_loop_quit (d->loop);
|
||||
}
|
||||
|
||||
static NMClient *
|
||||
_nmtstc_client_new (gboolean sync)
|
||||
{
|
||||
gs_free GError *error = NULL;
|
||||
NMClient *client;
|
||||
|
||||
/* Create a NMClient instance synchronously, and arbitrarily use either
|
||||
* the sync or async constructor.
|
||||
*
|
||||
* Note that the sync and async construct differ in one important aspect:
|
||||
* the async constructor iterates the current g_main_context_get_thread_default(),
|
||||
* while the sync constructor does not! Aside from that, both should behave
|
||||
* pretty much the same way. */
|
||||
|
||||
if (sync) {
|
||||
nm_auto_destroy_and_unref_gsource GSource *source = NULL;
|
||||
|
||||
if (nmtst_get_rand_bool ()) {
|
||||
/* the current main context must not be iterated! */
|
||||
source = g_idle_source_new ();
|
||||
g_source_set_callback (source, nmtst_g_source_assert_not_called, NULL, NULL);
|
||||
g_source_attach (source, g_main_context_get_thread_default ());
|
||||
}
|
||||
|
||||
if (nmtst_get_rand_bool ()) {
|
||||
gboolean success;
|
||||
|
||||
client = g_object_new (NM_TYPE_CLIENT, NULL);
|
||||
g_assert (NM_IS_CLIENT (client));
|
||||
|
||||
success = g_initable_init (G_INITABLE (client),
|
||||
NULL,
|
||||
nmtst_get_rand_bool () ? &error : NULL);
|
||||
nmtst_assert_success (success, error);
|
||||
} else {
|
||||
client = nm_client_new (NULL,
|
||||
nmtst_get_rand_bool () ? &error : NULL);
|
||||
}
|
||||
} else {
|
||||
nm_auto_unref_gmainloop GMainLoop *loop = NULL;
|
||||
NMTstcClientNewData d = { .loop = NULL, };
|
||||
|
||||
loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
|
||||
|
||||
d.loop = loop;
|
||||
nm_client_new_async (NULL,
|
||||
_nmtstc_client_new_cb,
|
||||
&d);
|
||||
g_main_loop_run (loop);
|
||||
g_assert (NM_IS_CLIENT (d.client));
|
||||
client = d.client;
|
||||
}
|
||||
|
||||
nmtst_assert_success (NM_IS_CLIENT (client), error);
|
||||
return client;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GMainLoop *loop;
|
||||
NMClient *client;
|
||||
bool sync;
|
||||
} NewSyncInsideDispatchedData;
|
||||
|
||||
static gboolean
|
||||
_nmtstc_client_new_inside_loop_do (gpointer user_data)
|
||||
{
|
||||
NewSyncInsideDispatchedData *d = user_data;
|
||||
|
||||
g_assert (d->loop);
|
||||
g_assert (!d->client);
|
||||
|
||||
d->client = nmtstc_client_new (d->sync);
|
||||
g_main_loop_quit (d->loop);
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static NMClient *
|
||||
_nmtstc_client_new_inside_loop (gboolean sync)
|
||||
{
|
||||
GMainContext *context = g_main_context_get_thread_default ();
|
||||
nm_auto_unref_gmainloop GMainLoop *loop = g_main_loop_new (context, FALSE);
|
||||
NewSyncInsideDispatchedData d = {
|
||||
.sync = sync,
|
||||
.loop = loop,
|
||||
};
|
||||
nm_auto_destroy_and_unref_gsource GSource *source = NULL;
|
||||
|
||||
source = g_idle_source_new ();
|
||||
g_source_set_callback (source, _nmtstc_client_new_inside_loop_do, &d, NULL);
|
||||
g_source_attach (source, context);
|
||||
|
||||
g_main_loop_run (loop);
|
||||
g_assert (NM_IS_CLIENT (d.client));
|
||||
return d.client;
|
||||
}
|
||||
|
||||
NMClient *
|
||||
nmtstc_client_new (gboolean allow_iterate_main_context)
|
||||
{
|
||||
gboolean inside_loop;
|
||||
gboolean sync;
|
||||
|
||||
if (!allow_iterate_main_context) {
|
||||
sync = TRUE;
|
||||
inside_loop = FALSE;
|
||||
} else {
|
||||
/* The caller allows to iterate the main context. That that point,
|
||||
* we can both use the synchronous and the asynchronous initialization,
|
||||
* both should yield the same result. Choose one randomly. */
|
||||
sync = nmtst_get_rand_bool ();
|
||||
inside_loop = ((nmtst_get_rand_uint32 () % 3) == 0);
|
||||
}
|
||||
|
||||
if (inside_loop) {
|
||||
/* Create the client on an idle handler of the current context.
|
||||
* In practice, it should make no difference, which this check
|
||||
* tries to prove. */
|
||||
return _nmtstc_client_new_inside_loop (sync);
|
||||
}
|
||||
|
||||
return _nmtstc_client_new (sync);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue