autopkgtest: Wait for Swift results for correct triggering package

Swift results were considered for older versions of triggers instead of waiting
for results for the actual package/version that triggered a new test.

This broke due to two reasons:

 * When evaluating the test results we need to check whether we have a result
   for the tested package/version that got triggered by the current excuse, not
   just for any older excuse.

 * AutoPackageTest.fetch_swift_results() re-downloaded all results for a
   package due to a wrong "marker" value: The marker needs to be the
   complete object path, not just the timestamp suffix. This caused old test
   results to be considered as "newer than the given marker".
This commit is contained in:
Martin Pitt 2015-07-31 12:42:07 +02:00
parent 6b46400973
commit e32af66634
3 changed files with 174 additions and 7 deletions

View File

@ -263,9 +263,7 @@ class AutoPackageTest(object):
query = {'delimiter': '@',
'prefix': '%s/%s/%s/%s/' % (self.series, arch, srchash(src), src)}
try:
# don't include the last run again, so make the marker
# "infinitesimally later" by appending 'zz'
query['marker'] = self.test_results[src][arch][0] + 'zz'
query['marker'] = query['prefix'] + self.test_results[src][arch][0]
except KeyError:
# no stamp yet, download all results
pass
@ -334,8 +332,8 @@ class AutoPackageTest(object):
# allow some skipped tests, but nothing else
passed = exitcode in [0, 2]
self.log_verbose('Fetched test result for %s/%s on %s: %s' % (
src, ver, arch, passed and 'pass' or 'fail'))
self.log_verbose('Fetched test result for %s/%s/%s %s: %s' % (
src, ver, arch, stamp, passed and 'pass' or 'fail'))
# remove matching test requests, remember triggers
satisfied_triggers = set()

View File

@ -1894,10 +1894,16 @@ class Britney(object):
url = cloud_url % {'h': srchash(testsrc), 's': testsrc,
'r': self.options.series, 'a': arch}
try:
if autopkgtest.test_results[testsrc][arch][1][testver][0]:
(_, ver_map, ever_passed) = autopkgtest.test_results[testsrc][arch]
(passed, triggers) = ver_map[testver]
# triggers might contain tuples or lists
if (e.name, e.ver[1]) not in triggers and [e.name, e.ver[1]] not in triggers:
raise KeyError('No result for trigger %s/%s yet' % (e.name, e.ver[1]))
if passed:
status = 'PASS'
else:
if autopkgtest.test_results[testsrc][arch][2]:
if ever_passed:
status = 'REGRESSION'
else:
status = 'ALWAYSFAIL'

View File

