#928 check tag existence in list-tagged cmd and listTagged* APIs
Merged 5 years ago by mikem. Opened 5 years ago by julian8628.
julian8628/koji issue/926  into  master

file modified
+9 -2
@@ -2378,7 +2378,7 @@ 

      usage = _("usage: %prog list-tagged [options] tag [package]")

      usage += _("\n(Specify the --help global option for a list of other help options)")

      parser = OptionParser(usage=usage)

-     parser.add_option("--arch", help=_("List rpms for this arch"))

+     parser.add_option("--arch", action="append", default=[], help=_("List rpms for this arch"))

      parser.add_option("--rpms", action="store_true", help=_("Show rpms instead of builds"))

      parser.add_option("--inherit", action="store_true", help=_("Follow inheritance"))

      parser.add_option("--latest", action="store_true", help=_("Only show the latest builds/rpms"))
@@ -2405,7 +2405,7 @@ 

          package = args[1]

      tag = args[0]

      opts = {}

-     for key in ('latest','inherit'):

+     for key in ('latest', 'inherit'):

          opts[key] = getattr(options, key)

      if options.latest_n is not None:

          opts['latest'] = options.latest_n
@@ -2420,12 +2420,19 @@ 

      if options.type:

          opts['type'] = options.type

      event = koji.util.eventFromOpts(session, options)

+     event_id = None

      if event:

          opts['event'] = event['id']

+         event_id = event['id']

          event['timestr'] = time.asctime(time.localtime(event['ts']))

          if not options.quiet:

              print("Querying at event %(id)i (%(timestr)s)" % event)

  

+     # check if tag exist(s|ed)

+     taginfo = session.getTag(tag, event=event_id)

+     if not taginfo:

+         parser.error(_("No such tag: %s" % tag))

+ 

      if options.rpms:

          rpms, builds = session.listTaggedRPMS(tag, **opts)

          data = rpms

file modified
+6 -8
@@ -9624,9 +9624,8 @@ 

  

      def listTagged(self, tag, event=None, inherit=False, prefix=None, latest=False, package=None, owner=None, type=None):

          """List builds tagged with tag"""

-         if not isinstance(tag, (int, long)):

-             #lookup tag id

-             tag = get_tag_id(tag, strict=True)

+         #lookup tag id

+         tag = get_tag(tag, strict=True, event=event)['id']

          results = readTaggedBuilds(tag, event, inherit=inherit, latest=latest, package=package, owner=owner, type=type)

          if prefix:

              prefix = prefix.lower()
@@ -9635,15 +9634,14 @@ 

  

      def listTaggedRPMS(self, tag, event=None, inherit=False, latest=False, package=None, arch=None, rpmsigs=False, owner=None, type=None):

          """List rpms and builds within tag"""

-         if not isinstance(tag, (int, long)):

-             #lookup tag id

-             tag = get_tag_id(tag, strict=True)

+         #lookup tag id

+         tag = get_tag(tag, strict=True, event=event)['id']

          return readTaggedRPMS(tag, event=event, inherit=inherit, latest=latest, package=package, arch=arch, rpmsigs=rpmsigs, owner=owner, type=type)

  

      def listTaggedArchives(self, tag, event=None, inherit=False, latest=False, package=None, type=None):

          """List archives and builds within a tag"""

-         if not isinstance(tag, (int, long)):

-             tag = get_tag_id(tag, strict=True)

+         # lookup tag id

