mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-23 18:52:09 +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
8881cb6d76
commit
1ae5e8c9cd
@ -7,6 +7,9 @@
|
|||||||
|
|
||||||
#include "gdbus-tests.h"
|
#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_SERVICE_DBUS "org.freedesktop.DBus"
|
||||||
#define DBUS_PATH_DBUS "/org/freedesktop/DBus"
|
#define DBUS_PATH_DBUS "/org/freedesktop/DBus"
|
||||||
#define DBUS_INTERFACE_DBUS DBUS_SERVICE_DBUS
|
#define DBUS_INTERFACE_DBUS DBUS_SERVICE_DBUS
|
||||||
@ -22,6 +25,9 @@
|
|||||||
#define EXAMPLE_INTERFACE "org.gtk.GDBus.ExampleInterface"
|
#define EXAMPLE_INTERFACE "org.gtk.GDBus.ExampleInterface"
|
||||||
#define FOO_SIGNAL "Foo"
|
#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. */
|
/* Log @s in a debug message. */
|
||||||
static inline const char *
|
static inline const char *
|
||||||
nonnull (const char *s,
|
nonnull (const char *s,
|
||||||
@ -101,7 +107,8 @@ typedef struct
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
TestConn sender;
|
const char *string_sender;
|
||||||
|
TestConn unique_sender;
|
||||||
const char *path;
|
const char *path;
|
||||||
const char *iface;
|
const char *iface;
|
||||||
const char *member;
|
const char *member;
|
||||||
@ -109,11 +116,18 @@ typedef struct
|
|||||||
GDBusSignalFlags flags;
|
GDBusSignalFlags flags;
|
||||||
} TestSubscribe;
|
} TestSubscribe;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
TestConn owner;
|
||||||
|
} TestOwnName;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
TEST_ACTION_NONE = 0,
|
TEST_ACTION_NONE = 0,
|
||||||
TEST_ACTION_SUBSCRIBE,
|
TEST_ACTION_SUBSCRIBE,
|
||||||
TEST_ACTION_EMIT_SIGNAL,
|
TEST_ACTION_EMIT_SIGNAL,
|
||||||
|
TEST_ACTION_OWN_NAME,
|
||||||
} TestAction;
|
} TestAction;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -122,6 +136,7 @@ typedef struct
|
|||||||
union {
|
union {
|
||||||
TestEmitSignal signal;
|
TestEmitSignal signal;
|
||||||
TestSubscribe subscribe;
|
TestSubscribe subscribe;
|
||||||
|
TestOwnName own_name;
|
||||||
} u;
|
} u;
|
||||||
} TestStep;
|
} TestStep;
|
||||||
|
|
||||||
@ -247,7 +262,7 @@ static const TestPlan plan_match_twice =
|
|||||||
{
|
{
|
||||||
.action = TEST_ACTION_SUBSCRIBE,
|
.action = TEST_ACTION_SUBSCRIBE,
|
||||||
.u.subscribe = {
|
.u.subscribe = {
|
||||||
.sender = TEST_CONN_SERVICE,
|
.unique_sender = TEST_CONN_SERVICE,
|
||||||
.path = EXAMPLE_PATH,
|
.path = EXAMPLE_PATH,
|
||||||
.iface = EXAMPLE_INTERFACE,
|
.iface = EXAMPLE_INTERFACE,
|
||||||
},
|
},
|
||||||
@ -267,7 +282,7 @@ static const TestPlan plan_match_twice =
|
|||||||
{
|
{
|
||||||
.action = TEST_ACTION_SUBSCRIBE,
|
.action = TEST_ACTION_SUBSCRIBE,
|
||||||
.u.subscribe = {
|
.u.subscribe = {
|
||||||
.sender = TEST_CONN_SERVICE,
|
.unique_sender = TEST_CONN_SERVICE,
|
||||||
.path = EXAMPLE_PATH,
|
.path = EXAMPLE_PATH,
|
||||||
.iface = EXAMPLE_INTERFACE,
|
.iface = EXAMPLE_INTERFACE,
|
||||||
},
|
},
|
||||||
@ -296,7 +311,7 @@ static const TestPlan plan_limit_by_unique_name =
|
|||||||
/* Subscriber wants to receive signals from service */
|
/* Subscriber wants to receive signals from service */
|
||||||
.action = TEST_ACTION_SUBSCRIBE,
|
.action = TEST_ACTION_SUBSCRIBE,
|
||||||
.u.subscribe = {
|
.u.subscribe = {
|
||||||
.sender = TEST_CONN_SERVICE,
|
.unique_sender = TEST_CONN_SERVICE,
|
||||||
.path = EXAMPLE_PATH,
|
.path = EXAMPLE_PATH,
|
||||||
.iface = EXAMPLE_INTERFACE,
|
.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
|
typedef struct
|
||||||
{
|
{
|
||||||
const TestPlan *plan;
|
const TestPlan *plan;
|
||||||
@ -540,11 +611,16 @@ fixture_subscribe (Fixture *f,
|
|||||||
GDBusConnection *subscriber = f->conns[TEST_CONN_SUBSCRIBER];
|
GDBusConnection *subscriber = f->conns[TEST_CONN_SUBSCRIBER];
|
||||||
const char *sender;
|
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",
|
g_test_message ("\tSender: %s %s",
|
||||||
test_conn_descriptions[subscribe->sender],
|
test_conn_descriptions[subscribe->unique_sender],
|
||||||
sender);
|
sender);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -689,6 +765,43 @@ fixture_emit_signal (Fixture *f,
|
|||||||
connection_wait_for_bus (f->conns[signal->sender]);
|
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
|
static void
|
||||||
fixture_run_plan (Fixture *f,
|
fixture_run_plan (Fixture *f,
|
||||||
const TestPlan *plan,
|
const TestPlan *plan,
|
||||||
@ -721,6 +834,11 @@ fixture_run_plan (Fixture *f,
|
|||||||
fixture_emit_signal (f, &step->u.signal, i);
|
fixture_emit_signal (f, &step->u.signal, i);
|
||||||
break;
|
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:
|
case TEST_ACTION_NONE:
|
||||||
/* Padding to fill the rest of the array, do nothing */
|
/* Padding to fill the rest of the array, do nothing */
|
||||||
break;
|
break;
|
||||||
@ -933,6 +1051,7 @@ main (int argc,
|
|||||||
ADD_SUBSCRIBE_TEST (broadcast_from_anyone);
|
ADD_SUBSCRIBE_TEST (broadcast_from_anyone);
|
||||||
ADD_SUBSCRIBE_TEST (match_twice);
|
ADD_SUBSCRIBE_TEST (match_twice);
|
||||||
ADD_SUBSCRIBE_TEST (limit_by_unique_name);
|
ADD_SUBSCRIBE_TEST (limit_by_unique_name);
|
||||||
|
ADD_SUBSCRIBE_TEST (limit_by_well_known_name);
|
||||||
|
|
||||||
return g_test_run();
|
return g_test_run();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user