From 6a3315dad3c6d23dc41480d8083d4c59d971caa5 Mon Sep 17 00:00:00 2001 From: Ralph Bean Date: Mar 27 2018 11:29:42 +0000 Subject: [PATCH 1/5] Make the list of allowed outcomes configurable. This will let other resultsdb instances expand the list. --- diff --git a/resultsdb/config.py b/resultsdb/config.py index e4ba6b8..0093d5c 100644 --- a/resultsdb/config.py +++ b/resultsdb/config.py @@ -46,6 +46,9 @@ class Config(object): 'create_testcase': [], } + # Extend the list of allowed outcomes. + ADDITIONAL_RESULT_OUTCOMES = () + # Supported values: "oidc" AUTH_MODULE = None diff --git a/resultsdb/models/results.py b/resultsdb/models/results.py index e07e832..a8f4857 100644 --- a/resultsdb/models/results.py +++ b/resultsdb/models/results.py @@ -20,14 +20,14 @@ import datetime import uuid as lib_uuid -from resultsdb import db +from resultsdb import db, app from resultsdb.serializers import DBSerialize __all__ = ['Testcase', 'Group', 'Result', 'ResultData', 'GroupsToResults', 'RESULT_OUTCOME'] - -RESULT_OUTCOME = ('PASSED', 'INFO', 'FAILED', 'NEEDS_INSPECTION') +PRESET_OUTCOMES = ('PASSED', 'INFO', 'FAILED', 'NEEDS_INSPECTION') +RESULT_OUTCOME = PRESET_OUTCOMES + app.config.get('ADDITIONAL_RESULT_OUTCOMES', []) JOB_STATUS = [] From 7b4efe4787795b3d870678c4dcc5a657f56ace7a Mon Sep 17 00:00:00 2001 From: Ralph Bean Date: Mar 27 2018 11:42:58 +0000 Subject: [PATCH 2/5] Add outcomes to landing page, for discoverability. --- diff --git a/resultsdb/config.py b/resultsdb/config.py index 0093d5c..9402eeb 100644 --- a/resultsdb/config.py +++ b/resultsdb/config.py @@ -113,3 +113,4 @@ class TestingConfig(Config): TRAP_BAD_REQUEST_ERRORS = True FEDMENU_URL = 'https://apps.stg.fedoraproject.org/fedmenu' FEDMENU_DATA_URL = 'https://apps.stg.fedoraproject.org/js/data.js' + ADDITIONAL_RESULT_OUTCOMES = ('AMAZING',) diff --git a/resultsdb/controllers/api_v1.py b/resultsdb/controllers/api_v1.py index 1eda3f1..9eeea42 100644 --- a/resultsdb/controllers/api_v1.py +++ b/resultsdb/controllers/api_v1.py @@ -683,5 +683,6 @@ def landing_page(): "documentation": "http://docs.resultsdb.apiary.io/", "jobs": url_for('.get_jobs', _external=True), "results": url_for('.get_results', _external=True), - "testcases": url_for('.get_testcases', _external=True) + "testcases": url_for('.get_testcases', _external=True), + "outcomes": RESULT_OUTCOME, }), 300 diff --git a/resultsdb/controllers/api_v2.py b/resultsdb/controllers/api_v2.py index 983f5ed..aae7192 100644 --- a/resultsdb/controllers/api_v2.py +++ b/resultsdb/controllers/api_v2.py @@ -779,5 +779,6 @@ def landing_page(): "documentation": "http://docs.resultsdb20.apiary.io/", "groups": url_for('.get_groups', _external=True), "results": url_for('.get_results', _external=True), - "testcases": url_for('.get_testcases', _external=True) + "testcases": url_for('.get_testcases', _external=True), + "outcomes": RESULT_OUTCOME, }), 300 diff --git a/testing/functest_api_v20.py b/testing/functest_api_v20.py index 36080b9..9321f87 100644 --- a/testing/functest_api_v20.py +++ b/testing/functest_api_v20.py @@ -853,3 +853,9 @@ class TestFuncApiV20(): assert plugin.history[0]['groups'] == [self.ref_group_uuid] assert plugin.history[0]['note'] == self.ref_result_note assert plugin.history[0]['testcase']['name'] == self.ref_testcase_name + + def test_get_outcomes_on_landing_page(self): + r = self.app.get('/api/v2.0/') + data = json.loads(r.data) + assert r.status_code == 300 + assert data['outcomes'] == ['PASSED', 'INFO', 'FAILED', 'NEEDS_INSPECTION', 'AMAZING'] From 5b42c53eaad03ac3849e1efdd93a1d83faed55ec Mon Sep 17 00:00:00 2001 From: Ralph Bean Date: Mar 29 2018 01:20:30 +0000 Subject: [PATCH 3/5] Replace the enum outcome with a string. --- diff --git a/resultsdb/alembic/versions/cd581d0e83df_change_outcome_from_enum_to_string.py b/resultsdb/alembic/versions/cd581d0e83df_change_outcome_from_enum_to_string.py new file mode 100644 index 0000000..6e730f1 --- /dev/null +++ b/resultsdb/alembic/versions/cd581d0e83df_change_outcome_from_enum_to_string.py @@ -0,0 +1,30 @@ +"""Change outcome from enum to string. + +Revision ID: cd581d0e83df +Revises: 4dbe714897fe +Create Date: 2018-03-28 20:47:27.338605 + +""" + +# revision identifiers, used by Alembic. +revision = 'cd581d0e83df' +down_revision = '4dbe714897fe' +branch_labels = None +depends_on = None + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + op.execute( + "ALTER TABLE result " + "ALTER COLUMN outcome " + "TYPE VARCHAR(32)") + + +def downgrade(): + op.execute( + "ALTER TABLE result " + "ALTER COLUMN outcome " + "TYPE resultoutcome USING outcome::resultoutcome") diff --git a/resultsdb/models/results.py b/resultsdb/models/results.py index a8f4857..8b1dbd8 100644 --- a/resultsdb/models/results.py +++ b/resultsdb/models/results.py @@ -20,6 +20,8 @@ import datetime import uuid as lib_uuid +from sqlalchemy.orm import validates + from resultsdb import db, app from resultsdb.serializers import DBSerialize @@ -95,7 +97,7 @@ class Result(db.Model, DBSerialize): testcase_name = db.Column(db.Text, db.ForeignKey('testcase.name')) submit_time = db.Column(db.DateTime, default=datetime.datetime.utcnow) - outcome = db.Column(db.Enum(*RESULT_OUTCOME, name='resultoutcome')) + outcome = db.Column(db.String(32)) note = db.Column(db.Text) ref_url = db.Column(db.Text) @@ -115,6 +117,13 @@ class Result(db.Model, DBSerialize): self.note = note self.groups = groups + @validates('outcome') + def validate_email(self, key, outcome): + if outcome not in RESULT_OUTCOME: + raise ValueError( + "outcome %s must be one of %r" % (outcome, RESULT_OUTCOME)) + return outcome + class ResultData(db.Model, DBSerialize): From 633b7c4ce3ccf729b25aa38f73fc64c82797376f Mon Sep 17 00:00:00 2001 From: Ralph Bean Date: Apr 03 2018 16:41:40 +0000 Subject: [PATCH 4/5] Remove unnecessary validator. --- diff --git a/resultsdb/models/results.py b/resultsdb/models/results.py index 8b1dbd8..95017a7 100644 --- a/resultsdb/models/results.py +++ b/resultsdb/models/results.py @@ -20,8 +20,6 @@ import datetime import uuid as lib_uuid -from sqlalchemy.orm import validates - from resultsdb import db, app from resultsdb.serializers import DBSerialize @@ -117,13 +115,6 @@ class Result(db.Model, DBSerialize): self.note = note self.groups = groups - @validates('outcome') - def validate_email(self, key, outcome): - if outcome not in RESULT_OUTCOME: - raise ValueError( - "outcome %s must be one of %r" % (outcome, RESULT_OUTCOME)) - return outcome - class ResultData(db.Model, DBSerialize): From 23628ca7aa6e081ff0489f3af53810f58f83fdd9 Mon Sep 17 00:00:00 2001 From: Ralph Bean Date: Apr 03 2018 19:01:03 +0000 Subject: [PATCH 5/5] Test creation of results with custom outcomes. --- diff --git a/testing/functest_api_v20.py b/testing/functest_api_v20.py index 9321f87..f3c0c60 100644 --- a/testing/functest_api_v20.py +++ b/testing/functest_api_v20.py @@ -854,6 +854,24 @@ class TestFuncApiV20(): assert plugin.history[0]['note'] == self.ref_result_note assert plugin.history[0]['testcase']['name'] == self.ref_testcase_name + def test_create_result_custom_outcome(self): + self.test_create_group() + self.test_create_testcase() + ref_result = copy.deepcopy(self.ref_result) + ref_result['outcome'] = 'AMAZING' + + r, data = self.helper_create_result(outcome='AMAZING') + + assert r.status_code == 201 + assert data == ref_result + + ref_result = copy.deepcopy(self.ref_result) + ref_result['outcome'] = 'SILLY' + + r, data = self.helper_create_result(outcome='SILLY') + + assert r.status_code == 400 + def test_get_outcomes_on_landing_page(self): r = self.app.get('/api/v2.0/') data = json.loads(r.data)