Skip to content
This repository has been archived by the owner on Dec 27, 2021. It is now read-only.

Commit

Permalink
Improve test infrastructure.
Browse files Browse the repository at this point in the history
- Reanimate vmtests.
- Use waf to run tests.
- Run clang-tidy of C++ sources.
- Ensure noisicaä still runs on Ubuntu 16.04.
- Upgrade mypy to 0.720 and fix new issues.
  • Loading branch information
odahoda committed Aug 11, 2019
1 parent 55c999a commit 53ccc97
Show file tree
Hide file tree
Showing 193 changed files with 3,708 additions and 2,427 deletions.
2 changes: 1 addition & 1 deletion .dir-locals.el
Expand Up @@ -6,7 +6,7 @@

((nil . (
; Projetile
(projectile-project-test-cmd . "bin/runtests")
(projectile-project-test-cmd . "./waf test")

(pyvenv-workon . "noisicaa")

Expand Down
1 change: 1 addition & 0 deletions .projectile
@@ -1,2 +1,3 @@
-/build
-/venv
-/vmtests
2 changes: 2 additions & 0 deletions 3rdparty/typeshed/Cython.pyi
@@ -0,0 +1,2 @@
from typing import Any
def __getattr__(arrr: str) -> Any: ...
2 changes: 2 additions & 0 deletions 3rdparty/typeshed/asynctest.pyi
@@ -0,0 +1,2 @@
from typing import Any
def __getattr__(arrr: str) -> Any: ...
2 changes: 2 additions & 0 deletions 3rdparty/typeshed/coverage.pyi
@@ -0,0 +1,2 @@
from typing import Any
def __getattr__(arrr: str) -> Any: ...
2 changes: 2 additions & 0 deletions 3rdparty/typeshed/cpuinfo.pyi
@@ -0,0 +1,2 @@
from typing import Any
def __getattr__(arrr: str) -> Any: ...
2 changes: 2 additions & 0 deletions 3rdparty/typeshed/numpy.pyi
@@ -0,0 +1,2 @@
from typing import Any
def __getattr__(arrr: str) -> Any: ...
2 changes: 2 additions & 0 deletions 3rdparty/typeshed/xmlrunner.pyi
@@ -0,0 +1,2 @@
from typing import Any
def __getattr__(arrr: str) -> Any: ...
36 changes: 0 additions & 36 deletions bin/commit-check

This file was deleted.

2 changes: 1 addition & 1 deletion build_utils/waf/README.md
@@ -1,7 +1,7 @@
Custom `waf` tools used for building noisicaä.

Running pylint on these files (these files are used to build, they are not built themselves, so
`runtests` does not know about them):
`./waf test` does not know about them):

```bash
PYTHONPATH=$(ls -d .waf*) bin/runpylint build_utils.waf
Expand Down
126 changes: 126 additions & 0 deletions build_utils/waf/cpp.py
@@ -0,0 +1,126 @@
# -*- mode: python -*-

# @begin:license
#
# Copyright (c) 2015-2019, Benjamin Niemann <pink@odahoda.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# @end:license

import os
import os.path
import subprocess
import sys

from waflib.Configure import conf
from waflib.Task import Task
from waflib import Utils


def configure(ctx):
if ctx.env.ENABLE_TEST:
ctx.find_program('clang-tidy-8', var='CLANG_TIDY', mandatory=False)



class run_clang_tidy(Task):
always_run = True

def __str__(self):
return self.inputs[0].relpath()

def keyword(self):
return 'Lint (clang-tidy)'

@property
def mod_name(self):
mod_path = self.inputs[0].relpath()
assert mod_path.endswith('.cpp')
return '.'.join(os.path.splitext(mod_path)[0].split(os.sep))

@property
def test_id(self):
return self.mod_name + ':clang-tidy'

def run(self):
ctx = self.generator.bld

success = True
try:
argv = [
ctx.env.CLANG_TIDY[0],
'-quiet',
self.inputs[0].relpath(),
'--',
'-Wall',
'-I.', '-Ibuild',
]
argv += ['-I%s' % p for p in ctx.env.INCLUDES_LILV]
argv += ['-I%s' % p for p in ctx.env.INCLUDES_SUIL]
argv += ['-I%s' % p for p in ctx.env.INCLUDES_GTK2]
argv += ['-I%s' % p for p in ctx.env.INCLUDES]

env = dict(os.environ)

kw = {
'cwd': ctx.top_dir,
'env': env,
'stdout': subprocess.PIPE,
'stderr': subprocess.PIPE,
}

ctx.log_command(argv, kw)
_, out, _ = Utils.run_process(argv, kw)
out = out.strip()

if out:
success = False

out_path = os.path.join(ctx.TEST_RESULTS_PATH, self.mod_name, 'clang-tidy.log')
os.makedirs(os.path.dirname(out_path), exist_ok=True)
with open(out_path, 'wb') as fp:
fp.write(out)

if out and ctx.options.fail_fast:
sys.stderr.write(out.decode('utf-8'))
sys.stderr.write('\n')
raise RuntimeError("clang-tidy for %s failed." % self.mod_name)

except Exception:
success = False
raise

finally:
ctx.record_test_state(self.test_id, success)


@conf
def cpp_module(ctx, source, **kwargs):
assert source.endswith('.cpp')

source_node = ctx.path.make_node(source)

if (ctx.cmd == 'test'
and ctx.env.CLANG_TIDY
and ctx.should_run_test(source_node)
and {'all', 'lint', 'clang-tidy'} & ctx.TEST_TAGS):
with ctx.group(ctx.GRP_RUN_TESTS):
task = run_clang_tidy(env=ctx.env)
task.set_inputs(source_node)
if not ctx.options.only_failed or not ctx.get_test_state(task.test_id):
ctx.add_to_group(task)

return source_node
36 changes: 28 additions & 8 deletions build_utils/waf/csound.py
Expand Up @@ -21,9 +21,12 @@
# @end:license

import os.path
import subprocess
import sys

from waflib.Configure import conf
from waflib.Task import Task
from waflib import Utils


def configure(ctx):
Expand All @@ -41,24 +44,41 @@ def run(self):
ctx = self.generator.bld
cwd = ctx.srcnode

env = {
'LD_LIBRARY_PATH': os.path.join(ctx.env.VIRTUAL_ENV, 'lib'),
}

cmd = [
ctx.env.CSOUND[0],
'-o' + self.outputs[0].path_from(cwd),
self.inputs[0].path_from(cwd),
]
return self.exec_command(cmd, cwd=cwd, env=env)
kw = {
'cwd': cwd.abspath(),
'stdout': subprocess.PIPE,
'stderr': subprocess.STDOUT,
}
ctx.log_command(cmd, kw)
rc, out, _ = Utils.run_process(cmd, kw)
if rc:
sys.stderr.write(out.decode('utf-8'))
return rc


@conf
def rendered_csound(ctx, source):
def rendered_csound(ctx, source, install=None, install_to=None, chmod=0o644):
assert source.endswith('.csnd')

wav_path = os.path.splitext(source)[0] + '.wav'
target = ctx.path.get_bld().make_node(wav_path)

task = compile_csound(env=ctx.env)
task.set_inputs(ctx.path.find_resource(source))
wav_path = os.path.splitext(source)[0] + '.wav'
task.set_outputs(ctx.path.get_bld().make_node(wav_path))
task.set_outputs(target)
ctx.add_to_group(task)

if install is None:
install = ctx.in_group(ctx.GRP_BUILD_MAIN)

if install:
if install_to is None:
install_to = os.path.join(
ctx.env.DATADIR, target.parent.path_from(ctx.bldnode.make_node('data')))

ctx.install_files(install_to, target, chmod=chmod)
17 changes: 9 additions & 8 deletions build_utils/waf/cython.py
Expand Up @@ -90,7 +90,7 @@ def cy_module(ctx, source, use=None):
install_path=None,
)

if ctx.get_group_name(ctx.current_group) == 'noisicaa':
if ctx.in_group(ctx.GRP_BUILD_MAIN):
ctx.install_files(os.path.join(ctx.env.LIBDIR, mod.parent.relpath()), mod)

if pxd.exists():
Expand All @@ -99,14 +99,15 @@ def cy_module(ctx, source, use=None):
if pyi.exists():
ctx.static_file(pyi, install=False)

return mod


@conf
def cy_test(ctx, source, use=None):
def cy_test(ctx, source, use=None, **kwargs):
if not ctx.env.ENABLE_TEST:
return

old_grp = ctx.current_group
ctx.set_group('tests')
try:
ctx.cy_module(source, use=use)
finally:
ctx.set_group(old_grp)
with ctx.group(ctx.GRP_BUILD_TESTS):
target = ctx.cy_module(source, use=use)

ctx.add_py_test_runner(target, **kwargs)
3 changes: 1 addition & 2 deletions build_utils/waf/faust.py
Expand Up @@ -49,14 +49,13 @@ def faust_dsp(ctx, cls_name, source='processor.dsp'):
],
cls_name=cls_name)

if ctx.get_group_name(ctx.current_group) == 'noisicaa':
if ctx.in_group(ctx.GRP_BUILD_MAIN):
ctx.install_files(os.path.join(ctx.env.LIBDIR, json.parent.relpath()), json)

ctx.shlib(
target='noisicaa-builtin_nodes-%s-processor' % cls_name.lower(),
source='processor.cpp',
use=[
'NOISELIB',
'noisicaa-audioproc-public',
'noisicaa-host_system',
],
Expand Down
9 changes: 4 additions & 5 deletions build_utils/waf/install.py
Expand Up @@ -27,7 +27,6 @@
import pathlib
import shutil
import subprocess
import textwrap

import packaging.markers
import packaging.requirements
Expand Down Expand Up @@ -64,7 +63,7 @@ def install_runtime_pip_packages(ctx):
stdout=subprocess.PIPE, check=True)
installed_packages = {
packaging.utils.canonicalize_name(p['name']): (p['name'], p['version'])
for p in json.loads(p.stdout)}
for p in json.loads(p.stdout.decode('utf-8'))}

required_packages = set()

Expand Down Expand Up @@ -108,7 +107,7 @@ def install_runtime_pip_packages(ctx):
# File is not under site-packages.
continue

dest_path = os.path.join(ctx.env.LIBDIR, rel_path)
dest_path = os.path.join(ctx.env.LIBDIR, str(rel_path))

if not ctx.progress_bar:
Logs.info(
Expand All @@ -118,5 +117,5 @@ def install_runtime_pip_packages(ctx):

if not os.path.isdir(os.path.dirname(dest_path)):
os.makedirs(os.path.dirname(dest_path))
shutil.copyfile(src_path, dest_path)
shutil.copystat(src_path, dest_path)
shutil.copyfile(str(src_path), dest_path)
shutil.copystat(str(src_path), dest_path)
4 changes: 2 additions & 2 deletions build_utils/waf/model.py
Expand Up @@ -42,7 +42,7 @@ def run(self):
'--template', self.inputs[1].abspath(),
os.path.relpath(self.inputs[0].abspath(), ctx.top_dir),
]
return self.exec_command(cmd, cwd=ctx.top_dir, env={'PYTHONPATH': ctx.out_dir})
return self.exec_command(cmd, cwd=ctx.top_dir)


@conf
Expand All @@ -58,5 +58,5 @@ def model_description(
os.path.join(os.path.dirname(output), 'model.proto')))
ctx.add_to_group(task)

if ctx.get_group_name(ctx.current_group) == 'noisicaa':
if ctx.in_group(ctx.GRP_BUILD_MAIN):
ctx.install_files(os.path.join(ctx.env.LIBDIR, model_node.parent.relpath()), model_node)
4 changes: 3 additions & 1 deletion build_utils/waf/proto.py
Expand Up @@ -86,7 +86,7 @@ def py_proto(ctx, source):
task.set_outputs(ctx.path.get_bld().make_node(pyi_path))
ctx.add_to_group(task)

if ctx.get_group_name(ctx.current_group) == 'noisicaa':
if ctx.in_group(ctx.GRP_BUILD_MAIN):
ctx.install_files(os.path.join(ctx.env.LIBDIR, pb2_node.parent.relpath()), pb2_node)
ctx.install_files(os.path.join(ctx.env.LIBDIR, pb2c_node.parent.relpath()), pb2c_node)

Expand Down Expand Up @@ -132,3 +132,5 @@ def cpp_proto(ctx, source):
task.set_outputs(ctx.path.get_bld().make_node(
os.path.splitext(source)[0] + '.pb.h'))
ctx.add_to_group(task)

return os.path.splitext(source)[0] + '.pb.cc'

0 comments on commit 53ccc97

Please sign in to comment.