policies: Make policies suite name agnostic

Signed-off-by: Niels Thykier <niels@thykier.net>
ubuntu/rebased
Niels Thykier 7 years ago
parent 54e5eb0e74
commit 6c6b8fcb96

@ -387,8 +387,10 @@ class AutopkgtestPolicy(BasePolicy):
def tests_for_source(self, src, ver, arch): def tests_for_source(self, src, ver, arch):
'''Iterate over all tests that should be run for given source and arch''' '''Iterate over all tests that should be run for given source and arch'''
sources_info = self.britney.sources['testing'] source_suite = self.suite_info.primary_source_suite
binaries_info = self.britney.binaries['testing'][arch][0] target_suite = self.suite_info.target_suite
sources_info = target_suite.sources
binaries_info = target_suite.binaries[arch][0]
reported_pkgs = set() reported_pkgs = set()
@ -422,7 +424,7 @@ class AutopkgtestPolicy(BasePolicy):
return [] return []
# we want to test the package itself, if it still has a test in unstable # we want to test the package itself, if it still has a test in unstable
srcinfo = self.britney.sources['unstable'][src] srcinfo = source_suite.sources[src]
if 'autopkgtest' in srcinfo.testsuite or self.has_autodep8(srcinfo, binaries_info): if 'autopkgtest' in srcinfo.testsuite or self.has_autodep8(srcinfo, binaries_info):
reported_pkgs.add(src) reported_pkgs.add(src)
tests.append((src, ver)) tests.append((src, ver))

