glib r6465 - in trunk/gio: . tests



Author: tbzatek
Date: Wed Feb  6 13:52:07 2008
New Revision: 6465
URL: http://svn.gnome.org/viewvc/glib?rev=6465&view=rev

Log:
2008-02-06  Tomas Bzatek  <tbzatek redhat com> 

        * tests/Makefile.am:
        * tests/live-g-file.c: 
        * tests/live-g-file.txt:
        New GIO testing module working over real data



Added:
   trunk/gio/tests/live-g-file.c
   trunk/gio/tests/live-g-file.txt
Modified:
   trunk/gio/ChangeLog
   trunk/gio/tests/Makefile.am

Modified: trunk/gio/tests/Makefile.am
==============================================================================
--- trunk/gio/tests/Makefile.am	(original)
+++ trunk/gio/tests/Makefile.am	Wed Feb  6 13:52:07 2008
@@ -16,7 +16,7 @@
 	$(top_builddir)/gio/libgio-2.0.la
 
 
-TEST_PROGS       += memory-input-stream g-file g-file-info data-input-stream data-output-stream
+TEST_PROGS       += memory-input-stream g-file g-file-info data-input-stream data-output-stream live-g-file
 
 memory_input_stream_SOURCES	  = memory-input-stream.c
 memory_input_stream_LDADD	  = $(progs_ldadd)
@@ -33,4 +33,5 @@
 data_output_stream_SOURCES	= data-output-stream.c
 data_output_stream_LDADD	= $(progs_ldadd)
 
-
+live_g_file_SOURCES	  = live-g-file.c
+live_g_file_LDADD	  = $(progs_ldadd)

