commit:     8d442378bbb03b1c95595d0a21a012291245bda7
Author:     Felix Bier <flx.bier <AT> gmail <DOT> com>
AuthorDate: Tue May 11 21:46:49 2021 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Mon May 24 06:22:38 2021 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=8d442378

unmerge: Add tests for unmerge order

This commit adds unit tests for verifying the unmerge order
that is calculated by unmerge_display().

Signed-off-by: Felix Bier <felix.bier <AT> rohde-schwarz.com>
Signed-off-by: Zac Medico <zmedico <AT> gentoo.org>

 lib/portage/tests/resolver/test_unmerge_order.py | 179 +++++++++++++++++++++++
 1 file changed, 179 insertions(+)

diff --git a/lib/portage/tests/resolver/test_unmerge_order.py 
b/lib/portage/tests/resolver/test_unmerge_order.py
new file mode 100644
index 000000000..298bfd9ea
--- /dev/null
+++ b/lib/portage/tests/resolver/test_unmerge_order.py
@@ -0,0 +1,179 @@
+# 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()

Reply via email to