PR#417 Python3 support for CLI + XMLRPC client

Merges #417
https://pagure.io/koji/pull-request/417
This commit is contained in:
Mike McLean 2017-06-01 12:58:41 -04:00
commit 4f4639ec93
68 changed files with 5790 additions and 5612 deletions

View file

@ -1,5 +1,5 @@
[run]
omit =
/usr/lib/*
/usr/*
tests/*

12
.coveragerc3 Normal file
View file

@ -0,0 +1,12 @@
[run]
; extra omissions for py3 for now
omit =
/usr/*
tests/*
hub/*
util/*
koji/ssl/*
koji/daemon.py
koji/tasks.py

View file

@ -66,9 +66,21 @@ git-clean:
test:
coverage erase
PYTHONPATH=hub/.:plugins/hub/.:plugins/builder/. nosetests --with-coverage --cover-package .
PYTHONPATH=hub/.:plugins/hub/.:plugins/builder/. coverage run \
--source . /usr/bin/nosetests
coverage report
coverage html
@echo Coverage report in htmlcov/index.html
@echo Full coverage report in htmlcov/index.html
test3:
coverage erase
PYTHONPATH=hub/.:plugins/hub/.:plugins/builder/. coverage3 run \
--rcfile .coveragerc3 --source . \
/usr/bin/nosetests-3 \
tests/test_lib tests/test_cli
coverage report
coverage html
@echo Full coverage report in htmlcov/index.html
subdirs:
for d in $(SUBDIRS); do make -C $$d; [ $$? = 0 ] || exit 1; done

View file

@ -15,5 +15,5 @@ install:
mkdir -p $(DESTDIR)/usr/bin
install -p -m 755 $(FILES) $(DESTDIR)/usr/bin
install -p -m 644 koji.conf $(DESTDIR)/etc/koji.conf
mkdir -p $(DESTDIR)/etc/koji.conf.d
install -p -m 644 koji.conf $(DESTDIR)/etc/koji.conf

184
cli/koji
View file

@ -24,7 +24,14 @@
# Mike Bonnet <mikeb@redhat.com>
# Cristian Balint <cbalint@redhat.com>
from __future__ import absolute_import
from __future__ import division
import sys
from six.moves import range
from six.moves import zip
import six
from six.moves import filter
from six.moves import map
try:
import krbV
except ImportError: # pragma: no cover
@ -40,7 +47,7 @@ except ImportError: # pragma: no cover
import simplejson as json
except ImportError:
json = None
import ConfigParser
import six.moves.configparser
import base64
import dateutil.parser
import errno
@ -52,15 +59,14 @@ import logging
import os
import re
import pprint
import pycurl
import random
import socket
import stat
import string
import time
import traceback
import urlgrabber.grabber as grabber
import urlgrabber.progress as progress
import xmlrpclib
import six.moves.xmlrpc_client
try:
import libcomps
except ImportError: # pragma: no cover
@ -110,6 +116,12 @@ def _(args):
"""Stub function for translation"""
return args
def _printable_unicode(s):
if six.PY2:
return s.encode('utf-8')
else:
return s
ARGMAP = {'None': None,
'True': True,
'False': False}
@ -142,7 +154,7 @@ categories = {
def get_epilog_str(progname=None):
if progname is None:
progname = os.path.basename(sys.argv[0]) or 'koji'
categories_ordered=', '.join(sorted(['all'] + categories.keys()))
categories_ordered=', '.join(sorted(['all'] + list(categories.keys())))
epilog_str = '''
Try "%(progname)s --help" for help about global options
Try "%(progname)s help" to get all available commands
@ -237,12 +249,12 @@ def get_options():
# load local config
try:
result = koji.read_config(options.profile, user_config=options.configFile)
except koji.ConfigurationError, e:
except koji.ConfigurationError as e:
parser.error(e.args[0])
assert False # pragma: no cover
# update options according to local config
for name, value in result.iteritems():
for name, value in six.iteritems(result):
if getattr(options, name, None) is None:
setattr(options, name, value)
@ -275,7 +287,7 @@ def get_options():
def ensure_connection(session):
try:
ret = session.getAPIVersion()
except xmlrpclib.ProtocolError:
except six.moves.xmlrpc_client.ProtocolError:
error(_("Error: Unable to connect to server"))
if ret != koji.API_VERSION:
warn(_("WARNING: The server is at API version %d and the client is at %d" % (ret, koji.API_VERSION)))
@ -339,7 +351,7 @@ class TaskWatcher(object):
error = None
try:
result = self.session.getTaskResult(self.id)
except (xmlrpclib.Fault,koji.GenericError),e:
except (six.moves.xmlrpc_client.Fault,koji.GenericError) as e:
error = e
if error is None:
# print("%s: complete" % self.str())
@ -448,7 +460,7 @@ def watch_tasks(session,tasklist,quiet=False):
tasks[task_id] = TaskWatcher(task_id,session,quiet=quiet)
while True:
all_done = True
for task_id,task in tasks.items():
for task_id, task in list(tasks.items()):
changed = task.update()
if not task.is_done():
all_done = False
@ -461,7 +473,7 @@ def watch_tasks(session,tasklist,quiet=False):
rv = 1
for child in session.getTaskChildren(task_id):
child_id = child['id']
if not child_id in tasks.keys():
if not child_id in list(tasks.keys()):
tasks[child_id] = TaskWatcher(child_id, session, task.level + 1, quiet=quiet)
tasks[child_id].update()
# If we found new children, go through the list again,
@ -511,7 +523,7 @@ def watch_logs(session, tasklist, opts):
output = list_task_output_all_volumes(session, task_id)
# convert to list of (file, volume)
files = []
for filename, volumes in output.iteritems():
for filename, volumes in six.iteritems(output):
files += [(filename, volume) for volume in volumes]
if opts.log:
@ -547,7 +559,7 @@ def list_task_output_all_volumes(session, task_id):
"""List task output with all volumes, or fake it"""
try:
return session.listTaskOutput(task_id, all_volumes=True)
except koji.GenericError, e:
except koji.GenericError as e:
if 'got an unexpected keyword argument' not in str(e):
raise
# otherwise leave off the option and fake it
@ -941,7 +953,7 @@ def _progress_callback(uploaded, total, piece, time, total_time):
def _running_in_bg():
try:
return (not os.isatty(0)) or (os.getpgrp() != os.tcgetpgrp(0))
except OSError, e:
except OSError as e:
return True
def handle_build(options, session, args):
@ -1164,11 +1176,11 @@ def handle_maven_build(options, session, args):
try:
params = koji.util.parse_maven_param(build_opts.inis, scratch=build_opts.scratch,
section=build_opts.section)
except ValueError, e:
except ValueError as e:
parser.error(e.args[0])
opts = params.values()[0]
opts = list(params.values())[0]
if opts.pop('type', 'maven') != 'maven':
parser.error(_("Section %s does not contain a maven-build config") % params.keys()[0])
parser.error(_("Section %s does not contain a maven-build config") % list(params.keys())[0])
source = opts.pop('scmurl')
else:
source = args[1]
@ -1223,11 +1235,11 @@ def handle_wrapper_rpm(options, session, args):
try:
params = koji.util.parse_maven_param(build_opts.inis, scratch=build_opts.scratch,
section=build_opts.section)
except ValueError, e:
except ValueError as e:
parser.error(e.args[0])
opts = params.values()[0]
opts = list(params.values())[0]
if opts.get('type') != 'wrapper':
parser.error(_("Section %s does not contain a wrapper-rpm config") % params.keys()[0])
parser.error(_("Section %s does not contain a wrapper-rpm config") % list(params.keys())[0])
url = opts['scmurl']
package = opts['buildrequires'][0]
target_info = session.getBuildTarget(target, strict=True)
@ -1297,7 +1309,7 @@ def handle_maven_chain(options, session, args):
opts[key] = val
try:
builds = koji.util.parse_maven_chain(args[1:], scratch=opts.get('scratch'))
except ValueError, e:
except ValueError as e:
parser.error(e.args[0])
priority = None
if build_opts.background:
@ -1491,7 +1503,7 @@ def anon_handle_mock_config(options, session, args):
name = "%(tag_name)s-repo_%(repoid)s" % opts
output = koji.genMockConfig(name, arch, **opts)
if options.ofile:
fo = file(options.ofile, 'w')
fo = open(options.ofile, 'w')
fo.write(output)
fo.close()
else:
@ -1576,7 +1588,7 @@ def handle_restart_hosts(options, session, args):
def linked_upload(localfile, path, name=None):
"""Link a file into the (locally writable) workdir, bypassing upload"""
old_umask = os.umask(002)
old_umask = os.umask(0o02)
try:
if name is None:
name = os.path.basename(localfile)
@ -1625,7 +1637,7 @@ def handle_import(options, session, args):
nvr = "%(name)s-%(version)s-%(release)s" % koji.parse_NVRA(data['sourcerpm'])
to_import.setdefault(nvr,[]).append((path,data))
builds_missing = False
nvrs = to_import.keys()
nvrs = list(to_import.keys())
nvrs.sort()
for nvr in nvrs:
to_import[nvr].sort()
@ -1672,7 +1684,7 @@ def handle_import(options, session, args):
sys.stdout.flush()
try:
session.importRPM(serverdir, os.path.basename(path))
except koji.GenericError, e:
except koji.GenericError as e:
print(_("\nError importing: %s" % str(e).splitlines()[-1]))
sys.stdout.flush()
else:
@ -1759,7 +1771,7 @@ def handle_import_cg(options, session, args):
parser.error(_("Unable to find json module"))
assert False # pragma: no cover
activate_session(session)
metadata = json.load(file(args[0], 'r'))
metadata = json.load(open(args[0], 'r'))
if 'output' not in metadata:
print(_("Metadata contains no output"))
sys.exit(1)
@ -1850,7 +1862,11 @@ def _import_comps(session, filename, tag, options):
}
if pkg.type == libcomps.PACKAGE_TYPE_CONDITIONAL:
pkgopts['requires'] = pkg.requires
print(" Package: %s: %r" % (pkg.name, pkgopts))
for k in pkgopts.keys():
if six.PY2 and isinstance(pkgopts[k], unicode):
pkgopts[k] = str(pkgopts[k])
s_opts = ', '.join(["'%s': %r" % (k, pkgopts[k]) for k in sorted(list(pkgopts.keys()))])
print(" Package: %s: {%s}" % (pkg.name, s_opts))
session.groupPackageListAdd(tag, group.id, pkg.name, force=force, **pkgopts)
# libcomps does not support group dependencies
# libcomps does not support metapkgs
@ -1875,11 +1891,15 @@ def _import_comps_alt(session, filename, tag, options):
('optional', group.optional_packages),
('conditional', group.conditional_packages)]:
for pkg in pdata:
#yum.comps does not support basearchonly
pkgopts = {'type' : ptype}
if ptype == 'conditional':
pkgopts['requires'] = pdata[pkg]
#yum.comps does not support basearchonly
print(" Package: %s: %r" % (pkg, pkgopts))
for k in pkgopts.keys():
if six.PY2 and isinstance(pkgopts[k], unicode):
pkgopts[k] = str(pkgopts[k])
s_opts = ', '.join(["'%s': %r" % (k, pkgopts[k]) for k in sorted(list(pkgopts.keys()))])
print(" Package: %s: {%s}" % (pkg, s_opts))
session.groupPackageListAdd(tag, group.groupid, pkg, force=force, **pkgopts)
#yum.comps does not support group dependencies
#yum.comps does not support metapkgs
@ -2024,11 +2044,11 @@ def handle_prune_signed_copies(options, session, args):
#(with the modification that we check to see if the build was latest within
#the last N days)
if options.ignore_tag_file:
fo = file(options.ignore_tag_file)
fo = open(options.ignore_tag_file)
options.ignore_tag.extend([line.strip() for line in fo.readlines()])
fo.close()
if options.protect_tag_file:
fo = file(options.protect_tag_file)
fo = open(options.protect_tag_file)
options.protect_tag.extend([line.strip() for line in fo.readlines()])
fo.close()
if options.debug:
@ -2087,7 +2107,7 @@ def handle_prune_signed_copies(options, session, args):
#that the build was recently untagged from
tags.setdefault(entry['tag_name'], 1)
if options.debug:
print("Tags: %s" % tags.keys())
print("Tags: %s" % list(tags.keys()))
for tag_name in tags:
if tag_name == options.trashcan_tag:
if options.debug:
@ -2119,7 +2139,7 @@ def handle_prune_signed_copies(options, session, args):
timeline.sort()
#find most recent creation entry for our build and crop there
latest_ts = None
for i in xrange(len(timeline)-1, -1, -1):
for i in range(len(timeline)-1, -1, -1):
#searching in reverse cronological order
event_id, is_create, entry = timeline[i]
if entry['build_id'] == binfo['id'] and is_create:
@ -2257,7 +2277,7 @@ def handle_prune_signed_copies(options, session, args):
build_space = 0
if not by_sig and options.debug:
print("(build has no signatures)")
for sigkey, rpms in by_sig.iteritems():
for sigkey, rpms in six.iteritems(by_sig):
mycount = 0
archdirs = {}
sigdirs = {}
@ -2281,7 +2301,7 @@ def handle_prune_signed_copies(options, session, args):
print("Unlinking: %s" % signedpath)
try:
os.unlink(signedpath)
except OSError, e:
except OSError as e:
print("Error removing %s: %s" % (signedpath, e))
print("This script needs write access to %s" % koji.BASEDIR)
continue
@ -2301,10 +2321,10 @@ def handle_prune_signed_copies(options, session, args):
print("Removing dir: %s" % dir)
try:
os.rmdir(dir)
except OSError, e:
except OSError as e:
print("Error removing %s: %s" % (signedpath, e))
if len(sigdirs) == 1:
dir = sigdirs.keys()[0]
dir = list(sigdirs.keys())[0]
if options.test:
print("Would have removed dir: %s" % dir)
else:
@ -2312,7 +2332,7 @@ def handle_prune_signed_copies(options, session, args):
print("Removing dir: %s" % dir)
try:
os.rmdir(dir)
except OSError, e:
except OSError as e:
print("Error removing %s: %s" % (signedpath, e))
elif len(sigdirs) > 1:
print("Warning: more than one signature dir for %s: %r" % (sigkey, sigdirs))
@ -2546,7 +2566,7 @@ def handle_import_in_place(options, session, args):
sys.stdout.write(_("importing %s... ") % nvr)
try:
session.importBuildInPlace(data)
except koji.GenericError, e:
except koji.GenericError as e:
print(_("\nError importing: %s" % str(e).splitlines()[-1]))
sys.stdout.flush()
else:
@ -3671,35 +3691,35 @@ def handle_clone_tag(options, session, args):
dstgroups[group['name']] = group
#construct to-do lists.
paddlist = [] # list containing new packages to be added from src tag
for (package_name, pkg) in srcpkgs.iteritems():
for (package_name, pkg) in six.iteritems(srcpkgs):
if package_name not in dstpkgs:
paddlist.append(pkg)
paddlist.sort(key = lambda x: x['package_name'])
pdellist = [] # list containing packages no more present in dst tag
for (package_name, pkg) in dstpkgs.iteritems():
for (package_name, pkg) in six.iteritems(dstpkgs):
if package_name not in srcpkgs:
pdellist.append(pkg)
pdellist.sort(key = lambda x: x['package_name'])
baddlist = [] # list containing new builds to be added from src tag
for (nvr, lbld) in srclblds.iteritems():
for (nvr, lbld) in six.iteritems(srclblds):
if nvr not in dstlblds:
baddlist.append(lbld)
baddlist.sort(key = lambda x: x['package_name'])
bdellist = [] # list containing new builds to be removed from src tag
for (nvr, lbld) in dstlblds.iteritems():
for (nvr, lbld) in six.iteritems(dstlblds):
if nvr not in srclblds:
bdellist.append(lbld)
bdellist.sort(key = lambda x: x['package_name'])
gaddlist = [] # list containing new groups to be added from src tag
for (grpname, group) in srcgroups.iteritems():
for (grpname, group) in six.iteritems(srcgroups):
if grpname not in dstgroups:
gaddlist.append(group)
gdellist = [] # list containing groups to be removed from src tag
for (grpname, group) in dstgroups.iteritems():
for (grpname, group) in six.iteritems(dstgroups):
if grpname not in srcgroups:
gdellist.append(group)
grpchanges = {} # dict of changes to make in shared groups
for (grpname, group) in srcgroups.iteritems():
for (grpname, group) in six.iteritems(srcgroups):
if grpname in dstgroups:
grpchanges[grpname] = {'adds':[], 'dels':[]}
# Store whether group is inherited or not
@ -4041,15 +4061,15 @@ def _printInheritance(tags, sibdepths=None, reverse=False):
if depth < currtag['currdepth']:
outspacing = depth - outdepth
sys.stdout.write(' ' * (outspacing * 3 - 1))
sys.stdout.write(u'\u2502'.encode('UTF-8'))
sys.stdout.write(_printable_unicode(u'\u2502'))
outdepth = depth
sys.stdout.write(' ' * ((currtag['currdepth'] - outdepth) * 3 - 1))
if siblings:
sys.stdout.write(u'\u251c'.encode('UTF-8'))
sys.stdout.write(_printable_unicode(u'\u251c'))
else:
sys.stdout.write(u'\u2514'.encode('UTF-8'))
sys.stdout.write(u'\u2500'.encode('UTF-8'))
sys.stdout.write(_printable_unicode(u'\u2514'))
sys.stdout.write(_printable_unicode(u'\u2500'))
if reverse:
sys.stdout.write('%(name)s (%(tag_id)i)\n' % currtag)
else:
@ -4148,7 +4168,7 @@ def anon_handle_list_tags(options, session, args):
assert False # pragma: no cover
tags = session.listTags(buildinfo.get('id',None), pkginfo.get('id',None))
tags.sort(lambda a,b: cmp(a['name'],b['name']))
tags.sort(key=lambda x: x['name'])
#if options.verbose:
# fmt = "%(name)s [%(id)i] %(perm)s %(locked)s %(arches)s"
if options.show_id:
@ -4393,7 +4413,7 @@ def _print_histline(entry, **kwargs):
else:
return '%s.name' % key
if edit:
keys = x.keys()
keys = list(x.keys())
keys.sort()
y = other[-1]
for key in keys:
@ -4408,7 +4428,7 @@ def _print_histline(entry, **kwargs):
continue
print(" %s: %s -> %s" % (key, x[key], y[key]))
elif create and options.verbose and table != 'tag_listing':
keys = x.keys()
keys = list(x.keys())
keys.sort()
# the table keys have already been represented in the base format string
also_hidden = list(_table_keys[table])
@ -4884,7 +4904,7 @@ def anon_handle_taginfo(options, session, args):
print("Include all Maven archives?: %s" % (info['maven_include_all'] and 'yes' or 'no'))
if 'extra' in info:
print("Tag options:")
keys = info['extra'].keys()
keys = list(info['extra'].keys())
keys.sort()
for key in keys:
print(" %s : %s" % (key, pprint.pformat(info['extra'][key])))
@ -5437,7 +5457,7 @@ def _pick_external_repo_priority(session, tag):
if not repolist:
priority = 5
else:
priority = (repolist[-1]['priority'] + 7) / 5 * 5
priority = (repolist[-1]['priority'] + 7) // 5 * 5
#at least 3 higher than current max and a multiple of 5
return priority
@ -5914,7 +5934,7 @@ def handle_image_build(options, session, args):
if not os.path.exists(task_options.config):
parser.error(_("%s not found!" % task_options.config))
section = 'image-build'
config = ConfigParser.ConfigParser()
config = six.moves.configparser.ConfigParser()
conf_fd = open(task_options.config)
config.readfp(conf_fd)
conf_fd.close()
@ -6524,7 +6544,7 @@ def handle_make_task(opts, session, args):
if value is not None:
taskopts[key] = value
task_id = session.makeTask(method=args[0],
arglist=map(arg_filter,args[1:]),
arglist=list(map(arg_filter,args[1:])),
**taskopts)
print("Created task id %d" % task_id)
if _running_in_bg() or not options.watch:
@ -6732,7 +6752,7 @@ def anon_handle_download_build(options, session, args):
# We want the latest build, not a specific build
try:
builds = session.listTagged(suboptions.latestfrom, latest=True, package=build, type=suboptions.type)
except koji.GenericError, data:
except koji.GenericError as data:
print("Error finding latest build: %s" % data)
return 1
if not builds:
@ -6813,15 +6833,29 @@ def anon_handle_download_build(options, session, args):
url = pathinfo.build(info) + '/' + fname
urls.append((url, os.path.basename(fname)))
if suboptions.quiet:
pg = None
else:
pg = progress.TextMeter()
def _progress(download_t, download_d, upload_t, upload_d):
if download_t == 0:
percent_done = 0.0
else:
percent_done = float(download_d)/float(download_t)
percent_done_str = "%02d%%" % (percent_done * 100)
data_done = _format_size(download_d)
sys.stdout.write("[% -36s] % 4s % 10s\r" % ('='*(int(percent_done * 36)), percent_done_str, data_done))
sys.stdout.flush()
for url, relpath in urls:
if '/' in relpath:
koji.ensuredir(os.path.dirname(relpath))
grabber.urlgrab(url, filename=relpath, progress_obj=pg, text=relpath)
print(relpath)
c = pycurl.Curl()
c.setopt(c.URL, url)
c.setopt(c.WRITEDATA, open(relpath, 'wb'))
if not suboptions.quiet:
c.setopt(c.NOPROGRESS, False)
c.setopt(c.XFERINFOFUNCTION, _progress)
c.perform()
print('')
def anon_handle_download_logs(options, session, args):
@ -6861,7 +6895,7 @@ def anon_handle_download_logs(options, session, args):
full_filename = os.path.normpath(os.path.join(task_log_dir, FAIL_LOG))
koji.ensuredir(os.path.dirname(full_filename))
sys.stdout.write("Writing: %s\n" % full_filename)
file(full_filename, 'w').write(content)
open(full_filename, 'w').write(content)
def download_log(task_log_dir, task_id, filename, blocksize=102400, volume=None):
# Create directories only if there is any log file to write to
@ -6874,11 +6908,11 @@ def anon_handle_download_logs(options, session, args):
contents = 'IGNORE ME!'
if suboptions.cont and os.path.exists(full_filename):
sys.stdout.write("Continuing: %s\n" % full_filename)
fd = file(full_filename, 'ab')
fd = open(full_filename, 'ab')
offset = fd.tell()
else:
sys.stdout.write("Downloading: %s\n" % full_filename)
fd = file(full_filename, 'wb')
fd = open(full_filename, 'wb')
offset = 0
try:
while contents:
@ -6975,7 +7009,7 @@ def anon_handle_download_task(options, session, args):
downloadable_tasks.append(base_task)
else:
subtasks = session.getTaskChildren(base_task_id)
downloadable_tasks.extend(filter(check_downloadable, subtasks))
downloadable_tasks.extend(list(filter(check_downloadable, subtasks)))
# get files for download
@ -7064,7 +7098,7 @@ def anon_handle_wait_repo(options, session, args):
targets = session.getBuildTargets(destTagID=tag_info['id'])
if targets:
maybe = {}.fromkeys([t['build_tag_name'] for t in targets])
maybe = maybe.keys()
maybe = list(maybe.keys())
maybe.sort()
print("Suggested tags: %s" % ', '.join(maybe))
return 1
@ -7321,7 +7355,7 @@ def handle_moshimoshi(options, session, args):
if not u:
print("Not authenticated")
u = {'name' : 'anonymous user'}
print("%s, %s!" % (random.choice(greetings).encode('utf-8'), u["name"]))
print("%s, %s!" % (_printable_unicode(random.choice(greetings)), u["name"]))
print("")
print("You are using the hub at %s" % session.baseurl)
authtype = u.get('authtype', getattr(session, 'authtype', None))
@ -7379,7 +7413,7 @@ def handle_runroot(options, session, args):
kwargs['new_chroot'] = True
task_id = session.runroot(tag, arch, command, **kwargs)
except koji.GenericError, e:
except koji.GenericError as e:
if 'Invalid method' in str(e):
print("* The runroot plugin appears to not be installed on the"
" koji hub. Please contact the administrator.")
@ -7455,7 +7489,7 @@ def handle_save_failed_tree(options, session, args):
try:
task_id = session.saveFailedTree(br_id, opts.full)
except koji.GenericError, e:
except koji.GenericError as e:
m = str(e)
if 'Invalid method' in m:
print(_("* The save_failed_tree plugin appears to not be "
@ -7489,7 +7523,7 @@ def handle_help(options, session, args):
chosen = set(args)
if options.admin:
chosen.add('admin')
avail = set(categories.keys() + ['all'])
avail = set(list(categories.keys()) + ['all'])
unavail = chosen - avail
for arg in unavail:
print("No such help category: %s" % arg)
@ -7502,7 +7536,7 @@ def handle_help(options, session, args):
def list_commands(categories_chosen=None):
if categories_chosen is None or "all" in categories_chosen:
categories_chosen = categories.keys()
categories_chosen = list(categories.keys())
else:
# copy list since we're about to modify it
categories_chosen = list(categories_chosen)
@ -7570,9 +7604,9 @@ def activate_session(session):
session.krb_login(principal=options.principal, keytab=options.keytab, proxyuser=options.runas)
else:
session.krb_login(proxyuser=options.runas)
except socket.error, e:
except socket.error as e:
warn(_("Could not connect to Kerberos authentication service: %s") % e.args[1])
except Exception, e:
except Exception as e:
if krbV is not None and isinstance(e, krbV.Krb5Error):
error(_("Kerberos authentication failed: %s (%s)") % (e.args[1], e.args[0]))
else:

View file

@ -667,8 +667,8 @@ You will need to install the following packages to actually run the tests.
* ``python-krbV``
* ``python-mock``
* ``python-simplejson``
* ``python-urlgrabber``
* ``python-psycopg2``
* ``python-pycurl``
* ``python-requests``
* ``python-qpid-proton``

View file

@ -9884,7 +9884,7 @@ class RootExports(object):
headers = koji.get_header_fields(rpm_path, headers)
for key, value in headers.items():
if isinstance(value, basestring):
if isinstance(value, six.string_types):
headers[key] = koji.fixEncoding(value, remove_nonprintable=True)
return headers

View file

@ -1,4 +1,21 @@
%{!?python_sitelib: %define python_sitelib %(%{__python} -c "from %distutils.sysconfig import get_python_lib; print(get_python_lib())")}
# Enable Python 3 builds for Fedora + EPEL >5
# NOTE: do **NOT** change 'epel' to 'rhel' here, as this spec is also
%if 0%{?fedora} || 0%{?epel} > 5
%bcond_without python3
# If the definition isn't available for python3_pkgversion, define it
%{?!python3_pkgversion:%global python3_pkgversion 3}
%else
%bcond_with python3
%endif
# Compatibility with RHEL. These macros have been added to EPEL but
# not yet to RHEL proper.
# https://bugzilla.redhat.com/show_bug.cgi?id=1307190
%{!?__python2: %global __python2 /usr/bin/python2}
%{!?python2_sitelib: %global python2_sitelib %(%{__python2} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")}
%{!?python2_sitearch: %global python2_sitearch %(%{__python2} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")}
%{!?py2_build: %global py2_build %{expand: CFLAGS="%{optflags}" %{__python2} setup.py %{?py_setup_args} build --executable="%{__python2} -s"}}
%{!?py2_install: %global py2_install %{expand: CFLAGS="%{optflags}" %{__python2} setup.py %{?py_setup_args} install -O1 --skip-build --root %{buildroot}}}
%if 0%{?fedora} >= 21 || 0%{?redhat} >= 7
%global use_systemd 1
@ -25,26 +42,57 @@ URL: https://pagure.io/koji
Source: https://releases.pagure.org/koji/koji-%{version}.tar.bz2
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildArch: noarch
Requires: python-krbV >= 1.0.13
Requires: rpm-python
Requires: pyOpenSSL
Requires: python-requests
Requires: python-requests-kerberos
Requires: python-urlgrabber
Requires: python-dateutil
BuildRequires: python
%if 0%{with python3}
Requires: python3-%{name} = %{version}-%{release}
Requires: python3-pycurl
Requires: python3-libcomps
%else
Requires: python2-%{name} = %{version}-%{release}
Requires: python2-pycurl
%if 0%{?fedora} || 0%{?rhel} >= 7
Requires: python2-libcomps
%endif
%endif
%if %{use_systemd}
BuildRequires: systemd
BuildRequires: pkgconfig
%endif
%if 0%{?fedora} || 0%{?rhel} >= 7
Requires: python-libcomps
%endif
%description
Koji is a system for building and tracking RPMS. The base package
contains shared libraries and the command-line interface.
%package -n python2-%{name}
Summary: Build system tools python library
%{?python_provide:%python_provide python2-%{name}}
BuildRequires: python2-devel
Requires: python-krbV >= 1.0.13
Requires: rpm-python
Requires: pyOpenSSL
Requires: python-requests
Requires: python-requests-kerberos
Requires: python-dateutil
Requires: python-six
%description -n python2-%{name}
desc
%if 0%{with python3}
%package -n python3-%{name}
Summary: Build system tools python library
%{?python_provide:%python_provide python3-%{name}}
BuildRequires: python3-devel
Requires: python3-rpm
Requires: python3-pyOpenSSL
Requires: python3-requests
Requires: python3-requests-kerberos
Requires: python3-dateutil
Requires: python3-six
%description -n python3-%{name}
desc
%endif
%package hub
Summary: Koji XMLRPC interface
Group: Applications/Internet
@ -189,6 +237,12 @@ koji-web is a web UI to the Koji system.
%install
rm -rf $RPM_BUILD_ROOT
make DESTDIR=$RPM_BUILD_ROOT %{?install_opt} install
%if 0%{with python3}
cd koji
make DESTDIR=$RPM_BUILD_ROOT PYTHON=python3 %{?install_opt} install
# alter python interpreter in koji CLI
sed -i 's/\#\!\/usr\/bin\/python/\#\!\/usr\/bin\/python3/' $RPM_BUILD_ROOT/usr/bin/koji
%endif
%clean
rm -rf $RPM_BUILD_ROOT
@ -196,11 +250,19 @@ rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
%{_bindir}/*
%{python_sitelib}/%{name}
%config(noreplace) /etc/koji.conf
%dir /etc/koji.conf.d
%doc docs Authors COPYING LGPL
%files -n python2-%{name}
%defattr(-,root,root)
%{python2_sitelib}/%{name}
%if 0%{with python3}
%files -n python3-koji
%{python3_sitelib}/%{name}
%endif
%files hub
%defattr(-,root,root)
%{_datadir}/koji-hub

View file

@ -1,9 +1,15 @@
SUBDIRS = ssl
PYTHON=python
PACKAGE = $(shell basename `pwd`)
PYFILES = $(wildcard *.py)
PYSCRIPTS = context.py
ifeq ($(PYTHON), python3)
# for python3 we fully support only basic library + CLI
PYFILES = __init__.py util.py
PYSCRIPTS =
SUBDIRS =
else
PYFILES = $(wildcard *.py)
PYSCRIPTS = context.py
SUBDIRS = ssl
endif
PYVER := $(shell $(PYTHON) -c 'import sys; print("%.3s" % (sys.version))')
PYSYSDIR := $(shell $(PYTHON) -c 'import sys; print(sys.prefix)')
PYLIBDIR = $(PYSYSDIR)/lib/python$(PYVER)

View file

@ -21,19 +21,23 @@
# Mike McLean <mikem@redhat.com>
# Mike Bonnet <mikeb@redhat.com>
from __future__ import absolute_import
import sys
from six.moves import range
from six.moves import zip
import six
krbV = None
try:
import krbV
except ImportError: # pragma: no cover
sys.stderr.write("Warning: Could not install krbV module. Kerberos support will be disabled.\n")
sys.stderr.flush()
pass
import base64
import datetime
import ConfigParser
import six.moves.configparser
import errno
import exceptions
from fnmatch import fnmatch
import httplib
import six.moves.http_client
import imp
import logging
import logging.handlers
@ -69,15 +73,13 @@ import struct
import tempfile
import time
import traceback
import urllib
import urllib2
import urlparse
import util
from . import util
import warnings
import xmlrpclib
import six.moves.xmlrpc_client
import xml.sax
import xml.sax.handler
from xmlrpclib import loads, dumps, Fault
from six.moves.xmlrpc_client import loads, dumps, Fault
import six.moves.urllib
PROFILE_MODULES = {} # {module_name: module_instance}
@ -87,7 +89,7 @@ def _(args):
## Constants ##
RPM_HEADER_MAGIC = '\x8e\xad\xe8'
RPM_HEADER_MAGIC = six.b('\x8e\xad\xe8')
RPM_TAG_HEADERSIGNATURES = 62
RPM_TAG_FILEDIGESTALGO = 5011
RPM_SIGTAG_PGP = 1002
@ -261,6 +263,8 @@ PRIO_DEFAULT = 20
## BEGIN kojikamid dup
#Exceptions
PythonImportError = ImportError # will be masked by koji's one
class GenericError(Exception):
"""Base class for our custom exceptions"""
faultCode = 1000
@ -408,7 +412,7 @@ def listFaults():
info['name'] = n
info['desc'] = getattr(v, '__doc__', None)
ret.append(info)
ret.sort(lambda a, b: cmp(a['faultCode'], b['faultCode']))
ret.sort(key=lambda x: x['faultCode'])
return ret
#functions for encoding/decoding optional arguments
@ -444,7 +448,7 @@ def decode_args2(args, names, strict=True):
args, opts = decode_args(*args)
if strict and len(names) < len(args):
raise TypeError("Expecting at most %i arguments" % len(names))
ret = dict(zip(names, args))
ret = dict(list(zip(names, args)))
ret.update(opts)
return ret
@ -460,7 +464,7 @@ def encode_int(n):
def decode_int(n):
"""If n is not an integer, attempt to convert it"""
if isinstance(n, (int, long)):
if isinstance(n, six.integer_types):
return n
#else
return int(n)
@ -471,7 +475,7 @@ def safe_xmlrpc_loads(s):
"""Load xmlrpc data from a string, but catch faults"""
try:
return loads(s)
except Fault, f:
except Fault as f:
return f
## BEGIN kojikamid dup
@ -528,7 +532,7 @@ def multibyte(data):
"""Convert a list of bytes to an integer (network byte order)"""
sum = 0
n = len(data)
for i in xrange(n):
for i in range(n):
sum += data[i] << (8 * (n - i - 1))
return sum
@ -547,8 +551,8 @@ def rpm_hdr_size(f, ofs=None):
f = filename or file object
ofs = offset of the header
"""
if isinstance(f, (str, unicode)):
fo = file(f, 'rb')
if isinstance(f, six.string_types):
fo = open(f, 'rb')
else:
fo = f
if ofs != None:
@ -564,7 +568,7 @@ def rpm_hdr_size(f, ofs=None):
# now read two 4-byte integers which tell us
# - # of index entries
# - bytes of data in header
data = [ord(x) for x in fo.read(8)]
data = [_ord(x) for x in fo.read(8)]
il = multibyte(data[0:4])
dl = multibyte(data[4:8])
@ -577,7 +581,7 @@ def rpm_hdr_size(f, ofs=None):
# add eight bytes for section header
hdrsize = hdrsize + 8
if not isinstance(f, (str, unicode)):
if not isinstance(f, six.string_types):
fo.close()
return hdrsize
@ -594,23 +598,23 @@ class RawHeader(object):
def version(self):
#fourth byte is the version
return ord(self.header[3])
return _ord(self.header[3])
def _index(self):
# read two 4-byte integers which tell us
# - # of index entries (each 16 bytes long)
# - bytes of data in header
data = [ord(x) for x in self.header[8:12]]
data = [_ord(x) for x in self.header[8:12]]
il = multibyte(data[:4])
dl = multibyte(data[4:8])
#read the index (starts at offset 16)
index = {}
for i in xrange(il):
for i in range(il):
entry = []
for j in xrange(4):
for j in range(4):
ofs = 16 + i*16 + j*4
data = [ord(x) for x in self.header[ofs:ofs+4]]
data = [_ord(x) for x in self.header[ofs:ofs+4]]
entry.append(multibyte(data))
#print("Tag: %d, Type: %d, Offset: %x, Count: %d" % tuple(entry))
index[entry[0]] = entry
@ -627,11 +631,11 @@ class RawHeader(object):
print("Store at offset %d (%0x)" % (store, store))
#sort entries by offset, dtype
#also rearrange: tag, dtype, offset, count -> offset, dtype, tag, count
order = sorted([(x[2], x[1], x[0], x[3]) for x in self.index.itervalues()])
order = sorted([(x[2], x[1], x[0], x[3]) for x in six.itervalues(self.index)])
next = store
#map some rpmtag codes
tags = {}
for name, code in rpm.__dict__.iteritems():
for name, code in six.iteritems(rpm.__dict__):
if name.startswith('RPMTAG_') and isinstance(code, int):
tags[code] = name[7:].lower()
for entry in order:
@ -653,15 +657,15 @@ class RawHeader(object):
next = pos
elif dtype == 1:
#char
for i in xrange(count):
for i in range(count):
print("Char: %r" % self.header[pos])
pos += 1
next = pos
elif dtype >= 2 and dtype <= 5:
#integer
n = 1 << (dtype - 2)
for i in xrange(count):
data = [ord(x) for x in self.header[pos:pos+n]]
for i in range(count):
data = [_ord(x) for x in self.header[pos:pos+n]]
print("%r" % data)
num = multibyte(data)
print("Int(%d): %d" % (n, num))
@ -669,7 +673,7 @@ class RawHeader(object):
next = pos
elif dtype == 6:
# string (null terminated)
end = self.header.find('\0', pos)
end = self.header.find(six.b('\0'), pos)
print("String(%d): %r" % (end-pos, self.header[pos:end]))
next = end + 1
elif dtype == 7:
@ -677,15 +681,15 @@ class RawHeader(object):
next = pos+count
elif dtype == 8:
# string array
for i in xrange(count):
end = self.header.find('\0', pos)
for i in range(count):
end = self.header.find(six.b('\0'), pos)
print("String(%d): %r" % (end-pos, self.header[pos:end]))
pos = end + 1
next = pos
elif dtype == 9:
# unicode string array
for i in xrange(count):
end = self.header.find('\0', pos)
for i in range(count):
end = self.header.find(six.b('\0'), pos)
print("i18n(%d): %r" % (end-pos, self.header[pos:end]))
pos = end + 1
next = pos
@ -714,7 +718,7 @@ class RawHeader(object):
if dtype >= 2 and dtype <= 5:
n = 1 << (dtype - 2)
# n-byte integer
data = [ord(x) for x in self.header[pos:pos+n]]
data = [_ord(x) for x in self.header[pos:pos+n]]
return multibyte(data)
elif dtype == 6:
# string (null terminated)
@ -738,7 +742,7 @@ class RawHeader(object):
def rip_rpm_sighdr(src):
"""Rip the signature header out of an rpm"""
(start, size) = find_rpm_sighdr(src)
fo = file(src, 'rb')
fo = open(src, 'rb')
fo.seek(start, 0)
sighdr = fo.read(size)
fo.close()
@ -749,15 +753,22 @@ def rip_rpm_hdr(src):
(start, size) = find_rpm_sighdr(src)
start += size
size = rpm_hdr_size(src, start)
fo = file(src, 'rb')
fo = open(src, 'rb')
fo.seek(start, 0)
hdr = fo.read(size)
fo.close()
return hdr
def _ord(s):
# in python2 it is char/str, while in py3 it is already int/bytes
if isinstance(s, int):
return s
else:
return ord(s)
def __parse_packet_header(pgp_packet):
"""Parse pgp_packet header, return tag type and the rest of pgp_packet"""
byte0 = ord(pgp_packet[0])
byte0 = _ord(pgp_packet[0])
if (byte0 & 0x80) == 0:
raise ValueError('Not an OpenPGP packet')
if (byte0 & 0x40) == 0:
@ -771,12 +782,12 @@ def __parse_packet_header(pgp_packet):
length = struct.unpack(fmt, pgp_packet[1:offset])[0]
else:
tag = byte0 & 0x3F
byte1 = ord(pgp_packet[1])
byte1 = _ord(pgp_packet[1])
if byte1 < 192:
length = byte1
offset = 2
elif byte1 < 224:
length = ((byte1 - 192) << 8) + ord(pgp_packet[2]) + 192
length = ((byte1 - 192) << 8) + _ord(pgp_packet[2]) + 192
offset = 3
elif byte1 == 255:
length = struct.unpack('>I', pgp_packet[2:6])[0]
@ -793,17 +804,17 @@ def __subpacket_key_ids(subs):
"""Parse v4 signature subpackets and return a list of issuer key IDs"""
res = []
while len(subs) > 0:
byte0 = ord(subs[0])
byte0 = _ord(subs[0])
if byte0 < 192:
length = byte0
off = 1
elif byte0 < 255:
length = ((byte0 - 192) << 8) + ord(subs[1]) + 192
length = ((byte0 - 192) << 8) + _ord(subs[1]) + 192
off = 2
else:
length = struct.unpack('>I', subs[1:5])[0]
off = 5
if ord(subs[off]) == 16:
if _ord(subs[off]) == 16:
res.append(subs[off+1 : off+length])
subs = subs[off+length:]
return res
@ -813,9 +824,9 @@ def get_sigpacket_key_id(sigpacket):
(tag, sigpacket) = __parse_packet_header(sigpacket)
if tag != 2:
raise ValueError('Not a signature packet')
if ord(sigpacket[0]) == 0x03:
if _ord(sigpacket[0]) == 0x03:
key_id = sigpacket[11:15]
elif ord(sigpacket[0]) == 0x04:
elif _ord(sigpacket[0]) == 0x04:
sub_len = struct.unpack('>H', sigpacket[4:6])[0]
off = 6 + sub_len
key_ids = __subpacket_key_ids(sigpacket[6:off])
@ -828,7 +839,7 @@ def get_sigpacket_key_id(sigpacket):
key_id = key_ids[0][-4:]
else:
raise NotImplementedError(
'Unknown PGP signature packet version %s' % ord(sigpacket[0]))
'Unknown PGP signature packet version %s' % _ord(sigpacket[0]))
return hex_string(key_id)
def get_sighdr_key(sighdr):
@ -848,8 +859,8 @@ def splice_rpm_sighdr(sighdr, src, dst=None, bufsize=8192):
if dst is None:
(fd, dst) = tempfile.mkstemp()
os.close(fd)
src_fo = file(src, 'rb')
dst_fo = file(dst, 'wb')
src_fo = open(src, 'rb')
dst_fo = open(dst, 'wb')
dst_fo.write(src_fo.read(start))
dst_fo.write(sighdr)
src_fo.seek(size, 1)
@ -867,8 +878,8 @@ def get_rpm_header(f, ts=None):
if ts is None:
ts = rpm.TransactionSet()
ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES|rpm._RPMVSF_NODIGESTS)
if isinstance(f, (str, unicode)):
fo = file(f, "r")
if isinstance(f, six.string_types):
fo = open(f, "r")
else:
fo = f
hdr = ts.hdrFromFdno(fo.fileno())
@ -910,8 +921,14 @@ def get_header_field(hdr, name, src_arch=False):
# HACK: workaround for https://bugzilla.redhat.com/show_bug.cgi?id=991329
if result is None:
result = []
elif isinstance(result, (int, long)):
elif isinstance(result, six.integer_types):
result = [result]
if six.PY3 and isinstance(result, bytes):
try:
result = result.decode('utf-8')
except UnicodeDecodeError:
# typically signatures
pass
return result
@ -993,7 +1010,7 @@ def check_NVR(nvr, strict=False):
return False
def _check_NVR(nvr):
if isinstance(nvr, basestring):
if isinstance(nvr, six.string_types):
nvr = parse_NVR(nvr)
if '-' in nvr['version']:
raise GenericError('The "-" character not allowed in version field')
@ -1022,7 +1039,7 @@ def check_NVRA(nvra, strict=False):
def _check_NVRA(nvra):
if isinstance(nvra, basestring):
if isinstance(nvra, six.string_types):
nvra = parse_NVRA(nvra)
if '-' in nvra['version']:
raise GenericError('The "-" character not allowed in version field')
@ -1112,7 +1129,7 @@ def parse_pom(path=None, contents=None):
values = {}
handler = POMHandler(values, fields)
if path:
fd = file(path)
fd = open(path)
contents = fd.read()
fd.close()
@ -1133,7 +1150,7 @@ def parse_pom(path=None, contents=None):
xml.sax.parseString(contents, handler)
for field in fields:
if field not in values.keys():
if field not in list(values.keys()):
raise GenericError('could not extract %s from POM: %s' % (field, (path or '<contents>')))
return values
@ -1174,7 +1191,7 @@ def mavenLabel(maveninfo):
def hex_string(s):
"""Converts a string to a string of hex digits"""
return ''.join(['%02x' % ord(x) for x in s])
return ''.join(['%02x' % _ord(x) for x in s])
def make_groups_spec(grplist, name='buildsys-build', buildgroup=None):
@ -1214,7 +1231,7 @@ BuildArch: noarch
continue
data.append("#Group: %s\n" % group_name)
pkglist = list(group['packagelist'])
pkglist.sort(lambda a, b: cmp(a['package'], b['package']))
pkglist.sort(key=lambda x: x['package'])
for pkg in pkglist:
pkg_name = pkg['package']
if pkg_name in seen_pkg:
@ -1256,7 +1273,7 @@ def generate_comps(groups, expand_groups=False):
"""]
groups = list(groups)
group_idx = dict([(g['name'], g) for g in groups])
groups.sort(lambda a, b: cmp(a['name'], b['name']))
groups.sort(key=lambda x: x['name'])
for g in groups:
group_id = g['name']
name = g['display_name']
@ -1283,7 +1300,7 @@ def generate_comps(groups, expand_groups=False):
""" <grouplist>
""")
grouplist = list(g['grouplist'])
grouplist.sort(lambda a, b: cmp(a['name'], b['name']))
grouplist.sort(key=lambda x: x['name'])
for x in grouplist:
#['req_id','type','is_metapkg','name']
name = x['name']
@ -1319,7 +1336,7 @@ def generate_comps(groups, expand_groups=False):
""")
if g['packagelist']:
packagelist = list(g['packagelist'])
packagelist.sort(lambda a, b: cmp(a['package'], b['package']))
packagelist.sort(key=lambda x: x['package'])
for p in packagelist:
data.append(
""" %s
@ -1346,7 +1363,7 @@ def generate_comps(groups, expand_groups=False):
""" <!-- Expanding Group: %s -->
""" % group_name)
pkglist = list(group['packagelist'])
pkglist.sort(lambda a, b: cmp(a['package'], b['package']))
pkglist.sort(key=lambda x: x['package'])
for pkg in pkglist:
pkg_name = pkg['package']
if pkg_name in seen_pkg:
@ -1427,14 +1444,14 @@ def genMockConfig(name, arch, managed=False, repoid=None, tag_name=None, **opts)
if opts.get('use_host_resolv', False) and os.path.exists('/etc/hosts'):
# if we're setting up DNS,
# also copy /etc/hosts from the host
etc_hosts = file('/etc/hosts')
etc_hosts = open('/etc/hosts')
files['etc/hosts'] = etc_hosts.read()
etc_hosts.close()
mavenrc = ''
if opts.get('maven_opts'):
mavenrc = 'export MAVEN_OPTS="%s"\n' % ' '.join(opts['maven_opts'])
if opts.get('maven_envs'):
for name, val in opts['maven_envs'].iteritems():
for name, val in six.iteritems(opts['maven_envs']):
mavenrc += 'export %s="%s"\n' % (name, val)
if mavenrc:
files['etc/mavenrc'] = mavenrc
@ -1497,10 +1514,10 @@ name=build
""" % locals())
parts.append("\n")
for key, value in config_opts.iteritems():
for key, value in six.iteritems(config_opts):
parts.append("config_opts[%r] = %r\n" % (key, value))
parts.append("\n")
for key, value in plugin_conf.iteritems():
for key, value in six.iteritems(plugin_conf):
parts.append("config_opts['plugin_conf'][%r] = %r\n" % (key, value))
parts.append("\n")
@ -1508,14 +1525,14 @@ name=build
# This line is REQUIRED for mock to work if bind_opts defined.
parts.append("config_opts['internal_dev_setup'] = False\n")
for key in bind_opts.keys():
for mnt_src, mnt_dest in bind_opts.get(key).iteritems():
for mnt_src, mnt_dest in six.iteritems(bind_opts.get(key)):
parts.append("config_opts['plugin_conf']['bind_mount_opts'][%r].append((%r, %r))\n" % (key, mnt_src, mnt_dest))
parts.append("\n")
for key, value in macros.iteritems():
for key, value in six.iteritems(macros):
parts.append("config_opts['macros'][%r] = %r\n" % (key, value))
parts.append("\n")
for key, value in files.iteritems():
for key, value in six.iteritems(files):
parts.append("config_opts['files'][%r] = %r\n" % (key, value))
return ''.join(parts)
@ -1561,7 +1578,7 @@ def openRemoteFile(relpath, topurl=None, topdir=None, tempdir=None):
on options"""
if topurl:
url = "%s/%s" % (topurl, relpath)
src = urllib2.urlopen(url)
src = six.moves.urllib.request.urlopen(url)
fo = tempfile.TemporaryFile(dir=tempdir)
shutil.copyfileobj(src, fo)
src.close()
@ -1578,7 +1595,7 @@ def config_directory_contents(dir_name):
configs = []
try:
conf_dir_contents = os.listdir(dir_name)
except OSError, exception:
except OSError as exception:
if exception.errno != errno.ENOENT:
raise
else:
@ -1659,7 +1676,7 @@ def read_config(profile_name, user_config=None):
got_conf = False
for configFile in configs:
f = open(configFile)
config = ConfigParser.ConfigParser()
config = six.moves.configparser.ConfigParser()
config.readfp(f)
f.close()
if config.has_section(profile_name):
@ -1754,7 +1771,7 @@ def get_profile_module(profile_name, config=None):
class PathInfo(object):
# ASCII numbers and upper- and lower-case letter for use in tmpdir()
ASCII_CHARS = [chr(i) for i in range(48, 58) + range(65, 91) + range(97, 123)]
ASCII_CHARS = [chr(i) for i in list(range(48, 58)) + list(range(65, 91)) + list(range(97, 123))]
def __init__(self, topdir=None):
self._topdir = topdir
@ -1942,7 +1959,7 @@ def is_conn_error(e):
return True
# else
return False
if isinstance(e, httplib.BadStatusLine):
if isinstance(e, six.moves.http_client.BadStatusLine):
return True
if requests is not None:
try:
@ -1952,7 +1969,7 @@ def is_conn_error(e):
e2 = getattr(e, 'args', [None])[0]
if isinstance(e2, requests.packages.urllib3.exceptions.ProtocolError):
e3 = getattr(e2, 'args', [None, None])[1]
if isinstance(e3, httplib.BadStatusLine):
if isinstance(e3, six.moves.http_client.BadStatusLine):
return True
if isinstance(e2, socket.error):
# same check as unwrapped socket error
@ -2035,6 +2052,8 @@ class ClientSession(object):
if self.rsession:
self.rsession.close()
if self.opts.get('use_old_ssl', False) or requests is None:
if not six.PY2:
raise GenericError('use_old_ssl is only supported on python2')
import koji.compatrequests
self.rsession = koji.compatrequests.Session()
else:
@ -2086,7 +2105,7 @@ class ClientSession(object):
pass
if not krbV:
raise exceptions.ImportError(
raise PythonImportError(
"Please install python-krbV to use kerberos."
)
@ -2137,7 +2156,7 @@ class ClientSession(object):
# decode and decrypt the login info
sinfo_priv = base64.decodestring(sinfo_enc)
sinfo_str = ac.rd_priv(sinfo_priv)
sinfo = dict(zip(['session-id', 'session-key'], sinfo_str.split()))
sinfo = dict(list(zip(['session-id', 'session-key'], sinfo_str.split())))
if not sinfo:
self.logger.warn('No session info received')
@ -2151,8 +2170,7 @@ class ClientSession(object):
"""Get the Kerberos principal of the server we're connecting
to, based on baseurl."""
uri = urlparse.urlsplit(self.baseurl)
host, port = urllib.splitport(uri[1])
host = six.moves.urllib.parse.urlparse(self.baseurl).hostname
if self.opts.get('krb_rdns', True):
servername = socket.getfqdn(host)
else:
@ -2164,13 +2182,13 @@ class ClientSession(object):
def gssapi_login(self, proxyuser=None):
if not HTTPKerberosAuth:
raise exceptions.ImportError(
raise PythonImportError(
"Please install python-requests-kerberos to use GSSAPI."
)
# force https
old_baseurl = self.baseurl
uri = urlparse.urlsplit(self.baseurl)
uri = six.moves.urllib.parse.urlsplit(self.baseurl)
if uri[0] != 'https':
self.baseurl = 'https://%s%s' % (uri[1], uri[2])
@ -2214,7 +2232,7 @@ class ClientSession(object):
# when API is changed
# force https
uri = urlparse.urlsplit(self.baseurl)
uri = six.moves.urllib.parse.urlsplit(self.baseurl)
if uri[0] != 'https':
self.baseurl = 'https://%s%s' % (uri[1], uri[2])
@ -2289,7 +2307,7 @@ class ClientSession(object):
sinfo = self.sinfo.copy()
sinfo['callnum'] = self.callnum
self.callnum += 1
handler = "%s?%s" % (self.baseurl, urllib.urlencode(sinfo))
handler = "%s?%s" % (self.baseurl, six.moves.urllib.parse.urlencode(sinfo))
elif name == 'sslLogin':
handler = self.baseurl + '/ssllogin'
else:
@ -2308,7 +2326,7 @@ class ClientSession(object):
for i in (0, 1):
try:
return self._sendOneCall(handler, headers, request)
except Exception, e:
except Exception as e:
if i or not is_conn_error(e):
raise
self.logger.debug("Connection Error: %s", e)
@ -2364,7 +2382,7 @@ class ClientSession(object):
return ret
def _read_xmlrpc_response(self, response):
p, u = xmlrpclib.getparser()
p, u = six.moves.xmlrpc_client.getparser()
for chunk in response.iter_content(8192):
if self.opts.get('debug_xmlrpc', False):
print("body: %r" % chunk)
@ -2401,7 +2419,7 @@ class ClientSession(object):
# note that, for logged-in sessions the server should tell us (via a RetryError fault)
# if the call cannot be retried. For non-logged-in sessions, all calls should be read-only
# and hence retryable.
except Fault, fault:
except Fault as fault:
#try to convert the fault to a known exception
err = convertFault(fault)
if isinstance(err, ServerOffline):
@ -2417,7 +2435,7 @@ class ClientSession(object):
except (SystemExit, KeyboardInterrupt):
#(depending on the python version, these may or may not be subclasses of Exception)
raise
except Exception, e:
except Exception as e:
tb_str = ''.join(traceback.format_exception(*sys.exc_info()))
self.new_session()
@ -2490,7 +2508,7 @@ class ClientSession(object):
if name is None:
name = os.path.basename(localfile)
self.logger.debug("Fast upload: %s to %s/%s", localfile, path, name)
fo = file(localfile, 'rb')
fo = open(localfile, 'rb')
ofs = 0
size = os.path.getsize(localfile)
start = time.time()
@ -2560,7 +2578,7 @@ class ClientSession(object):
args['volume'] = volume
size = len(chunk)
self.callnum += 1
handler = "%s?%s" % (self.baseurl, urllib.urlencode(args))
handler = "%s?%s" % (self.baseurl, six.moves.urllib.parse.urlencode(args))
headers = [
('User-Agent', 'koji/1'),
("Content-Type", "application/octet-stream"),
@ -2598,7 +2616,7 @@ class ClientSession(object):
start = time.time()
# XXX - stick in a config or something
retries = 3
fo = file(localfile, "r") #specify bufsize?
fo = open(localfile, "r") #specify bufsize?
totalsize = os.path.getsize(localfile)
ofs = 0
md5sum = md5_constructor()
@ -2695,7 +2713,7 @@ class DBHandler(logging.Handler):
values = []
data = {}
record.message = record.getMessage()
for key, value in self.mapping.iteritems():
for key, value in six.iteritems(self.mapping):
value = str(value)
if value.find("%(asctime)") >= 0:
if self.formatter:
@ -2895,7 +2913,7 @@ def _taskLabel(taskInfo):
return '%s (%s)' % (method, arch)
CONTROL_CHARS = [chr(i) for i in range(32)]
NONPRINTABLE_CHARS = ''.join([c for c in CONTROL_CHARS if c not in '\r\n\t'])
NONPRINTABLE_CHARS = six.b(''.join([c for c in CONTROL_CHARS if c not in '\r\n\t']))
def removeNonprintable(value):
# expects raw-encoded string, not unicode
return value.translate(None, NONPRINTABLE_CHARS)
@ -2907,9 +2925,9 @@ def fixEncoding(value, fallback='iso8859-15', remove_nonprintable=False):
encoded in the 'fallback' charset.
"""
if not value:
return ''
return six.b('')
if isinstance(value, unicode):
if isinstance(value, six.text_type):
# value is already unicode, so just convert it
# to a utf8-encoded str
s = value.encode('utf8')
@ -2943,7 +2961,7 @@ def fixEncodingRecurse(value, fallback='iso8859-15', remove_nonprintable=False):
k = fixEncodingRecurse(k, fallback=fallback, remove_nonprintable=remove_nonprintable)
ret[k] = v
return ret
elif isinstance(value, unicode):
elif isinstance(value, six.text_type):
if remove_nonprintable:
return removeNonprintable(value.encode('utf8'))
else:

View file

@ -19,14 +19,21 @@
# Mike McLean <mikem@redhat.com>
# Mike Bonnet <mikeb@redhat.com>
from __future__ import absolute_import
import socket
import string
import random
import base64
import krbV
try:
import krbV
except ImportError:
krbV = None
import koji
import cgi #for parse_qs
from context import context
from .context import context
from six.moves import range
from six.moves import zip
import six
# 1 - load session if provided
# - check uri for session id
@ -76,7 +83,7 @@ class Session(object):
try:
id = long(args['session-id'][0])
key = args['session-key'][0]
except KeyError, field:
except KeyError as field:
raise koji.AuthError('%s not specified in session args' % field)
try:
callnum = args['callnum'][0]
@ -96,7 +103,7 @@ class Session(object):
'EXTRACT(EPOCH FROM update_time)': 'update_ts',
'user_id': 'user_id',
}
fields, aliases = zip(*fields.items())
fields, aliases = list(zip(*list(fields.items())))
q = """
SELECT %s FROM sessions
WHERE id = %%(id)i
@ -108,7 +115,7 @@ class Session(object):
row = c.fetchone()
if not row:
raise koji.AuthError('Invalid session or bad credentials')
session_data = dict(zip(aliases, row))
session_data = dict(list(zip(aliases, row)))
#check for expiration
if session_data['expired']:
raise koji.AuthExpired('session "%i" has expired' % id)
@ -146,7 +153,7 @@ class Session(object):
fields = ('name', 'status', 'usertype')
q = """SELECT %s FROM users WHERE id=%%(user_id)s""" % ','.join(fields)
c.execute(q, session_data)
user_data = dict(zip(fields, c.fetchone()))
user_data = dict(list(zip(fields, c.fetchone())))
if user_data['status'] != koji.USER_STATUS['NORMAL']:
raise koji.AuthError('logins by %s are not allowed' % user_data['name'])
@ -297,6 +304,10 @@ class Session(object):
if self.logged_in:
raise koji.AuthError("Already logged in")
if krbV is None:
# python3 is not supported
raise koji.AuthError("krbV module not installed")
if not (context.opts.get('AuthPrincipal') and context.opts.get('AuthKeytab')):
raise koji.AuthError('not configured for Kerberos authentication')
@ -525,7 +536,7 @@ class Session(object):
def getPerms(self):
if not self.logged_in:
return []
return self.perms.keys()
return list(self.perms.keys())
def hasPerm(self, name):
if not self.logged_in:
@ -697,7 +708,7 @@ def get_user_data(user_id):
row = c.fetchone()
if not row:
return None
return dict(zip(fields, row))
return dict(list(zip(fields, row)))
def login(*args, **opts):
return context.session.login(*args, **opts)
@ -738,7 +749,7 @@ if __name__ == '__main__':
print("logging in with session 1")
session_info = sess.login('host/1', 'foobar', {'hostip':'127.0.0.1'})
#wrap values in lists
session_info = dict([[k, [v]] for k, v in session_info.iteritems()])
session_info = dict([[k, [v]] for k, v in six.iteritems(session_info)])
print("Session 1: %s" % sess)
print("Session 1 info: %r" % session_info)
print("Creating session 2")

View file

@ -26,11 +26,11 @@ import os
import logging
import xmlrpclib
import signal
import urllib2
import shutil
import random
import time
import pprint
import six.moves.urllib.request
def scan_mounts(topdir):
"""Search path for mountpoints"""
@ -309,7 +309,7 @@ class BaseTaskHandler(object):
return fn
self.logger.debug("Downloading %s", relpath)
url = "%s/%s" % (self.options.topurl, relpath)
fsrc = urllib2.urlopen(url)
fsrc = six.moves.urllib.request.urlopen(url)
if not os.path.exists(os.path.dirname(fn)):
os.makedirs(os.path.dirname(fn))
fdst = file(fn, 'w')

View file

@ -18,6 +18,7 @@
# Mike McLean <mikem@redhat.com>
# Mike Bonnet <mikeb@redhat.com>
from __future__ import absolute_import
import calendar
from fnmatch import fnmatch
import koji
@ -30,8 +31,10 @@ import shutil
import stat
import sys
import time
import ConfigParser
import six.moves.configparser
from zlib import adler32
from six.moves import range
import six
# imported from kojiweb and kojihub
try:
@ -124,7 +127,7 @@ def multi_fnmatch(s, patterns):
If patterns is a string, it will be split() first
"""
if isinstance(patterns, basestring):
if isinstance(patterns, six.string_types):
patterns = patterns.split()
for pat in patterns:
if fnmatch(s, pat):
@ -154,7 +157,7 @@ def call_with_argcheck(func, args, kwargs=None):
kwargs = {}
try:
return func(*args, **kwargs)
except TypeError, e:
except TypeError as e:
if sys.exc_info()[2].tb_next is None:
# The stack is only one high, so the error occurred in this function.
# Therefore, we assume the TypeError is due to a parameter mismatch
@ -238,11 +241,11 @@ class LazyDict(dict):
return [(key, lazy_eval(val)) for key, val in super(LazyDict, self).items()]
def itervalues(self):
for val in super(LazyDict, self).itervalues():
for val in six.itervalues(super(LazyDict, self)):
yield lazy_eval(val)
def iteritems(self):
for key, val in super(LazyDict, self).iteritems():
for key, val in six.iteritems(super(LazyDict, self)):
yield key, lazy_eval(val)
def pop(self, key, *args, **kwargs):
@ -457,19 +460,23 @@ def setup_rlimits(opts, logger=None):
logger.warn('Setting resource limit: %s = %r', key, limits)
try:
resource.setrlimit(rcode, tuple(limits))
except ValueError, e:
except ValueError as e:
logger.error("Unable to set %s: %s", key, e)
class adler32_constructor(object):
#mimicing the hashlib constructors
def __init__(self, arg=''):
self._value = adler32(arg) & 0xffffffffL
if six.PY3 and isinstance(arg, str):
arg = bytes(arg, 'utf-8')
self._value = adler32(arg) & 0xffffffff
#the bitwise and works around a bug in some versions of python
#see: https://bugs.python.org/issue1202
def update(self, arg):
self._value = adler32(arg, self._value) & 0xffffffffL
if six.PY3 and isinstance(arg, str):
arg = bytes(arg, 'utf-8')
self._value = adler32(arg, self._value) & 0xffffffff
def digest(self):
return self._value
@ -496,11 +503,11 @@ def tsort(parts):
parts = parts.copy()
result = []
while True:
level = set([name for name, deps in parts.iteritems() if not deps])
level = set([name for name, deps in six.iteritems(parts) if not deps])
if not level:
break
result.append(level)
parts = dict([(name, deps - level) for name, deps in parts.iteritems()
parts = dict([(name, deps - level) for name, deps in six.iteritems(parts)
if name not in level])
if parts:
raise ValueError('total ordering not possible')
@ -586,9 +593,9 @@ def parse_maven_params(confs, chain=False, scratch=False):
"""
if not isinstance(confs, (list, tuple)):
confs = [confs]
config = ConfigParser.ConfigParser()
config = six.moves.configparser.ConfigParser()
for conf in confs:
conf_fd = file(conf)
conf_fd = open(conf)
config.readfp(conf_fd)
conf_fd.close()
builds = {}

View file

@ -1,3 +1,4 @@
from __future__ import absolute_import
import os
import sys

View file

@ -1,12 +1,12 @@
from __future__ import absolute_import
import unittest
import os
import sys
import mock
import rpm
import tempfile
import koji
from loadkojid import kojid
from .loadkojid import kojid
from six.moves import range
class FakeHeader(dict):

File diff suppressed because it is too large Load diff

View file

@ -1,39 +1,39 @@
Group: additional-devel (Additional Development)
Package: alsa-lib-devel: {'type': 'default', 'basearchonly': False}
Package: audit-libs-devel: {'type': 'default', 'basearchonly': False}
Package: binutils-devel: {'type': 'default', 'basearchonly': False}
Package: boost-devel: {'type': 'default', 'basearchonly': False}
Package: bzip2-devel: {'type': 'default', 'basearchonly': False}
Package: cyrus-sasl-devel: {'type': 'default', 'basearchonly': False}
Package: alsa-lib-devel: {'basearchonly': False, 'type': 'default'}
Package: audit-libs-devel: {'basearchonly': False, 'type': 'default'}
Package: binutils-devel: {'basearchonly': False, 'type': 'default'}
Package: boost-devel: {'basearchonly': False, 'type': 'default'}
Package: bzip2-devel: {'basearchonly': False, 'type': 'default'}
Package: cyrus-sasl-devel: {'basearchonly': False, 'type': 'default'}
Group: backup-client (Backup Client)
Package: amanda-client: {'type': 'mandatory', 'basearchonly': False}
Package: bacula-client: {'type': 'optional', 'basearchonly': False}
Package: amanda-client: {'basearchonly': False, 'type': 'mandatory'}
Package: bacula-client: {'basearchonly': False, 'type': 'optional'}
Group: backup-server (Backup Server)
Package: amanda-server: {'type': 'mandatory', 'basearchonly': False}
Package: mt-st: {'type': 'optional', 'basearchonly': False}
Package: mtx: {'type': 'optional', 'basearchonly': False}
Package: amanda-server: {'basearchonly': False, 'type': 'mandatory'}
Package: mt-st: {'basearchonly': False, 'type': 'optional'}
Package: mtx: {'basearchonly': False, 'type': 'optional'}
Group: ansible-node (Ansible node)
Package: python2-dnf: {'type': 'mandatory', 'basearchonly': False}
Package: libselinux-python: {'requires': u'selinux-policy', 'type': 'conditional', 'basearchonly': False}
Package: python2-dnf: {'basearchonly': False, 'type': 'mandatory'}
Package: libselinux-python: {'basearchonly': False, 'requires': 'selinux-policy', 'type': 'conditional'}
Group: d-development (D Development Tools and Libraries)
Package: ldc: {'type': 'mandatory', 'basearchonly': True}
Package: ldc-druntime: {'type': 'mandatory', 'basearchonly': True}
Package: ldc-druntime-devel: {'type': 'mandatory', 'basearchonly': True}
Package: ldc-phobos-devel: {'type': 'mandatory', 'basearchonly': True}
Package: make: {'type': 'mandatory', 'basearchonly': False}
Package: pkgconfig: {'type': 'mandatory', 'basearchonly': False}
Package: ctags: {'type': 'default', 'basearchonly': False}
Package: indent: {'type': 'default', 'basearchonly': False}
Package: astyle: {'type': 'optional', 'basearchonly': False}
Package: cmake: {'type': 'optional', 'basearchonly': False}
Package: derelict-devel: {'type': 'optional', 'basearchonly': False}
Package: geany: {'type': 'optional', 'basearchonly': False}
Package: gl3n-devel: {'type': 'optional', 'basearchonly': False}
Package: insight: {'type': 'optional', 'basearchonly': False}
Package: nemiver: {'type': 'optional', 'basearchonly': False}
Package: uncrustify: {'type': 'optional', 'basearchonly': False}
Package: ldc: {'basearchonly': True, 'type': 'mandatory'}
Package: ldc-druntime: {'basearchonly': True, 'type': 'mandatory'}
Package: ldc-druntime-devel: {'basearchonly': True, 'type': 'mandatory'}
Package: ldc-phobos-devel: {'basearchonly': True, 'type': 'mandatory'}
Package: make: {'basearchonly': False, 'type': 'mandatory'}
Package: pkgconfig: {'basearchonly': False, 'type': 'mandatory'}
Package: ctags: {'basearchonly': False, 'type': 'default'}
Package: indent: {'basearchonly': False, 'type': 'default'}
Package: astyle: {'basearchonly': False, 'type': 'optional'}
Package: cmake: {'basearchonly': False, 'type': 'optional'}
Package: derelict-devel: {'basearchonly': False, 'type': 'optional'}
Package: geany: {'basearchonly': False, 'type': 'optional'}
Package: gl3n-devel: {'basearchonly': False, 'type': 'optional'}
Package: insight: {'basearchonly': False, 'type': 'optional'}
Package: nemiver: {'basearchonly': False, 'type': 'optional'}
Package: uncrustify: {'basearchonly': False, 'type': 'optional'}
Group: empty-group-1 (empty group 1)
Group: empty-group-2 (empty group 2)
Group: unknown-group (unknown group)
Package: unknown: {'type': 'unknown', 'basearchonly': False}
Package: unknown2: {'type': 'unknown', 'basearchonly': False}
Package: unknown: {'basearchonly': False, 'type': 'unknown'}
Package: unknown2: {'basearchonly': False, 'type': 'unknown'}

View file

@ -1,3 +1,4 @@
from __future__ import absolute_import
import os
import sys
@ -5,11 +6,14 @@ import sys
# koji module, or the koji cli module. Jump through hoops accordingly.
# https://stackoverflow.com/questions/67631/how-to-import-a-module-given-the-full-path
CLI_FILENAME = os.path.dirname(__file__) + "/../../cli/koji"
'''
if sys.version_info[0] >= 3:
import importlib.util
spec = importlib.util.spec_from_file_location("koji_cli", CLI_FILENAME)
cli = importlib.util.module_from_spec(spec)
spec.loader.exec_module(cli)
else:
import imp
cli = imp.load_source('koji_cli', CLI_FILENAME)
'''
import imp
cli = imp.load_source('koji_cli', CLI_FILENAME)

View file

@ -1,14 +1,15 @@
from __future__ import absolute_import
import unittest
import StringIO as stringio
import os
import sys
import mock
import six
import loadcli
from . import loadcli
cli = loadcli.cli
@ -18,7 +19,7 @@ class TestAddGroup(unittest.TestCase):
# Show long diffs in error output...
maxDiff = None
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_add_group(self, activate_session_mock, stdout):
tag = 'tag'
@ -47,7 +48,7 @@ class TestAddGroup(unittest.TestCase):
session.groupListAdd.assert_called_once_with(tag, group)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_add_group_dupl(self, activate_session_mock, stdout):
tag = 'tag'
@ -76,8 +77,8 @@ class TestAddGroup(unittest.TestCase):
session.groupListAdd.assert_not_called()
self.assertEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_add_group_help(
self,
@ -113,7 +114,7 @@ class TestAddGroup(unittest.TestCase):
session.groupListAdd.assert_not_called()
self.assertEqual(cm.exception.code, 2)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_add_group_no_perm(self, activate_session_mock, stdout):
tag = 'tag'
@ -139,7 +140,7 @@ class TestAddGroup(unittest.TestCase):
session.groupListAdd.assert_not_called()
self.assertEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_add_group_no_tag(self, activate_session_mock, stdout):
tag = 'tag'

View file

@ -1,14 +1,12 @@
from __future__ import absolute_import
import unittest
import StringIO as stringio
import os
import sys
import mock
import six
import loadcli
from . import loadcli
cli = loadcli.cli
@ -18,7 +16,7 @@ class TestAddHost(unittest.TestCase):
# Show long diffs in error output...
maxDiff = None
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_add_host(self, activate_session_mock, stdout):
host = 'host'
@ -48,7 +46,7 @@ class TestAddHost(unittest.TestCase):
session.addHost.assert_called_once_with(host, arches, **kwargs)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_add_host_no_krb_principal(
self, activate_session_mock, stdout):
@ -75,7 +73,7 @@ class TestAddHost(unittest.TestCase):
session.addHost.assert_called_once_with(host, arches)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_add_host_dupl(self, activate_session_mock, stdout):
host = 'host'
@ -102,8 +100,8 @@ class TestAddHost(unittest.TestCase):
session.addHost.assert_not_called()
self.assertEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_add_host_help(self, activate_session_mock, stderr, stdout):
arguments = []
@ -133,7 +131,7 @@ class TestAddHost(unittest.TestCase):
session.addHost.assert_not_called()
self.assertEqual(cm.exception.code, 2)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_add_host_failed(self, activate_session_mock, stdout):
host = 'host'

View file

@ -1,14 +1,12 @@
from __future__ import absolute_import
import unittest
import StringIO as stringio
import os
import sys
import mock
import six
import loadcli
from . import loadcli
cli = loadcli.cli
@ -18,7 +16,7 @@ class TestAddHostToChannel(unittest.TestCase):
# Show long diffs in error output...
maxDiff = None
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_add_host_to_channel(self, activate_session_mock, stdout):
host = 'host'
@ -47,7 +45,7 @@ class TestAddHostToChannel(unittest.TestCase):
session.addHostToChannel.assert_called_once_with(host, channel)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_add_host_to_channel_list(
self, activate_session_mock, stdout):
@ -75,7 +73,7 @@ class TestAddHostToChannel(unittest.TestCase):
session.addHostToChannel.assert_not_called()
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_add_host_to_channel_new(
self, activate_session_mock, stdout):
@ -106,7 +104,7 @@ class TestAddHostToChannel(unittest.TestCase):
host, channel, **kwargs)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_add_host_to_channel_no_channel(
self, activate_session_mock, stdout):
@ -134,7 +132,7 @@ class TestAddHostToChannel(unittest.TestCase):
session.addHostToChannel.assert_not_called()
self.assertEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_add_host_to_channel_no_host(
self, activate_session_mock, stdout):
@ -164,8 +162,8 @@ class TestAddHostToChannel(unittest.TestCase):
session.addHostToChannel.assert_not_called()
self.assertEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_add_host_to_channel_help(
self, activate_session_mock, stderr, stdout):

View file

@ -1,17 +1,14 @@
from __future__ import absolute_import
import unittest
import StringIO as stringio
import os
import sys
import mock
import six
from mock import call
import loadcli
from . import loadcli
cli = loadcli.cli
@ -21,7 +18,7 @@ class TestAddPkg(unittest.TestCase):
# Show long diffs in error output...
maxDiff = None
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_add_pkg(self, activate_session_mock, stdout):
tag = 'tag'
@ -66,7 +63,7 @@ class TestAddPkg(unittest.TestCase):
session.multiCall.assert_called_once_with(strict=True)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_add_pkg_multi_pkg(self, activate_session_mock, stdout):
tag = 'tag'
@ -110,7 +107,7 @@ class TestAddPkg(unittest.TestCase):
call.multiCall(strict=True)])
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_add_pkg_owner_no_exists(
self, activate_session_mock, stdout):
@ -143,7 +140,7 @@ class TestAddPkg(unittest.TestCase):
[call.getUser(owner)])
self.assertEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_add_pkg_tag_no_exists(self, activate_session_mock, stdout):
tag = 'tag'
@ -179,8 +176,8 @@ class TestAddPkg(unittest.TestCase):
call.getTag(tag)])
self.assertEqual(cm.exception.code, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_add_pkg_no_owner(
self, activate_session_mock, stderr, stdout):
@ -217,8 +214,8 @@ class TestAddPkg(unittest.TestCase):
session.packageListAdd.assert_not_called()
self.assertEqual(cm.exception.code, 2)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_add_pkg_no_arg(
self, activate_session_mock, stderr, stdout):

View file

@ -1,17 +1,14 @@
from __future__ import absolute_import
import unittest
import StringIO as stringio
import os
import sys
import mock
import six
from mock import call
import loadcli
from . import loadcli
cli = loadcli.cli
@ -21,7 +18,7 @@ class TestBlockPkg(unittest.TestCase):
# Show long diffs in error output...
maxDiff = None
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_block_pkg(self, activate_session_mock, stdout):
tag = 'tag'
@ -53,7 +50,7 @@ class TestBlockPkg(unittest.TestCase):
session.multiCall.assert_called_once_with(strict=True)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_block_pkg_multi_pkg(self, activate_session_mock, stdout):
tag = 'tag'
@ -91,7 +88,7 @@ class TestBlockPkg(unittest.TestCase):
strict=True)])
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_block_pkg_no_package(self, activate_session_mock, stdout):
tag = 'tag'
@ -124,7 +121,7 @@ class TestBlockPkg(unittest.TestCase):
session.multiCall.assert_not_called()
self.assertEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_block_pkg_tag_no_exists(
self, activate_session_mock, stdout):
@ -152,8 +149,8 @@ class TestBlockPkg(unittest.TestCase):
session.packageListBlock.assert_not_called()
self.assertEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_block_pkg_help(
self, activate_session_mock, stderr, stdout):

View file

@ -1,14 +1,12 @@
from __future__ import absolute_import
import unittest
import StringIO as stringio
import os
import sys
import mock
import six
import loadcli
from . import loadcli
cli = loadcli.cli
@ -25,7 +23,7 @@ class TestBuild(unittest.TestCase):
# Mock out the xmlrpc server
self.session = mock.MagicMock()
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._unique_path', return_value='random_path')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@ -76,7 +74,7 @@ Task info: weburl/taskinfo?taskID=1
self.session, [task_id], quiet=self.options.quiet)
self.assertEqual(rv, 0)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._unique_path', return_value='random_path')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@ -124,8 +122,8 @@ Task info: weburl/taskinfo?taskID=1
self.session, [task_id], quiet=self.options.quiet)
self.assertEqual(rv, 0)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._unique_path', return_value='random_path')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@ -167,8 +165,8 @@ Task info: weburl/taskinfo?taskID=1
watch_tasks_mock.assert_not_called()
self.assertEqual(cm.exception.code, 2)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._unique_path', return_value='random_path')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@ -221,8 +219,8 @@ Options:
watch_tasks_mock.assert_not_called()
self.assertEqual(cm.exception.code, 0)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._unique_path', return_value='random_path')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@ -267,7 +265,7 @@ Options:
watch_tasks_mock.assert_not_called()
self.assertEqual(cm.exception.code, 2)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._unique_path', return_value='random_path')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@ -312,7 +310,7 @@ Task info: weburl/taskinfo?taskID=1
self.session, [task_id], quiet=self.options.quiet)
self.assertEqual(rv, 0)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._unique_path', return_value='random_path')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@ -356,7 +354,7 @@ Task info: weburl/taskinfo?taskID=1
watch_tasks_mock.assert_not_called()
self.assertEqual(cm.exception.code, 2)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._unique_path', return_value='random_path')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@ -404,7 +402,7 @@ Task info: weburl/taskinfo?taskID=1
watch_tasks_mock.assert_not_called()
self.assertEqual(cm.exception.code, 2)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._unique_path', return_value='random_path')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@ -452,7 +450,7 @@ Task info: weburl/taskinfo?taskID=1
watch_tasks_mock.assert_not_called()
self.assertEqual(cm.exception.code, 2)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._unique_path', return_value='random_path')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@ -507,7 +505,7 @@ Task info: weburl/taskinfo?taskID=1
self.session, [task_id], quiet=self.options.quiet)
self.assertEqual(rv, 0)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._unique_path', return_value='random_path')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@ -555,7 +553,7 @@ Task info: weburl/taskinfo?taskID=1
self.session, [task_id], quiet=self.options.quiet)
self.assertEqual(rv, 0)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._unique_path', return_value='random_path')
@mock.patch('koji_cli._running_in_bg', return_value=True)
@ -606,7 +604,7 @@ Task info: weburl/taskinfo?taskID=1
watch_tasks_mock.assert_not_called()
self.assertIsNone(rv)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._unique_path', return_value='random_path')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@ -658,7 +656,7 @@ Task info: weburl/taskinfo?taskID=1
self.session, [task_id], quiet=self.options.quiet)
self.assertEqual(rv, 0)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._unique_path', return_value='random_path')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@ -707,7 +705,7 @@ Task info: weburl/taskinfo?taskID=1
self.session, [task_id], quiet=quiet)
self.assertEqual(rv, 0)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._unique_path', return_value='random_path')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@ -760,7 +758,7 @@ Task info: weburl/taskinfo?taskID=1
self.session, [task_id], quiet=self.options.quiet)
self.assertEqual(rv, 0)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._unique_path', return_value='random_path')
@mock.patch('koji_cli._running_in_bg', return_value=False)

View file

@ -1,14 +1,12 @@
from __future__ import absolute_import
import unittest
import StringIO as stringio
import os
import sys
import mock
import six
import loadcli
from . import loadcli
cli = loadcli.cli
@ -25,7 +23,7 @@ class TestChainBuild(unittest.TestCase):
# Mock out the xmlrpc server
self.session = mock.MagicMock()
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@mock.patch('koji_cli.watch_tasks', return_value=0)
@ -84,8 +82,8 @@ Task info: weburl/taskinfo?taskID=1
self.session, [task_id], quiet=self.options.quiet)
self.assertEqual(rv, 0)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@mock.patch('koji_cli.watch_tasks', return_value=0)
@ -124,8 +122,8 @@ Task info: weburl/taskinfo?taskID=1
watch_tasks_mock.assert_not_called()
self.assertEqual(cm.exception.code, 2)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@mock.patch('koji_cli.watch_tasks', return_value=0)
@ -168,7 +166,7 @@ Options:
watch_tasks_mock.assert_not_called()
self.assertEqual(cm.exception.code, 0)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@mock.patch('koji_cli.watch_tasks', return_value=0)
@ -217,7 +215,7 @@ Options:
watch_tasks_mock.assert_not_called()
self.assertEqual(cm.exception.code, 2)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@mock.patch('koji_cli.watch_tasks', return_value=0)
@ -276,7 +274,7 @@ Options:
watch_tasks_mock.assert_not_called()
self.assertEqual(cm.exception.code, 2)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@mock.patch('koji_cli.watch_tasks', return_value=0)
@ -363,7 +361,7 @@ Target target is not usable for a chain-build
self.session.getBuildTarget.return_value = target_info
self.session.getTag.return_value = dest_tag_info
self.session.getFullInheritance.return_value = tag_tree
with mock.patch('sys.stdout', new_callable=stringio.StringIO) as stdout:
with mock.patch('sys.stdout', new_callable=six.StringIO) as stdout:
# Run it and check immediate output
# args: target badnvr : http://scm2 http://scm3 n-v-r-1 : n-v-r-2 n-v-r-3
# expected: failed, src is neither scm nor good n-v-r
@ -384,7 +382,7 @@ Target target is not usable for a chain-build
watch_tasks_mock.assert_not_called()
self.assertEqual(rv, 1)
with mock.patch('sys.stdout', new_callable=stringio.StringIO) as stdout:
with mock.patch('sys.stdout', new_callable=six.StringIO) as stdout:
source_args = [
'path/n-v-r',
':',
@ -402,7 +400,7 @@ Target target is not usable for a chain-build
expected = '"path/n-v-r" is not a SCM URL or package N-V-R\n'
self.assertMultiLineEqual(actual, expected)
with mock.patch('sys.stdout', new_callable=stringio.StringIO) as stdout:
with mock.patch('sys.stdout', new_callable=six.StringIO) as stdout:
source_args = [
'badn-vr',
':',
@ -420,7 +418,7 @@ Target target is not usable for a chain-build
expected = '"badn-vr" is not a SCM URL or package N-V-R\n'
self.assertMultiLineEqual(actual, expected)
with mock.patch('sys.stdout', new_callable=stringio.StringIO) as stdout:
with mock.patch('sys.stdout', new_callable=six.StringIO) as stdout:
source_args = [
'badn-v-r.rpm',
':',
@ -438,7 +436,7 @@ Target target is not usable for a chain-build
expected = '"badn-v-r.rpm" is not a SCM URL or package N-V-R\n'
self.assertMultiLineEqual(actual, expected)
with mock.patch('sys.stderr', new_callable=stringio.StringIO) as stderr:
with mock.patch('sys.stderr', new_callable=six.StringIO) as stderr:
source_args = ['http://scm']
args = [target] + source_args
@ -458,7 +456,7 @@ If there are no dependencies, use the build command instead
self.assertMultiLineEqual(actual, expected)
self.assertEqual(cm.exception.code, 2)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@mock.patch('koji_cli.watch_tasks', return_value=0)
@ -521,7 +519,7 @@ Task info: weburl/taskinfo?taskID=1
self.session, [task_id], quiet=self.options.quiet)
self.assertEqual(rv, 0)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@mock.patch('koji_cli.watch_tasks', return_value=0)
@ -583,7 +581,7 @@ Task info: weburl/taskinfo?taskID=1
self.session, [task_id], quiet=self.options.quiet)
self.assertEqual(rv, 0)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._running_in_bg', return_value=True)
@mock.patch('koji_cli.watch_tasks', return_value=0)
@ -645,7 +643,7 @@ Task info: weburl/taskinfo?taskID=1
watch_tasks_mock.assert_not_called()
self.assertIsNone(rv)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@mock.patch('koji_cli.watch_tasks', return_value=0)

View file

@ -1,16 +1,13 @@
from __future__ import absolute_import
import unittest
import StringIO as stringio
import os
import sys
import mock
import six
from mock import call
import loadcli
from . import loadcli
cli = loadcli.cli
@ -20,7 +17,7 @@ class TestEditHost(unittest.TestCase):
# Show long diffs in error output...
maxDiff = None
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_edit_host(self, activate_session_mock, stdout):
host = 'host'
@ -59,7 +56,7 @@ class TestEditHost(unittest.TestCase):
self.assertEqual(session.multiCall.call_count, 2)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_edit_host_failed(self, activate_session_mock, stdout):
host = 'host'
@ -98,7 +95,7 @@ class TestEditHost(unittest.TestCase):
self.assertEqual(session.multiCall.call_count, 2)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_edit_multi_host(self, activate_session_mock, stdout):
hosts = ['host1', 'host2']
@ -144,8 +141,8 @@ class TestEditHost(unittest.TestCase):
call.multiCall(strict=True)])
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_edit_host_no_arg(
self, activate_session_mock, stderr, stdout):
@ -180,7 +177,7 @@ class TestEditHost(unittest.TestCase):
session.multiCall.assert_not_called()
self.assertEqual(cm.exception.code, 2)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_edit_host_no_host(self, activate_session_mock, stdout):
host = 'host'

View file

@ -1,16 +1,13 @@
from __future__ import absolute_import
import unittest
import StringIO as stringio
import os
import sys
import mock
import six
from mock import call
import loadcli
from . import loadcli
cli = loadcli.cli
@ -21,7 +18,7 @@ class TestEditTag(unittest.TestCase):
# Show long diffs in error output...
maxDiff = None
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_edit_tag(self, activate_session_mock, stdout):
tag = 'tag'
@ -40,7 +37,7 @@ class TestEditTag(unittest.TestCase):
args.append('--rename=' + rename)
args.append('--maven-support')
args.append('--include-all')
for k, x in extra.iteritems():
for k, x in six.iteritems(extra):
args.append('-x')
args.append(k + '=' + str(x))
for r in remove_extra:
@ -98,8 +95,8 @@ class TestEditTag(unittest.TestCase):
session.editTag2.assert_called_once_with(tag, **opts)
self.assertEqual(rv, None)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_edit_tag_help(self, activate_session_mock, stderr, stdout):
args = ['--help']
@ -145,8 +142,8 @@ Options:
session.editTag2.assert_not_called()
self.assertEqual(cm.exception.code, 0)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_edit_tag_no_arg(self, activate_session_mock, stderr, stdout):
args = []

View file

@ -1,10 +1,11 @@
from __future__ import absolute_import
import json
import unittest
import StringIO as stringio
import os
import sys
import mock
import loadcli
import six
from . import loadcli
try:
import libcomps
@ -22,7 +23,7 @@ class TestImportComps(unittest.TestCase):
# Show long diffs in error output...
maxDiff = None
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.libcomps')
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._import_comps')
@ -62,7 +63,7 @@ class TestImportComps(unittest.TestCase):
mock_import_comps_alt.assert_not_called()
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.libcomps', new=None)
@mock.patch('koji_cli.yumcomps', create=True)
@mock.patch('koji_cli.activate_session')
@ -103,7 +104,7 @@ class TestImportComps(unittest.TestCase):
session, filename, tag, local_options)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.libcomps', new=None)
@mock.patch('koji_cli.yumcomps', new=None, create=True)
@mock.patch('koji_cli.activate_session')
@ -140,7 +141,7 @@ class TestImportComps(unittest.TestCase):
mock_import_comps_alt.assert_not_called()
self.assertEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._import_comps')
@mock.patch('koji_cli._import_comps_alt')
@ -175,8 +176,8 @@ class TestImportComps(unittest.TestCase):
mock_import_comps_alt.assert_not_called()
self.assertEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._import_comps')
@mock.patch('koji_cli._import_comps_alt')
@ -215,7 +216,7 @@ class TestImportComps(unittest.TestCase):
self.assertEqual(cm.exception.code, 2)
@unittest.skipIf(libcomps is None, "No libcomps")
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
def test_import_comps_libcomps(self, stdout):
comps_file = os.path.dirname(__file__) + '/data/comps-example.xml'
stdout_file = os.path.dirname(
@ -230,7 +231,7 @@ class TestImportComps(unittest.TestCase):
stdout)
@unittest.skipIf(libcomps is None, "No libcomps")
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
def test_import_comps_sample_libcomps(self, stdout):
comps_file = os.path.dirname(__file__) + '/data/comps-sample.xml'
stdout_file = os.path.dirname(
@ -245,7 +246,7 @@ class TestImportComps(unittest.TestCase):
stdout)
@unittest.skipIf(yumcomps is None, "No yum.comps")
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.libcomps', new=None)
@mock.patch('koji_cli.yumcomps', create=True, new=yumcomps)
def test_import_comps_yumcomps(self, stdout):
@ -262,7 +263,7 @@ class TestImportComps(unittest.TestCase):
stdout)
@unittest.skipIf(yumcomps is None, "No yum.comps")
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.libcomps', new=None)
@mock.patch('koji_cli.yumcomps', create=True, new=yumcomps)
def test_import_comps_sample_yumcomps(self, stdout):

View file

@ -1,12 +1,10 @@
import os
import sys
import unittest
import StringIO as stringio
from __future__ import absolute_import
import mock
import os
import unittest
import six
import loadcli
from . import loadcli
cli = loadcli.cli
@ -26,24 +24,30 @@ class TestListCommands(unittest.TestCase):
# Show long diffs in error output...
maxDiff = None
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
def test_list_commands(self, stdout):
cli.list_commands()
actual = stdout.getvalue()
actual = actual.replace('nosetests', 'koji')
if six.PY2:
actual = actual.replace('nosetests', 'koji')
else:
actual = actual.replace('nosetests-3', 'koji')
filename = os.path.dirname(__file__) + '/data/list-commands.txt'
with open(filename, 'rb') as f:
expected = f.read().decode('ascii')
self.assertMultiLineEqual(actual, expected)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
def test_handle_admin_help(self, stdout):
options, arguments = mock.MagicMock(), mock.MagicMock()
options.admin = True
self.parser.parse_args.return_value = [options, arguments]
cli.handle_help(self.options, self.session, self.args)
actual = stdout.getvalue()
actual = actual.replace('nosetests', 'koji')
if six.PY2:
actual = actual.replace('nosetests', 'koji')
else:
actual = actual.replace('nosetests-3', 'koji')
filename = os.path.dirname(__file__) + '/data/list-commands-admin.txt'
with open(filename, 'rb') as f:
expected = f.read().decode('ascii')

View file

@ -1,14 +1,12 @@
from __future__ import absolute_import
import unittest
import StringIO as stringio
import os
import sys
import mock
import six
import loadcli
from . import loadcli
import optparse
cli = loadcli.cli
@ -45,7 +43,7 @@ class TestMavenBuild(unittest.TestCase):
# Mock out the xmlrpc server
self.session = mock.MagicMock()
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@mock.patch('koji_cli.watch_tasks', return_value=0)
@ -86,8 +84,8 @@ Task info: weburl/taskinfo?taskID=1
self.session, [task_id], quiet=self.options.quiet)
self.assertEqual(rv, 0)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@mock.patch('koji_cli.watch_tasks', return_value=0)
@ -126,8 +124,8 @@ Task info: weburl/taskinfo?taskID=1
watch_tasks_mock.assert_not_called()
self.assertEqual(cm.exception.code, 2)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@mock.patch('koji_cli.watch_tasks', return_value=0)
@ -166,8 +164,8 @@ Task info: weburl/taskinfo?taskID=1
watch_tasks_mock.assert_not_called()
self.assertEqual(cm.exception.code, 2)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@mock.patch('koji_cli.watch_tasks', return_value=0)
@ -234,7 +232,7 @@ Options:
watch_tasks_mock.assert_not_called()
self.assertEqual(cm.exception.code, 0)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@mock.patch('koji_cli.watch_tasks', return_value=0)
@ -275,7 +273,7 @@ Options:
watch_tasks_mock.assert_not_called()
self.assertEqual(cm.exception.code, 2)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@mock.patch('koji_cli.watch_tasks', return_value=0)
@ -320,7 +318,7 @@ Options:
watch_tasks_mock.assert_not_called()
self.assertEqual(cm.exception.code, 2)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@mock.patch('koji_cli.watch_tasks', return_value=0)
@ -365,8 +363,8 @@ Options:
watch_tasks_mock.assert_not_called()
self.assertEqual(cm.exception.code, 2)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch(
'koji.util.parse_maven_param',
@ -498,7 +496,7 @@ Task info: weburl/taskinfo?taskID=1
self.session.mavenBuild.assert_not_called()
self.assertEqual(cm.exception.code, 2)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji.util.parse_maven_param')
@mock.patch('koji.util.maven_opts')
@ -550,7 +548,7 @@ Task info: weburl/taskinfo?taskID=1
watch_tasks_mock.assert_not_called()
self.assertEqual(cm.exception.code, 2)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji.util.parse_maven_param')
@mock.patch('koji.util.maven_opts', return_value={})
@ -632,7 +630,7 @@ Task info: weburl/taskinfo?taskID=1
self.session.mavenBuild.assert_called_once_with(
source, target, opts, priority=priority)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._running_in_bg', return_value=False)
@mock.patch('koji_cli.watch_tasks', return_value=0)
@ -676,7 +674,7 @@ Task info: weburl/taskinfo?taskID=1
self.session, [task_id], quiet=self.options.quiet)
self.assertEqual(rv, 0)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli._running_in_bg', return_value=True)
@mock.patch('koji_cli.watch_tasks', return_value=0)
@ -720,7 +718,7 @@ Task info: weburl/taskinfo?taskID=1
watch_tasks_mock.assert_not_called()
self.assertIsNone(rv)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji.util.parse_maven_param')
@mock.patch('koji.util.maven_opts', return_value={})

View file

@ -1,14 +1,12 @@
from __future__ import absolute_import
import unittest
import StringIO as stringio
import os
import sys
import mock
import six
import loadcli
from . import loadcli
cli = loadcli.cli
@ -18,7 +16,7 @@ class TestRemoveChannel(unittest.TestCase):
# Show long diffs in error output...
maxDiff = None
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_remove_channel(self, activate_session_mock, stdout):
channel = 'channel'
@ -43,7 +41,7 @@ class TestRemoveChannel(unittest.TestCase):
session.removeChannel.assert_called_once_with(channel, force=None)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_remove_channel_force(self, activate_session_mock, stdout):
channel = 'channel'
@ -69,7 +67,7 @@ class TestRemoveChannel(unittest.TestCase):
session.removeChannel.assert_called_once_with(channel, force=True)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_remove_channel_no_channel(
self, activate_session_mock, stdout):
@ -95,8 +93,8 @@ class TestRemoveChannel(unittest.TestCase):
session.removeChannel.assert_not_called()
self.assertEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_remove_channel_help(
self, activate_session_mock, stderr, stdout):

View file

@ -1,14 +1,12 @@
from __future__ import absolute_import
import unittest
import StringIO as stringio
import os
import sys
import mock
import six
import loadcli
from . import loadcli
cli = loadcli.cli
@ -18,7 +16,7 @@ class TestRemoveHostFromChannel(unittest.TestCase):
# Show long diffs in error output...
maxDiff = None
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_remove_host_from_channel(
self, activate_session_mock, stdout):
@ -48,7 +46,7 @@ class TestRemoveHostFromChannel(unittest.TestCase):
session.removeHostFromChannel.assert_called_once_with(host, channel)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_remove_host_from_channel_no_host(
self, activate_session_mock, stdout):
@ -76,7 +74,7 @@ class TestRemoveHostFromChannel(unittest.TestCase):
session.removeHostFromChannel.assert_not_called()
self.assertEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_remove_host_from_channel_not_a_member(
self, activate_session_mock, stdout):
@ -107,8 +105,8 @@ class TestRemoveHostFromChannel(unittest.TestCase):
session.removeHostFromChannel.assert_not_called()
self.assertEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_remove_host_from_channel_help(
self, activate_session_mock, stderr, stdout):

View file

@ -1,17 +1,14 @@
from __future__ import absolute_import
import unittest
import StringIO as stringio
import os
import sys
import mock
import six
from mock import call
import loadcli
from . import loadcli
cli = loadcli.cli
@ -21,7 +18,7 @@ class TestRemovePkg(unittest.TestCase):
# Show long diffs in error output...
maxDiff = None
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_remove_pkg(self, activate_session_mock, stdout):
tag = 'tag'
@ -54,7 +51,7 @@ class TestRemovePkg(unittest.TestCase):
session.multiCall.assert_called_once_with(strict=True)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_remove_pkg_multi_pkg(self, activate_session_mock, stdout):
tag = 'tag'
@ -93,7 +90,7 @@ class TestRemovePkg(unittest.TestCase):
strict=True)])
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_remove_pkg_force(self, activate_session_mock, stdout):
tag = 'tag'
@ -132,7 +129,7 @@ class TestRemovePkg(unittest.TestCase):
strict=True)])
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_remove_pkg_no_package(self, activate_session_mock, stdout):
tag = 'tag'
@ -165,7 +162,7 @@ class TestRemovePkg(unittest.TestCase):
session.multiCall.assert_not_called()
self.assertEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_remove_pkg_tag_no_exists(
self, activate_session_mock, stdout):
@ -193,8 +190,8 @@ class TestRemovePkg(unittest.TestCase):
session.packageListRemove.assert_not_called()
self.assertEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_remove_pkg_help(
self, activate_session_mock, stderr, stdout):

View file

@ -1,14 +1,12 @@
from __future__ import absolute_import
import unittest
import StringIO as stringio
import os
import sys
import mock
import six
import loadcli
from . import loadcli
cli = loadcli.cli
@ -18,7 +16,7 @@ class TestRenameChannel(unittest.TestCase):
# Show long diffs in error output...
maxDiff = None
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_rename_channel(self, activate_session_mock, stdout):
old_name = 'old_name'
@ -44,7 +42,7 @@ class TestRenameChannel(unittest.TestCase):
session.renameChannel.assert_called_once_with(old_name, new_name)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_rename_channel_no_channel(
self, activate_session_mock, stdout):
@ -71,8 +69,8 @@ class TestRenameChannel(unittest.TestCase):
session.renameChannel.assert_not_called()
self.assertEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stderr', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
def test_handle_rename_channel_help(
self, activate_session_mock, stderr, stdout):

View file

@ -1,8 +1,9 @@
from __future__ import absolute_import
import unittest
import mock
import loadcli
from . import loadcli
cli = loadcli.cli

View file

@ -1,13 +1,13 @@
from __future__ import absolute_import
import os
import sys
import unittest
import koji
import StringIO as stringio
import six
import mock
import loadcli
from . import loadcli
cli = loadcli.cli
@ -29,7 +29,7 @@ class TestListCommands(unittest.TestCase):
# Show long diffs in error output...
maxDiff = None
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
def test_handle_runroot(self, stdout):
tag = 'tag'
arch = 'arch'

View file

@ -1,9 +1,10 @@
import StringIO
from __future__ import absolute_import
import unittest
import koji
import mock
import six
import loadcli
from . import loadcli
cli = loadcli.cli
@ -126,7 +127,7 @@ class TestSaveFailedTree(unittest.TestCase):
watch_tasks_mock.assert_called_once_with(self.session, [spawned_id],
quiet=options.quiet)
@mock.patch('sys.stdout', new_callable=StringIO.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.activate_session')
@mock.patch('koji_cli.watch_tasks')
def test_handle_save_failed_tree_errors(self, watch_tasks_mock, activate_session_mock, stdout):

View file

@ -1,6 +1,8 @@
from __future__ import absolute_import
import unittest
import loadcli
from . import loadcli
from six.moves import range
cli = loadcli.cli
@ -14,7 +16,7 @@ class TestUniquePath(unittest.TestCase):
cli._unique_path('prefix'))
self.assertRegexpMatches(
cli._unique_path('prefix'),
'^prefix/\d{10}\.\d{1,6}\.[a-zA-Z]{8}$')
'^prefix/\d{10}\.\d{1,7}\.[a-zA-Z]{8}$')
if __name__ == '__main__':
unittest.main()

View file

@ -1,9 +1,10 @@
from __future__ import absolute_import
import unittest
import mock
import sys
import StringIO as stringio
import six
import loadcli
from . import loadcli
cli = loadcli.cli
@ -30,7 +31,7 @@ class TestUploadProgressCallBack(unittest.TestCase):
self.assertEqual(cli._format_secs(4321), '01:12:01')
self.assertEqual(cli._format_secs(4321.567), '01:12:01')
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
def test_progress_callback(self, stdout):
cli._progress_callback(12300, 234000, 5670, 80, 900)
cli._progress_callback(45600, 234000, 5670, 0, 900)

View file

@ -1,14 +1,16 @@
from __future__ import absolute_import
import unittest
import os
import sys
import StringIO as stringio
import mock
from mock import call
import loadcli
from . import loadcli
from six.moves import range
import six
cli = loadcli.cli
@ -30,7 +32,7 @@ class TestWatchTasks(unittest.TestCase):
# Show long diffs in error output...
maxDiff = None
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
def test_watch_tasks_no_tasklist(self, stdout):
returned = cli.watch_tasks(self.session, [])
actual = stdout.getvalue()
@ -38,7 +40,7 @@ class TestWatchTasks(unittest.TestCase):
self.assertIsNone(returned)
self.assertEqual(actual, expected)
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.TaskWatcher')
@mock.patch('koji_cli.display_tasklist_status')
@mock.patch('koji_cli.display_task_results')
@ -64,7 +66,7 @@ class TestWatchTasks(unittest.TestCase):
def side_effect(*args, **kwargs):
rt = None
if args[0] not in range(2):
if args[0] not in list(range(2)):
rt = mock.MagicMock()
rt.level = args[2]
rt.is_done.return_value = True
@ -76,7 +78,7 @@ class TestWatchTasks(unittest.TestCase):
return rt
twClzMock.side_effect = side_effect
rv = cli.watch_tasks(self.session, range(2), quiet=False)
rv = cli.watch_tasks(self.session, list(range(2)), quiet=False)
actual = stdout.getvalue()
self.assertMultiLineEqual(
actual, "Watching tasks (this may be safely interrupted)...\n\n")
@ -168,7 +170,7 @@ class TestWatchTasks(unittest.TestCase):
call.display_task_results_mock({0: tw1, 1: tw2, 11: manager.tw11, 12: manager.tw12})
])
@mock.patch('sys.stdout', new_callable=stringio.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.TaskWatcher')
@mock.patch('koji_cli.display_tasklist_status')
@mock.patch('koji_cli.display_task_results')
@ -201,7 +203,7 @@ class TestWatchTasks(unittest.TestCase):
def side_effect(*args, **kwargs):
rt = None
if args[0] not in range(2):
if args[0] not in list(range(2)):
rt = mock.MagicMock()
rt.level = args[2]
rt.is_done.return_value = True
@ -215,7 +217,7 @@ class TestWatchTasks(unittest.TestCase):
twClzMock.side_effect = side_effect
with self.assertRaises(KeyboardInterrupt):
cli.watch_tasks(self.session, range(2), quiet=False)
cli.watch_tasks(self.session, list(range(2)), quiet=False)
actual = stdout.getvalue()
self.assertMultiLineEqual(

View file

@ -1,76 +0,0 @@
#!/usr/bin/python
# coding=utf-8
"""Test the __init__.py module"""
import koji
import unittest
class FixEncodingTestCase(unittest.TestCase):
"""Main test case container"""
simple_values = [
# [ value, fixed ]
['', ''],
[u'', ''],
[u'góðan daginn', 'g\xc3\xb3\xc3\xb0an daginn'],
[u'hej', 'hej'],
[u'zdravstvuite', 'zdravstvuite'],
[u'céad míle fáilte', 'c\xc3\xa9ad m\xc3\xadle f\xc3\xa1ilte'],
[u'dobrý den', 'dobr\xc3\xbd den'],
[u'hylô', 'hyl\xc3\xb4'],
[u'jó napot', 'j\xc3\xb3 napot'],
[u'tervehdys', 'tervehdys'],
[u'olá', 'ol\xc3\xa1'],
[u'grüezi', 'gr\xc3\xbcezi'],
[u'dobre dan', 'dobre dan'],
[u'hello', 'hello'],
[u'bună ziua', 'bun\xc4\x83 ziua'],
[u'こんにちは', '\xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1\xe3\x81\xaf'],
[u'你好', '\xe4\xbd\xa0\xe5\xa5\xbd'],
[u'नमस्कार', '\xe0\xa4\xa8\xe0\xa4\xae\xe0\xa4\xb8\xe0\xa5\x8d\xe0\xa4\x95\xe0\xa4\xbe\xe0\xa4\xb0'],
[u'안녕하세요', '\xec\x95\x88\xeb\x85\x95\xed\x95\x98\xec\x84\xb8\xec\x9a\x94'],
]
def test_fixEncoding(self):
"""Test the fixEncoding function"""
for a, b in self.simple_values:
self.assertEqual(koji.fixEncoding(a), b)
self.assertEqual(koji.fixEncoding(b), b)
c = a.encode('utf16')
self.assertEqual(koji.fixEncoding(c, fallback='utf16'), b)
d = a[:-3] + u'\x00\x01' + a[-3:]
self.assertEqual(koji.fixEncoding(d, remove_nonprintable=True), b)
complex_values = [
# [ value, fixed ]
[{}, {}],
[(), ()],
[None, None],
[[], []],
[{u'a': 'a' , 'b' : {'c': u'c\x00'}},
{ 'a': 'a' , 'b' : {'c': 'c\x00'}}],
# iso8859-15 fallback
['g\xf3\xf0an daginn', 'g\xc3\xb3\xc3\xb0an daginn'],
]
nonprint = [
['hello\0world\0', 'helloworld'],
[u'hello\0world\0', 'helloworld'],
[[u'hello\0world\0'], ['helloworld']],
[{0: u'hello\0world\0'}, {0: 'helloworld'}],
[[{0: u'hello\0world\0'}], [{0: 'helloworld'}]],
]
def test_fixEncodingRecurse(self):
"""Test the fixEncodingRecurse function"""
for a, b in self.simple_values:
self.assertEqual(koji.fixEncoding(a), b)
for a, b in self.complex_values:
self.assertEqual(koji.fixEncodingRecurse(a), b)
for a, b in self.nonprint:
self.assertEqual(koji.fixEncodingRecurse(a, remove_nonprintable=True), b)
if __name__ == '__main__':
unittest.main()

View file

@ -1,3 +1,4 @@
from __future__ import absolute_import
import mock
import os
import unittest
@ -11,7 +12,7 @@ class TestGetRPMDeps(unittest.TestCase):
@mock.patch('kojihub.get_build')
@mock.patch('koji.pathinfo')
def test_getRPMDeps(self, pi, build, rpm):
pi.build.return_value = os.path.join(os.path.dirname(__file__), '../data/rpms')
pi.build.return_value = os.path.join(os.path.dirname(__file__), '../test_lib/data/rpms')
pi.rpm.return_value = 'test-deps-1-1.fc24.x86_64.rpm'
getRPMDeps = kojihub.RootExports().getRPMDeps
res = getRPMDeps('')

View file

@ -1,5 +1,7 @@
from __future__ import absolute_import
import mock
import unittest
import six
import koji
@ -9,7 +11,7 @@ class TestClientSession(unittest.TestCase):
@mock.patch('socket.getfqdn')
def test_server_principal_rdns(self, getfqdn):
opts = {'krb_rdns': True}
session = koji.ClientSession('http://koji.example.com/kojihub', opts)
session = koji.ClientSession('http://koji.example.com:30/kojihub', opts)
cprinc = mock.MagicMock()
cprinc.realm = "REALM"
getfqdn.return_value = 'koji02.example.com'
@ -30,31 +32,30 @@ class TestClientSession(unittest.TestCase):
self.assertEqual(princ, 'host/koji.example.com@REALM')
getfqdn.assert_not_called()
@mock.patch('koji.compatrequests.Session')
@mock.patch('requests.Session')
def test_new_session(self, rsession, compat_session):
def test_new_session(self, rsession):
opts = {'use_old_ssl': False}
ksession = koji.ClientSession('http://koji.example.com/kojihub', opts)
# init should have called new_session for us
rsession.assert_called_once()
compat_session.assert_not_called()
@mock.patch('koji.compatrequests.Session')
@mock.patch('requests.Session')
def test_new_session_old(self, rsession, compat_session):
def test_new_session_old(self, rsession):
if six.PY3:
return
opts = {'use_old_ssl': True}
ksession = koji.ClientSession('http://koji.example.com/kojihub', opts)
# init should have called new_session for us
rsession.assert_not_called()
compat_session.assert_called_once()
@mock.patch('koji.compatrequests.Session')
@mock.patch('requests.Session')
def test_new_session_close(self, rsession, compat_session):
def test_new_session_close(self, rsession):
if six.PY3:
return
opts = {'use_old_ssl': True}
ksession = koji.ClientSession('http://koji.example.com/kojihub', opts)
my_rsession = mock.MagicMock()
@ -72,9 +73,12 @@ class TestFastUpload(unittest.TestCase):
self.do_fake_login()
# mocks
self.ksession._callMethod = mock.MagicMock()
self.compat_session = mock.patch('koji.compatrequests.Session').start()
self.ksession.retries = 1
self.rsession = mock.patch('requests.Session').start()
self.file_mock = mock.patch('__builtin__.file').start()
if six.PY2:
self.file_mock = mock.patch('__builtin__.open').start()
else:
self.file_mock = mock.patch('builtins.open').start()
self.getsize_mock = mock.patch('os.path.getsize').start()
def tearDown(self):

View file

@ -0,0 +1,78 @@
#!/usr/bin/python
# coding=utf-8
"""Test the __init__.py module"""
from __future__ import absolute_import
import koji
import six
import unittest
class FixEncodingTestCase(unittest.TestCase):
"""Main test case container"""
simple_values = [
# [ value, fixed ]
['', six.b('')],
[u'', six.b('')],
[u'góðan daginn', six.b('g\xc3\xb3\xc3\xb0an daginn')],
[u'hej', six.b('hej')],
[u'zdravstvuite', six.b('zdravstvuite')],
[u'céad míle fáilte', six.b('c\xc3\xa9ad m\xc3\xadle f\xc3\xa1ilte')],
[u'dobrý den', six.b('dobr\xc3\xbd den')],
[u'hylô', six.b('hyl\xc3\xb4')],
[u'jó napot', six.b('j\xc3\xb3 napot')],
[u'tervehdys', six.b('tervehdys')],
[u'olá', six.b('ol\xc3\xa1')],
[u'grüezi', six.b('gr\xc3\xbcezi')],
[u'dobre dan', six.b('dobre dan')],
[u'hello', six.b('hello')],
[u'bună ziua', six.b('bun\xc4\x83 ziua')],
[u'こんにちは', six.b('\xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1\xe3\x81\xaf')],
[u'你好', six.b('\xe4\xbd\xa0\xe5\xa5\xbd')],
[u'नमस्कार', six.b('\xe0\xa4\xa8\xe0\xa4\xae\xe0\xa4\xb8\xe0\xa5\x8d\xe0\xa4\x95\xe0\xa4\xbe\xe0\xa4\xb0')],
[u'안녕하세요', six.b('\xec\x95\x88\xeb\x85\x95\xed\x95\x98\xec\x84\xb8\xec\x9a\x94')],
]
def test_fixEncoding(self):
"""Test the fixEncoding function"""
for a, b in self.simple_values:
self.assertEqual(koji.fixEncoding(a), b)
self.assertEqual(koji.fixEncoding(b), b)
c = a.encode('utf16')
self.assertEqual(koji.fixEncoding(c, fallback='utf16'), b)
d = a[:-3] + u'\x00\x01' + a[-3:]
self.assertEqual(koji.fixEncoding(d, remove_nonprintable=True), b)
complex_values = [
# [ value, fixed ]
[{}, {}],
[(), ()],
[None, None],
[[], []],
[{u'a': 'a' , 'b' : {'c': u'c\x00'}},
{six.b('a'): six.b('a') , six.b('b') : {six.b('c'): six.b('c\x00')}}],
# iso8859-15 fallback
['g\xf3\xf0an daginn', six.b('g\xc3\xb3\xc3\xb0an daginn')],
]
nonprint = [
['hello\0world\0', six.b('helloworld')],
[u'hello\0world\0', six.b('helloworld')],
[[u'hello\0world\0'], [six.b('helloworld')]],
[{0: u'hello\0world\0'}, {0: six.b('helloworld')}],
[[{0: u'hello\0world\0'}], [{0: six.b('helloworld')}]],
]
def test_fixEncodingRecurse(self):
"""Test the fixEncodingRecurse function"""
for a, b in self.simple_values:
self.assertEqual(koji.fixEncoding(a), b)
for a, b in self.complex_values:
self.assertEqual(koji.fixEncodingRecurse(a), b)
for a, b in self.nonprint:
self.assertEqual(koji.fixEncodingRecurse(a, remove_nonprintable=True), b)
if __name__ == '__main__':
unittest.main()

View file

@ -2,6 +2,7 @@
"""Test the __init__.py module"""
from __future__ import absolute_import
import mock
import os
import rpm
@ -137,10 +138,10 @@ class HeaderTestCase(unittest.TestCase):
self.assertEqual(koji.get_header_fields(self.rpm_path, []), {})
# correct
self.assertEqual(['REQUIRES'], koji.get_header_fields(self.rpm_path, ['REQUIRES']).keys())
self.assertEqual(['REQUIRES'], list(koji.get_header_fields(self.rpm_path, ['REQUIRES']).keys()))
self.assertEqual(['PROVIDES', 'REQUIRES'], sorted(koji.get_header_fields(self.rpm_path, ['REQUIRES', 'PROVIDES'])))
hdr = koji.get_rpm_header(self.rpm_path)
self.assertEqual(['REQUIRES'], koji.get_header_fields(hdr, ['REQUIRES']).keys())
self.assertEqual(['REQUIRES'], list(koji.get_header_fields(hdr, ['REQUIRES']).keys()))
def test_get_header_field_src(self):

View file

@ -1,11 +1,15 @@
from __future__ import absolute_import
import unittest
import koji
import sys
import threading
import traceback
from six.moves import range
import six
# XXX remove skip when Fedora bug is fixed
@unittest.skipIf(six.PY3, "coverage bug Fedora, see rhbz#1452339")
class ProfilesTestCase(unittest.TestCase):
def test_profile_threading(self):
@ -14,7 +18,7 @@ class ProfilesTestCase(unittest.TestCase):
# loop a few times to increase chances of hitting race conditions
for i in range(20):
errors = {}
threads = [threading.Thread(target=stress, args=(errors, _)) for _ in xrange(100)]
threads = [threading.Thread(target=stress, args=(errors, _)) for _ in range(100)]
for t in threads:
t.start()
for t in threads:

View file

@ -1,10 +1,11 @@
from __future__ import absolute_import
import mock
import unittest
from mock import call
import os
import optparse
import ConfigParser
import six.moves.configparser
import koji
import koji.util
@ -39,6 +40,14 @@ class EnumTestCase(unittest.TestCase):
self.assertEquals(test[1:], ('two', 'three'))
def mock_open():
"""Return the right patch decorator for open"""
if six.PY2:
return mock.patch('__builtin__.open')
else:
return mock.patch('builtins.open')
class MiscFunctionTestCase(unittest.TestCase):
@mock.patch('os.path.exists')
@ -81,12 +90,12 @@ class MiscFunctionTestCase(unittest.TestCase):
islink.assert_called_once_with(dst)
move.assert_not_called()
@mock.patch('urllib2.urlopen')
@mock_open()
@mock.patch('six.moves.urllib.request.urlopen')
@mock.patch('tempfile.TemporaryFile')
@mock.patch('shutil.copyfileobj')
@mock.patch('__builtin__.open')
def test_openRemoteFile(self, m_open, m_copyfileobj, m_TemporaryFile,
m_urlopen):
def test_openRemoteFile(self, m_copyfileobj, m_TemporaryFile,
m_urlopen, m_open):
"""Test openRemoteFile function"""
mocks = [m_open, m_copyfileobj, m_TemporaryFile, m_urlopen]
@ -473,7 +482,7 @@ class MavenUtilTestCase(unittest.TestCase):
self.assertEqual(cm.exception.args[0], 'total ordering not possible')
def _read_conf(self, cfile):
config = ConfigParser.ConfigParser()
config = six.moves.configparser.ConfigParser()
path = os.path.dirname(__file__)
with open(path + cfile, 'r') as conf_file:
config.readfp(conf_file)

View file

@ -1,3 +1,4 @@
from __future__ import absolute_import
import unittest
# This is python-mock, not the rpm mock tool we know and love

View file

@ -1,3 +1,4 @@
from __future__ import absolute_import
import unittest
from nose.tools import raises

View file

@ -1,5 +1,5 @@
from __future__ import absolute_import
import random
from io import StringIO
from os import path, makedirs
from shutil import rmtree
from tempfile import gettempdir
@ -10,12 +10,13 @@ import koji
from koji.tasks import BaseTaskHandler, FakeTask, ForkTask, SleepTask, \
WaitTestTask, scan_mounts, umount_all, \
safe_rmtree
import six
def get_fake_mounts_file():
""" Returns contents of /prc/mounts in a file-like object
"""
return StringIO(unicode((
return six.StringIO(six.text_type((
'sysfs /sys sysfs rw,seclabel,nosuid,nodev,noexec,relatime 0 0\n'
'proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0\n'
'devtmpfs /dev devtmpfs rw,seclabel,nosuid,size=238836k,nr_inodes=59709,mode=755 0 0\n'
@ -110,7 +111,7 @@ class TasksTestCase(TestCase):
umount_all('/dev')
raise Exception('A GenericError was not raised during the test')
except koji.GenericError as e:
self.assertEquals(e.message,
self.assertEquals(e.args[0],
'umount failed (exit code 1) for /dev/shm')
# Patching the scan_mounts function instead of the built-in open function because this is only testing umount_all
@ -124,7 +125,7 @@ class TasksTestCase(TestCase):
umount_all('/dev')
raise Exception('A GenericError was not raised during the test')
except koji.GenericError as e:
self.assertEquals(e.message, 'Unmounting incomplete: [\'/dev/shm\', \'/dev/mqueue\']')
self.assertEquals(e.args[0], 'Unmounting incomplete: [\'/dev/shm\', \'/dev/mqueue\']')
@patch('os.path.isfile', return_value=True)
@patch('os.remove')
@ -170,7 +171,7 @@ class TasksTestCase(TestCase):
safe_rmtree('/mnt/folder', False, True)
raise Exception('A GenericError was not raised during the test')
except koji.GenericError as e:
self.assertEquals(e.message, 'file removal failed (code 1) for /mnt/folder')
self.assertEquals(e.args[0], 'file removal failed (code 1) for /mnt/folder')
@patch('os.path.isfile', return_value=False)
@patch('os.path.islink', return_value=False)
@ -184,7 +185,7 @@ class TasksTestCase(TestCase):
safe_rmtree('/mnt/folder', False, True)
raise Exception('A GenericError was not raised during the test')
except koji.GenericError as e:
self.assertEquals(e.message, 'dir removal failed (code 1) for /mnt/folder')
self.assertEquals(e.args[0], 'dir removal failed (code 1) for /mnt/folder')
def test_BaseTaskHandler_handler_not_set(self):
""" Tests that an exception is thrown when the handler function is not overwritten by the child class.
@ -355,7 +356,7 @@ class TasksTestCase(TestCase):
obj.wait([1551234, 1591234], all=True, failany=True)
raise Exception('A GeneralError was not raised.')
except koji.GenericError as e:
self.assertEquals(e.message, 'Uh oh, we\'ve got a problem here!')
self.assertEquals(e.args[0], 'Uh oh, we\'ve got a problem here!')
obj.session.host.taskSetWait.assert_called_once_with(12345678, [1551234, 1591234])
def test_BaseTaskHandler_getUploadDir(self):
@ -460,7 +461,7 @@ class TasksTestCase(TestCase):
obj = TestTask(123, 'some_method', ['random_arg'], None, options, temp_path)
self.assertEquals(obj.localPath('test.txt'), dummy_file)
@patch('urllib2.urlopen', return_value=StringIO(unicode('Important things\nSome more important things\n')))
@patch('six.moves.urllib.request.urlopen', return_value=six.StringIO(six.text_type('Important things\nSome more important things\n')))
def test_BaseTaskHandler_localPath_no_file(self, mock_urlopen):
"""
"""
@ -512,7 +513,7 @@ class TasksTestCase(TestCase):
obj.find_arch('noarch', host, None)
raise Exception('The BuildError Exception was not raised')
except koji.BuildError as e:
self.assertEquals(e.message, 'No arch list for this host: test.domain.local')
self.assertEquals(e.args[0], 'No arch list for this host: test.domain.local')
def test_BaseTaskHandler_find_arch_noarch_bad_tag(self):
""" Tests that the find_arch function raises an exception when the tag parameter doesn't contain a
@ -527,7 +528,7 @@ class TasksTestCase(TestCase):
obj.find_arch('noarch', host, tag)
raise Exception('The BuildError Exception was not raised')
except koji.BuildError as e:
self.assertEquals(e.message, 'No arch list for tag: some_package-1.2-build')
self.assertEquals(e.args[0], 'No arch list for tag: some_package-1.2-build')
def test_BaseTaskHandler_find_arch_noarch(self):
""" Tests that the find_arch function finds a match of x86_64 when the host only supports x86_64
@ -553,7 +554,7 @@ class TasksTestCase(TestCase):
obj.find_arch('noarch', host, tag)
raise Exception('The BuildError Exception was not raised')
except koji.BuildError as e:
self.assertEquals(e.message, ('host test.domain.local (i386) does not support '
self.assertEquals(e.args[0], ('host test.domain.local (i386) does not support '
'any arches of tag some_package-1.2-build (aarch64, x86_64)'))
def test_getRepo_tied_to_session(self):
@ -650,7 +651,7 @@ class TasksTestCase(TestCase):
raise Exception('The BuildError Exception was not raised')
except koji.BuildError as e:
obj.session.getRepo.assert_called_once_with(8472)
self.assertEquals(e.message, 'no repo (and no target) for tag rhel-7.3-build')
self.assertEquals(e.args[0], 'no repo (and no target) for tag rhel-7.3-build')
def test_FakeTask_handler(self):
""" Tests that the FakeTest handler can be instantiated and returns 42 when run

View file

@ -1,6 +1,7 @@
from __future__ import absolute_import
import unittest
import mock
import ConfigParser
import six.moves.configparser
# inject builder data
from tests.test_builder.loadkojid import kojid
@ -40,7 +41,7 @@ class FakeConfigParser(object):
try:
return self.CONFIG[section][key]
except KeyError:
raise ConfigParser.NoOptionError(section, key)
raise six.moves.configparser.NoOptionError(section, key)
class TestRunrootConfig(unittest.TestCase):

View file

@ -1,3 +1,4 @@
from __future__ import absolute_import
import mock
import os
import sys

View file

@ -40,7 +40,7 @@ import SimpleXMLRPCServer
import threading
import base64
import pwd
import urlgrabber
import pycurl
import fnmatch
from ConfigParser import ConfigParser
from optparse import OptionParser
@ -665,7 +665,10 @@ class VMExecTask(BaseTaskHandler):
else:
raise koji.BuildError('unsupported file type: %s' % type)
koji.ensuredir(os.path.dirname(localpath))
urlgrabber.urlgrab(remote_url, filename=localpath)
c = pycurl.Curl()
c.setopt(c.URL, remote_url)
c.setopt(c.WRITEDATA, open(localpath, 'wb'))
c.perform()
return file(localpath, 'r')