Remove g_type_init() calls
[platform/upstream/glib.git] / gio / tests / live-g-file.c
1 /* GLib testing framework examples and tests
2  * Copyright (C) 2008 Red Hat, Inc.
3  * Authors: Tomas Bzatek <tbzatek@redhat.com>
4  *
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.
8  *
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.
12  *
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.
21  */
22
23 #include <glib/glib.h>
24 #include <gio/gio.h>
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <sys/types.h>
28 #include <string.h>
29 #include <sys/stat.h>
30
31 #define DEFAULT_TEST_DIR                "testdir_live-g-file"
32
33 #define PATTERN_FILE_SIZE       0x10000
34 #define TEST_HANDLE_SPECIAL     TRUE
35
36 enum StructureExtraFlags
37 {
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,
45   TEST_COPY = 1 << 7,
46   TEST_MOVE = 1 << 8,
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,
53   TEST_OPEN = 1 << 15,
54   TEST_OVERWRITE = 1 << 16,
55   TEST_INVALID_SYMLINK = 1 << 17,
56 };
57
58 struct StructureItem
59 {
60   const char *filename;
61   const char *link_to;
62   GFileType file_type;
63   GFileCreateFlags create_flags;
64   guint32 mode;
65   gboolean handle_special;
66   enum StructureExtraFlags extra_flags;
67 };
68
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"
74
75
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},
103   };
104
105 static gboolean test_suite;
106 static gboolean write_test;
107 static gboolean verbose;
108 static gboolean posix_compat;
109
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, ...)
116 {
117   va_list args;
118   va_start (args, format);
119   if (verbose) g_print (format, args);
120   va_end (args);
121 }
122 #endif
123
124 static GFile *
125 create_empty_file (GFile * parent, const char *filename,
126                    GFileCreateFlags create_flags)
127 {
128   GFile *child;
129   GError *error;
130   GFileOutputStream *outs;
131
132   child = g_file_get_child (parent, filename);
133   g_assert (child != NULL);
134
135   error = NULL;
136   outs = g_file_replace (child, NULL, FALSE, create_flags, NULL, &error);
137   g_assert_no_error (error);
138   g_assert (outs != NULL);
139   error = NULL;
140   g_output_stream_close (G_OUTPUT_STREAM (outs), NULL, &error);
141   g_object_unref (outs);
142   return child;
143 }
144
145 static GFile *
146 create_empty_dir (GFile * parent, const char *filename)
147 {
148   GFile *child;
149   gboolean res;
150   GError *error;
151
152   child = g_file_get_child (parent, filename);
153   g_assert (child != NULL);
154   error = NULL;
155   res = g_file_make_directory (child, NULL, &error);
156   g_assert_cmpint (res, ==, TRUE);
157   g_assert_no_error (error);
158   return child;
159 }
160
161 static GFile *
162 create_symlink (GFile * parent, const char *filename, const char *points_to)
163 {
164   GFile *child;
165   gboolean res;
166   GError *error;
167
168   child = g_file_get_child (parent, filename);
169   g_assert (child != NULL);
170   error = 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);
174   return child;
175 }
176
177 static void
178 test_create_structure (gconstpointer test_data)
179 {
180   GFile *root;
181   GFile *child;
182   gboolean res;
183   GError *error;
184   GFileOutputStream *outs;
185   GDataOutputStream *outds;
186   guint i;
187   struct StructureItem item;
188
189   g_assert (test_data != NULL);
190   log ("\n  Going to create testing structure in '%s'...\n",
191        (char *) test_data);
192
193   root = g_file_new_for_commandline_arg ((char *) test_data);
194   g_assert (root != NULL);
195
196   /*  create root directory  */
197   res = g_file_make_directory (root, NULL, NULL);
198   /*  don't care about errors here  */
199
200   /*  create any other items  */
201   for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
202     {
203       item = sample_struct[i];
204       if ((item.handle_special)
205           || ((!posix_compat)
206               && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK)))
207         continue;
208
209       child = NULL;
210       switch (item.file_type)
211         {
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);
215           break;
216         case G_FILE_TYPE_DIRECTORY:
217           log ("    Creating directory '%s'...\n", item.filename);
218           child = create_empty_dir (root, item.filename);
219           break;
220         case G_FILE_TYPE_SYMBOLIC_LINK:
221           log ("    Creating symlink '%s' --> '%s'...\n", item.filename,
222                item.link_to);
223           child = create_symlink (root, item.filename, item.link_to);
224           break;
225         case G_FILE_TYPE_UNKNOWN:
226         case G_FILE_TYPE_SPECIAL:
227         case G_FILE_TYPE_SHORTCUT:
228         case G_FILE_TYPE_MOUNTABLE:
229         default:
230           break;
231         }
232       g_assert (child != NULL);
233
234       if ((item.mode > 0) && (posix_compat))
235         {
236           error = NULL;
237           res =
238             g_file_set_attribute_uint32 (child, G_FILE_ATTRIBUTE_UNIX_MODE,
239                                          item.mode,
240                                          G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
241                                          NULL, &error);
242           g_assert_cmpint (res, ==, TRUE);
243           g_assert_no_error (error);
244         }
245
246       g_object_unref (child);
247     }
248
249   /*  create a pattern file  */
250   log ("    Creating pattern file...");
251   child = g_file_get_child (root, "pattern_file");
252   g_assert (child != NULL);
253
254   error = NULL;
255   outs =
256     g_file_replace (child, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error);
257   g_assert_no_error (error);
258
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++)
263     {
264       error = NULL;
265       res = g_data_output_stream_put_byte (outds, i % 256, NULL, &error);
266       g_assert_no_error (error);
267     }
268   error = NULL;
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);
274   log (" done.\n");
275
276   g_object_unref (root);
277 }
278
279 static GFile *
280 file_exists (GFile * parent, const char *filename, gboolean * result)
281 {
282   GFile *child;
283   gboolean res;
284
285   if (result)
286     *result = FALSE;
287
288   child = g_file_get_child (parent, filename);
289   g_assert (child != NULL);
290   res = g_file_query_exists (child, NULL);
291   if (result)
292     *result = res;
293
294   return child;
295 }
296
297 static void
298 test_attributes (struct StructureItem item, GFileInfo * info)
299 {
300   GFileType ftype;
301   guint32 mode;
302   const char *name, *display_name, *edit_name, *copy_name, *symlink_target;
303   gboolean utf8_valid;
304   gboolean has_attr;
305   gboolean is_symlink;
306   gboolean can_read, can_write;
307
308   /*  standard::type  */
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);
314
315   /*  unix::mode  */
316   if ((item.mode > 0) && (posix_compat))
317     {
318       mode =
319         g_file_info_get_attribute_uint32 (info,
320                                           G_FILE_ATTRIBUTE_UNIX_MODE) & 0xFFF;
321       g_assert_cmpint (mode, ==, item.mode);
322     }
323
324   /*  access::can-read  */
325   if (item.file_type != G_FILE_TYPE_SYMBOLIC_LINK)
326     {
327       can_read =
328         g_file_info_get_attribute_boolean (info,
329                                            G_FILE_ATTRIBUTE_ACCESS_CAN_READ);
330       g_assert_cmpint (can_read, ==, TRUE);
331     }
332
333   /*  access::can-write  */
334   if ((write_test) && ((item.extra_flags & TEST_OVERWRITE) == TEST_OVERWRITE))
335     {
336       can_write =
337         g_file_info_get_attribute_boolean (info,
338                                            G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE);
339       g_assert_cmpint (can_write, ==, TRUE);
340     }
341
342   /*  standard::name  */
343   name = g_file_info_get_name (info);
344   g_assert (name != NULL);
345
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);
351
352   /*  standard::edit-name  */
353   edit_name = g_file_info_get_edit_name (info);
354   if (edit_name)
355     {
356       utf8_valid = g_utf8_validate (edit_name, -1, NULL);
357       g_assert_cmpint (utf8_valid, ==, TRUE);
358     }
359
360   /*  standard::copy-name  */
361   copy_name =
362     g_file_info_get_attribute_string (info,
363                                       G_FILE_ATTRIBUTE_STANDARD_COPY_NAME);
364   if (copy_name)
365     {
366       utf8_valid = g_utf8_validate (copy_name, -1, NULL);
367       g_assert_cmpint (utf8_valid, ==, TRUE);
368     }
369
370   /*  standard::is-symlink  */
371   if (posix_compat)
372     {
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);
376     }
377
378   /*  standard::symlink-target  */
379   if ((item.file_type == G_FILE_TYPE_SYMBOLIC_LINK) && (posix_compat))
380     {
381       symlink_target = g_file_info_get_symlink_target (info);
382       g_assert_cmpstr (symlink_target, ==, item.link_to);
383     }
384 }
385
386 static void
387 test_initial_structure (gconstpointer test_data)
388 {
389   GFile *root;
390   GFile *child;
391   gboolean res;
392   GError *error;
393   GFileInputStream *ins;
394   guint i;
395   GFileInfo *info;
396   guint32 size;
397   guchar *buffer;
398   gssize read, total_read;
399   struct StructureItem item;
400
401
402   g_assert (test_data != NULL);
403   log ("\n  Testing sample structure in '%s'...\n", (char *) test_data);
404
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);
409
410   /*  test the structure  */
411   for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
412     {
413       item = sample_struct[i];
414       if (((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK))
415           || (item.handle_special))
416         continue;
417
418       log ("    Testing file '%s'...\n", item.filename);
419
420       child = file_exists (root, item.filename, &res);
421       g_assert (child != NULL);
422       g_assert_cmpint (res, ==, TRUE);
423
424       error = NULL;
425       info =
426         g_file_query_info (child, "*", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
427                            NULL, &error);
428       g_assert_no_error (error);
429       g_assert (info != NULL);
430
431       test_attributes (item, info);
432
433       g_object_unref (child);
434       g_object_unref (info);
435     }
436
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);
442
443   error = NULL;
444   info =
445     g_file_query_info (child, "*", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL,
446                        &error);
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);
452
453   error = NULL;
454   ins = g_file_read (child, NULL, &error);
455   g_assert (ins != NULL);
456   g_assert_no_error (error);
457
458   buffer = g_malloc (PATTERN_FILE_SIZE);
459   total_read = 0;
460
461   while (total_read < PATTERN_FILE_SIZE)
462     {
463       error = NULL;
464       read =
465         g_input_stream_read (G_INPUT_STREAM (ins), buffer + total_read,
466                              PATTERN_FILE_SIZE, NULL, &error);
467       g_assert_no_error (error);
468       total_read += read;
469       log ("      read %"G_GSSIZE_FORMAT" bytes, total = %"G_GSSIZE_FORMAT" of %d.\n",
470            read, total_read, PATTERN_FILE_SIZE);
471     }
472   g_assert_cmpint (total_read, ==, PATTERN_FILE_SIZE);
473
474   error = NULL;
475   res = g_input_stream_close (G_INPUT_STREAM (ins), NULL, &error);
476   g_assert_no_error (error);
477   g_assert_cmpint (res, ==, TRUE);
478
479   for (i = 0; i < PATTERN_FILE_SIZE; i++)
480     g_assert_cmpint (*(buffer + i), ==, i % 256);
481
482   g_object_unref (ins);
483   g_object_unref (child);
484   g_free (buffer);
485   g_object_unref (root);
486 }
487
488 static void
489 traverse_recurse_dirs (GFile * parent, GFile * root)
490 {
491   gboolean res;
492   GError *error;
493   GFileEnumerator *enumerator;
494   GFileInfo *info;
495   GFile *descend;
496   char *relative_path;
497   guint i;
498   gboolean found;
499
500   g_assert (root != NULL);
501
502   error = NULL;
503   enumerator =
504     g_file_enumerate_children (parent, "*",
505                                G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL,
506                                &error);
507   g_assert (enumerator != NULL);
508   g_assert_no_error (error);
509
510   g_assert (g_file_enumerator_get_container (enumerator) == parent);
511
512   error = NULL;
513   info = g_file_enumerator_next_file (enumerator, NULL, &error);
514   while ((info) && (!error))
515     {
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);
520
521       found = FALSE;
522       for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
523         {
524           if (strcmp (sample_struct[i].filename, relative_path) == 0)
525             {
526               /*  test the attributes again  */
527               test_attributes (sample_struct[i], info);
528
529               found = TRUE;
530               break;
531             }
532         }
533       g_assert_cmpint (found, ==, TRUE);
534
535       log ("  Found file %s, relative to root: %s\n",
536            g_file_info_get_display_name (info), relative_path);
537
538       if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
539         traverse_recurse_dirs (descend, root);
540
541       g_object_unref (descend);
542       error = NULL;
543       g_object_unref (info);
544       g_free (relative_path);
545
546       info = g_file_enumerator_next_file (enumerator, NULL, &error);
547     }
548   g_assert_no_error (error);
549
550   error = NULL;
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));
555
556   g_object_unref (enumerator);
557 }
558
559 static void
560 test_traverse_structure (gconstpointer test_data)
561 {
562   GFile *root;
563   gboolean res;
564
565   g_assert (test_data != NULL);
566   log ("\n  Traversing through the sample structure in '%s'...\n",
567        (char *) test_data);
568
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);
573
574   traverse_recurse_dirs (root, root);
575
576   g_object_unref (root);
577 }
578
579
580
581
582 static void
583 test_enumerate (gconstpointer test_data)
584 {
585   GFile *root, *child;
586   gboolean res;
587   GError *error;
588   GFileEnumerator *enumerator;
589   GFileInfo *info;
590   guint i;
591   struct StructureItem item;
592
593
594   g_assert (test_data != NULL);
595   log ("\n  Test enumerate '%s'...\n", (char *) test_data);
596
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);
601
602
603   for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
604     {
605       item = sample_struct[i];
606       if ((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK))
607         continue;
608
609       if (((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS) ||
610           (((item.extra_flags & TEST_NO_ACCESS) == TEST_NO_ACCESS)
611            && posix_compat)
612           || ((item.extra_flags & TEST_ENUMERATE_FILE) ==
613               TEST_ENUMERATE_FILE))
614         {
615           log ("    Testing file '%s'\n", item.filename);
616           child = g_file_get_child (root, item.filename);
617           g_assert (child != NULL);
618           error = NULL;
619           enumerator =
620             g_file_enumerate_children (child, "*",
621                                        G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
622                                        NULL, &error);
623
624           if ((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS)
625             {
626               g_assert (enumerator == NULL);
627               g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
628             }
629           if ((item.extra_flags & TEST_ENUMERATE_FILE) == TEST_ENUMERATE_FILE)
630             {
631               g_assert (enumerator == NULL);
632               g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY);
633             }
634           if ((item.extra_flags & TEST_NO_ACCESS) == TEST_NO_ACCESS)
635             {
636               g_assert (enumerator != NULL);
637
638               error = 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  */
643             }
644
645           if (error)
646             g_error_free (error);
647
648           if (enumerator)
649             {
650               error = NULL;
651               res = g_file_enumerator_close (enumerator, NULL, &error);
652               g_assert_cmpint (res, ==, TRUE);
653               g_assert_no_error (error);
654
655               g_object_unref (enumerator);
656             }
657           g_object_unref (child);
658         }
659     }
660   g_object_unref (root);
661 }
662
663 static void
664 do_copy_move (GFile * root, struct StructureItem item, const char *target_dir,
665               enum StructureExtraFlags extra_flags)
666 {
667   GFile *dst_dir, *src_file, *dst_file;
668   gboolean res;
669   GError *error;
670
671   log ("    do_copy_move: '%s' --> '%s'\n", item.filename, target_dir);
672
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);
679
680   error = NULL;
681   if ((item.extra_flags & TEST_COPY) == TEST_COPY)
682     res =
683       g_file_copy (src_file, dst_file,
684                    G_FILE_COPY_NOFOLLOW_SYMLINKS |
685                    ((extra_flags ==
686                      TEST_OVERWRITE) ? G_FILE_COPY_OVERWRITE :
687                     G_FILE_COPY_NONE), NULL, NULL, NULL, &error);
688   else
689     res =
690       g_file_move (src_file, dst_file, G_FILE_COPY_NOFOLLOW_SYMLINKS, NULL,
691                    NULL, NULL, &error);
692
693   if (error)
694     log ("       res = %d, error code %d = %s\n", res, error->code,
695          error->message);
696
697   /*  copying file/directory to itself (".")  */
698   if (((item.extra_flags & TEST_NOT_EXISTS) != TEST_NOT_EXISTS) &&
699       (extra_flags == TEST_ALREADY_EXISTS))
700     {
701       g_assert_cmpint (res, ==, FALSE);
702       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS);
703     }
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))
707     {
708       g_assert_cmpint (res, ==, FALSE);
709       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY);
710     }
711   /*  source file is directory  */
712   else if ((item.extra_flags & TEST_COPY_ERROR_RECURSE) ==
713            TEST_COPY_ERROR_RECURSE)
714     {
715       g_assert_cmpint (res, ==, FALSE);
716       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_RECURSE);
717     }
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))
721     {
722       g_assert_cmpint (res, ==, FALSE);
723       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
724     }
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))
728     {
729       /* This works for root, see bug #552912 */
730       if (test_suite && getuid () == 0)
731         {
732           g_assert_cmpint (res, ==, TRUE);
733           g_assert_no_error (error);
734         }
735       else
736         {
737           g_assert_cmpint (res, ==, FALSE);
738           g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED);
739         }
740     }
741   /*  no error should be found, all exceptions defined above  */
742   else
743     {
744       g_assert_cmpint (res, ==, TRUE);
745       g_assert_no_error (error);
746     }
747
748   if (error)
749     g_error_free (error);
750
751
752   g_object_unref (dst_dir);
753   g_object_unref (src_file);
754   g_object_unref (dst_file);
755 }
756
757 static void
758 test_copy_move (gconstpointer test_data)
759 {
760   GFile *root;
761   gboolean res;
762   guint i;
763   struct StructureItem item;
764
765   log ("\n");
766
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);
772
773
774   for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
775     {
776       item = sample_struct[i];
777
778       if ((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK))
779         continue;
780
781       if (((item.extra_flags & TEST_COPY) == TEST_COPY) ||
782           ((item.extra_flags & TEST_MOVE) == TEST_MOVE))
783         {
784           /*  test copy/move to a directory, expecting no errors if source files exist  */
785           do_copy_move (root, item, TEST_DIR_TARGET, 0);
786
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)
789             {
790               /*  test overwrite for flagged files  */
791               if ((item.extra_flags & TEST_OVERWRITE) == TEST_OVERWRITE)
792                 {
793                   do_copy_move (root, item, TEST_DIR_TARGET, TEST_OVERWRITE);
794                 }
795               /*  source = target, should return G_IO_ERROR_EXISTS  */
796               do_copy_move (root, item, ".", TEST_ALREADY_EXISTS);
797               /*  target is file  */
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,
802                             TEST_NOT_EXISTS);
803
804               /*  tests on POSIX-compatible filesystems  */
805               if (posix_compat)
806                 {
807                   /*  target directory is not accessible (no execute flag)  */
808                   do_copy_move (root, item, TEST_DIR_NO_ACCESS,
809                                 TEST_NO_ACCESS);
810                   /*  target directory is readonly  */
811                   do_copy_move (root, item, TEST_DIR_NO_WRITE,
812                                 TEST_NO_ACCESS);
813                 }
814             }
815         }
816     }
817   g_object_unref (root);
818 }
819
820 static void
821 test_create (gconstpointer test_data)
822 {
823   GFile *root, *child;
824   gboolean res;
825   GError *error;
826   guint i;
827   struct StructureItem item;
828   GFileOutputStream *os;
829
830   g_assert (test_data != NULL);
831   log ("\n");
832
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);
837
838   for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
839     {
840       item = sample_struct[i];
841
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))
845         {
846           log ("  test_create: '%s'\n", item.filename);
847
848           child = g_file_get_child (root, item.filename);
849           g_assert (child != NULL);
850           error = NULL;
851           os = NULL;
852
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)
856             os =
857               g_file_replace (child, NULL, TRUE, item.create_flags, NULL,
858                               &error);
859           else if ((item.extra_flags & TEST_APPEND) == TEST_APPEND)
860             os = g_file_append_to (child, item.create_flags, NULL, &error);
861
862
863           if (error)
864             log ("       error code %d = %s\n", error->code, error->message);
865
866           if (((item.extra_flags & TEST_NOT_EXISTS) == 0) &&
867               ((item.extra_flags & TEST_CREATE) == TEST_CREATE))
868             {
869               g_assert (os == NULL);
870               g_assert_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS);
871             }
872           else if (item.file_type == G_FILE_TYPE_DIRECTORY)
873             {
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);
877               else
878                 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY);
879             }
880           else
881             {
882               g_assert (os != NULL);
883               g_assert_no_error (error);
884             }
885
886           if (error)
887             g_error_free (error);
888
889           if (os)
890             {
891               error = NULL;
892               res =
893                 g_output_stream_close (G_OUTPUT_STREAM (os), NULL, &error);
894               if (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);
899               g_object_unref (os);
900             }
901           g_object_unref (child);
902         }
903     }
904   g_object_unref (root);
905 }
906
907 static void
908 test_open (gconstpointer test_data)
909 {
910   GFile *root, *child;
911   gboolean res;
912   GError *error;
913   guint i;
914   struct StructureItem item;
915   GFileInputStream *input_stream;
916
917   g_assert (test_data != NULL);
918   log ("\n");
919
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);
924
925   for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
926     {
927       item = sample_struct[i];
928
929       if ((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK))
930         continue;
931
932       if ((item.extra_flags & TEST_OPEN) == TEST_OPEN)
933         {
934           log ("  test_open: '%s'\n", item.filename);
935
936           child = g_file_get_child (root, item.filename);
937           g_assert (child != NULL);
938           error = NULL;
939           input_stream = g_file_read (child, NULL, &error);
940
941           if (((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS) ||
942               ((item.extra_flags & TEST_INVALID_SYMLINK) ==
943                TEST_INVALID_SYMLINK))
944             {
945               g_assert (input_stream == NULL);
946               g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
947             }
948           else if (item.file_type == G_FILE_TYPE_DIRECTORY)
949             {
950               g_assert (input_stream == NULL);
951               g_assert_error (error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY);
952             }
953           else
954             {
955               g_assert (input_stream != NULL);
956               g_assert_no_error (error);
957             }
958
959           if (error)
960             g_error_free (error);
961
962           if (input_stream)
963             {
964               error = NULL;
965               res =
966                 g_input_stream_close (G_INPUT_STREAM (input_stream), NULL,
967                                       &error);
968               g_assert_cmpint (res, ==, TRUE);
969               g_assert_no_error (error);
970               g_object_unref (input_stream);
971             }
972           g_object_unref (child);
973         }
974     }
975   g_object_unref (root);
976 }
977
978 static void
979 test_delete (gconstpointer test_data)
980 {
981   GFile *root;
982   GFile *child;
983   gboolean res;
984   GError *error;
985   guint i;
986   struct StructureItem item;
987   gchar *path;
988
989   g_assert (test_data != NULL);
990   log ("\n");
991
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);
996
997   for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
998     {
999       item = sample_struct[i];
1000
1001       if ((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK))
1002         continue;
1003
1004       if (((item.extra_flags & TEST_DELETE_NORMAL) == TEST_DELETE_NORMAL) ||
1005           ((item.extra_flags & TEST_DELETE_TRASH) == TEST_DELETE_TRASH))
1006         {
1007           child = file_exists (root, item.filename, &res);
1008           g_assert (child != NULL);
1009           /*  we don't care about result here  */
1010
1011           path = g_file_get_path (child);
1012           log ("  Deleting %s, path = %s\n", item.filename, path);
1013           g_free (path);
1014
1015           error = NULL;
1016           if ((item.extra_flags & TEST_DELETE_NORMAL) == TEST_DELETE_NORMAL)
1017             res = g_file_delete (child, NULL, &error);
1018           else
1019             res = g_file_trash (child, NULL, &error);
1020
1021           if ((item.extra_flags & TEST_DELETE_NON_EMPTY) ==
1022               TEST_DELETE_NON_EMPTY)
1023             {
1024               g_assert_cmpint (res, ==, FALSE);
1025               g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_EMPTY);
1026             }
1027           if ((item.extra_flags & TEST_DELETE_FAILURE) == TEST_DELETE_FAILURE)
1028             {
1029               g_assert_cmpint (res, ==, FALSE);
1030               g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
1031             }
1032           if ((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS)
1033             {
1034               g_assert_cmpint (res, ==, FALSE);
1035               g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
1036             }
1037
1038           if (error)
1039             {
1040               log ("      result = %d, error = %s\n", res, error->message);
1041               g_error_free (error);
1042             }
1043
1044           g_object_unref (child);
1045         }
1046     }
1047   g_object_unref (root);
1048 }
1049
1050 static void
1051 test_make_directory_with_parents (gconstpointer test_data)
1052 {
1053   GFile *root, *child, *grandchild, *greatgrandchild;
1054   gboolean res;
1055   GError *error = NULL;
1056
1057   g_assert (test_data != NULL);
1058
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);
1063
1064   child = g_file_get_child (root, "a");
1065   grandchild = g_file_get_child (child, "b");
1066   greatgrandchild = g_file_get_child (grandchild, "c");
1067
1068   /* Check that we can successfully make directory hierarchies of
1069    * depth 1, 2, or 3
1070    */
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);
1076
1077   g_file_delete (child, NULL, NULL);
1078
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);
1084
1085   g_file_delete (grandchild, NULL, NULL);
1086   g_file_delete (child, NULL, NULL);
1087
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);
1093
1094   g_file_delete (greatgrandchild, NULL, NULL);
1095   g_file_delete (grandchild, NULL, NULL);
1096   g_file_delete (child, NULL, NULL);
1097
1098   /* Now test failure by trying to create a directory hierarchy
1099    * where a ancestor exists but is read-only
1100    */
1101
1102   /* No obvious way to do this on Windows */
1103   if (!posix_compat)
1104     goto out;
1105
1106 #ifndef G_PLATFORM_WIN32
1107   if (getuid() == 0) /* permissions are ignored for root */
1108     goto out;
1109 #endif
1110
1111   g_file_make_directory (child, NULL, NULL);
1112   g_assert_cmpint (res, ==, TRUE);
1113
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,
1118                                      NULL, NULL);
1119   g_assert_cmpint (res, ==, TRUE);
1120
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);
1125
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);
1130
1131 out:
1132   g_object_unref (greatgrandchild);
1133   g_object_unref (grandchild);
1134   g_object_unref (child);
1135   g_object_unref (root);
1136 }
1137
1138
1139 static void
1140 cleanup_dir_recurse (GFile *parent, GFile *root)
1141 {
1142   gboolean res;
1143   GError *error;
1144   GFileEnumerator *enumerator;
1145   GFileInfo *info;
1146   GFile *descend;
1147   char *relative_path;
1148
1149   g_assert (root != NULL);
1150
1151   enumerator =
1152     g_file_enumerate_children (parent, "*",
1153                                G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL,
1154                                NULL);
1155   if (! enumerator)
1156           return;
1157
1158   error = NULL;
1159   info = g_file_enumerator_next_file (enumerator, NULL, &error);
1160   while ((info) && (!error))
1161     {
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);
1167
1168       log ("    deleting '%s'\n", g_file_info_get_display_name (info));
1169
1170       if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
1171           cleanup_dir_recurse (descend, root);
1172       
1173       error = NULL;
1174       res = g_file_delete (descend, NULL, &error);
1175       g_assert_cmpint (res, ==, TRUE);
1176
1177       g_object_unref (descend);
1178       error = NULL;
1179       g_object_unref (info);
1180
1181       info = g_file_enumerator_next_file (enumerator, NULL, &error);
1182     }
1183   g_assert_no_error (error);
1184
1185   error = NULL;
1186   res = g_file_enumerator_close (enumerator, NULL, &error);
1187   g_assert_cmpint (res, ==, TRUE);
1188   g_assert_no_error (error);
1189
1190   g_object_unref (enumerator);
1191 }
1192
1193 static void
1194 prep_clean_structure (gconstpointer test_data)
1195 {
1196   GFile *root;
1197   
1198   g_assert (test_data != NULL);
1199   log ("\n  Cleaning target testing structure in '%s'...\n",
1200        (char *) test_data);
1201
1202   root = g_file_new_for_commandline_arg ((char *) test_data);
1203   g_assert (root != NULL);
1204   
1205   cleanup_dir_recurse (root, root);
1206
1207   g_file_delete (root, NULL, NULL);
1208   
1209   g_object_unref (root);
1210 }
1211
1212 int
1213 main (int argc, char *argv[])
1214 {
1215   static gboolean only_create_struct;
1216   const char *target_path;
1217   GError *error;
1218   GOptionContext *context;
1219
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},
1228     {NULL}
1229   };
1230
1231   test_suite = FALSE;
1232   verbose = FALSE;
1233   write_test = FALSE;
1234   only_create_struct = FALSE;
1235   target_path = NULL;
1236   posix_compat = FALSE;
1237
1238   /*  strip all gtester-specific args  */
1239   g_test_init (&argc, &argv, NULL);
1240
1241   /*  no extra parameters specified, assume we're executed from glib test suite  */ 
1242   if (argc < 2)
1243     {
1244           test_suite = TRUE;
1245           verbose = TRUE;
1246           write_test = TRUE;
1247           only_create_struct = FALSE;
1248           target_path = DEFAULT_TEST_DIR;
1249 #ifdef G_PLATFORM_WIN32
1250           posix_compat = FALSE;
1251 #else
1252           posix_compat = TRUE;
1253 #endif
1254     }
1255   
1256   /*  add trailing args  */
1257   error = NULL;
1258   context = g_option_context_new ("target_path");
1259   g_option_context_add_main_entries (context, cmd_entries, NULL);
1260   if (!g_option_context_parse (context, &argc, &argv, &error))
1261     {
1262       g_print ("option parsing failed: %s\n", error->message);
1263       return g_test_run ();
1264     }
1265
1266   /*  remaining arg should is the target path; we don't care of the extra args here  */ 
1267   if (argc >= 2)
1268     target_path = strdup (argv[1]);
1269   
1270   if (! target_path) 
1271     {
1272       g_print ("error: target path was not specified\n");
1273       g_print ("%s", g_option_context_get_help (context, TRUE, NULL));
1274       return g_test_run ();
1275     }
1276
1277   g_option_context_free (context);
1278   
1279   /*  Write test - clean target directory first  */
1280   /*    this can be also considered as a test - enumerate + delete  */ 
1281   if (write_test || only_create_struct)
1282     g_test_add_data_func ("/live-g-file/prep_clean_structure", target_path,
1283                   prep_clean_structure);
1284   
1285   /*  Write test - create new testing structure  */
1286   if (write_test || only_create_struct)
1287     g_test_add_data_func ("/live-g-file/create_structure", target_path,
1288                           test_create_structure);
1289
1290   /*  Read test - test the sample structure - expect defined attributes to be there  */
1291   if (!only_create_struct)
1292     g_test_add_data_func ("/live-g-file/test_initial_structure", target_path,
1293                           test_initial_structure);
1294
1295   /*  Read test - test traverse the structure - no special file should appear  */
1296   if (!only_create_struct)
1297     g_test_add_data_func ("/live-g-file/test_traverse_structure", target_path,
1298                           test_traverse_structure);
1299
1300   /*  Read test - enumerate  */
1301   if (!only_create_struct)
1302     g_test_add_data_func ("/live-g-file/test_enumerate", target_path,
1303                           test_enumerate);
1304
1305   /*  Read test - open (g_file_read())  */
1306   if (!only_create_struct)
1307     g_test_add_data_func ("/live-g-file/test_open", target_path, test_open);
1308
1309   /*  Write test - create  */
1310   if (write_test && (!only_create_struct))
1311     g_test_add_data_func ("/live-g-file/test_create", target_path,
1312                           test_create);
1313
1314   /*  Write test - copy, move  */
1315   if (write_test && (!only_create_struct))
1316     g_test_add_data_func ("/live-g-file/test_copy_move", target_path,
1317                           test_copy_move);
1318
1319   /*  Write test - delete, trash  */
1320   if (write_test && (!only_create_struct))
1321     g_test_add_data_func ("/live-g-file/test_delete", target_path,
1322                           test_delete);
1323
1324   /*  Write test - make_directory_with_parents */
1325   if (write_test && (!only_create_struct))
1326     g_test_add_data_func ("/live-g-file/test_make_directory_with_parents", target_path,
1327                           test_make_directory_with_parents);
1328
1329   if (write_test || only_create_struct)
1330     g_test_add_data_func ("/live-g-file/final_clean", target_path,
1331                   prep_clean_structure);
1332
1333   return g_test_run ();
1334
1335 }