Tooling for converting coverage data into a SQL DB
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
5.5 KiB

# Copyright 2016 Hewlett Packard Enterprise Development LP
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslo_config import cfg
from sqlalchemy import create_engine
from sqlalchemy.engine.url import make_url
from sqlalchemy.orm import sessionmaker
import logging
from coverage2sql.db import models
CONF.register_cli_opt(cfg.BoolOpt('verbose', short='v', default=False,
help='Verbose output including logging of '
'SQL statements'))
DAY_SECONDS = 60 * 60 * 24
Session = None
engine = None
def setup():
global engine
db_uri = make_url(CONF.database.connection)
pool_size = CONF.database.max_pool_size
pool_recycle = CONF.database.idle_timeout
if db_uri.get_backend_name() == 'sqlite' or (not pool_size
and not pool_recycle):
engine = create_engine(db_uri)
engine = create_engine(db_uri,
global Session
Session = sessionmaker(bind=engine)
def get_session(autocommit=True, expire_on_commit=False):
"""Get a new sqlalchemy Session instance
:param bool autocommit: Enable autocommit mode for the session.
:param bool expire_on_commit: Expire the session on commit defaults False.
global Session
session = Session(autocommit=autocommit,
# if --verbose was specified, turn on SQL logging
# note that this is done after the session has been initialized so that
# we can override the default sqlalchemy logging
if CONF.get('verbose', False):
return session
def create_coverage(project_name, coverage_rate=0.0, rates=[],
report_time=None, test_type='py27',
coverage_metadata=None, session=None):
"""Create a new coverage record in the database.
This method is used to add a new coverage in the database.
It tracks the coverage history.
:param str project_name: project_name e.g. openstack/tempest
:param float coverage_rate: coverage_rate defaults to 0
:param datetime.Datetime report_time: when the coverage was collected
defaults to None
:param str test_type: test_type like a task name of tox e.g. py27
:param str coverage_metadata: metadata for more additional data
:param session: optional session object if one isn't provided a new session
will be acquired for the duration of this operation
:return: The coverage object stored in the DB
:rtype: coverage2sql.models.Coverage
coverage = models.Coverage()
coverage.project_name = project_name
coverage.coverage_rate = coverage_rate
coverage.test_type = test_type
coverage.coverage_metadata = coverage_metadata
if report_time:
report_time = report_time.replace(tzinfo=None)
report_time_microsecond = report_time.microsecond
report_time_microsecond = None
coverage.report_time = report_time
coverage.report_time_microsecond = report_time_microsecond
coverage.coverage_metadata = coverage_metadata
session = session or get_session()
with session.begin():
return coverage
def add_file_rates(coverage_id, rates=[], session=None):
"""Add rates a specific coverage.
This method is used to add rate records in the database.
It tracks the coverage history by individual files.
:param int coverage_id: coverage_id
:param list rates: rates dict list which has
e.g. [{'filename': 'foo', 'line-rate': '0.1'}, ...]
:param session: optional session object if one isn't provided a new session
will be acquired for the duration of this operation
:return: The list of created files objects
:rtype: coverage2sql.models.File
session = session or get_session()
files = []
with session.begin():
for r in rates:
f = models.File()
f.coverage_id = coverage_id
f.filename = r['filename']
f.line_rate = r['line-rate']
return files
def get_coverage(project_name=None, test_type=None, session=None):
"""Get new coverage records in the database.
This method is used to get coverage records in the database. The records
are order by report_time.
:param str project_name: project_name e.g. openstack/tempest
:param str test_type: test_type e.g. py35
:return: The coverage objects from the DB
:rtype: list
session = session or get_session()
covs = session.query(models.Coverage)
if project_name:
covs = covs.filter_by(project_name=project_name)
if test_type:
covs = covs.filter_by(test_type=test_type)
return covs.order_by(models.Coverage.report_time).all()