mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-24 14:36:13 +01:00
tests: Add support for subscribing to signals from a well-known name
Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:
parent
124b4571bb
commit
14c3d6938e
@ -7,6 +7,9 @@
|
||||
|
||||
#include "gdbus-tests.h"
|
||||
|
||||
/* From the D-Bus Specification */
|
||||
#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1
|
||||
|
||||
#define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
|
||||
#define DBUS_PATH_DBUS "/org/freedesktop/DBus"
|
||||
#define DBUS_INTERFACE_DBUS DBUS_SERVICE_DBUS
|
||||
@ -22,6 +25,9 @@
|
||||
#define EXAMPLE_INTERFACE "org.gtk.GDBus.ExampleInterface"
|
||||
#define FOO_SIGNAL "Foo"
|
||||
|
||||
#define ALREADY_OWNED_NAME "org.gtk.Test.AlreadyOwned"
|
||||
#define OWNED_LATER_NAME "org.gtk.Test.OwnedLater"
|
||||
|
||||
/* Log @s in a debug message. */
|
||||
static inline const char *
|
||||
nonnull (const char *s,
|
||||
@ -101,7 +107,8 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
TestConn sender;
|
||||
const char *string_sender;
|
||||
TestConn unique_sender;
|
||||
const char *path;
|
||||
const char *iface;
|
||||
const char *member;
|
||||
@ -109,11 +116,18 @@ typedef struct
|
||||
GDBusSignalFlags flags;
|
||||
} TestSubscribe;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *name;
|
||||
TestConn owner;
|
||||
} TestOwnName;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TEST_ACTION_NONE = 0,
|
||||
TEST_ACTION_SUBSCRIBE,
|
||||
TEST_ACTION_EMIT_SIGNAL,
|
||||
TEST_ACTION_OWN_NAME,
|
||||
} TestAction;
|
||||
|
||||
typedef struct
|
||||
@ -122,6 +136,7 @@ typedef struct
|
||||
union {
|
||||
TestEmitSignal signal;
|
||||
TestSubscribe subscribe;
|
||||
TestOwnName own_name;
|
||||
} u;
|
||||
} TestStep;
|
||||
|
||||
@ -247,7 +262,7 @@ static const TestPlan plan_match_twice =
|
||||
{
|
||||
.action = TEST_ACTION_SUBSCRIBE,
|
||||
.u.subscribe = {
|
||||
.sender = TEST_CONN_SERVICE,
|
||||
.unique_sender = TEST_CONN_SERVICE,
|
||||
.path = EXAMPLE_PATH,
|
||||
.iface = EXAMPLE_INTERFACE,
|
||||
},
|
||||
@ -267,7 +282,7 @@ static const TestPlan plan_match_twice =
|
||||
{
|
||||
.action = TEST_ACTION_SUBSCRIBE,
|
||||
.u.subscribe = {
|
||||
.sender = TEST_CONN_SERVICE,
|
||||
.unique_sender = TEST_CONN_SERVICE,
|
||||
.path = EXAMPLE_PATH,
|
||||
.iface = EXAMPLE_INTERFACE,
|
||||
},
|
||||
@ -296,7 +311,7 @@ static const TestPlan plan_limit_by_unique_name =
|
||||
/* Subscriber wants to receive signals from service */
|
||||
.action = TEST_ACTION_SUBSCRIBE,
|
||||
.u.subscribe = {
|
||||
.sender = TEST_CONN_SERVICE,
|
||||
.unique_sender = TEST_CONN_SERVICE,
|
||||
.path = EXAMPLE_PATH,
|
||||
.iface = EXAMPLE_INTERFACE,
|
||||
},
|
||||
@ -343,6 +358,62 @@ static const TestPlan plan_limit_by_unique_name =
|
||||
},
|
||||
};
|
||||
|
||||
static const TestPlan plan_limit_by_well_known_name =
|
||||
{
|
||||
.description = "A subscription via a well-known name only accepts messages "
|
||||
"sent by the owner of that well-known name",
|
||||
.steps = {
|
||||
{
|
||||
/* Service already owns one name */
|
||||
.action = TEST_ACTION_OWN_NAME,
|
||||
.u.own_name = {
|
||||
.name = ALREADY_OWNED_NAME,
|
||||
.owner = TEST_CONN_SERVICE
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Subscriber wants to receive signals from service */
|
||||
.action = TEST_ACTION_SUBSCRIBE,
|
||||
.u.subscribe = {
|
||||
.string_sender = ALREADY_OWNED_NAME,
|
||||
.path = EXAMPLE_PATH,
|
||||
.iface = EXAMPLE_INTERFACE,
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Subscriber wants to receive signals from service by another name */
|
||||
.action = TEST_ACTION_SUBSCRIBE,
|
||||
.u.subscribe = {
|
||||
.string_sender = OWNED_LATER_NAME,
|
||||
.path = EXAMPLE_PATH,
|
||||
.iface = EXAMPLE_INTERFACE,
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Service claims another name */
|
||||
.action = TEST_ACTION_OWN_NAME,
|
||||
.u.own_name = {
|
||||
.name = OWNED_LATER_NAME,
|
||||
.owner = TEST_CONN_SERVICE
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Now the subscriber gets this signal twice, once for each
|
||||
* subscription; and similarly each of the two proxies gets this
|
||||
* signal twice */
|
||||
.action = TEST_ACTION_EMIT_SIGNAL,
|
||||
.u.signal = {
|
||||
.sender = TEST_CONN_SERVICE,
|
||||
.path = EXAMPLE_PATH,
|
||||
.iface = EXAMPLE_INTERFACE,
|
||||
.member = FOO_SIGNAL,
|
||||
.received_by_conn = 2,
|
||||
.received_by_proxy = 2
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const TestPlan *plan;
|
||||
@ -540,11 +611,16 @@ fixture_subscribe (Fixture *f,
|
||||
GDBusConnection *subscriber = f->conns[TEST_CONN_SUBSCRIBER];
|
||||
const char *sender;
|
||||
|
||||
if (subscribe->sender != TEST_CONN_NONE)
|
||||
if (subscribe->string_sender != NULL)
|
||||
{
|
||||
sender = f->unique_names[subscribe->sender];
|
||||
sender = subscribe->string_sender;
|
||||
g_test_message ("\tSender: %s", sender);
|
||||
}
|
||||
else if (subscribe->unique_sender != TEST_CONN_NONE)
|
||||
{
|
||||
sender = f->unique_names[subscribe->unique_sender];
|
||||
g_test_message ("\tSender: %s %s",
|
||||
test_conn_descriptions[subscribe->sender],
|
||||
test_conn_descriptions[subscribe->unique_sender],
|
||||
sender);
|
||||
}
|
||||
else
|
||||
@ -689,6 +765,43 @@ fixture_emit_signal (Fixture *f,
|
||||
connection_wait_for_bus (f->conns[signal->sender]);
|
||||
}
|
||||
|
||||
static void
|
||||
fixture_own_name (Fixture *f,
|
||||
const TestOwnName *own_name)
|
||||
{
|
||||
GVariant *call_result;
|
||||
guint32 flags;
|
||||
guint32 result_code;
|
||||
|
||||
g_test_message ("\tName: %s", own_name->name);
|
||||
g_test_message ("\tOwner: %s",
|
||||
test_conn_descriptions[own_name->owner]);
|
||||
|
||||
/* For simplicity, we do this via a direct bus call rather than
|
||||
* using g_bus_own_name_on_connection(). The flags in
|
||||
* GBusNameOwnerFlags are numerically equal to those in the
|
||||
* D-Bus wire protocol. */
|
||||
flags = G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE;
|
||||
call_result = g_dbus_connection_call_sync (f->conns[own_name->owner],
|
||||
DBUS_SERVICE_DBUS,
|
||||
DBUS_PATH_DBUS,
|
||||
DBUS_INTERFACE_DBUS,
|
||||
"RequestName",
|
||||
g_variant_new ("(su)",
|
||||
own_name->name,
|
||||
flags),
|
||||
G_VARIANT_TYPE ("(u)"),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
NULL,
|
||||
&f->error);
|
||||
g_assert_no_error (f->error);
|
||||
g_assert_nonnull (call_result);
|
||||
g_variant_get (call_result, "(u)", &result_code);
|
||||
g_assert_cmpuint (result_code, ==, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
|
||||
g_variant_unref (call_result);
|
||||
}
|
||||
|
||||
static void
|
||||
fixture_run_plan (Fixture *f,
|
||||
const TestPlan *plan,
|
||||
@ -721,6 +834,11 @@ fixture_run_plan (Fixture *f,
|
||||
fixture_emit_signal (f, &step->u.signal, i);
|
||||
break;
|
||||
|
||||
case TEST_ACTION_OWN_NAME:
|
||||
g_test_message ("Step %u: claiming bus name", i);
|
||||
fixture_own_name (f, &step->u.own_name);
|
||||
break;
|
||||
|
||||
case TEST_ACTION_NONE:
|
||||
/* Padding to fill the rest of the array, do nothing */
|
||||
break;
|
||||
@ -933,6 +1051,7 @@ main (int argc,
|
||||
ADD_SUBSCRIBE_TEST (broadcast_from_anyone);
|
||||
ADD_SUBSCRIBE_TEST (match_twice);
|
||||
ADD_SUBSCRIBE_TEST (limit_by_unique_name);
|
||||
ADD_SUBSCRIBE_TEST (limit_by_well_known_name);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user