Skip to content

Commit 5516268

Browse files
authored
Validator quality update (#25)
* Change testing trace * Removed version definition PyYaml * Use trace with 50 messages * Update osi version * Added black code formatter * Added vulture and removed unused variables * Removed redundant code and added explicit folders for vulture
1 parent e294a86 commit 5516268

35 files changed

+844
-984
lines changed

.travis.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ script:
3434
- python -m site
3535
- protoc --version
3636

37+
# Install black code formatter and check if it is applied
38+
- pip install black
39+
- black --check --exclude "(open-simulation-interface|proto2cpp)" .
40+
41+
# Install vulture and search for dead code with 100% confidence
42+
- pip install vulture
43+
- vulture *.py tests/ osivalidator/ --min-confidence 100
44+
3745
# Install osi-validation
3846
- cd open-simulation-interface
3947
- pip install .
@@ -43,9 +51,6 @@ script:
4351
# Generate parsed rules
4452
- python rules2yml.py -d rules
4553

46-
# Check if rule syntax in osi is correct
47-
# - python test_cases.py
48-
4954
# Show validator usage
5055
- osivalidator -h
5156

data/small_test.txt.lzma

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:b572e8d38c1ff03c6e58168e99be5560ca310c1052a6e9c20f74432b46547314
3-
size 130010
2+
oid sha256:97d4efda5888898a82044e2093ee605bade75290038afaf9a03d7bceecc91d98
3+
size 442

osivalidator/linked_proto_field.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,10 @@ def get_field(self, field_name):
9393

9494
field = getattr(self.value, field_name)
9595

96-
if (hasattr(self.value, 'DESCRIPTOR') and
97-
self.value.DESCRIPTOR.fields_by_name[field_name].label == 3):
96+
if (
97+
hasattr(self.value, "DESCRIPTOR")
98+
and self.value.DESCRIPTOR.fields_by_name[field_name].label == 3
99+
):
98100
return [
99101
LinkedProtoField(u_field, parent=self, name=field_name)
100102
for u_field in field

osivalidator/osi_doxygen_xml.py

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,18 @@ class OSIDoxygenXML:
2121
def __init__(self):
2222
dir_path = os.path.dirname(os.path.realpath(__file__))
2323
osivalidator_path = os.path.dirname(dir_path)
24-
self.osi_path = os.path.join(
25-
osivalidator_path, 'open-simulation-interface')
26-
self.osi_doc_path = os.path.join(self.osi_path, 'doc')
24+
self.osi_path = os.path.join(osivalidator_path, "open-simulation-interface")
25+
self.osi_doc_path = os.path.join(self.osi_path, "doc")
2726

28-
proto2cpp_path = os.path.join(osivalidator_path, 'proto2cpp')
27+
proto2cpp_path = os.path.join(osivalidator_path, "proto2cpp")
2928
self.proto2cpp_file_path = os.path.join(proto2cpp_path, "proto2cpp.py")
3029

3130
def generate_osi_doxygen_xml(self):
3231
"""
3332
Generate the Doxygen XML documentation in the OSI path
3433
"""
3534

36-
configuration = f'''
35+
configuration = f"""
3736
PROJECT_NAME = osi-validation
3837
INPUT = {self.osi_path}
3938
OUTPUT_DIRECTORY = {self.osi_doc_path}
@@ -48,10 +47,10 @@ def generate_osi_doxygen_xml(self):
4847
XML_PROGRAMLISTING = NO
4948
ALIASES = rules="<pre class=\"rules\">"
5049
ALIASES += endrules="</pre>"
51-
'''
50+
"""
5251

53-
doxyfile_path = os.path.join(self.osi_path, 'Doxyfile_validation')
54-
doxyfile = open(doxyfile_path, 'w')
52+
doxyfile_path = os.path.join(self.osi_path, "Doxyfile_validation")
53+
doxyfile = open(doxyfile_path, "w")
5554
doxyfile.write(configuration)
5655
doxyfile.close()
5756

@@ -65,7 +64,7 @@ def get_files(self):
6564
"""
6665
Return the path of the fields in OSI
6766
"""
68-
return glob.glob(os.path.join(self.osi_path, 'doc', 'xml', '*.xml'))
67+
return glob.glob(os.path.join(self.osi_path, "doc", "xml", "*.xml"))
6968

7069
def parse_rules(self):
7170
"""
@@ -78,19 +77,20 @@ def parse_rules(self):
7877
for xml_file in xml_files:
7978
tree = ET.parse(xml_file)
8079
memberdefs = tree.findall(
81-
"./compounddef/sectiondef/memberdef[@kind='variable']")
80+
"./compounddef/sectiondef/memberdef[@kind='variable']"
81+
)
8282
for memberdef in memberdefs:
83-
attr_path = memberdef.findtext(
84-
'definition').split()[-1].split('::')
85-
if attr_path[0] != 'osi3':
83+
attr_path = memberdef.findtext("definition").split()[-1].split("::")
84+
if attr_path[0] != "osi3":
8685
continue
8786
attr_path.pop(0)
8887
attr_rule = memberdef.findtext(
89-
'./detaileddescription//preformatted[last()]')
88+
"./detaileddescription//preformatted[last()]"
89+
)
9090
if not attr_rule:
9191
continue
9292

