#2044 Unify error messages in CLI
Merged 4 years ago by tkopecek. Opened 4 years ago by tkopecek.
tkopecek/koji issue2043  into  master

file modified
+81 -133
@@ -82,14 +82,12 @@ 

  

      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 @@ 

  

      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 @@ 

      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 @@ 

      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 @@ 

      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 @@ 

      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 @@ 

      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 @@ 

      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 @@ 

      # 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 @@ 

      # 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 @@ 

      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 @@ 

              # 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 @@ 

              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 @@ 

              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 @@ 

          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 @@ 

      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 @@ 

      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 @@ 

          }

          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 @@ 

      # 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 @@ 

          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 @@ 

          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 @@ 

      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 @@ 

      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 @@ 

  

      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 @@ 

      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 @@ 

          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 @@ 

      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 @@ 

      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 @@ 

          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 @@ 

      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 @@ 

          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 @@ 

      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 @@ 

      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 @@ 

      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 @@ 

                  # 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 @@ 

  

      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 @@ 

              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 @@ 

          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 @@ 

      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

@@ -51,9 +51,9 @@ 

          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 @@ 

              {'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 @@ 

          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 @@ 

          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 @@ 

          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 @@ 

          session.getTag.assert_called_once_with(tag)

          session.getTagGroups.assert_not_called()

          session.groupListAdd.assert_not_called()

-         self.assertEqual(rv, 1)

  

  

  if __name__ == '__main__':

file modified
+10 -19
@@ -3,15 +3,12 @@ 

  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 @@ 

          # 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 @@ 

          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 @@ 

          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 @@ 

          # 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()

@@ -10,8 +10,9 @@ 

      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 @@ 

              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 @@ 

          # 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 @@ 

          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 @@ 

          # 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 @@ 

          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 @@ 

          # 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 @@ 

          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__':

file modified
+14 -21
@@ -12,9 +12,10 @@ 

  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 @@ 

                            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 @@ 

          # 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 @@ 

          # 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 @@ 

          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 @@ 

          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 @@ 

          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 @@ 

          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 @@ 

          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__':

@@ -22,12 +22,14 @@ 

  %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 @@ 

          # 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()

  

@@ -18,9 +18,9 @@ 

  %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 @@ 

          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 @@ 

          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 @@ 

          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 @@ 

          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')

@@ -3,17 +3,14 @@ 

  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 @@ 

          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 @@ 

                  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 @@ 

          # 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 @@ 

              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 @@ 

          # 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 @@ 

          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 @@ 

          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 @@ 

          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()

file modified
+12 -34
@@ -152,8 +152,9 @@ 

          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 @@ 

          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 @@ 

          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] <target> <srpm path or scm url>
@@ -242,10 +240,6 @@ 

          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 @@ 

          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 @@ 

          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 @@ 

          # 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 @@ 

          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 @@ 

          # 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 @@ 

          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 @@ 

          # 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 @@ 

          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 @@ 

          self.session.logout.assert_not_called()

          watch_tasks_mock.assert_not_called()

          self.assertIsNone(rv)

- 

- 

- if __name__ == '__main__':

-     unittest.main()

