Home | History | Annotate | Download | only in tests
      1 /* GLib testing framework examples and tests
      2  * Copyright (C) 2008 Red Hat, Inc.
      3  * Authors: Tomas Bzatek <tbzatek (at) 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 <string.h>
     27 #include <sys/stat.h>
     28 
     29 #define DEFAULT_TEST_DIR		"testdir_live-g-file"
     30 
     31 #define PATTERN_FILE_SIZE	0x10000
     32 #define TEST_HANDLE_SPECIAL	TRUE
     33 
     34 enum StructureExtraFlags
     35 {
     36   TEST_DELETE_NORMAL = 1 << 0,
     37   TEST_DELETE_TRASH = 1 << 1,
     38   TEST_DELETE_NON_EMPTY = 1 << 2,
     39   TEST_DELETE_FAILURE = 1 << 3,
     40   TEST_NOT_EXISTS = 1 << 4,
     41   TEST_ENUMERATE_FILE = 1 << 5,
     42   TEST_NO_ACCESS = 1 << 6,
     43   TEST_COPY = 1 << 7,
     44   TEST_MOVE = 1 << 8,
     45   TEST_COPY_ERROR_RECURSE = 1 << 9,
     46   TEST_ALREADY_EXISTS = 1 << 10,
     47   TEST_TARGET_IS_FILE = 1 << 11,
     48   TEST_CREATE = 1 << 12,
     49   TEST_REPLACE = 1 << 13,
     50   TEST_APPEND = 1 << 14,
     51   TEST_OPEN = 1 << 15,
     52   TEST_OVERWRITE = 1 << 16,
     53   TEST_INVALID_SYMLINK = 1 << 17,
     54 };
     55 
     56 struct StructureItem
     57 {
     58   const char *filename;
     59   const char *link_to;
     60   GFileType file_type;
     61   GFileCreateFlags create_flags;
     62   guint32 mode;
     63   gboolean handle_special;
     64   enum StructureExtraFlags extra_flags;
     65 };
     66 
     67 #define TEST_DIR_NO_ACCESS		"dir_no-access"
     68 #define TEST_DIR_NO_WRITE		"dir_no-write"
     69 #define TEST_DIR_TARGET			"dir-target"
     70 #define TEST_NAME_NOT_EXISTS	"not_exists"
     71 #define TEST_TARGET_FILE		"target-file"
     72 
     73 
     74 static const struct StructureItem sample_struct[] = {
     75 /*	 filename				link	file_type				create_flags		mode | handle_special | extra_flags              */
     76     {"dir1",				NULL,	G_FILE_TYPE_DIRECTORY,	G_FILE_CREATE_NONE, 0, 0, TEST_DELETE_NORMAL | TEST_DELETE_NON_EMPTY | TEST_REPLACE | TEST_OPEN},
     77     {"dir1/subdir",			NULL,	G_FILE_TYPE_DIRECTORY,	G_FILE_CREATE_NONE, 0, 0, TEST_COPY	| TEST_COPY_ERROR_RECURSE | TEST_APPEND},
     78     {"dir2",				NULL,	G_FILE_TYPE_DIRECTORY,	G_FILE_CREATE_NONE, 0, 0, TEST_DELETE_NORMAL | TEST_MOVE | TEST_CREATE},
     79     {TEST_DIR_TARGET,		NULL,	G_FILE_TYPE_DIRECTORY,	G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_COPY_ERROR_RECURSE},
     80     {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},
     81     {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},
     82     {TEST_TARGET_FILE,		NULL,	G_FILE_TYPE_REGULAR,	G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_OPEN},
     83 	{"normal_file",			NULL,	G_FILE_TYPE_REGULAR,	G_FILE_CREATE_NONE, 0, 0, TEST_ENUMERATE_FILE | TEST_CREATE | TEST_OVERWRITE},
     84 	{"normal_file-symlink",	"normal_file",	G_FILE_TYPE_SYMBOLIC_LINK, G_FILE_CREATE_NONE, 0, 0, TEST_ENUMERATE_FILE | TEST_COPY | TEST_OPEN},
     85     {"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},
     86     {"private_file",		NULL,	G_FILE_TYPE_REGULAR,	G_FILE_CREATE_PRIVATE, 0, 0, TEST_COPY | TEST_OPEN | TEST_OVERWRITE | TEST_APPEND},
     87     {"normal_file2",		NULL,	G_FILE_TYPE_REGULAR,	G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_OVERWRITE | TEST_REPLACE},
     88     {"readonly_file",		NULL,	G_FILE_TYPE_REGULAR,	G_FILE_CREATE_NONE, S_IRUSR + S_IRGRP + S_IROTH, 0, TEST_DELETE_NORMAL | TEST_OPEN},
     89     {"UTF_pr\xcc\x8ci\xcc\x81lis\xcc\x8c z",
     90     						NULL,	G_FILE_TYPE_REGULAR,	G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_CREATE | TEST_OPEN | TEST_OVERWRITE},
     91     {"dir_pr\xcc\x8ci\xcc\x81lis\xcc\x8c z",
     92     						NULL,	G_FILE_TYPE_DIRECTORY,	G_FILE_CREATE_NONE, 0, 0, TEST_DELETE_NORMAL | TEST_CREATE},
     93     {"pattern_file",		NULL,	G_FILE_TYPE_REGULAR,	G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_COPY | TEST_OPEN | TEST_APPEND},
     94     {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},
     95     {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},
     96     {"not_exists2",			NULL,	G_FILE_TYPE_REGULAR,	G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_NOT_EXISTS | TEST_CREATE},
     97     {"not_exists3",			NULL,	G_FILE_TYPE_REGULAR,	G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_NOT_EXISTS | TEST_REPLACE},
     98     {"not_exists4",			NULL,	G_FILE_TYPE_REGULAR,	G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_NOT_EXISTS | TEST_APPEND},
     99     {"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},
    100 	{"lost_symlink",		"nowhere",	G_FILE_TYPE_SYMBOLIC_LINK, G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_DELETE_NORMAL | TEST_OPEN | TEST_INVALID_SYMLINK},
    101   };
    102 
    103 static gboolean write_test;
    104 static gboolean verbose;
    105 static gboolean posix_compat;
    106 
    107 #ifdef G_HAVE_ISO_VARARGS
    108 #define log(...) if (verbose)  g_print (__VA_ARGS__)
    109 #elif defined(G_HAVE_GNUC_VARARGS)
    110 #define log(msg...) if (verbose)  g_print (msg)
    111 #else  /* no varargs macros */
    112 static void log (const g_char *format, ...)
    113 {
    114   va_list args;
    115   va_start (args, format);
    116   if (verbose) g_print (format, args);
    117   va_end (args);
    118 }
    119 #endif
    120 
    121 static GFile *
    122 create_empty_file (GFile * parent, const char *filename,
    123 		   GFileCreateFlags create_flags)
    124 {
    125   GFile *child;
    126   gboolean res;
    127   GError *error;
    128   GFileOutputStream *outs;
    129 
    130   child = g_file_get_child (parent, filename);
    131   g_assert (child != NULL);
    132 
    133   error = NULL;
    134   outs = g_file_replace (child, NULL, FALSE, create_flags, NULL, &error);
    135   g_assert_no_error (error);
    136   g_assert (outs != NULL);
    137   error = NULL;
    138   res = g_output_stream_close (G_OUTPUT_STREAM (outs), NULL, &error);
    139   g_object_unref (outs);
    140   return child;
    141 }
    142 
    143 static GFile *
    144 create_empty_dir (GFile * parent, const char *filename)
    145 {
    146   GFile *child;
    147   gboolean res;
    148   GError *error;
    149 
    150   child = g_file_get_child (parent, filename);
    151   g_assert (child != NULL);
    152   error = NULL;
    153   res = g_file_make_directory (child, NULL, &error);
    154   g_assert_cmpint (res, ==, TRUE);
    155   g_assert_no_error (error);
    156   return child;
    157 }
    158 
    159 static GFile *
    160 create_symlink (GFile * parent, const char *filename, const char *points_to)
    161 {
    162   GFile *child;
    163   gboolean res;
    164   GError *error;
    165 
    166   child = g_file_get_child (parent, filename);
    167   g_assert (child != NULL);
    168   error = NULL;
    169   res = g_file_make_symbolic_link (child, points_to, NULL, &error);
    170   g_assert_cmpint (res, ==, TRUE);
    171   g_assert_no_error (error);
    172   return child;
    173 }
    174 
    175 static void
    176 test_create_structure (gconstpointer test_data)
    177 {
    178   GFile *root;
    179   GFile *child;
    180   gboolean res;
    181   GError *error;
    182   GFileOutputStream *outs;
    183   GDataOutputStream *outds;
    184   int i;
    185   struct StructureItem item;
    186 
    187   g_assert (test_data != NULL);
    188   log ("\n  Going to create testing structure in '%s'...\n",
    189        (char *) test_data);
    190 
    191   root = g_file_new_for_commandline_arg ((char *) test_data);
    192   g_assert (root != NULL);
    193 
    194   /*  create root directory  */
    195   res = g_file_make_directory (root, NULL, NULL);
    196   /*  don't care about errors here  */
    197 
    198   /*  create any other items  */
    199   for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
    200     {
    201       item = sample_struct[i];
    202       if ((item.handle_special)
    203 	  || ((!posix_compat)
    204 	      && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK)))
    205 	continue;
    206 
    207       child = NULL;
    208       switch (item.file_type)
    209 	{
    210 	case G_FILE_TYPE_REGULAR:
    211 	  log ("    Creating file '%s'...\n", item.filename);
    212 	  child = create_empty_file (root, item.filename, item.create_flags);
    213 	  break;
    214 	case G_FILE_TYPE_DIRECTORY:
    215 	  log ("    Creating directory '%s'...\n", item.filename);
    216 	  child = create_empty_dir (root, item.filename);
    217 	  break;
    218 	case G_FILE_TYPE_SYMBOLIC_LINK:
    219 	  log ("    Creating symlink '%s' --> '%s'...\n", item.filename,
    220 	       item.link_to);
    221 	  child = create_symlink (root, item.filename, item.link_to);
    222 	  break;
    223 	default:
    224 	  break;
    225 	}
    226       g_assert (child != NULL);
    227 
    228       if ((item.mode > 0) && (posix_compat))
    229 	{
    230 	  error = NULL;
    231 	  res =
    232 	    g_file_set_attribute_uint32 (child, G_FILE_ATTRIBUTE_UNIX_MODE,
    233 					 item.mode,
    234 					 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
    235 					 NULL, &error);
    236 	  g_assert_cmpint (res, ==, TRUE);
    237 	  g_assert_no_error (error);
    238 	}
    239 
    240       g_object_unref (child);
    241     }
    242 
    243   /*  create a pattern file  */
    244   log ("    Creating pattern file...");
    245   child = g_file_get_child (root, "pattern_file");
    246   g_assert (child != NULL);
    247 
    248   error = NULL;
    249   outs =
    250     g_file_replace (child, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error);
    251   g_assert_no_error (error);
    252 
    253   g_assert (outs != NULL);
    254   outds = g_data_output_stream_new (G_OUTPUT_STREAM (outs));
    255   g_assert (outds != NULL);
    256   for (i = 0; i < PATTERN_FILE_SIZE; i++)
    257     {
    258       error = NULL;
    259       res = g_data_output_stream_put_byte (outds, i % 256, NULL, &error);
    260       g_assert_no_error (error);
    261     }
    262   error = NULL;
    263   res = g_output_stream_close (G_OUTPUT_STREAM (outs), NULL, &error);
    264   g_assert_no_error (error);
    265   g_object_unref (outds);
    266   g_object_unref (outs);
    267   g_object_unref (child);
    268   log (" done.\n");
    269 
    270   g_object_unref (root);
    271 }
    272 
    273 static GFile *
    274 file_exists (GFile * parent, const char *filename, gboolean * result)
    275 {
    276   GFile *child;
    277   gboolean res;
    278 
    279   if (result)
    280     *result = FALSE;
    281 
    282   child = g_file_get_child (parent, filename);
    283   g_assert (child != NULL);
    284   res = g_file_query_exists (child, NULL);
    285   if (result)
    286     *result = res;
    287 
    288   return child;
    289 }
    290 
    291 static void
    292 test_attributes (struct StructureItem item, GFileInfo * info)
    293 {
    294   GFileType ftype;
    295   guint32 mode;
    296   const char *name, *display_name, *edit_name, *copy_name, *symlink_target;
    297   gboolean utf8_valid;
    298   gboolean has_attr;
    299   gboolean is_symlink;
    300   gboolean can_read, can_write;
    301 
    302   /*  standard::type  */
    303   has_attr = g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_TYPE);
    304   g_assert_cmpint (has_attr, ==, TRUE);
    305   ftype = g_file_info_get_file_type (info);
    306   g_assert_cmpint (ftype, !=, G_FILE_TYPE_UNKNOWN);
    307   g_assert_cmpint (ftype, ==, item.file_type);
    308 
    309   /*  unix::mode  */
    310   if ((item.mode > 0) && (posix_compat))
    311     {
    312       mode =
    313 	g_file_info_get_attribute_uint32 (info,
    314 					  G_FILE_ATTRIBUTE_UNIX_MODE) & 0xFFF;
    315       g_assert_cmpint (mode, ==, item.mode);
    316     }
    317 
    318   /*  access::can-read  */
    319   if (item.file_type != G_FILE_TYPE_SYMBOLIC_LINK)
    320     {
    321       can_read =
    322 	g_file_info_get_attribute_boolean (info,
    323 					   G_FILE_ATTRIBUTE_ACCESS_CAN_READ);
    324       g_assert_cmpint (can_read, ==, TRUE);
    325     }
    326 
    327   /*  access::can-write  */
    328   if ((write_test) && ((item.extra_flags & TEST_OVERWRITE) == TEST_OVERWRITE))
    329     {
    330       can_write =
    331 	g_file_info_get_attribute_boolean (info,
    332 					   G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE);
    333       g_assert_cmpint (can_write, ==, TRUE);
    334     }
    335 
    336   /*  standard::name  */
    337   name = g_file_info_get_name (info);
    338   g_assert (name != NULL);
    339 
    340   /*  standard::display-name  */
    341   display_name = g_file_info_get_display_name (info);
    342   g_assert (display_name != NULL);
    343   utf8_valid = g_utf8_validate (display_name, -1, NULL);
    344   g_assert_cmpint (utf8_valid, ==, TRUE);
    345 
    346   /*  standard::edit-name  */
    347   edit_name = g_file_info_get_edit_name (info);
    348   if (edit_name)
    349     {
    350       utf8_valid = g_utf8_validate (edit_name, -1, NULL);
    351       g_assert_cmpint (utf8_valid, ==, TRUE);
    352     }
    353 
    354   /*  standard::copy-name  */
    355   copy_name =
    356     g_file_info_get_attribute_string (info,
    357 				      G_FILE_ATTRIBUTE_STANDARD_COPY_NAME);
    358   if (copy_name)
    359     {
    360       utf8_valid = g_utf8_validate (copy_name, -1, NULL);
    361       g_assert_cmpint (utf8_valid, ==, TRUE);
    362     }
    363 
    364   /*  standard::is-symlink  */
    365   if (posix_compat)
    366     {
    367       is_symlink = g_file_info_get_is_symlink (info);
    368       g_assert_cmpint (is_symlink, ==,
    369 		       item.file_type == G_FILE_TYPE_SYMBOLIC_LINK);
    370     }
    371 
    372   /*  standard::symlink-target  */
    373   if ((item.file_type == G_FILE_TYPE_SYMBOLIC_LINK) && (posix_compat))
    374     {
    375       symlink_target = g_file_info_get_symlink_target (info);
    376       g_assert_cmpstr (symlink_target, ==, item.link_to);
    377     }
    378 }
    379 
    380 static void
    381 test_initial_structure (gconstpointer test_data)
    382 {
    383   GFile *root;
    384   GFile *child;
    385   gboolean res;
    386   GError *error;
    387   GFileInputStream *ins;
    388   int i;
    389   GFileInfo *info;
    390   guint32 size;
    391   guchar *buffer;
    392   gssize read, total_read;
    393   struct StructureItem item;
    394 
    395 
    396   g_assert (test_data != NULL);
    397   log ("\n  Testing sample structure in '%s'...\n", (char *) test_data);
    398 
    399   root = g_file_new_for_commandline_arg ((char *) test_data);
    400   g_assert (root != NULL);
    401   res = g_file_query_exists (root, NULL);
    402   g_assert_cmpint (res, ==, TRUE);
    403 
    404   /*  test the structure  */
    405   for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
    406     {
    407       item = sample_struct[i];
    408       if (((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK))
    409 	  || (item.handle_special))
    410 	continue;
    411 
    412       log ("    Testing file '%s'...\n", item.filename);
    413 
    414       child = file_exists (root, item.filename, &res);
    415       g_assert (child != NULL);
    416       g_assert_cmpint (res, ==, TRUE);
    417 
    418       error = NULL;
    419       info =
    420 	g_file_query_info (child, "*", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
    421 			   NULL, &error);
    422       g_assert_no_error (error);
    423       g_assert (info != NULL);
    424 
    425       test_attributes (item, info);
    426 
    427       g_object_unref (child);
    428     }
    429 
    430   /*  read and test the pattern file  */
    431   log ("    Testing pattern file...\n");
    432   child = file_exists (root, "pattern_file", &res);
    433   g_assert (child != NULL);
    434   g_assert_cmpint (res, ==, TRUE);
    435 
    436   error = NULL;
    437   info =
    438     g_file_query_info (child, "*", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL,
    439 		       &error);
    440   g_assert_no_error (error);
    441   g_assert (info != NULL);
    442   size = g_file_info_get_size (info);
    443   g_assert_cmpint (size, ==, PATTERN_FILE_SIZE);
    444 
    445   error = NULL;
    446   ins = g_file_read (child, NULL, &error);
    447   g_assert (ins != NULL);
    448   g_assert_no_error (error);
    449 
    450   buffer = g_malloc (PATTERN_FILE_SIZE);
    451   total_read = 0;
    452 
    453   while (total_read < PATTERN_FILE_SIZE)
    454     {
    455       error = NULL;
    456       read =
    457 	g_input_stream_read (G_INPUT_STREAM (ins), buffer + total_read,
    458 			     PATTERN_FILE_SIZE, NULL, &error);
    459       g_assert_no_error (error);
    460       total_read += read;
    461       log ("      read %d bytes, total = %d of %d.\n", read, total_read,
    462 	   PATTERN_FILE_SIZE);
    463     }
    464   g_assert_cmpint (total_read, ==, PATTERN_FILE_SIZE);
    465 
    466   error = NULL;
    467   res = g_input_stream_close (G_INPUT_STREAM (ins), NULL, &error);
    468   g_assert_no_error (error);
    469   g_assert_cmpint (res, ==, TRUE);
    470 
    471   for (i = 0; i < PATTERN_FILE_SIZE; i++)
    472     g_assert_cmpint (*(buffer + i), ==, i % 256);
    473 
    474   g_object_unref (ins);
    475   g_object_unref (child);
    476   g_free (buffer);
    477   g_object_unref (root);
    478 }
    479 
    480 static void
    481 traverse_recurse_dirs (GFile * parent, GFile * root)
    482 {
    483   gboolean res;
    484   GError *error;
    485   GFileEnumerator *enumerator;
    486   GFileInfo *info;
    487   GFile *descend;
    488   char *relative_path;
    489   int i;
    490   gboolean found;
    491 
    492   g_assert (root != NULL);
    493 
    494   error = NULL;
    495   enumerator =
    496     g_file_enumerate_children (parent, "*",
    497 			       G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL,
    498 			       &error);
    499   g_assert (enumerator != NULL);
    500   g_assert_no_error (error);
    501 
    502   error = NULL;
    503   info = g_file_enumerator_next_file (enumerator, NULL, &error);
    504   while ((info) && (!error))
    505     {
    506       descend = g_file_get_child (parent, g_file_info_get_name (info));
    507       g_assert (descend != NULL);
    508       relative_path = g_file_get_relative_path (root, descend);
    509       g_assert (relative_path != NULL);
    510 
    511       found = FALSE;
    512       for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
    513 	{
    514 	  if (strcmp (sample_struct[i].filename, relative_path) == 0)
    515 	    {
    516 	      /*  test the attributes again  */
    517 	      test_attributes (sample_struct[i], info);
    518 
    519 	      found = TRUE;
    520 	      break;
    521 	    }
    522 	}
    523       g_assert_cmpint (found, ==, TRUE);
    524 
    525       log ("  Found file %s, relative to root: %s\n",
    526 	   g_file_info_get_display_name (info), relative_path);
    527 
    528       if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
    529 	traverse_recurse_dirs (descend, root);
    530 
    531       g_object_unref (descend);
    532       error = NULL;
    533       info = g_file_enumerator_next_file (enumerator, NULL, &error);
    534     }
    535   g_assert_no_error (error);
    536 
    537   error = NULL;
    538   res = g_file_enumerator_close (enumerator, NULL, &error);
    539   g_assert_cmpint (res, ==, TRUE);
    540   g_assert_no_error (error);
    541 }
    542 
    543 static void
    544 test_traverse_structure (gconstpointer test_data)
    545 {
    546   GFile *root;
    547   gboolean res;
    548 
    549   g_assert (test_data != NULL);
    550   log ("\n  Traversing through the sample structure in '%s'...\n",
    551        (char *) test_data);
    552 
    553   root = g_file_new_for_commandline_arg ((char *) test_data);
    554   g_assert (root != NULL);
    555   res = g_file_query_exists (root, NULL);
    556   g_assert_cmpint (res, ==, TRUE);
    557 
    558   traverse_recurse_dirs (root, root);
    559 
    560   g_object_unref (root);
    561 }
    562 
    563 
    564 
    565 
    566 static void
    567 test_enumerate (gconstpointer test_data)
    568 {
    569   GFile *root, *child;
    570   gboolean res;
    571   GError *error;
    572   GFileEnumerator *enumerator;
    573   GFileInfo *info;
    574   int i;
    575   struct StructureItem item;
    576 
    577 
    578   g_assert (test_data != NULL);
    579   log ("\n  Test enumerate '%s'...\n", (char *) test_data);
    580 
    581   root = g_file_new_for_commandline_arg ((char *) test_data);
    582   g_assert (root != NULL);
    583   res = g_file_query_exists (root, NULL);
    584   g_assert_cmpint (res, ==, TRUE);
    585 
    586 
    587   for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
    588     {
    589       item = sample_struct[i];
    590       if ((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK))
    591 	continue;
    592 
    593       if (((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS) ||
    594 	  (((item.extra_flags & TEST_NO_ACCESS) == TEST_NO_ACCESS)
    595 	   && posix_compat)
    596 	  || ((item.extra_flags & TEST_ENUMERATE_FILE) ==
    597 	      TEST_ENUMERATE_FILE))
    598 	{
    599 	  log ("    Testing file '%s'\n", item.filename);
    600 	  child = g_file_get_child (root, item.filename);
    601 	  g_assert (child != NULL);
    602 	  error = NULL;
    603 	  enumerator =
    604 	    g_file_enumerate_children (child, "*",
    605 				       G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
    606 				       NULL, &error);
    607 
    608 	  if ((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS)
    609 	    {
    610 	      g_assert (enumerator == NULL);
    611 	      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
    612 	    }
    613 	  if ((item.extra_flags & TEST_ENUMERATE_FILE) == TEST_ENUMERATE_FILE)
    614 	    {
    615 	      g_assert (enumerator == NULL);
    616 	      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY);
    617 	    }
    618 	  if ((item.extra_flags & TEST_NO_ACCESS) == TEST_NO_ACCESS)
    619 	    {
    620 	      g_assert (enumerator != NULL);
    621 
    622 	      error = NULL;
    623 	      info = g_file_enumerator_next_file (enumerator, NULL, &error);
    624 	      g_assert (info == NULL);
    625 	      g_assert_no_error (error);
    626 	      /*  no items should be found, no error should be logged  */
    627 	    }
    628 
    629 	  if (error)
    630 	    g_error_free (error);
    631 
    632 	  if (enumerator)
    633 	    {
    634 	      error = NULL;
    635 	      res = g_file_enumerator_close (enumerator, NULL, &error);
    636 	      g_assert_cmpint (res, ==, TRUE);
    637 	      g_assert_no_error (error);
    638 	    }
    639 	  g_object_unref (child);
    640 	}
    641     }
    642   g_object_unref (root);
    643 }
    644 
    645 static void
    646 do_copy_move (GFile * root, struct StructureItem item, const char *target_dir,
    647 	      enum StructureExtraFlags extra_flags)
    648 {
    649   GFile *dst_dir, *src_file, *dst_file;
    650   gboolean res;
    651   GError *error;
    652 
    653   log ("    do_copy_move: '%s' --> '%s'\n", item.filename, target_dir);
    654 
    655   dst_dir = g_file_get_child (root, target_dir);
    656   g_assert (dst_dir != NULL);
    657   src_file = g_file_get_child (root, item.filename);
    658   g_assert (src_file != NULL);
    659   dst_file = g_file_get_child (dst_dir, item.filename);
    660   g_assert (dst_file != NULL);
    661 
    662   error = NULL;
    663   if ((item.extra_flags & TEST_COPY) == TEST_COPY)
    664     res =
    665       g_file_copy (src_file, dst_file,
    666 		   G_FILE_COPY_NOFOLLOW_SYMLINKS |
    667 		   ((extra_flags ==
    668 		     TEST_OVERWRITE) ? G_FILE_COPY_OVERWRITE :
    669 		    G_FILE_COPY_NONE), NULL, NULL, NULL, &error);
    670   else
    671     res =
    672       g_file_move (src_file, dst_file, G_FILE_COPY_NOFOLLOW_SYMLINKS, NULL,
    673 		   NULL, NULL, &error);
    674 
    675   if (error)
    676     log ("       res = %d, error code %d = %s\n", res, error->code,
    677 	 error->message);
    678 
    679   /*  copying file/directory to itself (".")  */
    680   if (((item.extra_flags & TEST_NOT_EXISTS) != TEST_NOT_EXISTS) &&
    681       (extra_flags == TEST_ALREADY_EXISTS))
    682     {
    683       g_assert_cmpint (res, ==, FALSE);
    684       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS);
    685     }
    686   /*  target file is a file, overwrite is not set  */
    687   else if (((item.extra_flags & TEST_NOT_EXISTS) != TEST_NOT_EXISTS) &&
    688 	   (extra_flags == TEST_TARGET_IS_FILE))
    689     {
    690       g_assert_cmpint (res, ==, FALSE);
    691       if (item.file_type == G_FILE_TYPE_DIRECTORY)
    692 	g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_RECURSE);
    693       else
    694 	g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY);
    695     }
    696   /*  source file is directory  */
    697   else if ((item.extra_flags & TEST_COPY_ERROR_RECURSE) ==
    698 	   TEST_COPY_ERROR_RECURSE)
    699     {
    700       g_assert_cmpint (res, ==, FALSE);
    701       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_RECURSE);
    702     }
    703   /*  source or target path doesn't exist  */
    704   else if (((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS) ||
    705 	   (extra_flags == TEST_NOT_EXISTS))
    706     {
    707       g_assert_cmpint (res, ==, FALSE);
    708       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
    709     }
    710   /*  source or target path permission denied  */
    711   else if (((item.extra_flags & TEST_NO_ACCESS) == TEST_NO_ACCESS) ||
    712 	   (extra_flags == TEST_NO_ACCESS))
    713     {
    714       g_assert_cmpint (res, ==, FALSE);
    715       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED);
    716     }
    717   /*  no error should be found, all exceptions defined above  */
    718   else
    719     {
    720       g_assert_cmpint (res, ==, TRUE);
    721       g_assert_no_error (error);
    722     }
    723 
    724   if (error)
    725     g_error_free (error);
    726 
    727 
    728   g_object_unref (dst_dir);
    729   g_object_unref (src_file);
    730   g_object_unref (dst_file);
    731 }
    732 
    733 static void
    734 test_copy_move (gconstpointer test_data)
    735 {
    736   GFile *root;
    737   gboolean res;
    738   int i;
    739   struct StructureItem item;
    740 
    741   log ("\n");
    742 
    743   g_assert (test_data != NULL);
    744   root = g_file_new_for_commandline_arg ((char *) test_data);
    745   g_assert (root != NULL);
    746   res = g_file_query_exists (root, NULL);
    747   g_assert_cmpint (res, ==, TRUE);
    748 
    749 
    750   for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
    751     {
    752       item = sample_struct[i];
    753 
    754       if ((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK))
    755 	continue;
    756 
    757       if (((item.extra_flags & TEST_COPY) == TEST_COPY) ||
    758 	  ((item.extra_flags & TEST_MOVE) == TEST_MOVE))
    759 	{
    760 	  /*  test copy/move to a directory, expecting no errors if source files exist  */
    761 	  do_copy_move (root, item, TEST_DIR_TARGET, 0);
    762 
    763 	  /*  some files have been already moved so we can't count with them in the tests  */
    764 	  if ((item.extra_flags & TEST_COPY) == TEST_COPY)
    765 	    {
    766 	      /*  test overwrite for flagged files  */
    767 	      if ((item.extra_flags & TEST_OVERWRITE) == TEST_OVERWRITE)
    768 		{
    769 		  do_copy_move (root, item, TEST_DIR_TARGET, TEST_OVERWRITE);
    770 		}
    771 	      /*  source = target, should return G_IO_ERROR_EXISTS  */
    772 	      do_copy_move (root, item, ".", TEST_ALREADY_EXISTS);
    773 	      /*  target is file  */
    774 	      do_copy_move (root, item, TEST_TARGET_FILE,
    775 			    TEST_TARGET_IS_FILE);
    776 	      /*  target path is invalid  */
    777 	      do_copy_move (root, item, TEST_NAME_NOT_EXISTS,
    778 			    TEST_NOT_EXISTS);
    779 
    780 	      /*  tests on POSIX-compatible filesystems  */
    781 	      if (posix_compat)
    782 		{
    783 		  /*  target directory is not accessible (no execute flag)  */
    784 		  do_copy_move (root, item, TEST_DIR_NO_ACCESS,
    785 				TEST_NO_ACCESS);
    786 		  /*  target directory is readonly  */
    787 		  do_copy_move (root, item, TEST_DIR_NO_WRITE,
    788 				TEST_NO_ACCESS);
    789 		}
    790 	    }
    791 	}
    792     }
    793   g_object_unref (root);
    794 }
    795 
    796 static void
    797 test_create (gconstpointer test_data)
    798 {
    799   GFile *root, *child;
    800   gboolean res;
    801   GError *error;
    802   int i;
    803   struct StructureItem item;
    804   GFileOutputStream *os;
    805 
    806   g_assert (test_data != NULL);
    807   log ("\n");
    808 
    809   root = g_file_new_for_commandline_arg ((char *) test_data);
    810   g_assert (root != NULL);
    811   res = g_file_query_exists (root, NULL);
    812   g_assert_cmpint (res, ==, TRUE);
    813 
    814   for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
    815     {
    816       item = sample_struct[i];
    817 
    818       if (((item.extra_flags & TEST_CREATE) == TEST_CREATE) ||
    819 	  ((item.extra_flags & TEST_REPLACE) == TEST_REPLACE) ||
    820 	  ((item.extra_flags & TEST_APPEND) == TEST_APPEND))
    821 	{
    822 	  log ("  test_create: '%s'\n", item.filename);
    823 
    824 	  child = g_file_get_child (root, item.filename);
    825 	  g_assert (child != NULL);
    826 	  error = NULL;
    827 	  os = NULL;
    828 
    829 	  if ((item.extra_flags & TEST_CREATE) == TEST_CREATE)
    830 	    os = g_file_create (child, item.create_flags, NULL, &error);
    831 	  else if ((item.extra_flags & TEST_REPLACE) == TEST_REPLACE)
    832 	    os =
    833 	      g_file_replace (child, NULL, TRUE, item.create_flags, NULL,
    834 			      &error);
    835 	  else if ((item.extra_flags & TEST_APPEND) == TEST_APPEND)
    836 	    os = g_file_append_to (child, item.create_flags, NULL, &error);
    837 
    838 
    839 	  if (error)
    840 	    log ("       error code %d = %s\n", error->code, error->message);
    841 
    842 	  if (((item.extra_flags & TEST_NOT_EXISTS) == 0) &&
    843 	      ((item.extra_flags & TEST_CREATE) == TEST_CREATE))
    844 	    {
    845 	      g_assert (os == NULL);
    846 	      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS);
    847 	    }
    848 	  else if (item.file_type == G_FILE_TYPE_DIRECTORY)
    849 	    {
    850 	      g_assert (os == NULL);
    851 	      if ((item.extra_flags & TEST_CREATE) == TEST_CREATE)
    852 		g_assert_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS);
    853 	      else
    854 		g_assert_error (error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY);
    855 	    }
    856 	  else
    857 	    {
    858 	      g_assert (os != NULL);
    859 	      g_assert_no_error (error);
    860 	    }
    861 
    862 	  if (error)
    863 	    g_error_free (error);
    864 
    865 	  if (os)
    866 	    {
    867 	      error = NULL;
    868 	      res =
    869 		g_output_stream_close (G_OUTPUT_STREAM (os), NULL, &error);
    870 	      if (error)
    871 		log ("         g_output_stream_close: error %d = %s\n",
    872 		     error->code, error->message);
    873 	      g_assert_cmpint (res, ==, TRUE);
    874 	      g_assert_no_error (error);
    875 	    }
    876 	  g_object_unref (child);
    877 	}
    878     }
    879   g_object_unref (root);
    880 }
    881 
    882 static void
    883 test_open (gconstpointer test_data)
    884 {
    885   GFile *root, *child;
    886   gboolean res;
    887   GError *error;
    888   int i;
    889   struct StructureItem item;
    890   GFileInputStream *input_stream;
    891 
    892   g_assert (test_data != NULL);
    893   log ("\n");
    894 
    895   root = g_file_new_for_commandline_arg ((char *) test_data);
    896   g_assert (root != NULL);
    897   res = g_file_query_exists (root, NULL);
    898   g_assert_cmpint (res, ==, TRUE);
    899 
    900   for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
    901     {
    902       item = sample_struct[i];
    903 
    904       if ((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK))
    905 	continue;
    906 
    907       if ((item.extra_flags & TEST_OPEN) == TEST_OPEN)
    908 	{
    909 	  log ("  test_open: '%s'\n", item.filename);
    910 
    911 	  child = g_file_get_child (root, item.filename);
    912 	  g_assert (child != NULL);
    913 	  error = NULL;
    914 	  input_stream = g_file_read (child, NULL, &error);
    915 
    916 	  if (((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS) ||
    917 	      ((item.extra_flags & TEST_INVALID_SYMLINK) ==
    918 	       TEST_INVALID_SYMLINK))
    919 	    {
    920 	      g_assert (input_stream == NULL);
    921 	      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
    922 	    }
    923 	  else if (item.file_type == G_FILE_TYPE_DIRECTORY)
    924 	    {
    925 	      g_assert (input_stream == NULL);
    926 	      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY);
    927 	    }
    928 	  else
    929 	    {
    930 	      g_assert (input_stream != NULL);
    931 	      g_assert_no_error (error);
    932 	    }
    933 
    934 	  if (error)
    935 	    g_error_free (error);
    936 
    937 	  if (input_stream)
    938 	    {
    939 	      error = NULL;
    940 	      res =
    941 		g_input_stream_close (G_INPUT_STREAM (input_stream), NULL,
    942 				      &error);
    943 	      g_assert_cmpint (res, ==, TRUE);
    944 	      g_assert_no_error (error);
    945 	    }
    946 	  g_object_unref (child);
    947 	}
    948     }
    949   g_object_unref (root);
    950 }
    951 
    952 static void
    953 test_delete (gconstpointer test_data)
    954 {
    955   GFile *root;
    956   GFile *child;
    957   gboolean res;
    958   GError *error;
    959   int i;
    960   struct StructureItem item;
    961 
    962   g_assert (test_data != NULL);
    963   log ("\n");
    964 
    965   root = g_file_new_for_commandline_arg ((char *) test_data);
    966   g_assert (root != NULL);
    967   res = g_file_query_exists (root, NULL);
    968   g_assert_cmpint (res, ==, TRUE);
    969 
    970   for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
    971     {
    972       item = sample_struct[i];
    973 
    974       if ((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK))
    975 	continue;
    976 
    977       if (((item.extra_flags & TEST_DELETE_NORMAL) == TEST_DELETE_NORMAL) ||
    978 	  ((item.extra_flags & TEST_DELETE_TRASH) == TEST_DELETE_TRASH))
    979 	{
    980 	  child = file_exists (root, item.filename, &res);
    981 	  g_assert (child != NULL);
    982 	  /*  we don't care about result here  */
    983 
    984 	  log ("  Deleting %s, path = %s\n", item.filename,
    985 	       g_file_get_path (child));
    986 	  error = NULL;
    987 	  if ((item.extra_flags & TEST_DELETE_NORMAL) == TEST_DELETE_NORMAL)
    988 	    res = g_file_delete (child, NULL, &error);
    989 	  else
    990 	    res = g_file_trash (child, NULL, &error);
    991 
    992 	  if ((item.extra_flags & TEST_DELETE_NON_EMPTY) ==
    993 	      TEST_DELETE_NON_EMPTY)
    994 	    {
    995 	      g_assert_cmpint (res, ==, FALSE);
    996 	      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_EMPTY);
    997 	    }
    998 	  if ((item.extra_flags & TEST_DELETE_FAILURE) == TEST_DELETE_FAILURE)
    999 	    {
   1000 	      g_assert_cmpint (res, ==, FALSE);
   1001 	      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
   1002 	    }
   1003 	  if ((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS)
   1004 	    {
   1005 	      g_assert_cmpint (res, ==, FALSE);
   1006 	      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
   1007 	    }
   1008 
   1009 	  if (error)
   1010 	    {
   1011 	      log ("      result = %d, error = %s\n", res, error->message);
   1012 	      g_error_free (error);
   1013 	    }
   1014 
   1015 	  g_object_unref (child);
   1016 	}
   1017     }
   1018   g_object_unref (root);
   1019 }
   1020 
   1021 
   1022 static void
   1023 cleanup_dir_recurse (GFile *parent, GFile *root)
   1024 {
   1025   gboolean res;
   1026   GError *error;
   1027   GFileEnumerator *enumerator;
   1028   GFileInfo *info;
   1029   GFile *descend;
   1030   char *relative_path;
   1031 
   1032   g_assert (root != NULL);
   1033 
   1034   error = NULL;
   1035   enumerator =
   1036     g_file_enumerate_children (parent, "*",
   1037 			       G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL,
   1038 			       &error);
   1039   if (! enumerator)
   1040 	  return;
   1041 
   1042   error = NULL;
   1043   info = g_file_enumerator_next_file (enumerator, NULL, &error);
   1044   while ((info) && (!error))
   1045     {
   1046       descend = g_file_get_child (parent, g_file_info_get_name (info));
   1047       g_assert (descend != NULL);
   1048       relative_path = g_file_get_relative_path (root, descend);
   1049       g_assert (relative_path != NULL);
   1050 
   1051       log ("    deleting '%s'\n", g_file_info_get_display_name (info));
   1052 
   1053       if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
   1054     	  cleanup_dir_recurse (descend, root);
   1055 
   1056       error = NULL;
   1057       res = g_file_delete (descend, NULL, &error);
   1058       g_assert_cmpint (res, ==, TRUE);
   1059 
   1060       g_object_unref (descend);
   1061       error = NULL;
   1062       info = g_file_enumerator_next_file (enumerator, NULL, &error);
   1063     }
   1064   g_assert_no_error (error);
   1065 
   1066   error = NULL;
   1067   res = g_file_enumerator_close (enumerator, NULL, &error);
   1068   g_assert_cmpint (res, ==, TRUE);
   1069   g_assert_no_error (error);
   1070 }
   1071 
   1072 static void
   1073 prep_clean_structure (gconstpointer test_data)
   1074 {
   1075   GFile *root;
   1076 
   1077   g_assert (test_data != NULL);
   1078   log ("\n  Cleaning target testing structure in '%s'...\n",
   1079        (char *) test_data);
   1080 
   1081   root = g_file_new_for_commandline_arg ((char *) test_data);
   1082   g_assert (root != NULL);
   1083 
   1084   cleanup_dir_recurse (root, root);
   1085 
   1086   g_file_delete (root, NULL, NULL);
   1087 
   1088   g_object_unref (root);
   1089 }
   1090 
   1091 int
   1092 main (int argc, char *argv[])
   1093 {
   1094   static gboolean only_create_struct;
   1095   static char *target_path;
   1096   GError *error;
   1097   GOptionContext *context;
   1098 
   1099   static GOptionEntry cmd_entries[] = {
   1100     {"read-write", 'w', 0, G_OPTION_ARG_NONE, &write_test,
   1101      "Perform write tests (incl. structure creation)", NULL},
   1102     {"create-struct", 'c', 0, G_OPTION_ARG_NONE, &only_create_struct,
   1103      "Only create testing structure (no tests)", NULL},
   1104     {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Be verbose", NULL},
   1105     {"posix", 'x', 0, G_OPTION_ARG_NONE, &posix_compat,
   1106      "Test POSIX-specific features (unix permissions, symlinks)", NULL},
   1107     {NULL}
   1108   };
   1109 
   1110   verbose = FALSE;
   1111   write_test = FALSE;
   1112   only_create_struct = FALSE;
   1113   target_path = NULL;
   1114   posix_compat = FALSE;
   1115 
   1116   /*  strip all gtester-specific args  */
   1117   g_type_init ();
   1118   g_test_init (&argc, &argv, NULL);
   1119 
   1120   /*  no extra parameters specified, assume we're executed from glib test suite  */
   1121   if (argc < 2)
   1122     {
   1123 	  verbose = TRUE;
   1124 	  write_test = TRUE;
   1125 	  only_create_struct = FALSE;
   1126 	  target_path = DEFAULT_TEST_DIR;
   1127 #ifdef G_PLATFORM_WIN32
   1128 	  posix_compat = FALSE;
   1129 #else
   1130 	  posix_compat = TRUE;
   1131 #endif
   1132     }
   1133 
   1134   /*  add trailing args  */
   1135   error = NULL;
   1136   context = g_option_context_new ("target_path");
   1137   g_option_context_add_main_entries (context, cmd_entries, NULL);
   1138   if (!g_option_context_parse (context, &argc, &argv, &error))
   1139     {
   1140       g_print ("option parsing failed: %s\n", error->message);
   1141       return g_test_run ();
   1142     }
   1143 
   1144   /*  remaining arg should is the target path; we don't care of the extra args here  */
   1145   if (argc >= 2)
   1146     target_path = strdup (argv[1]);
   1147 
   1148   if (! target_path)
   1149     {
   1150       g_print ("error: target path was not specified\n");
   1151       g_print ("%s", g_option_context_get_help (context, TRUE, NULL));
   1152       return g_test_run ();
   1153     }
   1154 
   1155 
   1156   /*  Write test - clean target directory first  */
   1157   /*    this can be also considered as a test - enumerate + delete  */
   1158   if (write_test || only_create_struct)
   1159     g_test_add_data_func ("/live-g-file/prep_clean_structure", target_path,
   1160     	  	  prep_clean_structure);
   1161 
   1162   /*  Write test - create new testing structure  */
   1163   if (write_test || only_create_struct)
   1164     g_test_add_data_func ("/live-g-file/create_structure", target_path,
   1165 			  test_create_structure);
   1166 
   1167   /*  Read test - test the sample structure - expect defined attributes to be there  */
   1168   if (!only_create_struct)
   1169     g_test_add_data_func ("/live-g-file/test_initial_structure", target_path,
   1170 			  test_initial_structure);
   1171 
   1172   /*  Read test - test traverse the structure - no special file should appear  */
   1173   if (!only_create_struct)
   1174     g_test_add_data_func ("/live-g-file/test_traverse_structure", target_path,
   1175 			  test_traverse_structure);
   1176 
   1177   /*  Read test - enumerate  */
   1178   if (!only_create_struct)
   1179     g_test_add_data_func ("/live-g-file/test_enumerate", target_path,
   1180 			  test_enumerate);
   1181 
   1182   /*  Read test - open (g_file_read())  */
   1183   if (!only_create_struct)
   1184     g_test_add_data_func ("/live-g-file/test_open", target_path, test_open);
   1185 
   1186   /*  Write test - create  */
   1187   if (write_test && (!only_create_struct))
   1188     g_test_add_data_func ("/live-g-file/test_create", target_path,
   1189 			  test_create);
   1190 
   1191   /*  Write test - copy, move  */
   1192   if (write_test && (!only_create_struct))
   1193     g_test_add_data_func ("/live-g-file/test_copy_move", target_path,
   1194 			  test_copy_move);
   1195 
   1196   /*  Write test - delete, trash  */
   1197   if (write_test && (!only_create_struct))
   1198     g_test_add_data_func ("/live-g-file/test_delete", target_path,
   1199 			  test_delete);
   1200 
   1201   if (write_test || only_create_struct)
   1202     g_test_add_data_func ("/live-g-file/final_clean", target_path,
   1203     	  	  prep_clean_structure);
   1204 
   1205   return g_test_run ();
   1206 
   1207 }
   1208