X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Ftests%2Fgdbus-peer.c;h=6c6f3b06bf8de8e5234243fbc25b32c678e512d1;hb=2a53b4d0e2c98a14aedf31e38f0ad1fb2e8fe26f;hp=e400d3b51af2526dc12e832688be3d09c59b85c3;hpb=41ce91d0579aa05b89e357c9fd59d9530ad7bf76;p=platform%2Fupstream%2Fglib.git
diff --git a/gio/tests/gdbus-peer.c b/gio/tests/gdbus-peer.c
index e400d3b..6c6f3b0 100644
--- a/gio/tests/gdbus-peer.c
+++ b/gio/tests/gdbus-peer.c
@@ -13,13 +13,13 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Public License along with this library; if not, see .
*
* Author: David Zeuthen
*/
+#include "config.h"
+
#include
#include
#include
@@ -28,28 +28,35 @@
#include
#include
#include
+#include
/* for g_unlink() */
#include
-#include
+#include
#include
#include
+#include
-/* used in test_overflow */
#ifdef G_OS_UNIX
#include
+#include
#endif
#include "gdbus-tests.h"
+#include "gdbus-object-manager-example/gdbus-example-objectmanager-generated.h"
+
#ifdef G_OS_UNIX
static gboolean is_unix = TRUE;
#else
static gboolean is_unix = FALSE;
#endif
+static gchar *tmp_address = NULL;
static gchar *test_guid = NULL;
+static GMutex service_loop_lock;
+static GCond service_loop_cond;
static GMainLoop *service_loop = NULL;
static GDBusServer *server = NULL;
static GMainLoop *loop = NULL;
@@ -99,12 +106,16 @@ test_interface_method_call (GDBusConnection *connection,
gpointer user_data)
{
PeerData *data = user_data;
+ const GDBusMethodInfo *info;
data->num_method_calls++;
g_assert_cmpstr (object_path, ==, "/org/gtk/GDBus/PeerTestObject");
g_assert_cmpstr (interface_name, ==, "org.gtk.GDBus.PeerTestInterface");
+ info = g_dbus_method_invocation_get_method_info (invocation);
+ g_assert_cmpstr (info->name, ==, method_name);
+
if (g_strcmp0 (method_name, "HelloPeer") == 0)
{
const gchar *greeting;
@@ -167,13 +178,15 @@ test_interface_method_call (GDBusConnection *connection,
error = NULL;
- fd = open (path, O_RDONLY);
+ fd = g_open (path, O_RDONLY, 0);
+ g_assert (fd != -1);
g_unix_fd_list_append (fd_list, fd, &error);
g_assert_no_error (error);
close (fd);
reply = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation));
g_dbus_message_set_unix_fd_list (reply, fd_list);
+ g_object_unref (fd_list);
g_object_unref (invocation);
error = NULL;
@@ -276,7 +289,7 @@ on_authorize_authenticated_peer (GDBusAuthObserver *observer,
}
/* Runs in thread we created GDBusServer in (since we didn't pass G_DBUS_SERVER_FLAGS_RUN_IN_THREAD) */
-static void
+static gboolean
on_new_connection (GDBusServer *server,
GDBusConnection *connection,
gpointer user_data)
@@ -291,6 +304,20 @@ on_new_connection (GDBusServer *server,
g_ptr_array_add (data->current_connections, g_object_ref (connection));
+#if G_CREDENTIALS_SUPPORTED
+ {
+ GCredentials *credentials;
+
+ credentials = g_dbus_connection_get_peer_credentials (connection);
+
+ g_assert (credentials != NULL);
+ g_assert_cmpuint (g_credentials_get_unix_user (credentials, NULL), ==,
+ getuid ());
+ g_assert_cmpuint (g_credentials_get_unix_pid (credentials, NULL), ==,
+ getpid ());
+ }
+#endif
+
/* export object on the newly established connection */
error = NULL;
reg_id = g_dbus_connection_register_object (connection,
@@ -304,6 +331,35 @@ on_new_connection (GDBusServer *server,
g_assert (reg_id > 0);
g_main_loop_quit (loop);
+
+ return TRUE;
+}
+
+static void
+create_service_loop (GMainContext *service_context)
+{
+ g_assert (service_loop == NULL);
+ g_mutex_lock (&service_loop_lock);
+ service_loop = g_main_loop_new (service_context, FALSE);
+ g_cond_broadcast (&service_loop_cond);
+ g_mutex_unlock (&service_loop_lock);
+}
+
+static void
+teardown_service_loop (void)
+{
+ g_mutex_lock (&service_loop_lock);
+ g_clear_pointer (&service_loop, g_main_loop_unref);
+ g_mutex_unlock (&service_loop_lock);
+}
+
+static void
+await_service_loop (void)
+{
+ g_mutex_lock (&service_loop_lock);
+ while (service_loop == NULL)
+ g_cond_wait (&service_loop_cond, &service_loop_lock);
+ g_mutex_unlock (&service_loop_lock);
}
static gpointer
@@ -311,15 +367,18 @@ service_thread_func (gpointer user_data)
{
PeerData *data = user_data;
GMainContext *service_context;
- GDBusAuthObserver *observer;
+ GDBusAuthObserver *observer, *o;
GError *error;
+ GDBusServerFlags f;
+ gchar *a, *g;
+ gboolean b;
service_context = g_main_context_new ();
g_main_context_push_thread_default (service_context);
error = NULL;
observer = g_dbus_auth_observer_new ();
- server = g_dbus_server_new_sync (is_unix ? "unix:tmpdir=/tmp/gdbus-test-" : "nonce-tcp:",
+ server = g_dbus_server_new_sync (tmp_address,
G_DBUS_SERVER_FLAGS_NONE,
test_guid,
observer,
@@ -335,16 +394,35 @@ service_thread_func (gpointer user_data)
"authorize-authenticated-peer",
G_CALLBACK (on_authorize_authenticated_peer),
data);
+
+ g_assert_cmpint (g_dbus_server_get_flags (server), ==, G_DBUS_SERVER_FLAGS_NONE);
+ g_assert_cmpstr (g_dbus_server_get_guid (server), ==, test_guid);
+ g_object_get (server,
+ "flags", &f,
+ "address", &a,
+ "guid", &g,
+ "active", &b,
+ "authentication-observer", &o,
+ NULL);
+ g_assert_cmpint (f, ==, G_DBUS_SERVER_FLAGS_NONE);
+ g_assert_cmpstr (a, ==, tmp_address);
+ g_assert_cmpstr (g, ==, test_guid);
+ g_assert (!b);
+ g_assert (o == observer);
+ g_free (a);
+ g_free (g);
+ g_object_unref (o);
+
g_object_unref (observer);
g_dbus_server_start (server);
- service_loop = g_main_loop_new (service_context, FALSE);
+ create_service_loop (service_context);
g_main_loop_run (service_loop);
g_main_context_pop_thread_default (service_context);
- g_main_loop_unref (service_loop);
+ teardown_service_loop ();
g_main_context_unref (service_context);
/* test code specifically unrefs the server - see below */
@@ -434,12 +512,12 @@ service_thread_func (gpointer data)
data);
g_socket_service_start (service);
- service_loop = g_main_loop_new (service_context, FALSE);
+ create_service_loop (service_context);
g_main_loop_run (service_loop);
g_main_context_pop_thread_default (service_context);
- g_main_loop_unref (service_loop);
+ teardown_service_loop ();
g_main_context_unref (service_context);
g_object_unref (address);
@@ -507,6 +585,55 @@ on_do_disconnect_in_idle (gpointer data)
}
#endif
+#ifdef G_OS_UNIX
+static gchar *
+read_all_from_fd (gint fd, gsize *out_len, GError **error)
+{
+ GString *str;
+ gchar buf[64];
+ gssize num_read;
+
+ str = g_string_new (NULL);
+
+ do
+ {
+ num_read = read (fd, buf, sizeof (buf));
+ if (num_read == -1)
+ {
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
+ continue;
+ g_set_error (error,
+ G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ "Failed reading %d bytes into offset %d: %s",
+ (gint) sizeof (buf),
+ (gint) str->len,
+ strerror (errno));
+ goto error;
+ }
+ else if (num_read > 0)
+ {
+ g_string_append_len (str, buf, num_read);
+ }
+ else if (num_read == 0)
+ {
+ break;
+ }
+ }
+ while (TRUE);
+
+ if (out_len != NULL)
+ *out_len = str->len;
+ return g_string_free (str, FALSE);
+
+ error:
+ if (out_len != NULL)
+ out_len = 0;
+ g_string_free (str, TRUE);
+ return NULL;
+}
+#endif
+
static void
test_peer (void)
{
@@ -540,13 +667,10 @@ test_peer (void)
g_assert (c == NULL);
/* bring up a server - we run the server in a different thread to avoid deadlocks */
- error = NULL;
- service_thread = g_thread_create (service_thread_func,
- &data,
- TRUE,
- &error);
- while (service_loop == NULL)
- g_thread_yield ();
+ service_thread = g_thread_new ("test_peer",
+ service_thread_func,
+ &data);
+ await_service_loop ();
g_assert (server != NULL);
/* bring up a connection and accept it */
@@ -650,16 +774,17 @@ test_peer (void)
GDBusMessage *method_reply_message;
GUnixFDList *fd_list;
gint fd;
- gchar buf[1024];
- gssize len;
+ gchar *buf;
+ gsize len;
gchar *buf2;
gsize len2;
+ const char *testfile = g_test_get_filename (G_TEST_DIST, "file.c", NULL);
method_call_message = g_dbus_message_new_method_call (NULL, /* name */
"/org/gtk/GDBus/PeerTestObject",
"org.gtk.GDBus.PeerTestInterface",
"OpenFile");
- g_dbus_message_set_body (method_call_message, g_variant_new ("(s)", "/etc/hosts"));
+ g_dbus_message_set_body (method_call_message, g_variant_new ("(s)", testfile));
error = NULL;
method_reply_message = g_dbus_connection_send_message_with_reply_sync (c,
method_call_message,
@@ -679,20 +804,23 @@ test_peer (void)
g_object_unref (method_call_message);
g_object_unref (method_reply_message);
- memset (buf, '\0', sizeof (buf));
- len = read (fd, buf, sizeof (buf) - 1);
+ error = NULL;
+ len = 0;
+ buf = read_all_from_fd (fd, &len, &error);
+ g_assert_no_error (error);
+ g_assert (buf != NULL);
close (fd);
error = NULL;
- g_file_get_contents ("/etc/hosts",
+ g_file_get_contents (testfile,
&buf2,
&len2,
&error);
g_assert_no_error (error);
- if (len2 > sizeof (buf))
- buf2[sizeof (buf)] = '\0';
- g_assert_cmpstr (buf, ==, buf2);
+ g_assert_cmpint (len, ==, len2);
+ g_assert (memcmp (buf, buf2, len) == 0);
g_free (buf2);
+ g_free (buf);
}
#else
error = NULL;
@@ -708,9 +836,8 @@ test_peer (void)
g_error_free (error);
#endif /* G_OS_UNIX */
- /* Check that g_socket_get_credentials() work - this really should
- * be in a GSocket-specific test suite but no such test suite exists
- * right now.
+ /* Check that g_socket_get_credentials() work - (though this really
+ * should be in socket.c)
*/
{
GSocket *socket;
@@ -719,18 +846,15 @@ test_peer (void)
g_assert (G_IS_SOCKET (socket));
error = NULL;
credentials = g_socket_get_credentials (socket, &error);
-#ifdef __linux__
- {
- struct ucred *native_creds;
- g_assert_no_error (error);
- g_assert (G_IS_CREDENTIALS (credentials));
- native_creds = g_credentials_get_native (credentials, G_CREDENTIALS_TYPE_LINUX_UCRED);
- g_assert (native_creds != NULL);
- g_assert (native_creds->uid == getuid ());
- g_assert (native_creds->gid == getgid ());
- g_assert (native_creds->pid == getpid ());
- }
- g_object_unref (credentials);
+
+#if G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED
+ g_assert_no_error (error);
+ g_assert (G_IS_CREDENTIALS (credentials));
+
+ g_assert_cmpuint (g_credentials_get_unix_user (credentials, NULL), ==,
+ getuid ());
+ g_assert_cmpuint (g_credentials_get_unix_pid (credentials, NULL), ==,
+ getpid ());
#else
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
g_assert (credentials == NULL);
@@ -748,6 +872,7 @@ test_peer (void)
NULL, /* cancellable */
&error);
_g_assert_error_domain (error, G_IO_ERROR);
+ g_error_free (error);
g_assert (c2 == NULL);
#if 0
@@ -848,8 +973,7 @@ dmp_data_free (DmpData *data)
g_main_loop_unref (data->loop);
g_main_context_unref (data->context);
g_object_unref (data->server);
- g_list_foreach (data->connections, (GFunc) g_object_unref, NULL);
- g_list_free (data->connections);
+ g_list_free_full (data->connections, g_object_unref);
g_free (data);
}
@@ -883,7 +1007,7 @@ static const GDBusInterfaceVTable dmp_interface_vtable =
/* Runs in thread we created GDBusServer in (since we didn't pass G_DBUS_SERVER_FLAGS_RUN_IN_THREAD) */
-static void
+static gboolean
dmp_on_new_connection (GDBusServer *server,
GDBusConnection *connection,
gpointer user_data)
@@ -924,6 +1048,8 @@ dmp_on_new_connection (GDBusServer *server,
NULL,
&error);
g_dbus_node_info_unref (node);
+
+ return TRUE;
}
static gpointer
@@ -938,7 +1064,7 @@ dmp_thread_func (gpointer user_data)
error = NULL;
guid = g_dbus_generate_guid ();
- data->server = g_dbus_server_new_sync ("unix:tmpdir=/tmp/gdbus-test-",
+ data->server = g_dbus_server_new_sync (tmp_address,
G_DBUS_SERVER_FLAGS_NONE,
guid,
NULL, /* GDBusAuthObserver */
@@ -971,11 +1097,9 @@ delayed_message_processing (void)
data = g_new0 (DmpData, 1);
- error = NULL;
- service_thread = g_thread_create (dmp_thread_func,
- data,
- TRUE,
- &error);
+ service_thread = g_thread_new ("dmp",
+ dmp_thread_func,
+ data);
while (data->server == NULL || !g_dbus_server_is_active (data->server))
g_thread_yield ();
@@ -1041,7 +1165,7 @@ nonce_tcp_on_authorize_authenticated_peer (GDBusAuthObserver *observer,
}
/* Runs in thread we created GDBusServer in (since we didn't pass G_DBUS_SERVER_FLAGS_RUN_IN_THREAD) */
-static void
+static gboolean
nonce_tcp_on_new_connection (GDBusServer *server,
GDBusConnection *connection,
gpointer user_data)
@@ -1051,6 +1175,8 @@ nonce_tcp_on_new_connection (GDBusServer *server,
g_ptr_array_add (data->current_connections, g_object_ref (connection));
g_main_loop_quit (loop);
+
+ return TRUE;
}
static gpointer
@@ -1086,12 +1212,12 @@ nonce_tcp_service_thread_func (gpointer user_data)
g_dbus_server_start (server);
- service_loop = g_main_loop_new (service_context, FALSE);
+ create_service_loop (service_context);
g_main_loop_run (service_loop);
g_main_context_pop_thread_default (service_context);
- g_main_loop_unref (service_loop);
+ teardown_service_loop ();
g_main_context_unref (service_context);
/* test code specifically unrefs the server - see below */
@@ -1117,16 +1243,12 @@ test_nonce_tcp (void)
error = NULL;
server = NULL;
- service_loop = NULL;
- service_thread = g_thread_create (nonce_tcp_service_thread_func,
- &data,
- TRUE,
- &error);
- while (service_loop == NULL)
- g_thread_yield ();
+ service_thread = g_thread_new ("nonce-tcp-service",
+ nonce_tcp_service_thread_func,
+ &data);
+ await_service_loop ();
g_assert (server != NULL);
-
/* bring up a connection and accept it */
data.accept_connection = TRUE;
error = NULL;
@@ -1138,7 +1260,7 @@ test_nonce_tcp (void)
g_assert_no_error (error);
g_assert (c != NULL);
while (data.current_connections->len < 1)
- g_main_loop_run (loop);
+ g_thread_yield ();
g_assert_cmpint (data.current_connections->len, ==, 1);
g_assert_cmpint (data.num_connection_attempts, ==, 1);
g_assert (g_dbus_connection_get_unique_name (c) == NULL);
@@ -1174,6 +1296,7 @@ test_nonce_tcp (void)
NULL, /* cancellable */
&error);
_g_assert_error_domain (error, G_IO_ERROR);
+ g_error_free (error);
g_assert (c == NULL);
/* Then try with a nonce-file of incorrect length - this will make
@@ -1193,6 +1316,7 @@ test_nonce_tcp (void)
NULL, /* cancellable */
&error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
+ g_error_free (error);
g_assert (c == NULL);
/* Finally try with no nonce-file at all */
@@ -1204,6 +1328,7 @@ test_nonce_tcp (void)
NULL, /* cancellable */
&error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
+ g_error_free (error);
g_assert (c == NULL);
g_free (nonce_file);
@@ -1244,138 +1369,344 @@ test_credentials (void)
/* ---------------------------------------------------------------------------------------------------- */
-#ifdef G_OS_UNIX
-
-/* Chosen to be big enough to overflow the socket buffer */
-#define OVERFLOW_NUM_SIGNALS 5000
-#define OVERFLOW_TIMEOUT_SEC 10
-
static gboolean
-overflow_filter_func (GDBusConnection *connection,
- GDBusMessage *message,
- gboolean incoming,
- gpointer user_data)
+tcp_anonymous_on_new_connection (GDBusServer *server,
+ GDBusConnection *connection,
+ gpointer user_data)
{
- volatile gint *counter = user_data;
- *counter += 1;
- return FALSE; /* don't drop the message */
+ gboolean *seen_connection = user_data;
+ *seen_connection = TRUE;
+ return TRUE;
}
-static gboolean
-overflow_on_500ms_later_func (gpointer user_data)
+static gpointer
+tcp_anonymous_service_thread_func (gpointer user_data)
{
- g_main_loop_quit (loop);
- return FALSE; /* don't keep the idle */
+ gboolean *seen_connection = user_data;
+ GMainContext *service_context;
+ GError *error;
+
+ service_context = g_main_context_new ();
+ g_main_context_push_thread_default (service_context);
+
+ error = NULL;
+ server = g_dbus_server_new_sync ("tcp:",
+ G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS,
+ test_guid,
+ NULL, /* GDBusObserver* */
+ NULL, /* GCancellable* */
+ &error);
+ g_assert_no_error (error);
+
+ g_signal_connect (server,
+ "new-connection",
+ G_CALLBACK (tcp_anonymous_on_new_connection),
+ seen_connection);
+
+ g_dbus_server_start (server);
+
+ create_service_loop (service_context);
+ g_main_loop_run (service_loop);
+
+ g_main_context_pop_thread_default (service_context);
+
+ teardown_service_loop ();
+ g_main_context_unref (service_context);
+
+ return NULL;
}
static void
-test_overflow (void)
+test_tcp_anonymous (void)
{
- gint sv[2];
- gint n;
- GSocket *socket;
- GSocketConnection *socket_connection;
- GDBusConnection *producer, *consumer;
+ gboolean seen_connection;
+ GThread *service_thread;
+ GDBusConnection *connection;
GError *error;
- GTimer *timer;
- volatile gint n_messages_received;
- volatile gint n_messages_sent;
- g_assert_cmpint (socketpair (AF_UNIX, SOCK_STREAM, 0, sv), ==, 0);
+ seen_connection = FALSE;
+ service_thread = g_thread_new ("tcp-anon-service",
+ tcp_anonymous_service_thread_func,
+ &seen_connection);
+ await_service_loop ();
+ g_assert (server != NULL);
error = NULL;
- socket = g_socket_new_from_fd (sv[0], &error);
+ connection = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (server),
+ G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
+ NULL, /* GDBusAuthObserver* */
+ NULL, /* GCancellable */
+ &error);
g_assert_no_error (error);
- socket_connection = g_socket_connection_factory_create_connection (socket);
- g_assert (socket_connection != NULL);
- g_object_unref (socket);
- producer = g_dbus_connection_new_sync (G_IO_STREAM (socket_connection),
- NULL, /* guid */
- G_DBUS_CONNECTION_FLAGS_NONE,
- NULL, /* GDBusAuthObserver */
- NULL, /* GCancellable */
- &error);
- g_dbus_connection_set_exit_on_close (producer, TRUE);
- g_assert_no_error (error);
- g_object_unref (socket_connection);
- n_messages_sent = 0;
- g_dbus_connection_add_filter (producer, overflow_filter_func, (gpointer) &n_messages_sent, NULL);
+ g_assert (connection != NULL);
+
+ while (!seen_connection)
+ g_thread_yield ();
+
+ g_object_unref (connection);
+
+ g_main_loop_quit (service_loop);
+ g_dbus_server_stop (server);
+ g_object_unref (server);
+ server = NULL;
+
+ g_thread_join (service_thread);
+}
- /* send enough data that we get an EAGAIN */
- for (n = 0; n < OVERFLOW_NUM_SIGNALS; n++)
+/* ---------------------------------------------------------------------------------------------------- */
+
+static GDBusServer *codegen_server = NULL;
+
+static gboolean
+codegen_on_animal_poke (ExampleAnimal *animal,
+ GDBusMethodInvocation *invocation,
+ gboolean make_sad,
+ gboolean make_happy,
+ gpointer user_data)
+{
+ if ((make_sad && make_happy) || (!make_sad && !make_happy))
{
- error = NULL;
- g_dbus_connection_emit_signal (producer,
- NULL, /* destination */
- "/org/foo/Object",
- "org.foo.Interface",
- "Member",
- g_variant_new ("(s)", "a string"),
- &error);
- g_assert_no_error (error);
+ g_main_loop_quit (service_loop);
+
+ g_dbus_method_invocation_return_dbus_error (invocation,
+ "org.gtk.GDBus.Examples.ObjectManager.Error.Failed",
+ "Exactly one of make_sad or make_happy must be TRUE");
+ goto out;
}
- /* sleep for 0.5 sec (to allow the GDBus IO thread to fill up the
- * kernel buffers) and verify that n_messages_sent <
- * OVERFLOW_NUM_SIGNALS
- *
- * This is to verify that not all the submitted messages have been
- * sent to the underlying transport.
- */
- g_timeout_add (500, overflow_on_500ms_later_func, NULL);
- g_main_loop_run (loop);
- g_assert_cmpint (n_messages_sent, <, OVERFLOW_NUM_SIGNALS);
+ if (make_sad)
+ {
+ if (g_strcmp0 (example_animal_get_mood (animal), "Sad") == 0)
+ {
+ g_dbus_method_invocation_return_dbus_error (invocation,
+ "org.gtk.GDBus.Examples.ObjectManager.Error.SadAnimalIsSad",
+ "Sad animal is already sad");
+ goto out;
+ }
+
+ example_animal_set_mood (animal, "Sad");
+ example_animal_complete_poke (animal, invocation);
+ goto out;
+ }
+
+ if (make_happy)
+ {
+ if (g_strcmp0 (example_animal_get_mood (animal), "Happy") == 0)
+ {
+ g_dbus_method_invocation_return_dbus_error (invocation,
+ "org.gtk.GDBus.Examples.ObjectManager.Error.HappyAnimalIsHappy",
+ "Happy animal is already happy");
+ goto out;
+ }
+
+ example_animal_set_mood (animal, "Happy");
+ example_animal_complete_poke (animal, invocation);
+ goto out;
+ }
+
+ g_assert_not_reached ();
+
+ out:
+ return TRUE; /* to indicate that the method was handled */
+}
+
+/* Runs in thread we created GDBusServer in (since we didn't pass G_DBUS_SERVER_FLAGS_RUN_IN_THREAD) */
+static gboolean
+codegen_on_new_connection (GDBusServer *server,
+ GDBusConnection *connection,
+ gpointer user_data)
+{
+ ExampleAnimal *animal = user_data;
+ GError *error = NULL;
+
+ /* g_print ("Client connected.\n" */
+ /* "Negotiated capabilities: unix-fd-passing=%d\n", */
+ /* g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING); */
- /* now suck it all out as a client, and add it up */
- socket = g_socket_new_from_fd (sv[1], &error);
+ g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (animal), connection,
+ "/Example/Animals/000", &error);
g_assert_no_error (error);
- socket_connection = g_socket_connection_factory_create_connection (socket);
- g_assert (socket_connection != NULL);
- g_object_unref (socket);
- consumer = g_dbus_connection_new_sync (G_IO_STREAM (socket_connection),
- NULL, /* guid */
- G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING,
- NULL, /* GDBusAuthObserver */
- NULL, /* GCancellable */
- &error);
+
+ return TRUE;
+}
+
+static gpointer
+codegen_service_thread_func (gpointer user_data)
+{
+ GMainContext *service_context;
+ ExampleAnimal *animal;
+ GError *error = NULL;
+
+ service_context = g_main_context_new ();
+ g_main_context_push_thread_default (service_context);
+
+ /* Create the animal in the right thread context */
+ animal = example_animal_skeleton_new ();
+
+ /* Handle Poke() D-Bus method invocations on the .Animal interface */
+ g_signal_connect (animal, "handle-poke",
+ G_CALLBACK (codegen_on_animal_poke),
+ NULL); /* user_data */
+
+ codegen_server = g_dbus_server_new_sync (tmp_address,
+ G_DBUS_SERVER_FLAGS_NONE,
+ test_guid,
+ NULL, /* observer */
+ NULL, /* cancellable */
+ &error);
g_assert_no_error (error);
- g_object_unref (socket_connection);
- n_messages_received = 0;
- g_dbus_connection_add_filter (consumer, overflow_filter_func, (gpointer) &n_messages_received, NULL);
- g_dbus_connection_start_message_processing (consumer);
+ g_dbus_server_start (codegen_server);
- timer = g_timer_new ();
- g_timer_start (timer);
+ g_signal_connect (codegen_server, "new-connection",
+ G_CALLBACK (codegen_on_new_connection),
+ animal);
+
+ create_service_loop (service_context);
+ g_main_loop_run (service_loop);
+
+ g_object_unref (animal);
+
+ g_main_context_pop_thread_default (service_context);
- while (n_messages_received < OVERFLOW_NUM_SIGNALS && g_timer_elapsed (timer, NULL) < OVERFLOW_TIMEOUT_SEC)
- g_main_context_iteration (NULL, FALSE);
+ teardown_service_loop ();
+ g_main_context_unref (service_context);
- g_assert_cmpint (n_messages_sent, ==, OVERFLOW_NUM_SIGNALS);
- g_assert_cmpint (n_messages_received, ==, OVERFLOW_NUM_SIGNALS);
+ g_dbus_server_stop (codegen_server);
+ g_object_unref (codegen_server);
+ codegen_server = NULL;
- g_timer_destroy (timer);
- g_object_unref (consumer);
- g_object_unref (producer);
+ return NULL;
}
-#else
+
+
+static gboolean
+codegen_quit_mainloop_timeout (gpointer data)
+{
+ g_main_loop_quit (loop);
+ return FALSE;
+}
+
static void
-test_overflow (void)
+codegen_test_peer (void)
{
- /* TODO: test this with e.g. GWin32InputStream/GWin32OutputStream */
+ GDBusConnection *connection;
+ ExampleAnimal *animal1, *animal2;
+ GThread *service_thread;
+ GError *error = NULL;
+ GVariant *value;
+ const gchar *s;
+
+ /* bring up a server - we run the server in a different thread to avoid deadlocks */
+ service_thread = g_thread_new ("codegen_test_peer",
+ codegen_service_thread_func,
+ NULL);
+ await_service_loop ();
+ g_assert (codegen_server != NULL);
+
+ /* Get an animal 1 ... */
+ connection = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (codegen_server),
+ G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
+ NULL, /* GDBusAuthObserver */
+ NULL, /* cancellable */
+ &error);
+ g_assert_no_error (error);
+ g_assert (connection != NULL);
+
+ animal1 = example_animal_proxy_new_sync (connection, 0, NULL,
+ "/Example/Animals/000", NULL, &error);
+ g_assert_no_error (error);
+ g_assert (animal1 != NULL);
+ g_object_unref (connection);
+
+ /* Get animal 2 ... */
+ connection = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (codegen_server),
+ G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
+ NULL, /* GDBusAuthObserver */
+ NULL, /* cancellable */
+ &error);
+ g_assert_no_error (error);
+ g_assert (connection != NULL);
+
+ animal2 = example_animal_proxy_new_sync (connection, 0, NULL,
+ "/Example/Animals/000", NULL, &error);
+ g_assert_no_error (error);
+ g_assert (animal2 != NULL);
+ g_object_unref (connection);
+
+ /* Make animal sad via animal1 */
+ example_animal_call_poke_sync (animal1, TRUE, FALSE, NULL, &error);
+ g_assert_no_error (error);
+
+ /* Poke server and make sure animal is updated */
+ value = g_dbus_proxy_call_sync (G_DBUS_PROXY (animal1),
+ "org.freedesktop.DBus.Peer.Ping",
+ NULL, G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &error);
+ g_assert_no_error (error);
+ g_assert (value != NULL);
+ g_variant_unref (value);
+
+ /* Give the proxies a chance to refresh in the defaul main loop */
+ g_timeout_add (100, codegen_quit_mainloop_timeout, NULL);
+ g_main_loop_run (loop);
+
+ /* Assert animals are sad */
+ g_assert_cmpstr (example_animal_get_mood (animal1), ==, "Sad");
+ g_assert_cmpstr (example_animal_get_mood (animal2), ==, "Sad");
+
+ /* Make animal happy via animal2 */
+ example_animal_call_poke_sync (animal2, FALSE, TRUE, NULL, &error);
+ g_assert_no_error (error);
+
+ /* Some random unrelated call, just to get some test coverage */
+ value = g_dbus_proxy_call_sync (G_DBUS_PROXY (animal2),
+ "org.freedesktop.DBus.Peer.GetMachineId",
+ NULL, G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &error);
+ g_assert_no_error (error);
+ g_variant_get (value, "(&s)", &s);
+ g_assert (g_dbus_is_guid (s));
+ g_variant_unref (value);
+
+ /* Poke server and make sure animal is updated */
+ value = g_dbus_proxy_call_sync (G_DBUS_PROXY (animal2),
+ "org.freedesktop.DBus.Peer.Ping",
+ NULL, G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &error);
+ g_assert_no_error (error);
+ g_assert (value != NULL);
+ g_variant_unref (value);
+
+ /* Give the proxies a chance to refresh in the defaul main loop */
+ g_timeout_add (1000, codegen_quit_mainloop_timeout, NULL);
+ g_main_loop_run (loop);
+
+ /* Assert animals are happy */
+ g_assert_cmpstr (example_animal_get_mood (animal1), ==, "Happy");
+ g_assert_cmpstr (example_animal_get_mood (animal2), ==, "Happy");
+
+ /* This final call making the animal happy and sad will cause
+ * the server to quit, when the server quits we dont get property
+ * change notifications anyway because those are done from an idle handler
+ */
+ example_animal_call_poke_sync (animal2, TRUE, TRUE, NULL, &error);
+
+ g_object_unref (animal1);
+ g_object_unref (animal2);
+ g_thread_join (service_thread);
}
-#endif
/* ---------------------------------------------------------------------------------------------------- */
+
int
main (int argc,
char *argv[])
{
gint ret;
GDBusNodeInfo *introspection_data = NULL;
+ gchar *tmpdir = NULL;
- g_type_init ();
- g_thread_init (NULL);
g_test_init (&argc, &argv, NULL);
introspection_data = g_dbus_node_info_new_for_xml (test_interface_introspection_xml, NULL);
@@ -1384,20 +1715,42 @@ main (int argc,
test_guid = g_dbus_generate_guid ();
+ if (is_unix)
+ {
+ if (g_unix_socket_address_abstract_names_supported ())
+ tmp_address = g_strdup ("unix:tmpdir=/tmp/gdbus-test-");
+ else
+ {
+ tmpdir = g_dir_make_tmp ("gdbus-test-XXXXXX", NULL);
+ tmp_address = g_strdup_printf ("unix:tmpdir=%s", tmpdir);
+ }
+ }
+ else
+ tmp_address = g_strdup ("nonce-tcp:");
+
/* all the tests rely on a shared main loop */
loop = g_main_loop_new (NULL, FALSE);
g_test_add_func ("/gdbus/peer-to-peer", test_peer);
g_test_add_func ("/gdbus/delayed-message-processing", delayed_message_processing);
g_test_add_func ("/gdbus/nonce-tcp", test_nonce_tcp);
+
+ g_test_add_func ("/gdbus/tcp-anonymous", test_tcp_anonymous);
g_test_add_func ("/gdbus/credentials", test_credentials);
- g_test_add_func ("/gdbus/overflow", test_overflow);
+ g_test_add_func ("/gdbus/codegen-peer-to-peer", codegen_test_peer);
ret = g_test_run();
g_main_loop_unref (loop);
g_free (test_guid);
g_dbus_node_info_unref (introspection_data);
+ if (is_unix)
+ g_free (tmp_address);
+ if (tmpdir)
+ {
+ g_rmdir (tmpdir);
+ g_free (tmpdir);
+ }
return ret;
}