Split out starting/stopping mock service into library

* Later this will be introspectable so we can start it from
   python or javascript based tests
This commit is contained in:
Stef Walter 2012-01-23 09:36:36 +01:00
parent 31d8f1508e
commit 116447c59e
8 changed files with 161 additions and 64 deletions

View File

@ -5,9 +5,24 @@ INCLUDES = \
-DSRCDIR="\"@abs_srcdir@\"" \ -DSRCDIR="\"@abs_srcdir@\"" \
$(NULL) $(NULL)
noinst_LTLIBRARIES = libmock_service.la
libmock_service_la_SOURCES = \
mock-service.c mock-service.h \
$(NULL)
libmock_service_la_CFLAGS = \
$(LIBGCRYPT_CFLAGS)
libmock_service_la_LIBADD = \
$(top_builddir)/egg/libegg.la \
$(top_builddir)/library/libgsecret.la \
$(LIBGCRYPT_LIBS)
LDADD = \ LDADD = \
$(top_builddir)/egg/libegg.la \ $(top_builddir)/egg/libegg.la \
$(top_builddir)/library/libgsecret.la \ $(top_builddir)/library/libgsecret.la \
$(top_builddir)/library/tests/libmock_service.la \
$(NULL) $(NULL)
TEST_PROGS = \ TEST_PROGS = \

View File

@ -0,0 +1,92 @@
/* GSecret - GLib wrapper for Secret Service
*
* Copyright 2011 Red Hat Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2 of the licence or (at
* your option) any later version.
*
* See the included COPYING file for more information.
*
* Author: Stef Walter <stefw@gnome.org>
*/
#include "config.h"
#include "mock-service.h"
#include "gsecret-private.h"
#include <errno.h>
#include <stdio.h>
static GPid pid = 0;
gboolean
mock_service_start (const gchar *mock_script,
GError **error)
{
gchar ready[8] = { 0, };
GSpawnFlags flags;
int wait_pipe[2];
GPollFD poll_fd;
gboolean ret;
gint polled;
gchar *argv[] = {
"python", (gchar *)mock_script,
"--name", MOCK_SERVICE_NAME,
"--ready", ready,
NULL
};
g_return_val_if_fail (mock_script != NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
_gsecret_service_set_default_bus_name (MOCK_SERVICE_NAME);
if (pipe (wait_pipe) < 0) {
g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errno),
"Couldn't create pipe for mock service");
return FALSE;
}
snprintf (ready, sizeof (ready), "%d", wait_pipe[1]);
flags = G_SPAWN_SEARCH_PATH | G_SPAWN_LEAVE_DESCRIPTORS_OPEN;
ret = g_spawn_async (SRCDIR, argv, NULL, flags, NULL, NULL, &pid, error);
close (wait_pipe[1]);
if (ret) {
poll_fd.events = G_IO_IN | G_IO_HUP | G_IO_ERR;
poll_fd.fd = wait_pipe[0];
poll_fd.revents = 0;
polled = g_poll (&poll_fd, 1, 2000);
if (polled < -1)
g_warning ("couldn't poll file descirptor: %s", g_strerror (errno));
if (polled != 1)
g_warning ("couldn't wait for mock service");
}
close (wait_pipe[0]);
return ret;
}
void
mock_service_stop (void)
{
if (!pid)
return;
if (kill (pid, SIGTERM) < 0) {
if (errno != ESRCH)
g_warning ("kill() failed: %s", g_strerror (errno));
}
g_spawn_close_pid (pid);
pid = 0;
}

View File

@ -0,0 +1,27 @@
/* GSecret - GLib wrapper for Secret Service
*
* Copyright 2012 Red Hat Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2 of the licence or (at
* your option) any later version.
*
* See the included COPYING file for more information.
*
* Author: Stef Walter <stefw@gnome.org>
*/
#ifndef _MOCK_SERVICE_H_
#define _MOCK_SERVICE_H_
#include <glib.h>
#define MOCK_SERVICE_NAME "org.mock.Service"
gboolean mock_service_start (const gchar *mock_script,
GError **error);
void mock_service_stop (void);
#endif /* _MOCK_SERVICE_H_ */

View File

