From 3debf372273293ebb247a00a4e70c5ab7a399c13 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Thu, 6 Mar 2014 10:34:39 +0100 Subject: daemon: Add a test of the control directory and environment variables Combine some code for starting a test daemon into a new internal utility functions. --- daemon/Makefile.am | 32 ++++++++ daemon/dbus/Makefile.am | 1 + daemon/dbus/test-service.c | 33 ++------ daemon/gkd-test.c | 103 ++++++++++++++++++++++++ daemon/gkd-test.h | 31 +++++++ daemon/test-startup.c | 195 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 369 insertions(+), 26 deletions(-) create mode 100644 daemon/gkd-test.c create mode 100644 daemon/gkd-test.h create mode 100644 daemon/test-startup.c diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 68023158..bcfff8c2 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -52,3 +52,35 @@ EXTRA_DIST += \ CLEANFILES += \ $(service_DATA) \ $(desktop_DATA) + +# ------------------------------------------------------------------- +# TESTS + +noinst_LTLIBRARIES += libgkd-test.la + +libgkd_test_la_SOURCES = \ + daemon/gkd-test.c \ + daemon/gkd-test.h + +daemon_CFLAGS = \ + $(DBUS_CFLAGS) \ + $(GCR_CFLAGS) + +daemon_LIBS = \ + libgkd-control-client.la \ + libgkd-test.la \ + libegg.la \ + libegg-test.la \ + $(GCR_BASE_LIBS) \ + $(GIO_LIBS) \ + $(GLIB_LIBS) + +daemon_TESTS = \ + test-startup + +test_startup_SOURCES = daemon/test-startup.c +test_startup_LDADD = $(daemon_LIBS) +test_statrup_CFLAGS = $(daemon_CFLAGS) + +check_PROGRAMS += $(daemon_TESTS) +TESTS += $(daemon_TESTS) diff --git a/daemon/dbus/Makefile.am b/daemon/dbus/Makefile.am index dead5f4c..5a031edd 100644 --- a/daemon/dbus/Makefile.am +++ b/daemon/dbus/Makefile.am @@ -70,6 +70,7 @@ daemon_dbus_CFLAGS = \ daemon_dbus_LIBS = \ libtestservice.la \ libgkd-dbus.la \ + libgkd-test.la \ libegg-test.la \ $(GCR_BASE_LIBS) \ $(GIO_LIBS) \ diff --git a/daemon/dbus/test-service.c b/daemon/dbus/test-service.c index 83a1a0f4..212e12f1 100644 --- a/daemon/dbus/test-service.c +++ b/daemon/dbus/test-service.c @@ -26,6 +26,8 @@ #include "gkd-secret-types.h" +#include "daemon/gkd-test.h" + #include "egg/egg-testing.h" #include @@ -57,16 +59,6 @@ on_test_service_vanished (GDBusConnection *connection, } } -static void -on_service_spawned (gpointer user_data) -{ - int fd; - - fd = g_open ("/dev/null", O_WRONLY, 0); - if (fd != -1) - dup2 (fd, 1); -} - void test_service_setup (TestService *test) { @@ -75,7 +67,7 @@ test_service_setup (TestService *test) GVariant *output; gchar **env; - gchar *args[] = { + const gchar *args[] = { BUILDDIR "/gnome-keyring-daemon", "--foreground", "--control-directory", @@ -97,21 +89,10 @@ test_service_setup (TestService *test) SRCDIR "/daemon/dbus/fixtures/test.keyring", NULL); - /* The schema directory */ - env = g_get_environ (); - env = g_environ_setenv (env, "GSETTINGS_SCHEMA_DIR", BUILDDIR "/schema", TRUE); - env = g_environ_setenv (env, "GNOME_KEYRING_TEST_PATH", test->directory, TRUE); - env = g_environ_setenv (env, "GNOME_KEYRING_TEST_SERVICE", test->bus_name, TRUE); - if (test->mock_prompter) - env = g_environ_setenv (env, "GNOME_KEYRING_TEST_PROMPTER", test->mock_prompter, TRUE); - - if (!g_spawn_async (NULL, args, env, - G_SPAWN_LEAVE_DESCRIPTORS_OPEN | G_SPAWN_DO_NOT_REAP_CHILD, - on_service_spawned, test, &test->pid, &error)) { - g_error ("couldn't start gnome-keyring-daemon for testing: %s", error->message); - g_assert_not_reached (); - } - + env = gkd_test_launch_daemon (test->directory, args, &test->pid, + "GNOME_KEYRING_TEST_SERVICE", test->bus_name, + test->mock_prompter ? "GNOME_KEYRING_TEST_PROMPTER" : NULL, test->mock_prompter, + NULL); g_strfreev (env); if (!test->available) { diff --git a/daemon/gkd-test.c b/daemon/gkd-test.c new file mode 100644 index 00000000..2ad46523 --- /dev/null +++ b/daemon/gkd-test.c @@ -0,0 +1,103 @@ +/* + Copyright (C) 2014 Red Hat Inc + + The Gnome Keyring Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Keyring Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + . + + Author: Stef Walter +*/ + +#include "config.h" + +#include "gkd-test.h" + +#include "egg/egg-testing.h" + +#include +#include +#include + +#include + +gchar ** +gkd_test_launch_daemon (const gchar *directory, + const gchar **argv, + GPid *pid, + ...) +{ + GError *error = NULL; + GString *output; + gchar **env; + gsize len; + gssize ret; + int out_fd; + gchar **result; + gchar *cmd; + va_list va; + const gchar *name; + const gchar *value; + + env = g_get_environ (); + env = g_environ_setenv (env, "GSETTINGS_SCHEMA_DIR", BUILDDIR "/schema", TRUE); + env = g_environ_setenv (env, "GNOME_KEYRING_TEST_PATH", directory, TRUE); + env = g_environ_setenv (env, "XDG_RUNTIME_DIR", directory, TRUE); + env = g_environ_setenv (env, "G_DEBUG", "fatal-warnings,fatal-criticals", FALSE); + + va_start (va, pid); + for (;;) { + name = va_arg (va, const gchar *); + if (!name) + break; + value = va_arg (va, const gchar *); + if (value) + env = g_environ_setenv (env, name, value, TRUE); + else + env = g_environ_unsetenv (env, name); + } + va_end (va); + + if (g_test_verbose ()) { + cmd = g_strjoinv (" ", (gchar **)argv); + g_print ("$ %s\n", cmd); + g_free (cmd); + } + + if (!g_spawn_async_with_pipes (NULL, (gchar **)argv, env, + G_SPAWN_LEAVE_DESCRIPTORS_OPEN | G_SPAWN_DO_NOT_REAP_CHILD, + NULL, NULL, pid, NULL, &out_fd, NULL, &error)) { + g_error ("couldn't start gnome-keyring-daemon for testing: %s", error->message); + } + + g_strfreev (env); + + /* The entire stdout of the daemon is environment variables */ + output = g_string_new (""); + for (;;) { + len = output->len; + g_string_set_size (output, len + 1024); + ret = read (out_fd, output->str + len, 1024); + if (ret < 0) + g_assert_cmpint (ret, ==, EAGAIN); + if (g_test_verbose ()) + g_print ("%.*s", (int)ret, output->str + len); + g_string_set_size (output, len + ret); + if (ret == 0) + break; + } + close (out_fd); + + result = g_strsplit (output->str, "\n", -1); + g_string_free (output, TRUE); + return result; +} diff --git a/daemon/gkd-test.h b/daemon/gkd-test.h new file mode 100644 index 00000000..b1f23cae --- /dev/null +++ b/daemon/gkd-test.h @@ -0,0 +1,31 @@ +/* + Copyright (C) 2014 Red Hat Inc + + The Gnome Keyring Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Keyring Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + . + + Author: Stef Walter +*/ + +#ifndef GKD_TEST_H_ +#define GKD_TEST_H_ + +#include + +gchar ** gkd_test_launch_daemon (const gchar *directory, + const gchar **argv, + GPid *pid, + ...) G_GNUC_NULL_TERMINATED; + +#endif /* GKD_TEST_H_ */ diff --git a/daemon/test-startup.c b/daemon/test-startup.c new file mode 100644 index 00000000..cea9f5d1 --- /dev/null +++ b/daemon/test-startup.c @@ -0,0 +1,195 @@ +/* + Copyright (C) 2014 Red Hat Inc + + The Gnome Keyring Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Keyring Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + . + + Author: Stef Walter +*/ + +#include "config.h" + +#include "gkd-test.h" + +#include "daemon/control/gkd-control.h" + +#include "egg/egg-testing.h" + +#include +#include +#include + +#include +#include +#include + +typedef struct { + GTestDBus *dbus; + gchar *directory; + GPid pid; +} Test; + +static void +setup (Test *test, + gconstpointer unused) +{ + test->dbus = g_test_dbus_new (G_TEST_DBUS_NONE); + g_test_dbus_up (test->dbus); + + test->directory = egg_tests_create_scratch_directory ( + SRCDIR "/daemon/dbus/fixtures/test.keyring", + NULL); +} + +static void +teardown (Test *test, + gconstpointer unused) +{ + if (test->pid) { + if (waitpid (test->pid, NULL, WNOHANG) != test->pid) { + kill (test->pid, SIGTERM); + g_assert_cmpint (waitpid (test->pid, NULL, 0), ==, test->pid); + } + g_spawn_close_pid (test->pid); + } + + egg_tests_remove_scratch_directory (test->directory); + g_free (test->directory); + + g_test_dbus_down (test->dbus); + g_object_unref (test->dbus); +} + +static void +test_control_valid (Test *test, + gconstpointer unused) +{ + gchar *fixed = g_strdup_printf ("%s/xxxx", test->directory); + + const gchar *argv[] = { + BUILDDIR "/gnome-keyring-daemon", "--foreground", + "--control-directory", fixed, + "--components=", NULL + }; + + gchar **output; + gint status; + GPid pid; + + output = gkd_test_launch_daemon (test->directory, argv, &pid, NULL); + + g_assert_cmpstr (g_environ_getenv (output, "GNOME_KEYRING_CONTROL"), ==, fixed); + g_strfreev (output); + + g_assert (gkd_control_quit (fixed, 0)); + g_assert_cmpint (waitpid (pid, &status, 0), ==, pid); + g_assert_cmpint (status, ==, 0); + + g_free (fixed); +} + +static void +test_control_creates (Test *test, + gconstpointer unused) +{ + gchar *directory = g_build_filename (test->directory, "under", NULL); + + const gchar *argv[] = { + BUILDDIR "/gnome-keyring-daemon", "--foreground", + "--control-directory", directory, + "--components=", NULL + }; + + gchar **output; + + output = gkd_test_launch_daemon (test->directory, argv, &test->pid, NULL); + g_assert_cmpstr (g_environ_getenv (output, "GNOME_KEYRING_CONTROL"), ==, directory); + g_strfreev (output); + + g_assert (g_file_test (directory, G_FILE_TEST_IS_DIR)); + g_free (directory); +} + +static void +test_control_noaccess (Test *test, + gconstpointer unused) +{ + gchar *noaccess = g_build_filename (test->directory, "under", NULL); + gchar *directory = g_build_filename (test->directory, "under", "subdir", NULL); + + const gchar *argv[] = { + BUILDDIR "/gnome-keyring-daemon", "--foreground", + "--control-directory", directory, + "--components=", NULL + }; + + gchar **output; + + if (g_mkdir_with_parents (noaccess, 0000) < 0) + g_assert_not_reached (); + + /* Should choose a different directory */ + output = gkd_test_launch_daemon (test->directory, argv, &test->pid, NULL); + g_assert_cmpstr (g_environ_getenv (output, "GNOME_KEYRING_CONTROL"), !=, directory); + g_strfreev (output); + + g_assert (!g_file_test (directory, G_FILE_TEST_IS_DIR)); + g_free (directory); + + if (chmod (noaccess, 0700) < 0) + g_assert_not_reached (); + g_free (noaccess); +} + +static void +test_control_badperm (Test *test, + gconstpointer unused) +{ + gchar *directory = g_build_filename (test->directory, "under", NULL); + + const gchar *argv[] = { + BUILDDIR "/gnome-keyring-daemon", "--foreground", + "--control-directory", directory, + "--components=", NULL + }; + + gchar **output; + + if (g_mkdir_with_parents (directory, 0777) < 0) + g_assert_not_reached (); + + /* Should choose a different directory */ + output = gkd_test_launch_daemon (test->directory, argv, &test->pid, NULL); + g_assert_cmpstr (g_environ_getenv (output, "GNOME_KEYRING_CONTROL"), !=, directory); + g_strfreev (output); + + g_free (directory); +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add ("/daemon/startup/control/valid", Test, NULL, + setup, test_control_valid, teardown); + g_test_add ("/daemon/startup/control/creates", Test, NULL, + setup, test_control_creates, teardown); + g_test_add ("/daemon/startup/control/noaccess", Test, NULL, + setup, test_control_noaccess, teardown); + g_test_add ("/daemon/startup/control/badperm", Test, NULL, + setup, test_control_badperm, teardown); + + return g_test_run (); +} -- cgit v1.2.3