diff --git a/autopkgtest.py b/autopkgtest.py index 23d692d..170b7e7 100644 --- a/autopkgtest.py +++ b/autopkgtest.py @@ -150,13 +150,11 @@ class AutoPackageTest(object): return True return False - def tests_for_source(self, src, ver): - '''Iterate over all tests that should be run for given source''' + def tests_for_source(self, src, ver, arch): + '''Iterate over all tests that should be run for given source and arch''' sources_info = self.britney.sources['unstable'] - # FIXME: For now assume that amd64 has all binaries that we are - # interested in for reverse dependency checking - binaries_info = self.britney.binaries['unstable']['amd64'][0] + binaries_info = self.britney.binaries['unstable'][arch][0] reported_pkgs = set() @@ -460,8 +458,8 @@ class AutoPackageTest(object): self.log_verbose('Requested autopkgtests for %s, exclusions: %s' % (['%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): - for arch in self.britney.options.adt_arches.split(): + for arch in self.britney.options.adt_arches.split(): + for (testsrc, testver) in self.tests_for_source(src, ver, arch): self.add_test_request(testsrc, testver, arch, src, ver) if self.britney.options.verbose: @@ -573,12 +571,13 @@ class AutoPackageTest(object): '''Return test results for triggering package Return (passed, src, ver, arch -> ALWAYSFAIL|PASS|FAIL|RUNNING) - iterator for all package tests that got triggered by trigsrc/trigver. + iterable for all package tests that got triggered by trigsrc/trigver. ''' - for testsrc, testver in self.tests_for_source(trigsrc, trigver): - passed = True - arch_status = {} - for arch in self.britney.options.adt_arches.split(): + # (src, ver) -> arch -> ALWAYSFAIL|PASS|FAIL|RUNNING + pkg_arch_result = {} + + for arch in self.britney.options.adt_arches.split(): + for testsrc, testver in self.tests_for_source(trigsrc, trigver, arch): try: (_, ver_map, ever_passed) = self.test_results[testsrc][arch] @@ -597,20 +596,18 @@ class AutoPackageTest(object): if (trigsrc, trigver) not in triggers and [trigsrc, trigver] not in triggers: raise KeyError('No result for trigger %s/%s yet' % (trigsrc, trigver)) if status: - arch_status[arch] = 'PASS' + result = 'PASS' else: # test failed, check ever_passed flag for that src/arch if ever_passed: - arch_status[arch] = 'REGRESSION' - passed = False + result = 'REGRESSION' else: - arch_status[arch] = 'ALWAYSFAIL' + result = 'ALWAYSFAIL' except KeyError: # no result for testsrc/testver/arch; still running? try: self.pending_tests[testsrc][testver][arch] - arch_status[arch] = 'RUNNING' - passed = False + result = 'RUNNING' except KeyError: # ignore if adt or swift results are disabled, # otherwise this is unexpected @@ -621,8 +618,9 @@ class AutoPackageTest(object): (testsrc, testver, arch, trigsrc, trigver)) continue - # disabled or ignored? - if not arch_status: - continue + pkg_arch_result.setdefault((testsrc, testver), {})[arch] = result - yield (passed, testsrc, testver, arch_status) + for ((testsrc, testver), arch_results) in pkg_arch_result.items(): + r = arch_results.values() + passed = 'REGRESSION' not in r and 'RUNNING' not in r + yield (passed, testsrc, testver, arch_results) diff --git a/tests/test_autopkgtest.py b/tests/test_autopkgtest.py index a5bace8..ee17cb2 100755 --- a/tests/test_autopkgtest.py +++ b/tests/test_autopkgtest.py @@ -388,6 +388,59 @@ lightgreen 1 i386 green 2 # not expecting any failures to retrieve from swift self.assertNotIn('Failure', out, out) + def test_multi_rdepends_arch_specific(self): + '''Multiple reverse dependencies with arch specific tests''' + + self.data.add('green64', False, {'Depends': 'libc6 (>= 0.9), libgreen1', + 'Architecture': 'amd64'}, + testsuite='autopkgtest') + + # first run requests tests and marks them as pending + self.do_test( + [('libgreen1', {'Version': '2', 'Source': 'green', 'Depends': 'libc6'}, 'autopkgtest')], + {'green': (False, {'green 2': {'amd64': 'RUNNING', 'i386': 'RUNNING'}, + 'lightgreen 1': {'amd64': 'RUNNING', 'i386': 'RUNNING'}, + 'darkgreen 1': {'amd64': 'RUNNING', 'i386': 'RUNNING'}, + 'green64 1': {'amd64': 'RUNNING'}, + }) + }) + + self.assertIn('green64 1 amd64', self.pending_requests) + self.assertNotIn('green64 1 i386', self.pending_requests) + + # second run collects the results + 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_100100@': (0, 'lightgreen 1'), + 'series/amd64/l/lightgreen/20150101_100101@': (0, 'lightgreen 1'), + # version in testing fails + 'series/i386/g/green/20150101_020000@': (4, 'green 1'), + 'series/amd64/g/green/20150101_020000@': (4, 'green 1'), + # version in unstable succeeds + 'series/i386/g/green/20150101_100200@': (0, 'green 2'), + 'series/amd64/g/green/20150101_100201@': (0, 'green 2'), + # only amd64 result for green64 + 'series/amd64/g/green64/20150101_100200@': (0, 'green64 1'), + }}) + + out = self.do_test( + [], + {'green': (True, {'green 2': {'amd64': 'PASS', 'i386': 'PASS'}, + 'lightgreen 1': {'amd64': 'PASS', 'i386': 'PASS'}, + 'darkgreen 1': {'amd64': 'PASS', 'i386': 'PASS'}, + 'green64 1': {'amd64': 'PASS'}, + }) + }, + {'green': [('old-version', '1'), ('new-version', '2')]} + )[0] + + # all tests ran, there should be no more pending ones + self.assertEqual(self.pending_requests, '') + + # 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'''