Skip to content

Commit 84f28fc

Browse files
authored
Merge pull request mesonbuild#6816 from dcbaker/framework-matrix
project test junit schema + a few more uses
2 parents 89bd55b + eb45ce6 commit 84f28fc

File tree

14 files changed

+214
-46
lines changed

14 files changed

+214
-46
lines changed

.editorconfig

+2
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,5 @@ indent_size = 2
2323
[meson.build]
2424
indent_size = 2
2525

26+
[*.json]
27+
indent_size = 2

.github/workflows/os_comp.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
- name: Install Dependencies
1616
run: |
1717
sudo apt update -yq
18-
sudo apt install -yq --no-install-recommends python3-setuptools python3-pip g++ gfortran gobjc gobjc++ zlib1g-dev python-dev python3-dev
18+
sudo apt install -yq --no-install-recommends python3-setuptools python3-pip g++ gfortran gobjc gobjc++ zlib1g-dev python-dev python3-dev python3-jsonschema
1919
- name: Install ninja-build tool
2020
uses: seanmiddleditch/gha-setup-ninja@v1
2121
- name: Python version

azure-pipelines.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ jobs:
100100
displayName: Install Dependencies
101101
- script: |
102102
set PATH=%CYGWIN_ROOT%\bin;%SYSTEMROOT%\system32
103-
env.exe -- python3 -m pip --disable-pip-version-check install pefile pytest-xdist
104-
displayName: pip install pefile pytest-xdist
103+
env.exe -- python3 -m pip --disable-pip-version-check install pefile pytest-xdist jsonschema
104+
displayName: pip install pefile pytest-xdist jsonschema
105105
- script: |
106106
set BOOST_ROOT=
107107
set PATH=%CYGWIN_ROOT%\bin;%SYSTEMROOT%\system32
@@ -169,7 +169,7 @@ jobs:
169169
mingw-w64-$(MSYS2_ARCH)-python3-setuptools ^
170170
mingw-w64-$(MSYS2_ARCH)-python3-pip ^
171171
%TOOLCHAIN%
172-
%MSYS2_ROOT%\usr\bin\bash -lc "python3 -m pip --disable-pip-version-check install pefile"
172+
%MSYS2_ROOT%\usr\bin\bash -lc "python3 -m pip --disable-pip-version-check install pefile jsonschema"
173173
displayName: Install Dependencies
174174
- script: |
175175
set BOOST_ROOT=

ci/ciimage/arch/install.sh

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pkgs=(
1212
itstool gtk3 java-environment=8 gtk-doc llvm clang sdl2 graphviz
1313
doxygen vulkan-validation-layers openssh mercurial gtk-sharp-2 qt5-tools
1414
libwmf valgrind cmake netcdf-fortran openmpi nasm gnustep-base gettext
15+
python-jsonschema
1516
# cuda
1617
)
1718

ci/run.ps1

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ python --version
6767

6868
# Needed for running unit tests in parallel.
6969
echo ""
70-
python -m pip --disable-pip-version-check install --upgrade pefile pytest-xdist
70+
python -m pip --disable-pip-version-check install --upgrade pefile pytest-xdist jsonschema
7171

7272
echo ""
7373
echo "=== Start running tests ==="

ci/travis_install.sh

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
1111
if [[ "$MESON_ARGS" =~ .*unity=on.* ]]; then
1212
which pkg-config || brew install pkg-config
1313
fi
14+
python3 -m pip install jsonschema
1415
elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
1516
msg "Running Linux setup"
1617
docker pull mesonbuild/eoan

