Merge branch 'mr/python-pre-commit-checkers-4' into 'master'

add pre-commit checks for python files

Closes #4

See merge request eng/toolchain/gnatcoll-db!2
This commit is contained in:
Vadim Godunko
2025-01-20 12:16:31 +00:00
9 changed files with 1390 additions and 891 deletions

9
.flake8 Normal file
View File

@@ -0,0 +1,9 @@
[flake8]
exclude = .git,__pycache__
filename = *.py
# See
# https://github.com/psf/black/blob/main/docs/guides/using_black_with_other_tools.md#flake8
# to understand the max-line-length and ignore settings.
max-line-length = 80
ignore = E203, E501, W503, B907
select = ANN,B,B9,BLK,C,E,F,T4,W

16
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,16 @@
repos:
- repo: https://github.com/psf/black
rev: 23.1.0
hooks:
- id: black
- repo: https://github.com/pycqa/flake8
rev: 6.0.0
hooks:
- id: flake8
additional_dependencies:
- flake8-bugbear
- flake8-builtins
- flake8-comprehensions
- flake8-docstrings
- flake8-rst-docstrings
- pygments

View File

@@ -11,46 +11,50 @@
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os, time
import time
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
# sys.path.insert(0, os.path.abspath('.'))
# -- General configuration -----------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx_rtd_theme']
extensions = ["sphinx_rtd_theme"]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
templates_path = ["_templates"]
# The suffix of source filenames.
source_suffix = '.rst'
source_suffix = ".rst"
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
master_doc = "index"
def get_copyright():
return u'2007-%s, AdaCore' % time.strftime("%Y")
return "2007-%s, AdaCore" % time.strftime("%Y")
# General information about the project.
project = u'GNATcoll - Database packages'
project = "GNATcoll - Database packages"
copyright = get_copyright()
def get_version():
"""Extract the version from configure.in"""
with open("../version_information", "r") as f:
return f.read().strip()
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
@@ -62,37 +66,37 @@ release = version
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']
exclude_patterns = ["_build"]
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = None
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# modindex_common_prefix = []
rst_epilog = """
.. |Tip| image:: tip.png
@@ -110,7 +114,7 @@ rst_epilog = """
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'sphinx_rtd_theme'
html_theme = "sphinx_rtd_theme"
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
@@ -122,52 +126,52 @@ html_theme_options = {
}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
html_logo = 'adacore-logo-white.png'
html_logo = "adacore-logo-white.png"
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
html_favicon = 'favicon.ico'
html_favicon = "favicon.ico"
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_static_path = ["_static"]
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# html_split_index = False
# If true, links to the reST sources are added to the pages.
html_show_sourcelink = False
@@ -176,57 +180,62 @@ html_show_sourcelink = False
html_show_sphinx = False
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'GNATColldoc'
htmlhelp_basename = "GNATColldoc"
# -- Options for LaTeX output --------------------------------------------------
# The paper size ('letter' or 'a4').
#latex_paper_size = 'letter'
# latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt'
# latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'gnatcoll-db.tex', u'GNATCOLL Documentation - Database packages',
u'AdaCore', 'manual'),
(
"index",
"gnatcoll-db.tex",
"GNATCOLL Documentation - Database packages",
"AdaCore",
"manual",
),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# latex_show_urls = False
# Additional stuff for the LaTeX preamble.
#latex_preamble = ''
# latex_preamble = ''
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# latex_domain_indices = True
# -- Options for manual page output --------------------------------------------
@@ -234,46 +243,51 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'gnatcoll-db', u'GNATcoll Documentation - Database packages',
[u'AdaCore'], 1)
(
"index",
"gnatcoll-db",
"GNATcoll Documentation - Database packages",
["AdaCore"],
1,
)
]
# -- Options for Epub output ---------------------------------------------------
# Bibliographic Dublin Core info.
epub_title = u'GNATColl'
epub_author = u'AdaCore'
epub_publisher = u'AdaCore'
epub_title = "GNATColl"
epub_author = "AdaCore"
epub_publisher = "AdaCore"
epub_copyright = copyright
# The language of the text. It defaults to the language option
# or en if the language is not set.
#epub_language = ''
# epub_language = ''
# The scheme of the identifier. Typical schemes are ISBN or URL.
#epub_scheme = ''
# epub_scheme = ''
# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#epub_identifier = ''
# epub_identifier = ''
# A unique identification for the text.
#epub_uid = ''
# epub_uid = ''
# HTML files that should be inserted before the pages created by sphinx.
# The format is a list of tuples containing the path and title.
#epub_pre_files = []
# epub_pre_files = []
# HTML files shat should be inserted after the pages created by sphinx.
# The format is a list of tuples containing the path and title.
#epub_post_files = []
# epub_post_files = []
# A list of files that should not be packed into the epub file.
#epub_exclude_files = []
# epub_exclude_files = []
# The depth of the table of contents in toc.ncx.
#epub_tocdepth = 3
# epub_tocdepth = 3
# Allow duplicate toc entries.
#epub_tocdup = True
# epub_tocdup = True

