mirror of
https://git.launchpad.net/~ubuntu-release/britney/+git/britney2-ubuntu
synced 2025-05-24 08:51:31 +00:00
Re-add 'unsatisfiable dependencies' information which dropped with the excuses key.
This commit is contained in:
parent
94bffad136
commit
80bf9060de
@ -1160,6 +1160,7 @@ class Britney(object):
|
|||||||
# if no package can satisfy the dependency, add this information to the excuse
|
# if no package can satisfy the dependency, add this information to the excuse
|
||||||
if not packages:
|
if not packages:
|
||||||
excuse.addhtml("%s/%s unsatisfiable Depends: %s" % (pkg, arch, block_txt.strip()))
|
excuse.addhtml("%s/%s unsatisfiable Depends: %s" % (pkg, arch, block_txt.strip()))
|
||||||
|
excuse.add_unsatisfiable_dep(block_txt.strip(), arch)
|
||||||
excuse.addreason("depends")
|
excuse.addreason("depends")
|
||||||
if arch not in self.options.break_arches:
|
if arch not in self.options.break_arches:
|
||||||
is_all_ok = False
|
is_all_ok = False
|
||||||
|
@ -60,6 +60,7 @@ class Excuse(object):
|
|||||||
self.deps = {}
|
self.deps = {}
|
||||||
self.sane_deps = []
|
self.sane_deps = []
|
||||||
self.break_deps = []
|
self.break_deps = []
|
||||||
|
self.unsat_deps = {}
|
||||||
self.bugs = []
|
self.bugs = []
|
||||||
self.newbugs = set()
|
self.newbugs = set()
|
||||||
self.oldbugs = set()
|
self.oldbugs = set()
|
||||||
@ -123,6 +124,13 @@ class Excuse(object):
|
|||||||
if (name, arch) not in self.break_deps:
|
if (name, arch) not in self.break_deps:
|
||||||
self.break_deps.append( (name, arch) )
|
self.break_deps.append( (name, arch) )
|
||||||
|
|
||||||
|
def add_unsatisfiable_dep(self, signature, arch):
|
||||||
|
"""Add an unsatisfiable dependency"""
|
||||||
|
if arch not in self.unsat_deps:
|
||||||
|
self.unsat_deps[arch] = []
|
||||||
|
if signature not in self.unsat_deps[arch]:
|
||||||
|
self.unsat_deps[arch].append(signature)
|
||||||
|
|
||||||
def invalidate_dep(self, name):
|
def invalidate_dep(self, name):
|
||||||
"""Invalidate dependency"""
|
"""Invalidate dependency"""
|
||||||
if name not in self.invalid_deps: self.invalid_deps.append(name)
|
if name not in self.invalid_deps: self.invalid_deps.append(name)
|
||||||
@ -246,7 +254,7 @@ class Excuse(object):
|
|||||||
'on-architectures': sorted(self.missing_builds),
|
'on-architectures': sorted(self.missing_builds),
|
||||||
'on-unimportant-architectures': sorted(self.missing_builds_ood_arch),
|
'on-unimportant-architectures': sorted(self.missing_builds_ood_arch),
|
||||||
}
|
}
|
||||||
if self.deps or self.invalid_deps or self.break_deps:
|
if self.deps or self.invalid_deps or self.break_deps or self.unsat_deps:
|
||||||
excusedata['dependencies'] = dep_data = {}
|
excusedata['dependencies'] = dep_data = {}
|
||||||
migrate_after = sorted(x for x in self.deps if x not in self.invalid_deps)
|
migrate_after = sorted(x for x in self.deps if x not in self.invalid_deps)
|
||||||
break_deps = [x for x, _ in self.break_deps if x not in self.deps]
|
break_deps = [x for x, _ in self.break_deps if x not in self.deps]
|
||||||
@ -257,6 +265,12 @@ class Excuse(object):
|
|||||||
dep_data['migrate-after'] = migrate_after
|
dep_data['migrate-after'] = migrate_after
|
||||||
if break_deps:
|
if break_deps:
|
||||||
dep_data['unimportant-dependencies'] = sorted(break_deps)
|
dep_data['unimportant-dependencies'] = sorted(break_deps)
|
||||||
|
if self.unsat_deps:
|
||||||
|
dep_data['unsatisfiable-dependencies'] = unsatisfiable = {}
|
||||||
|
for arch in self.unsat_deps:
|
||||||
|
unsatisfiable[arch] = []
|
||||||
|
for sig in self.unsat_deps[arch]:
|
||||||
|
unsatisfiable[arch].append("%s" % sig)
|
||||||
if self.needs_approval:
|
if self.needs_approval:
|
||||||
status = 'not-approved'
|
status = 'not-approved'
|
||||||
for h in self.hints:
|
for h in self.hints:
|
||||||
|
132
tests/test_yaml.py
Executable file
132
tests/test_yaml.py
Executable file
@ -0,0 +1,132 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
# (C) 2017 Canonical Ltd.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
import fileinput
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import pprint
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
import apt_pkg
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
sys.path.insert(0, PROJECT_DIR)
|
||||||
|
|
||||||
|
from tests import TestBase, mock_swift
|
||||||
|
|
||||||
|
apt_pkg.init()
|
||||||
|
|
||||||
|
|
||||||
|
class YamlTest(TestBase):
|
||||||
|
''' Validate generated yaml '''
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
self.fake_amqp = os.path.join(self.data.path, 'amqp')
|
||||||
|
|
||||||
|
# Set fake AMQP and Swift server
|
||||||
|
for line in fileinput.input(self.britney_conf, inplace=True):
|
||||||
|
if 'ADT_AMQP' in line:
|
||||||
|
print('ADT_AMQP = file://%s' % self.fake_amqp)
|
||||||
|
elif 'ADT_SWIFT_URL' in line:
|
||||||
|
print('ADT_SWIFT_URL = http://localhost:18085')
|
||||||
|
elif 'ADT_ARCHES' in line:
|
||||||
|
print('ADT_ARCHES = amd64 i386')
|
||||||
|
else:
|
||||||
|
sys.stdout.write(line)
|
||||||
|
|
||||||
|
self.data.add('libc6', False)
|
||||||
|
self.sourceppa_cache = {}
|
||||||
|
|
||||||
|
self.email_cache = {}
|
||||||
|
for pkg, vals in self.sourceppa_cache.items():
|
||||||
|
for version, empty in vals.items():
|
||||||
|
self.email_cache.setdefault(pkg, {})
|
||||||
|
self.email_cache[pkg][version] = True
|
||||||
|
|
||||||
|
# create mock Swift server (but don't start it yet, as tests first need
|
||||||
|
# to poke in results)
|
||||||
|
self.swift = mock_swift.AutoPkgTestSwiftServer(port=18085)
|
||||||
|
self.swift.set_results({})
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
del self.swift
|
||||||
|
|
||||||
|
def do_test(self, unstable_add):
|
||||||
|
'''Run britney with some unstable packages and verify excuses.
|
||||||
|
|
||||||
|
unstable_add is a list of (binpkgname, field_dict, daysold)
|
||||||
|
|
||||||
|
Return excuses_dict.
|
||||||
|
'''
|
||||||
|
age_file = os.path.join(self.data.path,
|
||||||
|
'data',
|
||||||
|
'series',
|
||||||
|
'Dates')
|
||||||
|
for (pkg, fields, daysold) in unstable_add:
|
||||||
|
self.data.add(pkg, True, fields, True, None)
|
||||||
|
self.sourceppa_cache.setdefault(pkg, {})
|
||||||
|
if fields['Version'] not in self.sourceppa_cache[pkg]:
|
||||||
|
self.sourceppa_cache[pkg][fields['Version']] = ''
|
||||||
|
with open(age_file, 'w') as f:
|
||||||
|
import time
|
||||||
|
do = time.time() - (60 * 60 * 24 * daysold)
|
||||||
|
f.write('%s %s %d' % (pkg, fields['Version'], do))
|
||||||
|
|
||||||
|
|
||||||
|
# Set up sourceppa cache for testing
|
||||||
|
sourceppa_path = os.path.join(self.data.dirs[True], 'SourcePPA')
|
||||||
|
with open(sourceppa_path, 'w', encoding='utf-8') as sourceppa:
|
||||||
|
sourceppa.write(json.dumps(self.sourceppa_cache))
|
||||||
|
|
||||||
|
(excuses_yaml, excuses_html, out) = self.run_britney()
|
||||||
|
|
||||||
|
# convert excuses to source indexed dict
|
||||||
|
excuses_dict = {}
|
||||||
|
for s in yaml.load(excuses_yaml)['sources']:
|
||||||
|
excuses_dict[s['source']] = s
|
||||||
|
|
||||||
|
if 'SHOW_EXCUSES' in os.environ:
|
||||||
|
print('------- excuses -----')
|
||||||
|
pprint.pprint(excuses_dict, width=200)
|
||||||
|
if 'SHOW_YAML' in os.environ:
|
||||||
|
print('------- excuses.yaml -----\n%s\n' % excuses_yaml)
|
||||||
|
if 'SHOW_HTML' in os.environ:
|
||||||
|
print('------- excuses.html -----\n%s\n' % excuses_html)
|
||||||
|
if 'SHOW_OUTPUT' in os.environ:
|
||||||
|
print('------- output -----\n%s\n' % out)
|
||||||
|
|
||||||
|
self.assertNotIn('FIXME', out)
|
||||||
|
|
||||||
|
return excuses_dict
|
||||||
|
|
||||||
|
def test_unsat_deps(self):
|
||||||
|
'''Test unsatisfiable dependencies list'''
|
||||||
|
pkg = ('libc6', {'Version': '2',
|
||||||
|
'Depends': 'notavailable (>= 2)'},
|
||||||
|
6)
|
||||||
|
|
||||||
|
excuse = self.do_test([pkg])
|
||||||
|
self.assertIn('notavailable (>= 2)', excuse['libc6']['dependencies']['unsatisfiable-dependencies']['amd64'])
|
||||||
|
|
||||||
|
def test_epoch_in_deps(self):
|
||||||
|
'''Test dependencies listing with epoch in versioned dep'''
|
||||||
|
pkg = ('libc6', {'Version': '2',
|
||||||
|
'Depends': 'datefudge (>= 99:1.0-0.1ubuntu8)'},
|
||||||
|
6)
|
||||||
|
|
||||||
|
excuse = self.do_test([pkg])
|
||||||
|
self.assertIn('datefudge', excuse['libc6']['dependencies']['unsatisfiable-dependencies']['amd64'][0])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
Loading…
x
Reference in New Issue
Block a user