tests: move tests to new _get_filename() API
[platform/upstream/glib.git] / gio / tests / file.c
1 #include <string.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <gio/gio.h>
5 #include <gio/gfiledescriptorbased.h>
6 #ifdef G_OS_UNIX
7 #include <sys/stat.h>
8 #endif
9
10 static void
11 test_basic (void)
12 {
13   GFile *file;
14   gchar *s;
15
16   file = g_file_new_for_path ("./some/directory/testfile");
17
18   s = g_file_get_basename (file);
19   g_assert_cmpstr (s, ==, "testfile");
20   g_free (s);
21
22   s = g_file_get_uri (file);
23   g_assert (g_str_has_prefix (s, "file://"));
24   g_assert (g_str_has_suffix (s, "/some/directory/testfile"));
25   g_free (s);
26
27   g_assert (g_file_has_uri_scheme (file, "file"));
28   s = g_file_get_uri_scheme (file);
29   g_assert_cmpstr (s, ==, "file");
30   g_free (s);
31
32   g_object_unref (file);
33 }
34
35 static void
36 test_parent (void)
37 {
38   GFile *file;
39   GFile *file2;
40   GFile *parent;
41   GFile *root;
42
43   file = g_file_new_for_path ("./some/directory/testfile");
44   file2 = g_file_new_for_path ("./some/directory");
45   root = g_file_new_for_path ("/");
46
47   g_assert (g_file_has_parent (file, file2));
48
49   parent = g_file_get_parent (file);
50   g_assert (g_file_equal (parent, file2));
51   g_object_unref (parent);
52
53   g_assert (g_file_get_parent (root) == NULL);
54
55   g_object_unref (file);
56   g_object_unref (file2);
57   g_object_unref (root);
58 }
59
60 static void
61 test_child (void)
62 {
63   GFile *file;
64   GFile *child;
65   GFile *child2;
66
67   file = g_file_new_for_path ("./some/directory");
68   child = g_file_get_child (file, "child");
69   g_assert (g_file_has_parent (child, file));
70
71   child2 = g_file_get_child_for_display_name (file, "child2", NULL);
72   g_assert (g_file_has_parent (child2, file));
73
74   g_object_unref (child);
75   g_object_unref (child2);
76   g_object_unref (file);
77 }
78
79 static void
80 test_type (void)
81 {
82   GFile *datapath_f;
83   GFile *file;
84   GFileType type;
85   GError *error = NULL;
86
87   datapath_f = g_file_new_for_path (g_test_get_dir (G_TEST_DISTED));
88
89   file = g_file_get_child (datapath_f, "g-icon.c");
90   type = g_file_query_file_type (file, 0, NULL);
91   g_assert_cmpint (type, ==, G_FILE_TYPE_REGULAR);
92   g_object_unref (file);
93
94   file = g_file_get_child (datapath_f, "schema-tests");
95   type = g_file_query_file_type (file, 0, NULL);
96   g_assert_cmpint (type, ==, G_FILE_TYPE_DIRECTORY);
97
98   g_file_read (file, NULL, &error);
99   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY);
100   g_error_free (error);
101   g_object_unref (file);
102
103   g_object_unref (datapath_f);
104 }
105
106
107 typedef struct
108 {
109   GFile *file;
110   GFileMonitor *monitor;
111   GOutputStream *ostream;
112   GInputStream *istream;
113   GMainLoop *loop;
114   gint buffersize;
115   gint monitor_created;
116   gint monitor_deleted;
117   gint monitor_changed;
118   gchar *monitor_path;
119   gint pos;
120   gchar *data;
121   gchar *buffer;
122   guint timeout;
123 } CreateDeleteData;
124
125 static void
126 monitor_changed (GFileMonitor      *monitor,
127                  GFile             *file,
128                  GFile             *other_file,
129                  GFileMonitorEvent  event_type,
130                  gpointer           user_data)
131 {
132   CreateDeleteData *data = user_data;
133   gchar *path;
134
135   path = g_file_get_path (file);
136   g_assert_cmpstr (data->monitor_path, ==, path);
137   g_free (path);
138
139   if (event_type == G_FILE_MONITOR_EVENT_CREATED)
140     data->monitor_created++;
141   if (event_type == G_FILE_MONITOR_EVENT_DELETED)
142     data->monitor_deleted++;
143   if (event_type == G_FILE_MONITOR_EVENT_CHANGED)
144     data->monitor_changed++;
145 }
146
147
148 static gboolean
149 quit_idle (gpointer user_data)
150 {
151   CreateDeleteData *data = user_data;
152
153   g_source_remove (data->timeout); 
154   g_main_loop_quit (data->loop);
155
156   return FALSE;
157 }
158
159 static void
160 iclosed_cb (GObject      *source,
161             GAsyncResult *res,
162             gpointer      user_data)
163 {
164   CreateDeleteData *data = user_data;
165   GError *error;
166   gboolean ret;
167
168   error = NULL;
169   ret = g_input_stream_close_finish (data->istream, res, &error);
170   g_assert_no_error (error);
171   g_assert (ret);
172
173   g_assert (g_input_stream_is_closed (data->istream));
174
175   ret = g_file_delete (data->file, NULL, &error);
176   g_assert (ret);
177   g_assert_no_error (error);
178
179   /* work around file monitor bug:
180    * inotify events are only processed every 1000 ms, regardless
181    * of the rate limit set on the file monitor
182    */
183   g_timeout_add (2000, quit_idle, data);
184 }
185
186 static void
187 read_cb (GObject      *source,
188          GAsyncResult *res,
189          gpointer      user_data)
190 {
191   CreateDeleteData *data = user_data;
192   GError *error;
193   gssize size;
194
195   error = NULL;
196   size = g_input_stream_read_finish (data->istream, res, &error);
197   g_assert_no_error (error);
198
199   data->pos += size;
200   if (data->pos < strlen (data->data))
201     {
202       g_input_stream_read_async (data->istream,
203                                  data->buffer + data->pos,
204                                  strlen (data->data) - data->pos,
205                                  0,
206                                  NULL,
207                                  read_cb,
208                                  data);
209     }
210   else
211     {
212       g_assert_cmpstr (data->buffer, ==, data->data);
213       g_assert (!g_input_stream_is_closed (data->istream));
214       g_input_stream_close_async (data->istream, 0, NULL, iclosed_cb, data);
215     }
216 }
217
218 static void
219 ipending_cb (GObject      *source,
220              GAsyncResult *res,
221              gpointer      user_data)
222 {
223   CreateDeleteData *data = user_data;
224   GError *error;
225
226   error = NULL;
227   g_input_stream_read_finish (data->istream, res, &error);
228   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PENDING);
229   g_error_free (error);
230 }
231
232 static void
233 skipped_cb (GObject      *source,
234             GAsyncResult *res,
235             gpointer      user_data)
236 {
237   CreateDeleteData *data = user_data;
238   GError *error;
239   gssize size;
240
241   error = NULL;
242   size = g_input_stream_skip_finish (data->istream, res, &error);
243   g_assert_no_error (error);
244   g_assert_cmpint (size, ==, data->pos);
245
246   g_input_stream_read_async (data->istream,
247                              data->buffer + data->pos,
248                              strlen (data->data) - data->pos,
249                              0,
250                              NULL,
251                              read_cb,
252                              data);
253   /* check that we get a pending error */
254   g_input_stream_read_async (data->istream,
255                              data->buffer + data->pos,
256                              strlen (data->data) - data->pos,
257                              0,
258                              NULL,
259                              ipending_cb,
260                              data);
261 }
262
263 static void
264 opened_cb (GObject      *source,
265            GAsyncResult *res,
266            gpointer      user_data)
267 {
268   GFileInputStream *base;
269   CreateDeleteData *data = user_data;
270   GError *error;
271
272   error = NULL;
273   base = g_file_read_finish (data->file, res, &error);
274   g_assert_no_error (error);
275
276   if (data->buffersize == 0)
277     data->istream = G_INPUT_STREAM (g_object_ref (base));
278   else
279     data->istream = g_buffered_input_stream_new_sized (G_INPUT_STREAM (base), data->buffersize);
280   g_object_unref (base);
281
282   data->buffer = g_new0 (gchar, strlen (data->data) + 1);
283
284   /* copy initial segment directly, then skip */
285   memcpy (data->buffer, data->data, 10);
286   data->pos = 10;
287
288   g_input_stream_skip_async (data->istream,
289                              10,
290                              0,
291                              NULL,
292                              skipped_cb,
293                              data);
294 }
295
296 static void
297 oclosed_cb (GObject      *source,
298             GAsyncResult *res,
299             gpointer      user_data)
300 {
301   CreateDeleteData *data = user_data;
302   GError *error;
303   gboolean ret;
304
305   error = NULL;
306   ret = g_output_stream_close_finish (data->ostream, res, &error);
307   g_assert_no_error (error);
308   g_assert (ret);
309   g_assert (g_output_stream_is_closed (data->ostream));
310
311   g_file_read_async (data->file, 0, NULL, opened_cb, data);
312 }
313
314 static void
315 written_cb (GObject      *source,
316             GAsyncResult *res,
317             gpointer      user_data)
318 {
319   CreateDeleteData *data = user_data;
320   gssize size;
321   GError *error;
322
323   error = NULL;
324   size = g_output_stream_write_finish (data->ostream, res, &error);
325   g_assert_no_error (error);
326
327   data->pos += size;
328   if (data->pos < strlen (data->data))
329     {
330       g_output_stream_write_async (data->ostream,
331                                    data->data + data->pos,
332                                    strlen (data->data) - data->pos,
333                                    0,
334                                    NULL,
335                                    written_cb,
336                                    data);
337     }
338   else
339     {
340       g_assert (!g_output_stream_is_closed (data->ostream));
341       g_output_stream_close_async (data->ostream, 0, NULL, oclosed_cb, data);
342     }
343 }
344
345 static void
346 opending_cb (GObject      *source,
347              GAsyncResult *res,
348              gpointer      user_data)
349 {
350   CreateDeleteData *data = user_data;
351   GError *error;
352
353   error = NULL;
354   g_output_stream_write_finish (data->ostream, res, &error);
355   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PENDING);
356   g_error_free (error);
357 }
358
359 static void
360 created_cb (GObject      *source,
361             GAsyncResult *res,
362             gpointer      user_data)
363 {
364   GFileOutputStream *base;
365   CreateDeleteData *data = user_data;
366   GError *error;
367
368   error = NULL;
369   base = g_file_create_finish (G_FILE (source), res, &error);
370   g_assert_no_error (error);
371   g_assert (g_file_query_exists  (data->file, NULL));
372
373   if (data->buffersize == 0)
374     data->ostream = G_OUTPUT_STREAM (g_object_ref (base));
375   else
376     data->ostream = g_buffered_output_stream_new_sized (G_OUTPUT_STREAM (base), data->buffersize);
377   g_object_unref (base);
378
379   g_output_stream_write_async (data->ostream,
380                                data->data,
381                                strlen (data->data),
382                                0,
383                                NULL,
384                                written_cb,
385                                data);
386   /* check that we get a pending error */
387   g_output_stream_write_async (data->ostream,
388                                data->data,
389                                strlen (data->data),
390                                0,
391                                NULL,
392                                opending_cb,
393                                data);
394 }
395
396 static gboolean
397 stop_timeout (gpointer data)
398 {
399   g_assert_not_reached ();
400
401   return FALSE;
402 }
403
404 /*
405  * This test does a fully async create-write-read-delete.
406  * Callbackistan.
407  */
408 static void
409 test_create_delete (gconstpointer d)
410 {
411   GError *error;
412   CreateDeleteData *data;
413   GFileIOStream *iostream;
414
415   data = g_new0 (CreateDeleteData, 1);
416
417   data->buffersize = GPOINTER_TO_INT (d);
418   data->data = "abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVXYZ0123456789";
419   data->pos = 0;
420
421   data->file = g_file_new_tmp ("g_file_create_delete_XXXXXX",
422                                &iostream, NULL);
423   g_assert (data->file != NULL);
424   g_object_unref (iostream);
425
426   data->monitor_path = g_file_get_path (data->file);
427   remove (data->monitor_path);
428
429   g_assert (!g_file_query_exists  (data->file, NULL));
430
431   error = NULL;
432   data->monitor = g_file_monitor_file (data->file, 0, NULL, &error);
433   g_assert_no_error (error);
434
435   /* This test doesn't work with GPollFileMonitor, because it assumes
436    * that the monitor will notice a create immediately followed by a
437    * delete, rather than coalescing them into nothing.
438    */
439   if (!strcmp (G_OBJECT_TYPE_NAME (data->monitor), "GPollFileMonitor"))
440     {
441       g_print ("skipping test for this GFileMonitor implementation");
442       goto skip;
443     }
444
445   g_file_monitor_set_rate_limit (data->monitor, 100);
446
447   g_signal_connect (data->monitor, "changed", G_CALLBACK (monitor_changed), data);
448
449   data->loop = g_main_loop_new (NULL, FALSE);
450
451   data->timeout = g_timeout_add (5000, stop_timeout, NULL);
452
453   g_file_create_async (data->file, 0, 0, NULL, created_cb, data);
454
455   g_main_loop_run (data->loop);
456
457   g_assert_cmpint (data->monitor_created, ==, 1);
458   g_assert_cmpint (data->monitor_deleted, ==, 1);
459   g_assert_cmpint (data->monitor_changed, >, 0);
460
461   g_assert (!g_file_monitor_is_cancelled (data->monitor));
462   g_file_monitor_cancel (data->monitor);
463   g_assert (g_file_monitor_is_cancelled (data->monitor));
464
465   g_main_loop_unref (data->loop);
466   g_object_unref (data->ostream);
467   g_object_unref (data->istream);
468
469  skip:
470   g_object_unref (data->monitor);
471   g_object_unref (data->file);
472   free (data->monitor_path);
473   g_free (data->buffer);
474   g_free (data);
475 }
476
477 static const gchar *replace_data =
478     "/**\n"
479     " * g_file_replace_contents_async:\n"
480     " * @file: input #GFile.\n"
481     " * @contents: string of contents to replace the file with.\n"
482     " * @length: the length of @contents in bytes.\n"
483     " * @etag: (allow-none): a new <link linkend=\"gfile-etag\">entity tag</link> for the @file, or %NULL\n"
484     " * @make_backup: %TRUE if a backup should be created.\n"
485     " * @flags: a set of #GFileCreateFlags.\n"
486     " * @cancellable: optional #GCancellable object, %NULL to ignore.\n"
487     " * @callback: a #GAsyncReadyCallback to call when the request is satisfied\n"
488     " * @user_data: the data to pass to callback function\n"
489     " * \n"
490     " * Starts an asynchronous replacement of @file with the given \n"
491     " * @contents of @length bytes. @etag will replace the document's\n"
492     " * current entity tag.\n"
493     " * \n"
494     " * When this operation has completed, @callback will be called with\n"
495     " * @user_user data, and the operation can be finalized with \n"
496     " * g_file_replace_contents_finish().\n"
497     " * \n"
498     " * If @cancellable is not %NULL, then the operation can be cancelled by\n"
499     " * triggering the cancellable object from another thread. If the operation\n"
500     " * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. \n"
501     " * \n"
502     " * If @make_backup is %TRUE, this function will attempt to \n"
503     " * make a backup of @file.\n"
504     " **/\n";
505
506 typedef struct
507 {
508   GFile *file;
509   const gchar *data;
510   GMainLoop *loop;
511   gboolean again;
512 } ReplaceLoadData;
513
514 static void replaced_cb (GObject      *source,
515                          GAsyncResult *res,
516                          gpointer      user_data);
517
518 static void
519 loaded_cb (GObject      *source,
520            GAsyncResult *res,
521            gpointer      user_data)
522 {
523   ReplaceLoadData *data = user_data;
524   gboolean ret;
525   GError *error;
526   gchar *contents;
527   gsize length;
528
529   error = NULL;
530   ret = g_file_load_contents_finish (data->file, res, &contents, &length, NULL, &error);
531   g_assert (ret);
532   g_assert_no_error (error);
533   g_assert_cmpint (length, ==, strlen (data->data));
534   g_assert_cmpstr (contents, ==, data->data);
535
536   g_free (contents);
537
538   if (data->again)
539     {
540       data->again = FALSE;
541       data->data = "pi pa po";
542
543       g_file_replace_contents_async (data->file,
544                                      data->data,
545                                      strlen (data->data),
546                                      NULL,
547                                      FALSE,
548                                      0,
549                                      NULL,
550                                      replaced_cb,
551                                      data);
552     }
553   else
554     {
555        error = NULL;
556        ret = g_file_delete (data->file, NULL, &error);
557        g_assert_no_error (error);
558        g_assert (ret);
559        g_assert (!g_file_query_exists (data->file, NULL));
560
561        g_main_loop_quit (data->loop);
562     }
563 }
564
565 static void
566 replaced_cb (GObject      *source,
567              GAsyncResult *res,
568              gpointer      user_data)
569 {
570   ReplaceLoadData *data = user_data;
571   GError *error;
572
573   error = NULL;
574   g_file_replace_contents_finish (data->file, res, NULL, &error);
575   g_assert_no_error (error);
576
577   g_file_load_contents_async (data->file, NULL, loaded_cb, data);
578 }
579
580 static void
581 test_replace_load (void)
582 {
583   ReplaceLoadData *data;
584   gchar *path;
585   GFileIOStream *iostream;
586
587   data = g_new0 (ReplaceLoadData, 1);
588   data->again = TRUE;
589   data->data = replace_data;
590
591   data->file = g_file_new_tmp ("g_file_replace_load_XXXXXX",
592                                &iostream, NULL);
593   g_assert (data->file != NULL);
594   g_object_unref (iostream);
595
596   path = g_file_get_path (data->file);
597   remove (path);
598
599   g_assert (!g_file_query_exists (data->file, NULL));
600
601   data->loop = g_main_loop_new (NULL, FALSE);
602
603   g_file_replace_contents_async (data->file,
604                                  data->data,
605                                  strlen (data->data),
606                                  NULL,
607                                  FALSE,
608                                  0,
609                                  NULL,
610                                  replaced_cb,
611                                  data);
612
613   g_main_loop_run (data->loop);
614
615   g_main_loop_unref (data->loop);
616   g_object_unref (data->file);
617   g_free (data);
618   free (path);
619 }
620
621 static void
622 test_replace_cancel (void)
623 {
624   GFile *tmpdir, *file;
625   GFileOutputStream *ostream;
626   GFileEnumerator *fenum;
627   GFileInfo *info;
628   GCancellable *cancellable;
629   gchar *path;
630   gsize nwrote;
631   GError *error = NULL;
632
633   g_test_bug ("629301");
634
635   path = g_dir_make_tmp ("g_file_replace_cancel_XXXXXX", &error);
636   g_assert_no_error (error);
637   tmpdir = g_file_new_for_path (path);
638   g_free (path);
639
640   file = g_file_get_child (tmpdir, "file");
641   g_file_replace_contents (file,
642                            replace_data,
643                            strlen (replace_data),
644                            NULL, FALSE, 0, NULL,
645                            NULL, &error);
646   g_assert_no_error (error);
647
648   ostream = g_file_replace (file, NULL, TRUE, 0, NULL, &error);
649   g_assert_no_error (error);
650
651   g_output_stream_write_all (G_OUTPUT_STREAM (ostream),
652                              replace_data, strlen (replace_data),
653                              &nwrote, NULL, &error);
654   g_assert_no_error (error);
655   g_assert_cmpint (nwrote, ==, strlen (replace_data));
656
657   /* At this point there should be two files; the original and the
658    * temporary.
659    */
660   fenum = g_file_enumerate_children (tmpdir, NULL, 0, NULL, &error);
661   g_assert_no_error (error);
662
663   info = g_file_enumerator_next_file (fenum, NULL, &error);
664   g_assert_no_error (error);
665   g_assert (info != NULL);
666   g_object_unref (info);
667   info = g_file_enumerator_next_file (fenum, NULL, &error);
668   g_assert_no_error (error);
669   g_assert (info != NULL);
670   g_object_unref (info);
671
672   g_file_enumerator_close (fenum, NULL, &error);
673   g_assert_no_error (error);
674   g_object_unref (fenum);
675
676   /* Make sure the temporary gets deleted even if we cancel. */
677   cancellable = g_cancellable_new ();
678   g_cancellable_cancel (cancellable);
679   g_output_stream_close (G_OUTPUT_STREAM (ostream), cancellable, &error);
680   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
681   g_clear_error (&error);
682
683   g_object_unref (cancellable);
684   g_object_unref (ostream);
685
686   g_file_delete (file, NULL, &error);
687   g_assert_no_error (error);
688   g_object_unref (file);
689
690   /* This will only succeed if the temp file was deleted. */
691   g_file_delete (tmpdir, NULL, &error);
692   g_assert_no_error (error);
693   g_object_unref (tmpdir);
694 }
695
696 static void
697 on_file_deleted (GObject      *object,
698                  GAsyncResult *result,
699                  gpointer      user_data)
700 {
701   GError *local_error = NULL;
702   GMainLoop *loop = user_data;
703
704   (void) g_file_delete_finish ((GFile*)object, result, &local_error);
705   g_assert_no_error (local_error);
706
707   g_main_loop_quit (loop);
708 }
709
710 static void
711 test_async_delete (void)
712 {
713   GFile *file;
714   GFileIOStream *iostream;
715   GError *local_error = NULL;
716   GError **error = &local_error;
717   GMainLoop *loop;
718
719   file = g_file_new_tmp ("g_file_delete_XXXXXX",
720                          &iostream, error);
721   g_assert_no_error (local_error);
722   g_object_unref (iostream);
723
724   g_assert (g_file_query_exists (file, NULL));
725
726   loop = g_main_loop_new (NULL, TRUE);
727
728   g_file_delete_async (file, G_PRIORITY_DEFAULT, NULL, on_file_deleted, loop);
729
730   g_main_loop_run (loop);
731
732   g_assert (!g_file_query_exists (file, NULL));
733
734   g_main_loop_unref (loop);
735   g_object_unref (file);
736 }
737
738 #ifdef G_OS_UNIX
739 static void
740 test_copy_preserve_mode (void)
741 {
742   GFile *tmpfile;
743   GFile *dest_tmpfile;
744   GFileInfo *dest_info;
745   GFileIOStream *iostream;
746   GError *local_error = NULL;
747   GError **error = &local_error;
748   guint32 romode = S_IFREG | 0600;
749   guint32 dest_mode;
750
751   tmpfile = g_file_new_tmp ("tmp-copy-preserve-modeXXXXXX",
752                             &iostream, error);
753   g_assert_no_error (local_error);
754   g_io_stream_close ((GIOStream*)iostream, NULL, error);
755   g_assert_no_error (local_error);
756   g_clear_object (&iostream);
757
758   g_file_set_attribute (tmpfile, G_FILE_ATTRIBUTE_UNIX_MODE, G_FILE_ATTRIBUTE_TYPE_UINT32,
759                         &romode, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
760                         NULL, error);
761   g_assert_no_error (local_error);
762
763   dest_tmpfile = g_file_new_tmp ("tmp-copy-preserve-modeXXXXXX",
764                                  &iostream, error);
765   g_assert_no_error (local_error);
766   g_io_stream_close ((GIOStream*)iostream, NULL, error);
767   g_assert_no_error (local_error);
768   g_clear_object (&iostream);
769
770   g_file_copy (tmpfile, dest_tmpfile, G_FILE_COPY_OVERWRITE | G_FILE_COPY_NOFOLLOW_SYMLINKS | G_FILE_COPY_ALL_METADATA,
771                NULL, NULL, NULL, error);
772   g_assert_no_error (local_error);
773
774   dest_info = g_file_query_info (dest_tmpfile, G_FILE_ATTRIBUTE_UNIX_MODE, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
775                                  NULL, error);
776   g_assert_no_error (local_error);
777
778   dest_mode = g_file_info_get_attribute_uint32 (dest_info, G_FILE_ATTRIBUTE_UNIX_MODE);
779   
780   g_assert_cmpint (dest_mode, ==, romode);
781
782   (void) g_file_delete (tmpfile, NULL, NULL);
783   (void) g_file_delete (dest_tmpfile, NULL, NULL);
784   
785   g_clear_object (&tmpfile);
786   g_clear_object (&dest_tmpfile);
787   g_clear_object (&dest_info);
788 }
789 #endif
790
791 int
792 main (int argc, char *argv[])
793 {
794   g_test_init (&argc, &argv, NULL);
795
796   g_test_bug_base ("http://bugzilla.gnome.org/");
797
798   g_test_add_func ("/file/basic", test_basic);
799   g_test_add_func ("/file/parent", test_parent);
800   g_test_add_func ("/file/child", test_child);
801   g_test_add_func ("/file/type", test_type);
802   g_test_add_data_func ("/file/async-create-delete/0", GINT_TO_POINTER (0), test_create_delete);
803   g_test_add_data_func ("/file/async-create-delete/1", GINT_TO_POINTER (1), test_create_delete);
804   g_test_add_data_func ("/file/async-create-delete/10", GINT_TO_POINTER (10), test_create_delete);
805   g_test_add_data_func ("/file/async-create-delete/25", GINT_TO_POINTER (25), test_create_delete);
806   g_test_add_data_func ("/file/async-create-delete/4096", GINT_TO_POINTER (4096), test_create_delete);
807   g_test_add_func ("/file/replace-load", test_replace_load);
808   g_test_add_func ("/file/replace-cancel", test_replace_cancel);
809   g_test_add_func ("/file/async-delete", test_async_delete);
810 #ifdef G_OS_UNIX
811   g_test_add_func ("/file/copy-preserve-mode", test_copy_preserve_mode);
812 #endif
813
814   return g_test_run ();
815 }