Merge branch 'dbus-1.8'
[platform/upstream/dbus.git] / test / monitor.c
1 /* Integration tests for monitor-mode D-Bus connections
2  *
3  * Copyright © 2010-2011 Nokia Corporation
4  * Copyright © 2015 Collabora Ltd.
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 <string.h>
30
31 #include "test-utils-glib.h"
32
33 typedef struct {
34     const char *config_file;
35     const char * const *match_rules;
36     gboolean care_about_our_names;
37 } Config;
38
39 typedef struct {
40     const Config *config;
41     TestMainContext *ctx;
42     DBusError e;
43     GError *ge;
44
45     gchar *address;
46     GPid daemon_pid;
47
48     DBusConnection *monitor;
49     DBusConnection *sender;
50     DBusConnection *recipient;
51
52     GQueue monitored;
53
54     const char *monitor_name;
55     const char *sender_name;
56     const char *recipient_name;
57
58     DBusConnection *systemd;
59     const char *systemd_name;
60     DBusMessage *systemd_message;
61     DBusConnection *activated;
62     const char *activated_name;
63     DBusMessage *activated_message;
64 } Fixture;
65
66 static const char * const no_match_rules[] = {
67     NULL
68 };
69
70 static const char * const wildcard_match_rules[] = {
71     "",
72     NULL,
73     FALSE
74 };
75
76 static const char * const eavesdrop_match_rules[] = {
77     "eavesdrop=true",
78     NULL,
79     FALSE
80 };
81
82 static const char * const no_eavesdrop_match_rules[] = {
83     "eavesdrop=false",
84     NULL,
85     FALSE
86 };
87
88 static const char * const selective_match_rules[] = {
89     "interface='com.example.Interesting'",
90     "interface='com.example.Fun'",
91     NULL,
92     FALSE
93 };
94
95 static Config forbidding_config = {
96     "valid-config-files/forbidding.conf",
97     NULL,
98     FALSE
99 };
100
101 static Config wildcard_config = {
102     NULL,
103     wildcard_match_rules,
104     FALSE
105 };
106
107 static Config selective_config = {
108     NULL,
109     selective_match_rules,
110     FALSE
111 };
112
113 static Config no_rules_config = {
114     NULL,
115     no_match_rules,
116     FALSE
117 };
118
119 static Config eavesdrop_config = {
120     NULL,
121     eavesdrop_match_rules,
122     FALSE
123 };
124
125 static Config no_eavesdrop_config = {
126     NULL,
127     no_eavesdrop_match_rules,
128     FALSE
129 };
130
131 static Config fake_systemd_config = {
132     "valid-config-files/systemd-activation.conf",
133     NULL,
134     FALSE
135 };
136
137 static Config side_effects_config = {
138     NULL,
139     NULL,
140     TRUE
141 };
142
143 static inline const char *
144 not_null2 (const char *x,
145     const char *fallback)
146 {
147   if (x == NULL)
148     return fallback;
149
150   return x;
151 }
152
153 static inline const char *
154 not_null (const char *x)
155 {
156   return not_null2 (x, "(null)");
157 }
158
159 #define log_message(m) _log_message (m, __FILE__, __LINE__)
160
161 G_GNUC_UNUSED
162 static void
163 _log_message (DBusMessage *m,
164     const char *file,
165     int line)
166 {
167   g_test_message ("%s:%d: message type %d (%s)", file, line,
168       dbus_message_get_type (m),
169       dbus_message_type_to_string (dbus_message_get_type (m)));
170   g_test_message ("\tfrom: %s",
171       not_null2 (dbus_message_get_sender (m), "(dbus-daemon)"));
172   g_test_message ("\tto: %s",
173       not_null2 (dbus_message_get_destination (m), "(broadcast)"));
174   g_test_message ("\tpath: %s",
175       not_null (dbus_message_get_path (m)));
176   g_test_message ("\tinterface: %s",
177       not_null (dbus_message_get_interface (m)));
178   g_test_message ("\tmember: %s",
179       not_null (dbus_message_get_member (m)));
180   g_test_message ("\tsignature: %s",
181       not_null (dbus_message_get_signature (m)));
182   g_test_message ("\terror name: %s",
183       not_null (dbus_message_get_error_name (m)));
184
185   if (strcmp ("s", dbus_message_get_signature (m)) == 0)
186     {
187       DBusError e = DBUS_ERROR_INIT;
188       const char *s;
189
190       dbus_message_get_args (m, &e,
191             DBUS_TYPE_STRING, &s,
192             DBUS_TYPE_INVALID);
193       test_assert_no_error (&e);
194       g_test_message ("\tstring payload: %s", s);
195     }
196 }
197
198 /* these are macros so they get the right line number */
199
200 #define assert_hello(m) \
201 do { \
202   g_assert_cmpstr (dbus_message_type_to_string (dbus_message_get_type (m)), \
203       ==, dbus_message_type_to_string (DBUS_MESSAGE_TYPE_METHOD_CALL)); \
204   g_assert_cmpstr (dbus_message_get_destination (m), ==, DBUS_SERVICE_DBUS); \
205   g_assert_cmpstr (dbus_message_get_path (m), ==, DBUS_PATH_DBUS); \
206   g_assert_cmpstr (dbus_message_get_interface (m), ==, DBUS_INTERFACE_DBUS); \
207   g_assert_cmpstr (dbus_message_get_member (m), ==, "Hello"); \
208   g_assert_cmpstr (dbus_message_get_signature (m), ==, ""); \
209   g_assert_cmpint (dbus_message_get_serial (m), !=, 0); \
210   g_assert_cmpint (dbus_message_get_reply_serial (m), ==, 0); \
211 } while (0)
212
213 #define assert_hello_reply(m) \
214 do { \
215   DBusError _e = DBUS_ERROR_INIT; \
216   const char *_s; \
217     \
218   g_assert_cmpstr (dbus_message_type_to_string (dbus_message_get_type (m)), \
219       ==, dbus_message_type_to_string (DBUS_MESSAGE_TYPE_METHOD_RETURN)); \
220   g_assert_cmpstr (dbus_message_get_sender (m), ==, DBUS_SERVICE_DBUS); \
221   g_assert_cmpstr (dbus_message_get_path (m), ==, NULL); \
222   g_assert_cmpstr (dbus_message_get_interface (m), ==, NULL); \
223   g_assert_cmpstr (dbus_message_get_member (m), ==, NULL); \
224   g_assert_cmpstr (dbus_message_get_signature (m), ==, "s"); \
225   g_assert_cmpint (dbus_message_get_serial (m), !=, 0); \
226   g_assert_cmpint (dbus_message_get_reply_serial (m), !=, 0); \
227     \
228   dbus_message_get_args (m, &_e, \
229         DBUS_TYPE_STRING, &_s, \
230         DBUS_TYPE_INVALID); \
231   test_assert_no_error (&_e); \
232   g_assert_cmpstr (dbus_message_get_destination (m), ==, _s); \
233 } while (0)
234
235 #define assert_name_acquired(m) \
236 do { \
237   DBusError _e = DBUS_ERROR_INIT; \
238   const char *_s; \
239     \
240   g_assert_cmpstr (dbus_message_type_to_string (dbus_message_get_type (m)), \
241       ==, dbus_message_type_to_string (DBUS_MESSAGE_TYPE_SIGNAL)); \
242   g_assert_cmpstr (dbus_message_get_sender (m), ==, DBUS_SERVICE_DBUS); \
243   g_assert_cmpstr (dbus_message_get_path (m), ==, DBUS_PATH_DBUS); \
244   g_assert_cmpstr (dbus_message_get_interface (m), ==, DBUS_INTERFACE_DBUS); \
245   g_assert_cmpstr (dbus_message_get_member (m), ==, "NameAcquired"); \
246   g_assert_cmpstr (dbus_message_get_signature (m), ==, "s"); \
247   g_assert_cmpint (dbus_message_get_serial (m), !=, 0); \
248   g_assert_cmpint (dbus_message_get_reply_serial (m), ==, 0); \
249     \
250   dbus_message_get_args (m, &_e, \
251         DBUS_TYPE_STRING, &_s, \
252         DBUS_TYPE_INVALID); \
253   test_assert_no_error (&_e); \
254   g_assert_cmpstr (dbus_message_get_destination (m), ==, _s); \
255 } while (0)
256
257 #define assert_method_call(m, sender, \
258     destination, path, iface, method, signature) \
259 do { \
260   g_assert_cmpstr (dbus_message_type_to_string (dbus_message_get_type (m)), \
261       ==, dbus_message_type_to_string (DBUS_MESSAGE_TYPE_METHOD_CALL)); \
262   g_assert_cmpstr (dbus_message_get_sender (m), ==, sender); \
263   g_assert_cmpstr (dbus_message_get_destination (m), ==, destination); \
264   g_assert_cmpstr (dbus_message_get_path (m), ==, path); \
265   g_assert_cmpstr (dbus_message_get_interface (m), ==, iface); \
266   g_assert_cmpstr (dbus_message_get_member (m), ==, method); \
267   g_assert_cmpstr (dbus_message_get_signature (m), ==, signature); \
268   g_assert_cmpint (dbus_message_get_serial (m), !=, 0); \
269   g_assert_cmpint (dbus_message_get_reply_serial (m), ==, 0); \
270 } while (0)
271
272 #define assert_signal(m, \
273     sender, path, iface, member, signature, \
274     destination) \
275 do { \
276   g_assert_cmpstr (dbus_message_type_to_string (dbus_message_get_type (m)), \
277       ==, dbus_message_type_to_string (DBUS_MESSAGE_TYPE_SIGNAL)); \
278   g_assert_cmpstr (dbus_message_get_sender (m), ==, sender); \
279   g_assert_cmpstr (dbus_message_get_destination (m), ==, destination); \
280   g_assert_cmpstr (dbus_message_get_path (m), ==, path); \
281   g_assert_cmpstr (dbus_message_get_interface (m), ==, iface); \
282   g_assert_cmpstr (dbus_message_get_member (m), ==, member); \
283   g_assert_cmpstr (dbus_message_get_signature (m), ==, signature); \
284   g_assert_cmpint (dbus_message_get_serial (m), !=, 0); \
285   g_assert_cmpint (dbus_message_get_reply_serial (m), ==, 0); \
286 } while (0)
287
288 #define assert_method_reply(m, sender, destination, signature) \
289 do { \
290   g_assert_cmpstr (dbus_message_type_to_string (dbus_message_get_type (m)), \
291       ==, dbus_message_type_to_string (DBUS_MESSAGE_TYPE_METHOD_RETURN)); \
292   g_assert_cmpstr (dbus_message_get_sender (m), ==, sender); \
293   g_assert_cmpstr (dbus_message_get_destination (m), ==, destination); \
294   g_assert_cmpstr (dbus_message_get_path (m), ==, NULL); \
295   g_assert_cmpstr (dbus_message_get_interface (m), ==, NULL); \
296   g_assert_cmpstr (dbus_message_get_member (m), ==, NULL); \
297   g_assert_cmpstr (dbus_message_get_signature (m), ==, signature); \
298   g_assert_cmpint (dbus_message_get_serial (m), !=, 0); \
299   g_assert_cmpint (dbus_message_get_reply_serial (m), !=, 0); \
300 } while (0)
301
302 #define assert_error_reply(m, sender, destination, error_name) \
303 do { \
304   g_assert_cmpstr (dbus_message_type_to_string (dbus_message_get_type (m)), \
305       ==, dbus_message_type_to_string (DBUS_MESSAGE_TYPE_ERROR)); \
306   g_assert_cmpstr (dbus_message_get_sender (m), ==, sender); \
307   g_assert_cmpstr (dbus_message_get_destination (m), ==, destination); \
308   g_assert_cmpstr (dbus_message_get_error_name (m), ==, error_name); \
309   g_assert_cmpstr (dbus_message_get_path (m), ==, NULL); \
310   g_assert_cmpstr (dbus_message_get_interface (m), ==, NULL); \
311   g_assert_cmpstr (dbus_message_get_member (m), ==, NULL); \
312   g_assert_cmpstr (dbus_message_get_signature (m), ==, "s"); \
313   g_assert_cmpint (dbus_message_get_serial (m), !=, 0); \
314   g_assert_cmpint (dbus_message_get_reply_serial (m), !=, 0); \
315 } while (0)
316
317 /* This is called after processing pending replies to our own method
318  * calls, but before anything else.
319  */
320 static DBusHandlerResult
321 monitor_filter (DBusConnection *connection,
322     DBusMessage *message,
323     void *user_data)
324 {
325   Fixture *f = user_data;
326
327   g_assert_cmpstr (dbus_message_get_interface (message), !=,
328       "com.example.Tedious");
329
330   /* we are not interested in the monitor getting NameAcquired or NameLost
331    * for most tests */
332   if (f->config == NULL || !f->config->care_about_our_names)
333     {
334       if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
335             "NameAcquired") ||
336           dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
337             "NameLost"))
338         {
339           DBusError e = DBUS_ERROR_INIT;
340           const char *s;
341
342           dbus_message_get_args (message, &e,
343                 DBUS_TYPE_STRING, &s,
344                 DBUS_TYPE_INVALID);
345           test_assert_no_error (&e);
346
347           if (strcmp (s, f->monitor_name) == 0)
348             {
349               /* ignore */
350               return DBUS_HANDLER_RESULT_HANDLED;
351             }
352         }
353     }
354
355   g_queue_push_tail (&f->monitored, dbus_message_ref (message));
356
357   return DBUS_HANDLER_RESULT_HANDLED;
358 }
359
360 static DBusHandlerResult
361 recipient_filter (DBusConnection *connection,
362     DBusMessage *message,
363     void *user_data)
364 {
365   g_assert_cmpstr (dbus_message_get_interface (message), !=,
366       "com.example.CannotSend");
367   g_assert_cmpstr (dbus_message_get_interface (message), !=,
368       "com.example.CannotReceive");
369
370   return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
371 }
372
373 static DBusHandlerResult
374 systemd_filter (DBusConnection *connection,
375     DBusMessage *message,
376     void *user_data)
377 {
378   Fixture *f = user_data;
379
380   if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
381         "NameAcquired") ||
382       dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
383         "NameLost"))
384     {
385       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
386     }
387
388   g_assert (f->systemd_message == NULL);
389   f->systemd_message = dbus_message_ref (message);
390
391   return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
392 }
393
394 static DBusHandlerResult
395 activated_filter (DBusConnection *connection,
396     DBusMessage *message,
397     void *user_data)
398 {
399   Fixture *f = user_data;
400
401   if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
402         "NameAcquired") ||
403       dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
404         "NameLost"))
405     {
406       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
407     }
408
409   g_assert (f->activated_message == NULL);
410   f->activated_message = dbus_message_ref (message);
411
412   return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
413 }
414
415 static void
416 setup (Fixture *f,
417     gconstpointer context)
418 {
419   f->config = context;
420
421   f->ctx = test_main_context_get ();
422
423   f->ge = NULL;
424   dbus_error_init (&f->e);
425
426   f->address = test_get_dbus_daemon (f->config ? f->config->config_file : NULL,
427       TEST_USER_ME, &f->daemon_pid);
428
429   if (f->address == NULL)
430     return;
431
432   f->monitor = test_connect_to_bus (f->ctx, f->address);
433   f->monitor_name = dbus_bus_get_unique_name (f->monitor);
434   f->sender = test_connect_to_bus (f->ctx, f->address);
435   f->sender_name = dbus_bus_get_unique_name (f->sender);
436   f->recipient = test_connect_to_bus (f->ctx, f->address);
437   f->recipient_name = dbus_bus_get_unique_name (f->recipient);
438
439   if (!dbus_connection_add_filter (f->monitor, monitor_filter, f, NULL))
440     g_error ("OOM");
441
442   if (!dbus_connection_add_filter (f->recipient, recipient_filter, f, NULL))
443     g_error ("OOM");
444 }
445
446 static void
447 become_monitor (Fixture *f)
448 {
449   DBusMessage *m;
450   DBusPendingCall *pc;
451   dbus_bool_t ok;
452   DBusMessageIter appender, array_appender;
453   const char * const *match_rules;
454   int i;
455   dbus_uint32_t zero = 0;
456
457   dbus_connection_set_route_peer_messages (f->monitor, TRUE);
458
459   if (f->config != NULL && f->config->match_rules != NULL)
460     match_rules = f->config->match_rules;
461   else
462     match_rules = wildcard_match_rules;
463
464   m = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
465       DBUS_PATH_DBUS, DBUS_INTERFACE_MONITORING, "BecomeMonitor");
466
467   if (m == NULL)
468     g_error ("OOM");
469
470   dbus_message_iter_init_append (m, &appender);
471
472   if (!dbus_message_iter_open_container (&appender, DBUS_TYPE_ARRAY, "s",
473         &array_appender))
474     g_error ("OOM");
475
476   for (i = 0; match_rules[i] != NULL; i++)
477     {
478       if (!dbus_message_iter_append_basic (&array_appender, DBUS_TYPE_STRING,
479             &match_rules[i]))
480         g_error ("OOM");
481     }
482
483   if (!dbus_message_iter_close_container (&appender, &array_appender) ||
484       !dbus_message_iter_append_basic (&appender, DBUS_TYPE_UINT32, &zero))
485     g_error ("OOM");
486
487   if (!dbus_connection_send_with_reply (f->monitor, m, &pc,
488         DBUS_TIMEOUT_USE_DEFAULT) ||
489       pc == NULL)
490     g_error ("OOM");
491
492   dbus_message_unref (m);
493   m = NULL;
494
495   if (dbus_pending_call_get_completed (pc))
496     test_pending_call_store_reply (pc, &m);
497   else if (!dbus_pending_call_set_notify (pc, test_pending_call_store_reply,
498         &m, NULL))
499     g_error ("OOM");
500
501   while (m == NULL)
502     test_main_context_iterate (f->ctx, TRUE);
503
504   ok = dbus_message_get_args (m, &f->e,
505       DBUS_TYPE_INVALID);
506   test_assert_no_error (&f->e);
507   g_assert (ok);
508
509   dbus_pending_call_unref (pc);
510   dbus_message_unref (m);
511   m = NULL;
512 }
513
514 /*
515  * Test the side-effects of becoming a monitor.
516  */
517 static void
518 test_become_monitor (Fixture *f,
519     gconstpointer context)
520 {
521   DBusMessage *m;
522   int ret;
523   dbus_bool_t got_unique = FALSE, got_a = FALSE, got_b = FALSE, got_c = FALSE;
524   dbus_bool_t lost_unique = FALSE, lost_a = FALSE, lost_b = FALSE, lost_c = FALSE;
525
526   if (f->address == NULL)
527     return;
528
529   ret = dbus_bus_request_name (f->monitor, "com.example.A",
530       DBUS_NAME_FLAG_DO_NOT_QUEUE, &f->e);
531   test_assert_no_error (&f->e);
532   g_assert_cmpint (ret, ==, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
533
534   ret = dbus_bus_request_name (f->monitor, "com.example.B",
535       DBUS_NAME_FLAG_DO_NOT_QUEUE, &f->e);
536   test_assert_no_error (&f->e);
537   g_assert_cmpint (ret, ==, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
538
539   ret = dbus_bus_request_name (f->monitor, "com.example.C",
540       DBUS_NAME_FLAG_DO_NOT_QUEUE, &f->e);
541   test_assert_no_error (&f->e);
542   g_assert_cmpint (ret, ==, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
543
544   while (!got_unique || !got_a || !got_b || !got_c)
545     {
546       if (g_queue_is_empty (&f->monitored))
547         test_main_context_iterate (f->ctx, TRUE);
548
549       while ((m = g_queue_pop_head (&f->monitored)) != NULL)
550         {
551           if (dbus_message_is_signal (m, DBUS_INTERFACE_DBUS,
552                 "NameAcquired"))
553             {
554               const char *name;
555               dbus_bool_t ok = dbus_message_get_args (m, &f->e,
556                   DBUS_TYPE_STRING, &name,
557                   DBUS_TYPE_INVALID);
558
559               g_assert_cmpstr (dbus_message_get_path (m), ==,
560                   DBUS_PATH_DBUS);
561
562               test_assert_no_error (&f->e);
563               g_assert (ok);
564
565               if (g_str_equal (name, f->monitor_name))
566                 {
567                   g_assert (!got_unique);
568                   got_unique = TRUE;
569                 }
570               else if (g_str_equal (name, "com.example.A"))
571                 {
572                   g_assert (!got_a);
573                   got_a = TRUE;
574                 }
575               else if (g_str_equal (name, "com.example.B"))
576                 {
577                   g_assert (!got_b);
578                   got_b = TRUE;
579                 }
580               else
581                 {
582                   g_assert_cmpstr (name, ==, "com.example.C");
583                   g_assert (!got_c);
584                   got_c = TRUE;
585                 }
586             }
587           else
588             {
589               g_error ("unexpected message %s.%s",
590                   dbus_message_get_interface (m),
591                   dbus_message_get_member (m));
592             }
593
594           dbus_message_unref (m);
595         }
596     }
597
598   become_monitor (f);
599
600   while (!lost_unique || !lost_a || !lost_b || !lost_c)
601     {
602       if (g_queue_is_empty (&f->monitored))
603         test_main_context_iterate (f->ctx, TRUE);
604
605       while ((m = g_queue_pop_head (&f->monitored)) != NULL)
606         {
607           if (dbus_message_is_signal (m, DBUS_INTERFACE_DBUS,
608                 "NameLost"))
609             {
610               const char *name;
611               dbus_bool_t ok = dbus_message_get_args (m, &f->e,
612                   DBUS_TYPE_STRING, &name,
613                   DBUS_TYPE_INVALID);
614
615               test_assert_no_error (&f->e);
616               g_assert (ok);
617
618               if (g_str_equal (name, f->monitor_name))
619                 {
620                   g_assert (!lost_unique);
621                   lost_unique = TRUE;
622                 }
623               else if (g_str_equal (name, "com.example.A"))
624                 {
625                   g_assert (!lost_a);
626                   lost_a = TRUE;
627                 }
628               else if (g_str_equal (name, "com.example.B"))
629                 {
630                   g_assert (!lost_b);
631                   lost_b = TRUE;
632                 }
633               else
634                 {
635                   g_assert_cmpstr (name, ==, "com.example.C");
636                   g_assert (!lost_c);
637                   lost_c = TRUE;
638                 }
639             }
640           else
641             {
642               g_error ("unexpected message %s.%s",
643                   dbus_message_get_interface (m),
644                   dbus_message_get_member (m));
645             }
646
647           dbus_message_unref (m);
648         }
649     }
650
651   /* Calling methods is forbidden; we get disconnected. */
652   dbus_bus_add_match (f->monitor, "", &f->e);
653   g_assert_cmpstr (f->e.name, ==, DBUS_ERROR_NO_REPLY);
654   g_assert (!dbus_connection_get_is_connected (f->monitor));
655
656   while (TRUE)
657     {
658       if (g_queue_is_empty (&f->monitored))
659         test_main_context_iterate (f->ctx, TRUE);
660
661       /* When we iterate all the connection's messages, we see ourselves
662        * losing all our names, then we're disconnected. */
663       while ((m = g_queue_pop_head (&f->monitored)) != NULL)
664         {
665           if (dbus_message_is_signal (m, DBUS_INTERFACE_LOCAL, "Disconnected"))
666             {
667               dbus_message_unref (m);
668               goto disconnected;
669             }
670           else
671             {
672               g_error ("unexpected message %s.%s",
673                   dbus_message_get_interface (m),
674                   dbus_message_get_member (m));
675             }
676
677           dbus_message_unref (m);
678         }
679     }
680
681 disconnected:
682
683   g_assert (lost_a);
684   g_assert (lost_b);
685   g_assert (lost_c);
686 }
687
688 static void
689 test_broadcast (Fixture *f,
690     gconstpointer context)
691 {
692   DBusMessage *m;
693
694   if (f->address == NULL)
695     return;
696
697   dbus_bus_add_match (f->recipient, "type='signal'", &f->e);
698   test_assert_no_error (&f->e);
699
700   become_monitor (f);
701
702   m = dbus_message_new_signal ("/foo", "com.example.bar", "BroadcastSignal1");
703   dbus_connection_send (f->sender, m, NULL);
704   dbus_message_unref (m);
705
706   m = dbus_message_new_signal ("/foo", "com.example.bar", "BroadcastSignal2");
707   dbus_connection_send (f->sender, m, NULL);
708   dbus_message_unref (m);
709
710   m = dbus_message_new_signal ("/foo", "com.example.bar", "BroadcastSignal3");
711   dbus_connection_send (f->sender, m, NULL);
712   dbus_message_unref (m);
713
714   while (g_queue_get_length (&f->monitored) < 3)
715     test_main_context_iterate (f->ctx, TRUE);
716
717   m = g_queue_pop_head (&f->monitored);
718   assert_signal (m, f->sender_name, "/foo", "com.example.bar",
719       "BroadcastSignal1", "", NULL);
720   dbus_message_unref (m);
721
722   m = g_queue_pop_head (&f->monitored);
723   assert_signal (m, f->sender_name, "/foo", "com.example.bar",
724       "BroadcastSignal2", "", NULL);
725   dbus_message_unref (m);
726
727   m = g_queue_pop_head (&f->monitored);
728   assert_signal (m, f->sender_name, "/foo", "com.example.bar",
729       "BroadcastSignal3", "", NULL);
730   dbus_message_unref (m);
731
732   m = g_queue_pop_head (&f->monitored);
733   g_assert (m == NULL);
734 }
735
736 static void
737 test_forbidden_broadcast (Fixture *f,
738     gconstpointer context)
739 {
740   DBusMessage *m;
741
742   if (f->address == NULL)
743     return;
744
745   dbus_bus_add_match (f->recipient, "type='signal'", &f->e);
746   test_assert_no_error (&f->e);
747
748   become_monitor (f);
749
750   m = dbus_message_new_signal ("/foo", "com.example.CannotSend",
751       "BroadcastSignal1");
752   dbus_connection_send (f->sender, m, NULL);
753   dbus_message_unref (m);
754
755   m = dbus_message_new_signal ("/foo", "com.example.CannotReceive",
756       "BroadcastSignal2");
757   dbus_connection_send (f->sender, m, NULL);
758   dbus_message_unref (m);
759
760   m = dbus_message_new_signal ("/foo", "com.example.CannotSend",
761       "BroadcastSignal3");
762   dbus_connection_send (f->sender, m, NULL);
763   dbus_message_unref (m);
764
765   while (g_queue_get_length (&f->monitored) < 6)
766     test_main_context_iterate (f->ctx, TRUE);
767
768   m = g_queue_pop_head (&f->monitored);
769   assert_signal (m, f->sender_name, "/foo", "com.example.CannotSend",
770       "BroadcastSignal1", "", NULL);
771   dbus_message_unref (m);
772
773   m = g_queue_pop_head (&f->monitored);
774   assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
775       DBUS_ERROR_ACCESS_DENIED);
776   dbus_message_unref (m);
777
778   m = g_queue_pop_head (&f->monitored);
779   assert_signal (m, f->sender_name, "/foo", "com.example.CannotReceive",
780       "BroadcastSignal2", "", NULL);
781   dbus_message_unref (m);
782
783   m = g_queue_pop_head (&f->monitored);
784   assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
785       DBUS_ERROR_ACCESS_DENIED);
786   dbus_message_unref (m);
787
788   m = g_queue_pop_head (&f->monitored);
789   assert_signal (m, f->sender_name, "/foo", "com.example.CannotSend",
790       "BroadcastSignal3", "", NULL);
791   dbus_message_unref (m);
792
793   m = g_queue_pop_head (&f->monitored);
794   assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
795       DBUS_ERROR_ACCESS_DENIED);
796   dbus_message_unref (m);
797
798   m = g_queue_pop_head (&f->monitored);
799   g_assert (m == NULL);
800 }
801
802 static void
803 test_unicast_signal (Fixture *f,
804     gconstpointer context)
805 {
806   DBusMessage *m;
807
808   if (f->address == NULL)
809     return;
810
811   become_monitor (f);
812
813   m = dbus_message_new_signal ("/foo", "com.example.bar", "UnicastSignal1");
814   if (!dbus_message_set_destination (m, f->recipient_name))
815     g_error ("OOM");
816   dbus_connection_send (f->sender, m, NULL);
817   dbus_message_unref (m);
818
819   m = dbus_message_new_signal ("/foo", "com.example.bar", "UnicastSignal2");
820   if (!dbus_message_set_destination (m, f->recipient_name))
821     g_error ("OOM");
822   dbus_connection_send (f->sender, m, NULL);
823   dbus_message_unref (m);
824
825   m = dbus_message_new_signal ("/foo", "com.example.bar", "UnicastSignal3");
826   if (!dbus_message_set_destination (m, f->recipient_name))
827     g_error ("OOM");
828   dbus_connection_send (f->sender, m, NULL);
829   dbus_message_unref (m);
830
831   while (g_queue_get_length (&f->monitored) < 3)
832     test_main_context_iterate (f->ctx, TRUE);
833
834   m = g_queue_pop_head (&f->monitored);
835   assert_signal (m, f->sender_name, "/foo",
836       "com.example.bar", "UnicastSignal1", "", f->recipient_name);
837   dbus_message_unref (m);
838
839   m = g_queue_pop_head (&f->monitored);
840   assert_signal (m, f->sender_name, "/foo",
841       "com.example.bar", "UnicastSignal2", "", f->recipient_name);
842   dbus_message_unref (m);
843
844   m = g_queue_pop_head (&f->monitored);
845   assert_signal (m, f->sender_name, "/foo",
846       "com.example.bar", "UnicastSignal3", "", f->recipient_name);
847   dbus_message_unref (m);
848
849   m = g_queue_pop_head (&f->monitored);
850   g_assert (m == NULL);
851 }
852
853 static void
854 test_forbidden (Fixture *f,
855     gconstpointer context)
856 {
857   DBusMessage *m;
858
859   if (f->address == NULL)
860     return;
861
862   become_monitor (f);
863
864   m = dbus_message_new_signal ("/foo", "com.example.CannotSend",
865       "UnicastSignal1");
866   if (!dbus_message_set_destination (m, f->recipient_name))
867     g_error ("OOM");
868   dbus_connection_send (f->sender, m, NULL);
869   dbus_message_unref (m);
870
871   m = dbus_message_new_signal ("/foo", "com.example.CannotReceive",
872       "UnicastSignal2");
873   if (!dbus_message_set_destination (m, f->recipient_name))
874     g_error ("OOM");
875   dbus_connection_send (f->sender, m, NULL);
876   dbus_message_unref (m);
877
878   m = dbus_message_new_signal ("/foo", "com.example.CannotSend",
879       "UnicastSignal3");
880   if (!dbus_message_set_destination (m, f->recipient_name))
881     g_error ("OOM");
882   dbus_connection_send (f->sender, m, NULL);
883   dbus_message_unref (m);
884
885   while (g_queue_get_length (&f->monitored) < 6)
886     test_main_context_iterate (f->ctx, TRUE);
887
888   m = g_queue_pop_head (&f->monitored);
889   assert_signal (m, f->sender_name, "/foo",
890       "com.example.CannotSend", "UnicastSignal1", "", f->recipient_name);
891   dbus_message_unref (m);
892
893   m = g_queue_pop_head (&f->monitored);
894   assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
895       DBUS_ERROR_ACCESS_DENIED);
896   dbus_message_unref (m);
897
898   m = g_queue_pop_head (&f->monitored);
899   assert_signal (m, f->sender_name, "/foo",
900       "com.example.CannotReceive", "UnicastSignal2", "", f->recipient_name);
901   dbus_message_unref (m);
902
903   m = g_queue_pop_head (&f->monitored);
904   assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
905       DBUS_ERROR_ACCESS_DENIED);
906   dbus_message_unref (m);
907
908   m = g_queue_pop_head (&f->monitored);
909   assert_signal (m, f->sender_name, "/foo",
910       "com.example.CannotSend", "UnicastSignal3", "", f->recipient_name);
911   dbus_message_unref (m);
912
913   m = g_queue_pop_head (&f->monitored);
914   assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
915       DBUS_ERROR_ACCESS_DENIED);
916   dbus_message_unref (m);
917
918   m = g_queue_pop_head (&f->monitored);
919   g_assert (m == NULL);
920 }
921
922 static void
923 test_method_call (Fixture *f,
924     gconstpointer context)
925 {
926   DBusMessage *m;
927
928   if (f->address == NULL)
929     return;
930
931   become_monitor (f);
932
933   /* regression test for
934    * https://bugs.freedesktop.org/show_bug.cgi?id=90952 */
935   m = dbus_message_new_method_call (f->recipient_name, "/foo",
936       DBUS_INTERFACE_PEER, "Ping");
937   dbus_connection_send (f->sender, m, NULL);
938   dbus_message_unref (m);
939
940   while (g_queue_get_length (&f->monitored) < 2)
941     test_main_context_iterate (f->ctx, TRUE);
942
943   m = g_queue_pop_head (&f->monitored);
944   assert_method_call (m, f->sender_name, f->recipient_name, "/foo",
945       DBUS_INTERFACE_PEER, "Ping", "");
946   dbus_message_unref (m);
947
948   m = g_queue_pop_head (&f->monitored);
949   assert_method_reply (m, f->recipient_name, f->sender_name, "");
950   dbus_message_unref (m);
951
952   m = g_queue_pop_head (&f->monitored);
953   g_assert (m == NULL);
954
955   m = dbus_message_new_method_call (f->recipient_name, "/foo", "com.example.bar",
956       "Call1");
957   dbus_connection_send (f->sender, m, NULL);
958   dbus_message_unref (m);
959
960   while (g_queue_get_length (&f->monitored) < 2)
961     test_main_context_iterate (f->ctx, TRUE);
962
963   m = g_queue_pop_head (&f->monitored);
964   assert_method_call (m, f->sender_name, f->recipient_name, "/foo",
965       "com.example.bar", "Call1", "");
966   dbus_message_unref (m);
967
968   m = g_queue_pop_head (&f->monitored);
969   assert_error_reply (m, f->recipient_name, f->sender_name,
970       DBUS_ERROR_UNKNOWN_METHOD);
971   dbus_message_unref (m);
972
973   m = g_queue_pop_head (&f->monitored);
974   g_assert (m == NULL);
975 }
976
977 static void
978 test_forbidden_method_call (Fixture *f,
979     gconstpointer context)
980 {
981   DBusMessage *m;
982
983   if (f->address == NULL)
984     return;
985
986   become_monitor (f);
987
988   m = dbus_message_new_method_call (f->recipient_name, "/foo",
989       "com.example.CannotSend", "Call1");
990   dbus_connection_send (f->sender, m, NULL);
991   dbus_message_unref (m);
992
993   while (g_queue_get_length (&f->monitored) < 2)
994     test_main_context_iterate (f->ctx, TRUE);
995
996   m = g_queue_pop_head (&f->monitored);
997   assert_method_call (m, f->sender_name, f->recipient_name, "/foo",
998       "com.example.CannotSend", "Call1", "");
999   dbus_message_unref (m);
1000
1001   m = g_queue_pop_head (&f->monitored);
1002   assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
1003       DBUS_ERROR_ACCESS_DENIED);
1004   dbus_message_unref (m);
1005
1006   m = g_queue_pop_head (&f->monitored);
1007   g_assert (m == NULL);
1008
1009   m = dbus_message_new_method_call (f->recipient_name, "/foo",
1010       "com.example.CannotReceive", "Call2");
1011   dbus_connection_send (f->sender, m, NULL);
1012   dbus_message_unref (m);
1013
1014   while (g_queue_get_length (&f->monitored) < 2)
1015     test_main_context_iterate (f->ctx, TRUE);
1016
1017   m = g_queue_pop_head (&f->monitored);
1018   assert_method_call (m, f->sender_name, f->recipient_name, "/foo",
1019       "com.example.CannotReceive", "Call2", "");
1020   dbus_message_unref (m);
1021
1022   m = g_queue_pop_head (&f->monitored);
1023   assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
1024       DBUS_ERROR_ACCESS_DENIED);
1025   dbus_message_unref (m);
1026
1027   m = g_queue_pop_head (&f->monitored);
1028   g_assert (m == NULL);
1029 }
1030
1031 static void
1032 test_dbus_daemon (Fixture *f,
1033     gconstpointer context)
1034 {
1035   DBusMessage *m;
1036   int res;
1037
1038   if (f->address == NULL)
1039     return;
1040
1041   become_monitor (f);
1042
1043   res = dbus_bus_request_name (f->sender, "com.example.Sender",
1044       DBUS_NAME_FLAG_DO_NOT_QUEUE, &f->e);
1045   test_assert_no_error (&f->e);
1046   g_assert_cmpint (res, ==, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
1047
1048   res = dbus_bus_release_name (f->sender, "com.example.Sender", &f->e);
1049   test_assert_no_error (&f->e);
1050   g_assert_cmpint (res, ==, DBUS_RELEASE_NAME_REPLY_RELEASED);
1051
1052   while (g_queue_get_length (&f->monitored) < 8)
1053     test_main_context_iterate (f->ctx, TRUE);
1054
1055   m = g_queue_pop_head (&f->monitored);
1056   assert_method_call (m, f->sender_name, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
1057       DBUS_INTERFACE_DBUS, "RequestName", "su");
1058   dbus_message_unref (m);
1059
1060   m = g_queue_pop_head (&f->monitored);
1061   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS,
1062       "NameOwnerChanged", "sss", NULL);
1063   dbus_message_unref (m);
1064
1065   /* FIXME: should we get this? */
1066   m = g_queue_pop_head (&f->monitored);
1067   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS,
1068       "NameAcquired", "s", f->sender_name);
1069   dbus_message_unref (m);
1070
1071   m = g_queue_pop_head (&f->monitored);
1072   assert_method_reply (m, DBUS_SERVICE_DBUS, f->sender_name, "u");
1073   dbus_message_unref (m);
1074
1075   m = g_queue_pop_head (&f->monitored);
1076   assert_method_call (m, f->sender_name, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
1077       DBUS_INTERFACE_DBUS, "ReleaseName", "s");
1078   dbus_message_unref (m);
1079
1080   /* FIXME: should we get this? */
1081   m = g_queue_pop_head (&f->monitored);
1082   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS,
1083       "NameLost", "s", f->sender_name);
1084   dbus_message_unref (m);
1085
1086   m = g_queue_pop_head (&f->monitored);
1087   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS,
1088       "NameOwnerChanged", "sss", NULL);
1089   dbus_message_unref (m);
1090
1091   m = g_queue_pop_head (&f->monitored);
1092   assert_method_reply (m, DBUS_SERVICE_DBUS, f->sender_name, "u");
1093   dbus_message_unref (m);
1094
1095   m = g_queue_pop_head (&f->monitored);
1096   g_assert (m == NULL);
1097 }
1098
1099 static void
1100 test_selective (Fixture *f,
1101     gconstpointer context)
1102 {
1103   DBusMessage *m;
1104
1105   if (f->address == NULL)
1106     return;
1107
1108   /* Match rules added before becoming a monitor should be cleared:
1109    * if they weren't, this test would get Interesting twice, then Tedious,
1110    * and only see Fun after that. */
1111   dbus_bus_add_match (f->monitor,
1112       "eavesdrop='true',interface='com.example.Interesting'", &f->e);
1113   test_assert_no_error (&f->e);
1114   dbus_bus_add_match (f->monitor,
1115       "eavesdrop='true',interface='com.example.Tedious'", &f->e);
1116   test_assert_no_error (&f->e);
1117
1118   become_monitor (f);
1119
1120   m = dbus_message_new_signal ("/foo", "com.example.Interesting",
1121       "UnicastSignal1");
1122   if (!dbus_message_set_destination (m, f->recipient_name))
1123     g_error ("OOM");
1124   dbus_connection_send (f->sender, m, NULL);
1125   dbus_message_unref (m);
1126
1127   m = dbus_message_new_signal ("/foo", "com.example.Tedious",
1128       "UnicastSignal2");
1129   if (!dbus_message_set_destination (m, f->recipient_name))
1130     g_error ("OOM");
1131   dbus_connection_send (f->sender, m, NULL);
1132   dbus_message_unref (m);
1133
1134   m = dbus_message_new_signal ("/foo", "com.example.Fun",
1135       "UnicastSignal3");
1136   if (!dbus_message_set_destination (m, f->recipient_name))
1137     g_error ("OOM");
1138   dbus_connection_send (f->sender, m, NULL);
1139   dbus_message_unref (m);
1140
1141   while (g_queue_get_length (&f->monitored) < 2)
1142     test_main_context_iterate (f->ctx, TRUE);
1143
1144   /* We get the interesting signal and the fun signal, but not the tedious
1145    * signal. */
1146
1147   m = g_queue_pop_head (&f->monitored);
1148   assert_signal (m, f->sender_name, "/foo",
1149       "com.example.Interesting", "UnicastSignal1", "", f->recipient_name);
1150   dbus_message_unref (m);
1151
1152   m = g_queue_pop_head (&f->monitored);
1153   assert_signal (m, f->sender_name, "/foo",
1154       "com.example.Fun", "UnicastSignal3", "", f->recipient_name);
1155   dbus_message_unref (m);
1156
1157   m = g_queue_pop_head (&f->monitored);
1158   g_assert (m == NULL);
1159 }
1160
1161 static void
1162 expect_new_connection (Fixture *f)
1163 {
1164   DBusMessage *m;
1165
1166   while (g_queue_get_length (&f->monitored) < 4)
1167     test_main_context_iterate (f->ctx, TRUE);
1168
1169   m = g_queue_pop_head (&f->monitored);
1170   assert_hello (m);
1171   dbus_message_unref (m);
1172
1173   m = g_queue_pop_head (&f->monitored);
1174   assert_hello_reply (m);
1175   dbus_message_unref (m);
1176
1177   m = g_queue_pop_head (&f->monitored);
1178   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS,
1179       "NameOwnerChanged", "sss", NULL);
1180   dbus_message_unref (m);
1181
1182   m = g_queue_pop_head (&f->monitored);
1183   assert_name_acquired (m);
1184   dbus_message_unref (m);
1185 }
1186
1187 static void
1188 take_well_known_name (Fixture *f,
1189     DBusConnection *connection,
1190     const char *name)
1191 {
1192   int ret;
1193
1194   ret = dbus_bus_request_name (connection, name,
1195       DBUS_NAME_FLAG_DO_NOT_QUEUE, &f->e);
1196   test_assert_no_error (&f->e);
1197   g_assert_cmpint (ret, ==, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
1198 }
1199
1200 static void
1201 expect_take_well_known_name (Fixture *f,
1202     DBusConnection *connection,
1203     const char *name)
1204 {
1205   DBusMessage *m;
1206   const char *connection_name = dbus_bus_get_unique_name (connection);
1207
1208   while (g_queue_get_length (&f->monitored) < 4)
1209     test_main_context_iterate (f->ctx, TRUE);
1210
1211   m = g_queue_pop_head (&f->monitored);
1212   assert_method_call (m, connection_name, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
1213       DBUS_INTERFACE_DBUS, "RequestName", "su");
1214   dbus_message_unref (m);
1215
1216   m = g_queue_pop_head (&f->monitored);
1217   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS,
1218       "NameOwnerChanged", "sss", NULL);
1219   dbus_message_unref (m);
1220
1221   m = g_queue_pop_head (&f->monitored);
1222   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS,
1223       "NameAcquired", "s", connection_name);
1224   dbus_message_unref (m);
1225
1226   m = g_queue_pop_head (&f->monitored);
1227   assert_method_reply (m, DBUS_SERVICE_DBUS, connection_name, "u");
1228   dbus_message_unref (m);
1229 }
1230
1231 static void
1232 test_activation (Fixture *f,
1233     gconstpointer context)
1234 {
1235   DBusMessage *m;
1236
1237   if (f->address == NULL)
1238     return;
1239
1240   become_monitor (f);
1241
1242   /* The sender sends a message to an activatable service. */
1243   m = dbus_message_new_signal ("/foo", "com.example.bar", "UnicastSignal1");
1244   if (!dbus_message_set_destination (m, "com.example.SystemdActivatable1"))
1245     g_error ("OOM");
1246   dbus_connection_send (f->sender, m, NULL);
1247   dbus_message_unref (m);
1248
1249   /* We observe the activation request, and the message that caused it,
1250    * before systemd has even joined the bus. */
1251   while (g_queue_get_length (&f->monitored) < 2)
1252     test_main_context_iterate (f->ctx, TRUE);
1253
1254   m = g_queue_pop_head (&f->monitored);
1255   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
1256       "org.freedesktop.systemd1.Activator", "ActivationRequest", "s",
1257       "org.freedesktop.systemd1");
1258   dbus_message_unref (m);
1259   m = g_queue_pop_head (&f->monitored);
1260   assert_signal (m, f->sender_name, "/foo",
1261       "com.example.bar", "UnicastSignal1", "",
1262       "com.example.SystemdActivatable1");
1263   dbus_message_unref (m);
1264
1265   /* The fake systemd connects to the bus. */
1266   f->systemd = test_connect_to_bus (f->ctx, f->address);
1267   if (!dbus_connection_add_filter (f->systemd, systemd_filter, f, NULL))
1268     g_error ("OOM");
1269   f->systemd_name = dbus_bus_get_unique_name (f->systemd);
1270
1271   expect_new_connection (f);
1272   take_well_known_name (f, f->systemd, "org.freedesktop.systemd1");
1273   expect_take_well_known_name (f, f->systemd, "org.freedesktop.systemd1");
1274
1275   /* It gets its activation request. */
1276   while (f->systemd_message == NULL)
1277     test_main_context_iterate (f->ctx, TRUE);
1278
1279   m = f->systemd_message;
1280   f->systemd_message = NULL;
1281   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
1282       "org.freedesktop.systemd1.Activator", "ActivationRequest", "s",
1283       "org.freedesktop.systemd1");
1284   dbus_message_unref (m);
1285
1286   /* systemd starts the activatable service. */
1287   f->activated = test_connect_to_bus (f->ctx, f->address);
1288   if (!dbus_connection_add_filter (f->activated, activated_filter,
1289         f, NULL))
1290     g_error ("OOM");
1291   f->activated_name = dbus_bus_get_unique_name (f->activated);
1292
1293   expect_new_connection (f);
1294   take_well_known_name (f, f->activated, "com.example.SystemdActivatable1");
1295   expect_take_well_known_name (f, f->activated,
1296       "com.example.SystemdActivatable1");
1297
1298   /* The message is delivered to the activatable service. */
1299   while (f->activated_message == NULL)
1300     test_main_context_iterate (f->ctx, TRUE);
1301
1302   m = f->activated_message;
1303   f->activated_message = NULL;
1304   assert_signal (m, f->sender_name, "/foo",
1305       "com.example.bar", "UnicastSignal1", "",
1306       "com.example.SystemdActivatable1");
1307   dbus_message_unref (m);
1308
1309   /* The sender sends a message to a different activatable service. */
1310   m = dbus_message_new_signal ("/foo", "com.example.bar", "UnicastSignal2");
1311   if (!dbus_message_set_destination (m, "com.example.SystemdActivatable2"))
1312     g_error ("OOM");
1313   dbus_connection_send (f->sender, m, NULL);
1314   dbus_message_unref (m);
1315
1316   /* This time systemd is already ready for it. */
1317   while (g_queue_get_length (&f->monitored) < 2 ||
1318       f->systemd_message == NULL)
1319     test_main_context_iterate (f->ctx, TRUE);
1320
1321   m = f->systemd_message;
1322   f->systemd_message = NULL;
1323   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
1324       "org.freedesktop.systemd1.Activator", "ActivationRequest", "s",
1325       "org.freedesktop.systemd1");
1326   dbus_message_unref (m);
1327
1328   /* The monitor sees the activation request and the signal that
1329    * prompted it.*/
1330   m = g_queue_pop_head (&f->monitored);
1331   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
1332       "org.freedesktop.systemd1.Activator", "ActivationRequest", "s",
1333       "org.freedesktop.systemd1");
1334   dbus_message_unref (m);
1335   m = g_queue_pop_head (&f->monitored);
1336   assert_signal (m, f->sender_name, "/foo",
1337       "com.example.bar", "UnicastSignal2", "",
1338       "com.example.SystemdActivatable2");
1339   dbus_message_unref (m);
1340
1341   /* The activatable service takes its name. Here I'm faking it by using
1342    * an existing connection. */
1343   take_well_known_name (f, f->activated, "com.example.SystemdActivatable2");
1344
1345   /* The message is delivered to the activatable service.
1346    * Implementation detail: the monitor sees this happen before it even
1347    * sees that the name request happened, which is pretty odd. */
1348   while (f->activated_message == NULL)
1349     test_main_context_iterate (f->ctx, TRUE);
1350
1351   m = f->activated_message;
1352   f->activated_message = NULL;
1353   assert_signal (m, f->sender_name, "/foo",
1354       "com.example.bar", "UnicastSignal2", "",
1355       "com.example.SystemdActivatable2");
1356   dbus_message_unref (m);
1357
1358   expect_take_well_known_name (f, f->activated,
1359       "com.example.SystemdActivatable2");
1360
1361   /* A third activation. */
1362   m = dbus_message_new_signal ("/foo", "com.example.bar", "UnicastSignal3");
1363   if (!dbus_message_set_destination (m, "com.example.SystemdActivatable3"))
1364     g_error ("OOM");
1365   dbus_connection_send (f->sender, m, NULL);
1366   dbus_message_unref (m);
1367
1368   /* Once again, we see the activation request and the reason. */
1369   while (g_queue_get_length (&f->monitored) < 2)
1370     test_main_context_iterate (f->ctx, TRUE);
1371
1372   m = g_queue_pop_head (&f->monitored);
1373   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
1374       "org.freedesktop.systemd1.Activator", "ActivationRequest", "s",
1375       "org.freedesktop.systemd1");
1376   dbus_message_unref (m);
1377   m = g_queue_pop_head (&f->monitored);
1378   assert_signal (m, f->sender_name, "/foo",
1379       "com.example.bar", "UnicastSignal3", "",
1380       "com.example.SystemdActivatable3");
1381   dbus_message_unref (m);
1382
1383   /* systemd gets the request too. */
1384   while (f->systemd_message == NULL)
1385     test_main_context_iterate (f->ctx, TRUE);
1386
1387   m = f->systemd_message;
1388   f->systemd_message = NULL;
1389   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
1390       "org.freedesktop.systemd1.Activator", "ActivationRequest", "s",
1391       "org.freedesktop.systemd1");
1392   dbus_message_unref (m);
1393
1394   /* This time activation fails */
1395   m = dbus_message_new_signal ("/org/freedesktop/systemd1",
1396       "org.freedesktop.systemd1.Activator", "ActivationFailure");
1397
1398   do
1399     {
1400       const char *unit = "dbus-com.example.SystemdActivatable3.service";
1401       const char *error_name = "com.example.Nope";
1402       const char *error_message = "Computer says no";
1403
1404       if (!dbus_message_append_args (m,
1405             DBUS_TYPE_STRING, &unit,
1406             DBUS_TYPE_STRING, &error_name,
1407             DBUS_TYPE_STRING, &error_message,
1408             DBUS_TYPE_INVALID))
1409         g_error ("OOM");
1410     }
1411   while (0);
1412
1413   if (!dbus_message_set_destination (m, "org.freedesktop.DBus"))
1414     g_error ("OOM");
1415   dbus_connection_send (f->systemd, m, NULL);
1416   dbus_message_unref (m);
1417
1418   /* The monitor sees activation fail */
1419
1420   /* Once again, we see the activation request and the reason. */
1421   while (g_queue_get_length (&f->monitored) < 1)
1422     test_main_context_iterate (f->ctx, TRUE);
1423
1424   m = g_queue_pop_head (&f->monitored);
1425   assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
1426       "com.example.Nope");
1427   dbus_message_unref (m);
1428 }
1429
1430 static void
1431 teardown (Fixture *f,
1432     gconstpointer context G_GNUC_UNUSED)
1433 {
1434   dbus_error_free (&f->e);
1435   g_clear_error (&f->ge);
1436
1437   if (f->monitor != NULL)
1438     {
1439       dbus_connection_remove_filter (f->monitor, monitor_filter, f);
1440       dbus_connection_close (f->monitor);
1441       dbus_connection_unref (f->monitor);
1442       f->monitor = NULL;
1443     }
1444
1445   if (f->sender != NULL)
1446     {
1447       dbus_connection_close (f->sender);
1448       dbus_connection_unref (f->sender);
1449       f->sender = NULL;
1450     }
1451
1452   if (f->recipient != NULL)
1453     {
1454       dbus_connection_remove_filter (f->recipient, recipient_filter, f);
1455       dbus_connection_close (f->recipient);
1456       dbus_connection_unref (f->recipient);
1457       f->recipient = NULL;
1458     }
1459
1460   if (f->systemd != NULL)
1461     {
1462       dbus_connection_remove_filter (f->systemd, systemd_filter, f);
1463       dbus_connection_close (f->systemd);
1464       dbus_connection_unref (f->systemd);
1465       f->systemd = NULL;
1466     }
1467
1468   if (f->activated != NULL)
1469     {
1470       dbus_connection_remove_filter (f->activated, activated_filter, f);
1471       dbus_connection_close (f->activated);
1472       dbus_connection_unref (f->activated);
1473       f->activated = NULL;
1474     }
1475
1476   test_kill_pid (f->daemon_pid);
1477   g_spawn_close_pid (f->daemon_pid);
1478
1479   test_main_context_unref (f->ctx);
1480
1481   g_queue_foreach (&f->monitored, (GFunc) dbus_message_unref, NULL);
1482   g_queue_clear (&f->monitored);
1483
1484   g_free (f->address);
1485 }
1486
1487 int
1488 main (int argc,
1489     char **argv)
1490 {
1491   test_init (&argc, &argv);
1492
1493   g_test_add ("/monitor/become", Fixture, &side_effects_config,
1494       setup, test_become_monitor, teardown);
1495   g_test_add ("/monitor/broadcast", Fixture, NULL,
1496       setup, test_broadcast, teardown);
1497   g_test_add ("/monitor/forbidden-broadcast", Fixture, &forbidding_config,
1498       setup, test_forbidden_broadcast, teardown);
1499   g_test_add ("/monitor/unicast-signal", Fixture, NULL,
1500       setup, test_unicast_signal, teardown);
1501   g_test_add ("/monitor/forbidden", Fixture, &forbidding_config,
1502       setup, test_forbidden, teardown);
1503   g_test_add ("/monitor/method-call", Fixture, NULL,
1504       setup, test_method_call, teardown);
1505   g_test_add ("/monitor/forbidden-method", Fixture, &forbidding_config,
1506       setup, test_forbidden_method_call, teardown);
1507   g_test_add ("/monitor/dbus-daemon", Fixture, NULL,
1508       setup, test_dbus_daemon, teardown);
1509   g_test_add ("/monitor/selective", Fixture, &selective_config,
1510       setup, test_selective, teardown);
1511   g_test_add ("/monitor/wildcard", Fixture, &wildcard_config,
1512       setup, test_unicast_signal, teardown);
1513   g_test_add ("/monitor/no-rule", Fixture, &no_rules_config,
1514       setup, test_unicast_signal, teardown);
1515   g_test_add ("/monitor/eavesdrop", Fixture, &eavesdrop_config,
1516       setup, test_unicast_signal, teardown);
1517   g_test_add ("/monitor/no-eavesdrop", Fixture, &no_eavesdrop_config,
1518       setup, test_unicast_signal, teardown);
1519   g_test_add ("/monitor/activation", Fixture, &fake_systemd_config,
1520       setup, test_activation, teardown);
1521
1522   return g_test_run ();
1523 }