Skip to content

Commit 1699065

Browse files
authored
Merge pull request #70 from NethermindEth/feat/add-end-time-to-reports
Add end time and duration to reports and DB
2 parents 0f600b0 + 0a0d114 commit 1699065

File tree

5 files changed

+148
-32
lines changed

5 files changed

+148
-32
lines changed

fill_postgres_db.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,8 +282,12 @@ def load_aggregated_stats(output_csv_path: str) -> Dict[str, Dict[str, Any]]:
282282
'p99_mgas_s': float(row['p99 (MGas/s)']) if row.get('p99 (MGas/s)') and row['p99 (MGas/s)'].strip() else None,
283283
'min_mgas_s': float(row['Min (MGas/s)']) if row.get('Min (MGas/s)') and row['Min (MGas/s)'].strip() else None,
284284
'n_samples': int(row['N']) if row.get('N') and row['N'].strip() else None,
285-
# Add timestamp fields if they exist
285+
# Add timestamp and duration fields if they exist
286286
'start_time': row.get('Start Time') if row.get('Start Time') else None,
287+
'end_time': row.get('End Time') if row.get('End Time') else None,
288+
'test_duration': float(row['Duration (ms)']) if row.get('Duration (ms)') and row['Duration (ms)'].strip() else None,
289+
'fcu_duration': float(row['FCU time (ms)']) if row.get('FCU time (ms)') and row['FCU time (ms)'].strip() else None,
290+
'np_duration': float(row['NP time (ms)']) if row.get('NP time (ms)') and row['NP time (ms)'].strip() else None,
287291
'test_description': row.get('Description')
288292
}
289293
except ValueError as ve:
@@ -472,6 +476,15 @@ def populate_data_for_client(
472476
start_time = agg_stats.get('start_time')
473477
if start_time in (0, "0", "", None):
474478
start_time = None
479+
480+
end_time = agg_stats.get('end_time')
481+
if end_time in (0, "0", "", None):
482+
end_time = None
483+
484+
test_duration = agg_stats.get('test_duration')
485+
fcu_duration = agg_stats.get('fcu_duration')
486+
np_duration = agg_stats.get('np_duration')
487+
475488
record: Dict[str, Any] = {
476489
'client_name': client_name,
477490
'client_version': client_version,
@@ -488,6 +501,10 @@ def populate_data_for_client(
488501
'raw_run_mgas_s': raw_run_mgas_s,
489502
'raw_run_description': raw_run_description, # This is from the raw data row
490503
'start_time': start_time,
504+
'end_time': end_time,
505+
'test_duration': test_duration,
506+
'fcu_duration': fcu_duration,
507+
'np_duration': np_duration,
491508
**computer_specs
492509
}
493510
records_to_insert.append(record)

generate_postgres_schema.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,12 @@ def get_sql_for_benchmark_table(table_name: str) -> str:
3737
raw_run_duration_ms REAL NULL, -- Execution duration in milliseconds for this specific run
3838
raw_run_description TEXT NULL, -- Description from the raw_*.csv row, potentially more specific
3939
40-
-- Test execution timestamps
40+
-- Test execution timestamps and durations
4141
start_time TIMESTAMP WITH TIME ZONE NULL, -- Test start timestamp
42+
end_time TIMESTAMP WITH TIME ZONE NULL, -- Test end timestamp
43+
test_duration REAL NULL, -- Test duration in milliseconds
44+
fcu_duration REAL NULL, -- FCU (engine_forkchoiceUpdatedV3) duration in milliseconds
45+
np_duration REAL NULL, -- NP (engine_newPayloadV4) duration in milliseconds
4246
4347
-- Computer Specifications (parsed from system info, repeated per row, all nullable)
4448
spec_processor_type TEXT NULL,
@@ -90,6 +94,10 @@ def execute_sql_on_db(db_params: Dict[str, Any], table_name: str) -> None:
9094
("client_version", "TEXT NULL"),
9195
("start_time", "TIMESTAMP WITH TIME ZONE NULL"),
9296
("raw_run_duration_ms", "REAL NULL"),
97+
("end_time", "TIMESTAMP WITH TIME ZONE NULL"),
98+
("test_duration", "REAL NULL"),
99+
("fcu_duration", "REAL NULL"),
100+
("np_duration", "REAL NULL"),
93101
# Add other columns here in the future for schema evolution
94102
# e.g., ("new_feature_flag", "BOOLEAN DEFAULT FALSE")
95103
]

report_html.py

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ def get_html_report(client_results, clients, results_paths, test_cases, methods,
7474
'<th>N</th>\n'
7575
'<th class=\"title\">Description</th>\n'
7676
'<th>Start Time</th>\n'
77+
'<th>End Time</th>\n'
78+
f'<th onclick="sortTable(10, \'table_{client}\', true)" style="cursor: pointer;">Duration (ms) &uarr; &darr;</th>\n'
79+
f'<th onclick="sortTable(11, \'table_{client}\', true)" style="cursor: pointer;">FCU time (ms) &uarr; &darr;</th>\n'
80+
f'<th onclick="sortTable(12, \'table_{client}\', true)" style="cursor: pointer;">NP time (ms) &uarr; &darr;</th>\n'
7781
'</tr>\n'
7882
'</thread>\n'
7983
'<tbody>\n')
@@ -88,7 +92,11 @@ def get_html_report(client_results, clients, results_paths, test_cases, methods,
8892
f'<td>{data[1]}</td>\n'
8993
f'<td>{data[6]}</td>\n'
9094
f'<td style="text-align:left;" >{data[7]}</td>\n'
91-
f'<td>{data[8]}</td>\n</tr>\n')
95+
f'<td>{data[8]}</td>\n'
96+
f'<td>{data[9]}</td>\n'
97+
f'<td>{data[10]}</td>\n'
98+
f'<td>{data[11]}</td>\n'
99+
f'<td>{data[12]}</td>\n</tr>\n')
92100
results_to_print += '\n'
93101
results_to_print += ('</table>\n'
94102
'</tbody>\n')
@@ -153,7 +161,7 @@ def get_html_report(client_results, clients, results_paths, test_cases, methods,
153161
print(formatted_html)
154162
if not os.path.exists('reports'):
155163
os.mkdir('reports')
156-
with open(f'reports/index.html', 'w') as file:
164+
with open('reports/index.html', 'w') as file:
157165
file.write(formatted_html)
158166

159167
for client, gas_table in csv_table.items():
@@ -162,9 +170,9 @@ def get_html_report(client_results, clients, results_paths, test_cases, methods,
162170
csvwriter = csv.writer(csvfile)
163171
csvwriter.writerow(
164172
['Title', 'Max (MGas/s)', 'p50 (MGas/s)', 'p95 (MGas/s)', 'p99 (MGas/s)', 'Min (MGas/s)', 'N',
165-
'Description', "Start Time"])
173+
'Description', "Start Time", "End Time", "Duration (ms)", "FCU time (ms)", "NP time (ms)"])
166174
for test_case, data in gas_table.items():
167-
csvwriter.writerow([data[0], data[2], data[3], data[4], data[5], data[1], data[6], data[7], data[8]])
175+
csvwriter.writerow([data[0], data[2], data[3], data[4], data[5], data[1], data[6], data[7], data[8], data[9], data[10], data[11], data[12]])
168176

