Skip to content
Permalink
Browse files

Improve test infrastructure.

- 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 53ccc97183a04c96a24c06f1c0eb90a05af6a1fe
Showing with 3,708 additions and 2,427 deletions.
  1. +1 −1 .dir-locals.el
  2. +1 −0 .projectile
  3. +2 −0 3rdparty/typeshed/Cython.pyi
  4. +2 −0 3rdparty/typeshed/asynctest.pyi
  5. +2 −0 3rdparty/typeshed/coverage.pyi
  6. +2 −0 3rdparty/typeshed/cpuinfo.pyi
  7. +2 −0 3rdparty/typeshed/numpy.pyi
  8. +2 −0 3rdparty/typeshed/xmlrunner.pyi
  9. +0 −36 bin/commit-check
  10. +1 −1 build_utils/waf/README.md
  11. +126 −0 build_utils/waf/cpp.py
  12. +28 −8 build_utils/waf/csound.py
  13. +9 −8 build_utils/waf/cython.py
  14. +1 −2 build_utils/waf/faust.py
  15. +4 −5 build_utils/waf/install.py
  16. +2 −2 build_utils/waf/model.py
  17. +3 −1 build_utils/waf/proto.py
  18. +292 −9 build_utils/waf/python.py
  19. +8 −3 build_utils/waf/static.py
  20. +1 −1 build_utils/waf/svg.py
  21. +332 −0 build_utils/waf/test.py
  22. +73 −16 build_utils/waf/virtenv.py
  23. +29 −0 data/icons/placeholders/dialog-warning.svg
  24. +13 −0 data/icons/placeholders/document-new.svg
  25. +13 −0 data/icons/placeholders/document-open.svg
  26. +18 −0 data/icons/placeholders/document-save.svg
  27. +15 −0 data/icons/placeholders/edit-clear.svg
  28. +7 −0 data/icons/placeholders/edit-delete.svg
  29. +15 −0 data/icons/placeholders/edit-find.svg
  30. +13 −0 data/icons/placeholders/edit-select-all.svg
  31. +17 −0 data/icons/placeholders/edit-select.svg
  32. +17 −0 data/icons/placeholders/go-next.svg
  33. +17 −0 data/icons/placeholders/go-previous.svg
  34. +3 −0 data/icons/placeholders/icons.license
  35. +1 −0 data/icons/placeholders/icons.readme
  36. +13 −0 data/icons/placeholders/list-add.svg
  37. +10 −0 data/icons/placeholders/list-remove.svg
  38. +18 −0 data/icons/placeholders/media-playback-pause.svg
  39. +18 −0 data/icons/placeholders/media-playback-start.svg
  40. +17 −0 data/icons/placeholders/media-playlist-repeat.svg
  41. +22 −0 data/icons/placeholders/media-record.svg
  42. +18 −0 data/icons/placeholders/media-seek-backward.svg
  43. +18 −0 data/icons/placeholders/media-seek-forward.svg
  44. +18 −0 data/icons/placeholders/media-skip-backward.svg
  45. +18 −0 data/icons/placeholders/media-skip-forward.svg
  46. +6 −0 data/icons/placeholders/window-close.svg
  47. +13 −0 data/icons/placeholders/zoom-in.svg
  48. +14 −0 data/icons/placeholders/zoom-original.svg
  49. +13 −0 data/icons/placeholders/zoom-out.svg
  50. +6 −0 data/icons/wscript
  51. +0 −2 noisicaa/audioproc/audioproc.proto
  52. +1 −3 noisicaa/audioproc/engine/backend.cpp
  53. +4 −1 noisicaa/audioproc/engine/backend_null.cpp
  54. +8 −3 noisicaa/audioproc/engine/backend_portaudio.cpp
  55. +1 −0 noisicaa/audioproc/engine/backend_portaudio.h
  56. +8 −3 noisicaa/audioproc/engine/backend_renderer.cpp
  57. +2 −0 noisicaa/audioproc/engine/backend_renderer.h
  58. +12 −6 noisicaa/audioproc/engine/csound_util.cpp
  59. +1 −1 noisicaa/audioproc/engine/engine.pyx
  60. +3 −3 noisicaa/audioproc/engine/misc.cpp
  61. +1 −1 noisicaa/audioproc/engine/misc.h
  62. +0 −14 noisicaa/audioproc/engine/player.cpp
  63. +0 −4 noisicaa/audioproc/engine/player.h
  64. +0 −3 noisicaa/audioproc/engine/player.pxd
  65. +0 −2 noisicaa/audioproc/engine/player.pyi
  66. +2 −9 noisicaa/audioproc/engine/player.pyx
  67. +1 −1 noisicaa/audioproc/engine/plugin_host.cpp
  68. +1 −1 noisicaa/audioproc/engine/processor.h
  69. +2 −1 noisicaa/audioproc/engine/processor.pyi
  70. +1 −1 noisicaa/audioproc/engine/processor_plugin.cpp
  71. +1 −1 noisicaa/audioproc/engine/realm.h
  72. +0 −6 noisicaa/audioproc/engine/realm.pyx
  73. +3 −53 noisicaa/audioproc/engine/spec.cpp
  74. +1 −2 noisicaa/audioproc/engine/spec.h
  75. +1 −2 noisicaa/audioproc/engine/spec.pxd
  76. +1 −1 noisicaa/audioproc/engine/spec.pyx
  77. +9 −3 noisicaa/audioproc/engine/spec_test.pyx
  78. +40 −42 noisicaa/audioproc/engine/wscript
  79. +19 −36 noisicaa/audioproc/public/wscript
  80. +0 −109 noisicaa/bindings/ladspa.pyx
  81. +4 −4 noisicaa/bindings/sndfile.pyx
  82. +0 −3 noisicaa/bindings/sndfile_test.py
  83. +3 −1 noisicaa/bindings/wscript
  84. +1 −1 noisicaa/builtin_nodes/beat_track/wscript
  85. +2 −2 noisicaa/builtin_nodes/control_track/track_ui.py
  86. +3 −9 noisicaa/builtin_nodes/control_track/wscript
  87. +4 −1 noisicaa/builtin_nodes/custom_csound/node_ui.py
  88. +2 −6 noisicaa/builtin_nodes/custom_csound/wscript
  89. +3 −7 noisicaa/builtin_nodes/cv_mapper/wscript
  90. +4 −1 noisicaa/builtin_nodes/instrument/node_ui.py
  91. +2 −8 noisicaa/builtin_nodes/instrument/wscript
  92. +3 −1 noisicaa/builtin_nodes/metronome/node_ui.py
  93. +4 −7 noisicaa/builtin_nodes/metronome/wscript
  94. +4 −11 noisicaa/builtin_nodes/midi_cc_to_cv/wscript
  95. +4 −2 noisicaa/builtin_nodes/midi_looper/node_ui.py
  96. +3 −9 noisicaa/builtin_nodes/midi_looper/wscript
  97. +10 −4 noisicaa/builtin_nodes/midi_monitor/node_ui.py
  98. +2 −5 noisicaa/builtin_nodes/midi_monitor/wscript
  99. +2 −8 noisicaa/builtin_nodes/midi_source/wscript
  100. +3 −7 noisicaa/builtin_nodes/midi_velocity_mapper/wscript
  101. +2 −3 noisicaa/builtin_nodes/mixer/wscript
  102. +2 −2 noisicaa/builtin_nodes/oscilloscope/node_ui.py
  103. +0 −1 noisicaa/builtin_nodes/oscilloscope/processor.proto
  104. +3 −7 noisicaa/builtin_nodes/oscilloscope/wscript
  105. +2 −8 noisicaa/builtin_nodes/pianoroll/wscript
  106. +1 −1 noisicaa/builtin_nodes/processor_registry.cpp
  107. +2 −2 noisicaa/builtin_nodes/sample_track/track_ui.py
  108. +3 −9 noisicaa/builtin_nodes/sample_track/wscript
  109. +1 −1 noisicaa/builtin_nodes/score_track/wscript
  110. +3 −4 noisicaa/builtin_nodes/step_sequencer/node_ui.py
  111. +3 −8 noisicaa/builtin_nodes/step_sequencer/wscript
  112. +6 −8 noisicaa/builtin_nodes/wscript
  113. +2 −2 noisicaa/core/callbacks.py
  114. +2 −4 noisicaa/core/fileutil.py
  115. +10 −1 noisicaa/core/ipc.py
  116. +18 −16 bin/runtests → noisicaa/core/ipc_perftest.py
  117. +40 −28 noisicaa/core/ipc_test.py
  118. +6 −2 noisicaa/core/logging.cpp
  119. +1 −1 noisicaa/core/logging.h
  120. +0 −2 noisicaa/core/refcount.cpp
  121. +0 −2 noisicaa/core/refcount.h
  122. +1 −1 noisicaa/core/stacktrace.cpp
  123. +7 −5 noisicaa/core/status.cpp
  124. +1 −0 noisicaa/core/storage.py
  125. +7 −6 noisicaa/core/wscript
  126. +5 −6 noisicaa/host_system/wscript
  127. +1 −3 noisicaa/logging.py
  128. +2 −2 noisicaa/lv2/urid_mapper_process.py
  129. +3 −4 noisicaa/lv2/wscript
  130. +3 −0 noisicaa/music/__init__.py
  131. +3 −3 noisicaa/music/graph.py
  132. +4 −4 noisicaa/music/model_base.py
  133. +0 −1 noisicaa/music/mutations.proto
  134. +1 −1 noisicaa/music/mutations.py
  135. +1 −1 noisicaa/music/node_connector.py
  136. +7 −6 noisicaa/music/player.py
  137. +4 −6 noisicaa/music/player_integration_test.py
  138. +5 −5 noisicaa/music/project.py
  139. +1 −1 noisicaa/music/project_client.py
  140. +6 −3 noisicaa/music/wscript
  141. +1 −1 noisicaa/node_db/private/wscript
  142. +3 −6 noisicaa/node_db/wscript
  143. +6 −2 noisicaa/ui/audio_thread_profiler.py
  144. +12 −0 noisicaa/ui/editor_app_test.py
  145. +16 −8 noisicaa/ui/editor_window.py
  146. +0 −2 noisicaa/ui/flowlayout.py
  147. +4 −1 noisicaa/ui/graph/base_node.py
  148. +14 −12 noisicaa/ui/graph/canvas.py
  149. +2 −2 noisicaa/ui/graph/generic_node.py
  150. +8 −3 noisicaa/ui/graph/toolbox.py
  151. +6 −2 noisicaa/ui/instrument_library.py
  152. +0 −2 noisicaa/ui/load_history.py
  153. +1 −2 noisicaa/ui/mute_button.py
  154. +6 −2 noisicaa/ui/object_list_editor.py
  155. +19 −9 noisicaa/ui/open_project_dialog.py
  156. +10 −5 noisicaa/ui/pipeline_perf_monitor.py
  157. +4 −1 noisicaa/ui/project_debugger.py
  158. +7 −1 noisicaa/ui/project_registry_test.py
  159. +0 −1 noisicaa/ui/qled.py
  160. +0 −1 noisicaa/ui/qprogressindicator.py
  161. +6 −4 noisicaa/ui/render_dialog.py
  162. +4 −4 noisicaa/ui/session_helpers.py
  163. +14 −9 noisicaa/ui/stat_monitor.py
  164. +0 −2 noisicaa/ui/svg_symbol.py
  165. +0 −2 noisicaa/ui/svg_symbol_filetest.py
  166. +20 −16 noisicaa/ui/track_list/time_view_mixin.py
  167. +0 −2 noisicaa/ui/track_list/track_editor_tests.py
  168. +6 −2 noisicaa/ui/track_list/wscript
  169. +2 −2 noisicaa/ui/transfer_function_editor.py
  170. +7 −1 noisicaa/ui/transfer_function_editor_test.py
  171. +12 −8 noisicaa/ui/wscript
  172. +0 −1 noisidev/__init__.py
  173. +3 −5 noisidev/demo_project.py
  174. +2 −0 noisidev/mypy.ini
  175. +3 −1 noisidev/perf_stats.py
  176. +0 −1 noisidev/profutil.py
  177. +0 −8 noisidev/qttest.py
  178. +0 −641 noisidev/runtests.py
  179. +431 −28 noisidev/runvmtests.py
  180. +368 −0 noisidev/test_runner.py
  181. +3 −0 noisidev/testvm/__init__.py
  182. +345 −0 noisidev/testvm/debian.py
  183. +223 −0 noisidev/testvm/ubuntu.py
  184. +382 −0 noisidev/testvm/vm.py
  185. +10 −11 noisidev/uitest.py
  186. +0 −25 noisidev/unittest.py
  187. +7 −5 noisidev/unittest_mixins.py
  188. +14 −7 noisidev/unittest_processor_mixins.py
  189. +0 −20 noisidev/vmtests/__init__.py
  190. +0 −519 noisidev/vmtests/ubuntu.py
  191. +0 −320 noisidev/vmtests/vm.py
  192. +9 −8 noisidev/wscript
  193. +69 −38 wscript
@@ -6,7 +6,7 @@

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

(pyvenv-workon . "noisicaa")

@@ -1,2 +1,3 @@
-/build
-/venv
-/vmtests
@@ -0,0 +1,2 @@
from typing import Any
def __getattr__(arrr: str) -> Any: ...
@@ -0,0 +1,2 @@
from typing import Any
def __getattr__(arrr: str) -> Any: ...
@@ -0,0 +1,2 @@
from typing import Any
def __getattr__(arrr: str) -> Any: ...
@@ -0,0 +1,2 @@
from typing import Any
def __getattr__(arrr: str) -> Any: ...
@@ -0,0 +1,2 @@
from typing import Any
def __getattr__(arrr: str) -> Any: ...
@@ -0,0 +1,2 @@
from typing import Any
def __getattr__(arrr: str) -> Any: ...

This file was deleted.

@@ -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
@@ -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
@@ -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):
@@ -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)
@@ -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():
@@ -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)
@@ -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',
],
@@ -27,7 +27,6 @@
import pathlib
import shutil
import subprocess
import textwrap

import packaging.markers
import packaging.requirements
@@ -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()

@@ -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(
@@ -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)
@@ -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
@@ -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)
@@ -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)

@@ -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.
You can’t perform that action at this time.