From e0c9259e79f21c6ee19f996c1f5d817d510de663 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Fri, 20 Mar 2020 13:22:43 -0700 Subject: [PATCH] Add a json schema for the test.json used in tests This does a couple of nice things, one is that editors like vscode can be configured to use this schema to provide auto completion and error highlighting if invalid values are added or required values are missing. It also allows us test that the format of the test matrix work in a unit test, which I've added. It does require that the python jsonschema package is installed. --- .editorconfig | 2 + data/test.schema.json | 105 ++++++++++++++++++++++++++++++++++ docs/markdown/Contributing.md | 12 +++- run_unittests.py | 26 +++++++++ 4 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 data/test.schema.json diff --git a/.editorconfig b/.editorconfig index d84862726a1e..c2dd5d06aa36 100644 --- a/.editorconfig +++ b/.editorconfig @@ -23,3 +23,5 @@ indent_size = 2 [meson.build] indent_size = 2 +[*.json] +indent_size = 2 diff --git a/data/test.schema.json b/data/test.schema.json new file mode 100644 index 000000000000..72f160fd2961 --- /dev/null +++ b/data/test.schema.json @@ -0,0 +1,105 @@ +{ + "type": "object", + "properties": { + "env": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "installed": { + "type": "array", + "items": { + "type": "object", + "properties": { + "file": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "file", + "exe", + "shared_lib", + "pdb", + "implib", + "implibempty", + "expr" + ] + }, + "platform": { + "type": "string", + "enum": [ + "msvc", + "gcc", + "cygwin", + "!cygwin" + ] + }, + "version": { + "type": "string" + }, + "language": { + "type": "string" + } + }, + "required": [ + "file", + "type" + ] + } + }, + "matrix": { + "type": "object", + "additionalProperties": { + "properties": { + "options": { + "type": "array", + "items": { + "type": "object", + "properties": { + "val": { + "type": "string" + }, + "compilers": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "skip_on_env": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "val" + ] + } + }, + "exclude": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "do_not_set_opts": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "libdir", + "prefix" + ] + } + } + } +} diff --git a/docs/markdown/Contributing.md b/docs/markdown/Contributing.md index 6f4c397b801e..53329389b18f 100644 --- a/docs/markdown/Contributing.md +++ b/docs/markdown/Contributing.md @@ -294,9 +294,17 @@ Additionally, the `skip_on_env` key can be used to specify a list of environment variables. If at least one environment variable in `skip_on_env` is present, all matrix entries containing this value are skipped. -Similarly, the `compilers` key can be used to define a set of compilers required -for this value. +Similarly, the `compilers` key can be used to define a mapping of compilers to languages that are required for this value. +```json +{ + "compilers": { + "c": "gcc", + "cpp": "gcc", + "d": "gdc" + } +} +``` Specific option combinations can be excluded with the `exclude` section. It should be noted that `exclude` does not require exact matches. Instead, any matrix entry diff --git a/run_unittests.py b/run_unittests.py index 4cd6e1787a99..cc294dd695d4 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -1227,6 +1227,32 @@ def test_dependency_factory_order(self): actual = [m() for m in f(env, MachineChoice.HOST, {'required': False})] self.assertListEqual([m.type_name for m in actual], ['cmake', 'pkgconfig']) + def test_validate_json(self) -> None: + """Validate the json schema for the test cases.""" + try: + from jsonschema import validate, ValidationError + except ImportError: + if is_ci(): + raise + raise unittest.SkipTest('Python jsonschema module not found.') + + with Path('data/test.schema.json').open() as f: + schema = json.load(f) + + errors = [] # type: T.Tuple[str, Exception] + for p in Path('test cases').glob('**/test.json'): + with p.open() as f: + try: + validate(json.load(f), schema=schema) + except ValidationError as e: + errors.append((p.resolve(), e)) + + for f, e in errors: + print('Failed to validate: "{}"'.format(f)) + print(str(e)) + + self.assertFalse(errors) + @unittest.skipIf(is_tarball(), 'Skipping because this is a tarball release') class DataTests(unittest.TestCase):