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