PR#2733: Unify error messages

Merges #2733
https://pagure.io/koji/pull-request/2733

Fixes: #2720
https://pagure.io/koji/issue/2720
Unify error messages
This commit is contained in:
Tomas Kopecek 2021-03-16 08:43:39 +01:00
commit f45f8d8fca
77 changed files with 2170 additions and 348 deletions

View file

@ -82,7 +82,7 @@ def handle_add_group(goptions, session, args):
dsttag = session.getTag(tag) dsttag = session.getTag(tag)
if not dsttag: if not dsttag:
error("Unknown tag: %s" % tag) error("No such tag: %s" % tag)
groups = dict([(p['name'], p['group_id']) for p in session.getTagGroups(tag, inherit=False)]) groups = dict([(p['name'], p['group_id']) for p in session.getTagGroups(tag, inherit=False)])
group_id = groups.get(group, None) group_id = groups.get(group, None)
@ -108,7 +108,7 @@ def handle_block_group(goptions, session, args):
dsttag = session.getTag(tag) dsttag = session.getTag(tag)
if not dsttag: if not dsttag:
error("Unknown tag: %s" % tag) error("No such tag: %s" % tag)
groups = dict([(p['name'], p['group_id']) for p in session.getTagGroups(tag, inherit=False)]) groups = dict([(p['name'], p['group_id']) for p in session.getTagGroups(tag, inherit=False)])
group_id = groups.get(group, None) group_id = groups.get(group, None)
@ -134,7 +134,7 @@ def handle_remove_group(goptions, session, args):
dsttag = session.getTag(tag) dsttag = session.getTag(tag)
if not dsttag: if not dsttag:
error(_("Unknown tag: %s" % tag)) error(_("No such tag: %s") % tag)
groups = dict([(p['name'], p['group_id']) for p in session.getTagGroups(tag, inherit=False)]) groups = dict([(p['name'], p['group_id']) for p in session.getTagGroups(tag, inherit=False)])
group_id = groups.get(group, None) group_id = groups.get(group, None)
@ -341,7 +341,7 @@ def handle_add_pkg(goptions, session, args):
if not options.owner: if not options.owner:
parser.error(_("Please specify an owner for the package(s)")) parser.error(_("Please specify an owner for the package(s)"))
if not session.getUser(options.owner): if not session.getUser(options.owner):
error("User %s does not exist" % options.owner) error("No such user: %s" % options.owner)
activate_session(session, goptions) activate_session(session, goptions)
tag = args[0] tag = args[0]
opts = {} opts = {}
@ -498,12 +498,12 @@ def handle_build(options, session, args):
else: else:
build_target = session.getBuildTarget(target) build_target = session.getBuildTarget(target)
if not build_target: if not build_target:
parser.error(_("Unknown build target: %s" % target)) parser.error(_("No such build target: %s") % target)
dest_tag = session.getTag(build_target['dest_tag']) dest_tag = session.getTag(build_target['dest_tag'])
if not dest_tag: if not dest_tag:
parser.error(_("Unknown destination tag: %s" % build_target['dest_tag_name'])) parser.error(_("No such destination tag: %s") % build_target['dest_tag_name'])
if dest_tag['locked'] and not build_opts.scratch: if dest_tag['locked'] and not build_opts.scratch:
parser.error(_("Destination tag %s is locked" % dest_tag['name'])) parser.error(_("Destination tag %s is locked") % dest_tag['name'])
source = args[1] source = args[1]
opts = {} opts = {}
if build_opts.arch_override: if build_opts.arch_override:
@ -558,10 +558,10 @@ def handle_chain_build(options, session, args):
target = args[0] target = args[0]
build_target = session.getBuildTarget(target) build_target = session.getBuildTarget(target)
if not build_target: if not build_target:
parser.error(_("Unknown build target: %s" % target)) parser.error(_("No such build target: %s") % target)
dest_tag = session.getTag(build_target['dest_tag'], strict=True) dest_tag = session.getTag(build_target['dest_tag'], strict=True)
if dest_tag['locked']: if dest_tag['locked']:
parser.error(_("Destination tag %s is locked" % dest_tag['name'])) parser.error(_("Destination tag %s is locked") % dest_tag['name'])
# check that the destination tag is in the inheritance tree of the build tag # check that the destination tag is in the inheritance tree of the build tag
# otherwise there is no way that a chain-build can work # otherwise there is no way that a chain-build can work
@ -674,12 +674,12 @@ def handle_maven_build(options, session, args):
target = args[0] target = args[0]
build_target = session.getBuildTarget(target) build_target = session.getBuildTarget(target)
if not build_target: if not build_target:
parser.error(_("Unknown build target: %s" % target)) parser.error(_("No such build target: %s") % target)
dest_tag = session.getTag(build_target['dest_tag']) dest_tag = session.getTag(build_target['dest_tag'])
if not dest_tag: if not dest_tag:
parser.error(_("Unknown destination tag: %s" % build_target['dest_tag_name'])) parser.error(_("No such destination tag: %s") % build_target['dest_tag_name'])
if dest_tag['locked'] and not build_opts.scratch: if dest_tag['locked'] and not build_opts.scratch:
parser.error(_("Destination tag %s is locked" % dest_tag['name'])) parser.error(_("Destination tag %s is locked") % dest_tag['name'])
if build_opts.inis: if build_opts.inis:
try: try:
params = koji.util.parse_maven_param(build_opts.inis, scratch=build_opts.scratch, params = koji.util.parse_maven_param(build_opts.inis, scratch=build_opts.scratch,
@ -695,7 +695,7 @@ def handle_maven_build(options, session, args):
source = args[1] source = args[1]
opts = koji.util.maven_opts(build_opts, scratch=build_opts.scratch) opts = koji.util.maven_opts(build_opts, scratch=build_opts.scratch)
if '://' not in source: if '://' not in source:
parser.error(_("Invalid SCM URL: %s" % source)) parser.error(_("No such SCM URL: %s") % source)
if build_opts.debug: if build_opts.debug:
opts.setdefault('maven_options', []).append('--debug') opts.setdefault('maven_options', []).append('--debug')
if build_opts.skip_tag: if build_opts.skip_tag:
@ -811,10 +811,10 @@ def handle_maven_chain(options, session, args):
target = args[0] target = args[0]
build_target = session.getBuildTarget(target) build_target = session.getBuildTarget(target)
if not build_target: if not build_target:
parser.error(_("Unknown build target: %s") % target) parser.error(_("No such build target: %s") % target)
dest_tag = session.getTag(build_target['dest_tag']) dest_tag = session.getTag(build_target['dest_tag'])
if not dest_tag: if not dest_tag:
parser.error(_("Unknown destination tag: %s") % build_target['dest_tag_name']) parser.error(_("No such destination tag: %s") % build_target['dest_tag_name'])
if dest_tag['locked'] and not build_opts.scratch: if dest_tag['locked'] and not build_opts.scratch:
parser.error(_("Destination tag %s is locked") % dest_tag['name']) parser.error(_("Destination tag %s is locked") % dest_tag['name'])
opts = {} opts = {}
@ -984,7 +984,7 @@ def anon_handle_mock_config(goptions, session, args):
error(_("Please specify an arch")) error(_("Please specify an arch"))
tag = session.getTag(options.tag) tag = session.getTag(options.tag)
if not tag: if not tag:
parser.error(_("Invalid tag: %s" % options.tag)) parser.error(_("No such tag: %s") % options.tag)
arch = options.arch arch = options.arch
config = session.getBuildConfig(tag['id']) config = session.getBuildConfig(tag['id'])
if not config: if not config:
@ -1003,7 +1003,7 @@ def anon_handle_mock_config(goptions, session, args):
arch = options.arch arch = options.arch
target = session.getBuildTarget(options.target) target = session.getBuildTarget(options.target)
if not target: if not target:
parser.error(_("Invalid target: %s" % options.target)) parser.error(_("No such build target: %s") % options.target)
opts['tag_name'] = target['build_tag_name'] opts['tag_name'] = target['build_tag_name']
if options.latest: if options.latest:
opts['repoid'] = 'latest' opts['repoid'] = 'latest'
@ -1645,7 +1645,7 @@ def handle_prune_signed_copies(goptions, session, args):
if x['active']: if x['active']:
fmt += " [still active]" fmt += " [still active]"
else: else:
raise koji.GenericError("unknown event: (%r, %r)" % (event_id, x)) raise koji.GenericError("No such event: (%r, %r)" % (event_id, x))
time_str = time.asctime(time.localtime(ts)) time_str = time.asctime(time.localtime(ts))
return "%s: %s" % (time_str, fmt % x) return "%s: %s" % (time_str, fmt % x)
for nvr, binfo in builds: for nvr, binfo in builds:
@ -2214,7 +2214,7 @@ def handle_import_archive(options, session, args):
image_info = {'arch': suboptions.type_info} image_info = {'arch': suboptions.type_info}
suboptions.type_info = image_info suboptions.type_info = image_info
else: else:
parser.error(_("Unsupported archive type: %s" % suboptions.type)) parser.error(_("Unsupported archive type: %s") % suboptions.type)
buildinfo = session.getBuild(arg_filter(args[0])) buildinfo = session.getBuild(arg_filter(args[0]))
if not buildinfo: if not buildinfo:
@ -2273,7 +2273,7 @@ def handle_grant_permission(goptions, session, args):
for n in names: for n in names:
user = session.getUser(n) user = session.getUser(n)
if user is None: if user is None:
parser.error(_("No such user: %s" % n)) parser.error(_("No such user: %s") % n)
users.append(user) users.append(user)
kwargs = {} kwargs = {}
if options.new: if options.new:
@ -2296,7 +2296,7 @@ def handle_revoke_permission(goptions, session, args):
for n in names: for n in names:
user = session.getUser(n) user = session.getUser(n)
if user is None: if user is None:
parser.error(_("No such user: %s" % n)) parser.error(_("No such user: %s") % n)
users.append(user) users.append(user)
for user in users: for user in users:
session.revokePermission(user['name'], perm) session.revokePermission(user['name'], perm)
@ -2315,7 +2315,7 @@ def handle_grant_cg_access(goptions, session, args):
cg = args[1] cg = args[1]
uinfo = session.getUser(user) uinfo = session.getUser(user)
if uinfo is None: if uinfo is None:
parser.error(_("No such user: %s" % user)) parser.error(_("No such user: %s") % user)
kwargs = {} kwargs = {}
if options.new: if options.new:
kwargs['create'] = True kwargs['create'] = True
@ -2334,7 +2334,7 @@ def handle_revoke_cg_access(goptions, session, args):
cg = args[1] cg = args[1]
uinfo = session.getUser(user) uinfo = session.getUser(user)
if uinfo is None: if uinfo is None:
parser.error(_("No such user: %s" % user)) parser.error(_("No such user: %s") % user)
session.revokeCGAccess(uinfo['name'], cg) session.revokeCGAccess(uinfo['name'], cg)
@ -2512,7 +2512,7 @@ def anon_handle_list_tagged(goptions, session, args):
# check if tag exist(s|ed) # check if tag exist(s|ed)
taginfo = session.getTag(tag, event=event_id) taginfo = session.getTag(tag, event=event_id)
if not taginfo: if not taginfo:
parser.error(_("No such tag: %s" % tag)) parser.error(_("No such tag: %s") % tag)
if options.rpms: if options.rpms:
rpms, builds = session.listTaggedRPMS(tag, **opts) rpms, builds = session.listTaggedRPMS(tag, **opts)
@ -2860,7 +2860,7 @@ def anon_handle_list_hosts(goptions, session, args):
if options.channel: if options.channel:
channel = session.getChannel(options.channel) channel = session.getChannel(options.channel)
if not channel: if not channel:
parser.error(_('Unknown channel: %s' % options.channel)) parser.error(_('No such channel: %s') % options.channel)
opts['channelID'] = channel['id'] opts['channelID'] = channel['id']
if options.ready is not None: if options.ready is not None:
opts['ready'] = options.ready opts['ready'] = options.ready
@ -2960,12 +2960,12 @@ def anon_handle_list_pkgs(goptions, session, args):
if options.owner: if options.owner:
user = session.getUser(options.owner) user = session.getUser(options.owner)
if user is None: if user is None:
parser.error(_("Invalid user")) parser.error(_("No such user: %s") % options.owner)
opts['userID'] = user['id'] opts['userID'] = user['id']
if options.tag: if options.tag:
tag = session.getTag(options.tag) tag = session.getTag(options.tag)
if tag is None: if tag is None:
parser.error(_("Invalid tag")) parser.error(_("No such tag: %s") % options.tag)
opts['tagID'] = tag['id'] opts['tagID'] = tag['id']
if options.package: if options.package:
opts['pkgID'] = options.package opts['pkgID'] = options.package
@ -3061,7 +3061,7 @@ def anon_handle_list_builds(goptions, session, args):
except ValueError: except ValueError:
package = session.getPackageID(options.package) package = session.getPackageID(options.package)
if package is None: if package is None:
parser.error(_("Invalid package")) parser.error(_("No such package: %s") % options.package)
opts['packageID'] = package opts['packageID'] = package
if options.owner: if options.owner:
try: try:
@ -3069,7 +3069,7 @@ def anon_handle_list_builds(goptions, session, args):
except ValueError: except ValueError:
user = session.getUser(options.owner) user = session.getUser(options.owner)
if user is None: if user is None:
parser.error(_("Invalid owner")) parser.error(_("No such user: %s") % options.owner)
opts['userID'] = user['id'] opts['userID'] = user['id']
if options.volume: if options.volume:
try: try:
@ -3081,19 +3081,19 @@ def anon_handle_list_builds(goptions, session, args):
if options.volume == volume['name']: if options.volume == volume['name']:
volumeID = volume['id'] volumeID = volume['id']
if volumeID is None: if volumeID is None:
parser.error(_("Invalid volume")) parser.error(_("No such volume: %s") % options.volume)
opts['volumeID'] = volumeID opts['volumeID'] = volumeID
if options.state: if options.state:
try: try:
state = int(options.state) state = int(options.state)
if state > 4 or state < 0: if state > 4 or state < 0:
parser.error(_("Invalid state")) parser.error(_("Invalid state: %s") % options.state)
opts['state'] = state opts['state'] = state
except ValueError: except ValueError:
try: try:
opts['state'] = koji.BUILD_STATES[options.state] opts['state'] = koji.BUILD_STATES[options.state]
except KeyError: except KeyError:
parser.error(_("Invalid state")) parser.error(_("Invalid state: %s") % options.state)
if options.before: if options.before:
opts['completeBefore'] = options.before opts['completeBefore'] = options.before
if options.after: if options.after:
@ -3112,7 +3112,7 @@ def anon_handle_list_builds(goptions, session, args):
buildid = options.buildid buildid = options.buildid
data = [session.getBuild(buildid)] data = [session.getBuild(buildid)]
if data[0] is None: if data[0] is None:
parser.error(_("No build with ID '%s'" % buildid)) parser.error(_("No such build: '%s'") % buildid)
else: else:
# Check filter exists # Check filter exists
if any(opts): if any(opts):
@ -3447,10 +3447,10 @@ def handle_clone_tag(goptions, session, args):
try: try:
srctag = session.getBuildConfig(args[0], event=event.get('id')) srctag = session.getBuildConfig(args[0], event=event.get('id'))
except koji.GenericError: except koji.GenericError:
parser.error(_("Unknown src-tag: %s" % args[0])) parser.error(_("No such src-tag: %s") % args[0])
dsttag = session.getTag(args[1]) dsttag = session.getTag(args[1])
if not srctag: if not srctag:
parser.error(_("Unknown src-tag: %s" % args[0])) parser.error(_("No such src-tag: %s") % args[0])
if (srctag['locked'] and not options.force) \ if (srctag['locked'] and not options.force) \
or (dsttag and dsttag['locked'] and not options.force): or (dsttag and dsttag['locked'] and not options.force):
parser.error(_("Error: You are attempting to clone from or to a tag which is locked.\n" parser.error(_("Error: You are attempting to clone from or to a tag which is locked.\n"
@ -3931,11 +3931,11 @@ def handle_add_target(goptions, session, args):
chkbuildtag = session.getTag(build_tag) chkbuildtag = session.getTag(build_tag)
chkdesttag = session.getTag(dest_tag) chkdesttag = session.getTag(dest_tag)
if not chkbuildtag: if not chkbuildtag:
error("Build tag does not exist: %s" % build_tag) error("No such tag: %s" % build_tag)
if not chkbuildtag.get("arches", None): if not chkbuildtag.get("arches", None):
error("Build tag has no arches: %s" % build_tag) error("Build tag has no arches: %s" % build_tag)
if not chkdesttag: if not chkdesttag:
error("Destination tag does not exist: %s" % dest_tag) error("No such destination tag: %s" % dest_tag)
session.createBuildTarget(name, build_tag, dest_tag) session.createBuildTarget(name, build_tag, dest_tag)
@ -3959,7 +3959,7 @@ def handle_edit_target(goptions, session, args):
targetInfo = session.getBuildTarget(args[0]) targetInfo = session.getBuildTarget(args[0])
if targetInfo is None: if targetInfo is None:
raise koji.GenericError("No build target with the name or id '%s'" % args[0]) raise koji.GenericError("No such build target: %s" % args[0])
targetInfo['orig_name'] = targetInfo['name'] targetInfo['orig_name'] = targetInfo['name']
@ -3975,7 +3975,7 @@ def handle_edit_target(goptions, session, args):
if options.dest_tag: if options.dest_tag:
chkdesttag = session.getTag(options.dest_tag) chkdesttag = session.getTag(options.dest_tag)
if not chkdesttag: if not chkdesttag:
error("Destination tag does not exist: %s" % options.dest_tag) error("No such destination tag: %s" % options.dest_tag)
targetInfo['dest_tag_name'] = options.dest_tag targetInfo['dest_tag_name'] = options.dest_tag
session.editBuildTarget(targetInfo['orig_name'], targetInfo['name'], session.editBuildTarget(targetInfo['orig_name'], targetInfo['name'],
@ -3998,7 +3998,7 @@ def handle_remove_target(goptions, session, args):
target = args[0] target = args[0]
target_info = session.getBuildTarget(target) target_info = session.getBuildTarget(target)
if not target_info: if not target_info:
error("Build target %s does not exist" % target) error("No such build target: %s" % target)
session.deleteBuildTarget(target_info['id']) session.deleteBuildTarget(target_info['id'])
@ -4019,7 +4019,7 @@ def handle_remove_tag(goptions, session, args):
tag = args[0] tag = args[0]
tag_info = session.getTag(tag) tag_info = session.getTag(tag)
if not tag_info: if not tag_info:
error("Tag %s does not exist" % tag) error("No such tag: %s" % tag)
session.deleteTag(tag_info['id']) session.deleteTag(tag_info['id'])
@ -4040,9 +4040,9 @@ def anon_handle_list_targets(goptions, session, args):
targets = session.getBuildTargets(options.name) targets = session.getBuildTargets(options.name)
if len(targets) == 0: if len(targets) == 0:
if options.name: if options.name:
parser.error(_('Target "%s" does not exist' % options.name)) parser.error(_('No such build target: %s') % options.name)
else: else:
parser.error(_('No Targets were found')) parser.error(_('No targets were found'))
fmt = "%(name)-30s %(build_tag_name)-30s %(dest_tag_name)-30s" fmt = "%(name)-30s %(build_tag_name)-30s %(dest_tag_name)-30s"
if not options.quiet: if not options.quiet:
@ -4134,7 +4134,7 @@ def anon_handle_list_tag_inheritance(goptions, session, args):
else: else:
tag = session.getTag(args[0]) tag = session.getTag(args[0])
if not tag: if not tag:
parser.error(_("Unknown tag: %s" % args[0])) parser.error(_("No such tag: %s") % args[0])
opts = {} opts = {}
opts['reverse'] = options.reverse or False opts['reverse'] = options.reverse or False
@ -4149,17 +4149,17 @@ def anon_handle_list_tag_inheritance(goptions, session, args):
if match: if match:
tag1 = session.getTagID(match.group(1)) tag1 = session.getTagID(match.group(1))
if not tag1: if not tag1:
parser.error(_("Unknown tag: %s" % match.group(1))) parser.error(_("No such tag: %s") % match.group(1))
tag2 = session.getTagID(match.group(2)) tag2 = session.getTagID(match.group(2))
if not tag2: if not tag2:
parser.error(_("Unknown tag: %s" % match.group(2))) parser.error(_("No such tag: %s") % match.group(2))
opts['jumps'][str(tag1)] = tag2 opts['jumps'][str(tag1)] = tag2
if options.stop: if options.stop:
deprecated("--stop option is deprecated and will be removed in 1.26") deprecated("--stop option is deprecated and will be removed in 1.26")
tag1 = session.getTagID(options.stop) tag1 = session.getTagID(options.stop)
if not tag1: if not tag1:
parser.error(_("Unknown tag: %s" % options.stop)) parser.error(_("No such tag: %s") % options.stop)
opts['stops'] = {str(tag1): 1} opts['stops'] = {str(tag1): 1}
sys.stdout.write(' %s (%i)\n' % (tag['name'], tag['id'])) sys.stdout.write(' %s (%i)\n' % (tag['name'], tag['id']))
@ -4185,12 +4185,12 @@ def anon_handle_list_tags(goptions, session, args):
if options.package: if options.package:
pkginfo = session.getPackage(options.package) pkginfo = session.getPackage(options.package)
if not pkginfo: if not pkginfo:
parser.error(_("Invalid package %s" % options.package)) parser.error(_("No such package: %s") % options.package)
if options.build: if options.build:
buildinfo = session.getBuild(options.build) buildinfo = session.getBuild(options.build)
if not buildinfo: if not buildinfo:
parser.error(_("Invalid build %s" % options.build)) parser.error(_("No such build: %s") % options.build)
if not args: if not args:
# list everything if no pattern is supplied # list everything if no pattern is supplied
@ -4905,8 +4905,7 @@ def anon_handle_taginfo(goptions, session, args):
except ValueError: except ValueError:
info = None info = None
if info is None: if info is None:
print("No such tag: %s" % tag) parser.error(_('No such tag: %s') % tag)
sys.exit(1)
tags.append(info) tags.append(info)
for n, info in enumerate(tags): for n, info in enumerate(tags):
@ -5194,11 +5193,11 @@ def handle_add_tag_inheritance(goptions, session, args):
tag = session.getTag(args[0]) tag = session.getTag(args[0])
if not tag: if not tag:
parser.error(_("Invalid tag: %s" % args[0])) parser.error(_("No such tag: %s") % args[0])
parent = session.getTag(args[1]) parent = session.getTag(args[1])
if not parent: if not parent:
parser.error(_("Invalid tag: %s" % args[1])) parser.error(_("No such tag: %s") % args[1])
inheritanceData = session.getInheritanceData(tag['id']) inheritanceData = session.getInheritanceData(tag['id'])
priority = options.priority and int(options.priority) or 0 priority = options.priority and int(options.priority) or 0
@ -5251,14 +5250,14 @@ def handle_edit_tag_inheritance(goptions, session, args):
tag = session.getTag(args[0]) tag = session.getTag(args[0])
if not tag: if not tag:
parser.error(_("Invalid tag: %s" % args[0])) parser.error(_("No such tag: %s") % args[0])
parent = None parent = None
priority = None priority = None
if len(args) > 1: if len(args) > 1:
parent = session.getTag(args[1]) parent = session.getTag(args[1])
if not parent: if not parent:
parser.error(_("Invalid tag: %s" % args[1])) parser.error(_("No such tag: %s") % args[1])
if len(args) > 2: if len(args) > 2:
priority = args[2] priority = args[2]
@ -5327,14 +5326,14 @@ def handle_remove_tag_inheritance(goptions, session, args):
tag = session.getTag(args[0]) tag = session.getTag(args[0])
if not tag: if not tag:
parser.error(_("Invalid tag: %s" % args[0])) parser.error(_("No such tag: %s") % args[0])
parent = None parent = None
priority = None priority = None
if len(args) > 1: if len(args) > 1:
parent = session.getTag(args[1]) parent = session.getTag(args[1])
if not parent: if not parent:
parser.error(_("Invalid tag: %s" % args[1])) parser.error(_("No such tag: %s") % args[1])
if len(args) > 2: if len(args) > 2:
priority = args[2] priority = args[2]
@ -5899,11 +5898,10 @@ def _build_image_indirection(options, task_opts, session, args):
tmp_target = session.getBuildTarget(task_opts.target) tmp_target = session.getBuildTarget(task_opts.target)
if not tmp_target: if not tmp_target:
raise koji.GenericError(_("Unknown build target: %s" % tmp_target)) raise koji.GenericError(_("No such build target: %s") % tmp_target)
dest_tag = session.getTag(tmp_target['dest_tag']) dest_tag = session.getTag(tmp_target['dest_tag'])
if not dest_tag: if not dest_tag:
raise koji.GenericError(_("Unknown destination tag: %s" % raise koji.GenericError(_("No such destination tag: %s") % tmp_target['dest_tag_name'])
tmp_target['dest_tag_name']))
# Set the architecture # Set the architecture
task_opts.arch = koji.canonArch(task_opts.arch) task_opts.arch = koji.canonArch(task_opts.arch)
@ -6012,7 +6010,7 @@ def handle_image_build(options, session, args):
section = 'image-build' section = 'image-build'
config = koji.read_config_files([(task_options.config, True)]) config = koji.read_config_files([(task_options.config, True)])
if not config.has_section(section): if not config.has_section(section):
parser.error(_("single section called [%s] is required" % section)) parser.error(_("single section called [%s] is required") % section)
# pluck out the positional arguments first # pluck out the positional arguments first
args = [] args = []
for arg in ('name', 'version', 'target', 'install_tree'): for arg in ('name', 'version', 'target', 'install_tree'):
@ -6087,11 +6085,10 @@ def _build_image(options, task_opts, session, args, img_type):
target = args[2] target = args[2]
tmp_target = session.getBuildTarget(target) tmp_target = session.getBuildTarget(target)
if not tmp_target: if not tmp_target:
raise koji.GenericError(_("Unknown build target: %s" % target)) raise koji.GenericError(_("No such build target: %s") % target)
dest_tag = session.getTag(tmp_target['dest_tag']) dest_tag = session.getTag(tmp_target['dest_tag'])
if not dest_tag: if not dest_tag:
raise koji.GenericError(_("Unknown destination tag: %s" % raise koji.GenericError(_("No such destination tag: %s") % tmp_target['dest_tag_name'])
tmp_target['dest_tag_name']))
# Set the architecture # Set the architecture
if img_type == 'livemedia': if img_type == 'livemedia':
@ -6161,11 +6158,10 @@ def _build_image_oz(options, task_opts, session, args):
target = args[2] target = args[2]
tmp_target = session.getBuildTarget(target) tmp_target = session.getBuildTarget(target)
if not tmp_target: if not tmp_target:
raise koji.GenericError(_("Unknown build target: %s" % target)) raise koji.GenericError(_("No such build target: %s") % target)
dest_tag = session.getTag(tmp_target['dest_tag']) dest_tag = session.getTag(tmp_target['dest_tag'])
if not dest_tag: if not dest_tag:
raise koji.GenericError(_("Unknown destination tag: %s" % raise koji.GenericError(_("No such destination tag: %s") % tmp_target['dest_tag_name'])
tmp_target['dest_tag_name']))
# Set the architectures # Set the architectures
arches = [] arches = []
@ -6254,12 +6250,12 @@ def handle_win_build(options, session, args):
else: else:
build_target = session.getBuildTarget(target) build_target = session.getBuildTarget(target)
if not build_target: if not build_target:
parser.error(_("Unknown build target: %s" % target)) parser.error(_("No such build target: %s") % target)
dest_tag = session.getTag(build_target['dest_tag']) dest_tag = session.getTag(build_target['dest_tag'])
if not dest_tag: if not dest_tag:
parser.error(_("Unknown destination tag: %s" % build_target['dest_tag_name'])) parser.error(_("No such destination tag: %s") % build_target['dest_tag_name'])
if dest_tag['locked'] and not build_opts.scratch: if dest_tag['locked'] and not build_opts.scratch:
parser.error(_("Destination tag %s is locked" % dest_tag['name'])) parser.error(_("Destination tag %s is locked") % dest_tag['name'])
scmurl = args[1] scmurl = args[1]
vm_name = args[2] vm_name = args[2]
opts = {} opts = {}
@ -6654,7 +6650,7 @@ def handle_move_build(opts, session, args):
for arg in args[2:]: for arg in args[2:]:
pkg = session.getPackage(arg) pkg = session.getPackage(arg)
if not pkg: if not pkg:
print(_("Invalid package name %s, skipping." % arg)) print(_("No such package: %s, skipping.") % arg)
continue continue
tasklist = session.moveAllBuilds(args[0], args[1], arg, options.force) tasklist = session.moveAllBuilds(args[0], args[1], arg, options.force)
tasks.extend(tasklist) tasks.extend(tasklist)
@ -6662,7 +6658,7 @@ def handle_move_build(opts, session, args):
for arg in args[2:]: for arg in args[2:]:
build = session.getBuild(arg) build = session.getBuild(arg)
if not build: if not build:
print(_("Invalid build %s, skipping." % arg)) print(_("No such build: %s, skipping.") % arg)
continue continue
if build not in builds: if build not in builds:
builds.append(build) builds.append(build)
@ -6701,7 +6697,7 @@ def handle_untag_build(goptions, session, args):
activate_session(session, goptions) activate_session(session, goptions)
tag = session.getTag(args[0]) tag = session.getTag(args[0])
if not tag: if not tag:
parser.error(_("Invalid tag: %s" % args[0])) parser.error(_("No such tag: %s") % args[0])
if options.all: if options.all:
builds = [] builds = []
for pkg in args[1:]: for pkg in args[1:]:
@ -6949,7 +6945,7 @@ def anon_handle_download_logs(options, session, args):
assert task_id == int(task_id), "Task id must be number: %r" % task_id assert task_id == int(task_id), "Task id must be number: %r" % task_id
task_info = session.getTaskInfo(task_id) task_info = session.getTaskInfo(task_id)
if task_info is None: if task_info is None:
error(_("No such task id: %i" % task_id)) error(_("No such task: %d" % task_id))
files = list_task_output_all_volumes(session, task_id) files = list_task_output_all_volumes(session, task_id)
logs = [] # list of tuples (filename, volume) logs = [] # list of tuples (filename, volume)
for filename in files: for filename in files:
@ -7033,7 +7029,7 @@ def anon_handle_download_task(options, session, args):
base_task = session.getTaskInfo(base_task_id) base_task = session.getTaskInfo(base_task_id)
if not base_task: if not base_task:
error(_('No such task: #%i') % base_task_id) error(_('No such task: %d') % base_task_id)
if suboptions.wait and base_task['state'] not in ( if suboptions.wait and base_task['state'] not in (
koji.TASK_STATES['CLOSED'], koji.TASK_STATES['CLOSED'],
@ -7130,13 +7126,13 @@ def anon_handle_wait_repo(options, session, args):
if suboptions.target: if suboptions.target:
target_info = session.getBuildTarget(tag) target_info = session.getBuildTarget(tag)
if not target_info: if not target_info:
parser.error(_("Invalid build target: %s") % tag) parser.error(_("No such build target: %s") % tag)
tag = target_info['build_tag_name'] tag = target_info['build_tag_name']
tag_id = target_info['build_tag'] tag_id = target_info['build_tag']
else: else:
tag_info = session.getTag(tag) tag_info = session.getTag(tag)
if not tag_info: if not tag_info:
parser.error(_("Invalid tag: %s") % tag) parser.error(_("No such tag: %s") % tag)
targets = session.getBuildTargets(buildTagID=tag_info['id']) targets = session.getBuildTargets(buildTagID=tag_info['id'])
if not targets: if not targets:
warn("%(name)s is not a build tag for any target" % tag_info) warn("%(name)s is not a build tag for any target" % tag_info)
@ -7219,13 +7215,13 @@ def handle_regen_repo(options, session, args):
if suboptions.target: if suboptions.target:
info = session.getBuildTarget(tag) info = session.getBuildTarget(tag)
if not info: if not info:
parser.error(_("No matching build target: " + tag)) parser.error(_("No such build target: %s") % tag)
tag = info['build_tag_name'] tag = info['build_tag_name']
info = session.getTag(tag, strict=True) info = session.getTag(tag, strict=True)
else: else:
info = session.getTag(tag) info = session.getTag(tag)
if not info: if not info:
parser.error(_("No matching tag: " + tag)) parser.error(_("No such tag: %s") % tag)
tag = info['name'] tag = info['name']
targets = session.getBuildTargets(buildTagID=info['id']) targets = session.getBuildTargets(buildTagID=info['id'])
if not targets: if not targets:
@ -7334,7 +7330,7 @@ def handle_dist_repo(options, session, args):
keys = args[1:] keys = args[1:]
taginfo = session.getTag(tag) taginfo = session.getTag(tag)
if not taginfo: if not taginfo:
parser.error(_('unknown tag %s') % tag) parser.error(_('No such tag: %s') % tag)
if len(task_opts.arch) == 0: if len(task_opts.arch) == 0:
arches = taginfo['arches'] or '' arches = taginfo['arches'] or ''
task_opts.arch = arches.split() task_opts.arch = arches.split()
@ -7407,7 +7403,7 @@ def anon_handle_search(options, session, args):
parser.error(_("Please specify search pattern")) parser.error(_("Please specify search pattern"))
type = args[0] type = args[0]
if type not in _search_types: if type not in _search_types:
parser.error(_("Unknown search type: %s") % type) parser.error(_("No such search type: %s") % type)
pattern = args[1] pattern = args[1]
matchType = 'glob' matchType = 'glob'
if options.regex: if options.regex:
@ -7462,7 +7458,7 @@ def anon_handle_list_notifications(goptions, session, args):
ensure_connection(session, goptions) ensure_connection(session, goptions)
user = session.getUser(options.user) user = session.getUser(options.user)
if not user: if not user:
error("User %s does not exist" % options.user) error("No such user: %s" % options.user)
user_id = user['id'] user_id = user['id']
else: else:
activate_session(session, goptions) activate_session(session, goptions)
@ -7546,7 +7542,7 @@ def handle_add_notification(goptions, session, args):
if options.package: if options.package:
package_id = session.getPackageID(options.package) package_id = session.getPackageID(options.package)
if package_id is None: if package_id is None:
parser.error(_("Unknown package: %s") % options.package) parser.error(_("No such package: %s") % options.package)
else: else:
package_id = None package_id = None
@ -7554,7 +7550,7 @@ def handle_add_notification(goptions, session, args):
try: try:
tag_id = session.getTagID(options.tag, strict=True) tag_id = session.getTagID(options.tag, strict=True)
except koji.GenericError: except koji.GenericError:
parser.error(_("Unknown tag: %s") % options.tag) parser.error(_("No such tag: %s") % options.tag)
else: else:
tag_id = None tag_id = None
@ -7618,7 +7614,7 @@ def handle_edit_notification(goptions, session, args):
elif options.package: elif options.package:
package_id = session.getPackageID(options.package) package_id = session.getPackageID(options.package)
if package_id is None: if package_id is None:
parser.error(_("Unknown package: %s") % options.package) parser.error(_("No such package: %s") % options.package)
else: else:
package_id = old['package_id'] package_id = old['package_id']
@ -7628,7 +7624,7 @@ def handle_edit_notification(goptions, session, args):
try: try:
tag_id = session.getTagID(options.tag, strict=True) tag_id = session.getTagID(options.tag, strict=True)
except koji.GenericError: except koji.GenericError:
parser.error(_("Unknown tag: %s") % options.tag) parser.error(_("No such tag: %s") % options.tag)
else: else:
tag_id = old['tag_id'] tag_id = old['tag_id']
@ -7673,7 +7669,7 @@ def handle_block_notification(goptions, session, args):
if options.package: if options.package:
package_id = session.getPackageID(options.package) package_id = session.getPackageID(options.package)
if package_id is None: if package_id is None:
parser.error(_("Unknown package: %s") % options.package) parser.error(_("No such package: %s") % options.package)
else: else:
package_id = None package_id = None
@ -7681,7 +7677,7 @@ def handle_block_notification(goptions, session, args):
try: try:
tag_id = session.getTagID(options.tag, strict=True) tag_id = session.getTagID(options.tag, strict=True)
except koji.GenericError: except koji.GenericError:
parser.error(_("Unknown tag: %s") % options.tag) parser.error(_("No such tag: %s") % options.tag)
else: else:
tag_id = None tag_id = None

View file

@ -505,7 +505,7 @@ class Task(object):
info['result'] = self.getResult() info['result'] = self.getResult()
new_val = info[attr] new_val = info[attr]
else: else:
raise koji.GenericError('unknown callback type: %s' % cbtype) raise koji.GenericError('No such callback type: %s' % cbtype)
old_val = old_info[attr] old_val = old_info[attr]
if attr == 'state': if attr == 'state':
# state is passed in as an integer, but we want to use the string # state is passed in as an integer, but we want to use the string
@ -971,7 +971,7 @@ def _direct_pkglist_add(taginfo, pkginfo, owner, block, extra_arches, force,
pkg = lookup_package(pkginfo, strict=False) pkg = lookup_package(pkginfo, strict=False)
if not pkg: if not pkg:
if not isinstance(pkginfo, str): if not isinstance(pkginfo, str):
raise koji.GenericError("Invalid package: %s" % pkginfo) raise koji.GenericError("No such package: %s" % pkginfo)
if owner is not None: if owner is not None:
owner = get_user(owner, strict=True)['id'] owner = get_user(owner, strict=True)['id']
action = 'add' action = 'add'
@ -1263,7 +1263,7 @@ def list_tags(build=None, package=None, perms=True, queryOpts=None, pattern=None
# lookup build id # lookup build id
buildinfo = get_build(build) buildinfo = get_build(build)
if not buildinfo: if not buildinfo:
raise koji.GenericError('invalid build: %s' % build) raise koji.GenericError('No such build: %s' % build)
joins.append('tag_listing ON tag.id = tag_listing.tag_id') joins.append('tag_listing ON tag.id = tag_listing.tag_id')
clauses.append('tag_listing.active = true') clauses.append('tag_listing.active = true')
clauses.append('tag_listing.build_id = %(buildID)i') clauses.append('tag_listing.build_id = %(buildID)i')
@ -1271,7 +1271,7 @@ def list_tags(build=None, package=None, perms=True, queryOpts=None, pattern=None
elif package is not None: elif package is not None:
packageinfo = lookup_package(package) packageinfo = lookup_package(package)
if not packageinfo: if not packageinfo:
raise koji.GenericError('invalid package: %s' % package) raise koji.GenericError('No such package: %s' % package)
fields.extend( fields.extend(
['users.id', 'users.name', 'tag_packages.blocked', 'tag_packages.extra_arches']) ['users.id', 'users.name', 'tag_packages.blocked', 'tag_packages.extra_arches'])
aliases.extend(['owner_id', 'owner_name', 'blocked', 'extra_arches']) aliases.extend(['owner_id', 'owner_name', 'blocked', 'extra_arches'])
@ -1463,7 +1463,7 @@ def readTaggedRPMS(tag, package=None, arch=None, event=None, inherit=False, late
elif isinstance(arch, (list, tuple)): elif isinstance(arch, (list, tuple)):
clauses.append('rpminfo.arch IN %(arch)s') clauses.append('rpminfo.arch IN %(arch)s')
else: else:
raise koji.GenericError('invalid arch option: %s' % arch) raise koji.GenericError('Invalid type for arch option: %s' % type(arch))
fields, aliases = zip(*fields) fields, aliases = zip(*fields)
query = QueryProcessor(tables=tables, joins=joins, clauses=clauses, query = QueryProcessor(tables=tables, joins=joins, clauses=clauses,
@ -2941,7 +2941,7 @@ def set_tag_update(tag_id, utype, event_id=None, user_id=None):
"""Record a non-versioned tag update""" """Record a non-versioned tag update"""
utype_id = koji.TAG_UPDATE_TYPES.getnum(utype) utype_id = koji.TAG_UPDATE_TYPES.getnum(utype)
if utype_id is None: if utype_id is None:
raise koji.GenericError("Invalid update type: %s" % utype) raise koji.GenericError("No such update type: %s" % utype)
if event_id is None: if event_id is None:
event_id = get_event() event_id = get_event()
if user_id is None: if user_id is None:
@ -3010,7 +3010,7 @@ def _edit_build_target(buildTargetInfo, name, build_tag, dest_tag):
target = lookup_build_target(buildTargetInfo) target = lookup_build_target(buildTargetInfo)
if not target: if not target:
raise koji.GenericError('invalid build target: %s' % buildTargetInfo) raise koji.GenericError('No such build target: %s' % buildTargetInfo)
buildTargetID = target['id'] buildTargetID = target['id']
@ -3060,7 +3060,7 @@ def _delete_build_target(buildTargetInfo):
"""Delete build target, no access checks""" """Delete build target, no access checks"""
target = lookup_build_target(buildTargetInfo) target = lookup_build_target(buildTargetInfo)
if not target: if not target:
raise koji.GenericError('invalid build target: %s' % buildTargetInfo) raise koji.GenericError('No such build target: %s' % buildTargetInfo)
targetID = target['id'] targetID = target['id']
@ -3095,7 +3095,7 @@ def get_build_targets(info=None, event=None, buildTagID=None, destTagID=None, qu
elif isinstance(info, int): elif isinstance(info, int):
clauses.append('build_target.id = %(info)i') clauses.append('build_target.id = %(info)i')
else: else:
raise koji.GenericError('invalid type for lookup: %s' % type(info)) raise koji.GenericError('Invalid type for lookup: %s' % type(info))
if buildTagID is not None: if buildTagID is not None:
clauses.append('build_tag = %(buildTagID)i') clauses.append('build_tag = %(buildTagID)i')
if destTagID is not None: if destTagID is not None:
@ -3114,7 +3114,7 @@ def get_build_target(info, event=None, strict=False):
if len(targets) == 1: if len(targets) == 1:
return targets[0] return targets[0]
elif strict: elif strict:
raise koji.GenericError('No matching build target found: %s' % info) raise koji.GenericError('No such build target: %s' % info)
else: else:
return None return None
@ -3142,7 +3142,7 @@ def lookup_name(table, info, strict=False, create=False):
elif isinstance(info, str): elif isinstance(info, str):
q = """SELECT id,name FROM %s WHERE name=%%(info)s""" % table q = """SELECT id,name FROM %s WHERE name=%%(info)s""" % table
else: else:
raise koji.GenericError('invalid type for id lookup: %s' % type(info)) raise koji.GenericError('Invalid type for id lookup: %s' % type(info))
ret = _singleRow(q, locals(), fields, strict=False) ret = _singleRow(q, locals(), fields, strict=False)
if ret is None: if ret is None:
if strict: if strict:
@ -3336,7 +3336,7 @@ def get_tag(tagInfo, strict=False, event=None, blocked=False):
elif isinstance(tagInfo, str): elif isinstance(tagInfo, str):
clauses.append("tag.name = %(tagInfo)s") clauses.append("tag.name = %(tagInfo)s")
else: else:
raise koji.GenericError('invalid type for tagInfo: %s' % type(tagInfo)) raise koji.GenericError('Invalid type for tagInfo: %s' % type(tagInfo))
data = {'tagInfo': tagInfo} data = {'tagInfo': tagInfo}
fields, aliases = zip(*fields.items()) fields, aliases = zip(*fields.items())
@ -3345,7 +3345,7 @@ def get_tag(tagInfo, strict=False, event=None, blocked=False):
result = query.executeOne() result = query.executeOne()
if not result: if not result:
if strict: if strict:
raise koji.GenericError("Invalid tagInfo: %r" % tagInfo) raise koji.GenericError("No such tagInfo: %r" % tagInfo)
return None return None
result['extra'] = get_tag_extra(result, event, blocked=blocked) result['extra'] = get_tag_extra(result, event, blocked=blocked)
return result return result
@ -3364,7 +3364,7 @@ def get_tag_extra(tagInfo, event=None, blocked=False):
result = {} result = {}
for h in query.execute(): for h in query.execute():
if h['value'] is not None: if h['value'] is not None:
h['value'] = parse_json(h['value'], errstr="Invalid tag extra data: %s" % h['key']) h['value'] = parse_json(h['value'], errstr="No such tag extra data: %s" % h['key'])
if blocked: if blocked:
result[h['key']] = (h['blocked'], h['value']) result[h['key']] = (h['blocked'], h['value'])
else: else:
@ -3613,7 +3613,7 @@ def get_external_repos(info=None, url=None, event=None, queryOpts=None):
elif isinstance(info, int): elif isinstance(info, int):
clauses.append('id = %(info)i') clauses.append('id = %(info)i')
else: else:
raise koji.GenericError('invalid type for lookup: %s' % type(info)) raise koji.GenericError('Invalid type for lookup: %s' % type(info))
if url: if url:
clauses.append('url = %(url)s') clauses.append('url = %(url)s')
@ -3642,7 +3642,7 @@ def get_external_repo(info, strict=False, event=None):
return repos[0] return repos[0]
else: else:
if strict: if strict:
raise koji.GenericError('invalid repo info: %s' % info) raise koji.GenericError('No such repo: %s' % info)
else: else:
return None return None
@ -3714,7 +3714,7 @@ def add_external_repo_to_tag(tag_info, repo_info, priority, merge_mode='koji', a
if merge_mode is None: if merge_mode is None:
merge_mode = 'koji' merge_mode = 'koji'
if merge_mode not in koji.REPO_MERGE_MODES: if merge_mode not in koji.REPO_MERGE_MODES:
raise koji.GenericError('Invalid merge mode: %s' % merge_mode) raise koji.GenericError('No such merge mode: %s' % merge_mode)
tag = get_tag(tag_info, strict=True) tag = get_tag(tag_info, strict=True)
tag_id = tag['id'] tag_id = tag['id']
@ -3920,8 +3920,7 @@ def get_user(userInfo=None, strict=False, krb_princs=True):
data = {'info': userInfo} data = {'info': userInfo}
clauses = ['krb_principal = %(info)s OR name = %(info)s'] clauses = ['krb_principal = %(info)s OR name = %(info)s']
else: else:
raise koji.GenericError('invalid type for userInfo: %s' raise koji.GenericError('Invalid type for userInfo: %s' % type(userInfo))
% type(userInfo))
if isinstance(data, dict) and not data.get('info'): if isinstance(data, dict) and not data.get('info'):
clauses = [] clauses = []
uid = data.get('id') uid = data.get('id')
@ -3929,23 +3928,20 @@ def get_user(userInfo=None, strict=False, krb_princs=True):
if isinstance(uid, int): if isinstance(uid, int):
clauses.append('users.id = %(id)i') clauses.append('users.id = %(id)i')
else: else:
raise koji.GenericError('invalid type for userid: %s' raise koji.GenericError('Invalid type for userid: %s' % type(uid))
% type(uid))
username = data.get('name') username = data.get('name')
if username: if username:
if isinstance(username, str): if isinstance(username, str):
clauses.append('users.name = %(name)s') clauses.append('users.name = %(name)s')
else: else:
raise koji.GenericError('invalid type for username: %s' raise koji.GenericError('Invalid type for username: %s' % type(username))
% type(username))
krb_principal = data.get('krb_principal') krb_principal = data.get('krb_principal')
if krb_principal: if krb_principal:
if isinstance(krb_principal, str): if isinstance(krb_principal, str):
clauses.append('user_krb_principals.krb_principal' clauses.append('user_krb_principals.krb_principal'
' = %(krb_principal)s') ' = %(krb_principal)s')
else: else:
raise koji.GenericError('invalid type for krb_principal: %s' raise koji.GenericError('Invalid type for krb_principal: %s' % type(krb_principal))
% type(krb_principal))
query = QueryProcessor(tables=['users'], columns=fields, query = QueryProcessor(tables=['users'], columns=fields,
joins=['LEFT JOIN user_krb_principals' joins=['LEFT JOIN user_krb_principals'
@ -4063,8 +4059,7 @@ def list_user_krb_principals(user_info=None):
joins = ['users ON users.id = user_krb_principals.user_id'] joins = ['users ON users.id = user_krb_principals.user_id']
clauses = ['name = %(info)s'] clauses = ['name = %(info)s']
else: else:
raise koji.GenericError('invalid type for user_info: %s' raise koji.GenericError('Invalid type for user_info: %s' % type(user_info))
% type(user_info))
query = QueryProcessor(tables=['user_krb_principals'], query = QueryProcessor(tables=['user_krb_principals'],
columns=fields, joins=joins, columns=fields, joins=joins,
clauses=clauses, values=data, clauses=clauses, values=data,
@ -4088,8 +4083,7 @@ def get_user_by_krb_principal(krb_principal, strict=False, krb_princs=True):
if krb_principal is None: if krb_principal is None:
raise koji.GenericError("No kerberos principal provided") raise koji.GenericError("No kerberos principal provided")
if not isinstance(krb_principal, str): if not isinstance(krb_principal, str):
raise koji.GenericError("invalid type for krb_principal: %s" raise koji.GenericError("Invalid type for krb_principal: %s" % type(krb_principal))
% type(krb_principal))
return get_user({'krb_principal': krb_principal}, strict=strict, return get_user({'krb_principal': krb_principal}, strict=strict,
krb_princs=krb_princs) krb_princs=krb_princs)
@ -4108,7 +4102,7 @@ def find_build_id(X, strict=False):
elif isinstance(X, dict): elif isinstance(X, dict):
data = X data = X
else: else:
raise koji.GenericError("Invalid argument: %r" % X) raise koji.GenericError("Invalid type for argument: %r" % type(X))
if not ('name' in data and 'version' in data and 'release' in data): if not ('name' in data and 'version' in data and 'release' in data):
raise koji.GenericError('did not provide name, version, and release') raise koji.GenericError('did not provide name, version, and release')
@ -4125,7 +4119,7 @@ def find_build_id(X, strict=False):
# log_error("%r" % r ) # log_error("%r" % r )
if not r: if not r:
if strict: if strict:
raise koji.GenericError('No matching build found: %r' % X) raise koji.GenericError('No such build: %r' % X)
else: else:
return None return None
return r[0] return r[0]
@ -4211,7 +4205,7 @@ def get_build(buildInfo, strict=False):
if not result: if not result:
if strict: if strict:
raise koji.GenericError('No matching build found: %s' % buildInfo) raise koji.GenericError('No such build: %s' % buildInfo)
else: else:
return None return None
if result['cg_id']: if result['cg_id']:
@ -4384,7 +4378,7 @@ def get_rpm(rpminfo, strict=False, multi=False):
elif isinstance(rpminfo, dict): elif isinstance(rpminfo, dict):
data = rpminfo.copy() data = rpminfo.copy()
else: else:
raise koji.GenericError("Invalid argument: %r" % rpminfo) raise koji.GenericError("Invalid type for rpminfo: %r" % type(rpminfo))
clauses = [] clauses = []
if 'id' in data: if 'id' in data:
clauses.append("rpminfo.id=%(id)s") clauses.append("rpminfo.id=%(id)s")
@ -4495,7 +4489,7 @@ def list_rpms(buildID=None, buildrootID=None, imageID=None, componentBuildrootID
elif isinstance(arches, str): elif isinstance(arches, str):
clauses.append('rpminfo.arch = %(arches)s') clauses.append('rpminfo.arch = %(arches)s')
else: else:
raise koji.GenericError('invalid type for "arches" parameter: %s' % type(arches)) raise koji.GenericError('Invalid type for "arches" parameter: %s' % type(arches))
fields, aliases = zip(*fields) fields, aliases = zip(*fields)
query = QueryProcessor(columns=fields, aliases=aliases, query = QueryProcessor(columns=fields, aliases=aliases,
@ -5272,7 +5266,7 @@ def get_host(hostInfo, strict=False, event=None):
elif isinstance(hostInfo, str): elif isinstance(hostInfo, str):
clauses.append("host.name = %(hostInfo)s") clauses.append("host.name = %(hostInfo)s")
else: else:
raise koji.GenericError('invalid type for hostInfo: %s' % type(hostInfo)) raise koji.GenericError('Invalid type for hostInfo: %s' % type(hostInfo))
data = {'hostInfo': hostInfo} data = {'hostInfo': hostInfo}
fields, aliases = zip(*fields.items()) fields, aliases = zip(*fields.items())
@ -5349,7 +5343,7 @@ def get_channel(channelInfo, strict=False):
elif isinstance(channelInfo, str): elif isinstance(channelInfo, str):
query += """name = %(channelInfo)s""" query += """name = %(channelInfo)s"""
else: else:
raise koji.GenericError('invalid type for channelInfo: %s' % type(channelInfo)) raise koji.GenericError('Invalid type for channelInfo: %s' % type(channelInfo))
return _singleRow(query, locals(), fields, strict) return _singleRow(query, locals(), fields, strict)
@ -5722,9 +5716,8 @@ def check_volume_policy(data, strict=False, default=None):
return vol return vol
# otherwise # otherwise
if strict: if strict:
raise koji.GenericError("Policy returned invalid volume: %s" raise koji.GenericError("Policy returned no such volume: %s" % result)
% result) logger.error('Volume policy returned no such volume %s', result)
logger.error('Volume policy returned unknown volume %s', result)
# fall back to default # fall back to default
if default is not None: if default is not None:
vol = lookup_name('volume', default) vol = lookup_name('volume', default)
@ -5789,7 +5782,7 @@ def new_build(data, strict=False):
try: try:
data['extra'] = json.dumps(data['extra']) data['extra'] = json.dumps(data['extra'])
except Exception: except Exception:
raise koji.GenericError("Invalid build extra data: %(extra)r" % data) raise koji.GenericError("No such build extra data: %(extra)r" % data)
else: else:
data['extra'] = None data['extra'] = None
@ -5957,7 +5950,7 @@ def import_build(srpm, rpms, brmap=None, task_id=None, build_id=None, logs=None)
for relpath in [srpm] + rpms: for relpath in [srpm] + rpms:
fn = "%s/%s" % (uploadpath, relpath) fn = "%s/%s" % (uploadpath, relpath)
if not os.path.exists(fn): if not os.path.exists(fn):
raise koji.GenericError("no such file: %s" % fn) raise koji.GenericError("No such file: %s" % fn)
rpms = check_noarch_rpms(uploadpath, rpms, logs=logs) rpms = check_noarch_rpms(uploadpath, rpms, logs=logs)
@ -6048,7 +6041,7 @@ def import_rpm(fn, buildinfo=None, brootid=None, wrapper=False, fileinfo=None):
Designed to be called from import_build. Designed to be called from import_build.
""" """
if not os.path.exists(fn): if not os.path.exists(fn):
raise koji.GenericError("no such file: %s" % fn) raise koji.GenericError("No such file: %s" % fn)
# read rpm info # read rpm info
hdr = koji.get_rpm_header(fn) hdr = koji.get_rpm_header(fn)
@ -6078,7 +6071,7 @@ def import_rpm(fn, buildinfo=None, brootid=None, wrapper=False, fileinfo=None):
if buildinfo is None: if buildinfo is None:
# XXX - handle case where package is not a source rpm # XXX - handle case where package is not a source rpm
# and we still need to create a new build # and we still need to create a new build
raise koji.GenericError('No matching build') raise koji.GenericError('No such build')
state = koji.BUILD_STATES[buildinfo['state']] state = koji.BUILD_STATES[buildinfo['state']]
if state in ('FAILED', 'CANCELED', 'DELETED'): if state in ('FAILED', 'CANCELED', 'DELETED'):
nvr = "%(name)s-%(version)s-%(release)s" % buildinfo nvr = "%(name)s-%(version)s-%(release)s" % buildinfo
@ -6274,7 +6267,7 @@ class CG_Importer(object):
metaver = metadata['metadata_version'] metaver = metadata['metadata_version']
if metaver != 0: if metaver != 0:
raise koji.GenericError("Unknown metadata version: %r" % metaver) raise koji.GenericError("No such metadata version: %r" % metaver)
# TODO: basic metadata sanity check (use jsonschema?) # TODO: basic metadata sanity check (use jsonschema?)
@ -6322,7 +6315,7 @@ class CG_Importer(object):
# default to looking for uploaded file # default to looking for uploaded file
metadata = 'metadata.json' metadata = 'metadata.json'
if not isinstance(metadata, str): if not isinstance(metadata, str):
raise koji.GenericError("Invalid metadata value: %r" % metadata) raise koji.GenericError("Invalid type for metadata value: %r" % type(metadata))
if metadata.endswith('.json'): if metadata.endswith('.json'):
# handle uploaded metadata # handle uploaded metadata
workdir = koji.pathinfo.work() workdir = koji.pathinfo.work()
@ -6608,7 +6601,7 @@ class CG_Importer(object):
if match: if match:
files.append(match) files.append(match)
else: else:
raise koji.GenericError("Unknown component type: %(type)s" % comp) raise koji.GenericError("No such component type: %(type)s" % comp)
return rpms, files return rpms, files
def match_rpm(self, comp): def match_rpm(self, comp):
@ -6951,7 +6944,7 @@ def merge_scratch(task_id):
try: try:
task_info = task.getInfo(request=True) task_info = task.getInfo(request=True)
except koji.GenericError: except koji.GenericError:
raise koji.ImportError('invalid task: %s' % task_id) raise koji.ImportError('No such task: %s' % task_id)
task_params = koji.tasks.parse_task_params(task_info['method'], task_info['request']) task_params = koji.tasks.parse_task_params(task_info['method'], task_info['request'])
if task_info['state'] != koji.TASK_STATES['CLOSED']: if task_info['state'] != koji.TASK_STATES['CLOSED']:
raise koji.ImportError('task %s did not complete successfully' % task_id) raise koji.ImportError('task %s did not complete successfully' % task_id)
@ -7140,7 +7133,7 @@ def add_archive_type(name, description, extensions):
# No invalid or duplicate extensions # No invalid or duplicate extensions
for ext in extensions.split(' '): for ext in extensions.split(' '):
if not ext.replace('.', '').isalnum(): if not ext.replace('.', '').isalnum():
raise koji.GenericError('invalid %s file extension' % ext) raise koji.GenericError('No such %s file extension' % ext)
select = r"""SELECT id FROM archivetypes select = r"""SELECT id FROM archivetypes
WHERE extensions ~* E'(\\s|^)%s(\\s|$)'""" % ext WHERE extensions ~* E'(\\s|^)%s(\\s|$)'""" % ext
results = _multiRow(select, {}, ('id',)) results = _multiRow(select, {}, ('id',))
@ -7265,7 +7258,7 @@ def import_archive_internal(filepath, buildinfo, type, typeInfo, buildroot_id=No
if metadata_only: if metadata_only:
filepath = None filepath = None
elif not os.path.exists(filepath): elif not os.path.exists(filepath):
raise koji.GenericError('no such file: %s' % filepath) raise koji.GenericError('No such file: %s' % filepath)
archiveinfo = {'buildroot_id': buildroot_id} archiveinfo = {'buildroot_id': buildroot_id}
archiveinfo['build_id'] = buildinfo['id'] archiveinfo['build_id'] = buildinfo['id']
@ -7725,7 +7718,7 @@ def query_history(tables=None, **kwargs):
else: else:
for table in tables: for table in tables:
if table not in table_fields: if table not in table_fields:
raise koji.GenericError("Unknown history table: %s" % table) raise koji.GenericError("No such history table: %s" % table)
ret = {} ret = {}
for table in tables: for table in tables:
fields = {} fields = {}
@ -8541,7 +8534,7 @@ def drop_group_member(group, user):
user = get_user(user, strict=True) user = get_user(user, strict=True)
ginfo = get_user(group) ginfo = get_user(group)
if not ginfo or ginfo['usertype'] != koji.USERTYPES['GROUP']: if not ginfo or ginfo['usertype'] != koji.USERTYPES['GROUP']:
raise koji.GenericError("No such group: %s" % group) raise koji.GenericError("Not a group: %s" % group)
if user['id'] not in [u['id'] for u in get_group_members(group)]: if user['id'] not in [u['id'] for u in get_group_members(group)]:
raise koji.GenericError("No such user in group: %s" % group) raise koji.GenericError("No such user in group: %s" % group)
data = {'user_id': user['id'], 'group_id': ginfo['id']} data = {'user_id': user['id'], 'group_id': ginfo['id']}
@ -8556,7 +8549,7 @@ def get_group_members(group):
context.session.assertPerm('admin') context.session.assertPerm('admin')
ginfo = get_user(group) ginfo = get_user(group)
if not ginfo or ginfo['usertype'] != koji.USERTYPES['GROUP']: if not ginfo or ginfo['usertype'] != koji.USERTYPES['GROUP']:
raise koji.GenericError("Not a group: %s" % group) raise koji.GenericError("No such group: %s" % group)
group_id = ginfo['id'] group_id = ginfo['id']
columns = ('id', 'name', 'usertype', 'array_agg(krb_principal)') columns = ('id', 'name', 'usertype', 'array_agg(krb_principal)')
aliases = ('id', 'name', 'usertype', 'krb_principals') aliases = ('id', 'name', 'usertype', 'krb_principals')
@ -8580,7 +8573,7 @@ def get_group_members(group):
def set_user_status(user, status): def set_user_status(user, status):
context.session.assertPerm('admin') context.session.assertPerm('admin')
if not koji.USER_STATUS.get(status): if not koji.USER_STATUS.get(status):
raise koji.GenericError('invalid status: %s' % status) raise koji.GenericError('No such status: %s' % status)
if user['status'] == status: if user['status'] == status:
# nothing to do # nothing to do
return return
@ -8589,7 +8582,7 @@ def set_user_status(user, status):
rows = _dml(update, locals()) rows = _dml(update, locals())
# sanity check # sanity check
if rows == 0: if rows == 0:
raise koji.GenericError('invalid user ID: %i' % user_id) raise koji.GenericError('No such user ID: %i' % user_id)
def list_cgs(): def list_cgs():
@ -8673,7 +8666,7 @@ def assert_cg(cg, user=None):
cg = lookup_name('content_generator', cg, strict=True) cg = lookup_name('content_generator', cg, strict=True)
if user is None: if user is None:
if not context.session.logged_in: if not context.session.logged_in:
raise koji.AuthError("Not logged in") raise koji.AuthError("Not logged-in")
user = context.session.user_id user = context.session.user_id
user = get_user(user, strict=True) user = get_user(user, strict=True)
clauses = ['active = TRUE', 'user_id = %(user_id)s', 'cg_id = %(cg_id)s'] clauses = ['active = TRUE', 'user_id = %(user_id)s', 'cg_id = %(cg_id)s']
@ -9144,7 +9137,7 @@ SELECT %(col_str)s
elif order in self.columns: elif order in self.columns:
orderCol = order orderCol = order
else: else:
raise Exception('invalid order: ' + order) raise Exception('Invalid order: ' + order)
order_exprs.append(orderCol + direction) order_exprs.append(orderCol + direction)
return 'ORDER BY ' + ', '.join(order_exprs) return 'ORDER BY ' + ', '.join(order_exprs)
else: else:
@ -9320,7 +9313,7 @@ def policy_get_pkg(data):
if isinstance(data['package'], str): if isinstance(data['package'], str):
return {'id': None, 'name': data['package']} return {'id': None, 'name': data['package']}
else: else:
raise koji.GenericError("Invalid package: %s" % data['package']) raise koji.GenericError("No such package: %s" % data['package'])
return pkginfo return pkginfo
if 'build' in data: if 'build' in data:
binfo = get_build(data['build'], strict=True) binfo = get_build(data['build'], strict=True)
@ -10420,7 +10413,7 @@ class RootExports(object):
q = """SELECT id, EXTRACT(EPOCH FROM time) FROM events""" q = """SELECT id, EXTRACT(EPOCH FROM time) FROM events"""
if before is not None: if before is not None:
if not isinstance(before, NUMERIC_TYPES): if not isinstance(before, NUMERIC_TYPES):
raise koji.GenericError('invalid type for before: %s' % type(before)) raise koji.GenericError('Invalid type for before: %s' % type(before))
# use the repr() conversion because it retains more precision than the # use the repr() conversion because it retains more precision than the
# string conversion # string conversion
q += """ WHERE EXTRACT(EPOCH FROM time) < %(before)r""" q += """ WHERE EXTRACT(EPOCH FROM time) < %(before)r"""
@ -10571,7 +10564,7 @@ class RootExports(object):
chksum = get_verify_class(verify)() chksum = get_verify_class(verify)()
if tail is not None: if tail is not None:
if tail < 0: if tail < 0:
raise koji.GenericError("invalid tail value: %r" % tail) raise koji.GenericError("Invalid tail value: %r" % tail)
offset = max(st.st_size - tail, 0) offset = max(st.st_size - tail, 0)
os.lseek(fd, offset, 0) os.lseek(fd, offset, 0)
length = 0 length = 0
@ -11080,7 +11073,7 @@ class RootExports(object):
build_info = get_build(buildID) build_info = get_build(buildID)
if not build_info: if not build_info:
if strict: if strict:
raise koji.GenericError("Build %s doesn't exist" % buildID) raise koji.GenericError("No such build: %s" % buildID)
return _applyQueryOpts([], queryOpts) return _applyQueryOpts([], queryOpts)
srpms = self.listRPMs(buildID=build_info['id'], arches='src') srpms = self.listRPMs(buildID=build_info['id'], arches='src')
if not srpms: if not srpms:
@ -11093,7 +11086,7 @@ class RootExports(object):
if not filepath: if not filepath:
raise koji.GenericError('filepath must be specified with taskID') raise koji.GenericError('filepath must be specified with taskID')
if filepath.startswith('/') or '../' in filepath: if filepath.startswith('/') or '../' in filepath:
raise koji.GenericError('invalid filepath: %s' % filepath) raise koji.GenericError('Invalid filepath: %s' % filepath)
srpm_path = joinpath(koji.pathinfo.work(), srpm_path = joinpath(koji.pathinfo.work(),
koji.pathinfo.taskrelpath(taskID), koji.pathinfo.taskrelpath(taskID),
filepath) filepath)
@ -11114,7 +11107,7 @@ class RootExports(object):
elif isinstance(before, int): elif isinstance(before, int):
pass pass
else: else:
raise koji.GenericError('invalid type for before: %s' % type(before)) raise koji.GenericError('Invalid type for before: %s' % type(before))
if after: if after:
if isinstance(after, datetime.datetime): if isinstance(after, datetime.datetime):
@ -11124,7 +11117,7 @@ class RootExports(object):
elif isinstance(after, int): elif isinstance(after, int):
pass pass
else: else:
raise koji.GenericError('invalid type for after: %s' % type(after)) raise koji.GenericError('Invalid type for after: %s' % type(after))
results = [] results = []
@ -11754,7 +11747,7 @@ class RootExports(object):
if not filepath: if not filepath:
raise koji.GenericError('filepath must be specified with taskID') raise koji.GenericError('filepath must be specified with taskID')
if filepath.startswith('/') or '../' in filepath: if filepath.startswith('/') or '../' in filepath:
raise koji.GenericError('invalid filepath: %s' % filepath) raise koji.GenericError('Invalid filepath: %s' % filepath)
rpm_path = joinpath(koji.pathinfo.work(), rpm_path = joinpath(koji.pathinfo.work(),
koji.pathinfo.taskrelpath(taskID), koji.pathinfo.taskrelpath(taskID),
filepath) filepath)
@ -11795,7 +11788,7 @@ class RootExports(object):
r = query.executeOne() r = query.executeOne()
if not r: if not r:
if strict: if strict:
raise koji.GenericError('Invalid package name: %s' % name) raise koji.GenericError('No such package name: %s' % name)
return None return None
return r['id'] return r['id']
@ -11976,14 +11969,14 @@ class RootExports(object):
"""Enable logins by the specified user""" """Enable logins by the specified user"""
user = get_user(username) user = get_user(username)
if not user: if not user:
raise koji.GenericError('unknown user: %s' % username) raise koji.GenericError('No such user: %s' % username)
set_user_status(user, koji.USER_STATUS['NORMAL']) set_user_status(user, koji.USER_STATUS['NORMAL'])
def disableUser(self, username): def disableUser(self, username):
"""Disable logins by the specified user""" """Disable logins by the specified user"""
user = get_user(username) user = get_user(username)
if not user: if not user:
raise koji.GenericError('unknown user: %s' % username) raise koji.GenericError('No such user: %s' % username)
set_user_status(user, koji.USER_STATUS['BLOCKED']) set_user_status(user, koji.USER_STATUS['BLOCKED'])
listCGs = staticmethod(list_cgs) listCGs = staticmethod(list_cgs)
@ -12877,7 +12870,7 @@ class RootExports(object):
owner or the notification or an admin, raise a GenericError.""" owner or the notification or an admin, raise a GenericError."""
currentUser = self.getLoggedInUser() currentUser = self.getLoggedInUser()
if not currentUser: if not currentUser:
raise koji.GenericError('not logged-in') raise koji.GenericError('Not logged-in')
orig_notif = self.getBuildNotification(id, strict=True) orig_notif = self.getBuildNotification(id, strict=True)
if not (orig_notif['user_id'] == currentUser['id'] or self.hasPerm('admin')): if not (orig_notif['user_id'] == currentUser['id'] or self.hasPerm('admin')):
@ -12908,11 +12901,11 @@ class RootExports(object):
and the currently logged-in user is not an admin, raise a GenericError.""" and the currently logged-in user is not an admin, raise a GenericError."""
currentUser = self.getLoggedInUser() currentUser = self.getLoggedInUser()
if not currentUser: if not currentUser:
raise koji.GenericError('not logged in') raise koji.GenericError('Not logged-in')
notificationUser = self.getUser(user_id) notificationUser = self.getUser(user_id)
if not notificationUser: if not notificationUser:
raise koji.GenericError('invalid user ID: %s' % user_id) raise koji.GenericError('No such user ID: %s' % user_id)
if not (notificationUser['id'] == currentUser['id'] or self.hasPerm('admin')): if not (notificationUser['id'] == currentUser['id'] or self.hasPerm('admin')):
raise koji.GenericError('user %s cannot create notifications for user %s' % raise koji.GenericError('user %s cannot create notifications for user %s' %
@ -12946,7 +12939,7 @@ class RootExports(object):
notification = self.getBuildNotification(id, strict=True) notification = self.getBuildNotification(id, strict=True)
currentUser = self.getLoggedInUser() currentUser = self.getLoggedInUser()
if not currentUser: if not currentUser:
raise koji.GenericError('not logged-in') raise koji.GenericError('Not logged-in')
if not (notification['user_id'] == currentUser['id'] or if not (notification['user_id'] == currentUser['id'] or
self.hasPerm('admin')): self.hasPerm('admin')):
@ -12961,11 +12954,11 @@ class RootExports(object):
admin, raise a GenericError.""" admin, raise a GenericError."""
currentUser = self.getLoggedInUser() currentUser = self.getLoggedInUser()
if not currentUser: if not currentUser:
raise koji.GenericError('not logged in') raise koji.GenericError('Not logged-in')
notificationUser = self.getUser(user_id) notificationUser = self.getUser(user_id)
if not notificationUser: if not notificationUser:
raise koji.GenericError('invalid user ID: %s' % user_id) raise koji.GenericError('No such user ID: %s' % user_id)
if not (notificationUser['id'] == currentUser['id'] or self.hasPerm('admin')): if not (notificationUser['id'] == currentUser['id'] or self.hasPerm('admin')):
raise koji.GenericError('user %s cannot create notification blocks for user %s' % raise koji.GenericError('user %s cannot create notification blocks for user %s' %
@ -12993,7 +12986,7 @@ class RootExports(object):
block = self.getBuildNotificationBlock(id, strict=True) block = self.getBuildNotificationBlock(id, strict=True)
currentUser = self.getLoggedInUser() currentUser = self.getLoggedInUser()
if not currentUser: if not currentUser:
raise koji.GenericError('not logged-in') raise koji.GenericError('Not logged-in')
if not (block['user_id'] == currentUser['id'] or if not (block['user_id'] == currentUser['id'] or
self.hasPerm('admin')): self.hasPerm('admin')):
@ -13054,7 +13047,7 @@ class RootExports(object):
return _applyQueryOpts([], queryOpts) return _applyQueryOpts([], queryOpts)
table = self._searchTables.get(type) table = self._searchTables.get(type)
if not table: if not table:
raise koji.GenericError('unknown search type: %s' % type) raise koji.GenericError('No such search type: %s' % type)
if matchType == 'glob': if matchType == 'glob':
oper = 'ilike' oper = 'ilike'
@ -13396,7 +13389,7 @@ class Host(object):
if context.session.logged_in: if context.session.logged_in:
raise koji.AuthError("User %i is not a host" % context.session.user_id) raise koji.AuthError("User %i is not a host" % context.session.user_id)
else: else:
raise koji.AuthError("Not logged in") raise koji.AuthError("Not logged-in")
self.id = id self.id = id
self.same_host = (id == remote_id) self.same_host = (id == remote_id)
@ -13742,7 +13735,7 @@ class HostExports(object):
for relpath in [srpm] + rpms: for relpath in [srpm] + rpms:
fn = "%s/%s" % (uploadpath, relpath) fn = "%s/%s" % (uploadpath, relpath)
if not os.path.exists(fn): if not os.path.exists(fn):
raise koji.GenericError("no such file: %s" % fn) raise koji.GenericError("No such file: %s" % fn)
rpms = check_noarch_rpms(uploadpath, rpms, logs=logs) rpms = check_noarch_rpms(uploadpath, rpms, logs=logs)
@ -14519,7 +14512,7 @@ class HostExports(object):
pass pass
else: else:
if not ignore_unknown: if not ignore_unknown:
logger.error("Unknown file for %(group_id)s:%(artifact_id)s:%(version)s", logger.error("No such file for %(group_id)s:%(artifact_id)s:%(version)s",
maven_info) maven_info)
if build_id: if build_id:
build = get_build(build_id) build = get_build(build_id)
@ -14530,7 +14523,7 @@ class HostExports(object):
logger.error("Size mismatch, br: %i, db: %i", logger.error("Size mismatch, br: %i, db: %i",
fileinfo['size'], tag_archive['size']) fileinfo['size'], tag_archive['size'])
raise koji.BuildrootError( raise koji.BuildrootError(
'Unknown file in build environment: %s, size: %s' % 'No such file in build environment: %s, size: %s' %
('%s/%s' % (fileinfo['path'], fileinfo['filename']), fileinfo['size'])) ('%s/%s' % (fileinfo['path'], fileinfo['filename']), fileinfo['size']))
return br.updateArchiveList(archives, project) return br.updateArchiveList(archives, project)

View file

@ -155,7 +155,7 @@ class TestAddGroup(utils.CliTestCase):
handle_add_group(options, session, arguments) handle_add_group(options, session, arguments)
self.assertExitCode(ex, 1) self.assertExitCode(ex, 1)
actual = stderr.getvalue() actual = stderr.getvalue()
expected = 'Unknown tag: tag\n' expected = 'No such tag: tag\n'
self.assertMultiLineEqual(actual, expected) self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected. # Finally, assert that things were called as we expected.

View file

@ -1,12 +1,12 @@
from __future__ import absolute_import from __future__ import absolute_import
import koji import koji
import mock import mock
import unittest
from six.moves import StringIO from six.moves import StringIO
from koji_cli.commands import handle_add_notification from koji_cli.commands import handle_add_notification
from . import utils
class TestAddNotification(unittest.TestCase): class TestAddNotification(utils.CliTestCase):
def setUp(self): def setUp(self):
self.options = mock.MagicMock() self.options = mock.MagicMock()
self.options.quiet = True self.options.quiet = True
@ -114,3 +114,29 @@ class TestAddNotification(unittest.TestCase):
handle_add_notification(self.options, self.session, ['bogus']) handle_add_notification(self.options, self.session, ['bogus'])
self.session.createNotification.assert_not_called() self.session.createNotification.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_add_notification_non_exist_tag(self, stderr):
tag = 'tag_a'
expected = "Usage: %s add-notification [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such tag: %s\n" % (self.progname, self.progname, tag)
self.session.getTagID.side_effect = koji.GenericError
with self.assertRaises(SystemExit) as ex:
handle_add_notification(self.options, self.session, ['--tag', tag])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_add_notification_non_exist_pkg(self, stderr):
pkg = 'pkg_a'
expected = "Usage: %s add-notification [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such package: %s\n" % (self.progname, self.progname, pkg)
self.session.getPackageID.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_add_notification(self.options, self.session, ['--package', pkg])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)

View file

@ -1,11 +1,11 @@
from __future__ import absolute_import from __future__ import absolute_import
import mock
import os import os
import six
import sys import sys
import unittest import unittest
import mock
import six
from mock import call from mock import call
from koji_cli.commands import handle_add_pkg from koji_cli.commands import handle_add_pkg
@ -133,7 +133,7 @@ class TestAddPkg(utils.CliTestCase):
handle_add_pkg(options, session, args) handle_add_pkg(options, session, args)
self.assertExitCode(ex, 1) self.assertExitCode(ex, 1)
actual = stderr.getvalue() actual = stderr.getvalue()
expected = 'User owner does not exist\n' expected = 'No such user: %s\n' % owner
self.assertMultiLineEqual(actual, expected) self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected. # Finally, assert that things were called as we expected.
activate_session_mock.assert_not_called() activate_session_mock.assert_not_called()
@ -168,7 +168,7 @@ class TestAddPkg(utils.CliTestCase):
handle_add_pkg(options, session, args) handle_add_pkg(options, session, args)
self.assertExitCode(ex, 1) self.assertExitCode(ex, 1)
actual = stdout.getvalue() actual = stdout.getvalue()
expected = 'No such tag: tag\n' expected = 'No such tag: %s\n' % tag
self.assertMultiLineEqual(actual, expected) self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected. # Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options) activate_session_mock.assert_called_once_with(session, options)

View file

@ -0,0 +1,64 @@
from __future__ import absolute_import
from six.moves import StringIO
import mock
import koji
from koji_cli.commands import handle_add_tag_inheritance
from . import utils
class TestAddTagInheritance(utils.CliTestCase):
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
@mock.patch('sys.stderr', new_callable=StringIO)
def test_add_tag_inheritance_without_option(self, stderr):
expected = "Usage: %s add-tag-inheritance [options] <tag> <parent-tag>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: This command takes exctly two argument: " \
"a tag name or ID and that tag's new parent name " \
"or ID\n" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
handle_add_tag_inheritance(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_add_tag_inheritance_non_exist_tag(self, stderr):
tag = 'test-tag'
parent_tag = 'parent-test-tag'
expected = "Usage: %s add-tag-inheritance [options] <tag> <parent-tag>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such tag: %s\n" % (self.progname, self.progname, tag)
self.session.getTag.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_add_tag_inheritance(self.options, self.session, [tag, parent_tag])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_add_tag_inheritance_non_exist_parent_tag(self, stderr):
side_effect_result = [{'arches': 'x86_64',
'extra': {},
'id': 1,
'locked': False,
'maven_include_all': False,
'maven_support': False,
'name': 'test-tag',
'perm': None,
'perm_id': None},
None]
tag = 'test-tag'
parent_tag = 'parent-test-tag'
expected = "Usage: %s add-tag-inheritance [options] <tag> <parent-tag>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such tag: %s\n" % (self.progname, self.progname, parent_tag)
self.session.getTag.side_effect = side_effect_result
with self.assertRaises(SystemExit) as ex:
handle_add_tag_inheritance(self.options, self.session, [tag, parent_tag])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)

View file

@ -0,0 +1,85 @@
from __future__ import absolute_import
import mock
from six.moves import StringIO
import koji
from koji_cli.commands import handle_add_target
from . import utils
class TestAddTarget(utils.CliTestCase):
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
@mock.patch('sys.stderr', new_callable=StringIO)
def test_add_target_without_option(self, stderr):
expected = "Usage: %s add-target <name> <build tag> <dest tag>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Please specify a target name, a build tag, " \
"and destination tag\n" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
handle_add_target(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_add_target_non_exist_tag(self, stderr):
target = 'test-target'
tag = 'test-tag'
dest_tag = 'test-dest-tag'
expected = "No such tag: %s\n" % tag
self.session.getTag.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_add_target(self.options, self.session, [target, tag, dest_tag])
self.assertExitCode(ex, 1)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_add_target_tag_without_arch(self, stderr):
tag_info = {'arches': None,
'extra': {},
'id': 1,
'locked': False,
'maven_include_all': False,
'maven_support': False,
'name': 'test-tag',
'perm': None,
'perm_id': None}
target = 'test-target'
tag = 'test-tag'
dest_tag = 'test-dest-tag'
expected = "Build tag has no arches: %s\n" % tag
self.session.getTag.return_value = tag_info
with self.assertRaises(SystemExit) as ex:
handle_add_target(self.options, self.session, [target, tag, dest_tag])
self.assertExitCode(ex, 1)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_add_target_non_exist_dest_tag(self, stderr):
side_effect_result = [{'arches': 'x86_64',
'extra': {},
'id': 1,
'locked': False,
'maven_include_all': False,
'maven_support': False,
'name': 'test-tag',
'perm': None,
'perm_id': None
},
None,
]
target = 'test-target'
tag = 'test-tag'
dest_tag = 'test-dest-tag'
expected = "No such destination tag: %s\n" % dest_tag
self.session.getTag.side_effect = side_effect_result
with self.assertRaises(SystemExit) as ex:
handle_add_target(self.options, self.session, [target, tag, dest_tag])
self.assertExitCode(ex, 1)
self.assert_console_message(stderr, expected)

View file

@ -36,7 +36,7 @@ class TestBlockGroup(utils.CliTestCase):
handle_block_group(options, session, arguments) handle_block_group(options, session, arguments)
self.assertExitCode(ex, 1) self.assertExitCode(ex, 1)
actual = stderr.getvalue() actual = stderr.getvalue()
expected = 'Unknown tag: %s\n' % tag expected = 'No such tag: %s\n' % tag
self.assertMultiLineEqual(actual, expected) self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected. # Finally, assert that things were called as we expected.

View file

@ -0,0 +1,41 @@
from __future__ import absolute_import
import koji
import mock
from six.moves import StringIO
from koji_cli.commands import handle_block_notification
from . import utils
class TestBlockNotification(utils.CliTestCase):
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_block_notification_non_exist_tag(self, stderr):
tag = 'test-tag'
expected = "Usage: %s block-notification [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such tag: %s\n" % (self.progname, self.progname, tag)
self.session.getTagID.side_effect = koji.GenericError
with self.assertRaises(SystemExit) as ex:
handle_block_notification(self.options, self.session, ['--tag', tag])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_block_notification_non_exist_pkg(self, stderr):
pkg = 'test-pkg'
expected = "Usage: %s block-notification [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such package: %s\n" % (self.progname, self.progname, pkg)
self.session.getPackageID.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_block_notification(self.options, self.session, ['--package', pkg])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)

View file

@ -1,9 +1,10 @@
from __future__ import absolute_import from __future__ import absolute_import
import mock
import os import os
import six
import sys import sys
import mock
import six
from mock import call from mock import call
from koji_cli.commands import handle_block_pkg from koji_cli.commands import handle_block_pkg
@ -140,7 +141,7 @@ class TestBlockPkg(utils.CliTestCase):
handle_block_pkg(options, session, args) handle_block_pkg(options, session, args)
self.assertExitCode(ex, 1) self.assertExitCode(ex, 1)
actual = stderr.getvalue() actual = stderr.getvalue()
expected = 'No such tag: tag\n' expected = 'No such tag: %s\n' % tag
self.assertMultiLineEqual(actual, expected) self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected. # Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options) activate_session_mock.assert_called_once_with(session, options)

View file

@ -357,7 +357,7 @@ Task info: weburl/taskinfo?taskID=1
handle_build(self.options, self.session, args) handle_build(self.options, self.session, args)
self.assertExitCode(ex, 2) self.assertExitCode(ex, 2)
actual = stderr.getvalue() actual = stderr.getvalue()
expected = self.format_error_message( "Unknown build target: target") expected = self.format_error_message( "No such build target: target")
self.assertMultiLineEqual(actual, expected) self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected. # Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(self.session, self.options) activate_session_mock.assert_called_once_with(self.session, self.options)
@ -401,7 +401,7 @@ Task info: weburl/taskinfo?taskID=1
handle_build(self.options, self.session, args) handle_build(self.options, self.session, args)
self.assertExitCode(ex, 2) self.assertExitCode(ex, 2)
actual = stderr.getvalue() actual = stderr.getvalue()
expected = self.format_error_message("Unknown destination tag: dest_tag_name") expected = self.format_error_message("No such destination tag: dest_tag_name")
self.assertMultiLineEqual(actual, expected) self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected. # Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(self.session, self.options) activate_session_mock.assert_called_once_with(self.session, self.options)

View file

@ -202,7 +202,7 @@ Options:
expected = """Usage: %s chain-build [options] <target> <URL> [<URL> [:] <URL> [:] <URL> ...] expected = """Usage: %s chain-build [options] <target> <URL> [<URL> [:] <URL> [:] <URL> ...]
(Specify the --help global option for a list of other help options) (Specify the --help global option for a list of other help options)
%s: error: Unknown build target: target %s: error: No such build target: target
""" % (progname, progname) """ % (progname, progname)
self.assertMultiLineEqual(actual, expected) self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected. # Finally, assert that things were called as we expected.

View file

@ -94,7 +94,7 @@ clone-tag will create the destination tag if it does not already exist
self.options, self.options,
self.session, self.session,
args, args,
stderr=self.format_error_message("Unknown src-tag: src-tag"), stderr=self.format_error_message("No such src-tag: src-tag"),
activate_session=None) activate_session=None)
self.activate_session.assert_called_once() self.activate_session.assert_called_once()
self.activate_session.getTag.has_called([call('src-tag'), self.activate_session.getTag.has_called([call('src-tag'),

View file

@ -1,10 +1,11 @@
from __future__ import absolute_import from __future__ import absolute_import
from __future__ import print_function from __future__ import print_function
import unittest
import copy import copy
import mock import mock
import six import six
import unittest
from koji_cli.commands import handle_dist_repo from koji_cli.commands import handle_dist_repo
from . import utils from . import utils
@ -26,7 +27,7 @@ class TestDistRepo(utils.CliTestCase):
'arches': 'x86_64', 'arches': 'x86_64',
'maven_include_all': False, 'maven_include_all': False,
'perm_id': None 'perm_id': None
} }
def setUp(self): def setUp(self):
self.task_id = 1001 self.task_id = 1001
@ -91,10 +92,10 @@ via 'koji edit-tag -x distrepo.cancel_others=True'
arguments = [self.tag_name, self.fake_key] arguments = [self.tag_name, self.fake_key]
self.__run_test_handle_dist_repo(arguments, True) self.__run_test_handle_dist_repo(arguments, True)
self.watch_tasks.assert_called_with( self.watch_tasks.assert_called_with(
self.session, self.session,
[self.task_id], [self.task_id],
quiet=self.options.quiet, quiet=self.options.quiet,
poll_interval=self.options.poll_interval, topurl=self.options.topurl) poll_interval=self.options.poll_interval, topurl=self.options.topurl)
def test_handle_dist_repo_nowait(self): def test_handle_dist_repo_nowait(self):
arguments = [self.tag_name, self.fake_key, '--nowait'] arguments = [self.tag_name, self.fake_key, '--nowait']
@ -120,7 +121,8 @@ via 'koji edit-tag -x distrepo.cancel_others=True'
'--allow-missing-signatures', '--allow-missing-signatures',
'--skip-missing-signatures' '--skip-missing-signatures'
], ],
'err_str': 'allow_missing_signatures and skip_missing_signatures are mutually exclusive' 'err_str': 'allow_missing_signatures and skip_missing_signatures are mutually '
'exclusive'
} }
] ]
@ -137,7 +139,7 @@ via 'koji edit-tag -x distrepo.cancel_others=True'
# Case 2. Tag Error # Case 2. Tag Error
self.session.getTag.return_value = {} self.session.getTag.return_value = {}
expected = self.format_error_message('unknown tag %s' % self.tag_name) expected = self.format_error_message('No such tag: %s' % self.tag_name)
self.assert_system_exit( self.assert_system_exit(
handle_dist_repo, handle_dist_repo,
self.options, self.options,
@ -218,7 +220,7 @@ via 'koji edit-tag -x distrepo.cancel_others=True'
stderr=expected) stderr=expected)
# normal case # normal case
self.session.uploadWrapper = lambda *args, **kwargs: print ('uploadWrapper ...') self.session.uploadWrapper = lambda *args, **kwargs: print('uploadWrapper ...')
self.session.getTag.return_value.update({'arches': 'x86_64, i686'}) self.session.getTag.return_value.update({'arches': 'x86_64, i686'})
expected = 'uploadWrapper ...\n\n' expected = 'uploadWrapper ...\n\n'
arguments += ['--arch', 'x86_64', '--arch', 'i686'] arguments += ['--arch', 'x86_64', '--arch', 'i686']
@ -234,11 +236,11 @@ via 'koji edit-tag -x distrepo.cancel_others=True'
self.session.getRepo.return_value = {} self.session.getRepo.return_value = {}
expected = self.format_error_message("Can't find repo for tag: %s" % "test-repo1") expected = self.format_error_message("Can't find repo for tag: %s" % "test-repo1")
self.assert_system_exit( self.assert_system_exit(
handle_dist_repo, handle_dist_repo,
self.options, self.options,
self.session, self.session,
arguments, arguments,
stderr=expected) stderr=expected)
# Normal case, assume test-repo2 is expired # Normal case, assume test-repo2 is expired
self.session.getRepo.side_effect = [ self.session.getRepo.side_effect = [

View file

@ -1,10 +1,11 @@
from __future__ import absolute_import from __future__ import absolute_import
import mock import mock
from mock import call
import six import six
from . import utils
from koji_cli.commands import anon_handle_download_logs from koji_cli.commands import anon_handle_download_logs
from . import utils
class TestDownloadLogs(utils.CliTestCase): class TestDownloadLogs(utils.CliTestCase):
def mock_builtin_open(self, filepath, *args): def mock_builtin_open(self, filepath, *args):
@ -19,7 +20,8 @@ class TestDownloadLogs(utils.CliTestCase):
self.options.topurl = 'https://topurl' self.options.topurl = 'https://topurl'
# Mock out the xmlrpc server # Mock out the xmlrpc server
self.session = mock.MagicMock() self.session = mock.MagicMock()
self.list_task_output_all_volumes = mock.patch('koji_cli.commands.list_task_output_all_volumes').start() self.list_task_output_all_volumes = mock.patch(
'koji_cli.commands.list_task_output_all_volumes').start()
self.ensuredir = mock.patch('koji.ensuredir').start() self.ensuredir = mock.patch('koji.ensuredir').start()
self.download_file = mock.patch('koji_cli.commands.download_file').start() self.download_file = mock.patch('koji_cli.commands.download_file').start()
self.activate_session = mock.patch('koji_cli.commands.activate_session').start() self.activate_session = mock.patch('koji_cli.commands.activate_session').start()
@ -104,3 +106,12 @@ class TestDownloadLogs(utils.CliTestCase):
mock.call(123456, 'file1.log', offset=5, size=102400, volume='volume1'), mock.call(123456, 'file1.log', offset=5, size=102400, volume='volume1'),
]) ])
def test_anon_handle_download_logs_task_not_found(self):
task_id = '123333'
self.session.getTaskInfo.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_download_logs(self.options, self.session, [task_id])
self.assertExitCode(ex, 1)
actual = self.stderr.getvalue()
expected = 'No such task: %s\n' % task_id
self.assertMultiLineEqual(actual, expected)

View file

@ -1,10 +1,12 @@
from __future__ import absolute_import from __future__ import absolute_import
import mock
from mock import call
import os import os
import six
import sys import sys
import mock
import six
from mock import call
from koji_cli.commands import anon_handle_download_task from koji_cli.commands import anon_handle_download_task
from . import utils from . import utils
@ -34,7 +36,7 @@ class TestDownloadTask(utils.CliTestCase):
if target.endswith('.log') and arch is not None: if target.endswith('.log') and arch is not None:
target = "%s.%s.log" % (target.rstrip(".log"), arch) target = "%s.%s.log" % (target.rstrip(".log"), arch)
calls.append(call(url, target, quiet=None, noprogress=None, calls.append(call(url, target, quiet=None, noprogress=None,
size=total, num=i + 1)) size=total, num=i + 1))
return calls return calls
def setUp(self): def setUp(self):
@ -44,7 +46,8 @@ class TestDownloadTask(utils.CliTestCase):
self.options.topurl = 'https://topurl' self.options.topurl = 'https://topurl'
# Mock out the xmlrpc server # Mock out the xmlrpc server
self.session = mock.MagicMock() self.session = mock.MagicMock()
self.list_task_output_all_volumes = mock.patch('koji_cli.commands.list_task_output_all_volumes').start() self.list_task_output_all_volumes = mock.patch(
'koji_cli.commands.list_task_output_all_volumes').start()
self.ensuredir = mock.patch('koji.ensuredir').start() self.ensuredir = mock.patch('koji.ensuredir').start()
self.download_file = mock.patch('koji_cli.commands.download_file').start() self.download_file = mock.patch('koji_cli.commands.download_file').start()
self.ensure_connection = mock.patch('koji_cli.commands.ensure_connection').start() self.ensure_connection = mock.patch('koji_cli.commands.ensure_connection').start()
@ -102,7 +105,7 @@ class TestDownloadTask(utils.CliTestCase):
expected = '' expected = ''
self.assertMultiLineEqual(actual, expected) self.assertMultiLineEqual(actual, expected)
actual = self.stderr.getvalue() actual = self.stderr.getvalue()
expected = 'No such task: #123333\n' expected = 'No such task: %s\n' % task_id
self.assertMultiLineEqual(actual, expected) self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected. # Finally, assert that things were called as we expected.
self.ensure_connection.assert_called_once_with(self.session, self.options) self.ensure_connection.assert_called_once_with(self.session, self.options)

View file

@ -5,8 +5,10 @@ import unittest
from six.moves import StringIO from six.moves import StringIO
from koji_cli.commands import handle_edit_notification from koji_cli.commands import handle_edit_notification
from . import utils
class TestEditNotification(unittest.TestCase):
class TestEditNotification(utils.CliTestCase):
def setUp(self): def setUp(self):
self.options = mock.MagicMock() self.options = mock.MagicMock()
self.options.debug = False self.options.debug = False
@ -87,3 +89,33 @@ class TestEditNotification(unittest.TestCase):
handle_edit_notification(self.options, self.session, ['123']) handle_edit_notification(self.options, self.session, ['123'])
self.session.updateNotification.assert_not_called() self.session.updateNotification.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_edit_notification_non_exist_tag(self, stderr):
tag = 'test-tag'
expected = "Usage: %s edit-notification [options] <notification_id>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such tag: %s\n" % (self.progname, self.progname, tag)
self.session.getBuildNotification.return_value = \
{'id': 2345, 'package_id': 135, 'success_only': False}
self.session.getTagID.side_effect = koji.GenericError
with self.assertRaises(SystemExit) as ex:
handle_edit_notification(self.options, self.session, ['--tag', tag, '2345'])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_edit_notification_non_exist_pkg(self, stderr):
pkg = 'test-pkg'
expected = "Usage: %s edit-notification [options] <notification_id>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such package: %s\n" % (self.progname, self.progname, pkg)
self.session.getBuildNotification.return_value = \
{'id': 2345, 'package_id': 135, 'success_only': False}
self.session.getPackageID.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_edit_notification(self.options, self.session, ['--package', pkg, '2345'])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)

View file

@ -0,0 +1,67 @@
from __future__ import absolute_import
import mock
from six.moves import StringIO
import koji
from koji_cli.commands import handle_edit_tag_inheritance
from . import utils
class TestEditTagInheritance(utils.CliTestCase):
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
@mock.patch('sys.stderr', new_callable=StringIO)
def test_edit_tag_inheritance_without_option(self, stderr):
expected = "Usage: %s edit-tag-inheritance [options] <tag> <parent> <priority>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: This command takes at least one argument: " \
"a tag name or ID\n" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
handle_edit_tag_inheritance(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_edit_tag_inheritance_non_exist_tag(self, stderr):
tag = 'test-tag'
parent_tag = 'parent-test-tag'
priority = '99'
expected = "Usage: %s edit-tag-inheritance [options] <tag> <parent> <priority>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such tag: %s\n" % (self.progname, self.progname, tag)
self.session.getTag.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_edit_tag_inheritance(self.options, self.session,
[tag, parent_tag, priority])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_edit_tag_inheritance_non_exist_parent_tag(self, stderr):
side_effect_result = [{'arches': 'x86_64',
'extra': {},
'id': 1,
'locked': False,
'maven_include_all': False,
'maven_support': False,
'name': 'test-tag',
'perm': None,
'perm_id': None},
None]
tag = 'test-tag'
parent_tag = 'parent-test-tag'
priority = '99'
expected = "Usage: %s edit-tag-inheritance [options] <tag> <parent> <priority>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such tag: %s\n" % (self.progname, self.progname, parent_tag)
self.session.getTag.side_effect = side_effect_result
with self.assertRaises(SystemExit) as ex:
handle_edit_tag_inheritance(self.options, self.session,
[tag, parent_tag, priority])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)

View file

@ -0,0 +1,48 @@
from __future__ import absolute_import
import mock
from six.moves import StringIO
import koji
from koji_cli.commands import handle_edit_target
from . import utils
class TestEditTarget(utils.CliTestCase):
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
@mock.patch('sys.stderr', new_callable=StringIO)
def test_edit_target_without_option(self, stderr):
expected = "Usage: %s edit-target [options] <name>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Please specify a build target\n" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
handle_edit_target(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
def test_edit_target_non_exist_target(self):
target = 'test-target'
expected = "No such build target: %s" % target
self.session.getBuildTarget.return_value = None
with self.assertRaises(koji.GenericError) as cm:
handle_edit_target(self.options, self.session, [target])
self.assertEqual(expected, str(cm.exception))
self.session.getTag.assert_not_called()
self.session.editBuildTarget.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_edit_target_non_exist_dest_tag(self, stderr):
target = 'test-target'
dest_tag = 'test-dest-tag'
expected = "No such destination tag: %s\n" % dest_tag
self.session.getTag.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_edit_target(self.options, self.session, ['--dest-tag', dest_tag, target])
self.assertExitCode(ex, 1)
self.assert_console_message(stderr, expected)
self.session.editBuildTarget.assert_not_called()

View file

@ -192,7 +192,7 @@ class TestBuildImageOz(utils.CliTestCase):
_build_image_oz( _build_image_oz(
self.options, self.task_options, self.session, self.args) self.options, self.task_options, self.session, self.args)
self.assertEqual( self.assertEqual(
str(cm.exception), 'Unknown build target: %s' % self.args[2]) str(cm.exception), 'No such build target: %s' % self.args[2])
self.session.getBuildTarget.return_value = self.target_info self.session.getBuildTarget.return_value = self.target_info
self.session.getTag.return_value = {} self.session.getTag.return_value = {}
@ -201,7 +201,7 @@ class TestBuildImageOz(utils.CliTestCase):
self.options, self.task_options, self.session, self.args) self.options, self.task_options, self.session, self.args)
self.assertEqual( self.assertEqual(
str(cm.exception), str(cm.exception),
'Unknown destination tag: %s' % self.target_info['dest_tag_name']) 'No such destination tag: %s' % self.target_info['dest_tag_name'])
self.session.getTag.return_value = self.tag_info self.session.getTag.return_value = self.tag_info
with self.assertRaises(koji.GenericError) as cm: with self.assertRaises(koji.GenericError) as cm:

View file

@ -158,7 +158,7 @@ class TestBuildImageIndirection(utils.CliTestCase):
# Case 4. target not found error # Case 4. target not found error
self.session.getBuildTarget.return_value = {} self.session.getBuildTarget.return_value = {}
expected = "Unknown build target: %s" % {} expected = "No such build target: %s" % {}
with self.assertRaises(koji.GenericError) as cm: with self.assertRaises(koji.GenericError) as cm:
_build_image_indirection( _build_image_indirection(
self.options, self.task_opts, self.session, []) self.options, self.task_opts, self.session, [])
@ -168,7 +168,7 @@ class TestBuildImageIndirection(utils.CliTestCase):
# Case 5. tag not found error # Case 5. tag not found error
self.session.getBuildTarget.return_value = self.build_target self.session.getBuildTarget.return_value = self.build_target
self.session.getTag.return_value = {} self.session.getTag.return_value = {}
expected = "Unknown destination tag: %s" % self.build_target['dest_tag_name'] expected = "No such destination tag: %s" % self.build_target['dest_tag_name']
with self.assertRaises(koji.GenericError) as cm: with self.assertRaises(koji.GenericError) as cm:
_build_image_indirection( _build_image_indirection(
self.options, self.task_opts, self.session, []) self.options, self.task_opts, self.session, [])

View file

@ -0,0 +1,41 @@
from __future__ import absolute_import
import mock
from six.moves import StringIO
import koji
from koji_cli.commands import handle_import_archive
from . import utils
class TestImportArchive(utils.CliTestCase):
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
@mock.patch('sys.stderr', new_callable=StringIO)
def test_import_archive_without_option(self, stderr):
expected = "Usage: %s import-archive <build-id|n-v-r> <archive_path> [<archive_path2 ...]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: You must specify a build ID or N-V-R and " \
"an archive to import\n" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
handle_import_archive(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_import_archive_wrong_type(self, stderr):
archive_type = 'test-type'
archive_path = '/mnt/brew/work/test-archive.type'
expected = "Usage: %s import-archive <build-id|n-v-r> <archive_path> [<archive_path2 ...]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Unsupported archive type: %s\n" % (self.progname, self.progname,
archive_type)
with self.assertRaises(SystemExit) as ex:
handle_import_archive(self.options, self.session, ['--type', archive_type, '12',
archive_path])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)

View file

@ -1,10 +1,13 @@
from __future__ import absolute_import from __future__ import absolute_import
import json
import mock
import os import os
import six
import sys import sys
import unittest import unittest
import json
import mock
import six
from nose.plugins.skip import SkipTest
try: try:
import libcomps import libcomps
@ -15,13 +18,11 @@ try:
except ImportError: except ImportError:
yumcomps = None yumcomps = None
from nose.plugins.skip import SkipTest
import koji_cli.commands import koji_cli.commands
from koji_cli.commands import handle_import_comps, _import_comps,\ from koji_cli.commands import handle_import_comps, _import_comps, _import_comps_alt
_import_comps_alt
from . import utils from . import utils
class TestImportComps(utils.CliTestCase): class TestImportComps(utils.CliTestCase):
# Show long diffs in error output... # Show long diffs in error output...
maxDiff = None maxDiff = None
@ -172,7 +173,7 @@ class TestImportComps(utils.CliTestCase):
handle_import_comps(options, session, args) handle_import_comps(options, session, args)
self.assertExitCode(ex, 1) self.assertExitCode(ex, 1)
actual = stderr.getvalue() actual = stderr.getvalue()
expected = 'No such tag: tag\n' expected = 'No such tag: %s\n' % tag
self.assertMultiLineEqual(actual, expected) self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected. # Finally, assert that things were called as we expected.

View file

@ -0,0 +1,104 @@
from __future__ import absolute_import
import mock
from six.moves import StringIO
import koji
from koji_cli.commands import anon_handle_list_builds
from . import utils
class TestListBuilds(utils.CliTestCase):
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_builds_without_option(self, stderr):
expected = "Usage: %s list-builds [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Filter must be provided for list\n" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
anon_handle_list_builds(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_builds_non_exist_pkg(self, stderr):
pkg = 'test-pkg'
expected = "Usage: %s list-builds [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such package: %s\n" % (self.progname, self.progname, pkg)
self.session.getPackageID.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_list_builds(self.options, self.session,
['--package', pkg])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_builds_non_exist_owner(self, stderr):
owner = 'test-owner'
expected = "Usage: %s list-builds [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such user: %s\n" % (self.progname, self.progname, owner)
self.session.getUser.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_list_builds(self.options, self.session,
['--owner', owner])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_builds_non_exist_volume(self, stderr):
volume = 'test-volume'
expected = "Usage: %s list-builds [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such volume: %s\n" % (self.progname, self.progname, volume)
self.session.listVolumes.return_value = []
with self.assertRaises(SystemExit) as ex:
anon_handle_list_builds(self.options, self.session,
['--volume', volume])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_builds_invalid_state(self, stderr):
state = '6'
expected = "Usage: %s list-builds [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Invalid state: %s\n" % (self.progname, self.progname, state)
self.session.getTag.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_list_builds(self.options, self.session,
['--state', state])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_builds_invalid_state_string(self, stderr):
state = 'test-state'
expected = "Usage: %s list-builds [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Invalid state: %s\n" % (self.progname, self.progname, state)
self.session.getTag.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_list_builds(self.options, self.session,
['--state', state])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_builds_non_exist_build(self, stderr):
build = 222
expected = "Usage: %s list-builds [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such build: '%s'\n" % (self.progname, self.progname, build)
self.session.getBuild.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_list_builds(self.options, self.session,
['--build', build])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)

View file

@ -0,0 +1,28 @@
from __future__ import absolute_import
import mock
from six.moves import StringIO
import koji
from koji_cli.commands import anon_handle_list_hosts
from . import utils
class TestListHosts(utils.CliTestCase):
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_pkgs_non_exist_channel(self, stderr):
channel = 'test-channel'
expected = "Usage: %s list-hosts [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such channel: %s\n" % (self.progname, self.progname, channel)
self.session.getChannel.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_list_hosts(self.options, self.session, ['--channel', channel])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)

View file

@ -1,12 +1,14 @@
from __future__ import absolute_import from __future__ import absolute_import
import mock
import unittest import unittest
import mock
from six.moves import StringIO from six.moves import StringIO
import koji import koji
from koji_cli.commands import anon_handle_list_notifications from koji_cli.commands import anon_handle_list_notifications
class TestListNotifications(unittest.TestCase): class TestListNotifications(unittest.TestCase):
def setUp(self): def setUp(self):
self.options = mock.MagicMock() self.options = mock.MagicMock()
@ -29,7 +31,7 @@ class TestListNotifications(unittest.TestCase):
anon_handle_list_notifications(self.options, self.session, ['--mine']) anon_handle_list_notifications(self.options, self.session, ['--mine'])
actual = stdout.getvalue() actual = stdout.getvalue()
expected = '''\ expected = '''\
Notifications Notifications
ID Tag Package E-mail Success-only ID Tag Package E-mail Success-only
-------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------
@ -40,7 +42,7 @@ Notifications
No notification blocks No notification blocks
''' '''
self.maxDiff=None self.maxDiff = None
self.assertMultiLineEqual(actual, expected) self.assertMultiLineEqual(actual, expected)
activate_session_mock.assert_called_once() activate_session_mock.assert_called_once()
self.session.getTag.assert_has_calls([mock.call(1), mock.call(1)]) self.session.getTag.assert_has_calls([mock.call(1), mock.call(1)])
@ -74,7 +76,7 @@ No notification blocks
anon_handle_list_notifications(self.options, self.session, ['--user', 'random_name']) anon_handle_list_notifications(self.options, self.session, ['--user', 'random_name'])
actual = stdout.getvalue() actual = stdout.getvalue()
expected = '''\ expected = '''\
Notifications Notifications
ID Tag Package E-mail Success-only ID Tag Package E-mail Success-only
-------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------
@ -89,7 +91,7 @@ Notification blocks
12 * * 12 * *
''' '''
self.maxDiff=None self.maxDiff = None
self.assertMultiLineEqual(actual, expected) self.assertMultiLineEqual(actual, expected)
ensure_connection_mock.assert_called_once_with(self.session, self.options) ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_has_calls([mock.call(1), mock.call(1)]) self.session.getTag.assert_has_calls([mock.call(1), mock.call(1)])
@ -110,7 +112,6 @@ Notification blocks
self.session.getTag.assert_not_called() self.session.getTag.assert_not_called()
self.session.getPackage.assert_not_called() self.session.getPackage.assert_not_called()
@mock.patch('sys.exit') @mock.patch('sys.exit')
@mock.patch('sys.stderr', new_callable=StringIO) @mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_list_notifications_no_args(self, sys_stderr, sys_exit): def test_handle_list_notifications_no_args(self, sys_stderr, sys_exit):
@ -120,3 +121,18 @@ Notification blocks
anon_handle_list_notifications(self.options, self.session, []) anon_handle_list_notifications(self.options, self.session, [])
self.session.getBuildNotifications.assert_not_called() self.session.getBuildNotifications.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_notifications_user_non_exist_user(self, stderr):
username = 'random_name'
self.session.getUser.return_value = None
with self.assertRaises(SystemExit):
anon_handle_list_notifications(self.options, self.session,
['--user', username])
actual = stderr.getvalue()
expected = 'No such user: %s\n' % username
self.assertMultiLineEqual(actual, expected)
self.session.getBuildNotifications.assert_not_called()
self.session.getTag.assert_not_called()
self.session.getPackage.assert_not_called()

View file

@ -0,0 +1,40 @@
from __future__ import absolute_import
import mock
from six.moves import StringIO
import koji
from koji_cli.commands import anon_handle_list_pkgs
from . import utils
class TestListPkgs(utils.CliTestCase):
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_pkgs_non_exist_tag(self, stderr):
tag = 'test-tag'
expected = "Usage: %s list-pkgs [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such tag: %s\n" % (self.progname, self.progname, tag)
self.session.getTag.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_list_pkgs(self.options, self.session, ['--tag', tag])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_pkgs_non_exist_owner(self, stderr):
owner = 'test-owner'
expected = "Usage: %s list-pkgs [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such user: %s\n" % (self.progname, self.progname, owner)
self.session.getUser.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_list_pkgs(self.options, self.session, ['--owner', owner])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)

View file

@ -0,0 +1,57 @@
from __future__ import absolute_import
import mock
from six.moves import StringIO
import koji
from koji_cli.commands import anon_handle_list_tag_inheritance
from . import utils
class TestListTagInheritance(utils.CliTestCase):
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
self.tag = 'test-tag'
@mock.patch('sys.stderr', new_callable=StringIO)
def test_without_option(self, stderr):
expected = "Usage: %s list-tag-inheritance [options] <tag>\n\n" \
"Prints tag inheritance with basic information about links.\n" \
"Four flags could be seen in the output:\n" \
" M - maxdepth - limits inheritance to n-levels\n" \
" F - package filter (packages ignored for inheritance)\n" \
" I - intransitive link - inheritance immediately stops here\n" \
" N - noconfig - if tag is used in buildroot, its configuration values " \
"will not be used\n\n" \
"Exact values for maxdepth and package filter can be inquired by " \
"taginfo command.\n\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: This command takes exactly one argument: " \
"a tag name or ID\n" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
anon_handle_list_tag_inheritance(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_with_non_exist_tag(self, stderr):
expected = "Usage: %s list-tag-inheritance [options] <tag>\n\n" \
"Prints tag inheritance with basic information about links.\n" \
"Four flags could be seen in the output:\n" \
" M - maxdepth - limits inheritance to n-levels\n" \
" F - package filter (packages ignored for inheritance)\n" \
" I - intransitive link - inheritance immediately stops here\n" \
" N - noconfig - if tag is used in buildroot, its configuration values " \
"will not be used\n\n" \
"Exact values for maxdepth and package filter can be inquired by " \
"taginfo command.\n\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such tag: %s\n" % (self.progname, self.progname, self.tag)
self.session.getTag.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_list_tag_inheritance(self.options, self.session, [self.tag])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)

View file

@ -1,4 +1,3 @@
import sys
import os import os
import time import time
@ -177,8 +176,7 @@ class TestCliListTagged(utils.CliTestCase):
@mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji.util.eventFromOpts', return_value=None) @mock.patch('koji.util.eventFromOpts', return_value=None)
@mock.patch('koji_cli.commands.ensure_connection') @mock.patch('koji_cli.commands.ensure_connection')
def test_list_tagged_type_paths(self, ensure_connection_mock, def test_list_tagged_type_paths(self, ensure_connection_mock, event_from_opts_mock, stdout):
event_from_opts_mock, stdout):
args = ['tag', 'pkg', '--latest-n=3', '--type=maven', '--paths'] args = ['tag', 'pkg', '--latest-n=3', '--type=maven', '--paths']
self.session.listTagged.return_value = [{'id': 1, self.session.listTagged.return_value = [{'id': 1,
'name': 'packagename', 'name': 'packagename',

View file

@ -0,0 +1,40 @@
from __future__ import absolute_import
import mock
from six.moves import StringIO
import koji
from koji_cli.commands import anon_handle_list_tags
from . import utils
class TestListTags(utils.CliTestCase):
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_tags_non_exist_package(self, stderr):
pkg = 'test-pkg'
expected = "Usage: %s list-tags [options] [pattern]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such package: %s\n" % (self.progname, self.progname, pkg)
self.session.getPackage.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_list_tags(self.options, self.session, ['--package', pkg])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_tags_non_exist_build(self, stderr):
build = 'test-build'
expected = "Usage: %s list-tags [options] [pattern]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such build: %s\n" % (self.progname, self.progname, build)
self.session.getBuild.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_list_tags(self.options, self.session, ['--build', build])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)

View file

@ -1,16 +1,14 @@
import os import os
import re import re
import time import time
import unittest
from optparse import Values from optparse import Values
import six import six
import koji
import mock import mock
from . import utils import koji
from koji_cli.commands import anon_handle_list_targets from koji_cli.commands import anon_handle_list_targets
from . import utils
_mock_targets = [ _mock_targets = [
{ {
@ -41,7 +39,8 @@ class TestCliListTargets(utils.CliTestCase):
@mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session') @mock.patch('koji_cli.commands.activate_session')
def test_list_targets_error_args(self, ensure_connection_mock, stderr): def test_list_targets_error_args(self, ensure_connection_mock, stderr):
session = mock.MagicMock(getAPIVersion=lambda: koji.API_VERSION, getBuildTargets=lambda n: []) session = mock.MagicMock(getAPIVersion=lambda: koji.API_VERSION,
getBuildTargets=lambda n: [])
options = mock.MagicMock(quiet=False) options = mock.MagicMock(quiet=False)
with self.assertRaises(SystemExit) as ex: with self.assertRaises(SystemExit) as ex:
anon_handle_list_targets(options, session, ['aaa']) anon_handle_list_targets(options, session, ['aaa'])
@ -50,28 +49,32 @@ class TestCliListTargets(utils.CliTestCase):
@mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session') @mock.patch('koji_cli.commands.activate_session')
def test_list_targets_error_all_not_found(self, ensure_connection_mock, stderr): def test_list_targets_error_all_not_found(self, ensure_connection_mock, stderr):
session = mock.MagicMock(getAPIVersion=lambda: koji.API_VERSION, getBuildTargets=lambda n: []) session = mock.MagicMock(getAPIVersion=lambda: koji.API_VERSION,
getBuildTargets=lambda n: [])
options = mock.MagicMock(quiet=False) options = mock.MagicMock(quiet=False)
with self.assertRaises(SystemExit) as ex: with self.assertRaises(SystemExit) as ex:
anon_handle_list_targets(options, session, []) anon_handle_list_targets(options, session, [])
self.assertExitCode(ex, 2) self.assertExitCode(ex, 2)
self.assertTrue('No Targets were found' in stderr.getvalue()) self.assertTrue('No targets were found' in stderr.getvalue())
@mock.patch('optparse.OptionParser.parse_args', return_value=(Values({'quiet': False, 'name': 'f50'}), [])) @mock.patch('optparse.OptionParser.parse_args',
return_value=(Values({'quiet': False, 'name': 'f50'}), []))
@mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session') @mock.patch('koji_cli.commands.activate_session')
def test_list_targets_error_name_not_found(self, ensure_connection_mock, stderr, opt): def test_list_targets_error_name_not_found(self, ensure_connection_mock, stderr, opt):
session = mock.MagicMock(getAPIVersion=lambda: koji.API_VERSION, getBuildTargets=lambda n: []) session = mock.MagicMock(getAPIVersion=lambda: koji.API_VERSION,
getBuildTargets=lambda n: [])
options = mock.MagicMock(quiet=False) options = mock.MagicMock(quiet=False)
with self.assertRaises(SystemExit) as ex: with self.assertRaises(SystemExit) as ex:
anon_handle_list_targets(options, session, []) anon_handle_list_targets(options, session, [])
self.assertExitCode(ex, 2) self.assertExitCode(ex, 2)
self.assertTrue('Target "f50" does not exist' in stderr.getvalue()) self.assertTrue('No such build target:' in stderr.getvalue())
@mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session') @mock.patch('koji_cli.commands.activate_session')
def test_list_targets_all(self, ensure_connection_mock, stdout): def test_list_targets_all(self, ensure_connection_mock, stdout):
session = mock.MagicMock(getAPIVersion=lambda: koji.API_VERSION, getBuildTargets=lambda n: _mock_targets) session = mock.MagicMock(getAPIVersion=lambda: koji.API_VERSION,
getBuildTargets=lambda n: _mock_targets)
options = mock.MagicMock(quiet=False) options = mock.MagicMock(quiet=False)
anon_handle_list_targets(options, session, []) anon_handle_list_targets(options, session, [])
expected = [ expected = [
@ -82,11 +85,13 @@ class TestCliListTargets(utils.CliTestCase):
] ]
self.assertEqual(expected, [re.sub(' +', '|', l) for l in stdout.getvalue().split('\n')]) self.assertEqual(expected, [re.sub(' +', '|', l) for l in stdout.getvalue().split('\n')])
@mock.patch('optparse.OptionParser.parse_args', return_value=(Values({'quiet': False, 'name': 'f50'}), [])) @mock.patch('optparse.OptionParser.parse_args',
return_value=(Values({'quiet': False, 'name': 'f50'}), []))
@mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session') @mock.patch('koji_cli.commands.activate_session')
def test_list_targets_one(self, ensure_connection_mock, stdout, opt): def test_list_targets_one(self, ensure_connection_mock, stdout, opt):
session = mock.MagicMock(getAPIVersion=lambda: koji.API_VERSION, getBuildTargets=lambda n: _mock_targets) session = mock.MagicMock(getAPIVersion=lambda: koji.API_VERSION,
getBuildTargets=lambda n: _mock_targets)
options = mock.MagicMock(quiet=False) options = mock.MagicMock(quiet=False)
anon_handle_list_targets(options, session, []) anon_handle_list_targets(options, session, [])
expected = [ expected = [

View file

@ -262,7 +262,7 @@ Options:
%s maven-build --ini=CONFIG... [options] <target> %s maven-build --ini=CONFIG... [options] <target>
(Specify the --help global option for a list of other help options) (Specify the --help global option for a list of other help options)
%s: error: Unknown build target: target %s: error: No such build target: target
""" % (progname, progname, progname) """ % (progname, progname, progname)
self.assertMultiLineEqual(actual, expected) self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected. # Finally, assert that things were called as we expected.
@ -307,7 +307,7 @@ Options:
%s maven-build --ini=CONFIG... [options] <target> %s maven-build --ini=CONFIG... [options] <target>
(Specify the --help global option for a list of other help options) (Specify the --help global option for a list of other help options)
%s: error: Unknown destination tag: dest_tag %s: error: No such destination tag: dest_tag
""" % (progname, progname, progname) """ % (progname, progname, progname)
self.assertMultiLineEqual(actual, expected) self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected. # Finally, assert that things were called as we expected.
@ -536,7 +536,7 @@ Task info: weburl/taskinfo?taskID=1
%s maven-build --ini=CONFIG... [options] <target> %s maven-build --ini=CONFIG... [options] <target>
(Specify the --help global option for a list of other help options) (Specify the --help global option for a list of other help options)
%s: error: Invalid SCM URL: badscm %s: error: No such SCM URL: badscm
""" % (progname, progname, progname) """ % (progname, progname, progname)
self.assertMultiLineEqual(actual, expected) self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected. # Finally, assert that things were called as we expected.

View file

@ -60,7 +60,7 @@ class TestMavenChain(utils.CliTestCase):
# Unknonw target test # Unknonw target test
expected = self.format_error_message( expected = self.format_error_message(
"Unknown build target: %s" % self.target) "No such build target: %s" % self.target)
self.assert_system_exit( self.assert_system_exit(
handle_maven_chain, handle_maven_chain,
options, options,
@ -71,7 +71,7 @@ class TestMavenChain(utils.CliTestCase):
# Unknow destination tag test # Unknow destination tag test
session.getBuildTarget.return_value = target_info session.getBuildTarget.return_value = target_info
expected = self.format_error_message( expected = self.format_error_message(
"Unknown destination tag: %s" % target_info['dest_tag_name']) "No such destination tag: %s" % target_info['dest_tag_name'])
self.assert_system_exit( self.assert_system_exit(
handle_maven_chain, handle_maven_chain,
options, options,

View file

@ -1,7 +1,9 @@
from __future__ import absolute_import from __future__ import absolute_import
import unittest
import mock import mock
import six import six
import unittest
from koji_cli.commands import anon_handle_mock_config from koji_cli.commands import anon_handle_mock_config
from . import utils from . import utils
@ -210,7 +212,7 @@ config_opts['macros']['%distribution'] = 'Koji Testing'
self.assert_console_message(stderr, expected) self.assert_console_message(stderr, expected)
arguments = ['--tag', tag['name'], '--arch', tag['arch']] arguments = ['--tag', tag['name'], '--arch', tag['arch']]
expected = self.format_error_message("Invalid tag: %s" % tag['name']) expected = self.format_error_message("No such tag: %s" % tag['name'])
self.assert_system_exit( self.assert_system_exit(
anon_handle_mock_config, anon_handle_mock_config,
options, options,
@ -303,8 +305,7 @@ config_opts['macros']['%distribution'] = 'Koji Testing'
arguments = ['--target', target['name'], arguments = ['--target', target['name'],
'--arch', arch] '--arch', arch]
expected = self.format_error_message( expected = self.format_error_message("No such build target: %s" % target['name'])
"Invalid target: %s" % target['name'])
self.assert_system_exit( self.assert_system_exit(
anon_handle_mock_config, anon_handle_mock_config,
options, options,
@ -361,7 +362,7 @@ config_opts['macros']['%distribution'] = 'Koji Testing'
# Run it and check immediate output # Run it and check immediate output
# argument is empty # argument is empty
expected = self.format_error_message( expected = self.format_error_message(
"Please specify one of: --tag, --target, --task, --buildroot") "Please specify one of: --tag, --target, --task, --buildroot")
self.assert_system_exit( self.assert_system_exit(
anon_handle_mock_config, anon_handle_mock_config,
options, options,
@ -372,8 +373,7 @@ config_opts['macros']['%distribution'] = 'Koji Testing'
# name is specified twice case # name is specified twice case
arguments = [self.progname, '--name', 'name'] arguments = [self.progname, '--name', 'name']
expected = self.format_error_message( expected = self.format_error_message("Name already specified via option")
"Name already specified via option")
self.assert_system_exit( self.assert_system_exit(
anon_handle_mock_config, anon_handle_mock_config,
options, options,

View file

@ -1,7 +1,9 @@
from __future__ import absolute_import from __future__ import absolute_import
import unittest
import mock import mock
import six import six
import unittest
from koji_cli.commands import handle_move_build from koji_cli.commands import handle_move_build
from . import utils from . import utils
@ -48,7 +50,7 @@ class TestMoveBuild(utils.CliTestCase):
] ]
self.session.moveBuild.side_effect = tasks self.session.moveBuild.side_effect = tasks
expected = 'Invalid build %s, skipping.' % 'pkg_c-2.2-2fc26' + "\n" expected = 'No such build: %s, skipping.' % 'pkg_c-2.2-2fc26' + "\n"
for i, t in enumerate(tasks): for i, t in enumerate(tasks):
expected += "Created task %d, moving %s" % (t, pkgs[i]) + "\n" expected += "Created task %d, moving %s" % (t, pkgs[i]) + "\n"
@ -103,7 +105,7 @@ class TestMoveBuild(utils.CliTestCase):
[500, 501, 502], [601, 602, 603] [500, 501, 502], [601, 602, 603]
] ]
expected = 'Invalid package name %s, skipping.' % 'pkg_c-2.2-2fc26' + "\n" expected = 'No such package: %s, skipping.' % 'pkg_c-2.2-2fc26' + "\n"
with mock.patch('sys.stdout', new_callable=six.StringIO) as stdout: with mock.patch('sys.stdout', new_callable=six.StringIO) as stdout:
rv = handle_move_build(self.options, self.session, arguments) rv = handle_move_build(self.options, self.session, arguments)
@ -118,7 +120,8 @@ class TestMoveBuild(utils.CliTestCase):
# Case 1. without --all option # Case 1. without --all option
expected = self.format_error_message( expected = self.format_error_message(
"This command takes at least three arguments: two tags and one or more package n-v-r's") "This command takes at least three arguments: "
"two tags and one or more package n-v-r's")
for arg in [[], ['tag1'], ['tag1', 'tag2']]: for arg in [[], ['tag1'], ['tag1', 'tag2']]:
self.assert_system_exit( self.assert_system_exit(
handle_move_build, handle_move_build,
@ -130,7 +133,8 @@ class TestMoveBuild(utils.CliTestCase):
# Case 2. with --all option # Case 2. with --all option
expected = self.format_error_message( expected = self.format_error_message(
"This command, with --all, takes at least three arguments: two tags and one or more package names") "This command, with --all, takes at least three arguments: "
"two tags and one or more package names")
for arg in [['--all', 'tag1'], ['--all', 'tag1', 'tag2']]: for arg in [['--all', 'tag1'], ['--all', 'tag1', 'tag2']]:
self.assert_system_exit( self.assert_system_exit(
handle_move_build, handle_move_build,

View file

@ -1,9 +1,11 @@
from __future__ import absolute_import from __future__ import absolute_import
from __future__ import print_function from __future__ import print_function
import unittest
import copy import copy
import mock import mock
import six import six
import unittest
from koji_cli.commands import handle_regen_repo from koji_cli.commands import handle_regen_repo
from . import utils from . import utils
@ -25,7 +27,7 @@ class TestRegenRepo(utils.CliTestCase):
'arches': 'x86_64', 'arches': 'x86_64',
'maven_include_all': False, 'maven_include_all': False,
'perm_id': None 'perm_id': None
} }
def setUp(self): def setUp(self):
self.task_id = 1001 self.task_id = 1001
@ -85,7 +87,7 @@ class TestRegenRepo(utils.CliTestCase):
# show error if tag is not exist # show error if tag is not exist
self.session.getTag.return_value = {} self.session.getTag.return_value = {}
expected = self.format_error_message("No matching tag: " + self.tag_name) expected = self.format_error_message("No such tag: %s" % self.tag_name)
self.assert_system_exit( self.assert_system_exit(
handle_regen_repo, handle_regen_repo,
self.options, self.options,
@ -115,7 +117,7 @@ class TestRegenRepo(utils.CliTestCase):
# show error if target is not matched # show error if target is not matched
self.session.getBuildTarget.return_value = {} self.session.getBuildTarget.return_value = {}
expected = self.format_error_message("No matching build target: " + self.tag_name) expected = self.format_error_message("No such build target: " + self.tag_name)
self.assert_system_exit( self.assert_system_exit(
handle_regen_repo, handle_regen_repo,
self.options, self.options,
@ -143,8 +145,10 @@ class TestRegenRepo(utils.CliTestCase):
tests = [ tests = [
# [ arguments, error_string ] # [ arguments, error_string ]
[[], self.format_error_message("A tag name must be specified")], [[], self.format_error_message("A tag name must be specified")],
[['tag1', 'tag2'], self.format_error_message("Only a single tag name may be specified")], [['tag1', 'tag2'],
[['tag1', 'tag2', '--target'], self.format_error_message("Only a single target may be specified")], self.format_error_message("Only a single tag name may be specified")],
[['tag1', 'tag2', '--target'],
self.format_error_message("Only a single target may be specified")],
] ]
for test in tests: for test in tests:

View file

@ -17,30 +17,34 @@ class TestRemoveGroup(utils.CliTestCase):
%s: error: {message} %s: error: {message}
""" % (self.progname, self.progname) """ % (self.progname, self.progname)
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
@mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session') @mock.patch('koji_cli.commands.activate_session')
def test_handle_remove_group_nonexistent_tag(self, activate_session_mock, stdout, stderr): def test_handle_remove_group_nonexistent_tag(self, activate_session_mock, stderr, stdout):
tag = 'nonexistent-tag' tag = 'nonexistent-tag'
group = 'group' group = 'group'
arguments = [tag, group] arguments = [tag, group]
options = mock.MagicMock()
# Mock out the xmlrpc server # Mock out the xmlrpc server
session = mock.MagicMock() self.session.hasPerm.return_value = True
session.hasPerm.return_value = True self.session.getTag.return_value = None
session.getTag.return_value = None
with self.assertRaises(SystemExit): expected = 'No such tag: %s\n' % tag
handle_remove_group(options, session, arguments) with self.assertRaises(SystemExit) as ex:
handle_remove_group(self.options, self.session, arguments)
self.assertExitCode(ex, 1)
self.assert_console_message(stderr, expected)
# assert that things were called as we expected. # assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options) activate_session_mock.assert_called_once_with(self.session, self.options)
session.hasPerm.assert_called_once_with('admin') self.session.hasPerm.assert_called_once_with('admin')
session.getTag.assert_called_once_with(tag) self.session.getTag.assert_called_once_with(tag)
session.getTagGroups.assert_not_called() self.session.getTagGroups.assert_not_called()
session.groupListRemove.assert_not_called() self.session.groupListRemove.assert_not_called()
@mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO)
@ -49,23 +53,21 @@ class TestRemoveGroup(utils.CliTestCase):
tag = 'tag' tag = 'tag'
group = 'group' group = 'group'
arguments = [tag, group] arguments = [tag, group]
options = mock.MagicMock()
# Mock out the xmlrpc server # Mock out the xmlrpc server
session = mock.MagicMock() self.session.hasPerm.return_value = True
session.hasPerm.return_value = True self.session.getTag.return_value = tag
session.getTag.return_value = tag self.session.getTagGroups.return_value = []
session.getTagGroups.return_value = []
with self.assertRaises(SystemExit): with self.assertRaises(SystemExit):
handle_remove_group(options, session, arguments) handle_remove_group(self.options, self.session, arguments)
# assert that things were called as we expected. # assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options) activate_session_mock.assert_called_once_with(self.session, self.options)
session.hasPerm.assert_called_once_with('admin') self.session.hasPerm.assert_called_once_with('admin')
session.getTag.assert_called_once_with(tag) self.session.getTag.assert_called_once_with(tag)
session.getTagGroups.assert_called_once_with(tag, inherit=False) self.session.getTagGroups.assert_called_once_with(tag, inherit=False)
session.groupListRemove.assert_not_called() self.session.groupListRemove.assert_not_called()
@mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO)
@ -74,45 +76,40 @@ class TestRemoveGroup(utils.CliTestCase):
tag = 'tag' tag = 'tag'
group = 'group' group = 'group'
arguments = [tag, group] arguments = [tag, group]
options = mock.MagicMock()
# Mock out the xmlrpc server # Mock out the xmlrpc server
session = mock.MagicMock() self.session.hasPerm.return_value = True
session.hasPerm.return_value = True self.session.getTag.return_value = tag
session.getTag.return_value = tag self.session.getTagGroups.return_value = [
session.getTagGroups.return_value = [
{'name': 'group', 'group_id': 'groupId'}] {'name': 'group', 'group_id': 'groupId'}]
rv = handle_remove_group(options, session, arguments) rv = handle_remove_group(self.options, self.session, arguments)
# assert that things were called as we expected. # assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options) activate_session_mock.assert_called_once_with(self.session, self.options)
session.hasPerm.assert_called_once_with('admin') self.session.hasPerm.assert_called_once_with('admin')
session.getTag.assert_called_once_with(tag) self.session.getTag.assert_called_once_with(tag)
session.getTagGroups.assert_called_once_with(tag, inherit=False) self.session.getTagGroups.assert_called_once_with(tag, inherit=False)
session.groupListRemove.assert_called_once_with(tag, group) self.session.groupListRemove.assert_called_once_with(tag, group)
self.assertEqual(rv, None) self.assertEqual(rv, None)
@mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session') @mock.patch('koji_cli.commands.activate_session')
def test_handle_remove_group_error_handling(self, activate_session_mock, stdout, stderr): def test_handle_remove_group_error_handling(self, activate_session_mock, stdout, stderr):
session = mock.MagicMock()
options = mock.MagicMock()
expected = self.format_error_message( expected = self.format_error_message(
"Please specify a tag name and a group name") "Please specify a tag name and a group name")
for args in [[], ['tag'], ['tag', 'grp', 'etc']]: for args in [[], ['tag'], ['tag', 'grp', 'etc']]:
self.assert_system_exit( self.assert_system_exit(
handle_remove_group, handle_remove_group,
options, self.options,
session, self.session,
args, args,
stderr=expected, stderr=expected,
activate_session=None) activate_session=None)
# if we don't have 'tag' permission # if we don't have 'tag' permission
session.hasPerm.return_value = False self.session.hasPerm.return_value = False
with self.assertRaises(SystemExit): with self.assertRaises(SystemExit):
handle_remove_group(options, session, ['tag', 'grp']) handle_remove_group(self.options, self.session, ['tag', 'grp'])
activate_session_mock.assert_called_with(session, options) activate_session_mock.assert_called_with(self.session, self.options)

View file

@ -1,15 +1,17 @@
from __future__ import absolute_import from __future__ import absolute_import
import mock
import os import os
import six
import sys import sys
import unittest import unittest
import mock
import six
from mock import call from mock import call
from koji_cli.commands import handle_remove_pkg from koji_cli.commands import handle_remove_pkg
from . import utils from . import utils
class TestRemovePkg(utils.CliTestCase): class TestRemovePkg(utils.CliTestCase):
# Show long diffs in error output... # Show long diffs in error output...
@ -180,7 +182,7 @@ class TestRemovePkg(utils.CliTestCase):
handle_remove_pkg(options, session, args) handle_remove_pkg(options, session, args)
self.assertExitCode(ex, 1) self.assertExitCode(ex, 1)
actual = stderr.getvalue() actual = stderr.getvalue()
expected = 'No such tag: tag\n' expected = 'No such tag: %s\n' % tag
self.assertMultiLineEqual(actual, expected) self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected. # Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options) activate_session_mock.assert_called_once_with(session, options)

View file

@ -0,0 +1,36 @@
from __future__ import absolute_import
import mock
from six.moves import StringIO
import koji
from koji_cli.commands import handle_remove_tag
from . import utils
class TestRemoveTag(utils.CliTestCase):
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
@mock.patch('sys.stderr', new_callable=StringIO)
def test_remove_tag_without_option(self, stderr):
expected = "Usage: %s remove-tag [options] <name>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Please specify a tag to remove\n" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
handle_remove_tag(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_remove_tag_non_exist_tag(self, stderr):
tag = 'test-tag'
expected = "No such tag: %s\n" % tag
self.session.getTag.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_remove_tag(self.options, self.session, [tag])
self.assertExitCode(ex, 1)
self.assert_console_message(stderr, expected)

View file

@ -0,0 +1,65 @@
from __future__ import absolute_import
import mock
from six.moves import StringIO
import koji
from koji_cli.commands import handle_remove_tag_inheritance
from . import utils
class TestRemoveTagInheritance(utils.CliTestCase):
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
@mock.patch('sys.stderr', new_callable=StringIO)
def test_remove_tag_inheritance_without_option(self, stderr):
expected = "Usage: %s remove-tag-inheritance <tag> <parent> <priority>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: This command takes at least one argument: " \
"a tag name or ID\n" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
handle_remove_tag_inheritance(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_remove_tag_inheritance_non_exist_tag(self, stderr):
tag = 'test-tag'
parent_tag = 'parent-test-tag'
priority = '99'
expected = "Usage: %s remove-tag-inheritance <tag> <parent> <priority>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such tag: %s\n" % (self.progname, self.progname, tag)
self.session.getTag.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_remove_tag_inheritance(self.options, self.session, [tag, parent_tag, priority])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_remove_tag_inheritance_non_exist_parent_tag(self, stderr):
side_effect_result = [{'arches': 'x86_64',
'extra': {},
'id': 1,
'locked': False,
'maven_include_all': False,
'maven_support': False,
'name': 'test-tag',
'perm': None,
'perm_id': None},
None]
tag = 'test-tag'
parent_tag = 'parent-test-tag'
priority = '99'
expected = "Usage: %s remove-tag-inheritance <tag> <parent> <priority>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such tag: %s\n" % (self.progname, self.progname, parent_tag)
self.session.getTag.side_effect = side_effect_result
with self.assertRaises(SystemExit) as ex:
handle_remove_tag_inheritance(self.options, self.session, [tag, parent_tag, priority])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)

View file

@ -0,0 +1,37 @@
from __future__ import absolute_import
import mock
from six.moves import StringIO
import koji
from koji_cli.commands import handle_remove_target
from . import utils
class TestRemoveTarget(utils.CliTestCase):
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
@mock.patch('sys.stderr', new_callable=StringIO)
def test_remove_target_without_option(self, stderr):
expected = "Usage: %s remove-target [options] <name>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Please specify a build target to " \
"remove\n" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
handle_remove_target(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_remove_target_non_exist_target(self, stderr):
target = 'test-target'
expected = "No such build target: %s\n" % target
self.session.getBuildTarget.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_remove_target(self.options, self.session, [target])
self.assertExitCode(ex, 1)
self.assert_console_message(stderr, expected)

View file

@ -61,7 +61,7 @@ Available search types: package, build, tag, target, user, host, rpm, maven, win
{'argument': [], 'error': 'Please specify search type'}, {'argument': [], 'error': 'Please specify search type'},
{'argument': [s_type], 'error': 'Please specify search pattern'}, {'argument': [s_type], 'error': 'Please specify search pattern'},
{'argument': [s_type, s_patt], {'argument': [s_type, s_patt],
'error': 'Unknown search type: %s' % s_type} 'error': 'No such search type: %s' % s_type}
] ]
for case in cases: for case in cases:

View file

@ -224,7 +224,7 @@ class TestBuildImage(utils.CliTestCase):
# Case 2. target not found error # Case 2. target not found error
self.activate_session.reset_mock() self.activate_session.reset_mock()
self.session.getBuildTarget.return_value = {} self.session.getBuildTarget.return_value = {}
expected = "Unknown build target: %s" % self.arguments[2] expected = "No such build target: %s" % self.arguments[2]
args[-1] = img_type args[-1] = img_type
with self.assertRaises(koji.GenericError) as cm: with self.assertRaises(koji.GenericError) as cm:
_build_image(*args) _build_image(*args)
@ -235,7 +235,7 @@ class TestBuildImage(utils.CliTestCase):
self.activate_session.reset_mock() self.activate_session.reset_mock()
self.session.getBuildTarget.return_value = self.build_target self.session.getBuildTarget.return_value = self.build_target
self.session.getTag.return_value = {} self.session.getTag.return_value = {}
expected = "Unknown destination tag: %s" % self.build_target['dest_tag_name'] expected = "No such destination tag: %s" % self.build_target['dest_tag_name']
args[-1] = img_type args[-1] = img_type
with self.assertRaises(koji.GenericError) as cm: with self.assertRaises(koji.GenericError) as cm:
_build_image(*args) _build_image(*args)

View file

@ -0,0 +1,38 @@
from __future__ import absolute_import
import mock
from six.moves import StringIO
import koji
from koji_cli.commands import anon_handle_taginfo
from . import utils
class TestTaginfo(utils.CliTestCase):
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
@mock.patch('sys.stderr', new_callable=StringIO)
def test_taginfo_without_option(self, stderr):
expected = "Usage: %s taginfo [options] <tag> [<tag> ...]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Please specify a tag\n" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
anon_handle_taginfo(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_taginfo_non_exist_tag(self, stderr):
tag = 'test-tag'
expected = "Usage: %s taginfo [options] <tag> [<tag> ...]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such tag: %s\n" % (self.progname, self.progname, tag)
self.session.getBuildConfig.return_value = None
with self.assertRaises(SystemExit) as cm:
anon_handle_taginfo(self.options, self.session, [tag])
self.assertExitCode(cm, 2)
self.assert_console_message(stderr, expected)

View file

@ -0,0 +1,38 @@
from __future__ import absolute_import
import mock
from six.moves import StringIO
import koji
from koji_cli.commands import handle_unlock_tag
from . import utils
class TestUnlockTag(utils.CliTestCase):
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
@mock.patch('sys.stderr', new_callable=StringIO)
def test_unlock_tag_without_option(self, stderr):
expected = "Usage: %s unlock-tag [options] <tag> [<tag> ...]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Please specify a tag\n" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
handle_unlock_tag(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_unlock_tag_non_exist_tag(self, stderr):
tag = 'test-tag'
expected = "Usage: %s unlock-tag [options] <tag> [<tag> ...]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such tag: %s\n" % (self.progname, self.progname, tag)
self.session.getTag.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_unlock_tag(self.options, self.session, [tag])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)

View file

@ -0,0 +1,51 @@
from __future__ import absolute_import
import mock
from six.moves import StringIO
import koji
from koji_cli.commands import handle_untag_build
from . import utils
class TestUntagBuild(utils.CliTestCase):
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
@mock.patch('sys.stderr', new_callable=StringIO)
def test_untag_build_without_option(self, stderr):
expected = "Usage: %s untag-build [options] <tag> <pkg> [<pkg> ...]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: This command takes at least two arguments: " \
"a tag name/ID and one or more package " \
"n-v-r's\n" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
handle_untag_build(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_untag_build_without_option_non_latest_force(self, stderr):
expected = "Usage: %s untag-build [options] <tag> <pkg> [<pkg> ...]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Please specify a tag\n" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
handle_untag_build(self.options, self.session, ['--non-latest', '--force'])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_untag_build_non_exist_tag(self, stderr):
tag = 'test-tag'
pkg_info = {'id': 9, 'name': 'test-build'}
expected = "Usage: %s untag-build [options] <tag> <pkg> [<pkg> ...]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such tag: %s\n" % (self.progname, self.progname, tag)
self.session.getTag.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_untag_build(self.options, self.session, [tag, pkg_info['name']])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)

View file

@ -1,9 +1,12 @@
from __future__ import absolute_import from __future__ import absolute_import
from __future__ import absolute_import
from __future__ import print_function from __future__ import print_function
import unittest
import copy import copy
import mock import mock
import six import six
import unittest
from koji_cli.commands import anon_handle_wait_repo from koji_cli.commands import anon_handle_wait_repo
from . import utils from . import utils
@ -25,7 +28,7 @@ class TestWaitRepo(utils.CliTestCase):
'arches': 'x86_64', 'arches': 'x86_64',
'maven_include_all': False, 'maven_include_all': False,
'perm_id': None 'perm_id': None
} }
def setUp(self): def setUp(self):
self.task_id = 1001 self.task_id = 1001
@ -106,7 +109,8 @@ class TestWaitRepo(utils.CliTestCase):
arguments = [self.tag_name, '--target'] arguments = [self.tag_name, '--target']
self.options.quiet = False self.options.quiet = False
self.session.getBuildTarget.return_value = {'build_tag_name': self.tag_name, 'build_tag': 1} self.session.getBuildTarget.return_value = {'build_tag_name': self.tag_name,
'build_tag': 1}
self.session.getRepo.side_effect = [{}, {}, {'id': 1, 'name': 'DEFAULT'}] self.session.getRepo.side_effect = [{}, {}, {'id': 1, 'name': 'DEFAULT'}]
expected = 'Successfully waited 0:03 for a new %s repo' % self.tag_name + '\n' expected = 'Successfully waited 0:03 for a new %s repo' % self.tag_name + '\n'
self.__test_wait_repo(arguments, expected) self.__test_wait_repo(arguments, expected)
@ -143,7 +147,8 @@ class TestWaitRepo(utils.CliTestCase):
expected = 'Warning: nvr %s is not current in tag %s\n latest build in %s is %s' % \ expected = 'Warning: nvr %s is not current in tag %s\n latest build in %s is %s' % \
(builds[0], self.tag_name, self.tag_name, new_ver) + "\n" (builds[0], self.tag_name, self.tag_name, new_ver) + "\n"
expected += 'Warning: package sed is not in tag %s' % self.tag_name + '\n' expected += 'Warning: package sed is not in tag %s' % self.tag_name + '\n'
expected += 'Successfully waited 0:03 for %s to appear in the %s repo' % (pkgs, self.tag_name) + '\n' expected += 'Successfully waited 0:03 for %s to appear in the ' \
'%s repo\n' % (pkgs, self.tag_name)
self.__test_wait_repo(arguments, expected) self.__test_wait_repo(arguments, expected)
def test_anon_handle_wait_repo_with_build_timeout(self): def test_anon_handle_wait_repo_with_build_timeout(self):
@ -163,7 +168,8 @@ class TestWaitRepo(utils.CliTestCase):
] ]
self.checkForBuilds.return_value = True self.checkForBuilds.return_value = True
self.session.getRepo.return_value = {} self.session.getRepo.return_value = {}
expected = 'Unsuccessfully waited 1:02 for %s to appear in the %s repo' % (pkgs, self.tag_name) + '\n' expected = 'Unsuccessfully waited 1:02 for %s to appear in the %s ' \
'repo\n' % (pkgs, self.tag_name)
self.__test_wait_repo_timeout(arguments, expected, ret_code=1) self.__test_wait_repo_timeout(arguments, expected, ret_code=1)
def test_anon_handle_wait_repo_errors(self): def test_anon_handle_wait_repo_errors(self):
@ -172,8 +178,8 @@ class TestWaitRepo(utils.CliTestCase):
# [ arguments, error_string ] # [ arguments, error_string ]
[[], "Please specify a tag name"], [[], "Please specify a tag name"],
[['tag1', 'tag2'], "Only one tag may be specified"], [['tag1', 'tag2'], "Only one tag may be specified"],
[[self.tag_name], "Invalid tag: %s" % self.tag_name], [[self.tag_name], "No such tag: %s" % self.tag_name],
[[self.tag_name, '--target'], "Invalid build target: %s" % self.tag_name], [[self.tag_name, '--target'], "No such build target: %s" % self.tag_name],
] ]
self.session.getBuildTarget.return_value = {} self.session.getBuildTarget.return_value = {}

View file

@ -0,0 +1,78 @@
from __future__ import absolute_import
import mock
from six.moves import StringIO
import koji
from koji_cli.commands import handle_win_build
from . import utils
class TestWinBuild(utils.CliTestCase):
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
self.target = 'test-target'
self.dest_tag = 'destination-test_tag'
self.target_info = {'build_tag': 4,
'build_tag_name': 'test_tag',
'dest_tag': 5,
'dest_tag_name': self.dest_tag,
'id': 2,
'name': self.target}
self.scm_url = 'git://test.redhat.com/rpms/pkg-1.1.0' \
'?#3fab2ea42ecdc30a41daf1306154dfa04c4d64fd'
self.vm = 'test-vm'
@mock.patch('sys.stderr', new_callable=StringIO)
def test_win_build_without_option(self, stderr):
expected = "Usage: %s win-build [options] <target> <URL> <VM>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Exactly three arguments (a build target, a SCM URL, " \
"and a VM name) are required\n" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
handle_win_build(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_win_build_non_exist_build_target(self, stderr):
expected = "Usage: %s win-build [options] <target> <URL> <VM>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such build target: %s\n" % (self.progname, self.progname,
self.target)
self.session.getBuildTarget.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_win_build(self.options, self.session, [self.target, self.scm_url, self.vm])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_win_build_non_exist_dest_tag(self, stderr):
expected = "Usage: %s win-build [options] <target> <URL> <VM>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such destination tag: %s\n" % (self.progname, self.progname,
self.dest_tag)
self.session.getBuildTarget.return_value = self.target_info
self.session.getTag.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_win_build(self.options, self.session, [self.target, self.scm_url, self.vm])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_build_dest_tag_locked(self, stderr):
expected = "Usage: %s win-build [options] <target> <URL> <VM>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Destination tag %s is locked\n" % (self.progname, self.progname,
self.dest_tag)
dest_tag_info = {'name': self.dest_tag, 'locked': True}
self.session.getBuildTarget.return_value = self.target_info
self.session.getTag.return_value = dest_tag_info
with self.assertRaises(SystemExit) as ex:
handle_win_build(self.options, self.session, [self.target, self.scm_url, self.vm])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)

View file

@ -0,0 +1,13 @@
import unittest
import koji
import kojihub
class TestAddExternalRepoToTag(unittest.TestCase):
def test_with_wrong_merge_mode(self):
merge_mode = 'test-mode'
with self.assertRaises(koji.GenericError) as cm:
kojihub.add_external_repo_to_tag('tag', 'repo', 1, merge_mode=merge_mode)
self.assertEqual('No such merge mode: %s' % merge_mode, str(cm.exception))

View file

@ -0,0 +1,43 @@
import unittest
import mock
import koji
import kojihub
class TestAddGroupMember(unittest.TestCase):
def setUp(self):
self.exports = kojihub.RootExports()
self.get_user = mock.patch('kojihub.get_user').start()
def test_non_exist_user(self):
data = [{'id': 3,
'name': 'test-group',
'status': 0,
'usertype': 2,
'krb_principals': []},
None,
]
group = 'test-group'
username = 'test-user'
self.get_user.side_effect = data
with self.assertRaises(koji.GenericError) as cm:
self.exports.addGroupMember(group, username)
self.assertEqual("Not an user: %s" % username, str(cm.exception))
def test_non_exist_group(self):
data = [None,
{'id': 1,
'krb_principals': [],
'name': 'test-user',
'status': 0,
'usertype': 0}
]
group = 'test-group'
username = 'test-user'
self.get_user.side_effect = data
with self.assertRaises(koji.GenericError) as cm:
self.exports.addGroupMember(group, username)
self.assertEqual("Not a group: %s" % group, str(cm.exception))

View file

@ -33,13 +33,16 @@ class TestCGImporter(unittest.TestCase):
def test_get_metadata_is_not_instance(self): def test_get_metadata_is_not_instance(self):
x = kojihub.CG_Importer() x = kojihub.CG_Importer()
with self.assertRaises(GenericError): metadata = 42
x.get_metadata(42, '') with self.assertRaises(GenericError) as ex:
x.get_metadata(metadata, '')
self.assertEqual('Invalid type for metadata value: %s' % type(metadata), str(ex.exception))
def test_get_metadata_is_none(self): def test_get_metadata_is_none(self):
x = kojihub.CG_Importer() x = kojihub.CG_Importer()
with self.assertRaises(GenericError): with self.assertRaises(GenericError) as ex:
x.get_metadata(None, '') x.get_metadata(None, '')
self.assertEqual('No such file: metadata.json', str(ex.exception))
@mock.patch("koji.pathinfo.work") @mock.patch("koji.pathinfo.work")
def test_get_metadata_missing_json_file(self, work): def test_get_metadata_missing_json_file(self, work):
@ -170,6 +173,30 @@ class TestCGImporter(unittest.TestCase):
x.get_metadata('default.json', 'cg_importer_json') x.get_metadata('default.json', 'cg_importer_json')
x.import_metadata() x.import_metadata()
@mock.patch("kojihub.CG_Importer.get_metadata")
def test_do_import_no_such_metadata(self, get_metadata):
x = kojihub.CG_Importer()
metadata = {'metadata_version': 99,
'build': {
'name': 'f32-build-n2j8',
'version': '1.1',
'release': '1',
'epoch': 0,
'owner': 'kojiadmin'}
}
get_metadata.return_value = metadata
with self.assertRaises(koji.GenericError) as ex:
x.do_import(metadata, '/test/dir')
self.assertEqual('No such metadata version: %s' % metadata['metadata_version'],
str(ex.exception))
def test_match_componemt_wrong_component(self):
x = kojihub.CG_Importer()
components = [{'type': 'type'}]
with self.assertRaises(koji.GenericError) as ex:
x.match_components(components)
self.assertEqual('No such component type: %s' % components[0]['type'], str(ex.exception))
class TestMatchKojiFile(unittest.TestCase): class TestMatchKojiFile(unittest.TestCase):

View file

@ -0,0 +1,60 @@
import unittest
import mock
import koji
import kojihub
class TestCreateNotification(unittest.TestCase):
def setUp(self):
self.exports = kojihub.RootExports()
self.exports.getLoggedInUser = mock.MagicMock()
self.context = mock.patch('kojihub.context').start()
self.cursor = mock.MagicMock()
def test_non_exist_user(self):
user_id = 999
package_id = 555
tag_id = 111
success_only = False
logged_user = {'authtype': 2,
'id': 1,
'krb_principal': None,
'krb_principals': [],
'name': 'kojiadmin',
'status': 0,
'usertype': 0}
self.cursor.fetchone.return_value = None
self.context.cnx.cursor.return_value = self.cursor
self.exports.getLoggedInUser.return_value = logged_user
with self.assertRaises(koji.GenericError) as cm:
self.exports.createNotification(user_id, package_id, tag_id, success_only)
self.assertEqual('No such user ID: %s' % user_id, str(cm.exception))
class TestCreateNotificationBlock(unittest.TestCase):
def setUp(self):
self.exports = kojihub.RootExports()
self.exports.getLoggedInUser = mock.MagicMock()
self.context = mock.patch('kojihub.context').start()
self.cursor = mock.MagicMock()
def test_non_exist_user(self):
user_id = 999
package_id = 555
tag_id = 111
logged_user = {'authtype': 2,
'id': 1,
'krb_principal': None,
'krb_principals': [],
'name': 'kojiadmin',
'status': 0,
'usertype': 0}
self.cursor.fetchone.return_value = None
self.context.cnx.cursor.return_value = self.cursor
self.exports.getLoggedInUser.return_value = logged_user
with self.assertRaises(koji.GenericError) as cm:
self.exports.createNotificationBlock(user_id, package_id, tag_id)
self.assertEqual('No such user ID: %s' % user_id, str(cm.exception))

View file

@ -0,0 +1,20 @@
import unittest
import mock
import koji
import kojihub
class TestDeleteBuildTarget(unittest.TestCase):
def setUp(self):
self.lookup_name = mock.patch('kojihub.lookup_name').start()
self.exports = kojihub.RootExports()
def test_non_exist_target(self):
build_target = 'build-target'
self.lookup_name.return_value = None
with self.assertRaises(koji.GenericError) as cm:
self.exports.deleteBuildTarget(build_target)
self.assertEqual("No such build target: %s" % build_target, str(cm.exception))

View file

@ -0,0 +1,20 @@
import unittest
import mock
import koji
import kojihub
class TestDisableUser(unittest.TestCase):
def setUp(self):
self.exports = kojihub.RootExports()
self.get_user = mock.patch('kojihub.get_user').start()
def test_non_exist_user(self):
username = 'test-user'
self.get_user.return_value = None
with self.assertRaises(koji.GenericError) as cm:
self.exports.disableUser(username)
self.assertEqual("No such user: %s" % username, str(cm.exception))

View file

@ -0,0 +1,27 @@
import unittest
import mock
import koji
import kojihub
class TestEditBuildTarget(unittest.TestCase):
def setUp(self):
self.lookup_build_target = mock.patch('kojihub.lookup_build_target').start()
self.exports = kojihub.RootExports()
def test_non_exist_build_target(self):
session = kojihub.context.session = mock.MagicMock()
session.assertPerm = mock.MagicMock()
target_name = 'build-target'
name = 'build-target-rename'
build_tag = 'tag'
dest_tag = 'dest-tag'
self.lookup_build_target.return_value = None
with self.assertRaises(koji.GenericError) as cm:
self.exports.editBuildTarget(target_name, name, build_tag, dest_tag)
self.assertEqual("No such build target: %s" % target_name,
str(cm.exception))
session.assertPerm.called_once_with('target')

View file

@ -0,0 +1,20 @@
import unittest
import mock
import koji
import kojihub
class TestEnableUser(unittest.TestCase):
def setUp(self):
self.exports = kojihub.RootExports()
self.get_user = mock.patch('kojihub.get_user').start()
def test_non_exist_user(self):
username = 'test-user'
self.get_user.return_value = None
with self.assertRaises(koji.GenericError) as cm:
self.exports.enableUser(username)
self.assertEqual("No such user: %s" % username, str(cm.exception))

View file

@ -0,0 +1,47 @@
import unittest
import mock
import koji
import kojihub
class TestFindBuildId(unittest.TestCase):
def setUp(self):
self.context = mock.patch('kojihub.context').start()
self.cursor = mock.MagicMock()
def test_non_exist_build_dict(self):
build = {
'name': 'test_name',
'version': 'test_version',
'release': 'test_release',
}
self.cursor.fetchone.return_value = None
self.context.cnx.cursor.return_value = self.cursor
with self.assertRaises(koji.GenericError) as cm:
kojihub.find_build_id(build, strict=True)
self.assertEqual("No such build: %s" % build, str(cm.exception))
def test_invalid_argument(self):
build = ['test-build']
self.cursor.fetchone.return_value = None
self.context.cnx.cursor.return_value = self.cursor
with self.assertRaises(koji.GenericError) as cm:
kojihub.find_build_id(build)
self.assertEqual("Invalid type for argument: %s" % type(build), str(cm.exception))
def test_build_dict_without_release(self):
build = {
'name': 'test_name',
'version': 'test_version',
'epoch': 'test_epoch',
'owner': 'test_owner',
'extra': {'extra_key': 'extra_value'},
}
self.cursor.fetchone.return_value = None
self.context.cnx.cursor.return_value = self.cursor
with self.assertRaises(koji.GenericError) as cm:
kojihub.find_build_id(build, strict=True)
self.assertEqual("did not provide name, version, and release", str(cm.exception))

View file

@ -31,7 +31,7 @@ class TestGetPackageID(DBQueryTestCase):
'strict': True, 'strict': True,
'self': mock.ANY}) 'self': mock.ANY})
self.assertEqual(cm.exception.args[0], self.assertEqual(cm.exception.args[0],
'Invalid package name: invalidpkg') 'No such package name: invalidpkg')
def test_getPackageID_None(self): def test_getPackageID_None(self):
rv = kojihub.RootExports().getPackageID('invalidpkg') rv = kojihub.RootExports().getPackageID('invalidpkg')

View file

@ -0,0 +1,38 @@
import unittest
import mock
import koji
import kojihub
class TestGetRPM(unittest.TestCase):
def test_wrong_type_rpminfo(self):
rpminfo = ['test-user']
with self.assertRaises(koji.GenericError) as cm:
kojihub.get_rpm(rpminfo)
self.assertEqual("Invalid type for rpminfo: %s" % type(rpminfo), str(cm.exception))
class TestGetRPMHeaders(unittest.TestCase):
def setUp(self):
self.exports = kojihub.RootExports()
self.exports.getLoggedInUser = mock.MagicMock()
self.context = mock.patch('kojihub.context').start()
self.cursor = mock.MagicMock()
def test_taskid_invalid_path(self):
self.cursor.fetchone.return_value = None
self.context.cnx.cursor.return_value = self.cursor
filepath = '../test/path'
with self.assertRaises(koji.GenericError) as cm:
self.exports.getRPMHeaders(taskID=99, filepath=filepath)
self.assertEqual("Invalid filepath: %s" % filepath, str(cm.exception))
def test_taskid_without_filepath(self):
self.cursor.fetchone.return_value = None
self.context.cnx.cursor.return_value = self.cursor
with self.assertRaises(koji.GenericError) as cm:
self.exports.getRPMHeaders(taskID=99)
self.assertEqual("filepath must be specified with taskID", str(cm.exception))

View file

@ -0,0 +1,37 @@
import mock
import koji
import kojihub
from .utils import DBQueryTestCase
class TestGetBuild(DBQueryTestCase):
def setUp(self):
super(TestGetBuild, self).setUp()
self.find_build_id = mock.patch('kojihub.find_build_id').start()
def test_non_exist_build_string(self):
build = 'build-1-23'
self.find_build_id.side_effect = koji.GenericError('No such build: %s' % build)
with self.assertRaises(koji.GenericError) as cm:
kojihub.get_build(build, strict=True)
self.assertEqual('No such build: %s' % build, str(cm.exception))
def test_non_exist_build_int(self):
build = 11
self.find_build_id.return_value = build
with self.assertRaises(koji.GenericError) as cm:
kojihub.get_build(build, strict=True)
self.assertEqual('No such build: %s' % build, str(cm.exception))
def test_non_exist_build_dict(self):
build = {
'name': 'test_name',
'version': 'test_version',
'release': 'test_release',
}
self.find_build_id.side_effect = koji.GenericError('No such build: %s' % build['name'])
with self.assertRaises(koji.GenericError) as cm:
kojihub.get_build(build, strict=True)
self.assertEqual('No such build: %s' % build['name'], str(cm.exception))

View file

@ -0,0 +1,28 @@
import unittest
import mock
import koji
import kojihub
class TestGetBuildTarget(unittest.TestCase):
def setUp(self):
self.get_build_targets = mock.patch('kojihub.get_build_targets').start()
self.exports = kojihub.RootExports()
def test_non_exist_build_target(self):
build_target = 'build-target'
self.get_build_targets.return_value = []
with self.assertRaises(koji.GenericError) as cm:
self.exports.getBuildTarget(build_target, strict=True)
self.assertEqual("No such build target: %s" % build_target, str(cm.exception))
def test_wrong_type_build_target(self):
build_target = {'info_key': 'info_value'}
expected = "Invalid type for lookup: %s" % type(build_target)
self.get_build_targets.side_effect = koji.GenericError(expected)
with self.assertRaises(koji.GenericError) as cm:
self.exports.getBuildTarget(build_target, strict=True)
self.assertEqual(expected, str(cm.exception))

View file

@ -0,0 +1,65 @@
import unittest
import mock
import koji
import kojihub
from koji.util import joinpath
class TestGetChangelogEntries(unittest.TestCase):
def setUp(self):
self.exports = kojihub.RootExports()
self.get_build = mock.patch('kojihub.get_build').start()
self.context = mock.patch('kojihub.context').start()
self.cursor = mock.MagicMock()
self.os_path_exists = mock.patch('os.path.exists').start()
def test_non_exist_build(self):
build_id = 1
self.cursor.fetchone.return_value = None
self.context.cnx.cursor.return_value = self.cursor
self.get_build.return_value = None
with self.assertRaises(koji.GenericError) as cm:
self.exports.getChangelogEntries(buildID=build_id, strict=True)
self.assertEqual("No such build: %s" % build_id, str(cm.exception))
def test_taskid_invalid_path(self):
filepath = '../test/path'
with self.assertRaises(koji.GenericError) as cm:
self.exports.getChangelogEntries(taskID=99, filepath=filepath)
self.assertEqual("Invalid filepath: %s" % filepath, str(cm.exception))
def test_taskid_without_filepath(self):
with self.assertRaises(koji.GenericError) as cm:
self.exports.getChangelogEntries(taskID=99)
self.assertEqual("filepath must be specified with taskID", str(cm.exception))
def test_before_invalid_type(self):
before = {'before': '1133456'}
filepath = 'test/path'
self.os_path_exists.return_value = True
with self.assertRaises(koji.GenericError) as cm:
self.exports.getChangelogEntries(taskID=99, before=before, filepath=filepath)
self.assertEqual("Invalid type for before: %s" % type(before), str(cm.exception))
def test_after_invalid_type(self):
after = {'after': '1133456'}
filepath = 'test/path'
self.os_path_exists.return_value = True
with self.assertRaises(koji.GenericError) as cm:
self.exports.getChangelogEntries(taskID=99, after=after, filepath=filepath)
self.assertEqual("Invalid type for after: %s" % type(after), str(cm.exception))
def test_srpm_path_not_exist(self):
filepath = 'test/path'
task_id = 99
srpm_path = joinpath(koji.pathinfo.work(),
koji.pathinfo.taskrelpath(task_id),
filepath)
self.os_path_exists.return_value = False
with self.assertRaises(koji.GenericError) as cm:
self.exports.getChangelogEntries(taskID=task_id, filepath=filepath, strict=True)
self.assertEqual("SRPM %s doesn't exist" % srpm_path, str(cm.exception))

View file

@ -0,0 +1,22 @@
import unittest
import koji
import kojihub
class TestGetChannel(unittest.TestCase):
def test_wrong_type_channelInfo(self):
# dict
channel_info = {'channel': 'val'}
with self.assertRaises(koji.GenericError) as cm:
kojihub.get_channel(channel_info)
self.assertEqual('Invalid type for channelInfo: %s' % type(channel_info),
str(cm.exception))
#list
channel_info = ['channel']
with self.assertRaises(koji.GenericError) as cm:
kojihub.get_channel(channel_info)
self.assertEqual('Invalid type for channelInfo: %s' % type(channel_info),
str(cm.exception))

View file

@ -0,0 +1,20 @@
import unittest
import mock
import koji
import kojihub
class TestGetExternalRepo(unittest.TestCase):
def setUp(self):
self.get_external_repos = mock.patch('kojihub.get_external_repos').start()
self.exports = kojihub.RootExports()
def test_non_exist_repo(self):
repo = 'test-repo'
self.get_external_repos.return_value = []
with self.assertRaises(koji.GenericError) as cm:
self.exports.getExternalRepo(repo, strict=True)
self.assertEqual("No such repo: %s" % repo, str(cm.exception))

View file

@ -144,3 +144,9 @@ class TestGetExternalRepos(DBQueryTestCase):
self.assertEqual(rv, [{'id': 1, self.assertEqual(rv, [{'id': 1,
'name': 'ext_repo_1', 'name': 'ext_repo_1',
'url': 'http://example.com/repo/'}]) 'url': 'http://example.com/repo/'}])
def test_get_external_repos_wrong_type(self):
info = {'info_key': 'info_value'}
with self.assertRaises(koji.GenericError) as cm:
kojihub.get_external_repos(info=info)
self.assertEqual("Invalid type for lookup: %s" % type(info), str(cm.exception))

View file

@ -0,0 +1,20 @@
import unittest
import mock
import koji
import kojihub
class TestGetGroupMembers(unittest.TestCase):
def setUp(self):
self.get_user = mock.patch('kojihub.get_user').start()
self.exports = kojihub.RootExports()
def test_non_exist_group(self):
group = 'test-group'
self.get_user.return_value = []
with self.assertRaises(koji.GenericError) as cm:
self.exports.getGroupMembers(group)
self.assertEqual("No such group: %s" % group, str(cm.exception))

View file

@ -1,6 +1,7 @@
import mock
import unittest import unittest
import mock
import koji import koji
import kojihub import kojihub
@ -17,7 +18,7 @@ class TestSetHostEnabled(unittest.TestCase):
def setUp(self): def setUp(self):
self.QueryProcessor = mock.patch('kojihub.QueryProcessor', self.QueryProcessor = mock.patch('kojihub.QueryProcessor',
side_effect=self.getQuery).start() side_effect=self.getQuery).start()
self.queries = [] self.queries = []
self.context = mock.patch('kojihub.context').start() self.context = mock.patch('kojihub.context').start()
# It seems MagicMock will not automatically handle attributes that # It seems MagicMock will not automatically handle attributes that
@ -33,12 +34,12 @@ class TestSetHostEnabled(unittest.TestCase):
self.assertEqual(len(self.queries), 1) self.assertEqual(len(self.queries), 1)
query = self.queries[0] query = self.queries[0]
columns = ['host.id', 'host.user_id', 'host.name', 'host.ready', columns = ['host.id', 'host.user_id', 'host.name', 'host.ready',
'host.task_load', 'host_config.arches', 'host.task_load', 'host_config.arches',
'host_config.capacity', 'host_config.description', 'host_config.capacity', 'host_config.description',
'host_config.comment', 'host_config.enabled'] 'host_config.comment', 'host_config.enabled']
joins = ['host ON host.id = host_config.host_id'] joins = ['host ON host.id = host_config.host_id']
aliases = ['id', 'user_id', 'name', 'ready', 'task_load', aliases = ['id', 'user_id', 'name', 'ready', 'task_load',
'arches', 'capacity', 'description', 'comment', 'enabled'] 'arches', 'capacity', 'description', 'comment', 'enabled']
clauses = ['(host_config.active = TRUE)', 'host.name = %(hostInfo)s'] clauses = ['(host_config.active = TRUE)', 'host.name = %(hostInfo)s']
values = {'hostInfo': 'hostname'} values = {'hostInfo': 'hostname'}
self.assertEqual(query.tables, ['host_config']) self.assertEqual(query.tables, ['host_config'])
@ -54,14 +55,15 @@ class TestSetHostEnabled(unittest.TestCase):
self.assertEqual(len(self.queries), 1) self.assertEqual(len(self.queries), 1)
query = self.queries[0] query = self.queries[0]
columns = ['host.id', 'host.user_id', 'host.name', 'host.ready', columns = ['host.id', 'host.user_id', 'host.name', 'host.ready',
'host.task_load', 'host_config.arches', 'host.task_load', 'host_config.arches',
'host_config.capacity', 'host_config.description', 'host_config.capacity', 'host_config.description',
'host_config.comment', 'host_config.enabled'] 'host_config.comment', 'host_config.enabled']
joins = ['host ON host.id = host_config.host_id'] joins = ['host ON host.id = host_config.host_id']
aliases = ['id', 'user_id', 'name', 'ready', 'task_load', aliases = ['id', 'user_id', 'name', 'ready', 'task_load',
'arches', 'capacity', 'description', 'comment', 'enabled'] 'arches', 'capacity', 'description', 'comment', 'enabled']
clauses = ['(host_config.create_event <= 345 AND ( host_config.revoke_event IS NULL OR 345 < host_config.revoke_event ))', clauses = ['(host_config.create_event <= 345 AND ( host_config.revoke_event IS NULL '
'host.id = %(hostInfo)i'] 'OR 345 < host_config.revoke_event ))',
'host.id = %(hostInfo)i']
values = {'hostInfo': 123} values = {'hostInfo': 123}
self.assertEqual(query.tables, ['host_config']) self.assertEqual(query.tables, ['host_config'])
self.assertEqual(query.joins, joins) self.assertEqual(query.joins, joins)
@ -77,19 +79,21 @@ class TestSetHostEnabled(unittest.TestCase):
def test_get_host_missing(self): def test_get_host_missing(self):
self.QueryProcessor.side_effect = self.getQueryMissing self.QueryProcessor.side_effect = self.getQueryMissing
host_id = 123
r = self.exports.getHost(123) r = self.exports.getHost(host_id)
self.assertEqual(r, None) self.assertEqual(r, None)
with self.assertRaises(koji.GenericError): with self.assertRaises(koji.GenericError) as cm:
self.exports.getHost(123, strict=True) self.exports.getHost(host_id, strict=True)
self.assertEqual("Invalid hostInfo: %s" % host_id, str(cm.exception))
self.assertEqual(len(self.queries), 2) self.assertEqual(len(self.queries), 2)
self.QueryProcessor.side_effect = self.getQuery self.QueryProcessor.side_effect = self.getQuery
def test_get_host_invalid_hostinfo(self): def test_get_host_invalid_hostinfo(self):
with self.assertRaises(koji.GenericError): host_info = {'host_id': 567}
self.exports.getHost({'host_id': 567}) with self.assertRaises(koji.GenericError) as cm:
self.exports.getHost(host_info)
self.assertEqual("Invalid type for hostInfo: %s" % type(host_info), str(cm.exception))
self.assertEqual(len(self.queries), 0) self.assertEqual(len(self.queries), 0)

View file

@ -0,0 +1,16 @@
import unittest
import koji
import kojihub
class TestGetLastEvent(unittest.TestCase):
def setUp(self):
self.exports = kojihub.RootExports()
def test_wrong_type_before(self):
before = '12345'
with self.assertRaises(koji.GenericError) as cm:
self.exports.getLastEvent(before)
self.assertEqual("Invalid type for before: %s" % type(before), str(cm.exception))

View file

@ -0,0 +1,51 @@
import unittest
import koji
import kojihub
class TestGetUser(unittest.TestCase):
def setUp(self):
self.exports = kojihub.RootExports()
def test_wrong_format_user_info(self):
userinfo = ['test-user']
with self.assertRaises(koji.GenericError) as cm:
self.exports.getUser(userinfo)
self.assertEqual("Invalid type for userInfo: %s" % type(userinfo), str(cm.exception))
def test_wrong_format_userid(self):
userinfo = {'id': '123456'}
with self.assertRaises(koji.GenericError) as cm:
self.exports.getUser(userinfo)
self.assertEqual("Invalid type for userid: %s" % type(userinfo['id']), str(cm.exception))
def test_wrong_format_username(self):
userinfo = {'name': 57896}
with self.assertRaises(koji.GenericError) as cm:
self.exports.getUser(userinfo)
self.assertEqual("Invalid type for username: %s" % type(userinfo['name']),
str(cm.exception))
def test_wrong_format_krb_principal(self):
userinfo = {'krb_principal': 57896}
with self.assertRaises(koji.GenericError) as cm:
self.exports.getUser(userinfo)
self.assertEqual("Invalid type for krb_principal: %s" % type(userinfo['krb_principal']),
str(cm.exception))
class TestGetUserByKrbPrincipal(unittest.TestCase):
def test_wrong_type_krb_principal(self):
krb_principal = ['test-user']
with self.assertRaises(koji.GenericError) as cm:
kojihub.get_user_by_krb_principal(krb_principal)
self.assertEqual("Invalid type for krb_principal: %s" % type(krb_principal),
str(cm.exception))
def test_krb_principal_none(self):
krb_principal = None
with self.assertRaises(koji.GenericError) as cm:
kojihub.get_user_by_krb_principal(krb_principal)
self.assertEqual("No kerberos principal provided", str(cm.exception))

View file

@ -19,9 +19,12 @@ class TestImportRPM(unittest.TestCase):
# Touch a file # Touch a file
with open(self.src_filename, 'w'): with open(self.src_filename, 'w'):
pass pass
self.context = mock.patch('kojihub.context').start()
self.cursor = mock.MagicMock()
self.rpm_header_retval = { self.rpm_header_retval = {
'filename': 'name-version-release.arch.rpm', 'filename': 'name-version-release.arch.rpm',
'sourcepackage': 2,
1000: 'name', 1000: 'name',
1001: 'version', 1001: 'version',
1002: 'release', 1002: 'release',
@ -164,6 +167,36 @@ class TestImportRPM(unittest.TestCase):
} }
_dml.assert_called_once_with(statement, values) _dml.assert_called_once_with(statement, values)
@mock.patch('os.path.exists')
def test_non_exist_file(self, os_path_exist):
exports = kojihub.RootExports()
basename = 'rpm-1-34'
uploadpath = koji.pathinfo.work()
filepath = '%s/%s/%s' % (uploadpath, self.filename, basename)
os_path_exist.return_value = False
with self.assertRaises(koji.GenericError) as cm:
exports.importRPM(self.filename, basename)
self.assertEqual("No such file: %s" % filepath, str(cm.exception))
@mock.patch('koji.get_rpm_header')
@mock.patch('os.path.exists')
@mock.patch('os.path.basename')
def test_non_exist_file(self, os_path_basename, os_path_exist, get_rpm_header):
self.cursor.fetchone.return_value = None
self.context.cnx.cursor.return_value = self.cursor
retval = copy.copy(self.rpm_header_retval)
retval.update({
'filename': 'name-version-release.arch.rpm',
'sourcepackage': 2
})
get_rpm_header.return_value = retval
os_path_exist.return_value = True
os_path_basename.return_value = 'name-version-release.arch.rpm'
kojihub.get_build.return_value = None
with self.assertRaises(koji.GenericError) as cm:
kojihub.import_rpm(self.src_filename)
self.assertEqual("No such build", str(cm.exception))
class TestImportBuild(unittest.TestCase): class TestImportBuild(unittest.TestCase):
def setUp(self): def setUp(self):
@ -283,3 +316,12 @@ class TestImportBuild(unittest.TestCase):
'id': mock.ANY, 'id': mock.ANY,
} }
_dml.assert_called_once_with(statement, values) _dml.assert_called_once_with(statement, values)
@mock.patch('os.path.exists')
def test_import_build_non_exist_file(self, os_path_exists):
uploadpath = koji.pathinfo.work()
os_path_exists.return_value = False
with self.assertRaises(koji.GenericError) as cm:
kojihub.import_build(self.src_filename, [self.filename])
self.assertEqual("No such file: %s/%s" % (uploadpath, self.src_filename),
str(cm.exception))

View file

@ -0,0 +1,14 @@
import unittest
import koji
import kojihub
class TestListRpms(unittest.TestCase):
def test_wrong_type_arches(self):
arches = {'test-arch': 'val'}
with self.assertRaises(koji.GenericError) as cm:
kojihub.list_rpms(arches=arches)
self.assertEqual('Invalid type for "arches" parameter: %s' % type(arches),
str(cm.exception))

View file

@ -0,0 +1,45 @@
import unittest
import mock
import koji
import kojihub
class TestListTags(unittest.TestCase):
def setUp(self):
self.get_build = mock.patch('kojihub.get_build').start()
self.exports = kojihub.RootExports()
self.context = mock.patch('kojihub.context').start()
self.cursor = mock.MagicMock()
def test_non_exist_build(self):
build_id = 999
self.get_build.return_value = None
with self.assertRaises(koji.GenericError) as cm:
self.exports.listTags(build=build_id)
self.assertEqual("No such build: %s" % build_id, str(cm.exception))
build_name = 'test-build-1-23'
self.get_build.return_value = None
with self.assertRaises(koji.GenericError) as cm:
self.exports.listTags(build=build_name)
self.assertEqual("No such build: %s" % build_name, str(cm.exception))
def test_non_exist_package(self):
package_id = 999
self.cursor.fetchone.return_value = None
self.context.cnx.cursor.return_value = self.cursor
kojihub.lookup_package.return_value = koji.GenericError
with self.assertRaises(koji.GenericError) as cm:
self.exports.listTags(package=package_id)
self.assertEqual("No such package: %s" % package_id, str(cm.exception))
package_name = 'test-pkg'
self.cursor.fetchone.return_value = None
self.context.cnx.cursor.return_value = self.cursor
kojihub.lookup_package.return_value = koji.GenericError
with self.assertRaises(koji.GenericError) as cm:
self.exports.listTags(package=package_name)
self.assertEqual("No such package: %s" % package_name, str(cm.exception))

View file

@ -0,0 +1,18 @@
import unittest
import mock
import koji
import kojihub
class TestListUserKrbPrincipals(unittest.TestCase):
def setUp(self):
self.exports = kojihub.RootExports()
def test_wrong_format_user_info(self):
userinfo = ['test-user']
with self.assertRaises(koji.GenericError) as cm:
kojihub.list_user_krb_principals(userinfo)
self.assertEqual("Invalid type for user_info: %s" % type(userinfo), str(cm.exception))

View file

@ -151,7 +151,8 @@ class TestNewBuild(unittest.TestCase):
'extra': {'extra_key': CantDoJSON()}, 'extra': {'extra_key': CantDoJSON()},
} }
with self.assertRaises(koji.GenericError): with self.assertRaises(koji.GenericError) as cm:
kojihub.new_build(data) kojihub.new_build(data)
self.assertEqual(len(self.inserts), 0) self.assertEqual(len(self.inserts), 0)
self.assertEqual("No such build extra data: %(extra)r" % data, str(cm.exception))

View file

@ -257,14 +257,26 @@ class TestPkglistBlock(unittest.TestCase):
readPackageList.return_value = {} readPackageList.return_value = {}
# package needs to be name, not dict # package needs to be name, not dict
with self.assertRaises(koji.GenericError): with self.assertRaises(koji.GenericError) as ex:
kojihub._direct_pkglist_add(tag['name'], pkg, kojihub._direct_pkglist_add(tag['name'], pkg,
user['name'], block=block, extra_arches=extra_arches, user['name'], block=block, extra_arches=extra_arches,
force=force, update=update, policy=policy) force=force, update=update, policy=policy)
self.assertEqual("No such package: %s" % pkg, str(ex.exception))
lookup_package.assert_called_once_with(pkg, strict=False) @mock.patch('kojihub.get_tag')
self.assertEqual(self.run_callbacks.call_count, 0) @mock.patch('kojihub.lookup_package')
_pkglist_add.assert_not_called() def test_direct_pkglist_add_pkginfo_dict(self, lookup_package, get_tag):
pkg = {'id': 2, 'name': 'pkg', 'owner_id': 3}
user = 'user'
tag = {'id': 1, 'name': 'tag'}
expected = "Invalid type for id lookup: %s" % pkg
get_tag.return_value = tag
lookup_package.side_effect = koji.GenericError(expected)
with self.assertRaises(koji.GenericError) as ex:
kojihub._direct_pkglist_add(tag['name'], pkg, user, block=False, extra_arches='arch',
force=False, update=True)
self.assertEqual(expected, str(ex.exception))
@mock.patch('kojihub._pkglist_add') @mock.patch('kojihub._pkglist_add')
@mock.patch('kojihub.readPackageList') @mock.patch('kojihub.readPackageList')

View file

@ -0,0 +1,21 @@
import unittest
import koji
import kojihub
class TestSearch(unittest.TestCase):
def setUp(self):
self.exports = kojihub.RootExports()
def test_empty_terms(self):
with self.assertRaises(koji.GenericError) as cm:
self.exports.search('', 'type', 'glob')
self.assertEqual("empty search terms", str(cm.exception))
def test_wrong_type(self):
type = 'test-type'
with self.assertRaises(koji.GenericError) as cm:
self.exports.search('item', type, 'glob')
self.assertEqual("No such search type: %s" % type, str(cm.exception))

View file

@ -146,3 +146,33 @@ class TestTagBuild(unittest.TestCase):
self.assertEqual(update.data, data) self.assertEqual(update.data, data)
self.assertEqual(update.values, values) self.assertEqual(update.values, values)
update = self.updates[0] update = self.updates[0]
class TestGetTag(unittest.TestCase):
def getQuery(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = mock.MagicMock()
query.executeOne = self.query_executeOne
query.iterate = mock.MagicMock()
self.queries.append(query)
return query
def setUp(self):
self.query_executeOne = mock.MagicMock()
self.QueryProcessor = mock.patch('kojihub.QueryProcessor',
side_effect=self.getQuery).start()
self.queries = []
def test_get_tag_invalid_taginfo(self):
taginfo = {'test-tag': 'value'}
with self.assertRaises(koji.GenericError) as ex:
kojihub.get_tag(taginfo, strict=True)
self.assertEqual("Invalid type for tagInfo: %s" % type(taginfo), str(ex.exception))
def test_get_tag_non_exist_tag(self):
taginfo = 'test-tag'
self.query_executeOne.return_value = None
with self.assertRaises(koji.GenericError) as ex:
kojihub.get_tag(taginfo, strict=True)
self.assertEqual("No such tagInfo: '%s'" % taginfo, str(ex.exception))