commit:     c8dd97e8475686738b5c0c2c089f102a881b4820
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Mon Apr 19 02:28:09 2021 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Mon Apr 19 06:50:21 2021 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=c8dd97e8

tests: lazily evaluate cnf_* vars (bug 783957)

Lazily evaluate cnf_* variables, allowing for mock portage.const
settings created by ResolverPlayground. In ResolverPlayground,
create symlinks for PORTAGE_BIN_PATH scripts inside the mock
EPREFIX, and restore portage.const.EPREFIX in the cleanup method.

Bug: https://bugs.gentoo.org/783957
Signed-off-by: Zac Medico <zmedico <AT> gentoo.org>

 lib/portage/dispatch_conf.py                     |  4 +-
 lib/portage/tests/__init__.py                    | 59 +++++++++++++++++-------
 lib/portage/tests/resolver/ResolverPlayground.py | 39 +++++++++++++++-
 3 files changed, 83 insertions(+), 19 deletions(-)

diff --git a/lib/portage/dispatch_conf.py b/lib/portage/dispatch_conf.py
index 148c9dd92..0356ba7bc 100644
--- a/lib/portage/dispatch_conf.py
+++ b/lib/portage/dispatch_conf.py
@@ -1,5 +1,5 @@
 # archive_conf.py -- functionality common to archive-conf and dispatch-conf
-# Copyright 2003-2020 Gentoo Authors
+# Copyright 2003-2021 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
 # Library by Wayne Davison <[email protected]>, derived from code
@@ -116,7 +116,7 @@ def read_config(mandatory_opts):
        loader = KeyValuePairFileLoader(config_path, None)
        opts, _errors = loader.load()
        if not opts:
