From 0828c0262cb1308646c512c1756742c0aa494b32 Mon Sep 17 00:00:00 2001 From: Jana Cupova Date: Mar 15 2021 10:03:30 +0000 Subject: Unify error messages Unify error messages for CLI Unify error messages for hub Fixes: https://pagure.io/koji/issue/2720 --- diff --git a/cli/koji_cli/commands.py b/cli/koji_cli/commands.py index 8330886..6fefa1d 100644 --- a/cli/koji_cli/commands.py +++ b/cli/koji_cli/commands.py @@ -82,7 +82,7 @@ def handle_add_group(goptions, session, args): dsttag = session.getTag(tag) 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)]) group_id = groups.get(group, None) @@ -108,7 +108,7 @@ def handle_block_group(goptions, session, args): dsttag = session.getTag(tag) 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)]) group_id = groups.get(group, None) @@ -134,7 +134,7 @@ def handle_remove_group(goptions, session, args): dsttag = session.getTag(tag) 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)]) group_id = groups.get(group, None) @@ -341,7 +341,7 @@ def handle_add_pkg(goptions, session, args): if not options.owner: parser.error(_("Please specify an owner for the package(s)")) 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) tag = args[0] opts = {} @@ -498,12 +498,12 @@ def handle_build(options, session, args): else: build_target = session.getBuildTarget(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']) 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: - parser.error(_("Destination tag %s is locked" % dest_tag['name'])) + parser.error(_("Destination tag %s is locked") % dest_tag['name']) source = args[1] opts = {} if build_opts.arch_override: @@ -558,10 +558,10 @@ def handle_chain_build(options, session, args): target = args[0] build_target = session.getBuildTarget(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) 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 # 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] build_target = session.getBuildTarget(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']) 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: - parser.error(_("Destination tag %s is locked" % dest_tag['name'])) + parser.error(_("Destination tag %s is locked") % dest_tag['name']) if build_opts.inis: try: 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] opts = koji.util.maven_opts(build_opts, scratch=build_opts.scratch) if '://' not in source: - parser.error(_("Invalid SCM URL: %s" % source)) + parser.error(_("No such SCM URL: %s") % source) if build_opts.debug: opts.setdefault('maven_options', []).append('--debug') if build_opts.skip_tag: @@ -811,10 +811,10 @@ def handle_maven_chain(options, session, args): target = args[0] build_target = session.getBuildTarget(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']) 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: parser.error(_("Destination tag %s is locked") % dest_tag['name']) opts = {} @@ -984,7 +984,7 @@ def anon_handle_mock_config(goptions, session, args): error(_("Please specify an arch")) tag = session.getTag(options.tag) if not tag: - parser.error(_("Invalid tag: %s" % options.tag)) + parser.error(_("No such tag: %s") % options.tag) arch = options.arch config = session.getBuildConfig(tag['id']) if not config: @@ -1003,7 +1003,7 @@ def anon_handle_mock_config(goptions, session, args): arch = options.arch target = session.getBuildTarget(options.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'] if options.latest: opts['repoid'] = 'latest' @@ -1645,7 +1645,7 @@ def handle_prune_signed_copies(goptions, session, args): if x['active']: fmt += " [still active]" 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)) return "%s: %s" % (time_str, fmt % x) for nvr, binfo in builds: @@ -2214,7 +2214,7 @@ def handle_import_archive(options, session, args): image_info = {'arch': suboptions.type_info} suboptions.type_info = image_info else: - parser.error(_("Unsupported archive type: %s" % suboptions.type)) + parser.error(_("Unsupported archive type: %s") % suboptions.type) buildinfo = session.getBuild(arg_filter(args[0])) if not buildinfo: @@ -2273,7 +2273,7 @@ def handle_grant_permission(goptions, session, args): for n in names: user = session.getUser(n) if user is None: - parser.error(_("No such user: %s" % n)) + parser.error(_("No such user: %s") % n) users.append(user) kwargs = {} if options.new: @@ -2296,7 +2296,7 @@ def handle_revoke_permission(goptions, session, args): for n in names: user = session.getUser(n) if user is None: - parser.error(_("No such user: %s" % n)) + parser.error(_("No such user: %s") % n) users.append(user) for user in users: session.revokePermission(user['name'], perm) @@ -2315,7 +2315,7 @@ def handle_grant_cg_access(goptions, session, args): cg = args[1] uinfo = session.getUser(user) if uinfo is None: - parser.error(_("No such user: %s" % user)) + parser.error(_("No such user: %s") % user) kwargs = {} if options.new: kwargs['create'] = True @@ -2334,7 +2334,7 @@ def handle_revoke_cg_access(goptions, session, args): cg = args[1] uinfo = session.getUser(user) if uinfo is None: - parser.error(_("No such user: %s" % user)) + parser.error(_("No such user: %s") % user) session.revokeCGAccess(uinfo['name'], cg) @@ -2512,7 +2512,7 @@ def anon_handle_list_tagged(goptions, session, args): # check if tag exist(s|ed) taginfo = session.getTag(tag, event=event_id) if not taginfo: - parser.error(_("No such tag: %s" % tag)) + parser.error(_("No such tag: %s") % tag) if options.rpms: rpms, builds = session.listTaggedRPMS(tag, **opts) @@ -2858,7 +2858,7 @@ def anon_handle_list_hosts(goptions, session, args): if options.channel: channel = session.getChannel(options.channel) if not channel: - parser.error(_('Unknown channel: %s' % options.channel)) + parser.error(_('No such channel: %s') % options.channel) opts['channelID'] = channel['id'] if options.ready is not None: opts['ready'] = options.ready @@ -2958,12 +2958,12 @@ def anon_handle_list_pkgs(goptions, session, args): if options.owner: user = session.getUser(options.owner) if user is None: - parser.error(_("Invalid user")) + parser.error(_("No such user: %s") % options.owner) opts['userID'] = user['id'] if options.tag: tag = session.getTag(options.tag) if tag is None: - parser.error(_("Invalid tag")) + parser.error(_("No such tag: %s") % options.tag) opts['tagID'] = tag['id'] if options.package: opts['pkgID'] = options.package @@ -3059,7 +3059,7 @@ def anon_handle_list_builds(goptions, session, args): except ValueError: package = session.getPackageID(options.package) if package is None: - parser.error(_("Invalid package")) + parser.error(_("No such package: %s") % options.package) opts['packageID'] = package if options.owner: try: @@ -3067,7 +3067,7 @@ def anon_handle_list_builds(goptions, session, args): except ValueError: user = session.getUser(options.owner) if user is None: - parser.error(_("Invalid owner")) + parser.error(_("No such user: %s") % options.owner) opts['userID'] = user['id'] if options.volume: try: @@ -3079,19 +3079,19 @@ def anon_handle_list_builds(goptions, session, args): if options.volume == volume['name']: volumeID = volume['id'] if volumeID is None: - parser.error(_("Invalid volume")) + parser.error(_("No such volume: %s") % options.volume) opts['volumeID'] = volumeID if options.state: try: state = int(options.state) if state > 4 or state < 0: - parser.error(_("Invalid state")) + parser.error(_("Invalid state: %s") % options.state) opts['state'] = state except ValueError: try: opts['state'] = koji.BUILD_STATES[options.state] except KeyError: - parser.error(_("Invalid state")) + parser.error(_("Invalid state: %s") % options.state) if options.before: opts['completeBefore'] = options.before if options.after: @@ -3110,7 +3110,7 @@ def anon_handle_list_builds(goptions, session, args): buildid = options.buildid data = [session.getBuild(buildid)] if data[0] is None: - parser.error(_("No build with ID '%s'" % buildid)) + parser.error(_("No such build: '%s'") % buildid) else: # Check filter exists if any(opts): @@ -3445,10 +3445,10 @@ def handle_clone_tag(goptions, session, args): try: srctag = session.getBuildConfig(args[0], event=event.get('id')) 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]) 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) \ 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" @@ -3929,11 +3929,11 @@ def handle_add_target(goptions, session, args): chkbuildtag = session.getTag(build_tag) chkdesttag = session.getTag(dest_tag) 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): error("Build tag has no arches: %s" % build_tag) 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) @@ -3957,7 +3957,7 @@ def handle_edit_target(goptions, session, args): targetInfo = session.getBuildTarget(args[0]) 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'] @@ -3973,7 +3973,7 @@ def handle_edit_target(goptions, session, args): if options.dest_tag: chkdesttag = session.getTag(options.dest_tag) 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 session.editBuildTarget(targetInfo['orig_name'], targetInfo['name'], @@ -3996,7 +3996,7 @@ def handle_remove_target(goptions, session, args): target = args[0] target_info = session.getBuildTarget(target) if not target_info: - error("Build target %s does not exist" % target) + error("No such build target: %s" % target) session.deleteBuildTarget(target_info['id']) @@ -4017,7 +4017,7 @@ def handle_remove_tag(goptions, session, args): tag = args[0] tag_info = session.getTag(tag) if not tag_info: - error("Tag %s does not exist" % tag) + error("No such tag: %s" % tag) session.deleteTag(tag_info['id']) @@ -4038,9 +4038,9 @@ def anon_handle_list_targets(goptions, session, args): targets = session.getBuildTargets(options.name) if len(targets) == 0: if options.name: - parser.error(_('Target "%s" does not exist' % options.name)) + parser.error(_('No such build target: %s') % options.name) else: - parser.error(_('No Targets were found')) + parser.error(_('No targets were found')) fmt = "%(name)-30s %(build_tag_name)-30s %(dest_tag_name)-30s" if not options.quiet: @@ -4132,7 +4132,7 @@ def anon_handle_list_tag_inheritance(goptions, session, args): else: tag = session.getTag(args[0]) if not tag: - parser.error(_("Unknown tag: %s" % args[0])) + parser.error(_("No such tag: %s") % args[0]) opts = {} opts['reverse'] = options.reverse or False @@ -4147,17 +4147,17 @@ def anon_handle_list_tag_inheritance(goptions, session, args): if match: tag1 = session.getTagID(match.group(1)) 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)) 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 if options.stop: deprecated("--stop option is deprecated and will be removed in 1.26") tag1 = session.getTagID(options.stop) if not tag1: - parser.error(_("Unknown tag: %s" % options.stop)) + parser.error(_("No such tag: %s") % options.stop) opts['stops'] = {str(tag1): 1} sys.stdout.write(' %s (%i)\n' % (tag['name'], tag['id'])) @@ -4183,12 +4183,12 @@ def anon_handle_list_tags(goptions, session, args): if options.package: pkginfo = session.getPackage(options.package) if not pkginfo: - parser.error(_("Invalid package %s" % options.package)) + parser.error(_("No such package: %s") % options.package) if options.build: buildinfo = session.getBuild(options.build) if not buildinfo: - parser.error(_("Invalid build %s" % options.build)) + parser.error(_("No such build: %s") % options.build) if not args: # list everything if no pattern is supplied @@ -4903,8 +4903,7 @@ def anon_handle_taginfo(goptions, session, args): except ValueError: info = None if info is None: - print("No such tag: %s" % tag) - sys.exit(1) + parser.error(_('No such tag: %s') % tag) tags.append(info) for n, info in enumerate(tags): @@ -5192,11 +5191,11 @@ def handle_add_tag_inheritance(goptions, session, args): tag = session.getTag(args[0]) if not tag: - parser.error(_("Invalid tag: %s" % args[0])) + parser.error(_("No such tag: %s") % args[0]) parent = session.getTag(args[1]) if not parent: - parser.error(_("Invalid tag: %s" % args[1])) + parser.error(_("No such tag: %s") % args[1]) inheritanceData = session.getInheritanceData(tag['id']) priority = options.priority and int(options.priority) or 0 @@ -5249,14 +5248,14 @@ def handle_edit_tag_inheritance(goptions, session, args): tag = session.getTag(args[0]) if not tag: - parser.error(_("Invalid tag: %s" % args[0])) + parser.error(_("No such tag: %s") % args[0]) parent = None priority = None if len(args) > 1: parent = session.getTag(args[1]) if not parent: - parser.error(_("Invalid tag: %s" % args[1])) + parser.error(_("No such tag: %s") % args[1]) if len(args) > 2: priority = args[2] @@ -5325,14 +5324,14 @@ def handle_remove_tag_inheritance(goptions, session, args): tag = session.getTag(args[0]) if not tag: - parser.error(_("Invalid tag: %s" % args[0])) + parser.error(_("No such tag: %s") % args[0]) parent = None priority = None if len(args) > 1: parent = session.getTag(args[1]) if not parent: - parser.error(_("Invalid tag: %s" % args[1])) + parser.error(_("No such tag: %s") % args[1]) if len(args) > 2: priority = args[2] @@ -5897,11 +5896,10 @@ def _build_image_indirection(options, task_opts, session, args): tmp_target = session.getBuildTarget(task_opts.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']) if not dest_tag: - raise koji.GenericError(_("Unknown destination tag: %s" % - tmp_target['dest_tag_name'])) + raise koji.GenericError(_("No such destination tag: %s") % tmp_target['dest_tag_name']) # Set the architecture task_opts.arch = koji.canonArch(task_opts.arch) @@ -6010,7 +6008,7 @@ def handle_image_build(options, session, args): section = 'image-build' config = koji.read_config_files([(task_options.config, True)]) 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 args = [] for arg in ('name', 'version', 'target', 'install_tree'): @@ -6085,11 +6083,10 @@ def _build_image(options, task_opts, session, args, img_type): target = args[2] tmp_target = session.getBuildTarget(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']) if not dest_tag: - raise koji.GenericError(_("Unknown destination tag: %s" % - tmp_target['dest_tag_name'])) + raise koji.GenericError(_("No such destination tag: %s") % tmp_target['dest_tag_name']) # Set the architecture if img_type == 'livemedia': @@ -6159,11 +6156,10 @@ def _build_image_oz(options, task_opts, session, args): target = args[2] tmp_target = session.getBuildTarget(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']) if not dest_tag: - raise koji.GenericError(_("Unknown destination tag: %s" % - tmp_target['dest_tag_name'])) + raise koji.GenericError(_("No such destination tag: %s") % tmp_target['dest_tag_name']) # Set the architectures arches = [] @@ -6252,12 +6248,12 @@ def handle_win_build(options, session, args): else: build_target = session.getBuildTarget(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']) 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: - parser.error(_("Destination tag %s is locked" % dest_tag['name'])) + parser.error(_("Destination tag %s is locked") % dest_tag['name']) scmurl = args[1] vm_name = args[2] opts = {} @@ -6652,7 +6648,7 @@ def handle_move_build(opts, session, args): for arg in args[2:]: pkg = session.getPackage(arg) if not pkg: - print(_("Invalid package name %s, skipping." % arg)) + print(_("No such package: %s, skipping.") % arg) continue tasklist = session.moveAllBuilds(args[0], args[1], arg, options.force) tasks.extend(tasklist) @@ -6660,7 +6656,7 @@ def handle_move_build(opts, session, args): for arg in args[2:]: build = session.getBuild(arg) if not build: - print(_("Invalid build %s, skipping." % arg)) + print(_("No such build: %s, skipping.") % arg) continue if build not in builds: builds.append(build) @@ -6699,7 +6695,7 @@ def handle_untag_build(goptions, session, args): activate_session(session, goptions) tag = session.getTag(args[0]) if not tag: - parser.error(_("Invalid tag: %s" % args[0])) + parser.error(_("No such tag: %s") % args[0]) if options.all: builds = [] for pkg in args[1:]: @@ -6947,7 +6943,7 @@ def anon_handle_download_logs(options, session, args): assert task_id == int(task_id), "Task id must be number: %r" % task_id task_info = session.getTaskInfo(task_id) 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) logs = [] # list of tuples (filename, volume) for filename in files: @@ -7031,7 +7027,7 @@ def anon_handle_download_task(options, session, args): base_task = session.getTaskInfo(base_task_id) 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 ( koji.TASK_STATES['CLOSED'], @@ -7128,13 +7124,13 @@ def anon_handle_wait_repo(options, session, args): if suboptions.target: target_info = session.getBuildTarget(tag) 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_id = target_info['build_tag'] else: tag_info = session.getTag(tag) if not tag_info: - parser.error(_("Invalid tag: %s") % tag) + parser.error(_("No such tag: %s") % tag) targets = session.getBuildTargets(buildTagID=tag_info['id']) if not targets: warn("%(name)s is not a build tag for any target" % tag_info) @@ -7217,13 +7213,13 @@ def handle_regen_repo(options, session, args): if suboptions.target: info = session.getBuildTarget(tag) if not info: - parser.error(_("No matching build target: " + tag)) + parser.error(_("No such build target: %s") % tag) tag = info['build_tag_name'] info = session.getTag(tag, strict=True) else: info = session.getTag(tag) if not info: - parser.error(_("No matching tag: " + tag)) + parser.error(_("No such tag: %s") % tag) tag = info['name'] targets = session.getBuildTargets(buildTagID=info['id']) if not targets: @@ -7332,7 +7328,7 @@ def handle_dist_repo(options, session, args): keys = args[1:] taginfo = session.getTag(tag) if not taginfo: - parser.error(_('unknown tag %s') % tag) + parser.error(_('No such tag: %s') % tag) if len(task_opts.arch) == 0: arches = taginfo['arches'] or '' task_opts.arch = arches.split() @@ -7405,7 +7401,7 @@ def anon_handle_search(options, session, args): parser.error(_("Please specify search pattern")) type = args[0] if type not in _search_types: - parser.error(_("Unknown search type: %s") % type) + parser.error(_("No such search type: %s") % type) pattern = args[1] matchType = 'glob' if options.regex: @@ -7460,7 +7456,7 @@ def anon_handle_list_notifications(goptions, session, args): ensure_connection(session) user = session.getUser(options.user) if not user: - error("User %s does not exist" % options.user) + error("No such user: %s" % options.user) user_id = user['id'] else: activate_session(session, goptions) @@ -7544,7 +7540,7 @@ def handle_add_notification(goptions, session, args): if options.package: package_id = session.getPackageID(options.package) if package_id is None: - parser.error(_("Unknown package: %s") % options.package) + parser.error(_("No such package: %s") % options.package) else: package_id = None @@ -7552,7 +7548,7 @@ def handle_add_notification(goptions, session, args): try: tag_id = session.getTagID(options.tag, strict=True) except koji.GenericError: - parser.error(_("Unknown tag: %s") % options.tag) + parser.error(_("No such tag: %s") % options.tag) else: tag_id = None @@ -7616,7 +7612,7 @@ def handle_edit_notification(goptions, session, args): elif options.package: package_id = session.getPackageID(options.package) if package_id is None: - parser.error(_("Unknown package: %s") % options.package) + parser.error(_("No such package: %s") % options.package) else: package_id = old['package_id'] @@ -7626,7 +7622,7 @@ def handle_edit_notification(goptions, session, args): try: tag_id = session.getTagID(options.tag, strict=True) except koji.GenericError: - parser.error(_("Unknown tag: %s") % options.tag) + parser.error(_("No such tag: %s") % options.tag) else: tag_id = old['tag_id'] @@ -7671,7 +7667,7 @@ def handle_block_notification(goptions, session, args): if options.package: package_id = session.getPackageID(options.package) if package_id is None: - parser.error(_("Unknown package: %s") % options.package) + parser.error(_("No such package: %s") % options.package) else: package_id = None @@ -7679,7 +7675,7 @@ def handle_block_notification(goptions, session, args): try: tag_id = session.getTagID(options.tag, strict=True) except koji.GenericError: - parser.error(_("Unknown tag: %s") % options.tag) + parser.error(_("No such tag: %s") % options.tag) else: tag_id = None diff --git a/hub/kojihub.py b/hub/kojihub.py index 345c3b8..8d2d284 100644 --- a/hub/kojihub.py +++ b/hub/kojihub.py @@ -505,7 +505,7 @@ class Task(object): info['result'] = self.getResult() new_val = info[attr] else: - raise koji.GenericError('unknown callback type: %s' % cbtype) + raise koji.GenericError('No such callback type: %s' % cbtype) old_val = old_info[attr] if attr == 'state': # 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) if not pkg: 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: owner = get_user(owner, strict=True)['id'] action = 'add' @@ -1263,7 +1263,7 @@ def list_tags(build=None, package=None, perms=True, queryOpts=None, pattern=None # lookup build id buildinfo = get_build(build) 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') clauses.append('tag_listing.active = true') 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: packageinfo = lookup_package(package) if not packageinfo: - raise koji.GenericError('invalid package: %s' % package) + raise koji.GenericError('No such package: %s' % package) fields.extend( ['users.id', 'users.name', 'tag_packages.blocked', 'tag_packages.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)): clauses.append('rpminfo.arch IN %(arch)s') else: - raise koji.GenericError('invalid arch option: %s' % arch) + raise koji.GenericError('Invalid type for arch option: %s' % type(arch)) fields, aliases = zip(*fields) 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""" utype_id = koji.TAG_UPDATE_TYPES.getnum(utype) 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: event_id = get_event() if user_id is None: @@ -3010,7 +3010,7 @@ def _edit_build_target(buildTargetInfo, name, build_tag, dest_tag): target = lookup_build_target(buildTargetInfo) if not target: - raise koji.GenericError('invalid build target: %s' % buildTargetInfo) + raise koji.GenericError('No such build target: %s' % buildTargetInfo) buildTargetID = target['id'] @@ -3060,7 +3060,7 @@ def _delete_build_target(buildTargetInfo): """Delete build target, no access checks""" target = lookup_build_target(buildTargetInfo) if not target: - raise koji.GenericError('invalid build target: %s' % buildTargetInfo) + raise koji.GenericError('No such build target: %s' % buildTargetInfo) targetID = target['id'] @@ -3095,7 +3095,7 @@ def get_build_targets(info=None, event=None, buildTagID=None, destTagID=None, qu elif isinstance(info, int): clauses.append('build_target.id = %(info)i') 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: clauses.append('build_tag = %(buildTagID)i') if destTagID is not None: @@ -3114,7 +3114,7 @@ def get_build_target(info, event=None, strict=False): if len(targets) == 1: return targets[0] elif strict: - raise koji.GenericError('No matching build target found: %s' % info) + raise koji.GenericError('No such build target: %s' % info) else: return None @@ -3142,7 +3142,7 @@ def lookup_name(table, info, strict=False, create=False): elif isinstance(info, str): q = """SELECT id,name FROM %s WHERE name=%%(info)s""" % table 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) if ret is None: if strict: @@ -3336,7 +3336,7 @@ def get_tag(tagInfo, strict=False, event=None, blocked=False): elif isinstance(tagInfo, str): clauses.append("tag.name = %(tagInfo)s") else: - raise koji.GenericError('invalid type for tagInfo: %s' % type(tagInfo)) + raise koji.GenericError('Invalid type for tagInfo: %s' % type(tagInfo)) data = {'tagInfo': tagInfo} fields, aliases = zip(*fields.items()) @@ -3345,7 +3345,7 @@ def get_tag(tagInfo, strict=False, event=None, blocked=False): result = query.executeOne() if not result: if strict: - raise koji.GenericError("Invalid tagInfo: %r" % tagInfo) + raise koji.GenericError("No such tagInfo: %r" % tagInfo) return None result['extra'] = get_tag_extra(result, event, blocked=blocked) return result @@ -3364,7 +3364,7 @@ def get_tag_extra(tagInfo, event=None, blocked=False): result = {} for h in query.execute(): 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: result[h['key']] = (h['blocked'], h['value']) else: @@ -3613,7 +3613,7 @@ def get_external_repos(info=None, url=None, event=None, queryOpts=None): elif isinstance(info, int): clauses.append('id = %(info)i') else: - raise koji.GenericError('invalid type for lookup: %s' % type(info)) + raise koji.GenericError('Invalid type for lookup: %s' % type(info)) if url: clauses.append('url = %(url)s') @@ -3642,7 +3642,7 @@ def get_external_repo(info, strict=False, event=None): return repos[0] else: if strict: - raise koji.GenericError('invalid repo info: %s' % info) + raise koji.GenericError('No such repo: %s' % info) else: 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: merge_mode = 'koji' 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_id = tag['id'] @@ -3920,8 +3920,7 @@ def get_user(userInfo=None, strict=False, krb_princs=True): data = {'info': userInfo} clauses = ['krb_principal = %(info)s OR name = %(info)s'] else: - raise koji.GenericError('invalid type for userInfo: %s' - % type(userInfo)) + raise koji.GenericError('Invalid type for userInfo: %s' % type(userInfo)) if isinstance(data, dict) and not data.get('info'): clauses = [] uid = data.get('id') @@ -3929,23 +3928,20 @@ def get_user(userInfo=None, strict=False, krb_princs=True): if isinstance(uid, int): clauses.append('users.id = %(id)i') else: - raise koji.GenericError('invalid type for userid: %s' - % type(uid)) + raise koji.GenericError('Invalid type for userid: %s' % type(uid)) username = data.get('name') if username: if isinstance(username, str): clauses.append('users.name = %(name)s') else: - raise koji.GenericError('invalid type for username: %s' - % type(username)) + raise koji.GenericError('Invalid type for username: %s' % type(username)) krb_principal = data.get('krb_principal') if krb_principal: if isinstance(krb_principal, str): clauses.append('user_krb_principals.krb_principal' ' = %(krb_principal)s') else: - raise koji.GenericError('invalid type for krb_principal: %s' - % type(krb_principal)) + raise koji.GenericError('Invalid type for krb_principal: %s' % type(krb_principal)) query = QueryProcessor(tables=['users'], columns=fields, 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'] clauses = ['name = %(info)s'] else: - raise koji.GenericError('invalid type for user_info: %s' - % type(user_info)) + raise koji.GenericError('Invalid type for user_info: %s' % type(user_info)) query = QueryProcessor(tables=['user_krb_principals'], columns=fields, joins=joins, 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: raise koji.GenericError("No kerberos principal provided") if not isinstance(krb_principal, str): - raise koji.GenericError("invalid type for krb_principal: %s" - % type(krb_principal)) + raise koji.GenericError("Invalid type for krb_principal: %s" % type(krb_principal)) return get_user({'krb_principal': krb_principal}, strict=strict, krb_princs=krb_princs) @@ -4108,7 +4102,7 @@ def find_build_id(X, strict=False): elif isinstance(X, dict): data = X 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): 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 ) if not r: if strict: - raise koji.GenericError('No matching build found: %r' % X) + raise koji.GenericError('No such build: %r' % X) else: return None return r[0] @@ -4211,7 +4205,7 @@ def get_build(buildInfo, strict=False): if not result: if strict: - raise koji.GenericError('No matching build found: %s' % buildInfo) + raise koji.GenericError('No such build: %s' % buildInfo) else: return None if result['cg_id']: @@ -4384,7 +4378,7 @@ def get_rpm(rpminfo, strict=False, multi=False): elif isinstance(rpminfo, dict): data = rpminfo.copy() else: - raise koji.GenericError("Invalid argument: %r" % rpminfo) + raise koji.GenericError("Invalid type for rpminfo: %r" % type(rpminfo)) clauses = [] if 'id' in data: clauses.append("rpminfo.id=%(id)s") @@ -4495,7 +4489,7 @@ def list_rpms(buildID=None, buildrootID=None, imageID=None, componentBuildrootID elif isinstance(arches, str): clauses.append('rpminfo.arch = %(arches)s') 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) query = QueryProcessor(columns=fields, aliases=aliases, @@ -5272,7 +5266,7 @@ def get_host(hostInfo, strict=False, event=None): elif isinstance(hostInfo, str): clauses.append("host.name = %(hostInfo)s") else: - raise koji.GenericError('invalid type for hostInfo: %s' % type(hostInfo)) + raise koji.GenericError('Invalid type for hostInfo: %s' % type(hostInfo)) data = {'hostInfo': hostInfo} fields, aliases = zip(*fields.items()) @@ -5349,7 +5343,7 @@ def get_channel(channelInfo, strict=False): elif isinstance(channelInfo, str): query += """name = %(channelInfo)s""" 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) @@ -5722,9 +5716,8 @@ def check_volume_policy(data, strict=False, default=None): return vol # otherwise if strict: - raise koji.GenericError("Policy returned invalid volume: %s" - % result) - logger.error('Volume policy returned unknown volume %s', result) + raise koji.GenericError("Policy returned no such volume: %s" % result) + logger.error('Volume policy returned no such volume %s', result) # fall back to default if default is not None: vol = lookup_name('volume', default) @@ -5789,7 +5782,7 @@ def new_build(data, strict=False): try: data['extra'] = json.dumps(data['extra']) except Exception: - raise koji.GenericError("Invalid build extra data: %(extra)r" % data) + raise koji.GenericError("No such build extra data: %(extra)r" % data) else: 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: fn = "%s/%s" % (uploadpath, relpath) 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) @@ -6048,7 +6041,7 @@ def import_rpm(fn, buildinfo=None, brootid=None, wrapper=False, fileinfo=None): Designed to be called from import_build. """ 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 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: # XXX - handle case where package is not a source rpm # 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']] if state in ('FAILED', 'CANCELED', 'DELETED'): nvr = "%(name)s-%(version)s-%(release)s" % buildinfo @@ -6274,7 +6267,7 @@ class CG_Importer(object): metaver = metadata['metadata_version'] 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?) @@ -6322,7 +6315,7 @@ class CG_Importer(object): # default to looking for uploaded file metadata = 'metadata.json' 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'): # handle uploaded metadata workdir = koji.pathinfo.work() @@ -6608,7 +6601,7 @@ class CG_Importer(object): if match: files.append(match) else: - raise koji.GenericError("Unknown component type: %(type)s" % comp) + raise koji.GenericError("No such component type: %(type)s" % comp) return rpms, files def match_rpm(self, comp): @@ -6951,7 +6944,7 @@ def merge_scratch(task_id): try: task_info = task.getInfo(request=True) 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']) if task_info['state'] != koji.TASK_STATES['CLOSED']: 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 for ext in extensions.split(' '): 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 WHERE extensions ~* E'(\\s|^)%s(\\s|$)'""" % ext results = _multiRow(select, {}, ('id',)) @@ -7265,7 +7258,7 @@ def import_archive_internal(filepath, buildinfo, type, typeInfo, buildroot_id=No if metadata_only: filepath = None 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['build_id'] = buildinfo['id'] @@ -7725,7 +7718,7 @@ def query_history(tables=None, **kwargs): else: for table in tables: if table not in table_fields: - raise koji.GenericError("Unknown history table: %s" % table) + raise koji.GenericError("No such history table: %s" % table) ret = {} for table in tables: fields = {} @@ -8541,7 +8534,7 @@ def drop_group_member(group, user): user = get_user(user, strict=True) ginfo = get_user(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)]: raise koji.GenericError("No such user in group: %s" % group) data = {'user_id': user['id'], 'group_id': ginfo['id']} @@ -8556,7 +8549,7 @@ def get_group_members(group): context.session.assertPerm('admin') ginfo = get_user(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'] columns = ('id', 'name', 'usertype', 'array_agg(krb_principal)') aliases = ('id', 'name', 'usertype', 'krb_principals') @@ -8580,7 +8573,7 @@ def get_group_members(group): def set_user_status(user, status): context.session.assertPerm('admin') 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: # nothing to do return @@ -8589,7 +8582,7 @@ def set_user_status(user, status): rows = _dml(update, locals()) # sanity check 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(): @@ -8673,7 +8666,7 @@ def assert_cg(cg, user=None): cg = lookup_name('content_generator', cg, strict=True) if user is None: if not context.session.logged_in: - raise koji.AuthError("Not logged in") + raise koji.AuthError("Not logged-in") user = context.session.user_id user = get_user(user, strict=True) 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: orderCol = order else: - raise Exception('invalid order: ' + order) + raise Exception('Invalid order: ' + order) order_exprs.append(orderCol + direction) return 'ORDER BY ' + ', '.join(order_exprs) else: @@ -9320,7 +9313,7 @@ def policy_get_pkg(data): if isinstance(data['package'], str): return {'id': None, 'name': data['package']} else: - raise koji.GenericError("Invalid package: %s" % data['package']) + raise koji.GenericError("No such package: %s" % data['package']) return pkginfo if 'build' in data: binfo = get_build(data['build'], strict=True) @@ -10420,7 +10413,7 @@ class RootExports(object): q = """SELECT id, EXTRACT(EPOCH FROM time) FROM events""" if before is not None: 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 # string conversion q += """ WHERE EXTRACT(EPOCH FROM time) < %(before)r""" @@ -10571,7 +10564,7 @@ class RootExports(object): chksum = get_verify_class(verify)() if tail is not None: 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) os.lseek(fd, offset, 0) length = 0 @@ -11080,7 +11073,7 @@ class RootExports(object): build_info = get_build(buildID) if not build_info: if strict: - raise koji.GenericError("Build %s doesn't exist" % buildID) + raise koji.GenericError("No such build: %s" % buildID) return _applyQueryOpts([], queryOpts) srpms = self.listRPMs(buildID=build_info['id'], arches='src') if not srpms: @@ -11093,7 +11086,7 @@ class RootExports(object): if not filepath: raise koji.GenericError('filepath must be specified with taskID') 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(), koji.pathinfo.taskrelpath(taskID), filepath) @@ -11114,7 +11107,7 @@ class RootExports(object): elif isinstance(before, int): pass else: - raise koji.GenericError('invalid type for before: %s' % type(before)) + raise koji.GenericError('Invalid type for before: %s' % type(before)) if after: if isinstance(after, datetime.datetime): @@ -11124,7 +11117,7 @@ class RootExports(object): elif isinstance(after, int): pass else: - raise koji.GenericError('invalid type for after: %s' % type(after)) + raise koji.GenericError('Invalid type for after: %s' % type(after)) results = [] @@ -11754,7 +11747,7 @@ class RootExports(object): if not filepath: raise koji.GenericError('filepath must be specified with taskID') 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(), koji.pathinfo.taskrelpath(taskID), filepath) @@ -11795,7 +11788,7 @@ class RootExports(object): r = query.executeOne() if not r: if strict: - raise koji.GenericError('Invalid package name: %s' % name) + raise koji.GenericError('No such package name: %s' % name) return None return r['id'] @@ -11976,14 +11969,14 @@ class RootExports(object): """Enable logins by the specified user""" user = get_user(username) 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']) def disableUser(self, username): """Disable logins by the specified user""" user = get_user(username) 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']) listCGs = staticmethod(list_cgs) @@ -12877,7 +12870,7 @@ class RootExports(object): owner or the notification or an admin, raise a GenericError.""" currentUser = self.getLoggedInUser() if not currentUser: - raise koji.GenericError('not logged-in') + raise koji.GenericError('Not logged-in') orig_notif = self.getBuildNotification(id, strict=True) 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.""" currentUser = self.getLoggedInUser() if not currentUser: - raise koji.GenericError('not logged in') + raise koji.GenericError('Not logged-in') notificationUser = self.getUser(user_id) 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')): raise koji.GenericError('user %s cannot create notifications for user %s' % @@ -12946,7 +12939,7 @@ class RootExports(object): notification = self.getBuildNotification(id, strict=True) currentUser = self.getLoggedInUser() if not currentUser: - raise koji.GenericError('not logged-in') + raise koji.GenericError('Not logged-in') if not (notification['user_id'] == currentUser['id'] or self.hasPerm('admin')): @@ -12961,11 +12954,11 @@ class RootExports(object): admin, raise a GenericError.""" currentUser = self.getLoggedInUser() if not currentUser: - raise koji.GenericError('not logged in') + raise koji.GenericError('Not logged-in') notificationUser = self.getUser(user_id) 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')): 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) currentUser = self.getLoggedInUser() if not currentUser: - raise koji.GenericError('not logged-in') + raise koji.GenericError('Not logged-in') if not (block['user_id'] == currentUser['id'] or self.hasPerm('admin')): @@ -13054,7 +13047,7 @@ class RootExports(object): return _applyQueryOpts([], queryOpts) table = self._searchTables.get(type) if not table: - raise koji.GenericError('unknown search type: %s' % type) + raise koji.GenericError('No such search type: %s' % type) if matchType == 'glob': oper = 'ilike' @@ -13396,7 +13389,7 @@ class Host(object): if context.session.logged_in: raise koji.AuthError("User %i is not a host" % context.session.user_id) else: - raise koji.AuthError("Not logged in") + raise koji.AuthError("Not logged-in") self.id = id self.same_host = (id == remote_id) @@ -13742,7 +13735,7 @@ class HostExports(object): for relpath in [srpm] + rpms: fn = "%s/%s" % (uploadpath, relpath) 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) @@ -14519,7 +14512,7 @@ class HostExports(object): pass else: 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) if build_id: build = get_build(build_id) @@ -14530,7 +14523,7 @@ class HostExports(object): logger.error("Size mismatch, br: %i, db: %i", fileinfo['size'], tag_archive['size']) 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'])) return br.updateArchiveList(archives, project) diff --git a/tests/test_cli/test_add_group.py b/tests/test_cli/test_add_group.py index 04e5b42..ed09f18 100644 --- a/tests/test_cli/test_add_group.py +++ b/tests/test_cli/test_add_group.py @@ -155,7 +155,7 @@ class TestAddGroup(utils.CliTestCase): handle_add_group(options, session, arguments) self.assertExitCode(ex, 1) actual = stderr.getvalue() - expected = 'Unknown tag: tag\n' + expected = 'No such tag: tag\n' self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. diff --git a/tests/test_cli/test_add_notification.py b/tests/test_cli/test_add_notification.py index 51da4a2..577a45c 100644 --- a/tests/test_cli/test_add_notification.py +++ b/tests/test_cli/test_add_notification.py @@ -1,12 +1,12 @@ from __future__ import absolute_import import koji import mock -import unittest from six.moves import StringIO from koji_cli.commands import handle_add_notification +from . import utils -class TestAddNotification(unittest.TestCase): +class TestAddNotification(utils.CliTestCase): def setUp(self): self.options = mock.MagicMock() self.options.quiet = True @@ -114,3 +114,29 @@ class TestAddNotification(unittest.TestCase): handle_add_notification(self.options, self.session, ['bogus']) 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) diff --git a/tests/test_cli/test_add_pkg.py b/tests/test_cli/test_add_pkg.py index d50d878..fc644a3 100644 --- a/tests/test_cli/test_add_pkg.py +++ b/tests/test_cli/test_add_pkg.py @@ -1,11 +1,11 @@ from __future__ import absolute_import -import mock import os -import six import sys import unittest +import mock +import six from mock import call from koji_cli.commands import handle_add_pkg @@ -133,7 +133,7 @@ class TestAddPkg(utils.CliTestCase): handle_add_pkg(options, session, args) self.assertExitCode(ex, 1) actual = stderr.getvalue() - expected = 'User owner does not exist\n' + expected = 'No such user: %s\n' % owner self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. activate_session_mock.assert_not_called() @@ -168,7 +168,7 @@ class TestAddPkg(utils.CliTestCase): handle_add_pkg(options, session, args) self.assertExitCode(ex, 1) actual = stdout.getvalue() - expected = 'No such tag: tag\n' + expected = 'No such tag: %s\n' % tag self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. activate_session_mock.assert_called_once_with(session, options) diff --git a/tests/test_cli/test_add_tag_inheritance.py b/tests/test_cli/test_add_tag_inheritance.py new file mode 100644 index 0000000..5d45881 --- /dev/null +++ b/tests/test_cli/test_add_tag_inheritance.py @@ -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] \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] \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] \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) diff --git a/tests/test_cli/test_add_target.py b/tests/test_cli/test_add_target.py new file mode 100644 index 0000000..3952419 --- /dev/null +++ b/tests/test_cli/test_add_target.py @@ -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 \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) diff --git a/tests/test_cli/test_block_group.py b/tests/test_cli/test_block_group.py index a626a66..a755427 100644 --- a/tests/test_cli/test_block_group.py +++ b/tests/test_cli/test_block_group.py @@ -36,7 +36,7 @@ class TestBlockGroup(utils.CliTestCase): handle_block_group(options, session, arguments) self.assertExitCode(ex, 1) actual = stderr.getvalue() - expected = 'Unknown tag: %s\n' % tag + expected = 'No such tag: %s\n' % tag self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. diff --git a/tests/test_cli/test_block_notification.py b/tests/test_cli/test_block_notification.py new file mode 100644 index 0000000..2e44a7e --- /dev/null +++ b/tests/test_cli/test_block_notification.py @@ -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) diff --git a/tests/test_cli/test_block_pkg.py b/tests/test_cli/test_block_pkg.py index 3a906ca..d2439c5 100644 --- a/tests/test_cli/test_block_pkg.py +++ b/tests/test_cli/test_block_pkg.py @@ -1,9 +1,10 @@ from __future__ import absolute_import -import mock + import os -import six import sys +import mock +import six from mock import call from koji_cli.commands import handle_block_pkg @@ -140,7 +141,7 @@ class TestBlockPkg(utils.CliTestCase): handle_block_pkg(options, session, args) self.assertExitCode(ex, 1) actual = stderr.getvalue() - expected = 'No such tag: tag\n' + expected = 'No such tag: %s\n' % tag self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. activate_session_mock.assert_called_once_with(session, options) diff --git a/tests/test_cli/test_build.py b/tests/test_cli/test_build.py index 9068310..ba191d3 100644 --- a/tests/test_cli/test_build.py +++ b/tests/test_cli/test_build.py @@ -357,7 +357,7 @@ Task info: weburl/taskinfo?taskID=1 handle_build(self.options, self.session, args) self.assertExitCode(ex, 2) 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) # Finally, assert that things were called as we expected. 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) self.assertExitCode(ex, 2) 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) # Finally, assert that things were called as we expected. activate_session_mock.assert_called_once_with(self.session, self.options) diff --git a/tests/test_cli/test_chain_build.py b/tests/test_cli/test_chain_build.py index 0b9ac03..3e29901 100644 --- a/tests/test_cli/test_chain_build.py +++ b/tests/test_cli/test_chain_build.py @@ -202,7 +202,7 @@ Options: expected = """Usage: %s chain-build [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) self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. diff --git a/tests/test_cli/test_clone_tag.py b/tests/test_cli/test_clone_tag.py index d493bac..c7214ff 100644 --- a/tests/test_cli/test_clone_tag.py +++ b/tests/test_cli/test_clone_tag.py @@ -94,7 +94,7 @@ clone-tag will create the destination tag if it does not already exist self.options, self.session, 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) self.activate_session.assert_called_once() self.activate_session.getTag.has_called([call('src-tag'), diff --git a/tests/test_cli/test_dist_repo.py b/tests/test_cli/test_dist_repo.py index b400b62..194b661 100644 --- a/tests/test_cli/test_dist_repo.py +++ b/tests/test_cli/test_dist_repo.py @@ -1,10 +1,11 @@ from __future__ import absolute_import from __future__ import print_function + +import unittest import copy + import mock import six -import unittest - from koji_cli.commands import handle_dist_repo from . import utils @@ -26,7 +27,7 @@ class TestDistRepo(utils.CliTestCase): 'arches': 'x86_64', 'maven_include_all': False, 'perm_id': None - } + } def setUp(self): self.task_id = 1001 @@ -91,10 +92,10 @@ via 'koji edit-tag -x distrepo.cancel_others=True' arguments = [self.tag_name, self.fake_key] self.__run_test_handle_dist_repo(arguments, True) self.watch_tasks.assert_called_with( - self.session, - [self.task_id], - quiet=self.options.quiet, - poll_interval=self.options.poll_interval, topurl=self.options.topurl) + self.session, + [self.task_id], + quiet=self.options.quiet, + poll_interval=self.options.poll_interval, topurl=self.options.topurl) def test_handle_dist_repo_nowait(self): arguments = [self.tag_name, self.fake_key, '--nowait'] @@ -120,7 +121,8 @@ via 'koji edit-tag -x distrepo.cancel_others=True' '--allow-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 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( handle_dist_repo, self.options, @@ -218,7 +220,7 @@ via 'koji edit-tag -x distrepo.cancel_others=True' stderr=expected) # 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'}) expected = 'uploadWrapper ...\n\n' arguments += ['--arch', 'x86_64', '--arch', 'i686'] @@ -234,11 +236,11 @@ via 'koji edit-tag -x distrepo.cancel_others=True' self.session.getRepo.return_value = {} expected = self.format_error_message("Can't find repo for tag: %s" % "test-repo1") self.assert_system_exit( - handle_dist_repo, - self.options, - self.session, - arguments, - stderr=expected) + handle_dist_repo, + self.options, + self.session, + arguments, + stderr=expected) # Normal case, assume test-repo2 is expired self.session.getRepo.side_effect = [ diff --git a/tests/test_cli/test_download_logs.py b/tests/test_cli/test_download_logs.py index 982ad15..02e83f3 100644 --- a/tests/test_cli/test_download_logs.py +++ b/tests/test_cli/test_download_logs.py @@ -1,10 +1,11 @@ from __future__ import absolute_import + import mock -from mock import call import six -from . import utils from koji_cli.commands import anon_handle_download_logs +from . import utils + class TestDownloadLogs(utils.CliTestCase): def mock_builtin_open(self, filepath, *args): @@ -19,7 +20,8 @@ class TestDownloadLogs(utils.CliTestCase): self.options.topurl = 'https://topurl' # Mock out the xmlrpc server 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.download_file = mock.patch('koji_cli.commands.download_file').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'), ]) + 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) diff --git a/tests/test_cli/test_download_task.py b/tests/test_cli/test_download_task.py index 3918454..3c729a8 100644 --- a/tests/test_cli/test_download_task.py +++ b/tests/test_cli/test_download_task.py @@ -1,10 +1,12 @@ from __future__ import absolute_import -import mock -from mock import call + import os -import six import sys +import mock +import six +from mock import call + from koji_cli.commands import anon_handle_download_task from . import utils @@ -34,7 +36,7 @@ class TestDownloadTask(utils.CliTestCase): if target.endswith('.log') and arch is not None: target = "%s.%s.log" % (target.rstrip(".log"), arch) calls.append(call(url, target, quiet=None, noprogress=None, - size=total, num=i + 1)) + size=total, num=i + 1)) return calls def setUp(self): @@ -44,7 +46,8 @@ class TestDownloadTask(utils.CliTestCase): self.options.topurl = 'https://topurl' # Mock out the xmlrpc server 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.download_file = mock.patch('koji_cli.commands.download_file').start() self.ensure_connection = mock.patch('koji_cli.commands.ensure_connection').start() @@ -102,7 +105,7 @@ class TestDownloadTask(utils.CliTestCase): expected = '' self.assertMultiLineEqual(actual, expected) actual = self.stderr.getvalue() - expected = 'No such task: #123333\n' + expected = 'No such task: %s\n' % task_id self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. self.ensure_connection.assert_called_once_with(self.session) diff --git a/tests/test_cli/test_edit_notification.py b/tests/test_cli/test_edit_notification.py index 8204709..8bc92a3 100644 --- a/tests/test_cli/test_edit_notification.py +++ b/tests/test_cli/test_edit_notification.py @@ -5,8 +5,10 @@ import unittest from six.moves import StringIO from koji_cli.commands import handle_edit_notification +from . import utils -class TestEditNotification(unittest.TestCase): + +class TestEditNotification(utils.CliTestCase): def setUp(self): self.options = mock.MagicMock() self.options.debug = False @@ -87,3 +89,33 @@ class TestEditNotification(unittest.TestCase): handle_edit_notification(self.options, self.session, ['123']) 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] \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] \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) diff --git a/tests/test_cli/test_edit_tag_inheritance.py b/tests/test_cli/test_edit_tag_inheritance.py new file mode 100644 index 0000000..1de9266 --- /dev/null +++ b/tests/test_cli/test_edit_tag_inheritance.py @@ -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] \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] \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] \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) diff --git a/tests/test_cli/test_edit_target.py b/tests/test_cli/test_edit_target.py new file mode 100644 index 0000000..fdda38c --- /dev/null +++ b/tests/test_cli/test_edit_target.py @@ -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] \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() diff --git a/tests/test_cli/test_image_build.py b/tests/test_cli/test_image_build.py index 00040bc..5067e50 100644 --- a/tests/test_cli/test_image_build.py +++ b/tests/test_cli/test_image_build.py @@ -192,7 +192,7 @@ class TestBuildImageOz(utils.CliTestCase): _build_image_oz( self.options, self.task_options, self.session, self.args) 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.getTag.return_value = {} @@ -201,7 +201,7 @@ class TestBuildImageOz(utils.CliTestCase): self.options, self.task_options, self.session, self.args) self.assertEqual( 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 with self.assertRaises(koji.GenericError) as cm: diff --git a/tests/test_cli/test_image_build_indirection.py b/tests/test_cli/test_image_build_indirection.py index 9b6aa4a..d00c7ba 100644 --- a/tests/test_cli/test_image_build_indirection.py +++ b/tests/test_cli/test_image_build_indirection.py @@ -158,7 +158,7 @@ class TestBuildImageIndirection(utils.CliTestCase): # Case 4. target not found error self.session.getBuildTarget.return_value = {} - expected = "Unknown build target: %s" % {} + expected = "No such build target: %s" % {} with self.assertRaises(koji.GenericError) as cm: _build_image_indirection( self.options, self.task_opts, self.session, []) @@ -168,7 +168,7 @@ class TestBuildImageIndirection(utils.CliTestCase): # Case 5. tag not found error self.session.getBuildTarget.return_value = self.build_target 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: _build_image_indirection( self.options, self.task_opts, self.session, []) diff --git a/tests/test_cli/test_import_archive.py b/tests/test_cli/test_import_archive.py new file mode 100644 index 0000000..9db69aa --- /dev/null +++ b/tests/test_cli/test_import_archive.py @@ -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 [ (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) self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. @@ -307,7 +307,7 @@ Options: %s maven-build --ini=CONFIG... [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) self.assertMultiLineEqual(actual, 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] (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) self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. diff --git a/tests/test_cli/test_maven_chain.py b/tests/test_cli/test_maven_chain.py index 5510d07..fab8fe8 100644 --- a/tests/test_cli/test_maven_chain.py +++ b/tests/test_cli/test_maven_chain.py @@ -60,7 +60,7 @@ class TestMavenChain(utils.CliTestCase): # Unknonw target test expected = self.format_error_message( - "Unknown build target: %s" % self.target) + "No such build target: %s" % self.target) self.assert_system_exit( handle_maven_chain, options, @@ -71,7 +71,7 @@ class TestMavenChain(utils.CliTestCase): # Unknow destination tag test session.getBuildTarget.return_value = target_info 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( handle_maven_chain, options, diff --git a/tests/test_cli/test_mock_config.py b/tests/test_cli/test_mock_config.py index bea89db..d7bff43 100644 --- a/tests/test_cli/test_mock_config.py +++ b/tests/test_cli/test_mock_config.py @@ -1,7 +1,9 @@ from __future__ import absolute_import + +import unittest + import mock import six -import unittest from koji_cli.commands import anon_handle_mock_config from . import utils @@ -210,7 +212,7 @@ config_opts['macros']['%distribution'] = 'Koji Testing' self.assert_console_message(stderr, expected) 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( anon_handle_mock_config, options, @@ -303,8 +305,7 @@ config_opts['macros']['%distribution'] = 'Koji Testing' arguments = ['--target', target['name'], '--arch', arch] - expected = self.format_error_message( - "Invalid target: %s" % target['name']) + expected = self.format_error_message("No such build target: %s" % target['name']) self.assert_system_exit( anon_handle_mock_config, options, @@ -361,7 +362,7 @@ config_opts['macros']['%distribution'] = 'Koji Testing' # Run it and check immediate output # argument is empty 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( anon_handle_mock_config, options, @@ -372,8 +373,7 @@ config_opts['macros']['%distribution'] = 'Koji Testing' # name is specified twice case arguments = [self.progname, '--name', 'name'] - expected = self.format_error_message( - "Name already specified via option") + expected = self.format_error_message("Name already specified via option") self.assert_system_exit( anon_handle_mock_config, options, diff --git a/tests/test_cli/test_move_build.py b/tests/test_cli/test_move_build.py index 44d9312..28861cd 100644 --- a/tests/test_cli/test_move_build.py +++ b/tests/test_cli/test_move_build.py @@ -1,7 +1,9 @@ from __future__ import absolute_import + +import unittest + import mock import six -import unittest from koji_cli.commands import handle_move_build from . import utils @@ -48,7 +50,7 @@ class TestMoveBuild(utils.CliTestCase): ] 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): expected += "Created task %d, moving %s" % (t, pkgs[i]) + "\n" @@ -103,7 +105,7 @@ class TestMoveBuild(utils.CliTestCase): [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: rv = handle_move_build(self.options, self.session, arguments) @@ -118,7 +120,8 @@ class TestMoveBuild(utils.CliTestCase): # Case 1. without --all option 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']]: self.assert_system_exit( handle_move_build, @@ -130,7 +133,8 @@ class TestMoveBuild(utils.CliTestCase): # Case 2. with --all option 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']]: self.assert_system_exit( handle_move_build, diff --git a/tests/test_cli/test_regen_repo.py b/tests/test_cli/test_regen_repo.py index c19c411..bf8d8e6 100644 --- a/tests/test_cli/test_regen_repo.py +++ b/tests/test_cli/test_regen_repo.py @@ -1,9 +1,11 @@ from __future__ import absolute_import from __future__ import print_function + +import unittest import copy + import mock import six -import unittest from koji_cli.commands import handle_regen_repo from . import utils @@ -25,7 +27,7 @@ class TestRegenRepo(utils.CliTestCase): 'arches': 'x86_64', 'maven_include_all': False, 'perm_id': None - } + } def setUp(self): self.task_id = 1001 @@ -85,7 +87,7 @@ class TestRegenRepo(utils.CliTestCase): # show error if tag is not exist 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( handle_regen_repo, self.options, @@ -115,7 +117,7 @@ class TestRegenRepo(utils.CliTestCase): # show error if target is not matched 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( handle_regen_repo, self.options, @@ -143,8 +145,10 @@ class TestRegenRepo(utils.CliTestCase): tests = [ # [ arguments, error_string ] [[], 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', '--target'], self.format_error_message("Only a single target may be specified")], + [['tag1', 'tag2'], + 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: diff --git a/tests/test_cli/test_remove_group.py b/tests/test_cli/test_remove_group.py index 4314737..2c0947e 100644 --- a/tests/test_cli/test_remove_group.py +++ b/tests/test_cli/test_remove_group.py @@ -17,30 +17,34 @@ class TestRemoveGroup(utils.CliTestCase): %s: error: {message} """ % (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.stderr', new_callable=six.StringIO) @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' group = 'group' arguments = [tag, group] - options = mock.MagicMock() # Mock out the xmlrpc server - session = mock.MagicMock() - session.hasPerm.return_value = True - session.getTag.return_value = None + self.session.hasPerm.return_value = True + self.session.getTag.return_value = None - with self.assertRaises(SystemExit): - handle_remove_group(options, session, arguments) + expected = 'No such tag: %s\n' % tag + 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. - activate_session_mock.assert_called_once_with(session, options) - session.hasPerm.assert_called_once_with('admin') - session.getTag.assert_called_once_with(tag) - session.getTagGroups.assert_not_called() - session.groupListRemove.assert_not_called() + activate_session_mock.assert_called_once_with(self.session, self.options) + self.session.hasPerm.assert_called_once_with('admin') + self.session.getTag.assert_called_once_with(tag) + self.session.getTagGroups.assert_not_called() + self.session.groupListRemove.assert_not_called() @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO) @@ -49,23 +53,21 @@ class TestRemoveGroup(utils.CliTestCase): tag = 'tag' group = 'group' arguments = [tag, group] - options = mock.MagicMock() # Mock out the xmlrpc server - session = mock.MagicMock() - session.hasPerm.return_value = True - session.getTag.return_value = tag - session.getTagGroups.return_value = [] + self.session.hasPerm.return_value = True + self.session.getTag.return_value = tag + self.session.getTagGroups.return_value = [] 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. - activate_session_mock.assert_called_once_with(session, options) - session.hasPerm.assert_called_once_with('admin') - session.getTag.assert_called_once_with(tag) - session.getTagGroups.assert_called_once_with(tag, inherit=False) - session.groupListRemove.assert_not_called() + activate_session_mock.assert_called_once_with(self.session, self.options) + self.session.hasPerm.assert_called_once_with('admin') + self.session.getTag.assert_called_once_with(tag) + self.session.getTagGroups.assert_called_once_with(tag, inherit=False) + self.session.groupListRemove.assert_not_called() @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO) @@ -74,45 +76,40 @@ class TestRemoveGroup(utils.CliTestCase): tag = 'tag' group = 'group' arguments = [tag, group] - options = mock.MagicMock() # Mock out the xmlrpc server - session = mock.MagicMock() - session.hasPerm.return_value = True - session.getTag.return_value = tag - session.getTagGroups.return_value = [ + self.session.hasPerm.return_value = True + self.session.getTag.return_value = tag + self.session.getTagGroups.return_value = [ {'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. - activate_session_mock.assert_called_once_with(session, options) - session.hasPerm.assert_called_once_with('admin') - session.getTag.assert_called_once_with(tag) - session.getTagGroups.assert_called_once_with(tag, inherit=False) - session.groupListRemove.assert_called_once_with(tag, group) + activate_session_mock.assert_called_once_with(self.session, self.options) + self.session.hasPerm.assert_called_once_with('admin') + self.session.getTag.assert_called_once_with(tag) + self.session.getTagGroups.assert_called_once_with(tag, inherit=False) + self.session.groupListRemove.assert_called_once_with(tag, group) self.assertEqual(rv, None) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('koji_cli.commands.activate_session') def test_handle_remove_group_error_handling(self, activate_session_mock, stdout, stderr): - session = mock.MagicMock() - options = mock.MagicMock() - expected = self.format_error_message( "Please specify a tag name and a group name") for args in [[], ['tag'], ['tag', 'grp', 'etc']]: self.assert_system_exit( handle_remove_group, - options, - session, + self.options, + self.session, args, stderr=expected, activate_session=None) # if we don't have 'tag' permission - session.hasPerm.return_value = False + self.session.hasPerm.return_value = False with self.assertRaises(SystemExit): - handle_remove_group(options, session, ['tag', 'grp']) - activate_session_mock.assert_called_with(session, options) + handle_remove_group(self.options, self.session, ['tag', 'grp']) + activate_session_mock.assert_called_with(self.session, self.options) diff --git a/tests/test_cli/test_remove_pkg.py b/tests/test_cli/test_remove_pkg.py index 178e268..70f6a60 100644 --- a/tests/test_cli/test_remove_pkg.py +++ b/tests/test_cli/test_remove_pkg.py @@ -1,15 +1,17 @@ from __future__ import absolute_import -import mock + import os -import six import sys import unittest +import mock +import six from mock import call from koji_cli.commands import handle_remove_pkg from . import utils + class TestRemovePkg(utils.CliTestCase): # Show long diffs in error output... @@ -180,7 +182,7 @@ class TestRemovePkg(utils.CliTestCase): handle_remove_pkg(options, session, args) self.assertExitCode(ex, 1) actual = stderr.getvalue() - expected = 'No such tag: tag\n' + expected = 'No such tag: %s\n' % tag self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. activate_session_mock.assert_called_once_with(session, options) diff --git a/tests/test_cli/test_remove_tag.py b/tests/test_cli/test_remove_tag.py new file mode 100644 index 0000000..769f624 --- /dev/null +++ b/tests/test_cli/test_remove_tag.py @@ -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] \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) diff --git a/tests/test_cli/test_remove_tag_inheritance.py b/tests/test_cli/test_remove_tag_inheritance.py new file mode 100644 index 0000000..2b23cba --- /dev/null +++ b/tests/test_cli/test_remove_tag_inheritance.py @@ -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 \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 \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 \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) diff --git a/tests/test_cli/test_remove_target.py b/tests/test_cli/test_remove_target.py new file mode 100644 index 0000000..6d98218 --- /dev/null +++ b/tests/test_cli/test_remove_target.py @@ -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] \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) diff --git a/tests/test_cli/test_search.py b/tests/test_cli/test_search.py index a692092..c76ea81 100644 --- a/tests/test_cli/test_search.py +++ b/tests/test_cli/test_search.py @@ -61,7 +61,7 @@ Available search types: package, build, tag, target, user, host, rpm, maven, win {'argument': [], 'error': 'Please specify search type'}, {'argument': [s_type], 'error': 'Please specify search pattern'}, {'argument': [s_type, s_patt], - 'error': 'Unknown search type: %s' % s_type} + 'error': 'No such search type: %s' % s_type} ] for case in cases: diff --git a/tests/test_cli/test_spin_commands.py b/tests/test_cli/test_spin_commands.py index 66ce447..ac1bebe 100644 --- a/tests/test_cli/test_spin_commands.py +++ b/tests/test_cli/test_spin_commands.py @@ -224,7 +224,7 @@ class TestBuildImage(utils.CliTestCase): # Case 2. target not found error self.activate_session.reset_mock() 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 with self.assertRaises(koji.GenericError) as cm: _build_image(*args) @@ -235,7 +235,7 @@ class TestBuildImage(utils.CliTestCase): self.activate_session.reset_mock() self.session.getBuildTarget.return_value = self.build_target 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 with self.assertRaises(koji.GenericError) as cm: _build_image(*args) diff --git a/tests/test_cli/test_taginfo.py b/tests/test_cli/test_taginfo.py new file mode 100644 index 0000000..40c2bb8 --- /dev/null +++ b/tests/test_cli/test_taginfo.py @@ -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] [ ...]\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] [ ...]\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) diff --git a/tests/test_cli/test_unlock_tag.py b/tests/test_cli/test_unlock_tag.py new file mode 100644 index 0000000..75a114f --- /dev/null +++ b/tests/test_cli/test_unlock_tag.py @@ -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] [ ...]\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] [ ...]\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) diff --git a/tests/test_cli/test_untag_build.py b/tests/test_cli/test_untag_build.py new file mode 100644 index 0000000..2b987e5 --- /dev/null +++ b/tests/test_cli/test_untag_build.py @@ -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] [ ...]\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] [ ...]\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] [ ...]\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) diff --git a/tests/test_cli/test_wait_repo.py b/tests/test_cli/test_wait_repo.py index d0388f8..8f9dd38 100644 --- a/tests/test_cli/test_wait_repo.py +++ b/tests/test_cli/test_wait_repo.py @@ -1,9 +1,12 @@ from __future__ import absolute_import +from __future__ import absolute_import from __future__ import print_function + +import unittest import copy + import mock import six -import unittest from koji_cli.commands import anon_handle_wait_repo from . import utils @@ -25,7 +28,7 @@ class TestWaitRepo(utils.CliTestCase): 'arches': 'x86_64', 'maven_include_all': False, 'perm_id': None - } + } def setUp(self): self.task_id = 1001 @@ -106,7 +109,8 @@ class TestWaitRepo(utils.CliTestCase): arguments = [self.tag_name, '--target'] 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'}] expected = 'Successfully waited 0:03 for a new %s repo' % self.tag_name + '\n' 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' % \ (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 += '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) def test_anon_handle_wait_repo_with_build_timeout(self): @@ -163,7 +168,8 @@ class TestWaitRepo(utils.CliTestCase): ] self.checkForBuilds.return_value = True 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) def test_anon_handle_wait_repo_errors(self): @@ -172,8 +178,8 @@ class TestWaitRepo(utils.CliTestCase): # [ arguments, error_string ] [[], "Please specify a tag name"], [['tag1', 'tag2'], "Only one tag may be specified"], - [[self.tag_name], "Invalid tag: %s" % self.tag_name], - [[self.tag_name, '--target'], "Invalid build target: %s" % self.tag_name], + [[self.tag_name], "No such tag: %s" % self.tag_name], + [[self.tag_name, '--target'], "No such build target: %s" % self.tag_name], ] self.session.getBuildTarget.return_value = {} diff --git a/tests/test_cli/test_win_build.py b/tests/test_cli/test_win_build.py new file mode 100644 index 0000000..9aeac74 --- /dev/null +++ b/tests/test_cli/test_win_build.py @@ -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] \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] \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] \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] \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) diff --git a/tests/test_hub/test_add_external_repo_to_tag.py b/tests/test_hub/test_add_external_repo_to_tag.py new file mode 100644 index 0000000..0a47b36 --- /dev/null +++ b/tests/test_hub/test_add_external_repo_to_tag.py @@ -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)) diff --git a/tests/test_hub/test_add_group_member.py b/tests/test_hub/test_add_group_member.py new file mode 100644 index 0000000..4281216 --- /dev/null +++ b/tests/test_hub/test_add_group_member.py @@ -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)) diff --git a/tests/test_hub/test_cg_importer.py b/tests/test_hub/test_cg_importer.py index 176dbe5..1717963 100644 --- a/tests/test_hub/test_cg_importer.py +++ b/tests/test_hub/test_cg_importer.py @@ -33,13 +33,16 @@ class TestCGImporter(unittest.TestCase): def test_get_metadata_is_not_instance(self): x = kojihub.CG_Importer() - with self.assertRaises(GenericError): - x.get_metadata(42, '') + 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): x = kojihub.CG_Importer() - with self.assertRaises(GenericError): + with self.assertRaises(GenericError) as ex: x.get_metadata(None, '') + self.assertEqual('No such file: metadata.json', str(ex.exception)) @mock.patch("koji.pathinfo.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.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): diff --git a/tests/test_hub/test_create_notification.py b/tests/test_hub/test_create_notification.py new file mode 100644 index 0000000..e3ff819 --- /dev/null +++ b/tests/test_hub/test_create_notification.py @@ -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)) diff --git a/tests/test_hub/test_delete_build_target.py b/tests/test_hub/test_delete_build_target.py new file mode 100644 index 0000000..e5fd142 --- /dev/null +++ b/tests/test_hub/test_delete_build_target.py @@ -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)) diff --git a/tests/test_hub/test_disable_user.py b/tests/test_hub/test_disable_user.py new file mode 100644 index 0000000..60e51f4 --- /dev/null +++ b/tests/test_hub/test_disable_user.py @@ -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)) diff --git a/tests/test_hub/test_edit_build_target.py b/tests/test_hub/test_edit_build_target.py new file mode 100644 index 0000000..84e7bcf --- /dev/null +++ b/tests/test_hub/test_edit_build_target.py @@ -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') diff --git a/tests/test_hub/test_enable_user.py b/tests/test_hub/test_enable_user.py new file mode 100644 index 0000000..bc7ae2a --- /dev/null +++ b/tests/test_hub/test_enable_user.py @@ -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)) diff --git a/tests/test_hub/test_find_build_id.py b/tests/test_hub/test_find_build_id.py new file mode 100644 index 0000000..dd29172 --- /dev/null +++ b/tests/test_hub/test_find_build_id.py @@ -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)) diff --git a/tests/test_hub/test_getPackageID.py b/tests/test_hub/test_getPackageID.py index 01a0381..000284c 100644 --- a/tests/test_hub/test_getPackageID.py +++ b/tests/test_hub/test_getPackageID.py @@ -31,7 +31,7 @@ class TestGetPackageID(DBQueryTestCase): 'strict': True, 'self': mock.ANY}) self.assertEqual(cm.exception.args[0], - 'Invalid package name: invalidpkg') + 'No such package name: invalidpkg') def test_getPackageID_None(self): rv = kojihub.RootExports().getPackageID('invalidpkg') diff --git a/tests/test_hub/test_getRPM.py b/tests/test_hub/test_getRPM.py new file mode 100644 index 0000000..7b10fc6 --- /dev/null +++ b/tests/test_hub/test_getRPM.py @@ -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)) diff --git a/tests/test_hub/test_get_build.py b/tests/test_hub/test_get_build.py new file mode 100644 index 0000000..a6e42cf --- /dev/null +++ b/tests/test_hub/test_get_build.py @@ -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)) diff --git a/tests/test_hub/test_get_build_target.py b/tests/test_hub/test_get_build_target.py new file mode 100644 index 0000000..882b4da --- /dev/null +++ b/tests/test_hub/test_get_build_target.py @@ -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)) diff --git a/tests/test_hub/test_get_changelog_entries.py b/tests/test_hub/test_get_changelog_entries.py new file mode 100644 index 0000000..d75960f --- /dev/null +++ b/tests/test_hub/test_get_changelog_entries.py @@ -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)) diff --git a/tests/test_hub/test_get_channel.py b/tests/test_hub/test_get_channel.py new file mode 100644 index 0000000..c18425b --- /dev/null +++ b/tests/test_hub/test_get_channel.py @@ -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)) diff --git a/tests/test_hub/test_get_external_repo.py b/tests/test_hub/test_get_external_repo.py new file mode 100644 index 0000000..024f38f --- /dev/null +++ b/tests/test_hub/test_get_external_repo.py @@ -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)) diff --git a/tests/test_hub/test_get_external_repos.py b/tests/test_hub/test_get_external_repos.py index bd10a36..27e12b8 100644 --- a/tests/test_hub/test_get_external_repos.py +++ b/tests/test_hub/test_get_external_repos.py @@ -144,3 +144,9 @@ class TestGetExternalRepos(DBQueryTestCase): self.assertEqual(rv, [{'id': 1, 'name': 'ext_repo_1', '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)) diff --git a/tests/test_hub/test_get_group_members.py b/tests/test_hub/test_get_group_members.py new file mode 100644 index 0000000..82822f0 --- /dev/null +++ b/tests/test_hub/test_get_group_members.py @@ -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)) diff --git a/tests/test_hub/test_get_host.py b/tests/test_hub/test_get_host.py index 7bf38d0..59ed087 100644 --- a/tests/test_hub/test_get_host.py +++ b/tests/test_hub/test_get_host.py @@ -1,6 +1,7 @@ -import mock import unittest +import mock + import koji import kojihub @@ -17,7 +18,7 @@ class TestSetHostEnabled(unittest.TestCase): def setUp(self): self.QueryProcessor = mock.patch('kojihub.QueryProcessor', - side_effect=self.getQuery).start() + side_effect=self.getQuery).start() self.queries = [] self.context = mock.patch('kojihub.context').start() # It seems MagicMock will not automatically handle attributes that @@ -33,12 +34,12 @@ class TestSetHostEnabled(unittest.TestCase): self.assertEqual(len(self.queries), 1) query = self.queries[0] columns = ['host.id', 'host.user_id', 'host.name', 'host.ready', - 'host.task_load', 'host_config.arches', - 'host_config.capacity', 'host_config.description', - 'host_config.comment', 'host_config.enabled'] + 'host.task_load', 'host_config.arches', + 'host_config.capacity', 'host_config.description', + 'host_config.comment', 'host_config.enabled'] joins = ['host ON host.id = host_config.host_id'] 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'] values = {'hostInfo': 'hostname'} self.assertEqual(query.tables, ['host_config']) @@ -54,14 +55,15 @@ class TestSetHostEnabled(unittest.TestCase): self.assertEqual(len(self.queries), 1) query = self.queries[0] columns = ['host.id', 'host.user_id', 'host.name', 'host.ready', - 'host.task_load', 'host_config.arches', - 'host_config.capacity', 'host_config.description', - 'host_config.comment', 'host_config.enabled'] + 'host.task_load', 'host_config.arches', + 'host_config.capacity', 'host_config.description', + 'host_config.comment', 'host_config.enabled'] joins = ['host ON host.id = host_config.host_id'] aliases = ['id', 'user_id', 'name', 'ready', 'task_load', - 'arches', 'capacity', 'description', 'comment', 'enabled'] - clauses = ['(host_config.create_event <= 345 AND ( host_config.revoke_event IS NULL OR 345 < host_config.revoke_event ))', - 'host.id = %(hostInfo)i'] + 'arches', 'capacity', 'description', 'comment', 'enabled'] + clauses = ['(host_config.create_event <= 345 AND ( host_config.revoke_event IS NULL ' + 'OR 345 < host_config.revoke_event ))', + 'host.id = %(hostInfo)i'] values = {'hostInfo': 123} self.assertEqual(query.tables, ['host_config']) self.assertEqual(query.joins, joins) @@ -77,19 +79,21 @@ class TestSetHostEnabled(unittest.TestCase): def test_get_host_missing(self): self.QueryProcessor.side_effect = self.getQueryMissing - - r = self.exports.getHost(123) + host_id = 123 + r = self.exports.getHost(host_id) self.assertEqual(r, None) - with self.assertRaises(koji.GenericError): - self.exports.getHost(123, strict=True) + with self.assertRaises(koji.GenericError) as cm: + self.exports.getHost(host_id, strict=True) + self.assertEqual("Invalid hostInfo: %s" % host_id, str(cm.exception)) self.assertEqual(len(self.queries), 2) self.QueryProcessor.side_effect = self.getQuery def test_get_host_invalid_hostinfo(self): - with self.assertRaises(koji.GenericError): - self.exports.getHost({'host_id': 567}) - + host_info = {'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) diff --git a/tests/test_hub/test_get_last_event.py b/tests/test_hub/test_get_last_event.py new file mode 100644 index 0000000..5a06cd6 --- /dev/null +++ b/tests/test_hub/test_get_last_event.py @@ -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)) diff --git a/tests/test_hub/test_get_user.py b/tests/test_hub/test_get_user.py new file mode 100644 index 0000000..f8da250 --- /dev/null +++ b/tests/test_hub/test_get_user.py @@ -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)) diff --git a/tests/test_hub/test_import_build.py b/tests/test_hub/test_import_build.py index aa535ee..0f18a03 100644 --- a/tests/test_hub/test_import_build.py +++ b/tests/test_hub/test_import_build.py @@ -19,9 +19,12 @@ class TestImportRPM(unittest.TestCase): # Touch a file with open(self.src_filename, 'w'): pass + self.context = mock.patch('kojihub.context').start() + self.cursor = mock.MagicMock() self.rpm_header_retval = { 'filename': 'name-version-release.arch.rpm', + 'sourcepackage': 2, 1000: 'name', 1001: 'version', 1002: 'release', @@ -164,6 +167,36 @@ class TestImportRPM(unittest.TestCase): } _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): def setUp(self): @@ -283,3 +316,12 @@ class TestImportBuild(unittest.TestCase): 'id': mock.ANY, } _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)) diff --git a/tests/test_hub/test_list_rpms.py b/tests/test_hub/test_list_rpms.py new file mode 100644 index 0000000..88449dd --- /dev/null +++ b/tests/test_hub/test_list_rpms.py @@ -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)) diff --git a/tests/test_hub/test_list_tags.py b/tests/test_hub/test_list_tags.py new file mode 100644 index 0000000..73a4dd8 --- /dev/null +++ b/tests/test_hub/test_list_tags.py @@ -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)) diff --git a/tests/test_hub/test_list_user_krb_principals.py b/tests/test_hub/test_list_user_krb_principals.py new file mode 100644 index 0000000..3866510 --- /dev/null +++ b/tests/test_hub/test_list_user_krb_principals.py @@ -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)) diff --git a/tests/test_hub/test_new_build.py b/tests/test_hub/test_new_build.py index 6d95ebf..fef494b 100644 --- a/tests/test_hub/test_new_build.py +++ b/tests/test_hub/test_new_build.py @@ -151,7 +151,8 @@ class TestNewBuild(unittest.TestCase): 'extra': {'extra_key': CantDoJSON()}, } - with self.assertRaises(koji.GenericError): + with self.assertRaises(koji.GenericError) as cm: kojihub.new_build(data) self.assertEqual(len(self.inserts), 0) + self.assertEqual("No such build extra data: %(extra)r" % data, str(cm.exception)) diff --git a/tests/test_hub/test_pkglist.py b/tests/test_hub/test_pkglist.py index fa89a04..a9f660d 100644 --- a/tests/test_hub/test_pkglist.py +++ b/tests/test_hub/test_pkglist.py @@ -257,14 +257,26 @@ class TestPkglistBlock(unittest.TestCase): readPackageList.return_value = {} # 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, user['name'], block=block, extra_arches=extra_arches, 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) - self.assertEqual(self.run_callbacks.call_count, 0) - _pkglist_add.assert_not_called() + @mock.patch('kojihub.get_tag') + @mock.patch('kojihub.lookup_package') + 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.readPackageList') diff --git a/tests/test_hub/test_search.py b/tests/test_hub/test_search.py new file mode 100644 index 0000000..72fb162 --- /dev/null +++ b/tests/test_hub/test_search.py @@ -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)) diff --git a/tests/test_hub/test_tag_operations.py b/tests/test_hub/test_tag_operations.py index e67081f..33338be 100644 --- a/tests/test_hub/test_tag_operations.py +++ b/tests/test_hub/test_tag_operations.py @@ -146,3 +146,33 @@ class TestTagBuild(unittest.TestCase): self.assertEqual(update.data, data) self.assertEqual(update.values, values) 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))