Skip to content

Commit 2aa753c

Browse files
authored
Add automatic decoding of hashes in assert events (#284)
* Add automatic decoding for hashed files * make call location agnostic, remove shelling, add assert filtering * make assert filter more robust and extract code to helper * Remove build dependency, add --hash-file flag * add protections for incorrect paths or missing codes * make hash file detection more robust * make decoded filepaths absolute * simplify hashed file fetching and fix absolute path logic * Tweak/add --hash-file help content * replace HASH_FILE with FPRIME_HASHES_TXT_FILE * add empty list protection, remove absolute paths * remove Path dependency * Make HashFileParser more robust to missing args.deployment * Revert "Make HashFileParser more robust to missing args.deployment" This reverts commit 4084514. * remove HashFileParser from Comm * implement different HashFileParser inheritance strategy * fix typo
1 parent d3faac8 commit 2aa753c

File tree

3 files changed

+70
-1
lines changed

3 files changed

+70
-1
lines changed

src/fprime_gds/common/data_types/event_data.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from fprime_gds.common.data_types import sys_data
1313
from fprime_gds.common.utils.string_util import format_string_template
1414

15+
import os
1516

1617
class EventData(sys_data.SysData):
1718
"""
@@ -40,10 +41,20 @@ def __init__(self, event_args, event_time, event_temp):
4041
self.args = event_args
4142
self.time = event_time
4243
self.template = event_temp
44+
4345
if event_args is None:
4446
self.display_text = event_temp.description
45-
elif event_temp.format_str == "":
47+
return
48+
49+
if (
50+
(event_temp.name.startswith('AF_ASSERT') or event_temp.name == "AF_UNEXPECTED_ASSERT") and
51+
'FPRIME_HASHES_TXT_FILE' in os.environ
52+
):
53+
self._decode_hashed_files()
54+
55+
if event_temp.format_str == "":
4656
args_template = self.template.get_args()
57+
4758
self.display_text = str(
4859
[
4960
{args_template[index][0]: arg.val}
@@ -55,6 +66,28 @@ def __init__(self, event_args, event_time, event_temp):
5566
event_temp.format_str, tuple([arg.val for arg in event_args])
5667
)
5768

69+
def _decode_hashed_files(self):
70+
"Searches event args for hashed files and replaces each with its corresponding file name"
71+
72+
args_template = self.template.get_args()
73+
for index, arg in enumerate(self.args):
74+
75+
if not args_template[index]:
76+
continue
77+
if args_template[index][0] != 'file':
78+
continue
79+
try:
80+
hash_value = int(arg.val, 16)
81+
except ValueError:
82+
continue
83+
84+
hash_file = os.environ['FPRIME_HASHES_TXT_FILE']
85+
with open(hash_file) as file_handle:
86+
for line in file_handle:
87+
if hash_value == int(line.split(" ")[-1], 0):
88+
arg.val = line.split(':')[0].strip()
89+
break
90+
5891
def get_args(self):
5992
return self.args
6093

src/fprime_gds/executables/cli.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,6 +1045,39 @@ def handle_arguments(self, args, **kwargs):
10451045
return args
10461046

10471047

1048+
class HashFileParser(DictionaryParser):
1049+
"""Parser for detecting and loading the hashes.txt file for hash decoding"""
1050+
1051+
DESCRIPTION = "Hash file options"
1052+
1053+
def get_arguments(self)-> Dict[Tuple[str, ...], Dict[str, Any]]:
1054+
return {
1055+
("--hash-file",): {
1056+
"dest": "hash_file",
1057+
"action": "store",
1058+
"required": False,
1059+
"type": str,
1060+
"help": "Path to hashes.txt file map (found under build-artifacts dir by default)",
1061+
}
1062+
}
1063+
1064+
def handle_arguments(self, args, **kwargs):
1065+
if args.hash_file:
1066+
args.hash_file = Path(args.hash_file)
1067+
if not args.hash_file.exists():
1068+
msg = f"[ERROR] hash file location {args.hash_file} does not exist"
1069+
print(msg, file=sys.stderr)
1070+
sys.exit(-1)
1071+
return args
1072+
1073+
if args.deployment is None:
1074+
super().handle_arguments(args, **kwargs)
1075+
if args.deployment:
1076+
hash_file = (Path(args.deployment) / ".."/ ".." / "hashes.txt").resolve()
1077+
args.hash_file = hash_file if hash_file.exists() else None
1078+
return args
1079+
1080+
10481081
class FileHandlingParser(ParserBase):
10491082
"""Parser for deployments"""
10501083

@@ -1106,6 +1139,7 @@ class StandardPipelineParser(CompositeParser):
11061139

11071140
CONSTITUENTS = [
11081141
DictionaryParser,
1142+
HashFileParser,
11091143
FileHandlingParser,
11101144
MiddleWareParser,
11111145
LogDeployParser,

src/fprime_gds/executables/run_deployment.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ def launch_html(parsed_args):
124124
"SERVE_LOGS": "YES",
125125
}
126126
)
127+
if parsed_args.hash_file:
128+
flask_env.update({"FPRIME_HASHES_TXT_FILE": parsed_args.hash_file})
127129
gse_args = BASE_MODULE_ARGUMENTS + [
128130
"flask",
129131
"run",

0 commit comments

Comments
 (0)