aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/portage/tests/update/test_update_dbentry.py')
-rw-r--r--lib/portage/tests/update/test_update_dbentry.py397
1 files changed, 299 insertions, 98 deletions
diff --git a/lib/portage/tests/update/test_update_dbentry.py b/lib/portage/tests/update/test_update_dbentry.py
index bed0f4b7c..3b3f0caae 100644
--- a/lib/portage/tests/update/test_update_dbentry.py
+++ b/lib/portage/tests/update/test_update_dbentry.py
@@ -1,18 +1,23 @@
-# Copyright 2012-2013 Gentoo Foundation
+# Copyright 2012-2023 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
+import shutil
+import sys
import re
import textwrap
import portage
from portage import os
+from portage.const import SUPPORTED_GENTOO_BINPKG_FORMATS
from portage.dep import Atom
+from portage.exception import CorruptionKeyError
from portage.tests import TestCase
from portage.tests.resolver.ResolverPlayground import ResolverPlayground
from portage.update import update_dbentry
from portage.util import ensure_dirs
from portage.versions import _pkg_str
from portage._global_updates import _do_global_updates
+from portage.output import colorize
class UpdateDbentryTestCase(TestCase):
@@ -160,7 +165,6 @@ class UpdateDbentryTestCase(TestCase):
self.assertEqual(result, output_str)
def testUpdateDbentryDbapiTestCase(self):
-
ebuilds = {
"dev-libs/A-2::dont_apply_updates": {
"RDEPEND": "dev-libs/M dev-libs/N dev-libs/P",
@@ -184,9 +188,14 @@ class UpdateDbentryTestCase(TestCase):
"EAPI": "4",
"SLOT": "2",
},
+ "dev-libs/B-2::test_repo": {
+ "SLOT": "2",
+ "RDEPEND": "dev-libs/M dev-libs/N dev-libs/P",
+ "EAPI": "4",
+ },
"dev-libs/B-1::test_repo": {
"RDEPEND": "dev-libs/M dev-libs/N dev-libs/P",
- "EAPI": "4-python",
+ "EAPI": "4",
},
"dev-libs/M-1::test_repo": {
"EAPI": "4",
@@ -195,7 +204,7 @@ class UpdateDbentryTestCase(TestCase):
"EAPI": "4",
},
"dev-libs/N-2::test_repo": {
- "EAPI": "4-python",
+ "EAPI": "4",
},
}
@@ -211,7 +220,12 @@ class UpdateDbentryTestCase(TestCase):
},
"dev-libs/B-1::test_repo": {
"RDEPEND": "dev-libs/M dev-libs/N dev-libs/P",
- "EAPI": "4-python",
+ "EAPI": "4",
+ },
+ "dev-libs/B-2::test_repo": {
+ "SLOT": "2",
+ "RDEPEND": "dev-libs/M dev-libs/N dev-libs/P",
+ "EAPI": "4",
},
}
@@ -220,102 +234,289 @@ class UpdateDbentryTestCase(TestCase):
updates = textwrap.dedent(
"""
move dev-libs/M dev-libs/M-moved
- move dev-libs/N dev-libs/N.moved
"""
)
- playground = ResolverPlayground(
- binpkgs=binpkgs, ebuilds=ebuilds, installed=installed, world=world
+ for binpkg_format in SUPPORTED_GENTOO_BINPKG_FORMATS:
+ with self.subTest(binpkg_format=binpkg_format):
+ print(colorize("HILITE", binpkg_format), end=" ... ")
+ sys.stdout.flush()
+ playground = ResolverPlayground(
+ binpkgs=binpkgs,
+ ebuilds=ebuilds,
+ installed=installed,
+ world=world,
+ user_config={
+ "make.conf": (
+ f'BINPKG_FORMAT="{binpkg_format}"',
+ 'FEATURES="-binpkg-signing"',
+ ),
+ },
+ )
+
+ settings = playground.settings
+ trees = playground.trees
+ eroot = settings["EROOT"]
+ test_repo_location = settings.repositories["test_repo"].location
+ portdb = trees[eroot]["porttree"].dbapi
+ vardb = trees[eroot]["vartree"].dbapi
+ bindb = trees[eroot]["bintree"].dbapi
+ setconfig = trees[eroot]["root_config"].setconfig
+ selected_set = setconfig.getSets()["selected"]
+
+ updates_dir = os.path.join(test_repo_location, "profiles", "updates")
+
+ try:
+ ensure_dirs(updates_dir)
+ with open(os.path.join(updates_dir, "1Q-2010"), "w") as f:
+ f.write(updates)
+
+ # Create an empty updates directory, so that this
+ # repo doesn't inherit updates from the main repo.
+ ensure_dirs(
+ os.path.join(
+ portdb.getRepositoryPath("dont_apply_updates"),
+ "profiles",
+ "updates",
+ )
+ )
+
+ # Delete some things in order to trigger CorruptionKeyError during package moves.
+ corruption_atom = Atom("dev-libs/B:2")
+ # Demonstrate initial state.
+ self.assertEqual(bindb.match(corruption_atom), ["dev-libs/B-2"])
+ for cpv in bindb.match(corruption_atom):
+ os.unlink(bindb.bintree.getname(cpv))
+ self.assertRaises(
+ CorruptionKeyError,
+ bindb.aux_update,
+ cpv,
+ {"RDEPEND": "dev-libs/M-moved"},
+ )
+ # Demonstrate corrupt state.
+ self.assertEqual(bindb.match(corruption_atom), ["dev-libs/B-2"])
+
+ # Demonstrate initial state.
+ self.assertEqual(vardb.match(corruption_atom), ["dev-libs/B-2"])
+ for cpv in vardb.match(corruption_atom):
+ shutil.rmtree(vardb.getpath(cpv))
+ self.assertRaises(
+ CorruptionKeyError,
+ vardb.aux_update,
+ cpv,
+ {"RDEPEND": "dev-libs/M-moved"},
+ )
+ # Demonstrate correct state because vardbapi checks the disk.
+ self.assertEqual(vardb.match(corruption_atom), [])
+
+ global_noiselimit = portage.util.noiselimit
+ portage.util.noiselimit = -2
+ try:
+ _do_global_updates(trees, {})
+ finally:
+ portage.util.noiselimit = global_noiselimit
+
+ # Workaround for cache validation not working
+ # correctly when filesystem has timestamp precision
+ # of 1 second.
+ vardb._clear_cache()
+
+ # M -> M-moved
+ old_pattern = re.compile(r"\bdev-libs/M(\s|$)")
+ rdepend = vardb.aux_get("dev-libs/A-1", ["RDEPEND"])[0]
+ self.assertTrue(old_pattern.search(rdepend) is None)
+ self.assertTrue("dev-libs/M-moved" in rdepend)
+ rdepend = bindb.aux_get("dev-libs/A-1", ["RDEPEND"])[0]
+ self.assertTrue(old_pattern.search(rdepend) is None)
+ self.assertTrue("dev-libs/M-moved" in rdepend)
+ rdepend = vardb.aux_get("dev-libs/B-1", ["RDEPEND"])[0]
+ self.assertTrue(old_pattern.search(rdepend) is None)
+ self.assertTrue("dev-libs/M-moved" in rdepend)
+ rdepend = vardb.aux_get("dev-libs/B-1", ["RDEPEND"])[0]
+ self.assertTrue(old_pattern.search(rdepend) is None)
+ self.assertTrue("dev-libs/M-moved" in rdepend)
+
+ # dont_apply_updates
+ rdepend = vardb.aux_get("dev-libs/A-2", ["RDEPEND"])[0]
+ self.assertTrue("dev-libs/M" in rdepend)
+ self.assertTrue("dev-libs/M-moved" not in rdepend)
+ rdepend = bindb.aux_get("dev-libs/A-2", ["RDEPEND"])[0]
+ self.assertTrue("dev-libs/M" in rdepend)
+ self.assertTrue("dev-libs/M-moved" not in rdepend)
+
+ # Demonstrate that match still returns stale results
+ # due to intentional corruption.
+ self.assertEqual(bindb.match(corruption_atom), ["dev-libs/B-2"])
+
+ # Update bintree state so aux_get will properly raise KeyError.
+ for cpv in bindb.match(corruption_atom):
+ # Demonstrate that aux_get returns stale results.
+ self.assertEqual(
+ ["dev-libs/M dev-libs/N dev-libs/P"],
+ bindb.aux_get(cpv, ["RDEPEND"]),
+ )
+ bindb.bintree.remove(cpv)
+ self.assertEqual(bindb.match(corruption_atom), [])
+ self.assertRaises(
+ KeyError, bindb.aux_get, "dev-libs/B-2", ["RDEPEND"]
+ )
+ self.assertRaises(
+ KeyError, vardb.aux_get, "dev-libs/B-2", ["RDEPEND"]
+ )
+
+ selected_set.load()
+ self.assertTrue("dev-libs/M" not in selected_set)
+ self.assertTrue("dev-libs/M-moved" in selected_set)
+
+ finally:
+ playground.cleanup()
+
+ def testUpdateDbentryDbapiTestCaseWithSignature(self):
+ ebuilds = {
+ "dev-libs/A-2::dont_apply_updates": {
+ "RDEPEND": "dev-libs/M dev-libs/N dev-libs/P",
+ "EAPI": "4",
+ "SLOT": "2",
+ },
+ "dev-libs/B-2::dont_apply_updates": {
+ "RDEPEND": "dev-libs/M dev-libs/N dev-libs/P",
+ "EAPI": "4",
+ "SLOT": "2",
+ },
+ }
+
+ installed = {
+ "dev-libs/A-1::test_repo": {
+ "RDEPEND": "dev-libs/M dev-libs/N dev-libs/P",
+ "EAPI": "4",
+ },
+ "dev-libs/A-2::dont_apply_updates": {
+ "RDEPEND": "dev-libs/M dev-libs/N dev-libs/P",
+ "EAPI": "4",
+ "SLOT": "2",
+ },
+ "dev-libs/B-1::test_repo": {
+ "RDEPEND": "dev-libs/M dev-libs/N dev-libs/P",
+ "EAPI": "4",
+ },
+ "dev-libs/M-1::test_repo": {
+ "EAPI": "4",
+ },
+ "dev-libs/N-1::test_repo": {
+ "EAPI": "4",
+ },
+ "dev-libs/N-2::test_repo": {
+ "EAPI": "4",
+ },
+ }
+
+ binpkgs = {
+ "dev-libs/A-1::test_repo": {
+ "RDEPEND": "dev-libs/M dev-libs/N dev-libs/P",
+ "EAPI": "4",
+ },
+ "dev-libs/A-2::dont_apply_updates": {
+ "RDEPEND": "dev-libs/M dev-libs/N dev-libs/P",
+ "EAPI": "4",
+ "SLOT": "2",
+ },
+ "dev-libs/B-1::test_repo": {
+ "RDEPEND": "dev-libs/M dev-libs/N dev-libs/P",
+ "EAPI": "4",
+ },
+ }
+
+ world = ["dev-libs/M", "dev-libs/N"]
+
+ updates = textwrap.dedent(
+ """
+ move dev-libs/M dev-libs/M-moved
+ """
)
- settings = playground.settings
- trees = playground.trees
- eroot = settings["EROOT"]
- test_repo_location = settings.repositories["test_repo"].location
- portdb = trees[eroot]["porttree"].dbapi
- vardb = trees[eroot]["vartree"].dbapi
- bindb = trees[eroot]["bintree"].dbapi
- setconfig = trees[eroot]["root_config"].setconfig
- selected_set = setconfig.getSets()["selected"]
-
- updates_dir = os.path.join(test_repo_location, "profiles", "updates")
-
- try:
- ensure_dirs(updates_dir)
- with open(os.path.join(updates_dir, "1Q-2010"), "w") as f:
- f.write(updates)
-
- # Create an empty updates directory, so that this
- # repo doesn't inherit updates from the main repo.
- ensure_dirs(
- os.path.join(
- portdb.getRepositoryPath("dont_apply_updates"),
- "profiles",
- "updates",
+ for binpkg_format in ("gpkg",):
+ with self.subTest(binpkg_format=binpkg_format):
+ print(colorize("HILITE", binpkg_format), end=" ... ")
+ sys.stdout.flush()
+ playground = ResolverPlayground(
+ binpkgs=binpkgs,
+ ebuilds=ebuilds,
+ installed=installed,
+ world=world,
+ user_config={
+ "make.conf": (f'BINPKG_FORMAT="{binpkg_format}"',),
+ },
)
- )
-
- global_noiselimit = portage.util.noiselimit
- portage.util.noiselimit = -2
- try:
- _do_global_updates(trees, {})
- finally:
- portage.util.noiselimit = global_noiselimit
-
- # Workaround for cache validation not working
- # correctly when filesystem has timestamp precision
- # of 1 second.
- vardb._clear_cache()
-
- # M -> M-moved
- old_pattern = re.compile(r"\bdev-libs/M(\s|$)")
- rdepend = vardb.aux_get("dev-libs/A-1", ["RDEPEND"])[0]
- self.assertTrue(old_pattern.search(rdepend) is None)
- self.assertTrue("dev-libs/M-moved" in rdepend)
- rdepend = bindb.aux_get("dev-libs/A-1", ["RDEPEND"])[0]
- self.assertTrue(old_pattern.search(rdepend) is None)
- self.assertTrue("dev-libs/M-moved" in rdepend)
- rdepend = vardb.aux_get("dev-libs/B-1", ["RDEPEND"])[0]
- self.assertTrue(old_pattern.search(rdepend) is None)
- self.assertTrue("dev-libs/M-moved" in rdepend)
- rdepend = vardb.aux_get("dev-libs/B-1", ["RDEPEND"])[0]
- self.assertTrue(old_pattern.search(rdepend) is None)
- self.assertTrue("dev-libs/M-moved" in rdepend)
-
- # EAPI 4-python/*-progress N -> N.moved
- rdepend = vardb.aux_get("dev-libs/B-1", ["RDEPEND"])[0]
- old_pattern = re.compile(r"\bdev-libs/N(\s|$)")
- self.assertTrue(old_pattern.search(rdepend) is None)
- self.assertTrue("dev-libs/N.moved" in rdepend)
- rdepend = bindb.aux_get("dev-libs/B-1", ["RDEPEND"])[0]
- self.assertTrue(old_pattern.search(rdepend) is None)
- self.assertTrue("dev-libs/N.moved" in rdepend)
- self.assertRaises(KeyError, vardb.aux_get, "dev-libs/N-2", ["EAPI"])
- vardb.aux_get("dev-libs/N.moved-2", ["RDEPEND"])[0]
-
- # EAPI 4 does not allow dots in package names for N -> N.moved
- rdepend = vardb.aux_get("dev-libs/A-1", ["RDEPEND"])[0]
- self.assertTrue("dev-libs/N" in rdepend)
- self.assertTrue("dev-libs/N.moved" not in rdepend)
- rdepend = bindb.aux_get("dev-libs/A-1", ["RDEPEND"])[0]
- self.assertTrue("dev-libs/N" in rdepend)
- self.assertTrue("dev-libs/N.moved" not in rdepend)
- vardb.aux_get("dev-libs/N-1", ["RDEPEND"])[0]
- self.assertRaises(KeyError, vardb.aux_get, "dev-libs/N.moved-1", ["EAPI"])
-
- # dont_apply_updates
- rdepend = vardb.aux_get("dev-libs/A-2", ["RDEPEND"])[0]
- self.assertTrue("dev-libs/M" in rdepend)
- self.assertTrue("dev-libs/M-moved" not in rdepend)
- rdepend = bindb.aux_get("dev-libs/A-2", ["RDEPEND"])[0]
- self.assertTrue("dev-libs/M" in rdepend)
- self.assertTrue("dev-libs/M-moved" not in rdepend)
-
- selected_set.load()
- self.assertTrue("dev-libs/M" not in selected_set)
- self.assertTrue("dev-libs/M-moved" in selected_set)
- self.assertTrue("dev-libs/N" not in selected_set)
- self.assertTrue("dev-libs/N.moved" in selected_set)
-
- finally:
- playground.cleanup()
+
+ settings = playground.settings
+ trees = playground.trees
+ eroot = settings["EROOT"]
+ test_repo_location = settings.repositories["test_repo"].location
+ portdb = trees[eroot]["porttree"].dbapi
+ vardb = trees[eroot]["vartree"].dbapi
+ bindb = trees[eroot]["bintree"].dbapi
+ setconfig = trees[eroot]["root_config"].setconfig
+ selected_set = setconfig.getSets()["selected"]
+
+ updates_dir = os.path.join(test_repo_location, "profiles", "updates")
+
+ try:
+ ensure_dirs(updates_dir)
+ with open(os.path.join(updates_dir, "1Q-2010"), "w") as f:
+ f.write(updates)
+
+ # Create an empty updates directory, so that this
+ # repo doesn't inherit updates from the main repo.
+ ensure_dirs(
+ os.path.join(
+ portdb.getRepositoryPath("dont_apply_updates"),
+ "profiles",
+ "updates",
+ )
+ )
+
+ global_noiselimit = portage.util.noiselimit
+ portage.util.noiselimit = -2
+ try:
+ _do_global_updates(trees, {})
+ finally:
+ portage.util.noiselimit = global_noiselimit
+
+ # Workaround for cache validation not working
+ # correctly when filesystem has timestamp precision
+ # of 1 second.
+ vardb._clear_cache()
+
+ # M -> M-moved
+ old_pattern = re.compile(r"\bdev-libs/M(\s|$)")
+ rdepend = vardb.aux_get("dev-libs/A-1", ["RDEPEND"])[0]
+ self.assertTrue(old_pattern.search(rdepend) is None)
+ self.assertTrue("dev-libs/M-moved" in rdepend)
+ # Stale signed packages removed since a7bbb4fc4d38.
+ self.assertRaises(
+ KeyError, bindb.aux_get, "dev-libs/A-1", ["RDEPEND"]
+ )
+ # rdepend = bindb.aux_get("dev-libs/A-1", ["RDEPEND"])[0]
+ # self.assertFalse(old_pattern.search(rdepend) is None)
+ # self.assertFalse("dev-libs/M-moved" in rdepend)
+ rdepend = vardb.aux_get("dev-libs/B-1", ["RDEPEND"])[0]
+ self.assertTrue(old_pattern.search(rdepend) is None)
+ self.assertTrue("dev-libs/M-moved" in rdepend)
+ rdepend = vardb.aux_get("dev-libs/B-1", ["RDEPEND"])[0]
+ self.assertTrue(old_pattern.search(rdepend) is None)
+ self.assertTrue("dev-libs/M-moved" in rdepend)
+
+ # dont_apply_updates
+ rdepend = vardb.aux_get("dev-libs/A-2", ["RDEPEND"])[0]
+ self.assertTrue("dev-libs/M" in rdepend)
+ self.assertTrue("dev-libs/M-moved" not in rdepend)
+ rdepend = bindb.aux_get("dev-libs/A-2", ["RDEPEND"])[0]
+ self.assertTrue("dev-libs/M" in rdepend)
+ self.assertTrue("dev-libs/M-moved" not in rdepend)
+
+ selected_set.load()
+ self.assertTrue("dev-libs/M" not in selected_set)
+ self.assertTrue("dev-libs/M-moved" in selected_set)
+
+ finally:
+ playground.cleanup()