Install all test data
[platform/upstream/glib.git] / gio / tests / live-g-file.c
index 84e46a1..6edc99a 100644 (file)
@@ -23,6 +23,7 @@
 #include <glib/glib.h>
 #include <gio/gio.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <string.h>
@@ -53,6 +54,8 @@ enum StructureExtraFlags
   TEST_OPEN = 1 << 15,
   TEST_OVERWRITE = 1 << 16,
   TEST_INVALID_SYMLINK = 1 << 17,
+  TEST_HIDDEN = 1 << 18,
+  TEST_DOT_HIDDEN = 1 << 19,
 };
 
 struct StructureItem
@@ -100,6 +103,11 @@ static const struct StructureItem sample_struct[] = {
     {"not_exists4",                    NULL,   G_FILE_TYPE_REGULAR,    G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_NOT_EXISTS | TEST_APPEND},
     {"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},
        {"lost_symlink",                "nowhere",      G_FILE_TYPE_SYMBOLIC_LINK, G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_DELETE_NORMAL | TEST_OPEN | TEST_INVALID_SYMLINK},
+    {"dir_hidden",             NULL,   G_FILE_TYPE_DIRECTORY,  G_FILE_CREATE_NONE, 0, 0, 0},
+    {"dir_hidden/.hidden",             NULL,   G_FILE_TYPE_REGULAR,    G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, 0},
+    {"dir_hidden/.a-hidden-file",      NULL,   G_FILE_TYPE_REGULAR,    G_FILE_CREATE_NONE, 0, 0, TEST_HIDDEN},
+    {"dir_hidden/file-in-.hidden1",    NULL,   G_FILE_TYPE_REGULAR,    G_FILE_CREATE_NONE, 0, 0, TEST_HIDDEN | TEST_DOT_HIDDEN},
+    {"dir_hidden/file-in-.hidden2",    NULL,   G_FILE_TYPE_REGULAR,    G_FILE_CREATE_NONE, 0, 0, TEST_HIDDEN | TEST_DOT_HIDDEN},
   };
 
 static gboolean test_suite;
@@ -243,6 +251,24 @@ test_create_structure (gconstpointer test_data)
          g_assert_no_error (error);
        }
 
+      if ((item.extra_flags & TEST_DOT_HIDDEN) == TEST_DOT_HIDDEN)
+       {
+         gchar *dir, *path, *basename;
+         FILE *f;
+
+         dir = g_path_get_dirname (item.filename);
+         basename = g_path_get_basename (item.filename);
+         path = g_build_filename (test_data, dir, ".hidden", NULL);
+
+         f = fopen (path, "a");
+         fprintf (f, "%s\n", basename);
+         fclose (f);
+
+         g_free (dir);
+         g_free (path);
+         g_free (basename);
+       }
+
       g_object_unref (child);
     }
 
@@ -303,6 +329,7 @@ test_attributes (struct StructureItem item, GFileInfo * info)
   gboolean utf8_valid;
   gboolean has_attr;
   gboolean is_symlink;
+  gboolean is_hidden;
   gboolean can_read, can_write;
 
   /*  standard::type  */
@@ -381,6 +408,15 @@ test_attributes (struct StructureItem item, GFileInfo * info)
       symlink_target = g_file_info_get_symlink_target (info);
       g_assert_cmpstr (symlink_target, ==, item.link_to);
     }
+
+  /*  standard::is-hidden  */
+  if ((item.extra_flags & TEST_HIDDEN) == TEST_HIDDEN)
+    {
+      is_hidden =
+       g_file_info_get_attribute_boolean (info,
+                                          G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN);
+      g_assert_cmpint (is_hidden, ==, TRUE);
+    }
 }
 
 static void
@@ -431,6 +467,7 @@ test_initial_structure (gconstpointer test_data)
       test_attributes (item, info);
 
       g_object_unref (child);
+      g_object_unref (info);
     }
 
   /*  read and test the pattern file  */
@@ -447,6 +484,7 @@ test_initial_structure (gconstpointer test_data)
   g_assert (info != NULL);
   size = g_file_info_get_size (info);
   g_assert_cmpint (size, ==, PATTERN_FILE_SIZE);
