| # Copyright 2014 Gentoo Foundation |
| # Distributed under the terms of the GNU General Public License v2 |
| |
| import collections |
| |
| from portage.dep import Atom |
| from portage.tests import TestCase |
| from _emerge.resolver.package_tracker import PackageTracker, PackageTrackerDbapiWrapper |
| |
| class PackageTrackerTestCase(TestCase): |
| |
| FakePackage = collections.namedtuple("FakePackage", |
| ["root", "cp", "cpv", "slot", "slot_atom", "version", "repo"]) |
| |
| FakeConflict = collections.namedtuple("FakeConflict", |
| ["description", "root", "pkgs"]) |
| |
| def make_pkg(self, root, atom, repo="test_repo"): |
| atom = Atom(atom) |
| slot_atom = Atom("%s:%s" % (atom.cp, atom.slot)) |
| slot = atom.slot |
| |
| return self.FakePackage(root=root, cp=atom.cp, cpv=atom.cpv, |
| slot=slot, slot_atom=slot_atom, version=atom.version, repo=repo) |
| |
| def make_conflict(self, description, root, pkgs): |
| return self.FakeConflict(description=description, root=root, pkgs=pkgs) |
| |
| def test_add_remove_discard(self): |
| p = PackageTracker() |
| |
| x1 = self.make_pkg("/", "=dev-libs/X-1:0") |
| x2 = self.make_pkg("/", "=dev-libs/X-2:0") |
| |
| p.add_pkg(x1) |
| self.assertTrue(x1 in p) |
| self.assertTrue(p.contains(x1, installed=True)) |
| self.assertTrue(p.contains(x1, installed=False)) |
| p.remove_pkg(x1) |
| self.assertTrue(x1 not in p) |
| |
| p.add_pkg(x1) |
| self.assertTrue(x1 in p) |
| p.add_pkg(x1) |
| self.assertTrue(x1 in p) |
| |
| self.assertRaises(KeyError, p.remove_pkg, x2) |
| |
| p.add_pkg(x2) |
| self.assertTrue(x2 in p) |
| p.remove_pkg(x2) |
| self.assertTrue(x2 not in p) |
| p.discard_pkg(x2) |
| self.assertTrue(x2 not in p) |
| p.add_pkg(x2) |
| self.assertTrue(x2 in p) |
| |
| all_pkgs = list(p.all_pkgs("/")) |
| self.assertEqual(len(all_pkgs), 2) |
| self.assertTrue(all_pkgs[0] is x1 and all_pkgs[1] is x2) |
| |
| self.assertEqual(len(list(p.all_pkgs("/"))), 2) |
| self.assertEqual(len(list(p.all_pkgs("/xxx"))), 0) |
| |
| def test_match(self): |
| p = PackageTracker() |
| x1 = self.make_pkg("/", "=dev-libs/X-1:0") |
| x2 = self.make_pkg("/", "=dev-libs/X-2:0") |
| x3 = self.make_pkg("/", "=dev-libs/X-3:1") |
| |
| p.add_pkg(x2) |
| p.add_pkg(x1) |
| |
| matches = list(p.match("/", Atom("=dev-libs/X-1"))) |
| self.assertTrue(x1 in matches) |
| self.assertEqual(len(matches), 1) |
| |
| matches = list(p.match("/", Atom("dev-libs/X"))) |
| self.assertTrue(x1 is matches[0] and x2 is matches[1]) |
| self.assertEqual(len(matches), 2) |
| |
| matches = list(p.match("/xxx", Atom("dev-libs/X"))) |
| self.assertEqual(len(matches), 0) |
| |
| matches = list(p.match("/", Atom("dev-libs/Y"))) |
| self.assertEqual(len(matches), 0) |
| |
| p.add_pkg(x3) |
| matches = list(p.match("/", Atom("dev-libs/X"))) |
| self.assertTrue(x1 is matches[0] and x2 is matches[1] and x3 is matches[2]) |
| self.assertEqual(len(matches), 3) |
| |
| p.remove_pkg(x3) |
| matches = list(p.match("/", Atom("dev-libs/X"))) |
| self.assertTrue(x1 is matches[0] and x2 is matches[1]) |
| self.assertEqual(len(matches), 2) |
| |
| def test_dbapi_interface(self): |
| p = PackageTracker() |
| dbapi = PackageTrackerDbapiWrapper("/", p) |
| installed = self.make_pkg("/", "=dev-libs/X-0:0") |
| x1 = self.make_pkg("/", "=dev-libs/X-1:0") |
| x2 = self.make_pkg("/", "=dev-libs/X-2:0") |
| x3 = self.make_pkg("/", "=dev-libs/X-3:0") |
| x4 = self.make_pkg("/", "=dev-libs/X-4:6") |
| x5 = self.make_pkg("/xxx", "=dev-libs/X-5:6") |
| |
| def check_dbapi(pkgs): |
| all_pkgs = set(dbapi) |
| self.assertEqual(len(all_pkgs), len(pkgs)) |
| |
| x_atom = "dev-libs/X" |
| y_atom = "dev-libs/Y" |
| matches = dbapi.cp_list(x_atom) |
| for pkg in pkgs: |
| if pkg.root == "/" and pkg.cp == x_atom: |
| self.assertTrue(pkg in matches) |
| self.assertTrue(not dbapi.cp_list(y_atom)) |
| matches = dbapi.match(x_atom) |
| for pkg in pkgs: |
| if pkg.root == "/" and pkg.cp == x_atom: |
| self.assertTrue(pkg in matches) |
| self.assertTrue(not dbapi.match(y_atom)) |
| |
| check_dbapi([]) |
| |
| p.add_installed_pkg(installed) |
| check_dbapi([installed]) |
| |
| p.add_pkg(x1) |
| check_dbapi([x1]) |
| |
| p.remove_pkg(x1) |
| check_dbapi([installed]) |
| |
| dbapi.cpv_inject(x1) |
| check_dbapi([x1]) |
| |
| dbapi.cpv_inject(x2) |
| check_dbapi([x1, x2]) |
| |
| p.remove_pkg(x1) |
| check_dbapi([x2]) |
| |
| p.add_pkg(x5) |
| check_dbapi([x2]) |
| |
| |
| def test_installed(self): |
| p = PackageTracker() |
| x1 = self.make_pkg("/", "=dev-libs/X-1:0") |
| x1b = self.make_pkg("/", "=dev-libs/X-1.1:0") |
| x2 = self.make_pkg("/", "=dev-libs/X-2:0") |
| x3 = self.make_pkg("/", "=dev-libs/X-3:1") |
| |
| def check_installed(x, should_contain, num_pkgs): |
| self.assertEqual(x in p, should_contain) |
| self.assertEqual(p.contains(x), should_contain) |
| self.assertEqual(p.contains(x1, installed=True), should_contain) |
| self.assertEqual(p.contains(x1, installed=False), False) |
| self.assertEqual(len(list(p.all_pkgs("/"))), num_pkgs) |
| |
| def check_matches(atom, expected): |
| matches = list(p.match("/", Atom(atom))) |
| self.assertEqual(len(matches), len(expected)) |
| for x, y in zip(matches, expected): |
| self.assertTrue(x is y) |
| |
| p.add_installed_pkg(x1) |
| check_installed(x1, True, 1) |
| check_matches("dev-libs/X", [x1]) |
| |
| p.add_installed_pkg(x1) |
| check_installed(x1, True, 1) |
| check_matches("dev-libs/X", [x1]) |
| |
| p.add_pkg(x2) |
| check_installed(x1, False, 1) |
| check_matches("dev-libs/X", [x2]) |
| |
| p.add_installed_pkg(x1) |
| check_installed(x1, False, 1) |
| check_matches("dev-libs/X", [x2]) |
| |
| p.add_installed_pkg(x1b) |
| check_installed(x1, False, 1) |
| check_installed(x1b, False, 1) |
| check_matches("dev-libs/X", [x2]) |
| |
| p.remove_pkg(x2) |
| check_installed(x1, True, 2) |
| check_installed(x1b, True, 2) |
| check_matches("dev-libs/X", [x1, x1b]) |
| |
| def test_conflicts(self): |
| p = PackageTracker() |
| installed1 = self.make_pkg("/", "=dev-libs/X-0:0") |
| installed2 = self.make_pkg("/", "=dev-libs/X-0.1:0") |
| x1 = self.make_pkg("/", "=dev-libs/X-1:0") |
| x2 = self.make_pkg("/", "=dev-libs/X-2:0") |
| x3 = self.make_pkg("/", "=dev-libs/X-3:0") |
| x4 = self.make_pkg("/", "=dev-libs/X-4:4") |
| x4b = self.make_pkg("/", "=dev-libs/X-4:4b::x-repo") |
| |
| def check_conflicts(expected, slot_conflicts_only=False): |
| if slot_conflicts_only: |
| conflicts = list(p.slot_conflicts()) |
| else: |
| conflicts = list(p.conflicts()) |
| self.assertEqual(len(conflicts), len(expected)) |
| for got, exp in zip(conflicts, expected): |
| self.assertEqual(got.description, exp.description) |
| self.assertEqual(got.root, exp.root) |
| self.assertEqual(len(got.pkgs), len(exp.pkgs)) |
| self.assertEqual(len(got), len(exp.pkgs)) |
| for x, y in zip(got.pkgs, exp.pkgs): |
| self.assertTrue(x is y) |
| for x, y in zip(got, exp.pkgs): |
| self.assertTrue(x is y) |
| for x in exp.pkgs: |
| self.assertTrue(x in got) |
| |
| check_conflicts([]) |
| check_conflicts([]) |
| |
| p.add_installed_pkg(installed1) |
| p.add_installed_pkg(installed2) |
| check_conflicts([]) |
| |
| p.add_pkg(x1) |
| check_conflicts([]) |
| p.add_pkg(x2) |
| check_conflicts([self.make_conflict("slot conflict", "/", [x1, x2])]) |
| p.add_pkg(x3) |
| check_conflicts([self.make_conflict("slot conflict", "/", [x1, x2, x3])]) |
| p.remove_pkg(x3) |
| check_conflicts([self.make_conflict("slot conflict", "/", [x1, x2])]) |
| p.remove_pkg(x2) |
| check_conflicts([]) |
| p.add_pkg(x3) |
| check_conflicts([self.make_conflict("slot conflict", "/", [x1, x3])]) |
| p.add_pkg(x2) |
| check_conflicts([self.make_conflict("slot conflict", "/", [x1, x3, x2])]) |
| |
| p.add_pkg(x4) |
| check_conflicts([self.make_conflict("slot conflict", "/", [x1, x3, x2])]) |
| |
| p.add_pkg(x4b) |
| check_conflicts( |
| [ |
| self.make_conflict("slot conflict", "/", [x1, x3, x2]), |
| self.make_conflict("cpv conflict", "/", [x4, x4b]), |
| ] |
| ) |
| |
| check_conflicts( |
| [ |
| self.make_conflict("slot conflict", "/", [x1, x3, x2]), |
| ], |
| slot_conflicts_only=True |
| ) |