1 #include <sys/types.h>
2 #include <sys/stat.h>
3 #include <unistd.h>
4 #include <fcntl.h>
5 
6 #include "testsys.h"
7 #include "fixtures.h"
8 #include "test_metalink.h"
9 #include "librepo/rcodes.h"
10 #include "librepo/types.h"
11 #include "librepo/metalink.h"
12 #include "librepo/util.h"
13 
14 #define REPOMD              "repomd.xml"
15 #define METALINK_DIR        "metalinks"
16 
17 /* metalink_good_*
18  *      This metalink files shoud be always parsed without problems.
19  * metalink_bad_*
20  *      This metalink files are no valid, but parser could/should be
21  *      able parse it without returning (raising) an error.
22  *      But this behaviour could change in future releases.
23  *  metalink_really_bad_*
24  *      This files are invalid and shoudn't and parsing shoud raise an error.
25  **/
26 
START_TEST(test_metalink_init)27 START_TEST(test_metalink_init)
28 {
29     LrMetalink *ml = NULL;
30 
31     ml = lr_metalink_init();
32     ck_assert_ptr_nonnull(ml);
33     lr_metalink_free(ml);
34 }
35 END_TEST
36 
START_TEST(test_metalink_good_01)37 START_TEST(test_metalink_good_01)
38 {
39     int fd;
40     gboolean ret;
41     char *path;
42     LrMetalink *ml = NULL;
43     LrMetalinkHash *mlhash = NULL;
44     LrMetalinkUrl *mlurl = NULL;
45     GSList *elem = NULL;
46     GError *tmp_err = NULL;
47 
48     path = lr_pathconcat(test_globals.testdata_dir, METALINK_DIR,
49                          "metalink_good_01", NULL);
50     fd = open(path, O_RDONLY);
51     lr_free(path);
52     ck_assert_int_ge(fd, 0);
53     ml = lr_metalink_init();
54     ck_assert_ptr_nonnull(ml);
55     ret = lr_metalink_parse_file(ml, fd, REPOMD, NULL, NULL, &tmp_err);
56     ck_assert(ret);
57     ck_assert_ptr_null(tmp_err);
58     close(fd);
59 
60     ck_assert_ptr_nonnull(ml->filename);
61     ck_assert_str_eq(ml->filename, "repomd.xml");
62     ck_assert(ml->timestamp == 1337942396);
63     ck_assert(ml->size == 4309);
64     ck_assert(g_slist_length(ml->hashes) == 4);
65     ck_assert(g_slist_length(ml->urls) == 106);
66 
67     elem = g_slist_nth(ml->hashes, 0);
68     ck_assert_ptr_nonnull(elem);
69     mlhash = elem->data;
70     ck_assert_ptr_nonnull(mlhash);
71     ck_assert_ptr_nonnull(mlhash->type);
72     ck_assert_str_eq(mlhash->type, "md5");
73     ck_assert_ptr_nonnull(mlhash->value);
74     ck_assert_str_eq(mlhash->value, "20b6d77930574ae541108e8e7987ad3f");
75 
76     elem = g_slist_nth(ml->hashes, 1);
77     ck_assert_ptr_nonnull(elem);
78     mlhash = elem->data;
79     ck_assert_ptr_nonnull(mlhash);
80     ck_assert_ptr_nonnull(mlhash->type);
81     ck_assert_str_eq(mlhash->type, "sha1");
82     ck_assert_ptr_nonnull(mlhash->value);
83     ck_assert_str_eq(mlhash->value, "4a5ae1831a567b58e2e0f0de1529ca199d1d8319");
84 
85     elem = g_slist_nth(ml->hashes, 2);
86     ck_assert_ptr_nonnull(elem);
87     mlhash = elem->data;
88     ck_assert_ptr_nonnull(mlhash);
89     ck_assert_ptr_nonnull(mlhash->type);
90     ck_assert_str_eq(mlhash->type, "sha256");
91     ck_assert_ptr_nonnull(mlhash->value);
92     ck_assert_str_eq(mlhash->value, "0076c44aabd352da878d5c4d794901ac87f66afac869488f6a4ef166de018cdf");
93 
94     elem = g_slist_nth(ml->hashes, 3);
95     ck_assert_ptr_nonnull(elem);
96     mlhash = elem->data;
97     ck_assert_ptr_nonnull(mlhash);
98     ck_assert_ptr_nonnull(mlhash->type);
99     ck_assert_str_eq(mlhash->type, "sha512");
100     ck_assert_ptr_nonnull(mlhash->value);
101     ck_assert_str_eq(mlhash->value, "884dc465da67fee8fe3f11dab321a99d9a13b22ce97f84ceff210e82b6b1a8c635ccd196add1dd738807686714c3a0a048897e2d0650bc05302b3ee26de521fd");
102 
103     elem = g_slist_nth(ml->urls, 0);
104     ck_assert_ptr_nonnull(elem);
105     mlurl = elem->data;
106     ck_assert_ptr_nonnull(mlurl);
107     ck_assert_ptr_nonnull(mlurl->protocol);
108     ck_assert_str_eq(mlurl->protocol, "http");
109     ck_assert_ptr_nonnull(mlurl->type);
110     ck_assert_str_eq(mlurl->type, "http");
111     ck_assert_ptr_nonnull(mlurl->location);
112     ck_assert_str_eq(mlurl->location, "US");
113     ck_assert(mlurl->preference == 99);
114     ck_assert_ptr_nonnull(mlurl->url);
115     ck_assert_str_eq(mlurl->url,
116                    "http://mirror.pnl.gov/fedora/linux/releases/17/Everything/x86_64/os/repodata/repomd.xml");
117 
118     elem = g_slist_nth(ml->urls, 2);
119     ck_assert_ptr_nonnull(elem);
120     mlurl = elem->data;
121     ck_assert_ptr_nonnull(mlurl);
122     ck_assert_ptr_nonnull(mlurl->protocol);
123     ck_assert_str_eq(mlurl->protocol, "ftp");
124     ck_assert_ptr_nonnull(mlurl->type);
125     ck_assert_str_eq(mlurl->type, "ftp");
126     ck_assert_ptr_nonnull(mlurl->location);
127     ck_assert_str_eq(mlurl->location, "US");
128     ck_assert(mlurl->preference == 98);
129     ck_assert_ptr_nonnull(mlurl->url);
130     ck_assert_str_eq(mlurl->url,
131                    "ftp://mirrors.syringanetworks.net/fedora/releases/17/Everything/x86_64/os/repodata/repomd.xml");
132 
133     elem = g_slist_nth(ml->urls, 104);
134     ck_assert_ptr_nonnull(elem);
135     mlurl = elem->data;
136     ck_assert_ptr_nonnull(mlurl);
137     ck_assert_ptr_nonnull(mlurl->protocol);
138     ck_assert_str_eq(mlurl->protocol, "rsync");
139     ck_assert_ptr_nonnull(mlurl->type);
140     ck_assert_str_eq(mlurl->type, "rsync");
141     ck_assert_ptr_nonnull(mlurl->location);
142     ck_assert_str_eq(mlurl->location, "CA");
143     ck_assert(mlurl->preference == 48);
144     ck_assert_ptr_nonnull(mlurl->url);
145     ck_assert_str_eq(mlurl->url,
146                    "rsync://mirror.csclub.uwaterloo.ca/fedora-enchilada/linux/releases/17/Everything/x86_64/os/repodata/repomd.xml");
147 
148     lr_metalink_free(ml);
149 }
150 END_TEST
151 
START_TEST(test_metalink_good_02)152 START_TEST(test_metalink_good_02)
153 {
154     int fd;
155     gboolean ret;
156     char *path;
157     LrMetalink *ml = NULL;
158     GError *tmp_err = NULL;
159 
160     path = lr_pathconcat(test_globals.testdata_dir, METALINK_DIR,
161                          "metalink_good_02", NULL);
162     fd = open(path, O_RDONLY);
163     lr_free(path);
164     ck_assert_int_ge(fd, 0);
165     ml = lr_metalink_init();
166     ck_assert_ptr_nonnull(ml);
167     ret = lr_metalink_parse_file(ml, fd, REPOMD, NULL, NULL, &tmp_err);
168     ck_assert(ret);
169     ck_assert_ptr_null(tmp_err);
170     close(fd);
171 
172     ck_assert_ptr_nonnull(ml->filename);
173     ck_assert_str_eq(ml->filename, "repomd.xml");
174     ck_assert(ml->timestamp == 0);
175     ck_assert(ml->size == 0);
176     ck_assert(g_slist_length(ml->hashes) == 0);
177     ck_assert(g_slist_length(ml->urls) == 3);
178 
179     GSList *list = g_slist_nth(ml->urls, 0);
180     ck_assert_ptr_nonnull(list);
181     LrMetalinkUrl *mlurl = list->data;
182     ck_assert_ptr_nonnull(mlurl);
183     ck_assert_ptr_nonnull(mlurl->protocol);
184     ck_assert_str_eq(mlurl->protocol, "http");
185     ck_assert_ptr_nonnull(mlurl->type);
186     ck_assert_str_eq(mlurl->type, "http");
187     ck_assert_ptr_nonnull(mlurl->location);
188     ck_assert_str_eq(mlurl->location, "US");
189     ck_assert(mlurl->preference == 97);
190     ck_assert_ptr_nonnull(mlurl->url);
191     ck_assert_str_eq(mlurl->url,
192                    "http://mirror.pnl.gov/fedora/linux/releases/17/Everything/x86_64/os/repodata/repomd.xml");
193 
194     lr_metalink_free(ml);
195 }
196 END_TEST
197 
START_TEST(test_metalink_good_03)198 START_TEST(test_metalink_good_03)
199 {
200     int fd;
201     gboolean ret;
202     char *path;
203     LrMetalink *ml = NULL;
204     GError *tmp_err = NULL;
205 
206     path = lr_pathconcat(test_globals.testdata_dir, METALINK_DIR,
207                          "metalink_good_03", NULL);
208     fd = open(path, O_RDONLY);
209     lr_free(path);
210     ck_assert_int_ge(fd, 0);
211     ml = lr_metalink_init();
212     ck_assert_ptr_nonnull(ml);
213     ret = lr_metalink_parse_file(ml, fd, REPOMD, NULL, NULL, &tmp_err);
214     ck_assert(ret);
215     ck_assert_ptr_null(tmp_err);
216     close(fd);
217 
218     ck_assert_ptr_nonnull(ml->filename);
219     ck_assert_str_eq(ml->filename, "repomd.xml");
220     ck_assert(ml->timestamp == 0);
221     ck_assert(ml->size == 0);
222     ck_assert(g_slist_length(ml->hashes) == 0);
223     ck_assert(g_slist_length(ml->urls) == 0);
224 
225     lr_metalink_free(ml);
226 }
227 END_TEST
228 
229 static int
warning_cb(LrXmlParserWarningType type G_GNUC_UNUSED,char * msg G_GNUC_UNUSED,void * cbdata,GError ** err G_GNUC_UNUSED)230 warning_cb(LrXmlParserWarningType type G_GNUC_UNUSED,
231            char *msg G_GNUC_UNUSED,
232            void *cbdata,
233            GError **err G_GNUC_UNUSED)
234 {
235     *((int *) cbdata) += 1;
236     return LR_CB_RET_OK;
237 }
238 
START_TEST(test_metalink_bad_01)239 START_TEST(test_metalink_bad_01)
240 {
241     int fd;
242     gboolean ret;
243     char *path;
244     LrMetalink *ml = NULL;
245     LrMetalinkHash *mlhash = NULL;
246     LrMetalinkUrl *mlurl = NULL;
247     GSList *elem = NULL;
248     GError *tmp_err = NULL;
249 
250     path = lr_pathconcat(test_globals.testdata_dir, METALINK_DIR,
251                          "metalink_bad_01", NULL);
252     fd = open(path, O_RDONLY);
253     lr_free(path);
254     ck_assert_int_ge(fd, 0);
255     ml = lr_metalink_init();
256     ck_assert_ptr_nonnull(ml);
257     int call_counter = 0;
258     ret = lr_metalink_parse_file(ml, fd, REPOMD, warning_cb, &call_counter, &tmp_err);
259     ck_assert(ret);
260     ck_assert_ptr_null(tmp_err);
261     ck_assert_int_gt(call_counter, 0);
262     close(fd);
263 
264     ck_assert_ptr_nonnull(ml->filename);
265     ck_assert_str_eq(ml->filename, "repomd.xml");
266     ck_assert(ml->timestamp == 0);
267     ck_assert(ml->size == 0);
268     ck_assert(g_slist_length(ml->hashes) == 4);
269     ck_assert(g_slist_length(ml->urls) == 4);
270     ck_assert(g_slist_length(ml->alternates) == 0);
271 
272     elem = g_slist_nth(ml->hashes, 0);
273     ck_assert_ptr_nonnull(elem);
274     mlhash = elem->data;
275     ck_assert_ptr_nonnull(mlhash);
276     ck_assert_ptr_nonnull(mlhash->type);
277     ck_assert_str_eq(mlhash->type, "md5");
278     ck_assert_ptr_nonnull(mlhash->value);
279     ck_assert_str_eq(mlhash->value, "20b6d77930574ae541108e8e7987ad3f");
280 
281     elem = g_slist_nth(ml->hashes, 1);
282     ck_assert_ptr_nonnull(elem);
283     mlhash = elem->data;
284     ck_assert_ptr_nonnull(mlhash);
285     ck_assert_ptr_nonnull(mlhash->type);
286     ck_assert_str_eq(mlhash->type, "foo");
287     ck_assert_ptr_nonnull(mlhash->value);
288     ck_assert_str_eq(mlhash->value, "");
289 
290     elem = g_slist_nth(ml->hashes, 2);
291     ck_assert_ptr_nonnull(elem);
292     mlhash = elem->data;
293     ck_assert_ptr_nonnull(mlhash);
294     ck_assert_ptr_nonnull(mlhash->type);
295     ck_assert_str_eq(mlhash->type, "sha256");
296     ck_assert_ptr_nonnull(mlhash->value);
297     ck_assert_str_eq(mlhash->value, "0076c44aabd352da878d5c4d794901ac87f66afac869488f6a4ef166de018cdf");
298 
299     elem = g_slist_nth(ml->hashes, 3);
300     ck_assert_ptr_nonnull(elem);
301     mlhash = elem->data;
302     ck_assert_ptr_nonnull(mlhash);
303     ck_assert_ptr_nonnull(mlhash->type);
304     ck_assert_str_eq(mlhash->type, "sha512");
305     ck_assert_ptr_nonnull(mlhash->value);
306     ck_assert_str_eq(mlhash->value,
307                     "884dc465da67fee8fe3f11dab321a99d9a13b22ce97f84ceff210e82b6b1a8c635ccd196add1dd738807686714c3a0a048897e2d0650bc05302b3ee26de521fd");
308 
309     elem = g_slist_nth(ml->urls, 0);
310     ck_assert_ptr_nonnull(elem);
311     mlurl = elem->data;
312     ck_assert_ptr_nonnull(mlurl);
313     ck_assert_ptr_nonnull(mlurl->protocol);
314     ck_assert_str_eq(mlurl->protocol, "http");
315     ck_assert_ptr_nonnull(mlurl->type);
316     ck_assert_str_eq(mlurl->type, "http");
317     ck_assert_ptr_nonnull(mlurl->location);
318     ck_assert_str_eq(mlurl->location, "US");
319     ck_assert(mlurl->preference == 0);
320     ck_assert_ptr_nonnull(mlurl->url);
321     ck_assert_str_eq(mlurl->url,
322                    "http://mirror.pnl.gov/fedora/linux/releases/17/Everything/x86_64/os/repodata/repomd.xml");
323 
324     elem = g_slist_nth(ml->urls, 1);
325     ck_assert_ptr_nonnull(elem);
326     mlurl = elem->data;
327     ck_assert_ptr_nonnull(mlurl);
328     ck_assert_ptr_null(mlurl->protocol);
329     ck_assert_ptr_null(mlurl->type);
330     ck_assert_ptr_null(mlurl->location);
331     ck_assert(mlurl->preference >= 0 && mlurl->preference <= 100);
332     ck_assert_ptr_nonnull(mlurl->url);
333     ck_assert_str_eq(mlurl->url,
334                    "ftp://mirrors.syringanetworks.net/fedora/releases/17/Everything/x86_64/os/repodata/repomd.xml");
335 
336     elem = g_slist_nth(ml->urls, 2);
337     ck_assert_ptr_nonnull(elem);
338     mlurl = elem->data;
339     ck_assert_ptr_nonnull(mlurl);
340     ck_assert_ptr_null(mlurl->protocol);
341     ck_assert_ptr_null(mlurl->type);
342     ck_assert_ptr_null(mlurl->location);
343     ck_assert(mlurl->preference == 0);
344     ck_assert_ptr_nonnull(mlurl->url);
345     ck_assert_str_eq(mlurl->url,
346                    "rsync://mirrors.syringanetworks.net/fedora/releases/17/Everything/x86_64/os/repodata/repomd.xml");
347 
348     elem = g_slist_nth(ml->urls, 3);
349     ck_assert_ptr_nonnull(elem);
350     mlurl = elem->data;
351     ck_assert_ptr_nonnull(mlurl);
352     ck_assert_ptr_null(mlurl->protocol);
353     ck_assert_ptr_null(mlurl->type);
354     ck_assert_ptr_null(mlurl->location);
355     ck_assert(mlurl->preference == 0);
356     ck_assert_ptr_nonnull(mlurl->url);
357     ck_assert_str_eq(mlurl->url, "");
358 
359     lr_metalink_free(ml);
360 }
361 END_TEST
362 
START_TEST(test_metalink_bad_02)363 START_TEST(test_metalink_bad_02)
364 {
365     int fd;
366     gboolean ret;
367     char *path;
368     LrMetalink *ml = NULL;
369     GError *tmp_err = NULL;
370 
371     path = lr_pathconcat(test_globals.testdata_dir, METALINK_DIR,
372                          "metalink_bad_02", NULL);
373     fd = open(path, O_RDONLY);
374     lr_free(path);
375     ck_assert_int_ge(fd, 0);
376     ml = lr_metalink_init();
377     ck_assert_ptr_nonnull(ml);
378     ret = lr_metalink_parse_file(ml, fd, REPOMD, NULL, NULL, &tmp_err);
379     ck_assert(ret);
380     ck_assert_ptr_null(tmp_err);
381     close(fd);
382     ck_assert(g_slist_length(ml->urls) == 0);
383     lr_metalink_free(ml);
384 }
385 END_TEST
386 
START_TEST(test_metalink_really_bad_01)387 START_TEST(test_metalink_really_bad_01)
388 {
389     int fd;
390     gboolean ret;
391     char *path;
392     LrMetalink *ml = NULL;
393     GError *tmp_err = NULL;
394 
395     path = lr_pathconcat(test_globals.testdata_dir, METALINK_DIR,
396                          "metalink_really_bad_01", NULL);
397     fd = open(path, O_RDONLY);
398     lr_free(path);
399     ck_assert_int_ge(fd, 0);
400     ml = lr_metalink_init();
401     ck_assert_ptr_nonnull(ml);
402     ret = lr_metalink_parse_file(ml, fd, REPOMD, NULL, NULL, &tmp_err);
403     ck_assert(!ret);
404     ck_assert_ptr_nonnull(tmp_err);
405     g_error_free(tmp_err);
406     close(fd);
407     lr_metalink_free(ml);
408 }
409 END_TEST
410 
START_TEST(test_metalink_really_bad_02)411 START_TEST(test_metalink_really_bad_02)
412 {
413     int fd;
414     gboolean ret;
415     char *path;
416     LrMetalink *ml = NULL;
417     GError *tmp_err = NULL;
418 
419     path = lr_pathconcat(test_globals.testdata_dir, METALINK_DIR,
420                          "metalink_really_bad_02", NULL);
421     fd = open(path, O_RDONLY);
422     lr_free(path);
423     ck_assert_int_ge(fd, 0);
424     ml = lr_metalink_init();
425     ck_assert_ptr_nonnull(ml);
426     ret = lr_metalink_parse_file(ml, fd, REPOMD, NULL, NULL, &tmp_err);
427     ck_assert(!ret);
428     ck_assert_ptr_nonnull(tmp_err);
429     g_error_free(tmp_err);
430     close(fd);
431     lr_metalink_free(ml);
432 }
433 END_TEST
434 
START_TEST(test_metalink_really_bad_03)435 START_TEST(test_metalink_really_bad_03)
436 {
437     int fd;
438     gboolean ret;
439     char *path;
440     LrMetalink *ml = NULL;
441     GError *tmp_err = NULL;
442 
443     path = lr_pathconcat(test_globals.testdata_dir, METALINK_DIR,
444                          "metalink_really_bad_03", NULL);
445     fd = open(path, O_RDONLY);
446     lr_free(path);
447     ck_assert_int_ge(fd, 0);
448     ml = lr_metalink_init();
449     ck_assert_ptr_nonnull(ml);
450     ret = lr_metalink_parse_file(ml, fd, REPOMD, NULL, NULL, &tmp_err);
451     ck_assert(!ret);
452     ck_assert_ptr_nonnull(tmp_err);
453     g_error_free(tmp_err);
454     close(fd);
455     lr_metalink_free(ml);
456 }
457 END_TEST
458 
START_TEST(test_metalink_with_alternates)459 START_TEST(test_metalink_with_alternates)
460 {
461     int fd;
462     gboolean ret;
463     char *path;
464     LrMetalink *ml = NULL;
465     GSList *elem = NULL;
466     LrMetalinkHash *mlhash = NULL;
467     LrMetalinkAlternate *malternate = NULL;
468     GError *tmp_err = NULL;
469 
470     path = lr_pathconcat(test_globals.testdata_dir, METALINK_DIR,
471                          "metalink_with_alternates", NULL);
472     fd = open(path, O_RDONLY);
473     lr_free(path);
474     ck_assert_int_ge(fd, 0);
475     ml = lr_metalink_init();
476     ck_assert_ptr_nonnull(ml);
477     ret = lr_metalink_parse_file(ml, fd, REPOMD, NULL, NULL, &tmp_err);
478     ck_assert(ret);
479     ck_assert_ptr_null(tmp_err);
480     close(fd);
481 
482     ck_assert_ptr_nonnull(ml->filename);
483     ck_assert_str_eq(ml->filename, "repomd.xml");
484     ck_assert(g_slist_length(ml->hashes) == 4);
485     ck_assert(g_slist_length(ml->alternates) == 1);
486 
487     elem = g_slist_nth(ml->hashes, 0);
488     ck_assert_ptr_nonnull(elem);
489     mlhash = elem->data;
490     ck_assert_ptr_nonnull(mlhash);
491     ck_assert_ptr_nonnull(mlhash->type);
492     ck_assert_str_eq(mlhash->type, "md5");
493     ck_assert_ptr_nonnull(mlhash->value);
494     ck_assert_str_eq(mlhash->value, "0ffcd7798421c9a6760f3e4202cc4675");
495 
496     elem = g_slist_nth(ml->alternates, 0);
497     ck_assert_ptr_nonnull(elem);
498     malternate = elem->data;
499     ck_assert(malternate->timestamp == 1381706941);
500     ck_assert(malternate->size == 4761);
501     ck_assert(g_slist_length(malternate->hashes) == 4);
502     elem = g_slist_nth(malternate->hashes, 0);
503     mlhash = elem->data;
504     ck_assert_ptr_nonnull(mlhash);
505     ck_assert_ptr_nonnull(mlhash->type);
506     ck_assert_str_eq(mlhash->type, "md5");
507     ck_assert_ptr_nonnull(mlhash->value);
508     ck_assert_str_eq(mlhash->value, "0c5b64d395d5364633df7c8e97a07fd6");
509 
510     lr_metalink_free(ml);
511 }
512 END_TEST
513 
514 Suite *
metalink_suite(void)515 metalink_suite(void)
516 {
517     Suite *s = suite_create("metalink");
518     TCase *tc = tcase_create("Main");
519     tcase_add_test(tc, test_metalink_init);
520     tcase_add_test(tc, test_metalink_good_01);
521     tcase_add_test(tc, test_metalink_good_02);
522     tcase_add_test(tc, test_metalink_good_03);
523     tcase_add_test(tc, test_metalink_bad_01);
524     tcase_add_test(tc, test_metalink_bad_02);
525     tcase_add_test(tc, test_metalink_really_bad_01);
526     tcase_add_test(tc, test_metalink_really_bad_02);
527     tcase_add_test(tc, test_metalink_really_bad_03);
528     tcase_add_test(tc, test_metalink_with_alternates);
529     suite_add_tcase(s, tc);
530     return s;
531 }
532