| # Copyright 2021 Gentoo Authors |
| # Distributed under the terms of the GNU General Public License v2 |
| |
| import os |
| |
| from _emerge.unmerge import _unmerge_display |
| |
| from portage.tests import TestCase |
| from portage.tests.resolver.ResolverPlayground import ResolverPlayground |
| |
| class _TestData: |
| def __init__(self, unmerge_files, expected_pkgmap): |
| self.unmerge_files = unmerge_files |
| |
| # The pkgmap created by unmerge_display is a list where each entry is of the form |
| # {"selected": list(...), "omitted": set(...), "protected": set(...) }. |
| # To simplify the notation of the test data, we receive a list with entries of the form |
| # (s1,o1) |
| # The entries are then translated to the expected form: |
| # {"selected": s1, "omitted": o1, "protected": set()} |
| # The "protected" field is not relevant for testing ordering. |
| # The ordering of the "omitted" field is not relevant. |
| expand = lambda x: {"selected": x[0], "omitted": set(x[1]), "protected": set()} |
| self.expected_pkgmap = list(map(expand, expected_pkgmap)) |
| |
| class UnmergeOrderTestCase(TestCase): |
| |
| def testUnmergeOrder(self): |
| ebuilds = { |
| "c/x-1": {}, |
| |
| "c/y-2": {}, |
| "c/y-3": {}, |
| |
| "c/z-4": {}, |
| "c/z-5": {}, |
| "c/z-6": {}, |
| |
| "c/zz-4": {}, |
| "c/zz-5": {}, |
| "c/zz-6": {}, |
| } |
| installed = { |
| "c/x-1": {}, |
| |
| "c/y-2": {}, |
| |
| "c/z-4": {}, |
| "c/z-5": {}, |
| "c/z-6": {}, |
| |
| "c/zz-4": {}, |
| "c/zz-5": {}, |
| "c/zz-6": {}, |
| } |
| test_cases = ( |
| |
| # cp = category/package |
| # cpv = category/package-version |
| |
| # Single cpv atom, representing the only available instance of the cp. |
| # The pkgmap should contain exactly that cpv and no omitted packages. |
| _TestData(["c/x-1"], [ (["c/x-1"],[]) ]), |
| |
| # Single cp atom. The pkgmap should contain the only available cpv to |
| # which the cp expands, no omitted packages. |
| _TestData(["c/x"], [ (["c/x-1"],[]) ]), |
| |
| # Duplicate cpv atom, representing the only available instance of the cp. |
| # The pkgmap should contain the cpv with no omitted packages, and an empty |
| # entry representing the duplicate. |
| _TestData(["c/x-1", "c/x-1"], [ (["c/x-1"],[]), ([],[]) ]), |
| |
| # Duplicate cp atom, representing the only available instance. The pkgmap |
| # should contain the only available cpv to which the cp expands, with no |
| # omitted packages, and a second empty entry representing the duplicate. |
| _TestData(["c/x", "c/x"], [ (["c/x-1"],[]), ([],[]) ]), |
| |
| # Single cpv atom, representing one of the two available instances. The |
| # pkgmap should contain exactly that cpv. Since the other instance is not |
| # installed, there should be no omitted packages. |
| _TestData(["c/y-2"], [ (["c/y-2"],[]) ]), |
| |
| # Single cp atom. The pkgmap should contain exactly the only installed |
| # instance and no omitted packages. |
| _TestData(["c/y"], [ (["c/y-2"],[]) ]), |
| |
| # Single cpv atom, representing one of the three available instances. |
| # The pkgmap should contain exactly the cpv. Since all three instances |
| # are installed, the other two instances should be in the omitted packages. |
| _TestData(["c/z-4"], [ (["c/z-4"],["c/z-5","c/z-6"]) ]), |
| |
| # Single cp atom. The pkgmap should contain all three installed instances. |
| # Since there are no other installed instances, there should be no omitted |
| # packages. |
| _TestData(["c/z"], [ (["c/z-4","c/z-5","c/z-6"],[]) ]), |
| |
| # Two cpv atoms belonging to the same cp. The pkgmap should contain an |
| # entry for each cpv, in the same order. The third installed cpv belonging |
| # to the cp should be listed in the omitted section of each entry. |
| _TestData(["c/z-4","c/z-5"], [ (["c/z-4"],["c/z-6"]), (["c/z-5"],["c/z-6"]) ]), |
| _TestData(["c/z-5","c/z-4"], [ (["c/z-5"],["c/z-6"]), (["c/z-4"],["c/z-6"]) ]), |
| |
| # Three cpv atoms belonging to the same cp. The pkgmap should contain an |
| # entry for each cpv, in the same order. Since there are no other instances |
| # of the cp, the omitted section of each entry should be empty. |
| _TestData(["c/z-4","c/z-5","c/z-6"], [ (["c/z-4"],[]), (["c/z-5"],[]), (["c/z-6"],[]) ]), |
| _TestData(["c/z-6","c/z-5","c/z-4"], [ (["c/z-6"],[]), (["c/z-5"],[]), (["c/z-4"],[]) ]), |
| |
| # First a cp atom, then a cpv atom that is an instance of the cp. The |
| # pkgmap should contain an entry containing all installed cpv's that the cp |
| # expands to, in sorted order. It should then contain an empty entry |
| # representing the input cpv that is already covered by the expansion of |
| # the cp. |
| _TestData(["c/z","c/z-4"], [ (["c/z-4","c/z-5","c/z-6"],[]), ([],[]) ]), |
| _TestData(["c/z","c/z-6"], [ (["c/z-4","c/z-5","c/z-6"],[]), ([],[]) ]), |
| |
| # First a cpv atom, then the cp to which the cpv belongs. The pkgmap |
| # should contain an entry for the first cpv, then an entry containing |
| # the remaining cpv's to which the cp expands. |
| _TestData(["c/z-4","c/z"], [ (["c/z-4"],[]), (["c/z-5","c/z-6"],[]) ]), |
| _TestData(["c/z-6","c/z"], [ (["c/z-6"],[]), (["c/z-4","c/z-5"],[]) ]), |
| |
| # More mixed cp/cpv's. The cp should expand to all cpv's except those |
| # covered by a preceding cpv. The cpv's after the cp should result in empty |
| # entries, since they are already covered by the expansion of the cp. |
| _TestData(["c/z","c/z-4","c/z-5"], [ (["c/z-4","c/z-5","c/z-6"],[]), ([],[]), ([],[]) ]), |
| _TestData(["c/z","c/z-5","c/z-4"], [ (["c/z-4","c/z-5","c/z-6"],[]), ([],[]), ([],[]) ]), |
| _TestData(["c/z-4","c/z","c/z-5"], [ (["c/z-4"],[]), (["c/z-5","c/z-6"],[]), ([],[]) ]), |
| _TestData(["c/z-5","c/z","c/z-4"], [ (["c/z-5"],[]), (["c/z-4","c/z-6"],[]), ([],[]) ]), |
| _TestData(["c/z-4","c/z-5","c/z"], [ (["c/z-4"],[]), (["c/z-5"],[]), (["c/z-6"],[]) ]), |
| _TestData(["c/z-5","c/z-4","c/z"], [ (["c/z-5"],[]), (["c/z-4"],[]), (["c/z-6"],[]) ]), |
| _TestData(["c/z","c/z-4","c/z-5","c/z-6"], [ (["c/z-4","c/z-5","c/z-6"],[]), ([],[]), ([],[]), ([],[]) ]), |
| _TestData(["c/z","c/z-6","c/z-5","c/z-4"], [ (["c/z-4","c/z-5","c/z-6"],[]), ([],[]), ([],[]), ([],[]) ]), |
| _TestData(["c/z-4","c/z","c/z-5","c/z-6"], [ (["c/z-4"],[]), (["c/z-5","c/z-6"],[]), ([],[]), ([],[]) ]), |
| _TestData(["c/z-6","c/z","c/z-5","c/z-4"], [ (["c/z-6"],[]), (["c/z-4","c/z-5"],[]), ([],[]), ([],[]) ]), |
| _TestData(["c/z-4","c/z-5","c/z","c/z-6"], [ (["c/z-4"],[]), (["c/z-5"],[]), (["c/z-6"],[]), ([],[]) ]), |
| _TestData(["c/z-6","c/z-5","c/z","c/z-4"], [ (["c/z-6"],[]), (["c/z-5"],[]), (["c/z-4"],[]), ([],[]) ]), |
| _TestData(["c/z-4","c/z-5","c/z-6","c/z"], [ (["c/z-4"],[]), (["c/z-5"],[]), (["c/z-6"],[]), ([],[]) ]), |
| _TestData(["c/z-6","c/z-5","c/z-4","c/z"], [ (["c/z-6"],[]), (["c/z-5"],[]), (["c/z-4"],[]), ([],[]) ]), |
| |
| # Two cpv that do not belong to the same cp. The pkgmap should contain an |
| # entry for each cpv, in the same order. If there are other installed |
| # instances of the cp to which the cpv belongs, they should be listed |
| # in the omitted section. |
| _TestData(["c/x-1","c/y-2"], [ (["c/x-1"],[]), (["c/y-2"],[]) ]), |
| _TestData(["c/y-2","c/x-1"], [ (["c/y-2"],[]), (["c/x-1"],[]) ]), |
| _TestData(["c/x-1","c/z-4"], [ (["c/x-1"],[]), (["c/z-4"],["c/z-5","c/z-6"]) ]), |
| _TestData(["c/z-4","c/x-1"], [ (["c/z-4"],["c/z-5","c/z-6"]), (["c/x-1"],[]) ]), |
| |
| # cpv's/cp where some cpv's are not instances of the cp. The pkgmap should |
| # contain an entry for each in the same order, with the cp expanded |
| # to all installed instances. |
| _TestData(["c/x-1","c/z"], [ (["c/x-1"],[]), (["c/z-4","c/z-5","c/z-6"],[]) ]), |
| _TestData(["c/z","c/x-1"], [ (["c/z-4","c/z-5","c/z-6"],[]), (["c/x-1"],[]) ]), |
| _TestData(["c/x-1","c/z-4","c/z"], [ (["c/x-1"],[]), (["c/z-4"],[]), (["c/z-5","c/z-6"],[]) ]), |
| _TestData(["c/z-4","c/z","c/x-1"], [ (["c/z-4"],[]), (["c/z-5","c/z-6"],[]), (["c/x-1"],[]) ]), |
| _TestData(["c/x-1","c/z","c/z-4"], [ (["c/x-1"],[]), (["c/z-4","c/z-5","c/z-6"],[]), ([],[]) ]), |
| _TestData(["c/z","c/z-4","c/x-1"], [ (["c/z-4","c/z-5","c/z-6"],[]), ([],[]), (["c/x-1"],[]) ]), |
| |
| # Two different cp's. The pkglist should contain an entry for each cp, |
| # in the same order, containing all cpv's that the cp's expands to. |
| _TestData(["c/z","c/zz"], [ (["c/z-4","c/z-5","c/z-6"],[]), (["c/zz-4","c/zz-5","c/zz-6"],[]) ]), |
| _TestData(["c/zz","c/z"], [ (["c/zz-4","c/zz-5","c/zz-6"],[]), (["c/z-4","c/z-5","c/z-6"],[]) ]), |
| ) |
| |
| playground = ResolverPlayground(ebuilds=ebuilds, installed=installed) |
| |
| try: |
| for test_case in test_cases: |
| eroot = playground.settings['EROOT'] |
| root_config = playground.trees[eroot]["root_config"] |
| |
| res, pkgmap = _unmerge_display(root_config, [], "unmerge", test_case.unmerge_files, ordered=True) |
| |
| self.assertEqual(res, os.EX_OK) |
| self.assertEqual(pkgmap, test_case.expected_pkgmap) |
| finally: |
| playground.cleanup() |