1 /* GLib testing framework examples and tests
2 * Copyright (C) 2008 Red Hat, Inc.
3 * Authors: Tomas Bzatek <tbzatek@redhat.com>
5 * This work is provided "as is"; redistribution and modification
6 * in whole or in part, in any medium, physical or electronic is
7 * permitted without restriction.
9 * This work is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * In no event shall the authors or contributors be liable for any
14 * direct, indirect, incidental, special, exemplary, or consequential
15 * damages (including, but not limited to, procurement of substitute
16 * goods or services; loss of use, data, or profits; or business
17 * interruption) however caused and on any theory of liability, whether
18 * in contract, strict liability, or tort (including negligence or
19 * otherwise) arising in any way out of the use of this software, even
20 * if advised of the possibility of such damage.
23 #include <glib/glib.h>
27 #include <sys/types.h>
31 #define DEFAULT_TEST_DIR "testdir_live-g-file"
33 #define PATTERN_FILE_SIZE 0x10000
34 #define TEST_HANDLE_SPECIAL TRUE
36 enum StructureExtraFlags
38 TEST_DELETE_NORMAL = 1 << 0,
39 TEST_DELETE_TRASH = 1 << 1,
40 TEST_DELETE_NON_EMPTY = 1 << 2,
41 TEST_DELETE_FAILURE = 1 << 3,
42 TEST_NOT_EXISTS = 1 << 4,
43 TEST_ENUMERATE_FILE = 1 << 5,
44 TEST_NO_ACCESS = 1 << 6,
47 TEST_COPY_ERROR_RECURSE = 1 << 9,
48 TEST_ALREADY_EXISTS = 1 << 10,
49 TEST_TARGET_IS_FILE = 1 << 11,
50 TEST_CREATE = 1 << 12,
51 TEST_REPLACE = 1 << 13,
52 TEST_APPEND = 1 << 14,
54 TEST_OVERWRITE = 1 << 16,
55 TEST_INVALID_SYMLINK = 1 << 17,
63 GFileCreateFlags create_flags;
65 gboolean handle_special;
66 enum StructureExtraFlags extra_flags;
69 #define TEST_DIR_NO_ACCESS "dir_no-access"
70 #define TEST_DIR_NO_WRITE "dir_no-write"
71 #define TEST_DIR_TARGET "dir-target"
72 #define TEST_NAME_NOT_EXISTS "not_exists"
73 #define TEST_TARGET_FILE "target-file"
76 static const struct StructureItem sample_struct[] = {
77 /* filename link file_type create_flags mode | handle_special | extra_flags */
78 {"dir1", NULL, G_FILE_TYPE_DIRECTORY, G_FILE_CREATE_NONE, 0, 0, TEST_DELETE_NORMAL | TEST_DELETE_NON_EMPTY | TEST_REPLACE | TEST_OPEN},
79 {"dir1/subdir", NULL, G_FILE_TYPE_DIRECTORY, G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_COPY_ERROR_RECURSE | TEST_APPEND},
80 {"dir2", NULL, G_FILE_TYPE_DIRECTORY, G_FILE_CREATE_NONE, 0, 0, TEST_DELETE_NORMAL | TEST_MOVE | TEST_CREATE},
81 {TEST_DIR_TARGET, NULL, G_FILE_TYPE_DIRECTORY, G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_COPY_ERROR_RECURSE},
82 {TEST_DIR_NO_ACCESS, NULL, G_FILE_TYPE_DIRECTORY, G_FILE_CREATE_PRIVATE, S_IRUSR + S_IWUSR + S_IRGRP + S_IWGRP + S_IROTH + S_IWOTH, 0, TEST_NO_ACCESS | TEST_OPEN},
83 {TEST_DIR_NO_WRITE, NULL, G_FILE_TYPE_DIRECTORY, G_FILE_CREATE_PRIVATE, S_IRUSR + S_IXUSR + S_IRGRP + S_IXGRP + S_IROTH + S_IXOTH, 0, 0},
84 {TEST_TARGET_FILE, NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_OPEN},
85 {"normal_file", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, 0, TEST_ENUMERATE_FILE | TEST_CREATE | TEST_OVERWRITE},
86 {"normal_file-symlink", "normal_file", G_FILE_TYPE_SYMBOLIC_LINK, G_FILE_CREATE_NONE, 0, 0, TEST_ENUMERATE_FILE | TEST_COPY | TEST_OPEN},
87 {"executable_file", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, S_IRWXU + S_IRWXG + S_IRWXO, 0, TEST_DELETE_TRASH | TEST_COPY | TEST_OPEN | TEST_OVERWRITE | TEST_REPLACE},
88 {"private_file", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_PRIVATE, 0, 0, TEST_COPY | TEST_OPEN | TEST_OVERWRITE | TEST_APPEND},
89 {"normal_file2", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_OVERWRITE | TEST_REPLACE},
90 {"readonly_file", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, S_IRUSR + S_IRGRP + S_IROTH, 0, TEST_DELETE_NORMAL | TEST_OPEN},
91 {"UTF_pr\xcc\x8ci\xcc\x81lis\xcc\x8c z",
92 NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_CREATE | TEST_OPEN | TEST_OVERWRITE},
93 {"dir_pr\xcc\x8ci\xcc\x81lis\xcc\x8c z",
94 NULL, G_FILE_TYPE_DIRECTORY, G_FILE_CREATE_NONE, 0, 0, TEST_DELETE_NORMAL | TEST_CREATE},
95 {"pattern_file", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_COPY | TEST_OPEN | TEST_APPEND},
96 {TEST_NAME_NOT_EXISTS, NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_DELETE_NORMAL | TEST_NOT_EXISTS | TEST_COPY | TEST_OPEN},
97 {TEST_NAME_NOT_EXISTS, NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_DELETE_TRASH | TEST_NOT_EXISTS | TEST_MOVE},
98 {"not_exists2", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_NOT_EXISTS | TEST_CREATE},
99 {"not_exists3", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_NOT_EXISTS | TEST_REPLACE},
100 {"not_exists4", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_NOT_EXISTS | TEST_APPEND},
101 {"dir_no-execute/file", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_DELETE_NORMAL | TEST_DELETE_FAILURE | TEST_NOT_EXISTS | TEST_OPEN},
102 {"lost_symlink", "nowhere", G_FILE_TYPE_SYMBOLIC_LINK, G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_DELETE_NORMAL | TEST_OPEN | TEST_INVALID_SYMLINK},
105 static gboolean test_suite;
106 static gboolean write_test;
107 static gboolean verbose;
108 static gboolean posix_compat;
110 #ifdef G_HAVE_ISO_VARARGS
111 #define log(...) if (verbose) g_print (__VA_ARGS__)
112 #elif defined(G_HAVE_GNUC_VARARGS)
113 #define log(msg...) if (verbose) g_print (msg)
114 #else /* no varargs macros */
115 static void log (const g_char *format, ...)
118 va_start (args, format);
119 if (verbose) g_print (format, args);
125 create_empty_file (GFile * parent, const char *filename,
126 GFileCreateFlags create_flags)
130 GFileOutputStream *outs;
132 child = g_file_get_child (parent, filename);
133 g_assert (child != NULL);
136 outs = g_file_replace (child, NULL, FALSE, create_flags, NULL, &error);
137 g_assert_no_error (error);
138 g_assert (outs != NULL);
140 g_output_stream_close (G_OUTPUT_STREAM (outs), NULL, &error);
141 g_object_unref (outs);
146 create_empty_dir (GFile * parent, const char *filename)
152 child = g_file_get_child (parent, filename);
153 g_assert (child != NULL);
155 res = g_file_make_directory (child, NULL, &error);
156 g_assert_cmpint (res, ==, TRUE);
157 g_assert_no_error (error);
162 create_symlink (GFile * parent, const char *filename, const char *points_to)
168 child = g_file_get_child (parent, filename);
169 g_assert (child != NULL);
171 res = g_file_make_symbolic_link (child, points_to, NULL, &error);
172 g_assert_cmpint (res, ==, TRUE);
173 g_assert_no_error (error);
178 test_create_structure (gconstpointer test_data)
184 GFileOutputStream *outs;
185 GDataOutputStream *outds;
187 struct StructureItem item;
189 g_assert (test_data != NULL);
190 log ("\n Going to create testing structure in '%s'...\n",
193 root = g_file_new_for_commandline_arg ((char *) test_data);
194 g_assert (root != NULL);
196 /* create root directory */
197 res = g_file_make_directory (root, NULL, NULL);
198 /* don't care about errors here */
200 /* create any other items */
201 for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
203 item = sample_struct[i];
204 if ((item.handle_special)
206 && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK)))
210 switch (item.file_type)
212 case G_FILE_TYPE_REGULAR:
213 log (" Creating file '%s'...\n", item.filename);
214 child = create_empty_file (root, item.filename, item.create_flags);
216 case G_FILE_TYPE_DIRECTORY:
217 log (" Creating directory '%s'...\n", item.filename);
218 child = create_empty_dir (root, item.filename);
220 case G_FILE_TYPE_SYMBOLIC_LINK:
221 log (" Creating symlink '%s' --> '%s'...\n", item.filename,
223 child = create_symlink (root, item.filename, item.link_to);
225 case G_FILE_TYPE_UNKNOWN:
226 case G_FILE_TYPE_SPECIAL:
227 case G_FILE_TYPE_SHORTCUT:
228 case G_FILE_TYPE_MOUNTABLE:
232 g_assert (child != NULL);
234 if ((item.mode > 0) && (posix_compat))
238 g_file_set_attribute_uint32 (child, G_FILE_ATTRIBUTE_UNIX_MODE,
240 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
242 g_assert_cmpint (res, ==, TRUE);
243 g_assert_no_error (error);
246 g_object_unref (child);
249 /* create a pattern file */
250 log (" Creating pattern file...");
251 child = g_file_get_child (root, "pattern_file");
252 g_assert (child != NULL);
256 g_file_replace (child, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error);
257 g_assert_no_error (error);
259 g_assert (outs != NULL);
260 outds = g_data_output_stream_new (G_OUTPUT_STREAM (outs));
261 g_assert (outds != NULL);
262 for (i = 0; i < PATTERN_FILE_SIZE; i++)
265 res = g_data_output_stream_put_byte (outds, i % 256, NULL, &error);
266 g_assert_no_error (error);
269 res = g_output_stream_close (G_OUTPUT_STREAM (outs), NULL, &error);
270 g_assert_no_error (error);
271 g_object_unref (outds);
272 g_object_unref (outs);
273 g_object_unref (child);
276 g_object_unref (root);
280 file_exists (GFile * parent, const char *filename, gboolean * result)
288 child = g_file_get_child (parent, filename);
289 g_assert (child != NULL);
290 res = g_file_query_exists (child, NULL);
298 test_attributes (struct StructureItem item, GFileInfo * info)
302 const char *name, *display_name, *edit_name, *copy_name, *symlink_target;
306 gboolean can_read, can_write;
309 has_attr = g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_TYPE);
310 g_assert_cmpint (has_attr, ==, TRUE);
311 ftype = g_file_info_get_file_type (info);
312 g_assert_cmpint (ftype, !=, G_FILE_TYPE_UNKNOWN);
313 g_assert_cmpint (ftype, ==, item.file_type);
316 if ((item.mode > 0) && (posix_compat))
319 g_file_info_get_attribute_uint32 (info,
320 G_FILE_ATTRIBUTE_UNIX_MODE) & 0xFFF;
321 g_assert_cmpint (mode, ==, item.mode);
324 /* access::can-read */
325 if (item.file_type != G_FILE_TYPE_SYMBOLIC_LINK)
328 g_file_info_get_attribute_boolean (info,
329 G_FILE_ATTRIBUTE_ACCESS_CAN_READ);
330 g_assert_cmpint (can_read, ==, TRUE);
333 /* access::can-write */
334 if ((write_test) && ((item.extra_flags & TEST_OVERWRITE) == TEST_OVERWRITE))
337 g_file_info_get_attribute_boolean (info,
338 G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE);
339 g_assert_cmpint (can_write, ==, TRUE);
343 name = g_file_info_get_name (info);
344 g_assert (name != NULL);
346 /* standard::display-name */
347 display_name = g_file_info_get_display_name (info);
348 g_assert (display_name != NULL);
349 utf8_valid = g_utf8_validate (display_name, -1, NULL);
350 g_assert_cmpint (utf8_valid, ==, TRUE);
352 /* standard::edit-name */
353 edit_name = g_file_info_get_edit_name (info);
356 utf8_valid = g_utf8_validate (edit_name, -1, NULL);
357 g_assert_cmpint (utf8_valid, ==, TRUE);
360 /* standard::copy-name */
362 g_file_info_get_attribute_string (info,
363 G_FILE_ATTRIBUTE_STANDARD_COPY_NAME);
366 utf8_valid = g_utf8_validate (copy_name, -1, NULL);
367 g_assert_cmpint (utf8_valid, ==, TRUE);
370 /* standard::is-symlink */
373 is_symlink = g_file_info_get_is_symlink (info);
374 g_assert_cmpint (is_symlink, ==,
375 item.file_type == G_FILE_TYPE_SYMBOLIC_LINK);
378 /* standard::symlink-target */
379 if ((item.file_type == G_FILE_TYPE_SYMBOLIC_LINK) && (posix_compat))
381 symlink_target = g_file_info_get_symlink_target (info);
382 g_assert_cmpstr (symlink_target, ==, item.link_to);
387 test_initial_structure (gconstpointer test_data)
393 GFileInputStream *ins;
398 gssize read, total_read;
399 struct StructureItem item;
402 g_assert (test_data != NULL);
403 log ("\n Testing sample structure in '%s'...\n", (char *) test_data);
405 root = g_file_new_for_commandline_arg ((char *) test_data);
406 g_assert (root != NULL);
407 res = g_file_query_exists (root, NULL);
408 g_assert_cmpint (res, ==, TRUE);
410 /* test the structure */
411 for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
413 item = sample_struct[i];
414 if (((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK))
415 || (item.handle_special))
418 log (" Testing file '%s'...\n", item.filename);
420 child = file_exists (root, item.filename, &res);
421 g_assert (child != NULL);
422 g_assert_cmpint (res, ==, TRUE);
426 g_file_query_info (child, "*", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
428 g_assert_no_error (error);
429 g_assert (info != NULL);
431 test_attributes (item, info);
433 g_object_unref (child);
434 g_object_unref (info);
437 /* read and test the pattern file */
438 log (" Testing pattern file...\n");
439 child = file_exists (root, "pattern_file", &res);
440 g_assert (child != NULL);
441 g_assert_cmpint (res, ==, TRUE);
445 g_file_query_info (child, "*", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL,
447 g_assert_no_error (error);
448 g_assert (info != NULL);
449 size = g_file_info_get_size (info);
450 g_assert_cmpint (size, ==, PATTERN_FILE_SIZE);
451 g_object_unref (info);
454 ins = g_file_read (child, NULL, &error);
455 g_assert (ins != NULL);
456 g_assert_no_error (error);
458 buffer = g_malloc (PATTERN_FILE_SIZE);
461 while (total_read < PATTERN_FILE_SIZE)
465 g_input_stream_read (G_INPUT_STREAM (ins), buffer + total_read,
466 PATTERN_FILE_SIZE, NULL, &error);
467 g_assert_no_error (error);
469 log (" read %"G_GSSIZE_FORMAT" bytes, total = %"G_GSSIZE_FORMAT" of %d.\n",
470 read, total_read, PATTERN_FILE_SIZE);
472 g_assert_cmpint (total_read, ==, PATTERN_FILE_SIZE);
475 res = g_input_stream_close (G_INPUT_STREAM (ins), NULL, &error);
476 g_assert_no_error (error);
477 g_assert_cmpint (res, ==, TRUE);
479 for (i = 0; i < PATTERN_FILE_SIZE; i++)
480 g_assert_cmpint (*(buffer + i), ==, i % 256);
482 g_object_unref (ins);
483 g_object_unref (child);
485 g_object_unref (root);
489 traverse_recurse_dirs (GFile * parent, GFile * root)
493 GFileEnumerator *enumerator;
500 g_assert (root != NULL);
504 g_file_enumerate_children (parent, "*",
505 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL,
507 g_assert (enumerator != NULL);
508 g_assert_no_error (error);
510 g_assert (g_file_enumerator_get_container (enumerator) == parent);
513 info = g_file_enumerator_next_file (enumerator, NULL, &error);
514 while ((info) && (!error))
516 descend = g_file_get_child (parent, g_file_info_get_name (info));
517 g_assert (descend != NULL);
518 relative_path = g_file_get_relative_path (root, descend);
519 g_assert (relative_path != NULL);
522 for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
524 if (strcmp (sample_struct[i].filename, relative_path) == 0)
526 /* test the attributes again */
527 test_attributes (sample_struct[i], info);
533 g_assert_cmpint (found, ==, TRUE);
535 log (" Found file %s, relative to root: %s\n",
536 g_file_info_get_display_name (info), relative_path);
538 if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
539 traverse_recurse_dirs (descend, root);
541 g_object_unref (descend);
543 g_object_unref (info);
544 g_free (relative_path);
546 info = g_file_enumerator_next_file (enumerator, NULL, &error);
548 g_assert_no_error (error);
551 res = g_file_enumerator_close (enumerator, NULL, &error);
552 g_assert_cmpint (res, ==, TRUE);
553 g_assert_no_error (error);
554 g_assert (g_file_enumerator_is_closed (enumerator));
556 g_object_unref (enumerator);
560 test_traverse_structure (gconstpointer test_data)
565 g_assert (test_data != NULL);
566 log ("\n Traversing through the sample structure in '%s'...\n",
569 root = g_file_new_for_commandline_arg ((char *) test_data);
570 g_assert (root != NULL);
571 res = g_file_query_exists (root, NULL);
572 g_assert_cmpint (res, ==, TRUE);
574 traverse_recurse_dirs (root, root);
576 g_object_unref (root);
583 test_enumerate (gconstpointer test_data)
588 GFileEnumerator *enumerator;
591 struct StructureItem item;
594 g_assert (test_data != NULL);
595 log ("\n Test enumerate '%s'...\n", (char *) test_data);
597 root = g_file_new_for_commandline_arg ((char *) test_data);
598 g_assert (root != NULL);
599 res = g_file_query_exists (root, NULL);
600 g_assert_cmpint (res, ==, TRUE);
603 for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
605 item = sample_struct[i];
606 if ((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK))
609 if (((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS) ||
610 (((item.extra_flags & TEST_NO_ACCESS) == TEST_NO_ACCESS)
612 || ((item.extra_flags & TEST_ENUMERATE_FILE) ==
613 TEST_ENUMERATE_FILE))
615 log (" Testing file '%s'\n", item.filename);
616 child = g_file_get_child (root, item.filename);
617 g_assert (child != NULL);
620 g_file_enumerate_children (child, "*",
621 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
624 if ((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS)
626 g_assert (enumerator == NULL);
627 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
629 if ((item.extra_flags & TEST_ENUMERATE_FILE) == TEST_ENUMERATE_FILE)
631 g_assert (enumerator == NULL);
632 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY);
634 if ((item.extra_flags & TEST_NO_ACCESS) == TEST_NO_ACCESS)
636 g_assert (enumerator != NULL);
639 info = g_file_enumerator_next_file (enumerator, NULL, &error);
640 g_assert (info == NULL);
641 g_assert_no_error (error);
642 /* no items should be found, no error should be logged */
646 g_error_free (error);
651 res = g_file_enumerator_close (enumerator, NULL, &error);
652 g_assert_cmpint (res, ==, TRUE);
653 g_assert_no_error (error);
655 g_object_unref (enumerator);
657 g_object_unref (child);
660 g_object_unref (root);
664 do_copy_move (GFile * root, struct StructureItem item, const char *target_dir,
665 enum StructureExtraFlags extra_flags)
667 GFile *dst_dir, *src_file, *dst_file;
671 log (" do_copy_move: '%s' --> '%s'\n", item.filename, target_dir);
673 dst_dir = g_file_get_child (root, target_dir);
674 g_assert (dst_dir != NULL);
675 src_file = g_file_get_child (root, item.filename);
676 g_assert (src_file != NULL);
677 dst_file = g_file_get_child (dst_dir, item.filename);
678 g_assert (dst_file != NULL);
681 if ((item.extra_flags & TEST_COPY) == TEST_COPY)
683 g_file_copy (src_file, dst_file,
684 G_FILE_COPY_NOFOLLOW_SYMLINKS |
686 TEST_OVERWRITE) ? G_FILE_COPY_OVERWRITE :
687 G_FILE_COPY_NONE), NULL, NULL, NULL, &error);
690 g_file_move (src_file, dst_file, G_FILE_COPY_NOFOLLOW_SYMLINKS, NULL,
694 log (" res = %d, error code %d = %s\n", res, error->code,
697 /* copying file/directory to itself (".") */
698 if (((item.extra_flags & TEST_NOT_EXISTS) != TEST_NOT_EXISTS) &&
699 (extra_flags == TEST_ALREADY_EXISTS))
701 g_assert_cmpint (res, ==, FALSE);
702 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS);
704 /* target file is a file, overwrite is not set */
705 else if (((item.extra_flags & TEST_NOT_EXISTS) != TEST_NOT_EXISTS) &&
706 (extra_flags == TEST_TARGET_IS_FILE))
708 g_assert_cmpint (res, ==, FALSE);
709 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY);
711 /* source file is directory */
712 else if ((item.extra_flags & TEST_COPY_ERROR_RECURSE) ==
713 TEST_COPY_ERROR_RECURSE)
715 g_assert_cmpint (res, ==, FALSE);
716 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_RECURSE);
718 /* source or target path doesn't exist */
719 else if (((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS) ||
720 (extra_flags == TEST_NOT_EXISTS))
722 g_assert_cmpint (res, ==, FALSE);
723 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
725 /* source or target path permission denied */
726 else if (((item.extra_flags & TEST_NO_ACCESS) == TEST_NO_ACCESS) ||
727 (extra_flags == TEST_NO_ACCESS))
729 /* This works for root, see bug #552912 */
730 if (test_suite && getuid () == 0)
732 g_assert_cmpint (res, ==, TRUE);
733 g_assert_no_error (error);
737 g_assert_cmpint (res, ==, FALSE);
738 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED);
741 /* no error should be found, all exceptions defined above */
744 g_assert_cmpint (res, ==, TRUE);
745 g_assert_no_error (error);
749 g_error_free (error);
752 g_object_unref (dst_dir);
753 g_object_unref (src_file);
754 g_object_unref (dst_file);
758 test_copy_move (gconstpointer test_data)
763 struct StructureItem item;
767 g_assert (test_data != NULL);
768 root = g_file_new_for_commandline_arg ((char *) test_data);
769 g_assert (root != NULL);
770 res = g_file_query_exists (root, NULL);
771 g_assert_cmpint (res, ==, TRUE);
774 for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
776 item = sample_struct[i];
778 if ((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK))
781 if (((item.extra_flags & TEST_COPY) == TEST_COPY) ||
782 ((item.extra_flags & TEST_MOVE) == TEST_MOVE))
784 /* test copy/move to a directory, expecting no errors if source files exist */
785 do_copy_move (root, item, TEST_DIR_TARGET, 0);
787 /* some files have been already moved so we can't count with them in the tests */
788 if ((item.extra_flags & TEST_COPY) == TEST_COPY)
790 /* test overwrite for flagged files */
791 if ((item.extra_flags & TEST_OVERWRITE) == TEST_OVERWRITE)
793 do_copy_move (root, item, TEST_DIR_TARGET, TEST_OVERWRITE);
795 /* source = target, should return G_IO_ERROR_EXISTS */
796 do_copy_move (root, item, ".", TEST_ALREADY_EXISTS);
798 do_copy_move (root, item, TEST_TARGET_FILE,
799 TEST_TARGET_IS_FILE);
800 /* target path is invalid */
801 do_copy_move (root, item, TEST_NAME_NOT_EXISTS,
804 /* tests on POSIX-compatible filesystems */
807 /* target directory is not accessible (no execute flag) */
808 do_copy_move (root, item, TEST_DIR_NO_ACCESS,
810 /* target directory is readonly */
811 do_copy_move (root, item, TEST_DIR_NO_WRITE,
817 g_object_unref (root);
821 test_create (gconstpointer test_data)
827 struct StructureItem item;
828 GFileOutputStream *os;
830 g_assert (test_data != NULL);
833 root = g_file_new_for_commandline_arg ((char *) test_data);
834 g_assert (root != NULL);
835 res = g_file_query_exists (root, NULL);
836 g_assert_cmpint (res, ==, TRUE);
838 for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
840 item = sample_struct[i];
842 if (((item.extra_flags & TEST_CREATE) == TEST_CREATE) ||
843 ((item.extra_flags & TEST_REPLACE) == TEST_REPLACE) ||
844 ((item.extra_flags & TEST_APPEND) == TEST_APPEND))
846 log (" test_create: '%s'\n", item.filename);
848 child = g_file_get_child (root, item.filename);
849 g_assert (child != NULL);
853 if ((item.extra_flags & TEST_CREATE) == TEST_CREATE)
854 os = g_file_create (child, item.create_flags, NULL, &error);
855 else if ((item.extra_flags & TEST_REPLACE) == TEST_REPLACE)
857 g_file_replace (child, NULL, TRUE, item.create_flags, NULL,
859 else if ((item.extra_flags & TEST_APPEND) == TEST_APPEND)
860 os = g_file_append_to (child, item.create_flags, NULL, &error);
864 log (" error code %d = %s\n", error->code, error->message);
866 if (((item.extra_flags & TEST_NOT_EXISTS) == 0) &&
867 ((item.extra_flags & TEST_CREATE) == TEST_CREATE))
869 g_assert (os == NULL);
870 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS);
872 else if (item.file_type == G_FILE_TYPE_DIRECTORY)
874 g_assert (os == NULL);
875 if ((item.extra_flags & TEST_CREATE) == TEST_CREATE)
876 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS);
878 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY);
882 g_assert (os != NULL);
883 g_assert_no_error (error);
887 g_error_free (error);
893 g_output_stream_close (G_OUTPUT_STREAM (os), NULL, &error);
895 log (" g_output_stream_close: error %d = %s\n",
896 error->code, error->message);
897 g_assert_cmpint (res, ==, TRUE);
898 g_assert_no_error (error);
901 g_object_unref (child);
904 g_object_unref (root);
908 test_open (gconstpointer test_data)
914 struct StructureItem item;
915 GFileInputStream *input_stream;
917 g_assert (test_data != NULL);
920 root = g_file_new_for_commandline_arg ((char *) test_data);
921 g_assert (root != NULL);
922 res = g_file_query_exists (root, NULL);
923 g_assert_cmpint (res, ==, TRUE);
925 for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
927 item = sample_struct[i];
929 if ((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK))
932 if ((item.extra_flags & TEST_OPEN) == TEST_OPEN)
934 log (" test_open: '%s'\n", item.filename);
936 child = g_file_get_child (root, item.filename);
937 g_assert (child != NULL);
939 input_stream = g_file_read (child, NULL, &error);
941 if (((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS) ||
942 ((item.extra_flags & TEST_INVALID_SYMLINK) ==
943 TEST_INVALID_SYMLINK))
945 g_assert (input_stream == NULL);
946 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
948 else if (item.file_type == G_FILE_TYPE_DIRECTORY)
950 g_assert (input_stream == NULL);
951 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY);
955 g_assert (input_stream != NULL);
956 g_assert_no_error (error);
960 g_error_free (error);
966 g_input_stream_close (G_INPUT_STREAM (input_stream), NULL,
968 g_assert_cmpint (res, ==, TRUE);
969 g_assert_no_error (error);
970 g_object_unref (input_stream);
972 g_object_unref (child);
975 g_object_unref (root);
979 test_delete (gconstpointer test_data)
986 struct StructureItem item;
989 g_assert (test_data != NULL);
992 root = g_file_new_for_commandline_arg ((char *) test_data);
993 g_assert (root != NULL);
994 res = g_file_query_exists (root, NULL);
995 g_assert_cmpint (res, ==, TRUE);
997 for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
999 item = sample_struct[i];
1001 if ((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK))
1004 if (((item.extra_flags & TEST_DELETE_NORMAL) == TEST_DELETE_NORMAL) ||
1005 ((item.extra_flags & TEST_DELETE_TRASH) == TEST_DELETE_TRASH))
1007 child = file_exists (root, item.filename, &res);
1008 g_assert (child != NULL);
1009 /* we don't care about result here */
1011 path = g_file_get_path (child);
1012 log (" Deleting %s, path = %s\n", item.filename, path);
1016 if ((item.extra_flags & TEST_DELETE_NORMAL) == TEST_DELETE_NORMAL)
1017 res = g_file_delete (child, NULL, &error);
1019 res = g_file_trash (child, NULL, &error);
1021 if ((item.extra_flags & TEST_DELETE_NON_EMPTY) ==
1022 TEST_DELETE_NON_EMPTY)
1024 g_assert_cmpint (res, ==, FALSE);
1025 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_EMPTY);
1027 if ((item.extra_flags & TEST_DELETE_FAILURE) == TEST_DELETE_FAILURE)
1029 g_assert_cmpint (res, ==, FALSE);
1030 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
1032 if ((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS)
1034 g_assert_cmpint (res, ==, FALSE);
1035 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
1040 log (" result = %d, error = %s\n", res, error->message);
1041 g_error_free (error);
1044 g_object_unref (child);
1047 g_object_unref (root);
1051 test_make_directory_with_parents (gconstpointer test_data)
1053 GFile *root, *child, *grandchild, *greatgrandchild;
1055 GError *error = NULL;
1057 g_assert (test_data != NULL);
1059 root = g_file_new_for_commandline_arg ((char *) test_data);
1060 g_assert (root != NULL);
1061 res = g_file_query_exists (root, NULL);
1062 g_assert_cmpint (res, ==, TRUE);
1064 child = g_file_get_child (root, "a");
1065 grandchild = g_file_get_child (child, "b");
1066 greatgrandchild = g_file_get_child (grandchild, "c");
1068 /* Check that we can successfully make directory hierarchies of
1071 res = g_file_make_directory_with_parents (child, NULL, &error);
1072 g_assert_cmpint (res, ==, TRUE);
1073 g_assert_no_error (error);
1074 res = g_file_query_exists (child, NULL);
1075 g_assert_cmpint (res, ==, TRUE);
1077 g_file_delete (child, NULL, NULL);
1079 res = g_file_make_directory_with_parents (grandchild, NULL, &error);
1080 g_assert_cmpint (res, ==, TRUE);
1081 g_assert_no_error (error);
1082 res = g_file_query_exists (grandchild, NULL);
1083 g_assert_cmpint (res, ==, TRUE);
1085 g_file_delete (grandchild, NULL, NULL);
1086 g_file_delete (child, NULL, NULL);
1088 res = g_file_make_directory_with_parents (greatgrandchild, NULL, &error);
1089 g_assert_cmpint (res, ==, TRUE);
1090 g_assert_no_error (error);
1091 res = g_file_query_exists (greatgrandchild, NULL);
1092 g_assert_cmpint (res, ==, TRUE);
1094 g_file_delete (greatgrandchild, NULL, NULL);
1095 g_file_delete (grandchild, NULL, NULL);
1096 g_file_delete (child, NULL, NULL);
1098 /* Now test failure by trying to create a directory hierarchy
1099 * where a ancestor exists but is read-only
1102 /* No obvious way to do this on Windows */
1106 #ifndef G_PLATFORM_WIN32
1107 if (getuid() == 0) /* permissions are ignored for root */
1111 g_file_make_directory (child, NULL, NULL);
1112 g_assert_cmpint (res, ==, TRUE);
1114 res = g_file_set_attribute_uint32 (child,
1115 G_FILE_ATTRIBUTE_UNIX_MODE,
1116 S_IRUSR + S_IXUSR, /* -r-x------ */
1117 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
1119 g_assert_cmpint (res, ==, TRUE);
1121 res = g_file_make_directory_with_parents (grandchild, NULL, &error);
1122 g_assert_cmpint (res, ==, FALSE);
1123 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED);
1124 g_clear_error (&error);
1126 res = g_file_make_directory_with_parents (greatgrandchild, NULL, &error);
1127 g_assert_cmpint (res, ==, FALSE);
1128 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED);
1129 g_clear_error (&error);
1132 g_object_unref (greatgrandchild);
1133 g_object_unref (grandchild);
1134 g_object_unref (child);
1135 g_object_unref (root);
1140 cleanup_dir_recurse (GFile *parent, GFile *root)
1144 GFileEnumerator *enumerator;
1147 char *relative_path;
1149 g_assert (root != NULL);
1152 g_file_enumerate_children (parent, "*",
1153 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL,
1159 info = g_file_enumerator_next_file (enumerator, NULL, &error);
1160 while ((info) && (!error))
1162 descend = g_file_get_child (parent, g_file_info_get_name (info));
1163 g_assert (descend != NULL);
1164 relative_path = g_file_get_relative_path (root, descend);
1165 g_assert (relative_path != NULL);
1166 g_free (relative_path);
1168 log (" deleting '%s'\n", g_file_info_get_display_name (info));
1170 if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
1171 cleanup_dir_recurse (descend, root);
1174 res = g_file_delete (descend, NULL, &error);
1175 g_assert_cmpint (res, ==, TRUE);
1177 g_object_unref (descend);
1179 g_object_unref (info);
1181 info = g_file_enumerator_next_file (enumerator, NULL, &error);
1183 g_assert_no_error (error);
1186 res = g_file_enumerator_close (enumerator, NULL, &error);
1187 g_assert_cmpint (res, ==, TRUE);
1188 g_assert_no_error (error);
1190 g_object_unref (enumerator);
1194 prep_clean_structure (gconstpointer test_data)
1198 g_assert (test_data != NULL);
1199 log ("\n Cleaning target testing structure in '%s'...\n",
1200 (char *) test_data);
1202 root = g_file_new_for_commandline_arg ((char *) test_data);
1203 g_assert (root != NULL);
1205 cleanup_dir_recurse (root, root);
1207 g_file_delete (root, NULL, NULL);
1209 g_object_unref (root);
1213 main (int argc, char *argv[])
1215 static gboolean only_create_struct;
1216 const char *target_path;
1218 GOptionContext *context;
1220 static GOptionEntry cmd_entries[] = {
1221 {"read-write", 'w', 0, G_OPTION_ARG_NONE, &write_test,
1222 "Perform write tests (incl. structure creation)", NULL},
1223 {"create-struct", 'c', 0, G_OPTION_ARG_NONE, &only_create_struct,
1224 "Only create testing structure (no tests)", NULL},
1225 {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Be verbose", NULL},
1226 {"posix", 'x', 0, G_OPTION_ARG_NONE, &posix_compat,
1227 "Test POSIX-specific features (unix permissions, symlinks)", NULL},
1234 only_create_struct = FALSE;
1236 posix_compat = FALSE;
1238 /* strip all gtester-specific args */
1240 g_test_init (&argc, &argv, NULL);
1242 /* no extra parameters specified, assume we're executed from glib test suite */
1248 only_create_struct = FALSE;
1249 target_path = DEFAULT_TEST_DIR;
1250 #ifdef G_PLATFORM_WIN32
1251 posix_compat = FALSE;
1253 posix_compat = TRUE;
1257 /* add trailing args */
1259 context = g_option_context_new ("target_path");
1260 g_option_context_add_main_entries (context, cmd_entries, NULL);
1261 if (!g_option_context_parse (context, &argc, &argv, &error))
1263 g_print ("option parsing failed: %s\n", error->message);
1264 return g_test_run ();
1267 /* remaining arg should is the target path; we don't care of the extra args here */
1269 target_path = strdup (argv[1]);
1273 g_print ("error: target path was not specified\n");
1274 g_print ("%s", g_option_context_get_help (context, TRUE, NULL));
1275 return g_test_run ();
1278 g_option_context_free (context);
1280 /* Write test - clean target directory first */
1281 /* this can be also considered as a test - enumerate + delete */
1282 if (write_test || only_create_struct)
1283 g_test_add_data_func ("/live-g-file/prep_clean_structure", target_path,
1284 prep_clean_structure);
1286 /* Write test - create new testing structure */
1287 if (write_test || only_create_struct)
1288 g_test_add_data_func ("/live-g-file/create_structure", target_path,
1289 test_create_structure);
1291 /* Read test - test the sample structure - expect defined attributes to be there */
1292 if (!only_create_struct)
1293 g_test_add_data_func ("/live-g-file/test_initial_structure", target_path,
1294 test_initial_structure);
1296 /* Read test - test traverse the structure - no special file should appear */
1297 if (!only_create_struct)
1298 g_test_add_data_func ("/live-g-file/test_traverse_structure", target_path,
1299 test_traverse_structure);
1301 /* Read test - enumerate */
1302 if (!only_create_struct)
1303 g_test_add_data_func ("/live-g-file/test_enumerate", target_path,
1306 /* Read test - open (g_file_read()) */
1307 if (!only_create_struct)
1308 g_test_add_data_func ("/live-g-file/test_open", target_path, test_open);
1310 /* Write test - create */
1311 if (write_test && (!only_create_struct))
1312 g_test_add_data_func ("/live-g-file/test_create", target_path,
1315 /* Write test - copy, move */
1316 if (write_test && (!only_create_struct))
1317 g_test_add_data_func ("/live-g-file/test_copy_move", target_path,
1320 /* Write test - delete, trash */
1321 if (write_test && (!only_create_struct))
1322 g_test_add_data_func ("/live-g-file/test_delete", target_path,
1325 /* Write test - make_directory_with_parents */
1326 if (write_test && (!only_create_struct))
1327 g_test_add_data_func ("/live-g-file/test_make_directory_with_parents", target_path,
1328 test_make_directory_with_parents);
1330 if (write_test || only_create_struct)
1331 g_test_add_data_func ("/live-g-file/final_clean", target_path,
1332 prep_clean_structure);
1334 return g_test_run ();