1 #include "ContextTest.hpp"
2
3 CPPUNIT_TEST_SUITE_REGISTRATION(ContextTest);
4
5 #include "libdnf/dnf-context.hpp"
6 #include "libdnf/dnf-repo-loader.h"
7 #include "libdnf/sack/query.hpp"
8 #include "libdnf/nevra.hpp"
9 #include "libdnf/utils/File.hpp"
10 #include "libdnf/sack/packageset.hpp"
11 #include "libdnf/dnf-sack-private.hpp"
12
13 #include <memory>
14
15
setUp()16 void ContextTest::setUp()
17 {
18 dnf_context_set_config_file_path("");
19 context = dnf_context_new();
20 }
21
tearDown()22 void ContextTest::tearDown()
23 {
24 g_object_unref(context);
25 }
26
27 // XXX: look into sharing assert_list_names in the future
pkglist_has_nevra(GPtrArray * pkglist,const char * nevra)28 static gboolean pkglist_has_nevra(GPtrArray *pkglist, const char *nevra)
29 {
30 for (guint i = 0; i < pkglist->len; i++) {
31 DnfPackage *pkg = static_cast<DnfPackage *>(pkglist->pdata[i]);
32 if (g_str_equal(dnf_package_get_nevra(pkg), nevra))
33 return TRUE;
34 }
35 return FALSE;
36 }
37
testLoadModules()38 void ContextTest::testLoadModules()
39 {
40 GError *error = nullptr;
41
42 /* set up local context */
43 // set releasever to avoid crashing on missing /etc/os-release in the test data
44 dnf_context_set_release_ver(context, "26");
45 dnf_context_set_arch(context, "x86_64");
46 constexpr auto install_root = TESTDATADIR "/modules/";
47 dnf_context_set_install_root(context, install_root);
48 g_autoptr(DnfLock) lock = dnf_lock_new();
49 dnf_lock_set_lock_dir(lock, "/tmp");
50 constexpr auto repos_dir = TESTDATADIR "/modules/yum.repos.d/";
51 dnf_context_set_repo_dir(context, repos_dir);
52 dnf_context_set_solv_dir(context, "/tmp");
53 auto ret = dnf_context_setup(context, nullptr, &error);
54 g_assert_no_error(error);
55 g_assert(ret);
56
57 /* load local metadata repo */
58 DnfRepo *repo = dnf_repo_loader_get_repo_by_id(dnf_context_get_repo_loader(context), "test", &error);
59 g_assert_no_error(error);
60 g_assert(repo != nullptr);
61 g_assert_cmpint(dnf_repo_get_enabled(repo), ==, DNF_REPO_ENABLED_METADATA | DNF_REPO_ENABLED_PACKAGES);
62 g_assert_cmpint(dnf_repo_get_kind(repo), ==, DNF_REPO_KIND_LOCAL);
63
64 DnfState *state = dnf_state_new();
65 dnf_repo_check(repo, G_MAXUINT, state, &error);
66 g_object_unref(state);
67
68 // Setup platform to prevent logger critical message
69 dnf_context_set_platform_module(context, "platform:26");
70
71 state = dnf_context_get_state(context);
72 dnf_context_setup_sack(context, state, &error);
73 g_assert_no_error(error);
74
75 auto sack = dnf_context_get_sack(context);
76 auto moduleExcludes = std::unique_ptr<libdnf::PackageSet>(dnf_sack_get_module_excludes(sack));
77 CPPUNIT_ASSERT(moduleExcludes->size() != 0);
78
79 libdnf::ModulePackageContainer * c = dnf_sack_get_module_container(sack);
80 std::vector<libdnf::ModulePackage *> packages = c->getModulePackages();
81 for(auto const& package: packages) {
82 if (package->getName() == "httpd"){
83 // disabled stream
84 if (package->getStream() == "2.2")
85 sackHasNot(sack, package);
86 // default module:stream
87 if (package->getStream() == "2.4")
88 sackHas(sack, package);
89 }
90 }
91
92 {
93 libdnf::Query query{sack};
94 // no match with modular RPM $name -> keep
95 std::string nevra = "grub2-2.02-0.40.x86_64";
96 query.addFilter(HY_PKG_NEVRA_STRICT, HY_EQ, nevra.c_str());
97 auto packageSet = const_cast<libdnf::PackageSet *>(query.runSet());
98 CPPUNIT_ASSERT(dnf_packageset_count(packageSet) >= 1);
99 auto package = dnf_package_new(sack, packageSet->operator[](0));
100 CPPUNIT_ASSERT(dnf_package_get_nevra(package) == nevra);
101 g_object_unref(package);
102 query.clear();
103 }
104
105 {
106 libdnf::Query query{sack};
107 // $name matches with modular RPM $name -> exclude
108 std::string nevra = "httpd-2.2.10-1.x86_64";
109 query.addFilter(HY_PKG_NEVRA_STRICT, HY_EQ, nevra.c_str());
110 auto packageSet = const_cast<libdnf::PackageSet *>(query.runSet());
111 CPPUNIT_ASSERT(dnf_packageset_count(packageSet) == 0);
112 query.clear();
113 }
114
115 {
116 libdnf::Query query{sack};
117 // Provides: $name matches with modular RPM $name -> exclude
118 std::string nevra = "httpd-provides-name-3.0-1.x86_64";
119 query.addFilter(HY_PKG_NEVRA_STRICT, HY_EQ, nevra.c_str());
120 auto packageSet = const_cast<libdnf::PackageSet *>(query.runSet());
121 CPPUNIT_ASSERT(dnf_packageset_count(packageSet) == 0);
122 query.clear();
123 }
124
125 {
126 libdnf::Query query{sack};
127 // Provides: $name = ... matches with modular RPM $name -> exclude
128 std::string nevra = "httpd-provides-name-version-release-3.0-1.x86_64";
129 query.addFilter(HY_PKG_NEVRA_STRICT, HY_EQ, nevra.c_str());
130 auto packageSet = const_cast<libdnf::PackageSet *>(query.runSet());
131 CPPUNIT_ASSERT(dnf_packageset_count(packageSet) == 0);
132 query.clear();
133 }
134
135 // try to install a nonexistent module
136 const char *module_specs[] = {"nonexistent", NULL};
137 g_assert(!dnf_context_module_install(context, module_specs, &error));
138 g_assert(error);
139 g_assert(strstr(error->message, "Unable to resolve argument 'nonexistent'"));
140 g_clear_pointer(&error, g_error_free);
141
142 // wrong stream
143 module_specs[0] = "httpd:nonexistent";
144 g_assert(!dnf_context_module_install(context, module_specs, &error));
145 g_assert(error);
146 g_assert(strstr(error->message, "Unable to resolve argument 'httpd:nonexistent'"));
147 g_clear_pointer(&error, g_error_free);
148
149 // try to install non-existent profile
150 module_specs[0] = "httpd:2.4/nonexistent";
151 g_assert(!dnf_context_module_install(context, module_specs, &error));
152 g_assert(error);
153 g_assert(strstr(error->message, "No profile found matching 'nonexistent'"));
154 g_clear_pointer(&error, g_error_free);
155
156 // disable all modules
157 g_assert(dnf_context_module_disable_all(context, &error));
158 g_assert_no_error(error);
159
160 // installing a modular package should fail
161 g_assert(!dnf_context_install(context, "httpd-2.4.25-8.x86_64", &error));
162 g_assert(error);
163 g_assert(strstr(error->message, "No package matches 'httpd-2.4.25-8.x86_64'"));
164 g_clear_pointer(&error, g_error_free);
165
166 // reset all modules
167 g_assert(dnf_context_reset_all_modules(context, sack, &error));
168 g_assert_no_error(error);
169
170 // enable and install default profile from modulemd-defaults
171 module_specs[0] = "httpd:2.4";
172 g_assert(dnf_context_module_install(context, module_specs, &error));
173 g_assert_no_error(error);
174 HyGoal goal = dnf_context_get_goal(context);
175 g_assert_cmpint(hy_goal_run_flags(goal, DNF_NONE), ==, 0);
176 g_autoptr(GPtrArray) pkgs = hy_goal_list_installs(goal, &error);
177 g_assert_no_error(error);
178 g_assert(pkgs);
179 g_assert(pkglist_has_nevra(pkgs, "httpd-2.4.25-8.x86_64"));
180 g_assert(pkglist_has_nevra(pkgs, "libnghttp2-1.21.1-1.x86_64"));
181
182 // Verify we can install the default stream from modulemd-defaults.
183 // This would fail with EnableMultipleStreamsException if it didn't match
184 // the 2.4 stream since we enabled the 2.4 stream just above.
185 module_specs[0] = "httpd";
186 g_assert(dnf_context_module_install(context, module_specs, &error));
187 g_assert_no_error(error);
188 }
189
sackHas(DnfSack * sack,libdnf::ModulePackage * pkg) const190 void ContextTest::sackHas(DnfSack * sack, libdnf::ModulePackage * pkg) const
191 {
192 libdnf::Query query{sack};
193 auto artifacts = pkg->getArtifacts();
194 for(auto & artifact: artifacts) {
195 artifact = artifact.replace(artifact.find("-0:"), 3, "-");
196 query.addFilter(HY_PKG_NEVRA_STRICT, HY_EQ, artifact.c_str());
197
198 auto packageSet = const_cast<libdnf::PackageSet *>(query.runSet());
199 CPPUNIT_ASSERT(dnf_packageset_count(packageSet) >= 1);
200 auto package = dnf_package_new(sack, packageSet->operator[](0));
201 CPPUNIT_ASSERT(dnf_package_get_nevra(package) == artifact);
202 g_object_unref(package);
203
204 query.clear();
205
206 }
207 }
208
sackHasNot(DnfSack * sack,libdnf::ModulePackage * pkg) const209 void ContextTest::sackHasNot(DnfSack * sack, libdnf::ModulePackage * pkg) const
210 {
211 libdnf::Query query{sack};
212 auto artifacts = pkg->getArtifacts();
213 for(auto & artifact: artifacts) {
214 artifact = artifact.replace(artifact.find("-0:"), 3, "-");
215 query.addFilter(HY_PKG_NEVRA_STRICT, HY_EQ, artifact.c_str());
216
217 auto packageSet = const_cast<libdnf::PackageSet *>(query.runSet());
218 CPPUNIT_ASSERT(dnf_packageset_count(packageSet) == 0);
219
220 query.clear();
221 }
222 }
223