TransactionReplay: handle group package types

This information is stored in system state for each group and is used
during group upgrade.
This commit is contained in:
Aleš Matěj 2024-07-01 14:00:29 +02:00 committed by pkratoch
parent 9c2e215058
commit 52f52d4509
7 changed files with 89 additions and 13 deletions

View File

@ -1012,6 +1012,7 @@ GoalProblem Goal::Impl::add_replay_to_goal(
for (const auto & group_replay : replay.groups) {
libdnf5::GoalJobSettings settings_per_group = settings;
settings_per_group.set_group_no_packages(true);
settings_per_group.set_group_package_types(group_replay.package_types);
settings_per_group.set_group_search_groups(true);
settings_per_group.set_group_search_environments(false);
if (!group_replay.repo_id.empty()) {

View File

@ -1458,6 +1458,7 @@ std::string Transaction::serialize(
group_replay.reason = group.get_reason();
// TODO(amatej): does each group has to have at least one repo?
group_replay.repo_id = *(group.get_group().get_repos().begin());
group_replay.package_types = group.get_package_types();
if (!comps_path.empty()) {
group_replay.group_path = build_comps_xml_path(comps_path, xml_group.get_groupid());

View File

@ -350,6 +350,7 @@ std::string Transaction::serialize() {
group_replay.action = group.get_action();
group_replay.reason = group.get_reason();
group_replay.repo_id = group.get_repoid();
group_replay.package_types = group.get_package_types();
transaction_replay.groups.push_back(group_replay);
}

View File

@ -130,6 +130,8 @@ TransactionReplay parse_transaction_replay(const std::string & json_serialized_t
std::string reason;
std::string group_path;
std::string repo_id;
std::string joined_package_types;
comps::PackageType package_types;
if (json_object_is_type(json_groups, json_type_array) == 0) {
throw TransactionReplayError(M_("Unexpected type of \"groups\", array expected."));
@ -158,13 +160,22 @@ TransactionReplay parse_transaction_replay(const std::string & json_serialized_t
if (json_object_object_get_ex(group, "repo_id", &value) != 0) {
repo_id = json_object_get_string(value);
}
if (json_object_object_get_ex(group, "package_types", &value) != 0) {
joined_package_types = json_object_get_string(value);
auto package_types_vec = libdnf5::utils::string::split(joined_package_types, ",");
std::for_each(package_types_vec.begin(), package_types_vec.end(), libdnf5::utils::string::trim);
package_types = comps::package_type_from_string(package_types_vec);
} else {
package_types = comps::PackageType();
}
transaction_replay.groups.push_back(
{transaction_item_action_from_string(action),
transaction_item_reason_from_string(reason),
group_id,
group_path,
repo_id});
repo_id,
package_types});
}
}
@ -282,6 +293,11 @@ std::string json_serialize(const TransactionReplay & transaction_replay) {
json_object_object_add(json_group, "group_path", json_object_new_string(group.group_path.c_str()));
}
json_object_object_add(json_group, "repo_id", json_object_new_string(group.repo_id.c_str()));
json_object_object_add(
json_group,
"package_types",
json_object_new_string(
libdnf5::utils::string::join(package_types_to_strings(group.package_types), ", ").c_str()));
json_object_array_add(json_groups, json_group);
}
json_object_object_add(root, "groups", json_groups);

View File

@ -44,6 +44,7 @@ struct GroupReplay {
// Path to serialized comps group relative to the transaction json file
std::filesystem::path group_path;
std::string repo_id;
libdnf5::comps::PackageType package_types;
};
struct EnvironmentReplay {

View File

@ -47,6 +47,7 @@ static void add_transaction_item_group(
group_replay.action = action;
group_replay.reason = TransactionItemReason::USER;
group_replay.group_id = id;
group_replay.package_types = libdnf5::comps::PackageType::DEFAULT;
trans.groups.push_back(group_replay);
}
@ -96,7 +97,12 @@ void TransactionMergeTest::only_one_transaction() {
{TransactionItemAction::INSTALL, TransactionItemReason::USER, "", "bash-4-1.x86_64", "", ""}};
CPPUNIT_ASSERT_EQUAL(expected, replay.packages);
std::vector<GroupReplay> expected_groups = {
{TransactionItemAction::INSTALL, TransactionItemReason::USER, "vlc", "", ""}};
{TransactionItemAction::INSTALL,
TransactionItemReason::USER,
"vlc",
"",
"",
libdnf5::comps::PackageType::DEFAULT}};
CPPUNIT_ASSERT_EQUAL(expected_groups, replay.groups);
std::vector<EnvironmentReplay> expected_envs = {
{TransactionItemAction::INSTALL, "basic-desktop-environment", "", ""}};
@ -124,7 +130,12 @@ void TransactionMergeTest::two_disjoint() {
{TransactionItemAction::INSTALL, TransactionItemReason::USER, "", "bash-4-1.x86_64", "", ""}};
CPPUNIT_ASSERT_EQUAL(expected, replay.packages);
std::vector<GroupReplay> expected_groups = {
{TransactionItemAction::INSTALL, TransactionItemReason::USER, "vlc", "", ""}};
{TransactionItemAction::INSTALL,
TransactionItemReason::USER,
"vlc",
"",
"",
libdnf5::comps::PackageType::DEFAULT}};
CPPUNIT_ASSERT_EQUAL(expected_groups, replay.groups);
std::vector<EnvironmentReplay> expected_envs = {
{TransactionItemAction::INSTALL, "basic-desktop-environment", "", ""}};
@ -1374,7 +1385,13 @@ void TransactionMergeTest::group_install_install() {
auto [replay, problems] = libdnf5::transaction::merge_transactions({trans1, trans2}, na_to_installed_nevras);
std::vector<GroupReplay> expected = {{TransactionItemAction::INSTALL, TransactionItemReason::USER, "vlc", "", ""}};
std::vector<GroupReplay> expected = {
{TransactionItemAction::INSTALL,
TransactionItemReason::USER,
"vlc",
"",
"",
libdnf5::comps::PackageType::DEFAULT}};
CPPUNIT_ASSERT_EQUAL(expected, replay.groups);
CPPUNIT_ASSERT_EQUAL(std::vector<std::string>(), problems);
}
@ -1389,7 +1406,13 @@ void TransactionMergeTest::group_install_upgrade() {
auto [replay, problems] = libdnf5::transaction::merge_transactions({trans1, trans2}, na_to_installed_nevras);
std::vector<GroupReplay> expected = {{TransactionItemAction::INSTALL, TransactionItemReason::USER, "vlc", "", ""}};
std::vector<GroupReplay> expected = {
{TransactionItemAction::INSTALL,
TransactionItemReason::USER,
"vlc",
"",
"",
libdnf5::comps::PackageType::DEFAULT}};
CPPUNIT_ASSERT_EQUAL(expected, replay.groups);
CPPUNIT_ASSERT_EQUAL(std::vector<std::string>(), problems);
}
@ -1419,7 +1442,13 @@ void TransactionMergeTest::group_remove_upgrade() {
auto [replay, problems] = libdnf5::transaction::merge_transactions({trans1, trans2}, na_to_installed_nevras);
std::vector<GroupReplay> expected = {{TransactionItemAction::INSTALL, TransactionItemReason::USER, "vlc", "", ""}};
std::vector<GroupReplay> expected = {
{TransactionItemAction::INSTALL,
TransactionItemReason::USER,
"vlc",
"",
"",
libdnf5::comps::PackageType::DEFAULT}};
CPPUNIT_ASSERT_EQUAL(expected, replay.groups);
std::vector<std::string> expected_problems = {
{"Action 'Upgrade' 'vlc' cannot be merged because it is not present at that point -> "
@ -1437,7 +1466,13 @@ void TransactionMergeTest::group_remove_remove() {
auto [replay, problems] = libdnf5::transaction::merge_transactions({trans1, trans2}, na_to_installed_nevras);
std::vector<GroupReplay> expected = {{TransactionItemAction::REMOVE, TransactionItemReason::USER, "vlc", "", ""}};
std::vector<GroupReplay> expected = {
{TransactionItemAction::REMOVE,
TransactionItemReason::USER,
"vlc",
"",
"",
libdnf5::comps::PackageType::DEFAULT}};
CPPUNIT_ASSERT_EQUAL(expected, replay.groups);
std::vector<std::string> expected_problems = {
{"Action 'Remove' 'vlc' cannot be merged after it was 'Remove' in preceding "
@ -1455,7 +1490,13 @@ void TransactionMergeTest::group_upgrade_upgrade() {
auto [replay, problems] = libdnf5::transaction::merge_transactions({trans1, trans2}, na_to_installed_nevras);
std::vector<GroupReplay> expected = {{TransactionItemAction::UPGRADE, TransactionItemReason::USER, "vlc", "", ""}};
std::vector<GroupReplay> expected = {
{TransactionItemAction::UPGRADE,
TransactionItemReason::USER,
"vlc",
"",
"",
libdnf5::comps::PackageType::DEFAULT}};
CPPUNIT_ASSERT_EQUAL(expected, replay.groups);
CPPUNIT_ASSERT_EQUAL(std::vector<std::string>(), problems);
}
@ -1470,7 +1511,13 @@ void TransactionMergeTest::group_upgrade_remove() {
auto [replay, problems] = libdnf5::transaction::merge_transactions({trans1, trans2}, na_to_installed_nevras);
std::vector<GroupReplay> expected = {{TransactionItemAction::REMOVE, TransactionItemReason::USER, "vlc", "", ""}};
std::vector<GroupReplay> expected = {
{TransactionItemAction::REMOVE,
TransactionItemReason::USER,
"vlc",
"",
"",
libdnf5::comps::PackageType::DEFAULT}};
CPPUNIT_ASSERT_EQUAL(expected, replay.groups);
CPPUNIT_ASSERT_EQUAL(std::vector<std::string>(), problems);
}
@ -1485,7 +1532,13 @@ void TransactionMergeTest::group_upgrade_install() {
auto [replay, problems] = libdnf5::transaction::merge_transactions({trans1, trans2}, na_to_installed_nevras);
std::vector<GroupReplay> expected = {{TransactionItemAction::INSTALL, TransactionItemReason::USER, "vlc", "", ""}};
std::vector<GroupReplay> expected = {
{TransactionItemAction::INSTALL,
TransactionItemReason::USER,
"vlc",
"",
"",
libdnf5::comps::PackageType::DEFAULT}};
CPPUNIT_ASSERT_EQUAL(expected, replay.groups);
CPPUNIT_ASSERT_EQUAL(std::vector<std::string>(), problems);
}

View File

@ -22,6 +22,7 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.
#define TEST_LIBDNF5_UTILS_HPP
#include "system/state.hpp"
#include "utils/string.hpp"
#include <cppunit/extensions/HelperMacros.h>
#include <libdnf5/advisory/advisory_set.hpp>
@ -303,17 +304,19 @@ struct assertion_traits<libdnf5::transaction::GroupReplay> {
inline static bool equal(
const libdnf5::transaction::GroupReplay & left, const libdnf5::transaction::GroupReplay & right) {
return left.action == right.action && left.reason == right.reason && left.group_id == right.group_id &&
left.group_path == right.group_path && left.repo_id == right.repo_id;
left.group_path == right.group_path && left.repo_id == right.repo_id &&
left.package_types == right.package_types;
}
inline static std::string toString(const libdnf5::transaction::GroupReplay & replay) {
return fmt::format(
"GroupReplay: group_id: {}, action: {}, reason: {}, repo_id: {}, group_path: {}",
"GroupReplay: group_id: {}, action: {}, reason: {}, repo_id: {}, group_path: {}, package_types: {}",
replay.group_id,
libdnf5::transaction::transaction_item_action_to_string(replay.action),
libdnf5::transaction::transaction_item_reason_to_string(replay.reason),
replay.repo_id,
std::string(replay.group_path));
std::string(replay.group_path),
libdnf5::utils::string::join(package_types_to_strings(replay.package_types), ","));
}
};