93-
rules_lines = attr_rule.split('\n')
93+
rules_lines = attr_rule.split("\n")
9494

9595
for line_no, line in enumerate(rules_lines):
9696
if line.find(":") == -1 and line:
@@ -100,14 +100,13 @@ def parse_rules(self):
100100

101101
try:
102102
dict_rules = yaml.safe_load(attr_rule)
103-
except (yaml.parser.ParserError,
104-
yaml.parser.ScannerError) as error:
103+
except (yaml.parser.ParserError, yaml.parser.ScannerError) as error:
105104
print(attr_path, attr_rule, error)
106105
else:
107106
rules.append((attr_path, dict_rules))
108107
return rules
109108

110109

111-
if __name__ == '__main__':
110+
if __name__ == "__main__":
112111
osidx = OSIDoxygenXML()
113112
osidx.generate_osi_doxygen_xml()

osivalidator/osi_general_validator.py

Lines changed: 95 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -13,70 +13,95 @@
1313
from osivalidator.osi_trace import OSITrace
1414
from osivalidator.osi_rules_checker import OSIRulesChecker
1515

16+
1617
def check_positive_int(value):
1718
ivalue = int(value)
1819
if ivalue < 0:
1920
raise argparse.ArgumentTypeError("%s is an invalid positive int value" % value)
2021
return ivalue
2122

23+
2224
def command_line_arguments():
2325
""" Define and handle command line interface """
2426

2527
dir_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
2628

2729
parser = argparse.ArgumentParser(
28-
description='Validate data defined at the input',
29-
prog='osivalidator')
30-
parser.add_argument('data',
31-
help='Path to the file with OSI-serialized data.',
32-
type=str)
33-
parser.add_argument('--rules', '-r',
34-
help='Directory with text files containig rules. ',
35-
default=os.path.join(dir_path, 'requirements-osi-3'),
36-
type=str)
37-
parser.add_argument('--type', '-t',
38-
help='Name of the type used to serialize data.',
39-
choices=['SensorView', 'GroundTruth', 'SensorData'],
40-
default='SensorView',
41-
type=str,
42-
required=False)
43-
parser.add_argument('--output', '-o',
44-
help='Output folder of the log files.',
45-
default='output_logs',
46-
type=str,
47-
required=False)
48-
parser.add_argument('--timesteps',
49-
help='Number of timesteps to analyze. If -1, all.',
50-
type=int,
51-
default=-1,
52-
required=False)
53-
parser.add_argument('--debug',
54-
help='Set the debug mode to ON.',
55-
action="store_true")
56-
parser.add_argument('--verbose', '-v',
57-
help='Set the verbose mode to ON.',
58-
action="store_true")
59-
parser.add_argument('--parallel', '-p',
60-
help='Set parallel mode to ON.',
61-
default=False,
62-
required=False,
63-
action="store_true")
64-
parser.add_argument('--format', '-f',
65-
help='Set the format type of the trace.',
66-
choices=['separated', None],
67-
default=None,
68-
type=str,
69-
required=False)
70-
parser.add_argument('--blast', '-bl',
71-
help='Set the in-memory storage count of OSI messages during validation.',
72-
default=500,
73-
type=check_positive_int,
74-
required=False)
75-
parser.add_argument('--buffer', '-bu',
76-
help='Set the buffer size to retrieve OSI messages from trace file. Set it to 0 if you do not want to use buffering at all.',
77-
default=1000000,
78-
type=check_positive_int,
79-
required=False)
30+
description="Validate data defined at the input", prog="osivalidator"
31+
)
32+
parser.add_argument(
33+
"data", help="Path to the file with OSI-serialized data.", type=str
34+
)
35+
parser.add_argument(
36+
"--rules",
37+
"-r",
38+
help="Directory with text files containig rules. ",
39+
default=os.path.join(dir_path, "requirements-osi-3"),
40+
type=str,
41+
)
42+
parser.add_argument(
43+
"--type",
44+
"-t",
45+
help="Name of the type used to serialize data.",
46+
choices=["SensorView", "GroundTruth", "SensorData"],
47+
default="SensorView",
48+
type=str,
49+
required=False,
50+
)
51+
parser.add_argument(
52+
"--output",
53+
"-o",
54+
help="Output folder of the log files.",
55+
default="output_logs",
56+
type=str,
57+
required=False,
58+
)
59+
parser.add_argument(
60+
"--timesteps",
61+
help="Number of timesteps to analyze. If -1, all.",
62+
type=int,
63+
default=-1,
64+
required=False,
65+
)
66+
parser.add_argument(
67+
"--debug", help="Set the debug mode to ON.", action="store_true"
68+
)
69+
parser.add_argument(
70+
"--verbose", "-v", help="Set the verbose mode to ON.", action="store_true"
71+
)
72+
parser.add_argument(
73+
"--parallel",
74+
"-p",
75+
help="Set parallel mode to ON.",
76+
default=False,
77+
required=False,
78+
action="store_true",
79+
)
80+
parser.add_argument(
81+
"--format",
82+
"-f",
83+
help="Set the format type of the trace.",
84+
choices=["separated", None],
85+
default=None,
86+
type=str,
87+
required=False,
88+
)
89+
parser.add_argument(
90+
"--blast",
91+
"-bl",
92+
help="Set the in-memory storage count of OSI messages during validation.",
93+
default=500,
94+
type=check_positive_int,
95+
required=False,
96+
)
97+
parser.add_argument(
98+
"--buffer",
99+
"-bu",
100+
help="Set the buffer size to retrieve OSI messages from trace file. Set it to 0 if you do not want to use buffering at all.",
101+
default=1000000,
102+
type=check_positive_int,
103+
required=False,
104+
)
80105

