Skip to content

Commit

Permalink
Add hy_goal_lock
Browse files Browse the repository at this point in the history
This will be useful in rpm-ostree for us to express the fact that base
packages by default should be "locked"; i.e. we don't want libsolv to
try to update them.

For more information, see:
coreos/rpm-ostree#2125

Closes: #974
Approved by: kontura
  • Loading branch information
jlebon authored and rh-atomic-bot committed Aug 25, 2020
1 parent 6043874 commit 240fdd4
Show file tree
Hide file tree
Showing 11 changed files with 146 additions and 23 deletions.
1 change: 1 addition & 0 deletions data/tests/hawkey/@System.repo
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@
=Req: /usr/bin/away
=Pkg: tour 4 0 noarch
=Prv: /usr/bin/away
=Pkg: bloop 1.0 1 noarch
6 changes: 6 additions & 0 deletions data/tests/hawkey/updates.repo
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,9 @@
=Prv: dodo-dep
=Pkg: dodo-dep-b 1.0 1 noarch
=Prv: dodo-dep
=Pkg: bloop 1.0 1 noarch
=Pkg: bloop-ext 1.0 1 noarch
=Req: bloop = 1.0-1
=Pkg: bloop 2.0 1 noarch
=Pkg: bloop-ext 2.0 1 noarch
=Req: bloop = 2.0-1
6 changes: 6 additions & 0 deletions libdnf/goal/Goal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,12 @@ Goal::install(DnfPackage *new_pkg, bool optional)
packageToJob(new_pkg, &pImpl->staging, solverActions);
}

void
Goal::lock(DnfPackage *pkg)
{
queue_push2(&pImpl->staging, SOLVER_SOLVABLE|SOLVER_LOCK, dnf_package_get_id(pkg));
}

