Use upstream tag
[platform/upstream/libsecret.git] / libsecret / mock-service.c
1 /* libsecret - GLib wrapper for Secret Service
2  *
3  * Copyright 2011 Red Hat Inc.
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published
7  * by the Free Software Foundation; either version 2 of the licence or (at
8  * your option) any later version.
9  *
10  * See the included COPYING file for more information.
11  *
12  * Author: Stef Walter <stefw@gnome.org>
13  */
14
15
16 #include "config.h"
17
18 #include "mock-service.h"
19
20 #include "secret-private.h"
21
22 #include <errno.h>
23 #include <stdio.h>
24 #include <string.h>
25
26 static GTestDBus *test_bus = NULL;
27 static GPid pid = 0;
28
29 static gboolean
30 service_start (const gchar *mock_script,
31                GError **error)
32 {
33         gchar ready[8] = { 0, };
34         GSpawnFlags flags;
35         int wait_pipe[2];
36         GPollFD poll_fd;
37         gboolean ret;
38         gint polled;
39
40         gchar *argv[] = {
41                 "python", (gchar *)mock_script,
42                 "--name", MOCK_SERVICE_NAME,
43                 "--ready", ready,
44                 NULL
45         };
46
47         g_return_val_if_fail (mock_script != NULL, FALSE);
48         g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
49
50         test_bus = g_test_dbus_new (G_TEST_DBUS_NONE);
51         g_test_dbus_up (test_bus);
52
53         g_setenv ("SECRET_SERVICE_BUS_NAME", MOCK_SERVICE_NAME, TRUE);
54
55         if (pipe (wait_pipe) < 0) {
56                 g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errno),
57                                      "Couldn't create pipe for mock service");
58                 return FALSE;
59         }
60
61         snprintf (ready, sizeof (ready), "%d", wait_pipe[1]);
62
63         flags = G_SPAWN_SEARCH_PATH | G_SPAWN_LEAVE_DESCRIPTORS_OPEN;
64         ret = g_spawn_async (SRCDIR, argv, NULL, flags, NULL, NULL, &pid, error);
65
66         close (wait_pipe[1]);
67
68         if (ret) {
69                 poll_fd.events = G_IO_IN | G_IO_HUP | G_IO_ERR;
70                 poll_fd.fd = wait_pipe[0];
71                 poll_fd.revents = 0;
72
73                 polled = g_poll (&poll_fd, 1, 2000);
74                 if (polled < -1)
75                         g_warning ("couldn't poll file descirptor: %s", g_strerror (errno));
76                 if (polled != 1)
77                         g_warning ("couldn't wait for mock service");
78         }
79
80         close (wait_pipe[0]);
81         return ret;
82 }
83
84 gboolean
85 mock_service_start (const gchar *mock_script,
86                     GError **error)
87 {
88         gchar *path;
89         gboolean ret;
90
91         path = g_build_filename (SRCDIR, "libsecret", mock_script, NULL);
92         ret = service_start (path, error);
93         g_free (path);
94
95         return ret;
96 }
97
98 void
99 mock_service_stop (void)
100 {
101         const gchar *prgname;
102
103         if (!pid)
104                 return;
105
106         if (kill (pid, SIGTERM) < 0) {
107                 if (errno != ESRCH)
108                         g_warning ("kill() failed: %s", g_strerror (errno));
109         }
110
111         g_spawn_close_pid (pid);
112         pid = 0;
113
114         while (g_main_context_iteration (NULL, FALSE));
115
116         /*
117          * HACK: Don't worry about leaking tests when running under gjs.
118          * Waiting for the connection to go away is hopeless due to
119          * the way gjs garbage collects.
120          */
121         prgname = g_get_prgname ();
122         if (prgname && strstr (prgname, "gjs")) {
123                 g_test_dbus_stop (test_bus);
124
125         } else {
126                 g_test_dbus_down (test_bus);
127                 g_object_unref (test_bus);
128         }
129         test_bus = NULL;
130 }