diff options
author | Matt Spinler <spinler@us.ibm.com> | 2019-09-27 13:51:36 -0500 |
---|---|---|
committer | Matt Spinler <spinler@us.ibm.com> | 2019-10-25 13:52:44 -0500 |
commit | 5cb5deb6ed44ff670115e249e80bd4c2a3b8c8d7 (patch) | |
tree | 022618447b5d594597db13e1775730feaf0fe538 /extensions/openpower-pels/registry | |
parent | a96a7948c39b400b0c2556ed2df0fb206d29b04d (diff) | |
download | phosphor-logging-5cb5deb6ed44ff670115e249e80bd4c2a3b8c8d7.tar.gz phosphor-logging-5cb5deb6ed44ff670115e249e80bd4c2a3b8c8d7.zip |
PEL: Script to validate message registry JSON
This script will check the JSON against the schema, as well as do a few
other checks that can't be encoded into a schema.
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I97c0fc0f69baac3c076b557b67e47ce8abfccf36
Diffstat (limited to 'extensions/openpower-pels/registry')
-rwxr-xr-x | extensions/openpower-pels/registry/tools/process_registry.py | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/extensions/openpower-pels/registry/tools/process_registry.py b/extensions/openpower-pels/registry/tools/process_registry.py new file mode 100755 index 0000000..3357c0d --- /dev/null +++ b/extensions/openpower-pels/registry/tools/process_registry.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python + +import argparse +import json +import sys + +r""" +Validates the PEL message registry JSON, which includes checking it against +a JSON schema using the jsonschema module as well as doing some extra checks +that can't be encoded in the schema. +""" + + +def check_duplicate_names(registry_json): + r""" + Check that there aren't any message registry entries with the same + 'Name' field. There may be a use case for this in the future, but there + isn't right now. + + registry_json: The message registry JSON + """ + + names = {} + for entry in registry_json['PELs']: + if entry['Name'] in names.keys(): + sys.exit("Found multiple uses of error {}".format(entry['Name'])) + else: + names[entry['Name']] = {} + + +def check_component_id(registry_json): + r""" + Check that the upper byte of the ComponentID field matches the upper byte + of the ReasonCode field, but not on "11" type SRCs where they aren't + supposed to match. + + registry_json: The message registry JSON + """ + + for entry in registry_json['PELs']: + + # Don't check on "11" SRCs as those reason codes aren't supposed to + # match the component ID. + if entry.get('Type', '') == "11": + continue + + if 'ComponentID' in entry: + id = int(entry['ComponentID'], 16) + reason_code = int(entry['SRC']['ReasonCode'], 16) + + if (id & 0xFF00) != (reason_code & 0xFF00): + sys.exit("Found mismatching component ID {} vs reason " + "code {} for error {}".format( + entry['ComponentID'], + entry['SRC']['ReasonCode'], + entry['Name'])) + + +def check_message_args(registry_json): + r""" + Check that if the Message field uses the '%' style placeholders that there + are that many entries in the MessageArgSources field. Also checks that + the MessageArgSources field is present but only if there are placeholders. + + registry_json: The message registry JSON + """ + + for entry in registry_json['PELs']: + num_placeholders = entry['Documentation']['Message'].count('%') + if num_placeholders == 0: + continue + + if 'MessageArgSources' not in entry['Documentation']: + sys.exit("Missing MessageArgSources property for error {}". + format(entry['Name'])) + + if num_placeholders != \ + len(entry['Documentation']['MessageArgSources']): + sys.exit("Different number of placeholders found in " + "Message vs MessageArgSources for error {}". + format(entry['Name'])) + + +def validate_schema(registry, schema): + r""" + Validates the passed in JSON against the passed in schema JSON + + registry: Path of the file containing the registry JSON + schema: Path of the file containing the schema JSON + Use None to skip the pure schema validation + """ + + with open(registry) as registry_handle: + registry_json = json.load(registry_handle) + + if schema: + + import jsonschema + + with open(schema) as schema_handle: + schema_json = json.load(schema_handle) + + try: + jsonschema.validate(registry_json, schema_json) + except jsonschema.ValidationError as e: + print(e) + sys.exit("Schema validation failed") + + check_duplicate_names(registry_json) + + check_component_id(registry_json) + + check_message_args(registry_json) + + +if __name__ == '__main__': + + parser = argparse.ArgumentParser( + description='PEL message registry processor') + + parser.add_argument('-v', '--validate', action='store_true', + dest='validate', + help='Validate the JSON using the schema') + + parser.add_argument('-s', '--schema-file', dest='schema_file', + help='The message registry JSON schema file') + + parser.add_argument('-r', '--registry-file', dest='registry_file', + help='The message registry JSON file') + parser.add_argument('-k', '--skip-schema-validation', action='store_true', + dest='skip_schema', + help='Skip running schema validation. ' + 'Only do the extra checks.') + + args = parser.parse_args() + + if args.validate: + if not args.schema_file: + sys.exit("Schema file required") + + if not args.registry_file: + sys.exit("Registry file required") + + schema = args.schema_file + if args.skip_schema: + schema = None + + validate_schema(args.registry_file, schema) |