From 67c7ae109cad3003a7b87001084fd849b86a68d1 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 19 Mar 2013 12:43:21 +0000 Subject: [PATCH] In tests that do not rely on with-session-bus*.sh, use a transient $HOME This is one more way in which we can avoid touching the user's real files. Bug https://bugzilla.gnome.org/show_bug.cgi?id=690830 Reviewed-by: Philip Withnall [use "this." in response to review -smcv] Signed-off-by: Simon McVittie --- tests/lib/Makefile.am | 1 + tests/lib/eds/test-case.vala | 7 +++ tests/lib/haze-remove-directory.c | 56 +++++++++++++++++++++ tests/lib/test-case.vala | 101 ++++++++++++++++++++++++++++++++++++++ tests/lib/test-utils.vala | 5 ++ tests/lib/tracker/test-case.vala | 7 +++ 6 files changed, 177 insertions(+) create mode 100644 tests/lib/haze-remove-directory.c diff --git a/tests/lib/Makefile.am b/tests/lib/Makefile.am index 7d1b6d9..2ff0be8 100644 --- a/tests/lib/Makefile.am +++ b/tests/lib/Makefile.am @@ -31,6 +31,7 @@ DIST_SUBDIRS = \ noinst_LTLIBRARIES = libfolks-test.la libfolks_test_la_SOURCES = \ + haze-remove-directory.c \ test-case.vala \ test-case-helper.c \ test-utils.vala \ diff --git a/tests/lib/eds/test-case.vala b/tests/lib/eds/test-case.vala index 6b8446b..a4796dc 100644 --- a/tests/lib/eds/test-case.vala +++ b/tests/lib/eds/test-case.vala @@ -57,6 +57,13 @@ public class EdsTest.TestCase : Folks.TestCase true); } + public override string? create_transient_dir () + { + /* Don't do anything. We're currently relying on + * being wrapped in with-session-bus-eds.sh. */ + return null; + } + public override void private_bus_up () { /* Don't do anything. We're currently relying on diff --git a/tests/lib/haze-remove-directory.c b/tests/lib/haze-remove-directory.c new file mode 100644 index 0000000..f673270 --- /dev/null +++ b/tests/lib/haze-remove-directory.c @@ -0,0 +1,56 @@ +/* + * Originally from telepathy-haze's util.c — utility functions + * + * Copyright © 2007 Will Thompson + * + * Copying and distribution of this file, with or without modification, + * are permitted in any medium without royalty provided the copyright + * notice and this notice are preserved. + */ + +#include "folks-test.h" + +#include + +#define DEBUG g_debug + +gboolean +haze_remove_directory (const gchar *path) +{ + const gchar *child_path; + GDir *dir = g_dir_open (path, 0, NULL); + gboolean ret = TRUE; + + if (!dir) + return FALSE; + + while (ret && (child_path = g_dir_read_name (dir))) + { + gchar *child_full_path = g_build_filename (path, child_path, NULL); + + if (g_file_test (child_full_path, G_FILE_TEST_IS_DIR)) + { + if (!haze_remove_directory (child_full_path)) + ret = FALSE; + } + else + { + DEBUG ("deleting %s", child_full_path); + + if (g_unlink (child_full_path)) + ret = FALSE; + } + + g_free (child_full_path); + } + + g_dir_close (dir); + + if (ret) + { + DEBUG ("deleting %s", path); + ret = !g_rmdir (path); + } + + return ret; +} diff --git a/tests/lib/test-case.vala b/tests/lib/test-case.vala index f6f9a4e..3956999 100644 --- a/tests/lib/test-case.vala +++ b/tests/lib/test-case.vala @@ -42,12 +42,107 @@ public abstract class Folks.TestCase : Object LogAdaptor.set_up (); this._suite = new GLib.TestSuite (name); + this._transient_dir = this.create_transient_dir (); this.private_bus_up (); /* By default, no backend is allowed. Subclasses must override. */ Environment.set_variable ("FOLKS_BACKENDS_ALLOWED", "", true); } + private string? _transient_dir = null; + /** + * A transient directory normally created in the constructor and deleted + * in final_tear_down(). This can be used for temporary storage. + * The environment variables ``XDG_CONFIG_HOME``, ``XDG_DATA_HOME``, + * ``XDG_CACHE_HOME``, etc. point into it. + */ + public string transient_dir + { + get + { + assert (this._transient_dir != null); + return (!) this._transient_dir; + } + } + + /** + * Create and return a transient directory suitable for use as + * //transient_dir//. Set environment variables to point into it. + * + * This is only called once per process, so that it can be used in + * environment variables that are cached or otherwise considered to + * be process-global. As such, all tests in a TestCase share it. + * + * Subclasses may override this method to do additional setup + * (create more subdirectories or set more environment variables). + * + * FIXME: Subclasses relying on being called by with-session-bus-*.sh + * may override this method to return null, although we should really + * stop doing that. + */ + public virtual string? create_transient_dir () + { + unowned string tmp = Environment.get_tmp_dir (); + string transient = "%s/folks-test.XXXXXX".printf (tmp); + + if (GLib.DirUtils.mkdtemp (transient) == null) + error ("unable to create temporary directory in '%s': %s", + tmp, GLib.strerror (GLib.errno)); + + debug ("setting up in transient directory %s", transient); + + /* GLib >= 2.36, and various non-GNOME things, obey this. */ + Environment.set_variable ("HOME", transient, true); + /* GLib < 2.36 in Debian obeyed this (although upstream GLib < 2.36 + * used the home directory from passwd), so set it too. + * FIXME: remove this when we depend on 2.36. */ + Environment.set_variable ("G_HOME", transient, true); + + var cache = "%s/.cache".printf (transient); + Environment.set_variable ("XDG_CACHE_HOME", cache, true); + + if (GLib.DirUtils.create_with_parents (cache, 0700) != 0) + error ("unable to create '%s': %s", + cache, GLib.strerror (GLib.errno)); + + var config = "%s/.config".printf (transient); + Environment.set_variable ("XDG_CONFIG_HOME", config, true); + + if (GLib.DirUtils.create_with_parents (config, 0700) != 0) + error ("unable to create '%s': %s", + config, GLib.strerror (GLib.errno)); + + var local = "%s/.local/share".printf (transient); + Environment.set_variable ("XDG_DATA_HOME", local, true); + + if (GLib.DirUtils.create_with_parents (local, 0700) != 0) + error ("unable to create '%s': %s", + local, GLib.strerror (GLib.errno)); + + /* Under systemd user sessions this is meant to define the + * lifetime of a logged-in-user - the regression tests don't + * want to be part of this. */ + var runtime = "%s/XDG_RUNTIME_DIR".printf (transient); + Environment.set_variable ("XDG_RUNTIME_DIR", runtime, true); + + if (GLib.DirUtils.create_with_parents (runtime, 0700) != 0) + error ("unable to create '%s': %s", + runtime, GLib.strerror (GLib.errno)); + + /* Unset some things we don't want to inherit. In particular, + * Tracker might try to index XDG_*_DIR, which we don't want. */ + Environment.unset_variable ("XDG_DESKTOP_DIR"); + Environment.unset_variable ("XDG_DOCUMENTS_DIR"); + Environment.unset_variable ("XDG_DOWNLOAD_DIR"); + Environment.unset_variable ("XDG_MUSIC_DIR"); + Environment.unset_variable ("XDG_PICTURES_DIR"); + Environment.unset_variable ("XDG_PUBLICSHARE_DIR"); + Environment.unset_variable ("XDG_TEMPLATES_DIR"); + Environment.unset_variable ("XDG_VIDEOS_DIR"); + + return transient; + } + /** * A private D-Bus session, normally created by private_bus_up() * from the constructor. @@ -151,6 +246,12 @@ public abstract class Folks.TestCase : Object ((!) this.test_dbus).down (); this.test_dbus = null; } + + if (this._transient_dir != null) + { + unowned string dir = (!) this._transient_dir; + Folks.TestUtils.remove_directory_recursively (dir); + } } ~TestCase () diff --git a/tests/lib/test-utils.vala b/tests/lib/test-utils.vala index f6e97cd..878ff62 100644 --- a/tests/lib/test-utils.vala +++ b/tests/lib/test-utils.vala @@ -25,6 +25,11 @@ using GLib; public class Folks.TestUtils { + /* Implemented in C */ + [CCode (cname = "haze_remove_directory", + cheader_filename = "haze-remove-directory.h")] + public extern static bool remove_directory_recursively (string path); + /** * Compare the content of two {@link LoadableIcon}s for equality. * diff --git a/tests/lib/tracker/test-case.vala b/tests/lib/tracker/test-case.vala index b4dfa5c..6fd719f 100644 --- a/tests/lib/tracker/test-case.vala +++ b/tests/lib/tracker/test-case.vala @@ -63,6 +63,13 @@ public class TrackerTest.TestCase : Folks.TestCase this.tracker_backend = new TrackerTest.Backend (); } + public override string? create_transient_dir () + { + /* Don't do anything. We're currently relying on + * being wrapped in with-session-bus-tracker.sh. */ + return null; + } + public override void private_bus_up () { /* Don't do anything. We're currently relying on -- 2.7.4