View File

@@ -4,20 +4,18 @@ import os
import os.path
import re
pkg_re = re.compile("^(private)?\s*package\s*(\S+)")
pkg_re = re.compile(r"^(private)?\s*package\s*(\S+)")
def recursive_ls(dir):
"""Return the list of ads files in dir and its subdirs"""
result = set()
for f in os.listdir(dir):
if f.endswith(".ads") \
and f.startswith("gnatcoll-"):
if f.endswith(".ads") and f.startswith("gnatcoll-"):
private = False
pkg = ""
for l in file(os.path.join(dir, f)).readlines():
m = pkg_re.search(l)
for line in open(os.path.join(dir, f)).readlines():
m = pkg_re.search(line)
if m:
private = m.group(1)
pkg = m.group(2)
@@ -31,14 +29,17 @@ def recursive_ls(dir):
return result
list = recursive_ls("..")
out = file("help_gnatcoll-db.py", "wb")
out.write("""XML = r'''<?xml version="1.0"?>
out = open("help_gnatcoll-db.py", "w")
out.write(
"""XML = r'''<?xml version="1.0"?>
<GPS>
""")
"""
)
for pkg, f in sorted(list):
if '__' in f:
if "__" in f:
# An internal package with a specific naming scheme
continue
@@ -46,23 +47,28 @@ for pkg, f in sorted(list):
# Do we have a submenu ?
in_front = False
for pkg2, b in list:
for _, b in list:
if b.startswith(f + "-"):
item = menu[menu.rfind("/") + 1:]
item = menu[menu.rfind("/") + 1 :]
menu = menu + "/&lt;" + item + "&gt;"
break
out.write(""" <documentation_file>
out.write(
""" <documentation_file>
<shell>Editor.edit "%(file)s.ads"</shell>
<descr>%(package)s</descr>
<menu>/Help/%(menu)s</menu>
<category>GNAT Components Collection</category>
</documentation_file>
""" % {"file": f, "menu": menu, "package": pkg})
"""
% {"file": f, "menu": menu, "package": pkg}
)
out.write("""</GPS>'''
out.write(
"""</GPS>'''
import GPS
GPS.parse_xml(XML)
""")
"""
)
out.close()

File diff suppressed because it is too large Load Diff

View File

@@ -6,34 +6,33 @@ import os
import logging
TESTSUITE_ROOT_DIR = os.path.dirname(
os.path.dirname(os.path.abspath(__file__)))
TESTSUITE_ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
GNATCOLL_ROOT_DIR = os.path.dirname(TESTSUITE_ROOT_DIR)
# List of default components. By default postgres is not included
COMPONENTS = ['sql', 'sqlite', 'xref', 'gnatinspect',
'gnatcoll_db2ada', 'gnatcoll_sqlite2ada']
COMPONENTS = [
"sql",
"sqlite",
"xref",
"gnatinspect",
"gnatcoll_db2ada",
"gnatcoll_sqlite2ada",
]
# Properties to help compilation, and dependency resolution
COMPONENT_PROPERTIES = {
'xref': {
'requires': ['sqlite']},
'gnatinspect': {
'is_bin': True,
'requires': ['xref']},
'sql': {},
'gnatcoll_db2ada': {
'is_bin': True,
'requires': ['sql']},
'gnatcoll_sqlite2ada': {
'is_bin': True,
'component': 'gnatcoll_db2ada',
'make_args': ['DB_BACKEND=sqlite'],
'requires': ['sqlite']},
'postgres': {
'requires': ['sql']},
'sqlite': {
'requires': ['sql']}
"xref": {"requires": ["sqlite"]},
"gnatinspect": {"is_bin": True, "requires": ["xref"]},
"sql": {},
"gnatcoll_db2ada": {"is_bin": True, "requires": ["sql"]},
"gnatcoll_sqlite2ada": {
"is_bin": True,
"component": "gnatcoll_db2ada",
"make_args": ["DB_BACKEND=sqlite"],
"requires": ["sqlite"],
},
"postgres": {"requires": ["sql"]},
"sqlite": {"requires": ["sql"]},
}
@@ -49,14 +48,15 @@ def get_components_closure(components):
current_len = len(result)
while True:
for component in list(result):
assert component in COMPONENT_PROPERTIES, \
assert component in COMPONENT_PROPERTIES, (
"invalid component: %s" % component
)
properties = COMPONENT_PROPERTIES[component]
result |= set(properties.get('requires', set()))
result |= set(properties.get("requires", set()))
if len(result) == current_len:
break
current_len = len(result)
logging.info('Component closure: %s', ",".join(result))
logging.info("Component closure: %s", ",".join(result))
return list(result)
@@ -70,59 +70,61 @@ def make_gnatcoll_for_gcov(work_dir, components):
:rtype: (str, str, str)
:raise AssertError: in case compilation of installation fails
"""
logging.info('Compiling gnatcoll with gcov instrumentation')
build_dir = os.path.join(work_dir, 'build')
install_dir = os.path.join(work_dir, 'install')
logging.info("Compiling gnatcoll with gcov instrumentation")
build_dir = os.path.join(work_dir, "build")
install_dir = os.path.join(work_dir, "install")
mkdir(build_dir)
mkdir(install_dir)
# Add the resulting library into the GPR path
Env().add_search_path('GPR_PROJECT_PATH',
os.path.join(install_dir, 'share', 'gpr'))
Env().add_path(os.path.join(install_dir, 'bin'))
Env().add_search_path("GPR_PROJECT_PATH", os.path.join(install_dir, "share", "gpr"))
Env().add_path(os.path.join(install_dir, "bin"))
for component in components:
logging.info('Compiling: %s', component)
gcov_options = '-cargs -fprofile-arcs -ftest-coverage -gargs'
component_dir = COMPONENT_PROPERTIES[component].get('component',
component)
logging.info("Compiling: %s", component)
gcov_options = "-cargs -fprofile-arcs -ftest-coverage -gargs"
component_dir = COMPONENT_PROPERTIES[component].get("component", component)
if COMPONENT_PROPERTIES[component].get('is_bin'):
gcov_options += ' -largs -lgcov -gargs'
if COMPONENT_PROPERTIES[component].get("is_bin"):
gcov_options += " -largs -lgcov -gargs"
make_gnatcoll_cmd = [
'make', '-f',
os.path.join(GNATCOLL_ROOT_DIR, component_dir, 'Makefile'),
'BUILD=DEBUG',
'GPRBUILD_OPTIONS=%s' % gcov_options,
'ENABLE_SHARED=no'] + \
COMPONENT_PROPERTIES[component].get('make_args', [])
"make",
"-f",
os.path.join(GNATCOLL_ROOT_DIR, component_dir, "Makefile"),
"BUILD=DEBUG",
"GPRBUILD_OPTIONS=%s" % gcov_options,
"ENABLE_SHARED=no",
] + COMPONENT_PROPERTIES[component].get("make_args", [])
p = Run(make_gnatcoll_cmd, cwd=build_dir)
assert p.status == 0, "gnatcoll build failed:\n%s" % p.out
p = Run(make_gnatcoll_cmd + ['prefix=%s' % install_dir, 'install'],
cwd=build_dir)
p = Run(
make_gnatcoll_cmd + ["prefix=%s" % install_dir, "install"], cwd=build_dir
)
assert p.status == 0, "gnatcoll installation failed:\n%s" % p.out
return (os.path.join(install_dir, 'share', 'gpr'),
os.path.join(install_dir, 'include'),
os.path.join(build_dir, 'obj', 'static'))
return (
os.path.join(install_dir, "share", "gpr"),
os.path.join(install_dir, "include"),
os.path.join(build_dir, "obj", "static"),
)
# Associate a project file basename with a component
PROJECT = {
'sql': 'gnatcoll_sql',
'sqlite': 'gnatcoll_sqlite'}
PROJECT = {"sql": "gnatcoll_sql", "sqlite": "gnatcoll_sqlite"}
def gprbuild(driver,
project_file=None,
cwd=None,
gcov=False,
components=None,
scenario=None,
**kwargs):
def gprbuild(
driver,
project_file=None,
cwd=None,
gcov=False,
components=None,
scenario=None,
**kwargs
):
"""Launch gprbuild.
:param project_file: project file to compile. If None, we looks first for
@@ -144,37 +146,37 @@ def gprbuild(driver,
components = []
if cwd is None:
cwd = driver.test_env['working_dir']
cwd = driver.test_env["working_dir"]
mkdir(cwd)
if project_file is None:
project_file = os.path.join(driver.test_env['test_dir'],
'test.gpr')
project_file = os.path.join(driver.test_env["test_dir"], "test.gpr")
if not os.path.isfile(project_file):
project_file = os.path.join(cwd, 'test.gpr')
with open(os.path.join(TESTSUITE_ROOT_DIR, 'support',
'test.gpr'), 'r') as fd:
project_file = os.path.join(cwd, "test.gpr")
with open(
os.path.join(TESTSUITE_ROOT_DIR, "support", "test.gpr"), "r"
) as fd:
content = fd.read()
with open(project_file, 'w') as fd:
with open(project_file, "w") as fd:
for component in components:
project = PROJECT.get(component)
if project is not None:
fd.write('with "%s";\n' % project)
fd.write(content)
scenario['TEST_SOURCES'] = driver.test_env['test_dir']
scenario['SUPPORT_SOURCES'] = os.path.join(TESTSUITE_ROOT_DIR, 'support')
scenario["TEST_SOURCES"] = driver.test_env["test_dir"]
scenario["SUPPORT_SOURCES"] = os.path.join(TESTSUITE_ROOT_DIR, "support")
gprbuild_cmd = [
'gprbuild', '--relocate-build-tree', '-p', '-P', project_file]
gprbuild_cmd = ["gprbuild", "--relocate-build-tree", "-p", "-P", project_file]
for k, v in scenario.iteritems():
gprbuild_cmd.append('-X%s=%s' % (k, v))
gprbuild_cmd.append("-X%s=%s" % (k, v))
if gcov:
gprbuild_cmd += ['-largs', '-lgcov', '-cargs',
'-fprofile-arcs', '-ftest-coverage']
check_call(
driver,
gprbuild_cmd,
cwd=cwd,
**kwargs)
gprbuild_cmd += [
"-largs",
"-lgcov",
"-cargs",
"-fprofile-arcs",
"-ftest-coverage",
]
check_call(driver, gprbuild_cmd, cwd=cwd, **kwargs)
# If we get there it means the build succeeded.
return True

View File

@@ -32,31 +32,33 @@ class BasicTestDriver(TestDriver):
:param dag: tree of test fragment to amend
:type dag: e3.collection.dag.DAG
"""
self.add_fragment(dag, 'build')
self.add_fragment(dag, 'check_run', after=['build'])
self.add_fragment(dag, "build")
self.add_fragment(dag, "check_run", after=["build"])
if 'test_exe' not in self.test_env:
self.test_env['test_exe'] = 'obj/test'
if "test_exe" not in self.test_env:
self.test_env["test_exe"] = "obj/test"
def build(self, previous_values):
"""Build fragment."""
return gprbuild(self, gcov=self.env.gcov,
components=self.env.components)
return gprbuild(self, gcov=self.env.gcov, components=self.env.components)
def check_run(self, previous_values):
"""Check status fragment."""
if not previous_values['build']:
if not previous_values["build"]:
return
for data in self.test_env.get('data', []):
cp(os.path.join(self.test_env['test_dir'], data),
self.test_env['working_dir'], recursive=True)
for data in self.test_env.get("data", []):
cp(
os.path.join(self.test_env["test_dir"], data),
self.test_env["working_dir"],
recursive=True,
)
process = check_call(
self,
[os.path.join(self.test_env['working_dir'],
self.test_env['test_exe'])])
if '<=== TEST PASSED ===>' not in process.out:
[os.path.join(self.test_env["working_dir"], self.test_env["test_exe"])],
)
if "<=== TEST PASSED ===>" not in process.out:
self.result.set_status(TestStatus.FAIL)
else:
self.result.set_status(TestStatus.PASS)