data/test.schema.json

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
{
2+
"type": "object",
3+
"properties": {
4+
"env": {
5+
"type": "object",
6+
"additionalProperties": {
7+
"type": "string"
8+
}
9+
},
10+
"installed": {
11+
"type": "array",
12+
"items": {
13+
"type": "object",
14+
"properties": {
15+
"file": {
16+
"type": "string"
17+
},
18+
"type": {
19+
"type": "string",
20+
"enum": [
21+
"file",
22+
"exe",
23+
"shared_lib",
24+
"pdb",
25+
"implib",
26+
"implibempty",
27+
"expr"
28+
]
29+
},
30+
"platform": {
31+
"type": "string",
32+
"enum": [
33+
"msvc",
34+
"gcc",
35+
"cygwin",
36+
"!cygwin"
37+
]
38+
},
39+
"version": {
40+
"type": "string"
41+
},
42+
"language": {
43+
"type": "string"
44+
}
45+
},
46+
"required": [
47+
"file",
48+
"type"
49+
]
50+
}
51+
},
52+
"matrix": {
53+
"type": "object",
54+
"additionalProperties": {
55+
"properties": {
56+
"options": {
57+
"type": "array",
58+
"items": {
59+
"type": "object",
60+
"properties": {
61+
"val": {
62+
"type": "string"
63+
},
64+
"compilers": {
65+
"type": "object",
66+
"additionalProperties": {
67+
"type": "string"
68+
}
69+
},
70+
"skip_on_env": {
71+
"type": "array",
72+
"items": {
73+
"type": "string"
74+
}
75+
}
76+
},
77+
"required": [
78+
"val"
79+
]
80+
}
81+
},
82+
"exclude": {
83+
"type": "array",
84+
"items": {
85+
"type": "object",
86+
"additionalProperties": {
87+
"type": "string"
88+
}
89+
}
90+
}
91+
}
92+
}
93+
},
94+
"do_not_set_opts": {
95+
"type": "array",
96+
"items": {
97+
"type": "string",
98+
"enum": [
99+
"libdir",
100+
"prefix"
101+
]
102+
}
103+
}
104+
}
105+
}

docs/markdown/Contributing.md

+10-2
Original file line numberDiff line numberDiff line change
@@ -294,9 +294,17 @@ Additionally, the `skip_on_env` key can be used to specify a list of environment
294294
variables. If at least one environment variable in `skip_on_env` is present, all
295295
matrix entries containing this value are skipped.
296296

297-
Similarly, the `compilers` key can be used to define a set of compilers required
298-
for this value.
297+
Similarly, the `compilers` key can be used to define a mapping of compilers to languages that are required for this value.
299298

299+
```json
300+
{
301+
"compilers": {
302+
"c": "gcc",
303+
"cpp": "gcc",
304+
"d": "gdc"
305+
}
306+
}
307+
```
300308

301309
Specific option combinations can be excluded with the `exclude` section. It should
302310
be noted that `exclude` does not require exact matches. Instead, any matrix entry

run_project_tests.py

+27-22
Original file line numberDiff line numberDiff line change
@@ -404,21 +404,21 @@ def run_test_inprocess(testdir):
404404

405405
# Build directory name must be the same so Ccache works over
406406
# consecutive invocations.
407-
def create_deterministic_builddir(test: TestDef) -> str:
407+
def create_deterministic_builddir(test: TestDef, use_tmpdir: bool) -> str:
408408
import hashlib
409409
src_dir = test.path.as_posix()
410410
if test.name:
411411
src_dir += test.name
412412
rel_dirname = 'b ' + hashlib.sha256(src_dir.encode(errors='ignore')).hexdigest()[0:10]
413-
os.mkdir(rel_dirname)
414-
abs_pathname = os.path.join(os.getcwd(), rel_dirname)
413+
abs_pathname = os.path.join(tempfile.gettempdir() if use_tmpdir else os.getcwd(), rel_dirname)
414+
os.mkdir(abs_pathname)
415415
return abs_pathname
416416