void
Goal::favor(DnfPackage *pkg)
{
Expand Down
1 change: 1 addition & 0 deletions libdnf/goal/Goal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ struct Goal {
*/
void erase(HySelector sltr, int flags);
void install(DnfPackage *new_pkg, bool optional);
void lock(DnfPackage *new_pkg);
void favor(DnfPackage *new_pkg);
void disfavor(DnfPackage *new_pkg);

Expand Down
7 changes: 7 additions & 0 deletions libdnf/hy-goal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,13 @@ hy_goal_install_optional(HyGoal goal, DnfPackage *new_pkg)
return 0;
}

int
hy_goal_lock(HyGoal goal, DnfPackage *pkg, GError **error)
{
goal->lock(pkg);
return 0;
}

int
hy_goal_favor(HyGoal goal, DnfPackage *pkg)
{
Expand Down
10 changes: 10 additions & 0 deletions libdnf/hy-goal.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,16 @@ int hy_goal_install(HyGoal goal, DnfPackage *new_pkg);
*/
int hy_goal_install_optional(HyGoal goal, DnfPackage *new_pkg);

/**
* @brief Lock package state. If installed, remains installed. If uninstalled,
* remains uninstalled. Returns 0 on success.
*
* @param goal HyGoal
* @param pkg Package to lock
* @return int
*/
int hy_goal_lock(HyGoal goal, DnfPackage *pkg, GError **error);

/**
* @brief Favor package when considering alternatives. Return value is always 0.
*
Expand Down
12 changes: 6 additions & 6 deletions python/hawkey/tests/tests/test_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,13 +212,13 @@ def test_disabled_repo(self):
def test_multiple_flags(self):
q = hawkey.Query(self.sack).filter(name__glob__not=["p*", "j*"])
self.assertItemsEqual(list(map(lambda p: p.name, q.run())),
["baby", "dog", "flying", "fool", "gun", "tour"])
["baby", "bloop", "dog", "flying", "fool", "gun", "tour"])

def test_apply(self):
q = hawkey.Query(self.sack).filter(name__glob__not="p*").apply()
res = q.filter(name__glob__not="j*").run()
self.assertItemsEqual(list(map(lambda p: p.name, res)),
["baby", "dog", "flying", "fool", "gun", "tour"])
["baby", "bloop", "dog", "flying", "fool", "gun", "tour"])

def test_provides_glob_should_work(self):
q1 = hawkey.Query(self.sack).filter(provides__glob="penny*")
Expand Down Expand Up @@ -298,7 +298,7 @@ def test_downgradable(self):

def test_rco_glob(self):
q1 = hawkey.Query(self.sack).filter(requires__glob="*")
self.assertLength(q1, 10)
self.assertLength(q1, 12)
q2 = hawkey.Query(self.sack).filter(requires="*")
self.assertLength(q2, 0)
q3 = hawkey.Query(self.sack).filter(conflicts__glob="cu*")
Expand Down Expand Up @@ -326,9 +326,9 @@ def setUp(self):
def test_upgradable(self):
query = hawkey.Query(self.sack).filter(upgradable=True)
self.assertEqual({str(pkg) for pkg in query},
{"dog-1-1.x86_64", "flying-2-9.noarch",
"fool-1-3.noarch", "pilchard-1.2.3-1.i686",
"pilchard-1.2.3-1.x86_64"})
{"bloop-1.0-1.noarch", "dog-1-1.x86_64",
"flying-2-9.noarch", "fool-1-3.noarch",
"pilchard-1.2.3-1.i686", "pilchard-1.2.3-1.x86_64"})

def test_updates_noarch(self):
q = hawkey.Query(self.sack)
Expand Down
4 changes: 4 additions & 0 deletions tests/hawkey/README
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ pigs, tour
dodo, dodo-dep-a, dodo-dep-b
* testing favor/disfavor

bloop, bloop-ext
* bloop-1.0 installed, bloop-ext-1.0 and *-2.0 in updates
* for testing package locking

=== repos/yum ===

To test loading of yum repos we need an actual yum repo. It currently consists
Expand Down
110 changes: 99 additions & 11 deletions tests/hawkey/test_goal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -478,11 +478,11 @@ START_TEST(test_goal_upgrade_all)
if (implicitobsoleteusescolors) {
// Fedora, Mageia
assert_list_names<&dnf_package_get_name>(
true, plist, "dog", "flying", "fool", "pilchard", "pilchard", NULL);
true, plist, "bloop", "dog", "flying", "fool", "pilchard", "pilchard", NULL);
} else {
// openSUSE
assert_list_names<&dnf_package_get_name>(
true, plist, "dog", "flying", "fool", NULL);
true, plist, "bloop", "dog", "flying", "fool", NULL);
}

// see all obsoletes of fool:
Expand Down Expand Up @@ -789,6 +789,92 @@ START_TEST(test_goal_disfavor)
}
END_TEST

START_TEST(test_goal_lock)
{
DnfSack *sack = test_globals.sack;
HyGoal goal = hy_goal_create(sack);

// check that installing "bloop-ext" without locking the base works fine
// (and auto-updates the base)
g_auto(HySubject) subject = hy_subject_create("bloop-ext");
g_auto(HySelector) selector = hy_subject_get_best_selector(subject, sack, NULL, FALSE, "updates");
fail_if(!hy_goal_install_selector(goal, selector, NULL));
fail_if(hy_goal_run_flags(goal, DNF_NONE));

assert_iueo(goal, 1, 1, 0, 0);

GPtrArray *plist = hy_goal_list_installs(goal, NULL);
const char *nvra = dnf_package_get_nevra(
static_cast<DnfPackage *>(g_ptr_array_index(plist, 0)));
ck_assert_str_eq(nvra, "bloop-ext-2.0-1.noarch");
g_ptr_array_unref(plist);

plist = hy_goal_list_upgrades(goal, NULL);
nvra = dnf_package_get_nevra(
static_cast<DnfPackage *>(g_ptr_array_index(plist, 0)));
ck_assert_str_eq(nvra, "bloop-2.0-1.noarch");
g_ptr_array_unref(plist);

hy_goal_free(goal);

// now redo the same test, but lock the base pkg
goal = hy_goal_create(sack);

g_autoptr(DnfPackage) base_pkg = by_name_repo(sack, "bloop", HY_SYSTEM_REPO_NAME);
fail_if(base_pkg == NULL);
fail_if(hy_goal_lock(goal, base_pkg, NULL));

fail_if(!hy_goal_install_selector(goal, selector, NULL));
fail_if(hy_goal_run_flags(goal, DNF_NONE));

assert_iueo(goal, 1, 0, 0, 0);

plist = hy_goal_list_installs(goal, NULL);
nvra = dnf_package_get_nevra(
static_cast<DnfPackage *>(g_ptr_array_index(plist, 0)));
ck_assert_str_eq(nvra, "bloop-ext-1.0-1.noarch");
g_ptr_array_unref(plist);

hy_goal_free(goal);

// now purposely exclude the compatible version and check that we get a
// sensical error
goal = hy_goal_create(sack);
fail_if(hy_goal_lock(goal, base_pkg, NULL));

HyQuery q = hy_query_create(sack);
hy_query_filter(q, HY_PKG_NEVRA, HY_EQ, "bloop-ext-1.0-1.noarch");
hy_query_filter(q, HY_PKG_REPONAME, HY_EQ, "updates");
g_autoptr(DnfPackageSet) pset = hy_query_run_set(q);
dnf_sack_add_excludes(sack, pset);
hy_query_free(q);

fail_if(!hy_goal_install_selector(goal, selector, NULL));
// notice the ! here; we expect failure
fail_if(!hy_goal_run_flags(goal, DNF_NONE));

g_autoptr(GError) error = NULL;
fail_unless(hy_goal_list_installs(goal, &error) == NULL);
fail_unless(error->code == DNF_ERROR_NO_SOLUTION);
fail_unless(hy_goal_count_problems(goal) > 0);

auto problems = goal->describeProblemRules(0, true);
const char *expected[] = {
"package bloop-ext-2.0-1.noarch requires bloop = 2.0-1, but none of the providers can be installed",
"cannot install both bloop-2.0-1.noarch and bloop-1.0-1.noarch",
"conflicting requests",
"package bloop-ext-1.0-1.noarch is filtered out by exclude filtering"
};
ck_assert_int_eq(problems.size(), 4);
ck_assert_str_eq(problems[0].c_str(), expected[0]);
ck_assert_str_eq(problems[1].c_str(), expected[1]);
ck_assert_str_eq(problems[2].c_str(), expected[2]);
ck_assert_str_eq(problems[3].c_str(), expected[3]);

hy_goal_free(goal);
}
END_TEST

START_TEST(test_goal_installonly)
{
const char *installonly[] = {"fool", NULL};
Expand Down Expand Up @@ -829,10 +915,10 @@ START_TEST(test_goal_installonly_upgrade_all)
int implicitobsoleteusescolors = pool_get_flag(pool, POOL_FLAG_IMPLICITOBSOLETEUSESCOLORS);
if (implicitobsoleteusescolors) {
// Fedora, Mageia
assert_iueo(goal, 1, 4, 1, 0);
assert_iueo(goal, 1, 5, 1, 0);
} else {
// openSUSE
assert_iueo(goal, 1, 2, 1, 0);
assert_iueo(goal, 1, 3, 1, 0);
}

hy_goal_free(goal);
Expand All @@ -853,7 +939,7 @@ START_TEST(test_goal_upgrade_all_excludes)
HyGoal goal = hy_goal_create(sack);
hy_goal_upgrade_all(goal);
hy_goal_run_flags(goal, DNF_NONE);
fail_unless(size_and_free(hy_goal_list_upgrades(goal, NULL)) == 3);
fail_unless(size_and_free(hy_goal_list_upgrades(goal, NULL)) == 4);
hy_goal_free(goal);
}
END_TEST
Expand All @@ -869,10 +955,10 @@ START_TEST(test_goal_upgrade_disabled_repo)
int implicitobsoleteusescolors = pool_get_flag(pool, POOL_FLAG_IMPLICITOBSOLETEUSESCOLORS);
if (implicitobsoleteusescolors) {
// Fedora, Mageia
fail_unless(size_and_free(hy_goal_list_upgrades(goal, NULL)) == 5);
fail_unless(size_and_free(hy_goal_list_upgrades(goal, NULL)) == 6);
} else {
// openSUSE
fail_unless(size_and_free(hy_goal_list_upgrades(goal, NULL)) == 3);
fail_unless(size_and_free(hy_goal_list_upgrades(goal, NULL)) == 4);
}
hy_goal_free(goal);

Expand Down Expand Up @@ -973,13 +1059,13 @@ START_TEST(test_goal_distupgrade_all_keep_arch)
// gun pkg is not upgraded to latest version of different arch
if (implicitobsoleteusescolors) {
// Fedora, Mageia
assert_iueo(goal, 0, 5, 0, 1);
assert_list_names<&dnf_package_get_nevra>(true, plist, "dog-1-2.x86_64", "fool-1-5.noarch",
assert_iueo(goal, 0, 6, 0, 1);
assert_list_names<&dnf_package_get_nevra>(true, plist, "bloop-2.0-1.noarch", "dog-1-2.x86_64", "fool-1-5.noarch",
"flying-3.1-0.x86_64", "pilchard-1.2.4-1.x86_64", "pilchard-1.2.4-1.i686", NULL);
} else {
// openSUSE
assert_iueo(goal, 0, 4, 0, 1);
assert_list_names<&dnf_package_get_nevra>(true, plist, "dog-1-2.x86_64", "fool-1-5.noarch",
assert_iueo(goal, 0, 5, 0, 1);
assert_list_names<&dnf_package_get_nevra>(true, plist, "bloop-2.0-1.noarch", "dog-1-2.x86_64", "fool-1-5.noarch",
"flying-3.1-0.x86_64", "pilchard-1.2.4-2.x86_64", NULL);
}
g_ptr_array_unref(plist);
Expand Down Expand Up @@ -1076,6 +1162,7 @@ START_TEST(test_goal_unneeded)
HyGoal goal = hy_goal_create(sack);

userinstalled(sack, goal, "baby");
userinstalled(sack, goal, "bloop");
userinstalled(sack, goal, "dog");
userinstalled(sack, goal, "fool");
userinstalled(sack, goal, "gun");
Expand Down Expand Up @@ -1331,6 +1418,7 @@ goal_suite(void)
tcase_add_test(tc, test_goal_forcebest);
tcase_add_test(tc, test_goal_favor);
tcase_add_test(tc, test_goal_disfavor);
tcase_add_test(tc, test_goal_lock);
suite_add_tcase(s, tc);

tc = tcase_create("ModifiesSackState");
Expand Down
8 changes: 4 additions & 4 deletions tests/hawkey/test_query.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ START_TEST(test_upgrades)

HyQuery q = hy_query_create(test_globals.sack);
hy_query_filter_upgrades(q, 1);
fail_unless(query_count_results(q) == TEST_EXPECT_UPDATES_NSOLVABLES - 5);
fail_unless(query_count_results(q) == TEST_EXPECT_UPDATES_NSOLVABLES - 8);
hy_query_free(q);
}
END_TEST
Expand All @@ -493,7 +493,7 @@ START_TEST(test_upgradable)
{
HyQuery q = hy_query_create(test_globals.sack);
hy_query_filter_upgradable(q, 1);
ck_assert_int_eq(query_count_results(q), 5);
ck_assert_int_eq(query_count_results(q), 6);
hy_query_free(q);
}
END_TEST
Expand Down Expand Up @@ -893,7 +893,7 @@ START_TEST(test_query_multiple_flags)
hy_query_filter(q, HY_PKG_NAME, HY_NOT | HY_GLOB, "p*");
plist = hy_query_run(q);

ck_assert_int_eq(plist->len, 8);
ck_assert_int_eq(plist->len, 9);
g_ptr_array_unref(plist);
hy_query_free(q);
}
Expand All @@ -920,7 +920,7 @@ START_TEST(test_query_apply)
ck_assert_int_eq(_q.getApplied(), 0);
plist = hy_query_run(q);

ck_assert_int_eq(plist->len, 6);
ck_assert_int_eq(plist->len, 7);
g_ptr_array_unref(plist);
hy_query_free(q);
}
Expand Down
4 changes: 2 additions & 2 deletions tests/hawkey/testshared.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@
#define YUM_DIR_SUFFIX "yum/repodata/"
#define YUM_REPO_NAME "nevermac"
#define TEST_FIXED_ARCH "x86_64"
#define TEST_EXPECT_SYSTEM_PKGS 13
#define TEST_EXPECT_SYSTEM_PKGS 14
#define TEST_EXPECT_SYSTEM_NSOLVABLES TEST_EXPECT_SYSTEM_PKGS
#define TEST_EXPECT_MAIN_NSOLVABLES 14
#define TEST_EXPECT_UPDATES_NSOLVABLES 13
#define TEST_EXPECT_UPDATES_NSOLVABLES 17
#define TEST_EXPECT_YUM_NSOLVABLES 2

#ifdef __cplusplus
Expand Down

0 comments on commit 240fdd4

Please sign in to comment.