-               print(_('dispatch-conf: Error reading /etc/dispatch-conf.conf; 
fatal'), file=sys.stderr)
+               print(_('dispatch-conf: Error reading {}; 
fatal').format(config_path), file=sys.stderr)
                sys.exit(1)
 
        # Handle quote removal here, since KeyValuePairFileLoader doesn't do 
that.

diff --git a/lib/portage/tests/__init__.py b/lib/portage/tests/__init__.py
index 972c974f2..de7e140c5 100644
--- a/lib/portage/tests/__init__.py
+++ b/lib/portage/tests/__init__.py
@@ -1,5 +1,5 @@
 # tests/__init__.py -- Portage Unit Test functionality
-# Copyright 2006-2020 Gentoo Authors
+# Copyright 2006-2021 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
 import argparse
@@ -13,21 +13,48 @@ import portage
 from portage import os
 from portage import _encodings
 from portage import _unicode_decode
-from portage.const import (EPREFIX, GLOBAL_CONFIG_PATH, PORTAGE_BASE_PATH,
-       PORTAGE_BIN_PATH)
-
-
-if portage._not_installed:
-       cnf_path = os.path.join(PORTAGE_BASE_PATH, 'cnf')
-       cnf_etc_path = cnf_path
-       cnf_bindir = PORTAGE_BIN_PATH
-       cnf_sbindir = cnf_bindir
-else:
-       cnf_path = os.path.join(EPREFIX or '/', GLOBAL_CONFIG_PATH)
-       cnf_etc_path = os.path.join(EPREFIX or '/', 'etc')
-       cnf_eprefix = EPREFIX
-       cnf_bindir = os.path.join(EPREFIX or '/', 'usr', 'bin')
-       cnf_sbindir = os.path.join(EPREFIX or '/', 'usr', 'sbin')
+from portage.proxy.objectproxy import ObjectProxy
+
+
+# This remains constant when the real value is a mock.
+EPREFIX_ORIG = portage.const.EPREFIX
+
+
+class lazy_value(ObjectProxy):
+       __slots__ = ('_func',)
+       def __init__(self, func):
+               ObjectProxy.__init__(self)
+               object.__setattr__(self, '_func', func)
+       def _get_target(self):
+               return object.__getattribute__(self, '_func')()
+
+
+@lazy_value
+def cnf_path():
+       if portage._not_installed:
+               return os.path.join(portage.const.PORTAGE_BASE_PATH, 'cnf')
+       return os.path.join(EPREFIX_ORIG or '/', 
portage.const.GLOBAL_CONFIG_PATH.lstrip(os.sep))
+
+
+@lazy_value
+def cnf_etc_path():
+       if portage._not_installed:
+               return str(cnf_path)
+       return os.path.join(EPREFIX_ORIG or '/', 'etc')
+
+
+@lazy_value
+def cnf_bindir():
+       if portage._not_installed:
+               return portage.const.PORTAGE_BIN_PATH
+       return os.path.join(portage.const.EPREFIX or '/', 'usr', 'bin')
+
+
+@lazy_value
+def cnf_sbindir():
+       if portage._not_installed:
+               return str(cnf_bindir)
+       return os.path.join(portage.const.EPREFIX or '/', 'usr', 'sbin')
 
 
 def main():

diff --git a/lib/portage/tests/resolver/ResolverPlayground.py 
b/lib/portage/tests/resolver/ResolverPlayground.py
index 4575156f2..0e9a800f8 100644
--- a/lib/portage/tests/resolver/ResolverPlayground.py
+++ b/lib/portage/tests/resolver/ResolverPlayground.py
@@ -9,7 +9,11 @@ import portage
 from itertools import permutations
 from portage import os
 from portage import shutil
-from portage.const import (GLOBAL_CONFIG_PATH, USER_CONFIG_PATH)
+from portage.const import (
+       GLOBAL_CONFIG_PATH,
+       PORTAGE_BIN_PATH,
+       USER_CONFIG_PATH,
+)
 from portage.process import find_binary
 from portage.dep import Atom, _repo_separator
 from portage.package.ebuild.config import config
@@ -68,6 +72,27 @@ class ResolverPlayground:
 </pkgmetadata>
 """
 
+       portage_bin = (
+               'ebuild',
+               'egencache',
+               'emerge',
+               'emerge-webrsync',
+               'emirrordist',
+               'glsa-check',
+               'portageq',
+               'quickpkg',
+       )
+
+       portage_sbin = (
+               'archive-conf',
+               'dispatch-conf',
+               'emaint',
+               'env-update',
+               'etc-update',
+               'fixpackages',
+               'regenworld',
+       )
+
        def __init__(self, ebuilds={}, binpkgs={}, installed={}, profile={}, 
repo_configs={}, \
                user_config={}, sets={}, world=[], world_sets=[], distfiles={}, 
eclasses={},
                eprefix=None, targetroot=False, debug=False):
@@ -85,6 +110,14 @@ class ResolverPlayground:
                        # EPREFIX/bin is used by fake true_binaries. Real 
binaries goes into EPREFIX/usr/bin
                        eubin = os.path.join(self.eprefix, "usr", "bin")
                        ensure_dirs(eubin)
+                       for x in self.portage_bin:
+                               os.symlink(os.path.join(PORTAGE_BIN_PATH, x), 
os.path.join(eubin, x))
+
+                       eusbin = os.path.join(self.eprefix, "usr", "sbin")
+                       ensure_dirs(eusbin)
+                       for x in self.portage_sbin:
+                               os.symlink(os.path.join(PORTAGE_BIN_PATH, x), 
os.path.join(eusbin, x))
+
                        essential_binaries = (
                                "awk",
                                "basename",
@@ -140,6 +173,7 @@ class ResolverPlayground:
                # this because tests should be self-contained such that
                # the "real" value of portage.const.EPREFIX is entirely
                # irrelevant (see bug #492932).
+               self._orig_eprefix = portage.const.EPREFIX
                portage.const.EPREFIX = self.eprefix.rstrip(os.sep)
 
                self.eroot = self.eprefix + os.sep
@@ -645,6 +679,9 @@ class ResolverPlayground:
                        print("\nEROOT=%s" % self.eroot)
                else:
                        shutil.rmtree(self.eroot)
+               if hasattr(self, '_orig_eprefix'):
+                       portage.const.EPREFIX = self._orig_eprefix
+
 
 class ResolverPlaygroundTestCase:
 

Reply via email to