MemoryLimit has been replaced by MemoryMax
[platform/core/system/tlm.git] / tests / daemon / daemon-test.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 tlm (Tiny Login Manager)
5  *
6  * Copyright (C) 2014 Intel Corporation.
7  *
8  * Contact: Imran Zaman <imran.zaman@gmail.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  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22  * 02110-1301 USA
23  */
24
25 #include "config.h"
26 #include <check.h>
27 #include <error.h>
28 #include <errno.h>
29 #include <stdlib.h>
30 #include <gio/gio.h>
31 #include <glib.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include <fcntl.h>
35 #include <glib-unix.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38
39 #include "common/dbus/tlm-dbus.h"
40 #include "common/tlm-log.h"
41 #include "common/tlm-config.h"
42 #include "common/dbus/tlm-dbus-login-gen.h"
43 #include "common/tlm-utils.h"
44 #include "common/dbus/tlm-dbus-utils.h"
45
46 static gchar *exe_name = 0;
47 static GPid daemon_pid = 0;
48
49 static GMainLoop *main_loop = NULL;
50
51 static void
52 _stop_mainloop ()
53 {
54     if (main_loop) {
55         g_main_loop_quit (main_loop);
56     }
57 }
58
59 static void
60 _create_mainloop ()
61 {
62     if (main_loop == NULL) {
63         main_loop = g_main_loop_new (NULL, FALSE);
64     }
65 }
66
67 static void
68 _setup_daemon (void)
69 {
70     DBG ("Programe name : %s\n", exe_name);
71
72     GError *error = NULL;
73     /* start daemon maually */
74     gchar *argv[2];
75     gchar *test_daemon_path = g_build_filename (g_getenv("TLM_BIN_DIR"),
76             "tlm", NULL);
77     fail_if (test_daemon_path == NULL, "No UM daemon path found");
78
79     argv[0] = test_daemon_path;
80     argv[1] = NULL;
81     g_spawn_async (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL,
82             &daemon_pid, &error);
83     g_free (test_daemon_path);
84     fail_if (error != NULL, "Failed to span daemon : %s",
85             error ? error->message : "");
86     sleep (5); /* 5 seconds */
87
88     DBG ("Daemon PID = %d\n", daemon_pid);
89 }
90
91 static void
92 _teardown_daemon (void)
93 {
94     if (daemon_pid) kill (daemon_pid, SIGTERM);
95 }
96
97 GDBusConnection *
98 _get_root_socket_bus_connection (
99         GError **error)
100 {
101     gchar address[128];
102     g_snprintf (address, 127, TLM_DBUS_ROOT_SOCKET_ADDRESS);
103     return g_dbus_connection_new_for_address_sync (address,
104             G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, NULL, NULL, error);
105 }
106
107 GDBusConnection *
108 _get_bus_connection (
109         const gchar *seat_id,
110         GError **error)
111 {
112     uid_t ui_user_id = getuid ();
113
114     if (ui_user_id == 0) {
115         return _get_root_socket_bus_connection (error);
116     }
117
118     /* get dbus connection for specific user only */
119     gchar address[128];
120     g_snprintf (address, 127, "unix:path=%s/%s-%d", TLM_DBUS_SOCKET_PATH,
121             seat_id, ui_user_id);
122     return g_dbus_connection_new_for_address_sync (address,
123             G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, NULL, NULL, error);
124 }
125
126 TlmDbusLogin *
127 _get_login_object (
128         GDBusConnection *connection,
129         GError **error)
130 {
131     return tlm_dbus_login_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE,
132             NULL, TLM_LOGIN_OBJECTPATH, NULL, error);
133 }
134
135
136 static GVariant *
137 _get_session_property (
138         GDBusProxy *proxy,
139         const gchar *object_path,
140         const gchar *prop_key)
141 {
142     GError *error = NULL;
143     GVariant *result = NULL;
144     GVariant *prop_value = NULL;
145
146     result = g_dbus_connection_call_sync (
147             g_dbus_proxy_get_connection (proxy),
148             g_dbus_proxy_get_name (proxy),
149             object_path,
150             "org.freedesktop.DBus.Properties",
151             "GetAll",
152             g_variant_new ("(s)",  "org.freedesktop.login1.Session"),
153             G_VARIANT_TYPE ("(a{sv})"),
154             G_DBUS_CALL_FLAGS_NONE,
155             -1,
156             NULL,
157             &error);
158     if (error) {
159         DBG ("Failed with error %d:%s", error->code, error->message);
160         g_error_free (error);
161         error = NULL;
162         return NULL;
163     }
164
165     if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(a{sv})"))) {
166         GVariantIter *iter = NULL;
167         GVariant *item = NULL;
168         g_variant_get (result, "(a{sv})",  &iter);
169         while ((item = g_variant_iter_next_value (iter)))  {
170             gchar *key;
171             GVariant *value;
172             g_variant_get (item, "{sv}", &key, &value);
173             if (g_strcmp0 (key, prop_key) == 0) {
174                 prop_value = value;
175                 g_free (key); key = NULL;
176                 break;
177             }
178             g_free (key); key = NULL;
179             g_variant_unref (value); value = NULL;
180         }
181     }
182     g_variant_unref (result);
183     return prop_value;
184 }
185
186 static GVariant *
187 _get_property (
188         const gchar *prop_key)
189 {
190     GError *error = NULL;
191     GDBusProxy *proxy = NULL;
192     GVariant *res = NULL;
193     GVariant *prop_value = NULL;
194
195     GDBusConnection *connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL,
196             &error);
197     if (error) goto _finished;
198
199     proxy = g_dbus_proxy_new_sync (connection,
200             G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
201             "org.freedesktop.login1", //destintation
202             "/org/freedesktop/login1", //path
203             "org.freedesktop.login1.Manager", //interface
204             NULL, &error);
205     if (error) goto _finished;
206
207     res = g_dbus_proxy_call_sync (proxy, "GetSessionByPID",
208             g_variant_new ("(u)", getpid()), G_DBUS_CALL_FLAGS_NONE, -1,
209             NULL, &error);
210     if (res) {
211         gchar *obj_path = NULL;
212         g_variant_get (res, "(o)", &obj_path);
213         prop_value = _get_session_property (proxy, obj_path, prop_key);
214         g_variant_unref (res); res = NULL;
215         g_free (obj_path);
216     }
217
218 _finished:
219     if (error) {
220         DBG ("failed to listen for login events: %s", error->message);
221         g_error_free (error);
222     }
223     if (proxy) g_object_unref (proxy);
224     if (connection) g_object_unref (connection);
225
226     return prop_value;
227 }
228
229 /*
230  * Login object test cases
231  */
232 START_TEST (test_login_user)
233 {
234     DBG ("\n");
235     GError *error = NULL;
236     GDBusConnection *connection = NULL;
237     TlmDbusLogin *login_object = NULL;
238     GHashTable *environ = NULL;
239     GVariant *venv = NULL;
240     GVariant *vseat = NULL;
241     gchar *seat = NULL;
242
243     vseat = _get_property ("Seat");
244     fail_if (vseat == NULL);
245     g_variant_get (vseat, "(so)", &seat, NULL);
246     g_variant_unref (vseat);
247
248     connection = _get_bus_connection (seat, &error);
249     fail_if (connection == NULL, "failed to get bus connection : %s",
250             error ? error->message : "(null)");
251     g_free (seat);
252
253     login_object = _get_login_object (connection, &error);
254     fail_if (login_object == NULL, "failed to get login object: %s",
255             error ? error->message : "");
256
257     environ = g_hash_table_new_full ((GHashFunc)g_str_hash,
258             (GEqualFunc)g_str_equal,
259             (GDestroyNotify)g_free,
260             (GDestroyNotify)g_free);
261     venv = tlm_dbus_utils_hash_table_to_variant (environ);
262
263     g_hash_table_unref (environ);
264
265     fail_if (tlm_dbus_login_call_login_user_sync (login_object,
266             "seat0", "test01234567", "test1", venv, NULL, &error) == TRUE);
267
268     if (error) {
269         g_error_free (error);
270         error = NULL;
271     }
272     g_object_unref (login_object);
273     g_object_unref (connection);
274 }
275 END_TEST
276
277 Suite* daemon_suite (void)
278 {
279     TCase *tc = NULL;
280
281     Suite *s = suite_create ("Tlm daemon");
282     
283     tc = tcase_create ("Daemon tests");
284     tcase_set_timeout(tc, 15);
285     tcase_add_unchecked_fixture (tc, _setup_daemon, _teardown_daemon);
286     tcase_add_checked_fixture (tc, _create_mainloop, _stop_mainloop);
287
288     tcase_add_test (tc, test_login_user);
289     suite_add_tcase (s, tc);
290
291     return s;
292 }
293
294 int main (int argc, char *argv[])
295 {
296     int number_failed;
297     Suite *s = 0;
298     SRunner *sr = 0;
299    
300 #if !GLIB_CHECK_VERSION (2, 36, 0)
301     g_type_init ();
302 #endif
303
304     exe_name = argv[0];
305
306     s = daemon_suite();
307     sr = srunner_create(s);
308
309     srunner_run_all(sr, CK_VERBOSE);
310
311     number_failed = srunner_ntests_failed(sr);
312     srunner_free(sr);
313
314     return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
315 }