Skip to content

Fix schema: config:spack:packages is a required entry #247

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion stackinator/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def py2yaml(data, indent):

# load recipe yaml schema
config_schema = json.load(open(prefix / "schema/config.json"))
config_validator = validator(config_schema)
config_validator = extend_with_default(jsonschema.Draft201909Validator)(config_schema)
compilers_schema = json.load(open(prefix / "schema/compilers.json"))
compilers_validator = validator(compilers_schema)
environments_schema = json.load(open(prefix / "schema/environments.json"))
Expand Down
120 changes: 84 additions & 36 deletions stackinator/schema/config.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "http://json-schema.org/draft-2019-09/schema#",
"title": "Schema for Spack Stack config.yaml recipe file",
"type" : "object",
"additionalProperties": false,
"required": ["name", "spack"],
"unevaluatedProperties": false,
"required": ["name"],
"properties" : {
"name" : {
"type": "string"
Expand All @@ -12,38 +12,6 @@
"type" : "string",
"default" : "/user-environment"
},
"spack" : {
"type" : "object",
"additionalProperties": false,
"properties" : {
"repo": {
"type": "string"
},
"commit": {
"oneOf": [
{"type" : "string"},
{"type" : "null"}
],
"default": null
},
"packages" : {
"type" : "object",
"additionalProperties": false,
"properties" : {
"repo": {
"type": "string"
},
"commit": {
"oneOf": [
{"type" : "string"},
{"type" : "null"}
],
"default": null
}
}
}
}
},
"mirror" : {
"type" : "object",
"additionalProperties": false,
Expand Down Expand Up @@ -75,7 +43,87 @@
},
"version" : {
"type": "number",
"default": 1
"default": 1,
"minimum": 1,
"maximum": 2
}
},
"allOf": [
{
"if": {
"required": ["version"],
"properties": {
"version": {"const": 2 }
}
},
"then": {
"required": ["spack"],
"properties": {
"spack": {
"$ref": "#/$defs/git-repo",
"unevaluatedProperties": false,
"required": ["packages"],
"properties": {
"packages": {
"$ref": "#/$defs/git-repo",
"unevaluatedProperties": false
}
}
}
}
}
},
{
"if": {
"oneOf": [
{
"not": {
"required": ["version"]
}
},
{
"required": ["version"],
"properties": {
"version": {"const": 1 }
}
}
]
},
"then": {
"required": ["spack"],
"properties": {
"spack": {
"$ref": "#/$defs/git-repo",
"unevaluatedProperties": false
}
}
}
},
{
"if": {
"not": { "properties": { "version": { "minimum": 1, "maximum": 2} } }
},
"then": {
"properties": { "spack": {} }
}
}
],
"$defs": {
"git-repo": {
"type" : "object",
"required": ["repo"],
"properties" : {
"repo": {
"type": "string"
},
"commit": {
"oneOf": [
{"type" : "string"},
{"type" : "null"}
],
"default": null
}
}
}
}
}
30 changes: 21 additions & 9 deletions unittests/test_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ def test_config_yaml(yaml_path):
# test that the defaults are set as expected
with open(yaml_path / "config.defaults.yaml") as fid:
raw = yaml.load(fid, Loader=yaml.Loader)
schema.validator(schema.config_schema).validate(raw)
schema.config_validator.validate(raw)
assert raw["version"] == 1
assert raw["store"] == "/user-environment"
assert raw["spack"]["commit"] is None
assert raw["modules"] == True # noqa: E712
Expand All @@ -49,34 +50,45 @@ def test_config_yaml(yaml_path):

with open(yaml_path / "config.full.yaml") as fid:
raw = yaml.load(fid, Loader=yaml.Loader)
schema.validator(schema.config_schema).validate(raw)
schema.config_validator.validate(raw)
assert raw["version"] == 1
assert raw["store"] == "/alternative-point"
assert raw["spack"]["commit"] == "6408b51"
assert raw["modules"] == False # noqa: E712
assert raw["mirror"] == {"enable": True, "key": "/home/bob/veryprivate.key"}
assert raw["description"] == "a really useful environment"

with open(yaml_path / "config.defaults.v2.yaml") as fid:
raw = yaml.load(fid, Loader=yaml.Loader)
schema.config_validator.validate(raw)
assert raw["store"] == "/user-environment"
assert raw["spack"]["commit"] is None
assert raw["spack"]["packages"]["commit"] is None
assert raw["modules"] == True # noqa: E712
assert raw["mirror"] == {"enable": True, "key": None}
assert raw["description"] is None


def test_recipe_config_yaml(recipe_paths):
# validate the config.yaml in the test recipes
for p in recipe_paths:
with open(p / "config.yaml") as fid:
raw = yaml.load(fid, Loader=yaml.Loader)
schema.validator(schema.config_schema).validate(raw)
schema.config_validator.validate(raw)


def test_compilers_yaml(yaml_path):
# test that the defaults are set as expected
with open(yaml_path / "compilers.defaults.yaml") as fid:
raw = yaml.load(fid, Loader=yaml.Loader)
schema.validator(schema.compilers_schema).validate(raw)
schema.compilers_validator.validate(raw)
assert raw["bootstrap"] == {"spec": "gcc@11"}
assert raw["gcc"] == {"specs": ["[email protected]"]}
assert raw["llvm"] is None

with open(yaml_path / "compilers.full.yaml") as fid:
raw = yaml.load(fid, Loader=yaml.Loader)
schema.validator(schema.compilers_schema).validate(raw)
schema.compilers_validator.validate(raw)
assert raw["bootstrap"]["spec"] == "gcc@11"
assert raw["gcc"] == {"specs": ["gcc@11", "[email protected]", "[email protected]"]}
assert raw["llvm"] == {
Expand All @@ -90,13 +102,13 @@ def test_recipe_compilers_yaml(recipe_paths):
for p in recipe_paths:
with open(p / "compilers.yaml") as fid:
raw = yaml.load(fid, Loader=yaml.Loader)
schema.validator(schema.compilers_schema).validate(raw)
schema.compilers_validator.validate(raw)


def test_environments_yaml(yaml_path):
with open(yaml_path / "environments.full.yaml") as fid:
raw = yaml.load(fid, Loader=yaml.Loader)
schema.validator(schema.environments_schema).validate(raw)
schema.environments_validator.validate(raw)

# the defaults-env does not set fields
# test that they have been set to the defaults correctly
Expand Down Expand Up @@ -145,12 +157,12 @@ def test_environments_yaml(yaml_path):
jsonschema.exceptions.ValidationError,
match=r"Additional properties are not allowed \('providers' was unexpected",
):
schema.validator(schema.environments_schema).validate(raw)
schema.environments_validator.validate(raw)


def test_recipe_environments_yaml(recipe_paths):
# validate the environments.yaml in the test recipes
for p in recipe_paths:
with open(p / "environments.yaml") as fid:
raw = yaml.load(fid, Loader=yaml.Loader)
schema.validator(schema.environments_schema).validate(raw)
schema.environments_validator.validate(raw)
13 changes: 13 additions & 0 deletions unittests/yaml/config.defaults.v2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: 2
name: cuda-env
# store: /user-environment
spack:
repo: https://github.com/spack/spack.git
# commit: None
packages:
repo: https://github.com/spack/spack-packages.git
# commit: None
# mirror:
# key: None
# enable: True
# modules: True