Commit 213f7d84 authored by Luis Araujo's avatar Luis Araujo

Add support to save manual tests results into the database

This commit adds the initial support to save manual tests results
using the manual tests report forms into the database.

It also creates two new migrations for the DB in order to adapt the
database model better for manual tests results.
Signed-off-by: Luis Araujo's avatarLuis Araujo <luis.araujo@collabora.co.uk>
parent f99a502f
"""Add the Notes column to test cases and Path can be null
A Notes column will be used initially by manual test cases, later
this column can be mandatory and be used by automated test cases too.
The Path column can be Null now as manual test cases lack this field.
Revision ID: 9c1069d8e46f
Revises: 2c0d66b35cdd
Create Date: 2019-07-02 08:38:19.597654
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '9c1069d8e46f'
down_revision = '2c0d66b35cdd'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('testcases', sa.Column('notes', sa.String(), nullable=True))
op.alter_column('testcases', 'path',
existing_type=sa.VARCHAR(),
nullable=True)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('testcases', 'path',
existing_type=sa.VARCHAR(),
nullable=False)
op.drop_column('testcases', 'notes')
# ### end Alembic commands ###
"""Image Type, Architecture and Deployment columns cannot be NULL
These values are mandatory in order to build the correct image-type ID.
Revision ID: b5d2d0ec9599
Revises: 9c1069d8e46f
Create Date: 2019-07-02 11:15:51.463237
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'b5d2d0ec9599'
down_revision = '9c1069d8e46f'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('jobs', 'image_architecture',
existing_type=sa.VARCHAR(),
nullable=False)
op.alter_column('jobs', 'image_deployment',
existing_type=sa.VARCHAR(),
nullable=False)
op.alter_column('jobs', 'image_type',
existing_type=sa.VARCHAR(),
nullable=False)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('jobs', 'image_type',
existing_type=sa.VARCHAR(),
nullable=True)
op.alter_column('jobs', 'image_deployment',
existing_type=sa.VARCHAR(),
nullable=True)
op.alter_column('jobs', 'image_architecture',
existing_type=sa.VARCHAR(),
nullable=True)
# ### end Alembic commands ###
......@@ -51,9 +51,9 @@ class Job(db.Model):
image_url = db.Column(db.String, nullable=False)
image_release = db.Column(db.String, nullable=False)
image_build = db.Column(db.String, nullable=False)
image_deployment = db.Column(db.String)
image_type = db.Column(db.String)
image_architecture = db.Column(db.String)
image_deployment = db.Column(db.String, nullable=False)
image_type = db.Column(db.String, nullable=False)
image_architecture = db.Column(db.String, nullable=False)
image_platform = db.Column(db.String)
exec_type = db.Column(db.String(80), nullable=False)
......@@ -73,12 +73,15 @@ class TestCase(db.Model):
job_id = db.Column(db.Integer, db.ForeignKey('jobs.id'), nullable=False)
suite = db.Column(db.String, nullable=False)
repository = db.Column(db.String, nullable=False)
path = db.Column(db.String, nullable=False)
path = db.Column(db.String)
commit_id = db.Column(db.String)
result = db.Column(db.String, nullable=False)
lava_result_id = db.Column(db.Integer)
lava_url = db.Column(db.String)
# Notes box.
notes = db.Column(db.String)
class Result(db.Model):
"""Results for test cases."""
......
......@@ -96,7 +96,10 @@ def generate_report(image_release, image_version,
job.visibility ])
for test_case in TestCase.query.filter_by(job_id=job.id).all():
lava_url = config['lava-url'] + test_case.lava_url
# Manual tests have no lava_url
lava_url = '' if job.exec_type == 'manual' else \
config['lava-url'] + test_case.lava_url
test_cases.setdefault(test_case.suite, {}) \
.update({ image_type_id: (test_case.result, lava_url) })
......
......@@ -73,3 +73,68 @@ def save_job(job, db):
logging.info('Saving into database job id: %d', job.id)
db.session.add(job_db)
db.session.commit()
def save_manual_job(manual_tests_results, db,
image_release, image_version,
image_type, image_deployment):
img_type, img_arch, visibility = image_type.split('-')
# Assume at the beginning this is updating a record.
update = True
# Search for an existing manual job record for this image type, and use that
# for updating record.
job_db = Job.query.filter_by(image_release = image_release,
image_build = image_version,
image_deployment = image_deployment,
image_type = img_type,
image_architecture = img_arch,
visibility = visibility,
exec_type = "manual").first()
# Otherwise create a new entry in the DB for this image-type.
# NOTE: 'image_url' is empty, this can be improved later.
if not job_db:
job_db = Job(image_release = image_release,
image_build = image_version,
image_type = img_type,
image_architecture = img_arch,
image_deployment = image_deployment,
visibility = visibility,
exec_type = "manual",
image_url = "")
# It's a new job entry, not a record update in DB.
update = False
for elem, value in manual_tests_results.items():
# Every 'test_case: result' element has a '__test_case_notes: notes'
# metadata entry, skip it and fetch that directly from the dictionary.
if elem.startswith('__') and elem.endswith('_notes'):
continue
test_case = elem
result = value
# Fetch Notes for this test case.
notes = manual_tests_results.get('__'+test_case+'_notes', '')
if update:
# Find existing test case record and update value.
for testcase_record in job_db.testcases:
if testcase_record.suite == test_case:
testcase_record.result = result
testcase_record.notes = notes
break;
else:
# NOTE: 'repository' is empty, this can be improved later.
job_db.testcases.append(TestCase(suite = test_case, result = result,
notes = notes, repository = ""))
# Always update Tester name.
job_db.tester = username
if not update:
logging.info('Saving manual job for image type: %s,release: %s,' \
'version: %s', image_type, image_release, image_version)
db.session.add(job_db)
else:
logging.info('Updating manual job record for image type: %s,release: %s,' \
'version: %s', image_type, image_release, image_version)
db.session.commit()
......@@ -43,7 +43,7 @@
<!-- Text Area -->
<div class="col text-right">
<textarea id="{{ test_case }}_notes" name="{{ test_case }}_notes" class="form-control" style="height: 40px; margin-bottom: 10px" placeholder="Notes ..."></textarea>
<textarea id="__{{ test_case }}_notes" name="__{{ test_case }}_notes" class="form-control" style="height: 40px; margin-bottom: 10px" placeholder="Notes ..."></textarea>
</div>
</div>
......
......@@ -35,7 +35,7 @@ from config import config
from taskmanager import connect_to_phab, process_results
from testobjects import TestJob
from models import db
from save import save_job
from save import save_job, save_manual_job
from pages import generate_index, generate_report, \
generate_select_image, generate_submit_report, generate_submitted
from forms import SelectImageForm, SubmitReportForm
......@@ -147,6 +147,14 @@ def submit_report(image_release, image_version, image_type, image_deployment):
form = SubmitReportForm()
if form.validate_on_submit():
# Convert the ImmutableDict from request.form into a plain dictionary.
manual_tests_results = request.form.to_dict()
# Remove csrf_token received by the form.
manual_tests_results.pop('csrf_token')
save_manual_job(manual_tests_results, db,
image_release, image_version,
image_type, image_deployment)
return generate_submitted()
# Generate a submit report page with only manual test cases for the specified
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment