mirror of
https://pagure.io/fm-orchestrator.git
synced 2026-04-10 14:20:00 +08:00
New: Support querying of modules/components with multiple state value filtering
This commit is contained in:
@@ -498,7 +498,8 @@ parameters include:
|
||||
- ``owner``
|
||||
- ``rebuild_strategy``
|
||||
- ``scmurl``
|
||||
- ``state`` (can be the state name or the state ID e.g. ``state=done``)
|
||||
- ``state`` (Can be the state name or the state ID e.g. ``state=done``. This
|
||||
parameter can be given multiple times, in which case or-ing will be used.)
|
||||
- ``state_reason``
|
||||
- ``stream``
|
||||
- ``submitted_after`` (Zulu ISO 8601 format e.g. ``submitted_after=2016-08-22T09:40:07Z``)
|
||||
@@ -662,7 +663,9 @@ parameters include:
|
||||
- ``package``
|
||||
- ``ref``
|
||||
- ``scmurl``
|
||||
- ``state``
|
||||
- ``state`` (Can be the state name or the state ID. Koji states are used
|
||||
for resolving to IDs. This parameter can be given multiple times, in which
|
||||
case or-ing will be used.)
|
||||
- ``state_reason``
|
||||
- ``tagged`` (boolean e.g. "true" or "false")
|
||||
- ``tagged_in_final`` (boolean e.g. "true" or "false")
|
||||
|
||||
@@ -134,6 +134,9 @@ def filter_component_builds(flask_request):
|
||||
"""
|
||||
search_query = dict()
|
||||
for key in request.args.keys():
|
||||
# Search by state will be handled separately
|
||||
if key == 'state':
|
||||
continue
|
||||
# Only filter on valid database columns
|
||||
if key in models.ComponentBuild.__table__.columns.keys():
|
||||
if isinstance(models.ComponentBuild.__table__.columns[key].type, sqlalchemy_boolean):
|
||||
@@ -141,10 +144,12 @@ def filter_component_builds(flask_request):
|
||||
else:
|
||||
search_query[key] = flask_request.args[key]
|
||||
|
||||
state = flask_request.args.get('state', None)
|
||||
if state:
|
||||
# Multiple states can be supplied => or-ing will take place
|
||||
states = flask_request.args.getlist('state')
|
||||
search_states = []
|
||||
for state in states:
|
||||
if state.isdigit():
|
||||
search_query['state'] = state
|
||||
search_states.append(state)
|
||||
else:
|
||||
try:
|
||||
import koji
|
||||
@@ -152,9 +157,9 @@ def filter_component_builds(flask_request):
|
||||
raise ValidationError('Cannot filter by state names because koji isn\'t installed')
|
||||
|
||||
if state.upper() in koji.BUILD_STATES:
|
||||
search_query['state'] = koji.BUILD_STATES[state.upper()]
|
||||
search_states.append(koji.BUILD_STATES[state.upper()])
|
||||
else:
|
||||
raise ValidationError('An invalid state was supplied')
|
||||
raise ValidationError('Invalid state was supplied: %s' % state)
|
||||
|
||||
# Allow the user to specify the module build ID with a more intuitive key name
|
||||
if 'module_build' in flask_request.args:
|
||||
@@ -164,6 +169,8 @@ def filter_component_builds(flask_request):
|
||||
|
||||
if search_query:
|
||||
query = query.filter_by(**search_query)
|
||||
if search_states:
|
||||
query = query.filter(models.ComponentBuild.state.in_(search_states))
|
||||
|
||||
query = _add_order_by_clause(flask_request, query, models.ComponentBuild)
|
||||
|
||||
@@ -186,20 +193,24 @@ def filter_module_builds(flask_request):
|
||||
if key not in special_columns and key in models.ModuleBuild.__table__.columns.keys():
|
||||
search_query[key] = flask_request.args[key]
|
||||
|
||||
state = flask_request.args.get('state', None)
|
||||
if state:
|
||||
# Multiple states can be supplied => or-ing will take place
|
||||
states = flask_request.args.getlist('state')
|
||||
search_states = []
|
||||
for state in states:
|
||||
if state.isdigit():
|
||||
search_query['state'] = state
|
||||
search_states.append(state)
|
||||
else:
|
||||
if state in models.BUILD_STATES:
|
||||
search_query['state'] = models.BUILD_STATES[state]
|
||||
search_states.append(models.BUILD_STATES[state])
|
||||
else:
|
||||
raise ValidationError('An invalid state was supplied')
|
||||
raise ValidationError('Invalid state was supplied: %s' % state)
|
||||
|
||||
query = models.ModuleBuild.query
|
||||
|
||||
if search_query:
|
||||
query = query.filter_by(**search_query)
|
||||
if search_states:
|
||||
query = query.filter(models.ModuleBuild.state.in_(search_states))
|
||||
|
||||
# This is used when filtering the date request parameters, but it is here to avoid recompiling
|
||||
utc_iso_datetime_regex = re.compile(
|
||||
|
||||
@@ -442,6 +442,16 @@ class TestViews:
|
||||
data = json.loads(rv.data)
|
||||
assert data['meta']['total'] == 1
|
||||
|
||||
def test_query_component_builds_filter_state(self):
|
||||
rv = self.client.get('/module-build-service/1/component-builds/?state=3')
|
||||
data = json.loads(rv.data)
|
||||
assert data['meta']['total'] == 2
|
||||
|
||||
def test_query_component_builds_filter_multiple_states(self):
|
||||
rv = self.client.get('/module-build-service/1/component-builds/?state=3&state=1')
|
||||
data = json.loads(rv.data)
|
||||
assert data['meta']['total'] == 12
|
||||
|
||||
def test_query_builds_filter_name(self):
|
||||
rv = self.client.get('/module-build-service/1/module-builds/?name=nginx')
|
||||
data = json.loads(rv.data)
|
||||
@@ -500,6 +510,12 @@ class TestViews:
|
||||
data = json.loads(rv.data)
|
||||
assert data['meta']['total'] == 2
|
||||
|
||||
def test_query_builds_filter_multiple_states(self):
|
||||
rv = self.client.get(
|
||||
'/module-build-service/1/module-builds/?state=3&state=1')
|
||||
data = json.loads(rv.data)
|
||||
assert data['meta']['total'] == 4
|
||||
|
||||
def test_query_builds_two_filters(self):
|
||||
rv = self.client.get('/module-build-service/1/module-builds/?owner=Moe%20Szyslak'
|
||||
'&modified_after=2016-09-03T11:35:00Z')
|
||||
|
||||
Reference in New Issue
Block a user