1 /* GTK - The GIMP Toolkit
2 * autotestfilesystem.c: Automated tests for GtkFileSystem implementations
3 * Copyright (C) 2005, Novell, Inc.
6 * Federico Mena-Quintero <federico@novell.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
24 #define GTK_FILE_SYSTEM_ENABLE_UNSUPPORTED
31 #include <glib/gprintf.h>
33 #include <gtk/gtkfilesystem.h>
37 #define rmdir(d) _rmdir(d)
40 #define CALLBACK_TIMEOUT_MS 3000 /* Period after which the callback must have been called */
41 #define CANCEL_TIMEOUT_MS 100 /* We'll sleep for this much time before cancelling */
43 #define GET_FOLDER_FILENAME "/etc"
44 #define GET_INFO_FILENAME "/etc/passwd"
45 #define CREATE_FOLDER_FILENAME "/tmp/autotestfilesystem-tmp"
46 #define VOLUME_MOUNT_FILENAME "/"
48 /* This is stolen from gtkfilechooserdefault.c:set_file_system_backend() */
49 static GtkFileSystem *
50 get_file_system (void)
52 GtkFileSystem *file_system = NULL;
55 file_system = gtk_file_system_create ("gnome-vfs");
57 GtkSettings *settings = gtk_settings_get_default ();
58 gchar *default_backend = NULL;
60 g_object_get (settings, "gtk-file-chooser-backend", &default_backend, NULL);
63 file_system = gtk_file_system_create (default_backend);
64 g_free (default_backend);
69 #if defined (G_OS_UNIX)
70 file_system = gtk_file_system_unix_new ();
71 #elif defined (G_OS_WIN32)
72 file_system = gtk_file_system_win32_new ();
74 #error "No default filesystem implementation on the platform"
85 /***** Testing infrastructure *****/
88 gboolean callback_was_called;
89 gboolean timeout_was_called;
90 } TestCallbackClosure;
93 notify_callback_called (TestCallbackClosure *closure)
95 closure->callback_was_called = TRUE;
100 timeout_cb (gpointer data)
102 TestCallbackClosure *closure;
106 closure->timeout_was_called = TRUE;
113 wait_for_callback (TestCallbackClosure *closure)
115 gdk_threads_add_timeout (CALLBACK_TIMEOUT_MS, timeout_cb, closure);
120 const char *test_name;
121 gboolean callback_must_be_called;
122 gpointer (* setup_fn) (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
123 TestCallbackClosure *callback_closure);
124 void (* cleanup_fn) (gpointer data, gboolean *success, char **failure_reason);
128 run_test (TestSpec *test_spec)
130 GtkFileSystem *file_system;
131 TestCallbackClosure closure;
132 gboolean success_setup, success_cleanup;
134 gboolean callback_success;
136 char *setup_failure_reason;
137 char *cleanup_failure_reason;
139 file_system = get_file_system ();
142 printf ("FAIL: test \"%s\"\n", test_spec->test_name);
143 printf (" could not create file system!\n");
147 closure.callback_was_called = FALSE;
148 closure.timeout_was_called = FALSE;
150 success_setup = success_cleanup = callback_success = FALSE;
151 setup_failure_reason = cleanup_failure_reason = NULL;
153 test_data = test_spec->setup_fn (file_system, &success_setup, &setup_failure_reason, &closure);
156 wait_for_callback (&closure);
158 test_spec->cleanup_fn (test_data, &success_cleanup, &cleanup_failure_reason);
160 callback_success = (test_spec->callback_must_be_called == closure.callback_was_called);
163 g_object_unref (file_system);
165 passed = (success_setup && success_cleanup && callback_success);
167 printf ("%s: test \"%s\"\n", passed ? "PASS" : "FAIL", test_spec->test_name);
172 printf (" failure during setup: %s\n",
173 setup_failure_reason ? setup_failure_reason : "unknown failure");
176 if (!success_cleanup)
177 printf (" failure during cleanup: %s\n",
178 cleanup_failure_reason ? cleanup_failure_reason : "unknown failure");
180 if (!callback_success)
181 printf (" callback %s called but it %s called\n",
182 test_spec->callback_must_be_called ? "MUST BE" : "MUST NOT BE",
183 closure.callback_was_called ? "WAS" : "WAS NOT");
187 g_free (setup_failure_reason);
188 g_free (cleanup_failure_reason);
194 run_tests (TestSpec *test_specs, int num_tests)
201 for (i = 0; i < num_tests; i++)
202 if (run_test (test_specs + i))
205 if (num_passed == num_tests)
206 printf ("ALL TESTS PASSED\n");
208 printf ("%d of %d tests FAILED\n", (num_tests - num_passed), num_tests);
210 return (num_passed == num_tests);
215 /***** Test functions *****/
218 sleep_and_cancel_handle (GtkFileSystemHandle *handle)
220 g_usleep (CANCEL_TIMEOUT_MS * 1000);
221 gtk_file_system_cancel_operation (handle);
226 struct get_folder_data {
227 TestCallbackClosure *callback_closure;
228 GtkFileSystemHandle *handle;
229 GtkFileFolder *folder;
233 get_folder_cb (GtkFileSystemHandle *handle,
234 GtkFileFolder *folder,
238 struct get_folder_data *get_folder_data;
240 get_folder_data = data;
241 get_folder_data->folder = folder;
242 notify_callback_called (get_folder_data->callback_closure);
246 get_folder_generic_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
247 TestCallbackClosure *callback_closure)
249 struct get_folder_data *get_folder_data;
252 path = gtk_file_system_filename_to_path (file_system, GET_FOLDER_FILENAME);
256 *failure_reason = g_strdup_printf ("could not turn \"%s\" into a GtkFilePath", GET_FOLDER_FILENAME);
260 get_folder_data = g_new (struct get_folder_data, 1);
262 get_folder_data->callback_closure = callback_closure;
263 get_folder_data->folder = NULL;
265 get_folder_data->handle = gtk_file_system_get_folder (file_system,
270 gtk_file_path_free (path);
272 if (!get_folder_data->handle)
274 g_free (get_folder_data);
276 *failure_reason = g_strdup ("gtk_file_system_get_folder() returned a NULL handle");
282 return get_folder_data;
286 get_folder_no_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
287 TestCallbackClosure *callback_closure)
289 return get_folder_generic_setup (file_system, success, failure_reason, callback_closure);
293 get_folder_cleanup (gpointer data, gboolean *success, char **failure_reason)
295 struct get_folder_data *get_folder_data;
297 get_folder_data = data;
299 if (get_folder_data->folder)
300 g_object_unref (get_folder_data->folder);
302 g_free (get_folder_data);
308 get_folder_with_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
309 TestCallbackClosure *callback_closure)
311 struct get_folder_data *get_folder_data;
313 get_folder_data = get_folder_generic_setup (file_system, success, failure_reason, callback_closure);
316 sleep_and_cancel_handle (get_folder_data->handle);
318 return get_folder_data;
323 struct get_info_data {
324 TestCallbackClosure *callback_closure;
325 GtkFileSystemHandle *handle;
329 get_info_cb (GtkFileSystemHandle *handle,
330 const GtkFileInfo *file_info,
334 struct get_info_data *get_info_data;
336 get_info_data = data;
337 notify_callback_called (get_info_data->callback_closure);
341 get_info_generic_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
342 TestCallbackClosure *callback_closure)
345 struct get_info_data *get_info_data;
347 path = gtk_file_system_filename_to_path (file_system, GET_INFO_FILENAME);
351 *failure_reason = g_strdup_printf ("could not turn \"%s\" into a GtkFilePath", GET_INFO_FILENAME);
355 get_info_data = g_new (struct get_info_data, 1);
357 get_info_data->callback_closure = callback_closure;
358 get_info_data->handle = gtk_file_system_get_info (file_system,
363 gtk_file_path_free (path);
365 if (!get_info_data->handle)
367 g_free (get_info_data);
369 *failure_reason = g_strdup ("gtk_file_system_get_info() returned a NULL handle");
374 return get_info_data;
378 get_info_no_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
379 TestCallbackClosure *callback_closure)
381 return get_info_generic_setup (file_system, success, failure_reason, callback_closure);
385 get_info_cleanup (gpointer data, gboolean *success, char **failure_reason)
387 struct get_info_data *get_info_data;
389 get_info_data = data;
390 g_free (get_info_data);
396 get_info_with_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
397 TestCallbackClosure *callback_closure)
399 struct get_info_data *get_info_data;
401 get_info_data = get_info_generic_setup (file_system, success, failure_reason, callback_closure);
404 sleep_and_cancel_handle (get_info_data->handle);
406 return get_info_data;
411 struct create_folder_data {
412 TestCallbackClosure *callback_closure;
413 GtkFileSystemHandle *handle;
417 create_folder_cb (GtkFileSystemHandle *handle,
418 const GtkFilePath *path,
422 struct get_folder_data *get_folder_data;
424 get_folder_data = data;
425 notify_callback_called (get_folder_data->callback_closure);
429 create_folder_generic_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
430 TestCallbackClosure *callback_closure)
433 struct create_folder_data *create_folder_data;
435 path = gtk_file_system_filename_to_path (file_system, CREATE_FOLDER_FILENAME);
439 *failure_reason = g_strdup_printf ("could not turn \"%s\" into a GtkFilePath", CREATE_FOLDER_FILENAME);
443 create_folder_data = g_new (struct create_folder_data, 1);
445 create_folder_data->callback_closure = callback_closure;
446 create_folder_data->handle = gtk_file_system_create_folder (file_system,
450 gtk_file_path_free (path);
452 if (!create_folder_data->handle)
454 g_free (create_folder_data);
456 *failure_reason = g_strdup ("gtk_file_system_create_folder() returned a NULL handle");
461 return create_folder_data;
465 create_folder_no_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
466 TestCallbackClosure *callback_closure)
468 return create_folder_generic_setup (file_system, success, failure_reason, callback_closure);
472 create_folder_cleanup (gpointer data, gboolean *success, char **failure_reason)
474 struct create_folder_data *create_folder_data;
476 create_folder_data = data;
478 rmdir (CREATE_FOLDER_FILENAME);
480 g_free (create_folder_data);
486 create_folder_with_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
487 TestCallbackClosure *callback_closure)
489 struct create_folder_data *create_folder_data;
491 create_folder_data = create_folder_generic_setup (file_system, success, failure_reason, callback_closure);
494 sleep_and_cancel_handle (create_folder_data->handle);
496 return create_folder_data;
501 struct volume_mount_data {
502 TestCallbackClosure *callback_closure;
503 GtkFileSystemVolume *volume;
504 GtkFileSystemHandle *handle;
508 volume_mount_cb (GtkFileSystemHandle *handle,
509 GtkFileSystemVolume *volume,
513 struct volume_mount_data *volume_mount_data;
515 volume_mount_data = data;
516 notify_callback_called (volume_mount_data->callback_closure);
520 volume_mount_generic_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
521 TestCallbackClosure *callback_closure)
524 struct volume_mount_data *volume_mount_data;
526 path = gtk_file_system_filename_to_path (file_system, VOLUME_MOUNT_FILENAME);
530 *failure_reason = g_strdup_printf ("could not turn \"%s\" into a GtkFilePath", VOLUME_MOUNT_FILENAME);
534 volume_mount_data = g_new (struct volume_mount_data, 1);
536 volume_mount_data->callback_closure = callback_closure;
537 volume_mount_data->volume = gtk_file_system_get_volume_for_path (file_system, path);
538 gtk_file_path_free (path);
540 if (!volume_mount_data->volume)
542 g_free (volume_mount_data);
544 *failure_reason = g_strdup ("gtk_file_system_get_volume_for_path() returned a NULL volume");
548 volume_mount_data->handle = gtk_file_system_volume_mount (file_system,
549 volume_mount_data->volume,
552 if (!volume_mount_data->handle)
554 g_object_unref (volume_mount_data->volume);
555 g_free (volume_mount_data);
557 *failure_reason = g_strdup ("gtk_file_system_volume_mount() returned a NULL handle");
562 return volume_mount_data;
566 volume_mount_no_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
567 TestCallbackClosure *callback_closure)
569 return volume_mount_generic_setup (file_system, success, failure_reason, callback_closure);
573 volume_mount_cleanup (gpointer data, gboolean *success, char **failure_reason)
575 struct volume_mount_data *volume_mount_data;
577 volume_mount_data = data;
579 g_object_unref (volume_mount_data->volume);
580 g_free (volume_mount_data);
586 volume_mount_with_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
587 TestCallbackClosure *callback_closure)
589 struct volume_mount_data *volume_mount_data;
591 volume_mount_data = volume_mount_generic_setup (file_system, success, failure_reason, callback_closure);
594 sleep_and_cancel_handle (volume_mount_data->handle);
596 return volume_mount_data;
601 static TestSpec tests[] = {
603 "get_folder no cancel",
605 get_folder_no_cancel_setup,
609 "get_folder with cancel",
611 get_folder_with_cancel_setup,
615 "get_info no cancel",
617 get_info_no_cancel_setup,
621 "get_info with cancel",
623 get_info_with_cancel_setup,
627 "create_folder no cancel",
629 create_folder_no_cancel_setup,
630 create_folder_cleanup
633 "create_folder with cancel",
635 create_folder_with_cancel_setup,
636 create_folder_cleanup
639 "volume_mount no cancel",
641 volume_mount_no_cancel_setup,
645 "volume_mount with cancel",
647 volume_mount_with_cancel_setup,
656 static GLogFunc default_log_handler;
657 static int num_warnings;
658 static int num_errors;
659 static int num_critical_errors;
662 log_override_cb (const gchar *log_domain,
663 GLogLevelFlags log_level,
664 const gchar *message,
667 if (log_level & G_LOG_LEVEL_WARNING)
670 if (log_level & G_LOG_LEVEL_ERROR)
673 if (log_level & G_LOG_LEVEL_CRITICAL)
674 num_critical_errors++;
676 (* default_log_handler) (log_domain, log_level, message, user_data);
680 log_test (gboolean passed, const char *test_name, ...)
685 va_start (args, test_name);
686 str = g_strdup_vprintf (test_name, args);
689 g_printf ("%s: %s\n", passed ? "PASSED" : "FAILED", str);
694 main (int argc, char **argv)
697 gboolean zero_warnings;
698 gboolean zero_errors;
699 gboolean zero_critical_errors;
701 default_log_handler = g_log_set_default_handler (log_override_cb, NULL);
703 gtk_init (&argc, &argv);
707 passed = run_tests (tests, G_N_ELEMENTS (tests));
709 /* Warnings and errors */
711 zero_warnings = num_warnings == 0;
712 zero_errors = num_errors == 0;
713 zero_critical_errors = num_critical_errors == 0;
715 log_test (zero_warnings, "main(): zero warnings (actual number %d)", num_warnings);
716 log_test (zero_errors, "main(): zero errors (actual number %d)", num_errors);
717 log_test (zero_critical_errors, "main(): zero critical errors (actual number %d)", num_critical_errors);
721 passed = passed && zero_warnings && zero_errors && zero_critical_errors;
723 log_test (passed, "main(): ALL TESTS");