81106
return parser.parse_args()
82107

@@ -88,10 +113,11 @@ def command_line_arguments():
88113
LOGGER = OSIValidatorLogger()
89114
VALIDATION_RULES = OSIRules()
90115
ID_TO_TS = MANAGER.dict()
91-
BAR_SUFFIX = '%(index)d/%(max)d [%(elapsed_td)s]'
92-
BAR = Bar('', suffix=BAR_SUFFIX)
116+
BAR_SUFFIX = "%(index)d/%(max)d [%(elapsed_td)s]"
117+
BAR = Bar("", suffix=BAR_SUFFIX)
93118
MESSAGE_CACHE = MANAGER.dict()
94119

120+
95121
def main():
96122
"""Main method"""
97123

@@ -112,7 +138,12 @@ def main():
112138
# Read data
113139
print("Reading data ...")
114140
DATA = OSITrace(buffer_size=args.buffer)
115-
DATA.from_file(path=args.data, type_name=args.type, max_index=args.timesteps, format_type=args.format)
141+
DATA.from_file(
142+
path=args.data,
143+
type_name=args.type,
144+
max_index=args.timesteps,
145+
format_type=args.format,
146+
)
116147

117148
# Collect Validation Rules
118149
print("Collect validation rules ...")
@@ -138,7 +169,7 @@ def main():
138169

139170
# Increment the max-timestep to analyze
140171
max_timestep_blast += args.blast
141-
first_of_blast = (max_timestep_blast-args.blast)
172+
first_of_blast = max_timestep_blast - args.blast
142173
last_of_blast = min(max_timestep_blast, max_timestep)
143174

144175
# Cache messages
@@ -148,9 +179,9 @@ def main():
148179
if args.parallel:
149180
# Launch parallel computation
150181
# Recreate the pool
151-
try:
182+
try:
152183
pool = Pool()
153-
pool.map(process_timestep, range(first_of_blast, last_of_blast))
184+
pool.map(process_timestep, range(first_of_blast, last_of_blast))
154185

155186
except Exception as e:
156187
print(str(e))
@@ -163,7 +194,7 @@ def main():
163194
try:
164195
for i in range(first_of_blast, last_of_blast):
165196
process_timestep(i)
166-
197+
167198
except Exception as e:
168199
print(str(e))
169200

@@ -176,6 +207,7 @@ def main():
176207
# Synthetize
177208
LOGGER.synthetize_results_from_sqlite()
178209

210+
179211
def close_pool(pool):
180212
"""Cleanly close a pool to free the memory"""
181213
pool.close()
@@ -192,7 +224,7 @@ def process_timestep(timestep):
192224

193225
LOGGER.log_messages[timestep] = []
194226
LOGGER.debug_messages[timestep] = []
195-
LOGGER.info(None, f'Analyze message of timestamp {timestamp}', False)
227+
LOGGER.info(None, f"Analyze message of timestamp {timestamp}", False)
196228

197229
# Check if timestamp already exists
198230
if timestamp in TIMESTAMP_ANALYZED:
@@ -202,8 +234,9 @@ def process_timestep(timestep):
202234
BAR.goto(len(TIMESTAMP_ANALYZED))
203235

204236
# Check common rules
205-
getattr(rule_checker, 'is_valid')(
206-
message, VALIDATION_RULES.get_rules().get_type(MESSAGE_TYPE.value))
237+
getattr(rule_checker, "is_valid")(
238+
message, VALIDATION_RULES.get_rules().get_type(MESSAGE_TYPE.value)
239+
)
207240

208241
LOGS.extend(LOGGER.log_messages[timestep])
209242

0 commit comments

Comments
 (0)