+  g_object_unref (info);
 
   error = NULL;
   ins = g_file_read (child, NULL, &error);
@@ -511,7 +549,7 @@ traverse_recurse_dirs (GFile * parent, GFile * root)
   info = g_file_enumerator_next_file (enumerator, NULL, &error);
   while ((info) && (!error))
     {
-      descend = g_file_get_child (parent, g_file_info_get_name (info));
+      descend = g_file_enumerator_get_child (enumerator, info);
       g_assert (descend != NULL);
       relative_path = g_file_get_relative_path (root, descend);
       g_assert (relative_path != NULL);
@@ -538,6 +576,9 @@ traverse_recurse_dirs (GFile * parent, GFile * root)
 
       g_object_unref (descend);
       error = NULL;
+      g_object_unref (info);
+      g_free (relative_path);
+
       info = g_file_enumerator_next_file (enumerator, NULL, &error);
     }
   g_assert_no_error (error);
@@ -891,6 +932,7 @@ test_create (gconstpointer test_data)
                     error->code, error->message);
              g_assert_cmpint (res, ==, TRUE);
              g_assert_no_error (error);
+              g_object_unref (os);
            }
          g_object_unref (child);
        }
@@ -961,6 +1003,7 @@ test_open (gconstpointer test_data)
                                      &error);
              g_assert_cmpint (res, ==, TRUE);
              g_assert_no_error (error);
+              g_object_unref (input_stream);
            }
          g_object_unref (child);
        }
@@ -977,6 +1020,7 @@ test_delete (gconstpointer test_data)
   GError *error;
   guint i;
   struct StructureItem item;
+  gchar *path;
 
   g_assert (test_data != NULL);
   log ("\n");
@@ -1000,8 +1044,10 @@ test_delete (gconstpointer test_data)
          g_assert (child != NULL);
          /*  we don't care about result here  */
 
-         log ("  Deleting %s, path = %s\n", item.filename,
-              g_file_get_path (child));
+          path = g_file_get_path (child);
+         log ("  Deleting %s, path = %s\n", item.filename, path);
+          g_free (path);
+
          error = NULL;
          if ((item.extra_flags & TEST_DELETE_NORMAL) == TEST_DELETE_NORMAL)
            res = g_file_delete (child, NULL, &error);
@@ -1037,6 +1083,94 @@ test_delete (gconstpointer test_data)
   g_object_unref (root);
 }
 
