Support DB reporting for test_timetest.py (#2359)

This commit is contained in:
Vitaliy Urusovskij 2020-10-01 08:39:19 +03:00 committed by GitHub
parent 9ba4db7eae
commit c8530201dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 94 additions and 7 deletions

View File

@ -16,37 +16,65 @@ This plugin adds the following command-line options:
"""
# pylint:disable=import-error
import sys
import pytest
from pathlib import Path
import yaml
import hashlib
from test_runner.utils import expand_env_vars
from test_runner.utils import expand_env_vars, upload_timetest_data, \
DATABASE, DB_COLLECTIONS
# -------------------- CLI options --------------------
def pytest_addoption(parser):
"""Specify command-line options for all plugins"""
parser.addoption(
test_args_parser = parser.getgroup("timetest test run")
test_args_parser.addoption(
"--test_conf",
type=Path,
help="Path to test config",
help="path to a test config",
default=Path(__file__).parent / "test_config.yml"
)
parser.addoption(
test_args_parser.addoption(
"--exe",
required=True,
dest="executable",
type=Path,
help="Path to a timetest binary to execute",
help="path to a timetest binary to execute"
)
parser.addoption(
test_args_parser.addoption(
"--niter",
type=int,
help="Number of iterations to run executable and aggregate results",
help="number of iterations to run executable and aggregate results",
default=3
)
# TODO: add support of --mo, --omz etc. required for OMZ support
db_args_parser = parser.getgroup("timetest database use")
db_args_parser.addoption(
'--db_submit',
metavar="RUN_ID",
type=str,
help='submit results to the database. ' \
'`RUN_ID` should be a string uniquely identifying the run' \
' (like Jenkins URL or time)'
)
is_db_used = db_args_parser.parser.parse_known_args(sys.argv).db_submit
db_args_parser.addoption(
'--db_url',
type=str,
required=is_db_used,
help='MongoDB URL in a form "mongodb://server:port"'
)
db_args_parser.addoption(
'--db_collection',
type=str,
required=is_db_used,
help='collection name in "{}" database'.format(DATABASE),
choices=DB_COLLECTIONS
)
@pytest.fixture(scope="session")
@ -96,3 +124,47 @@ def pytest_make_parametrize_id(config, val, argname):
values = list(get_dict_values(val))
return "-".join(["_".join([key, val]) for key, val in zip(keys, values)])
@pytest.mark.hookwrapper
def pytest_runtest_makereport(item, call):
"""Pytest hook for report preparation.
Submit tests' data to a database.
"""
FIELDS_FOR_ID = ['timetest', 'model', 'device', 'niter', 'run_id']
FIELDS_FOR_SUBMIT = FIELDS_FOR_ID + ['_id', 'test_name',
'results', 'status', 'error_msg']
run_id = item.config.getoption("db_submit")
db_url = item.config.getoption("db_url")
db_collection = item.config.getoption("db_collection")
if not (run_id and db_url and db_collection):
yield
return
data = item.funcargs.copy()
data["timetest"] = data.pop("executable").stem
data.update({key: val for key, val in data["instance"].items()})
data['run_id'] = run_id
data['_id'] = hashlib.sha256(
''.join([str(data[key]) for key in FIELDS_FOR_ID]).encode()).hexdigest()
data["test_name"] = item.name
data["results"] = {}
data["status"] = "not_finished"
data["error_msg"] = ""
data = {field: data[field] for field in FIELDS_FOR_SUBMIT}
report = (yield).get_result()
if call.when in ["setup", "call"]:
if call.when == "call":
if not report.passed:
data["status"] = "failed"
data["error_msg"] = report.longrepr.reprcrash.message
else:
data["status"] = "passed"
upload_timetest_data(data, db_url, db_collection)

View File

@ -40,3 +40,5 @@ def test_timetest(instance, executable, niter):
}
retcode, aggr_stats = run_timetest(exe_args, log=logging)
assert retcode == 0, "Run of executable failed"
instance["results"] = aggr_stats # append values to report to DB

View File

@ -4,6 +4,11 @@
"""Utility module."""
import os
from pymongo import MongoClient
# constants
DATABASE = 'timetests' # database name for timetests results
DB_COLLECTIONS = ["commit", "nightly", "weekly"]
def expand_env_vars(obj):
@ -18,3 +23,11 @@ def expand_env_vars(obj):
else:
obj = os.path.expandvars(obj)
return obj
def upload_timetest_data(data, db_url, db_collection):
""" Upload timetest data to database
"""
client = MongoClient(db_url)
collection = client[DATABASE][db_collection]
collection.replace_one({'_id': data['_id']}, data, upsert=True)