file modified
+2 -5
@@ -122,15 +122,12 @@ 

  

          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"""

@@ -10,8 +10,9 @@ 

      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 @@ 

          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 @@ 

          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 @@ 

          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] <target> <URL> [<URL> [:] <URL> [:] <URL> ...]
@@ -169,10 +168,6 @@ 

          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 @@ 

          # 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] <target> <URL> [<URL> [:] <URL> [:] <URL> ...]

  (Specify the --help global option for a list of other help options)
@@ -221,10 +217,6 @@ 

          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 @@ 

          # 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] <target> <URL> [<URL> [:] <URL> [:] <URL> ...]

  (Specify the --help global option for a list of other help options)
@@ -283,17 +276,13 @@ 

          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 @@ 

          # 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 @@ 

          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 @@ 

          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 @@ 

              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 @@ 

              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 @@ 

              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 @@ 

              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 @@ 

  

              # 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] <target> <URL> [<URL> [:] <URL> [:] <URL> ...]

  (Specify the --help global option for a list of other help options)
@@ -468,10 +466,6 @@ 

  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')

@@ -24,12 +24,14 @@ 

  """ % (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 @@ 

          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 @@ 

          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()

@@ -4,17 +4,14 @@ 

  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 @@ 

          # 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 @@ 

                                                        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 @@ 

          # 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 @@ 

          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 @@ 

          # 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 @@ 

          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 @@ 

          # 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 @@ 

          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 @@ 

          # 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 @@ 

          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 <task_id>

  (Specify the --help global option for a list of other help options)
@@ -363,18 +346,15 @@ 

          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 @@ 

  %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 @@ 

  %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()

@@ -11,8 +11,9 @@ 

  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 @@ 

          # 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 @@ 

          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 @@ 

          # 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 @@ 

          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()

@@ -3,17 +3,14 @@ 

  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 @@ 

          # 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] <name>
@@ -139,10 +137,6 @@ 

          # 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 @@ 

          # 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 @@ 

          # 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()

@@ -10,11 +10,12 @@ 

  

  

  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 @@ 

          # 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 @@ 

          # 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__':

@@ -23,12 +23,14 @@ 

  %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 @@ 

          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 @@ 

          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()

@@ -23,8 +23,9 @@ 

  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 @@ 

              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 @@ 

              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 @@ 

          # 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 @@ 

          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 @@ 

              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 @@ 

          # 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 @@ 

          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 @@ 

          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 @@ 

          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):

@@ -22,12 +22,14 @@ 

  %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 @@ 

          # 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]]

@@ -11,6 +11,7 @@ 

      import unittest

  

  from koji_cli.commands import handle_maven_build

+ from . import utils

  

  EMPTY_BUILD_OPTS = {

      'specfile': None,
@@ -32,7 +33,7 @@ 

      'inis': []}

  

  

- class TestMavenBuild(unittest.TestCase):

+ class TestMavenBuild(utils.CliTestCase):

      # Show long diffs in error output...

      maxDiff = None

  
@@ -103,8 +104,9 @@ 

          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 @@ 

          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 @@ 

          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 @@ 

          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 @@ 

          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] <target> <URL>
@@ -239,10 +235,6 @@ 

          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 @@ 

          # 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] <target> <URL>

         %s maven-build --ini=CONFIG... [options] <target>
@@ -283,10 +276,6 @@ 

          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 @@ 

          # 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] <target> <URL>

         %s maven-build --ini=CONFIG... [options] <target>
@@ -331,10 +321,6 @@ 

          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 @@ 

          # 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] <target> <URL>

         %s maven-build --ini=CONFIG... [options] <target>
@@ -379,10 +366,6 @@ 

          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 @@ 

          # 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] <target> <URL>

         %s maven-build --ini=CONFIG... [options] <target>
@@ -488,10 +472,6 @@ 

              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 @@ 

          # 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] <target> <URL>

         %s maven-build --ini=CONFIG... [options] <target>
@@ -519,10 +500,6 @@ 

              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 @@ 

          # 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] <target> <URL>

         %s maven-build --ini=CONFIG... [options] <target>
@@ -574,10 +552,6 @@ 

          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')

@@ -142,8 +142,10 @@ 

  

          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 @@ 

  

          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 @@ 

          # 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 @@ 

  

          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 @@ 

  

          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,

@@ -9,9 +9,10 @@ 

      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 @@ 

          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 @@ 

          # 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 @@ 

          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 @@ 

          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__':

@@ -9,8 +9,9 @@ 

      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 @@ 

          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 @@ 

          # 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 @@ 

          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 @@ 

          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 @@ 

          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 @@ 

          # 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 @@ 

          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__':

@@ -10,17 +10,17 @@ 

  

  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 @@ 

          # 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 @@ 

          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 @@ 

                              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 @@ 

          # 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 @@ 

              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 @@ 

          # 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 @@ 

          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 @@ 

          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 @@ 

          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__':