169177

170178
def main():
@@ -213,16 +221,31 @@ def main():
213221
client_results[client][test_case_name][gas][method] = []
214222
failed_tests[client][test_case_name][gas][method] = []
215223
for run in range(1, runs + 1):
216-
responses, results, timestamp = utils.extract_response_and_result(results_paths, client, test_case_name,
224+
responses, results, timestamp, duration, fcu_duration, np_duration = utils.extract_response_and_result(results_paths, client, test_case_name,
217225
gas, run, method, fields)
218226
client_results[client][test_case_name][gas][method].append(results)
219227
failed_tests[client][test_case_name][gas][method].append(not responses)
220228
# print(test_case_name + " : " + str(timestamp))
221229
if str(timestamp) != "0":
222-
client_results[client][test_case_name]["timestamp"] = utils.convert_dotnet_ticks_to_utc(timestamp)
230+
# Store raw timestamp in ticks for calculation, not converted string
231+
client_results[client][test_case_name]["timestamp_ticks"] = timestamp
232+
# Only store duration if non-zero to avoid overwriting valid values
233+
if duration != 0:
234+
client_results[client][test_case_name]["duration"] = duration
235+
if fcu_duration != 0:
236+
client_results[client][test_case_name]["fcu_duration"] = fcu_duration
237+
if np_duration != 0:
238+
client_results[client][test_case_name]["np_duration"] = np_duration
223239
else:
224-
if "timestamp" not in str(client_results[client][test_case_name]):
225-
client_results[client][test_case_name]["timestamp"] = 0
240+
if "timestamp_ticks" not in client_results[client][test_case_name]:
241+
client_results[client][test_case_name]["timestamp_ticks"] = 0
242+
# Initialize duration to 0 only if not set yet
243+
if "duration" not in client_results[client][test_case_name]:
244+
client_results[client][test_case_name]["duration"] = 0
245+
if "fcu_duration" not in client_results[client][test_case_name]:
246+
client_results[client][test_case_name]["fcu_duration"] = 0
247+
if "np_duration" not in client_results[client][test_case_name]:
248+
client_results[client][test_case_name]["np_duration"] = 0
226249

227250
gas_set = set()
228251
for test_case_name, test_case_gas in test_cases.items():

report_tables.py

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def get_table_report(client_results, clients, results_paths, test_cases, methods
2323
image_to_print = el_images[client_without_tag]
2424
results_to_print += f'{client.capitalize()} - {image_to_print} - Benchmarking Report' + '\n'
2525
results_to_print += (center_string('Title',
26-
68) + '| Min (MGas/s) | Max (MGas/s) | p50 (MGas/s) | p95 (MGas/s) | p99 (MGas/s) | N | Description | Start time\n')
26+
68) + '| Min (MGas/s) | Max (MGas/s) | p50 (MGas/s) | p95 (MGas/s) | p99 (MGas/s) | N | Description | Start time | End time | Duration (ms) | FCU time (ms) | NP time (ms)\n')
2727
gas_table_norm = utils.get_gas_table(client_results, client, test_cases, gas_set, methods[0], metadata)
2828
for test_case, data in gas_table_norm.items():
2929
results_to_print += (f'{align_left_string(data[0], 68)}|'
@@ -34,13 +34,17 @@ def get_table_report(client_results, clients, results_paths, test_cases, methods
3434
f'{center_string(data[5], 14)}|'
3535
f'{center_string(data[6], 7)}|'
3636
f'{align_left_string(data[7], 50)}|'
37-
f'{data[8]}\n')
37+
f'{data[8]}|'
38+
f'{data[9]}|'
39+
f'{center_string(data[10], 14)}|'
40+
f'{center_string(data[11], 15)}|'
41+
f'{center_string(data[12], 14)}\n')
3842
results_to_print += '\n'
3943

