Configuration schema are checked against jsonschema draft 4 meta-schema (#10247)
fixes #10246
This commit is contained in:
parent
dce9fc4d63
commit
2e8aa6cb24
149
lib/spack/spack/test/data/jsonschema_meta.json
Normal file
149
lib/spack/spack/test/data/jsonschema_meta.json
Normal file
@ -0,0 +1,149 @@
|
||||
{
|
||||
"id": "http://json-schema.org/draft-04/schema#",
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Core schema meta-schema",
|
||||
"definitions": {
|
||||
"schemaArray": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": { "$ref": "#" }
|
||||
},
|
||||
"positiveInteger": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"positiveIntegerDefault0": {
|
||||
"allOf": [ { "$ref": "#/definitions/positiveInteger" }, { "default": 0 } ]
|
||||
},
|
||||
"simpleTypes": {
|
||||
"enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ]
|
||||
},
|
||||
"stringArray": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"$schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": {},
|
||||
"multipleOf": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"exclusiveMinimum": true
|
||||
},
|
||||
"maximum": {
|
||||
"type": "number"
|
||||
},
|
||||
"exclusiveMaximum": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"minimum": {
|
||||
"type": "number"
|
||||
},
|
||||
"exclusiveMinimum": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"maxLength": { "$ref": "#/definitions/positiveInteger" },
|
||||
"minLength": { "$ref": "#/definitions/positiveIntegerDefault0" },
|
||||
"pattern": {
|
||||
"type": "string",
|
||||
"format": "regex"
|
||||
},
|
||||
"additionalItems": {
|
||||
"anyOf": [
|
||||
{ "type": "boolean" },
|
||||
{ "$ref": "#" }
|
||||
],
|
||||
"default": {}
|
||||
},
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{ "$ref": "#" },
|
||||
{ "$ref": "#/definitions/schemaArray" }
|
||||
],
|
||||
"default": {}
|
||||
},
|
||||
"maxItems": { "$ref": "#/definitions/positiveInteger" },
|
||||
"minItems": { "$ref": "#/definitions/positiveIntegerDefault0" },
|
||||
"uniqueItems": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"maxProperties": { "$ref": "#/definitions/positiveInteger" },
|
||||
"minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" },
|
||||
"required": { "$ref": "#/definitions/stringArray" },
|
||||
"additionalProperties": {
|
||||
"anyOf": [
|
||||
{ "type": "boolean" },
|
||||
{ "$ref": "#" }
|
||||
],
|
||||
"default": {}
|
||||
},
|
||||
"definitions": {
|
||||
"type": "object",
|
||||
"additionalProperties": { "$ref": "#" },
|
||||
"default": {}
|
||||
},
|
||||
"properties": {
|
||||
"type": "object",
|
||||
"additionalProperties": { "$ref": "#" },
|
||||
"default": {}
|
||||
},
|
||||
"patternProperties": {
|
||||
"type": "object",
|
||||
"additionalProperties": { "$ref": "#" },
|
||||
"default": {}
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"anyOf": [
|
||||
{ "$ref": "#" },
|
||||
{ "$ref": "#/definitions/stringArray" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"enum": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
},
|
||||
"type": {
|
||||
"anyOf": [
|
||||
{ "$ref": "#/definitions/simpleTypes" },
|
||||
{
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/simpleTypes" },
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"format": { "type": "string" },
|
||||
"allOf": { "$ref": "#/definitions/schemaArray" },
|
||||
"anyOf": { "$ref": "#/definitions/schemaArray" },
|
||||
"oneOf": { "$ref": "#/definitions/schemaArray" },
|
||||
"not": { "$ref": "#" }
|
||||
},
|
||||
"dependencies": {
|
||||
"exclusiveMaximum": [ "maximum" ],
|
||||
"exclusiveMinimum": [ "minimum" ]
|
||||
},
|
||||
"default": {}
|
||||
}
|
@ -42,7 +42,10 @@
|
||||
os.path.join(spack_lib_path, 'external', 'jinja2', 'asyncfilters.py'),
|
||||
os.path.join(spack_lib_path, 'external', 'jinja2', 'asyncsupport.py'),
|
||||
os.path.join(spack_lib_path, 'external', 'yaml', 'lib3'),
|
||||
os.path.join(spack_lib_path, 'external', 'pyqver3.py')]
|
||||
os.path.join(spack_lib_path, 'external', 'pyqver3.py'),
|
||||
# Uses importlib
|
||||
os.path.join(spack_lib_path, 'spack', 'test', 'schema.py')
|
||||
]
|
||||
|
||||
else:
|
||||
import pyqver3 as pyqver
|
||||
@ -55,7 +58,10 @@
|
||||
os.path.join(spack_lib_path, 'external', 'jinja2', 'asyncfilters.py'),
|
||||
os.path.join(spack_lib_path, 'external', 'jinja2', 'asyncsupport.py'),
|
||||
os.path.join(spack_lib_path, 'external', 'yaml', 'lib'),
|
||||
os.path.join(spack_lib_path, 'external', 'pyqver2.py')]
|
||||
os.path.join(spack_lib_path, 'external', 'pyqver2.py'),
|
||||
# Uses importlib
|
||||
os.path.join(spack_lib_path, 'spack', 'test', 'schema.py')
|
||||
]
|
||||
|
||||
|
||||
def pyfiles(search_paths, exclude=()):
|
||||
|
@ -3,10 +3,14 @@
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
|
||||
import json
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
import jsonschema
|
||||
import pytest
|
||||
|
||||
|
||||
import spack.paths
|
||||
import spack.schema
|
||||
|
||||
|
||||
@ -50,6 +54,17 @@ def module_suffixes_schema():
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def meta_schema():
|
||||
"""Meta schema for JSON schema validation (Draft 4)"""
|
||||
meta_schema_file = os.path.join(
|
||||
spack.paths.test_path, 'data', 'jsonschema_meta.json'
|
||||
)
|
||||
with open(meta_schema_file) as f:
|
||||
ms = json.load(f)
|
||||
return ms
|
||||
|
||||
|
||||
@pytest.mark.regression('9857')
|
||||
def test_validate_spec(validate_spec_schema):
|
||||
v = spack.schema.Validator(validate_spec_schema)
|
||||
@ -75,3 +90,27 @@ def test_module_suffixes(module_suffixes_schema):
|
||||
v.validate(data)
|
||||
|
||||
assert 'is an invalid spec' in str(exc_err.value)
|
||||
|
||||
|
||||
@pytest.mark.regression('10246')
|
||||
@pytest.mark.skipif(
|
||||
sys.version_info < (2, 7),
|
||||
reason='requires python2.7 or higher because of importlib')
|
||||
@pytest.mark.parametrize('config_name', [
|
||||
'compilers',
|
||||
'config',
|
||||
'env',
|
||||
'merged',
|
||||
'mirrors',
|
||||
'modules',
|
||||
'packages',
|
||||
'repos'
|
||||
])
|
||||
def test_schema_validation(meta_schema, config_name):
|
||||
import importlib
|
||||
module_name = 'spack.schema.{0}'.format(config_name)
|
||||
module = importlib.import_module(module_name)
|
||||
schema = getattr(module, 'schema')
|
||||
|
||||
# If this validation throws the test won't pass
|
||||
jsonschema.validate(schema, meta_schema)
|
||||
|
Loading…
Reference in New Issue
Block a user