In tests that do not rely on with-session-bus*.sh, use a transient $HOME
authorSimon McVittie <simon.mcvittie@collabora.co.uk>
Tue, 19 Mar 2013 12:43:21 +0000 (12:43 +0000)
committerSimon McVittie <simon.mcvittie@collabora.co.uk>
Wed, 20 Mar 2013 11:48:25 +0000 (11:48 +0000)
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 <philip@tecnocode.co.uk>
[use "this." in response to review -smcv]
Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
tests/lib/Makefile.am
tests/lib/eds/test-case.vala
tests/lib/haze-remove-directory.c [new file with mode: 0644]
tests/lib/test-case.vala
tests/lib/test-utils.vala
tests/lib/tracker/test-case.vala

index 7d1b6d9..2ff0be8 100644 (file)
@@ -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 \
index 6b8446b..a4796dc 100644 (file)
@@ -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 (file)
index 0000000..f673270
--- /dev/null
@@ -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 <glib/gstdio.h>
+
+#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;
+}
index f6f9a4e..3956999 100644 (file)
@@ -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 ()
index f6e97cd..878ff62 100644 (file)
@@ -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.
    *
index b4dfa5c..6fd719f 100644 (file)
@@ -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