From c9173b3ca3a7c8fa9e007fdba5b5742b90588d12 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Thu, 13 Aug 2015 08:31:55 +0200 Subject: [PATCH] Promote packages with unbuilt reverse dependencies if testing version succeeds Commit 463 ("Don't promote packages with unbuilt reverse dependencies") turned out to be too strict: This holds up too many innocent packages in -proposed. If unstable has an unbuilt/uninstallable reverse dependency D of a package P, trigger a test anyway (which will then most likely run against the testing version of D). If that succeeds, the unstable P did not break D and can be accepted. If it fails, D needs to be fixed. Ideally we would set up some clever apt pinning to force installation of testing-D, to avoid running into the uninstallability of unstable-D, but this is tricky and error prone. Drop the temporary "UNINST" state from commit 466 again. Instead, excuses.html will now show a test against the testing version of D together with a note that the unstable version is unbuilt/uninstallable. This should ideally clear up all cases where a requested result is neither present or pending. Log an error if that still happens (will be checked in the next couple of runs), and ensure in the tests that we don't trigger any outstanding "FIXME" log messages. --- autopkgtest.py | 36 +++++++++++++++++++++--------------- britney.py | 6 +++++- tests/test_autopkgtest.py | 8 +++++--- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/autopkgtest.py b/autopkgtest.py index 31a932c..7a1c37f 100644 --- a/autopkgtest.py +++ b/autopkgtest.py @@ -38,7 +38,6 @@ ADT_EXCUSES_LABELS = { "ALWAYSFAIL": 'Always failed', "REGRESSION": 'Regression', "RUNNING": 'Test in progress', - "UNINST": 'Unbuilt/uninstallable', } @@ -170,11 +169,19 @@ class AutoPackageTest(object): continue for rdep in rdeps: rdep_src = binaries_info[rdep][SOURCE] - rdep_src_info = sources_info[rdep_src] + # if rdep_src/unstable is known to be not built yet or + # uninstallable, try to run tests against testing; if that + # works, then the unstable src does not break the testing + # rdep_src and is fine + if rdep_src in self.excludes: + rdep_src_info = self.britney.sources['testing'][rdep_src] + self.log_verbose('Reverse dependency %s of %s/%s is unbuilt or uninstallable, running test against testing version %s' % + (rdep_src, src, ver, rdep_src_info[VERSION])) + else: + rdep_src_info = sources_info[rdep_src] if rdep_src_info[AUTOPKGTEST] or self.has_autodep8(rdep_src_info): if rdep_src not in reported_pkgs: - # we don't care about the version of rdep - tests.append((rdep_src, sources_info[rdep_src][VERSION])) + tests.append((rdep_src, rdep_src_info[VERSION])) reported_pkgs.add(rdep_src) tests.sort(key=lambda (s, v): s) @@ -395,12 +402,11 @@ class AutoPackageTest(object): # def request(self, packages, excludes=None): - if excludes is None: - excludes = [] - self.excludes.update(excludes) + if excludes: + self.excludes.update(excludes) 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(self.excludes))) for src, ver in packages: for (testsrc, testver) in self.tests_for_source(src, ver): if testsrc not in self.excludes: @@ -496,7 +502,7 @@ class AutoPackageTest(object): def results(self, trigsrc, trigver): '''Return test results for triggering package - Return (passed, src, ver, arch -> ALWAYSFAIL|PASS|FAIL|RUNNING|UNINST) + Return (passed, src, ver, arch -> ALWAYSFAIL|PASS|FAIL|RUNNING) iterator for all package tests that got triggered by trigsrc/trigver. ''' for testsrc, testver in self.tests_for_source(trigsrc, trigver): @@ -525,13 +531,13 @@ class AutoPackageTest(object): arch_status[arch] = 'RUNNING' passed = False except KeyError: - # neither done nor pending; excluded? - if testsrc in self.excludes: - arch_status[arch] = 'UNINST' - passed = False + # ignore if adt or swift results are disabled, + # otherwise this is unexpected + if not hasattr(self.britney.options, 'adt_swift_url'): continue - - # ignore if adt or swift results are disabled + # FIXME: Ignore this error for now as it crashes britney, but investigate! + self.log_error('FIXME: Result for %s/%s/%s (triggered by %s/%s) is neither known nor pending!' % + (testsrc, testver, arch, trigsrc, trigver)) continue # disabled or ignored? diff --git a/britney.py b/britney.py index 5b518d2..d709706 100755 --- a/britney.py +++ b/britney.py @@ -1860,7 +1860,11 @@ class Britney(object): 'r': self.options.series, 'a': arch} archmsg.append('%s: %s' % (url, arch, ADT_EXCUSES_LABELS[arch_status[arch]])) - e.addhtml('autopkgtest for %s %s: %s' % (adtsrc, adtver, ', '.join(archmsg))) + if adtsrc in autopkgtest_excludes: + note = ' (%s is unbuilt/uninstallable)' % self.sources['unstable'][adtsrc][VERSION] + else: + note = '' + e.addhtml('autopkgtest for %s %s%s: %s' % (adtsrc, adtver, note, ', '.join(archmsg))) # hints can override failures if not passed: diff --git a/tests/test_autopkgtest.py b/tests/test_autopkgtest.py index e1de222..47c2412 100644 --- a/tests/test_autopkgtest.py +++ b/tests/test_autopkgtest.py @@ -106,6 +106,8 @@ class TestAutoPkgTest(TestBase): except IOError: self.pending_requests = None + self.assertNotIn('FIXME', out) + return out def test_no_request_for_uninstallable(self): @@ -378,7 +380,7 @@ lightgreen 1 i386 green 2 NOT_CONSIDERED) os.unlink(self.fake_amqp) - # add unbuilt lightgreen + # add unbuilt lightgreen; should run tests against the old version self.data.add_src('lightgreen', True, {'Version': '2', 'Testsuite': 'autopkgtest'}) self.do_test( [], @@ -387,14 +389,14 @@ lightgreen 1 i386 green 2 r'\blightgreen\b.*>1 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.*Unbuilt/uninstallable.*i386.*Unbuilt/uninstallable', + r'autopkgtest for lightgreen 1 \(2 is unbuilt/uninstallable\): .*amd64.*Regression.*i386.*Regression', 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 + # now lightgreen 2 gets built, should trigger a new test run self.swift.set_results({'autopkgtest-series': { 'series/i386/l/lightgreen/20150101_100200@': (0, 'lightgreen 2'), 'series/amd64/l/lightgreen/20150101_102000@': (0, 'lightgreen 2'),