1 /* Simple sanity-check for loopback through TCP and Unix sockets. 2 * 3 * Author: Simon McVittie <simon.mcvittie (at) collabora.co.uk> 4 * Copyright 2010-2011 Nokia Corporation 5 * 6 * Permission is hereby granted, free of charge, to any person 7 * obtaining a copy of this software and associated documentation files 8 * (the "Software"), to deal in the Software without restriction, 9 * including without limitation the rights to use, copy, modify, merge, 10 * publish, distribute, sublicense, and/or sell copies of the Software, 11 * and to permit persons to whom the Software is furnished to do so, 12 * subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be 15 * included in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 21 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 22 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 * SOFTWARE. 25 */ 26 27 #include <config.h> 28 29 #include <glib.h> 30 31 #include <dbus/dbus.h> 32 #include <dbus/dbus-glib-lowlevel.h> 33 34 typedef struct { 35 DBusError e; 36 37 DBusServer *server; 38 DBusConnection *server_conn; 39 /* queue of DBusMessage */ 40 GQueue server_messages; 41 42 DBusConnection *client_conn; 43 } Fixture; 44 45 static void 46 assert_no_error (const DBusError *e) 47 { 48 if (G_UNLIKELY (dbus_error_is_set (e))) 49 g_error ("expected success but got error: %s: %s", e->name, e->message); 50 } 51 52 static DBusHandlerResult 53 server_message_cb (DBusConnection *server_conn, 54 DBusMessage *message, 55 void *data) 56 { 57 Fixture *f = data; 58 59 g_assert (server_conn == f->server_conn); 60 g_queue_push_tail (&f->server_messages, dbus_message_ref (message)); 61 62 return DBUS_HANDLER_RESULT_HANDLED; 63 } 64 65 static void 66 new_conn_cb (DBusServer *server, 67 DBusConnection *server_conn, 68 void *data) 69 { 70 Fixture *f = data; 71 dbus_bool_t have_mem; 72 73 g_assert (f->server_conn == NULL); 74 f->server_conn = dbus_connection_ref (server_conn); 75 dbus_connection_setup_with_g_main (server_conn, NULL); 76 77 have_mem = dbus_connection_add_filter (server_conn, 78 server_message_cb, f, NULL); 79 g_assert (have_mem); 80 } 81 82 static void 83 setup (Fixture *f, 84 gconstpointer addr) 85 { 86 dbus_error_init (&f->e); 87 g_queue_init (&f->server_messages); 88 89 f->server = dbus_server_listen (addr, &f->e); 90 assert_no_error (&f->e); 91 g_assert (f->server != NULL); 92 93 dbus_server_set_new_connection_function (f->server, 94 new_conn_cb, f, NULL); 95 dbus_server_setup_with_g_main (f->server, NULL); 96 } 97 98 static void 99 test_connect (Fixture *f, 100 gconstpointer addr G_GNUC_UNUSED) 101 { 102 g_assert (f->server_conn == NULL); 103 104 f->client_conn = dbus_connection_open_private ( 105 dbus_server_get_address (f->server), &f->e); 106 assert_no_error (&f->e); 107 g_assert (f->client_conn != NULL); 108 dbus_connection_setup_with_g_main (f->client_conn, NULL); 109 110 while (f->server_conn == NULL) 111 { 112 g_print ("."); 113 g_main_context_iteration (NULL, TRUE); 114 } 115 } 116 117 static void 118 test_message (Fixture *f, 119 gconstpointer addr) 120 { 121 dbus_bool_t have_mem; 122 dbus_uint32_t serial; 123 DBusMessage *outgoing, *incoming; 124 125 test_connect (f, addr); 126 127 outgoing = dbus_message_new_signal ("/com/example/Hello", 128 "com.example.Hello", "Greeting"); 129 g_assert (outgoing != NULL); 130 131 have_mem = dbus_connection_send (f->client_conn, outgoing, &serial); 132 g_assert (have_mem); 133 g_assert (serial != 0); 134 135 while (g_queue_is_empty (&f->server_messages)) 136 { 137 g_print ("."); 138 g_main_context_iteration (NULL, TRUE); 139 } 140 141 g_assert_cmpuint (g_queue_get_length (&f->server_messages), ==, 1); 142 143 incoming = g_queue_pop_head (&f->server_messages); 144 145 g_assert (!dbus_message_contains_unix_fds (incoming)); 146 g_assert_cmpstr (dbus_message_get_destination (incoming), ==, NULL); 147 g_assert_cmpstr (dbus_message_get_error_name (incoming), ==, NULL); 148 g_assert_cmpstr (dbus_message_get_interface (incoming), ==, 149 "com.example.Hello"); 150 g_assert_cmpstr (dbus_message_get_member (incoming), ==, "Greeting"); 151 g_assert_cmpstr (dbus_message_get_sender (incoming), ==, NULL); 152 g_assert_cmpstr (dbus_message_get_signature (incoming), ==, ""); 153 g_assert_cmpstr (dbus_message_get_path (incoming), ==, "/com/example/Hello"); 154 g_assert_cmpuint (dbus_message_get_serial (incoming), ==, serial); 155 156 dbus_message_unref (incoming); 157 158 dbus_message_unref (outgoing); 159 } 160 161 static void 162 teardown (Fixture *f, 163 gconstpointer addr G_GNUC_UNUSED) 164 { 165 if (f->client_conn != NULL) 166 { 167 dbus_connection_close (f->client_conn); 168 dbus_connection_unref (f->client_conn); 169 f->client_conn = NULL; 170 } 171 172 if (f->server_conn != NULL) 173 { 174 dbus_connection_close (f->server_conn); 175 dbus_connection_unref (f->server_conn); 176 f->server_conn = NULL; 177 } 178 179 if (f->server != NULL) 180 { 181 dbus_server_disconnect (f->server); 182 dbus_server_unref (f->server); 183 f->server = NULL; 184 } 185 } 186 187 int 188 main (int argc, 189 char **argv) 190 { 191 g_test_init (&argc, &argv, NULL); 192 193 g_test_add ("/connect/tcp", Fixture, "tcp:host=127.0.0.1", setup, 194 test_connect, teardown); 195 g_test_add ("/message/tcp", Fixture, "tcp:host=127.0.0.1", setup, 196 test_message, teardown); 197 198 g_test_add ("/connect/nonce-tcp", Fixture, "nonce-tcp:host=127.0.0.1", setup, 199 test_connect, teardown); 200 g_test_add ("/message/nonce-tcp", Fixture, "nonce-tcp:host=127.0.0.1", setup, 201 test_message, teardown); 202 203 #ifdef DBUS_UNIX 204 g_test_add ("/connect/unix", Fixture, "unix:tmpdir=/tmp", setup, 205 test_connect, teardown); 206 g_test_add ("/message/unix", Fixture, "unix:tmpdir=/tmp", setup, 207 test_message, teardown); 208 #endif 209 210 return g_test_run (); 211 } 212