Allow reusing gather phase results.
- Get also requires/provides of RPMs in package set. - Store the results of gather phase as pickle file. - Reuse old gather phase results in case Pungi configuration did not change, the "names" of RPMs in global package set did not change and their requires/provides did not change. - Add `gather_allow_reuse` option to enable this feature. Signed-off-by: Jan Kaluza <jkaluza@redhat.com> Add gather_allow_reuse, add more tests and better handling of gather_lookaside_repos.
This commit is contained in:
parent
a32bf4046f
commit
169fa5b453
@ -642,6 +642,10 @@ Options
|
|||||||
(*bool*) -- When set to ``True``, *Pungi* will build a self-hosting tree by
|
(*bool*) -- When set to ``True``, *Pungi* will build a self-hosting tree by
|
||||||
following build dependencies. Only use when ``gather_method = "deps"``.
|
following build dependencies. Only use when ``gather_method = "deps"``.
|
||||||
|
|
||||||
|
**gather_allow_reuse** = False
|
||||||
|
(*bool*) -- When set to ``True``, *Pungi* will try to reuse gather results
|
||||||
|
from old compose specified by ``--old-composes``.
|
||||||
|
|
||||||
**greedy_method**
|
**greedy_method**
|
||||||
(*str*) -- This option controls how package requirements are satisfied in
|
(*str*) -- This option controls how package requirements are satisfied in
|
||||||
case a particular ``Requires`` has multiple candidates.
|
case a particular ``Requires`` has multiple candidates.
|
||||||
|
@ -641,6 +641,7 @@ def make_schema():
|
|||||||
"default": _get_default_gather_backend(),
|
"default": _get_default_gather_backend(),
|
||||||
},
|
},
|
||||||
"gather_profiler": {"type": "boolean", "default": False},
|
"gather_profiler": {"type": "boolean", "default": False},
|
||||||
|
"gather_allow_reuse": {"type": "boolean", "default": False},
|
||||||
"pkgset_source": {"type": "string", "enum": ["koji", "repos"]},
|
"pkgset_source": {"type": "string", "enum": ["koji", "repos"]},
|
||||||
"createrepo_c": {"type": "boolean", "default": True},
|
"createrepo_c": {"type": "boolean", "default": True},
|
||||||
"createrepo_checksum": {
|
"createrepo_checksum": {
|
||||||
|
@ -154,6 +154,24 @@ class WorkPaths(object):
|
|||||||
path = os.path.join(path, file_name)
|
path = os.path.join(path, file_name)
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
def gather_result(self, arch=None, variant=None, create_dir=True):
|
||||||
|
"""
|
||||||
|
Examples:
|
||||||
|
work/x86_64/gather_result/x86_64.result
|
||||||
|
work/x86_64/gather_result/Server.x86_64.result
|
||||||
|
"""
|
||||||
|
arch = arch or "global"
|
||||||
|
file_name = ""
|
||||||
|
if variant:
|
||||||
|
file_name += variant.uid + "."
|
||||||
|
file_name += arch + "."
|
||||||
|
file_name += "result"
|
||||||
|
path = os.path.join(self.topdir(arch, create_dir=create_dir), "gather_result")
|
||||||
|
if create_dir:
|
||||||
|
makedirs(path)
|
||||||
|
path = os.path.join(path, file_name)
|
||||||
|
return path
|
||||||
|
|
||||||
def pungi_conf(self, arch=None, variant=None, create_dir=True, source_name=None):
|
def pungi_conf(self, arch=None, variant=None, create_dir=True, source_name=None):
|
||||||
"""
|
"""
|
||||||
Examples:
|
Examples:
|
||||||
|
@ -18,6 +18,8 @@ import json
|
|||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import threading
|
import threading
|
||||||
|
import six
|
||||||
|
from six.moves import cPickle as pickle
|
||||||
|
|
||||||
from kobo.rpmlib import parse_nvra
|
from kobo.rpmlib import parse_nvra
|
||||||
from kobo.shortcuts import run
|
from kobo.shortcuts import run
|
||||||
@ -166,6 +168,206 @@ def get_gather_methods(compose, variant):
|
|||||||
return global_method_name, methods
|
return global_method_name, methods
|
||||||
|
|
||||||
|
|
||||||
|
def load_old_gather_result(compose, arch, variant):
|
||||||
|
"""
|
||||||
|
Helper method to load `gather_packages` result from old compose.
|
||||||
|
"""
|
||||||
|
gather_result = compose.paths.work.gather_result(variant=variant, arch=arch)
|
||||||
|
old_gather_result = compose.paths.old_compose_path(gather_result)
|
||||||
|
if not old_gather_result:
|
||||||
|
return None
|
||||||
|
|
||||||
|
compose.log_info("Loading old GATHER phase results: %s", old_gather_result)
|
||||||
|
with open(old_gather_result, "rb") as f:
|
||||||
|
old_result = pickle.load(f)
|
||||||
|
return old_result
|
||||||
|
|
||||||
|
|
||||||
|
def load_old_compose_config(compose):
|
||||||
|
"""
|
||||||
|
Helper method to load Pungi config dump from old compose.
|
||||||
|
"""
|
||||||
|
config_dump_full = compose.paths.log.log_file("global", "config-dump")
|
||||||
|
config_dump_full = compose.paths.old_compose_path(config_dump_full)
|
||||||
|
if not config_dump_full:
|
||||||
|
return None
|
||||||
|
|
||||||
|
compose.log_info("Loading old config file: %s", config_dump_full)
|
||||||
|
with open(config_dump_full, "r") as f:
|
||||||
|
old_config = json.load(f)
|
||||||
|
return old_config
|
||||||
|
|
||||||
|
|
||||||
|
def reuse_old_gather_packages(compose, arch, variant, package_sets):
|
||||||
|
"""
|
||||||
|
Tries to reuse `gather_packages` result from older compose.
|
||||||
|
|
||||||
|
:param Compose compose: Compose instance.
|
||||||
|
:param str arch: Architecture to reuse old gather data for.
|
||||||
|
:param str variant: Variant to reuse old gather data for.
|
||||||
|
:param list package_sets: List of package sets to gather packages from.
|
||||||
|
:return: Old `gather_packages` result or None if old result cannot be used.
|
||||||
|
"""
|
||||||
|
log_msg = "Cannot reuse old GATHER phase results - %s"
|
||||||
|
if not compose.conf["gather_allow_reuse"]:
|
||||||
|
compose.log_info(log_msg % "reuse of old gather results is disabled.")
|
||||||
|
return
|
||||||
|
|
||||||
|
old_result = load_old_gather_result(compose, arch, variant)
|
||||||
|
if old_result is None:
|
||||||
|
compose.log_info(log_msg % "no old gather results.")
|
||||||
|
return
|
||||||
|
|
||||||
|
old_config = load_old_compose_config(compose)
|
||||||
|
if old_config is None:
|
||||||
|
compose.log_info(log_msg % "no old compose config dump.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# The dumps/loads is needed to convert all unicode strings to non-unicode ones.
|
||||||
|
config = json.loads(json.dumps(compose.conf))
|
||||||
|
for opt, value in old_config.items():
|
||||||
|
# Gather lookaside repos are updated during the gather phase. Check that
|
||||||
|
# the gather_lookaside_repos except the ones added are the same.
|
||||||
|
if opt == "gather_lookaside_repos" and opt in config:
|
||||||
|
value_to_compare = []
|
||||||
|
# Filter out repourls which starts with `compose.topdir` and also remove
|
||||||
|
# their parent list in case it would be empty.
|
||||||
|
for variant, per_arch_repos in config[opt]:
|
||||||
|
per_arch_repos_to_compare = {}
|
||||||
|
for arch, repourl in per_arch_repos.items():
|
||||||
|
# The gather_lookaside_repos config allows setting multiple repourls
|
||||||
|
# using list, but `_update_config` always uses strings. Therefore we
|
||||||
|
# only try to filter out string_types.
|
||||||
|
if isinstance(repourl, six.string_types):
|
||||||
|
continue
|
||||||
|
if not repourl.startswith(compose.topdir):
|
||||||
|
per_arch_repos_to_compare[arch] = repourl
|
||||||
|
if per_arch_repos_to_compare:
|
||||||
|
value_to_compare.append([variant, per_arch_repos_to_compare])
|
||||||
|
if value != value_to_compare:
|
||||||
|
compose.log_info(
|
||||||
|
log_msg
|
||||||
|
% ("compose configuration option gather_lookaside_repos changed.")
|
||||||
|
)
|
||||||
|
return
|
||||||
|
continue
|
||||||
|
if opt not in config or config[opt] != value:
|
||||||
|
compose.log_info(
|
||||||
|
log_msg % ("compose configuration option %s changed." % opt)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
result = {
|
||||||
|
"rpm": [],
|
||||||
|
"srpm": [],
|
||||||
|
"debuginfo": [],
|
||||||
|
}
|
||||||
|
|
||||||
|
for pkgset in package_sets:
|
||||||
|
global_pkgset = pkgset["global"]
|
||||||
|
|
||||||
|
# Return in case the old file cache does not exist.
|
||||||
|
if global_pkgset.old_file_cache is None:
|
||||||
|
compose.log_info(log_msg % "old file cache does not exist.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Do quick check to find out the number of input RPMs is the same in both
|
||||||
|
# old and new cache.
|
||||||
|
if len(global_pkgset.old_file_cache) != len(global_pkgset.file_cache):
|
||||||
|
compose.log_info(log_msg % "some RPMs have been added/removed.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Create temporary dict mapping RPM path to record in `old_result`. This
|
||||||
|
# is needed later to make things faster.
|
||||||
|
old_result_cache = {}
|
||||||
|
for old_result_key, old_result_records in old_result.items():
|
||||||
|
for old_result_record in old_result_records:
|
||||||
|
old_result_cache[old_result_record["path"]] = [
|
||||||
|
old_result_key,
|
||||||
|
old_result_record,
|
||||||
|
]
|
||||||
|
|
||||||
|
# The `old_file_cache` contains all the input RPMs from old pkgset. Some
|
||||||
|
# of these RPMs will be in older versions/releases than the ones in the
|
||||||
|
# new `file_cache`. This is OK, but we need to be able to pair them so we
|
||||||
|
# know that particular RPM package from `old_file_cache` has been updated
|
||||||
|
# by another package in the new `file_cache`.
|
||||||
|
# Following code uses "`rpm_obj.arch`-`rpm_obj.sourcerpm`-`rpm_obj.name`"
|
||||||
|
# as a key to map RPMs from `old_file_cache` to RPMs in `file_cache`.
|
||||||
|
#
|
||||||
|
# At first, we need to create helper dict with the mentioned key. The value
|
||||||
|
# is tuple in (rpm_obj, old_result_key, old_result_record) format.
|
||||||
|
key_to_old_rpm_obj = {}
|
||||||
|
for rpm_path, rpm_obj in global_pkgset.old_file_cache.items():
|
||||||
|
key = "%s-%s-%s" % (
|
||||||
|
rpm_obj.arch,
|
||||||
|
rpm_obj.sourcerpm or rpm_obj.name,
|
||||||
|
rpm_obj.name,
|
||||||
|
)
|
||||||
|
|
||||||
|
# With the current aproach, we cannot reuse old gather result in case
|
||||||
|
# there are multiple RPMs with the same arch, sourcerpm and name.
|
||||||
|
if key in key_to_old_rpm_obj:
|
||||||
|
compose.log_info(
|
||||||
|
log_msg % ("two RPMs with the same key exist: %s." % key)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
old_result_key, old_result_record = old_result_cache.get(
|
||||||
|
rpm_path, [None, None]
|
||||||
|
)
|
||||||
|
key_to_old_rpm_obj[key] = [rpm_obj, old_result_key, old_result_record]
|
||||||
|
|
||||||
|
# The `key_to_old_rpm_obj` now contains all the RPMs in the old global
|
||||||
|
# package set. We will now compare these old RPMs with the RPMs in the
|
||||||
|
# current global package set.
|
||||||
|
for rpm_path, rpm_obj in global_pkgset.file_cache.items():
|
||||||
|
key = "%s-%s-%s" % (
|
||||||
|
rpm_obj.arch,
|
||||||
|
rpm_obj.sourcerpm or rpm_obj.name,
|
||||||
|
rpm_obj.name,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check that this RPM existed even in the old package set.
|
||||||
|
if key not in key_to_old_rpm_obj:
|
||||||
|
compose.log_info(log_msg % "some RPMs have been added.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Check that requires or provides of this RPM is stil the same.
|
||||||
|
old_rpm_obj, old_result_key, old_result_record = key_to_old_rpm_obj[key]
|
||||||
|
if (
|
||||||
|
old_rpm_obj.requires != rpm_obj.requires
|
||||||
|
or old_rpm_obj.provides != rpm_obj.provides
|
||||||
|
):
|
||||||
|
compose.log_info(
|
||||||
|
log_msg % "requires or provides of some RPMs have changed."
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Add this RPM into the current result in case it has been in the
|
||||||
|
# old result.
|
||||||
|
if old_result_key and old_result_record:
|
||||||
|
# Update the path to RPM, because in the `old_result_record`,
|
||||||
|
# we might have path to old build of this RPM, but the rpm_path
|
||||||
|
# contains the updated one with the same requires/provides.
|
||||||
|
old_result_record["path"] = rpm_path
|
||||||
|
result[old_result_key].append(old_result_record)
|
||||||
|
|
||||||
|
# Delete the key from key_to_old_rpm_obj so we can find out later if all
|
||||||
|
# RPMs from the old package set have their counterpart in the current
|
||||||
|
# package set.
|
||||||
|
del key_to_old_rpm_obj[key]
|
||||||
|
|
||||||
|
# Check that all the RPMs from old_file_cache has been mapped to some RPM
|
||||||
|
# in the new file cache.
|
||||||
|
for per_arch_dict in key_to_old_rpm_obj.values():
|
||||||
|
if len(per_arch_dict) != 0:
|
||||||
|
compose.log_info(log_msg % "some RPMs have been removed.")
|
||||||
|
return
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def gather_packages(compose, arch, variant, package_sets, fulltree_excludes=None):
|
def gather_packages(compose, arch, variant, package_sets, fulltree_excludes=None):
|
||||||
# multilib white/black-list is per-arch, common for all variants
|
# multilib white/black-list is per-arch, common for all variants
|
||||||
multilib_whitelist = get_multilib_whitelist(compose, arch)
|
multilib_whitelist = get_multilib_whitelist(compose, arch)
|
||||||
@ -189,7 +391,10 @@ def gather_packages(compose, arch, variant, package_sets, fulltree_excludes=None
|
|||||||
prepopulate = get_prepopulate_packages(compose, arch, variant)
|
prepopulate = get_prepopulate_packages(compose, arch, variant)
|
||||||
fulltree_excludes = fulltree_excludes or set()
|
fulltree_excludes = fulltree_excludes or set()
|
||||||
|
|
||||||
if methods == "hybrid":
|
reused_result = reuse_old_gather_packages(compose, arch, variant, package_sets)
|
||||||
|
if reused_result:
|
||||||
|
result = reused_result
|
||||||
|
elif methods == "hybrid":
|
||||||
# This variant is using a hybrid solver. Gather all inputs and run the
|
# This variant is using a hybrid solver. Gather all inputs and run the
|
||||||
# method once.
|
# method once.
|
||||||
|
|
||||||
@ -257,6 +462,10 @@ def gather_packages(compose, arch, variant, package_sets, fulltree_excludes=None
|
|||||||
for t in ("rpm", "srpm", "debuginfo"):
|
for t in ("rpm", "srpm", "debuginfo"):
|
||||||
result[t].extend(pkg_map.get(t, []))
|
result[t].extend(pkg_map.get(t, []))
|
||||||
|
|
||||||
|
gather_result = compose.paths.work.gather_result(variant=variant, arch=arch)
|
||||||
|
with open(gather_result, "wb") as f:
|
||||||
|
pickle.dump(result, f, protocol=pickle.HIGHEST_PROTOCOL)
|
||||||
|
|
||||||
compose.log_info("[DONE ] %s" % msg)
|
compose.log_info("[DONE ] %s" % msg)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ from pungi.wrappers.pungi import PungiWrapper
|
|||||||
|
|
||||||
from pungi.arch import tree_arch_to_yum_arch
|
from pungi.arch import tree_arch_to_yum_arch
|
||||||
import pungi.phases.gather
|
import pungi.phases.gather
|
||||||
|
from pungi.phases.pkgset.pkgsets import ExtendedRpmWrapper
|
||||||
|
|
||||||
import pungi.phases.gather.method
|
import pungi.phases.gather.method
|
||||||
|
|
||||||
@ -97,7 +98,7 @@ def _format_packages(pkgs):
|
|||||||
"""Sort packages and merge name with arch."""
|
"""Sort packages and merge name with arch."""
|
||||||
result = set()
|
result = set()
|
||||||
for pkg, pkg_arch in pkgs:
|
for pkg, pkg_arch in pkgs:
|
||||||
if type(pkg) in [SimpleRpmWrapper, RpmWrapper]:
|
if type(pkg) in [SimpleRpmWrapper, RpmWrapper, ExtendedRpmWrapper]:
|
||||||
pkg_name = pkg.name
|
pkg_name = pkg.name
|
||||||
else:
|
else:
|
||||||
pkg_name = pkg
|
pkg_name = pkg
|
||||||
|
@ -21,6 +21,7 @@ import six
|
|||||||
import pungi.arch
|
import pungi.arch
|
||||||
from pungi.util import pkg_is_rpm, pkg_is_srpm, pkg_is_debug
|
from pungi.util import pkg_is_rpm, pkg_is_srpm, pkg_is_debug
|
||||||
from pungi.wrappers.comps import CompsWrapper
|
from pungi.wrappers.comps import CompsWrapper
|
||||||
|
from pungi.phases.pkgset.pkgsets import ExtendedRpmWrapper
|
||||||
|
|
||||||
import pungi.phases.gather.method
|
import pungi.phases.gather.method
|
||||||
from kobo.pkgset import SimpleRpmWrapper, RpmWrapper
|
from kobo.pkgset import SimpleRpmWrapper, RpmWrapper
|
||||||
@ -83,7 +84,8 @@ class GatherMethodNodeps(pungi.phases.gather.method.GatherMethodBase):
|
|||||||
):
|
):
|
||||||
continue
|
continue
|
||||||
elif (
|
elif (
|
||||||
type(gathered_pkg) in [SimpleRpmWrapper, RpmWrapper]
|
type(gathered_pkg)
|
||||||
|
in [SimpleRpmWrapper, RpmWrapper, ExtendedRpmWrapper]
|
||||||
and pkg.nevra != gathered_pkg.nevra
|
and pkg.nevra != gathered_pkg.nevra
|
||||||
):
|
):
|
||||||
continue
|
continue
|
||||||
|
@ -34,6 +34,19 @@ from pungi.util import pkg_is_srpm
|
|||||||
from pungi.arch import get_valid_arches, is_excluded
|
from pungi.arch import get_valid_arches, is_excluded
|
||||||
|
|
||||||
|
|
||||||
|
class ExtendedRpmWrapper(kobo.pkgset.SimpleRpmWrapper):
|
||||||
|
"""
|
||||||
|
ExtendedRpmWrapper extracts only certain RPM fields instead of
|
||||||
|
keeping the whole RPM header in memory.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, file_path, ts=None, **kwargs):
|
||||||
|
kobo.pkgset.SimpleRpmWrapper.__init__(self, file_path, ts=ts)
|
||||||
|
header = kobo.rpmlib.get_rpm_header(file_path, ts=ts)
|
||||||
|
self.requires = set(kobo.rpmlib.get_header_field(header, "requires"))
|
||||||
|
self.provides = set(kobo.rpmlib.get_header_field(header, "provides"))
|
||||||
|
|
||||||
|
|
||||||
class ReaderPool(ThreadPool):
|
class ReaderPool(ThreadPool):
|
||||||
def __init__(self, package_set, logger=None):
|
def __init__(self, package_set, logger=None):
|
||||||
ThreadPool.__init__(self, logger)
|
ThreadPool.__init__(self, logger)
|
||||||
@ -55,14 +68,19 @@ class ReaderThread(WorkerThread):
|
|||||||
|
|
||||||
# In case we have old file cache data, try to reuse it.
|
# In case we have old file cache data, try to reuse it.
|
||||||
if self.pool.package_set.old_file_cache:
|
if self.pool.package_set.old_file_cache:
|
||||||
# The kobo.pkgset.FileCache does not have any method to check if
|
# Try to find the RPM in old_file_cache and reuse it instead of
|
||||||
# the RPM is in cache. Instead it just re-uses the cached RPM data,
|
# reading its headers again.
|
||||||
# if available, in .add() method.
|
try:
|
||||||
# Therefore we call `old_file_cache.add()` which either returns the
|
rpm_obj = self.pool.package_set.old_file_cache[rpm_path]
|
||||||
# cached RPM object fast or just loads it from filesystem. We then
|
except KeyError:
|
||||||
# add the returned RPM object to real `file_cache` directly.
|
rpm_obj = None
|
||||||
rpm_obj = self.pool.package_set.old_file_cache.add(rpm_path)
|
|
||||||
self.pool.package_set.file_cache[rpm_path] = rpm_obj
|
# Also reload rpm_obj if it's not ExtendedRpmWrapper object
|
||||||
|
# to get the requires/provides data into the cache.
|
||||||
|
if rpm_obj and isinstance(rpm_obj, ExtendedRpmWrapper):
|
||||||
|
self.pool.package_set.file_cache[rpm_path] = rpm_obj
|
||||||
|
else:
|
||||||
|
rpm_obj = self.pool.package_set.file_cache.add(rpm_path)
|
||||||
else:
|
else:
|
||||||
rpm_obj = self.pool.package_set.file_cache.add(rpm_path)
|
rpm_obj = self.pool.package_set.file_cache.add(rpm_path)
|
||||||
self.pool.package_set.rpms_by_arch.setdefault(rpm_obj.arch, []).append(rpm_obj)
|
self.pool.package_set.rpms_by_arch.setdefault(rpm_obj.arch, []).append(rpm_obj)
|
||||||
@ -90,7 +108,7 @@ class PackageSetBase(kobo.log.LoggingBase):
|
|||||||
):
|
):
|
||||||
super(PackageSetBase, self).__init__(logger=logger)
|
super(PackageSetBase, self).__init__(logger=logger)
|
||||||
self.name = name
|
self.name = name
|
||||||
self.file_cache = kobo.pkgset.FileCache(kobo.pkgset.SimpleRpmWrapper)
|
self.file_cache = kobo.pkgset.FileCache(ExtendedRpmWrapper)
|
||||||
self.old_file_cache = None
|
self.old_file_cache = None
|
||||||
self.sigkey_ordering = tuple(sigkey_ordering or [None])
|
self.sigkey_ordering = tuple(sigkey_ordering or [None])
|
||||||
self.arches = arches
|
self.arches = arches
|
||||||
|
@ -24,12 +24,14 @@ class MockPackageSet(dict):
|
|||||||
|
|
||||||
|
|
||||||
class MockPkg(object):
|
class MockPkg(object):
|
||||||
def __init__(self, path, is_system_release=False):
|
def __init__(self, path, is_system_release=False, **kwargs):
|
||||||
self.path = path
|
self.path = path
|
||||||
self.is_system_release = is_system_release
|
self.is_system_release = is_system_release
|
||||||
filename = os.path.basename(path)
|
filename = os.path.basename(path)
|
||||||
self.nvr, self.arch, _ = filename.rsplit(".", 2)
|
self.nvr, self.arch, _ = filename.rsplit(".", 2)
|
||||||
self.name, self.version, self.release = self.nvr.rsplit("-", 2)
|
self.name, self.version, self.release = self.nvr.rsplit("-", 2)
|
||||||
|
for k, v in kwargs.items():
|
||||||
|
setattr(self, k, v)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return self.nvr
|
return self.nvr
|
||||||
@ -1080,6 +1082,11 @@ class TestGatherPackages(helpers.PungiTestCase):
|
|||||||
if s == "comps"
|
if s == "comps"
|
||||||
else (None, None, None)
|
else (None, None, None)
|
||||||
)
|
)
|
||||||
|
get_gather_method.return_value.return_value.return_value = {
|
||||||
|
"rpm": [],
|
||||||
|
"srpm": [],
|
||||||
|
"debuginfo": [],
|
||||||
|
}
|
||||||
compose = helpers.DummyCompose(self.topdir, {"gather_method": "hybrid"})
|
compose = helpers.DummyCompose(self.topdir, {"gather_method": "hybrid"})
|
||||||
variant = compose.variants["Server"]
|
variant = compose.variants["Server"]
|
||||||
pkg_set = mock.Mock()
|
pkg_set = mock.Mock()
|
||||||
@ -1094,6 +1101,297 @@ class TestGatherPackages(helpers.PungiTestCase):
|
|||||||
self.assertEqual(method_kwargs["groups"], groups)
|
self.assertEqual(method_kwargs["groups"], groups)
|
||||||
|
|
||||||
|
|
||||||
|
class TestReuseOldGatherPackages(helpers.PungiTestCase):
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_gather_result")
|
||||||
|
def test_reuse_no_old_gather_result(self, load_old_gather_result):
|
||||||
|
load_old_gather_result.return_value = None
|
||||||
|
|
||||||
|
compose = helpers.DummyCompose(self.topdir, {"gather_allow_reuse": True})
|
||||||
|
result = gather.reuse_old_gather_packages(
|
||||||
|
compose, "x86_64", compose.variants["Server"], []
|
||||||
|
)
|
||||||
|
self.assertEqual(result, None)
|
||||||
|
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_gather_result")
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_compose_config")
|
||||||
|
def test_reuse_no_old_compose_config(
|
||||||
|
self, load_old_compose_config, load_old_gather_result
|
||||||
|
):
|
||||||
|
load_old_gather_result.return_value = {
|
||||||
|
"rpm": [{"path": "/build/bash-1.0.0-1.x86_64.rpm"}],
|
||||||
|
"srpm": [],
|
||||||
|
"debuginfo": [],
|
||||||
|
}
|
||||||
|
|
||||||
|
compose = helpers.DummyCompose(self.topdir, {"gather_allow_reuse": True})
|
||||||
|
load_old_compose_config.return_value = None
|
||||||
|
|
||||||
|
result = gather.reuse_old_gather_packages(
|
||||||
|
compose, "x86_64", compose.variants["Server"], []
|
||||||
|
)
|
||||||
|
self.assertEqual(result, None)
|
||||||
|
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_gather_result")
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_compose_config")
|
||||||
|
def test_reuse_compose_config_different(
|
||||||
|
self, load_old_compose_config, load_old_gather_result
|
||||||
|
):
|
||||||
|
load_old_gather_result.return_value = {
|
||||||
|
"rpm": [{"path": "/build/bash-1.0.0-1.x86_64.rpm"}],
|
||||||
|
"srpm": [],
|
||||||
|
"debuginfo": [],
|
||||||
|
}
|
||||||
|
|
||||||
|
compose = helpers.DummyCompose(self.topdir, {"gather_allow_reuse": True})
|
||||||
|
compose_conf_copy = dict(compose.conf)
|
||||||
|
compose_conf_copy["gather_method"] = "nodeps"
|
||||||
|
load_old_compose_config.return_value = compose_conf_copy
|
||||||
|
|
||||||
|
result = gather.reuse_old_gather_packages(
|
||||||
|
compose, "x86_64", compose.variants["Server"], []
|
||||||
|
)
|
||||||
|
self.assertEqual(result, None)
|
||||||
|
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_gather_result")
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_compose_config")
|
||||||
|
def test_reuse_compose_config_different(
|
||||||
|
self, load_old_compose_config, load_old_gather_result
|
||||||
|
):
|
||||||
|
load_old_gather_result.return_value = {
|
||||||
|
"rpm": [{"path": "/build/bash-1.0.0-1.x86_64.rpm"}],
|
||||||
|
"srpm": [],
|
||||||
|
"debuginfo": [],
|
||||||
|
}
|
||||||
|
|
||||||
|
compose = helpers.DummyCompose(self.topdir, {"gather_allow_reuse": True})
|
||||||
|
compose_conf_copy = dict(compose.conf)
|
||||||
|
compose_conf_copy["gather_method"] = "nodeps"
|
||||||
|
load_old_compose_config.return_value = compose_conf_copy
|
||||||
|
|
||||||
|
result = gather.reuse_old_gather_packages(
|
||||||
|
compose, "x86_64", compose.variants["Server"], []
|
||||||
|
)
|
||||||
|
self.assertEqual(result, None)
|
||||||
|
|
||||||
|
def _prepare_package_sets(
|
||||||
|
self, load_old_gather_result, extra_global_pkgs=None, **kwargs
|
||||||
|
):
|
||||||
|
old_rpm = "/build/bash-1.0.0-1.x86_64.rpm"
|
||||||
|
new_rpm = "/build/bash-1.0.0-2.x86_64.rpm"
|
||||||
|
|
||||||
|
pkg_old = MockPkg(old_rpm, sourcerpm="bash", requires=[], provides=[])
|
||||||
|
pkg_new = MockPkg(new_rpm, sourcerpm="bash", **kwargs)
|
||||||
|
pkgset = MockPackageSet(pkg_new)
|
||||||
|
pkgset.old_file_cache = {pkg_old.path: pkg_old}
|
||||||
|
pkgset.file_cache = {pkg_new.path: pkg_new}
|
||||||
|
package_sets = [{"global": pkgset, "x86_64": pkgset}]
|
||||||
|
|
||||||
|
load_old_gather_result.return_value = {
|
||||||
|
"rpm": [{"path": old_rpm}],
|
||||||
|
"srpm": [],
|
||||||
|
"debuginfo": [],
|
||||||
|
}
|
||||||
|
return package_sets
|
||||||
|
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_gather_result")
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_compose_config")
|
||||||
|
def test_reuse(self, load_old_compose_config, load_old_gather_result):
|
||||||
|
package_sets = self._prepare_package_sets(
|
||||||
|
load_old_gather_result, requires=[], provides=[]
|
||||||
|
)
|
||||||
|
compose = helpers.DummyCompose(self.topdir, {"gather_allow_reuse": True})
|
||||||
|
load_old_compose_config.return_value = compose.conf
|
||||||
|
|
||||||
|
result = gather.reuse_old_gather_packages(
|
||||||
|
compose, "x86_64", compose.variants["Server"], package_sets
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
result,
|
||||||
|
{
|
||||||
|
"debuginfo": [],
|
||||||
|
"rpm": [{"path": "/build/bash-1.0.0-2.x86_64.rpm"}],
|
||||||
|
"srpm": [],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_gather_result")
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_compose_config")
|
||||||
|
def test_reuse_update_gather_lookaside_repos(
|
||||||
|
self, load_old_compose_config, load_old_gather_result
|
||||||
|
):
|
||||||
|
package_sets = self._prepare_package_sets(
|
||||||
|
load_old_gather_result, requires=[], provides=[]
|
||||||
|
)
|
||||||
|
compose = helpers.DummyCompose(self.topdir, {"gather_allow_reuse": True})
|
||||||
|
load_old_compose_config.return_value = copy.deepcopy(compose.conf)
|
||||||
|
|
||||||
|
gather._update_config(compose, "Server", "x86_64", compose.topdir)
|
||||||
|
result = gather.reuse_old_gather_packages(
|
||||||
|
compose, "x86_64", compose.variants["Server"], package_sets
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
result,
|
||||||
|
{
|
||||||
|
"debuginfo": [],
|
||||||
|
"rpm": [{"path": "/build/bash-1.0.0-2.x86_64.rpm"}],
|
||||||
|
"srpm": [],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_gather_result")
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_compose_config")
|
||||||
|
def test_reuse_update_gather_lookaside_repos_different_initial_repos(
|
||||||
|
self, load_old_compose_config, load_old_gather_result
|
||||||
|
):
|
||||||
|
package_sets = self._prepare_package_sets(
|
||||||
|
load_old_gather_result, requires=[], provides=[]
|
||||||
|
)
|
||||||
|
compose = helpers.DummyCompose(self.topdir, {"gather_allow_reuse": True})
|
||||||
|
lookasides = compose.conf["gather_lookaside_repos"]
|
||||||
|
lookasides.append(("^Server$", {"x86_64": "http://localhost/real.repo"}))
|
||||||
|
load_old_compose_config.return_value = copy.deepcopy(compose.conf)
|
||||||
|
|
||||||
|
gather._update_config(compose, "Server", "x86_64", compose.topdir)
|
||||||
|
result = gather.reuse_old_gather_packages(
|
||||||
|
compose, "x86_64", compose.variants["Server"], package_sets
|
||||||
|
)
|
||||||
|
self.assertEqual(result, None)
|
||||||
|
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_gather_result")
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_compose_config")
|
||||||
|
def test_reuse_no_old_file_cache(
|
||||||
|
self, load_old_compose_config, load_old_gather_result
|
||||||
|
):
|
||||||
|
package_sets = self._prepare_package_sets(
|
||||||
|
load_old_gather_result, requires=[], provides=[]
|
||||||
|
)
|
||||||
|
package_sets[0]["global"].old_file_cache = {
|
||||||
|
"/build/foo-1-1.x86_64.rpm": MockPkg("foo-1-1.x86_64.rpm", sourcerpm="foo")
|
||||||
|
}
|
||||||
|
compose = helpers.DummyCompose(self.topdir, {"gather_allow_reuse": True})
|
||||||
|
load_old_compose_config.return_value = compose.conf
|
||||||
|
|
||||||
|
result = gather.reuse_old_gather_packages(
|
||||||
|
compose, "x86_64", compose.variants["Server"], package_sets
|
||||||
|
)
|
||||||
|
self.assertEqual(result, None)
|
||||||
|
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_gather_result")
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_compose_config")
|
||||||
|
def test_reuse_no_old_file_cache(
|
||||||
|
self, load_old_compose_config, load_old_gather_result
|
||||||
|
):
|
||||||
|
package_sets = self._prepare_package_sets(
|
||||||
|
load_old_gather_result, requires=[], provides=[]
|
||||||
|
)
|
||||||
|
package_sets[0]["global"].old_file_cache = {
|
||||||
|
"/build/foo-1-1.x86_64.rpm": MockPkg("foo-1-1.x86_64.rpm", sourcerpm="foo")
|
||||||
|
}
|
||||||
|
compose = helpers.DummyCompose(self.topdir, {"gather_allow_reuse": True})
|
||||||
|
load_old_compose_config.return_value = compose.conf
|
||||||
|
|
||||||
|
result = gather.reuse_old_gather_packages(
|
||||||
|
compose, "x86_64", compose.variants["Server"], package_sets
|
||||||
|
)
|
||||||
|
self.assertEqual(result, None)
|
||||||
|
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_gather_result")
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_compose_config")
|
||||||
|
def test_reuse_two_rpms_from_same_source(
|
||||||
|
self, load_old_compose_config, load_old_gather_result
|
||||||
|
):
|
||||||
|
package_sets = self._prepare_package_sets(
|
||||||
|
load_old_gather_result, requires=[], provides=[]
|
||||||
|
)
|
||||||
|
bash_pkg = MockPkg(
|
||||||
|
"bash-1-2.x86_64.rpm", sourcerpm="bash", requires=[], provides=[]
|
||||||
|
)
|
||||||
|
pkg_set = package_sets[0]["global"]
|
||||||
|
pkg_set.old_file_cache["/build/bash-1-2.x86_64.rpm"] = bash_pkg
|
||||||
|
pkg_set.file_cache["/build/bash-1-2.x86_64.rpm"] = bash_pkg
|
||||||
|
compose = helpers.DummyCompose(self.topdir, {"gather_allow_reuse": True})
|
||||||
|
load_old_compose_config.return_value = compose.conf
|
||||||
|
|
||||||
|
result = gather.reuse_old_gather_packages(
|
||||||
|
compose, "x86_64", compose.variants["Server"], package_sets
|
||||||
|
)
|
||||||
|
self.assertEqual(result, None)
|
||||||
|
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_gather_result")
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_compose_config")
|
||||||
|
def test_reuse_rpm_added_removed(
|
||||||
|
self, load_old_compose_config, load_old_gather_result
|
||||||
|
):
|
||||||
|
package_sets = self._prepare_package_sets(
|
||||||
|
load_old_gather_result, requires=[], provides=[]
|
||||||
|
)
|
||||||
|
foo_pkg = MockPkg(
|
||||||
|
"foo-1-1.x86_64.rpm", sourcerpm="foo", requires=[], provides=[]
|
||||||
|
)
|
||||||
|
file_pkg = MockPkg(
|
||||||
|
"file-1-1.x86_64.rpm", sourcerpm="file", requires=[], provides=[]
|
||||||
|
)
|
||||||
|
pkg_set = package_sets[0]["global"]
|
||||||
|
pkg_set.old_file_cache["/build/file-1-1.x86_64.rpm"] = file_pkg
|
||||||
|
pkg_set.file_cache["/build/foo-1-1.x86_64.rpm"] = foo_pkg
|
||||||
|
compose = helpers.DummyCompose(self.topdir, {"gather_allow_reuse": True})
|
||||||
|
load_old_compose_config.return_value = compose.conf
|
||||||
|
|
||||||
|
result = gather.reuse_old_gather_packages(
|
||||||
|
compose, "x86_64", compose.variants["Server"], package_sets
|
||||||
|
)
|
||||||
|
self.assertEqual(result, None)
|
||||||
|
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_gather_result")
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_compose_config")
|
||||||
|
def test_reuse_different_packages(
|
||||||
|
self, load_old_compose_config, load_old_gather_result
|
||||||
|
):
|
||||||
|
package_sets = self._prepare_package_sets(
|
||||||
|
load_old_gather_result, requires=[], provides=["foo"]
|
||||||
|
)
|
||||||
|
package_sets[0]["global"].old_file_cache = None
|
||||||
|
compose = helpers.DummyCompose(self.topdir, {"gather_allow_reuse": True})
|
||||||
|
load_old_compose_config.return_value = compose.conf
|
||||||
|
|
||||||
|
result = gather.reuse_old_gather_packages(
|
||||||
|
compose, "x86_64", compose.variants["Server"], package_sets
|
||||||
|
)
|
||||||
|
self.assertEqual(result, None)
|
||||||
|
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_gather_result")
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_compose_config")
|
||||||
|
def test_reuse_requires_changed(
|
||||||
|
self, load_old_compose_config, load_old_gather_result
|
||||||
|
):
|
||||||
|
package_sets = self._prepare_package_sets(
|
||||||
|
load_old_gather_result, requires=["foo"], provides=[]
|
||||||
|
)
|
||||||
|
compose = helpers.DummyCompose(self.topdir, {"gather_allow_reuse": True})
|
||||||
|
load_old_compose_config.return_value = compose.conf
|
||||||
|
|
||||||
|
result = gather.reuse_old_gather_packages(
|
||||||
|
compose, "x86_64", compose.variants["Server"], package_sets
|
||||||
|
)
|
||||||
|
self.assertEqual(result, None)
|
||||||
|
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_gather_result")
|
||||||
|
@mock.patch("pungi.phases.gather.load_old_compose_config")
|
||||||
|
def test_reuse_provides_changed(
|
||||||
|
self, load_old_compose_config, load_old_gather_result
|
||||||
|
):
|
||||||
|
package_sets = self._prepare_package_sets(
|
||||||
|
load_old_gather_result, requires=[], provides=["foo"]
|
||||||
|
)
|
||||||
|
compose = helpers.DummyCompose(self.topdir, {"gather_allow_reuse": True})
|
||||||
|
load_old_compose_config.return_value = compose.conf
|
||||||
|
|
||||||
|
result = gather.reuse_old_gather_packages(
|
||||||
|
compose, "x86_64", compose.variants["Server"], package_sets
|
||||||
|
)
|
||||||
|
self.assertEqual(result, None)
|
||||||
|
|
||||||
|
|
||||||
class TestWritePrepopulate(helpers.PungiTestCase):
|
class TestWritePrepopulate(helpers.PungiTestCase):
|
||||||
def test_without_config(self):
|
def test_without_config(self):
|
||||||
compose = helpers.DummyCompose(self.topdir, {})
|
compose = helpers.DummyCompose(self.topdir, {})
|
||||||
|
Loading…
Reference in New Issue
Block a user