Added: trunk/gio/tests/live-g-file.c
==============================================================================
--- (empty file)
+++ trunk/gio/tests/live-g-file.c	Wed Feb  6 13:52:07 2008
@@ -0,0 +1,1160 @@
+/* GLib testing framework examples and tests
+ * Copyright (C) 2008 Red Hat, Inc.
+ * Authors: Tomas Bzatek <tbzatek redhat com>
+ *
+ * This work is provided "as is"; redistribution and modification
+ * in whole or in part, in any medium, physical or electronic is
+ * permitted without restriction.
+ *
+ * This work is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In no event shall the authors or contributors be liable for any
+ * direct, indirect, incidental, special, exemplary, or consequential
+ * damages (including, but not limited to, procurement of substitute
+ * goods or services; loss of use, data, or profits; or business
+ * interruption) however caused and on any theory of liability, whether
+ * in contract, strict liability, or tort (including negligence or
+ * otherwise) arising in any way out of the use of this software, even
+ * if advised of the possibility of such damage.
+ */
+
+#include <glib/gtestutils.h>
+#include <glib/glib.h>
+#include <gio/gio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#define PATTERN_FILE_SIZE	0x10000
+
+#define TEST_HANDLE_SPECIAL	TRUE
+
+enum StructureExtraFlags
+{
+  TEST_DELETE_NORMAL = 1 << 0,
+  TEST_DELETE_TRASH = 1 << 1,
+  TEST_DELETE_NON_EMPTY = 1 << 2,
+  TEST_DELETE_FAILURE = 1 << 3,
+  TEST_NOT_EXISTS = 1 << 4,
+  TEST_ENUMERATE_FILE = 1 << 5,
+  TEST_NO_ACCESS = 1 << 6,
+  TEST_COPY = 1 << 7,
+  TEST_MOVE = 1 << 8,
+  TEST_COPY_ERROR_RECURSE = 1 << 9,
+  TEST_ALREADY_EXISTS = 1 << 10,
+  TEST_TARGET_IS_FILE = 1 << 11,
+  TEST_CREATE = 1 << 12,
+  TEST_REPLACE = 1 << 13,
+  TEST_APPEND = 1 << 14,
+  TEST_OPEN = 1 << 15,
+  TEST_OVERWRITE = 1 << 16,
+  TEST_INVALID_SYMLINK = 1 << 17,
+};
+
+struct StructureItem
+{
+  const char *filename;
+  const char *link_to;
+  GFileType file_type;
+  GFileCreateFlags create_flags;
+  guint32 mode;
+  gboolean handle_special;
+  enum StructureExtraFlags extra_flags;
+};
+
+#define TEST_DIR_NO_ACCESS		"dir_no-access"
+#define TEST_DIR_NO_WRITE		"dir_no-write"
+#define TEST_DIR_TARGET			"dir-target"
+#define TEST_NAME_NOT_EXISTS	"not_exists"
+#define TEST_TARGET_FILE		"target-file"
+
+
+const struct StructureItem sample_struct[] = {
+/*	 filename				link	file_type				create_flags		mode | handle_special | extra_flags              */
+    {"dir1",				NULL,	G_FILE_TYPE_DIRECTORY,	G_FILE_CREATE_NONE, 0, 0, TEST_DELETE_NORMAL | TEST_DELETE_NON_EMPTY | TEST_REPLACE | TEST_OPEN},
+    {"dir1/subdir",			NULL,	G_FILE_TYPE_DIRECTORY,	G_FILE_CREATE_NONE, 0, 0, TEST_COPY	| TEST_COPY_ERROR_RECURSE | TEST_APPEND},
+    {"dir2",				NULL,	G_FILE_TYPE_DIRECTORY,	G_FILE_CREATE_NONE, 0, 0, TEST_DELETE_NORMAL | TEST_MOVE | TEST_CREATE},
+    {TEST_DIR_TARGET,		NULL,	G_FILE_TYPE_DIRECTORY,	G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_COPY_ERROR_RECURSE},
+    {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},
+    {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},
+    {TEST_TARGET_FILE,		NULL,	G_FILE_TYPE_REGULAR,	G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_OPEN},
+	{"normal_file",			NULL,	G_FILE_TYPE_REGULAR,	G_FILE_CREATE_NONE, 0, 0, TEST_ENUMERATE_FILE | TEST_CREATE | TEST_OVERWRITE},
+	{"normal_file-symlink",	"normal_file",	G_FILE_TYPE_SYMBOLIC_LINK, G_FILE_CREATE_NONE, 0, 0, TEST_ENUMERATE_FILE | TEST_COPY | TEST_OPEN},
+    {"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},
+    {"private_file",		NULL,	G_FILE_TYPE_REGULAR,	G_FILE_CREATE_PRIVATE, 0, 0, TEST_COPY | TEST_OPEN | TEST_OVERWRITE | TEST_APPEND},
+    {"normal_file2",		NULL,	G_FILE_TYPE_REGULAR,	G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_OVERWRITE | TEST_REPLACE},
+    {"readonly_file",		NULL,	G_FILE_TYPE_REGULAR,	G_FILE_CREATE_NONE, S_IRUSR + S_IRGRP + S_IROTH, 0, TEST_DELETE_NORMAL | TEST_OPEN},
+    {"UTF_p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88",
+    						NULL,	G_FILE_TYPE_REGULAR,	G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_CREATE | TEST_OPEN | TEST_OVERWRITE},
+    {"dir_p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88",
+    						NULL,	G_FILE_TYPE_DIRECTORY,	G_FILE_CREATE_NONE, 0, 0, TEST_DELETE_NORMAL | TEST_CREATE},
+    {"pattern_file",		NULL,	G_FILE_TYPE_REGULAR,	G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_COPY | TEST_OPEN | TEST_APPEND},
+    {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},
+    {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},
+    {"not_exists2",			NULL,	G_FILE_TYPE_REGULAR,	G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_NOT_EXISTS | TEST_CREATE},
+    {"not_exists3",			NULL,	G_FILE_TYPE_REGULAR,	G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_NOT_EXISTS | TEST_REPLACE},
+    {"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},
+  };
+
+
+
+
+static gboolean write_test;
+static gboolean verbose;
+static gboolean posix_compat;
+
+#define log(msg...) if (verbose)  g_print (msg)
+
+
+
+
+
+
+
+GFile *
+create_empty_file (GFile * parent, const char *filename,
+		   GFileCreateFlags create_flags)
+{
+  GFile *child;
+  gboolean res;
+  GError *error;
+  GFileOutputStream *outs;
+
+
+  child = g_file_get_child (parent, filename);
+  g_assert (child != NULL);
+
+  error = NULL;
+  outs = g_file_replace (child, NULL, FALSE, create_flags, NULL, &error);
+  g_assert (error == NULL);
+  g_assert (outs != NULL);
+  error = NULL;
+  res = g_output_stream_close (G_OUTPUT_STREAM (outs), NULL, &error);
+  g_object_unref (outs);
+  return child;
+}
+
+GFile *
+create_empty_dir (GFile * parent, const char *filename)
+{
+  GFile *child;
+  gboolean res;
+  GError *error;
+
+  child = g_file_get_child (parent, filename);
+  g_assert (child != NULL);
+  error = NULL;
+  res = g_file_make_directory (child, NULL, &error);
+  g_assert_cmpint (res, ==, TRUE);
+  g_assert (error == NULL);
+  return child;
+}
+
+GFile *
+create_symlink (GFile * parent, const char *filename, const char *points_to)
+{
+  GFile *child;
+  gboolean res;
+  GError *error;
+
+  child = g_file_get_child (parent, filename);
+  g_assert (child != NULL);
+  error = NULL;
+  res = g_file_make_symbolic_link (child, points_to, NULL, &error);
+  g_assert_cmpint (res, ==, TRUE);
+  g_assert (error == NULL);
+  return child;
+}
+
+static void
+test_create_structure (gconstpointer test_data)
+{
+  GFile *root;
+  GFile *child;
+  gboolean res;
+  GError *error;
+  GFileOutputStream *outs;
+  GDataOutputStream *outds;
+  int i;
+  struct StructureItem item;
+
+
+  g_assert (test_data != NULL);
+  log ("\n  Going to create testing structure in '%s'...\n",
+       (char *) test_data);
+
+  root = g_file_new_for_commandline_arg ((char *) test_data);
+  g_assert (root != NULL);
+
+  /*  create root directory  */
+  res = g_file_make_directory (root, NULL, NULL);
+  /*  don't care about errors here  */
+
+
+  /*  create any other items  */
+  for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
+    {
+      item = sample_struct[i];
+      if ((item.handle_special)
+	  || ((!posix_compat)
+	      && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK)))
+	continue;
+
+      child = NULL;
+      switch (item.file_type)
+	{
+	case G_FILE_TYPE_REGULAR:
+	  log ("    Creating file '%s'...\n", item.filename);
+	  child = create_empty_file (root, item.filename, item.create_flags);
+	  break;
+	case G_FILE_TYPE_DIRECTORY:
+	  log ("    Creating directory '%s'...\n", item.filename);
+	  child = create_empty_dir (root, item.filename);
+	  break;
+	case G_FILE_TYPE_SYMBOLIC_LINK:
+	  log ("    Creating symlink '%s' --> '%s'...\n", item.filename,
+	       item.link_to);
+	  child = create_symlink (root, item.filename, item.link_to);
+	  break;
+	default:
+	  break;
+	}
+      g_assert (child != NULL);
+
+      if ((item.mode > 0) && (posix_compat))
+	{
+	  error = NULL;
+	  res =
+	    g_file_set_attribute_uint32 (child, G_FILE_ATTRIBUTE_UNIX_MODE,
+					 item.mode,
+					 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+					 NULL, &error);
+	  g_assert_cmpint (res, ==, TRUE);
+	  g_assert (error == NULL);
+	}
+
+      g_object_unref (child);
+    }
+
+  /*  create a pattern file  */
+  log ("    Creating pattern file...");
+  child = g_file_get_child (root, "pattern_file");
+  g_assert (child != NULL);
+
+  error = NULL;
+  outs =
+    g_file_replace (child, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error);
+  g_assert (error == NULL);
+
+  g_assert (outs != NULL);
+  outds = g_data_output_stream_new (G_OUTPUT_STREAM (outs));
+  g_assert (outds != NULL);
+  for (i = 0; i < PATTERN_FILE_SIZE; i++)
+    {
+      error = NULL;
+      res = g_data_output_stream_put_byte (outds, i % 256, NULL, &error);
+      g_assert (error == NULL);
+    }
+  error = NULL;
+  res = g_output_stream_close (G_OUTPUT_STREAM (outs), NULL, &error);
+  g_assert (error == NULL);
+  g_object_unref (outds);
+  g_object_unref (outs);
+  g_object_unref (child);
+  log (" done.\n");
+
+  g_object_unref (root);
+}
+
+
+
+
+
+GFile *
+file_exists (GFile * parent, const char *filename, gboolean * result)
+{
+  GFile *child;
+  gboolean res;
+
+  if (result)
+    *result = FALSE;
+
+  child = g_file_get_child (parent, filename);
+  g_assert (child != NULL);
+  res = g_file_query_exists (child, NULL);
+  if (result)
+    *result = res;
+
+  return child;
+}
+
+void
+test_attributes (struct StructureItem item, GFileInfo * info)
+{
+  GFileType ftype;
+  guint32 mode;
+  const char *name, *display_name, *edit_name, *copy_name, *symlink_target;
+  gboolean utf8_valid;
+  gboolean has_attr;
+  gboolean is_symlink;
+  gboolean can_read, can_write;
+
+  /*  standard::type  */
+  has_attr = g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_TYPE);
+  g_assert_cmpint (has_attr, ==, TRUE);
+  ftype = g_file_info_get_file_type (info);
+  g_assert_cmpint (ftype, !=, G_FILE_TYPE_UNKNOWN);
+  g_assert_cmpint (ftype, ==, item.file_type);
+
+  /*  unix::mode  */
+  if ((item.mode > 0) && (posix_compat))
+    {
+      mode =
+	g_file_info_get_attribute_uint32 (info,
+					  G_FILE_ATTRIBUTE_UNIX_MODE) & 0xFFF;
+      g_assert_cmpint (mode, ==, item.mode);
+    }
+
+  /*  access::can-read  */
+  if (item.file_type != G_FILE_TYPE_SYMBOLIC_LINK)
+    {
+      can_read =
+	g_file_info_get_attribute_boolean (info,
+					   G_FILE_ATTRIBUTE_ACCESS_CAN_READ);
+      g_assert_cmpint (can_read, ==, TRUE);
+    }
+
+  /*  access::can-write  */
+  if ((write_test) && ((item.extra_flags & TEST_OVERWRITE) == TEST_OVERWRITE))
+    {
+      can_write =
+	g_file_info_get_attribute_boolean (info,
+					   G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE);
+      g_assert_cmpint (can_write, ==, TRUE);
+    }
+
+  /*  standard::name  */
+  name = g_file_info_get_name (info);
+  g_assert (name != NULL);
+
+  /*  standard::display-name  */
+  display_name = g_file_info_get_display_name (info);
+  g_assert (display_name != NULL);
+  utf8_valid = g_utf8_validate (display_name, -1, NULL);
+  g_assert_cmpint (utf8_valid, ==, TRUE);
+
+  /*  standard::edit-name  */
+  edit_name = g_file_info_get_edit_name (info);
+  if (edit_name)
+    {
+      utf8_valid = g_utf8_validate (edit_name, -1, NULL);
+      g_assert_cmpint (utf8_valid, ==, TRUE);
+    }
+
+  /*  standard::copy-name  */
+  copy_name =
+    g_file_info_get_attribute_string (info,
+				      G_FILE_ATTRIBUTE_STANDARD_COPY_NAME);
+  if (copy_name)
+    {
+      utf8_valid = g_utf8_validate (copy_name, -1, NULL);
+      g_assert_cmpint (utf8_valid, ==, TRUE);
+    }
+
+  /*  standard::is-symlink  */
+  if (posix_compat)
+    {
+      is_symlink = g_file_info_get_is_symlink (info);
+      g_assert_cmpint (is_symlink, ==,
+		       item.file_type == G_FILE_TYPE_SYMBOLIC_LINK);
+    }
+
+  /*  standard::symlink-target  */
+  if ((item.file_type == G_FILE_TYPE_SYMBOLIC_LINK) && (posix_compat))
+    {
+      symlink_target = g_file_info_get_symlink_target (info);
+      g_assert_cmpstr (symlink_target, ==, item.link_to);
+    }
+}
+
+
+static void
+test_initial_structure (gconstpointer test_data)
+{
+  GFile *root;
+  GFile *child;
+  gboolean res;
+  GError *error;
+  GFileInputStream *ins;
+  int i;
+  GFileInfo *info;
+  guint32 size;
+  guchar *buffer;
+  gssize read, total_read;
+  struct StructureItem item;
+
+
+  g_assert (test_data != NULL);
+  log ("\n  Testing sample structure in '%s'...\n", (char *) test_data);
+
+  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);
+
+
+  /*  test the structure  */
+  for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
+    {
+      item = sample_struct[i];
+      if (((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK))
+	  || (item.handle_special))
+	continue;
+
+      log ("    Testing file '%s'...\n", item.filename);
+
+      child = file_exists (root, item.filename, &res);
+      g_assert (child != NULL);
+      g_assert_cmpint (res, ==, TRUE);
+
+      error = NULL;
+      info =
+	g_file_query_info (child, "*", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+			   NULL, &error);
+      g_assert (error == NULL);
+      g_assert (info != NULL);
+
+      test_attributes (item, info);
+
+      g_object_unref (child);
+    }
+
+
+  /*  read and test the pattern file  */
+  log ("    Testing pattern file...\n");
+  child = file_exists (root, "pattern_file", &res);
+  g_assert (child != NULL);
+  g_assert_cmpint (res, ==, TRUE);
+
+  error = NULL;
+  info =
+    g_file_query_info (child, "*", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL,
+		       &error);
+  g_assert (error == NULL);
+  g_assert (info != NULL);
+  size = g_file_info_get_size (info);
+  g_assert_cmpint (size, ==, PATTERN_FILE_SIZE);
+
+  error = NULL;
+  ins = g_file_read (child, NULL, &error);
+  g_assert (ins != NULL);
+  g_assert (error == NULL);
+
+  buffer = g_malloc (PATTERN_FILE_SIZE);
+  total_read = 0;
+
+  while (total_read < PATTERN_FILE_SIZE)
+    {
+      error = NULL;
+      read =
+	g_input_stream_read (G_INPUT_STREAM (ins), buffer + total_read,
+			     PATTERN_FILE_SIZE, NULL, &error);
+      g_assert (error == NULL);
+      total_read += read;
+      log ("      read %d bytes, total = %d of %d.\n", read, total_read,
+	   PATTERN_FILE_SIZE);
+    }
+  g_assert_cmpint (total_read, ==, PATTERN_FILE_SIZE);
+
+  error = NULL;
+  res = g_input_stream_close (G_INPUT_STREAM (ins), NULL, &error);
+  g_assert (error == NULL);
+  g_assert_cmpint (res, ==, TRUE);
+
+  for (i = 0; i < PATTERN_FILE_SIZE; i++)
+    g_assert_cmpint (*(buffer + i), ==, i % 256);
+
+  g_object_unref (ins);
+  g_object_unref (child);
+  g_free (buffer);
+  g_object_unref (root);
+}
+
+
+
+
+
+
+void
+traverse_recurse_dirs (GFile * parent, GFile * root)
+{
+  gboolean res;
+  GError *error;
+  GFileEnumerator *enumerator;
+  GFileInfo *info;
+  GFile *descend;
+  char *relative_path;
+  int i;
+  gboolean found;
+
+
+  g_assert (root != NULL);
+
+  error = NULL;
+  enumerator =
+    g_file_enumerate_children (parent, "*",
+			       G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL,
+			       &error);
+  g_assert (enumerator != NULL);
+  g_assert (error == NULL);
+
+  error = NULL;
+  info = g_file_enumerator_next_file (enumerator, NULL, &error);
+  while ((info) && (!error))
+    {
+      descend = g_file_get_child (parent, g_file_info_get_name (info));
+      g_assert (descend != NULL);
+      relative_path = g_file_get_relative_path (root, descend);
+      g_assert (relative_path != NULL);
+
+      found = FALSE;
+      for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
+	{
+	  if (strcmp (sample_struct[i].filename, relative_path) == 0)
+	    {
+	      /*  test the attributes again  */
+	      test_attributes (sample_struct[i], info);
+
+	      found = TRUE;
+	      break;
+	    }
+	}
+      g_assert_cmpint (found, ==, TRUE);
+
+      log ("  Found file %s, relative to root: %s\n",
+	   g_file_info_get_display_name (info), relative_path);
+
+      if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
+	traverse_recurse_dirs (descend, root);
+
+      g_object_unref (descend);
+      error = NULL;
+      info = g_file_enumerator_next_file (enumerator, NULL, &error);
+    }
+  g_assert (error == NULL);
+
+
+  error = NULL;
+  res = g_file_enumerator_close (enumerator, NULL, &error);
+  g_assert_cmpint (res, ==, TRUE);
+  g_assert (error == NULL);
+}
+
+static void
+test_traverse_structure (gconstpointer test_data)
+{
+  GFile *root;
+  gboolean res;
+
+  g_assert (test_data != NULL);
+  log ("\n  Traversing through the sample structure in '%s'...\n",
+       (char *) test_data);
+
+  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);
+
+  traverse_recurse_dirs (root, root);
+
+  g_object_unref (root);
+}
+
+
+
+
+static void
+test_enumerate (gconstpointer test_data)
+{
+  GFile *root, *child;
+  gboolean res;
+  GError *error;
+  GFileEnumerator *enumerator;
+  GFileInfo *info;
+  int i;
+  struct StructureItem item;
+
+
+  g_assert (test_data != NULL);
+  log ("\n  Test enumerate '%s'...\n", (char *) test_data);
+
+  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);
+
+
+  for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
+    {
+      item = sample_struct[i];
+      if ((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK))
+	continue;
+
+      if (((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS) ||
+	  (((item.extra_flags & TEST_NO_ACCESS) == TEST_NO_ACCESS)
+	   && posix_compat)
+	  || ((item.extra_flags & TEST_ENUMERATE_FILE) ==
+	      TEST_ENUMERATE_FILE))
+	{
+	  log ("    Testing file '%s'\n", item.filename);
+	  child = g_file_get_child (root, item.filename);
+	  g_assert (child != NULL);
+	  error = NULL;
+	  enumerator =
+	    g_file_enumerate_children (child, "*",
+				       G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+				       NULL, &error);
+
+	  if ((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS)
+	    {
+	      g_assert (enumerator == NULL);
+	      g_assert_cmpint (error->code, ==, G_IO_ERROR_NOT_FOUND);
+	    }
+	  if ((item.extra_flags & TEST_ENUMERATE_FILE) == TEST_ENUMERATE_FILE)
+	    {
+	      g_assert (enumerator == NULL);
+	      g_assert_cmpint (error->code, ==, G_IO_ERROR_NOT_DIRECTORY);
+	    }
+	  if ((item.extra_flags & TEST_NO_ACCESS) == TEST_NO_ACCESS)
+	    {
+	      g_assert (enumerator != NULL);
+
+	      error = NULL;
+	      info = g_file_enumerator_next_file (enumerator, NULL, &error);
+	      g_assert (info == NULL);
+	      g_assert (error == NULL);
+	      /*  no items should be found, no error should be logged  */
+	    }
+
+	  if (error)
+	    g_error_free (error);
+
+	  if (enumerator)
+	    {
+	      error = NULL;
+	      res = g_file_enumerator_close (enumerator, NULL, &error);
+	      g_assert_cmpint (res, ==, TRUE);
+	      g_assert (error == NULL);
+	    }
+	  g_object_unref (child);
+	}
+    }
+  g_object_unref (root);
+}
+
+
+
+
+
+
+void
+do_copy_move (GFile * root, struct StructureItem item, const char *target_dir,
+	      enum StructureExtraFlags extra_flags)
+{
+  GFile *dst_dir, *src_file, *dst_file;
+  gboolean res;
+  GError *error;
+
+  log ("    do_copy_move: '%s' --> '%s'\n", item.filename, target_dir);
+
+  dst_dir = g_file_get_child (root, target_dir);
+  g_assert (dst_dir != NULL);
+  src_file = g_file_get_child (root, item.filename);
+  g_assert (src_file != NULL);
+  dst_file = g_file_get_child (dst_dir, item.filename);
+  g_assert (dst_file != NULL);
+
+  error = NULL;
+  if ((item.extra_flags & TEST_COPY) == TEST_COPY)
+    res =
+      g_file_copy (src_file, dst_file,
+		   G_FILE_COPY_NOFOLLOW_SYMLINKS |
+		   ((extra_flags ==
+		     TEST_OVERWRITE) ? G_FILE_COPY_OVERWRITE :
+		    G_FILE_COPY_NONE), NULL, NULL, NULL, &error);
+  else
+    res =
+      g_file_move (src_file, dst_file, G_FILE_COPY_NOFOLLOW_SYMLINKS, NULL,
+		   NULL, NULL, &error);
+
+  if (error)
+    log ("       res = %d, error code %d = %s\n", res, error->code,
+	 error->message);
+
+
+  /*  copying file/directory to itself (".")  */
+  if (((item.extra_flags & TEST_NOT_EXISTS) != TEST_NOT_EXISTS) &&
+      (extra_flags == TEST_ALREADY_EXISTS))
+    {
+      g_assert_cmpint (res, ==, FALSE);
+      g_assert_cmpint (error->code, ==, G_IO_ERROR_EXISTS);
+    }
+  /*  target file is a file, overwrite is not set  */
+  else if (((item.extra_flags & TEST_NOT_EXISTS) != TEST_NOT_EXISTS) &&
+	   (extra_flags == TEST_TARGET_IS_FILE))
+    {
+      g_assert_cmpint (res, ==, FALSE);
+      if (item.file_type == G_FILE_TYPE_DIRECTORY)
+	g_assert_cmpint (error->code, ==, G_IO_ERROR_WOULD_RECURSE);
+      else
+	g_assert_cmpint (error->code, ==, G_IO_ERROR_NOT_DIRECTORY);
+    }
+  /*  source file is directory  */
+  else if ((item.extra_flags & TEST_COPY_ERROR_RECURSE) ==
+	   TEST_COPY_ERROR_RECURSE)
+    {
+      g_assert_cmpint (res, ==, FALSE);
+      g_assert_cmpint (error->code, ==, G_IO_ERROR_WOULD_RECURSE);
+    }
+  /*  source or target path doesn't exist  */
+  else if (((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS) ||
+	   (extra_flags == TEST_NOT_EXISTS))
+    {
+      g_assert_cmpint (res, ==, FALSE);
+      g_assert_cmpint (error->code, ==, G_IO_ERROR_NOT_FOUND);
+    }
+  /*  source or target path permission denied  */
+  else if (((item.extra_flags & TEST_NO_ACCESS) == TEST_NO_ACCESS) ||
+	   (extra_flags == TEST_NO_ACCESS))
+    {
+      g_assert_cmpint (res, ==, FALSE);
+      g_assert_cmpint (error->code, ==, G_IO_ERROR_PERMISSION_DENIED);
+    }
+  /*  no error should be found, all exceptions defined above  */
+  else
+    {
+      g_assert_cmpint (res, ==, TRUE);
+      g_assert (error == NULL);
+    }
+
+  if (error)
+    g_error_free (error);
+
+
+  g_object_unref (dst_dir);
+  g_object_unref (src_file);
+  g_object_unref (dst_file);
+}
+
+static void
+test_copy_move (gconstpointer test_data)
+{
+  GFile *root;
+  gboolean res;
+  int i;
+  struct StructureItem item;
+
+
+  log ("\n");
+
+  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);
+
+
+  for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
+    {
+      item = sample_struct[i];
+
+      if ((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK))
+	continue;
+
+      if (((item.extra_flags & TEST_COPY) == TEST_COPY) ||
+	  ((item.extra_flags & TEST_MOVE) == TEST_MOVE))
+	{
+	  /*  test copy/move to a directory, expecting no errors if source files exist  */
+	  do_copy_move (root, item, TEST_DIR_TARGET, 0);
+
+	  /*  some files have been already moved so we can't count with them in the tests  */
+	  if ((item.extra_flags & TEST_COPY) == TEST_COPY)
+	    {
+	      /*  test overwrite for flagged files  */
+	      if ((item.extra_flags & TEST_OVERWRITE) == TEST_OVERWRITE)
+		{
+		  do_copy_move (root, item, TEST_DIR_TARGET, TEST_OVERWRITE);
+		}
+	      /*  source = target, should return G_IO_ERROR_EXISTS  */
+	      do_copy_move (root, item, ".", TEST_ALREADY_EXISTS);
+	      /*  target is file  */
+	      do_copy_move (root, item, TEST_TARGET_FILE,
+			    TEST_TARGET_IS_FILE);
+	      /*  target path is invalid  */
+	      do_copy_move (root, item, TEST_NAME_NOT_EXISTS,
+			    TEST_NOT_EXISTS);
+
+	      /*  tests on POSIX-compatible filesystems  */
+	      if (posix_compat)
+		{
+		  /*  target directory is not accessible (no execute flag)  */
+		  do_copy_move (root, item, TEST_DIR_NO_ACCESS,
+				TEST_NO_ACCESS);
+		  /*  target directory is readonly  */
+		  do_copy_move (root, item, TEST_DIR_NO_WRITE,
+				TEST_NO_ACCESS);
+		}
+	    }
+	}
+    }
+  g_object_unref (root);
+}
+
+
+
+
+
+static void
+test_create (gconstpointer test_data)
+{
+  GFile *root, *child;
+  gboolean res;
+  GError *error;
+  int i;
+  struct StructureItem item;
+  GFileOutputStream *os;
+
+
+  g_assert (test_data != NULL);
+  log ("\n");
+
+  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);
+
+
+  for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
+    {
+      item = sample_struct[i];
+
+      if (((item.extra_flags & TEST_CREATE) == TEST_CREATE) ||
+	  ((item.extra_flags & TEST_REPLACE) == TEST_REPLACE) ||
+	  ((item.extra_flags & TEST_APPEND) == TEST_APPEND))
+	{
+	  log ("  test_create: '%s'\n", item.filename);
+
+	  child = g_file_get_child (root, item.filename);
+	  g_assert (child != NULL);
+	  error = NULL;
+	  os = NULL;
+
+	  if ((item.extra_flags & TEST_CREATE) == TEST_CREATE)
+	    os = g_file_create (child, item.create_flags, NULL, &error);
+	  else if ((item.extra_flags & TEST_REPLACE) == TEST_REPLACE)
+	    os =
+	      g_file_replace (child, NULL, TRUE, item.create_flags, NULL,
+			      &error);
+	  else if ((item.extra_flags & TEST_APPEND) == TEST_APPEND)
+	    os = g_file_append_to (child, item.create_flags, NULL, &error);
+
+
+	  if (error)
+	    log ("       error code %d = %s\n", error->code, error->message);
+
+
+	  if (((item.extra_flags & TEST_NOT_EXISTS) == 0) &&
+	      ((item.extra_flags & TEST_CREATE) == TEST_CREATE))
+	    {
+	      g_assert (os == NULL);
+	      g_assert (error != NULL);
+	      g_assert_cmpint (error->code, ==, G_IO_ERROR_EXISTS);
+	    }
+	  else if (item.file_type == G_FILE_TYPE_DIRECTORY)
+	    {
+	      g_assert (os == NULL);
+	      g_assert (error != NULL);
+	      if ((item.extra_flags & TEST_CREATE) == TEST_CREATE)
+		g_assert_cmpint (error->code, ==, G_IO_ERROR_EXISTS);
+	      else
+		g_assert_cmpint (error->code, ==, G_IO_ERROR_IS_DIRECTORY);
+	    }
+	  else
+	    {
+	      g_assert (os != NULL);
+	      g_assert (error == NULL);
+	    }
+
+	  if (error)
+	    g_error_free (error);
+
+	  if (os)
+	    {
+	      error = NULL;
+	      res =
+		g_output_stream_close (G_OUTPUT_STREAM (os), NULL, &error);
+	      if (error)
+		log ("         g_output_stream_close: error %d = %s\n",
+		     error->code, error->message);
+	      g_assert_cmpint (res, ==, TRUE);
+	      g_assert (error == NULL);
+	    }
+	  g_object_unref (child);
+	}
+    }
+  g_object_unref (root);
+}
+
+
+
+
+static void
+test_open (gconstpointer test_data)
+{
+  GFile *root, *child;
+  gboolean res;
+  GError *error;
+  int i;
+  struct StructureItem item;
+  GFileInputStream *input_stream;
+
+
+  g_assert (test_data != NULL);
+  log ("\n");
+
+  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);
+
+
+  for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
+    {
+      item = sample_struct[i];
+
+      if ((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK))
+	continue;
+
+      if ((item.extra_flags & TEST_OPEN) == TEST_OPEN)
+	{
+	  log ("  test_open: '%s'\n", item.filename);
+
+	  child = g_file_get_child (root, item.filename);
+	  g_assert (child != NULL);
+	  error = NULL;
+	  input_stream = g_file_read (child, NULL, &error);
+
+	  if (((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS) ||
+	      ((item.extra_flags & TEST_INVALID_SYMLINK) ==
+	       TEST_INVALID_SYMLINK))
+	    {
+	      g_assert (input_stream == NULL);
+	      g_assert_cmpint (error->code, ==, G_IO_ERROR_NOT_FOUND);
+	    }
+	  else if (item.file_type == G_FILE_TYPE_DIRECTORY)
+	    {
+	      g_assert (input_stream == NULL);
+	      g_assert_cmpint (error->code, ==, G_IO_ERROR_IS_DIRECTORY);
+	    }
+	  else
+	    {
+	      g_assert (input_stream != NULL);
+	      g_assert (error == NULL);
+	    }
+
+	  if (error)
+	    g_error_free (error);
+
+	  if (input_stream)
+	    {
+	      error = NULL;
+	      res =
+		g_input_stream_close (G_INPUT_STREAM (input_stream), NULL,
+				      &error);
+	      g_assert_cmpint (res, ==, TRUE);
+	      g_assert (error == NULL);
+	    }
+	  g_object_unref (child);
+	}
+    }
+  g_object_unref (root);
+}
+
+
+
+
+
+static void
+test_delete (gconstpointer test_data)
+{
+  GFile *root;
+  GFile *child;
+  gboolean res;
+  GError *error;
+  int i;
+  struct StructureItem item;
+
+
+  g_assert (test_data != NULL);
+  log ("\n");
+
+  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);
+
+  for (i = 0; i < G_N_ELEMENTS (sample_struct); i++)
+    {
+      item = sample_struct[i];
+
+      if ((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK))
+	continue;
+
+      if (((item.extra_flags & TEST_DELETE_NORMAL) == TEST_DELETE_NORMAL) ||
+	  ((item.extra_flags & TEST_DELETE_TRASH) == TEST_DELETE_TRASH))
+	{
+	  child = file_exists (root, item.filename, &res);
+	  g_assert (child != NULL);
+	  /*  we don't care about result here  */
+
+	  log ("  Deleting %s, path = %s\n", item.filename,
+	       g_file_get_path (child));
+	  error = NULL;
+	  if ((item.extra_flags & TEST_DELETE_NORMAL) == TEST_DELETE_NORMAL)
+	    res = g_file_delete (child, NULL, &error);
+	  else
+	    res = g_file_trash (child, NULL, &error);
+
+	  if ((item.extra_flags & TEST_DELETE_NON_EMPTY) ==
+	      TEST_DELETE_NON_EMPTY)
+	    {
+	      g_assert_cmpint (res, ==, FALSE);
+	      g_assert (error != NULL);
+	      g_assert_cmpint (error->code, ==, G_IO_ERROR_NOT_EMPTY);
+	    }
+	  if ((item.extra_flags & TEST_DELETE_FAILURE) == TEST_DELETE_FAILURE)
+	    {
+	      g_assert_cmpint (res, ==, FALSE);
+	      g_assert (error != NULL);
+	      g_assert_cmpint (error->code, !=, 0);
+	    }
+	  if ((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS)
+	    {
+	      g_assert_cmpint (res, ==, FALSE);
+	      g_assert (error != NULL);
+	      g_assert_cmpint (error->code, ==, G_IO_ERROR_NOT_FOUND);
+	    }
+
+	  if (error)
+	    {
+	      log ("      result = %d, error = %s\n", res, error->message);
+	      g_error_free (error);
+	    }
+
+
+	  g_object_unref (child);
+	}
+    }
+  g_object_unref (root);
+}
+
+
+
+
+
+
+
+int
+main (int argc, char *argv[])
+{
+  static gboolean create_struct;
+  static char *target_path;
+  GError *error;
+  GOptionContext *context;
+
+  verbose = FALSE;
+  write_test = FALSE;
+  create_struct = FALSE;
+  target_path = NULL;
+  posix_compat = FALSE;
+
+  static GOptionEntry cmd_entries[] = {
+    {"read-write", 'w', 0, G_OPTION_ARG_NONE, &write_test,
+     "Perform write tests (incl. structure creation)", NULL},
+    {"create-struct", 'c', 0, G_OPTION_ARG_NONE, &create_struct,
+     "Only create testing structure (no tests)", NULL},
+    {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Be verbose", NULL},
+    {"posix", 'x', 0, G_OPTION_ARG_NONE, &posix_compat,
+     "Test POSIX-specific features (unix permissions, symlinks)", NULL},
+    {NULL}
+  };
+
+  /*  strip all gtester-specific args  */
+  g_type_init ();
+  g_test_init (&argc, &argv, NULL);
+
+  /*  add trailing args  */
+  error = NULL;
+  context = g_option_context_new ("target_path");
+  g_option_context_add_main_entries (context, cmd_entries, NULL);
+  if (!g_option_context_parse (context, &argc, &argv, &error))
+    {
+      g_print ("option parsing failed: %s\n", error->message);
+      return g_test_run ();
+    }
+
+  /*  missing mandatory arg for target dir  */
+  if (argc < 2)
+    {
+      g_print (g_option_context_get_help (context, TRUE, NULL));
+      return g_test_run ();
+    }
+  target_path = strdup (argv[1]);
+
+
+
+  /*  Write test - create new testing structure  */
+  if (write_test || create_struct)
+    g_test_add_data_func ("/live-g-file/create_structure", target_path,
+			  test_create_structure);
+
+  /*  Read test - test the sample structure - expect defined attributes to be there  */
+  if (!create_struct)
+    g_test_add_data_func ("/live-g-file/test_initial_structure", target_path,
+			  test_initial_structure);
+
+  /*  Read test - test traverse the structure - no special file should appear  */
+  if (!create_struct)
+    g_test_add_data_func ("/live-g-file/test_traverse_structure", target_path,
+			  test_traverse_structure);
+
+  /*  Read test - enumerate  */
+  if (!create_struct)
+    g_test_add_data_func ("/live-g-file/test_enumerate", target_path,
+			  test_enumerate);
+
+  /*  Read test - open (g_file_read())  */
+  if (!create_struct)
+    g_test_add_data_func ("/live-g-file/test_open", target_path, test_open);
+
+  /*  Write test - create  */
+  if (write_test && (!create_struct))
+    g_test_add_data_func ("/live-g-file/test_create", target_path,
+			  test_create);
+
+  /*  Write test - copy, move  */
+  if (write_test && (!create_struct))
+    g_test_add_data_func ("/live-g-file/test_copy_move", target_path,
+			  test_copy_move);
+
+  /*  Write test - delete, trash  */
+  if (write_test && (!create_struct))
+    g_test_add_data_func ("/live-g-file/test_delete", target_path,
+			  test_delete);
+
+  return g_test_run ();
+}

Added: trunk/gio/tests/live-g-file.txt
==============================================================================
--- (empty file)
+++ trunk/gio/tests/live-g-file.txt	Wed Feb  6 13:52:07 2008
@@ -0,0 +1,27 @@
+Before you start testing it would be good to explain how it works.
+
+The script works in three modes:
+ 1. read-only (no special arguments) - suitable for read-only backends. Just 
+        create the sample structure using the second mode, pack it (tar -p is 
+        preffered to preserve unix modes) and put it on a reachable place.
+ 2. create-structure - only creates reference structure for later testing 
+        in read-only mode
+ 3. write mode - full test suite, creates testing structure and performs all 
+        read and write tests. Please note the delete/move tests are included 
+        in this mode and target directory structure is unusable after the script
+        is finished.
+
+
+To see the list of available parameters just run 'live-g-file --help'
+
+
+Notes:
+ - it's advised to clean target directory first, otherwise some tests might fail
+   (i.e. the tests creating testing structure)
+
+
+Tested:
+ - local filesystem (/tmp/...)
+ - file:// uri (file:///tmp/...)
+ - locatest:// gvfs backend (localtest:///tmp/...)
+ - FAT16 filesystem (no POSIX extensions)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]