Skip to content
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

Fix some validator-specific crashes #395

Merged
merged 11 commits into from
Jul 17, 2020
Merged
8 changes: 7 additions & 1 deletion optimade/models/entries.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@ class TypedRelationship(Relationship):
# This may be updated when moving to Python 3.8
@validator("data")
def check_rel_type(cls, data):
if hasattr(cls, "_req_type") and any(obj.type != cls._req_type for obj in data):
if not isinstance(data, list):
# All relationships at this point are empty-to-many relationships in JSON:API:
# https://jsonapi.org/format/1.0/#document-resource-object-linkage
raise ValueError("`data` key in a relationship must always store a list.")
ml-evs marked this conversation as resolved.
Show resolved Hide resolved
if hasattr(cls, "_req_type") and any(
getattr(obj, "type", None) != cls._req_type for obj in data
):
raise ValueError("Object stored in relationship data has wrong type")
return data

Expand Down
35 changes: 26 additions & 9 deletions optimade/validator/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@ def validate():
import traceback

parser = argparse.ArgumentParser(
prog="optimade_validator",
prog="optimade-validator",
description="""Tests OPTIMADE implementations for compliance with the optimade-python-tools models.

- To test an entire implementation (at say example.com/optimade/v1) for all required/available endpoints:

$ optimade_validator http://example.com/optimade/v1
$ optimade-validator http://example.com/optimade/v1

- To test a particular response of an implementation against a particular model:

$ optimade_validator http://example.com/optimade/v1/structures/id=1234 --as_type structure
$ optimade-validator http://example.com/optimade/v1/structures/id=1234 --as-type structure

- To test a particular response of an implementation against a particular model:

$ optimade_validator http://example.com/optimade/v1/structures --as_type structures
$ optimade-validator http://example.com/optimade/v1/structures --as-type structures
""",
formatter_class=argparse.RawDescriptionHelpFormatter,
)
Expand All @@ -39,24 +39,39 @@ def validate():
),
)
parser.add_argument(
ml-evs marked this conversation as resolved.
Show resolved Hide resolved
"--verbosity", "-v", type=int, default=0, help="The verbosity of the output"
"-v",
"--verbosity",
action="count",
default=0,
help="""Increase the verbosity of the output.""",
)
parser.add_argument(
"--as_type",
"-a",
"-t",
"--as-type",
type=str,
help=(
"Validate the request URL with the provided type, rather than scanning the entire implementation e.g. "
"optimade_validator `http://example.com/optimade/v1/structures/0 --as_type structure`"
"optimade-validator `http://example.com/optimade/v1/structures/0 --as-type structure`"
),
)
parser.add_argument(
"--index",
action="store_true",
help=(
"Flag for whether the specified OPTIMADE implementation is an Index meta-database or not. [default=False]"
"Flag for whether the specified OPTIMADE implementation is an Index meta-database or not."
),
)
parser.add_argument(
"--skip-optional",
action="store_true",
help=("Flag for whether the skip the tests of optional features."),
)

parser.add_argument(
"--fail-fast",
action="store_true",
help="Whether to exit on first test failure.",
)

args = vars(parser.parse_args())

Expand Down Expand Up @@ -84,6 +99,8 @@ def validate():
verbosity=args["verbosity"],
as_type=args["as_type"],
index=args["index"],
run_optional_tests=not args["skip_optional"],
fail_fast=args["fail_fast"],
)

try:
Expand Down
28 changes: 1 addition & 27 deletions optimade/validator/data/filters.txt
Original file line number Diff line number Diff line change
@@ -1,41 +1,15 @@
_exmpl1_bandgap<2.0 OR _exmpl2_bandgap<2.5
ml-evs marked this conversation as resolved.
Show resolved Hide resolved
NOT ( chemical_formula_hill = "Al" AND chemical_formula_anonymous = "A" OR chemical_formula_anonymous = "H2O" AND NOT chemical_formula_hill = "Ti" )
NOT ( chemical_formula_anonymous = "A" OR chemical_formula_anonymous = "H2O" )
nelements > 3
chemical_formula_hill = "H2O" AND chemical_formula_anonymous != "AB"
_exmpl_aax <= +.1e8 OR nelements >= 10 AND NOT ( _exmpl_x != "Some string" OR NOT _exmpl_a = 7)
_exmpl_spacegroup="P2"
_exmpl_cell_volume<100.0
_exmpl_bandgap > 5.0 AND _exmpl_molecular_weight < 350
_exmpl_melting_point<300 AND nelements=4 AND elements="Si,O2"
_exmpl_some_string_property = 42
5 < _exmpl_a
identifier CONTAINS x
identifier STARTS WITH x
identifier ENDS WITH x
chemical_formula_anonymous CONTAINS "C2" AND chemical_formula_anonymous STARTS WITH "A2"
chemical_formula_anonymous STARTS "B2" AND chemical_formula_anonymous ENDS WITH "D2"
list HAS value
list HAS ALL values
list HAS ANY values
list LENGTH value
NOT list HAS inverse
calculations.id HAS "calc-id-96"
authors.lastname HAS "Schmit"
identifier IS UNKNOWN
NOT identifier IS KNOWN
chemical_formula_hill IS KNOWN AND NOT chemical_formula_anonymous IS UNKNOWN
NOT a > b OR c = 100 AND f = "C2 H6"
(NOT (a > b)) OR ( (c = 100) AND (f = "C2 H6") )
a >= 0 AND NOT b < c OR c = 0
((a >= 0) AND (NOT (b < c))) OR (c = 0)
elements HAS ALL "Si", "Al", "O"
elements HAS ALL "Si", "Al", "O" AND elements LENGTH 3
nelements=4
nelements>=2 AND nelements<=7
chemical_formula_descriptive="(H2O)2 Na"
chemical_formula_descriptive CONTAINS "H2O"
chemical_formula_reduced="H2NaO"
chemical_formula_hill="H2O2"
chemical_formula_anonymous="A2B"
nsites=4
nsites>=2 AND nsites<=7