dbus-queue.h 7.52 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright © 2018 Endless Mobile, Inc.
 *
 * 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
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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 Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Authors:
 *  - Philip Withnall <withnall@endlessm.com>
 */

#pragma once

#include <gio/gio.h>
#include <glib.h>
#include <glib-object.h>

G_BEGIN_DECLS

typedef struct _GtDBusQueue GtDBusQueue;

GtDBusQueue *gt_dbus_queue_new  (void);
void         gt_dbus_queue_free (GtDBusQueue *self);

G_DEFINE_AUTOPTR_CLEANUP_FUNC (GtDBusQueue, gt_dbus_queue_free)

GDBusConnection *gt_dbus_queue_get_client_connection (GtDBusQueue *self);

gboolean gt_dbus_queue_connect         (GtDBusQueue         *self,
                                        GError             **error);
void     gt_dbus_queue_disconnect      (GtDBusQueue         *self,
                                        gboolean             assert_queue_empty);

guint    gt_dbus_queue_own_name        (GtDBusQueue         *self,
                                        const gchar         *name);
void     gt_dbus_queue_unown_name      (GtDBusQueue         *self,
                                        guint                id);

guint    gt_dbus_queue_export_object   (GtDBusQueue         *self,
                                        const gchar         *object_path,
                                        GDBusInterfaceInfo  *interface_info,
                                        GError             **error);
void     gt_dbus_queue_unexport_object (GtDBusQueue         *self,
                                        guint                id);

57 58 59 60 61 62 63 64 65 66
/**
 * GtDBusQueueServerFunc:
 * @queue: a #GtDBusQueue
 * @user_data: user data passed to gt_dbus_queue_set_server_func()
 *
 * Function called in the server thread to handle incoming method calls. See
 * gt_dbus_queue_set_server_func() for details.
 *
 * Since: 0.1.0
 */
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
typedef void (*GtDBusQueueServerFunc) (GtDBusQueue *queue,
                                       gpointer     user_data);

void     gt_dbus_queue_set_server_func (GtDBusQueue           *self,
                                        GtDBusQueueServerFunc  func,
                                        gpointer               user_data);

gsize    gt_dbus_queue_get_n_messages   (GtDBusQueue            *self);
gboolean gt_dbus_queue_try_pop_message  (GtDBusQueue            *self,
                                         GDBusMethodInvocation **out_invocation);
gboolean gt_dbus_queue_pop_message      (GtDBusQueue            *self,
                                         GDBusMethodInvocation **out_invocation);

gboolean gt_dbus_queue_match_client_message (GtDBusQueue           *self,
                                             GDBusMethodInvocation *invocation,
                                             const gchar           *expected_object_path,
                                             const gchar           *expected_interface_name,
                                             const gchar           *expected_method_name,
                                             const gchar           *expected_parameters_string);

gchar   *gt_dbus_queue_format_message       (GDBusMethodInvocation *invocation);
gchar   *gt_dbus_queue_format_messages      (GtDBusQueue           *self);

/**
 * gt_dbus_queue_assert_no_messages:
 * @self: a #GtDBusQueue
 *
 * Assert that there are no messages currently in the mock service’s message
 * queue.
 *
 * If there are, an assertion fails and some debug output is printed.
 *
 * Since: 0.1.0
 */
#define gt_dbus_queue_assert_no_messages(self) \
  G_STMT_START { \
    if (gt_dbus_queue_get_n_messages (self) > 0) \
      { \
        g_autofree gchar *anm_list = gt_dbus_queue_format_messages (self); \
        g_autofree gchar *anm_message = \
            g_strdup_printf ("Expected no messages, but saw %" G_GSIZE_FORMAT ":\n%s", \
                             gt_dbus_queue_get_n_messages (self), \
                             anm_list); \
        g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
                             anm_message); \
      } \
  } G_STMT_END

/**
 * gt_dbus_queue_assert_pop_message:
 * @self: a #GtDBusQueue
 * @expected_object_path: object path the invocation is expected to be calling
 * @expected_interface_name: interface name the invocation is expected to be calling
 * @expected_method_name: method name the invocation is expected to be calling
 * @parameters_format: g_variant_get() format string to extract the parameters
 *    from the popped #GDBusMethodInvocation into the return locations provided
 *    in @...
 * @...: return locations for the parameter placeholders given in @parameters_format
 *
 * Assert that a message can be popped off the mock service’s message queue
 * (using gt_dbus_queue_pop_message(), which will block) and that it is a method
 * call from the #GtDBusQueue’s client connection to the mock service, calling
 * @expected_method_name on @expected_interface_name at @expected_object_path
 * (as determined using gt_dbus_queue_match_client_message() with a %NULL
 * parameters argument). The parameters in the method call will be returned in
 * the return locations given in the varargs, according to the
 * @parameters_format, using g_variant_get_va().
 *
 * If a timeout occurs when popping a message, or if the popped message doesn’t
 * match the expected object path, interface name or method name, an assertion
 * fails and some debug output is printed.
 *
 * Returns: (transfer full): the popped #GDBusMethodInvocation
 * Since: 0.1.0
 */
#define gt_dbus_queue_assert_pop_message(self, expected_object_path, expected_interface_name, expected_method_name, parameters_format, ...) \
  gt_dbus_queue_assert_pop_message_impl (self, G_LOG_DOMAIN, __FILE__, __LINE__, \
                                         G_STRFUNC, expected_object_path, \
                                         expected_interface_name, \
                                         expected_method_name, \
                                         parameters_format, __VA_ARGS__)

/* Private implementations of the assertion functions above. */

/*< private >*/
GDBusMethodInvocation *gt_dbus_queue_assert_pop_message_impl (GtDBusQueue *self,
                                                              const gchar *macro_log_domain,
                                                              const gchar *macro_file,
                                                              gint         macro_line,
                                                              const gchar *macro_function,
                                                              const gchar *object_path,
                                                              const gchar *interface_name,
                                                              const gchar *method_name,
                                                              const gchar *parameters_format,
                                                              ...);

G_END_DECLS