session: Disconnect free ride session
[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         if (fix->manager_changed != NULL)
96                 fix->manager_changed(fix);
97 }
98
99 static gboolean handle_manager_changed(DBusConnection *connection,
100                                 DBusMessage *message,
101                                 void *user_data)
102 {
103         struct test_fix *fix = user_data;
104
105         DBusMessageIter iter;
106
107         if (dbus_message_iter_init(message, &iter))
108                 manager_changed(fix, &iter);
109
110         return TRUE;
111 }
112
113 guint util_call(struct test_fix *fix, GSourceFunc func,
114                 GDestroyNotify notify)
115 {
116         GSource *source;
117         guint id;
118
119         source = g_timeout_source_new(0);
120         g_source_set_callback(source, func, fix, notify);
121         id = g_source_attach(source, g_main_loop_get_context(fix->main_loop));
122         g_source_unref(source);
123
124         return id;
125 }
126
127 void util_setup(struct test_fix *fix, gconstpointer data)
128 {
129         DBusMessage *msg;
130
131         fix->main_loop = g_main_loop_new(NULL, FALSE);
132         fix->main_connection = g_dbus_setup_private(DBUS_BUS_SYSTEM,
133                                                         NULL, NULL);
134         fix->watch = g_dbus_add_service_watch(fix->main_connection,
135                                                 CONNMAN_SERVICE,
136                                                 NULL,
137                                                 connman_died,
138                                                 NULL, NULL);
139         fix->manager_watch = g_dbus_add_signal_watch(fix->main_connection,
140                                                 NULL, NULL,
141                                                 CONNMAN_MANAGER_INTERFACE,
142                                                 PROPERTY_CHANGED,
143                                                 handle_manager_changed,
144                                                 fix, NULL);
145
146         msg = manager_get_properties(fix->main_connection);
147         manager_parse_properties(msg, &fix->manager);
148         dbus_message_unref(msg);
149 }
150
151 void util_teardown(struct test_fix *fix, gconstpointer data)
152 {
153         g_dbus_remove_watch(fix->main_connection, fix->watch);
154         g_dbus_remove_watch(fix->main_connection, fix->manager_watch);
155         dbus_connection_close(fix->main_connection);
156         dbus_connection_unref(fix->main_connection);
157
158         g_main_loop_unref(fix->main_loop);
159 }
160
161 static void util_wrapper(struct test_fix *fix, gconstpointer data)
162 {
163         GSourceFunc func = data;
164 #if ENABLE_WRAPPER
165         if (g_test_trap_fork(60 * 1000 * 1000, 0) == TRUE) {
166                 util_call(fix, func, NULL);
167                 g_main_loop_run(fix->main_loop);
168                 exit(0);
169         }
170
171         g_test_trap_assert_passed();
172 #else
173         util_call(fix, func, NULL);
174         g_main_loop_run(fix->main_loop);
175 #endif
176 }
177
178 void util_test_add(const char *test_name, GSourceFunc test_func,
179                         util_test_setup_cb setup_cb,
180                         util_test_teardown_cb teardown_cb)
181 {
182         g_test_add(test_name, struct test_fix, test_func,
183                 setup_cb, util_wrapper, teardown_cb);
184 }
185
186 void util_session_create(struct test_fix *fix, unsigned int max_sessions)
187 {
188         unsigned int i;
189
190         fix->max_sessions = max_sessions;
191         fix->session = g_try_new0(struct test_session, max_sessions);
192
193         for (i = 0; i < max_sessions; i++) {
194                 fix->session[i].fix = fix;
195                 fix->session[i].info = g_try_new0(struct test_session_info, 1);
196                 fix->session[i].connection = g_dbus_setup_private(
197                                                 DBUS_BUS_SYSTEM, NULL, NULL);
198         }
199 }
200
201 void util_session_destroy(gpointer data)
202 {
203         struct test_fix *fix = data;
204
205         unsigned int i;
206
207         for (i = 0; i < fix->max_sessions; i++) {
208                 dbus_connection_close(fix->session[i].connection);
209                 g_free(fix->session[i].info);
210         }
211
212         g_free(fix->session);
213 }
214
215 void util_session_init(struct test_session *session)
216 {
217         DBusMessage *msg;
218         DBusMessageIter iter;
219         const char *path;
220         int err;
221
222         err = session_notify_register(session, session->notify_path);
223         g_assert(err == 0);
224
225         msg = manager_create_session(session->connection,
226                                         session->info,
227                                         session->notify_path);
228         g_assert(msg != NULL);
229         dbus_message_iter_init(msg, &iter);
230
231         dbus_message_iter_get_basic(&iter, &path);
232         session->session_path = g_strdup(path);
233
234         dbus_message_unref(msg);
235 }
236
237 void util_session_cleanup(struct test_session *session)
238 {
239         DBusMessage *msg;
240         int err;
241
242         msg = manager_destroy_session(session->connection,
243                                         session->session_path);
244         g_assert(msg != NULL);
245         dbus_message_unref(msg);
246
247         err = session_notify_unregister(session,
248                                         session->notify_path);
249         g_assert(err == 0);
250
251         g_free(session->info->bearer);
252         g_free(session->info->name);
253         g_free(session->info->interface);
254         g_slist_foreach(session->info->allowed_bearers,
255                         bearer_info_cleanup, NULL);
256         g_slist_free(session->info->allowed_bearers);
257
258         session->notify = NULL;
259         g_free(session->notify_path);
260         g_free(session->session_path);
261 }