417-
def run_test(test: TestDef, extra_args, compiler, backend, flags, commands, should_fail):
417+
def run_test(test: TestDef, extra_args, compiler, backend, flags, commands, should_fail, use_tmp: bool):
418418
if test.skip:
419419
return None
420-
with AutoDeletedDir(create_deterministic_builddir(test)) as build_dir:
421-
with AutoDeletedDir(tempfile.mkdtemp(prefix='i ', dir=os.getcwd())) as install_dir:
420+
with AutoDeletedDir(create_deterministic_builddir(test, use_tmp)) as build_dir:
421+
with AutoDeletedDir(tempfile.mkdtemp(prefix='i ', dir=None if use_tmp else os.getcwd())) as install_dir:
422422
try:
423423
return _run_test(test, build_dir, install_dir, extra_args, compiler, backend, flags, commands, should_fail)
424424
except TestResult as r:
@@ -666,8 +666,8 @@ def have_d_compiler():
666666
return True
667667
return False
668668

669-
def have_objc_compiler():
670-
with AutoDeletedDir(tempfile.mkdtemp(prefix='b ', dir='.')) as build_dir:
669+
def have_objc_compiler(use_tmp: bool) -> bool:
670+
with AutoDeletedDir(tempfile.mkdtemp(prefix='b ', dir=None if use_tmp else '.')) as build_dir:
671671
env = environment.Environment(None, build_dir, get_fake_options('/'))
672672
try:
673673
objc_comp = env.detect_objc_compiler(MachineChoice.HOST)
@@ -682,8 +682,8 @@ def have_objc_compiler():
682682
return False
683683
return True
684684

685-
def have_objcpp_compiler():
686-
with AutoDeletedDir(tempfile.mkdtemp(prefix='b ', dir='.')) as build_dir:
685+
def have_objcpp_compiler(use_tmp: bool) -> bool:
686+
with AutoDeletedDir(tempfile.mkdtemp(prefix='b ', dir=None if use_tmp else '.')) as build_dir:
687687
env = environment.Environment(None, build_dir, get_fake_options('/'))
688688
try:
689689
objcpp_comp = env.detect_objcpp_compiler(MachineChoice.HOST)
@@ -734,7 +734,11 @@ def skippable(suite, test):
734734

735735
# Scientific libraries are skippable on certain systems
736736
# See the discussion here: https://github.com/mesonbuild/meson/pull/6562
737-
if any([test.endswith(x) for x in ['17 mpi', '25 hdf5', '30 scalapack']]) and skip_scientific:
737+
if any([x in test for x in ['17 mpi', '25 hdf5', '30 scalapack']]) and skip_scientific:
738+
return True
739+
740+
# These create OS specific tests, and need to be skippable
741+
if any([x in test for x in ['16 sdl', '17 mpi']]):
738742
return True
739743

740744
# No frameworks test should be skipped on linux CI, as we expect all
@@ -805,7 +809,7 @@ def should_skip_rust(backend: Backend) -> bool:
805809
return True
806810
return False
807811

