mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-04-02 13:53:06 +02:00
tests/gmenumodel: Add test cases using peer-to-peer D-Bus connection
https://bugzilla.gnome.org/show_bug.cgi?id=720380
This commit is contained in:
parent
f29065c315
commit
c71098ddab
@ -1,4 +1,7 @@
|
|||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
|
#include <gio/gunixsocketaddress.h>
|
||||||
|
#include <glib/gstdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "gdbus-sessionbus.h"
|
#include "gdbus-sessionbus.h"
|
||||||
|
|
||||||
@ -715,6 +718,180 @@ test_random (void)
|
|||||||
g_rand_free (rand);
|
g_rand_free (rand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GDBusConnection *client_connection;
|
||||||
|
GDBusConnection *server_connection;
|
||||||
|
GDBusServer *server;
|
||||||
|
|
||||||
|
GThread *service_thread;
|
||||||
|
GMutex service_loop_lock;
|
||||||
|
GCond service_loop_cond;
|
||||||
|
|
||||||
|
GMainLoop *service_loop;
|
||||||
|
GMainLoop *loop;
|
||||||
|
} PeerConnection;
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
on_new_connection (GDBusServer *server,
|
||||||
|
GDBusConnection *connection,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
PeerConnection *data = user_data;
|
||||||
|
|
||||||
|
data->server_connection = g_object_ref (connection);
|
||||||
|
|
||||||
|
g_main_loop_quit (data->loop);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_service_loop (GMainContext *service_context,
|
||||||
|
PeerConnection *data)
|
||||||
|
{
|
||||||
|
g_assert (data->service_loop == NULL);
|
||||||
|
g_mutex_lock (&data->service_loop_lock);
|
||||||
|
data->service_loop = g_main_loop_new (service_context, FALSE);
|
||||||
|
g_cond_broadcast (&data->service_loop_cond);
|
||||||
|
g_mutex_unlock (&data->service_loop_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
teardown_service_loop (PeerConnection *data)
|
||||||
|
{
|
||||||
|
g_mutex_lock (&data->service_loop_lock);
|
||||||
|
g_clear_pointer (&data->service_loop, g_main_loop_unref);
|
||||||
|
g_mutex_unlock (&data->service_loop_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
await_service_loop (PeerConnection *data)
|
||||||
|
{
|
||||||
|
g_mutex_lock (&data->service_loop_lock);
|
||||||
|
while (data->service_loop == NULL)
|
||||||
|
g_cond_wait (&data->service_loop_cond, &data->service_loop_lock);
|
||||||
|
g_mutex_unlock (&data->service_loop_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gpointer
|
||||||
|
service_thread_func (gpointer user_data)
|
||||||
|
{
|
||||||
|
PeerConnection *data = user_data;
|
||||||
|
GMainContext *service_context;
|
||||||
|
GError *error;
|
||||||
|
gchar *address;
|
||||||
|
gchar *tmpdir;
|
||||||
|
GDBusServerFlags flags;
|
||||||
|
gchar *guid;
|
||||||
|
|
||||||
|
service_context = g_main_context_new ();
|
||||||
|
g_main_context_push_thread_default (service_context);
|
||||||
|
|
||||||
|
tmpdir = NULL;
|
||||||
|
flags = G_DBUS_SERVER_FLAGS_NONE;
|
||||||
|
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
if (g_unix_socket_address_abstract_names_supported ())
|
||||||
|
address = g_strdup ("unix:tmpdir=/tmp/test-dbus-peer");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tmpdir = g_dir_make_tmp ("test-dbus-peer-XXXXXX", NULL);
|
||||||
|
address = g_strdup_printf ("unix:tmpdir=%s", tmpdir);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
address = g_strdup ("nonce-tcp:");
|
||||||
|
flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
guid = g_dbus_generate_guid ();
|
||||||
|
|
||||||
|
error = NULL;
|
||||||
|
data->server = g_dbus_server_new_sync (address,
|
||||||
|
flags,
|
||||||
|
guid,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&error);
|
||||||
|
g_assert_no_error (error);
|
||||||
|
g_free (address);
|
||||||
|
g_free (guid);
|
||||||
|
|
||||||
|
g_signal_connect (data->server,
|
||||||
|
"new-connection",
|
||||||
|
G_CALLBACK (on_new_connection),
|
||||||
|
data);
|
||||||
|
|
||||||
|
g_dbus_server_start (data->server);
|
||||||
|
|
||||||
|
create_service_loop (service_context, data);
|
||||||
|
g_main_loop_run (data->service_loop);
|
||||||
|
|
||||||
|
g_main_context_pop_thread_default (service_context);
|
||||||
|
|
||||||
|
teardown_service_loop (data);
|
||||||
|
g_main_context_unref (service_context);
|
||||||
|
|
||||||
|
if (tmpdir)
|
||||||
|
{
|
||||||
|
g_rmdir (tmpdir);
|
||||||
|
g_free (tmpdir);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
peer_connection_up (PeerConnection *data)
|
||||||
|
{
|
||||||
|
GError *error;
|
||||||
|
|
||||||
|
memset (data, '\0', sizeof (PeerConnection));
|
||||||
|
data->loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
|
||||||
|
g_mutex_init (&data->service_loop_lock);
|
||||||
|
g_cond_init (&data->service_loop_cond);
|
||||||
|
|
||||||
|
/* bring up a server - we run the server in a different thread to
|
||||||
|
avoid deadlocks */
|
||||||
|
data->service_thread = g_thread_new ("test_dbus_peer",
|
||||||
|
service_thread_func,
|
||||||
|
data);
|
||||||
|
await_service_loop (data);
|
||||||
|
g_assert (data->server != NULL);
|
||||||
|
|
||||||
|
/* bring up a connection and accept it */
|
||||||
|
error = NULL;
|
||||||
|
data->client_connection =
|
||||||
|
g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (data->server),
|
||||||
|
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
|
||||||
|
NULL, /* GDBusAuthObserver */
|
||||||
|
NULL, /* cancellable */
|
||||||
|
&error);
|
||||||
|
g_assert_no_error (error);
|
||||||
|
g_assert (data->client_connection != NULL);
|
||||||
|
while (data->server_connection == NULL)
|
||||||
|
g_main_loop_run (data->loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
peer_connection_down (PeerConnection *data)
|
||||||
|
{
|
||||||
|
g_object_unref (data->client_connection);
|
||||||
|
g_object_unref (data->server_connection);
|
||||||
|
|
||||||
|
g_dbus_server_stop (data->server);
|
||||||
|
g_object_unref (data->server);
|
||||||
|
|
||||||
|
g_main_loop_quit (data->service_loop);
|
||||||
|
g_thread_join (data->service_thread);
|
||||||
|
|
||||||
|
g_mutex_clear (&data->service_loop_lock);
|
||||||
|
g_cond_clear (&data->service_loop_cond);
|
||||||
|
|
||||||
|
g_main_loop_unref (data->loop);
|
||||||
|
}
|
||||||
|
|
||||||
struct roundtrip_state
|
struct roundtrip_state
|
||||||
{
|
{
|
||||||
RandomMenu *random;
|
RandomMenu *random;
|
||||||
@ -754,20 +931,23 @@ roundtrip_step (gpointer data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_dbus_roundtrip (void)
|
do_roundtrip (GDBusConnection *exporter_connection,
|
||||||
|
GDBusConnection *proxy_connection)
|
||||||
{
|
{
|
||||||
struct roundtrip_state state;
|
struct roundtrip_state state;
|
||||||
GDBusConnection *bus;
|
|
||||||
guint export_id;
|
guint export_id;
|
||||||
guint id;
|
guint id;
|
||||||
|
|
||||||
bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
|
|
||||||
|
|
||||||
state.rand = g_rand_new_with_seed (g_test_rand_int ());
|
state.rand = g_rand_new_with_seed (g_test_rand_int ());
|
||||||
|
|
||||||
state.random = random_menu_new (state.rand, 2);
|
state.random = random_menu_new (state.rand, 2);
|
||||||
export_id = g_dbus_connection_export_menu_model (bus, "/", G_MENU_MODEL (state.random), NULL);
|
export_id = g_dbus_connection_export_menu_model (exporter_connection,
|
||||||
state.proxy = g_dbus_menu_model_get (bus, g_dbus_connection_get_unique_name (bus), "/");
|
"/",
|
||||||
|
G_MENU_MODEL (state.random),
|
||||||
|
NULL);
|
||||||
|
state.proxy = g_dbus_menu_model_get (proxy_connection,
|
||||||
|
g_dbus_connection_get_unique_name (proxy_connection),
|
||||||
|
"/");
|
||||||
state.proxy_mirror = mirror_menu_new (G_MENU_MODEL (state.proxy));
|
state.proxy_mirror = mirror_menu_new (G_MENU_MODEL (state.proxy));
|
||||||
state.count = 0;
|
state.count = 0;
|
||||||
state.success = 0;
|
state.success = 0;
|
||||||
@ -780,13 +960,32 @@ test_dbus_roundtrip (void)
|
|||||||
g_main_loop_unref (state.loop);
|
g_main_loop_unref (state.loop);
|
||||||
g_source_remove (id);
|
g_source_remove (id);
|
||||||
g_object_unref (state.proxy);
|
g_object_unref (state.proxy);
|
||||||
g_dbus_connection_unexport_menu_model (bus, export_id);
|
g_dbus_connection_unexport_menu_model (exporter_connection, export_id);
|
||||||
g_object_unref (state.random);
|
g_object_unref (state.random);
|
||||||
g_object_unref (state.proxy_mirror);
|
g_object_unref (state.proxy_mirror);
|
||||||
g_rand_free (state.rand);
|
g_rand_free (state.rand);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_dbus_roundtrip (void)
|
||||||
|
{
|
||||||
|
GDBusConnection *bus;
|
||||||
|
|
||||||
|
bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
|
||||||
|
do_roundtrip (bus, bus);
|
||||||
g_object_unref (bus);
|
g_object_unref (bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_dbus_peer_roundtrip (void)
|
||||||
|
{
|
||||||
|
PeerConnection peer;
|
||||||
|
|
||||||
|
peer_connection_up (&peer);
|
||||||
|
do_roundtrip (peer.server_connection, peer.client_connection);
|
||||||
|
peer_connection_down (&peer);
|
||||||
|
}
|
||||||
|
|
||||||
static gint items_changed_count;
|
static gint items_changed_count;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -810,9 +1009,9 @@ stop_loop (gpointer data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_dbus_subscriptions (void)
|
do_subscriptions (GDBusConnection *exporter_connection,
|
||||||
|
GDBusConnection *proxy_connection)
|
||||||
{
|
{
|
||||||
GDBusConnection *bus;
|
|
||||||
GMenu *menu;
|
GMenu *menu;
|
||||||
GDBusMenuModel *proxy;
|
GDBusMenuModel *proxy;
|
||||||
GMainLoop *loop;
|
GMainLoop *loop;
|
||||||
@ -821,14 +1020,17 @@ test_dbus_subscriptions (void)
|
|||||||
|
|
||||||
loop = g_main_loop_new (NULL, FALSE);
|
loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
|
||||||
bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
|
|
||||||
|
|
||||||
menu = g_menu_new ();
|
menu = g_menu_new ();
|
||||||
|
|
||||||
export_id = g_dbus_connection_export_menu_model (bus, "/", G_MENU_MODEL (menu), &error);
|
export_id = g_dbus_connection_export_menu_model (exporter_connection,
|
||||||
|
"/",
|
||||||
|
G_MENU_MODEL (menu),
|
||||||
|
&error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
|
|
||||||
proxy = g_dbus_menu_model_get (bus, g_dbus_connection_get_unique_name (bus), "/");
|
proxy = g_dbus_menu_model_get (proxy_connection,
|
||||||
|
g_dbus_connection_get_unique_name (proxy_connection),
|
||||||
|
"/");
|
||||||
items_changed_count = 0;
|
items_changed_count = 0;
|
||||||
g_signal_connect (proxy, "items-changed",
|
g_signal_connect (proxy, "items-changed",
|
||||||
G_CALLBACK (items_changed), NULL);
|
G_CALLBACK (items_changed), NULL);
|
||||||
@ -878,13 +1080,32 @@ test_dbus_subscriptions (void)
|
|||||||
|
|
||||||
g_assert_cmpint (items_changed_count, ==, 6);
|
g_assert_cmpint (items_changed_count, ==, 6);
|
||||||
|
|
||||||
g_dbus_connection_unexport_menu_model (bus, export_id);
|
g_dbus_connection_unexport_menu_model (exporter_connection, export_id);
|
||||||
g_object_unref (menu);
|
g_object_unref (menu);
|
||||||
|
|
||||||
g_main_loop_unref (loop);
|
g_main_loop_unref (loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_dbus_subscriptions (void)
|
||||||
|
{
|
||||||
|
GDBusConnection *bus;
|
||||||
|
|
||||||
|
bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
|
||||||
|
do_subscriptions (bus, bus);
|
||||||
g_object_unref (bus);
|
g_object_unref (bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_dbus_peer_subscriptions (void)
|
||||||
|
{
|
||||||
|
PeerConnection peer;
|
||||||
|
|
||||||
|
peer_connection_up (&peer);
|
||||||
|
do_subscriptions (peer.server_connection, peer.client_connection);
|
||||||
|
peer_connection_down (&peer);
|
||||||
|
}
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
do_modify (gpointer data)
|
do_modify (gpointer data)
|
||||||
{
|
{
|
||||||
@ -1229,6 +1450,8 @@ main (int argc, char **argv)
|
|||||||
g_test_add_func ("/gmenu/dbus/roundtrip", test_dbus_roundtrip);
|
g_test_add_func ("/gmenu/dbus/roundtrip", test_dbus_roundtrip);
|
||||||
g_test_add_func ("/gmenu/dbus/subscriptions", test_dbus_subscriptions);
|
g_test_add_func ("/gmenu/dbus/subscriptions", test_dbus_subscriptions);
|
||||||
g_test_add_func ("/gmenu/dbus/threaded", test_dbus_threaded);
|
g_test_add_func ("/gmenu/dbus/threaded", test_dbus_threaded);
|
||||||
|
g_test_add_func ("/gmenu/dbus/peer/roundtrip", test_dbus_peer_roundtrip);
|
||||||
|
g_test_add_func ("/gmenu/dbus/peer/subscriptions", test_dbus_peer_subscriptions);
|
||||||
g_test_add_func ("/gmenu/attributes", test_attributes);
|
g_test_add_func ("/gmenu/attributes", test_attributes);
|
||||||
g_test_add_func ("/gmenu/attributes/iterate", test_attribute_iter);
|
g_test_add_func ("/gmenu/attributes/iterate", test_attribute_iter);
|
||||||
g_test_add_func ("/gmenu/links", test_links);
|
g_test_add_func ("/gmenu/links", test_links);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user