+         tag = get_tag(tag, strict=True, event=event)['id']

          return readTaggedArchives(tag, event=event, inherit=inherit, latest=latest, package=package, type=type)

  

      def listBuilds(self, packageID=None, userID=None, taskID=None, prefix=None, state=None,

@@ -8,6 +8,8 @@ 

      import unittest2 as unittest

  except ImportError:

      import unittest

+ import time

+ 

  import koji

  import koji.util

  from .loadkojid import kojid
@@ -55,6 +57,7 @@ 

      def setUp(self):

          self.original_timezone = os.environ.get('TZ')

          os.environ['TZ'] = 'US/Eastern'

+         time.tzset()

          self.tempdir = tempfile.mkdtemp()

          self.SMTP = mock.patch('smtplib.SMTP').start()

          self.session = mock.MagicMock()
@@ -67,6 +70,7 @@ 

              del os.environ['TZ']

          else:

              os.environ['TZ'] = self.original_timezone

+         time.tzset()

          mock.patch.stopall()

  

      def test_build_notification(self):

@@ -0,0 +1,253 @@ 

+ import sys

+ import os

+ import time

+ 

+ import mock

+ 

+ from koji_cli.commands import anon_handle_list_tagged

+ from . import utils

+ 

+ 

+ class TestCliListTagged(utils.CliTestCase):

+     # Show long diffs in error output...

+     maxDiff = None

+ 

+     def setUp(self):

+         self.original_timezone = os.environ.get('TZ')

+         os.environ['TZ'] = 'US/Eastern'

+         time.tzset()

+         self.error_format = """Usage: %s list-tagged [options] tag [package]

+ (Specify the --help global option for a list of other help options)

+ 

+ %s: error: {message}

+ """ % (self.progname, self.progname)

+         self.session = mock.MagicMock()

+         self.options = mock.MagicMock(quiet=False)

+         self.session.getTag.return_value = {'id': 1}

+         self.session.listTaggedRPMS.return_value = [[{'id': 100,

+                                                       'build_id': 1,

+                                                       'name': 'rpmA',

+                                                       'version': '0.0.1',

+                                                       'release': '1.el6',

+                                                       'arch': 'noarch',

+                                                       'sigkey': 'sigkey'},

+                                                      {'id': 101,

+                                                       'build_id': 1,

+                                                       'name': 'rpmA',

+                                                       'version': '0.0.1',

+                                                       'release': '1.el6',

+                                                       'arch': 'x86_64',

+                                                       'sigkey': 'sigkey'}

+                                                      ], [{'id': 1,

+                                                           'name': 'packagename',

+                                                           'version': 'version',

+                                                           'release': '1.el6',

+                                                           'nvr': 'n-v-r',

+                                                           'tag_name': 'tag',

+                                                           'owner_name': 'owner'}]]

+         self.session.listTagged.return_value = [{'id': 1,

+                                                  'name': 'packagename',

+                                                  'version': 'version',

+                                                  'release': '1.el6',

+                                                  'nvr': 'n-v-r',

+                                                  'tag_name': 'tag',

+                                                  'owner_name': 'owner'}]

+ 

+     def tearDown(self):

+         if self.original_timezone is None:

+             del os.environ['TZ']

+         else:

+             os.environ['TZ'] = self.original_timezone

+         time.tzset()

+ 

+     @mock.patch('koji.util.eventFromOpts', return_value={'id': 1000,

+                                                          'ts': 1000000.11})

+     @mock.patch('koji_cli.commands.activate_session')

+     def test_list_tagged_builds(self, activate_session_mock,

+                                 event_from_opts_mock):

+         args = ['tag', 'pkg', '--latest', '--inherit', '--event=1000']

+ 

+         anon_handle_list_tagged(self.options, self.session, args)

+         activate_session_mock.assert_called_once_with(self.session,

+                                                       self.options)

+         self.session.getTag.assert_called_once_with('tag', event=1000)

+         self.session.listTagged.assert_called_once_with('tag',

+                                                         event=1000,

+                                                         inherit=True,

+                                                         latest=True,

+                                                         package='pkg')

+         self.session.listTaggedRPMS.assert_not_called()

+         self.assert_console_message(sys.stdout,

+                                     'Querying at event 1000 (Mon Jan 12 08:46:40 1970)\n'

+                                     'Build                                     Tag                   Built by\n'

+                                     '----------------------------------------  --------------------  ----------------\n'

+                                     'n-v-r                                     tag                   owner\n')

+ 

+     @mock.patch('koji.util.eventFromOpts', return_value=None)

+     @mock.patch('koji_cli.commands.activate_session')

+     def test_list_tagged_builds_paths(self, activate_session_mock,

+                                       event_from_opts_mock):

+         args = ['tag', 'pkg', '--latest', '--inherit', '--paths']

+ 

+         anon_handle_list_tagged(self.options, self.session, args)

+         self.assert_console_message(sys.stdout,

+                                     'Build                                     Tag                   Built by\n'

+                                     '----------------------------------------  --------------------  ----------------\n'

+                                     '/mnt/koji/packages/packagename/version/1.el6  tag                   owner\n')

+ 

+     @mock.patch('koji.util.eventFromOpts', return_value=None)

+     @mock.patch('koji_cli.commands.activate_session')

+     def test_list_tagged_rpms(self, activate_session_mock,

+                               event_from_opts_mock):

+         args = ['tag', 'pkg', '--latest-n=3', '--rpms', '--sigs',

+                 '--arch=x86_64', '--arch=noarch']

+ 

+         anon_handle_list_tagged(self.options, self.session, args)

+         activate_session_mock.assert_called_once_with(self.session,

+                                                       self.options)

+         self.session.getTag.assert_called_once_with('tag', event=None)

+         self.session.listTaggedRPMS.assert_called_once_with('tag',

+                                                             package='pkg',

+                                                             inherit=None,

+                                                             latest=3,

+                                                             rpmsigs=True,

+                                                             arch=['x86_64',

+                                                                   'noarch'])

+         self.session.listTagged.assert_not_called()

+         self.assert_console_message(sys.stdout,

+                                     'sigkey rpmA-0.0.1-1.el6.noarch\n'

+                                     'sigkey rpmA-0.0.1-1.el6.x86_64\n')

+ 

+     @mock.patch('koji.util.eventFromOpts', return_value=None)

+     @mock.patch('koji_cli.commands.activate_session')

+     def test_list_tagged_rpms_paths(self, activate_session_mock,

+                                     event_from_opts_mock):

+         args = ['tag', 'pkg', '--latest-n=3', '--rpms',

+                 '--arch=x86_64', '--paths']

+ 

+         anon_handle_list_tagged(self.options, self.session, args)

+         self.assert_console_message(sys.stdout,

+                                     '/mnt/koji/packages/packagename/version/1.el6/noarch/rpmA-0.0.1-1.el6.noarch.rpm\n'

+                                     '/mnt/koji/packages/packagename/version/1.el6/x86_64/rpmA-0.0.1-1.el6.x86_64.rpm\n')

+ 

+ 

+     @mock.patch('koji.util.eventFromOpts', return_value=None)

+     @mock.patch('koji_cli.commands.activate_session')

+     def test_list_tagged_sigs_paths(self, activate_session_mock,

+                                     event_from_opts_mock):

+         args = ['tag', 'pkg', '--latest-n=3', '--rpms', '--sigs',

+                 '--arch=x86_64', '--paths']

+ 

+         anon_handle_list_tagged(self.options, self.session, args)

+         self.assert_console_message(sys.stdout, '')

+ 

+     @mock.patch('koji.util.eventFromOpts', return_value=None)

+     @mock.patch('koji_cli.commands.activate_session')

+     def test_list_tagged_type(self, activate_session_mock,

+                               event_from_opts_mock):

+         args = ['tag', 'pkg', '--latest-n=3', '--type=maven']

+         self.session.listTagged.return_value = [{'id': 1,

+                                                  'name': 'packagename',

+                                                  'version': 'version',

+                                                  'release': '1.el6',

+                                                  'nvr': 'n-v-r',

+                                                  'tag_name': 'tag',

+                                                  'owner_name': 'owner',

+                                                  'maven_group_id': 'group',

+                                                  'maven_artifact_id': 'artifact'}]

+ 

+         anon_handle_list_tagged(self.options, self.session, args)

+         activate_session_mock.assert_called_once_with(self.session,

+                                                       self.options)

+         self.session.getTag.assert_called_once_with('tag', event=None)

+         self.session.listTagged.assert_called_once_with('tag',

+                                                         package='pkg',

+                                                         inherit=None,

+                                                         latest=3,

+                                                         type='maven')

+         self.session.listTaggedRPMS.assert_not_called()

+         self.assert_console_message(sys.stdout,

+                                     'Build                                     Tag                   Group Id              Artifact Id           Built by\n'

+                                     '----------------------------------------  --------------------  --------------------  --------------------  ----------------\n'

+                                     'n-v-r                                     tag                   group                 artifact              owner\n')

+ 

+ 

+     @mock.patch('koji.util.eventFromOpts', return_value=None)

+     @mock.patch('koji_cli.commands.activate_session')

+     def test_list_tagged_type_paths(self, activate_session_mock,

+                               event_from_opts_mock):

+         args = ['tag', 'pkg', '--latest-n=3', '--type=maven', '--paths']

+         self.session.listTagged.return_value = [{'id': 1,

+                                                  'name': 'packagename',

+                                                  'version': 'version',

+                                                  'release': '1.el6',

+                                                  'nvr': 'n-v-r',

+                                                  'tag_name': 'tag',

+                                                  'owner_name': 'owner',

+                                                  'maven_group_id': 'group',

+                                                  'maven_artifact_id': 'artifact'}]

+ 

+         anon_handle_list_tagged(self.options, self.session, args)

+         self.assert_console_message(sys.stdout,

+                                     'Build                                     Tag                   Group Id              Artifact Id           Built by\n'

+                                     '----------------------------------------  --------------------  --------------------  --------------------  ----------------\n'

+                                     '/mnt/koji/packages/packagename/version/1.el6/maven  tag                   group                 artifact              owner\n')

+ 

+     @mock.patch('koji.util.eventFromOpts', return_value={'id': 1000,

+                                                          'ts': 1000000.11})

+     def test_list_tagged_args(self, event_from_opts_mock):

+         # Case 1, no argument

+         expected = self.format_error_message(

+             "A tag name must be specified")

+         self.assert_system_exit(

+             anon_handle_list_tagged,

+             self.options,

+             self.session,

+             [],

+             stderr=expected,

+             activate_session=None)

+ 

+         # Case 2, arguments > 2

+         expected = self.format_error_message(

+             "Only one package name may be specified")

+         self.assert_system_exit(

+             anon_handle_list_tagged,

+             self.options,

+             self.session,

+             ['tag', 'pkg1', 'pkg2'],

+             stderr=expected,

+             activate_session=None)

+ 

+         # Case 3, no tag found

+         expected = self.format_error_message(

+             "No such tag: tag")

+         self.session.getTag.return_value = None

+         self.assert_system_exit(

+             anon_handle_list_tagged,

+             self.options,

+             self.session,

+             ['tag', 'pkg1'],

+             stderr=expected)

+ 

+     def test_handle_list_tagged_help(self):

+         self.assert_help(

+             anon_handle_list_tagged,

+             """Usage: %s list-tagged [options] tag [package]

+ (Specify the --help global option for a list of other help options)

+ 

+ Options:

+   -h, --help      show this help message and exit

+   --arch=ARCH     List rpms for this arch

+   --rpms          Show rpms instead of builds

+   --inherit       Follow inheritance

+   --latest        Only show the latest builds/rpms

+   --latest-n=N    Only show the latest N builds/rpms

+   --quiet         Do not print the header information

+   --paths         Show the file paths

+   --sigs          Show signatures

+   --type=TYPE     Show builds of the given type only.  Currently supported

+                   types: maven, win, image

+   --event=EVENT#  query at event

+   --ts=TIMESTAMP  query at timestamp

+   --repo=REPO#    query at event for a repo

+ """ % self.progname)

and support append for '--arch'
fixes #926
fixes #933

Maybe it does make sense to check tag existence earlier in readTaggedBuilds, etc. as it is required argument there?
@mikem ?

rebased onto 5ca4a725a14dab95a7c420a03b2de1edbc1d36ec

5 years ago

1 new commit added

  • cli: support multiple arches in list-tagged
5 years ago

Looks fine, but the new unit test fails because of TZ differences

1 new commit added

  • fix timezone in test_list_tagged
5 years ago

Test now works in py2 but fails in py3

Test now works in py2 but fails in py3

@tkopecek Could you give me the error? It passes on my F24 with py3.5

1 new commit added

  • try the best to put source target scratch into policy_data in make_task
5 years ago

4 new commits added

  • fix timezone in test_list_tagged
  • cli: support multiple arches in list-tagged
  • unit test for cli list-tagged command
  • check tag existence in list-tagged cmd and listTagged* APIs
5 years ago

4 new commits added

  • fix timezone in test_list_tagged
  • cli: support multiple arches in list-tagged
  • unit test for cli list-tagged command
  • check tag existence in list-tagged cmd and listTagged* APIs
5 years ago

@tkopecek
I've updated the unittest, please try again

Works now, thanks! :thumbsup:

rebased onto bebb455

5 years ago

rebased onto da7f971

5 years ago

rebased onto bebb455

5 years ago

Commit 898de96 fixes this pull-request

Pull-Request has been merged by mikem

5 years ago