@ -300,6 +300,153 @@ lightgreen 2 i386 lightgreen 2
'''
self.assertEqual(self.pending_requests, expected_pending)
def test_result_from_older_version(self):
'''test result from older version than the uploaded one'''
self.swift.set_results({'autopkgtest-series': {
'series/i386/d/darkgreen/20150101_100000@': (0, 'darkgreen 1'),
'series/amd64/d/darkgreen/20150101_100000@': (0, 'darkgreen 1'),
}})
self.do_test(
[('darkgreen', {'Version': '2', 'Depends': 'libc6 (>= 0.9), libgreen1'}, 'autopkgtest')],
# FIXME: while we only submit requests through AMQP, but don't consider
# their results, we don't expect this to hold back stuff.
VALID_CANDIDATE,
[r'\bdarkgreen\b.*>1</a> to .*>2<',
r'autopkgtest for darkgreen 2: .*amd64.*in progress.*i386.*in progress'])
self.assertEqual(
self.amqp_requests,
set(['debci-series-i386:darkgreen', 'debci-series-amd64:darkgreen']))
self.assertEqual(self.pending_requests,
'darkgreen 2 amd64 darkgreen 2\ndarkgreen 2 i386 darkgreen 2\n')
os.unlink(self.fake_amqp)
# second run gets the results for darkgreen 2
self.swift.set_results({'autopkgtest-series': {
'series/i386/d/darkgreen/20150101_100000@': (0, 'darkgreen 1'),
'series/amd64/d/darkgreen/20150101_100000@': (0, 'darkgreen 1'),
'series/i386/d/darkgreen/20150101_100010@': (0, 'darkgreen 2'),
'series/amd64/d/darkgreen/20150101_100010@': (0, 'darkgreen 2'),
}})
self.do_test(
[],
VALID_CANDIDATE,
[r'\bdarkgreen\b.*>1</a> to .*>2<',
r'autopkgtest for darkgreen 2: .*amd64.*Pass.*i386.*Pass'])
self.assertEqual(self.amqp_requests, set())
self.assertEqual(self.pending_requests, '')
# next run sees a newer darkgreen, should re-run tests
self.data.remove_all(True)
self.do_test(
[('darkgreen', {'Version': '3', 'Depends': 'libc6 (>= 0.9), libgreen1'}, 'autopkgtest')],
# FIXME: while we only submit requests through AMQP, but don't consider
# their results, we don't expect this to hold back stuff.
VALID_CANDIDATE,
[r'\bdarkgreen\b.*>1</a> to .*>3<',
r'autopkgtest for darkgreen 3: .*amd64.*in progress.*i386.*in progress'])
self.assertEqual(
self.amqp_requests,
set(['debci-series-i386:darkgreen', 'debci-series-amd64:darkgreen']))
self.assertEqual(self.pending_requests,
'darkgreen 3 amd64 darkgreen 3\ndarkgreen 3 i386 darkgreen 3\n')
def test_old_result_from_rdep_version(self):
'''re-runs reverse dependency test on new versions'''
self.swift.set_results({'autopkgtest-series': {
'series/i386/g/green/20150101_100000@': (0, 'green 1'),
'series/amd64/g/green/20150101_100000@': (0, 'green 1'),
'series/i386/g/green/20150101_100010@': (0, 'green 2'),
'series/amd64/g/green/20150101_100010@': (0, 'green 2'),
'series/i386/d/darkgreen/20150101_100000@': (0, 'darkgreen 1'),
'series/amd64/d/darkgreen/20150101_100000@': (0, 'darkgreen 1'),
'series/i386/l/lightgreen/20150101_100000@': (0, 'lightgreen 1'),
'series/amd64/l/lightgreen/20150101_100000@': (0, 'lightgreen 1'),
}})
self.do_test(
[('libgreen1', {'Version': '2', 'Source': 'green', 'Depends': 'libc6'}, 'autopkgtest')],
VALID_CANDIDATE,
[r'\green\b.*>1</a> to .*>2<',
r'autopkgtest for green 2: .*amd64.*Pass.*i386.*Pass',
r'autopkgtest for darkgreen 1: .*amd64.*Pass.*i386.*Pass'])
self.assertEqual(
self.amqp_requests,
set(['debci-series-i386:green', 'debci-series-amd64:green',
'debci-series-i386:lightgreen', 'debci-series-amd64:lightgreen',
'debci-series-i386:darkgreen', 'debci-series-amd64:darkgreen']))
self.assertEqual(self.pending_requests, '')
os.unlink(self.fake_amqp)
self.data.remove_all(True)
# second run: new version re-triggers all tests
self.do_test(
[('libgreen1', {'Version': '3', 'Source': 'green', 'Depends': 'libc6'}, 'autopkgtest')],
# FIXME: while we only submit requests through AMQP, but don't consider
# their results, we don't expect this to hold back stuff.
VALID_CANDIDATE,
[r'\green\b.*>1</a> to .*>3<',
r'autopkgtest for green 3: .*amd64.*in progress.*i386.*in progress',
r'autopkgtest for lightgreen 1: .*amd64.*in progress.*i386.*in progress',
r'autopkgtest for darkgreen 1: .*amd64.*in progress.*i386.*in progress'])
self.assertEqual(
self.amqp_requests,
set(['debci-series-i386:green', 'debci-series-amd64:green',
'debci-series-i386:lightgreen', 'debci-series-amd64:lightgreen',
'debci-series-i386:darkgreen', 'debci-series-amd64:darkgreen']))
expected_pending = '''darkgreen 1 amd64 green 3
darkgreen 1 i386 green 3
green 3 amd64 green 3
green 3 i386 green 3
lightgreen 1 amd64 green 3
lightgreen 1 i386 green 3
'''
self.assertEqual(self.pending_requests, expected_pending)
os.unlink(self.fake_amqp)
# third run gets the results for green and lightgreen, darkgreen is
# still running
self.swift.set_results({'autopkgtest-series': {
'series/i386/g/green/20150101_100020@': (0, 'green 3'),
'series/amd64/g/green/20150101_100020@': (0, 'green 3'),
'series/i386/d/darkgreen/20150101_100000@': (0, 'darkgreen 1'),
'series/amd64/d/darkgreen/20150101_100000@': (0, 'darkgreen 1'),
'series/i386/l/lightgreen/20150101_100010@': (0, 'lightgreen 1'),
'series/amd64/l/lightgreen/20150101_100010@': (0, 'lightgreen 1'),
}})
self.do_test(
[],
# FIXME: while we only submit requests through AMQP, but don't consider
# their results, we don't expect this to hold back stuff.
VALID_CANDIDATE,
[r'\green\b.*>1</a> to .*>3<',
r'autopkgtest for green 3: .*amd64.*Pass.*i386.*Pass',
r'autopkgtest for lightgreen 1: .*amd64.*Pass.*i386.*Pass',
r'autopkgtest for darkgreen 1: .*amd64.*in progress.*i386.*in progress'])
self.assertEqual(self.amqp_requests, set())
self.assertEqual(self.pending_requests,
'darkgreen 1 amd64 green 3\ndarkgreen 1 i386 green 3\n')
# fourth run finally gets the new darkgreen result
self.swift.set_results({'autopkgtest-series': {
'series/i386/d/darkgreen/20150101_100010@': (0, 'darkgreen 1'),
'series/amd64/d/darkgreen/20150101_100010@': (0, 'darkgreen 1'),
}})
self.do_test(
[], VALID_CANDIDATE,
[r'\green\b.*>1</a> to .*>3<',
r'autopkgtest for green 3: .*amd64.*Pass.*i386.*Pass',
r'autopkgtest for lightgreen 1: .*amd64.*Pass.*i386.*Pass',
r'autopkgtest for darkgreen 1: .*amd64.*Pass.*i386.*Pass'])
self.assertEqual(self.amqp_requests, set())
self.assertEqual(self.pending_requests, '')
def test_tmpfail(self):
'''tmpfail result is considered a failure'''
@ -406,6 +553,22 @@ lightgreen 2 i386 lightgreen 2
# green
self.data.remove_all(True)
self.swift.set_results({'autopkgtest-series': {
'series/i386/g/green/20150101_100101@': (0, 'green 1'),
'series/amd64/g/green/20150101_100101@': (0, 'green 1'),
'series/i386/g/green/20150101_100201@': (0, 'green 2'),
'series/amd64/g/green/20150101_100201@': (0, 'green 2'),
'series/i386/l/lightgreen/20150101_100101@': (0, 'lightgreen 1'),
'series/amd64/l/lightgreen/20150101_100101@': (0, 'lightgreen 1'),
'series/i386/l/lightgreen/20150101_100201@': (4, 'lightgreen 2'),
'series/amd64/l/lightgreen/20150101_100201@': (4, 'lightgreen 2'),
# add new result for lightgreen 1
'series/i386/l/lightgreen/20150101_100301@': (0, 'lightgreen 1'),
'series/amd64/l/lightgreen/20150101_100301@': (0, 'lightgreen 1'),
'series/i386/d/darkgreen/20150101_100000@': (0, 'darkgreen 1'),
'series/amd64/d/darkgreen/20150101_100001@': (0, 'darkgreen 1'),
}})
# next run should re-trigger lightgreen 1 to test against green/2
self.do_test(
[('libgreen1', {'Version': '2', 'Source': 'green', 'Depends': 'libc6'}, 'autopkgtest')],