View File

@@ -43,37 +43,45 @@ class DB2AdaTestDriver(TestDriver):
:param dag: tree of test fragment to amend
:type dag: e3.collection.dag.DAG
"""
self.add_fragment(dag, 'db2ada')
self.add_fragment(dag, 'build', after=['db2ada'])
self.add_fragment(dag, 'check_run', after=['build'])
self.add_fragment(dag, "db2ada")
self.add_fragment(dag, "build", after=["db2ada"])
self.add_fragment(dag, "check_run", after=["build"])
if 'test_exe' not in self.test_env:
self.test_env['test_exe'] = 'obj/test'
if "test_exe" not in self.test_env:
self.test_env["test_exe"] = "obj/test"
def db2ada(self, previous_values):
"""Run db2ada."""
mkdir(self.test_env['working_dir'])
mkdir(self.test_env["working_dir"])
db2ada_args = []
db2ada = 'gnatcoll_db2ada'
db2ada = "gnatcoll_db2ada"
# If necessary initialize an sqlite database
if 'sqlite_db' in self.test_env:
check_call(self,
['sqlite3', 'db.db', '-cmd',
".read %s" % os.path.join(self.test_env['test_dir'],
self.test_env['sqlite_db'])],
input="|")
db2ada = 'gnatcoll_sqlite2ada'
if "sqlite_db" in self.test_env:
check_call(
self,
[
"sqlite3",
"db.db",
"-cmd",
".read %s"
% os.path.join(
self.test_env["test_dir"], self.test_env["sqlite_db"]
),
],
input="|",
)
db2ada = "gnatcoll_sqlite2ada"
db2ada_args.append(
'-dbname=%s' % os.path.join(self.test_env['working_dir'],
'db.db'))
"-dbname=%s" % os.path.join(self.test_env["working_dir"], "db.db")
)
# Compute db2ada arguments
for value in self.test_env.get('db2ada', []):
if value.startswith('-dbmodel='):
dbmodel = value.split('=', 1)[1]
dbmodel = os.path.join(self.test_env['test_dir'], dbmodel)
db2ada_args.append('-dbmodel=%s' % dbmodel)
for value in self.test_env.get("db2ada", []):
if value.startswith("-dbmodel="):
dbmodel = value.split("=", 1)[1]
dbmodel = os.path.join(self.test_env["test_dir"], dbmodel)
db2ada_args.append("-dbmodel=%s" % dbmodel)
else:
db2ada_args.append(value)
@@ -81,23 +89,25 @@ class DB2AdaTestDriver(TestDriver):
def build(self, previous_values):
"""Build fragment."""
return gprbuild(self, gcov=self.env.gcov,
components=self.env.components)
return gprbuild(self, gcov=self.env.gcov, components=self.env.components)
def check_run(self, previous_values):
"""Check status fragment."""
if not previous_values['build']:
if not previous_values["build"]:
return
for data in self.test_env.get('data', []):
cp(os.path.join(self.test_env['test_dir'], data),
self.test_env['working_dir'], recursive=True)
for data in self.test_env.get("data", []):
cp(
os.path.join(self.test_env["test_dir"], data),
self.test_env["working_dir"],
recursive=True,
)
process = check_call(
self,
[os.path.join(self.test_env['working_dir'],
self.test_env['test_exe'])])
if '<=== TEST PASSED ===>' not in process.out:
[os.path.join(self.test_env["working_dir"], self.test_env["test_exe"])],
)
if "<=== TEST PASSED ===>" not in process.out:
self.result.set_status(TestStatus.FAIL)
else:
self.result.set_status(TestStatus.PASS)

View File

@@ -1,7 +1,11 @@
#!/usr/bin/env python
from drivers import (make_gnatcoll_for_gcov,
TESTSUITE_ROOT_DIR, COMPONENTS,
COMPONENT_PROPERTIES, get_components_closure)
from drivers import (
make_gnatcoll_for_gcov,
TESTSUITE_ROOT_DIR,
COMPONENTS,
COMPONENT_PROPERTIES,
get_components_closure,
)
from drivers.basic import BasicTestDriver
from drivers.db2ada import DB2AdaTestDriver
from e3.testsuite import Testsuite
@@ -14,35 +18,35 @@ import logging
class MyTestsuite(Testsuite):
CROSS_SUPPORT = True
TEST_SUBDIR = 'tests'
DRIVERS = {
'db2ada': DB2AdaTestDriver,
'default': BasicTestDriver}
TEST_SUBDIR = "tests"
DRIVERS = {"db2ada": DB2AdaTestDriver, "default": BasicTestDriver}
def add_options(self):
self.main.argument_parser.add_argument(
'--gcov',
"--gcov",
help="compute testsuite coverage of gnatcoll",
default=False,
action="store_true")
action="store_true",
)
self.main.argument_parser.add_argument(
'--components',
"--components",
help="list of component to test in %s (default: %s)"
% (",".join(COMPONENT_PROPERTIES.keys()),
",".join(COMPONENTS)),
default=','.join(COMPONENTS))
% (",".join(COMPONENT_PROPERTIES.keys()), ",".join(COMPONENTS)),
default=",".join(COMPONENTS),
)
def tear_up(self):
logging.info('running testsuite for components: %s' %
self.main.args.components)
logging.info("running testsuite for components: %s" % self.main.args.components)
self.env.gcov = self.main.args.gcov
self.env.components = get_components_closure(
self.main.args.components.split(','))
self.main.args.components.split(",")
)
self.env.enable_cleanup = self.main.args.enable_cleanup
if self.main.args.gcov:
work_dir = os.path.join(TESTSUITE_ROOT_DIR, 'gcov')
work_dir = os.path.join(TESTSUITE_ROOT_DIR, "gcov")
gpr_dir, src_dir, obj_dir = make_gnatcoll_for_gcov(
work_dir, self.env.components)
work_dir, self.env.components
)
self.env.gnatcoll_gpr_dir = gpr_dir
self.env.gnatcoll_src_dir = src_dir
self.env.gnatcoll_obj_dir = obj_dir
@@ -53,33 +57,36 @@ class MyTestsuite(Testsuite):
# We need to call gcov on gcda present both in gnatcoll itself and
# tests (for generics coverage).
gcda_files = \
find(os.path.join(self.env.gnatcoll_obj_dir), '*.gcda') + \
find(os.path.join(self.env.working_dir), '*.gcda')
mkdir(os.path.join(wd, 'gcov', 'results'))
gcr = os.path.join(wd, 'gcov', 'results')
Run(['gcov'] + gcda_files,
cwd=os.path.join(wd, 'gcov', 'results'))
gcda_files = find(os.path.join(self.env.gnatcoll_obj_dir), "*.gcda") + find(
os.path.join(self.env.working_dir), "*.gcda"
)
mkdir(os.path.join(wd, "gcov", "results"))
gcr = os.path.join(wd, "gcov", "results")
Run(["gcov"] + gcda_files, cwd=os.path.join(wd, "gcov", "results"))
total_sources = 0
total_covered = 0
for source_file in find(self.env.gnatcoll_src_dir, '*.ad[sb]'):
for source_file in find(self.env.gnatcoll_src_dir, "*.ad[sb]"):
base_file = os.path.basename(source_file)
if not os.path.isfile(os.path.join(gcr, base_file + '.gcov')):
if not os.path.isfile(os.path.join(gcr, base_file + ".gcov")):
total = 1
covered = 0
with open(source_file) as fd:
total = len([line for line in fd
if line.strip() and
not re.match(r' *--', line)])
total = len(
[
line
for line in fd
if line.strip() and not re.match(r" *--", line)
]
)
else:
with open(os.path.join(gcr, base_file + '.gcov')) as fd:
with open(os.path.join(gcr, base_file + ".gcov")) as fd:
total = 0
covered = 0
for line in fd:
if re.match(r' *-:', line):
if re.match(r" *-:", line):
pass
elif re.match(r' *[#=]{5}:', line):
elif re.match(r" *[#=]{5}:", line):
total += 1
else:
total += 1
@@ -87,26 +94,30 @@ class MyTestsuite(Testsuite):
total_sources += total
total_covered += covered
logging.info('%6.2f %% %8d/%-8d %s',
float(covered) * 100.0 / float(total),
covered,
total,
os.path.basename(source_file))
logging.info(
"%6.2f %% %8d/%-8d %s",
float(covered) * 100.0 / float(total),
covered,
total,
os.path.basename(source_file),
)
logging.info('%6.2f %% %8d/%-8d %s',
float(total_covered) * 100.0 / float(total_sources),
total_covered,
total_sources,
'TOTAL')
logging.info(
"%6.2f %% %8d/%-8d %s",
float(total_covered) * 100.0 / float(total_sources),
total_covered,
total_sources,
"TOTAL",
)
super(MyTestsuite, self).tear_down()
@property
def default_driver(self):
return 'default'
return "default"
if __name__ == '__main__':
if __name__ == "__main__":
suite = MyTestsuite(os.path.dirname(__file__))
suite.testsuite_main()
for k, v in suite.test_status_counters.iteritems():
print '%-24s: %d' % (k, v)
print("%-24s: %d" % (k, v))