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