diff --git a/hub/kojihub.py b/hub/kojihub.py index 1cdbe0d1..45fd06d9 100644 --- a/hub/kojihub.py +++ b/hub/kojihub.py @@ -11568,12 +11568,28 @@ class RootExports(object): task.setPriority(priority, recurse=recurse) def listTagged(self, tag, event=None, inherit=False, prefix=None, latest=False, package=None, - owner=None, type=None): - """List builds tagged with tag""" + owner=None, type=None, strict=True): + """List builds tagged with tag. + + :param int|str tag: tag name or ID number + :param int event: event ID + :param bool inherit: If inherit is True, follow the tag hierarchy and return + a list of tagged builds for all tags in the tree + :param str prefix: only builds whose package name starts with that prefix + :param bool|int latest: True for latest build per package, + N to get N latest builds per package. + :param str package: only builds of the specified package + :param owner: only builds of the specified owner + :param str type: only builds of the given btype (such as maven or image) + :param bool strict: If tag doesn't exist, an exception is raised, + unless strict is False in which case returns an empty list. + """ # 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) + tag = get_tag(tag, strict=strict, event=event) + if not tag: + return [] + results = readTaggedBuilds(tag['id'], event, inherit=inherit, latest=latest, + package=package, owner=owner, type=type) if prefix: prefix = prefix.lower() results = [build for build in results @@ -11581,24 +11597,56 @@ class RootExports(object): return results 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""" + rpmsigs=False, owner=None, type=None, strict=True): + """List rpms and builds within tag. + + :param int|str tag: tag name or ID number + :param int event: event ID + :param bool inherit: If inherit is True, follow the tag hierarchy and return + a list of tagged RPMs for all tags in the tree + :param bool|int latest: Set to "True" to get the single latest build. Set + to an int "N" to get the latest "N" builds. If + unspecified, the default value is "False", and + Koji will list all builds in the tag. + :param str package: only rpms of the specified package + :param str arch: only rpms of the specified arch + :param str rpmsigs: only rpms of the specified rpmsigs + :param str owner: only rpms of the specified owner + :param str type: only rpms of the given btype (such as maven or image) + :param bool strict: If tag doesn't exist, an exception is raised, + unless strict is False in which case returns an empty list. + """ # 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) + tag = get_tag(tag, strict=strict, event=event) + if not tag: + return [] + return readTaggedRPMS(tag['id'], 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""" + type=None, strict=True): + """List archives and builds within a tag. + + :param int|str tag: tag name or ID number + :param int event: event ID + :param bool inherit: If inherit is True, follow the tag hierarchy and return + a list of tagged archives for all tags in the tree + :param bool|int latest: Set to "True" to get tagged archives just from latest build. + Set latest=N to get only the N latest tagged RPMs. + :param str package: only archives of the specified package + :param str type: only archives of the given btype (such as maven or image) + :param bool strict: If tag doesn't exist, an exception is raised, + unless strict is False in which case returns an empty list. + """ # lookup tag id - tag = get_tag(tag, strict=True, event=event)['id'] - return readTaggedArchives(tag, event=event, inherit=inherit, latest=latest, + tag = get_tag(tag, strict=strict, event=event) + if not tag: + return [] + return readTaggedArchives(tag['id'], event=event, inherit=inherit, latest=latest, package=package, type=type) def listBuilds(self, packageID=None, userID=None, taskID=None, prefix=None, state=None, - volumeID=None, source=None, - createdBefore=None, createdAfter=None, + volumeID=None, source=None, createdBefore=None, createdAfter=None, completeBefore=None, completeAfter=None, type=None, typeInfo=None, queryOpts=None, pattern=None, cgID=None): """ diff --git a/tests/test_hub/test_list_tagged.py b/tests/test_hub/test_list_tagged.py new file mode 100644 index 00000000..6c43365d --- /dev/null +++ b/tests/test_hub/test_list_tagged.py @@ -0,0 +1,38 @@ +import unittest + +import koji +import kojihub +import mock + +QP = kojihub.QueryProcessor + + +class TestListTagged(unittest.TestCase): + def setUp(self): + self.QueryProcessor = mock.patch('kojihub.QueryProcessor', + side_effect=self.getQuery).start() + self.queries = [] + self.get_tag = mock.patch('kojihub.get_tag').start() + self.exports = kojihub.RootExports() + self.context = mock.patch('kojihub.context').start() + self.cursor = mock.MagicMock() + + def getQuery(self, *args, **kwargs): + query = QP(*args, **kwargs) + query.execute = mock.MagicMock() + query.executeOne = mock.MagicMock() + self.queries.append(query) + return query + + def test_non_exist_tag_without_strict(self): + self.get_tag.return_value = None + self.exports.listTagged('non-existing-tag', strict=False) + self.assertEqual(len(self.queries), 0) + + def test_non_exist_tag_with_strict(self): + tag_name = 'non-existing-tag' + error_message = "No such tagInfo: '%s'" % tag_name + self.get_tag.side_effect = koji.GenericError(error_message) + with self.assertRaises(koji.GenericError) as cm: + self.exports.listTagged(tag_name) + self.assertEqual(error_message, str(cm.exception)) diff --git a/tests/test_hub/test_list_tagged_archives.py b/tests/test_hub/test_list_tagged_archives.py new file mode 100644 index 00000000..73096f95 --- /dev/null +++ b/tests/test_hub/test_list_tagged_archives.py @@ -0,0 +1,38 @@ +import unittest + +import koji +import kojihub +import mock + +QP = kojihub.QueryProcessor + + +class TestListTaggedArchives(unittest.TestCase): + def setUp(self): + self.QueryProcessor = mock.patch('kojihub.QueryProcessor', + side_effect=self.getQuery).start() + self.queries = [] + self.get_tag = mock.patch('kojihub.get_tag').start() + self.exports = kojihub.RootExports() + self.context = mock.patch('kojihub.context').start() + self.cursor = mock.MagicMock() + + def getQuery(self, *args, **kwargs): + query = QP(*args, **kwargs) + query.execute = mock.MagicMock() + query.executeOne = mock.MagicMock() + self.queries.append(query) + return query + + def test_non_exist_tag_without_strict(self): + self.get_tag.return_value = None + self.exports.listTagged('non-existing-tag', strict=False) + self.assertEqual(len(self.queries), 0) + + def test_non_exist_tag_with_strict(self): + tag_name = 'non-existing-tag' + error_message = "No such tagInfo: '%s'" % tag_name + self.get_tag.side_effect = koji.GenericError(error_message) + with self.assertRaises(koji.GenericError) as cm: + self.exports.listTagged(tag_name) + self.assertEqual(error_message, str(cm.exception)) diff --git a/tests/test_hub/test_list_tagged_rpms.py b/tests/test_hub/test_list_tagged_rpms.py new file mode 100644 index 00000000..c92d4e8e --- /dev/null +++ b/tests/test_hub/test_list_tagged_rpms.py @@ -0,0 +1,38 @@ +import unittest + +import koji +import kojihub +import mock + +QP = kojihub.QueryProcessor + + +class TestListTaggedRPMS(unittest.TestCase): + def setUp(self): + self.QueryProcessor = mock.patch('kojihub.QueryProcessor', + side_effect=self.getQuery).start() + self.queries = [] + self.get_tag = mock.patch('kojihub.get_tag').start() + self.exports = kojihub.RootExports() + self.context = mock.patch('kojihub.context').start() + self.cursor = mock.MagicMock() + + def getQuery(self, *args, **kwargs): + query = QP(*args, **kwargs) + query.execute = mock.MagicMock() + query.executeOne = mock.MagicMock() + self.queries.append(query) + return query + + def test_non_exist_tag_without_strict(self): + self.get_tag.return_value = None + self.exports.listTaggedRPMS('non-existing-tag', strict=False) + self.assertEqual(len(self.queries), 0) + + def test_non_exist_tag_with_strict(self): + tag_name = 'non-existing-tag' + error_message = "No such tagInfo: '%s'" % tag_name + self.get_tag.side_effect = koji.GenericError(error_message) + with self.assertRaises(koji.GenericError) as cm: + self.exports.listTaggedRPMS(tag_name) + self.assertEqual(error_message, str(cm.exception))