listBuilds accept also package name and user name

Fixes: https://pagure.io/koji/issue/1209
This commit is contained in:
Jana Cupova 2021-05-18 08:00:47 +02:00 committed by Tomas Kopecek
parent 58fe3930ed
commit c4a2f01184
2 changed files with 141 additions and 54 deletions

View file

@ -11315,79 +11315,78 @@ class RootExports(object):
createdBefore=None, createdAfter=None,
completeBefore=None, completeAfter=None, type=None, typeInfo=None,
queryOpts=None, pattern=None):
"""Return a list of builds that match the given parameters
"""
Return a list of builds that match the given parameters
Filter parameters
- packageID: only builds of the specified package (numeric id)
- userID: only builds owned by the given user (numeric id)
- taskID: only builds with the given task ID
If taskID is -1, only builds with a non-null task id
- volumeID: only builds stored on the given volume (numeric id)
- source: only builds where the source field matches (glob pattern)
- prefix: only builds whose package name starts with that prefix
- pattern: only builds whose nvr matches the glob pattern
- state: only builds in the given state (numeric value)
:param int|str packageID: only builds of the specified package
:param int|str userID: only builds owned by the given user
:param int taskID: only builds with the given task ID
If taskID is -1, only builds with a non-null task id
:param int volumeID: only builds stored on the given volume
:param str source: only builds where the source field matches (glob pattern)
:param str prefix: only builds whose package name starts with that prefix
:param str pattern: only builds whose nvr matches the glob pattern
:param int stage: only builds in the given state
Timestamp filter parameters
- these limit the results to builds where the corresponding
timestamp is before or after the given time
- the time value may be specified as seconds since the epoch or
in ISO format ('YYYY-MM-DD HH24:MI:SS')
- filters for creation_time:
- createdBefore
- createdAfter
- filters for completion_time:
- completeBefore
- completeAfter
:param str|timestamp createdBefore: filter for creation_time
:param str|timestamp createdAfter: filter for creation_time
:param str|timestamp completeBefore: filter for completion_time
:param str|timestamp completeAfter: filter for completion_time
Build type parameters:
- type: only builds of the given btype (such as maven or image)
- typeInfo: only builds with matching type-specific info (given
as a dictionary). Can only be used in conjunction with the
type parameter. Only limited types are supported.
:param str type: only builds of the given btype (such as maven or image)
:param dict typeInfo: only builds with matching type-specific info (given
as a dictionary). Can only be used in conjunction with the
type parameter. Only limited types are supported.
For type=maven, the provided group_id, artifact_id, and/or version
fields are matched
For type=maven, the provided group_id, artifact_id, and/or version
fields are matched
For type=win, the provided platform fields are matched
For type=win, the provided platform fields are matched
Returns a list of maps. Each map contains the following keys:
:returns: Returns a list of maps. Each map contains the following keys:
- build_id
- version
- release
- epoch
- state
- package_id
- package_name
- name (same as package_name)
- nvr (synthesized for sorting purposes)
- owner_id
- owner_name
- volume_id
- volume_name
- source
- creation_event_id
- creation_time
- creation_ts
- start_time
- start_ts
- completion_time
- completion_ts
- task_id
- extra
- build_id
- version
- release
- epoch
- state
- package_id
- package_name
- name (same as package_name)
- nvr (synthesized for sorting purposes)
- owner_id
- owner_name
- volume_id
- volume_name
- source
- creation_event_id
- creation_time
- creation_ts
- start_time
- start_ts
- completion_time
- completion_ts
- task_id
- extra
If type == 'maven', each map will also contain the following keys:
If type == 'maven', each map will also contain the following keys:
- maven_group_id
- maven_artifact_id
- maven_version
- maven_group_id
- maven_artifact_id
- maven_version
If type == 'win', each map will also contain the following key:
If type == 'win', each map will also contain the following key:
- platform
- platform
If no builds match, an empty list is returned.
If no builds match, an empty list is returned.
"""
fields = [('build.id', 'build_id'), ('build.version', 'version'),
('build.release', 'release'),
@ -11414,8 +11413,10 @@ class RootExports(object):
'LEFT JOIN users ON build.owner = users.id']
clauses = []
if packageID is not None:
packageID = get_package_id(packageID, strict=True)
clauses.append('package.id = %(packageID)i')
if userID is not None:
userID = get_user(userID, strict=True)['id']
clauses.append('users.id = %(userID)i')
if volumeID is not None:
clauses.append('volume.id = %(volumeID)i')

View file

@ -0,0 +1,86 @@
import unittest
import mock
import koji
import kojihub
QP = kojihub.QueryProcessor
class TestListBuilds(unittest.TestCase):
def getQuery(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = mock.MagicMock()
query.executeOne = self.query_executeOne
query.iterate = mock.MagicMock()
self.queries.append(query)
return query
def setUp(self):
self.maxDiff = None
self.exports = kojihub.RootExports()
self.query_executeOne = mock.MagicMock()
self.QueryProcessor = mock.patch('kojihub.QueryProcessor',
side_effect=self.getQuery).start()
self.queries = []
self.context = mock.patch('kojihub.context').start()
self.cursor = mock.MagicMock()
self.build_list = [{'build_id': 9,
'epoch': 0,
'name': 'test-package',
'nvr': 'test-package-11-12',
'owner_id': 1,
'owner_name': 'kojiadmin',
'package_id': 11,
'package_name': 'test-package',
'release': '12',
'state': 3,
'task_id': 879,
'version': '11',
'volume_id': 0,
'volume_name': 'DEFAULT'}]
def test_wrong_package(self):
package = 'test-package'
kojihub.get_package_id.return_value = package
with self.assertRaises(koji.GenericError) as cm:
self.exports.listBuilds(packageID=package)
self.assertEqual('No such entry in table package: %s' % package, str(cm.exception))
@mock.patch('kojihub.get_package_id')
def test_package_string(self, get_package_id):
package = 'test-package'
package_id = 1
get_package_id.return_value = package_id
self.query_executeOne.return_value = None
self.exports.listBuilds(packageID=package)
self.assertEqual(len(self.queries), 1)
args, kwargs = self.QueryProcessor.call_args
qp = QP(**kwargs)
self.assertEquals(qp.tables, ['build'])
self.assertEquals(qp.columns, ['build.id', 'build.completion_time',
'EXTRACT(EPOCH FROM build.completion_time)',
'events.id', 'events.time',
'EXTRACT(EPOCH FROM events.time)', 'build.epoch',
'build.extra', 'package.name',
"package.name || '-' || build.version || '-' || "
"build.release", 'users.id', 'users.name', 'package.id',
'package.name', 'build.release', 'build.source',
'build.start_time', 'EXTRACT(EPOCH FROM build.start_time)',
'build.state', 'build.task_id', 'build.version',
'volume.id', 'volume.name'])
self.assertEqual(qp.clauses, ['package.id = %(packageID)i'])
self.assertEquals(qp.joins, ['LEFT JOIN events ON build.create_event = events.id',
'LEFT JOIN package ON build.pkg_id = package.id',
'LEFT JOIN volume ON build.volume_id = volume.id',
'LEFT JOIN users ON build.owner = users.id'])
@mock.patch('kojihub.get_user')
def test_wrong_user(self, get_user):
user = 'test-user'
get_user.side_effect = koji.GenericError('No such user: %s' % user)
with self.assertRaises(koji.GenericError) as cm:
self.exports.listBuilds(userID=user)
self.assertEqual('No such user: %s' % user, str(cm.exception))