From 7c5b237e660714144b3c7914bc34a3fa9315ab9e Mon Sep 17 00:00:00 2001 From: Tomas Kopecek Date: Apr 22 2020 12:49:28 +0000 Subject: [PATCH 1/2] replace print + return 1 with error() --- diff --git a/cli/koji_cli/commands.py b/cli/koji_cli/commands.py index e85d137..0a8a88e 100644 --- a/cli/koji_cli/commands.py +++ b/cli/koji_cli/commands.py @@ -82,14 +82,12 @@ def handle_add_group(goptions, session, args): dsttag = session.getTag(tag) if not dsttag: - print("Unknown tag: %s" % tag) - return 1 + error("Unknown tag: %s" % tag) groups = dict([(p['name'], p['group_id']) for p in session.getTagGroups(tag, inherit=False)]) group_id = groups.get(group, None) if group_id is not None: - print("Group %s already exists for tag %s" % (group, tag)) - return 1 + error("Group %s already exists for tag %s" % (group, tag)) session.groupListAdd(tag, group) @@ -110,14 +108,12 @@ def handle_block_group(goptions, session, args): dsttag = session.getTag(tag) if not dsttag: - print("Unknown tag: %s" % tag) - return 1 + error("Unknown tag: %s" % tag) groups = dict([(p['name'], p['group_id']) for p in session.getTagGroups(tag, inherit=False)]) group_id = groups.get(group, None) if group_id is None: - print("Group %s doesn't exist within tag %s" % (group, tag)) - return 1 + error("Group %s doesn't exist within tag %s" % (group, tag)) session.groupListBlock(tag, group) @@ -234,15 +230,14 @@ def handle_edit_host(options, session, args): session.multicall = True for host in args: session.getHost(host) - error = False + error_hit = False for host, [info] in zip(args, session.multiCall(strict=True)): if not info: - print(_("Host %s does not exist") % host) - error = True + warn(_("Host %s does not exist") % host) + error_hit = True - if error: - print(_("No changes made, please correct the command line")) - return 1 + if error_hit: + error(_("No changes made, please correct the command line")) session.multicall = True for host in args: @@ -272,13 +267,11 @@ def handle_add_host_to_channel(goptions, session, args): if not options.new: channelinfo = session.getChannel(channel) if not channelinfo: - print("No such channel: %s" % channel) - return 1 + error("No such channel: %s" % channel) host = args[0] hostinfo = session.getHost(host) if not hostinfo: - print("No such host: %s" % host) - return 1 + error("No such host: %s" % host) kwargs = {} if options.new: kwargs['create'] = True @@ -296,14 +289,12 @@ def handle_remove_host_from_channel(goptions, session, args): activate_session(session, goptions) hostinfo = session.getHost(host) if not hostinfo: - print("No such host: %s" % host) - return 1 + error("No such host: %s" % host) hostchannels = [c['name'] for c in session.listChannels(hostinfo['id'])] channel = args[1] if channel not in hostchannels: - print("Host %s is not a member of channel %s" % (host, channel)) - return 1 + error("Host %s is not a member of channel %s" % (host, channel)) session.removeHostFromChannel(host, channel) @@ -319,8 +310,7 @@ def handle_remove_channel(goptions, session, args): activate_session(session, goptions) cinfo = session.getChannel(args[0]) if not cinfo: - print("No such channel: %s" % args[0]) - return 1 + error("No such channel: %s" % args[0]) session.removeChannel(args[0], force=options.force) @@ -334,8 +324,7 @@ def handle_rename_channel(goptions, session, args): activate_session(session, goptions) cinfo = session.getChannel(args[0]) if not cinfo: - print("No such channel: %s" % args[0]) - return 1 + error("No such channel: %s" % args[0]) session.renameChannel(args[0], args[1]) @@ -352,8 +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): - print("User %s does not exist" % options.owner) - return 1 + error("User %s does not exist" % options.owner) activate_session(session, goptions) tag = args[0] opts = {} @@ -398,18 +386,17 @@ def handle_block_pkg(goptions, session, args): # check if list of packages exists for that tag already dsttag = session.getTag(tag) if dsttag is None: - print("No such tag: %s" % tag) - return 1 + error("No such tag: %s" % tag) pkglist = dict([(p['package_name'], p['package_id']) for p in session.listPackages(tagID=dsttag['id'], inherited=True)]) ret = 0 for package in args[1:]: package_id = pkglist.get(package, None) if package_id is None: - print("Package %s doesn't exist in tag %s" % (package, tag)) + warn("Package %s doesn't exist in tag %s" % (package, tag)) ret = 1 if ret: - return ret + error(code=ret) session.multicall = True for package in args[1:]: # force is not supported on older hub, so use it only explicitly @@ -436,18 +423,17 @@ def handle_remove_pkg(goptions, session, args): # check if list of packages exists for that tag already dsttag = session.getTag(tag) if dsttag is None: - print("No such tag: %s" % tag) - return 1 + error("No such tag: %s" % tag) pkglist = dict([(p['package_name'], p['package_id']) for p in session.listPackages(tagID=dsttag['id'])]) ret = 0 for package in args[1:]: package_id = pkglist.get(package, None) if package_id is None: - print("Package %s is not in tag %s" % (package, tag)) + warn("Package %s is not in tag %s" % (package, tag)) ret = 1 if ret: - return ret + error(code=ret) session.multicall = True for package in args[1:]: session.packageListRemove(tag, package, **opts) @@ -584,11 +570,9 @@ def handle_chain_build(options, session, args): ancestors = session.getFullInheritance(build_target['build_tag']) if dest_tag['id'] not in [build_target['build_tag']] + \ [ancestor['parent_id'] for ancestor in ancestors]: - print(_("Packages in destination tag %(dest_tag_name)s are not inherited by build tag " - "%(build_tag_name)s" % build_target)) - print(_("Target %s is not usable for a chain-build" % build_target['name'])) - return 1 - + warn(_("Packages in destination tag %(dest_tag_name)s are not inherited by build tag " + "%(build_tag_name)s" % build_target)) + error(_("Target %s is not usable for a chain-build" % build_target['name'])) sources = args[1:] src_list = [] @@ -608,8 +592,7 @@ def handle_chain_build(options, session, args): # quick check that it looks like a N-V-R build_level.append(src) else: - print(_('"%s" is not a SCM URL or package N-V-R' % src)) - return 1 + error(_('"%s" is not a SCM URL or package N-V-R' % src)) if build_level: src_list.append(build_level) @@ -980,8 +963,7 @@ def anon_handle_mock_config(goptions, session, args): parser.error(_("Task id must be an integer")) broots = session.listBuildroots(taskID=task_id) if not broots: - print(_("No buildroots for task %s (or no such task)") % options.task) - return 1 + error(_("No buildroots for task %s (or no such task)") % options.task) if len(broots) > 1: print(_("Multiple buildroots found: %s" % [br['id'] for br in broots])) brootinfo = broots[-1] @@ -995,29 +977,25 @@ def anon_handle_mock_config(goptions, session, args): options.name = "%s-task_%i" % (opts['tag_name'], task_id) elif options.tag: if not options.arch: - print(_("Please specify an arch")) - return 1 + error(_("Please specify an arch")) tag = session.getTag(options.tag) if not tag: parser.error(_("Invalid tag: %s" % options.tag)) arch = options.arch config = session.getBuildConfig(tag['id']) if not config: - print(_("Could not get config info for tag: %(name)s") % tag) - return 1 + error(_("Could not get config info for tag: %(name)s") % tag) opts['tag_name'] = tag['name'] if options.latest: opts['repoid'] = 'latest' else: repo = session.getRepo(config['id']) if not repo: - print(_("Could not get a repo for tag: %(name)s") % tag) - return 1 + error(_("Could not get a repo for tag: %(name)s") % tag) opts['repoid'] = repo['id'] elif options.target: if not options.arch: - print(_("Please specify an arch")) - return 1 + error(_("Please specify an arch")) arch = options.arch target = session.getBuildTarget(options.target) if not target: @@ -1028,8 +1006,7 @@ def anon_handle_mock_config(goptions, session, args): else: repo = session.getRepo(target['build_tag']) if not repo: - print(_("Could not get a repo for tag: %s") % opts['tag_name']) - return 1 + error(_("Could not get a repo for tag: %s") % opts['tag_name']) opts['repoid'] = repo['id'] else: parser.error(_("Please specify one of: --tag, --target, --task, --buildroot")) @@ -1069,14 +1046,13 @@ def handle_disable_host(goptions, session, args): session.multicall = True for host in args: session.getHost(host) - error = False + error_hit = False for host, [id] in zip(args, session.multiCall(strict=True)): if not id: print("Host %s does not exist" % host) - error = True - if error: - print("No changes made. Please correct the command line.") - return 1 + error_hit = True + if error_hit: + error("No changes made. Please correct the command line.") session.multicall = True for host in args: session.disableHost(host) @@ -1099,14 +1075,13 @@ def handle_enable_host(goptions, session, args): session.multicall = True for host in args: session.getHost(host) - error = False + error_hit = False for host, [id] in zip(args, session.multiCall(strict=True)): if not id: print("Host %s does not exist" % host) - error = True - if error: - print("No changes made. Please correct the command line.") - return 1 + error_hit = True + if error_hit: + error("No changes made. Please correct the command line.") session.multicall = True for host in args: session.enableHost(host) @@ -1149,10 +1124,9 @@ def handle_restart_hosts(options, session, args): } others = session.listTasks(query) if others: - print('Found other restartHosts tasks running.') - print('Task ids: %r' % [t['id'] for t in others]) - print('Use --force to run anyway') - return 1 + warn('Found other restartHosts tasks running.') + warn('Task ids: %r' % [t['id'] for t in others]) + error('Use --force to run anyway') callopts = {} if my_opts.channel: @@ -1389,15 +1363,13 @@ def handle_import_comps(goptions, session, args): # check if the tag exists dsttag = session.getTag(args[1]) if dsttag is None: - print("No such tag: %s" % args[1]) - return 1 + error("No such tag: %s" % args[1]) if libcomps is not None: _import_comps(session, args[0], args[1], local_options) elif yumcomps is not None: _import_comps_alt(session, args[0], args[1], local_options) else: - print("comps module not available") - return 1 + error("comps module not available") def _import_comps(session, filename, tag, options): @@ -1933,8 +1905,7 @@ def handle_set_build_volume(goptions, session, args): parser.error(_("You must provide a volume and at least one build")) volinfo = session.getVolume(args[0]) if not volinfo: - print("No such volume: %s" % args[0]) - return 1 + error("No such volume: %s" % args[0]) activate_session(session, goptions) builds = [] for nvr in args[1:]: @@ -1946,8 +1917,7 @@ def handle_set_build_volume(goptions, session, args): else: builds.append(binfo) if not builds: - print("No builds to move") - return 1 + error("No builds to move") for binfo in builds: session.changeBuildVolume(binfo['id'], volinfo['id']) if options.verbose: @@ -1964,8 +1934,7 @@ def handle_add_volume(goptions, session, args): name = args[0] volinfo = session.getVolume(name) if volinfo: - print("Volume %s already exists" % name) - return 1 + error("Volume %s already exists" % name) activate_session(session, goptions) volinfo = session.addVolume(name) print("Added volume %(name)s with id %(id)i" % volinfo) @@ -1993,8 +1962,7 @@ def handle_list_permissions(goptions, session, args): if options.user: user = session.getUser(options.user) if not user: - print("User %s does not exist" % options.user) - return 1 + error("User %s does not exist" % options.user) perms = session.getUserPerms(user['id']) elif options.mine: perms = session.getPerms() @@ -2987,8 +2955,7 @@ def anon_handle_list_pkgs(goptions, session, args): data = session.listPackages(**opts) if not data: - print("(no matching packages)") - return 1 + error("(no matching packages)") if not options.quiet: if allpkgs: print("Package") @@ -3893,14 +3860,11 @@ def handle_add_target(goptions, session, args): chkbuildtag = session.getTag(build_tag) chkdesttag = session.getTag(dest_tag) if not chkbuildtag: - print("Build tag does not exist: %s" % build_tag) - return 1 + error("Build tag does not exist: %s" % build_tag) if not chkbuildtag.get("arches", None): - print("Build tag has no arches: %s" % build_tag) - return 1 + error("Build tag has no arches: %s" % build_tag) if not chkdesttag: - print("Destination tag does not exist: %s" % dest_tag) - return 1 + error("Destination tag does not exist: %s" % dest_tag) session.createBuildTarget(name, build_tag, dest_tag) @@ -3934,16 +3898,13 @@ def handle_edit_target(goptions, session, args): targetInfo['build_tag_name'] = options.build_tag chkbuildtag = session.getTag(options.build_tag) if not chkbuildtag: - print("Build tag does not exist: %s" % options.build_tag) - return 1 + error("Build tag does not exist: %s" % options.build_tag) if not chkbuildtag.get("arches", None): - print("Build tag has no arches: %s" % options.build_tag) - return 1 + error("Build tag has no arches: %s" % options.build_tag) if options.dest_tag: chkdesttag = session.getTag(options.dest_tag) if not chkdesttag: - print("Destination tag does not exist: %s" % options.dest_tag) - return 1 + error("Destination tag does not exist: %s" % options.dest_tag) targetInfo['dest_tag_name'] = options.dest_tag session.editBuildTarget(targetInfo['orig_name'], targetInfo['name'], @@ -3966,8 +3927,7 @@ def handle_remove_target(goptions, session, args): target = args[0] target_info = session.getBuildTarget(target) if not target_info: - print("Build target %s does not exist" % target) - return 1 + error("Build target %s does not exist" % target) session.deleteBuildTarget(target_info['id']) @@ -3988,8 +3948,7 @@ def handle_remove_tag(goptions, session, args): tag = args[0] tag_info = session.getTag(tag) if not tag_info: - print("Tag %s does not exist" % tag) - return 1 + error("Tag %s does not exist" % tag) session.deleteTag(tag_info['id']) @@ -5260,18 +5219,14 @@ def handle_edit_tag_inheritance(goptions, session, args): data = [datum for datum in data if datum['priority'] == priority] if len(data) == 0: - print(_("No inheritance link found to remove. Please check your arguments")) - return 1 + error(_("No inheritance link found to remove. Please check your arguments")) elif len(data) > 1: print(_("Multiple matches for tag.")) if not parent: - print(_("Please specify a parent on the command line.")) - return 1 + error(_("Please specify a parent on the command line.")) if not priority: - print(_("Please specify a priority on the command line.")) - return 1 - print(_("Error: Key constraints may be broken. Exiting.")) - return 1 + error(_("Please specify a priority on the command line.")) + error(_("Error: Key constraints may be broken. Exiting.")) # len(data) == 1 data = data[0] @@ -5279,9 +5234,8 @@ def handle_edit_tag_inheritance(goptions, session, args): inheritanceData = session.getInheritanceData(tag['id']) samePriority = [datum for datum in inheritanceData if datum['priority'] == options.priority] if samePriority: - print(_("Error: There is already an active inheritance with that priority on %s, " + error(_("Error: There is already an active inheritance with that priority on %s, " "please specify a different priority with --priority.") % tag['name']) - return 1 new_data = data.copy() if options.priority is not None and options.priority.isdigit(): @@ -5292,8 +5246,7 @@ def handle_edit_tag_inheritance(goptions, session, args): elif options.maxdepth.lower() == "none": new_data['maxdepth'] = None else: - print(_("Invalid maxdepth: %s") % options.maxdepth) - return 1 + error(_("Invalid maxdepth: %s") % options.maxdepth) if options.intransitive: new_data['intransitive'] = options.intransitive if options.noconfig: @@ -5616,10 +5569,9 @@ def handle_remove_external_repo(goptions, session, args): if delete: # removing entirely if current_tags and not options.force: - print(_("Error: external repo %s used by tag(s): %s") % - (repo, ', '.join(current_tags))) - print(_("Use --force to remove anyway")) - return 1 + warn(_("Error: external repo %s used by tag(s): %s") % + (repo, ', '.join(current_tags))) + error(_("Use --force to remove anyway")) session.deleteExternalRepo(args[0]) else: for tag in tags: @@ -6441,15 +6393,13 @@ def handle_set_pkg_owner_global(goptions, session, args): packages = args[1:] user = session.getUser(owner) if not user: - print("No such user: %s" % owner) - return 1 + error("No such user: %s" % owner) opts = {'with_dups': True} old_user = None if options.old_user: old_user = session.getUser(options.old_user) if not old_user: - print("No such user: %s" % options.old_user) - return 1 + error("No such user: %s" % options.old_user) opts['userID'] = old_user['id'] to_change = [] for package in packages: @@ -6461,8 +6411,7 @@ def handle_set_pkg_owner_global(goptions, session, args): if not packages and options.old_user: entries = session.listPackages(**opts) if not entries: - print("No data for user %s" % old_user['name']) - return 1 + error("No data for user %s" % old_user['name']) to_change.extend(entries) for entry in to_change: if user['id'] == entry['owner_id']: @@ -6730,11 +6679,11 @@ def handle_untag_build(goptions, session, args): # not in tag, see if it even exists binfo = session.getBuild(nvr) if not binfo: - print(_("No such build: %s") % nvr) + warn(_("No such build: %s") % nvr) else: - print(_("Build %s not in tag %s") % (nvr, tag['name'])) + warn(_("Build %s not in tag %s") % (nvr, tag['name'])) if not options.force: - return 1 + error() builds.reverse() for binfo in builds: if options.test: @@ -6791,7 +6740,7 @@ def anon_handle_download_build(options, session, args): if build.isdigit(): if suboptions.latestfrom: - error("--latestfrom not compatible with build IDs, specify a package name.") + parser.error("--latestfrom not compatible with build IDs, specify a package name.") build = int(build) if suboptions.task_id: builds = session.listBuilds(taskID=build) @@ -7115,13 +7064,13 @@ def anon_handle_wait_repo(options, session, args): parser.error(_("Invalid tag: %s") % tag) targets = session.getBuildTargets(buildTagID=tag_info['id']) if not targets: - print("%(name)s is not a build tag for any target" % tag_info) + warn("%(name)s is not a build tag for any target" % tag_info) targets = session.getBuildTargets(destTagID=tag_info['id']) if targets: maybe = {}.fromkeys([t['build_tag_name'] for t in targets]) maybe = sorted(maybe.keys()) - print("Suggested tags: %s" % ', '.join(maybe)) - return 1 + warn("Suggested tags: %s" % ', '.join(maybe)) + error() tag_id = tag_info['id'] for nvr in builds: @@ -7150,12 +7099,12 @@ def anon_handle_wait_repo(options, session, args): if (time.time() - start) >= (suboptions.timeout * 60.0): if not suboptions.quiet: if builds: - print("Unsuccessfully waited %s for %s to appear in the %s repo" % + error("Unsuccessfully waited %s for %s to appear in the %s repo" % (koji.util.duration(start), koji.util.printList(suboptions.builds), tag)) else: - print("Unsuccessfully waited %s for a new %s repo" % + error("Unsuccessfully waited %s for a new %s repo" % (koji.util.duration(start), tag)) - return 1 + error() time.sleep(options.poll_interval) last_repo = repo @@ -7439,8 +7388,7 @@ def anon_handle_list_notifications(goptions, session, args): if options.user: user = session.getUser(options.user) if not user: - print("User %s does not exist" % options.user) - return 1 + error("User %s does not exist" % options.user) user_id = user['id'] else: user_id = None From 2372b3c2b4602e9dd8570765dfdc1d9c1e7e2acc Mon Sep 17 00:00:00 2001 From: Tomas Kopecek Date: Apr 22 2020 12:49:28 +0000 Subject: [PATCH 2/2] fix tests --- diff --git a/tests/test_cli/test_add_group.py b/tests/test_cli/test_add_group.py index a045647..dc1582c 100644 --- a/tests/test_cli/test_add_group.py +++ b/tests/test_cli/test_add_group.py @@ -51,9 +51,9 @@ class TestAddGroup(utils.CliTestCase): session.groupListAdd.assert_called_once_with(tag, group) self.assertNotEqual(rv, 1) - @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_add_group_dupl(self, activate_session_mock, stdout): + def test_handle_add_group_dupl(self, activate_session_mock, stderr): tag = 'tag' group = 'group' arguments = [tag, group] @@ -67,8 +67,10 @@ class TestAddGroup(utils.CliTestCase): {'name': 'group', 'group_id': 'groupId'}] # Run it and check immediate output - rv = handle_add_group(options, session, arguments) - actual = stdout.getvalue() + with self.assertRaises(SystemExit) as ex: + handle_add_group(options, session, arguments) + self.assertExitCode(ex, 1) + actual = stderr.getvalue() expected = 'Group group already exists for tag tag\n' self.assertMultiLineEqual(actual, expected) @@ -78,7 +80,6 @@ class TestAddGroup(utils.CliTestCase): session.getTag.assert_called_once_with(tag) session.getTagGroups.assert_called_once_with(tag, inherit=False) session.groupListAdd.assert_not_called() - self.assertEqual(rv, 1) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO) @@ -139,9 +140,9 @@ class TestAddGroup(utils.CliTestCase): session.getTagGroups.assert_not_called() session.groupListAdd.assert_not_called() - @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_add_group_no_tag(self, activate_session_mock, stdout): + def test_handle_add_group_no_tag(self, activate_session_mock, stderr): tag = 'tag' group = 'group' arguments = [tag, group] @@ -153,8 +154,10 @@ class TestAddGroup(utils.CliTestCase): session.getTag.return_value = None # Run it and check immediate output - rv = handle_add_group(options, session, arguments) - actual = stdout.getvalue() + with self.assertRaises(SystemExit) as ex: + handle_add_group(options, session, arguments) + self.assertExitCode(ex, 1) + actual = stderr.getvalue() expected = 'Unknown tag: tag\n' self.assertMultiLineEqual(actual, expected) @@ -164,7 +167,6 @@ class TestAddGroup(utils.CliTestCase): session.getTag.assert_called_once_with(tag) session.getTagGroups.assert_not_called() session.groupListAdd.assert_not_called() - self.assertEqual(rv, 1) if __name__ == '__main__': diff --git a/tests/test_cli/test_add_host.py b/tests/test_cli/test_add_host.py index 5c8faa7..511e46e 100644 --- a/tests/test_cli/test_add_host.py +++ b/tests/test_cli/test_add_host.py @@ -3,15 +3,12 @@ import mock import os import six import sys -try: - import unittest2 as unittest -except ImportError: - import unittest import koji from koji_cli.commands import handle_add_host +from . import utils -class TestAddHost(unittest.TestCase): +class TestAddHost(utils.CliTestCase): # Show long diffs in error output... maxDiff = None @@ -90,8 +87,9 @@ class TestAddHost(unittest.TestCase): # Run it and check immediate output # args: host, arch1, arch2, --krb-principal=krb # expected: failed, host already exists - with self.assertRaises(SystemExit): + with self.assertRaises(SystemExit) as ex: handle_add_host(options, session, arguments) + self.assertExitCode(ex, 1) actual = stderr.getvalue() expected = 'host is already in the database\n' self.assertMultiLineEqual(actual, expected) @@ -112,8 +110,9 @@ class TestAddHost(unittest.TestCase): session = mock.MagicMock() # Run it and check immediate output - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_add_host(options, session, arguments) + self.assertExitCode(ex, 2) actual_stdout = stdout.getvalue() actual_stderr = stderr.getvalue() expected_stdout = '' @@ -129,14 +128,10 @@ class TestAddHost(unittest.TestCase): activate_session_mock.assert_not_called() session.hasHost.assert_not_called() session.addHost.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) - @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_add_host_failed(self, activate_session_mock, stdout): + def test_handle_add_host_failed(self, activate_session_mock, stderr): host = 'host' arches = ['arch1', 'arch2'] krb_principal = '--krb-principal=krb' @@ -153,16 +148,12 @@ class TestAddHost(unittest.TestCase): # Run it and check immediate output # args: host, arch1, arch2, --krb-principal=krb # expected: failed - with self.assertRaises(koji.GenericError): + with self.assertRaises(koji.GenericError) as ex: handle_add_host(options, session, arguments) - actual = stdout.getvalue() + actual = stderr.getvalue() expected = '' self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. activate_session_mock.assert_called_once_with(session, options) session.getHost.assert_called_once_with(host) session.addHost.assert_called_once_with(host, arches, **kwargs) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/test_cli/test_add_host_to_channel.py b/tests/test_cli/test_add_host_to_channel.py index 9220bfe..1c3c245 100644 --- a/tests/test_cli/test_add_host_to_channel.py +++ b/tests/test_cli/test_add_host_to_channel.py @@ -10,8 +10,9 @@ except ImportError: import unittest from koji_cli.commands import handle_add_host_to_channel +from . import utils -class TestAddHostToChannel(unittest.TestCase): +class TestAddHostToChannel(utils.CliTestCase): # Show long diffs in error output... maxDiff = None @@ -104,10 +105,10 @@ class TestAddHostToChannel(unittest.TestCase): host, channel, **kwargs) self.assertNotEqual(rv, 1) - @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_add_host_to_channel_no_channel( - self, activate_session_mock, stdout): + self, activate_session_mock, stderr): host = 'host' channel = 'channel' channel_info = None @@ -121,8 +122,10 @@ class TestAddHostToChannel(unittest.TestCase): # Run it and check immediate output # args: host, channel # expected: failed, channel not found - rv = handle_add_host_to_channel(options, session, args) - actual = stdout.getvalue() + with self.assertRaises(SystemExit) as ex: + handle_add_host_to_channel(options, session, args) + self.assertExitCode(ex, 1) + actual = stderr.getvalue() expected = 'No such channel: channel\n' self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. @@ -130,12 +133,11 @@ class TestAddHostToChannel(unittest.TestCase): session.getChannel.assert_called_once_with(channel) session.getHost.assert_not_called() session.addHostToChannel.assert_not_called() - self.assertEqual(rv, 1) - @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_add_host_to_channel_no_host( - self, activate_session_mock, stdout): + self, activate_session_mock, stderr): host = 'host' host_info = None channel = 'channel' @@ -151,8 +153,10 @@ class TestAddHostToChannel(unittest.TestCase): # Run it and check immediate output # args: host, channel # expected: success - rv = handle_add_host_to_channel(options, session, args) - actual = stdout.getvalue() + with self.assertRaises(SystemExit) as ex: + handle_add_host_to_channel(options, session, args) + self.assertExitCode(ex, 1) + actual = stderr.getvalue() expected = 'No such host: host\n' self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. @@ -160,7 +164,6 @@ class TestAddHostToChannel(unittest.TestCase): session.getChannel.assert_called_once_with(channel) session.getHost.assert_called_once_with(host) session.addHostToChannel.assert_not_called() - self.assertEqual(rv, 1) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO) @@ -177,8 +180,9 @@ class TestAddHostToChannel(unittest.TestCase): # Run it and check immediate output # args: _empty_ # expected: failed, help msg shows - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_add_host_to_channel(options, session, args) + self.assertExitCode(ex, 2) actual_stdout = stdout.getvalue() actual_stderr = stderr.getvalue() expected_stdout = '' @@ -196,10 +200,6 @@ class TestAddHostToChannel(unittest.TestCase): session.getChannel.assert_not_called() session.listChannels.assert_not_called() session.addHostToChannel.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) if __name__ == '__main__': diff --git a/tests/test_cli/test_add_pkg.py b/tests/test_cli/test_add_pkg.py index 20bca2a..e8d5b28 100644 --- a/tests/test_cli/test_add_pkg.py +++ b/tests/test_cli/test_add_pkg.py @@ -12,9 +12,10 @@ except ImportError: from mock import call from koji_cli.commands import handle_add_pkg +from . import utils -class TestAddPkg(unittest.TestCase): +class TestAddPkg(utils.CliTestCase): # Show long diffs in error output... maxDiff = None @@ -108,10 +109,10 @@ class TestAddPkg(unittest.TestCase): call.multiCall(strict=True)]) self.assertNotEqual(rv, 1) - @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_add_pkg_owner_no_exists( - self, activate_session_mock, stdout): + self, activate_session_mock, stderr): tag = 'tag' packages = ['package1', 'package2', 'package3'] owner = 'owner' @@ -131,15 +132,16 @@ class TestAddPkg(unittest.TestCase): # args: --owner, --extra-arches='arch1,arch2 arch3, arch4', # tag, package1, package2, package3 # expected: failed: owner does not exist - rv = handle_add_pkg(options, session, args) - actual = stdout.getvalue() + with self.assertRaises(SystemExit) as ex: + handle_add_pkg(options, session, args) + self.assertExitCode(ex, 1) + actual = stderr.getvalue() expected = 'User owner does not exist\n' self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. activate_session_mock.assert_not_called() self.assertEqual(session.mock_calls, [call.getUser(owner)]) - self.assertEqual(rv, 1) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('koji_cli.commands.activate_session') @@ -165,8 +167,9 @@ class TestAddPkg(unittest.TestCase): # args: --owner, --extra-arches='arch1,arch2 arch3, arch4', # tag, package1, package2, package3 # expected: failed: tag does not exist - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_add_pkg(options, session, args) + self.assertExitCode(ex, 1) actual = stdout.getvalue() expected = 'No such tag: tag\n' self.assertMultiLineEqual(actual, expected) @@ -175,10 +178,6 @@ class TestAddPkg(unittest.TestCase): self.assertEqual(session.mock_calls, [call.getUser(owner), call.getTag(tag)]) - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 1) - else: - self.assertEqual(cm.exception.code, 1) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO) @@ -197,8 +196,9 @@ class TestAddPkg(unittest.TestCase): session = mock.MagicMock() # Run it and check immediate output - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_add_pkg(options, session, args) + self.assertExitCode(ex, 2) actual_stdout = stdout.getvalue() actual_stderr = stderr.getvalue() expected_stdout = '' @@ -216,10 +216,6 @@ class TestAddPkg(unittest.TestCase): session.getTag.assert_not_called() session.listPackages.assert_not_called() session.packageListAdd.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO) @@ -234,8 +230,9 @@ class TestAddPkg(unittest.TestCase): session = mock.MagicMock() # Run it and check immediate output - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_add_pkg(options, session, args) + self.assertExitCode(ex, 2) actual_stdout = stdout.getvalue() actual_stderr = stderr.getvalue() expected_stdout = '' @@ -253,10 +250,6 @@ class TestAddPkg(unittest.TestCase): session.getTag.assert_not_called() session.listPackages.assert_not_called() session.packageListAdd.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) if __name__ == '__main__': diff --git a/tests/test_cli/test_add_volume.py b/tests/test_cli/test_add_volume.py index 4a0b889..0710321 100644 --- a/tests/test_cli/test_add_volume.py +++ b/tests/test_cli/test_add_volume.py @@ -22,12 +22,14 @@ class TestAddVolume(utils.CliTestCase): %s: error: {message} """ % (self.progname, self.progname) + @mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('koji_cli.commands.activate_session') def test_handle_add_volume( self, activate_session_mock, - stdout): + stdout, + stderr): """Test handle_add_volume function""" session = mock.MagicMock() options = mock.MagicMock() @@ -49,8 +51,10 @@ class TestAddVolume(utils.CliTestCase): # Case 2. volume already exists expected = "Volume %s already exists" % vol_name + "\n" session.getVolume.return_value = vol_info - self.assertEqual(1, handle_add_volume(options, session, [vol_name])) - self.assert_console_message(stdout, expected) + with self.assertRaises(SystemExit) as ex: + handle_add_volume(options, session, [vol_name]) + self.assertExitCode(ex, 1) + self.assert_console_message(stderr, expected) session.getVolume.assert_called_with(vol_name) activate_session_mock.assert_not_called() diff --git a/tests/test_cli/test_block_group.py b/tests/test_cli/test_block_group.py index de83739..a626a66 100644 --- a/tests/test_cli/test_block_group.py +++ b/tests/test_cli/test_block_group.py @@ -18,9 +18,9 @@ class TestBlockGroup(utils.CliTestCase): %s: error: {message} """ % (self.progname, self.progname) - @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_block_group_nonexistent_tag(self, activate_session_mock, stdout): + def test_handle_block_group_nonexistent_tag(self, activate_session_mock, stderr): tag = 'nonexistent-tag' group = 'group' arguments = [tag, group] @@ -32,8 +32,10 @@ class TestBlockGroup(utils.CliTestCase): session.getTag.return_value = None # Run it and check immediate output - rv = handle_block_group(options, session, arguments) - actual = stdout.getvalue() + with self.assertRaises(SystemExit) as ex: + handle_block_group(options, session, arguments) + self.assertExitCode(ex, 1) + actual = stderr.getvalue() expected = 'Unknown tag: %s\n' % tag self.assertMultiLineEqual(actual, expected) @@ -43,11 +45,10 @@ class TestBlockGroup(utils.CliTestCase): session.getTag.assert_called_once_with(tag) session.getTagGroups.assert_not_called() session.groupListBlock.assert_not_called() - self.assertEqual(rv, 1) - @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_block_group_nonexistent_group(self, activate_session_mock, stdout): + def test_handle_block_group_nonexistent_group(self, activate_session_mock, stderr): tag = 'tag' group = 'group' arguments = [tag, group] @@ -60,8 +61,10 @@ class TestBlockGroup(utils.CliTestCase): session.getTagGroups.return_value = [] # Run it and check immediate output - rv = handle_block_group(options, session, arguments) - actual = stdout.getvalue() + with self.assertRaises(SystemExit) as ex: + handle_block_group(options, session, arguments) + self.assertExitCode(ex, 1) + actual = stderr.getvalue() expected = "Group %s doesn't exist within tag %s\n" % (group, tag) self.assertMultiLineEqual(actual, expected) @@ -71,7 +74,6 @@ class TestBlockGroup(utils.CliTestCase): session.getTag.assert_called_once_with(tag) session.getTagGroups.assert_called_once_with(tag, inherit=False) session.groupListBlock.assert_not_called() - self.assertEqual(rv, 1) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('koji_cli.commands.activate_session') diff --git a/tests/test_cli/test_block_pkg.py b/tests/test_cli/test_block_pkg.py index a7bf3e0..3a906ca 100644 --- a/tests/test_cli/test_block_pkg.py +++ b/tests/test_cli/test_block_pkg.py @@ -3,17 +3,14 @@ import mock import os import six import sys -try: - import unittest2 as unittest -except ImportError: - import unittest from mock import call from koji_cli.commands import handle_block_pkg +from . import utils -class TestBlockPkg(unittest.TestCase): +class TestBlockPkg(utils.CliTestCase): # Show long diffs in error output... maxDiff = None @@ -48,7 +45,7 @@ class TestBlockPkg(unittest.TestCase): session.packageListBlock.assert_called_once_with( tag, package, force=True) session.multiCall.assert_called_once_with(strict=True) - self.assertNotEqual(rv, 1) + self.assertFalse(rv) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('koji_cli.commands.activate_session') @@ -88,9 +85,9 @@ class TestBlockPkg(unittest.TestCase): call.multiCall(strict=True)]) self.assertNotEqual(rv, 1) - @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_block_pkg_no_package(self, activate_session_mock, stdout): + def test_handle_block_pkg_no_package(self, activate_session_mock, stderr): tag = 'tag' dsttag = {'name': tag, 'id': 1} packages = ['package1', 'package2', 'package3'] @@ -108,8 +105,10 @@ class TestBlockPkg(unittest.TestCase): # Run it and check immediate output # args: tag, package1, package2, package3 # expected: failed: can not find package2 under tag - rv = handle_block_pkg(options, session, args) - actual = stdout.getvalue() + with self.assertRaises(SystemExit) as ex: + handle_block_pkg(options, session, args) + self.assertExitCode(ex, 1) + actual = stderr.getvalue() expected = 'Package package2 doesn\'t exist in tag tag\n' self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. @@ -119,12 +118,11 @@ class TestBlockPkg(unittest.TestCase): tagID=dsttag['id'], inherited=True) session.packageListBlock.assert_not_called() session.multiCall.assert_not_called() - self.assertEqual(rv, 1) - @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_block_pkg_tag_no_exists( - self, activate_session_mock, stdout): + self, activate_session_mock, stderr): tag = 'tag' dsttag = None packages = ['package1', 'package2', 'package3'] @@ -138,8 +136,10 @@ class TestBlockPkg(unittest.TestCase): # Run it and check immediate output # args: tag, package1, package2, package3 # expected: failed: tag does not exist - rv = handle_block_pkg(options, session, args) - actual = stdout.getvalue() + with self.assertRaises(SystemExit) as ex: + handle_block_pkg(options, session, args) + self.assertExitCode(ex, 1) + actual = stderr.getvalue() expected = 'No such tag: tag\n' self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. @@ -147,7 +147,6 @@ class TestBlockPkg(unittest.TestCase): session.getTag.assert_called_once_with(tag) session.listPackages.assert_not_called() session.packageListBlock.assert_not_called() - self.assertEqual(rv, 1) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO) @@ -163,8 +162,9 @@ class TestBlockPkg(unittest.TestCase): session = mock.MagicMock() # Run it and check immediate output - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_block_pkg(options, session, args) + self.assertExitCode(ex, 2) actual_stdout = stdout.getvalue() actual_stderr = stderr.getvalue() expected_stdout = '' @@ -181,11 +181,3 @@ class TestBlockPkg(unittest.TestCase): session.getTag.assert_not_called() session.listPackages.assert_not_called() session.packageListBlock.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/test_cli/test_build.py b/tests/test_cli/test_build.py index 0766916..3c6477a 100644 --- a/tests/test_cli/test_build.py +++ b/tests/test_cli/test_build.py @@ -152,8 +152,9 @@ Task info: weburl/taskinfo?taskID=1 progname = os.path.basename(sys.argv[0]) or 'koji' # Run it and check immediate output - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_build(self.options, self.session, args) + self.assertExitCode(ex, 2) actual_stdout = stdout.getvalue() actual_stderr = stderr.getvalue() expected_stdout = '' @@ -171,10 +172,6 @@ Task info: weburl/taskinfo?taskID=1 self.session.build.assert_not_called() self.session.logout.assert_not_called() watch_tasks_mock.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO) @@ -194,8 +191,9 @@ Task info: weburl/taskinfo?taskID=1 progname = os.path.basename(sys.argv[0]) or 'koji' # Run it and check immediate output - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_build(self.options, self.session, args) + self.assertExitCode(ex, 0) actual_stdout = stdout.getvalue() actual_stderr = stderr.getvalue() expected_stdout = """Usage: %s build [options] @@ -242,10 +240,6 @@ Options: self.session.build.assert_not_called() self.session.logout.assert_not_called() watch_tasks_mock.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 0) - else: - self.assertEqual(cm.exception.code, 0) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO) @@ -268,8 +262,9 @@ Options: progname = os.path.basename(sys.argv[0]) or 'koji' # Run it and check immediate output - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_build(self.options, self.session, args) + self.assertExitCode(ex, 2) actual_stdout = stdout.getvalue() actual_stderr = stderr.getvalue() expected_stdout = '' @@ -287,10 +282,6 @@ Options: self.session.build.assert_not_called() self.session.logout.assert_not_called() watch_tasks_mock.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('koji_cli.commands.activate_session') @@ -361,8 +352,9 @@ Task info: weburl/taskinfo?taskID=1 # Run it and check immediate output # args: target, http://scm # expected: failed, target not found - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_build(self.options, self.session, args) + self.assertExitCode(ex, 2) actual = stderr.getvalue() expected = self.format_error_message( "Unknown build target: target") self.assertMultiLineEqual(actual, expected) @@ -376,10 +368,6 @@ Task info: weburl/taskinfo?taskID=1 self.session.build.assert_not_called() self.session.logout.assert_not_called() watch_tasks_mock.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) @mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('koji_cli.commands.activate_session') @@ -408,8 +396,9 @@ Task info: weburl/taskinfo?taskID=1 # Run it and check immediate output # args: target, http://scm # expected: failed, dest_tag not found - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: 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") self.assertMultiLineEqual(actual, expected) @@ -423,10 +412,6 @@ Task info: weburl/taskinfo?taskID=1 self.session.build.assert_not_called() self.session.logout.assert_not_called() watch_tasks_mock.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) @mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('koji_cli.commands.activate_session') @@ -455,8 +440,9 @@ Task info: weburl/taskinfo?taskID=1 # Run it and check immediate output # args: target, http://scm # expected: failed, dest_tag is locked - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_build(self.options, self.session, args) + self.assertExitCode(ex, 2) actual = stderr.getvalue() expected = self.format_error_message("Destination tag dest_tag_name is locked") self.assertMultiLineEqual(actual, expected) @@ -470,10 +456,6 @@ Task info: weburl/taskinfo?taskID=1 self.session.build.assert_not_called() self.session.logout.assert_not_called() watch_tasks_mock.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('koji_cli.commands.activate_session') @@ -838,7 +820,3 @@ Task info: weburl/taskinfo?taskID=1 self.session.logout.assert_not_called() watch_tasks_mock.assert_not_called() self.assertIsNone(rv) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/test_cli/test_call.py b/tests/test_cli/test_call.py index 8ffcf89..dfba8b8 100644 --- a/tests/test_cli/test_call.py +++ b/tests/test_cli/test_call.py @@ -122,15 +122,12 @@ class TestCall(utils.CliTestCase): for mod, msg in module.items(): with mock.patch('koji_cli.commands.%s' % mod, new=None): - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_call(options, session, arguments) + self.assertExitCode(ex, 2) expected = self.format_error_message(msg) self.assert_console_message(stderr, expected) activate_session_mock.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) def test_handle_call_help(self): """Test handle_call help message""" diff --git a/tests/test_cli/test_chain_build.py b/tests/test_cli/test_chain_build.py index b8ab16d..f98b7c9 100644 --- a/tests/test_cli/test_chain_build.py +++ b/tests/test_cli/test_chain_build.py @@ -10,8 +10,9 @@ except ImportError: import unittest from koji_cli.commands import handle_chain_build +from . import utils -class TestChainBuild(unittest.TestCase): +class TestChainBuild(utils.CliTestCase): # Show long diffs in error output... maxDiff = None @@ -100,8 +101,9 @@ Task info: weburl/taskinfo?taskID=1 progname = os.path.basename(sys.argv[0]) or 'koji' # Run it and check immediate output - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_chain_build(self.options, self.session, args) + self.assertExitCode(ex, 2) actual_stdout = stdout.getvalue() actual_stderr = stderr.getvalue() expected_stdout = '' @@ -122,10 +124,6 @@ Task info: weburl/taskinfo?taskID=1 self.session.chainBuild.assert_not_called() self.session.logout.assert_not_called() watch_tasks_mock.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO) @@ -143,8 +141,9 @@ Task info: weburl/taskinfo?taskID=1 progname = os.path.basename(sys.argv[0]) or 'koji' # Run it and check immediate output - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_chain_build(self.options, self.session, args) + self.assertExitCode(ex, 0) actual_stdout = stdout.getvalue() actual_stderr = stderr.getvalue() expected_stdout = """Usage: %s chain-build [options] [ [:] [:] ...] @@ -169,10 +168,6 @@ Options: self.session.chainBuild.assert_not_called() self.session.logout.assert_not_called() watch_tasks_mock.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 0) - else: - self.assertEqual(cm.exception.code, 0) @mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('koji_cli.commands.activate_session') @@ -203,8 +198,9 @@ Options: # Run it and check immediate output # args: target http://scm1 : http://scm2 http://scm3 n-v-r-1 : n-v-r-2 n-v-r-3 # expected: failed, target not found - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_chain_build(self.options, self.session, args) + self.assertExitCode(ex, 2) actual = stderr.getvalue() expected = """Usage: %s chain-build [options] [ [:] [:] ...] (Specify the --help global option for a list of other help options) @@ -221,10 +217,6 @@ Options: self.session.chainBuild.assert_not_called() self.session.logout.assert_not_called() watch_tasks_mock.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) @mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('koji_cli.commands.activate_session') @@ -265,8 +257,9 @@ Options: # Run it and check immediate output # args: target http://scm1 : http://scm2 http://scm3 n-v-r-1 : n-v-r-2 n-v-r-3 # expected: failed, dest_tag is locked - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_chain_build(self.options, self.session, args) + self.assertExitCode(ex, 2) actual = stderr.getvalue() expected = """Usage: %s chain-build [options] [ [:] [:] ...] (Specify the --help global option for a list of other help options) @@ -283,17 +276,13 @@ Options: self.session.chainBuild.assert_not_called() self.session.logout.assert_not_called() watch_tasks_mock.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) - @mock.patch('sys.stdout', new_callable=six.StringIO) + @mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('koji_cli.commands.activate_session') @mock.patch('koji_cli.commands._running_in_bg', return_value=False) @mock.patch('koji_cli.commands.watch_tasks', return_value=0) def test_handle_build_dest_tag_not_inherited_by_build_tag( - self, watch_tasks_mock, running_in_bg_mock, activate_session_mock, stdout): + self, watch_tasks_mock, running_in_bg_mock, activate_session_mock, stderr): target = 'target' dest_tag = 'dest_tag' dest_tag_id = 2 @@ -324,8 +313,10 @@ Options: # Run it and check immediate output # args: target, target http://scm1 : http://scm2 http://scm3 n-v-r-1 : n-v-r-2 n-v-r-3 # expected: failed, dest_tag is not in build_tag's inheritance - rv = handle_chain_build(self.options, self.session, args) - actual = stdout.getvalue() + with self.assertRaises(SystemExit) as ex: + handle_chain_build(self.options, self.session, args) + self.assertExitCode(ex, 1) + actual = stderr.getvalue() expected = """Packages in destination tag dest_tag are not inherited by build tag build_tag Target target is not usable for a chain-build """ @@ -339,7 +330,6 @@ Target target is not usable for a chain-build self.session.chainBuild.assert_not_called() self.session.logout.assert_not_called() watch_tasks_mock.assert_not_called() - self.assertEqual(rv, 1) @mock.patch('koji_cli.commands.activate_session') @mock.patch('koji_cli.commands._running_in_bg', return_value=False) @@ -375,12 +365,14 @@ Target target is not usable for a chain-build self.session.getBuildTarget.return_value = target_info self.session.getTag.return_value = dest_tag_info self.session.getFullInheritance.return_value = tag_tree - with mock.patch('sys.stdout', new_callable=six.StringIO) as stdout: + with mock.patch('sys.stderr', new_callable=six.StringIO) as stderr: # Run it and check immediate output # args: target badnvr : http://scm2 http://scm3 n-v-r-1 : n-v-r-2 n-v-r-3 # expected: failed, src is neither scm nor good n-v-r - rv = handle_chain_build(self.options, self.session, args) - actual = stdout.getvalue() + with self.assertRaises(SystemExit) as ex: + handle_chain_build(self.options, self.session, args) + self.assertExitCode(ex, 1) + actual = stderr.getvalue() expected = '"badnvr" is not a SCM URL or package N-V-R\n' self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. @@ -394,9 +386,8 @@ Target target is not usable for a chain-build running_in_bg_mock.assert_not_called() self.session.logout.assert_not_called() watch_tasks_mock.assert_not_called() - self.assertEqual(rv, 1) - with mock.patch('sys.stdout', new_callable=six.StringIO) as stdout: + with mock.patch('sys.stderr', new_callable=six.StringIO) as stderr: source_args = [ 'path/n-v-r', ':', @@ -409,12 +400,14 @@ Target target is not usable for a chain-build args = [target] + source_args # args: target path/n-v-r : http://scm2 http://scm3 n-v-r-1 : n-v-r-2 n-v-r-3 # expected: failed - handle_chain_build(self.options, self.session, args) - actual = stdout.getvalue() + with self.assertRaises(SystemExit) as ex: + handle_chain_build(self.options, self.session, args) + self.assertExitCode(ex, 1) + actual = stderr.getvalue() expected = '"path/n-v-r" is not a SCM URL or package N-V-R\n' self.assertMultiLineEqual(actual, expected) - with mock.patch('sys.stdout', new_callable=six.StringIO) as stdout: + with mock.patch('sys.stderr', new_callable=six.StringIO) as stderr: source_args = [ 'badn-vr', ':', @@ -427,12 +420,14 @@ Target target is not usable for a chain-build args = [target] + source_args # args: target badn-vr : http://scm2 http://scm3 n-v-r-1 : n-v-r-2 n-v-r-3 # expected: failed - handle_chain_build(self.options, self.session, args) - actual = stdout.getvalue() + with self.assertRaises(SystemExit) as ex: + handle_chain_build(self.options, self.session, args) + self.assertExitCode(ex, 1) + actual = stderr.getvalue() expected = '"badn-vr" is not a SCM URL or package N-V-R\n' self.assertMultiLineEqual(actual, expected) - with mock.patch('sys.stdout', new_callable=six.StringIO) as stdout: + with mock.patch('sys.stderr', new_callable=six.StringIO) as stderr: source_args = [ 'badn-v-r.rpm', ':', @@ -445,8 +440,10 @@ Target target is not usable for a chain-build args = [target] + source_args # args: target badn-v-r.rpm : http://scm2 http://scm3 n-v-r-1 : n-v-r-2 n-v-r-3 # expected: failed - handle_chain_build(self.options, self.session, args) - actual = stdout.getvalue() + with self.assertRaises(SystemExit) as ex: + handle_chain_build(self.options, self.session, args) + self.assertExitCode(ex, 1) + actual = stderr.getvalue() expected = '"badn-v-r.rpm" is not a SCM URL or package N-V-R\n' self.assertMultiLineEqual(actual, expected) @@ -458,8 +455,9 @@ Target target is not usable for a chain-build # args: target http://scm # expected: failed, only one src found - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_chain_build(self.options, self.session, args) + self.assertExitCode(ex, 2) actual = stderr.getvalue() expected = """Usage: %s chain-build [options] [ [:] [:] ...] (Specify the --help global option for a list of other help options) @@ -468,10 +466,6 @@ Target target is not usable for a chain-build If there are no dependencies, use the build command instead """ % (progname, progname) self.assertMultiLineEqual(actual, expected) - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('koji_cli.commands.activate_session') diff --git a/tests/test_cli/test_disable_host.py b/tests/test_cli/test_disable_host.py index 5f44aba..e8824e6 100644 --- a/tests/test_cli/test_disable_host.py +++ b/tests/test_cli/test_disable_host.py @@ -24,12 +24,14 @@ class TestDisableHost(utils.CliTestCase): """ % (self.progname, self.progname) + @mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('koji_cli.commands.activate_session') def test_handle_disable_host( self, activate_session_mock, - stdout): + stdout, + stderr): """Test %s function""" % handle_disable_host.__name__ arguments = [] options = mock.MagicMock() @@ -59,7 +61,9 @@ class TestDisableHost(utils.CliTestCase): session.multiCall.return_value = [[None], [None]] arguments = ['host1', 'host2'] - self.assertEqual(1, handle_disable_host(options, session, arguments)) + with self.assertRaises(SystemExit) as ex: + handle_disable_host(options, session, arguments) + self.assertExitCode(ex, 1) activate_session_mock.assert_called_once() session.getHost.assert_has_calls([call('host1'), call('host2')]) session.multiCall.assert_called_once() @@ -68,8 +72,8 @@ class TestDisableHost(utils.CliTestCase): expect = '' for host in arguments: expect += "Host %s does not exist\n" % host - expect += "No changes made. Please correct the command line.\n" self.assert_console_message(stdout, expect) + self.assert_console_message(stderr, "No changes made. Please correct the command line.\n") # reset session mocks activate_session_mock.reset_mock() diff --git a/tests/test_cli/test_download_task.py b/tests/test_cli/test_download_task.py index e89fd8f..b405e60 100644 --- a/tests/test_cli/test_download_task.py +++ b/tests/test_cli/test_download_task.py @@ -4,17 +4,14 @@ from mock import call import os import six import sys -try: - import unittest2 as unittest -except ImportError: - import unittest from koji_cli.commands import anon_handle_download_task +from . import utils progname = os.path.basename(sys.argv[0]) or 'koji' -class TestDownloadTask(unittest.TestCase): +class TestDownloadTask(utils.CliTestCase): # Show long diffs in error output... maxDiff = None @@ -98,8 +95,9 @@ class TestDownloadTask(unittest.TestCase): # Run it and check immediate output # args: task_id # expected: error - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: anon_handle_download_task(self.options, self.session, args) + self.assertExitCode(ex, 1) actual = self.stdout.getvalue() expected = '' self.assertMultiLineEqual(actual, expected) @@ -111,10 +109,6 @@ class TestDownloadTask(unittest.TestCase): self.options) self.session.getTaskInfo.assert_called_once_with(task_id) self.session.getTaskChildren.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 1) - else: - self.assertEqual(cm.exception.code, 1) def test_handle_download_task_parent(self): task_id = 123333 @@ -220,8 +214,9 @@ class TestDownloadTask(unittest.TestCase): # Run it and check immediate output # args: task_id --arch=s390,ppc # expected: failure - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: anon_handle_download_task(self.options, self.session, args) + self.assertExitCode(ex, 1) actual = self.stdout.getvalue() expected = '' self.assertMultiLineEqual(actual, expected) @@ -234,10 +229,6 @@ class TestDownloadTask(unittest.TestCase): self.session.getTaskChildren.assert_not_called() self.list_task_output_all_volumes.assert_called_once_with(self.session, task_id) self.download_file.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 1) - else: - self.assertEqual(cm.exception.code, 1) def test_handle_download_parent_not_finished(self): task_id = 123333 @@ -256,8 +247,9 @@ class TestDownloadTask(unittest.TestCase): # Run it and check immediate output # args: task_id # expected: failure - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: anon_handle_download_task(self.options, self.session, args) + self.assertExitCode(ex, 1) actual = self.stdout.getvalue() expected = '' self.assertMultiLineEqual(actual, expected) @@ -270,10 +262,6 @@ class TestDownloadTask(unittest.TestCase): self.session.getTaskChildren.assert_not_called() self.list_task_output_all_volumes.assert_called_once_with(self.session, task_id) self.download_file.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 1) - else: - self.assertEqual(cm.exception.code, 1) def test_handle_download_child_not_finished(self): task_id = 123333 @@ -290,8 +278,9 @@ class TestDownloadTask(unittest.TestCase): # Run it and check immediate output # args: task_id # expected: failure - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: anon_handle_download_task(self.options, self.session, args) + self.assertExitCode(ex, 1) actual = self.stdout.getvalue() expected = '' self.assertMultiLineEqual(actual, expected) @@ -304,10 +293,6 @@ class TestDownloadTask(unittest.TestCase): self.session.getTaskChildren.assert_called_once_with(task_id) self.list_task_output_all_volumes.assert_called_once_with(self.session, 22222) self.download_file.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 1) - else: - self.assertEqual(cm.exception.code, 1) def test_handle_download_invalid_file_name(self): task_id = 123333 @@ -320,8 +305,9 @@ class TestDownloadTask(unittest.TestCase): # Run it and check immediate output # args: task_id # expected: failure - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: anon_handle_download_task(self.options, self.session, args) + self.assertExitCode(ex, 1) actual = self.stdout.getvalue() expected = '' self.assertMultiLineEqual(actual, expected) @@ -334,18 +320,15 @@ class TestDownloadTask(unittest.TestCase): self.session.getTaskChildren.assert_not_called() self.list_task_output_all_volumes.assert_called_once_with(self.session, task_id) self.download_file.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 1) - else: - self.assertEqual(cm.exception.code, 1) def test_handle_download_help(self): args = ['--help'] # Run it and check immediate output # args: --help # expected: failure - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: anon_handle_download_task(self.options, self.session, args) + self.assertExitCode(ex, 0) actual = self.stdout.getvalue() expected = """Usage: %s download-task (Specify the --help global option for a list of other help options) @@ -363,18 +346,15 @@ Options: actual = self.stderr.getvalue() expected = '' self.assertEqual(actual, expected) - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 0) - else: - self.assertEqual(cm.exception.code, 0) def test_handle_download_no_task_id(self): args = [] # Run it and check immediate output # no args # expected: failure - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: anon_handle_download_task(self.options, self.session, args) + self.assertExitCode(ex, 2) actual = self.stdout.getvalue() expected = '' self.assertMultiLineEqual(actual, expected) @@ -385,18 +365,15 @@ Options: %s: error: Please specify a task ID """ % (progname, progname) self.assertEqual(actual, expected) - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) def test_handle_download_multi_task_id(self): args = ["123", "456"] # Run it and check immediate output # args: 123 456 # expected: failure - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: anon_handle_download_task(self.options, self.session, args) + self.assertExitCode(ex, 2) actual = self.stdout.getvalue() expected = '' self.assertMultiLineEqual(actual, expected) @@ -407,11 +384,3 @@ Options: %s: error: Only one task ID may be specified """ % (progname, progname) self.assertEqual(actual, expected) - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/test_cli/test_edit_host.py b/tests/test_cli/test_edit_host.py index 6b5641f..578db7a 100644 --- a/tests/test_cli/test_edit_host.py +++ b/tests/test_cli/test_edit_host.py @@ -11,8 +11,9 @@ except ImportError: from mock import call from koji_cli.commands import handle_edit_host +from . import utils -class TestEditHost(unittest.TestCase): +class TestEditHost(utils.CliTestCase): # Show long diffs in error output... maxDiff = None @@ -157,8 +158,9 @@ class TestEditHost(unittest.TestCase): # Run it and check immediate output # args: _empty_ # expected: failed - should specify host - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_edit_host(options, session, args) + self.assertExitCode(ex, 2) actual_stdout = stdout.getvalue() actual_stderr = stderr.getvalue() expected_stdout = '' @@ -175,14 +177,10 @@ class TestEditHost(unittest.TestCase): session.getHost.assert_not_called() session.editHost.assert_not_called() session.multiCall.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) - @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_edit_host_no_host(self, activate_session_mock, stdout): + def test_handle_edit_host_no_host(self, activate_session_mock, stderr): host = 'host' host_info = None arches = 'arch1 arch2' @@ -204,8 +202,10 @@ class TestEditHost(unittest.TestCase): # args: host, --arches='arch1 arch2', --capacity=0.22, # --description=description, --comment=comment # expected: failed -- getHost() == None - rv = handle_edit_host(options, session, args) - actual = stdout.getvalue() + with self.assertRaises(SystemExit) as ex: + handle_edit_host(options, session, args) + self.assertExitCode(ex, 1) + actual = stderr.getvalue() expected = """Host host does not exist No changes made, please correct the command line """ @@ -215,7 +215,6 @@ No changes made, please correct the command line session.getHost.assert_called_once_with(host) session.editHost.assert_not_called() self.assertEqual(session.multiCall.call_count, 1) - self.assertEqual(rv, 1) if __name__ == '__main__': unittest.main() diff --git a/tests/test_cli/test_edit_tag.py b/tests/test_cli/test_edit_tag.py index b08404b..719dcbb 100644 --- a/tests/test_cli/test_edit_tag.py +++ b/tests/test_cli/test_edit_tag.py @@ -3,17 +3,14 @@ import mock import os import six import sys -try: - import unittest2 as unittest -except ImportError: - import unittest from koji_cli.commands import handle_edit_tag +from . import utils progname = os.path.basename(sys.argv[0]) or 'koji' -class TestEditTag(unittest.TestCase): +class TestEditTag(utils.CliTestCase): # Show long diffs in error output... maxDiff = None @@ -107,8 +104,9 @@ class TestEditTag(unittest.TestCase): # Run it and check immediate output # args: --help # expected: failed, help info shows - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_edit_tag(options, session, args) + self.assertExitCode(ex, 0) actual_stdout = stdout.getvalue() actual_stderr = stderr.getvalue() expected_stdout = """Usage: %s edit-tag [options] @@ -139,10 +137,6 @@ Options: # Finally, assert that things were called as we expected. activate_session_mock.assert_not_called() session.editTag2.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 0) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO) @@ -157,8 +151,9 @@ Options: # Run it and check immediate output # args: --help # expected: failed, help info shows - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_edit_tag(options, session, args) + self.assertExitCode(ex, 2) actual_stdout = stdout.getvalue() actual_stderr = stderr.getvalue() expected_stdout = '' @@ -172,11 +167,3 @@ Options: # Finally, assert that things were called as we expected. activate_session_mock.assert_not_called() session.editTag2.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/test_cli/test_edit_user.py b/tests/test_cli/test_edit_user.py index 12e43af..5c79920 100644 --- a/tests/test_cli/test_edit_user.py +++ b/tests/test_cli/test_edit_user.py @@ -10,11 +10,12 @@ except ImportError: from koji_cli.commands import handle_edit_user +from . import utils progname = os.path.basename(sys.argv[0]) or 'koji' -class TestEditUser(unittest.TestCase): +class TestEditUser(utils.CliTestCase): # Show long diffs in error output... maxDiff = None @@ -101,8 +102,9 @@ Options: # Run it and check immediate output # args: --help # expected: failed, help info shows - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_edit_user(options, session, args) + self.assertExitCode(ex, 2) actual_stdout = stdout.getvalue() actual_stderr = stderr.getvalue() expected_stdout = '' @@ -116,11 +118,6 @@ Options: # Finally, assert that things were called as we expected. activate_session_mock.assert_not_called() session.editUser.assert_not_called() - if isinstance(cm.exception, int): - # RHEL6 - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) if __name__ == '__main__': diff --git a/tests/test_cli/test_enable_host.py b/tests/test_cli/test_enable_host.py index 20fc5ee..fc5941f 100644 --- a/tests/test_cli/test_enable_host.py +++ b/tests/test_cli/test_enable_host.py @@ -23,12 +23,14 @@ class TestEnableHost(utils.CliTestCase): %s: error: {message} """ % (self.progname, self.progname) + @mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('koji_cli.commands.activate_session') def test_handle_enable_host( self, activate_session_mock, - stdout): + stdout, + stderr): """Test %s function""" % handle_enable_host.__name__ arguments = [] options = mock.MagicMock() @@ -58,7 +60,9 @@ class TestEnableHost(utils.CliTestCase): session.multiCall.return_value = [[None], [None]] arguments = ['host1', 'host2'] - self.assertEqual(1, handle_enable_host(options, session, arguments)) + with self.assertRaises(SystemExit) as ex: + handle_enable_host(options, session, arguments) + self.assertExitCode(ex, 1) activate_session_mock.assert_called_once() session.getHost.assert_has_calls([call('host1'), call('host2')]) session.multiCall.assert_called_once() @@ -67,8 +71,9 @@ class TestEnableHost(utils.CliTestCase): expect = '' for host in arguments: expect += "Host %s does not exist\n" % host - expect += "No changes made. Please correct the command line.\n" + stderr_exp = "No changes made. Please correct the command line.\n" self.assert_console_message(stdout, expect) + self.assert_console_message(stderr, stderr_exp) # reset session mocks activate_session_mock.reset_mock() diff --git a/tests/test_cli/test_import_comps.py b/tests/test_cli/test_import_comps.py index 1f78b87..18abae4 100644 --- a/tests/test_cli/test_import_comps.py +++ b/tests/test_cli/test_import_comps.py @@ -23,8 +23,9 @@ from nose.plugins.skip import SkipTest import koji_cli.commands from koji_cli.commands import handle_import_comps, _import_comps,\ _import_comps_alt +from . import utils -class TestImportComps(unittest.TestCase): +class TestImportComps(utils.CliTestCase): # Show long diffs in error output... maxDiff = None @@ -109,7 +110,7 @@ class TestImportComps(unittest.TestCase): session, filename, tag, local_options) self.assertNotEqual(rv, 1) - @mock.patch('sys.stdout', new_callable=six.StringIO) + @mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('koji_cli.commands.libcomps', new=None) @mock.patch('koji_cli.commands.yumcomps', new=None, create=True) @mock.patch('koji_cli.commands.activate_session') @@ -120,7 +121,7 @@ class TestImportComps(unittest.TestCase): mock_import_comps_alt, mock_import_comps, mock_activate_session, - stdout): + stderr): filename = './data/comps-example.xml' tag = 'tag' tag_info = {'name': tag, 'id': 1} @@ -134,8 +135,10 @@ class TestImportComps(unittest.TestCase): # Run it and check immediate output # args: --force, ./data/comps-example.xml, tag # expected: failed, no comps available - rv = handle_import_comps(options, session, args) - actual = stdout.getvalue() + with self.assertRaises(SystemExit) as ex: + handle_import_comps(options, session, args) + self.assertExitCode(ex, 1) + actual = stderr.getvalue() expected = 'comps module not available\n' self.assertMultiLineEqual(actual, expected) @@ -144,9 +147,8 @@ class TestImportComps(unittest.TestCase): session.getTag.assert_called_once_with(tag) mock_import_comps.assert_not_called() mock_import_comps_alt.assert_not_called() - self.assertEqual(rv, 1) - @mock.patch('sys.stdout', new_callable=six.StringIO) + @mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('koji_cli.commands.activate_session') @mock.patch('koji_cli.commands._import_comps') @mock.patch('koji_cli.commands._import_comps_alt') @@ -155,7 +157,7 @@ class TestImportComps(unittest.TestCase): mock_import_comps_alt, mock_import_comps, mock_activate_session, - stdout): + stderr): filename = './data/comps-example.xml' tag = 'tag' tag_info = None @@ -169,8 +171,10 @@ class TestImportComps(unittest.TestCase): # Run it and check immediate output # args: ./data/comps-example.xml, tag # expected: failed: tag does not exist - rv = handle_import_comps(options, session, args) - actual = stdout.getvalue() + with self.assertRaises(SystemExit) as ex: + handle_import_comps(options, session, args) + self.assertExitCode(ex, 1) + actual = stderr.getvalue() expected = 'No such tag: tag\n' self.assertMultiLineEqual(actual, expected) @@ -179,7 +183,6 @@ class TestImportComps(unittest.TestCase): session.getTag.assert_called_once_with(tag) mock_import_comps.assert_not_called() mock_import_comps_alt.assert_not_called() - self.assertEqual(rv, 1) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO) @@ -200,8 +203,9 @@ class TestImportComps(unittest.TestCase): session = mock.MagicMock() # Run it and check immediate output - with self.assertRaises(SystemExit) as cm: - rv = handle_import_comps(options, session, args) + with self.assertRaises(SystemExit) as ex: + handle_import_comps(options, session, args) + self.assertExitCode(ex, 2) actual_stdout = stdout.getvalue() actual_stderr = stderr.getvalue() expected_stdout = '' @@ -218,10 +222,6 @@ class TestImportComps(unittest.TestCase): session.getTag.assert_not_called() session.getTagGroups.assert_not_called() session.groupListAdd.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) @mock.patch('sys.stdout', new_callable=six.StringIO) def test_import_comps_libcomps(self, stdout): diff --git a/tests/test_cli/test_list_permissions.py b/tests/test_cli/test_list_permissions.py index b817d1f..1afb215 100644 --- a/tests/test_cli/test_list_permissions.py +++ b/tests/test_cli/test_list_permissions.py @@ -22,12 +22,14 @@ class TestListPermissions(utils.CliTestCase): %s: error: {message} """ % (self.progname, self.progname) + @mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('koji_cli.commands.activate_session') def test_handle_list_permissions( self, activate_session_mock, - stdout): + stdout, + stderr): """Test handle_list_permissions function""" session = mock.MagicMock() options = mock.MagicMock() @@ -54,8 +56,10 @@ class TestListPermissions(utils.CliTestCase): # case 2. user does not exists expected = "User %s does not exist" % user + "\n" session.getUser.return_value = None - self.assertEqual(1, handle_list_permissions(options, session, ['--user', user])) - self.assert_console_message(stdout, expected) + with self.assertRaises(SystemExit) as ex: + handle_list_permissions(options, session, ['--user', user]) + self.assertExitCode(ex, 1) + self.assert_console_message(stderr, expected) # case 3. List user permission perms = [p['name'] for p in all_perms[::1]] diff --git a/tests/test_cli/test_maven_build.py b/tests/test_cli/test_maven_build.py index fac3cb5..f21086c 100644 --- a/tests/test_cli/test_maven_build.py +++ b/tests/test_cli/test_maven_build.py @@ -11,6 +11,7 @@ except ImportError: import unittest from koji_cli.commands import handle_maven_build +from . import utils EMPTY_BUILD_OPTS = { 'specfile': None, @@ -32,7 +33,7 @@ EMPTY_BUILD_OPTS = { 'inis': []} -class TestMavenBuild(unittest.TestCase): +class TestMavenBuild(utils.CliTestCase): # Show long diffs in error output... maxDiff = None @@ -103,8 +104,9 @@ Task info: weburl/taskinfo?taskID=1 progname = os.path.basename(sys.argv[0]) or 'koji' # Run it and check immediate output - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_maven_build(self.options, self.session, args) + self.assertExitCode(ex, 2) actual_stdout = stdout.getvalue() actual_stderr = stderr.getvalue() expected_stdout = '' @@ -125,10 +127,6 @@ Task info: weburl/taskinfo?taskID=1 self.session.mavenBuild.assert_not_called() self.session.logout.assert_not_called() watch_tasks_mock.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO) @@ -146,8 +144,9 @@ Task info: weburl/taskinfo?taskID=1 progname = os.path.basename(sys.argv[0]) or 'koji' # Run it and check immediate output - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_maven_build(self.options, self.session, args) + self.assertExitCode(ex, 2) actual_stdout = stdout.getvalue() actual_stderr = stderr.getvalue() expected_stdout = '' @@ -168,10 +167,6 @@ Task info: weburl/taskinfo?taskID=1 self.session.mavenBuild.assert_not_called() self.session.logout.assert_not_called() watch_tasks_mock.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO) @@ -189,8 +184,9 @@ Task info: weburl/taskinfo?taskID=1 progname = os.path.basename(sys.argv[0]) or 'koji' # Run it and check immediate output - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_maven_build(self.options, self.session, args) + self.assertExitCode(ex, 0) actual_stdout = stdout.getvalue() actual_stderr = stderr.getvalue() expected_stdout = """Usage: %s maven-build [options] @@ -239,10 +235,6 @@ Options: self.session.mavenBuild.assert_not_called() self.session.logout.assert_not_called() watch_tasks_mock.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 0) @mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('koji_cli.commands.activate_session') @@ -265,8 +257,9 @@ Options: # Run it and check immediate output # args: target http://scm # expected: failed, target not found - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_maven_build(self.options, self.session, args) + self.assertExitCode(ex, 2) actual = stderr.getvalue() expected = """Usage: %s maven-build [options] %s maven-build --ini=CONFIG... [options] @@ -283,10 +276,6 @@ Options: self.session.mavenBuild.assert_not_called() self.session.logout.assert_not_called() watch_tasks_mock.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) @mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('koji_cli.commands.activate_session') @@ -313,8 +302,9 @@ Options: # Run it and check immediate output # args: target http://scm # expected: failed, dest_tag not found - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_maven_build(self.options, self.session, args) + self.assertExitCode(ex, 2) actual = stderr.getvalue() expected = """Usage: %s maven-build [options] %s maven-build --ini=CONFIG... [options] @@ -331,10 +321,6 @@ Options: self.session.mavenBuild.assert_not_called() self.session.logout.assert_not_called() watch_tasks_mock.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) @mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('koji_cli.commands.activate_session') @@ -361,8 +347,9 @@ Options: # Run it and check immediate output # args: target http://scm # expected: failed, dest_tag is locked - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_maven_build(self.options, self.session, args) + self.assertExitCode(ex, 2) actual = stderr.getvalue() expected = """Usage: %s maven-build [options] %s maven-build --ini=CONFIG... [options] @@ -379,10 +366,6 @@ Options: self.session.mavenBuild.assert_not_called() self.session.logout.assert_not_called() watch_tasks_mock.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) @mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('sys.stdout', new_callable=six.StringIO) @@ -473,8 +456,9 @@ Task info: weburl/taskinfo?taskID=1 # Run it and check immediate output # args: --ini=config1.ini --ini=config2.ini --section=section target # expected: failed, no type == 'maven' found - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_maven_build(self.options, self.session, args) + self.assertExitCode(ex, 2) actual = stderr.getvalue() expected = """Usage: %s maven-build [options] %s maven-build --ini=CONFIG... [options] @@ -488,10 +472,6 @@ Task info: weburl/taskinfo?taskID=1 build_opts.inis, scratch=scratch, section=section) maven_opts_mock.assert_not_called() self.session.mavenBuild.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) stdout.seek(0) stdout.truncate() @@ -504,8 +484,9 @@ Task info: weburl/taskinfo?taskID=1 # Run it and check immediate output # args: --ini=config1.ini --ini=config2.ini --section=section target # expected: failed, ValueError raised when parsing .ini files - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_maven_build(self.options, self.session, args) + self.assertExitCode(ex, 2) actual = stderr.getvalue() expected = """Usage: %s maven-build [options] %s maven-build --ini=CONFIG... [options] @@ -519,10 +500,6 @@ Task info: weburl/taskinfo?taskID=1 build_opts.inis, scratch=scratch, section=section) maven_opts_mock.assert_not_called() self.session.mavenBuild.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) @mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('koji_cli.commands.activate_session') @@ -554,8 +531,9 @@ Task info: weburl/taskinfo?taskID=1 # Run it and check immediate output # args: target badscm # expected: failed, scm is invalid - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_maven_build(self.options, self.session, args) + self.assertExitCode(ex, 2) actual = stderr.getvalue() expected = """Usage: %s maven-build [options] %s maven-build --ini=CONFIG... [options] @@ -574,10 +552,6 @@ Task info: weburl/taskinfo?taskID=1 self.session.mavenBuild.assert_not_called() self.session.logout.assert_not_called() watch_tasks_mock.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('koji_cli.commands.activate_session') diff --git a/tests/test_cli/test_mock_config.py b/tests/test_cli/test_mock_config.py index 1ca0d0b..028c806 100644 --- a/tests/test_cli/test_mock_config.py +++ b/tests/test_cli/test_mock_config.py @@ -142,8 +142,10 @@ config_opts['macros']['%distribution'] = 'Koji Testing' arguments = ['--task', str(task_id)] expected = "No buildroots for task %s (or no such task)\n" % str(task_id) - self.assertEqual(1, anon_handle_mock_config(options, session, arguments)) - self.assert_console_message(stdout, expected) + with self.assertRaises(SystemExit) as ex: + anon_handle_mock_config(options, session, arguments) + self.assertExitCode(ex, 1) + self.assert_console_message(stderr, expected) multi_broots = [ {'id': 1101, 'repo_id': 101, 'tag_name': 'tag_101', 'arch': 'x86_64'}, @@ -191,8 +193,10 @@ config_opts['macros']['%distribution'] = 'Koji Testing' arguments = ['--tag', tag['name']] expected = "Please specify an arch\n" - self.assertEqual(1, anon_handle_mock_config(options, session, arguments)) - self.assert_console_message(stdout, expected) + with self.assertRaises(SystemExit) as ex: + anon_handle_mock_config(options, session, arguments) + self.assertExitCode(ex, 1) + self.assert_console_message(stderr, expected) arguments = ['--tag', tag['name'], '--arch', tag['arch']] expected = self.format_error_message("Invalid tag: %s" % tag['name']) @@ -206,14 +210,18 @@ config_opts['macros']['%distribution'] = 'Koji Testing' # return tag info session.getTag.return_value = tag expected = "Could not get config info for tag: %(name)s\n" % tag - self.assertEqual(1, anon_handle_mock_config(options, session, arguments)) - self.assert_console_message(stdout, expected) + with self.assertRaises(SystemExit) as ex: + anon_handle_mock_config(options, session, arguments) + self.assertExitCode(ex, 1) + self.assert_console_message(stderr, expected) # return build config session.getBuildConfig.return_value = {'id': 301, 'extra': {}} expected = "Could not get a repo for tag: %(name)s\n" % tag - self.assertEqual(1, anon_handle_mock_config(options, session, arguments)) - self.assert_console_message(stdout, expected) + with self.assertRaises(SystemExit) as ex: + anon_handle_mock_config(options, session, arguments) + self.assertExitCode(ex, 1) + self.assert_console_message(stderr, expected) # return repo session.getRepo.return_value = {'id': 101} @@ -262,8 +270,10 @@ config_opts['macros']['%distribution'] = 'Koji Testing' arguments = ['--target', target['name']] expected = "Please specify an arch\n" - self.assertEqual(1, anon_handle_mock_config(options, session, arguments)) - self.assert_console_message(stdout, expected) + with self.assertRaises(SystemExit) as ex: + anon_handle_mock_config(options, session, arguments) + self.assertExitCode(ex, 1) + self.assert_console_message(stderr, expected) arguments = ['--target', target['name'], '--arch', arch] @@ -278,8 +288,10 @@ config_opts['macros']['%distribution'] = 'Koji Testing' session.getBuildTarget.return_value = target expected = "Could not get a repo for tag: %s\n" % target['build_tag_name'] - self.assertEqual(1, anon_handle_mock_config(options, session, arguments)) - self.assert_console_message(stdout, expected) + with self.assertRaises(SystemExit) as ex: + anon_handle_mock_config(options, session, arguments) + self.assertExitCode(ex, 1) + self.assert_console_message(stderr, expected) arguments = self.common_args + ['--target', target['name'], '--arch', arch, diff --git a/tests/test_cli/test_remove_channel.py b/tests/test_cli/test_remove_channel.py index 61fe9d5..a82ca69 100644 --- a/tests/test_cli/test_remove_channel.py +++ b/tests/test_cli/test_remove_channel.py @@ -9,9 +9,10 @@ except ImportError: import unittest from koji_cli.commands import handle_remove_channel +from . import utils -class TestRemoveChannel(unittest.TestCase): +class TestRemoveChannel(utils.CliTestCase): # Show long diffs in error output... maxDiff = None @@ -67,10 +68,10 @@ class TestRemoveChannel(unittest.TestCase): session.removeChannel.assert_called_once_with(channel, force=True) self.assertNotEqual(rv, 1) - @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_channel_no_channel( - self, activate_session_mock, stdout): + self, activate_session_mock, stderr): channel = 'channel' channel_info = None args = [channel] @@ -83,15 +84,16 @@ class TestRemoveChannel(unittest.TestCase): # Run it and check immediate output # args: channel # expected: failed: no such channel - rv = handle_remove_channel(options, session, args) - actual = stdout.getvalue() + with self.assertRaises(SystemExit) as ex: + handle_remove_channel(options, session, args) + self.assertExitCode(ex, 1) + actual = stderr.getvalue() expected = 'No such channel: channel\n' self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. activate_session_mock.assert_called_once_with(session, options) session.getChannel.assert_called_once_with(channel) session.removeChannel.assert_not_called() - self.assertEqual(rv, 1) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO) @@ -106,8 +108,9 @@ class TestRemoveChannel(unittest.TestCase): session = mock.MagicMock() # Run it and check immediate output - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_remove_channel(options, session, args) + self.assertExitCode(ex, 2) actual_stdout = stdout.getvalue() actual_stderr = stderr.getvalue() expected_stdout = '' @@ -123,10 +126,6 @@ class TestRemoveChannel(unittest.TestCase): activate_session_mock.assert_not_called() session.getChannel.assert_not_called() session.removeChannel.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) if __name__ == '__main__': diff --git a/tests/test_cli/test_remove_host_from_channel.py b/tests/test_cli/test_remove_host_from_channel.py index 35c9cba..a0dd8a1 100644 --- a/tests/test_cli/test_remove_host_from_channel.py +++ b/tests/test_cli/test_remove_host_from_channel.py @@ -9,8 +9,9 @@ except ImportError: import unittest from koji_cli.commands import handle_remove_host_from_channel +from . import utils -class TestRemoveHostFromChannel(unittest.TestCase): +class TestRemoveHostFromChannel(utils.CliTestCase): # Show long diffs in error output... maxDiff = None @@ -45,10 +46,10 @@ class TestRemoveHostFromChannel(unittest.TestCase): session.removeHostFromChannel.assert_called_once_with(host, channel) self.assertNotEqual(rv, 1) - @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_host_from_channel_no_host( - self, activate_session_mock, stdout): + self, activate_session_mock, stderr): host = 'host' host_info = None channel = 'channel' @@ -62,8 +63,10 @@ class TestRemoveHostFromChannel(unittest.TestCase): # Run it and check immediate output # args: host, channel # expected: failed: no such host - rv = handle_remove_host_from_channel(options, session, args) - actual = stdout.getvalue() + with self.assertRaises(SystemExit) as ex: + handle_remove_host_from_channel(options, session, args) + self.assertExitCode(ex, 1) + actual = stderr.getvalue() expected = 'No such host: host\n' self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. @@ -71,12 +74,11 @@ class TestRemoveHostFromChannel(unittest.TestCase): session.getHost.assert_called_once_with(host) session.listChannels.assert_not_called() session.removeHostFromChannel.assert_not_called() - self.assertEqual(rv, 1) - @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_host_from_channel_not_a_member( - self, activate_session_mock, stdout): + self, activate_session_mock, stderr): host = 'host' host_info = {'id': 1} channel = 'channel' @@ -92,9 +94,11 @@ class TestRemoveHostFromChannel(unittest.TestCase): session.listChannels.return_value = channel_infos # Run it and check immediate output # args: host, channel - # expected: success: host isn't belong to channel - rv = handle_remove_host_from_channel(options, session, args) - actual = stdout.getvalue() + # expected: failed: host isn't belong to channel + with self.assertRaises(SystemExit) as ex: + handle_remove_host_from_channel(options, session, args) + self.assertExitCode(ex, 1) + actual = stderr.getvalue() expected = 'Host host is not a member of channel channel\n' self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. @@ -102,7 +106,6 @@ class TestRemoveHostFromChannel(unittest.TestCase): session.getHost.assert_called_once_with(host) session.listChannels.assert_called_once_with(host_info['id']) session.removeHostFromChannel.assert_not_called() - self.assertEqual(rv, 1) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO) @@ -119,8 +122,9 @@ class TestRemoveHostFromChannel(unittest.TestCase): # Run it and check immediate output # args: _empty_ # expected: failed, help msg shows - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_remove_host_from_channel(options, session, args) + self.assertExitCode(ex, 2) actual_stdout = stdout.getvalue() actual_stderr = stderr.getvalue() expected_stdout = '' @@ -137,10 +141,6 @@ class TestRemoveHostFromChannel(unittest.TestCase): session.getHost.assert_not_called() session.listChannels.assert_not_called() session.removeHostFromChannel.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) if __name__ == '__main__': diff --git a/tests/test_cli/test_remove_pkg.py b/tests/test_cli/test_remove_pkg.py index bf8e366..8c5df10 100644 --- a/tests/test_cli/test_remove_pkg.py +++ b/tests/test_cli/test_remove_pkg.py @@ -10,17 +10,17 @@ except ImportError: from mock import call - from koji_cli.commands import handle_remove_pkg +from . import utils -class TestRemovePkg(unittest.TestCase): +class TestRemovePkg(utils.CliTestCase): # Show long diffs in error output... maxDiff = 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_pkg(self, activate_session_mock, stdout): + def test_handle_remove_pkg(self, activate_session_mock, stderr): tag = 'tag' dsttag = {'name': tag, 'id': 1} package = 'package' @@ -37,8 +37,8 @@ class TestRemovePkg(unittest.TestCase): # Run it and check immediate output # args: tag, package # expected: success - rv = handle_remove_pkg(options, session, args) - actual = stdout.getvalue() + handle_remove_pkg(options, session, args) + actual = stderr.getvalue() expected = '' self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. @@ -49,7 +49,6 @@ class TestRemovePkg(unittest.TestCase): session.packageListRemove.assert_called_once_with( tag, package, **kwargs) session.multiCall.assert_called_once_with(strict=True) - self.assertNotEqual(rv, 1) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('koji_cli.commands.activate_session') @@ -129,9 +128,9 @@ class TestRemovePkg(unittest.TestCase): strict=True)]) self.assertNotEqual(rv, 1) - @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_pkg_no_package(self, activate_session_mock, stdout): + def test_handle_remove_pkg_no_package(self, activate_session_mock, stderr): tag = 'tag' dsttag = {'name': tag, 'id': 1} packages = ['package1', 'package2', 'package3'] @@ -149,8 +148,10 @@ class TestRemovePkg(unittest.TestCase): # Run it and check immediate output # args: tag, package1, package2, package3 # expected: failed: can not find package2 under tag - rv = handle_remove_pkg(options, session, args) - actual = stdout.getvalue() + with self.assertRaises(SystemExit) as ex: + handle_remove_pkg(options, session, args) + self.assertExitCode(ex, 1) + actual = stderr.getvalue() expected = 'Package package2 is not in tag tag\n' self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. @@ -160,12 +161,11 @@ class TestRemovePkg(unittest.TestCase): tagID=dsttag['id']) session.packageListRemove.assert_not_called() session.multiCall.assert_not_called() - self.assertEqual(rv, 1) - @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_pkg_tag_no_exists( - self, activate_session_mock, stdout): + self, activate_session_mock, stderr): tag = 'tag' dsttag = None packages = ['package1', 'package2', 'package3'] @@ -179,8 +179,10 @@ class TestRemovePkg(unittest.TestCase): # Run it and check immediate output # args: tag, package1, package2, package3 # expected: failed: tag does not exist - rv = handle_remove_pkg(options, session, args) - actual = stdout.getvalue() + with self.assertRaises(SystemExit) as ex: + handle_remove_pkg(options, session, args) + self.assertExitCode(ex, 1) + actual = stderr.getvalue() expected = 'No such tag: tag\n' self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. @@ -188,7 +190,6 @@ class TestRemovePkg(unittest.TestCase): session.getTag.assert_called_once_with(tag) session.listPackages.assert_not_called() session.packageListRemove.assert_not_called() - self.assertEqual(rv, 1) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO) @@ -204,8 +205,9 @@ class TestRemovePkg(unittest.TestCase): session = mock.MagicMock() # Run it and check immediate output - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_remove_pkg(options, session, args) + self.assertExitCode(ex, 2) actual_stdout = stdout.getvalue() actual_stderr = stderr.getvalue() expected_stdout = '' @@ -222,10 +224,6 @@ class TestRemovePkg(unittest.TestCase): session.getTag.assert_not_called() session.listPackages.assert_not_called() session.packageListRemove.assert_not_called() - if isinstance(cm.exception, int): - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) if __name__ == '__main__': diff --git a/tests/test_cli/test_rename_channel.py b/tests/test_cli/test_rename_channel.py index 9d0835b..45857e6 100644 --- a/tests/test_cli/test_rename_channel.py +++ b/tests/test_cli/test_rename_channel.py @@ -9,9 +9,10 @@ except ImportError: import unittest from koji_cli.commands import handle_rename_channel +from . import utils -class TestRenameChannel(unittest.TestCase): +class TestRenameChannel(utils.CliTestCase): # Show long diffs in error output... maxDiff = None @@ -42,10 +43,10 @@ class TestRenameChannel(unittest.TestCase): session.renameChannel.assert_called_once_with(old_name, new_name) self.assertNotEqual(rv, 1) - @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_rename_channel_no_channel( - self, activate_session_mock, stdout): + self, activate_session_mock, stderr): old_name = 'old_name' new_name = 'new_name' channel_info = None @@ -59,15 +60,16 @@ class TestRenameChannel(unittest.TestCase): # Run it and check immediate output # args: old_name, new_name # expected: failed: no such channel - rv = handle_rename_channel(options, session, args) - actual = stdout.getvalue() + with self.assertRaises(SystemExit) as ex: + handle_rename_channel(options, session, args) + self.assertExitCode(ex, 1) + actual = stderr.getvalue() expected = 'No such channel: old_name\n' self.assertMultiLineEqual(actual, expected) # Finally, assert that things were called as we expected. activate_session_mock.assert_called_once_with(session, options) session.getChannel.assert_called_once_with(old_name) session.renameChannel.assert_not_called() - self.assertEqual(rv, 1) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('sys.stderr', new_callable=six.StringIO) @@ -82,8 +84,9 @@ class TestRenameChannel(unittest.TestCase): session = mock.MagicMock() # Run it and check immediate output - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: handle_rename_channel(options, session, args) + self.assertExitCode(ex, 2) actual_stdout = stdout.getvalue() actual_stderr = stderr.getvalue() expected_stdout = '' @@ -99,11 +102,6 @@ class TestRenameChannel(unittest.TestCase): activate_session_mock.assert_not_called() session.getChannel.assert_not_called() session.renameChannel.assert_not_called() - if isinstance(cm.exception, int): - # python 2.6.6 - self.assertEqual(cm.exception, 2) - else: - self.assertEqual(cm.exception.code, 2) if __name__ == '__main__': diff --git a/tests/test_cli/test_restart_host.py b/tests/test_cli/test_restart_host.py index a70c919..296c2ae 100644 --- a/tests/test_cli/test_restart_host.py +++ b/tests/test_cli/test_restart_host.py @@ -48,6 +48,7 @@ class TestRestartHosts(utils.CliTestCase): watch_tasks_mock.assert_called_with( session, [self.task_id], quiet=None, poll_interval=3) + @mock.patch('sys.stderr', new_callable=six.StringIO) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('koji_cli.commands.watch_tasks') @mock.patch('koji_cli.commands._running_in_bg') @@ -57,7 +58,8 @@ class TestRestartHosts(utils.CliTestCase): activate_session_mock, running_in_bg_mock, watch_tasks_mock, - stdout): + stdout, + stderr): """Test %s function when there has other restart tasks exist""" % handle_restart_hosts.__name__ options = mock.MagicMock() session = mock.MagicMock() @@ -99,7 +101,9 @@ class TestRestartHosts(utils.CliTestCase): # has other restart tasks are running case session.listTasks.return_value = [{'id': 1}, {'id': 2}, {'id': 3}] - self.assertEqual(1, handle_restart_hosts(options, session, [])) + with self.assertRaises(SystemExit) as ex: + handle_restart_hosts(options, session, []) + self.assertExitCode(ex, 1) activate_session_mock.assert_called_once() query_opt = { @@ -115,7 +119,7 @@ class TestRestartHosts(utils.CliTestCase): expect += "Task ids: %r\n" % \ [t['id'] for t in session.listTasks.return_value] expect += "Use --force to run anyway\n" - self.assert_console_message(stdout, expect) + self.assert_console_message(stderr, expect) @mock.patch('koji_cli.commands.watch_tasks') @mock.patch('koji_cli.commands._running_in_bg') diff --git a/tests/test_cli/test_set_build_volume.py b/tests/test_cli/test_set_build_volume.py index 85c1850..357527e 100644 --- a/tests/test_cli/test_set_build_volume.py +++ b/tests/test_cli/test_set_build_volume.py @@ -47,19 +47,31 @@ class TestSetBuildVolume(utils.CliTestCase): # Case 2. wrong volume session.getVolume.return_value = {} expected = "No such volume: %s" % volume + "\n" - self.assertEqual( - 1, handle_set_build_volume(options, session, [volume, build])) - self.assert_console_message(stdout, expected) - activate_session_mock.assert_not_called() + self.assert_system_exit( + handle_set_build_volume, + options, + session, + [volume, build], + exit_code=1, + stdout='', + stderr=expected, + activate_session=None) # Case 3. no build found session.getVolume.return_value = volinfo session.getBuild.return_value = {} - expected = "No such build: %s" % build + "\n" - expected += "No builds to move" + "\n" - self.assertEqual( - 1, handle_set_build_volume(options, session, [volume, build])) - self.assert_console_message(stdout, expected) + stdout_exp = "No such build: %s" % build + "\n" + stderr_exp = "No builds to move" + "\n" + self.assert_system_exit( + handle_set_build_volume, + options, + session, + [volume, build], + exit_code=1, + stdout=stdout_exp, + stderr=stderr_exp, + activate_session=None) + # Case 3. Build already in volume session.getBuild.side_effect = [ @@ -74,12 +86,19 @@ class TestSetBuildVolume(utils.CliTestCase): }, ] - expected = "Build %s already on volume %s" % \ + stdout_exp = "Build %s already on volume %s" % \ (build, volinfo['name']) + "\n" - expected += "No builds to move" + "\n" - self.assertEqual( - 1, handle_set_build_volume(options, session, [volume, build])) - self.assert_console_message(stdout, expected) + stderr_exp = "No builds to move" + "\n" + self.assert_system_exit( + handle_set_build_volume, + options, + session, + [volume, build], + exit_code=1, + stdout=stdout_exp, + stderr=stderr_exp, + activate_session=None) + # Case 4. Change build volume build = "sed-4.4-1.fc26" diff --git a/tests/test_cli/test_wait_repo.py b/tests/test_cli/test_wait_repo.py index 09e41c9..a73776f 100644 --- a/tests/test_cli/test_wait_repo.py +++ b/tests/test_cli/test_wait_repo.py @@ -61,19 +61,39 @@ class TestWaitRepo(utils.CliTestCase): @mock.patch('time.time') @mock.patch('sys.stdout', new_callable=six.StringIO) - def __test_wait_repo(self, args, expected, stdout, time_mock): + @mock.patch('sys.stderr', new_callable=six.StringIO) + def __test_wait_repo(self, args, expected, stderr, stdout, time_mock, ret_code=0): self.options.quiet = False time_mock.side_effect = [0, 1, 2, 3] - anon_handle_wait_repo(self.options, self.session, args) - self.assert_console_message(stdout, expected) + if ret_code: + with self.assertRaises(SystemExit) as ex: + anon_handle_wait_repo(self.options, self.session, args) + self.assertExitCode(ex, ret_code) + self.assert_console_message(stderr, expected) + self.assert_console_message(stdout, '') + else: + rv = anon_handle_wait_repo(self.options, self.session, args) + self.assert_console_message(stdout, expected) + self.assert_console_message(stderr, '') + self.assertIn(rv, [0, None]) @mock.patch('time.time') @mock.patch('sys.stdout', new_callable=six.StringIO) - def __test_wait_repo_timeout(self, args, expected, stdout, time_mock): + @mock.patch('sys.stderr', new_callable=six.StringIO) + def __test_wait_repo_timeout(self, args, expected, stderr, stdout, time_mock, ret_code=0): self.options.quiet = False time_mock.side_effect = [0, 61, 62] - anon_handle_wait_repo(self.options, self.session, args + ['--timeout', '1']) - self.assert_console_message(stdout, expected) + if ret_code: + with self.assertRaises(SystemExit) as ex: + anon_handle_wait_repo(self.options, self.session, args + ['--timeout', '1']) + self.assertExitCode(ex, ret_code) + self.assert_console_message(stderr, expected) + self.assert_console_message(stdout, '') + else: + rv = anon_handle_wait_repo(self.options, self.session, args + ['--timeout', '1']) + self.assert_console_message(stdout, expected) + self.assert_console_message(stderr, '') + self.assertIn(rv, [0, None]) def test_anon_handle_wait_repo(self): """Test anon_handle_wait_repo function""" @@ -102,7 +122,7 @@ class TestWaitRepo(utils.CliTestCase): self.session.getRepo.return_value = {} self.checkForBuilds.return_value = True expected = 'Unsuccessfully waited 1:02 for a new %s repo' % self.tag_name + '\n' - self.__test_wait_repo_timeout(arguments, expected) + self.__test_wait_repo_timeout(arguments, expected, ret_code=1) def test_anon_handle_wait_repo_with_build(self): """Test anon_handle_wait_repo function with --build options""" @@ -147,7 +167,7 @@ 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' - self.__test_wait_repo_timeout(arguments, expected) + self.__test_wait_repo_timeout(arguments, expected, ret_code=1) def test_anon_handle_wait_repo_errors(self): """Test anon_handle_wait_repo function errors and exceptions""" @@ -172,17 +192,18 @@ class TestWaitRepo(utils.CliTestCase): activate_session=None) self.activate_session.assert_not_called() - @mock.patch('sys.stdout', new_callable=six.StringIO) - def test_anon_handle_wait_repo_target_not_found(self, stdout): + @mock.patch('sys.stderr', new_callable=six.StringIO) + def test_anon_handle_wait_repo_target_not_found(self, stderr): """Test anon_handle_wait_repo function on target not found cases""" # Case 1. both build and dest targets are not found self.session.getTag.return_value = self.TAG.copy() self.session.getBuildTargets.return_value = [] - rv = anon_handle_wait_repo(self.options, self.session, [self.tag_name]) - self.assertEqual(rv, 1) + with self.assertRaises(SystemExit) as ex: + anon_handle_wait_repo(self.options, self.session, [self.tag_name]) + self.assertExitCode(ex, 1) expected = "%(name)s is not a build tag for any target" % self.TAG + "\n" - self.assert_console_message(stdout, expected) + self.assert_console_message(stderr, expected) # Cas 2. dest is matched, show suggestion self.session.getBuildTargets.side_effect = [ @@ -193,11 +214,12 @@ class TestWaitRepo(utils.CliTestCase): {'build_tag_name': 'build-tag-3'}, ], ] - rv = anon_handle_wait_repo(self.options, self.session, [self.tag_name]) - self.assertEqual(rv, 1) + with self.assertRaises(SystemExit) as ex: + anon_handle_wait_repo(self.options, self.session, [self.tag_name]) + self.assertExitCode(ex, 1) expected = "%(name)s is not a build tag for any target" % self.TAG + "\n" expected += "Suggested tags: build-tag-1, build-tag-2, build-tag-3\n" - self.assert_console_message(stdout, expected) + self.assert_console_message(stderr, expected) def test_anon_handle_wait_repo_help(self): """Test anon_handle_wait_repo help message""" diff --git a/tests/test_cli/utils.py b/tests/test_cli/utils.py index d1c2c9b..31bb4f6 100644 --- a/tests/test_cli/utils.py +++ b/tests/test_cli/utils.py @@ -184,17 +184,13 @@ class CliTestCase(unittest.TestCase): with session_patch as session: with stdout_patch as stdout: with stderr_patch as stderr: - with self.assertRaises(SystemExit) as cm: + with self.assertRaises(SystemExit) as ex: callableObj(*test_args, **test_kwargs) + self.assertExitCode(ex, exit_code) session.assert_called_once() self.assert_console_message(stdout, **message['stdout']) self.assert_console_message(stderr, **message['stderr']) assert_function() - if isinstance(cm.exception, int): - # python 2.6.6 - self.assertEqual(cm.exception, exit_code) - else: - self.assertEqual(cm.exception.code, exit_code) @mock.patch('koji_cli.commands.activate_session') def assert_help(self, callableObj, message, activate_session_mock): @@ -212,6 +208,12 @@ class CliTestCase(unittest.TestCase): exit_code=0) activate_session_mock.assert_not_called() + def assertExitCode(self, ex, code): + if isinstance(ex.exception, int): + self.assertEqual(ex.exception, code) + else: + self.assertEqual(ex.exception.code, code) + def get_builtin_open(): if six.PY2: