Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import logging
from pathlib import Path
from xmlschema.etree import etree_tostring
from xmlschema import XMLSchema, XMLSchemaParseError
def BuildSchemaDictonary (fileList):
if len(fileList) == 0:
logging.info("No schema files provided")
return []
logging.info("Schema locations:")
schemaLocations = []
for schemaFile in fileList:
try:
xs = XMLSchema(schemaFile, validation='skip')
schemaLocations.append((xs.default_namespace, str(Path(schemaFile).resolve())))
logging.info(" [ {0} -> {1} ]".format(xs.default_namespace, schemaFile))
except XMLSchemaParseError as ex:
logging.warning (" [ {0} failed to parse: {1} ]".format(schemaFile, ex))
return schemaLocations
def BuildSchema (coreFile, fileList = None):
schemaLocations = []
if fileList and len(fileList) > 0:
schemaLocations = BuildSchemaDictonary(fileList)
coreSchema = XMLSchema(str(Path(coreFile)), locations=schemaLocations)
return coreSchema
def ValidateXSDFiles (fileList):
if len(fileList) == 0:
logging.info("No schema files provided")
return {}
schemaLocations = BuildSchemaDictonary(fileList)
errors = {}
logging.info("Schema validation:")
for schemaFile in fileList:
try:
schema = XMLSchema(schemaFile, locations = schemaLocations, validation="lax")
logging.info(schemaFile + ": OK")
errors[schemaFile] = [f"{etree_tostring(e.elem, e.namespaces, ' ', 20)} - {e.message}" for e in schema.all_errors]
except XMLSchemaParseError as ex:
logging.warning(schemaFile + ": Failed validation ({0})".format(ex.message))
if (ex.schema_url) and (ex.schema_url != ex.origin_url):
logging.warning(" Error comes from {0}, suppressing".format(ex.schema_url))
errors[schemaFile] = []
else:
errors[schemaFile] = [ex]
return errors
def ValidateAllXSDFilesInPath (path):
schemaGlob = [str(f) for f in Path(path).rglob("*.xsd")]
return ValidateXSDFiles(schemaGlob)
def ValidateInstanceDocuments (coreFile, supportingSchemas, instanceDocs):
if (instanceDocs is None) or len(instanceDocs) == 0:
logging.warning ("No instance documents provided")
return []
schema = BuildSchema(coreFile, supportingSchemas)
errors = []
for instanceDoc in instanceDocs:
try:
schema.validate(instanceDoc)
logging.info ("{0} passed validation".format(instanceDoc))
except Exception as ex:
logging.error ("{0} failed validation: {1}".format(instanceDoc, ex))
return errors
def processResults (results, stageName):
"""
Counts the number of errors and writes out the output per filename
:param results: List of filenames (str or Pathlib Path)
:param stageName: Name to decorate the output with
:returns: The number of files which had errors
"""
print("")
errorCount = sum([1 for r in results.values() if not r['ok']])
logging.info(f"{errorCount} {stageName} errors encountered")
print(f"{'-':-<60}")
print(f"{stageName} results:")
print(f"{'-':-<60}")
for filename, result in results.items():
print(f" {filename:.<55}{'..OK' if result['ok'] else 'FAIL'}")
if not result['ok']:
if isinstance(result['message'], list):
for thing in result['message']:
print(f" {thing['message']}")
else:
print(f" {result['message']}")
print(f"{'-':-<60}")
print(f"{stageName} errors: {errorCount}")
print(f"{'-':-<60}")
return errorCount
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG)
logging.info('Searching for XSD files')
fileList = list(Path(".").rglob("*.xsd")) + list(Path(".").rglob("*.xsd"))
logging.info(f'{len(fileList)} XSD files found')
for file in fileList:
logging.debug(f' {file}')
ignoreList = Path('testing/xsd_ignore.txt').read_text().splitlines()
ignoredFiles = []
for ignore in ignoreList:
logging.debug(f'Ignoring pattern {ignore}')
for file in fileList:
if ignore in str(file):
ignoredFiles.append(file)
logging.debug(f" Ignoring {str(file)} as contains {ignore}")
ignoredFiles = list(set(ignoredFiles))
logging.info(f'{len(ignoredFiles)} files ignored')
for file in ignoredFiles:
logging.debug(f' {file}')
fileList = [file for file in fileList if file not in ignoredFiles]
logging.info(f'{len(fileList)} files to process')
for file in fileList:
logging.debug(f' {file}')
if len(fileList) == 0:
logging.warning ("No files specified")
exit(0)
logging.info("Parsing ASN1 files")
parseResults = syntaxCheckXSD(fileList)
if processResults(parseResults, "Parsing") > 0:
exit(-1)
logging.info ("Getting compile targets")
compileTargets = json.loads(Path('testing/asn_compile_targets.json').read_text())
logging.info (f"{len(compileTargets)} compile targets found")
compileResults = compileAllTargets(compileTargets)
if processResults(compileResults, "Compiling") > 0:
exit(-1)