+static void
+test_make_directory_with_parents (gconstpointer test_data)
+{
+  GFile *root, *child, *grandchild, *greatgrandchild;
+  gboolean res;
+  GError *error = NULL;
+
+  g_assert (test_data != NULL);
+
+  root = g_file_new_for_commandline_arg ((char *) test_data);
+  g_assert (root != NULL);
+  res = g_file_query_exists (root, NULL);
+  g_assert_cmpint (res, ==, TRUE);
+
+  child = g_file_get_child (root, "a");
+  grandchild = g_file_get_child (child, "b");
+  greatgrandchild = g_file_get_child (grandchild, "c");
+
+  /* Check that we can successfully make directory hierarchies of
+   * depth 1, 2, or 3
+   */
+  res = g_file_make_directory_with_parents (child, NULL, &error);
+  g_assert_cmpint (res, ==, TRUE);
+  g_assert_no_error (error);
+  res = g_file_query_exists (child, NULL);
+  g_assert_cmpint (res, ==, TRUE);
+
+  g_file_delete (child, NULL, NULL);
+
+  res = g_file_make_directory_with_parents (grandchild, NULL, &error);
+  g_assert_cmpint (res, ==, TRUE);
+  g_assert_no_error (error);
+  res = g_file_query_exists (grandchild, NULL);
+  g_assert_cmpint (res, ==, TRUE);
+
+  g_file_delete (grandchild, NULL, NULL);
+  g_file_delete (child, NULL, NULL);
+
+  res = g_file_make_directory_with_parents (greatgrandchild, NULL, &error);
+  g_assert_cmpint (res, ==, TRUE);
+  g_assert_no_error (error);
+  res = g_file_query_exists (greatgrandchild, NULL);
+  g_assert_cmpint (res, ==, TRUE);
+
+  g_file_delete (greatgrandchild, NULL, NULL);
+  g_file_delete (grandchild, NULL, NULL);
+  g_file_delete (child, NULL, NULL);
+
+  /* Now test failure by trying to create a directory hierarchy
+   * where a ancestor exists but is read-only
+   */
+
+  /* No obvious way to do this on Windows */
+  if (!posix_compat)
+    goto out;
+
+#ifndef G_PLATFORM_WIN32
+  if (getuid() == 0) /* permissions are ignored for root */
+    goto out;
+#endif
+
+  g_file_make_directory (child, NULL, NULL);
+  g_assert_cmpint (res, ==, TRUE);
+
+  res = g_file_set_attribute_uint32 (child,
+                                     G_FILE_ATTRIBUTE_UNIX_MODE,
+                                     S_IRUSR + S_IXUSR, /* -r-x------ */
+                                     G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+                                     NULL, NULL);
+  g_assert_cmpint (res, ==, TRUE);
+
+  res = g_file_make_directory_with_parents (grandchild, NULL, &error);
+  g_assert_cmpint (res, ==, FALSE);
+  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED);
+  g_clear_error (&error);
+
+  res = g_file_make_directory_with_parents (greatgrandchild, NULL, &error);
+  g_assert_cmpint (res, ==, FALSE);
+  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED);
+  g_clear_error (&error);
+
+out:
+  g_object_unref (greatgrandchild);
+  g_object_unref (grandchild);
+  g_object_unref (child);
+  g_object_unref (root);
+}
+
 
 static void
 cleanup_dir_recurse (GFile *parent, GFile *root)
@@ -1050,11 +1184,10 @@ cleanup_dir_recurse (GFile *parent, GFile *root)
 
   g_assert (root != NULL);
 
-  error = NULL;
   enumerator =
     g_file_enumerate_children (parent, "*",
                               G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL,
-                              &error);
+                              NULL);
   if (! enumerator)
          return;
 
@@ -1062,10 +1195,11 @@ cleanup_dir_recurse (GFile *parent, GFile *root)
   info = g_file_enumerator_next_file (enumerator, NULL, &error);
   while ((info) && (!error))
     {
-      descend = g_file_get_child (parent, g_file_info_get_name (info));
+      descend = g_file_enumerator_get_child (enumerator, info);
       g_assert (descend != NULL);
       relative_path = g_file_get_relative_path (root, descend);
       g_assert (relative_path != NULL);
+      g_free (relative_path);
 
       log ("    deleting '%s'\n", g_file_info_get_display_name (info));
 
@@ -1078,6 +1212,8 @@ cleanup_dir_recurse (GFile *parent, GFile *root)
 
       g_object_unref (descend);
       error = NULL;
+      g_object_unref (info);
+
       info = g_file_enumerator_next_file (enumerator, NULL, &error);
     }
   g_assert_no_error (error);
@@ -1136,7 +1272,6 @@ main (int argc, char *argv[])
   posix_compat = FALSE;
 
   /*  strip all gtester-specific args  */
-  g_type_init ();
   g_test_init (&argc, &argv, NULL);
 
   /*  no extra parameters specified, assume we're executed from glib test suite  */ 
@@ -1175,6 +1310,7 @@ main (int argc, char *argv[])
       return g_test_run ();
     }
 
+  g_option_context_free (context);
   
   /*  Write test - clean target directory first  */
   /*    this can be also considered as a test - enumerate + delete  */ 
@@ -1221,6 +1357,11 @@ main (int argc, char *argv[])
     g_test_add_data_func ("/live-g-file/test_delete", target_path,
                          test_delete);
 
+  /*  Write test - make_directory_with_parents */
+  if (write_test && (!only_create_struct))
+    g_test_add_data_func ("/live-g-file/test_make_directory_with_parents", target_path,
+                         test_make_directory_with_parents);
+
   if (write_test || only_create_struct)
     g_test_add_data_func ("/live-g-file/final_clean", target_path,
                  prep_clean_structure);