808-
def detect_tests_to_run(only: T.List[str]) -> T.List[T.Tuple[str, T.List[TestDef], bool]]:
812+
def detect_tests_to_run(only: T.List[str], use_tmp: bool) -> T.List[T.Tuple[str, T.List[TestDef], bool]]:
809813
"""
810814
Parameters
811815
----------
@@ -842,8 +846,8 @@ def detect_tests_to_run(only: T.List[str]) -> T.List[T.Tuple[str, T.List[TestDef
842846
('vala', 'vala', backend is not Backend.ninja or not shutil.which(os.environ.get('VALAC', 'valac'))),
843847
('rust', 'rust', should_skip_rust(backend)),
844848
('d', 'd', backend is not Backend.ninja or not have_d_compiler()),
845-
('objective c', 'objc', backend not in (Backend.ninja, Backend.xcode) or not have_objc_compiler()),
846-
('objective c++', 'objcpp', backend not in (Backend.ninja, Backend.xcode) or not have_objcpp_compiler()),
849+
('objective c', 'objc', backend not in (Backend.ninja, Backend.xcode) or not have_objc_compiler(options.use_tmpdir)),
850+
('objective c++', 'objcpp', backend not in (Backend.ninja, Backend.xcode) or not have_objcpp_compiler(options.use_tmpdir)),
847851
('fortran', 'fortran', skip_fortran or backend != Backend.ninja),
848852
('swift', 'swift', backend not in (Backend.ninja, Backend.xcode) or not shutil.which('swiftc')),
849853
# CUDA tests on Windows: use Ninja backend: python run_project_tests.py --only cuda --backend ninja
@@ -866,16 +870,16 @@ def detect_tests_to_run(only: T.List[str]) -> T.List[T.Tuple[str, T.List[TestDef
866870

867871
def run_tests(all_tests: T.List[T.Tuple[str, T.List[TestDef], bool]],
868872
log_name_base: str, failfast: bool,
869-
extra_args: T.List[str]) -> T.Tuple[int, int, int]:
873+
extra_args: T.List[str], use_tmp: bool) -> T.Tuple[int, int, int]:
870874
global logfile
871875
txtname = log_name_base + '.txt'
872876
with open(txtname, 'w', encoding='utf-8', errors='ignore') as lf:
873877
logfile = lf
874-
return _run_tests(all_tests, log_name_base, failfast, extra_args)
878+
return _run_tests(all_tests, log_name_base, failfast, extra_args, use_tmp)
875879

876880
def _run_tests(all_tests: T.List[T.Tuple[str, T.List[TestDef], bool]],
877881
log_name_base: str, failfast: bool,
878-
extra_args: T.List[str]) -> T.Tuple[int, int, int]:
882+
extra_args: T.List[str], use_tmp: bool) -> T.Tuple[int, int, int]:
879883
global stop, executor, futures, system_compiler
880884
xmlname = log_name_base + '.xml'
881885
junit_root = ET.Element('testsuites')
@@ -929,7 +933,7 @@ def _run_tests(all_tests: T.List[T.Tuple[str, T.List[TestDef], bool]],
929933

930934
t.skip = skipped or t.skip
931935
result = executor.submit(run_test, t, extra_args + suite_args + t.args,
932-
system_compiler, backend, backend_flags, commands, should_fail)
936+
system_compiler, backend, backend_flags, commands, should_fail, use_tmp)
933937
futures.append((testname, t, result))
934938
for (testname, t, result) in futures:
935939
sys.stdout.flush()
@@ -1047,7 +1051,7 @@ def check_meson_commands_work(options):
10471051
global backend, compile_commands, test_commands, install_commands
10481052
testdir = PurePath('test cases', 'common', '1 trivial').as_posix()
10491053
meson_commands = mesonlib.python_command + [get_meson_script()]
1050-
with AutoDeletedDir(tempfile.mkdtemp(prefix='b ', dir='.')) as build_dir:
1054+
with AutoDeletedDir(tempfile.mkdtemp(prefix='b ', dir=None if options.use_tmpdir else '.')) as build_dir:
10511055
print('Checking that configuring works...')
10521056
gen_cmd = meson_commands + [testdir, build_dir] + backend_flags + options.extra_args
10531057
pc, o, e = Popen_safe(gen_cmd)
@@ -1072,7 +1076,7 @@ def check_meson_commands_work(options):
10721076
def detect_system_compiler(options):
10731077
global system_compiler, compiler_id_map
10741078

1075-
with AutoDeletedDir(tempfile.mkdtemp(prefix='b ', dir='.')) as build_dir:
1079+
with AutoDeletedDir(tempfile.mkdtemp(prefix='b ', dir=None if options.use_tmpdir else '.')) as build_dir:
10761080
fake_opts = get_fake_options('/')
10771081
if options.cross_file:
10781082
fake_opts.cross_file = [options.cross_file]
@@ -1139,6 +1143,7 @@ def get_version(t: dict) -> str:
11391143
help='Not used, only here to simplify run_tests.py')
11401144
parser.add_argument('--only', help='name of test(s) to run', nargs='+', choices=ALL_TESTS)
11411145
parser.add_argument('--cross-file', action='store', help='File describing cross compilation environment.')
1146+
parser.add_argument('--use-tmpdir', action='store_true', help='Use tmp directory for temporary files.')
11421147
options = parser.parse_args()
11431148
if options.cross_file:
11441149
options.extra_args += ['--cross-file', options.cross_file]
@@ -1152,8 +1157,8 @@ def get_version(t: dict) -> str:
11521157
check_format()
11531158
check_meson_commands_work(options)
11541159
try:
1155-
all_tests = detect_tests_to_run(options.only)
1156-
(passing_tests, failing_tests, skipped_tests) = run_tests(all_tests, 'meson-test-run', options.failfast, options.extra_args)
1160+
all_tests = detect_tests_to_run(options.only, options.use_tmpdir)
1161+
(passing_tests, failing_tests, skipped_tests) = run_tests(all_tests, 'meson-test-run', options.failfast, options.extra_args, options.use_tmpdir)
11571162
except StopException:
11581163
pass
11591164
print('\nTotal passed tests:', green(str(passing_tests)))

run_unittests.py

+26
Original file line numberDiff line numberDiff line change
@@ -1227,6 +1227,32 @@ def test_dependency_factory_order(self):
12271227
actual = [m() for m in f(env, MachineChoice.HOST, {'required': False})]
12281228
self.assertListEqual([m.type_name for m in actual], ['cmake', 'pkgconfig'])
12291229

1230+
def test_validate_json(self) -> None:
1231+
"""Validate the json schema for the test cases."""
1232+
try:
1233+
from jsonschema import validate, ValidationError
1234+
except ImportError:
1235+
if is_ci():
1236+
raise
1237+
raise unittest.SkipTest('Python jsonschema module not found.')
1238+
1239+
with Path('data/test.schema.json').open() as f:
1240+
schema = json.load(f)
1241+
1242+
errors = [] # type: T.Tuple[str, Exception]
1243+
for p in Path('test cases').glob('**/test.json'):
1244+
with p.open() as f:
1245+
try:
1246+
validate(json.load(f), schema=schema)
1247+
except ValidationError as e:
1248+
errors.append((p.resolve(), e))
1249+
1250+
for f, e in errors:
1251+
print('Failed to validate: "{}"'.format(f))
1252+
print(str(e))
1253+
1254+
self.assertFalse(errors)
1255+
12301256

12311257
@unittest.skipIf(is_tarball(), 'Skipping because this is a tarball release')
12321258
class DataTests(unittest.TestCase):
+3-17
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
project('sdl2 test', 'c')
22

3-
sdl2_dep = dependency('sdl2', version : '>=2.0.0', required: false)
3+
method = get_option('method')
4+
5+
sdl2_dep = dependency('sdl2', version : '>=2.0.0', required : false, method : method)
46

57
if not sdl2_dep.found()
68
error('MESON_SKIP_TEST sdl2 not found.')
@@ -9,19 +11,3 @@ endif
911
e = executable('sdl2prog', 'sdl2prog.c', dependencies : sdl2_dep)
1012

1113
test('sdl2test', e)
12-
13-
if sdl2_dep.type_name() == 'extraframeworks'
14-
# The SDL OSX framework does not ship with detection executables
15-
# so skip the remaining tests.
16-
subdir_done()
17-
endif
18-
19-
# Ensure that we can find it with sdl2-config too, using the legacy method name
20-
configdep = dependency('sdl2', method : 'sdlconfig')
21-
22-
# And the modern method name
23-
configdep = dependency('sdl2', method : 'config-tool')
24-
25-
# Check we can apply a version constraint
26-
dependency('sdl2', version: '>=@0@'.format(sdl2_dep.version()), method: 'pkg-config')
27-
dependency('sdl2', version: '>=@0@'.format(sdl2_dep.version()), method: 'config-tool')

0 commit comments

Comments
 (0)