@ -89,12 +89,11 @@ class BasePolicy(object):
:param source_data_tdist Information about the source package :param source_data_tdist Information about the source package
in the target distribution (e.g. "testing"). This is the in the target distribution (e.g. "testing"). This is the
data structure in Britney.sources['testing'][source_name] data structure in source_suite.sources[source_name]
:param source_data_srcdist Information about the source :param source_data_srcdist Information about the source
package in the source distribution (e.g. "unstable" or "tpu"). package in the source distribution (e.g. "unstable" or "tpu").
This is the data structure in suite.sources[source_name] This is the data structure in target_suite.sources[source_name]
Britney.sources[suite][source_name]
:return A Policy Verdict (e.g. PolicyVerdict.PASS) :return A Policy Verdict (e.g. PolicyVerdict.PASS)
""" """
@ -191,14 +190,15 @@ class AgePolicy(BasePolicy):
def initialise(self, britney): def initialise(self, britney):
super().initialise(britney) super().initialise(britney)
self._read_dates_file() self._read_dates_file()
self._read_urgencies_file(britney) self._read_urgencies_file()
def save_state(self, britney): def save_state(self, britney):
super().save_state(britney) super().save_state(britney)
self._write_dates_file() self._write_dates_file()
def apply_policy_impl(self, age_info, suite, source_name, source_data_tdist, source_data_srcdist, excuse): def apply_policy_impl(self, age_info, suite, source_name, source_data_tdist, source_data_srcdist, excuse):
# retrieve the urgency for the upload, ignoring it if this is a NEW package (not present in testing) # retrieve the urgency for the upload, ignoring it if this is a NEW package
# (not present in the target suite)
urgency = self._urgencies.get(source_name, self.options.default_urgency) urgency = self._urgencies.get(source_name, self.options.default_urgency)
if urgency not in self._min_days: if urgency not in self._min_days:
@ -295,7 +295,7 @@ class AgePolicy(BasePolicy):
def _read_dates_file(self): def _read_dates_file(self):
"""Parse the dates file""" """Parse the dates file"""
dates = self._dates dates = self._dates
fallback_filename = os.path.join(self.suite_info['testing'].path, 'Dates') fallback_filename = os.path.join(self.suite_info.target_suite.path, 'Dates')
using_new_name = False using_new_name = False
try: try:
filename = os.path.join(self.options.state_dir, 'age-policy-dates') filename = os.path.join(self.options.state_dir, 'age-policy-dates')
@ -328,10 +328,10 @@ class AgePolicy(BasePolicy):
with open(filename, mode='x', encoding='utf-8'): with open(filename, mode='x', encoding='utf-8'):
pass pass
def _read_urgencies_file(self, britney): def _read_urgencies_file(self):
urgencies = self._urgencies urgencies = self._urgencies
min_days_default = self._min_days_default min_days_default = self._min_days_default
fallback_filename = os.path.join(self.suite_info['testing'].path, 'Urgency') fallback_filename = os.path.join(self.suite_info.target_suite.path, 'Urgency')
try: try:
filename = os.path.join(self.options.state_dir, 'age-policy-urgencies') filename = os.path.join(self.options.state_dir, 'age-policy-urgencies')
if not os.path.exists(filename) and os.path.exists(fallback_filename): if not os.path.exists(filename) and os.path.exists(fallback_filename):
@ -339,6 +339,9 @@ class AgePolicy(BasePolicy):
except AttributeError: except AttributeError:
filename = fallback_filename filename = fallback_filename
sources_s = self.suite_info.primary_source_suite.sources
sources_t = self.suite_info.target_suite.sources
with open(filename, errors='surrogateescape', encoding='ascii') as fd: with open(filename, errors='surrogateescape', encoding='ascii') as fd:
for line in fd: for line in fd:
# <source> <version> <urgency> # <source> <version> <urgency>
@ -355,13 +358,13 @@ class AgePolicy(BasePolicy):
if mindays_old <= mindays_new: if mindays_old <= mindays_new:
continue continue
# if the package exists in testing and it is more recent, do nothing # if the package exists in the target suite and it is more recent, do nothing
tsrcv = britney.sources['testing'].get(l[0], None) tsrcv = sources_t.get(l[0], None)
if tsrcv and apt_pkg.version_compare(tsrcv.version, l[1]) >= 0: if tsrcv and apt_pkg.version_compare(tsrcv.version, l[1]) >= 0:
continue continue
# if the package doesn't exist in unstable or it is older, do nothing # if the package doesn't exist in the primary source suite or it is older, do nothing
usrcv = britney.sources['unstable'].get(l[0], None) usrcv = sources_s.get(l[0], None)
if not usrcv or apt_pkg.version_compare(usrcv.version, l[1]) < 0: if not usrcv or apt_pkg.version_compare(usrcv.version, l[1]) < 0:
continue continue
@ -373,9 +376,9 @@ class AgePolicy(BasePolicy):
try: try:
directory = self.options.state_dir directory = self.options.state_dir
basename = 'age-policy-dates' basename = 'age-policy-dates'
old_file = os.path.join(self.suite_info['testing'].path, 'Dates') old_file = os.path.join(self.suite_info.target_suite.path, 'Dates')
except AttributeError: except AttributeError:
directory = self.suite_info['testing'].path directory = self.suite_info.target_suite.path
basename = 'Dates' basename = 'Dates'
old_file = None old_file = None
filename = os.path.join(directory, basename) filename = os.path.join(directory, basename)
@ -400,12 +403,10 @@ class RCBugPolicy(BasePolicy):
The RCBugPolicy's decision is influenced by the following: The RCBugPolicy's decision is influenced by the following:
State files: State files:
* ${STATE_DIR}/rc-bugs-unstable: File containing RC bugs for packages in * ${STATE_DIR}/rc-bugs-${SUITE_NAME}: File containing RC bugs for packages in
the source suite. the given suite (one for both primary source suite and the target sutie is
- This file needs to be updated externally. needed).
* ${STATE_DIR}/rc-bugs-testing: File containing RC bugs for packages in - These files need to be updated externally.
the target suite.
- This file needs to be updated externally.
""" """
def __init__(self, options, suite_info): def __init__(self, options, suite_info):
@ -420,11 +421,13 @@ class RCBugPolicy(BasePolicy):
def initialise(self, britney): def initialise(self, britney):
super().initialise(britney) super().initialise(britney)
fallback_unstable = os.path.join(self.suite_info['unstable'].path, 'BugsV') source_suite = self.suite_info.primary_source_suite
fallback_testing = os.path.join(self.suite_info['testing'].path, 'BugsV') target_suite = self.suite_info.target_suite
fallback_unstable = os.path.join(source_suite.path, 'BugsV')
fallback_testing = os.path.join(target_suite.path, 'BugsV')
try: try:
filename_unstable = os.path.join(self.options.state_dir, 'rc-bugs-unstable') filename_unstable = os.path.join(self.options.state_dir, 'rc-bugs-%s' % source_suite.name)
filename_testing = os.path.join(self.options.state_dir, 'rc-bugs-testing') filename_testing = os.path.join(self.options.state_dir, 'rc-bugs-%s' % target_suite.name)
if not os.path.exists(filename_unstable) and not os.path.exists(filename_testing) and \ if not os.path.exists(filename_unstable) and not os.path.exists(filename_testing) and \
os.path.exists(fallback_unstable) and os.path.exists(fallback_testing): os.path.exists(fallback_unstable) and os.path.exists(fallback_testing):
filename_unstable = fallback_unstable filename_unstable = fallback_unstable
@ -432,28 +435,28 @@ class RCBugPolicy(BasePolicy):
except AttributeError: except AttributeError:
filename_unstable = fallback_unstable filename_unstable = fallback_unstable
filename_testing = fallback_testing filename_testing = fallback_testing
self._bugs['unstable'] = self._read_bugs(filename_unstable) self._bugs['source'] = self._read_bugs(filename_unstable)
self._bugs['testing'] = self._read_bugs(filename_testing) self._bugs['target'] = self._read_bugs(filename_testing)
def apply_policy_impl(self, rcbugs_info, suite, source_name, source_data_tdist, source_data_srcdist, excuse): def apply_policy_impl(self, rcbugs_info, suite, source_name, source_data_tdist, source_data_srcdist, excuse):
bugs_t = set() bugs_t = set()
bugs_u = set() bugs_u = set()
for src_key in (source_name, 'src:%s' % source_name): for src_key in (source_name, 'src:%s' % source_name):
if source_data_tdist and src_key in self._bugs['testing']: if source_data_tdist and src_key in self._bugs['target']:
bugs_t.update(self._bugs['testing'][src_key]) bugs_t.update(self._bugs['target'][src_key])
if src_key in self._bugs['unstable']: if src_key in self._bugs['source']:
bugs_u.update(self._bugs['unstable'][src_key]) bugs_u.update(self._bugs['source'][src_key])
for pkg, _, _ in source_data_srcdist.binaries: for pkg, _, _ in source_data_srcdist.binaries:
if pkg in self._bugs['unstable']: if pkg in self._bugs['source']:
bugs_u |= self._bugs['unstable'][pkg] bugs_u |= self._bugs['source'][pkg]
if source_data_tdist: if source_data_tdist:
for pkg, _, _ in source_data_tdist.binaries: for pkg, _, _ in source_data_tdist.binaries:
if pkg in self._bugs['testing']: if pkg in self._bugs['target']:
bugs_t |= self._bugs['testing'][pkg] bugs_t |= self._bugs['target'][pkg]
# If a package is not in testing, it has no RC bugs per # If a package is not in the target suite, it has no RC bugs per
# definition. Unfortunately, it seems that the live-data is # definition. Unfortunately, it seems that the live-data is
# not always accurate (e.g. live-2011-12-13 suggests that # not always accurate (e.g. live-2011-12-13 suggests that
# obdgpslogger had the same bug in testing and unstable, # obdgpslogger had the same bug in testing and unstable,
@ -461,7 +464,7 @@ class RCBugPolicy(BasePolicy):
# - For the curious, obdgpslogger was removed on that day # - For the curious, obdgpslogger was removed on that day
# and the BTS probably had not caught up with that fact. # and the BTS probably had not caught up with that fact.
# (https://tracker.debian.org/news/415935) # (https://tracker.debian.org/news/415935)
assert not bugs_t or source_data_tdist, "%s had bugs in testing but is not in testing" % source_name assert not bugs_t or source_data_tdist, "%s had bugs in the target suite but is not present" % source_name
success_verdict = PolicyVerdict.PASS success_verdict = PolicyVerdict.PASS
@ -538,8 +541,8 @@ class PiupartsPolicy(BasePolicy):
def __init__(self, options, suite_info): def __init__(self, options, suite_info):
super().__init__('piuparts', options, suite_info, {SuiteClass.PRIMARY_SOURCE_SUITE}) super().__init__('piuparts', options, suite_info, {SuiteClass.PRIMARY_SOURCE_SUITE})
self._piuparts = { self._piuparts = {
'unstable': None, 'source': None,
'testing': None, 'target': None,
} }
def register_hints(self, hint_parser): def register_hints(self, hint_parser):
@ -547,21 +550,23 @@ class PiupartsPolicy(BasePolicy):
def initialise(self, britney): def initialise(self, britney):
super().initialise(britney) super().initialise(britney)
source_suite = self.suite_info.primary_source_suite
target_suite = self.suite_info.target_suite
try: try:
filename_unstable = os.path.join(self.options.state_dir, 'piuparts-summary-unstable.json') filename_unstable = os.path.join(self.options.state_dir, 'piuparts-summary-%s.json' % source_suite.name)
filename_testing = os.path.join(self.options.state_dir, 'piuparts-summary-testing.json') filename_testing = os.path.join(self.options.state_dir, 'piuparts-summary-%s.json' % target_suite.name)
except AttributeError as e: # pragma: no cover except AttributeError as e: # pragma: no cover
raise RuntimeError("Please set STATE_DIR in the britney configuration") from e raise RuntimeError("Please set STATE_DIR in the britney configuration") from e
self._piuparts['unstable'] = self._read_piuparts_summary(filename_unstable, keep_url=True) self._piuparts['source'] = self._read_piuparts_summary(filename_unstable, keep_url=True)
self._piuparts['testing'] = self._read_piuparts_summary(filename_testing, keep_url=False) self._piuparts['target'] = self._read_piuparts_summary(filename_testing, keep_url=False)
def apply_policy_impl(self, piuparts_info, suite, source_name, source_data_tdist, source_data_srcdist, excuse): def apply_policy_impl(self, piuparts_info, suite, source_name, source_data_tdist, source_data_srcdist, excuse):
if source_name in self._piuparts['testing']: if source_name in self._piuparts['target']:
testing_state = self._piuparts['testing'][source_name][0] testing_state = self._piuparts['target'][source_name][0]
else: else:
testing_state = 'X' testing_state = 'X'
if source_name in self._piuparts['unstable']: if source_name in self._piuparts['source']:
unstable_state, url = self._piuparts['unstable'][source_name] unstable_state, url = self._piuparts['source'][source_name]
else: else:
unstable_state = 'X' unstable_state = 'X'
url = None url = None
@ -584,7 +589,7 @@ class PiupartsPolicy(BasePolicy):
msg = 'Ignoring piuparts failure (Not a regression) - {0}'.format(url_html) msg = 'Ignoring piuparts failure (Not a regression) - {0}'.format(url_html)
result = PolicyVerdict.PASS result = PolicyVerdict.PASS
elif unstable_state == 'W': elif unstable_state == 'W':
msg = 'Waiting for piuparts test results (stalls testing migration) - {0}'.format(url_html) msg = 'Waiting for piuparts test results (stalls migration) - {0}'.format(url_html)
result = PolicyVerdict.REJECTED_TEMPORARILY result = PolicyVerdict.REJECTED_TEMPORARILY
piuparts_info['test-results'] = 'waiting-for-test-results' piuparts_info['test-results'] = 'waiting-for-test-results'
else: else:
@ -661,14 +666,18 @@ class BuildDependsPolicy(BasePolicy):
sources_s = None sources_s = None
sources_t = None sources_t = None
source_suite = self.suite_info[suite]
target_suite = self.suite_info.target_suite
binaries_s = source_suite.binaries
binaries_t = target_suite.binaries
unsat_bd = {} unsat_bd = {}
relevant_archs = {binary.architecture for binary in source_data_srcdist.binaries relevant_archs = {binary.architecture for binary in source_data_srcdist.binaries
if britney.all_binaries[binary].architecture != 'all'} if britney.all_binaries[binary].architecture != 'all'}
for arch in (arch for arch in self.options.architectures if arch in relevant_archs): for arch in (arch for arch in self.options.architectures if arch in relevant_archs):
# retrieve the binary package from the specified suite and arch # retrieve the binary package from the specified suite and arch
binaries_s_a, provides_s_a = britney.binaries[suite][arch] binaries_s_a, provides_s_a = binaries_s[arch]
binaries_t_a, provides_t_a = britney.binaries['testing'][arch] binaries_t_a, provides_t_a = binaries_t[arch]
# for every dependency block (formed as conjunction of disjunction) # for every dependency block (formed as conjunction of disjunction)
for block_txt in deps.split(','): for block_txt in deps.split(','):
block = parse_src_depends(block_txt, False, arch) block = parse_src_depends(block_txt, False, arch)
@ -679,9 +688,9 @@ class BuildDependsPolicy(BasePolicy):
# Relation is not relevant for this architecture. # Relation is not relevant for this architecture.
continue continue
block = block[0] block = block[0]
# if the block is satisfied in testing, then skip the block # if the block is satisfied in the target suite, then skip the block
if get_dependency_solvers(block, binaries_t_a, provides_t_a, build_depends=True): if get_dependency_solvers(block, binaries_t_a, provides_t_a, build_depends=True):
# Satisfied in testing; all ok. # Satisfied in the target suite; all ok.
continue continue
# check if the block can be satisfied in the source suite, and list the solving packages # check if the block can be satisfied in the source suite, and list the solving packages
@ -689,7 +698,7 @@ class BuildDependsPolicy(BasePolicy):
packages = [binaries_s_a[p].source for p in packages] packages = [binaries_s_a[p].source for p in packages]
# if the dependency can be satisfied by the same source package, skip the block: # if the dependency can be satisfied by the same source package, skip the block:
# obviously both binary packages will enter testing together # obviously both binary packages will enter the target suite together
if source_name in packages: if source_name in packages:
continue continue
@ -704,8 +713,8 @@ class BuildDependsPolicy(BasePolicy):
continue continue
if not sources_t: if not sources_t:
sources_t = britney.sources['testing'] sources_t = target_suite.sources
sources_s = britney.sources[suite] sources_s = source_suite.sources
# for the solving packages, update the excuse to add the dependencies # for the solving packages, update the excuse to add the dependencies
for p in packages: for p in packages:

Loading…
Cancel
Save