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, see <http://www.gnu.org/licenses/>.
22 #define GTK_FILE_SYSTEM_ENABLE_UNSUPPORTED
29 #include <glib/gprintf.h>
31 #include <gtk/gtkfilesystem.h>
35 #define rmdir(d) _rmdir(d)
38 #define CALLBACK_TIMEOUT_MS 3000 /* Period after which the callback must have been called */
39 #define CANCEL_TIMEOUT_MS 100 /* We'll sleep for this much time before cancelling */
41 #define GET_FOLDER_FILENAME "/etc"
42 #define GET_INFO_FILENAME "/etc/passwd"
43 #define CREATE_FOLDER_FILENAME "/tmp/autotestfilesystem-tmp"
44 #define VOLUME_MOUNT_FILENAME "/"
46 /* This is stolen from gtkfilechooserdefault.c:set_file_system_backend() */
47 static GtkFileSystem *
48 get_file_system (void)
50 GtkFileSystem *file_system = NULL;
53 file_system = gtk_file_system_create ("gnome-vfs");
55 GtkSettings *settings = gtk_settings_get_default ();
56 gchar *default_backend = NULL;
58 g_object_get (settings, "gtk-file-chooser-backend", &default_backend, NULL);
61 file_system = gtk_file_system_create (default_backend);
62 g_free (default_backend);
67 #if defined (G_OS_UNIX)
68 file_system = gtk_file_system_unix_new ();
69 #elif defined (G_OS_WIN32)
70 file_system = gtk_file_system_win32_new ();
72 #error "No default filesystem implementation on the platform"
83 /***** Testing infrastructure *****/
86 gboolean callback_was_called;
87 gboolean timeout_was_called;
88 } TestCallbackClosure;
91 notify_callback_called (TestCallbackClosure *closure)
93 closure->callback_was_called = TRUE;
98 timeout_cb (gpointer data)
100 TestCallbackClosure *closure;
104 closure->timeout_was_called = TRUE;
111 wait_for_callback (TestCallbackClosure *closure)
113 gdk_threads_add_timeout (CALLBACK_TIMEOUT_MS, timeout_cb, closure);
118 const char *test_name;
119 gboolean callback_must_be_called;
120 gpointer (* setup_fn) (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
121 TestCallbackClosure *callback_closure);
122 void (* cleanup_fn) (gpointer data, gboolean *success, char **failure_reason);
126 run_test (TestSpec *test_spec)
128 GtkFileSystem *file_system;
129 TestCallbackClosure closure;
130 gboolean success_setup, success_cleanup;
132 gboolean callback_success;
134 char *setup_failure_reason;
135 char *cleanup_failure_reason;
137 file_system = get_file_system ();
140 printf ("FAIL: test \"%s\"\n", test_spec->test_name);
141 printf (" could not create file system!\n");
145 closure.callback_was_called = FALSE;
146 closure.timeout_was_called = FALSE;
148 success_setup = success_cleanup = callback_success = FALSE;
149 setup_failure_reason = cleanup_failure_reason = NULL;
151 test_data = test_spec->setup_fn (file_system, &success_setup, &setup_failure_reason, &closure);
154 wait_for_callback (&closure);
156 test_spec->cleanup_fn (test_data, &success_cleanup, &cleanup_failure_reason);
158 callback_success = (test_spec->callback_must_be_called == closure.callback_was_called);
161 g_object_unref (file_system);
163 passed = (success_setup && success_cleanup && callback_success);
165 printf ("%s: test \"%s\"\n", passed ? "PASS" : "FAIL", test_spec->test_name);
170 printf (" failure during setup: %s\n",
171 setup_failure_reason ? setup_failure_reason : "unknown failure");
174 if (!success_cleanup)
175 printf (" failure during cleanup: %s\n",
176 cleanup_failure_reason ? cleanup_failure_reason : "unknown failure");
178 if (!callback_success)
179 printf (" callback %s called but it %s called\n",
180 test_spec->callback_must_be_called ? "MUST BE" : "MUST NOT BE",
181 closure.callback_was_called ? "WAS" : "WAS NOT");
185 g_free (setup_failure_reason);
186 g_free (cleanup_failure_reason);
192 run_tests (TestSpec *test_specs, int num_tests)
199 for (i = 0; i < num_tests; i++)
200 if (run_test (test_specs + i))
203 if (num_passed == num_tests)
204 printf ("ALL TESTS PASSED\n");
206 printf ("%d of %d tests FAILED\n", (num_tests - num_passed), num_tests);
208 return (num_passed == num_tests);
213 /***** Test functions *****/
216 sleep_and_cancel_handle (GtkFileSystemHandle *handle)
218 g_usleep (CANCEL_TIMEOUT_MS * 1000);
219 gtk_file_system_cancel_operation (handle);
224 struct get_folder_data {
225 TestCallbackClosure *callback_closure;
226 GtkFileSystemHandle *handle;
227 GtkFileFolder *folder;
231 get_folder_cb (GtkFileSystemHandle *handle,
232 GtkFileFolder *folder,
236 struct get_folder_data *get_folder_data;
238 get_folder_data = data;
239 get_folder_data->folder = folder;
240 notify_callback_called (get_folder_data->callback_closure);
244 get_folder_generic_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
245 TestCallbackClosure *callback_closure)
247 struct get_folder_data *get_folder_data;
250 path = gtk_file_system_filename_to_path (file_system, GET_FOLDER_FILENAME);
254 *failure_reason = g_strdup_printf ("could not turn \"%s\" into a GtkFilePath", GET_FOLDER_FILENAME);
258 get_folder_data = g_new (struct get_folder_data, 1);
260 get_folder_data->callback_closure = callback_closure;
261 get_folder_data->folder = NULL;
263 get_folder_data->handle = gtk_file_system_get_folder (file_system,
268 gtk_file_path_free (path);
270 if (!get_folder_data->handle)
272 g_free (get_folder_data);
274 *failure_reason = g_strdup ("gtk_file_system_get_folder() returned a NULL handle");
280 return get_folder_data;
284 get_folder_no_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
285 TestCallbackClosure *callback_closure)
287 return get_folder_generic_setup (file_system, success, failure_reason, callback_closure);
291 get_folder_cleanup (gpointer data, gboolean *success, char **failure_reason)
293 struct get_folder_data *get_folder_data;
295 get_folder_data = data;
297 if (get_folder_data->folder)
298 g_object_unref (get_folder_data->folder);
300 g_free (get_folder_data);
306 get_folder_with_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
307 TestCallbackClosure *callback_closure)
309 struct get_folder_data *get_folder_data;
311 get_folder_data = get_folder_generic_setup (file_system, success, failure_reason, callback_closure);
314 sleep_and_cancel_handle (get_folder_data->handle);
316 return get_folder_data;
321 struct get_info_data {
322 TestCallbackClosure *callback_closure;
323 GtkFileSystemHandle *handle;
327 get_info_cb (GtkFileSystemHandle *handle,
328 const GtkFileInfo *file_info,
332 struct get_info_data *get_info_data;
334 get_info_data = data;
335 notify_callback_called (get_info_data->callback_closure);
339 get_info_generic_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
340 TestCallbackClosure *callback_closure)
343 struct get_info_data *get_info_data;
345 path = gtk_file_system_filename_to_path (file_system, GET_INFO_FILENAME);
349 *failure_reason = g_strdup_printf ("could not turn \"%s\" into a GtkFilePath", GET_INFO_FILENAME);
353 get_info_data = g_new (struct get_info_data, 1);
355 get_info_data->callback_closure = callback_closure;
356 get_info_data->handle = gtk_file_system_get_info (file_system,
361 gtk_file_path_free (path);
363 if (!get_info_data->handle)
365 g_free (get_info_data);
367 *failure_reason = g_strdup ("gtk_file_system_get_info() returned a NULL handle");
372 return get_info_data;
376 get_info_no_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
377 TestCallbackClosure *callback_closure)
379 return get_info_generic_setup (file_system, success, failure_reason, callback_closure);
383 get_info_cleanup (gpointer data, gboolean *success, char **failure_reason)
385 struct get_info_data *get_info_data;
387 get_info_data = data;
388 g_free (get_info_data);
394 get_info_with_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
395 TestCallbackClosure *callback_closure)
397 struct get_info_data *get_info_data;
399 get_info_data = get_info_generic_setup (file_system, success, failure_reason, callback_closure);
402 sleep_and_cancel_handle (get_info_data->handle);
404 return get_info_data;
409 struct create_folder_data {
410 TestCallbackClosure *callback_closure;
411 GtkFileSystemHandle *handle;
415 create_folder_cb (GtkFileSystemHandle *handle,
416 const GtkFilePath *path,
420 struct get_folder_data *get_folder_data;
422 get_folder_data = data;
423 notify_callback_called (get_folder_data->callback_closure);
427 create_folder_generic_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
428 TestCallbackClosure *callback_closure)
431 struct create_folder_data *create_folder_data;
433 path = gtk_file_system_filename_to_path (file_system, CREATE_FOLDER_FILENAME);
437 *failure_reason = g_strdup_printf ("could not turn \"%s\" into a GtkFilePath", CREATE_FOLDER_FILENAME);
441 create_folder_data = g_new (struct create_folder_data, 1);
443 create_folder_data->callback_closure = callback_closure;
444 create_folder_data->handle = gtk_file_system_create_folder (file_system,
448 gtk_file_path_free (path);
450 if (!create_folder_data->handle)
452 g_free (create_folder_data);
454 *failure_reason = g_strdup ("gtk_file_system_create_folder() returned a NULL handle");
459 return create_folder_data;
463 create_folder_no_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
464 TestCallbackClosure *callback_closure)
466 return create_folder_generic_setup (file_system, success, failure_reason, callback_closure);
470 create_folder_cleanup (gpointer data, gboolean *success, char **failure_reason)
472 struct create_folder_data *create_folder_data;
474 create_folder_data = data;
476 rmdir (CREATE_FOLDER_FILENAME);
478 g_free (create_folder_data);
484 create_folder_with_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
485 TestCallbackClosure *callback_closure)
487 struct create_folder_data *create_folder_data;
489 create_folder_data = create_folder_generic_setup (file_system, success, failure_reason, callback_closure);
492 sleep_and_cancel_handle (create_folder_data->handle);
494 return create_folder_data;
499 struct volume_mount_data {
500 TestCallbackClosure *callback_closure;
501 GtkFileSystemVolume *volume;
502 GtkFileSystemHandle *handle;
506 volume_mount_cb (GtkFileSystemHandle *handle,
507 GtkFileSystemVolume *volume,
511 struct volume_mount_data *volume_mount_data;
513 volume_mount_data = data;
514 notify_callback_called (volume_mount_data->callback_closure);
518 volume_mount_generic_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
519 TestCallbackClosure *callback_closure)
522 struct volume_mount_data *volume_mount_data;
524 path = gtk_file_system_filename_to_path (file_system, VOLUME_MOUNT_FILENAME);
528 *failure_reason = g_strdup_printf ("could not turn \"%s\" into a GtkFilePath", VOLUME_MOUNT_FILENAME);
532 volume_mount_data = g_new (struct volume_mount_data, 1);
534 volume_mount_data->callback_closure = callback_closure;
535 volume_mount_data->volume = gtk_file_system_get_volume_for_path (file_system, path);
536 gtk_file_path_free (path);
538 if (!volume_mount_data->volume)
540 g_free (volume_mount_data);
542 *failure_reason = g_strdup ("gtk_file_system_get_volume_for_path() returned a NULL volume");
546 volume_mount_data->handle = gtk_file_system_volume_mount (file_system,
547 volume_mount_data->volume,
550 if (!volume_mount_data->handle)
552 g_object_unref (volume_mount_data->volume);
553 g_free (volume_mount_data);
555 *failure_reason = g_strdup ("gtk_file_system_volume_mount() returned a NULL handle");
560 return volume_mount_data;
564 volume_mount_no_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
565 TestCallbackClosure *callback_closure)
567 return volume_mount_generic_setup (file_system, success, failure_reason, callback_closure);
571 volume_mount_cleanup (gpointer data, gboolean *success, char **failure_reason)
573 struct volume_mount_data *volume_mount_data;
575 volume_mount_data = data;
577 g_object_unref (volume_mount_data->volume);
578 g_free (volume_mount_data);
584 volume_mount_with_cancel_setup (GtkFileSystem *file_system, gboolean *success, char **failure_reason,
585 TestCallbackClosure *callback_closure)
587 struct volume_mount_data *volume_mount_data;
589 volume_mount_data = volume_mount_generic_setup (file_system, success, failure_reason, callback_closure);
592 sleep_and_cancel_handle (volume_mount_data->handle);
594 return volume_mount_data;
599 static TestSpec tests[] = {
601 "get_folder no cancel",
603 get_folder_no_cancel_setup,
607 "get_folder with cancel",
609 get_folder_with_cancel_setup,
613 "get_info no cancel",
615 get_info_no_cancel_setup,
619 "get_info with cancel",
621 get_info_with_cancel_setup,
625 "create_folder no cancel",
627 create_folder_no_cancel_setup,
628 create_folder_cleanup
631 "create_folder with cancel",
633 create_folder_with_cancel_setup,
634 create_folder_cleanup
637 "volume_mount no cancel",
639 volume_mount_no_cancel_setup,
643 "volume_mount with cancel",
645 volume_mount_with_cancel_setup,
654 static GLogFunc default_log_handler;
655 static int num_warnings;
656 static int num_errors;
657 static int num_critical_errors;
660 log_override_cb (const gchar *log_domain,
661 GLogLevelFlags log_level,
662 const gchar *message,
665 if (log_level & G_LOG_LEVEL_WARNING)
668 if (log_level & G_LOG_LEVEL_ERROR)
671 if (log_level & G_LOG_LEVEL_CRITICAL)
672 num_critical_errors++;
674 (* default_log_handler) (log_domain, log_level, message, user_data);
678 log_test (gboolean passed, const char *test_name, ...)
683 va_start (args, test_name);
684 str = g_strdup_vprintf (test_name, args);
687 g_printf ("%s: %s\n", passed ? "PASSED" : "FAILED", str);
692 main (int argc, char **argv)
695 gboolean zero_warnings;
696 gboolean zero_errors;
697 gboolean zero_critical_errors;
699 default_log_handler = g_log_set_default_handler (log_override_cb, NULL);
701 gtk_init (&argc, &argv);
705 passed = run_tests (tests, G_N_ELEMENTS (tests));
707 /* Warnings and errors */
709 zero_warnings = num_warnings == 0;
710 zero_errors = num_errors == 0;
711 zero_critical_errors = num_critical_errors == 0;
713 log_test (zero_warnings, "main(): zero warnings (actual number %d)", num_warnings);
714 log_test (zero_errors, "main(): zero errors (actual number %d)", num_errors);
715 log_test (zero_critical_errors, "main(): zero critical errors (actual number %d)", num_critical_errors);
719 passed = passed && zero_warnings && zero_errors && zero_critical_errors;
721 log_test (passed, "main(): ALL TESTS");