zephyr/scripts/sanity_chk/scl.py

73 lines
2.3 KiB
Python

#! /usr/bin/python
#
# SPDX-License-Identifier: Apache-2.0
# Zephyr's Sanity Check library
#
# Set of code that other projects can also import to do things on
# Zephyr's sanity check testcases.
import logging
import yaml
log = logging.getLogger("scl")
#
#
def yaml_load(filename):
"""
Safely load a YAML document
Follows recomendations from
https://security.openstack.org/guidelines/dg_avoid-dangerous-input-parsing-libraries.html.
:param str filename: filename to load
:raises yaml.scanner: On YAML scan issues
:raises: any other exception on file access erors
:return: dictionary representing the YAML document
"""
try:
with open(filename, 'r') as f:
return yaml.safe_load(f)
except yaml.scanner.ScannerError as e: # For errors parsing schema.yaml
mark = e.problem_mark
cmark = e.context_mark
log.error("%s:%d:%d: error: %s (note %s context @%s:%d:%d %s)",
mark.name, mark.line, mark.column, e.problem,
e.note, cmark.name, cmark.line, cmark.column, e.context)
raise
# If pykwalify is installed, then the validate functionw ill work --
# otherwise, it is a stub and we'd warn about it.
try:
import pykwalify.core
# Don't print error messages yourself, let us do it
logging.getLogger("pykwalify.core").setLevel(50)
def _yaml_validate(data, schema):
if not schema:
return
c = pykwalify.core.Core(source_data=data, schema_data=schema)
c.validate(raise_exception=True)
except ImportError as e:
log.warning("can't import pykwalify; won't validate YAML (%s)", e)
def _yaml_validate(data, schema):
pass
def yaml_load_verify(filename, schema):
"""
Safely load a testcase/sample yaml document and validate it
against the YAML schema, returing in case of success the YAML data.
:param str filename: name of the file to load and process
:param dict schema: loaded YAML schema (can load with :func:`yaml_load`)
# 'document.yaml' contains a single YAML document.
:raises yaml.scanner.ScannerError: on YAML parsing error
:raises pykwalify.errors.SchemaError: on Schema violation error
"""
# 'document.yaml' contains a single YAML document.
y = yaml_load(filename)
_yaml_validate(y, schema)
return y