Files
bearhub/tests/gems/arch/test_updates.py
Sebastian Palencsar 4a119968bc Release 0.10.7-bearhub.6
Complete M1 identity work, fix runtime URL regressions, repair the test
suite, add CI, migrate packaging/AppImage branding to Bearhub, and
document the Qt6/PySide6 migration plan.
2026-06-26 19:22:28 +02:00

1421 lines
85 KiB
Python

from unittest import TestCase
from unittest.mock import patch, Mock, MagicMock
from bauh.api.abstract.controller import UpgradeRequirement
from bauh.gems.arch.dependencies import DependenciesAnalyser
from bauh.gems.arch.model import ArchPackage
from bauh.gems.arch.updates import UpdatesSummarizer
from bauh.view.util.translation import I18n
class UpdatesSummarizerGetUpgradeRequirementsTest(TestCase):
def setUp(self) -> None:
self.aur_client = MagicMock()
self.aur_client.read_index.return_value = set()
self.deps_analyser = MagicMock()
self._i18n = {"arch.info.conflicts with": "", "arch.update_summary.to_install.dep_conflict": "{} {}",
"arch.info.required by": "", "arch.info.depends on": ""}
self.i18n = I18n(default_key='en_US', default_locale=self._i18n, current_key='en_US', current_locale=self._i18n)
self.summarizer = UpdatesSummarizer(aur_client=self.aur_client,
aur_supported=True,
i18n=self.i18n,
logger=Mock(),
deps_analyser=self.deps_analyser,
watcher=Mock())
self.config_ = {"automatch_providers": True,
"prefer_repository_provider": True,
"check_dependency_breakage": True}
@patch("bauh.gems.arch.updates.pacman")
def test__should_not_return_installed_to_remove_when_conflict_with_installed_version_fails(self, pacman: Mock):
"""
If the newest version o package A conflicts with an installed package named B, but the conflict expression
doesn't match (e.g: A conflict expressions (B <= 0.7), B (0.8)) then B should not be marked as a package
to be removed.
"""
pkg_a = ArchPackage(name="A", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pacman.map_provided.side_effect = [{"A": {"A"}, # remote provided
"A=1.1.0": {"A"},
"B": {"B"},
"B=0.8": {"B"}
},
{"A": {"A"}, # provided
"A=1.0.0": {"A"},
"B": {"B"},
"B=0.8": {"B"}
}
]
pacman.map_repositories.return_value = {"A": pkg_a.repository, "B": "community"}
pacman.map_updates_data.return_value = {"A": {'ds': 1,
's': 1,
'v': pkg_a.latest_version,
'c': {"B<=0.7"},
'p': {"A": {"A"},
"A=1.1.0": {"A"}},
'd': set(),
'r': "community",
'des': pkg_a.name}}
pacman.map_installed.return_value = {"A": pkg_a.version, "B": "0.8-1"}
pacman.get_installed_size.return_value = {"A": 1, "B": 1}
pacman.map_required_by.return_value = {"A": set()}
self.deps_analyser.map_missing_deps.return_value = list()
res = self.summarizer.summarize(pkgs=[pkg_a], root_password=None, arch_config=self.config_)
for method in ('map_provided', 'map_repositories', 'map_updates_data', 'map_installed',
'get_installed_size', 'map_required_by'):
getattr(pacman, method).assert_called()
for method in ('map_missing_deps',):
getattr(self.deps_analyser, method).assert_called()
self.assertFalse(res.to_remove)
self.assertFalse(res.to_install)
self.assertEqual([UpgradeRequirement(pkg=pkg_a, required_size=1, extra_size=0)], res.to_upgrade)
@patch("bauh.gems.arch.updates.pacman")
def test__should_return_installed_to_remove_when_conflict_with_installed_version_matches(self, pacman: Mock):
"""
If the newest version o package A conflicts with an installed package named B and the conflict expression
matches (e.g: A conflict expressions (B <= 0.7), B (0.7)) then B should be marked as a package to be removed.
"""
pkg_a = ArchPackage(name="A", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pacman.map_provided.side_effect = [{"A": {"A"}, # remote provided
"A==1.0.1": {"A"},
"B": {"B"},
"B=0.7": {"B"}
},
{"A": {"A"}, # provided
"A=1.0.0": {"A"},
"B": {"B"},
"B=0.7": {"B"}
},
{"B": {"B"}, # provided to remove
"B=0.7": {"B"}
}
]
pacman.map_repositories.return_value = {"A": pkg_a.repository, "B": "community"}
pacman.map_updates_data.return_value = {"A": {'ds': 1,
's': 1,
'v': pkg_a.latest_version,
'c': {"B<=0.7"},
'p': {"A": {"A"},
"A=1.1.0": {"A"}},
'd': set(),
'r': "community",
'des': pkg_a.name}}
pacman.map_installed.return_value = {"A": pkg_a.version, "B": "0.7-1"}
pacman.get_installed_size.return_value = {"A": 1, "B": 1}
pacman.map_required_by.return_value = {"A": set()}
self.deps_analyser.map_missing_deps.return_value = list()
self.deps_analyser.map_all_required_by.return_value = set()
res = self.summarizer.summarize(pkgs=[pkg_a], root_password=None, arch_config=self.config_)
for method in ('map_provided', 'map_repositories', 'map_updates_data', 'map_installed',
'get_installed_size', 'map_required_by'):
getattr(pacman, method).assert_called()
for method in ('map_missing_deps', 'map_all_required_by'):
getattr(self.deps_analyser, method).assert_called()
self.assertFalse(res.to_install)
self.assertEqual([UpgradeRequirement(pkg=pkg_a, required_size=1, extra_size=0)], res.to_upgrade)
pkg_b = ArchPackage(name="B", installed=True, i18n=self.i18n)
self.assertEqual([UpgradeRequirement(pkg=pkg_b, reason=" 'A'", extra_size=1)], res.to_remove)
@patch("bauh.gems.arch.updates.pacman")
def test__should_return_installed_to_remove_when_conflict_with_installed_matches(self, pacman: Mock):
"""
If the newest version o package A conflicts with an installed package named B,
then B should be marked as a package to be removed.
"""
pkg_a = ArchPackage(name="A", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pacman.map_provided.side_effect = [{"A": {"A"}, # remote provided
"A==1.0.1": {"A"},
"B": {"B"},
"B=0.7": {"B"}
},
{"A": {"A"}, # provided
"A=1.0.0": {"A"},
"B": {"B"},
"B=0.7": {"B"}
},
{"B": {"B"}, # provided to remove
"B=0.7": {"B"}
}
]
pacman.map_repositories.return_value = {"A": pkg_a.repository, "B": "community"}
pacman.map_updates_data.return_value = {"A": {'ds': 1,
's': 1,
'v': pkg_a.latest_version,
'c': {"B"},
'p': {"A": {"A"},
"A=1.1.0": {"A"}},
'd': set(),
'r': "community",
'des': pkg_a.name}}
pacman.map_installed.return_value = {"A": pkg_a.version, "B": "0.7-1"}
pacman.get_installed_size.return_value = {"A": 1, "B": 1}
pacman.map_required_by.return_value = {"A": set()}
self.deps_analyser.map_missing_deps.return_value = list()
self.deps_analyser.map_all_required_by.return_value = set()
res = self.summarizer.summarize(pkgs=[pkg_a], root_password=None, arch_config=self.config_)
for method in ('map_provided', 'map_repositories', 'map_updates_data', 'map_installed',
'get_installed_size', 'map_required_by'):
getattr(pacman, method).assert_called()
for method in ('map_missing_deps', 'map_all_required_by'):
getattr(self.deps_analyser, method).assert_called()
self.assertFalse(res.to_install)
self.assertEqual([UpgradeRequirement(pkg=pkg_a, required_size=1, extra_size=0)], res.to_upgrade)
pkg_b = ArchPackage(name="B", installed=True, i18n=self.i18n)
self.assertEqual([UpgradeRequirement(pkg=pkg_b, reason=" 'A'", extra_size=1)], res.to_remove)
@patch("bauh.gems.arch.updates.pacman")
def test__should_not_return_installed_to_remove_when_conflict_with_is_self_conflict(self, pacman: Mock):
"""
If the newest version o package A conflicts with itself, then A should not be marked as a package to be removed.
"""
pkg_a = ArchPackage(name="A", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pacman.map_provided.side_effect = [{"A": {"A"}, # remote provided
"A=1.1.0": {"A"},
"C": {"A"}
},
{"A": {"A"}, # provided
"A=1.0.0": {"A"},
"C": {"A"}
}
]
pacman.map_repositories.return_value = {"A": pkg_a.repository}
pacman.map_updates_data.return_value = {"A": {'ds': 1,
's': 1,
'v': pkg_a.latest_version,
'c': {"A<=1.0.0"},
'p': {"A": {"A"},
"A=1.1.0": {"A"},
"C": {"A"}},
'd': set(),
'r': "community",
'des': pkg_a.name}}
pacman.map_installed.return_value = {"A": pkg_a.version}
pacman.get_installed_size.return_value = {"A": 1}
pacman.map_required_by.return_value = {"A": set()}
self.deps_analyser.map_missing_deps.return_value = list()
res = self.summarizer.summarize(pkgs=[pkg_a], root_password=None, arch_config=self.config_)
for method in ('map_provided', 'map_repositories', 'map_updates_data', 'map_installed',
'get_installed_size', 'map_required_by'):
getattr(pacman, method).assert_called()
self.assertFalse(res.to_remove)
self.assertFalse(res.to_install)
self.assertEqual([UpgradeRequirement(pkg=pkg_a, required_size=1, extra_size=0)], res.to_upgrade)
@patch("bauh.gems.arch.updates.pacman")
def test__should_not_return_installed_to_remove_when_conflict_with_provided_version_fails(self, pacman: Mock):
"""
If the newest version o package A conflicts with a provided package C (by installed package B),
but the conflict expression doesn't match (e.g: A conflict expressions (C <= 0.7), C (0.8))
then B should not be marked as a package to be removed.
"""
pkg_a = ArchPackage(name="A", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pacman.map_provided.side_effect = [{"A": {"A"}, # remote provided
"A=1.1.0": {"A"},
"B": {"B", "C"},
"B=0.8": {"B", "C"},
"C": {"B"}
},
{"A": {"A"}, # provided
"A=1.0.0": {"A"},
"B": {"B", "C"},
"B=0.8": {"B", "C"},
"C": {"B"}
}
]
pacman.map_repositories.return_value = {"A": pkg_a.repository, "B": "community"}
pacman.map_updates_data.return_value = {"A": {'ds': 1,
's': 1,
'v': pkg_a.latest_version,
'c': {"C<=0.7"},
'p': {"A": {"A"},
"A=1.1.0": {"A"}},
'd': set(),
'r': "community",
'des': pkg_a.name}}
pacman.map_installed.return_value = {"A": pkg_a.version, "B": "0.8-1"}
pacman.get_installed_size.return_value = {"A": 1, "B": 1}
pacman.map_required_by.return_value = {"A": set()}
self.deps_analyser.map_missing_deps.return_value = list()
res = self.summarizer.summarize(pkgs=[pkg_a], root_password=None, arch_config=self.config_)
for method in ('map_provided', 'map_repositories', 'map_updates_data', 'map_installed',
'get_installed_size', 'map_required_by'):
getattr(pacman, method).assert_called()
self.assertFalse(res.to_remove)
self.assertFalse(res.to_install)
self.assertEqual([UpgradeRequirement(pkg=pkg_a, required_size=1, extra_size=0)], res.to_upgrade)
@patch("bauh.gems.arch.updates.pacman")
def test__not_return_to_remove_when_conflict_with_provided_virtual_package_with_version_fails(self, pacman: Mock):
"""
Scenario:
- Package V (2.5.0)[update] -> conflicts: X<21.1.1, X-ABI-VIDEODRV_VERSION<25, X-ABI-VIDEODRV_VERSION>=26
- Package X (21.1.5)[installed] -> provides: X-ABI-VIDEODRV_VERSION=25.2, X
* X provides X-ABI-VIDEODRV_VERSION with a specific version (25.2)
"""
pkg_a = ArchPackage(name="V", version="2.5.0-1", latest_version="2.6.0-1", repository="community")
pacman.map_provided.side_effect = [{"V": {"V"}, # remote provided
"V=2.5.0": {"V"},
"X": {"X"},
"X=21.1.5": {"X"},
"X-ABI-VIDEODRV_VERSION=25.2": {"X"},
"X-ABI-VIDEODRV_VERSION": {"X"}
},
{"V": {"V"}, # provided
"V=2.5.0": {"V"},
"X": {"X"},
"X=21.1.5": {"X"},
"X-ABI-VIDEODRV_VERSION=25.2": {"X"},
"X-ABI-VIDEODRV_VERSION": {"X"}
},
]
pacman.map_repositories.return_value = {"V": pkg_a.repository, "X": "community"}
pacman.map_updates_data.return_value = {"V": {'ds': 1,
's': 1,
'v': pkg_a.latest_version,
'c': {"X<21.1.1",
"X-ABI-VIDEODRV_VERSION<25",
"X-ABI-VIDEODRV_VERSION>=26"},
'p': {"V": {"V"},
"V=2.5.0": {"A"}},
'd': set(),
'r': "community",
'des': pkg_a.name}}
pacman.map_installed.return_value = {"V": pkg_a.version, "X": "21.1.5-1"}
pacman.get_installed_size.return_value = {"V": 1, "X": 1}
pacman.map_required_by.return_value = {"V": set()}
self.deps_analyser.map_missing_deps.return_value = list()
res = self.summarizer.summarize(pkgs=[pkg_a], root_password=None, arch_config=self.config_)
for method in ('map_provided', 'map_repositories', 'map_updates_data', 'map_installed',
'get_installed_size', 'map_required_by'):
getattr(pacman, method).assert_called()
self.assertFalse(res.to_remove)
self.assertFalse(res.to_install)
self.assertEqual([UpgradeRequirement(pkg=pkg_a, required_size=1, extra_size=0)], res.to_upgrade)
@patch("bauh.gems.arch.updates.pacman")
def test__return_installed_virtual_with_defined_version_to_remove_when_conflict_version_matches(self, pacman: Mock):
"""
Scenario:
- Package V (2.5.0)[update] -> conflicts: X<21.1.1, X-ABI-VIDEODRV_VERSION<25, X-ABI-VIDEODRV_VERSION>=26
- Package X (21.1.5)[installed] -> provides: X-ABI-VIDEODRV_VERSION=26, X
* X provides X-ABI-VIDEODRV_VERSION with a specific version (26)
"""
pkg_a = ArchPackage(name="V", version="2.5.0-1", latest_version="2.6.0-1", repository="community")
pacman.map_provided.side_effect = [{"V": {"V"}, # remote provided
"V=2.5.0": {"V"},
"X": {"X"},
"X=21.1.5": {"X"},
"X-ABI-VIDEODRV_VERSION=26": {"X"},
"X-ABI-VIDEODRV_VERSION": {"X"}
},
{"V": {"V"}, # provided
"V=2.5.0": {"V"},
"X": {"X"},
"X=21.1.5": {"X"},
"X-ABI-VIDEODRV_VERSION=26": {"X"},
"X-ABI-VIDEODRV_VERSION": {"X"}
},
{"X": {"X"}, # provided to remove
"X=21.1.5": {"X"},
"X-ABI-VIDEODRV_VERSION=26": {"X"},
"X-ABI-VIDEODRV_VERSION": {"X"}
}
]
pacman.map_repositories.return_value = {"V": pkg_a.repository, "X": "community"}
pacman.map_updates_data.return_value = {"V": {'ds': 1,
's': 1,
'v': pkg_a.latest_version,
'c': {"X<21.1.1",
"X-ABI-VIDEODRV_VERSION<25",
"X-ABI-VIDEODRV_VERSION>=26"},
'p': {"V": {"V"},
"V=2.5.0": {"A"}},
'd': set(),
'r': "community",
'des': pkg_a.name}}
pacman.map_installed.return_value = {"V": pkg_a.version, "X": "21.1.5-1"}
pacman.get_installed_size.return_value = {"V": 1, "X": 1}
pacman.map_required_by.return_value = {"V": set()}
self.deps_analyser.map_missing_deps.return_value = list()
self.deps_analyser.map_all_required_by.return_value = set()
res = self.summarizer.summarize(pkgs=[pkg_a], root_password=None, arch_config=self.config_)
for method in ('map_provided', 'map_repositories', 'map_updates_data', 'map_installed',
'get_installed_size', 'map_required_by'):
getattr(pacman, method).assert_called()
for method in ('map_missing_deps', 'map_all_required_by'):
getattr(self.deps_analyser, method).assert_called()
self.assertFalse(res.to_install)
self.assertEqual([UpgradeRequirement(pkg=pkg_a, required_size=1, extra_size=0)], res.to_upgrade)
pkg_b = ArchPackage(name="X", installed=True, i18n=self.i18n)
self.assertEqual([UpgradeRequirement(pkg=pkg_b, reason=" 'V'", extra_size=1)], res.to_remove)
@patch("bauh.gems.arch.updates.pacman")
def test__return_installed_virtual_with_defined_version_to_remove_when_conflict_matches__case_2(self, pacman: Mock):
"""
This test case covers the same scenario as the above, but adds an additional provider for the same
virtual package with a non-conflicting version
Scenario:
- Package V (2.5.0)[update] -> conflicts: X<21.1.1, X-ABI-VIDEODRV_VERSION<25, X-ABI-VIDEODRV_VERSION>=26
- Package X (21.1.5)[installed] -> provides: X-ABI-VIDEODRV_VERSION=26, X
- Package Z (2.0.0)[installed] -> provides: X-ABI-VIDEODRV_VERSION=25.2, Z
* X provides X-ABI-VIDEODRV_VERSION with a specific version (26) [conflict]
* Z provides X-ABI-VIDEODRV_VERSION with a specific version (25.2) [no conflict]
"""
pkg_a = ArchPackage(name="V", version="2.5.0-1", latest_version="2.6.0-1", repository="community")
pacman.map_provided.side_effect = [{"V": {"V"}, # remote provided
"V=2.5.0": {"V"},
"X": {"X"},
"X=21.1.5": {"X"},
"X-ABI-VIDEODRV_VERSION=26": {"X"},
"Z": {"Z"},
"Z=2.0.0": {"X"},
"X-ABI-VIDEODRV_VERSION=25.2": {"Z"},
"X-ABI-VIDEODRV_VERSION": {"X", "Z"},
},
{"V": {"V"}, # provided
"V=2.5.0": {"V"},
"X": {"X"},
"X=21.1.5": {"X"},
"X-ABI-VIDEODRV_VERSION=26": {"X"},
"Z": {"Z"},
"Z=2.0.0": {"X"},
"X-ABI-VIDEODRV_VERSION=25.2": {"Z"},
"X-ABI-VIDEODRV_VERSION": {"X", "Z"},
},
{"X": {"X"}, # provided to remove
"X=21.1.5": {"X"},
"X-ABI-VIDEODRV_VERSION=26": {"X"},
"X-ABI-VIDEODRV_VERSION": {"X", "Z"}
}
]
pacman.map_repositories.return_value = {"V": pkg_a.repository, "X": "community"}
pacman.map_updates_data.return_value = {"V": {'ds': 1,
's': 1,
'v': pkg_a.latest_version,
'c': {"X<21.1.1",
"X-ABI-VIDEODRV_VERSION<25",
"X-ABI-VIDEODRV_VERSION>=26"},
'p': {"V": {"V"},
"V=2.5.0": {"A"}},
'd': set(),
'r': "community",
'des': pkg_a.name}}
pacman.map_installed.return_value = {"V": pkg_a.version, "X": "21.1.5-1", "Z": "2.0.0-1"}
pacman.get_installed_size.return_value = {"V": 1, "X": 1, "Z": 1}
pacman.map_required_by.return_value = {"V": set()}
self.deps_analyser.map_missing_deps.return_value = list()
self.deps_analyser.map_all_required_by.return_value = set()
res = self.summarizer.summarize(pkgs=[pkg_a], root_password=None, arch_config=self.config_)
for method in ('map_provided', 'map_repositories', 'map_updates_data', 'map_installed',
'get_installed_size', 'map_required_by'):
getattr(pacman, method).assert_called()
for method in ('map_missing_deps', 'map_all_required_by'):
getattr(self.deps_analyser, method).assert_called()
self.assertFalse(res.to_install)
self.assertEqual([UpgradeRequirement(pkg=pkg_a, required_size=1, extra_size=0)], res.to_upgrade)
pkg_b = ArchPackage(name="X", installed=True, i18n=self.i18n)
self.assertEqual([UpgradeRequirement(pkg=pkg_b, reason=" 'V'", extra_size=1)], res.to_remove)
@patch("bauh.gems.arch.updates.pacman")
def test__should_return_installed_package_to_remove_when_conflict_with_provided_matches_version(self, pacman: Mock):
"""
If the newest version o package A conflicts with a provided package C (by installed package B),
and the conflict expression matches (e.g: A conflict expressions (C <= 0.7), C (0.7))
then B should be marked as a package to be removed.
"""
pkg_a = ArchPackage(name="A", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pacman.map_provided.side_effect = [{"A": {"A"}, # remote provided
"A=1.1.0": {"A"},
"B": {"B", "C"},
"B=0.8": {"B", "C"},
"C": {"B"}
},
{"A": {"A"}, # provided
"A=1.0.0": {"A"},
"B": {"B", "C"},
"B=0.7": {"B", "C"},
"C": {"B"}
},
{"B": {"B"}, # provided to remove
"B=0.7": {"B"}
}
]
pacman.map_repositories.return_value = {"A": pkg_a.repository, "B": "community"}
pacman.map_updates_data.return_value = {"A": {'ds': 1,
's': 1,
'v': pkg_a.latest_version,
'c': {"C<=0.7"},
'p': {"A": {"A"},
"A=1.1.0": {"A"}},
'd': set(),
'r': "community",
'des': pkg_a.name}}
pacman.map_installed.return_value = {"A": pkg_a.version, "B": "0.7-1"}
pacman.get_installed_size.return_value = {"A": 1, "B": 1}
pacman.map_required_by.return_value = {"A": set()}
self.deps_analyser.map_missing_deps.return_value = list()
self.deps_analyser.map_all_required_by.return_value = set()
res = self.summarizer.summarize(pkgs=[pkg_a], root_password=None, arch_config=self.config_)
for method in ('map_provided', 'map_repositories', 'map_updates_data', 'map_installed',
'get_installed_size', 'map_required_by'):
getattr(pacman, method).assert_called()
for method in ('map_missing_deps', 'map_all_required_by'):
getattr(self.deps_analyser, method).assert_called()
self.assertFalse(res.to_install)
self.assertEqual([UpgradeRequirement(pkg=pkg_a, required_size=1, extra_size=0)], res.to_upgrade)
pkg_b = ArchPackage(name="B", installed=True, i18n=self.i18n)
self.assertEqual([UpgradeRequirement(pkg=pkg_b, reason=" 'A'", extra_size=1)], res.to_remove)
@patch("bauh.gems.arch.updates.pacman")
def test__should_return_installed_package_to_remove_when_conflict_with_provided_matches(self, pacman: Mock):
"""
If the newest version o package A conflicts with a provided package C (by installed package B),
then B should be marked as a package to be removed.
"""
pkg_a = ArchPackage(name="A", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pacman.map_provided.side_effect = [{"A": {"A"}, # remote provided
"A=1.1.0": {"A"},
"B": {"B", "C"},
"B=0.8": {"B", "C"},
"C": {"B"}
},
{"A": {"A"}, # provided
"A=1.0.0": {"A"},
"B": {"B", "C"},
"B=0.7": {"B", "C"},
"C": {"B"}
},
{"B": {"B"}, # provided to remove
"B=0.7": {"B"}
}
]
pacman.map_repositories.return_value = {"A": pkg_a.repository, "B": "community"}
pacman.map_updates_data.return_value = {"A": {'ds': 1,
's': 1,
'v': pkg_a.latest_version,
'c': {"C"},
'p': {"A": {"A"},
"A=1.1.0": {"A"}},
'd': set(),
'r': "community",
'des': pkg_a.name}}
pacman.map_installed.return_value = {"A": pkg_a.version, "B": "0.7-1"}
pacman.get_installed_size.return_value = {"A": 1, "B": 1}
pacman.map_required_by.return_value = {"A": set()}
self.deps_analyser.map_missing_deps.return_value = list()
self.deps_analyser.map_all_required_by.return_value = set()
res = self.summarizer.summarize(pkgs=[pkg_a], root_password=None, arch_config=self.config_)
for method in ('map_provided', 'map_repositories', 'map_updates_data', 'map_installed',
'get_installed_size', 'map_required_by'):
getattr(pacman, method).assert_called()
for method in ('map_missing_deps', 'map_all_required_by'):
getattr(self.deps_analyser, method).assert_called()
self.assertFalse(res.to_install)
self.assertEqual([UpgradeRequirement(pkg=pkg_a, required_size=1, extra_size=0)], res.to_upgrade)
pkg_b = ArchPackage(name="B", installed=True, i18n=self.i18n)
self.assertEqual([UpgradeRequirement(pkg=pkg_b, reason=" 'A'", extra_size=1)], res.to_remove)
@patch("bauh.gems.arch.updates.pacman")
def test__should_not_return_installed_to_remove_when_conflict_with_provider_is_self_conflict(self, pacman: Mock):
"""
If the newest version o package A conflicts with a provided package C (by A itself),
then A should not be marked as a package to be removed.
"""
pkg_a = ArchPackage(name="A", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pacman.map_provided.side_effect = [{"A": {"A"}, # remote provided
"A=1.1.0": {"A"},
"C": {"A"}
},
{"A": {"A"}, # provided
"A=1.0.0": {"A"},
"C": {"A"}
}
]
pacman.map_repositories.return_value = {"A": pkg_a.repository}
pacman.map_updates_data.return_value = {"A": {'ds': 1,
's': 1,
'v': pkg_a.latest_version,
'c': {"C<=1.0.0"},
'p': {"A": {"A"},
"A=1.1.0": {"A"},
"C": {"A"}},
'd': set(),
'r': "community",
'des': pkg_a.name}}
pacman.map_installed.return_value = {"A": pkg_a.version}
pacman.get_installed_size.return_value = {"A": 1}
pacman.map_required_by.return_value = {"A": set()}
self.deps_analyser.map_missing_deps.return_value = list()
res = self.summarizer.summarize(pkgs=[pkg_a], root_password=None, arch_config=self.config_)
for method in ('map_provided', 'map_repositories', 'map_updates_data', 'map_installed',
'get_installed_size', 'map_required_by'):
getattr(pacman, method).assert_called()
self.assertFalse(res.to_remove)
self.assertFalse(res.to_install)
self.assertEqual([UpgradeRequirement(pkg=pkg_a, required_size=1, extra_size=0)], res.to_upgrade)
@patch("bauh.gems.arch.updates.pacman")
def test__return_as_cannot_upgrade_when_several_to_upgrade_conflict_with_each_other(self, pacman: Mock):
"""
Consider package A and B are selected to be upgraded:
If the newest version o package A conflicts with B, and newest version of B conflicts with A, then
both should be returned as "cannot upgrade"
"""
pkg_a = ArchPackage(name="A", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pkg_b = ArchPackage(name="B", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pacman.map_provided.side_effect = [{"A": {"A"}, # remote provided
"A=1.1.0": {"A"},
"B": {"B"},
"B=1.1.0": {"B"}
},
{"A": {"A"}, # provided
"A=1.0.0": {"A"},
"B": {"B"},
"B=1.0.0": {"B"},
}
]
pacman.map_repositories.return_value = {"A": pkg_a.repository, "B": pkg_b.repository}
pacman.map_updates_data.return_value = {"A": {'ds': 1,
's': 1,
'v': pkg_a.latest_version,
'c': {"B"},
'p': {"A": {"A"},
"A=1.1.0": {"A"}},
'd': set(),
'r': pkg_a.repository,
'des': pkg_a.name},
"B": {'ds': 1,
's': 1,
'v': pkg_b.latest_version,
'c': {"A"},
'p': {"B": {"B"},
"B=1.1.0": {"B"}},
'd': set(),
'r': pkg_a.repository,
'des': pkg_a.name}
}
pacman.map_installed.return_value = {"A": pkg_a.version, "B": pkg_b.version}
self.deps_analyser.map_missing_deps.return_value = list()
self.deps_analyser.map_all_required_by.return_value = set()
res = self.summarizer.summarize(pkgs=[pkg_a, pkg_b], root_password=None, arch_config=self.config_)
for method in ('map_provided', 'map_repositories', 'map_updates_data', 'map_installed'):
getattr(pacman, method).assert_called()
for method in ('map_missing_deps',):
getattr(self.deps_analyser, method).assert_called()
self.assertFalse(res.to_install)
self.assertFalse(res.to_upgrade)
self.assertEqual(2, len(res.cannot_upgrade))
self.assertIn(UpgradeRequirement(pkg=pkg_a, reason=" 'B'"), res.cannot_upgrade)
self.assertIn(UpgradeRequirement(pkg=pkg_b, reason=" 'A'"), res.cannot_upgrade)
@patch("bauh.gems.arch.updates.pacman")
def test__return_as_cannot_upgrade_when_several_to_upgrade_conflict_with_provided_by_each_other(self, pacman: Mock):
"""
Consider package A and B are selected to be upgraded:
If the newest version o package A conflicts with C (provided by B), and newest version of B
conflicts with D (provided by A), then both should be returned as "cannot upgrade"
"""
pkg_a = ArchPackage(name="A", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pkg_b = ArchPackage(name="B", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pacman.map_provided.side_effect = [{"A": {"A"}, # remote provided
"A=1.1.0": {"A"},
"B": {"B"},
"B=1.1.0": {"B"}
},
{"A": {"A"}, # provided
"A=1.0.0": {"A"},
"B": {"B"},
"B=1.0.0": {"B"},
}
]
pacman.map_repositories.return_value = {"A": pkg_a.repository, "B": pkg_b.repository}
pacman.map_updates_data.return_value = {"A": {'ds': 1,
's': 1,
'v': pkg_a.latest_version,
'c': {"C"},
'p': {"A": {"A"},
"A=1.1.0": {"A"},
"D": {"A"}},
'd': set(),
'r': pkg_a.repository,
'des': pkg_a.name},
"B": {'ds': 1,
's': 1,
'v': pkg_b.latest_version,
'c': {"D"},
'p': {"B": {"B"},
"B=1.1.0": {"B"},
"C": {"B"}},
'd': set(),
'r': pkg_a.repository,
'des': pkg_a.name}
}
pacman.map_installed.return_value = {"A": pkg_a.version, "B": pkg_b.version}
self.deps_analyser.map_missing_deps.return_value = list()
self.deps_analyser.map_all_required_by.return_value = set()
res = self.summarizer.summarize(pkgs=[pkg_a, pkg_b], root_password=None, arch_config=self.config_)
for method in ('map_provided', 'map_repositories', 'map_updates_data', 'map_installed'):
getattr(pacman, method).assert_called()
for method in ('map_missing_deps',):
getattr(self.deps_analyser, method).assert_called()
self.assertFalse(res.to_install)
self.assertFalse(res.to_upgrade)
self.assertEqual(2, len(res.cannot_upgrade))
self.assertIn(UpgradeRequirement(pkg=pkg_a, reason=" 'B'"), res.cannot_upgrade)
self.assertIn(UpgradeRequirement(pkg=pkg_b, reason=" 'A'"), res.cannot_upgrade)
@patch("bauh.gems.arch.updates.pacman")
def test__return_as_to_remove_when_a_package_to_upgrade_conflicts_with_another(self, pacman: Mock):
"""
Consider package A and B are selected to be upgraded:
If the newest version o package A conflicts with B, then B should be marked as 'to_remove'
"""
pkg_a = ArchPackage(name="A", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pkg_b = ArchPackage(name="B", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pacman.map_provided.side_effect = [{"A": {"A"}, # remote provided
"A=1.1.0": {"A"},
"B": {"B"},
"B=1.1.0": {"B"}
},
{"A": {"A"}, # provided
"A=1.0.0": {"A"},
"B": {"B"},
"B=1.0.0": {"B"},
}
]
pacman.map_repositories.return_value = {"A": pkg_a.repository, "B": pkg_b.repository}
pacman.map_updates_data.return_value = {"A": {'ds': 1,
's': 1,
'v': pkg_a.latest_version,
'c': {"B"},
'p': {"A": {"A"},
"A=1.1.0": {"A"}},
'd': set(),
'r': pkg_a.repository,
'des': pkg_a.name},
"B": {'ds': 1,
's': 1,
'v': pkg_b.latest_version,
'c': set(),
'p': {"B": {"B"},
"B=1.1.0": {"B"}},
'd': set(),
'r': pkg_a.repository,
'des': pkg_a.name}
}
pacman.map_installed.return_value = {"A": pkg_a.version, "B": pkg_b.version}
pacman.get_installed_size.return_value = {"A": 1, "B": 1}
pacman.map_required_by.return_value = {"A": set(), "B": set()}
self.deps_analyser.map_missing_deps.return_value = list()
self.deps_analyser.map_all_required_by.return_value = set()
res = self.summarizer.summarize(pkgs=[pkg_a, pkg_b], root_password=None, arch_config=self.config_)
for method in ('map_provided', 'map_repositories', 'map_updates_data', 'map_installed',
'get_installed_size', 'map_required_by'):
getattr(pacman, method).assert_called()
for method in ('map_missing_deps', 'map_all_required_by'):
getattr(self.deps_analyser, method).assert_called()
self.assertFalse(res.cannot_upgrade)
self.assertFalse(res.to_install)
self.assertEqual([UpgradeRequirement(pkg=pkg_a, required_size=1, extra_size=0)], res.to_upgrade)
self.assertEqual([UpgradeRequirement(pkg=pkg_b, reason=" 'A'", extra_size=1)], res.to_remove)
@patch("bauh.gems.arch.updates.pacman")
def test__return_as_to_remove_when_a_package_to_upgrade_conflicts_with_provided_by_another(self, pacman: Mock):
"""
Consider package A and B are selected to be upgraded:
If the newest version o package A conflicts with C (provided by B), then B should be marked as 'to_remove'
"""
pkg_a = ArchPackage(name="A", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pkg_b = ArchPackage(name="B", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pacman.map_provided.side_effect = [{"A": {"A"}, # remote provided
"A=1.1.0": {"A"},
"B": {"B"},
"B=1.1.0": {"B"},
"C": {"B"}
},
{"A": {"A"}, # provided
"A=1.0.0": {"A"},
"B": {"B"},
"B=1.0.0": {"B"},
"C": {"B"}
}
]
pacman.map_repositories.return_value = {"A": pkg_a.repository, "B": pkg_b.repository}
pacman.map_updates_data.return_value = {"A": {'ds': 1,
's': 1,
'v': pkg_a.latest_version,
'c': {"C"},
'p': {"A": {"A"},
"A=1.1.0": {"A"}},
'd': set(),
'r': pkg_a.repository,
'des': pkg_a.name},
"B": {'ds': 1,
's': 1,
'v': pkg_b.latest_version,
'c': set(),
'p': {"B": {"B"},
"B=1.1.0": {"B"},
"C": {"B"}},
'd': set(),
'r': pkg_a.repository,
'des': pkg_a.name}
}
pacman.map_installed.return_value = {"A": pkg_a.version, "B": pkg_b.version}
pacman.get_installed_size.return_value = {"A": 1, "B": 1}
pacman.map_required_by.return_value = {"A": set(), "B": set()}
self.deps_analyser.map_missing_deps.return_value = list()
self.deps_analyser.map_all_required_by.return_value = set()
res = self.summarizer.summarize(pkgs=[pkg_a, pkg_b], root_password=None, arch_config=self.config_)
for method in ('map_provided', 'map_repositories', 'map_updates_data', 'map_installed',
'get_installed_size', 'map_required_by'):
getattr(pacman, method).assert_called()
for method in ('map_missing_deps', 'map_all_required_by'):
getattr(self.deps_analyser, method).assert_called()
self.assertFalse(res.cannot_upgrade)
self.assertFalse(res.to_install)
self.assertEqual([UpgradeRequirement(pkg=pkg_a, required_size=1, extra_size=0)], res.to_upgrade)
self.assertEqual([UpgradeRequirement(pkg=pkg_b, reason=" 'A'", extra_size=1)], res.to_remove)
@patch("bauh.gems.arch.updates.pacman")
def test__return_as_to_remove_when_a_package_to_upgrade_conflicts_with_provided_version_by_another(self, pacman: Mock):
"""
Consider package A and B are selected to be upgraded:
If the newest version o package A conflicts with specific version of C (provided by B),
then B should be marked as 'to_remove'
"""
pkg_a = ArchPackage(name="A", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pkg_b = ArchPackage(name="B", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pacman.map_provided.side_effect = [{"A": {"A"}, # remote provided
"A=1.1.0": {"A"},
"B": {"B"},
"B=1.1.0": {"B"},
"C": {"B"}
},
{"A": {"A"}, # provided
"A=1.0.0": {"A"},
"B": {"B"},
"B=1.0.0": {"B"},
"C": {"B"}
}
]
pacman.map_repositories.return_value = {"A": pkg_a.repository, "B": pkg_b.repository}
pacman.map_updates_data.return_value = {"A": {'ds': 1,
's': 1,
'v': pkg_a.latest_version,
'c': {"C<=1.1.0"},
'p': {"A": {"A"},
"A=1.1.0": {"A"}},
'd': set(),
'r': pkg_a.repository,
'des': pkg_a.name},
"B": {'ds': 1,
's': 1,
'v': pkg_b.latest_version,
'c': set(),
'p': {"B": {"B"},
"B=1.1.0": {"B"},
"C": {"B"}},
'd': set(),
'r': pkg_a.repository,
'des': pkg_a.name}
}
pacman.map_installed.return_value = {"A": pkg_a.version, "B": pkg_b.version}
pacman.get_installed_size.return_value = {"A": 1, "B": 1}
pacman.map_required_by.return_value = {"A": set(), "B": set()}
self.deps_analyser.map_missing_deps.return_value = list()
self.deps_analyser.map_all_required_by.return_value = set()
res = self.summarizer.summarize(pkgs=[pkg_a, pkg_b], root_password=None, arch_config=self.config_)
for method in ('map_provided', 'map_repositories', 'map_updates_data', 'map_installed',
'get_installed_size', 'map_required_by'):
getattr(pacman, method).assert_called()
for method in ('map_missing_deps', 'map_all_required_by'):
getattr(self.deps_analyser, method).assert_called()
self.assertFalse(res.cannot_upgrade)
self.assertFalse(res.to_install)
self.assertEqual([UpgradeRequirement(pkg=pkg_a, required_size=1, extra_size=0)], res.to_upgrade)
self.assertEqual([UpgradeRequirement(pkg=pkg_b, reason=" 'A'", extra_size=1)], res.to_remove)
@patch("bauh.gems.arch.dependencies.pacman")
@patch("bauh.gems.arch.updates.pacman")
def test__return_as_cannot_upgrade_when_several_packages_to_install_conflict_with_each_other(self, *mocks: Mock):
"""
Consider package A and B are selected to be upgraded:
If the newest version o package A requires a new package C that conflicts D (new dependency of B),
and D conflicts with C, then A and B should be marked as 'cannot upgrade'.
"""
pkg_a = ArchPackage(name="A", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pkg_b = ArchPackage(name="B", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pacman, pacman_dependencies = mocks[0], mocks[1]
pacman.map_provided.side_effect = [{"A": {"A"}, # remote provided
"A=1.1.0": {"A"},
"B": {"B"},
"B=1.1.0": {"B"},
"C": {"C"},
"D": {"D"}
},
{"A": {"A"}, # provided
"A=1.0.0": {"A"},
"B": {"B"},
"B=1.0.0": {"B"},
}
]
pacman.map_repositories.return_value = {c: "community" for c in ("A", "B", "C", "D")}
pacman.map_updates_data.side_effect = [{"A": {'ds': 1,
's': 1,
'v': pkg_a.latest_version,
'c': set(),
'p': {"A": {"A"},
"A=1.1.0": {"A"}},
'd': {"C"},
'r': pkg_a.repository,
'des': "A"},
"B": {'ds': 1,
's': 1,
'v': pkg_b.latest_version,
'c': set(),
'p': {"B": {"B"},
"B=1.1.0": {"B"}},
'd': {"D"},
'r': pkg_a.repository,
'des': "B"}
},
{"C": {'ds': 1,
's': 1,
'v': "1.1.0-1",
'c': {"D"},
'p': {"C": {"C"},
"C=1.1.0": {"C"}},
'd': set(),
'r': "community",
'des': "C"},
"D": {'ds': 1,
's': 1,
'v': pkg_b.latest_version,
'c': {"C"},
'p': {"D": {"D"},
"D=1.1.0": {"D"}},
'd': set(),
'r': "community",
'des': "D"}
}]
pacman_dependencies.map_updates_data.return_value = {"C": {'ds': 1,
's': 1,
'v': "1.1.0-1",
'c': {"D"},
'p': {"C": {"C"},
"C=1.1.0": {"C"}},
'd': set(),
'r': "community",
'des': "C"},
"D": {'ds': 1,
's': 1,
'v': pkg_b.latest_version,
'c': {"C"},
'p': {"D": {"D"},
"D=1.1.0": {"D"}},
'd': set(),
'r': "community",
'des': "D"}
}
pacman.map_installed.return_value = {"A": pkg_a.version, "B": pkg_b.version}
pacman.map_required_by.return_value = {c: set() for c in ("A", "B", "C", "D")}
self.deps_analyser = DependenciesAnalyser(aur_client=self.aur_client, i18n=self.i18n, logger=Mock())
self.summarizer.deps_analyser = self.deps_analyser
res = self.summarizer.summarize(pkgs=[pkg_a, pkg_b], root_password=None, arch_config=self.config_)
for method in ('map_provided', 'map_repositories', 'map_updates_data', 'map_installed'):
getattr(pacman, method).assert_called()
pacman_dependencies.map_updates_data.assert_called()
self.assertFalse(res.to_install)
self.assertFalse(res.to_upgrade)
self.assertEqual(2, len(res.cannot_upgrade))
self.assertIn(UpgradeRequirement(pkg=pkg_a, reason="'C' 'D'"), res.cannot_upgrade)
self.assertIn(UpgradeRequirement(pkg=pkg_b, reason="'C' 'D'"), res.cannot_upgrade)
@patch("bauh.gems.arch.dependencies.pacman")
@patch("bauh.gems.arch.updates.pacman")
def test__return_as_cannot_upgrade_when_packages_to_install_conflict_with_version_of_each_other(self, *mocks: Mock):
"""
Consider package A and B are selected to be upgraded:
If the newest version o package A requires a new package C that conflicts with D's version
(new dependency of B), and D conflicts with C's version, then A and B should be marked as 'cannot upgrade'.
"""
pkg_a = ArchPackage(name="A", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pkg_b = ArchPackage(name="B", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pacman, pacman_dependencies = mocks[0], mocks[1]
pacman.map_provided.side_effect = [{"A": {"A"}, # remote provided
"A=1.1.0": {"A"},
"B": {"B"},
"B=1.1.0": {"B"},
"C": {"C"},
"D": {"D"}
},
{"A": {"A"}, # provided
"A=1.0.0": {"A"},
"B": {"B"},
"B=1.0.0": {"B"},
}
]
pacman.map_repositories.return_value = {c: "community" for c in ("A", "B", "C", "D")}
pacman.map_updates_data.side_effect = [{"A": {'ds': 1,
's': 1,
'v': pkg_a.latest_version,
'c': set(),
'p': {"A": {"A"},
"A=1.1.0": {"A"}},
'd': {"C"},
'r': pkg_a.repository,
'des': "A"},
"B": {'ds': 1,
's': 1,
'v': pkg_b.latest_version,
'c': set(),
'p': {"B": {"B"},
"B=1.1.0": {"B"}},
'd': {"D"},
'r': pkg_a.repository,
'des': "B"}
},
{"C": {'ds': 1,
's': 1,
'v': "1.1.0-1",
'c': {"D<=1.1.0"},
'p': {"C": {"C"},
"C=1.1.0": {"C"}},
'd': set(),
'r': "community",
'des': "C"},
"D": {'ds': 1,
's': 1,
'v': pkg_b.latest_version,
'c': {"C<=1.1.0"},
'p': {"D": {"D"},
"D=1.1.0": {"D"}},
'd': set(),
'r': "community",
'des': "D"}
}]
pacman_dependencies.map_updates_data.return_value = {"C": {'ds': 1,
's': 1,
'v': "1.1.0-1",
'c': {"D<=1.1.0"},
'p': {"C": {"C"},
"C=1.1.0": {"C"}},
'd': set(),
'r': "community",
'des': "C"},
"D": {'ds': 1,
's': 1,
'v': pkg_b.latest_version,
'c': {"C<=1.1.0"},
'p': {"D": {"D"},
"D=1.1.0": {"D"}},
'd': set(),
'r': "community",
'des': "D"}
}
pacman.map_installed.return_value = {"A": pkg_a.version, "B": pkg_b.version}
pacman.map_required_by.return_value = {c: set() for c in ("A", "B", "C", "D")}
self.deps_analyser = DependenciesAnalyser(aur_client=self.aur_client, i18n=self.i18n, logger=Mock())
self.summarizer.deps_analyser = self.deps_analyser
res = self.summarizer.summarize(pkgs=[pkg_a, pkg_b], root_password=None, arch_config=self.config_)
for method in ('map_provided', 'map_repositories', 'map_updates_data', 'map_installed'):
getattr(pacman, method).assert_called()
pacman_dependencies.map_updates_data.assert_called()
self.assertFalse(res.to_install)
self.assertFalse(res.to_upgrade)
self.assertEqual(2, len(res.cannot_upgrade))
self.assertIn(UpgradeRequirement(pkg=pkg_a, reason="'C' 'D'"), res.cannot_upgrade)
self.assertIn(UpgradeRequirement(pkg=pkg_b, reason="'C' 'D'"), res.cannot_upgrade)
@patch("bauh.gems.arch.dependencies.pacman")
@patch("bauh.gems.arch.updates.pacman")
def test__return_as_to_remove_when_to_update_conflicts_with_to_install(self, *mocks: Mock):
"""
Consider package A and B are selected to be upgraded:
If the newest version o package A requires a new package C that conflicts with B,
then B should be marked as "to_remove"
"""
pkg_a = ArchPackage(name="A", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pkg_b = ArchPackage(name="B", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pacman, pacman_dependencies = mocks[0], mocks[1]
pacman.map_provided.side_effect = [{"A": {"A"}, # remote provided
"A=1.1.0": {"A"},
"B": {"B"},
"B=1.1.0": {"B"},
"C": {"C"}
},
{"A": {"A"}, # provided
"A=1.0.0": {"A"},
"B": {"B"},
"B=1.0.0": {"B"},
}
]
pacman.map_repositories.return_value = {c: "community" for c in ("A", "B", "C")}
pacman.map_updates_data.side_effect = [{"A": {'ds': 1,
's': 1,
'v': pkg_a.latest_version,
'c': set(),
'p': {"A": {"A"},
"A=1.1.0": {"A"}},
'd': {"C"},
'r': pkg_a.repository,
'des': "A"},
"B": {'ds': 1,
's': 1,
'v': pkg_b.latest_version,
'c': set(),
'p': {"B": {"B"},
"B=1.1.0": {"B"}},
'd': set(),
'r': pkg_a.repository,
'des': "B"}
},
{"C": {'ds': 1,
's': 1,
'v': "1.1.0-1",
'c': {"B"},
'p': {"C": {"C"},
"C=1.1.0": {"C"}},
'd': set(),
'r': "community",
'des': "C"}
}
]
pacman_dependencies.map_updates_data.return_value = {"C": {'ds': 1,
's': 1,
'v': "1.1.0-1",
'c': {"B"},
'p': {"C": {"C"},
"C=1.1.0": {"C"}},
'd': set(),
'r': "community",
'des': "C"}
}
pacman.map_installed.return_value = {"A": pkg_a.version, "B": pkg_b.version}
pacman.map_required_by.return_value = {c: set() for c in ("A", "B", "C")}
pacman.get_installed_size.return_value = {"A": 1, "B": 1, "C": 1}
self.deps_analyser = DependenciesAnalyser(aur_client=self.aur_client, i18n=self.i18n, logger=Mock())
self.summarizer.deps_analyser = self.deps_analyser
res = self.summarizer.summarize(pkgs=[pkg_a, pkg_b], root_password=None, arch_config=self.config_)
for method in ('map_provided', 'map_repositories', 'map_updates_data', 'map_installed', 'get_installed_size',
'map_required_by'):
getattr(pacman, method).assert_called()
pacman_dependencies.map_updates_data.assert_called()
self.assertFalse(res.cannot_upgrade)
pkg_c = ArchPackage(name="C", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
self.assertEqual([UpgradeRequirement(pkg=pkg_c, required_size=1, extra_size=1, reason=": A")], res.to_install)
self.assertEqual([UpgradeRequirement(pkg=pkg_a, required_size=1, extra_size=0)], res.to_upgrade)
self.assertEqual([UpgradeRequirement(pkg=pkg_b, extra_size=1, reason=" 'C'")], res.to_remove)
@patch("bauh.gems.arch.dependencies.pacman")
@patch("bauh.gems.arch.updates.pacman")
def test__return_as_to_remove_when_to_update_conflicts_with_specific_version_of_install(self, *mocks: Mock):
"""
Consider package A and B are selected to be upgraded:
If the newest version o package A requires a new package C that conflicts with latest version of B,
then B should be marked as 'to_remove'.
"""
pkg_a = ArchPackage(name="A", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pkg_b = ArchPackage(name="B", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pacman, pacman_dependencies = mocks[0], mocks[1]
pacman.map_provided.side_effect = [{"A": {"A"}, # remote provided
"A=1.1.0": {"A"},
"B": {"B"},
"B=1.1.0": {"B"},
"C": {"C"}
},
{"A": {"A"}, # provided
"A=1.0.0": {"A"},
"B": {"B"},
"B=1.0.0": {"B"},
}
]
pacman.map_repositories.return_value = {c: "community" for c in ("A", "B", "C")}
pacman.map_updates_data.side_effect = [{"A": {'ds': 1,
's': 1,
'v': pkg_a.latest_version,
'c': set(),
'p': {"A": {"A"},
"A=1.1.0": {"A"}},
'd': {"C"},
'r': pkg_a.repository,
'des': "A"},
"B": {'ds': 1,
's': 1,
'v': pkg_b.latest_version,
'c': set(),
'p': {"B": {"B"},
"B=1.1.0": {"B"}},
'd': set(),
'r': pkg_a.repository,
'des': "B"}
},
{"C": {'ds': 1,
's': 1,
'v': "1.1.0-1",
'c': {"B<=1.1.0"},
'p': {"C": {"C"},
"C=1.1.0": {"C"}},
'd': set(),
'r': "community",
'des': "C"}
}
]
pacman_dependencies.map_updates_data.return_value = {"C": {'ds': 1,
's': 1,
'v': "1.1.0-1",
'c': {"B<=1.1.0"},
'p': {"C": {"C"},
"C=1.1.0": {"C"}},
'd': set(),
'r': "community",
'des': "C"}
}
pacman.map_installed.return_value = {"A": pkg_a.version, "B": pkg_b.version}
pacman.map_required_by.return_value = {c: set() for c in ("A", "B", "C")}
pacman.get_installed_size.return_value = {"A": 1, "B": 1, "C": 1}
self.deps_analyser = DependenciesAnalyser(aur_client=self.aur_client, i18n=self.i18n, logger=Mock())
self.summarizer.deps_analyser = self.deps_analyser
res = self.summarizer.summarize(pkgs=[pkg_a, pkg_b], root_password=None, arch_config=self.config_)
for method in ('map_provided', 'map_repositories', 'map_updates_data', 'map_installed', 'get_installed_size',
'map_required_by'):
getattr(pacman, method).assert_called()
pacman_dependencies.map_updates_data.assert_called()
self.assertFalse(res.cannot_upgrade)
pkg_c = ArchPackage(name="C", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
self.assertEqual([UpgradeRequirement(pkg=pkg_c, required_size=1, extra_size=1, reason=": A")], res.to_install)
self.assertEqual([UpgradeRequirement(pkg=pkg_a, required_size=1, extra_size=0)], res.to_upgrade)
self.assertEqual([UpgradeRequirement(pkg=pkg_b, extra_size=1, reason=" 'C'")], res.to_remove)
@patch("bauh.gems.arch.dependencies.pacman")
@patch("bauh.gems.arch.updates.pacman")
def test__return_as_to_remove_when_to_update_conflicts_with_to_install_and_it_has_deps(self, *mocks: Mock):
"""
Consider package A and B are selected to be upgraded:
If the newest version o package A requires a new package C that conflicts with B,
then B should be marked as "to_remove" and its dependents as well (package 'D').
"""
pkg_a = ArchPackage(name="A", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pkg_b = ArchPackage(name="B", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
pacman, pacman_dependencies = mocks[0], mocks[1]
pacman.map_provided.side_effect = [{"A": {"A"}, # remote provided
"A=1.1.0": {"A"},
"B": {"B"},
"B=1.1.0": {"B"},
"C": {"C"}
},
{"A": {"A"}, # provided
"A=1.0.0": {"A"},
"B": {"B"},
"B=1.0.0": {"B"},
"D": {"D"},
"D=0.7.0": {"D"}
},
{"B": {"B"}, # provided to remove
"B=1.0.0": {"B"},
"D": {"D"},
"D=0.7.0": {"D"}
}
]
pacman.map_repositories.return_value = {c: "community" for c in ("A", "B", "C", "D")}
pacman.map_updates_data.side_effect = [{"A": {'ds': 1,
's': 1,
'v': pkg_a.latest_version,
'c': set(),
'p': {"A": {"A"},
"A=1.1.0": {"A"}},
'd': {"C"},
'r': pkg_a.repository,
'des': "A"},
"B": {'ds': 1,
's': 1,
'v': pkg_b.latest_version,
'c': set(),
'p': {"B": {"B"},
"B=1.1.0": {"B"}},
'd': set(),
'r': pkg_a.repository,
'des': "B"}
},
{"C": {'ds': 1,
's': 1,
'v': "1.1.0-1",
'c': {"B"},
'p': {"C": {"C"},
"C=1.1.0": {"C"}},
'd': set(),
'r': "community",
'des': "C"}
}
]
pacman_dependencies.map_updates_data.return_value = {"C": {'ds': 1,
's': 1,
'v': "1.1.0-1",
'c': {"B"},
'p': {"C": {"C"},
"C=1.1.0": {"C"}},
'd': set(),
'r': "community",
'des': "C"}
}
pacman_dependencies.map_required_by.return_value = {"B": {"D"}}
pacman.map_installed.return_value = {"A": pkg_a.version, "B": pkg_b.version, "D": "0.7.0"}
pacman.map_required_by.return_value = {**{c: set() for c in ("A", "C", "D")}, "B": {"D"}}
pacman.map_required_dependencies.return_value = {"D": {"B"}}
pacman.get_installed_size.return_value = {"A": 1, "B": 1, "C": 1, "D": 1}
self.deps_analyser = DependenciesAnalyser(aur_client=self.aur_client, i18n=self.i18n, logger=Mock())
self.summarizer.deps_analyser = self.deps_analyser
res = self.summarizer.summarize(pkgs=[pkg_a, pkg_b], root_password=None, arch_config=self.config_)
for method in ('map_provided', 'map_repositories', 'map_updates_data', 'map_installed', 'get_installed_size',
'map_required_by', 'map_required_dependencies'):
getattr(pacman, method).assert_called()
for method in ('map_updates_data', 'map_required_by'):
getattr(pacman_dependencies, method).assert_called()
self.assertFalse(res.cannot_upgrade)
self.assertEqual([UpgradeRequirement(pkg=pkg_a, required_size=1, extra_size=0)], res.to_upgrade)
pkg_c = ArchPackage(name="C", version="1.0.0-1", latest_version="1.1.0-1", repository="community")
self.assertEqual([UpgradeRequirement(pkg=pkg_c, required_size=1, extra_size=1, reason=": A")], res.to_install)
self.assertEqual(2, len(res.to_remove))
self.assertIn(UpgradeRequirement(pkg=pkg_b, extra_size=1, reason=" 'C'"), res.to_remove)
pkg_d = ArchPackage(name="D", repository="community", version="0.7.0-1", latest_version="0.7.0-1")
self.assertIn(UpgradeRequirement(pkg=pkg_d, extra_size=1, reason=" 'B=1.0.0'"), res.to_remove)