Esempio n. 1
0
def _validate(database: Mapping[str, Any], schemaPath: str) -> None:
	"""
	Validates a database against a schema.

	Note:
		The `jsonschema` library validates python data structures directly and
		produces nice error messages, but validation is slow.
		The `rapidjson` library validates much faster, however it produces poor error messages.
		For this reason rapidjson is used for the initial
		validation, and jsonschema is used if there is a failure.

	Args:
		database: The database to be validated.
		schemaPath: The location of the schema.
	"""
	with open(schemaPath, "r", encoding="utf-8") as fileObj:
		schema: Dict[str, Any] = json.load(fileObj)
	validate: Callable[[str], None] = rapidjson.Validator(rapidjson.dumps(schema))
	try:
		validate(rapidjson.dumps(database))
	except rapidjson.ValidationError as rapidjsonExc:
		try:
			jsonschema.validate(database, schema)
		except jsonschema.ValidationError as jsonschemaExc:
			raise SchemaValidationError(str(jsonschemaExc)) from jsonschemaExc
		else:
			logger.warning(
				f"Error: jsonschema did not raise an exception, whereas rapidjson raised {rapidjsonExc}."
			)
			raise SchemaValidationError(str(rapidjsonExc)) from rapidjsonExc
Esempio n. 2
0
def _load_schema(name, path=__file__):
    """Load a schema from disk"""
    path = os.path.join(os.path.dirname(path), name + '.yaml')
    with open(path) as handle:
        schema = yaml.safe_load(handle)
    fast_schema = rapidjson.Validator(rapidjson.dumps(schema))
    return path, (schema, fast_schema)
Esempio n. 3
0
def load_schemas(path):
    """return a dictionary containing "{namespace}.{doctype}.{doctype}" to validator"""
    schemas = {}
    for root, _, files in os.walk(path):
        for name in files:
            if name.endswith(".schema.json"):
                schemafile = os.path.join(root, name)
                name = parse_schema_name(schemafile)
                with open(schemafile, "r") as f:
                    schemas[name] = rapidjson.Validator(f.read())
    return schemas
Esempio n. 4
0
    def _validate(self, candidate):
        """Checks whether a legend is valid or not.

        Args:
            candidate (dict): Candidate legend.
        
        Raises:
            Exception if legend does not fit the schmea
        """

        validate = rapidjson.Validator(self.schema)
        validate(rapidjson.dumps(candidate))
        return candidate
Esempio n. 5
0
    def save(path, result):
        try:
            validate = json.Validator(json.dumps(REPORT_SCHEMA))
            validate(json.dumps(result))
        except ValueError as error:
            print(error.args)
            exit(-1)

        os.makedirs(os.path.dirname(path), exist_ok=True)

        print("Writing to {}".format(path))
        with open(path, 'w') as f:
            json.dump(result, f, indent=4, sort_keys=True)
Esempio n. 6
0
def load_namespace(base, namespace):
    """Return a dictionary of all files with the `*.schema.json` suffix.

    Namespaces help differentiate ingestion systems. For example, `telemetry`
    refers to pings generated by various Firefox products. Other namespaced
    ingestion pipelines may exists due to generic ingestion.
    """
    schemas = dict()
    for root, _, files in os.walk(os.path.join(base, namespace)):
        for name in files:
            if not name.endswith(".schema.json"):
                continue
            with open(os.path.join(root, name), "r") as f:
                key = name.split(".schema.json")[0]
                schemas[key] = rapidjson.Validator(f.read())
                print("Registered {}.{} ".format(namespace, key))
    return schemas
def test_failed_validation():
    tracemalloc.start()

    schema = """{
        "$schema": "http://json-schema.org/draft-04/schema#",
        "required": ["id", "name"],
        "type": "object",
        "properties": {
            "id": {"type": "integer"},
            "name": {"type": "string"}
        }
    }""".encode("utf-8")

    obj = """{
        "id": 50
    }""".encode("utf-8")

    validate = rj.Validator(schema)

    snapshot1 = tracemalloc.take_snapshot().filter_traces(
        (tracemalloc.Filter(True, __file__), ))

    # start the test
    for j in range(1000):
        try:
            validate(obj)
        except rj.ValidationError:
            pass

    del j

    gc.collect()

    snapshot2 = tracemalloc.take_snapshot().filter_traces(
        (tracemalloc.Filter(True, __file__), ))

    top_stats = snapshot2.compare_to(snapshot1, 'lineno')
    tracemalloc.stop()

    for stat in top_stats[:10]:
        assert stat.count_diff < 3
Esempio n. 8
0
def test_invalid(schema, json, details):
    validate = rj.Validator(schema)
    with pytest.raises(ValueError) as error:
        validate(json)
    assert error.value.args == details
Esempio n. 9
0
def test_valid(schema, json):
    validate = rj.Validator(schema)
    validate(json)
Esempio n. 10
0
def test_invalid_json():
    validate = rj.Validator('""')
    pytest.raises(ValueError, validate, '')
    pytest.raises(ValueError, validate, '"')
def test_additional_and_pattern_properties_valid(schema, json):
    validate = rj.Validator(schema)
    validate(json)
def test_invalid_json():
    validate = rj.Validator('""')
    pytest.raises(rj.JSONDecodeError, validate, '')
    pytest.raises(rj.JSONDecodeError, validate, '"')