New: Support querying of modules/components with multiple state value filtering

This commit is contained in:
Filip Valder
2018-06-12 12:13:33 +02:00
parent 29130e3da5
commit f1fc7ed467
3 changed files with 42 additions and 12 deletions

View File

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

View File

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

View File

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