1 /* GLib testing framework examples and tests
2  *
3  * Copyright (C) 2011 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include <string.h>
20 #include <gio/gio.h>
21 #include <glibconfig.h>
22 #include "gconstructor.h"
23 #include "test_resources2.h"
24 #include "digit_test_resources.h"
25 
26 #ifdef _MSC_VER
27 # define MODULE_FILENAME_PREFIX ""
28 #else
29 # define MODULE_FILENAME_PREFIX "lib"
30 #endif
31 
32 static void
test_resource(GResource * resource)33 test_resource (GResource *resource)
34 {
35   GError *error = NULL;
36   gboolean found, success;
37   gsize size;
38   guint32 flags;
39   GBytes *data;
40   char **children;
41   GInputStream *in;
42   char buffer[128];
43   const gchar *not_found_paths[] =
44     {
45       "/not/there",
46       "/",
47       "",
48     };
49   gsize i;
50 
51   for (i = 0; i < G_N_ELEMENTS (not_found_paths); i++)
52     {
53       found = g_resource_get_info (resource,
54                                    not_found_paths[i],
55                                    G_RESOURCE_LOOKUP_FLAGS_NONE,
56                                    &size, &flags, &error);
57       g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
58       g_clear_error (&error);
59       g_assert_false (found);
60     }
61 
62   found = g_resource_get_info (resource,
63 			       "/test1.txt",
64 			       G_RESOURCE_LOOKUP_FLAGS_NONE,
65 			       &size, &flags, &error);
66   g_assert (found);
67   g_assert_no_error (error);
68   g_assert_cmpint (size, ==, 6);
69   g_assert_cmpuint (flags, ==, G_RESOURCE_FLAGS_COMPRESSED);
70 
71   found = g_resource_get_info (resource,
72                                "/empty.txt",
73                                G_RESOURCE_LOOKUP_FLAGS_NONE,
74                                &size, &flags, &error);
75   g_assert_true (found);
76   g_assert_no_error (error);
77   g_assert_cmpint (size, ==, 0);
78   g_assert_cmpuint (flags, ==, G_RESOURCE_FLAGS_COMPRESSED);
79 
80   found = g_resource_get_info (resource,
81 			       "/a_prefix/test2.txt",
82 			       G_RESOURCE_LOOKUP_FLAGS_NONE,
83 			       &size, &flags, &error);
84   g_assert (found);
85   g_assert_no_error (error);
86   g_assert_cmpint (size, ==, 6);
87   g_assert_cmpuint (flags, ==, 0);
88 
89   found = g_resource_get_info (resource,
90 			       "/a_prefix/test2-alias.txt",
91 			       G_RESOURCE_LOOKUP_FLAGS_NONE,
92 			       &size, &flags, &error);
93   g_assert (found);
94   g_assert_no_error (error);
95   g_assert_cmpint (size, ==, 6);
96   g_assert_cmpuint (flags, ==, 0);
97 
98   for (i = 0; i < G_N_ELEMENTS (not_found_paths); i++)
99     {
100       data = g_resource_lookup_data (resource,
101                                      not_found_paths[i],
102                                      G_RESOURCE_LOOKUP_FLAGS_NONE,
103                                      &error);
104       g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
105       g_clear_error (&error);
106       g_assert_null (data);
107     }
108 
109   data = g_resource_lookup_data (resource,
110 				 "/test1.txt",
111 				 G_RESOURCE_LOOKUP_FLAGS_NONE,
112 				 &error);
113   g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n");
114   g_assert_no_error (error);
115   g_bytes_unref (data);
116 
117   data = g_resource_lookup_data (resource,
118                                  "/empty.txt",
119                                  G_RESOURCE_LOOKUP_FLAGS_NONE,
120                                  &error);
121   g_assert_cmpuint (g_bytes_get_size (data), ==, 0);
122   g_assert_no_error (error);
123   g_bytes_unref (data);
124 
125   for (i = 0; i < G_N_ELEMENTS (not_found_paths); i++)
126     {
127       in = g_resource_open_stream (resource,
128                                    not_found_paths[i],
129                                    G_RESOURCE_LOOKUP_FLAGS_NONE,
130                                    &error);
131       g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
132       g_clear_error (&error);
133       g_assert_null (in);
134     }
135 
136   in = g_resource_open_stream (resource,
137 			       "/test1.txt",
138 			       G_RESOURCE_LOOKUP_FLAGS_NONE,
139 			       &error);
140   g_assert (in != NULL);
141   g_assert_no_error (error);
142 
143   success = g_input_stream_read_all (in, buffer, sizeof (buffer) - 1,
144 				     &size,
145 				     NULL, &error);
146   g_assert (success);
147   g_assert_no_error (error);
148   g_assert_cmpint (size, ==, 6);
149   buffer[size] = 0;
150   g_assert_cmpstr (buffer, ==, "test1\n");
151 
152   g_input_stream_close (in, NULL, &error);
153   g_assert_no_error (error);
154   g_clear_object (&in);
155 
156   in = g_resource_open_stream (resource,
157                                "/empty.txt",
158                                G_RESOURCE_LOOKUP_FLAGS_NONE,
159                                &error);
160   g_assert_no_error (error);
161   g_assert_nonnull (in);
162 
163   success = g_input_stream_read_all (in, buffer, sizeof (buffer) - 1,
164                                      &size,
165                                      NULL, &error);
166   g_assert_no_error (error);
167   g_assert_true (success);
168   g_assert_cmpint (size, ==, 0);
169 
170   g_input_stream_close (in, NULL, &error);
171   g_assert_no_error (error);
172   g_clear_object (&in);
173 
174   data = g_resource_lookup_data (resource,
175 				 "/a_prefix/test2.txt",
176 				 G_RESOURCE_LOOKUP_FLAGS_NONE,
177 				 &error);
178   g_assert (data != NULL);
179   g_assert_no_error (error);
180   size = g_bytes_get_size (data);
181   g_assert_cmpint (size, ==, 6);
182   g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test2\n");
183   g_bytes_unref (data);
184 
185   data = g_resource_lookup_data (resource,
186 				 "/a_prefix/test2-alias.txt",
187 				 G_RESOURCE_LOOKUP_FLAGS_NONE,
188 				 &error);
189   g_assert (data != NULL);
190   g_assert_no_error (error);
191   size = g_bytes_get_size (data);
192   g_assert_cmpint (size, ==, 6);
193   g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test2\n");
194   g_bytes_unref (data);
195 
196   for (i = 0; i < G_N_ELEMENTS (not_found_paths); i++)
197     {
198       if (g_str_equal (not_found_paths[i], "/"))
199         continue;
200 
201       children = g_resource_enumerate_children (resource,
202                                                 not_found_paths[i],
203                                                 G_RESOURCE_LOOKUP_FLAGS_NONE,
204                                                 &error);
205       g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
206       g_clear_error (&error);
207       g_assert_null (children);
208     }
209 
210   children = g_resource_enumerate_children  (resource,
211 					     "/a_prefix",
212 					     G_RESOURCE_LOOKUP_FLAGS_NONE,
213 					     &error);
214   g_assert (children != NULL);
215   g_assert_no_error (error);
216   g_assert_cmpint (g_strv_length (children), ==, 2);
217   g_strfreev (children);
218 
219   /* Test the preferred lookup where we have a trailing slash. */
220   children = g_resource_enumerate_children  (resource,
221 					     "/a_prefix/",
222 					     G_RESOURCE_LOOKUP_FLAGS_NONE,
223 					     &error);
224   g_assert (children != NULL);
225   g_assert_no_error (error);
226   g_assert_cmpint (g_strv_length (children), ==, 2);
227   g_strfreev (children);
228 
229   /* test with a path > 256 and no trailing slash to test the
230    * slow path of resources where we allocate a modified path.
231    */
232   children = g_resource_enumerate_children  (resource,
233 					     "/not/here/not/here/not/here/not/here/not/here/not/here/not/here"
234 					     "/not/here/not/here/not/here/not/here/not/here/not/here/not/here"
235 					     "/not/here/not/here/not/here/not/here/not/here/not/here/not/here"
236 					     "/not/here/not/here/not/here/not/here/not/here/not/here/not/here"
237 					     "/not/here/not/here/not/here/not/here/not/here/not/here/not/here"
238 					     "/with/no/trailing/slash",
239 					     G_RESOURCE_LOOKUP_FLAGS_NONE,
240 					     &error);
241   g_assert (children == NULL);
242   g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
243   g_clear_error (&error);
244 }
245 
246 static void
test_resource_file(void)247 test_resource_file (void)
248 {
249   GResource *resource;
250   GError *error = NULL;
251 
252   resource = g_resource_load ("not-there", &error);
253   g_assert (resource == NULL);
254   g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT);
255   g_clear_error (&error);
256 
257   resource = g_resource_load (g_test_get_filename (G_TEST_BUILT, "test.gresource", NULL), &error);
258   g_assert (resource != NULL);
259   g_assert_no_error (error);
260 
261   test_resource (resource);
262   g_resource_unref (resource);
263 }
264 
265 static void
test_resource_file_path(void)266 test_resource_file_path (void)
267 {
268   static const struct {
269     const gchar *input;
270     const gchar *expected;
271   } test_uris[] = {
272     { "resource://", "resource:///" },
273     { "resource:///", "resource:///" },
274     { "resource://////", "resource:///" },
275     { "resource:///../../../", "resource:///" },
276     { "resource:///../../..", "resource:///" },
277     { "resource://abc", "resource:///abc" },
278     { "resource:///abc/", "resource:///abc" },
279     { "resource:/a/b/../c/", "resource:///a/c" },
280     { "resource://../a/b/../c/../", "resource:///a" },
281     { "resource://a/b/cc//bb//a///", "resource:///a/b/cc/bb/a" },
282     { "resource://././././", "resource:///" },
283     { "resource://././././../", "resource:///" },
284     { "resource://a/b/c/d.png", "resource:///a/b/c/d.png" },
285     { "resource://a/b/c/..png", "resource:///a/b/c/..png" },
286     { "resource://a/b/c/./png", "resource:///a/b/c/png" },
287   };
288   guint i;
289 
290   for (i = 0; i < G_N_ELEMENTS (test_uris); i++)
291     {
292       GFile *file;
293       gchar *uri;
294 
295       file = g_file_new_for_uri (test_uris[i].input);
296       g_assert (file != NULL);
297 
298       uri = g_file_get_uri (file);
299       g_assert (uri != NULL);
300 
301       g_assert_cmpstr (uri, ==, test_uris[i].expected);
302 
303       g_object_unref (file);
304       g_free (uri);
305     }
306 }
307 
308 static void
test_resource_data(void)309 test_resource_data (void)
310 {
311   GResource *resource;
312   GError *error = NULL;
313   gboolean loaded_file;
314   char *content;
315   gsize content_size;
316   GBytes *data;
317 
318   loaded_file = g_file_get_contents (g_test_get_filename (G_TEST_BUILT, "test.gresource", NULL),
319                                      &content, &content_size, NULL);
320   g_assert (loaded_file);
321 
322   data = g_bytes_new_take (content, content_size);
323   resource = g_resource_new_from_data (data, &error);
324   g_bytes_unref (data);
325   g_assert (resource != NULL);
326   g_assert_no_error (error);
327 
328   test_resource (resource);
329 
330   g_resource_unref (resource);
331 }
332 
333 static void
test_resource_data_unaligned(void)334 test_resource_data_unaligned (void)
335 {
336   GResource *resource;
337   GError *error = NULL;
338   gboolean loaded_file;
339   char *content, *content_copy;
340   gsize content_size;
341   GBytes *data;
342 
343   loaded_file = g_file_get_contents (g_test_get_filename (G_TEST_BUILT, "test.gresource", NULL),
344                                      &content, &content_size, NULL);
345   g_assert (loaded_file);
346 
347   content_copy = g_new (char, content_size + 1);
348   memcpy (content_copy + 1, content, content_size);
349 
350   data = g_bytes_new_with_free_func (content_copy + 1, content_size,
351                                      (GDestroyNotify) g_free, content_copy);
352   g_free (content);
353   resource = g_resource_new_from_data (data, &error);
354   g_bytes_unref (data);
355   g_assert (resource != NULL);
356   g_assert_no_error (error);
357 
358   test_resource (resource);
359 
360   g_resource_unref (resource);
361 }
362 
363 /* Test error handling for corrupt GResource files (specifically, a corrupt
364  * GVDB header). */
365 static void
test_resource_data_corrupt(void)366 test_resource_data_corrupt (void)
367 {
368   /* A GVDB header is 6 guint32s, and requires a magic number in the first two
369    * guint32s. A set of zero bytes of a greater length is considered corrupt. */
370   static const guint8 data[sizeof (guint32) * 7] = { 0, };
371   GBytes *bytes = NULL;
372   GResource *resource = NULL;
373   GError *local_error = NULL;
374 
375   bytes = g_bytes_new_static (data, sizeof (data));
376   resource = g_resource_new_from_data (bytes, &local_error);
377   g_bytes_unref (bytes);
378   g_assert_error (local_error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_INTERNAL);
379   g_assert_null (resource);
380 
381   g_clear_error (&local_error);
382 }
383 
384 /* Test handling for empty GResource files. They should also be treated as
385  * corrupt. */
386 static void
test_resource_data_empty(void)387 test_resource_data_empty (void)
388 {
389   GBytes *bytes = NULL;
390   GResource *resource = NULL;
391   GError *local_error = NULL;
392 
393   bytes = g_bytes_new_static (NULL, 0);
394   resource = g_resource_new_from_data (bytes, &local_error);
395   g_bytes_unref (bytes);
396   g_assert_error (local_error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_INTERNAL);
397   g_assert_null (resource);
398 
399   g_clear_error (&local_error);
400 }
401 
402 static void
test_resource_registered(void)403 test_resource_registered (void)
404 {
405   GResource *resource;
406   GError *error = NULL;
407   gboolean found, success;
408   gsize size;
409   guint32 flags;
410   GBytes *data;
411   char **children;
412   GInputStream *in;
413   char buffer[128];
414 
415   resource = g_resource_load (g_test_get_filename (G_TEST_BUILT, "test.gresource", NULL), &error);
416   g_assert (resource != NULL);
417   g_assert_no_error (error);
418 
419   found = g_resources_get_info ("/test1.txt",
420 				G_RESOURCE_LOOKUP_FLAGS_NONE,
421 				&size, &flags, &error);
422   g_assert (!found);
423   g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
424   g_clear_error (&error);
425 
426   g_resources_register (resource);
427 
428   found = g_resources_get_info ("/test1.txt",
429 				G_RESOURCE_LOOKUP_FLAGS_NONE,
430 				&size, &flags, &error);
431   g_assert (found);
432   g_assert_no_error (error);
433   g_assert_cmpint (size, ==, 6);
434   g_assert (flags == (G_RESOURCE_FLAGS_COMPRESSED));
435 
436   found = g_resources_get_info ("/empty.txt",
437                                 G_RESOURCE_LOOKUP_FLAGS_NONE,
438                                 &size, &flags, &error);
439   g_assert_no_error (error);
440   g_assert_true (found);
441   g_assert_cmpint (size, ==, 0);
442   g_assert (flags == (G_RESOURCE_FLAGS_COMPRESSED));
443 
444   found = g_resources_get_info ("/a_prefix/test2.txt",
445 				G_RESOURCE_LOOKUP_FLAGS_NONE,
446 				&size, &flags, &error);
447   g_assert (found);
448   g_assert_no_error (error);
449   g_assert_cmpint (size, ==, 6);
450   g_assert_cmpint (flags, ==, 0);
451 
452   found = g_resources_get_info ("/a_prefix/test2-alias.txt",
453 				G_RESOURCE_LOOKUP_FLAGS_NONE,
454 				&size, &flags, &error);
455   g_assert (found);
456   g_assert_no_error (error);
457   g_assert_cmpint (size, ==, 6);
458   g_assert_cmpuint (flags, ==, 0);
459 
460   data = g_resources_lookup_data ("/test1.txt",
461 				  G_RESOURCE_LOOKUP_FLAGS_NONE,
462 				  &error);
463   g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n");
464   g_assert_no_error (error);
465   g_bytes_unref (data);
466 
467   in = g_resources_open_stream ("/test1.txt",
468 				G_RESOURCE_LOOKUP_FLAGS_NONE,
469 				&error);
470   g_assert (in != NULL);
471   g_assert_no_error (error);
472 
473   success = g_input_stream_read_all (in, buffer, sizeof (buffer) - 1,
474 				     &size,
475 				     NULL, &error);
476   g_assert (success);
477   g_assert_no_error (error);
478   g_assert_cmpint (size, ==, 6);
479   buffer[size] = 0;
480   g_assert_cmpstr (buffer, ==, "test1\n");
481 
482   g_input_stream_close (in, NULL, &error);
483   g_assert_no_error (error);
484   g_clear_object (&in);
485 
486   data = g_resources_lookup_data ("/empty.txt",
487                                   G_RESOURCE_LOOKUP_FLAGS_NONE,
488                                   &error);
489   g_assert_no_error (error);
490   g_assert_cmpuint (g_bytes_get_size (data), ==, 0);
491   g_bytes_unref (data);
492 
493   in = g_resources_open_stream ("/empty.txt",
494                                 G_RESOURCE_LOOKUP_FLAGS_NONE,
495                                 &error);
496   g_assert_no_error (error);
497   g_assert_nonnull (in);
498 
499   success = g_input_stream_read_all (in, buffer, sizeof (buffer) - 1,
500                                      &size,
501                                      NULL, &error);
502   g_assert_no_error (error);
503   g_assert_true (success);
504   g_assert_cmpint (size, ==, 0);
505 
506   g_input_stream_close (in, NULL, &error);
507   g_assert_no_error (error);
508   g_clear_object (&in);
509 
510   data = g_resources_lookup_data ("/a_prefix/test2.txt",
511 				  G_RESOURCE_LOOKUP_FLAGS_NONE,
512 				  &error);
513   g_assert (data != NULL);
514   g_assert_no_error (error);
515   size = g_bytes_get_size (data);
516   g_assert_cmpint (size, ==, 6);
517   g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test2\n");
518   g_bytes_unref (data);
519 
520   data = g_resources_lookup_data ("/a_prefix/test2-alias.txt",
521 				  G_RESOURCE_LOOKUP_FLAGS_NONE,
522 				  &error);
523   g_assert (data != NULL);
524   g_assert_no_error (error);
525   size = g_bytes_get_size (data);
526   g_assert_cmpint (size, ==, 6);
527   g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test2\n");
528   g_bytes_unref (data);
529 
530   children = g_resources_enumerate_children ("/not/here",
531 					     G_RESOURCE_LOOKUP_FLAGS_NONE,
532 					     &error);
533   g_assert (children == NULL);
534   g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
535   g_clear_error (&error);
536 
537   children = g_resources_enumerate_children ("/a_prefix",
538 					     G_RESOURCE_LOOKUP_FLAGS_NONE,
539 					     &error);
540   g_assert (children != NULL);
541   g_assert_no_error (error);
542   g_assert_cmpint (g_strv_length (children), ==, 2);
543   g_strfreev (children);
544 
545   g_resources_unregister (resource);
546   g_resource_unref (resource);
547 
548   found = g_resources_get_info ("/test1.txt",
549 				G_RESOURCE_LOOKUP_FLAGS_NONE,
550 				&size, &flags, &error);
551   g_assert (!found);
552   g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
553   g_clear_error (&error);
554 }
555 
556 static void
test_resource_automatic(void)557 test_resource_automatic (void)
558 {
559   GError *error = NULL;
560   gboolean found;
561   gsize size;
562   guint32 flags;
563   GBytes *data;
564 
565   found = g_resources_get_info ("/auto_loaded/test1.txt",
566 				G_RESOURCE_LOOKUP_FLAGS_NONE,
567 				&size, &flags, &error);
568   g_assert (found);
569   g_assert_no_error (error);
570   g_assert_cmpint (size, ==, 6);
571   g_assert_cmpint (flags, ==, 0);
572 
573   data = g_resources_lookup_data ("/auto_loaded/test1.txt",
574 				  G_RESOURCE_LOOKUP_FLAGS_NONE,
575 				  &error);
576   g_assert (data != NULL);
577   g_assert_no_error (error);
578   size = g_bytes_get_size (data);
579   g_assert_cmpint (size, ==, 6);
580   g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n");
581   g_bytes_unref (data);
582 }
583 
584 static void
test_resource_manual(void)585 test_resource_manual (void)
586 {
587   GError *error = NULL;
588   gboolean found;
589   gsize size;
590   guint32 flags;
591   GBytes *data;
592 
593   found = g_resources_get_info ("/manual_loaded/test1.txt",
594 				G_RESOURCE_LOOKUP_FLAGS_NONE,
595 				&size, &flags, &error);
596   g_assert (found);
597   g_assert_no_error (error);
598   g_assert_cmpint (size, ==, 6);
599   g_assert_cmpuint (flags, ==, 0);
600 
601   data = g_resources_lookup_data ("/manual_loaded/test1.txt",
602 				  G_RESOURCE_LOOKUP_FLAGS_NONE,
603 				  &error);
604   g_assert (data != NULL);
605   g_assert_no_error (error);
606   size = g_bytes_get_size (data);
607   g_assert_cmpint (size, ==, 6);
608   g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n");
609   g_bytes_unref (data);
610 }
611 
612 static void
test_resource_manual2(void)613 test_resource_manual2 (void)
614 {
615   GResource *resource;
616   GBytes *data;
617   gsize size;
618   GError *error = NULL;
619 
620   resource = _g_test2_get_resource ();
621 
622   data = g_resource_lookup_data (resource,
623                                  "/manual_loaded/test1.txt",
624 				 G_RESOURCE_LOOKUP_FLAGS_NONE,
625 				 &error);
626   g_assert (data != NULL);
627   g_assert_no_error (error);
628   size = g_bytes_get_size (data);
629   g_assert_cmpint (size, ==, 6);
630   g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n");
631   g_bytes_unref (data);
632 
633   g_resource_unref (resource);
634 }
635 
636 /* Test building resources with external data option,
637  * where data is linked in as binary instead of compiled in.
638  * Checks if resources are automatically registered and
639  * data can be found and read. */
640 static void
test_resource_binary_linked(void)641 test_resource_binary_linked (void)
642 {
643   #ifndef __linux__
644   g_test_skip ("--external-data test only works on Linux");
645   return;
646   #else /* if __linux__ */
647   GError *error = NULL;
648   gboolean found;
649   gsize size;
650   guint32 flags;
651   GBytes *data;
652 
653   found = g_resources_get_info ("/binary_linked/test1.txt",
654 				G_RESOURCE_LOOKUP_FLAGS_NONE,
655 				&size, &flags, &error);
656   g_assert_true (found);
657   g_assert_no_error (error);
658   g_assert_cmpint (size, ==, 6);
659   g_assert_cmpuint (flags, ==, 0);
660 
661   data = g_resources_lookup_data ("/binary_linked/test1.txt",
662 				  G_RESOURCE_LOOKUP_FLAGS_NONE,
663 				  &error);
664   g_assert_nonnull (data);
665   g_assert_no_error (error);
666   size = g_bytes_get_size (data);
667   g_assert_cmpint (size, ==, 6);
668   g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n");
669   g_bytes_unref (data);
670   #endif /* if __linux__ */
671 }
672 
673 /* Test resource whose xml file starts with more than one digit
674  * and where no explicit c-name is given
675  * Checks if resources are successfully registered and
676  * data can be found and read. */
677 static void
test_resource_digits(void)678 test_resource_digits (void)
679 {
680   GError *error = NULL;
681   gboolean found;
682   gsize size;
683   guint32 flags;
684   GBytes *data;
685 
686   found = g_resources_get_info ("/digit_test/test1.txt",
687 				G_RESOURCE_LOOKUP_FLAGS_NONE,
688 				&size, &flags, &error);
689   g_assert_true (found);
690   g_assert_no_error (error);
691   g_assert_cmpint (size, ==, 6);
692   g_assert_cmpuint (flags, ==, 0);
693 
694   data = g_resources_lookup_data ("/digit_test/test1.txt",
695 				  G_RESOURCE_LOOKUP_FLAGS_NONE,
696 				  &error);
697   g_assert_nonnull (data);
698   g_assert_no_error (error);
699   size = g_bytes_get_size (data);
700   g_assert_cmpint (size, ==, 6);
701   g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n");
702   g_bytes_unref (data);
703 }
704 
705 static void
test_resource_module(void)706 test_resource_module (void)
707 {
708   GIOModule *module;
709   gboolean found;
710   gsize size;
711   guint32 flags;
712   GBytes *data;
713   GError *error;
714 
715 #ifdef GLIB_STATIC_COMPILATION
716   /* The resource module is statically linked with a separate copy
717    * of a GLib so g_static_resource_init won't work as expected. */
718   g_test_skip ("Resource modules aren't supported in static builds.");
719   return;
720 #endif
721 
722   if (g_module_supported ())
723     {
724       module = g_io_module_new (g_test_get_filename (G_TEST_BUILT,
725                                                      MODULE_FILENAME_PREFIX "resourceplugin",
726                                                      NULL));
727 
728       error = NULL;
729 
730       found = g_resources_get_info ("/resourceplugin/test1.txt",
731 				    G_RESOURCE_LOOKUP_FLAGS_NONE,
732 				    &size, &flags, &error);
733       g_assert (!found);
734       g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
735       g_clear_error (&error);
736 
737       g_type_module_use (G_TYPE_MODULE (module));
738 
739       found = g_resources_get_info ("/resourceplugin/test1.txt",
740 				    G_RESOURCE_LOOKUP_FLAGS_NONE,
741 				    &size, &flags, &error);
742       g_assert (found);
743       g_assert_no_error (error);
744       g_assert_cmpint (size, ==, 6);
745       g_assert_cmpuint (flags, ==, 0);
746 
747       data = g_resources_lookup_data ("/resourceplugin/test1.txt",
748 				      G_RESOURCE_LOOKUP_FLAGS_NONE,
749 				      &error);
750       g_assert (data != NULL);
751       g_assert_no_error (error);
752       size = g_bytes_get_size (data);
753       g_assert_cmpint (size, ==, 6);
754       g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n");
755       g_bytes_unref (data);
756 
757       g_type_module_unuse (G_TYPE_MODULE (module));
758 
759       found = g_resources_get_info ("/resourceplugin/test1.txt",
760 				    G_RESOURCE_LOOKUP_FLAGS_NONE,
761 				    &size, &flags, &error);
762       g_assert (!found);
763       g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
764       g_clear_error (&error);
765     }
766 }
767 
768 static void
test_uri_query_info(void)769 test_uri_query_info (void)
770 {
771   GResource *resource;
772   GError *error = NULL;
773   gboolean loaded_file;
774   char *content;
775   gsize content_size;
776   GBytes *data;
777   GFile *file;
778   GFileInfo *info;
779   const char *content_type;
780   gchar *mime_type = NULL;
781   const char *fs_type;
782   gboolean readonly;
783 
784   loaded_file = g_file_get_contents (g_test_get_filename (G_TEST_BUILT, "test.gresource", NULL),
785                                      &content, &content_size, NULL);
786   g_assert (loaded_file);
787 
788   data = g_bytes_new_take (content, content_size);
789   resource = g_resource_new_from_data (data, &error);
790   g_bytes_unref (data);
791   g_assert (resource != NULL);
792   g_assert_no_error (error);
793 
794   g_resources_register (resource);
795 
796   file = g_file_new_for_uri ("resource://" "/a_prefix/test2-alias.txt");
797   info = g_file_query_info (file, "*", 0, NULL, &error);
798   g_assert_no_error (error);
799 
800   content_type = g_file_info_get_content_type (info);
801   g_assert (content_type);
802   mime_type = g_content_type_get_mime_type (content_type);
803   g_assert (mime_type);
804   g_assert_cmpstr (mime_type, ==, "text/plain");
805   g_free (mime_type);
806 
807   g_object_unref (info);
808 
809   info = g_file_query_filesystem_info (file, "*", NULL, &error);
810   g_assert_no_error (error);
811 
812   fs_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE);
813   g_assert_cmpstr (fs_type, ==, "resource");
814   readonly = g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY);
815   g_assert_true (readonly);
816 
817   g_object_unref (info);
818 
819   g_assert_cmpuint  (g_file_hash (file), !=, 0);
820 
821   g_object_unref (file);
822 
823   g_resources_unregister (resource);
824   g_resource_unref (resource);
825 }
826 
827 static void
test_uri_file(void)828 test_uri_file (void)
829 {
830   GResource *resource;
831   GError *error = NULL;
832   gboolean loaded_file;
833   char *content;
834   gsize content_size;
835   GBytes *data;
836   GFile *file;
837   GFileInfo *info;
838   gchar *name;
839   GFile *file2, *parent;
840   GFileEnumerator *enumerator;
841   gchar *scheme;
842   GFileAttributeInfoList *attrs;
843   GInputStream *stream;
844   gchar buf[1024];
845   gboolean ret;
846   gssize skipped;
847 
848   loaded_file = g_file_get_contents (g_test_get_filename (G_TEST_BUILT, "test.gresource", NULL),
849                                      &content, &content_size, NULL);
850   g_assert (loaded_file);
851 
852   data = g_bytes_new_take (content, content_size);
853   resource = g_resource_new_from_data (data, &error);
854   g_bytes_unref (data);
855   g_assert (resource != NULL);
856   g_assert_no_error (error);
857 
858   g_resources_register (resource);
859 
860   file = g_file_new_for_uri ("resource://" "/a_prefix/test2-alias.txt");
861 
862   g_assert (g_file_get_path (file) == NULL);
863 
864   name = g_file_get_parse_name (file);
865   g_assert_cmpstr (name, ==, "resource:///a_prefix/test2-alias.txt");
866   g_free (name);
867 
868   name = g_file_get_uri (file);
869   g_assert_cmpstr (name, ==, "resource:///a_prefix/test2-alias.txt");
870   g_free (name);
871 
872   g_assert (!g_file_is_native (file));
873   g_assert (!g_file_has_uri_scheme (file, "http"));
874   g_assert (g_file_has_uri_scheme (file, "resource"));
875   scheme = g_file_get_uri_scheme (file);
876   g_assert_cmpstr (scheme, ==, "resource");
877   g_free (scheme);
878 
879   file2 = g_file_dup (file);
880   g_assert (g_file_equal (file, file2));
881   g_object_unref (file2);
882 
883   parent = g_file_get_parent (file);
884   enumerator = g_file_enumerate_children (parent, G_FILE_ATTRIBUTE_STANDARD_NAME, 0, NULL, &error);
885   g_assert_no_error (error);
886 
887   file2 = g_file_get_child_for_display_name (parent, "test2-alias.txt", &error);
888   g_assert_no_error (error);
889   g_assert (g_file_equal (file, file2));
890   g_object_unref (file2);
891 
892   info = g_file_enumerator_next_file (enumerator, NULL, &error);
893   g_assert_no_error (error);
894   g_assert (info != NULL);
895   g_object_unref (info);
896 
897   info = g_file_enumerator_next_file (enumerator, NULL, &error);
898   g_assert_no_error (error);
899   g_assert (info != NULL);
900   g_object_unref (info);
901 
902   info = g_file_enumerator_next_file (enumerator, NULL, &error);
903   g_assert_no_error (error);
904   g_assert (info == NULL);
905 
906   g_file_enumerator_close (enumerator, NULL, &error);
907   g_assert_no_error (error);
908   g_object_unref (enumerator);
909 
910   file2 = g_file_new_for_uri ("resource://" "a_prefix/../a_prefix//test2-alias.txt");
911   g_assert (g_file_equal (file, file2));
912 
913   g_assert (g_file_has_prefix (file, parent));
914 
915   name = g_file_get_relative_path (parent, file);
916   g_assert_cmpstr (name, ==, "test2-alias.txt");
917   g_free (name);
918 
919   g_object_unref (parent);
920 
921   attrs = g_file_query_settable_attributes (file, NULL, &error);
922   g_assert_no_error (error);
923   g_file_attribute_info_list_unref (attrs);
924 
925   attrs = g_file_query_writable_namespaces (file, NULL, &error);
926   g_assert_no_error (error);
927   g_file_attribute_info_list_unref (attrs);
928 
929   stream = G_INPUT_STREAM (g_file_read (file, NULL, &error));
930   g_assert_no_error (error);
931   g_assert_cmpint (g_seekable_tell (G_SEEKABLE (stream)), ==, 0);
932   g_assert (g_seekable_can_seek (G_SEEKABLE (G_SEEKABLE (stream))));
933   ret = g_seekable_seek (G_SEEKABLE (stream), 1, G_SEEK_SET, NULL, &error);
934   g_assert (ret);
935   g_assert_no_error (error);
936   skipped = g_input_stream_skip (stream, 1, NULL, &error);
937   g_assert_cmpint (skipped, ==, 1);
938   g_assert_no_error (error);
939 
940   memset (buf, 0, 1024);
941   ret = g_input_stream_read_all (stream, &buf, 1024, NULL, NULL, &error);
942   g_assert (ret);
943   g_assert_no_error (error);
944   g_assert_cmpstr (buf, ==, "st2\n");
945   info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (stream),
946                                          G_FILE_ATTRIBUTE_STANDARD_SIZE,
947                                          NULL,
948                                          &error);
949   g_assert_no_error (error);
950   g_assert (info != NULL);
951   g_assert_cmpint (g_file_info_get_size (info), ==, 6);
952   g_object_unref (info);
953 
954   ret = g_input_stream_close (stream, NULL, &error);
955   g_assert (ret);
956   g_assert_no_error (error);
957   g_object_unref (stream);
958 
959   g_object_unref (file);
960   g_object_unref (file2);
961 
962   g_resources_unregister (resource);
963   g_resource_unref (resource);
964 }
965 
966 static void
test_resource_64k(void)967 test_resource_64k (void)
968 {
969   GError *error = NULL;
970   gboolean found;
971   gsize size;
972   guint32 flags;
973   GBytes *data;
974   gchar **tokens;
975 
976   found = g_resources_get_info ("/big_prefix/gresource-big-test.txt",
977 				G_RESOURCE_LOOKUP_FLAGS_NONE,
978 				&size, &flags, &error);
979   g_assert_true (found);
980   g_assert_no_error (error);
981 
982   /* Check size: 100 of all lower case letters + newline char +
983    *             100 all upper case letters + newline char +
984    *             100 of all numbers between 0 to 9 + newline char
985    *             (for 12 iterations)
986    */
987 
988   g_assert_cmpint (size, ==, (26 + 26 + 10) * (100 + 1) * 12);
989   g_assert_cmpuint (flags, ==, 0);
990   data = g_resources_lookup_data ("/big_prefix/gresource-big-test.txt",
991 				  G_RESOURCE_LOOKUP_FLAGS_NONE,
992 				  &error);
993   g_assert_nonnull (data);
994   g_assert_no_error (error);
995   size = g_bytes_get_size (data);
996 
997   g_assert_cmpint (size, ==, (26 + 26 + 10) * (100 + 1) * 12);
998   tokens = g_strsplit ((const gchar *) g_bytes_get_data (data, NULL), "\n", -1);
999 
1000   /* check tokens[x] == entry at gresource-big-test.txt's line, where x = line - 1 */
1001   g_assert_cmpstr (tokens[0], ==, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
1002   g_assert_cmpstr (tokens[27], ==, "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB");
1003   g_assert_cmpstr (tokens[183], ==, "7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777");
1004   g_assert_cmpstr (tokens[600], ==, "QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ");
1005   g_assert_cmpstr (tokens[742], ==, "8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888");
1006   g_strfreev (tokens);
1007   g_bytes_unref (data);
1008 }
1009 
1010 /* Check that g_resources_get_info() respects G_RESOURCE_OVERLAYS */
1011 static void
test_overlay(void)1012 test_overlay (void)
1013 {
1014   if (g_test_subprocess ())
1015     {
1016        GError *error = NULL;
1017        gboolean res;
1018        gsize size;
1019        char *overlay;
1020        char *path;
1021 
1022        path = g_test_build_filename (G_TEST_DIST, "test1.overlay", NULL);
1023        overlay = g_strconcat ("/auto_loaded/test1.txt=", path, NULL);
1024 
1025        g_setenv ("G_RESOURCE_OVERLAYS", overlay, TRUE);
1026        res = g_resources_get_info ("/auto_loaded/test1.txt", 0, &size, NULL, &error);
1027        g_assert_true (res);
1028        g_assert_no_error (error);
1029        /* test1.txt is 6 bytes, test1.overlay is 23 */
1030        g_assert_cmpint (size, ==, 23);
1031 
1032        g_free (overlay);
1033        g_free (path);
1034 
1035        return;
1036     }
1037   g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_INHERIT_STDERR);
1038   g_test_trap_assert_passed ();
1039 }
1040 
1041 int
main(int argc,char * argv[])1042 main (int   argc,
1043       char *argv[])
1044 {
1045   g_test_init (&argc, &argv, NULL);
1046 
1047   _g_test2_register_resource ();
1048   _digit_test_register_resource ();
1049 
1050   g_test_add_func ("/resource/file", test_resource_file);
1051   g_test_add_func ("/resource/file-path", test_resource_file_path);
1052   g_test_add_func ("/resource/data", test_resource_data);
1053   g_test_add_func ("/resource/data_unaligned", test_resource_data_unaligned);
1054   g_test_add_func ("/resource/data-corrupt", test_resource_data_corrupt);
1055   g_test_add_func ("/resource/data-empty", test_resource_data_empty);
1056   g_test_add_func ("/resource/registered", test_resource_registered);
1057   g_test_add_func ("/resource/manual", test_resource_manual);
1058   g_test_add_func ("/resource/manual2", test_resource_manual2);
1059 #ifdef G_HAS_CONSTRUCTORS
1060   g_test_add_func ("/resource/automatic", test_resource_automatic);
1061   /* This only uses automatic resources too, so it tests the constructors and destructors */
1062   g_test_add_func ("/resource/module", test_resource_module);
1063   g_test_add_func ("/resource/binary-linked", test_resource_binary_linked);
1064 #endif
1065   g_test_add_func ("/resource/uri/query-info", test_uri_query_info);
1066   g_test_add_func ("/resource/uri/file", test_uri_file);
1067   g_test_add_func ("/resource/64k", test_resource_64k);
1068   g_test_add_func ("/resource/overlay", test_overlay);
1069   g_test_add_func ("/resource/digits", test_resource_digits);
1070 
1071   return g_test_run();
1072 }
1073