2010-05-06 20:13:59 +02:00
|
|
|
/* GLib testing framework examples and tests
|
|
|
|
*
|
2010-05-10 14:07:28 +02:00
|
|
|
* Copyright (C) 2008-2010 Red Hat, Inc.
|
2010-05-06 20:13:59 +02:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
2017-05-27 17:19:21 +02:00
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
2010-05-06 20:13:59 +02:00
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General
|
2014-01-23 12:58:29 +01:00
|
|
|
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
2010-05-06 20:13:59 +02:00
|
|
|
*
|
|
|
|
* Author: David Zeuthen <davidz@redhat.com>
|
|
|
|
*/
|
|
|
|
|
2011-05-01 17:17:14 +02:00
|
|
|
#include "config.h"
|
|
|
|
|
2010-05-06 20:13:59 +02:00
|
|
|
#include <gio/gio.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
/* for open(2) */
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.h>
|
2010-08-27 16:50:03 +02:00
|
|
|
#include <string.h>
|
2010-05-06 20:13:59 +02:00
|
|
|
|
2010-07-16 19:19:48 +02:00
|
|
|
/* for g_unlink() */
|
|
|
|
#include <glib/gstdio.h>
|
|
|
|
|
2010-11-11 15:57:25 +01:00
|
|
|
#include <gio/gnetworking.h>
|
2010-05-06 20:13:59 +02:00
|
|
|
#include <gio/gunixsocketaddress.h>
|
2010-05-14 02:29:04 +02:00
|
|
|
#include <gio/gunixfdlist.h>
|
2013-09-18 19:40:09 +02:00
|
|
|
#include <gio/gcredentialsprivate.h>
|
2010-05-06 20:13:59 +02:00
|
|
|
|
2010-08-13 18:56:19 +02:00
|
|
|
#ifdef G_OS_UNIX
|
|
|
|
#include <gio/gunixconnection.h>
|
2010-08-27 16:50:03 +02:00
|
|
|
#include <errno.h>
|
2010-08-13 18:56:19 +02:00
|
|
|
#endif
|
2010-05-06 20:13:59 +02:00
|
|
|
|
2010-08-13 18:56:19 +02:00
|
|
|
#include "gdbus-tests.h"
|
2010-05-06 20:13:59 +02:00
|
|
|
|
Rework the build system for a new tests approach
Perform a substantial cleanup of the build system with respect to
building and installing testcases.
First, Makefile.decl has been renamed glib.mk and substantially
expanded. We intend to add more stuff here in the future, like canned
rules for mkenums, marshallers, resources, etc.
By default, tests are no longer compiled as part of 'make'. They will
be built when 'make check' is run. The old behaviour can be obtained
with --enable-always-build-tests.
--disable-modular-tests is gone (because tests are no longer built by
default). There is no longer any way to cause 'make check' to be a
no-op, but that's not very useful anyway.
A new glibtests.m4 file is introduced. Along with glib.mk, this
provides for consistent handling of --enable-installed-tests and
--enable-always-build-tests (mentioned above).
Port our various test-installing Makefiles to the new framework.
This patch substantially improves the situation in the toplevel tests/
directory. Things are now somewhat under control there. There were
some tests being built that weren't even being run and we run those now.
The long-running GObject performance tests in this directory have been
removed from 'make check' because they take too long.
As an experiment, 'make check' now runs the testcases on win32 builds,
by default. We can't run them under gtester (since it uses a pipe to
communicate with the subprocess) so just toss them in TESTS. Most of
them are passing on win32.
Things are not quite done here, but this patch is already a substantial
improvement. More to come.
2013-05-30 06:07:32 +02:00
|
|
|
#include "gdbus-object-manager-example/gdbus-example-objectmanager-generated.h"
|
2011-12-02 17:20:21 +01:00
|
|
|
|
2010-05-06 20:13:59 +02:00
|
|
|
#ifdef G_OS_UNIX
|
|
|
|
static gboolean is_unix = TRUE;
|
|
|
|
#else
|
|
|
|
static gboolean is_unix = FALSE;
|
|
|
|
#endif
|
|
|
|
|
2011-08-27 17:33:43 +02:00
|
|
|
static gchar *tmp_address = NULL;
|
2010-05-06 20:13:59 +02:00
|
|
|
static gchar *test_guid = NULL;
|
2013-05-22 18:41:32 +02:00
|
|
|
static GMutex service_loop_lock;
|
|
|
|
static GCond service_loop_cond;
|
2010-05-06 20:13:59 +02:00
|
|
|
static GMainLoop *service_loop = NULL;
|
|
|
|
static GDBusServer *server = NULL;
|
|
|
|
static GMainLoop *loop = NULL;
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------------------------------------- */
|
|
|
|
/* Test that peer-to-peer connections work */
|
|
|
|
/* ---------------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
gboolean accept_connection;
|
|
|
|
gint num_connection_attempts;
|
|
|
|
GPtrArray *current_connections;
|
|
|
|
guint num_method_calls;
|
|
|
|
gboolean signal_received;
|
|
|
|
} PeerData;
|
|
|
|
|
|
|
|
static const gchar *test_interface_introspection_xml =
|
|
|
|
"<node>"
|
|
|
|
" <interface name='org.gtk.GDBus.PeerTestInterface'>"
|
|
|
|
" <method name='HelloPeer'>"
|
|
|
|
" <arg type='s' name='greeting' direction='in'/>"
|
|
|
|
" <arg type='s' name='response' direction='out'/>"
|
|
|
|
" </method>"
|
|
|
|
" <method name='EmitSignal'/>"
|
2010-07-14 17:14:58 +02:00
|
|
|
" <method name='EmitSignalWithNameSet'/>"
|
2010-05-06 20:13:59 +02:00
|
|
|
" <method name='OpenFile'>"
|
|
|
|
" <arg type='s' name='path' direction='in'/>"
|
|
|
|
" </method>"
|
|
|
|
" <signal name='PeerSignal'>"
|
|
|
|
" <arg type='s' name='a_string'/>"
|
|
|
|
" </signal>"
|
|
|
|
" <property type='s' name='PeerProperty' access='read'/>"
|
|
|
|
" </interface>"
|
|
|
|
"</node>";
|
2010-07-19 21:45:27 +02:00
|
|
|
static GDBusInterfaceInfo *test_interface_introspection_data = NULL;
|
2010-05-06 20:13:59 +02:00
|
|
|
|
|
|
|
static void
|
|
|
|
test_interface_method_call (GDBusConnection *connection,
|
|
|
|
const gchar *sender,
|
|
|
|
const gchar *object_path,
|
|
|
|
const gchar *interface_name,
|
|
|
|
const gchar *method_name,
|
|
|
|
GVariant *parameters,
|
|
|
|
GDBusMethodInvocation *invocation,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
PeerData *data = user_data;
|
2010-08-23 06:36:36 +02:00
|
|
|
const GDBusMethodInfo *info;
|
2010-05-06 20:13:59 +02:00
|
|
|
|
|
|
|
data->num_method_calls++;
|
|
|
|
|
|
|
|
g_assert_cmpstr (object_path, ==, "/org/gtk/GDBus/PeerTestObject");
|
|
|
|
g_assert_cmpstr (interface_name, ==, "org.gtk.GDBus.PeerTestInterface");
|
|
|
|
|
2010-08-23 06:36:36 +02:00
|
|
|
info = g_dbus_method_invocation_get_method_info (invocation);
|
|
|
|
g_assert_cmpstr (info->name, ==, method_name);
|
|
|
|
|
2010-05-06 20:13:59 +02:00
|
|
|
if (g_strcmp0 (method_name, "HelloPeer") == 0)
|
|
|
|
{
|
|
|
|
const gchar *greeting;
|
|
|
|
gchar *response;
|
|
|
|
|
2010-05-14 20:07:15 +02:00
|
|
|
g_variant_get (parameters, "(&s)", &greeting);
|
2010-05-06 20:13:59 +02:00
|
|
|
|
|
|
|
response = g_strdup_printf ("You greeted me with '%s'.",
|
|
|
|
greeting);
|
|
|
|
g_dbus_method_invocation_return_value (invocation,
|
|
|
|
g_variant_new ("(s)", response));
|
|
|
|
g_free (response);
|
|
|
|
}
|
|
|
|
else if (g_strcmp0 (method_name, "EmitSignal") == 0)
|
|
|
|
{
|
|
|
|
GError *error;
|
|
|
|
|
|
|
|
error = NULL;
|
|
|
|
g_dbus_connection_emit_signal (connection,
|
|
|
|
NULL,
|
|
|
|
"/org/gtk/GDBus/PeerTestObject",
|
|
|
|
"org.gtk.GDBus.PeerTestInterface",
|
|
|
|
"PeerSignal",
|
|
|
|
NULL,
|
|
|
|
&error);
|
|
|
|
g_assert_no_error (error);
|
2010-07-14 17:14:58 +02:00
|
|
|
g_dbus_method_invocation_return_value (invocation, NULL);
|
|
|
|
}
|
|
|
|
else if (g_strcmp0 (method_name, "EmitSignalWithNameSet") == 0)
|
|
|
|
{
|
|
|
|
GError *error;
|
|
|
|
gboolean ret;
|
|
|
|
GDBusMessage *message;
|
|
|
|
|
|
|
|
message = g_dbus_message_new_signal ("/org/gtk/GDBus/PeerTestObject",
|
|
|
|
"org.gtk.GDBus.PeerTestInterface",
|
|
|
|
"PeerSignalWithNameSet");
|
|
|
|
g_dbus_message_set_sender (message, ":1.42");
|
|
|
|
|
|
|
|
error = NULL;
|
2010-07-19 22:07:57 +02:00
|
|
|
ret = g_dbus_connection_send_message (connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error);
|
2010-07-14 17:14:58 +02:00
|
|
|
g_assert_no_error (error);
|
|
|
|
g_assert (ret);
|
|
|
|
g_object_unref (message);
|
|
|
|
|
2010-05-06 20:13:59 +02:00
|
|
|
g_dbus_method_invocation_return_value (invocation, NULL);
|
|
|
|
}
|
|
|
|
else if (g_strcmp0 (method_name, "OpenFile") == 0)
|
|
|
|
{
|
2010-05-20 16:51:00 +02:00
|
|
|
#ifdef G_OS_UNIX
|
2010-05-06 20:13:59 +02:00
|
|
|
const gchar *path;
|
|
|
|
GDBusMessage *reply;
|
|
|
|
GError *error;
|
|
|
|
gint fd;
|
|
|
|
GUnixFDList *fd_list;
|
|
|
|
|
2010-05-14 20:07:15 +02:00
|
|
|
g_variant_get (parameters, "(&s)", &path);
|
2010-05-06 20:13:59 +02:00
|
|
|
|
|
|
|
fd_list = g_unix_fd_list_new ();
|
|
|
|
|
|
|
|
error = NULL;
|
|
|
|
|
2012-08-28 00:30:06 +02:00
|
|
|
fd = g_open (path, O_RDONLY, 0);
|
2013-05-20 22:50:28 +02:00
|
|
|
g_assert (fd != -1);
|
2010-05-06 20:13:59 +02:00
|
|
|
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);
|
2010-09-03 22:02:11 +02:00
|
|
|
g_object_unref (fd_list);
|
2010-05-06 20:13:59 +02:00
|
|
|
g_object_unref (invocation);
|
|
|
|
|
|
|
|
error = NULL;
|
|
|
|
g_dbus_connection_send_message (connection,
|
|
|
|
reply,
|
2010-07-19 22:07:57 +02:00
|
|
|
G_DBUS_SEND_MESSAGE_FLAGS_NONE,
|
2010-05-06 20:13:59 +02:00
|
|
|
NULL, /* out_serial */
|
|
|
|
&error);
|
|
|
|
g_assert_no_error (error);
|
|
|
|
g_object_unref (reply);
|
2010-05-20 16:51:00 +02:00
|
|
|
#else
|
|
|
|
g_dbus_method_invocation_return_dbus_error (invocation,
|
|
|
|
"org.gtk.GDBus.NotOnUnix",
|
|
|
|
"Your OS does not support file descriptor passing");
|
|
|
|
#endif
|
2010-05-06 20:13:59 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_assert_not_reached ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static GVariant *
|
|
|
|
test_interface_get_property (GDBusConnection *connection,
|
|
|
|
const gchar *sender,
|
|
|
|
const gchar *object_path,
|
|
|
|
const gchar *interface_name,
|
|
|
|
const gchar *property_name,
|
|
|
|
GError **error,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
g_assert_cmpstr (object_path, ==, "/org/gtk/GDBus/PeerTestObject");
|
|
|
|
g_assert_cmpstr (interface_name, ==, "org.gtk.GDBus.PeerTestInterface");
|
|
|
|
g_assert_cmpstr (property_name, ==, "PeerProperty");
|
|
|
|
|
|
|
|
return g_variant_new_string ("ThePropertyValue");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static const GDBusInterfaceVTable test_interface_vtable =
|
|
|
|
{
|
|
|
|
test_interface_method_call,
|
|
|
|
test_interface_get_property,
|
|
|
|
NULL /* set_property */
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_proxy_signal_received (GDBusProxy *proxy,
|
|
|
|
gchar *sender_name,
|
|
|
|
gchar *signal_name,
|
|
|
|
GVariant *parameters,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
PeerData *data = user_data;
|
|
|
|
|
|
|
|
data->signal_received = TRUE;
|
|
|
|
|
|
|
|
g_assert (sender_name == NULL);
|
|
|
|
g_assert_cmpstr (signal_name, ==, "PeerSignal");
|
|
|
|
g_main_loop_quit (loop);
|
|
|
|
}
|
|
|
|
|
2010-07-14 17:14:58 +02:00
|
|
|
static void
|
|
|
|
on_proxy_signal_received_with_name_set (GDBusProxy *proxy,
|
|
|
|
gchar *sender_name,
|
|
|
|
gchar *signal_name,
|
|
|
|
GVariant *parameters,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
PeerData *data = user_data;
|
|
|
|
|
|
|
|
data->signal_received = TRUE;
|
|
|
|
|
|
|
|
g_assert_cmpstr (sender_name, ==, ":1.42");
|
|
|
|
g_assert_cmpstr (signal_name, ==, "PeerSignalWithNameSet");
|
|
|
|
g_main_loop_quit (loop);
|
|
|
|
}
|
|
|
|
|
2010-05-06 20:13:59 +02:00
|
|
|
/* ---------------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static gboolean
|
2010-05-13 22:20:31 +02:00
|
|
|
on_authorize_authenticated_peer (GDBusAuthObserver *observer,
|
|
|
|
GIOStream *stream,
|
|
|
|
GCredentials *credentials,
|
|
|
|
gpointer user_data)
|
2010-05-06 20:13:59 +02:00
|
|
|
{
|
|
|
|
PeerData *data = user_data;
|
2010-05-13 22:20:31 +02:00
|
|
|
gboolean authorized;
|
2010-05-06 20:13:59 +02:00
|
|
|
|
|
|
|
data->num_connection_attempts++;
|
|
|
|
|
2010-05-13 22:20:31 +02:00
|
|
|
authorized = TRUE;
|
2010-05-06 20:13:59 +02:00
|
|
|
if (!data->accept_connection)
|
|
|
|
{
|
2010-05-13 22:20:31 +02:00
|
|
|
authorized = FALSE;
|
2010-05-06 20:13:59 +02:00
|
|
|
g_main_loop_quit (loop);
|
|
|
|
}
|
|
|
|
|
2010-05-13 22:20:31 +02:00
|
|
|
return authorized;
|
2010-05-06 20:13:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Runs in thread we created GDBusServer in (since we didn't pass G_DBUS_SERVER_FLAGS_RUN_IN_THREAD) */
|
2010-09-09 20:00:46 +02:00
|
|
|
static gboolean
|
2010-05-06 20:13:59 +02:00
|
|
|
on_new_connection (GDBusServer *server,
|
|
|
|
GDBusConnection *connection,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
PeerData *data = user_data;
|
|
|
|
GError *error;
|
|
|
|
guint reg_id;
|
|
|
|
|
2015-05-11 18:03:00 +02:00
|
|
|
//g_printerr ("Client connected.\n"
|
2010-05-06 20:13:59 +02:00
|
|
|
// "Negotiated capabilities: unix-fd-passing=%d\n",
|
|
|
|
// g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING);
|
|
|
|
|
|
|
|
g_ptr_array_add (data->current_connections, g_object_ref (connection));
|
|
|
|
|
2013-09-18 19:40:09 +02:00
|
|
|
#if G_CREDENTIALS_SUPPORTED
|
2012-11-08 15:09:23 +01:00
|
|
|
{
|
|
|
|
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
|
|
|
|
|
2010-05-06 20:13:59 +02:00
|
|
|
/* export object on the newly established connection */
|
|
|
|
error = NULL;
|
|
|
|
reg_id = g_dbus_connection_register_object (connection,
|
|
|
|
"/org/gtk/GDBus/PeerTestObject",
|
|
|
|
test_interface_introspection_data,
|
|
|
|
&test_interface_vtable,
|
|
|
|
data,
|
|
|
|
NULL, /* GDestroyNotify for data */
|
|
|
|
&error);
|
|
|
|
g_assert_no_error (error);
|
|
|
|
g_assert (reg_id > 0);
|
|
|
|
|
|
|
|
g_main_loop_quit (loop);
|
2010-09-09 20:00:46 +02:00
|
|
|
|
|
|
|
return TRUE;
|
2010-05-06 20:13:59 +02:00
|
|
|
}
|
|
|
|
|
gdbus-peer test: let GDBusServer start before notifying main thread
When running the nonce-tcp and tcp-anonymous tests in one run
of gdbus-peer, or running one of them twice via command-line options
"-p /gdbus/tcp-anonymous -p /gdbus/tcp-anonymous", the one run second
would sometimes fail to connect with ECONNRESET.
Adding more debug messages revealed that in the successful case,
g_main_loop_run() was executed in the server thread first:
# tcp-anonymous: server thread: listening on tcp:host=localhost,port=53517
# tcp-anonymous: server thread: starting server...
# tcp-anonymous: server thread: creating main loop...
# tcp-anonymous: server thread: running main loop...
# tcp-anonymous: main thread: trying tcp:host=localhost,port=53517...
# tcp-anonymous: main thread: waiting for server thread...
but in the failing case, the main thread attempted to connect
before the call to g_main_loop_run() in the server thread:
# tcp-anonymous: server thread: listening on tcp:host=localhost,port=40659
# tcp-anonymous: server thread: starting server...
# tcp-anonymous: server thread: creating main loop...
# tcp-anonymous: main thread: trying tcp:host=localhost,port=40659...
# tcp-anonymous: server thread: running main loop...
(The log message "creating main loop" was immediately before
create_service_loop(), and "running main loop" was immediately
before g_main_loop_run().)
To ensure that the GDBusServer has a chance to start accepting
connections before the main thread tries to connect to it, do not
tell the main thread about the service_loop immediately, but instead
defer it to an idle.
Bug: https://bugzilla.gnome.org/show_bug.cgi?id=749079
Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
Reviewed-by: Philip Withnall <philip.withnall@collabora.co.uk>
2015-05-07 17:45:48 +02:00
|
|
|
/* We don't tell the main thread about the new GDBusServer until it has
|
|
|
|
* had a chance to start listening. */
|
|
|
|
static gboolean
|
|
|
|
idle_in_service_loop (gpointer loop)
|
2013-05-22 18:41:32 +02:00
|
|
|
{
|
|
|
|
g_assert (service_loop == NULL);
|
|
|
|
g_mutex_lock (&service_loop_lock);
|
gdbus-peer test: let GDBusServer start before notifying main thread
When running the nonce-tcp and tcp-anonymous tests in one run
of gdbus-peer, or running one of them twice via command-line options
"-p /gdbus/tcp-anonymous -p /gdbus/tcp-anonymous", the one run second
would sometimes fail to connect with ECONNRESET.
Adding more debug messages revealed that in the successful case,
g_main_loop_run() was executed in the server thread first:
# tcp-anonymous: server thread: listening on tcp:host=localhost,port=53517
# tcp-anonymous: server thread: starting server...
# tcp-anonymous: server thread: creating main loop...
# tcp-anonymous: server thread: running main loop...
# tcp-anonymous: main thread: trying tcp:host=localhost,port=53517...
# tcp-anonymous: main thread: waiting for server thread...
but in the failing case, the main thread attempted to connect
before the call to g_main_loop_run() in the server thread:
# tcp-anonymous: server thread: listening on tcp:host=localhost,port=40659
# tcp-anonymous: server thread: starting server...
# tcp-anonymous: server thread: creating main loop...
# tcp-anonymous: main thread: trying tcp:host=localhost,port=40659...
# tcp-anonymous: server thread: running main loop...
(The log message "creating main loop" was immediately before
create_service_loop(), and "running main loop" was immediately
before g_main_loop_run().)
To ensure that the GDBusServer has a chance to start accepting
connections before the main thread tries to connect to it, do not
tell the main thread about the service_loop immediately, but instead
defer it to an idle.
Bug: https://bugzilla.gnome.org/show_bug.cgi?id=749079
Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
Reviewed-by: Philip Withnall <philip.withnall@collabora.co.uk>
2015-05-07 17:45:48 +02:00
|
|
|
service_loop = loop;
|
2013-05-22 18:41:32 +02:00
|
|
|
g_cond_broadcast (&service_loop_cond);
|
|
|
|
g_mutex_unlock (&service_loop_lock);
|
gdbus-peer test: let GDBusServer start before notifying main thread
When running the nonce-tcp and tcp-anonymous tests in one run
of gdbus-peer, or running one of them twice via command-line options
"-p /gdbus/tcp-anonymous -p /gdbus/tcp-anonymous", the one run second
would sometimes fail to connect with ECONNRESET.
Adding more debug messages revealed that in the successful case,
g_main_loop_run() was executed in the server thread first:
# tcp-anonymous: server thread: listening on tcp:host=localhost,port=53517
# tcp-anonymous: server thread: starting server...
# tcp-anonymous: server thread: creating main loop...
# tcp-anonymous: server thread: running main loop...
# tcp-anonymous: main thread: trying tcp:host=localhost,port=53517...
# tcp-anonymous: main thread: waiting for server thread...
but in the failing case, the main thread attempted to connect
before the call to g_main_loop_run() in the server thread:
# tcp-anonymous: server thread: listening on tcp:host=localhost,port=40659
# tcp-anonymous: server thread: starting server...
# tcp-anonymous: server thread: creating main loop...
# tcp-anonymous: main thread: trying tcp:host=localhost,port=40659...
# tcp-anonymous: server thread: running main loop...
(The log message "creating main loop" was immediately before
create_service_loop(), and "running main loop" was immediately
before g_main_loop_run().)
To ensure that the GDBusServer has a chance to start accepting
connections before the main thread tries to connect to it, do not
tell the main thread about the service_loop immediately, but instead
defer it to an idle.
Bug: https://bugzilla.gnome.org/show_bug.cgi?id=749079
Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
Reviewed-by: Philip Withnall <philip.withnall@collabora.co.uk>
2015-05-07 17:45:48 +02:00
|
|
|
|
|
|
|
return G_SOURCE_REMOVE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
run_service_loop (GMainContext *service_context)
|
|
|
|
{
|
|
|
|
GMainLoop *loop;
|
|
|
|
GSource *source;
|
|
|
|
|
|
|
|
g_assert (service_loop == NULL);
|
|
|
|
|
|
|
|
loop = g_main_loop_new (service_context, FALSE);
|
|
|
|
source = g_idle_source_new ();
|
|
|
|
g_source_set_callback (source, idle_in_service_loop, loop, NULL);
|
|
|
|
g_source_attach (source, service_context);
|
|
|
|
g_source_unref (source);
|
|
|
|
g_main_loop_run (loop);
|
2013-05-22 18:41:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2010-05-06 20:13:59 +02:00
|
|
|
static gpointer
|
|
|
|
service_thread_func (gpointer user_data)
|
|
|
|
{
|
|
|
|
PeerData *data = user_data;
|
|
|
|
GMainContext *service_context;
|
2012-04-08 16:20:10 +02:00
|
|
|
GDBusAuthObserver *observer, *o;
|
2010-05-06 20:13:59 +02:00
|
|
|
GError *error;
|
2012-04-08 16:20:10 +02:00
|
|
|
GDBusServerFlags f;
|
|
|
|
gchar *a, *g;
|
|
|
|
gboolean b;
|
2010-05-06 20:13:59 +02:00
|
|
|
|
|
|
|
service_context = g_main_context_new ();
|
|
|
|
g_main_context_push_thread_default (service_context);
|
|
|
|
|
|
|
|
error = NULL;
|
|
|
|
observer = g_dbus_auth_observer_new ();
|
2011-08-27 17:33:43 +02:00
|
|
|
server = g_dbus_server_new_sync (tmp_address,
|
2010-05-06 20:13:59 +02:00
|
|
|
G_DBUS_SERVER_FLAGS_NONE,
|
|
|
|
test_guid,
|
|
|
|
observer,
|
|
|
|
NULL, /* cancellable */
|
|
|
|
&error);
|
|
|
|
g_assert_no_error (error);
|
|
|
|
|
|
|
|
g_signal_connect (server,
|
|
|
|
"new-connection",
|
|
|
|
G_CALLBACK (on_new_connection),
|
|
|
|
data);
|
|
|
|
g_signal_connect (observer,
|
2010-05-13 22:20:31 +02:00
|
|
|
"authorize-authenticated-peer",
|
|
|
|
G_CALLBACK (on_authorize_authenticated_peer),
|
2010-05-06 20:13:59 +02:00
|
|
|
data);
|
2012-04-08 16:20:10 +02:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2010-05-06 20:13:59 +02:00
|
|
|
g_object_unref (observer);
|
|
|
|
|
|
|
|
g_dbus_server_start (server);
|
|
|
|
|
gdbus-peer test: let GDBusServer start before notifying main thread
When running the nonce-tcp and tcp-anonymous tests in one run
of gdbus-peer, or running one of them twice via command-line options
"-p /gdbus/tcp-anonymous -p /gdbus/tcp-anonymous", the one run second
would sometimes fail to connect with ECONNRESET.
Adding more debug messages revealed that in the successful case,
g_main_loop_run() was executed in the server thread first:
# tcp-anonymous: server thread: listening on tcp:host=localhost,port=53517
# tcp-anonymous: server thread: starting server...
# tcp-anonymous: server thread: creating main loop...
# tcp-anonymous: server thread: running main loop...
# tcp-anonymous: main thread: trying tcp:host=localhost,port=53517...
# tcp-anonymous: main thread: waiting for server thread...
but in the failing case, the main thread attempted to connect
before the call to g_main_loop_run() in the server thread:
# tcp-anonymous: server thread: listening on tcp:host=localhost,port=40659
# tcp-anonymous: server thread: starting server...
# tcp-anonymous: server thread: creating main loop...
# tcp-anonymous: main thread: trying tcp:host=localhost,port=40659...
# tcp-anonymous: server thread: running main loop...
(The log message "creating main loop" was immediately before
create_service_loop(), and "running main loop" was immediately
before g_main_loop_run().)
To ensure that the GDBusServer has a chance to start accepting
connections before the main thread tries to connect to it, do not
tell the main thread about the service_loop immediately, but instead
defer it to an idle.
Bug: https://bugzilla.gnome.org/show_bug.cgi?id=749079
Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
Reviewed-by: Philip Withnall <philip.withnall@collabora.co.uk>
2015-05-07 17:45:48 +02:00
|
|
|
run_service_loop (service_context);
|
2010-05-06 20:13:59 +02:00
|
|
|
|
|
|
|
g_main_context_pop_thread_default (service_context);
|
|
|
|
|
2013-05-22 18:41:32 +02:00
|
|
|
teardown_service_loop ();
|
2010-05-06 20:13:59 +02:00
|
|
|
g_main_context_unref (service_context);
|
|
|
|
|
|
|
|
/* test code specifically unrefs the server - see below */
|
|
|
|
g_assert (server == NULL);
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
static gboolean
|
|
|
|
on_incoming_connection (GSocketService *service,
|
|
|
|
GSocketConnection *socket_connection,
|
|
|
|
GObject *source_object,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
PeerData *data = user_data;
|
|
|
|
|
|
|
|
if (data->accept_connection)
|
|
|
|
{
|
|
|
|
GError *error;
|
|
|
|
guint reg_id;
|
|
|
|
GDBusConnection *connection;
|
|
|
|
|
|
|
|
error = NULL;
|
|
|
|
connection = g_dbus_connection_new_sync (G_IO_STREAM (socket_connection),
|
|
|
|
test_guid,
|
|
|
|
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER,
|
|
|
|
NULL, /* cancellable */
|
|
|
|
&error);
|
|
|
|
g_assert_no_error (error);
|
|
|
|
|
|
|
|
g_ptr_array_add (data->current_connections, connection);
|
|
|
|
|
|
|
|
/* export object on the newly established connection */
|
|
|
|
error = NULL;
|
|
|
|
reg_id = g_dbus_connection_register_object (connection,
|
|
|
|
"/org/gtk/GDBus/PeerTestObject",
|
|
|
|
&test_interface_introspection_data,
|
|
|
|
&test_interface_vtable,
|
|
|
|
data,
|
|
|
|
NULL, /* GDestroyNotify for data */
|
|
|
|
&error);
|
|
|
|
g_assert_no_error (error);
|
|
|
|
g_assert (reg_id > 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* don't do anything */
|
|
|
|
}
|
|
|
|
|
|
|
|
data->num_connection_attempts++;
|
|
|
|
|
|
|
|
g_main_loop_quit (loop);
|
|
|
|
|
|
|
|
/* stops other signal handlers from being invoked */
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gpointer
|
|
|
|
service_thread_func (gpointer data)
|
|
|
|
{
|
|
|
|
GMainContext *service_context;
|
|
|
|
gchar *socket_path;
|
|
|
|
GSocketAddress *address;
|
|
|
|
GError *error;
|
|
|
|
|
|
|
|
service_context = g_main_context_new ();
|
|
|
|
g_main_context_push_thread_default (service_context);
|
|
|
|
|
|
|
|
socket_path = g_strdup_printf ("/tmp/gdbus-test-pid-%d", getpid ());
|
|
|
|
address = g_unix_socket_address_new (socket_path);
|
|
|
|
|
|
|
|
service = g_socket_service_new ();
|
|
|
|
error = NULL;
|
|
|
|
g_socket_listener_add_address (G_SOCKET_LISTENER (service),
|
|
|
|
address,
|
|
|
|
G_SOCKET_TYPE_STREAM,
|
|
|
|
G_SOCKET_PROTOCOL_DEFAULT,
|
|
|
|
NULL, /* source_object */
|
|
|
|
NULL, /* effective_address */
|
|
|
|
&error);
|
|
|
|
g_assert_no_error (error);
|
|
|
|
g_signal_connect (service,
|
|
|
|
"incoming",
|
|
|
|
G_CALLBACK (on_incoming_connection),
|
|
|
|
data);
|
|
|
|
g_socket_service_start (service);
|
|
|
|
|
gdbus-peer test: let GDBusServer start before notifying main thread
When running the nonce-tcp and tcp-anonymous tests in one run
of gdbus-peer, or running one of them twice via command-line options
"-p /gdbus/tcp-anonymous -p /gdbus/tcp-anonymous", the one run second
would sometimes fail to connect with ECONNRESET.
Adding more debug messages revealed that in the successful case,
g_main_loop_run() was executed in the server thread first:
# tcp-anonymous: server thread: listening on tcp:host=localhost,port=53517
# tcp-anonymous: server thread: starting server...
# tcp-anonymous: server thread: creating main loop...
# tcp-anonymous: server thread: running main loop...
# tcp-anonymous: main thread: trying tcp:host=localhost,port=53517...
# tcp-anonymous: main thread: waiting for server thread...
but in the failing case, the main thread attempted to connect
before the call to g_main_loop_run() in the server thread:
# tcp-anonymous: server thread: listening on tcp:host=localhost,port=40659
# tcp-anonymous: server thread: starting server...
# tcp-anonymous: server thread: creating main loop...
# tcp-anonymous: main thread: trying tcp:host=localhost,port=40659...
# tcp-anonymous: server thread: running main loop...
(The log message "creating main loop" was immediately before
create_service_loop(), and "running main loop" was immediately
before g_main_loop_run().)
To ensure that the GDBusServer has a chance to start accepting
connections before the main thread tries to connect to it, do not
tell the main thread about the service_loop immediately, but instead
defer it to an idle.
Bug: https://bugzilla.gnome.org/show_bug.cgi?id=749079
Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
Reviewed-by: Philip Withnall <philip.withnall@collabora.co.uk>
2015-05-07 17:45:48 +02:00
|
|
|
run_service_loop (service_context);
|
2010-05-06 20:13:59 +02:00
|
|
|
|
|
|
|
g_main_context_pop_thread_default (service_context);
|
|
|
|
|
2013-05-22 18:41:32 +02:00
|
|
|
teardown_service_loop ();
|
2010-05-06 20:13:59 +02:00
|
|
|
g_main_context_unref (service_context);
|
|
|
|
|
|
|
|
g_object_unref (address);
|
|
|
|
g_free (socket_path);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
static gboolean
|
|
|
|
check_connection (gpointer user_data)
|
|
|
|
{
|
|
|
|
PeerData *data = user_data;
|
|
|
|
guint n;
|
|
|
|
|
|
|
|
for (n = 0; n < data->current_connections->len; n++)
|
|
|
|
{
|
|
|
|
GDBusConnection *c;
|
|
|
|
GIOStream *stream;
|
|
|
|
|
|
|
|
c = G_DBUS_CONNECTION (data->current_connections->pdata[n]);
|
|
|
|
stream = g_dbus_connection_get_stream (c);
|
|
|
|
|
|
|
|
g_debug ("In check_connection for %d: connection %p, stream %p", n, c, stream);
|
|
|
|
g_debug ("closed = %d", g_io_stream_is_closed (stream));
|
|
|
|
|
|
|
|
GSocket *socket;
|
|
|
|
socket = g_socket_connection_get_socket (G_SOCKET_CONNECTION (stream));
|
|
|
|
g_debug ("socket_closed = %d", g_socket_is_closed (socket));
|
|
|
|
g_debug ("socket_condition_check = %d", g_socket_condition_check (socket, G_IO_IN|G_IO_OUT|G_IO_ERR|G_IO_HUP));
|
|
|
|
|
|
|
|
gchar buf[128];
|
|
|
|
GError *error;
|
|
|
|
gssize num_read;
|
|
|
|
error = NULL;
|
|
|
|
num_read = g_input_stream_read (g_io_stream_get_input_stream (stream),
|
|
|
|
buf,
|
|
|
|
128,
|
|
|
|
NULL,
|
|
|
|
&error);
|
|
|
|
if (num_read < 0)
|
|
|
|
{
|
|
|
|
g_debug ("error: %s", error->message);
|
|
|
|
g_error_free (error);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_debug ("no error, read %d bytes", (gint) num_read);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
on_do_disconnect_in_idle (gpointer data)
|
|
|
|
{
|
|
|
|
GDBusConnection *c = G_DBUS_CONNECTION (data);
|
|
|
|
g_debug ("GDC %p has ref_count %d", c, G_OBJECT (c)->ref_count);
|
|
|
|
g_dbus_connection_disconnect (c);
|
|
|
|
g_object_unref (c);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-08-27 16:50:03 +02:00
|
|
|
#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
|
|
|
|
{
|
2017-07-31 12:30:55 +02:00
|
|
|
int errsv;
|
|
|
|
|
2010-08-27 16:50:03 +02:00
|
|
|
num_read = read (fd, buf, sizeof (buf));
|
2017-07-31 12:30:55 +02:00
|
|
|
errsv = errno;
|
2010-08-27 16:50:03 +02:00
|
|
|
if (num_read == -1)
|
|
|
|
{
|
2017-07-31 12:30:55 +02:00
|
|
|
if (errsv == EAGAIN || errsv == EWOULDBLOCK)
|
2010-08-27 16:50:03 +02:00
|
|
|
continue;
|
|
|
|
g_set_error (error,
|
|
|
|
G_IO_ERROR,
|
2017-07-31 12:30:55 +02:00
|
|
|
g_io_error_from_errno (errsv),
|
2010-08-27 16:50:03 +02:00
|
|
|
"Failed reading %d bytes into offset %d: %s",
|
|
|
|
(gint) sizeof (buf),
|
|
|
|
(gint) str->len,
|
2017-07-31 12:30:55 +02:00
|
|
|
g_strerror (errsv));
|
2010-08-27 16:50:03 +02:00
|
|
|
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)
|
2016-08-13 10:24:23 +02:00
|
|
|
*out_len = 0;
|
2010-08-27 16:50:03 +02:00
|
|
|
g_string_free (str, TRUE);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-05-06 20:13:59 +02:00
|
|
|
static void
|
|
|
|
test_peer (void)
|
|
|
|
{
|
|
|
|
GDBusConnection *c;
|
|
|
|
GDBusConnection *c2;
|
|
|
|
GDBusProxy *proxy;
|
|
|
|
GError *error;
|
|
|
|
PeerData data;
|
|
|
|
GVariant *value;
|
|
|
|
GVariant *result;
|
|
|
|
const gchar *s;
|
|
|
|
GThread *service_thread;
|
2010-07-14 17:14:58 +02:00
|
|
|
gulong signal_handler_id;
|
2010-05-06 20:13:59 +02:00
|
|
|
|
|
|
|
memset (&data, '\0', sizeof (PeerData));
|
|
|
|
data.current_connections = g_ptr_array_new_with_free_func (g_object_unref);
|
|
|
|
|
|
|
|
/* first try to connect when there is no server */
|
|
|
|
error = NULL;
|
|
|
|
c = g_dbus_connection_new_for_address_sync (is_unix ? "unix:path=/tmp/gdbus-test-does-not-exist-pid" :
|
|
|
|
/* NOTE: Even if something is listening on port 12345 the connection
|
|
|
|
* will fail because the nonce file doesn't exist */
|
|
|
|
"nonce-tcp:host=localhost,port=12345,noncefile=this-does-not-exist-gdbus",
|
|
|
|
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
|
2010-05-13 22:32:11 +02:00
|
|
|
NULL, /* GDBusAuthObserver */
|
2010-05-06 20:13:59 +02:00
|
|
|
NULL, /* cancellable */
|
|
|
|
&error);
|
|
|
|
_g_assert_error_domain (error, G_IO_ERROR);
|
|
|
|
g_assert (!g_dbus_error_is_remote_error (error));
|
|
|
|
g_clear_error (&error);
|
|
|
|
g_assert (c == NULL);
|
|
|
|
|
|
|
|
/* bring up a server - we run the server in a different thread to avoid deadlocks */
|
2011-10-10 15:49:50 +02:00
|
|
|
service_thread = g_thread_new ("test_peer",
|
|
|
|
service_thread_func,
|
2011-10-13 07:00:57 +02:00
|
|
|
&data);
|
2013-05-22 18:41:32 +02:00
|
|
|
await_service_loop ();
|
2010-05-06 20:13:59 +02:00
|
|
|
g_assert (server != NULL);
|
|
|
|
|
|
|
|
/* bring up a connection and accept it */
|
|
|
|
data.accept_connection = TRUE;
|
|
|
|
error = NULL;
|
|
|
|
c = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (server),
|
|
|
|
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
|
2010-05-13 22:32:11 +02:00
|
|
|
NULL, /* GDBusAuthObserver */
|
2010-05-06 20:13:59 +02:00
|
|
|
NULL, /* cancellable */
|
|
|
|
&error);
|
|
|
|
g_assert_no_error (error);
|
|
|
|
g_assert (c != NULL);
|
|
|
|
while (data.current_connections->len < 1)
|
|
|
|
g_main_loop_run (loop);
|
|
|
|
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);
|
|
|
|
g_assert_cmpstr (g_dbus_connection_get_guid (c), ==, test_guid);
|
|
|
|
|
|
|
|
/* check that we create a proxy, read properties, receive signals and invoke
|
|
|
|
* the HelloPeer() method. Since the server runs in another thread it's fine
|
|
|
|
* to use synchronous blocking API here.
|
|
|
|
*/
|
|
|
|
error = NULL;
|
|
|
|
proxy = g_dbus_proxy_new_sync (c,
|
|
|
|
G_DBUS_PROXY_FLAGS_NONE,
|
|
|
|
NULL,
|
|
|
|
NULL, /* bus_name */
|
|
|
|
"/org/gtk/GDBus/PeerTestObject",
|
|
|
|
"org.gtk.GDBus.PeerTestInterface",
|
|
|
|
NULL, /* GCancellable */
|
|
|
|
&error);
|
|
|
|
g_assert_no_error (error);
|
|
|
|
g_assert (proxy != NULL);
|
|
|
|
error = NULL;
|
2010-05-13 02:43:40 +02:00
|
|
|
value = g_dbus_proxy_get_cached_property (proxy, "PeerProperty");
|
2010-05-06 20:13:59 +02:00
|
|
|
g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "ThePropertyValue");
|
|
|
|
|
|
|
|
/* try invoking a method */
|
|
|
|
error = NULL;
|
2010-05-10 17:47:08 +02:00
|
|
|
result = g_dbus_proxy_call_sync (proxy,
|
|
|
|
"HelloPeer",
|
|
|
|
g_variant_new ("(s)", "Hey Peer!"),
|
|
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
|
|
-1,
|
|
|
|
NULL, /* GCancellable */
|
|
|
|
&error);
|
2010-05-06 20:13:59 +02:00
|
|
|
g_assert_no_error (error);
|
2010-05-14 20:07:15 +02:00
|
|
|
g_variant_get (result, "(&s)", &s);
|
2010-05-06 20:13:59 +02:00
|
|
|
g_assert_cmpstr (s, ==, "You greeted me with 'Hey Peer!'.");
|
|
|
|
g_variant_unref (result);
|
|
|
|
g_assert_cmpint (data.num_method_calls, ==, 1);
|
|
|
|
|
|
|
|
/* make the other peer emit a signal - catch it */
|
2010-07-14 17:14:58 +02:00
|
|
|
signal_handler_id = g_signal_connect (proxy,
|
|
|
|
"g-signal",
|
|
|
|
G_CALLBACK (on_proxy_signal_received),
|
|
|
|
&data);
|
2010-05-06 20:13:59 +02:00
|
|
|
g_assert (!data.signal_received);
|
2010-05-10 17:47:08 +02:00
|
|
|
g_dbus_proxy_call (proxy,
|
|
|
|
"EmitSignal",
|
|
|
|
NULL, /* no arguments */
|
|
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
|
|
-1,
|
|
|
|
NULL, /* GCancellable */
|
|
|
|
NULL, /* GAsyncReadyCallback - we don't care about the result */
|
|
|
|
NULL); /* user_data */
|
2010-05-06 20:13:59 +02:00
|
|
|
g_main_loop_run (loop);
|
|
|
|
g_assert (data.signal_received);
|
|
|
|
g_assert_cmpint (data.num_method_calls, ==, 2);
|
2010-07-14 17:14:58 +02:00
|
|
|
g_signal_handler_disconnect (proxy, signal_handler_id);
|
|
|
|
|
|
|
|
/* Also ensure that messages with the sender header-field set gets
|
|
|
|
* delivered to the proxy - note that this doesn't really make sense
|
|
|
|
* e.g. names are meaning-less in a peer-to-peer case... but we
|
|
|
|
* support it because it makes sense in certain bridging
|
|
|
|
* applications - see e.g. #623815.
|
|
|
|
*/
|
|
|
|
signal_handler_id = g_signal_connect (proxy,
|
|
|
|
"g-signal",
|
|
|
|
G_CALLBACK (on_proxy_signal_received_with_name_set),
|
|
|
|
&data);
|
|
|
|
data.signal_received = FALSE;
|
|
|
|
g_dbus_proxy_call (proxy,
|
|
|
|
"EmitSignalWithNameSet",
|
|
|
|
NULL, /* no arguments */
|
|
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
|
|
-1,
|
|
|
|
NULL, /* GCancellable */
|
|
|
|
NULL, /* GAsyncReadyCallback - we don't care about the result */
|
|
|
|
NULL); /* user_data */
|
|
|
|
g_main_loop_run (loop);
|
|
|
|
g_assert (data.signal_received);
|
|
|
|
g_assert_cmpint (data.num_method_calls, ==, 3);
|
|
|
|
g_signal_handler_disconnect (proxy, signal_handler_id);
|
2010-05-06 20:13:59 +02:00
|
|
|
|
|
|
|
/* check for UNIX fd passing */
|
|
|
|
#ifdef G_OS_UNIX
|
|
|
|
{
|
|
|
|
GDBusMessage *method_call_message;
|
|
|
|
GDBusMessage *method_reply_message;
|
|
|
|
GUnixFDList *fd_list;
|
|
|
|
gint fd;
|
2010-08-27 16:50:03 +02:00
|
|
|
gchar *buf;
|
|
|
|
gsize len;
|
2010-05-06 20:13:59 +02:00
|
|
|
gchar *buf2;
|
|
|
|
gsize len2;
|
2013-05-29 14:49:16 +02:00
|
|
|
const char *testfile = g_test_get_filename (G_TEST_DIST, "file.c", NULL);
|
2010-05-06 20:13:59 +02:00
|
|
|
|
|
|
|
method_call_message = g_dbus_message_new_method_call (NULL, /* name */
|
|
|
|
"/org/gtk/GDBus/PeerTestObject",
|
|
|
|
"org.gtk.GDBus.PeerTestInterface",
|
|
|
|
"OpenFile");
|
2013-05-20 22:50:28 +02:00
|
|
|
g_dbus_message_set_body (method_call_message, g_variant_new ("(s)", testfile));
|
2010-05-06 20:13:59 +02:00
|
|
|
error = NULL;
|
|
|
|
method_reply_message = g_dbus_connection_send_message_with_reply_sync (c,
|
|
|
|
method_call_message,
|
2010-07-19 22:07:57 +02:00
|
|
|
G_DBUS_SEND_MESSAGE_FLAGS_NONE,
|
2010-05-06 20:13:59 +02:00
|
|
|
-1,
|
|
|
|
NULL, /* out_serial */
|
|
|
|
NULL, /* cancellable */
|
|
|
|
&error);
|
|
|
|
g_assert_no_error (error);
|
2010-05-06 23:31:51 +02:00
|
|
|
g_assert (g_dbus_message_get_message_type (method_reply_message) == G_DBUS_MESSAGE_TYPE_METHOD_RETURN);
|
2010-05-06 20:13:59 +02:00
|
|
|
fd_list = g_dbus_message_get_unix_fd_list (method_reply_message);
|
|
|
|
g_assert (fd_list != NULL);
|
|
|
|
g_assert_cmpint (g_unix_fd_list_get_length (fd_list), ==, 1);
|
|
|
|
error = NULL;
|
|
|
|
fd = g_unix_fd_list_get (fd_list, 0, &error);
|
|
|
|
g_assert_no_error (error);
|
|
|
|
g_object_unref (method_call_message);
|
|
|
|
g_object_unref (method_reply_message);
|
|
|
|
|
2010-08-27 16:50:03 +02:00
|
|
|
error = NULL;
|
2010-09-04 19:24:50 +02:00
|
|
|
len = 0;
|
2010-08-27 16:50:03 +02:00
|
|
|
buf = read_all_from_fd (fd, &len, &error);
|
|
|
|
g_assert_no_error (error);
|
|
|
|
g_assert (buf != NULL);
|
2010-05-06 20:13:59 +02:00
|
|
|
close (fd);
|
|
|
|
|
|
|
|
error = NULL;
|
2013-05-20 22:50:28 +02:00
|
|
|
g_file_get_contents (testfile,
|
2010-05-06 20:13:59 +02:00
|
|
|
&buf2,
|
|
|
|
&len2,
|
|
|
|
&error);
|
|
|
|
g_assert_no_error (error);
|
2014-12-03 11:57:29 +01:00
|
|
|
g_assert_cmpmem (buf, len, buf2, len2);
|
2010-05-06 20:13:59 +02:00
|
|
|
g_free (buf2);
|
2010-08-27 16:50:03 +02:00
|
|
|
g_free (buf);
|
2010-05-06 20:13:59 +02:00
|
|
|
}
|
2010-05-20 16:51:00 +02:00
|
|
|
#else
|
|
|
|
error = NULL;
|
|
|
|
result = g_dbus_proxy_call_sync (proxy,
|
|
|
|
"OpenFile",
|
|
|
|
g_variant_new ("(s)", "boo"),
|
|
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
|
|
-1,
|
|
|
|
NULL, /* GCancellable */
|
|
|
|
&error);
|
|
|
|
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR);
|
|
|
|
g_assert (result == NULL);
|
|
|
|
g_error_free (error);
|
2010-05-06 20:13:59 +02:00
|
|
|
#endif /* G_OS_UNIX */
|
|
|
|
|
2013-09-18 19:40:09 +02:00
|
|
|
/* Check that g_socket_get_credentials() work - (though this really
|
|
|
|
* should be in socket.c)
|
2010-07-20 20:02:14 +02:00
|
|
|
*/
|
|
|
|
{
|
|
|
|
GSocket *socket;
|
|
|
|
GCredentials *credentials;
|
|
|
|
socket = g_socket_connection_get_socket (G_SOCKET_CONNECTION (g_dbus_connection_get_stream (c)));
|
|
|
|
g_assert (G_IS_SOCKET (socket));
|
|
|
|
error = NULL;
|
|
|
|
credentials = g_socket_get_credentials (socket, &error);
|
2013-09-18 19:40:09 +02:00
|
|
|
|
|
|
|
#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 ());
|
2018-06-27 10:57:21 +02:00
|
|
|
g_object_unref (credentials);
|
2010-07-20 20:02:14 +02:00
|
|
|
#else
|
|
|
|
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
|
|
|
|
g_assert (credentials == NULL);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2010-05-06 20:13:59 +02:00
|
|
|
|
|
|
|
/* bring up a connection - don't accept it - this should fail
|
|
|
|
*/
|
|
|
|
data.accept_connection = FALSE;
|
|
|
|
error = NULL;
|
|
|
|
c2 = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (server),
|
|
|
|
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
|
2010-05-13 22:32:11 +02:00
|
|
|
NULL, /* GDBusAuthObserver */
|
2010-05-06 20:13:59 +02:00
|
|
|
NULL, /* cancellable */
|
|
|
|
&error);
|
|
|
|
_g_assert_error_domain (error, G_IO_ERROR);
|
Plug some mem leaks in gdbus-peer test
==29535== 56 (24 direct, 32 indirect) bytes in 1 blocks are definitely lost in loss record 1,112 of 1,264
==29535== at 0x4005BDC: malloc (vg_replace_malloc.c:195)
==29535== by 0x4057094: g_malloc (gmem.c:134)
==29535== by 0x406F2D6: g_slice_alloc (gslice.c:836)
==29535== by 0x406F364: g_slice_copy (gslice.c:858)
==29535== by 0x403A9B2: g_error_copy (gerror.c:160)
==29535== by 0x42066D3: initable_init (gdbusconnection.c:2314)
==29535== by 0x41A73E5: g_initable_init (ginitable.c:105)
==29535== by 0x41A7587: g_initable_new_valist (ginitable.c:218)
==29535== by 0x41A742A: g_initable_new (ginitable.c:138)
==29535== by 0x4206DCC: g_dbus_connection_new_for_address_sync (gdbusconnection.c:2585)
==29535== by 0x804D63A: test_nonce_tcp (gdbus-peer.c:1229)
==29535== 107 (24 direct, 83 indirect) bytes in 1 blocks are definitely lost in loss record 1,188 of 1,264
==29535== at 0x4005BDC: malloc (vg_replace_malloc.c:195)
==29535== by 0x4057094: g_malloc (gmem.c:134)
==29535== by 0x406F2D6: g_slice_alloc (gslice.c:836)
==29535== by 0x406F364: g_slice_copy (gslice.c:858)
==29535== by 0x403A9B2: g_error_copy (gerror.c:160)
==29535== by 0x42066D3: initable_init (gdbusconnection.c:2314)
==29535== by 0x41A73E5: g_initable_init (ginitable.c:105)
==29535== by 0x41A7587: g_initable_new_valist (ginitable.c:218)
==29535== by 0x41A742A: g_initable_new (ginitable.c:138)
==29535== by 0x4206DCC: g_dbus_connection_new_for_address_sync (gdbusconnection.c:2585)
==29535== by 0x804D8E8: test_nonce_tcp (gdbus-peer.c:1259)
==29535== 112 (24 direct, 88 indirect) bytes in 1 blocks are definitely lost in loss record 1,193 of 1,264
==29535== at 0x4005BDC: malloc (vg_replace_malloc.c:195)
==29535== by 0x4057094: g_malloc (gmem.c:134)
==29535== by 0x406F2D6: g_slice_alloc (gslice.c:836)
==29535== by 0x406F364: g_slice_copy (gslice.c:858)
==29535== by 0x403A9B2: g_error_copy (gerror.c:160)
==29535== by 0x42066D3: initable_init (gdbusconnection.c:2314)
==29535== by 0x41A73E5: g_initable_init (ginitable.c:105)
==29535== by 0x41A7587: g_initable_new_valist (ginitable.c:218)
==29535== by 0x41A742A: g_initable_new (ginitable.c:138)
==29535== by 0x4206DCC: g_dbus_connection_new_for_address_sync (gdbusconnection.c:2585)
==29535== by 0x804D79A: test_nonce_tcp (gdbus-peer.c:1248)
==29535== 73 (24 direct, 49 indirect) bytes in 1 blocks are definitely lost in loss record 1,152 of 1,264
==29535== at 0x4005BDC: malloc (vg_replace_malloc.c:195)
==29535== by 0x4057094: g_malloc (gmem.c:134)
==29535== by 0x406F2D6: g_slice_alloc (gslice.c:836)
==29535== by 0x406F364: g_slice_copy (gslice.c:858)
==29535== by 0x403A9B2: g_error_copy (gerror.c:160)
==29535== by 0x42066D3: initable_init (gdbusconnection.c:2314)
==29535== by 0x41A73E5: g_initable_init (ginitable.c:105)
==29535== by 0x41A7587: g_initable_new_valist (ginitable.c:218)
==29535== by 0x41A742A: g_initable_new (ginitable.c:138)
==29535== by 0x4206DCC: g_dbus_connection_new_for_address_sync (gdbusconnection.c:2585)
==29535== by 0x804C6CE: test_peer (gdbus-peer.c:803)
Bug #628331.
2010-09-03 22:03:48 +02:00
|
|
|
g_error_free (error);
|
2010-05-06 20:13:59 +02:00
|
|
|
g_assert (c2 == NULL);
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
/* TODO: THIS TEST DOESN'T WORK YET */
|
|
|
|
|
|
|
|
/* bring up a connection - accept it.. then disconnect from the client side - check
|
|
|
|
* that the server side gets the disconnect signal.
|
|
|
|
*/
|
|
|
|
error = NULL;
|
|
|
|
data.accept_connection = TRUE;
|
|
|
|
c2 = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (server),
|
|
|
|
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
|
2010-05-13 22:32:11 +02:00
|
|
|
NULL, /* GDBusAuthObserver */
|
2010-05-06 20:13:59 +02:00
|
|
|
NULL, /* cancellable */
|
|
|
|
&error);
|
|
|
|
g_assert_no_error (error);
|
|
|
|
g_assert (c2 != NULL);
|
|
|
|
g_assert (!g_dbus_connection_get_is_disconnected (c2));
|
|
|
|
while (data.num_connection_attempts < 3)
|
|
|
|
g_main_loop_run (loop);
|
|
|
|
g_assert_cmpint (data.current_connections->len, ==, 2);
|
|
|
|
g_assert_cmpint (data.num_connection_attempts, ==, 3);
|
|
|
|
g_assert (!g_dbus_connection_get_is_disconnected (G_DBUS_CONNECTION (data.current_connections->pdata[1])));
|
|
|
|
g_idle_add (on_do_disconnect_in_idle, c2);
|
|
|
|
g_debug ("==================================================");
|
|
|
|
g_debug ("==================================================");
|
|
|
|
g_debug ("==================================================");
|
|
|
|
g_debug ("waiting for disconnect on connection %p, stream %p",
|
|
|
|
data.current_connections->pdata[1],
|
|
|
|
g_dbus_connection_get_stream (data.current_connections->pdata[1]));
|
|
|
|
|
|
|
|
g_timeout_add (2000, check_connection, &data);
|
|
|
|
//_g_assert_signal_received (G_DBUS_CONNECTION (data.current_connections->pdata[1]), "closed");
|
|
|
|
g_main_loop_run (loop);
|
|
|
|
g_assert (g_dbus_connection_get_is_disconnected (G_DBUS_CONNECTION (data.current_connections->pdata[1])));
|
|
|
|
g_ptr_array_set_size (data.current_connections, 1); /* remove disconnected connection object */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* unref the server and stop listening for new connections
|
|
|
|
*
|
|
|
|
* This won't bring down the established connections - check that c is still connected
|
|
|
|
* by invoking a method
|
|
|
|
*/
|
|
|
|
//g_socket_service_stop (service);
|
|
|
|
//g_object_unref (service);
|
|
|
|
g_dbus_server_stop (server);
|
|
|
|
g_object_unref (server);
|
|
|
|
server = NULL;
|
|
|
|
|
|
|
|
error = NULL;
|
2010-05-10 17:47:08 +02:00
|
|
|
result = g_dbus_proxy_call_sync (proxy,
|
|
|
|
"HelloPeer",
|
|
|
|
g_variant_new ("(s)", "Hey Again Peer!"),
|
|
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
|
|
-1,
|
|
|
|
NULL, /* GCancellable */
|
|
|
|
&error);
|
2010-05-06 20:13:59 +02:00
|
|
|
g_assert_no_error (error);
|
2010-05-14 20:07:15 +02:00
|
|
|
g_variant_get (result, "(&s)", &s);
|
2010-05-06 20:13:59 +02:00
|
|
|
g_assert_cmpstr (s, ==, "You greeted me with 'Hey Again Peer!'.");
|
|
|
|
g_variant_unref (result);
|
2010-07-14 17:14:58 +02:00
|
|
|
g_assert_cmpint (data.num_method_calls, ==, 5);
|
2010-05-06 20:13:59 +02:00
|
|
|
|
|
|
|
#if 0
|
|
|
|
/* TODO: THIS TEST DOESN'T WORK YET */
|
|
|
|
|
|
|
|
/* now disconnect from the server side - check that the client side gets the signal */
|
|
|
|
g_assert_cmpint (data.current_connections->len, ==, 1);
|
|
|
|
g_assert (G_DBUS_CONNECTION (data.current_connections->pdata[0]) != c);
|
|
|
|
g_dbus_connection_disconnect (G_DBUS_CONNECTION (data.current_connections->pdata[0]));
|
|
|
|
if (!g_dbus_connection_get_is_disconnected (c))
|
|
|
|
_g_assert_signal_received (c, "closed");
|
|
|
|
g_assert (g_dbus_connection_get_is_disconnected (c));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
g_object_unref (c);
|
|
|
|
g_ptr_array_unref (data.current_connections);
|
|
|
|
g_object_unref (proxy);
|
|
|
|
|
|
|
|
g_main_loop_quit (service_loop);
|
|
|
|
g_thread_join (service_thread);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------------------------------------- */
|
|
|
|
|
2010-06-30 17:43:42 +02:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
GDBusServer *server;
|
|
|
|
GMainContext *context;
|
|
|
|
GMainLoop *loop;
|
|
|
|
|
|
|
|
GList *connections;
|
|
|
|
} DmpData;
|
|
|
|
|
|
|
|
static void
|
|
|
|
dmp_data_free (DmpData *data)
|
|
|
|
{
|
|
|
|
g_main_loop_unref (data->loop);
|
|
|
|
g_main_context_unref (data->context);
|
|
|
|
g_object_unref (data->server);
|
2012-01-02 15:20:42 +01:00
|
|
|
g_list_free_full (data->connections, g_object_unref);
|
2010-06-30 17:43:42 +02:00
|
|
|
g_free (data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dmp_on_method_call (GDBusConnection *connection,
|
|
|
|
const gchar *sender,
|
|
|
|
const gchar *object_path,
|
|
|
|
const gchar *interface_name,
|
|
|
|
const gchar *method_name,
|
|
|
|
GVariant *parameters,
|
|
|
|
GDBusMethodInvocation *invocation,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
//DmpData *data = user_data;
|
|
|
|
gint32 first;
|
|
|
|
gint32 second;
|
|
|
|
g_variant_get (parameters,
|
|
|
|
"(ii)",
|
|
|
|
&first,
|
|
|
|
&second);
|
|
|
|
g_dbus_method_invocation_return_value (invocation,
|
|
|
|
g_variant_new ("(i)", first + second));
|
|
|
|
}
|
|
|
|
|
|
|
|
static const GDBusInterfaceVTable dmp_interface_vtable =
|
|
|
|
{
|
|
|
|
dmp_on_method_call,
|
|
|
|
NULL, /* get_property */
|
|
|
|
NULL /* set_property */
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* Runs in thread we created GDBusServer in (since we didn't pass G_DBUS_SERVER_FLAGS_RUN_IN_THREAD) */
|
2010-09-09 20:00:46 +02:00
|
|
|
static gboolean
|
2010-06-30 17:43:42 +02:00
|
|
|
dmp_on_new_connection (GDBusServer *server,
|
|
|
|
GDBusConnection *connection,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
DmpData *data = user_data;
|
|
|
|
GDBusNodeInfo *node;
|
|
|
|
GError *error;
|
|
|
|
|
|
|
|
/* accept the connection */
|
|
|
|
data->connections = g_list_prepend (data->connections, g_object_ref (connection));
|
|
|
|
|
|
|
|
error = NULL;
|
|
|
|
node = g_dbus_node_info_new_for_xml ("<node>"
|
|
|
|
" <interface name='org.gtk.GDBus.DmpInterface'>"
|
|
|
|
" <method name='AddPair'>"
|
|
|
|
" <arg type='i' name='first' direction='in'/>"
|
|
|
|
" <arg type='i' name='second' direction='in'/>"
|
|
|
|
" <arg type='i' name='sum' direction='out'/>"
|
|
|
|
" </method>"
|
|
|
|
" </interface>"
|
|
|
|
"</node>",
|
|
|
|
&error);
|
|
|
|
g_assert_no_error (error);
|
|
|
|
|
|
|
|
/* sleep 100ms before exporting an object - this is to test that
|
|
|
|
* G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING really works
|
|
|
|
* (GDBusServer uses this feature).
|
|
|
|
*/
|
|
|
|
usleep (100 * 1000);
|
|
|
|
|
|
|
|
/* export an object */
|
|
|
|
error = NULL;
|
|
|
|
g_dbus_connection_register_object (connection,
|
|
|
|
"/dmp/test",
|
|
|
|
node->interfaces[0],
|
|
|
|
&dmp_interface_vtable,
|
|
|
|
data,
|
|
|
|
NULL,
|
|
|
|
&error);
|
2010-06-30 18:19:28 +02:00
|
|
|
g_dbus_node_info_unref (node);
|
2010-09-09 20:00:46 +02:00
|
|
|
|
|
|
|
return TRUE;
|
2010-06-30 17:43:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static gpointer
|
|
|
|
dmp_thread_func (gpointer user_data)
|
|
|
|
{
|
|
|
|
DmpData *data = user_data;
|
|
|
|
GError *error;
|
|
|
|
gchar *guid;
|
|
|
|
|
|
|
|
data->context = g_main_context_new ();
|
|
|
|
g_main_context_push_thread_default (data->context);
|
|
|
|
|
|
|
|
error = NULL;
|
|
|
|
guid = g_dbus_generate_guid ();
|
2011-08-27 17:33:43 +02:00
|
|
|
data->server = g_dbus_server_new_sync (tmp_address,
|
2010-06-30 17:43:42 +02:00
|
|
|
G_DBUS_SERVER_FLAGS_NONE,
|
|
|
|
guid,
|
|
|
|
NULL, /* GDBusAuthObserver */
|
|
|
|
NULL, /* GCancellable */
|
|
|
|
&error);
|
|
|
|
g_assert_no_error (error);
|
|
|
|
g_signal_connect (data->server,
|
|
|
|
"new-connection",
|
|
|
|
G_CALLBACK (dmp_on_new_connection),
|
|
|
|
data);
|
|
|
|
|
|
|
|
g_dbus_server_start (data->server);
|
|
|
|
|
|
|
|
data->loop = g_main_loop_new (data->context, FALSE);
|
|
|
|
g_main_loop_run (data->loop);
|
|
|
|
|
|
|
|
g_main_context_pop_thread_default (data->context);
|
|
|
|
|
|
|
|
g_free (guid);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
delayed_message_processing (void)
|
|
|
|
{
|
|
|
|
GError *error;
|
|
|
|
DmpData *data;
|
|
|
|
GThread *service_thread;
|
|
|
|
guint n;
|
|
|
|
|
|
|
|
data = g_new0 (DmpData, 1);
|
|
|
|
|
2011-10-10 15:49:50 +02:00
|
|
|
service_thread = g_thread_new ("dmp",
|
|
|
|
dmp_thread_func,
|
2011-10-13 07:00:57 +02:00
|
|
|
data);
|
2010-06-30 17:43:42 +02:00
|
|
|
while (data->server == NULL || !g_dbus_server_is_active (data->server))
|
|
|
|
g_thread_yield ();
|
|
|
|
|
|
|
|
for (n = 0; n < 5; n++)
|
|
|
|
{
|
|
|
|
GDBusConnection *c;
|
|
|
|
GVariant *res;
|
|
|
|
gint32 val;
|
|
|
|
|
|
|
|
error = NULL;
|
|
|
|
c = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (data->server),
|
|
|
|
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
|
|
|
|
NULL, /* GDBusAuthObserver */
|
|
|
|
NULL, /* GCancellable */
|
|
|
|
&error);
|
|
|
|
g_assert_no_error (error);
|
|
|
|
|
|
|
|
error = NULL;
|
|
|
|
res = g_dbus_connection_call_sync (c,
|
|
|
|
NULL, /* bus name */
|
|
|
|
"/dmp/test",
|
|
|
|
"org.gtk.GDBus.DmpInterface",
|
|
|
|
"AddPair",
|
|
|
|
g_variant_new ("(ii)", 2, n),
|
|
|
|
G_VARIANT_TYPE ("(i)"),
|
|
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
|
|
-1, /* timeout_msec */
|
|
|
|
NULL, /* GCancellable */
|
|
|
|
&error);
|
|
|
|
g_assert_no_error (error);
|
|
|
|
g_variant_get (res, "(i)", &val);
|
|
|
|
g_assert_cmpint (val, ==, 2 + n);
|
|
|
|
g_variant_unref (res);
|
|
|
|
g_object_unref (c);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_main_loop_quit (data->loop);
|
|
|
|
g_thread_join (service_thread);
|
|
|
|
dmp_data_free (data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------------------------------------- */
|
|
|
|
|
2010-07-16 19:19:48 +02:00
|
|
|
static gboolean
|
|
|
|
nonce_tcp_on_authorize_authenticated_peer (GDBusAuthObserver *observer,
|
|
|
|
GIOStream *stream,
|
|
|
|
GCredentials *credentials,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
PeerData *data = user_data;
|
|
|
|
gboolean authorized;
|
|
|
|
|
|
|
|
data->num_connection_attempts++;
|
|
|
|
|
|
|
|
authorized = TRUE;
|
|
|
|
if (!data->accept_connection)
|
|
|
|
{
|
|
|
|
authorized = FALSE;
|
|
|
|
g_main_loop_quit (loop);
|
|
|
|
}
|
|
|
|
|
|
|
|
return authorized;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Runs in thread we created GDBusServer in (since we didn't pass G_DBUS_SERVER_FLAGS_RUN_IN_THREAD) */
|
2010-09-09 20:00:46 +02:00
|
|
|
static gboolean
|
2010-07-16 19:19:48 +02:00
|
|
|
nonce_tcp_on_new_connection (GDBusServer *server,
|
|
|
|
GDBusConnection *connection,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
PeerData *data = user_data;
|
|
|
|
|
|
|
|
g_ptr_array_add (data->current_connections, g_object_ref (connection));
|
|
|
|
|
|
|
|
g_main_loop_quit (loop);
|
2010-09-09 20:00:46 +02:00
|
|
|
|
|
|
|
return TRUE;
|
2010-07-16 19:19:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static gpointer
|
|
|
|
nonce_tcp_service_thread_func (gpointer user_data)
|
|
|
|
{
|
|
|
|
PeerData *data = user_data;
|
|
|
|
GMainContext *service_context;
|
|
|
|
GDBusAuthObserver *observer;
|
|
|
|
GError *error;
|
|
|
|
|
|
|
|
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 ("nonce-tcp:",
|
|
|
|
G_DBUS_SERVER_FLAGS_NONE,
|
|
|
|
test_guid,
|
|
|
|
observer,
|
|
|
|
NULL, /* cancellable */
|
|
|
|
&error);
|
|
|
|
g_assert_no_error (error);
|
|
|
|
|
|
|
|
g_signal_connect (server,
|
|
|
|
"new-connection",
|
|
|
|
G_CALLBACK (nonce_tcp_on_new_connection),
|
|
|
|
data);
|
|
|
|
g_signal_connect (observer,
|
|
|
|
"authorize-authenticated-peer",
|
|
|
|
G_CALLBACK (nonce_tcp_on_authorize_authenticated_peer),
|
|
|
|
data);
|
|
|
|
g_object_unref (observer);
|
|
|
|
|
|
|
|
g_dbus_server_start (server);
|
|
|
|
|
gdbus-peer test: let GDBusServer start before notifying main thread
When running the nonce-tcp and tcp-anonymous tests in one run
of gdbus-peer, or running one of them twice via command-line options
"-p /gdbus/tcp-anonymous -p /gdbus/tcp-anonymous", the one run second
would sometimes fail to connect with ECONNRESET.
Adding more debug messages revealed that in the successful case,
g_main_loop_run() was executed in the server thread first:
# tcp-anonymous: server thread: listening on tcp:host=localhost,port=53517
# tcp-anonymous: server thread: starting server...
# tcp-anonymous: server thread: creating main loop...
# tcp-anonymous: server thread: running main loop...
# tcp-anonymous: main thread: trying tcp:host=localhost,port=53517...
# tcp-anonymous: main thread: waiting for server thread...
but in the failing case, the main thread attempted to connect
before the call to g_main_loop_run() in the server thread:
# tcp-anonymous: server thread: listening on tcp:host=localhost,port=40659
# tcp-anonymous: server thread: starting server...
# tcp-anonymous: server thread: creating main loop...
# tcp-anonymous: main thread: trying tcp:host=localhost,port=40659...
# tcp-anonymous: server thread: running main loop...
(The log message "creating main loop" was immediately before
create_service_loop(), and "running main loop" was immediately
before g_main_loop_run().)
To ensure that the GDBusServer has a chance to start accepting
connections before the main thread tries to connect to it, do not
tell the main thread about the service_loop immediately, but instead
defer it to an idle.
Bug: https://bugzilla.gnome.org/show_bug.cgi?id=749079
Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
Reviewed-by: Philip Withnall <philip.withnall@collabora.co.uk>
2015-05-07 17:45:48 +02:00
|
|
|
run_service_loop (service_context);
|
2010-07-16 19:19:48 +02:00
|
|
|
|
|
|
|
g_main_context_pop_thread_default (service_context);
|
|
|
|
|
2013-05-22 18:41:32 +02:00
|
|
|
teardown_service_loop ();
|
2010-07-16 19:19:48 +02:00
|
|
|
g_main_context_unref (service_context);
|
|
|
|
|
|
|
|
/* test code specifically unrefs the server - see below */
|
|
|
|
g_assert (server == NULL);
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_nonce_tcp (void)
|
|
|
|
{
|
|
|
|
PeerData data;
|
|
|
|
GError *error;
|
|
|
|
GThread *service_thread;
|
|
|
|
GDBusConnection *c;
|
|
|
|
gchar *s;
|
|
|
|
gchar *nonce_file;
|
|
|
|
gboolean res;
|
|
|
|
const gchar *address;
|
|
|
|
|
|
|
|
memset (&data, '\0', sizeof (PeerData));
|
|
|
|
data.current_connections = g_ptr_array_new_with_free_func (g_object_unref);
|
|
|
|
|
|
|
|
error = NULL;
|
|
|
|
server = NULL;
|
2011-10-10 15:49:50 +02:00
|
|
|
service_thread = g_thread_new ("nonce-tcp-service",
|
|
|
|
nonce_tcp_service_thread_func,
|
2011-10-13 07:00:57 +02:00
|
|
|
&data);
|
2013-05-22 18:41:32 +02:00
|
|
|
await_service_loop ();
|
2010-07-16 19:19:48 +02:00
|
|
|
g_assert (server != NULL);
|
|
|
|
|
|
|
|
/* bring up a connection and accept it */
|
|
|
|
data.accept_connection = TRUE;
|
|
|
|
error = NULL;
|
|
|
|
c = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (server),
|
|
|
|
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
|
|
|
|
NULL, /* GDBusAuthObserver */
|
|
|
|
NULL, /* cancellable */
|
|
|
|
&error);
|
|
|
|
g_assert_no_error (error);
|
|
|
|
g_assert (c != NULL);
|
|
|
|
while (data.current_connections->len < 1)
|
2011-06-20 22:32:03 +02:00
|
|
|
g_thread_yield ();
|
2010-07-16 19:19:48 +02:00
|
|
|
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);
|
|
|
|
g_assert_cmpstr (g_dbus_connection_get_guid (c), ==, test_guid);
|
|
|
|
g_object_unref (c);
|
|
|
|
|
|
|
|
/* now, try to subvert the nonce file (this assumes noncefile is the last key/value pair)
|
|
|
|
*/
|
|
|
|
|
|
|
|
address = g_dbus_server_get_client_address (server);
|
|
|
|
|
|
|
|
s = strstr (address, "noncefile=");
|
|
|
|
g_assert (s != NULL);
|
|
|
|
s += sizeof "noncefile=" - 1;
|
|
|
|
nonce_file = g_strdup (s);
|
|
|
|
|
|
|
|
/* First try invalid data in the nonce file - this will actually
|
|
|
|
* make the client send this and the server will reject it. The way
|
|
|
|
* it works is that if the nonce doesn't match, the server will
|
|
|
|
* simply close the connection. So, from the client point of view,
|
|
|
|
* we can see a variety of errors.
|
|
|
|
*/
|
|
|
|
error = NULL;
|
|
|
|
res = g_file_set_contents (nonce_file,
|
|
|
|
"0123456789012345",
|
|
|
|
-1,
|
|
|
|
&error);
|
|
|
|
g_assert_no_error (error);
|
|
|
|
g_assert (res);
|
|
|
|
c = g_dbus_connection_new_for_address_sync (address,
|
|
|
|
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
|
|
|
|
NULL, /* GDBusAuthObserver */
|
|
|
|
NULL, /* cancellable */
|
|
|
|
&error);
|
|
|
|
_g_assert_error_domain (error, G_IO_ERROR);
|
Plug some mem leaks in gdbus-peer test
==29535== 56 (24 direct, 32 indirect) bytes in 1 blocks are definitely lost in loss record 1,112 of 1,264
==29535== at 0x4005BDC: malloc (vg_replace_malloc.c:195)
==29535== by 0x4057094: g_malloc (gmem.c:134)
==29535== by 0x406F2D6: g_slice_alloc (gslice.c:836)
==29535== by 0x406F364: g_slice_copy (gslice.c:858)
==29535== by 0x403A9B2: g_error_copy (gerror.c:160)
==29535== by 0x42066D3: initable_init (gdbusconnection.c:2314)
==29535== by 0x41A73E5: g_initable_init (ginitable.c:105)
==29535== by 0x41A7587: g_initable_new_valist (ginitable.c:218)
==29535== by 0x41A742A: g_initable_new (ginitable.c:138)
==29535== by 0x4206DCC: g_dbus_connection_new_for_address_sync (gdbusconnection.c:2585)
==29535== by 0x804D63A: test_nonce_tcp (gdbus-peer.c:1229)
==29535== 107 (24 direct, 83 indirect) bytes in 1 blocks are definitely lost in loss record 1,188 of 1,264
==29535== at 0x4005BDC: malloc (vg_replace_malloc.c:195)
==29535== by 0x4057094: g_malloc (gmem.c:134)
==29535== by 0x406F2D6: g_slice_alloc (gslice.c:836)
==29535== by 0x406F364: g_slice_copy (gslice.c:858)
==29535== by 0x403A9B2: g_error_copy (gerror.c:160)
==29535== by 0x42066D3: initable_init (gdbusconnection.c:2314)
==29535== by 0x41A73E5: g_initable_init (ginitable.c:105)
==29535== by 0x41A7587: g_initable_new_valist (ginitable.c:218)
==29535== by 0x41A742A: g_initable_new (ginitable.c:138)
==29535== by 0x4206DCC: g_dbus_connection_new_for_address_sync (gdbusconnection.c:2585)
==29535== by 0x804D8E8: test_nonce_tcp (gdbus-peer.c:1259)
==29535== 112 (24 direct, 88 indirect) bytes in 1 blocks are definitely lost in loss record 1,193 of 1,264
==29535== at 0x4005BDC: malloc (vg_replace_malloc.c:195)
==29535== by 0x4057094: g_malloc (gmem.c:134)
==29535== by 0x406F2D6: g_slice_alloc (gslice.c:836)
==29535== by 0x406F364: g_slice_copy (gslice.c:858)
==29535== by 0x403A9B2: g_error_copy (gerror.c:160)
==29535== by 0x42066D3: initable_init (gdbusconnection.c:2314)
==29535== by 0x41A73E5: g_initable_init (ginitable.c:105)
==29535== by 0x41A7587: g_initable_new_valist (ginitable.c:218)
==29535== by 0x41A742A: g_initable_new (ginitable.c:138)
==29535== by 0x4206DCC: g_dbus_connection_new_for_address_sync (gdbusconnection.c:2585)
==29535== by 0x804D79A: test_nonce_tcp (gdbus-peer.c:1248)
==29535== 73 (24 direct, 49 indirect) bytes in 1 blocks are definitely lost in loss record 1,152 of 1,264
==29535== at 0x4005BDC: malloc (vg_replace_malloc.c:195)
==29535== by 0x4057094: g_malloc (gmem.c:134)
==29535== by 0x406F2D6: g_slice_alloc (gslice.c:836)
==29535== by 0x406F364: g_slice_copy (gslice.c:858)
==29535== by 0x403A9B2: g_error_copy (gerror.c:160)
==29535== by 0x42066D3: initable_init (gdbusconnection.c:2314)
==29535== by 0x41A73E5: g_initable_init (ginitable.c:105)
==29535== by 0x41A7587: g_initable_new_valist (ginitable.c:218)
==29535== by 0x41A742A: g_initable_new (ginitable.c:138)
==29535== by 0x4206DCC: g_dbus_connection_new_for_address_sync (gdbusconnection.c:2585)
==29535== by 0x804C6CE: test_peer (gdbus-peer.c:803)
Bug #628331.
2010-09-03 22:03:48 +02:00
|
|
|
g_error_free (error);
|
2010-07-16 19:19:48 +02:00
|
|
|
g_assert (c == NULL);
|
|
|
|
|
|
|
|
/* Then try with a nonce-file of incorrect length - this will make
|
|
|
|
* the client complain - we won't even try connecting to the server
|
|
|
|
* for this
|
|
|
|
*/
|
|
|
|
error = NULL;
|
|
|
|
res = g_file_set_contents (nonce_file,
|
|
|
|
"0123456789012345_",
|
|
|
|
-1,
|
|
|
|
&error);
|
|
|
|
g_assert_no_error (error);
|
|
|
|
g_assert (res);
|
|
|
|
c = g_dbus_connection_new_for_address_sync (address,
|
|
|
|
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
|
|
|
|
NULL, /* GDBusAuthObserver */
|
|
|
|
NULL, /* cancellable */
|
|
|
|
&error);
|
|
|
|
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
|
Plug some mem leaks in gdbus-peer test
==29535== 56 (24 direct, 32 indirect) bytes in 1 blocks are definitely lost in loss record 1,112 of 1,264
==29535== at 0x4005BDC: malloc (vg_replace_malloc.c:195)
==29535== by 0x4057094: g_malloc (gmem.c:134)
==29535== by 0x406F2D6: g_slice_alloc (gslice.c:836)
==29535== by 0x406F364: g_slice_copy (gslice.c:858)
==29535== by 0x403A9B2: g_error_copy (gerror.c:160)
==29535== by 0x42066D3: initable_init (gdbusconnection.c:2314)
==29535== by 0x41A73E5: g_initable_init (ginitable.c:105)
==29535== by 0x41A7587: g_initable_new_valist (ginitable.c:218)
==29535== by 0x41A742A: g_initable_new (ginitable.c:138)
==29535== by 0x4206DCC: g_dbus_connection_new_for_address_sync (gdbusconnection.c:2585)
==29535== by 0x804D63A: test_nonce_tcp (gdbus-peer.c:1229)
==29535== 107 (24 direct, 83 indirect) bytes in 1 blocks are definitely lost in loss record 1,188 of 1,264
==29535== at 0x4005BDC: malloc (vg_replace_malloc.c:195)
==29535== by 0x4057094: g_malloc (gmem.c:134)
==29535== by 0x406F2D6: g_slice_alloc (gslice.c:836)
==29535== by 0x406F364: g_slice_copy (gslice.c:858)
==29535== by 0x403A9B2: g_error_copy (gerror.c:160)
==29535== by 0x42066D3: initable_init (gdbusconnection.c:2314)
==29535== by 0x41A73E5: g_initable_init (ginitable.c:105)
==29535== by 0x41A7587: g_initable_new_valist (ginitable.c:218)
==29535== by 0x41A742A: g_initable_new (ginitable.c:138)
==29535== by 0x4206DCC: g_dbus_connection_new_for_address_sync (gdbusconnection.c:2585)
==29535== by 0x804D8E8: test_nonce_tcp (gdbus-peer.c:1259)
==29535== 112 (24 direct, 88 indirect) bytes in 1 blocks are definitely lost in loss record 1,193 of 1,264
==29535== at 0x4005BDC: malloc (vg_replace_malloc.c:195)
==29535== by 0x4057094: g_malloc (gmem.c:134)
==29535== by 0x406F2D6: g_slice_alloc (gslice.c:836)
==29535== by 0x406F364: g_slice_copy (gslice.c:858)
==29535== by 0x403A9B2: g_error_copy (gerror.c:160)
==29535== by 0x42066D3: initable_init (gdbusconnection.c:2314)
==29535== by 0x41A73E5: g_initable_init (ginitable.c:105)
==29535== by 0x41A7587: g_initable_new_valist (ginitable.c:218)
==29535== by 0x41A742A: g_initable_new (ginitable.c:138)
==29535== by 0x4206DCC: g_dbus_connection_new_for_address_sync (gdbusconnection.c:2585)
==29535== by 0x804D79A: test_nonce_tcp (gdbus-peer.c:1248)
==29535== 73 (24 direct, 49 indirect) bytes in 1 blocks are definitely lost in loss record 1,152 of 1,264
==29535== at 0x4005BDC: malloc (vg_replace_malloc.c:195)
==29535== by 0x4057094: g_malloc (gmem.c:134)
==29535== by 0x406F2D6: g_slice_alloc (gslice.c:836)
==29535== by 0x406F364: g_slice_copy (gslice.c:858)
==29535== by 0x403A9B2: g_error_copy (gerror.c:160)
==29535== by 0x42066D3: initable_init (gdbusconnection.c:2314)
==29535== by 0x41A73E5: g_initable_init (ginitable.c:105)
==29535== by 0x41A7587: g_initable_new_valist (ginitable.c:218)
==29535== by 0x41A742A: g_initable_new (ginitable.c:138)
==29535== by 0x4206DCC: g_dbus_connection_new_for_address_sync (gdbusconnection.c:2585)
==29535== by 0x804C6CE: test_peer (gdbus-peer.c:803)
Bug #628331.
2010-09-03 22:03:48 +02:00
|
|
|
g_error_free (error);
|
2010-07-16 19:19:48 +02:00
|
|
|
g_assert (c == NULL);
|
|
|
|
|
|
|
|
/* Finally try with no nonce-file at all */
|
|
|
|
g_assert_cmpint (g_unlink (nonce_file), ==, 0);
|
|
|
|
error = NULL;
|
|
|
|
c = g_dbus_connection_new_for_address_sync (address,
|
|
|
|
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
|
|
|
|
NULL, /* GDBusAuthObserver */
|
|
|
|
NULL, /* cancellable */
|
|
|
|
&error);
|
|
|
|
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
|
Plug some mem leaks in gdbus-peer test
==29535== 56 (24 direct, 32 indirect) bytes in 1 blocks are definitely lost in loss record 1,112 of 1,264
==29535== at 0x4005BDC: malloc (vg_replace_malloc.c:195)
==29535== by 0x4057094: g_malloc (gmem.c:134)
==29535== by 0x406F2D6: g_slice_alloc (gslice.c:836)
==29535== by 0x406F364: g_slice_copy (gslice.c:858)
==29535== by 0x403A9B2: g_error_copy (gerror.c:160)
==29535== by 0x42066D3: initable_init (gdbusconnection.c:2314)
==29535== by 0x41A73E5: g_initable_init (ginitable.c:105)
==29535== by 0x41A7587: g_initable_new_valist (ginitable.c:218)
==29535== by 0x41A742A: g_initable_new (ginitable.c:138)
==29535== by 0x4206DCC: g_dbus_connection_new_for_address_sync (gdbusconnection.c:2585)
==29535== by 0x804D63A: test_nonce_tcp (gdbus-peer.c:1229)
==29535== 107 (24 direct, 83 indirect) bytes in 1 blocks are definitely lost in loss record 1,188 of 1,264
==29535== at 0x4005BDC: malloc (vg_replace_malloc.c:195)
==29535== by 0x4057094: g_malloc (gmem.c:134)
==29535== by 0x406F2D6: g_slice_alloc (gslice.c:836)
==29535== by 0x406F364: g_slice_copy (gslice.c:858)
==29535== by 0x403A9B2: g_error_copy (gerror.c:160)
==29535== by 0x42066D3: initable_init (gdbusconnection.c:2314)
==29535== by 0x41A73E5: g_initable_init (ginitable.c:105)
==29535== by 0x41A7587: g_initable_new_valist (ginitable.c:218)
==29535== by 0x41A742A: g_initable_new (ginitable.c:138)
==29535== by 0x4206DCC: g_dbus_connection_new_for_address_sync (gdbusconnection.c:2585)
==29535== by 0x804D8E8: test_nonce_tcp (gdbus-peer.c:1259)
==29535== 112 (24 direct, 88 indirect) bytes in 1 blocks are definitely lost in loss record 1,193 of 1,264
==29535== at 0x4005BDC: malloc (vg_replace_malloc.c:195)
==29535== by 0x4057094: g_malloc (gmem.c:134)
==29535== by 0x406F2D6: g_slice_alloc (gslice.c:836)
==29535== by 0x406F364: g_slice_copy (gslice.c:858)
==29535== by 0x403A9B2: g_error_copy (gerror.c:160)
==29535== by 0x42066D3: initable_init (gdbusconnection.c:2314)
==29535== by 0x41A73E5: g_initable_init (ginitable.c:105)
==29535== by 0x41A7587: g_initable_new_valist (ginitable.c:218)
==29535== by 0x41A742A: g_initable_new (ginitable.c:138)
==29535== by 0x4206DCC: g_dbus_connection_new_for_address_sync (gdbusconnection.c:2585)
==29535== by 0x804D79A: test_nonce_tcp (gdbus-peer.c:1248)
==29535== 73 (24 direct, 49 indirect) bytes in 1 blocks are definitely lost in loss record 1,152 of 1,264
==29535== at 0x4005BDC: malloc (vg_replace_malloc.c:195)
==29535== by 0x4057094: g_malloc (gmem.c:134)
==29535== by 0x406F2D6: g_slice_alloc (gslice.c:836)
==29535== by 0x406F364: g_slice_copy (gslice.c:858)
==29535== by 0x403A9B2: g_error_copy (gerror.c:160)
==29535== by 0x42066D3: initable_init (gdbusconnection.c:2314)
==29535== by 0x41A73E5: g_initable_init (ginitable.c:105)
==29535== by 0x41A7587: g_initable_new_valist (ginitable.c:218)
==29535== by 0x41A742A: g_initable_new (ginitable.c:138)
==29535== by 0x4206DCC: g_dbus_connection_new_for_address_sync (gdbusconnection.c:2585)
==29535== by 0x804C6CE: test_peer (gdbus-peer.c:803)
Bug #628331.
2010-09-03 22:03:48 +02:00
|
|
|
g_error_free (error);
|
2010-07-16 19:19:48 +02:00
|
|
|
g_assert (c == NULL);
|
|
|
|
|
|
|
|
g_free (nonce_file);
|
|
|
|
|
|
|
|
g_dbus_server_stop (server);
|
|
|
|
g_object_unref (server);
|
|
|
|
server = NULL;
|
|
|
|
|
|
|
|
g_main_loop_quit (service_loop);
|
|
|
|
g_thread_join (service_thread);
|
2018-06-27 10:57:21 +02:00
|
|
|
|
|
|
|
g_ptr_array_unref (data.current_connections);
|
2010-07-16 19:19:48 +02:00
|
|
|
}
|
|
|
|
|
2010-07-29 08:20:29 +02:00
|
|
|
static void
|
|
|
|
test_credentials (void)
|
|
|
|
{
|
|
|
|
GCredentials *c1, *c2;
|
|
|
|
GError *error;
|
|
|
|
gchar *desc;
|
|
|
|
|
|
|
|
c1 = g_credentials_new ();
|
|
|
|
c2 = g_credentials_new ();
|
|
|
|
|
|
|
|
error = NULL;
|
|
|
|
if (g_credentials_set_unix_user (c2, getuid (), &error))
|
|
|
|
g_assert_no_error (error);
|
|
|
|
|
|
|
|
g_clear_error (&error);
|
|
|
|
g_assert (g_credentials_is_same_user (c1, c2, &error));
|
|
|
|
g_assert_no_error (error);
|
|
|
|
|
|
|
|
desc = g_credentials_to_string (c1);
|
|
|
|
g_assert (desc != NULL);
|
|
|
|
g_free (desc);
|
|
|
|
|
|
|
|
g_object_unref (c1);
|
|
|
|
g_object_unref (c2);
|
|
|
|
}
|
|
|
|
|
2010-07-16 19:19:48 +02:00
|
|
|
/* ---------------------------------------------------------------------------------------------------- */
|
|
|
|
|
2011-04-14 00:21:16 +02:00
|
|
|
static gboolean
|
|
|
|
tcp_anonymous_on_new_connection (GDBusServer *server,
|
|
|
|
GDBusConnection *connection,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
gboolean *seen_connection = user_data;
|
|
|
|
*seen_connection = TRUE;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gpointer
|
|
|
|
tcp_anonymous_service_thread_func (gpointer user_data)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
|
gdbus-peer test: let GDBusServer start before notifying main thread
When running the nonce-tcp and tcp-anonymous tests in one run
of gdbus-peer, or running one of them twice via command-line options
"-p /gdbus/tcp-anonymous -p /gdbus/tcp-anonymous", the one run second
would sometimes fail to connect with ECONNRESET.
Adding more debug messages revealed that in the successful case,
g_main_loop_run() was executed in the server thread first:
# tcp-anonymous: server thread: listening on tcp:host=localhost,port=53517
# tcp-anonymous: server thread: starting server...
# tcp-anonymous: server thread: creating main loop...
# tcp-anonymous: server thread: running main loop...
# tcp-anonymous: main thread: trying tcp:host=localhost,port=53517...
# tcp-anonymous: main thread: waiting for server thread...
but in the failing case, the main thread attempted to connect
before the call to g_main_loop_run() in the server thread:
# tcp-anonymous: server thread: listening on tcp:host=localhost,port=40659
# tcp-anonymous: server thread: starting server...
# tcp-anonymous: server thread: creating main loop...
# tcp-anonymous: main thread: trying tcp:host=localhost,port=40659...
# tcp-anonymous: server thread: running main loop...
(The log message "creating main loop" was immediately before
create_service_loop(), and "running main loop" was immediately
before g_main_loop_run().)
To ensure that the GDBusServer has a chance to start accepting
connections before the main thread tries to connect to it, do not
tell the main thread about the service_loop immediately, but instead
defer it to an idle.
Bug: https://bugzilla.gnome.org/show_bug.cgi?id=749079
Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
Reviewed-by: Philip Withnall <philip.withnall@collabora.co.uk>
2015-05-07 17:45:48 +02:00
|
|
|
run_service_loop (service_context);
|
2011-04-14 00:21:16 +02:00
|
|
|
|
|
|
|
g_main_context_pop_thread_default (service_context);
|
|
|
|
|
2013-05-22 18:41:32 +02:00
|
|
|
teardown_service_loop ();
|
2011-04-14 00:21:16 +02:00
|
|
|
g_main_context_unref (service_context);
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_tcp_anonymous (void)
|
|
|
|
{
|
|
|
|
gboolean seen_connection;
|
|
|
|
GThread *service_thread;
|
|
|
|
GDBusConnection *connection;
|
|
|
|
GError *error;
|
|
|
|
|
|
|
|
seen_connection = FALSE;
|
2011-10-10 15:49:50 +02:00
|
|
|
service_thread = g_thread_new ("tcp-anon-service",
|
|
|
|
tcp_anonymous_service_thread_func,
|
2011-10-13 07:00:57 +02:00
|
|
|
&seen_connection);
|
2013-05-22 18:41:32 +02:00
|
|
|
await_service_loop ();
|
2011-04-14 00:21:16 +02:00
|
|
|
g_assert (server != NULL);
|
|
|
|
|
|
|
|
error = NULL;
|
|
|
|
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);
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------------------------------------- */
|
|
|
|
|
2011-12-02 17:20:21 +01:00
|
|
|
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))
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2015-05-11 18:03:00 +02:00
|
|
|
/* g_printerr ("Client connected.\n" */
|
2011-12-02 17:20:21 +01:00
|
|
|
/* "Negotiated capabilities: unix-fd-passing=%d\n", */
|
|
|
|
/* g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING); */
|
|
|
|
|
|
|
|
g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (animal), connection,
|
|
|
|
"/Example/Animals/000", &error);
|
|
|
|
g_assert_no_error (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_dbus_server_start (codegen_server);
|
|
|
|
|
|
|
|
g_signal_connect (codegen_server, "new-connection",
|
|
|
|
G_CALLBACK (codegen_on_new_connection),
|
|
|
|
animal);
|
|
|
|
|
gdbus-peer test: let GDBusServer start before notifying main thread
When running the nonce-tcp and tcp-anonymous tests in one run
of gdbus-peer, or running one of them twice via command-line options
"-p /gdbus/tcp-anonymous -p /gdbus/tcp-anonymous", the one run second
would sometimes fail to connect with ECONNRESET.
Adding more debug messages revealed that in the successful case,
g_main_loop_run() was executed in the server thread first:
# tcp-anonymous: server thread: listening on tcp:host=localhost,port=53517
# tcp-anonymous: server thread: starting server...
# tcp-anonymous: server thread: creating main loop...
# tcp-anonymous: server thread: running main loop...
# tcp-anonymous: main thread: trying tcp:host=localhost,port=53517...
# tcp-anonymous: main thread: waiting for server thread...
but in the failing case, the main thread attempted to connect
before the call to g_main_loop_run() in the server thread:
# tcp-anonymous: server thread: listening on tcp:host=localhost,port=40659
# tcp-anonymous: server thread: starting server...
# tcp-anonymous: server thread: creating main loop...
# tcp-anonymous: main thread: trying tcp:host=localhost,port=40659...
# tcp-anonymous: server thread: running main loop...
(The log message "creating main loop" was immediately before
create_service_loop(), and "running main loop" was immediately
before g_main_loop_run().)
To ensure that the GDBusServer has a chance to start accepting
connections before the main thread tries to connect to it, do not
tell the main thread about the service_loop immediately, but instead
defer it to an idle.
Bug: https://bugzilla.gnome.org/show_bug.cgi?id=749079
Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
Reviewed-by: Philip Withnall <philip.withnall@collabora.co.uk>
2015-05-07 17:45:48 +02:00
|
|
|
run_service_loop (service_context);
|
2011-12-02 17:20:21 +01:00
|
|
|
|
|
|
|
g_object_unref (animal);
|
|
|
|
|
|
|
|
g_main_context_pop_thread_default (service_context);
|
|
|
|
|
2013-05-22 18:41:32 +02:00
|
|
|
teardown_service_loop ();
|
2011-12-02 17:20:21 +01:00
|
|
|
g_main_context_unref (service_context);
|
|
|
|
|
|
|
|
g_dbus_server_stop (codegen_server);
|
|
|
|
g_object_unref (codegen_server);
|
|
|
|
codegen_server = NULL;
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-11-02 00:35:38 +01:00
|
|
|
static gboolean
|
2011-12-02 17:20:21 +01:00
|
|
|
codegen_quit_mainloop_timeout (gpointer data)
|
|
|
|
{
|
|
|
|
g_main_loop_quit (loop);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
codegen_test_peer (void)
|
|
|
|
{
|
|
|
|
GDBusConnection *connection;
|
|
|
|
ExampleAnimal *animal1, *animal2;
|
|
|
|
GThread *service_thread;
|
|
|
|
GError *error = NULL;
|
|
|
|
GVariant *value;
|
2013-12-24 06:05:01 +01:00
|
|
|
const gchar *s;
|
2011-12-02 17:20:21 +01:00
|
|
|
|
|
|
|
/* 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);
|
2013-05-22 18:41:32 +02:00
|
|
|
await_service_loop ();
|
2011-12-02 17:20:21 +01:00
|
|
|
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);
|
|
|
|
|
2013-12-24 06:05:01 +01:00
|
|
|
/* 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);
|
2018-02-19 12:11:36 +01:00
|
|
|
g_test_message ("Machine ID: %s", s);
|
2018-02-19 15:36:42 +01:00
|
|
|
/* It's valid for machine-id inside containers to be empty, so we
|
|
|
|
* need to test for that possibility
|
|
|
|
*/
|
|
|
|
g_assert ((s == NULL || *s == '\0') || g_dbus_is_guid (s));
|
2013-12-24 06:05:01 +01:00
|
|
|
g_variant_unref (value);
|
|
|
|
|
2011-12-02 17:20:21 +01:00
|
|
|
/* 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);
|
2018-06-27 10:57:21 +02:00
|
|
|
g_clear_error (&error);
|
2011-12-02 17:20:21 +01:00
|
|
|
|
|
|
|
g_object_unref (animal1);
|
|
|
|
g_object_unref (animal2);
|
|
|
|
g_thread_join (service_thread);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
2010-05-06 20:13:59 +02:00
|
|
|
int
|
|
|
|
main (int argc,
|
|
|
|
char *argv[])
|
|
|
|
{
|
|
|
|
gint ret;
|
|
|
|
GDBusNodeInfo *introspection_data = NULL;
|
2011-08-27 17:33:43 +02:00
|
|
|
gchar *tmpdir = NULL;
|
2010-05-06 20:13:59 +02:00
|
|
|
|
|
|
|
g_test_init (&argc, &argv, NULL);
|
|
|
|
|
|
|
|
introspection_data = g_dbus_node_info_new_for_xml (test_interface_introspection_xml, NULL);
|
|
|
|
g_assert (introspection_data != NULL);
|
|
|
|
test_interface_introspection_data = introspection_data->interfaces[0];
|
|
|
|
|
|
|
|
test_guid = g_dbus_generate_guid ();
|
|
|
|
|
2011-08-27 17:33:43 +02:00
|
|
|
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:");
|
|
|
|
|
2010-05-06 20:13:59 +02:00
|
|
|
/* 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);
|
2010-06-30 17:43:42 +02:00
|
|
|
g_test_add_func ("/gdbus/delayed-message-processing", delayed_message_processing);
|
2010-12-02 20:09:08 +01:00
|
|
|
g_test_add_func ("/gdbus/nonce-tcp", test_nonce_tcp);
|
2013-06-01 03:24:21 +02:00
|
|
|
|
2011-04-14 00:21:16 +02:00
|
|
|
g_test_add_func ("/gdbus/tcp-anonymous", test_tcp_anonymous);
|
2010-07-29 08:20:29 +02:00
|
|
|
g_test_add_func ("/gdbus/credentials", test_credentials);
|
2011-12-02 17:20:21 +01:00
|
|
|
g_test_add_func ("/gdbus/codegen-peer-to-peer", codegen_test_peer);
|
2010-05-06 20:13:59 +02:00
|
|
|
|
|
|
|
ret = g_test_run();
|
|
|
|
|
|
|
|
g_main_loop_unref (loop);
|
|
|
|
g_free (test_guid);
|
|
|
|
g_dbus_node_info_unref (introspection_data);
|
2011-08-27 17:33:43 +02:00
|
|
|
if (is_unix)
|
|
|
|
g_free (tmp_address);
|
|
|
|
if (tmpdir)
|
|
|
|
{
|
|
|
|
g_rmdir (tmpdir);
|
|
|
|
g_free (tmpdir);
|
|
|
|
}
|
2010-05-06 20:13:59 +02:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|