Hello community, here is the log from the commit of package openSUSE-release-tools for openSUSE:Factory checked in at 2018-02-09 15:46:40 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/openSUSE-release-tools (Old) and /work/SRC/openSUSE:Factory/.openSUSE-release-tools.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "openSUSE-release-tools" Fri Feb 9 15:46:40 2018 rev:52 rq:573915 version:20180207.878b87b Changes: -------- --- /work/SRC/openSUSE:Factory/openSUSE-release-tools/openSUSE-release-tools.changes 2018-02-07 18:42:05.994254052 +0100 +++ /work/SRC/openSUSE:Factory/.openSUSE-release-tools.new/openSUSE-release-tools.changes 2018-02-09 15:46:47.217026716 +0100 @@ -1,0 +2,25 @@ +Wed Feb 07 22:26:00 UTC 2018 - opensuse-releaseteam@opensuse.org + +- Update to version 20180207.878b87b: + * osc-staging: select: reword documentation to include XML reference. + * osc-staging: select: mention additional supplemented request values. + * osc-staging: select: mention quick strategy in documentation. + * osc-staging: select: add filter-by example using hashtag in description. + +------------------------------------------------------------------- +Wed Feb 07 03:15:11 UTC 2018 - opensuse-releaseteam@opensuse.org + +- Update to version 20180206.56df1cf: + * osclib/conf: include Leap for Factory during pkglistgen. + * pkglistgen: include some hints about the difference between solv files. + * pkglistgen: integrate drop list creation into update_and_solve. + * pkglistgen: do_dump_solv(): handle old-style product repo format. + * pkglistgen: do_create_droplist(): print to file when output_dir available. + * pkglistgen: provide update_merge() to combine free and nonfree solv. + * osclib/util: provide project_list_family* and project_version(). + * osclib/stagingapi: get_staging_projects(): utilize project_list_prefix(). + * osclib/core: provide project_list_prefix(). + * osclib/conf: add download-baseurl for Leap and Factory. + * osclib/conf: support version in project pattern as value replacement. + +------------------------------------------------------------------- Old: ---- openSUSE-release-tools-20180206.faa028a.obscpio New: ---- openSUSE-release-tools-20180207.878b87b.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ openSUSE-release-tools.spec ++++++ --- /var/tmp/diff_new_pack.6jVX9f/_old 2018-02-09 15:46:48.600977019 +0100 +++ /var/tmp/diff_new_pack.6jVX9f/_new 2018-02-09 15:46:48.600977019 +0100 @@ -20,7 +20,7 @@ %define source_dir osc-plugin-factory %define announcer_filename factory-package-news Name: openSUSE-release-tools -Version: 20180206.faa028a +Version: 20180207.878b87b Release: 0 Summary: Tools to aid in staging and release work for openSUSE/SUSE License: GPL-2.0+ AND MIT ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.6jVX9f/_old 2018-02-09 15:46:48.648975296 +0100 +++ /var/tmp/diff_new_pack.6jVX9f/_new 2018-02-09 15:46:48.652975152 +0100 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/openSUSE/osc-plugin-factory.git</param> - <param name="changesrevision">faa028a805bdebf740dda3e38ac261e9e4f4f489</param> + <param name="changesrevision">b2c2fee6f5b0a0e812eccff9dd1e446a489025e9</param> </service> </servicedata> ++++++ openSUSE-release-tools-20180206.faa028a.obscpio -> openSUSE-release-tools-20180207.878b87b.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openSUSE-release-tools-20180206.faa028a/osc-staging.py new/openSUSE-release-tools-20180207.878b87b/osc-staging.py --- old/openSUSE-release-tools-20180206.faa028a/osc-staging.py 2018-02-07 04:01:04.000000000 +0100 +++ new/openSUSE-release-tools-20180207.878b87b/osc-staging.py 2018-02-07 23:20:07.000000000 +0100 @@ -237,12 +237,19 @@ Requests may either be the target package or the request ID. When using --filter-by or --group-by the xpath will be applied to the - request node as returned by OBS. Several values will supplement the - normal request node. + request node as returned by OBS. Use the following on a current request + to see the XML structure. + + osc api /request/1337 + + A number of additional values will supplement the normal request node. - ./action/target/@devel_project: the devel project for the package + - ./action/target/@devel_project_super: super devel project if relevant - ./action/target/@ring: the ring to which the package belongs - - ./@ignored: either false or the provided message + - ./@aged: either True or False based on splitter-request-age-threshold + - ./@nonfree: set to nonfree if targetting nonfree sub project + - ./@ignored: either False or the provided message Some useful examples: @@ -250,6 +257,7 @@ --filter-by './action/target/[@devel_project="YaST:Head"]' --filter-by './action/target[starts-with(@ring, "1")]' --filter-by '@id!="1234567"' + --filter-by 'contains(description, "#Portus")' --group-by='./action/target/@devel_project' --group-by='./action/target/@ring' @@ -278,6 +286,7 @@ Built in strategies may be specified as well. For example: select --strategy devel + select --strategy quick select --strategy special select --strategy super diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openSUSE-release-tools-20180206.faa028a/osclib/conf.py new/openSUSE-release-tools-20180207.878b87b/osclib/conf.py --- old/openSUSE-release-tools-20180206.faa028a/osclib/conf.py 2018-02-07 04:01:04.000000000 +0100 +++ new/openSUSE-release-tools-20180207.878b87b/osclib/conf.py 2018-02-07 23:20:07.000000000 +0100 @@ -47,12 +47,14 @@ 'lock-ns': 'openSUSE', 'delreq-review': 'factory-maintainers', 'main-repo': 'standard', + 'download-baseurl': 'http://download.opensuse.org/tumbleweed/', # check_source.py 'devel-project-enforce': 'True', 'review-team': 'opensuse-review-team', 'repo-checker': 'repo-checker', + 'pkglistgen-product-family-include': 'openSUSE:Leap:N', }, - r'openSUSE:(?P<project>Leap:[\d.]+)': { + r'openSUSE:(?P<project>Leap:(?P<version>[\d.]+))': { 'staging': 'openSUSE:%(project)s:Staging', 'staging-group': 'factory-staging', 'staging-archs': 'i586 x86_64', @@ -67,6 +69,7 @@ 'lock-ns': 'openSUSE', 'delreq-review': None, 'main-repo': 'standard', + 'download-baseurl': 'http://download.opensuse.org/distribution/leap/%(version)s/', # check_source.py # review-team optionally added by leaper.py. 'repo-checker': 'repo-checker', @@ -188,6 +191,8 @@ defaults[k] = v % {'project': project} elif isinstance(v, basestring) and '%(project.lower)s' in v: defaults[k] = v % {'project.lower': project.lower()} + elif isinstance(v, basestring) and '%(version)s' in v: + defaults[k] = v % {'version': match.group('version')} else: defaults[k] = v break diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openSUSE-release-tools-20180206.faa028a/osclib/core.py new/openSUSE-release-tools-20180207.878b87b/osclib/core.py --- old/openSUSE-release-tools-20180206.faa028a/osclib/core.py 2018-02-07 04:01:04.000000000 +0100 +++ new/openSUSE-release-tools-20180207.878b87b/osclib/core.py 2018-02-07 23:20:07.000000000 +0100 @@ -3,6 +3,7 @@ from dateutil.parser import parse as date_parse import re from xml.etree import cElementTree as ET +from lxml import etree as ETL from urllib2 import HTTPError from osc.core import get_binarylist @@ -173,3 +174,10 @@ created = request.find('history').get('when') created = date_parse(created) return datetime.utcnow() - created + +def project_list_prefix(apiurl, prefix): + """Get a list of project with the same prefix.""" + query = {'match': 'starts-with(@name, "{}")'.format(prefix)} + url = makeurl(apiurl, ['search', 'project', 'id'], query) + root = ETL.parse(http_GET(url)).getroot() + return root.xpath('project/@name') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openSUSE-release-tools-20180206.faa028a/osclib/stagingapi.py new/openSUSE-release-tools-20180207.878b87b/osclib/stagingapi.py --- old/openSUSE-release-tools-20180206.faa028a/osclib/stagingapi.py 2018-02-07 04:01:04.000000000 +0100 +++ new/openSUSE-release-tools-20180207.878b87b/osclib/stagingapi.py 2018-02-07 23:20:07.000000000 +0100 @@ -49,6 +49,7 @@ from osclib.cache import Cache from osclib.core import devel_project_get +from osclib.core import project_list_prefix from osclib.comments import CommentAPI from osclib.ignore_command import IgnoreCommand from osclib.memoize import memoize @@ -333,17 +334,10 @@ :return list of known staging projects """ - projects = [] + projects = project_list_prefix(self.apiurl, self.cstaging + ':') + if not include_dvd: + projects = filter(lambda p: not p.endswith(':DVD'), projects) - query = "id?match=starts-with(@name,'{}:')".format(self.cstaging) - url = self.makeurl(['search', 'project', query]) - projxml = http_GET(url) - root = ET.parse(projxml).getroot() - for val in root.findall('project'): - project = val.get('name') - if not include_dvd and project.endswith(':DVD'): - continue - projects.append(project) return projects def extract_staging_short(self, p): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openSUSE-release-tools-20180206.faa028a/osclib/util.py new/openSUSE-release-tools-20180207.878b87b/osclib/util.py --- old/openSUSE-release-tools-20180206.faa028a/osclib/util.py 1970-01-01 01:00:00.000000000 +0100 +++ new/openSUSE-release-tools-20180207.878b87b/osclib/util.py 2018-02-07 23:20:07.000000000 +0100 @@ -0,0 +1,78 @@ +from osclib.core import project_list_prefix + + +def project_list_family(apiurl, project): + """ + Determine the available projects within the same product family. + + Skips < SLE-12 due to format change. + """ + if project == 'openSUSE:Factory': + return [project] + + count_original = project.count(':') + if project.startswith('SUSE:SLE'): + project = ':'.join(project.split(':')[:2]) + family_filter = lambda p: p.endswith(':GA') and not p.startswith('SUSE:SLE-11') + else: + family_filter = lambda p: p.count(':') == count_original + + prefix = ':'.join(project.split(':')[:-1]) + projects = project_list_prefix(apiurl, prefix) + + return filter(family_filter, projects) + +def project_list_family_prior(apiurl, project, include_self=False): + """ + Determine the available projects within the same product family released + prior to the specified project. + """ + projects = project_list_family(apiurl, project) + past = False + prior = [] + for entry in sorted(projects, key=project_list_family_sorter, reverse=True): + if entry == project: + past = True + if not include_self: + continue + + if past: + prior.append(entry) + + return prior + +def project_list_family_sorter(project): + """Extract key to be used as sorter (oldest to newest).""" + version = project_version(project) + + if version >= 42: + version -= 42 + + if project.endswith(':Update'): + version += 0.01 + + return version + +def project_version(project): + """ + Extract a float representation of the project version. + + For example: + - openSUSE:Leap:15.0 -> 15.0 + - openSUSE:Leap:42.3 -> 42.3 + - SUSE:SLE-15:GA -> 15.0 + - SUSE:SLE-15-SP1:GA -> 15.1 + """ + if ':Leap:' in project: + return float(project.split(':')[2]) + + if ':SLE-' in project: + version = project.split(':')[1] + parts = version.split('-') + version = float(parts[1]) + if len(parts) > 2: + # Add each service pack as a tenth. + version += float(parts[2][2:]) / 10 + return version + + return None diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openSUSE-release-tools-20180206.faa028a/pkglistgen.py new/openSUSE-release-tools-20180207.878b87b/pkglistgen.py --- old/openSUSE-release-tools-20180206.faa028a/pkglistgen.py 2018-02-07 04:01:04.000000000 +0100 +++ new/openSUSE-release-tools-20180207.878b87b/pkglistgen.py 2018-02-07 23:20:07.000000000 +0100 @@ -40,6 +40,8 @@ from osc import conf from osclib.conf import Config from osclib.stagingapi import StagingAPI +from osclib.util import project_list_family +from osclib.util import project_list_family_prior from xdg.BaseDirectory import save_cache_path import glob import solv @@ -754,6 +756,32 @@ fh.close() return global_update + def update_merge(self, nonfree): + """Merge free and nonfree solv files or copy free to merged""" + for prp in self.tool.repos: + project, repo = prp.split('/') + for arch in self.tool.architectures: + solv_file = os.path.join( + CACHEDIR, 'repo-{}-{}-{}.solv'.format(project, repo, arch)) + solv_file_merged = os.path.join( + CACHEDIR, 'repo-{}-{}-{}.merged.solv'.format(project, repo, arch)) + + if not nonfree: + shutil.copyfile(solv_file, solv_file_merged) + continue + + solv_file_nonfree = os.path.join( + CACHEDIR, 'repo-{}-{}-{}.solv'.format(nonfree, repo, arch)) + self.solv_merge(solv_file, solv_file_nonfree, solv_file_merged) + + def solv_merge(self, solv1, solv2, solv_merged): + with open(solv_merged, 'w') as handle: + p = subprocess.Popen(['mergesolv', solv1, solv2], stdout=handle) + p.communicate() + + if p.returncode: + raise Exception('failed to create merged solv file') + def do_create_droplist(self, subcmd, opts, *oldsolv): """${cmd_name}: generate list of obsolete packages @@ -785,7 +813,7 @@ r = pool.add_repo(prp) r.add_solv(fn) - sysrepo = pool.add_repo(os.path.basename(old).replace('.repo.solv', '')) + sysrepo = pool.add_repo(os.path.basename(old).replace('.merged.solv', '')) sysrepo.add_solv(old) pool.createwhatprovides() @@ -811,16 +839,24 @@ # mark it explicitly to avoid having 2 pools while GC is not run del pool + ofh = sys.stdout + if self.options.output_dir: + name = os.path.join(self.options.output_dir, 'obsoletepackages.inc') + ofh = open(name, 'w') + for reponame in sorted(set(drops.values())): - print("<!-- %s -->" % reponame) + print("<!-- %s -->" % reponame, file=ofh) for p in sorted(drops): if drops[p] != reponame: continue - print(" <obsoletepackage>%s</obsoletepackage>" % p) + print(" <obsoletepackage>%s</obsoletepackage>" % p, file=ofh) @cmdln.option('--overwrite', action='store_true', help='overwrite if output file exists') def do_dump_solv(self, subcmd, opts, baseurl): """${cmd_name}: fetch repomd and dump solv + Dumps solv from published repository. Use solve to generate from + pre-published repository. + If an output directory is specified, a file named according to the build is created there. Otherwise the solv file is dumped to stdout. @@ -832,19 +868,11 @@ name = None ofh = sys.stdout if self.options.output_dir: - url = urlparse.urljoin(baseurl, 'media.1/media') - with requests.get(url) as media: - for i, line in enumerate(media.iter_lines()): - if i != 1: - continue - name = line - if name is None or '-Build' not in name: - raise Exception('media.1/media includes no build number') - - name = '{}/{}.solv'.format(self.options.output_dir, name) + build, repo_style = self.dump_solv_build(baseurl) + name = '{}/{}.solv'.format(self.options.output_dir, build) if not opts.overwrite and os.path.exists(name): logger.info("%s exists", name) - return + return name ofh = open(name + '.new', 'w') pool = solv.Pool() @@ -852,7 +880,8 @@ repo = pool.add_repo(''.join(random.choice(string.letters) for _ in range(5))) f = tempfile.TemporaryFile() - url = urlparse.urljoin(baseurl, 'repodata/repomd.xml') + path_prefix = 'suse/' if name and repo_style == 'build' else '' + url = urlparse.urljoin(baseurl, path_prefix + 'repodata/repomd.xml') repomd = requests.get(url) ns = { 'r': 'http://linux.duke.edu/metadata/repo' } root = ET.fromstring(repomd.content) @@ -860,7 +889,7 @@ f.write(repomd.content) os.lseek(f.fileno(), 0, os.SEEK_SET) repo.add_repomdxml(f, 0) - url = urlparse.urljoin(baseurl, location) + url = urlparse.urljoin(baseurl, path_prefix + location) with requests.get(url, stream=True) as primary: content = gzip.GzipFile(fileobj=StringIO(primary.content)) os.lseek(f.fileno(), 0, os.SEEK_SET) @@ -873,6 +902,28 @@ if name is not None: os.rename(name + '.new', name) + return name + + def dump_solv_build(self, baseurl): + """Determine repo format and build string from remote repository.""" + url = urlparse.urljoin(baseurl, 'media.1/media') + with requests.get(url) as media: + for i, line in enumerate(media.iter_lines()): + if i != 1: + continue + name = line + + if name is not None and '-Build' in name: + return name, 'media' + + url = urlparse.urljoin(baseurl, 'media.1/build') + with requests.get(url) as build: + name = build.content.strip() + + if name is not None and '-Build' in name: + return name, 'build' + + raise Exception('media.1/{media,build} includes no build number') @cmdln.option('--ignore-unresolvable', action='store_true', help='ignore unresolvable and missing packges') @cmdln.option('--ignore-recommended', action='store_true', help='do not include recommended packages automatically') @@ -882,6 +933,9 @@ def do_solve(self, subcmd, opts): """${cmd_name}: Solve groups + Generates solv from pre-published repository contained in local cache. + Use dump_solv to extract solv from published repository. + ${cmd_usage} ${cmd_option_list} """ @@ -980,14 +1034,14 @@ if opts.scope == 'target': self.options.repos = ['/'.join([target_project, main_repo])] - self.update_and_solve_target(apiurl, target_project, target_config, main_repo, opts) + self.update_and_solve_target(apiurl, target_project, target_config, main_repo, opts, drop_list=True) return elif opts.scope == 'ports': # TODO Continue supporting #1297, but should be abstracted. main_repo = 'ports' opts.project += ':Ports' self.options.repos = ['/'.join([opts.project, main_repo])] - self.update_and_solve_target(apiurl, target_project, target_config, main_repo, opts) + self.update_and_solve_target(apiurl, target_project, target_config, main_repo, opts, drop_list=True) return elif opts.scope == 'rings': opts.project = api.rings[1] @@ -1022,7 +1076,7 @@ return def update_and_solve_target(self, apiurl, target_project, target_config, main_repo, opts, - skip_release=False): + skip_release=False, drop_list=False): print('[{}] {}/{}: update and solve'.format(opts.scope, opts.project, main_repo)) group = target_config.get('pkglistgen-group', '000package-groups') @@ -1083,6 +1137,26 @@ print('-> do_update') self.do_update('update', opts) + nonfree = target_config.get('nonfree') + if nonfree and drop_list: + print('-> do_update nonfree') + + # Switch to nonfree repo (ugly, but that's how the code was setup). + self.options.repos_ = self.options.repos + self.options.repos = ['/'.join([nonfree, main_repo])] + self.postoptparse() + + opts_nonfree = copy.deepcopy(opts) + opts_nonfree.project = nonfree + self.do_update('update', opts_nonfree) + + # Switch repo back to main target project. + self.options.repos = self.options.repos_ + self.postoptparse() + + print('-> update_merge') + self.update_merge(nonfree if drop_list else False) + print('-> do_solve') opts.ignore_unresolvable = bool(target_config.get('pkglistgen-ignore-unresolvable')) opts.ignore_recommended = bool(target_config.get('pkglistgen-ignore-recommended')) @@ -1091,6 +1165,26 @@ opts.locales_from = target_config.get('pkglistgen-locales-from') self.do_solve('solve', opts) + if drop_list: + # Ensure solv files from all releases in product family are updated. + print('-> solv_cache_update') + cache_dir_solv = save_cache_path('opensuse-packagelists', 'solv') + family_include = target_config.get('pkglistgen-product-family-include') + solv_prior = self.solv_cache_update( + apiurl, cache_dir_solv, target_project, family_include, opts) + + # Include pre-final release solv files for target project. These + # files will only exist from previous runs. + cache_dir_solv_current = os.path.join(cache_dir_solv, target_project) + solv_prior.update(glob.glob(os.path.join(cache_dir_solv_current, '*.merged.solv'))) + for solv_file in solv_prior: + logger.debug(solv_file.replace(cache_dir_solv, '')) + + print('-> do_create_droplist') + # Reset to product after solv_cache_update(). + self.options.output_dir = product_dir + self.do_create_droplist('create_droplist', opts, *solv_prior) + delete_products = target_config.get('pkglistgen-delete-products', '').split(' ') self.unlink_list(product_dir, delete_products) @@ -1117,6 +1211,55 @@ self.build_stub(release_dir, 'spec') self.commit_package(release_dir) + def solv_cache_update(self, apiurl, cache_dir_solv, target_project, family_include, opts): + """Dump solv files (do_dump_solv) for all products in family.""" + prior = set() + + project_family = project_list_family_prior(apiurl, target_project, include_self=True) + if family_include: + # Include projects from a different family if desired. + project_family.extend(project_list_family(apiurl, family_include)) + + for project in project_family: + config = Config(project) + project_config = conf.config[project] + + baseurl = project_config.get('download-baseurl') + if not baseurl: + logger.warning('no baseurl configured for {}'.format(project)) + continue + + urls = [urlparse.urljoin(baseurl, 'repo/oss/')] + if project_config.get('nonfree'): + urls.append(urlparse.urljoin(baseurl, 'repo/non-oss/')) + + names = [] + for url in urls: + print('-> do_dump_solv for {}/{}'.format( + project, os.path.basename(os.path.normpath(url)))) + logger.debug(url) + + self.options.output_dir = os.path.join(cache_dir_solv, project) + if not os.path.exists(self.options.output_dir): + os.makedirs(self.options.output_dir) + + opts.overwrite = False + names.append(self.do_dump_solv('dump_solv', opts, url)) + + if not len(names): + logger.warning('no solv files were dumped for {}'.format(project)) + continue + + # Merge nonfree solv with free solv or copy free solv as merged. + merged = names[0].replace('.solv', '.merged.solv') + if len(names) == 2: + self.solv_merge(names[0], names[1], merged) + else: + shutil.copyfile(names[0], merged) + prior.add(merged) + + return prior + def move_list(self, file_list, destination): for name in file_list: os.rename(name, os.path.join(destination, os.path.basename(name))) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openSUSE-release-tools-20180206.faa028a/tests/obs.py new/openSUSE-release-tools-20180207.878b87b/tests/obs.py --- old/openSUSE-release-tools-20180206.faa028a/tests/obs.py 2018-02-07 04:01:04.000000000 +0100 +++ new/openSUSE-release-tools-20180207.878b87b/tests/obs.py 2018-02-07 23:20:07.000000000 +0100 @@ -19,6 +19,7 @@ import re import string import time +import urllib import urllib2 import urlparse import xml.etree.cElementTree as ET @@ -810,7 +811,8 @@ @GET('/search/project/id') def search_project_id(self, request, uri, headers): """Return a search result /search/project/id.""" - assert urlparse.urlparse(uri).query == "match=starts-with(@name,'openSUSE:Factory:Staging:')" + assert urlparse.urlparse(uri).query == urllib.urlencode( + {'match': 'starts-with(@name, "openSUSE:Factory:Staging:")'}) response = (404, headers, '<result>Not found</result>') try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openSUSE-release-tools-20180206.faa028a/tests/util_tests.py new/openSUSE-release-tools-20180207.878b87b/tests/util_tests.py --- old/openSUSE-release-tools-20180206.faa028a/tests/util_tests.py 1970-01-01 01:00:00.000000000 +0100 +++ new/openSUSE-release-tools-20180207.878b87b/tests/util_tests.py 2018-02-07 23:20:07.000000000 +0100 @@ -0,0 +1,81 @@ +from osclib.util import project_list_family +from osclib.util import project_list_family_prior +from osclib.util import project_list_family_sorter +from osclib.util import project_list_prefix +from osclib import util +import unittest + + +class TestUtil(unittest.TestCase): + def setUp(self): + util._project_list_prefix = util.project_list_prefix + + def project_list_prefix_replacement(apiurl, prefix): + if prefix == 'openSUSE:Leap': + return [ + 'openSUSE:Leap:15.0', + 'openSUSE:Leap:15.0:Update', + 'openSUSE:Leap:15.0:NonFree', + 'openSUSE:Leap:15.0:NonFree:Update', + 'openSUSE:Leap:42.2', + 'openSUSE:Leap:42.3', + 'openSUSE:Leap:42.3:Update', + 'openSUSE:Leap:42.3:NonFree', + 'openSUSE:Leap:42.3:NonFree:Update', + ] + elif prefix == 'SUSE': + return [ + 'SUSE:SLE-10', + 'SUSE:SLE-10:SP2', + 'SUSE:SLE-11', + 'SUSE:SLE-11:GA', + 'SUSE:SLE-11:SP1', + 'SUSE:SLE-11:SP1:Update', + 'SUSE:SLE-12:GA', + 'SUSE:SLE-12-SP1:GA', + 'SUSE:SLE-12-SP1:Update', + 'SUSE:SLE-15:GA', + ] + + return [] + + util.project_list_prefix = project_list_prefix_replacement + + def tearDown(self): + util.project_list_prefix = util._project_list_prefix + + def test_project_list_family(self): + self.assertEqual(project_list_family(None, 'openSUSE:Factory'), ['openSUSE:Factory']) + + expected = ['openSUSE:Leap:15.0', 'openSUSE:Leap:42.2', 'openSUSE:Leap:42.3'] + self.assertEqual(expected, project_list_family(None, 'openSUSE:Leap:15.0')) + self.assertEqual(expected, project_list_family(None, 'openSUSE:Leap:42.3')) + + expected = ['SUSE:SLE-12:GA', 'SUSE:SLE-12-SP1:GA', 'SUSE:SLE-15:GA'] + self.assertEqual(expected, project_list_family(None, 'SUSE:SLE-15:GA')) + self.assertEqual(expected, project_list_family(None, 'SUSE:SLE-15-SP1:GA')) + + def test_project_list_family_sorter(self): + projects = sorted(project_list_family(None, 'openSUSE:Leap:15.0'), key=project_list_family_sorter) + self.assertEqual(projects[0], 'openSUSE:Leap:42.2') + self.assertEqual(projects[2], 'openSUSE:Leap:15.0') + + projects = sorted(project_list_family(None, 'SUSE:SLE-15:GA'), key=project_list_family_sorter) + self.assertEqual(projects[0], 'SUSE:SLE-12:GA') + self.assertEqual(projects[2], 'SUSE:SLE-15:GA') + + def test_project_list_family_prior(self): + projects = project_list_family_prior(None, 'openSUSE:Leap:15.0', include_self=True) + self.assertEqual(projects, ['openSUSE:Leap:15.0', 'openSUSE:Leap:42.3', 'openSUSE:Leap:42.2']) + + projects = project_list_family_prior(None, 'openSUSE:Leap:15.0') + self.assertEqual(projects, ['openSUSE:Leap:42.3', 'openSUSE:Leap:42.2']) + + projects = project_list_family_prior(None, 'openSUSE:Leap:42.3') + self.assertEqual(projects, ['openSUSE:Leap:42.2']) + + projects = project_list_family_prior(None, 'SUSE:SLE-15:GA') + self.assertEqual(projects, ['SUSE:SLE-12-SP1:GA', 'SUSE:SLE-12:GA']) + + projects = project_list_family_prior(None, 'SUSE:SLE-12-SP1:GA') + self.assertEqual(projects, ['SUSE:SLE-12:GA']) ++++++ openSUSE-release-tools.obsinfo ++++++ --- /var/tmp/diff_new_pack.6jVX9f/_old 2018-02-09 15:46:49.236954183 +0100 +++ /var/tmp/diff_new_pack.6jVX9f/_new 2018-02-09 15:46:49.236954183 +0100 @@ -1,5 +1,5 @@ name: openSUSE-release-tools -version: 20180206.faa028a -mtime: 1517972464 -commit: faa028a805bdebf740dda3e38ac261e9e4f4f489 +version: 20180207.878b87b +mtime: 1518042007 +commit: 878b87b2a96b4a8546437979af947df0a75d5531