@ -29,6 +29,7 @@ import gobject
COLLECTION_PREFIX = "/org/freedesktop/secrets/collection/" COLLECTION_PREFIX = "/org/freedesktop/secrets/collection/"
bus_name = 'org.freedesktop.Secret.MockService' bus_name = 'org.freedesktop.Secret.MockService'
ready_pipe = -1
objects = { } objects = { }
class NotSupported(dbus.exceptions.DBusException): class NotSupported(dbus.exceptions.DBusException):
@ -261,7 +262,12 @@ class SecretService(dbus.service.Object):
SecretItem(collection, "item_three", attributes={ "number": "3", "string": "three", "parity": "odd" }) SecretItem(collection, "item_three", attributes={ "number": "3", "string": "three", "parity": "odd" })
def listen(self): def listen(self):
global ready_pipe
loop = gobject.MainLoop() loop = gobject.MainLoop()
if ready_pipe >= 0:
os.write(ready_pipe, "GO")
os.close(ready_pipe)
ready_pipe = -1
loop.run() loop.run()
def add_session(self, session): def add_session(self, session):
@ -323,15 +329,17 @@ class SecretService(dbus.service.Object):
def parse_options(args): def parse_options(args):
global bus_name global bus_name, ready_pipe
try: try:
opts, args = getopt.getopt(args, "name", ["name="]) opts, args = getopt.getopt(args, "nr", ["name=", "ready="])
except getopt.GetoptError, err: except getopt.GetoptError, err:
print str(err) print str(err)
sys.exit(2) sys.exit(2)
for o, a in opts: for o, a in opts:
if o in ("--name"): if o in ("-n", "--name"):
bus_name = a bus_name = a
elif o in ("-r", "--ready"):
ready_pipe = int(a)
else: else:
assert False, "unhandled option" assert False, "unhandled option"
return args return args

View File

