1 /*
2  * Copyright (C) 2012-2015 Red Hat, Inc.
3  *
4  * Licensed under the GNU Lesser General Public License Version 2.1
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <check.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <sys/types.h>
26 
27 
28 #include <solv/testcase.h>
29 
30 #include <glib/gstdio.h>
31 
32 #include <libdnf/repo/Repo-private.hpp>
33 #include "libdnf/dnf-types.h"
34 #include "libdnf/hy-package-private.hpp"
35 #include "libdnf/hy-repo-private.hpp"
36 #include "libdnf/dnf-sack-private.hpp"
37 #include "libdnf/hy-util.h"
38 #include "libdnf/hy-iutil-private.hpp"
39 #include "fixtures.h"
40 #include "testsys.h"
41 #include "test_suites.h"
42 
START_TEST(test_environment)43 START_TEST(test_environment)
44 {
45     /* check the tmpdir was created */
46     fail_if(access(test_globals.tmpdir, W_OK));
47 }
48 END_TEST
49 
START_TEST(test_sack_create)50 START_TEST(test_sack_create)
51 {
52     g_autoptr(DnfSack) sack = dnf_sack_new();
53     dnf_sack_set_cachedir(sack, test_globals.tmpdir);
54     fail_unless(dnf_sack_setup(sack, DNF_SACK_SETUP_FLAG_MAKE_CACHE_DIR, NULL));
55     fail_if(sack == NULL, NULL);
56     fail_if(dnf_sack_get_pool(sack) == NULL, NULL);
57 }
58 END_TEST
59 
START_TEST(test_give_cache_fn)60 START_TEST(test_give_cache_fn)
61 {
62     DnfSack *sack = dnf_sack_new();
63     dnf_sack_set_cachedir(sack, test_globals.tmpdir);
64     fail_unless(dnf_sack_setup(sack, DNF_SACK_SETUP_FLAG_MAKE_CACHE_DIR, NULL));
65 
66     char *path = dnf_sack_give_cache_fn(sack, "rain", NULL);
67     fail_if(strstr(path, "rain.solv") == NULL);
68     g_free(path);
69 
70     path = dnf_sack_give_cache_fn(sack, "rain", HY_EXT_FILENAMES);
71     fail_if(strstr(path, "rain-filenames.solvx") == NULL);
72     g_free(path);
73     g_object_unref(sack);
74 }
75 END_TEST
76 
START_TEST(test_list_arches)77 START_TEST(test_list_arches)
78 {
79     DnfSack *sack = dnf_sack_new();
80     dnf_sack_set_cachedir(sack, test_globals.tmpdir);
81     dnf_sack_set_arch(sack, TEST_FIXED_ARCH, NULL);
82     fail_unless(dnf_sack_setup(sack, DNF_SACK_SETUP_FLAG_MAKE_CACHE_DIR, NULL));
83     const char ** arches = dnf_sack_list_arches(sack);
84 
85     /* noarch, x86_64, athlon, i686, i586, i486, i386 */
86     fail_unless(g_strv_length((gchar**)arches) >= 6 && g_strv_length((gchar**)arches) <= 7);
87 
88     if (g_strv_length((gchar**)arches) == 7) {
89         // Fedora, Mageia
90         ck_assert_str_eq(arches[0], "noarch");
91         ck_assert_str_eq(arches[1], "x86_64");
92         ck_assert_str_eq(arches[2], "athlon");
93         ck_assert_str_eq(arches[3], "i686");
94         ck_assert_str_eq(arches[4], "i586");
95         ck_assert_str_eq(arches[5], "i486");
96         ck_assert_str_eq(arches[6], "i386");
97     } else {
98         // openSUSE, Debian - "athlon" is not available
99         ck_assert_str_eq(arches[0], "noarch");
100         ck_assert_str_eq(arches[1], "x86_64");
101         ck_assert_str_eq(arches[2], "i686");
102         ck_assert_str_eq(arches[3], "i586");
103         ck_assert_str_eq(arches[4], "i486");
104         ck_assert_str_eq(arches[5], "i386");
105     }
106 
107     g_free(arches);
108     g_object_unref(sack);
109 }
110 END_TEST
111 
START_TEST(test_load_repo_err)112 START_TEST(test_load_repo_err)
113 {
114     g_autoptr(GError) error = NULL;
115     DnfSack *sack = dnf_sack_new();
116     dnf_sack_set_cachedir(sack, test_globals.tmpdir);
117     fail_unless(dnf_sack_setup(sack, DNF_SACK_SETUP_FLAG_MAKE_CACHE_DIR, &error));
118     g_assert(sack != NULL);
119     HyRepo repo = hy_repo_create("crabalocker");
120     g_assert(repo != NULL);
121     hy_repo_set_string(repo, HY_REPO_MD_FN, "/non/existing");
122     fail_unless(!dnf_sack_load_repo(sack, repo, 0, &error));
123     fail_unless(g_error_matches (error, DNF_ERROR, DNF_ERROR_FILE_INVALID));
124     hy_repo_free(repo);
125     g_object_unref(sack);
126 }
127 END_TEST
128 
START_TEST(test_repo_written)129 START_TEST(test_repo_written)
130 {
131     DnfSack *sack = dnf_sack_new();
132     dnf_sack_set_cachedir(sack, test_globals.tmpdir);
133     fail_unless(dnf_sack_setup(sack, DNF_SACK_SETUP_FLAG_MAKE_CACHE_DIR, NULL));
134     char *filename = dnf_sack_give_cache_fn(sack, "test_sack_written", NULL);
135 
136     fail_unless(access(filename, R_OK|W_OK));
137     setup_yum_sack(sack, "test_sack_written");
138 
139     HyRepo repo = hrepo_by_name(sack, "test_sack_written");
140     auto repoImpl = libdnf::repoGetImpl(repo);
141     fail_if(repo == NULL);
142     fail_unless(repoImpl->state_main == _HY_WRITTEN);
143     fail_unless(repoImpl->state_filelists == _HY_WRITTEN);
144     fail_unless(repoImpl->state_presto == _HY_WRITTEN);
145     fail_if(access(filename, R_OK|W_OK));
146 
147     g_free(filename);
148     g_object_unref(sack);
149 }
150 END_TEST
151 
START_TEST(test_add_cmdline_package)152 START_TEST(test_add_cmdline_package)
153 {
154     g_autoptr(DnfSack) sack = dnf_sack_new();
155     dnf_sack_set_cachedir(sack, test_globals.tmpdir);
156 
157     g_autofree gchar *path_mystery = g_build_filename (TESTDATADIR, "/hawkey/yum/mystery-devel-19.67-1.noarch.rpm", NULL);
158     g_autoptr(DnfPackage) pkg_mystery = dnf_sack_add_cmdline_package (sack, path_mystery);
159     const gchar *location_mystery = dnf_package_get_location(pkg_mystery);
160     ck_assert_str_eq(path_mystery, location_mystery);
161 
162     g_autofree gchar *path_tour = g_build_filename (TESTDATADIR, "/hawkey/yum/tour-4-6.noarch.rpm", NULL);
163     g_autoptr(DnfPackage) pkg_tour = dnf_sack_add_cmdline_package (sack, path_tour);
164     const gchar *location_tour = dnf_package_get_location(pkg_tour);
165     ck_assert_str_eq(path_tour, location_tour);
166 
167     g_autofree gchar *path_null_rpm = g_build_filename (test_globals.tmpdir, "null.rpm", NULL);
168     FILE *fp = g_fopen (path_null_rpm, "w");
169     fail_unless (fp != NULL);
170     fclose (fp);
171     fail_unless (dnf_sack_add_cmdline_package (sack, path_null_rpm) == NULL);
172 }
173 END_TEST
174 
START_TEST(test_repo_load)175 START_TEST(test_repo_load)
176 {
177     fail_unless(dnf_sack_count(test_globals.sack) ==
178                 TEST_EXPECT_SYSTEM_NSOLVABLES);
179 }
180 END_TEST
181 
182 static void
check_filelist(Pool * pool)183 check_filelist(Pool *pool)
184 {
185     Dataiterator di;
186     int count;
187     Id last_found_solvable = 0;
188     dataiterator_init(&di, pool, 0, 0, SOLVABLE_FILELIST, "/usr/bin/ste",
189                       SEARCH_STRING | SEARCH_FILES | SEARCH_COMPLETE_FILELIST);
190     for (count = 0; dataiterator_step(&di); ++count)
191         last_found_solvable = di.solvid;
192     fail_unless(count == 1);
193     fail_if(last_found_solvable == 0);
194     dataiterator_free(&di);
195 
196     dataiterator_init(&di, pool, 0, last_found_solvable, SOLVABLE_FILELIST, "/",
197                       SEARCH_STRINGSTART | SEARCH_FILES);
198     for (count = 0; dataiterator_step(&di); ++count)
199         fail_if(strncmp(di.kv.str, "/usr/bin/", strlen("/usr/bin/")));
200     fail_unless(count == 3);
201     dataiterator_free(&di);
202 
203     dataiterator_init(&di, pool, 0, 0, SOLVABLE_FILELIST,
204                       "/usr/lib/python2.7/site-packages/tour/today.pyc",
205                       SEARCH_STRING | SEARCH_FILES | SEARCH_COMPLETE_FILELIST);
206     for (count = 0; dataiterator_step(&di); ++count) ;
207     fail_unless(count == 1);
208     dataiterator_free(&di);
209 }
210 
START_TEST(test_filelist)211 START_TEST(test_filelist)
212 {
213     DnfSack *sack = test_globals.sack;
214     HyRepo repo = hrepo_by_name(sack, YUM_REPO_NAME);
215     char *fn_solv = dnf_sack_give_cache_fn(sack, YUM_REPO_NAME, HY_EXT_FILENAMES);
216 
217     fail_unless(libdnf::repoGetImpl(repo)->state_filelists == _HY_WRITTEN);
218     fail_if(access(fn_solv, R_OK));
219     g_free(fn_solv);
220 
221     check_filelist(dnf_sack_get_pool(test_globals.sack));
222 }
223 END_TEST
224 
START_TEST(test_filelist_from_cache)225 START_TEST(test_filelist_from_cache)
226 {
227     DnfSack *sack = dnf_sack_new();
228     dnf_sack_set_cachedir(sack, test_globals.tmpdir);
229     fail_unless(dnf_sack_setup(sack, DNF_SACK_SETUP_FLAG_MAKE_CACHE_DIR, NULL));
230     setup_yum_sack(sack, YUM_REPO_NAME);
231 
232     HyRepo repo = hrepo_by_name(sack, YUM_REPO_NAME);
233     fail_unless(libdnf::repoGetImpl(repo)->state_filelists == _HY_LOADED_CACHE);
234     check_filelist(dnf_sack_get_pool(sack));
235     g_object_unref(sack);
236 }
237 END_TEST
238 
239 static void
check_prestoinfo(Pool * pool)240 check_prestoinfo(Pool *pool)
241 {
242     Dataiterator di;
243 
244     dataiterator_init(&di, pool, NULL, SOLVID_META, DELTA_PACKAGE_NAME, "tour",
245                       SEARCH_STRING);
246     dataiterator_prepend_keyname(&di, REPOSITORY_DELTAINFO);
247     fail_unless(dataiterator_step(&di));
248     dataiterator_setpos_parent(&di);
249     const char *attr;
250     attr = pool_lookup_str(pool, SOLVID_POS, DELTA_SEQ_NAME);
251     ck_assert_str_eq(attr, "tour");
252     attr = pool_lookup_str(pool, SOLVID_POS, DELTA_SEQ_EVR);
253     ck_assert_str_eq(attr, "4-5");
254     attr = pool_lookup_str(pool, SOLVID_POS, DELTA_LOCATION_DIR);
255     ck_assert_str_eq(attr, "drpms");
256     dataiterator_free(&di);
257     return;
258 }
259 
START_TEST(test_presto)260 START_TEST(test_presto)
261 {
262     DnfSack *sack = test_globals.sack;
263     HyRepo repo = hrepo_by_name(sack, YUM_REPO_NAME);
264     char *fn_solv = dnf_sack_give_cache_fn(sack, YUM_REPO_NAME, HY_EXT_PRESTO);
265 
266     fail_if(access(fn_solv, R_OK));
267     fail_unless(libdnf::repoGetImpl(repo)->state_presto == _HY_WRITTEN);
268     g_free(fn_solv);
269     check_prestoinfo(dnf_sack_get_pool(sack));
270 }
271 END_TEST
272 
START_TEST(test_presto_from_cache)273 START_TEST(test_presto_from_cache)
274 {
275     DnfSack *sack = dnf_sack_new();
276     dnf_sack_set_cachedir(sack, test_globals.tmpdir);
277     dnf_sack_set_arch(sack, TEST_FIXED_ARCH, NULL);
278     fail_unless(dnf_sack_setup(sack, DNF_SACK_SETUP_FLAG_MAKE_CACHE_DIR, NULL));
279     setup_yum_sack(sack, YUM_REPO_NAME);
280 
281     HyRepo repo = hrepo_by_name(sack, YUM_REPO_NAME);
282     fail_unless(libdnf::repoGetImpl(repo)->state_presto == _HY_LOADED_CACHE);
283     check_prestoinfo(dnf_sack_get_pool(sack));
284     g_object_unref(sack);
285 }
286 END_TEST
287 
288 Suite *
sack_suite(void)289 sack_suite(void)
290 {
291     Suite *s = suite_create("Sack");
292     TCase *tc = tcase_create("Core");
293     tcase_add_test(tc, test_environment);
294     tcase_add_test(tc, test_sack_create);
295     tcase_add_test(tc, test_give_cache_fn);
296     tcase_add_test(tc, test_list_arches);
297     tcase_add_test(tc, test_load_repo_err);
298     tcase_add_test(tc, test_repo_written);
299     tcase_add_test(tc, test_add_cmdline_package);
300     suite_add_tcase(s, tc);
301 
302     tc = tcase_create("Repos");
303     tcase_add_unchecked_fixture(tc, fixture_system_only, teardown);
304     tcase_add_test(tc, test_repo_load);
305     suite_add_tcase(s, tc);
306 
307     tc = tcase_create("YumRepo");
308     tcase_add_unchecked_fixture(tc, fixture_yum, teardown);
309     tcase_add_test(tc, test_filelist);
310     tcase_add_test(tc, test_filelist_from_cache);
311     tcase_add_test(tc, test_presto);
312     tcase_add_test(tc, test_presto_from_cache);
313     suite_add_tcase(s, tc);
314 
315     tc = tcase_create("SackKnows");
316     tcase_add_unchecked_fixture(tc, fixture_all, teardown);
317     suite_add_tcase(s, tc);
318 
319     return s;
320 }
321