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

@ -345,6 +345,74 @@ lightgreen 1 i386 green 2
# not expecting any failures to retrieve from swift
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):
'''force-badtest hint'''

Loading…
Cancel
Save