@ -17,6 +17,8 @@
#include "gsecret-password.h" #include "gsecret-password.h"
#include "gsecret-private.h" #include "gsecret-private.h"
#include "mock-service.h"
#include "egg/egg-testing.h" #include "egg/egg-testing.h"
#include <glib.h> #include <glib.h>
@ -24,8 +26,6 @@
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
static gchar *MOCK_NAME = "org.mock.Service";
static const GSecretSchema DELETE_SCHEMA = { static const GSecretSchema DELETE_SCHEMA = {
"org.mock.schema.Delete", "org.mock.schema.Delete",
{ {
@ -45,27 +45,16 @@ setup (Test *test,
{ {
GError *error = NULL; GError *error = NULL;
const gchar *mock_script = data; const gchar *mock_script = data;
gchar *argv[] = {
"python", (gchar *)mock_script,
"--name", MOCK_NAME,
NULL
};
_gsecret_service_set_default_bus_name (MOCK_NAME); mock_service_start (mock_script, &error);
g_spawn_async (SRCDIR, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, &test->pid, &error);
g_assert_no_error (error); g_assert_no_error (error);
g_usleep (200 * 1000);
} }
static void static void
teardown (Test *test, teardown (Test *test,
gconstpointer unused) gconstpointer unused)
{ {
g_assert (test->pid); mock_service_stop ();
if (kill (test->pid, SIGTERM) < 0)
g_error ("kill() failed: %s", g_strerror (errno));
g_spawn_close_pid (test->pid);
} }
static void static void

View File

@ -20,6 +20,8 @@
#include "gsecret-private.h" #include "gsecret-private.h"
#include "gsecret-prompt.h" #include "gsecret-prompt.h"
#include "mock-service.h"
#include "egg/egg-testing.h" #include "egg/egg-testing.h"
#include <glib.h> #include <glib.h>
@ -27,10 +29,7 @@
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
static gchar *MOCK_NAME = "org.mock.Service";
typedef struct { typedef struct {
GPid pid;
GDBusConnection *connection; GDBusConnection *connection;
GSecretService *service; GSecretService *service;
} Test; } Test;
@ -41,17 +40,9 @@ setup (Test *test,
{ {
GError *error = NULL; GError *error = NULL;
const gchar *mock_script = data; const gchar *mock_script = data;
gchar *argv[] = {
"python", (gchar *)mock_script,
"--name", MOCK_NAME,
NULL
};
_gsecret_service_set_default_bus_name (MOCK_NAME); mock_service_start (mock_script, &error);
g_spawn_async (SRCDIR, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, &test->pid, &error);
g_assert_no_error (error); g_assert_no_error (error);
g_usleep (200 * 1000);
test->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); test->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
g_assert_no_error (error); g_assert_no_error (error);
@ -68,12 +59,7 @@ teardown (Test *test,
g_object_unref (test->service); g_object_unref (test->service);
egg_assert_not_object (test->service); egg_assert_not_object (test->service);
g_assert (test->pid); mock_service_stop ();
if (kill (test->pid, SIGTERM) < 0) {
if (errno != ESRCH)
g_error ("kill() failed: %s", g_strerror (errno));
}
g_spawn_close_pid (test->pid);
g_dbus_connection_flush_sync (test->connection, NULL, &error); g_dbus_connection_flush_sync (test->connection, NULL, &error);
g_assert_no_error (error); g_assert_no_error (error);

View File

@ -16,6 +16,8 @@
#include "gsecret-service.h" #include "gsecret-service.h"
#include "gsecret-private.h" #include "gsecret-private.h"
#include "mock-service.h"
#include "egg/egg-testing.h" #include "egg/egg-testing.h"
#include <glib.h> #include <glib.h>
@ -46,17 +48,9 @@ setup_mock (Test *test,
{ {
GError *error = NULL; GError *error = NULL;
const gchar *mock_script = data; const gchar *mock_script = data;
gchar *argv[] = {
"python", (gchar *)mock_script,
"--name", MOCK_NAME,
NULL
};
_gsecret_service_set_default_bus_name (MOCK_NAME); mock_service_start (mock_script, &error);
g_spawn_async (SRCDIR, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, &test->pid, &error);
g_assert_no_error (error); g_assert_no_error (error);
g_usleep (200 * 1000);
} }
static void static void
@ -77,10 +71,7 @@ static void
teardown_mock (Test *test, teardown_mock (Test *test,
gconstpointer unused) gconstpointer unused)
{ {
g_assert (test->pid); mock_service_stop ();
if (kill (test->pid, SIGTERM) < 0)
g_error ("kill() failed: %s", g_strerror (errno));
g_spawn_close_pid (test->pid);
} }
static void static void

View File

@ -17,6 +17,8 @@
#include "gsecret-service.h" #include "gsecret-service.h"
#include "gsecret-private.h" #include "gsecret-private.h"
#include "mock-service.h"
#include "egg/egg-testing.h" #include "egg/egg-testing.h"
#include <glib.h> #include <glib.h>
@ -24,8 +26,6 @@
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
static gchar *MOCK_NAME = "org.mock.Service";
typedef struct { typedef struct {
GPid pid; GPid pid;
GDBusConnection *connection; GDBusConnection *connection;
@ -38,17 +38,9 @@ setup (Test *test,
{ {
GError *error = NULL; GError *error = NULL;
const gchar *mock_script = data; const gchar *mock_script = data;
gchar *argv[] = {
"python", (gchar *)mock_script,
"--name", MOCK_NAME,
NULL
};
_gsecret_service_set_default_bus_name (MOCK_NAME); mock_service_start (mock_script, &error);
g_spawn_async (SRCDIR, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, &test->pid, &error);
g_assert_no_error (error); g_assert_no_error (error);
g_usleep (200 * 1000);
test->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); test->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
g_assert_no_error (error); g_assert_no_error (error);
@ -65,10 +57,7 @@ teardown (Test *test,
g_object_unref (test->service); g_object_unref (test->service);
egg_assert_not_object (test->service); egg_assert_not_object (test->service);
g_assert (test->pid); mock_service_stop ();
if (kill (test->pid, SIGTERM) < 0)
g_error ("kill() failed: %s", g_strerror (errno));
g_spawn_close_pid (test->pid);
g_dbus_connection_flush_sync (test->connection, NULL, &error); g_dbus_connection_flush_sync (test->connection, NULL, &error);
g_assert_no_error (error); g_assert_no_error (error);