aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/portage/tests/dbapi/test_bintree.py')
-rw-r--r--lib/portage/tests/dbapi/test_bintree.py231
1 files changed, 231 insertions, 0 deletions
diff --git a/lib/portage/tests/dbapi/test_bintree.py b/lib/portage/tests/dbapi/test_bintree.py
new file mode 100644
index 000000000..91ac338a0
--- /dev/null
+++ b/lib/portage/tests/dbapi/test_bintree.py
@@ -0,0 +1,231 @@
+# Copyright 2022-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+from unittest.mock import MagicMock, patch, call
+import os
+import tempfile
+
+from portage.tests import TestCase
+
+from portage.dbapi.bintree import binarytree
+from portage.localization import _
+from portage.const import BINREPOS_CONF_FILE
+
+
+class BinarytreeTestCase(TestCase):
+ @classmethod
+ def setUpClass(cls):
+ """
+ Create a temporary TMPDIR which prevents test
+ methods of this class from leaving behind an empty
+ /tmp/Packages file if TMPDIR is initially unset.
+ """
+ cls._orig_tmpdir = os.environ.get("TMPDIR")
+ cls._tmpdir = tempfile.TemporaryDirectory()
+ os.environ["TMPDIR"] = cls._tmpdir.name
+
+ @classmethod
+ def tearDownClass(cls):
+ cls._tmpdir.cleanup()
+ if cls._orig_tmpdir is None:
+ os.environ.pop("TMPDIR", None)
+ else:
+ os.environ["TMPDIR"] = cls._orig_tmpdir
+ del cls._orig_tmpdir, cls._tmpdir
+
+ def test_required_init_params(self):
+ with self.assertRaises(TypeError) as cm:
+ binarytree()
+ self.assertEqual(str(cm.exception), "pkgdir parameter is required")
+ with self.assertRaises(TypeError) as cm:
+ binarytree(pkgdir=os.getenv("TMPDIR", "/tmp"))
+ self.assertEqual(str(cm.exception), "settings parameter is required")
+
+ def test_init_with_legacy_params_warns(self):
+ with self.assertWarns(DeprecationWarning):
+ binarytree(
+ _unused=None, pkgdir=os.getenv("TMPDIR", "/tmp"), settings=MagicMock()
+ )
+ with self.assertWarns(DeprecationWarning):
+ binarytree(
+ virtual=None, pkgdir=os.getenv("TMPDIR", "/tmp"), settings=MagicMock()
+ )
+
+ def test_instance_has_required_attrs(self):
+ # Quite smoky test. What would it be a better testing strategy?
+ # Not sure yet...
+ required_attrs_no_multi_instance = {
+ "pkgdir",
+ "_multi_instance",
+ "dbapi",
+ "update_ents",
+ "move_slot_ent",
+ "populated",
+ "tree",
+ "_binrepos_conf",
+ "_remote_has_index",
+ "_remotepkgs",
+ "_additional_pkgs",
+ "invalids",
+ "invalid_paths",
+ "settings",
+ "_pkg_paths",
+ "_populating",
+ "_all_directory",
+ "_pkgindex_version",
+ "_pkgindex_hashes",
+ "_pkgindex_file",
+ "_pkgindex_keys",
+ "_pkgindex_aux_keys",
+ "_pkgindex_use_evaluated_keys",
+ "_pkgindex_header",
+ "_pkgindex_header_keys",
+ "_pkgindex_default_pkg_data",
+ "_pkgindex_inherited_keys",
+ "_pkgindex_default_header_data",
+ "_pkgindex_translated_keys",
+ "_pkgindex_allowed_pkg_keys",
+ }
+ no_multi_instance_settings = MagicMock()
+ no_multi_instance_settings.features = ""
+ no_multi_instance_bt = binarytree(
+ pkgdir=os.getenv("TMPDIR", "/tmp"), settings=no_multi_instance_settings
+ )
+ multi_instance_settings = MagicMock()
+ multi_instance_settings.features = "binpkg-multi-instance"
+ multi_instance_bt = binarytree(
+ pkgdir=os.getenv("TMPDIR", "/tmp"), settings=multi_instance_settings
+ )
+ for attr in required_attrs_no_multi_instance:
+ getattr(no_multi_instance_bt, attr)
+ getattr(multi_instance_bt, attr)
+ # The next attribute is the difference between multi instance
+ # and no multi instance:
+ getattr(multi_instance_bt, "_allocate_filename")
+
+ @patch("portage.dbapi.bintree.binarytree._populate_local")
+ def test_populate_without_updates_repos_nor_getbinspkgs(self, ppopulate_local):
+ bt = binarytree(pkgdir=os.getenv("TMPDIR", "/tmp"), settings=MagicMock())
+ ppopulate_local.return_value = {}
+ bt.populate()
+ ppopulate_local.assert_called_once_with(reindex=True, invalid_errors=True)
+ self.assertFalse(bt._populating)
+ self.assertTrue(bt.populated)
+
+ @patch("portage.dbapi.bintree.binarytree._populate_local")
+ def test_populate_calls_twice_populate_local_if_updates(self, ppopulate_local):
+ bt = binarytree(pkgdir=os.getenv("TMPDIR", "/tmp"), settings=MagicMock())
+ bt.populate()
+ self.assertIn(
+ call(reindex=True, invalid_errors=True), ppopulate_local.mock_calls
+ )
+ self.assertIn(call(), ppopulate_local.mock_calls)
+ self.assertEqual(ppopulate_local.call_count, 2)
+
+ @patch("portage.dbapi.bintree.binarytree._populate_additional")
+ @patch("portage.dbapi.bintree.binarytree._populate_local")
+ def test_populate_with_repos(self, ppopulate_local, ppopulate_additional):
+ repos = ("one", "two")
+ bt = binarytree(pkgdir=os.getenv("TMPDIR", "/tmp"), settings=MagicMock())
+ bt.populate(add_repos=repos)
+ ppopulate_additional.assert_called_once_with(repos)
+
+ @patch("portage.dbapi.bintree.BinRepoConfigLoader")
+ @patch("portage.dbapi.bintree.binarytree._populate_remote")
+ @patch("portage.dbapi.bintree.binarytree._populate_local")
+ def test_populate_with_getbinpkgs(
+ self, ppopulate_local, ppopulate_remote, pBinRepoConfigLoader
+ ):
+ refresh = "something"
+ settings = MagicMock()
+ settings.__getitem__.return_value = "/some/path"
+ bt = binarytree(pkgdir=os.getenv("TMPDIR", "/tmp"), settings=settings)
+ bt.populate(getbinpkgs=True, getbinpkg_refresh=refresh)
+ ppopulate_remote.assert_called_once_with(
+ getbinpkg_refresh=refresh, pretend=False
+ )
+
+ @patch("portage.dbapi.bintree.writemsg")
+ @patch("portage.dbapi.bintree.BinRepoConfigLoader")
+ @patch("portage.dbapi.bintree.binarytree._populate_remote")
+ @patch("portage.dbapi.bintree.binarytree._populate_local")
+ def test_populate_with_getbinpkgs_and_not_BinRepoConfigLoader(
+ self, ppopulate_local, ppopulate_remote, pBinRepoConfigLoader, pwritemsg
+ ):
+ refresh = "something"
+ settings = MagicMock()
+ portage_root = "/some/path"
+ settings.__getitem__.return_value = portage_root
+ pBinRepoConfigLoader.return_value = None
+ conf_file = os.path.join(portage_root, BINREPOS_CONF_FILE)
+ bt = binarytree(pkgdir=os.getenv("TMPDIR", "/tmp"), settings=settings)
+ bt.populate(getbinpkgs=True, getbinpkg_refresh=refresh)
+ ppopulate_remote.assert_not_called()
+ pwritemsg.assert_called_once_with(
+ _(
+ f"!!! {conf_file} is missing (or PORTAGE_BINHOST is unset)"
+ ", but use is requested.\n"
+ ),
+ noiselevel=-1,
+ )
+
+ @patch("portage.dbapi.bintree.BinRepoConfigLoader")
+ @patch("portage.dbapi.bintree.binarytree._populate_remote")
+ @patch("portage.dbapi.bintree.binarytree._populate_local")
+ def test_default_getbinpkg_refresh_in_populate(
+ self, ppopulate_local, ppopulate_remote, pBinRepoConfigLoader
+ ):
+ """Bug #864259
+ This test fixes the bug. It requires that
+ ``_emerge.actions.run_action`` calls ``binarytree.populate``
+ explicitly with ``getbinpkg_refresh=True``
+ """
+ settings = MagicMock()
+ settings.__getitem__.return_value = "/some/path"
+ bt = binarytree(pkgdir=os.getenv("TMPDIR", "/tmp"), settings=settings)
+ bt.populate(getbinpkgs=True)
+ ppopulate_remote.assert_called_once_with(getbinpkg_refresh=False, pretend=False)
+
+ @patch("portage.dbapi.bintree.BinRepoConfigLoader")
+ @patch("portage.dbapi.bintree.binarytree._run_trust_helper")
+ def test_default_getbinpkg_refresh_in_populate_trusthelper(
+ self, run_trust_helper, pBinRepoConfigLoader
+ ):
+ """
+ Test for bug #915842.
+
+ Verify that we call the trust helper in non-pretend mode.
+ """
+ settings = MagicMock()
+ settings.features = ["binpkg-request-signature"]
+ settings.__getitem__.return_value = "/some/path"
+
+ d = tempfile.TemporaryDirectory()
+ try:
+ bt = binarytree(pkgdir=d.name, settings=settings)
+ bt.populate(getbinpkgs=True, pretend=False)
+ run_trust_helper.assert_called_once()
+ finally:
+ d.cleanup()
+
+ @patch("portage.dbapi.bintree.BinRepoConfigLoader")
+ @patch("portage.dbapi.bintree.binarytree._run_trust_helper")
+ def test_default_getbinpkg_refresh_in_populate_trusthelper_pretend(
+ self, run_trust_helper, pBinRepoConfigLoader
+ ):
+ """
+ Test for bug #915842.
+
+ Verify we do not call the trust helper in pretend mode.
+ """
+ settings = MagicMock()
+ settings.features = ["binpkg-request-signature"]
+ settings.__getitem__.return_value = "/some/path"
+
+ d = tempfile.TemporaryDirectory()
+ try:
+ bt = binarytree(pkgdir=d.name, settings=settings)
+ bt.populate(getbinpkgs=True, pretend=True)
+ run_trust_helper.assert_not_called()
+ finally:
+ d.cleanup()