]> Pileus Git - ~andy/gtk/commitdiff
Renamed to gtk_file_system_create() so that it will get exported and we
authorFederico Mena Quintero <federico@novell.com>
Wed, 23 Aug 2006 21:59:18 +0000 (21:59 +0000)
committerFederico Mena Quintero <federico@src.gnome.org>
Wed, 23 Aug 2006 21:59:18 +0000 (21:59 +0000)
2006-08-23  Federico Mena Quintero  <federico@novell.com>

* gtk/gtkfilesystem.[ch] (_gtk_file_system_create): Renamed to
gtk_file_system_create() so that it will get exported and we can
use it in the test program.

* gtk/gtk.symbols: Added gtk_file_system_create.

* gtk/gtkfilechooserdefault.c (set_file_system_backend): Use
gtk_file_system_create().

* tests/autotestfilesystem.c: New file with automatic tests for
the async callbacks and cancelation policy of GtkFileSystem.

* tests/Makefile.am: Added autotestfilesystem.

tests/autotestfilesystem.c [new file with mode: 0644]

diff --git a/tests/autotestfilesystem.c b/tests/autotestfilesystem.c
new file mode 100644 (file)
index 0000000..33bd6ba
--- /dev/null
@@ -0,0 +1,719 @@
+/* GTK - The GIMP Toolkit
+ * autotestfilesystem.c: Automated tests for GtkFileSystem implementations
+ * Copyright (C) 2005, Novell, Inc.
+ *
+ * Authors:
+ *   Federico Mena-Quintero <federico@novell.com>
+ *
+ * This library 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 License, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#define GTK_FILE_SYSTEM_ENABLE_UNSUPPORTED
+
+#include <config.h>
+#include <string.h>
+#include <unistd.h>
+#include <glib/gprintf.h>
+#include <gtk/gtk.h>
+#include <gtk/gtkfilesystem.h>
+
+#define CALLBACK_TIMEOUT_MS 3000       /* Period after which the callback must have been called */
+#define CANCEL_TIMEOUT_MS 100          /* We'll sleep for this much time before cancelling */
+
+#define GET_FOLDER_FILENAME "/etc"
+#define GET_INFO_FILENAME "/etc/passwd"
+#define CREATE_FOLDER_FILENAME "/tmp/autotestfilesystem-tmp"
+#define VOLUME_MOUNT_FILENAME "/"
+
+/* This is stolen from gtkfilechooserdefault.c:set_file_system_backend() */
+static GtkFileSystem *
+get_file_system (void)
+{
+  GtkFileSystem *file_system = NULL;
+
+#if 1
+  file_system = gtk_file_system_create ("gnome-vfs");
+#else
+  GtkSettings *settings = gtk_settings_get_default ();
+  gchar *default_backend = NULL;
+
+  g_object_get (settings, "gtk-file-chooser-backend", &default_backend, NULL);
+  if (default_backend)
+    {
+      file_system = gtk_file_system_create (default_backend);
+      g_free (default_backend);
+    }
+
+  if (!file_system)
+    {
+#if defined (G_OS_UNIX)
+      file_system = gtk_file_system_unix_new ();
+#elif defined (G_OS_WIN32)
+      file_system = gtk_file_system_win32_new ();
+#else
+#error "No default filesystem implementation on the platform"
+#endif
+    }
+
+#endif
+
+  return file_system;
+}
+
+\f
+
+/***** Testing infrastructure *****/
+
+typedef struct {
+  gboolean callback_was_called;
+  gboolean timeout_was_called;
+} TestCallbackClosure;
+
+static void
+notify_callback_called (TestCallbackClosure *closure)
+{
+  closure->callback_was_called = TRUE;
+  gtk_main_quit ();
+}
+
+static gboolean
+timeout_cb (gpointer data)
+{
+  TestCallbackClosure *closure;
+
+  closure = data;
+
+  closure->timeout_was_called = TRUE;
+  gtk_main_quit ();
+
+  return FALSE;
+}
+
+static void
+wait_for_callback (TestCallbackClosure *closure)
+{
+  g_timeout_add (CALLBACK_TIMEOUT_MS, timeout_cb, closure);
+  gtk_main ();
+}
+
+typedef struct {
+  const char *test_name;
+  gboolean callback_must_be_called;
+  gpointer (* setup_fn) (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
+                        TestCallbackClosure *callback_closure);
+  void (* cleanup_fn) (gpointer data, gboolean *success, char **failure_reason);
+} TestSpec;
+
+static gboolean
+run_test (TestSpec *test_spec)
+{
+  GtkFileSystem *file_system;
+  TestCallbackClosure closure;
+  gboolean success_setup, success_cleanup;
+  gpointer test_data;
+  gboolean callback_success;
+  gboolean passed;
+  char *setup_failure_reason;
+  char *cleanup_failure_reason;
+
+  file_system = get_file_system ();
+  if (!file_system)
+    {
+      printf ("FAIL: test \"%s\"\n", test_spec->test_name);
+      printf ("      could not create file system!\n");
+      return FALSE;
+    }
+
+  closure.callback_was_called = FALSE;
+  closure.timeout_was_called = FALSE;
+
+  success_setup = success_cleanup = callback_success = FALSE;
+  setup_failure_reason = cleanup_failure_reason = NULL;
+
+  test_data = test_spec->setup_fn (file_system, &success_setup, &setup_failure_reason, &closure);
+  if (success_setup)
+    {
+      wait_for_callback (&closure);
+
+      test_spec->cleanup_fn (test_data, &success_cleanup, &cleanup_failure_reason);
+
+      callback_success = (test_spec->callback_must_be_called == closure.callback_was_called);
+    }
+
+  g_object_unref (file_system);
+
+  passed = (success_setup && success_cleanup && callback_success);
+
+  printf ("%s: test \"%s\"\n", passed ? "PASS" : "FAIL", test_spec->test_name);
+
+  if (!passed)
+    {
+      if (!success_setup)
+       printf ("      failure during setup: %s\n",
+               setup_failure_reason ? setup_failure_reason : "unknown failure");
+      else
+       {
+         if (!success_cleanup)
+           printf ("      failure during cleanup: %s\n",
+                   cleanup_failure_reason ? cleanup_failure_reason : "unknown failure");
+
+         if (!callback_success)
+           printf ("      callback %s called but it %s called\n",
+                   test_spec->callback_must_be_called ? "MUST BE" : "MUST NOT BE",
+                   closure.callback_was_called ? "WAS" : "WAS NOT");
+       }
+    }
+
+  g_free (setup_failure_reason);
+  g_free (cleanup_failure_reason);
+
+  return passed;
+}
+
+static gboolean
+run_tests (TestSpec *test_specs, int num_tests)
+{
+  int i;
+  int num_passed;
+
+  num_passed = 0;
+
+  for (i = 0; i < num_tests; i++)
+    if (run_test (test_specs + i))
+      num_passed++;
+
+  if (num_passed == num_tests)
+    printf ("ALL TESTS PASSED\n");
+  else
+    printf ("%d of %d tests FAILED\n", (num_tests - num_passed), num_tests);
+
+  return (num_passed == num_tests);
+}
+
+\f
+
+/***** Test functions *****/
+
+static void
+sleep_and_cancel_handle (GtkFileSystemHandle *handle)
+{
+  g_usleep (CANCEL_TIMEOUT_MS * 1000);
+  gtk_file_system_cancel_operation (handle);
+}
+
+/* get_folder */
+
+struct get_folder_data {
+  TestCallbackClosure *callback_closure;
+  GtkFileSystemHandle *handle;
+  GtkFileFolder *folder;
+};
+
+static void
+get_folder_cb (GtkFileSystemHandle *handle,
+              GtkFileFolder       *folder,
+              const GError        *error,
+              gpointer             data)
+{
+  struct get_folder_data *get_folder_data;
+
+  get_folder_data = data;
+  get_folder_data->folder = folder;
+  notify_callback_called (get_folder_data->callback_closure);
+}
+
+static gpointer
+get_folder_generic_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
+                         TestCallbackClosure *callback_closure)
+{
+  struct get_folder_data *get_folder_data;
+  GtkFilePath *path;
+
+  path = gtk_file_system_filename_to_path (file_system, GET_FOLDER_FILENAME);
+  if (!path)
+    {
+      *success = FALSE;
+      *failure_reason = g_strdup_printf ("could not turn \"%s\" into a GtkFilePath", GET_FOLDER_FILENAME);
+      return NULL;
+    }
+
+  get_folder_data = g_new (struct get_folder_data, 1);
+
+  get_folder_data->callback_closure = callback_closure;
+  get_folder_data->folder = NULL;
+
+  get_folder_data->handle = gtk_file_system_get_folder (file_system,
+                                                       path,
+                                                       GTK_FILE_INFO_ALL,
+                                                       get_folder_cb,
+                                                       get_folder_data);
+  gtk_file_path_free (path);
+
+  if (!get_folder_data->handle)
+    {
+      g_free (get_folder_data);
+      *success = FALSE;
+      *failure_reason = g_strdup ("gtk_file_system_get_folder() returned a NULL handle");
+      return NULL;
+    }
+
+  *success = TRUE;
+
+  return get_folder_data;
+}
+
+static gpointer
+get_folder_no_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
+                           TestCallbackClosure *callback_closure)
+{
+  return get_folder_generic_setup (file_system, success, failure_reason, callback_closure);
+}
+
+static void
+get_folder_cleanup (gpointer data, gboolean *success, char **failure_reason)
+{
+  struct get_folder_data *get_folder_data;
+
+  get_folder_data = data;
+
+  if (get_folder_data->folder)
+    g_object_unref (get_folder_data->folder);
+
+  g_free (get_folder_data);
+
+  *success = TRUE;
+}
+
+static gpointer
+get_folder_with_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
+                             TestCallbackClosure *callback_closure)
+{
+  struct get_folder_data *get_folder_data;
+
+  get_folder_data = get_folder_generic_setup (file_system, success, failure_reason, callback_closure);
+
+  if (*success)
+    sleep_and_cancel_handle (get_folder_data->handle);
+
+  return get_folder_data;
+}
+
+/* get_info */
+
+struct get_info_data {
+  TestCallbackClosure *callback_closure;
+  GtkFileSystemHandle *handle;
+};
+
+static void
+get_info_cb (GtkFileSystemHandle *handle,
+            const GtkFileInfo   *file_info,
+            const GError        *error,
+            gpointer             data)
+{
+  struct get_info_data *get_info_data;
+
+  get_info_data = data;
+  notify_callback_called (get_info_data->callback_closure);
+}
+
+static gpointer
+get_info_generic_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
+                       TestCallbackClosure *callback_closure)
+{
+  GtkFilePath *path;
+  struct get_info_data *get_info_data;
+
+  path = gtk_file_system_filename_to_path (file_system, GET_INFO_FILENAME);
+  if (!path)
+    {
+      *success = FALSE;
+      *failure_reason = g_strdup_printf ("could not turn \"%s\" into a GtkFilePath", GET_INFO_FILENAME);
+      return NULL;
+    }
+
+  get_info_data = g_new (struct get_info_data, 1);
+
+  get_info_data->callback_closure = callback_closure;
+  get_info_data->handle = gtk_file_system_get_info (file_system,
+                                                   path,
+                                                   GTK_FILE_INFO_ALL,
+                                                   get_info_cb,
+                                                   get_info_data);
+  gtk_file_path_free (path);
+
+  if (!get_info_data->handle)
+    {
+      g_free (get_info_data);
+      *success = FALSE;
+      *failure_reason = g_strdup ("gtk_file_system_get_info() returned a NULL handle");
+      return NULL;
+    }
+
+  *success = TRUE;
+  return get_info_data;
+}
+
+static gpointer
+get_info_no_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
+                         TestCallbackClosure *callback_closure)
+{
+  return get_info_generic_setup (file_system, success, failure_reason, callback_closure);
+}
+
+static void
+get_info_cleanup (gpointer data, gboolean *success, char **failure_reason)
+{
+  struct get_info_data *get_info_data;
+
+  get_info_data = data;
+  g_free (get_info_data);
+
+  *success = TRUE;
+}
+
+static gpointer
+get_info_with_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
+                           TestCallbackClosure *callback_closure)
+{
+  struct get_info_data *get_info_data;
+
+  get_info_data = get_info_generic_setup (file_system, success, failure_reason, callback_closure);
+
+  if (*success)
+    sleep_and_cancel_handle (get_info_data->handle);
+
+  return get_info_data;
+}
+
+/* create_folder */
+
+struct create_folder_data {
+  TestCallbackClosure *callback_closure;
+  GtkFileSystemHandle *handle;
+};
+
+static void
+create_folder_cb (GtkFileSystemHandle *handle,
+                 const GtkFilePath   *path,
+                 const GError        *error,
+                 gpointer             data)
+{
+  struct get_folder_data *get_folder_data;
+
+  get_folder_data = data;
+  notify_callback_called (get_folder_data->callback_closure);
+}
+
+static gpointer
+create_folder_generic_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
+                            TestCallbackClosure *callback_closure)
+{
+  GtkFilePath *path;
+  struct create_folder_data *create_folder_data;
+
+  path = gtk_file_system_filename_to_path (file_system, CREATE_FOLDER_FILENAME);
+  if (!path)
+    {
+      *success = FALSE;
+      *failure_reason = g_strdup_printf ("could not turn \"%s\" into a GtkFilePath", CREATE_FOLDER_FILENAME);
+      return NULL;
+    }
+
+  create_folder_data = g_new (struct create_folder_data, 1);
+
+  create_folder_data->callback_closure = callback_closure;
+  create_folder_data->handle = gtk_file_system_create_folder (file_system,
+                                                             path,
+                                                             create_folder_cb,
+                                                             create_folder_data);
+  gtk_file_path_free (path);
+
+  if (!create_folder_data->handle)
+    {
+      g_free (create_folder_data);
+      *success = FALSE;
+      *failure_reason = g_strdup ("gtk_file_system_create_folder() returned a NULL handle");
+      return NULL;
+    }
+
+  *success = TRUE;
+  return create_folder_data;
+}
+
+static gpointer
+create_folder_no_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
+                              TestCallbackClosure *callback_closure)
+{
+  return create_folder_generic_setup (file_system, success, failure_reason, callback_closure);
+}
+
+static void
+create_folder_cleanup (gpointer data, gboolean *success, char **failure_reason)
+{
+  struct create_folder_data *create_folder_data;
+
+  create_folder_data = data;
+
+  rmdir (CREATE_FOLDER_FILENAME);
+
+  g_free (create_folder_data);
+
+  *success = TRUE;
+}
+
+static gpointer
+create_folder_with_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
+                                TestCallbackClosure *callback_closure)
+{
+  struct create_folder_data *create_folder_data;
+
+  create_folder_data = create_folder_generic_setup (file_system, success, failure_reason, callback_closure);
+
+  if (*success)
+    sleep_and_cancel_handle (create_folder_data->handle);
+
+  return create_folder_data;
+}
+
+/* volume_mount */
+
+struct volume_mount_data {
+  TestCallbackClosure *callback_closure;
+  GtkFileSystemVolume *volume;
+  GtkFileSystemHandle *handle;
+};
+
+static void
+volume_mount_cb (GtkFileSystemHandle *handle,
+                GtkFileSystemVolume *volume,
+                const GError        *error,
+                gpointer             data)
+{
+  struct volume_mount_data *volume_mount_data;
+
+  volume_mount_data = data;
+  notify_callback_called (volume_mount_data->callback_closure);
+}
+
+static gpointer
+volume_mount_generic_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
+                           TestCallbackClosure *callback_closure)
+{
+  GtkFilePath *path;
+  struct volume_mount_data *volume_mount_data;
+
+  path = gtk_file_system_filename_to_path (file_system, VOLUME_MOUNT_FILENAME);
+  if (!path)
+    {
+      *success = FALSE;
+      *failure_reason = g_strdup_printf ("could not turn \"%s\" into a GtkFilePath", VOLUME_MOUNT_FILENAME);
+      return NULL;
+    }
+
+  volume_mount_data = g_new (struct volume_mount_data, 1);
+
+  volume_mount_data->callback_closure = callback_closure;
+  volume_mount_data->volume = gtk_file_system_get_volume_for_path (file_system, path);
+  gtk_file_path_free (path);
+
+  if (!volume_mount_data->volume)
+    {
+      g_free (volume_mount_data);
+      *success = FALSE;
+      *failure_reason = g_strdup ("gtk_file_system_get_volume_for_path() returned a NULL volume");
+      return NULL;
+    }
+
+  volume_mount_data->handle = gtk_file_system_volume_mount (file_system,
+                                                           volume_mount_data->volume,
+                                                           volume_mount_cb,
+                                                           volume_mount_data);
+  if (!volume_mount_data->handle)
+    {
+      g_object_unref (volume_mount_data->volume);
+      g_free (volume_mount_data);
+      *success = FALSE;
+      *failure_reason = g_strdup ("gtk_file_system_volume_mount() returned a NULL handle");
+      return NULL;
+    }
+
+  *success = TRUE;
+  return volume_mount_data;
+}
+
+static gpointer
+volume_mount_no_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
+                             TestCallbackClosure *callback_closure)
+{
+  return volume_mount_generic_setup (file_system, success, failure_reason, callback_closure);
+}
+
+static void
+volume_mount_cleanup (gpointer data, gboolean *success, char **failure_reason)
+{
+  struct volume_mount_data *volume_mount_data;
+
+  volume_mount_data = data;
+
+  g_object_unref (volume_mount_data->volume);
+  g_free (volume_mount_data);
+
+  *success = TRUE;
+}
+
+static gpointer
+volume_mount_with_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
+                               TestCallbackClosure *callback_closure)
+{
+  struct volume_mount_data *volume_mount_data;
+
+  volume_mount_data = volume_mount_generic_setup (file_system, success, failure_reason, callback_closure);
+
+  if (*success)
+    sleep_and_cancel_handle (volume_mount_data->handle);
+
+  return volume_mount_data;
+}
+
+/* tests */
+
+static TestSpec tests[] = {
+  {
+    "get_folder no cancel",
+    TRUE,
+    get_folder_no_cancel_setup,
+    get_folder_cleanup
+  },
+  {
+    "get_folder with cancel",
+    FALSE,
+    get_folder_with_cancel_setup,
+    get_folder_cleanup
+  },
+  {
+    "get_info no cancel",
+    TRUE,
+    get_info_no_cancel_setup,
+    get_info_cleanup
+  },
+  {
+    "get_info with cancel",
+    FALSE,
+    get_info_with_cancel_setup,
+    get_info_cleanup
+  },
+  {
+    "create_folder no cancel",
+    TRUE,
+    create_folder_no_cancel_setup,
+    create_folder_cleanup
+  },
+  {
+    "create_folder with cancel",
+    FALSE,
+    create_folder_with_cancel_setup,
+    create_folder_cleanup
+  },
+  {
+    "volume_mount no cancel",
+    TRUE,
+    volume_mount_no_cancel_setup,
+    volume_mount_cleanup
+  },
+  {
+    "volume_mount with cancel",
+    FALSE,
+    volume_mount_with_cancel_setup,
+    volume_mount_cleanup
+  }
+};
+
+\f
+
+/***** main *****/
+
+static GLogFunc default_log_handler;
+static int num_warnings;
+static int num_errors;
+static int num_critical_errors;
+
+static void
+log_override_cb (const gchar   *log_domain,
+                GLogLevelFlags log_level,
+                const gchar   *message,
+                gpointer       user_data)
+{
+  if (log_level & G_LOG_LEVEL_WARNING)
+    num_warnings++;
+
+  if (log_level & G_LOG_LEVEL_ERROR)
+    num_errors++;
+
+  if (log_level & G_LOG_LEVEL_CRITICAL)
+    num_critical_errors++;
+
+  (* default_log_handler) (log_domain, log_level, message, user_data);
+}
+
+static void
+log_test (gboolean passed, const char *test_name, ...)
+{
+  va_list args;
+  char *str;
+
+  va_start (args, test_name);
+  str = g_strdup_vprintf (test_name, args);
+  va_end (args);
+
+  g_printf ("%s: %s\n", passed ? "PASSED" : "FAILED", str);
+  g_free (str);
+}
+
+int
+main (int argc, char **argv)
+{
+  gboolean passed;
+  gboolean zero_warnings;
+  gboolean zero_errors;
+  gboolean zero_critical_errors;
+
+  default_log_handler = g_log_set_default_handler (log_override_cb, NULL);
+
+  gtk_init (&argc, &argv);
+
+  /* Start tests */
+
+  passed = run_tests (tests, G_N_ELEMENTS (tests));
+
+  /* Warnings and errors */
+
+  zero_warnings = num_warnings == 0;
+  zero_errors = num_errors == 0;
+  zero_critical_errors = num_critical_errors == 0;
+
+  log_test (zero_warnings, "main(): zero warnings (actual number %d)", num_warnings);
+  log_test (zero_errors, "main(): zero errors (actual number %d)", num_errors);
+  log_test (zero_critical_errors, "main(): zero critical errors (actual number %d)", num_critical_errors);
+
+  /* Done */
+
+  passed = passed && zero_warnings && zero_errors && zero_critical_errors;
+
+  log_test (passed, "main(): ALL TESTS");
+
+  return 0;
+}