4044
print(results_to_print)
4145
if not os.path.exists('reports'):
4246
os.mkdir('reports')
43-
with open(f'reports/tables_norm.txt', 'w') as file:
47+
with open('reports/tables_norm.txt', 'w') as file:
4448
file.write(results_to_print)
4549

4650

@@ -105,16 +109,31 @@ def main():
105109
client_results[client][test_case_name][gas][method] = []
106110
failed_tests[client][test_case_name][gas][method] = []
107111
for run in range(1, runs + 1):
108-
responses, results, timestamp = utils.extract_response_and_result(results_paths, client, test_case_name,
112+
responses, results, timestamp, duration, fcu_duration, np_duration = utils.extract_response_and_result(results_paths, client, test_case_name,
109113
gas, run, method, fields)
110114
client_results[client][test_case_name][gas][method].append(results)
111115
failed_tests[client][test_case_name][gas][method].append(not responses)
112116
# print(test_case_name + " : " + str(timestamp))
113117
if str(timestamp) != "0":
114-
client_results[client][test_case_name]["timestamp"] = utils.convert_dotnet_ticks_to_utc(timestamp)
118+
# Store raw timestamp in ticks for calculation, not converted string
119+
client_results[client][test_case_name]["timestamp_ticks"] = timestamp
120+
# Only store duration if non-zero to avoid overwriting valid values
121+
if duration != 0:
122+
client_results[client][test_case_name]["duration"] = duration
123+
if fcu_duration != 0:
124+
client_results[client][test_case_name]["fcu_duration"] = fcu_duration
125+
if np_duration != 0:
126+
client_results[client][test_case_name]["np_duration"] = np_duration
115127
else:
116-
if "timestamp" not in client_results[client][test_case_name]:
117-
client_results[client][test_case_name]["timestamp"] = 0
128+
if "timestamp_ticks" not in client_results[client][test_case_name]:
129+
client_results[client][test_case_name]["timestamp_ticks"] = 0
130+
# Initialize duration to 0 only if not set yet
131+
if "duration" not in client_results[client][test_case_name]:
132+
client_results[client][test_case_name]["duration"] = 0
133+
if "fcu_duration" not in client_results[client][test_case_name]:
134+
client_results[client][test_case_name]["fcu_duration"] = 0
135+
if "np_duration" not in client_results[client][test_case_name]:
136+
client_results[client][test_case_name]["np_duration"] = 0
118137

119138

120139
gas_set = set()

0 commit comments

Comments
 (0)