@@ -9,9 +9,10 @@ 

      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 @@ 

          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 @@ 

          # 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 @@ 

          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 @@ 

          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__':

@@ -48,6 +48,7 @@ 

          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 @@ 

              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 @@ 

          # 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 @@ 

          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')

@@ -47,19 +47,31 @@ 

          # 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 @@ 

              },

          ]

  

-         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"

@@ -61,19 +61,39 @@ 

  

      @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 @@ 

          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 @@ 

          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 @@ 

                  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 @@ 

                  {'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"""

file modified
+8 -6
@@ -184,17 +184,13 @@ 

          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 @@ 

              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:

pretty please pagure-ci rebuild

4 years ago

rebased onto bcf14478d5fe862a43244f5244411e2c559785a0

4 years ago
         id = session.addHost(host, args[1:], **kwargs)
-        if id:
-            print("%s added: id %d" % (host, id))
+        print("%s added: id %d" % (host, id))

This change seems out of place in context. It's true that addHost can't return None, but this change shouldn't be lumped in with the rest. If we're going to do more general cleanup here, might as well rename that id variable too ;)

                 if not binfo:
-                    print(_("No such build: %s") % nvr)
+                    error(_("No such build: %s") % nvr)
                 else:
-                    print(_("Build %s not in tag %s") % (nvr, tag['name']))
+                    error(_("Build %s not in tag %s") % (nvr, tag['name']))
                 if not options.force:
-                    return 1
+                    error()

The old code would not raise these errors with --force, but looks like this will in all cases. Maybe...

                binfo = session.getBuild(nvr)
                msg = warn if options.force else error
                if not binfo:
                    msg(_("No such build: %s") % nvr)
                else:
                    msg(_("Build %s not in tag %s") % (nvr, tag['name']))

otherwise looks ok, though will conflict with #2038, maybe more

rebased onto 7c5b237

4 years ago

Commit 6a07c50 fixes this pull-request

Pull-Request has been merged by tkopecek

4 years ago

Metadata Update from @jcupova:
- Pull-request tagged with: testing-done

3 years ago
Changes Summary 29
+81 -133
file changed
cli/koji_cli/commands.py
+12 -10
file changed
tests/test_cli/test_add_group.py
+10 -19
file changed
tests/test_cli/test_add_host.py
+16 -16
file changed
tests/test_cli/test_add_host_to_channel.py
+14 -21
file changed
tests/test_cli/test_add_pkg.py
+7 -3
file changed
tests/test_cli/test_add_volume.py
+12 -10
file changed
tests/test_cli/test_block_group.py
+17 -25
file changed
tests/test_cli/test_block_pkg.py
+12 -34
file changed
tests/test_cli/test_build.py
+2 -5
file changed
tests/test_cli/test_call.py
+38 -44
file changed
tests/test_cli/test_chain_build.py
+7 -3
file changed
tests/test_cli/test_disable_host.py
+18 -49
file changed
tests/test_cli/test_download_task.py
+10 -11
file changed
tests/test_cli/test_edit_host.py
+6 -19
file changed
tests/test_cli/test_edit_tag.py
+4 -7
file changed
tests/test_cli/test_edit_user.py
+8 -3
file changed
tests/test_cli/test_enable_host.py
+17 -17
file changed
tests/test_cli/test_import_comps.py
+7 -3
file changed
tests/test_cli/test_list_permissions.py
+20 -46
file changed
tests/test_cli/test_maven_build.py
+24 -12
file changed
tests/test_cli/test_mock_config.py
+10 -11
file changed
tests/test_cli/test_remove_channel.py
+17 -17
file changed
tests/test_cli/test_remove_host_from_channel.py
+20 -22
file changed
tests/test_cli/test_remove_pkg.py
+10 -12
file changed
tests/test_cli/test_rename_channel.py
+7 -3
file changed
tests/test_cli/test_restart_host.py
+33 -14
file changed
tests/test_cli/test_set_build_volume.py
+38 -16
file changed
tests/test_cli/test_wait_repo.py
+8 -6
file changed
tests/test_cli/utils.py