From 835c2d5993d8c66c0045c165228aad2c46fd7040 Mon Sep 17 00:00:00 2001 From: Valerij Maljulin Date: Nov 25 2020 12:53:03 +0000 Subject: Support scenario field for HTTP API JIRA: RHELWF-1881 --- diff --git a/tests/test_api_v10.py b/tests/test_api_v10.py index 4cab225..775139e 100644 --- a/tests/test_api_v10.py +++ b/tests/test_api_v10.py @@ -58,6 +58,7 @@ def test_create_waiver(mocked_user, client, session): assert res_data['product_version'] == 'fool-1' assert res_data['waived'] is True assert res_data['comment'] == 'it broke' + assert res_data['scenario'] is None def test_create_waiver_with_subject(mocked_user, client, session): @@ -89,6 +90,7 @@ def test_create_waiver_with_result_id(mocked_user, mocked_resultsdb, client, ses 'data': { 'type': ['koji_build'], 'item': ['somebuild'], + 'scenario': ['somescenario'], }, 'testcase': {'name': 'sometest'} } @@ -105,6 +107,7 @@ def test_create_waiver_with_result_id(mocked_user, mocked_resultsdb, client, ses res_data = json.loads(r.get_data(as_text=True)) assert r.status_code == 201 assert res_data['username'] == 'foo' + assert res_data['scenario'] == 'somescenario' assert res_data['subject'] == {'type': 'koji_build', 'item': 'somebuild'} assert res_data['subject_type'] == 'koji_build' assert res_data['subject_identifier'] == 'somebuild' @@ -158,6 +161,31 @@ def test_create_waiver_without_comment(mocked_user, client, session): assert res_data['message']['comment'] == 'Missing required parameter in the JSON body' +def test_create_waiver_with_scenario(mocked_user, client, session): + data = { + 'subject_type': 'koji_build', + 'subject_identifier': 'glibc-2.26-27.fc27', + 'testcase': 'testcase1', + 'product_version': 'fool-1', + 'scenario': 'scenario1', + 'waived': True, + 'comment': 'it broke', + } + r = client.post('/api/v1.0/waivers/', data=json.dumps(data), + content_type='application/json') + res_data = json.loads(r.get_data(as_text=True)) + assert r.status_code == 201 + assert res_data['username'] == 'foo' + assert res_data['subject'] == {'type': 'koji_build', 'item': 'glibc-2.26-27.fc27'} + assert res_data['subject_type'] == 'koji_build' + assert res_data['subject_identifier'] == 'glibc-2.26-27.fc27' + assert res_data['testcase'] == 'testcase1' + assert res_data['product_version'] == 'fool-1' + assert res_data['waived'] is True + assert res_data['comment'] == 'it broke' + assert res_data['scenario'] == 'scenario1' + + def test_create_waiver_with_unknown_result_id(mocked_user, mocked_resultsdb, client, session): mocked_resultsdb.side_effect = HTTPError(response=Mock(status=404)) data = { @@ -253,6 +281,39 @@ def test_get_waiver(client, session): assert res_data['product_version'] == waiver.product_version assert res_data['waived'] is True assert res_data['comment'] == waiver.comment + assert res_data['scenario'] is None + + +def test_get_waiver_by_scenario(client, session): + scenario_name = 'scenario19' + # create a new waiver + waiver1 = create_waiver( + session, subject_type='koji_build', subject_identifier='glibc-2.26-27.fc27', + testcase='testcase1', username='foo', product_version='foo-1', comment='bla bla bla', + scenario=scenario_name + ) + create_waiver( + session, subject_type='bodhi_update', subject_identifier='glibc-2.26-27.fc27', + testcase='testcase1', username='foo', product_version='foo-1', comment='bla bla bla', + scenario='yyyyyy' + ) + r = client.get(f'/api/v1.0/waivers/?scenario={scenario_name}') + assert r.status_code == 200 + res_data = json.loads(r.get_data(as_text=True)) + assert len(res_data['data']) == 1 + assert res_data['data'][0]['username'] == waiver1.username + assert res_data['data'][0]['subject'] == {'type': 'koji_build', 'item': 'glibc-2.26-27.fc27'} + assert res_data['data'][0]['subject_type'] == waiver1.subject_type + assert res_data['data'][0]['subject_identifier'] == waiver1.subject_identifier + assert res_data['data'][0]['testcase'] == waiver1.testcase + assert res_data['data'][0]['product_version'] == waiver1.product_version + assert res_data['data'][0]['waived'] is True + assert res_data['data'][0]['comment'] == waiver1.comment + assert res_data['data'][0]['scenario'] == scenario_name + assert res_data['prev'] is None + assert res_data['next'] is None + assert res_data['first'] == res_data['last'] + assert res_data['last'] == f'http://localhost/api/v1.0/waivers/?page=1&scenario={scenario_name}' def test_404_for_nonexistent_waiver(client, session): diff --git a/tests/utils.py b/tests/utils.py index 52dbda2..4d751a2 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -4,9 +4,9 @@ from waiverdb.models import Waiver def create_waiver(session, subject_type, subject_identifier, testcase, username, product_version, - waived=True, comment=None, proxied_by=None): + waived=True, comment=None, proxied_by=None, scenario=None): waiver = Waiver(subject_type, subject_identifier, testcase, username, product_version, - waived, comment, proxied_by) + waived, comment, proxied_by, scenario) session.add(waiver) session.flush() return waiver diff --git a/waiverdb/api_v1.py b/waiverdb/api_v1.py index 4f3261b..3031d05 100644 --- a/waiverdb/api_v1.py +++ b/waiverdb/api_v1.py @@ -121,6 +121,7 @@ RP['create_waiver'].add_argument('waived', type=bool, required=True, location='j RP['create_waiver'].add_argument('product_version', type=str, required=True, location='json') RP['create_waiver'].add_argument('comment', type=str, required=True, location='json') RP['create_waiver'].add_argument('username', type=str, default=None, location='json') +RP['create_waiver'].add_argument('scenario', type=str, default=None, location='json') RP['get_waivers'] = reqparse.RequestParser() RP['get_waivers'].add_argument('subject_type', location='args') @@ -129,6 +130,7 @@ RP['get_waivers'].add_argument('testcase', location='args') RP['get_waivers'].add_argument('product_version', location='args') RP['get_waivers'].add_argument('username', location='args') RP['get_waivers'].add_argument('include_obsolete', type=bool, default=False, location='args') +RP['get_waivers'].add_argument('scenario', type=str, default=None, location='args') # XXX This matches the since query parameter in resultsdb but I think it would # be good to use two parameters(since and until). RP['get_waivers'].add_argument('since', type=reqparse_since, location='args') @@ -198,6 +200,7 @@ class WaiversResource(Resource): :query string subject_type: Only include waivers for the given subject type. :query string subject_identifier: Only include waivers for the given subject identifier. :query string testcase: Only include waivers for the given test case name. + :query string scenario: Only include waivers for the given scenario name. :query string product_version: Only include waivers for the given product version. :query string username: Only include waivers which were submitted by @@ -222,6 +225,8 @@ class WaiversResource(Resource): query = query.filter(Waiver.subject_identifier == args['subject_identifier']) if args['testcase']: query = query.filter(Waiver.testcase == args['testcase']) + if args['scenario']: + query = query.filter(Waiver.scenario == args['scenario']) if args['product_version']: query = query.filter(Waiver.product_version == args['product_version']) if args['username']: @@ -290,6 +295,7 @@ class WaiversResource(Resource): "subject_type": "compose", "subject_identifier": "Fedora-9000-19700101.n.18", "testcase": "compose.install_no_user", + "scenario": null, "timestamp": "2017-03-16T17:42:04.209638", "username": "jcline", "waived": false, @@ -301,6 +307,7 @@ class WaiversResource(Resource): waiver is for. The semantics of this identifier depend on the "subject_type". For example, Koji builds are identified by their NVR. :json string testcase: The result testcase for the waiver. + :json string scenario: The result scenario for the waiver. :json boolean waived: Whether or not the result is waived. :json string product_version: The product version string. :json string comment: A comment explaining the waiver. @@ -354,9 +361,9 @@ class WaiversResource(Resource): # WaiverDB < 0.6 if args['result_id']: - if args['subject'] or args['testcase']: - raise BadRequest('Only result_id or subject and ' - 'testcase are allowed. Not both.') + if args['subject'] or args['testcase'] or args['scenario']: + raise BadRequest('result_id argument should not be used together with arguments: ' + '"subject", "testcase" or "scenario"') try: result = get_resultsdb_result(args.pop('result_id')) except requests.HTTPError as e: @@ -381,6 +388,8 @@ class WaiversResource(Resource): 'id for this result. Please try again specifying ' 'a subject and a testcase.') args['testcase'] = result['testcase']['name'] + if 'scenario' in result_data: + args['scenario'] = result_data['scenario'][0] # WaiverDB < 0.11 if args['subject']: @@ -412,7 +421,9 @@ class WaiversResource(Resource): args['product_version'], args['waived'], args['comment'], - proxied_by) + proxied_by, + args['scenario'] + ) class WaiverResource(Resource): @@ -486,6 +497,7 @@ class FilteredWaiversResource(Resource): "subject_type": "compose", "subject_identifier": "Fedora-9000-19700101.n.18", "testcase": "compose.install_no_user", + "scenario": null, "timestamp": "2017-03-16T17:42:04.209638", "username": "jcline", "waived": true, @@ -514,6 +526,8 @@ class FilteredWaiversResource(Resource): inner_clauses.append(Waiver.subject_identifier == filter_['subject_identifier']) if 'testcase' in filter_: inner_clauses.append(Waiver.testcase == filter_['testcase']) + if 'scenario' in filter_: + inner_clauses.append(Waiver.scenario == filter_['scenario']) if 'product_version' in filter_: inner_clauses.append(Waiver.product_version == filter_['product_version']) if 'username' in filter_: diff --git a/waiverdb/fields.py b/waiverdb/fields.py index ff1d73d..f15521a 100644 --- a/waiverdb/fields.py +++ b/waiverdb/fields.py @@ -19,6 +19,7 @@ waiver_fields = { 'subject': BackwardsCompatibleSubjectField, 'testcase': fields.String, 'username': fields.String, + 'scenario': fields.String, 'proxied_by': fields.String, 'product_version': fields.String, 'waived': fields.Boolean, diff --git a/waiverdb/models/waivers.py b/waiverdb/models/waivers.py index 0e1fbae..c3a4f7f 100644 --- a/waiverdb/models/waivers.py +++ b/waiverdb/models/waivers.py @@ -58,7 +58,7 @@ class Waiver(db.Model): ) def __init__(self, subject_type, subject_identifier, testcase, username, product_version, - waived=False, comment=None, proxied_by=None): + waived=False, comment=None, proxied_by=None, scenario=None): self.subject_type = subject_type self.subject_identifier = subject_identifier self.testcase = testcase @@ -67,12 +67,13 @@ class Waiver(db.Model): self.waived = waived self.comment = comment self.proxied_by = proxied_by + self.scenario = scenario def __repr__(self): - return ('%s(subject_type=%r, subject_identifier=%r, testcase=%r, username=%r, ' + return ('%s(subject_type=%r, subject_identifier=%r, testcase=%r, scenario=%r, username=%r, ' 'product_version=%r, waived=%r)' % (self.__class__.__name__, self.subject_type, self.subject_identifier, - self.testcase, self.username, self.product_version, self.waived)) + self.testcase, self.scenario, self.username, self.product_version, self.waived)) @classmethod def by_results(cls, query, results):