9376974c5ecd95f54ed72920eb5662b271f49f7e
[profile/ivi/message-port.git] / tests / test-app.c
1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 /*
4  * This file is part of message-port.
5  *
6  * Copyright (C) 2013 Intel Corporation.
7  *
8  * Contact: Amarnath Valluri <amarnath.valluri@linux.intel.com>
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23  * 02110-1301 USA
24  */
25
26 #include "config.h"
27 #include <glib.h>
28 #include <unistd.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <message-port.h>
32 #include <bundle.h>
33 #include <unistd.h>
34
35 int __pipe[2]; /* pipe between two process */
36 pid_t __daemon_pid; /* dbus daemon pid */
37
38 const gchar *PARENT_TEST_PORT = "parent_test_port";
39 const gchar *PARENT_TEST_TRUSTED_PORT = "parent_test_trusted_port";
40 const gchar *CHILD_TEST_PORT = "child_test_port";
41 const gchar *CHILD_TEST_TRUSTED_PORT = "child_test_trusted_port";
42
43 struct AsyncTestData
44 {
45     GMainLoop *m_loop;
46     gboolean   result;
47 } *__test_data  = NULL;
48
49 #define TEST_CASE(case) \
50 do { \
51     if (case() != TRUE) { \
52         g_printerr ("%s: FAIL\n", #case); \
53         return -1; \
54     } \
55     else g_print ("%s: SUCCESS\n", #case); \
56 }while (0)
57
58
59 #define test_assert(expr, msg...) \
60 do { \
61     if ((expr) == FALSE) {\
62         g_print ("%s +%d: assert(%s):%s\n", __FUNCTION__, __LINE__, #expr, ##msg); \
63         return FALSE; \
64     } \
65 } while(0);
66
67
68 static void _dump_data (const char *key, const int type, const bundle_keyval_t *kv, void *user_data)
69 {
70     gchar *val = NULL;
71     size_t size;
72     bundle_keyval_get_basic_val ((bundle_keyval_t*)kv, (void**)&val, &size);
73     g_debug ("       %s - %s", key, val);
74 }
75
76 void (_on_child_got_message)(int port_id, const char* remote_app_id, const char* remote_port, gboolean trusted_message, bundle* data)
77 {
78     gchar *name = NULL;
79     messageport_get_local_port_name (port_id, &name),
80     g_debug ("CHILD: GOT MESSAGE at prot '%s' FROM :'%s' - '%s", name,
81         remote_app_id ? remote_app_id : "unknwon app", remote_port ? remote_port : "unknwon");
82     g_free (name);
83     g_assert (data);
84
85     bundle_foreach (data, _dump_data, NULL);
86
87     /* Write acknoledgement */
88     if (write (__pipe[1], "OK", strlen("OK") + 1) < 3) {
89         g_warning ("WRITE failed");
90     }
91
92     if (__test_data) {
93         __test_data->result = TRUE;
94         g_main_loop_quit (__test_data->m_loop);
95     }
96 }
97
98 void (_on_parent_got_message)(int port_id, const char* remote_app_id, const char* remote_port, gboolean trusted_message, bundle* data)
99 {
100     gchar *name = NULL;
101     gboolean found = FALSE;
102     bundle *b = NULL;
103     messageport_get_local_port_name (port_id, &name),
104     g_debug ("PARENT: GOT MESSAGE at prot %s FROM :'%s' app - '%s' port", name,
105         remote_app_id ? remote_app_id : "unknwon", remote_port ? remote_port : "unknwon");
106     g_free (name);
107
108     g_assert (data);
109
110     bundle_foreach (data, _dump_data, NULL);
111
112     /* Write acknoledgement */
113     if ( write (__pipe[1], "OK", strlen("OK") + 1) < 3) {
114         g_warning ("WRITE failed");
115     }
116
117     /* check message is coming from remote port to send back to message,
118      * if not ignore */
119     if (!remote_app_id || !remote_port) {
120         return;
121     }
122
123     messageport_error_e res = trusted_message ? messageport_check_trusted_remote_port (remote_app_id, remote_port, &found)
124                                               : messageport_check_remote_port (remote_app_id, remote_port, &found);
125     if (!found) {
126         g_warning ("PARENT: Could not found remote port (%d)", res);
127         return ;
128     }
129
130     g_debug ("PARENT: Found remote prot");
131
132     bundle *reply = bundle_create ();
133
134     bundle_add (reply, "Results", "GOT_IT");
135
136     g_debug ("PARENT: Sending reply ....");
137     res = trusted_message ? messageport_send_trusted_message (remote_app_id, remote_port, reply)
138                           : messageport_send_message (remote_app_id, remote_port, reply);
139     bundle_free (reply);
140     if (res != MESSAGEPORT_ERROR_NONE)
141     {
142         g_warning ("PARENT: Faile to send message to server : %d", res);
143     }
144     else g_debug ("PARENT: Data sent successfully");
145 }
146
147 int _register_test_port (const gchar *port_name, gboolean is_trusted, messageport_message_cb cb)
148 {
149     int port_id = is_trusted ? messageport_register_trusted_local_port (port_name, cb)
150                              : messageport_register_local_port (port_name, cb);
151
152     return port_id;
153 }
154
155 static gboolean
156 test_register_local_port ()
157 {
158     int port_id =  _register_test_port (PARENT_TEST_PORT, FALSE, _on_parent_got_message);
159
160     test_assert (port_id >= 0, "Failed to register port '%s', error : %d", PARENT_TEST_PORT, port_id);
161
162     return TRUE;
163 }
164
165 static gboolean
166 test_register_trusted_local_port()
167 {
168     int port_id =  _register_test_port (PARENT_TEST_TRUSTED_PORT, TRUE, _on_parent_got_message);
169
170     test_assert (port_id >= 0, "Failed to register port '%s', error : %d", PARENT_TEST_TRUSTED_PORT, port_id);
171
172     return TRUE;
173 }
174
175 static gboolean
176 test_check_remote_port()
177 {
178     const gchar remote_app_id[128];
179     gboolean found = FALSE;
180     messageport_error_e res;
181
182     g_sprintf (remote_app_id, "%d", getppid());
183
184     res = messageport_check_remote_port (remote_app_id, PARENT_TEST_PORT, &found);
185
186     test_assert (res == MESSAGEPORT_ERROR_NONE, "Fail to find remote port '%s' at app_id '%s', error: %d", PARENT_TEST_PORT, remote_app_id, res);
187
188     return TRUE;
189 }
190
191 static gboolean
192 test_check_trusted_remote_port()
193 {
194     const gchar remote_app_id[128];
195     gboolean found = FALSE;
196     messageport_error_e res;
197
198     g_sprintf (remote_app_id, "%d", getppid());
199
200     res = messageport_check_trusted_remote_port (remote_app_id, PARENT_TEST_TRUSTED_PORT, &found);
201     test_assert (res == MESSAGEPORT_ERROR_NONE, "Fail to find trusted remote port '%s' at app_id '%s', error: %d", PARENT_TEST_TRUSTED_PORT, remote_app_id, res);
202
203     return TRUE;
204 }
205
206 static gboolean
207 test_send_message()
208 {
209     messageport_error_e res;
210     const gchar remote_app_id[128];
211     bundle *b = bundle_create ();
212     bundle_add (b, "Name", "Amarnath");
213     bundle_add (b, "Email", "amarnath.valluri@intel.com");
214
215     g_sprintf (remote_app_id, "%d", getppid());
216     res = messageport_send_message (remote_app_id, PARENT_TEST_PORT, b);
217     bundle_free (b);
218     test_assert (res == MESSAGEPORT_ERROR_NONE, "Fail to send message to port '%s' at app_id : '%s', error : %d", PARENT_TEST_PORT, remote_app_id, res);
219
220     gchar result[32];
221
222     test_assert ((read (__pipe[0], &result, sizeof(result)) > 0), "Parent did not received the message");
223     test_assert ((g_strcmp0 (result, "OK") == 0), "Parent did not received the message");
224
225     return TRUE;
226 }
227
228 static gboolean
229 test_send_trusted_message()
230 {
231     messageport_error_e res;
232     const gchar remote_app_id[128];
233     bundle *b = bundle_create ();
234     bundle_add (b, "Name", "Amarnath");
235     bundle_add (b, "Email", "amarnath.valluri@intel.com");
236
237     g_sprintf (remote_app_id, "%d", getppid());
238     res = messageport_send_trusted_message (remote_app_id, PARENT_TEST_TRUSTED_PORT, b);
239     bundle_free (b);
240     test_assert (res == MESSAGEPORT_ERROR_NONE, "Fail to send message to port '%s' at app_id : '%s', error : %d", PARENT_TEST_PORT, remote_app_id, res);
241
242     gchar result[32];
243
244     test_assert( (read (__pipe[0], &result, sizeof(result)) > 0), "Parent did not received the message");
245     test_assert( (g_strcmp0 (result, "OK") == 0), "Parent did not received the message");
246
247     return TRUE;
248 }
249
250 static gboolean
251 _update_test_result (gpointer data)
252 {
253     if (__test_data) {
254         __test_data->result = FALSE;
255         g_main_loop_quit (__test_data->m_loop);
256     }
257
258     return FALSE;
259 }
260
261 static gboolean
262 test_send_bidirectional_message()
263 {
264     messageport_error_e res;
265     int local_port_id = 0;
266     const gchar remote_app_id[128];
267     gchar result[32];
268     gboolean child_got_message = FALSE;
269     bundle *b = bundle_create ();
270     bundle_add (b, "Name", "Amarnath");
271     bundle_add (b, "Email", "amarnath.valluri@intel.com");
272
273     child_got_message = FALSE;
274
275     /* register local message port for return message */
276     test_assert ((local_port_id = _register_test_port (CHILD_TEST_PORT, FALSE, _on_child_got_message)) > 0,
277         "Fail to register message port");
278
279     g_sprintf (remote_app_id, "%d", getppid());
280     res = messageport_send_bidirectional_message (local_port_id, remote_app_id, PARENT_TEST_PORT, b);
281     bundle_free (b);
282     test_assert (res == MESSAGEPORT_ERROR_NONE,
283         "Fail to send message to port '%s' at app_id : '%s', error : %d", PARENT_TEST_PORT, remote_app_id, res);
284
285
286     test_assert( (read (__pipe[0], &result, sizeof(result)) > 0), "Parent did not received the message");
287     test_assert( (g_strcmp0 (result, "OK") == 0), "Parent did not received the message");
288
289     __test_data = g_new0 (struct AsyncTestData, 1);
290     __test_data->m_loop = g_main_loop_new (NULL, FALSE);
291     g_timeout_add_seconds (5, _update_test_result, NULL);
292
293     g_main_loop_run (__test_data->m_loop);
294     child_got_message = __test_data->result;
295
296     g_main_loop_unref (__test_data->m_loop);
297     g_free (__test_data);
298     __test_data = NULL;
299
300     test_assert (child_got_message == TRUE, "Child did not recieved reply");
301
302     return TRUE;
303 }
304
305 static gboolean
306 test_send_bidirectional_trusted_message()
307 {
308     messageport_error_e res;
309     int local_port_id = 0;
310     const gchar remote_app_id[128];
311     gchar result[32];
312     gboolean child_got_message = FALSE;
313     bundle *b = bundle_create ();
314     bundle_add (b, "Name", "Amarnath");
315     bundle_add (b, "Email", "amarnath.valluri@intel.com");
316
317     child_got_message = FALSE;
318
319     /* register local message port for return message */
320     test_assert ((local_port_id = _register_test_port (CHILD_TEST_TRUSTED_PORT, FALSE, _on_child_got_message)) > 0,
321         "Fail to register message port");
322
323     g_sprintf (remote_app_id, "%d", getppid());
324     res = messageport_send_bidirectional_trusted_message (local_port_id, remote_app_id, PARENT_TEST_TRUSTED_PORT, b);
325     bundle_free (b);
326     test_assert (res == MESSAGEPORT_ERROR_NONE,
327         "Fail to send message to port '%s' at app_id : '%s', error : %d", PARENT_TEST_TRUSTED_PORT, remote_app_id, res);
328
329
330     test_assert( (read (__pipe[0], &result, sizeof(result)) > 0), "Parent did not received the message");
331     test_assert( (g_strcmp0 (result, "OK") == 0), "Parent did not received the message");
332
333     __test_data = g_new0 (struct AsyncTestData, 1);
334     __test_data->m_loop = g_main_loop_new (NULL, FALSE);
335     g_timeout_add_seconds (5, _update_test_result, NULL);
336
337     g_main_loop_run (__test_data->m_loop);
338     child_got_message = __test_data->result;
339
340     g_main_loop_unref (__test_data->m_loop);
341     g_free (__test_data);
342     __test_data = NULL;
343
344     test_assert (child_got_message == TRUE, "Child did not recieved reply");
345
346     return TRUE;
347 }
348
349 static gboolean
350 test_get_local_port_name()
351 {
352     int local_port_id = 0;
353     messageport_error_e res;
354     gchar *port_name = NULL;
355
356     test_assert ((local_port_id = _register_test_port (CHILD_TEST_TRUSTED_PORT, FALSE, _on_child_got_message)) > 0,
357         "Fail to register test port : error : %d", local_port_id);
358     
359     res = messageport_get_local_port_name (local_port_id, &port_name);
360     test_assert (res == MESSAGEPORT_ERROR_NONE, "Failed to get message port name, error: %d", res);
361
362     test_assert (g_strcmp0 (port_name, CHILD_TEST_TRUSTED_PORT) == 0, "Got wrong port name");
363
364     return TRUE;
365 }
366
367 static gboolean
368 test_check_trusted_local_port ()
369 {
370     int local_port_id = 0;
371     messageport_error_e res;
372     gboolean is_trusted;
373
374     test_assert ((local_port_id = _register_test_port (CHILD_TEST_PORT, FALSE, _on_child_got_message)) > 0,
375         "Fail to register test port : error : %d", local_port_id);
376     
377     res = messageport_check_trusted_local_port (local_port_id, &is_trusted);
378     test_assert (res == MESSAGEPORT_ERROR_NONE, "Failed to get message port name, error: %d", res);
379     test_assert (is_trusted == FALSE, "Go FLSE for trusted port");
380
381     test_assert ((local_port_id = _register_test_port (CHILD_TEST_TRUSTED_PORT, TRUE, _on_child_got_message)) > 0,
382         "Fail to register test port : error : %d", local_port_id);
383     
384     res = messageport_check_trusted_local_port (local_port_id, &is_trusted);
385     test_assert (res == MESSAGEPORT_ERROR_NONE, "Failed to get message port name, error: %d", res);
386     test_assert (is_trusted == TRUE, "Go TRUE for untrusted port");
387
388     return TRUE;
389 }
390
391
392 static gboolean
393 _on_term (gpointer userdata)
394 {
395     g_main_loop_quit ((GMainLoop *)userdata);
396
397     return FALSE;
398 }
399
400 static gboolean
401 test_setup ()
402 {
403     GIOChannel *channel = NULL;
404     gchar *bus_address = NULL;
405     gint tmp_fd = 0;
406     gint pipe_fd[2];
407     gchar *argv[4] ;
408     gsize len = 0;
409     const gchar *dbus_monitor = NULL;
410     GError *error = NULL;
411
412     argv[0] = "dbus-daemon";
413     argv[1] = "--print-address=<<fd>>";
414     argv[2] = "--config-file="TEST_DBUS_DAEMON_CONF_FILE;
415     argv[3] = NULL;
416
417     if (pipe(pipe_fd)== -1) {
418         GSpawnFlags flags = G_SPAWN_SEARCH_PATH;
419         argv[1] = g_strdup_printf ("--print-address=1");
420         g_spawn_async_with_pipes (NULL, argv, NULL, flags, NULL, NULL, &__daemon_pid, NULL, NULL, &tmp_fd, &error);
421     } else {
422         GSpawnFlags flags = (GSpawnFlags)(G_SPAWN_SEARCH_PATH | G_SPAWN_LEAVE_DESCRIPTORS_OPEN);
423         tmp_fd = pipe_fd[0];
424         argv[1] = g_strdup_printf ("--print-address=%d", pipe_fd[1]);
425         g_spawn_async (NULL, argv, NULL, flags, NULL, NULL, &__daemon_pid, &error);
426         g_free (argv[1]);
427     }
428     test_assert (error == NULL, "Failed to span daemon : %s", error->message);
429     test_assert (__daemon_pid != 0, "Failed to get daemon pid");
430     sleep (5); /* 5 seconds */
431
432     channel = g_io_channel_unix_new (tmp_fd);
433     g_io_channel_read_line (channel, &bus_address, NULL, &len, &error);
434     test_assert (error == NULL, "Failed to daemon address : %s", error->message);
435     g_io_channel_unref (channel);
436
437     if (pipe_fd[0]) close (pipe_fd[0]);
438     if (pipe_fd[1]) close (pipe_fd[1]);
439
440     if (bus_address) bus_address[len] = '\0';
441     test_assert (bus_address != NULL && bus_address[0] != 0, "Failed to get dbus-daemon address");
442
443     setenv("DBUS_SESSION_BUS_ADDRESS", bus_address, TRUE);
444
445     g_print ("Dbus daemon start at : %s\n", bus_address);
446
447     g_free (bus_address);
448
449     return TRUE;
450 }
451
452 static void
453 test_cleanup ()
454 {
455    if (__daemon_pid) kill (__daemon_pid, SIGTERM);
456 }
457
458
459 int main (int argc, char *argv[])
460 {
461     pid_t child_pid;
462
463     if (!test_setup()) {
464         g_error ("Could not start session bus!!! \n");
465         return -1;
466     }
467
468     if (pipe (__pipe)) {
469         g_warning ("Failed to open pipe");
470         return -1;
471     }
472
473     child_pid = fork ();
474     
475     if (child_pid < 0) {
476         g_error ("Failed to fork ");
477     }
478     else if (child_pid > 0)  {
479         /* parent process */
480         GMainLoop *m_loop = g_main_loop_new (NULL, FALSE);
481         /* server ports */
482         TEST_CASE(test_register_local_port);
483         TEST_CASE(test_register_trusted_local_port);
484         TEST_CASE(test_get_local_port_name);
485         TEST_CASE(test_check_trusted_local_port);
486
487         g_unix_signal_add (SIGTERM, _on_term, m_loop);
488
489         g_main_loop_run (m_loop);
490         g_main_loop_unref (m_loop);
491     }
492     else {
493         /* child process */
494         /* sleep sometime till server ports are ready */
495         sleep (3);
496
497         TEST_CASE(test_check_remote_port);
498         TEST_CASE(test_check_trusted_remote_port);
499         TEST_CASE(test_send_message);
500         TEST_CASE(test_send_bidirectional_message);
501         TEST_CASE(test_send_trusted_message);
502         TEST_CASE(test_send_bidirectional_trusted_message);
503
504         /* end of tests */
505         kill(getppid(), SIGTERM);
506
507     }
508
509     test_cleanup();
510
511     return 0;
512 }
513