5 * Copyright (C) 2011 BMW Car IT GmbH.
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.
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.
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
29 #include <sys/types.h>
33 #include "session-test.h"
35 #define POLICYDIR STORAGEDIR "/session_policy_local"
37 enum test_session_state {
38 TEST_SESSION_STATE_0 = 0,
39 TEST_SESSION_STATE_1 = 1,
40 TEST_SESSION_STATE_2 = 2,
41 TEST_SESSION_STATE_3 = 3,
44 static enum test_session_state get_session_state(struct test_session *session)
46 return GPOINTER_TO_UINT(session->fix->user_data);
49 static void set_session_state(struct test_session *session,
50 enum test_session_state state)
52 session->fix->user_data = GUINT_TO_POINTER(state);
55 static struct test_session *get_session(struct test_session *session,
58 return &session->fix->session[index];
61 static void test_session_create_no_notify(struct test_fix *fix)
65 util_session_create(fix, 1);
67 msg = manager_create_session(fix->session->connection,
68 fix->session->info, "/foo");
70 g_assert(dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_ERROR);
72 dbus_message_unref(msg);
74 util_idle_call(fix, util_quit_loop, util_session_destroy);
77 static void test_session_destroy_no_notify(struct test_fix *fix)
81 util_session_create(fix, 1);
83 msg = manager_destroy_session(fix->session->connection, "/foo");
86 util_idle_call(fix, util_quit_loop, util_session_destroy);
89 static void test_session_create_notify(struct test_session *session)
91 LOG("session %p", session);
93 util_idle_call(session->fix, util_quit_loop, util_session_destroy);
96 static void test_session_create(struct test_fix *fix)
98 struct test_session *session;
102 util_session_create(fix, 1);
103 session = fix->session;
105 session->notify_path = "/foo";
106 session->notify = test_session_create_notify;
108 err = session_notify_register(session, session->notify_path);
111 msg = manager_create_session(session->connection,
113 session->notify_path);
115 g_assert(dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_ERROR);
117 dbus_message_unref(msg);
120 static void test_session_create_destroy(struct test_fix *fix)
122 struct test_session *session;
124 util_session_create(fix, 1);
125 session = fix->session;
127 session->notify_path = g_strdup("/foo");
129 util_session_init(fix->session);
130 util_session_cleanup(fix->session);
132 util_idle_call(fix, util_quit_loop, util_session_destroy);
135 static void test_session_create_dup_notification(struct test_fix *fix)
137 struct test_session *session0, *session1;
140 util_session_create(fix, 2);
141 session0 = &fix->session[0];
142 session1 = &fix->session[1];
144 session0->notify_path = g_strdup("/foo");
145 session1->notify_path = session0->notify_path;
147 util_session_init(session0);
149 msg = manager_create_session(session1->connection,
151 session1->notify_path);
154 util_session_cleanup(session0);
156 util_idle_call(fix, util_quit_loop, util_session_destroy);
159 static void test_session_create_many_notify(struct test_session *session)
163 LOG("session %p", session);
165 nr = GPOINTER_TO_UINT(session->fix->user_data);
167 session->fix->user_data = GUINT_TO_POINTER(nr);
172 util_idle_call(session->fix, util_quit_loop, util_session_destroy);
175 static void test_session_create_many(struct test_fix *fix)
177 struct test_session *session;
182 fix->user_data = GUINT_TO_POINTER(max);
184 util_session_create(fix, max);
186 for (i = 0; i < max; i++) {
187 session = &fix->session[i];
189 session->notify_path = g_strdup_printf("/foo/%d", i);
190 session->notify = test_session_create_many_notify;
192 util_session_init(session);
196 static void set_session_mode(struct test_fix *fix,
201 msg = manager_set_session_mode(fix->main_connection, enable);
203 g_assert(dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_ERROR);
205 dbus_message_unref(msg);
208 static void test_session_connect_notify(struct test_session *session)
210 LOG("session %p state %d", session, session->info->state);
212 if (session->info->state == CONNMAN_SESSION_STATE_DISCONNECTED)
215 util_session_cleanup(session);
217 util_idle_call(session->fix, util_quit_loop, util_session_destroy);
220 static void test_session_connect(struct test_fix *fix)
222 struct test_session *session;
225 util_session_create(fix, 1);
226 session = fix->session;
228 session->notify_path = g_strdup("/foo");
229 session->notify = test_session_connect_notify;
230 util_session_init(session);
232 msg = session_connect(session->connection, session);
234 g_assert(dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_ERROR);
236 dbus_message_unref(msg);
239 static void test_session_disconnect_notify(struct test_session *session)
241 LOG("session %p state %d", session, session->info->state);
243 if (session->info->state >= CONNMAN_SESSION_STATE_CONNECTED)
246 util_session_cleanup(session);
248 util_idle_call(session->fix, util_quit_loop, util_session_destroy);
251 static void test_session_disconnect(struct test_fix *fix)
253 struct test_session *session;
256 util_session_create(fix, 1);
257 session = fix->session;
259 session->notify_path = g_strdup("/foo");
260 session->notify = test_session_disconnect_notify;
261 util_session_init(session);
263 msg = session_disconnect(session->connection, session);
265 dbus_message_unref(msg);
268 static void test_session_connect_disconnect_notify(struct test_session *session)
270 enum test_session_state state = get_session_state(session);
271 enum test_session_state next_state = state;
274 LOG("state %d session %p %s state %d", state, session,
275 session->notify_path, session->info->state);
278 case TEST_SESSION_STATE_0:
279 if (session->info->state == CONNMAN_SESSION_STATE_DISCONNECTED)
280 next_state = TEST_SESSION_STATE_1;
281 if (session->info->state == CONNMAN_SESSION_STATE_CONNECTED) {
282 LOG("state was already connected, continuing");
283 next_state = TEST_SESSION_STATE_2;
286 case TEST_SESSION_STATE_1:
287 if (session->info->state >= CONNMAN_SESSION_STATE_CONNECTED)
288 next_state = TEST_SESSION_STATE_2;
290 case TEST_SESSION_STATE_2:
291 if (session->info->state == CONNMAN_SESSION_STATE_DISCONNECTED)
292 next_state = TEST_SESSION_STATE_3;
297 if (state == next_state)
300 set_session_state(session, next_state);
302 LOG("next_state %d", next_state);
304 switch (next_state) {
305 case TEST_SESSION_STATE_1:
306 msg = session_connect(session->connection, session);
308 dbus_message_unref(msg);
310 case TEST_SESSION_STATE_2:
311 msg = session_disconnect(session->connection, session);
313 dbus_message_unref(msg);
315 case TEST_SESSION_STATE_3:
316 util_session_cleanup(session);
317 util_idle_call(session->fix, util_quit_loop,
318 util_session_destroy);
325 static void test_session_connect_disconnect(struct test_fix *fix)
327 struct test_session *session;
330 * +-------------------+
332 * +-------------------+
336 * +-------------------+
338 * +-------------------+
342 * +-------------------+
344 * +-------------------+
347 util_session_create(fix, 1);
348 session = fix->session;
350 session->notify_path = g_strdup("/foo");
351 session->notify = test_session_connect_disconnect_notify;
353 util_session_init(session);
355 set_session_state(session, TEST_SESSION_STATE_0);
358 static void test_session_connect_free_ride_notify(struct test_session *session)
360 struct test_session *session0 = get_session(session, 0);
361 struct test_session *session1 = get_session(session, 1);
362 enum test_session_state state = get_session_state(session);
363 enum test_session_state next_state = state;
366 LOG("state %d session %p %s state %d", state, session,
367 session->notify_path, session->info->state);
370 case TEST_SESSION_STATE_0:
371 if (session0->info->state == CONNMAN_SESSION_STATE_DISCONNECTED
372 && session1->info->state ==
373 CONNMAN_SESSION_STATE_DISCONNECTED) {
374 next_state = TEST_SESSION_STATE_1;
376 if (session0->info->state == CONNMAN_SESSION_STATE_CONNECTED &&
377 session1->info->state ==
378 CONNMAN_SESSION_STATE_CONNECTED) {
379 LOG("state was already connected, continuing");
380 next_state = TEST_SESSION_STATE_2;
384 case TEST_SESSION_STATE_1:
385 if (session0->info->state >= CONNMAN_SESSION_STATE_CONNECTED &&
386 session1->info->state >=
387 CONNMAN_SESSION_STATE_CONNECTED) {
388 next_state = TEST_SESSION_STATE_2;
392 case TEST_SESSION_STATE_2:
393 if (session0->info->state == CONNMAN_SESSION_STATE_DISCONNECTED
394 && (session1->info->state ==
395 CONNMAN_SESSION_STATE_DISCONNECTED ||
396 session1->info->state ==
397 CONNMAN_SESSION_STATE_CONNECTED) ) {
398 LOG("session0 /foo is disconnected, session1 /bar "
399 "can be either connected or disconnected");
400 next_state = TEST_SESSION_STATE_3;
404 case TEST_SESSION_STATE_3:
409 if (state == next_state)
412 set_session_state(session, next_state);
414 LOG("next_state %d", next_state);
416 switch (next_state) {
417 case TEST_SESSION_STATE_0:
420 case TEST_SESSION_STATE_1:
421 msg = session_connect(session0->connection, session0);
423 dbus_message_unref(msg);
427 case TEST_SESSION_STATE_2:
428 msg = session_disconnect(session0->connection, session0);
430 dbus_message_unref(msg);
433 case TEST_SESSION_STATE_3:
434 util_session_cleanup(session0);
435 util_session_cleanup(session1);
437 util_idle_call(session0->fix, util_quit_loop,
438 util_session_destroy);
444 static void test_session_connect_free_ride(struct test_fix *fix)
446 struct test_session *session0, *session1;
449 * +-------------------+
451 * +-------------------+
455 * +-------------------+
457 * +-------------------+
461 * +-------------------+
462 * | FOO-BAR-CONNECTED |
463 * +-------------------+
467 * +-------------------+
469 * +-------------------+
472 util_session_create(fix, 2);
473 session0 = &fix->session[0];
474 session1 = &fix->session[1];
476 session0->notify_path = g_strdup("/foo");
477 session1->notify_path = g_strdup("/bar");
478 session0->notify = test_session_connect_free_ride_notify;
479 session1->notify = test_session_connect_free_ride_notify;
481 util_session_init(session0);
482 util_session_init(session1);
484 set_session_state(session0, TEST_SESSION_STATE_0);
487 static void policy_save(GKeyFile *keyfile, char *pathname)
491 GError *error = NULL;
493 data = g_key_file_to_data(keyfile, &length, NULL);
495 if (!g_file_set_contents(pathname, data, length, &error)) {
496 DBG("Failed to store information: %s", error->message);
504 static void policy_allowed_bearers(const char *allowed_bearers)
511 LOG("update to '%s'", allowed_bearers);
517 keyfile = g_key_file_new();
518 g_key_file_set_string(keyfile, "policy_foo", "uid", pwd->pw_name);
519 g_key_file_set_string(keyfile, "policy_foo", "AllowedBearers",
522 pathname = g_strdup_printf("%s/foo.policy", POLICYDIR);
523 policy_save(keyfile, pathname);
526 g_key_file_free(keyfile);
529 static void policy_remove_file(void)
533 pathname = g_strdup_printf("%s/foo.policy", POLICYDIR);
538 static void test_session_policy_notify(struct test_session *session)
540 enum test_session_state state = get_session_state(session);
541 enum test_session_state next_state = state;
544 LOG("state %d session %p %s state %d", state, session,
545 session->notify_path, session->info->state);
548 case TEST_SESSION_STATE_0:
549 if (session->info->state == CONNMAN_SESSION_STATE_DISCONNECTED)
550 next_state = TEST_SESSION_STATE_1;
552 case TEST_SESSION_STATE_1:
553 if (session->info->state >= CONNMAN_SESSION_STATE_CONNECTED)
554 next_state = TEST_SESSION_STATE_2;
556 case TEST_SESSION_STATE_2:
557 if (session->info->state == CONNMAN_SESSION_STATE_DISCONNECTED)
558 next_state = TEST_SESSION_STATE_3;
563 if (state == next_state)
566 set_session_state(session, next_state);
568 LOG("next_state %d", next_state);
570 switch (next_state) {
571 case TEST_SESSION_STATE_1:
572 policy_allowed_bearers("ethernet");
574 msg = session_connect(session->connection, session);
576 dbus_message_unref(msg);
578 case TEST_SESSION_STATE_2:
579 policy_allowed_bearers("");
581 case TEST_SESSION_STATE_3:
582 policy_remove_file();
583 util_session_cleanup(session);
584 util_idle_call(session->fix, util_quit_loop,
585 util_session_destroy);
592 static void test_session_policy(struct test_fix *fix)
594 struct test_session *session;
597 * +-------------------+
599 * +-------------------+
601 * | write policy AllowedBearers = ethernet
603 * +-------------------+
605 * +-------------------+
607 * | write policy AllowedBearers =
609 * +-------------------+
611 * +-------------------+
614 policy_remove_file();
616 util_session_create(fix, 1);
617 session = fix->session;
619 session->notify_path = g_strdup("/foo");
620 session->notify = test_session_policy_notify;
622 util_session_init(session);
624 set_session_state(session, TEST_SESSION_STATE_0);
627 static bool is_online(struct test_fix *fix)
629 if (g_strcmp0(fix->manager.state, "online") == 0)
635 static void enable_session_mode(struct test_fix *fix)
637 set_session_mode(fix, true);
640 util_idle_call(fix, util_quit_loop, NULL);
643 static void manager_state_changed(struct test_fix *fix)
645 if (!is_online(fix)) {
646 fix->manager_changed = NULL;
647 util_idle_call(fix, util_quit_loop, NULL);
651 static void disable_session_mode(struct test_fix *fix)
653 set_session_mode(fix, false);
656 static void setup_cb(struct test_fix *fix)
658 fix->manager_changed = manager_state_changed;
660 util_call(fix, enable_session_mode, NULL);
663 static void teardown_cb(struct test_fix *fix)
665 util_call(fix, disable_session_mode, NULL);
666 util_idle_call(fix, util_quit_loop, NULL);
669 int main(int argc, char *argv[])
671 g_test_init(&argc, &argv, NULL);
673 util_test_add("/manager/session create no notify",
674 test_session_create_no_notify, setup_cb, teardown_cb);
675 util_test_add("/manager/session destroy no notify",
676 test_session_destroy_no_notify, setup_cb, teardown_cb);
677 util_test_add("/manager/session create",
678 test_session_create, setup_cb, teardown_cb);
679 util_test_add("/manager/session create destroy",
680 test_session_create_destroy, setup_cb, teardown_cb);
681 util_test_add("/manager/session create duplicate notification",
682 test_session_create_dup_notification, setup_cb, teardown_cb);
683 util_test_add("/manager/session create many",
684 test_session_create_many, setup_cb, teardown_cb);
686 util_test_add("/session/connect",
687 test_session_connect, setup_cb, teardown_cb);
688 util_test_add("/session/disconnect",
689 test_session_disconnect, setup_cb, teardown_cb);
690 util_test_add("/session/connect disconnect",
691 test_session_connect_disconnect, setup_cb, teardown_cb);
692 util_test_add("/session/connect free-ride",
693 test_session_connect_free_ride, setup_cb, teardown_cb);
695 util_test_add("/session/policy",
696 test_session_policy, setup_cb, teardown_cb);