unit: Add PropertyChanged watch for Manager
[framework/connectivity/connman.git] / unit / utils.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2011  BWM CarIT GmbH. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdlib.h>
27
28 #include "gdbus/gdbus.h"
29
30 #include "test-connman.h"
31
32 #define ENABLE_WRAPPER 1
33 #define PROPERTY_CHANGED                "PropertyChanged"
34
35 gboolean util_quit_loop(gpointer data)
36 {
37         struct test_fix *fix = data;
38
39         g_main_loop_quit(fix->main_loop);
40
41         return FALSE;
42 }
43
44 guint util_idle_call(struct test_fix *fix, GSourceFunc func,
45                         GDestroyNotify notify)
46 {
47         GSource *source;
48         guint id;
49
50         source = g_idle_source_new();
51         g_source_set_callback(source, func, fix, notify);
52         id = g_source_attach(source, g_main_loop_get_context(fix->main_loop));
53         g_source_unref(source);
54
55         return id;
56 }
57
58 static void connman_died(DBusConnection *connection, void *user_data)
59 {
60         g_assert(FALSE);
61 }
62
63 static void manager_changed(struct test_fix *fix,
64                                         DBusMessageIter *entry)
65 {
66         DBusMessageIter iter;
67         const char *key;
68         const char *value;
69         int type;
70
71         dbus_message_iter_get_basic(entry, &key);
72
73         LOG("key %s", key);
74
75         dbus_message_iter_next(entry);
76
77         dbus_message_iter_recurse(entry, &iter);
78
79         type = dbus_message_iter_get_arg_type(&iter);
80
81         if (type != DBUS_TYPE_STRING)
82                 return;
83
84         dbus_message_iter_get_basic(&iter, &value);
85
86         if (g_str_equal(key, "State") == TRUE) {
87                 LOG("State %s", value);
88
89                 if (fix->manager.state != NULL)
90                         g_free(fix->manager.state);
91
92                 fix->manager.state = g_strdup(value);
93         }
94 }
95
96 static gboolean handle_manager_changed(DBusConnection *connection,
97                                 DBusMessage *message,
98                                 void *user_data)
99 {
100         struct test_fix *fix = user_data;
101
102         DBusMessageIter iter;
103
104         if (dbus_message_iter_init(message, &iter))
105                 manager_changed(fix, &iter);
106
107         return TRUE;
108 }
109
110 guint util_call(struct test_fix *fix, GSourceFunc func,
111                 GDestroyNotify notify)
112 {
113         GSource *source;
114         guint id;
115
116         source = g_timeout_source_new(0);
117         g_source_set_callback(source, func, fix, notify);
118         id = g_source_attach(source, g_main_loop_get_context(fix->main_loop));
119         g_source_unref(source);
120
121         return id;
122 }
123
124 void util_setup(struct test_fix *fix, gconstpointer data)
125 {
126         DBusMessage *msg;
127
128         fix->main_loop = g_main_loop_new(NULL, FALSE);
129         fix->main_connection = g_dbus_setup_private(DBUS_BUS_SYSTEM,
130                                                         NULL, NULL);
131         fix->watch = g_dbus_add_service_watch(fix->main_connection,
132                                                 CONNMAN_SERVICE,
133                                                 NULL,
134                                                 connman_died,
135                                                 NULL, NULL);
136         fix->manager_watch = g_dbus_add_signal_watch(fix->main_connection,
137                                                 NULL, NULL,
138                                                 CONNMAN_MANAGER_INTERFACE,
139                                                 PROPERTY_CHANGED,
140                                                 handle_manager_changed,
141                                                 fix, NULL);
142
143         msg = manager_get_properties(fix->main_connection);
144         manager_parse_properties(msg, &fix->manager);
145         dbus_message_unref(msg);
146 }
147
148 void util_teardown(struct test_fix *fix, gconstpointer data)
149 {
150         g_dbus_remove_watch(fix->main_connection, fix->watch);
151         g_dbus_remove_watch(fix->main_connection, fix->manager_watch);
152         dbus_connection_close(fix->main_connection);
153         dbus_connection_unref(fix->main_connection);
154
155         g_main_loop_unref(fix->main_loop);
156 }
157
158 static void util_wrapper(struct test_fix *fix, gconstpointer data)
159 {
160         GSourceFunc func = data;
161 #if ENABLE_WRAPPER
162         if (g_test_trap_fork(60 * 1000 * 1000, 0) == TRUE) {
163                 util_call(fix, func, NULL);
164                 g_main_loop_run(fix->main_loop);
165                 exit(0);
166         }
167
168         g_test_trap_assert_passed();
169 #else
170         util_call(fix, func, NULL);
171         g_main_loop_run(fix->main_loop);
172 #endif
173 }
174
175 void util_test_add(const char *test_name, GSourceFunc test_func,
176                         util_test_setup_cb setup_cb,
177                         util_test_teardown_cb teardown_cb)
178 {
179         g_test_add(test_name, struct test_fix, test_func,
180                 setup_cb, util_wrapper, teardown_cb);
181 }
182
183 void util_session_create(struct test_fix *fix, unsigned int max_sessions)
184 {
185         unsigned int i;
186
187         fix->max_sessions = max_sessions;
188         fix->session = g_try_new0(struct test_session, max_sessions);
189
190         for (i = 0; i < max_sessions; i++) {
191                 fix->session[i].fix = fix;
192                 fix->session[i].info = g_try_new0(struct test_session_info, 1);
193                 fix->session[i].connection = g_dbus_setup_private(
194                                                 DBUS_BUS_SYSTEM, NULL, NULL);
195         }
196 }
197
198 void util_session_destroy(gpointer data)
199 {
200         struct test_fix *fix = data;
201
202         unsigned int i;
203
204         for (i = 0; i < fix->max_sessions; i++) {
205                 dbus_connection_close(fix->session[i].connection);
206                 g_free(fix->session[i].info);
207         }
208
209         g_free(fix->session);
210 }
211
212 void util_session_init(struct test_session *session)
213 {
214         DBusMessage *msg;
215         DBusMessageIter iter;
216         const char *path;
217         int err;
218
219         err = session_notify_register(session, session->notify_path);
220         g_assert(err == 0);
221
222         msg = manager_create_session(session->connection,
223                                         session->info,
224                                         session->notify_path);
225         g_assert(msg != NULL);
226         dbus_message_iter_init(msg, &iter);
227
228         dbus_message_iter_get_basic(&iter, &path);
229         session->session_path = g_strdup(path);
230
231         dbus_message_unref(msg);
232 }
233
234 void util_session_cleanup(struct test_session *session)
235 {
236         DBusMessage *msg;
237         int err;
238
239         msg = manager_destroy_session(session->connection,
240                                         session->session_path);
241         g_assert(msg != NULL);
242         dbus_message_unref(msg);
243
244         err = session_notify_unregister(session,
245                                         session->notify_path);
246         g_assert(err == 0);
247
248         g_free(session->info->bearer);
249         g_free(session->info->name);
250         g_free(session->info->interface);
251         g_slist_foreach(session->info->allowed_bearers,
252                         bearer_info_cleanup, NULL);
253         g_slist_free(session->info->allowed_bearers);
254
255         session->notify = NULL;
256         g_free(session->notify_path);
257         g_free(session->session_path);
258 }