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
29 #include <glib/gprintf.h>
31 #include <gtk/gtkfilesystem.h>
33 #define CALLBACK_TIMEOUT_MS 3000 /* Period after which the callback must have been called */
34 #define CANCEL_TIMEOUT_MS 100 /* We'll sleep for this much time before cancelling */
36 #define GET_FOLDER_FILENAME "/etc"
37 #define GET_INFO_FILENAME "/etc/passwd"
38 #define CREATE_FOLDER_FILENAME "/tmp/autotestfilesystem-tmp"
39 #define VOLUME_MOUNT_FILENAME "/"
41 /* This is stolen from gtkfilechooserdefault.c:set_file_system_backend() */
42 static GtkFileSystem *
43 get_file_system (void)
45 GtkFileSystem *file_system = NULL;
48 file_system = gtk_file_system_create ("gnome-vfs");
50 GtkSettings *settings = gtk_settings_get_default ();
51 gchar *default_backend = NULL;
53 g_object_get (settings, "gtk-file-chooser-backend", &default_backend, NULL);
56 file_system = gtk_file_system_create (default_backend);
57 g_free (default_backend);
62 #if defined (G_OS_UNIX)
63 file_system = gtk_file_system_unix_new ();
64 #elif defined (G_OS_WIN32)
65 file_system = gtk_file_system_win32_new ();
67 #error "No default filesystem implementation on the platform"
78 /***** Testing infrastructure *****/
81 gboolean callback_was_called;
82 gboolean timeout_was_called;
83 } TestCallbackClosure;
86 notify_callback_called (TestCallbackClosure *closure)
88 closure->callback_was_called = TRUE;
93 timeout_cb (gpointer data)
95 TestCallbackClosure *closure;
99 closure->timeout_was_called = TRUE;
106 wait_for_callback (TestCallbackClosure *closure)
108 g_timeout_add (CALLBACK_TIMEOUT_MS, timeout_cb, closure);
113 const char *test_name;
114 gboolean callback_must_be_called;
115 gpointer (* setup_fn) (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
116 TestCallbackClosure *callback_closure);
117 void (* cleanup_fn) (gpointer data, gboolean *success, char **failure_reason);
121 run_test (TestSpec *test_spec)
123 GtkFileSystem *file_system;
124 TestCallbackClosure closure;
125 gboolean success_setup, success_cleanup;
127 gboolean callback_success;
129 char *setup_failure_reason;
130 char *cleanup_failure_reason;
132 file_system = get_file_system ();
135 printf ("FAIL: test \"%s\"\n", test_spec->test_name);
136 printf (" could not create file system!\n");
140 closure.callback_was_called = FALSE;
141 closure.timeout_was_called = FALSE;
143 success_setup = success_cleanup = callback_success = FALSE;
144 setup_failure_reason = cleanup_failure_reason = NULL;
146 test_data = test_spec->setup_fn (file_system, &success_setup, &setup_failure_reason, &closure);
149 wait_for_callback (&closure);
151 test_spec->cleanup_fn (test_data, &success_cleanup, &cleanup_failure_reason);
153 callback_success = (test_spec->callback_must_be_called == closure.callback_was_called);
156 g_object_unref (file_system);
158 passed = (success_setup && success_cleanup && callback_success);
160 printf ("%s: test \"%s\"\n", passed ? "PASS" : "FAIL", test_spec->test_name);
165 printf (" failure during setup: %s\n",
166 setup_failure_reason ? setup_failure_reason : "unknown failure");
169 if (!success_cleanup)
170 printf (" failure during cleanup: %s\n",
171 cleanup_failure_reason ? cleanup_failure_reason : "unknown failure");
173 if (!callback_success)
174 printf (" callback %s called but it %s called\n",
175 test_spec->callback_must_be_called ? "MUST BE" : "MUST NOT BE",
176 closure.callback_was_called ? "WAS" : "WAS NOT");
180 g_free (setup_failure_reason);
181 g_free (cleanup_failure_reason);
187 run_tests (TestSpec *test_specs, int num_tests)
194 for (i = 0; i < num_tests; i++)
195 if (run_test (test_specs + i))
198 if (num_passed == num_tests)
199 printf ("ALL TESTS PASSED\n");
201 printf ("%d of %d tests FAILED\n", (num_tests - num_passed), num_tests);
203 return (num_passed == num_tests);
208 /***** Test functions *****/
211 sleep_and_cancel_handle (GtkFileSystemHandle *handle)
213 g_usleep (CANCEL_TIMEOUT_MS * 1000);
214 gtk_file_system_cancel_operation (handle);
219 struct get_folder_data {
220 TestCallbackClosure *callback_closure;
221 GtkFileSystemHandle *handle;
222 GtkFileFolder *folder;
226 get_folder_cb (GtkFileSystemHandle *handle,
227 GtkFileFolder *folder,
231 struct get_folder_data *get_folder_data;
233 get_folder_data = data;
234 get_folder_data->folder = folder;
235 notify_callback_called (get_folder_data->callback_closure);
239 get_folder_generic_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
240 TestCallbackClosure *callback_closure)
242 struct get_folder_data *get_folder_data;
245 path = gtk_file_system_filename_to_path (file_system, GET_FOLDER_FILENAME);
249 *failure_reason = g_strdup_printf ("could not turn \"%s\" into a GtkFilePath", GET_FOLDER_FILENAME);
253 get_folder_data = g_new (struct get_folder_data, 1);
255 get_folder_data->callback_closure = callback_closure;
256 get_folder_data->folder = NULL;
258 get_folder_data->handle = gtk_file_system_get_folder (file_system,
263 gtk_file_path_free (path);
265 if (!get_folder_data->handle)
267 g_free (get_folder_data);
269 *failure_reason = g_strdup ("gtk_file_system_get_folder() returned a NULL handle");
275 return get_folder_data;
279 get_folder_no_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
280 TestCallbackClosure *callback_closure)
282 return get_folder_generic_setup (file_system, success, failure_reason, callback_closure);
286 get_folder_cleanup (gpointer data, gboolean *success, char **failure_reason)
288 struct get_folder_data *get_folder_data;
290 get_folder_data = data;
292 if (get_folder_data->folder)
293 g_object_unref (get_folder_data->folder);
295 g_free (get_folder_data);
301 get_folder_with_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
302 TestCallbackClosure *callback_closure)
304 struct get_folder_data *get_folder_data;
306 get_folder_data = get_folder_generic_setup (file_system, success, failure_reason, callback_closure);
309 sleep_and_cancel_handle (get_folder_data->handle);
311 return get_folder_data;
316 struct get_info_data {
317 TestCallbackClosure *callback_closure;
318 GtkFileSystemHandle *handle;
322 get_info_cb (GtkFileSystemHandle *handle,
323 const GtkFileInfo *file_info,
327 struct get_info_data *get_info_data;
329 get_info_data = data;
330 notify_callback_called (get_info_data->callback_closure);
334 get_info_generic_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
335 TestCallbackClosure *callback_closure)
338 struct get_info_data *get_info_data;
340 path = gtk_file_system_filename_to_path (file_system, GET_INFO_FILENAME);
344 *failure_reason = g_strdup_printf ("could not turn \"%s\" into a GtkFilePath", GET_INFO_FILENAME);
348 get_info_data = g_new (struct get_info_data, 1);
350 get_info_data->callback_closure = callback_closure;
351 get_info_data->handle = gtk_file_system_get_info (file_system,
356 gtk_file_path_free (path);
358 if (!get_info_data->handle)
360 g_free (get_info_data);
362 *failure_reason = g_strdup ("gtk_file_system_get_info() returned a NULL handle");
367 return get_info_data;
371 get_info_no_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
372 TestCallbackClosure *callback_closure)
374 return get_info_generic_setup (file_system, success, failure_reason, callback_closure);
378 get_info_cleanup (gpointer data, gboolean *success, char **failure_reason)
380 struct get_info_data *get_info_data;
382 get_info_data = data;
383 g_free (get_info_data);
389 get_info_with_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
390 TestCallbackClosure *callback_closure)
392 struct get_info_data *get_info_data;
394 get_info_data = get_info_generic_setup (file_system, success, failure_reason, callback_closure);
397 sleep_and_cancel_handle (get_info_data->handle);
399 return get_info_data;
404 struct create_folder_data {
405 TestCallbackClosure *callback_closure;
406 GtkFileSystemHandle *handle;
410 create_folder_cb (GtkFileSystemHandle *handle,
411 const GtkFilePath *path,
415 struct get_folder_data *get_folder_data;
417 get_folder_data = data;
418 notify_callback_called (get_folder_data->callback_closure);
422 create_folder_generic_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
423 TestCallbackClosure *callback_closure)
426 struct create_folder_data *create_folder_data;
428 path = gtk_file_system_filename_to_path (file_system, CREATE_FOLDER_FILENAME);
432 *failure_reason = g_strdup_printf ("could not turn \"%s\" into a GtkFilePath", CREATE_FOLDER_FILENAME);
436 create_folder_data = g_new (struct create_folder_data, 1);
438 create_folder_data->callback_closure = callback_closure;
439 create_folder_data->handle = gtk_file_system_create_folder (file_system,
443 gtk_file_path_free (path);
445 if (!create_folder_data->handle)
447 g_free (create_folder_data);
449 *failure_reason = g_strdup ("gtk_file_system_create_folder() returned a NULL handle");
454 return create_folder_data;
458 create_folder_no_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
459 TestCallbackClosure *callback_closure)
461 return create_folder_generic_setup (file_system, success, failure_reason, callback_closure);
465 create_folder_cleanup (gpointer data, gboolean *success, char **failure_reason)
467 struct create_folder_data *create_folder_data;
469 create_folder_data = data;
471 rmdir (CREATE_FOLDER_FILENAME);
473 g_free (create_folder_data);
479 create_folder_with_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
480 TestCallbackClosure *callback_closure)
482 struct create_folder_data *create_folder_data;
484 create_folder_data = create_folder_generic_setup (file_system, success, failure_reason, callback_closure);
487 sleep_and_cancel_handle (create_folder_data->handle);
489 return create_folder_data;
494 struct volume_mount_data {
495 TestCallbackClosure *callback_closure;
496 GtkFileSystemVolume *volume;
497 GtkFileSystemHandle *handle;
501 volume_mount_cb (GtkFileSystemHandle *handle,
502 GtkFileSystemVolume *volume,
506 struct volume_mount_data *volume_mount_data;
508 volume_mount_data = data;
509 notify_callback_called (volume_mount_data->callback_closure);
513 volume_mount_generic_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
514 TestCallbackClosure *callback_closure)
517 struct volume_mount_data *volume_mount_data;
519 path = gtk_file_system_filename_to_path (file_system, VOLUME_MOUNT_FILENAME);
523 *failure_reason = g_strdup_printf ("could not turn \"%s\" into a GtkFilePath", VOLUME_MOUNT_FILENAME);
527 volume_mount_data = g_new (struct volume_mount_data, 1);
529 volume_mount_data->callback_closure = callback_closure;
530 volume_mount_data->volume = gtk_file_system_get_volume_for_path (file_system, path);
531 gtk_file_path_free (path);
533 if (!volume_mount_data->volume)
535 g_free (volume_mount_data);
537 *failure_reason = g_strdup ("gtk_file_system_get_volume_for_path() returned a NULL volume");
541 volume_mount_data->handle = gtk_file_system_volume_mount (file_system,
542 volume_mount_data->volume,
545 if (!volume_mount_data->handle)
547 g_object_unref (volume_mount_data->volume);
548 g_free (volume_mount_data);
550 *failure_reason = g_strdup ("gtk_file_system_volume_mount() returned a NULL handle");
555 return volume_mount_data;
559 volume_mount_no_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
560 TestCallbackClosure *callback_closure)
562 return volume_mount_generic_setup (file_system, success, failure_reason, callback_closure);
566 volume_mount_cleanup (gpointer data, gboolean *success, char **failure_reason)
568 struct volume_mount_data *volume_mount_data;
570 volume_mount_data = data;
572 g_object_unref (volume_mount_data->volume);
573 g_free (volume_mount_data);
579 volume_mount_with_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
580 TestCallbackClosure *callback_closure)
582 struct volume_mount_data *volume_mount_data;
584 volume_mount_data = volume_mount_generic_setup (file_system, success, failure_reason, callback_closure);
587 sleep_and_cancel_handle (volume_mount_data->handle);
589 return volume_mount_data;
594 static TestSpec tests[] = {
596 "get_folder no cancel",
598 get_folder_no_cancel_setup,
602 "get_folder with cancel",
604 get_folder_with_cancel_setup,
608 "get_info no cancel",
610 get_info_no_cancel_setup,
614 "get_info with cancel",
616 get_info_with_cancel_setup,
620 "create_folder no cancel",
622 create_folder_no_cancel_setup,
623 create_folder_cleanup
626 "create_folder with cancel",
628 create_folder_with_cancel_setup,
629 create_folder_cleanup
632 "volume_mount no cancel",
634 volume_mount_no_cancel_setup,
638 "volume_mount with cancel",
640 volume_mount_with_cancel_setup,
649 static GLogFunc default_log_handler;
650 static int num_warnings;
651 static int num_errors;
652 static int num_critical_errors;
655 log_override_cb (const gchar *log_domain,
656 GLogLevelFlags log_level,
657 const gchar *message,
660 if (log_level & G_LOG_LEVEL_WARNING)
663 if (log_level & G_LOG_LEVEL_ERROR)
666 if (log_level & G_LOG_LEVEL_CRITICAL)
667 num_critical_errors++;
669 (* default_log_handler) (log_domain, log_level, message, user_data);
673 log_test (gboolean passed, const char *test_name, ...)
678 va_start (args, test_name);
679 str = g_strdup_vprintf (test_name, args);
682 g_printf ("%s: %s\n", passed ? "PASSED" : "FAILED", str);
687 main (int argc, char **argv)
690 gboolean zero_warnings;
691 gboolean zero_errors;
692 gboolean zero_critical_errors;
694 default_log_handler = g_log_set_default_handler (log_override_cb, NULL);
696 gtk_init (&argc, &argv);
700 passed = run_tests (tests, G_N_ELEMENTS (tests));
702 /* Warnings and errors */
704 zero_warnings = num_warnings == 0;
705 zero_errors = num_errors == 0;
706 zero_critical_errors = num_critical_errors == 0;
708 log_test (zero_warnings, "main(): zero warnings (actual number %d)", num_warnings);
709 log_test (zero_errors, "main(): zero errors (actual number %d)", num_errors);
710 log_test (zero_critical_errors, "main(): zero critical errors (actual number %d)", num_critical_errors);
714 passed = passed && zero_warnings && zero_errors && zero_critical_errors;
716 log_test (passed, "main(): ALL TESTS");