Don't promote packages with unbuilt reverse dependencies

If a reverse dependency D of a package P is not built yet, then D will be in
"exclusions" as we can't sensibly run D's tests at that time. In that case,
don't just ignore the missing test result but consider D's test as "in
progress".

Note that this might lead to stalling an innocent P if a broken (FTBFS) D gets
uploaded at the same time. This can/should be handled by overrides if fixing
D isn't appropriate, but this is better than allowing P to break D in that
situation.
bzr-import-20160707
Martin Pitt 10 years ago
parent ee4450b671
commit ca9987def8

@ -77,6 +77,7 @@ class AutoPackageTest(object):
self.distribution = distribution self.distribution = distribution
self.series = series self.series = series
self.debug = debug self.debug = debug
self.excludes = set()
self.test_state_dir = os.path.join(britney.options.unstable, self.test_state_dir = os.path.join(britney.options.unstable,
'autopkgtest') 'autopkgtest')
# map of requested tests from request() # map of requested tests from request()
@ -395,12 +396,13 @@ class AutoPackageTest(object):
def request(self, packages, excludes=None): def request(self, packages, excludes=None):
if excludes is None: if excludes is None:
excludes = [] excludes = []
self.excludes.update(excludes)
self.log_verbose('Requested autopkgtests for %s, exclusions: %s' % self.log_verbose('Requested autopkgtests for %s, exclusions: %s' %
(['%s/%s' % i for i in packages], str(excludes))) (['%s/%s' % i for i in packages], str(excludes)))
for src, ver in packages: for src, ver in packages:
for (testsrc, testver) in self.tests_for_source(src, ver): for (testsrc, testver) in self.tests_for_source(src, ver):
if testsrc not in excludes: if testsrc not in self.excludes:
for arch in self.britney.options.adt_arches.split(): for arch in self.britney.options.adt_arches.split():
self.add_test_request(testsrc, testver, arch, src, ver) self.add_test_request(testsrc, testver, arch, src, ver)
@ -522,8 +524,16 @@ class AutoPackageTest(object):
arch_status[arch] = 'RUNNING' arch_status[arch] = 'RUNNING'
passed = False passed = False
except KeyError: except KeyError:
# neither done nor pending -> exclusion, or disabled # neither done nor pending; excluded?
continue if testsrc in self.excludes:
arch_status[arch] = 'RUNNING'
passed = False
continue
# ignore if Swift results are disabled
if not hasattr(self.britney.options, 'adt_swift_url'):
continue
raise
# disabled or ignored? # disabled or ignored?
if not arch_status: if not arch_status:

@ -345,6 +345,74 @@ lightgreen 1 i386 green 2
# not expecting any failures to retrieve from swift # not expecting any failures to retrieve from swift
self.assertNotIn('Failure', out, out) self.assertNotIn('Failure', out, out)
def test_unbuilt(self):
'''Unbuilt package should not trigger tests or get considered'''
self.data.add_src('green', True, {'Version': '2', 'Testsuite': 'autopkgtest'})
self.do_test(
[],
NOT_CONSIDERED,
[r'\bgreen\b.*>1</a> to .*>2<',
r'missing build on.*amd64.*green, libgreen1'],
['autopkgtest'])
def test_rdepends_unbuilt(self):
'''Unbuilt reverse dependency'''
# old lightgreen fails, thus new green should be held back
self.swift.set_results({'autopkgtest-series': {
'series/i386/d/darkgreen/20150101_100000@': (0, 'darkgreen 1'),
'series/amd64/d/darkgreen/20150101_100001@': (0, 'darkgreen 1'),
'series/i386/l/lightgreen/20150101_100000@': (0, 'lightgreen 1'),
'series/i386/l/lightgreen/20150101_100100@': (4, 'lightgreen 1'),
'series/amd64/l/lightgreen/20150101_100000@': (0, 'lightgreen 1'),
'series/amd64/l/lightgreen/20150101_100100@': (4, 'lightgreen 1'),
'series/i386/g/green/20150101_020000@': (0, 'green 1'),
'series/amd64/g/green/20150101_020000@': (0, 'green 1'),
'series/i386/g/green/20150101_100200@': (0, 'green 2'),
'series/amd64/g/green/20150101_100201@': (0, 'green 2'),
}})
# run britney once to pick up previous results
self.do_test(
[('libgreen1', {'Version': '2', 'Source': 'green', 'Depends': 'libc6'}, 'autopkgtest')],
NOT_CONSIDERED)
os.unlink(self.fake_amqp)
# add unbuilt lightgreen
self.data.add_src('lightgreen', True, {'Version': '2', 'Testsuite': 'autopkgtest'})
self.do_test(
[],
NOT_CONSIDERED,
[r'\bgreen\b.*>1</a> to .*>2<',
r'\blightgreen\b.*>1</a> to .*>2<',
r'autopkgtest for green 2: .*amd64.*Pass.*i386.*Pass',
r'autopkgtest for darkgreen 1: .*amd64.*Pass.*i386.*Pass',
r'autopkgtest for lightgreen 2: .*amd64.*in progress.*i386.*in progress',
r'lightgreen has no up-to-date binaries on any arch'],
['Valid candidate'])
# lightgreen's tests should not be triggered yet while it is unbuilt
self.assertEqual(self.amqp_requests, set())
# now lightgreen gets built and a test result
self.swift.set_results({'autopkgtest-series': {
'series/i386/l/lightgreen/20150101_100200@': (0, 'lightgreen 2'),
'series/amd64/l/lightgreen/20150101_102000@': (0, 'lightgreen 2'),
}})
self.data.remove_all(True)
self.do_test(
[('libgreen1', {'Version': '2', 'Source': 'green', 'Depends': 'libc6'}, 'autopkgtest'),
('lightgreen', {'Version': '2'}, 'autopkgtest')],
VALID_CANDIDATE,
[r'\bgreen\b.*>1</a> to .*>2<',
r'\blightgreen\b.*>1</a> to .*>2<',
r'autopkgtest for green 2: .*amd64.*Pass.*i386.*Pass',
r'autopkgtest for darkgreen 1: .*amd64.*Pass.*i386.*Pass',
r'autopkgtest for lightgreen 2: .*amd64.*Pass.*i386.*Pass'],
['Not considered'])
self.assertEqual(self.amqp_requests,
set(['debci-series-amd64:lightgreen', 'debci-series-i386:lightgreen']))
def test_hint_force_badtest(self): def test_hint_force_badtest(self):
'''force-badtest hint''' '''force-badtest hint'''

Loading…
Cancel
Save