18
18
from dateutil .parser import isoparse
19
19
20
20
21
+ # TODO(elainewy): change this to benchmark.benchmark_regression_report once the table is created
21
22
BENCHMARK_REGRESSION_REPORT_TABLE = "fortesting.benchmark_regression_report"
23
+ BENCHMARK_REGRESSION_TRACKING_CONFIG_IDS = ["compiler_regression" ]
22
24
23
25
logging .basicConfig (
24
26
level = logging .INFO ,
33
35
"CLICKHOUSE_USERNAME" : os .getenv ("CLICKHOUSE_USERNAME" , "" ),
34
36
}
35
37
36
- # TODO(elainewy): change this to benchmark.benchmark_regression_report once the table is created
37
- BENCHMARK_REGRESSION_TRACKING_CONFIG_IDS = ["compiler_regression" ]
38
-
39
38
40
39
def format_ts_with_t (ts : int ) -> str :
41
40
return dt .datetime .fromtimestamp (ts , tz = dt .timezone .utc ).strftime (
@@ -54,7 +53,6 @@ def get_clickhouse_client(
54
53
return clickhouse_connect .get_client (
55
54
host = host , user = user , password = password , secure = True , verify = False
56
55
)
57
-
58
56
return clickhouse_connect .get_client (
59
57
host = host , user = user , password = password , secure = True
60
58
)
@@ -77,8 +75,10 @@ def __init__(
77
75
config_id : str ,
78
76
end_time : int ,
79
77
is_dry_run : bool = False ,
78
+ is_pass_check : bool = False ,
80
79
) -> None :
81
80
self .is_dry_run = is_dry_run
81
+ self .is_pass_check = is_pass_check
82
82
self .config_id = config_id
83
83
self .end_time = end_time
84
84
@@ -127,6 +127,7 @@ def process(
127
127
should_generate = self ._should_generate_report (
128
128
cc , self .end_time , self .config_id , report_freq
129
129
)
130
+
130
131
if not should_generate :
131
132
self .log_info (
132
133
"Skip generate report" ,
@@ -138,7 +139,6 @@ def process(
138
139
f"with frequency { report_freq .get_text ()} ..."
139
140
)
140
141
141
- self .log_info ("get target data" )
142
142
target , ls , le = self .get_target (config , self .end_time )
143
143
if not target :
144
144
self .log_info (
@@ -157,12 +157,11 @@ def process(
157
157
regression_report = generator .generate ()
158
158
if self .is_dry_run :
159
159
print (json .dumps (regression_report , indent = 2 , default = str ))
160
- return
161
-
162
160
reportManager = ReportManager (
163
161
config = config ,
164
162
regression_report = regression_report ,
165
163
db_table_name = BENCHMARK_REGRESSION_REPORT_TABLE ,
164
+ is_dry_run = self .is_dry_run ,
166
165
)
167
166
reportManager .run (cc , ENVS ["GITHUB_TOKEN" ])
168
167
return
@@ -172,7 +171,8 @@ def get_target(self, config: BenchmarkConfig, end_time: int):
172
171
target_s = end_time - data_range .comparison_timedelta_s ()
173
172
target_e = end_time
174
173
self .log_info (
175
- f"get baseline data for time range [{ format_ts_with_t (target_s )} ,{ format_ts_with_t (target_e )} ]"
174
+ "getting target data for time range "
175
+ f"[{ format_ts_with_t (target_s )} ,{ format_ts_with_t (target_e )} ] ..."
176
176
)
177
177
target_data = self ._fetch_from_benchmark_ts_api (
178
178
config_id = config .id ,
@@ -181,7 +181,7 @@ def get_target(self, config: BenchmarkConfig, end_time: int):
181
181
source = config .source ,
182
182
)
183
183
self .log_info (
184
- f"found { len (target_data .time_series )} # of data, with time range { target_data .time_range } " ,
184
+ f"done. found { len (target_data .time_series )} # of data groups , with time range { target_data .time_range } " ,
185
185
)
186
186
if not target_data .time_range or not target_data .time_range .end :
187
187
return None , target_s , target_e
@@ -196,7 +196,8 @@ def get_baseline(self, config: BenchmarkConfig, end_time: int):
196
196
baseline_s = end_time - data_range .total_timedelta_s ()
197
197
baseline_e = end_time - data_range .comparison_timedelta_s ()
198
198
self .log_info (
199
- f"get baseline data for time range [{ format_ts_with_t (baseline_s )} ,{ format_ts_with_t (baseline_e )} ]"
199
+ "getting baseline data for time range "
200
+ f"[{ format_ts_with_t (baseline_s )} ,{ format_ts_with_t (baseline_e )} ] ..."
200
201
)
201
202
# fetch baseline from api
202
203
raw_data = self ._fetch_from_benchmark_ts_api (
@@ -207,11 +208,7 @@ def get_baseline(self, config: BenchmarkConfig, end_time: int):
207
208
)
208
209
209
210
self .log_info (
210
- f"get baseline data for time range [{ format_ts_with_t (baseline_s )} ,{ format_ts_with_t (baseline_e )} ]"
211
- )
212
-
213
- self .log_info (
214
- f"found { len (raw_data .time_series )} # of data, with time range { raw_data .time_range } " ,
211
+ f"Done. found { len (raw_data .time_series )} # of data, with time range { raw_data .time_range } " ,
215
212
)
216
213
217
214
baseline_latest_ts = int (isoparse (raw_data .time_range .end ).timestamp ())
@@ -269,11 +266,8 @@ def _fetch_from_benchmark_ts_api(
269
266
)
270
267
271
268
elapsed_ms = (time .perf_counter () - t0 ) * 1000.0
272
- logger .info (
273
- "[%s] call OK in %.1f ms (query_len=%d)" ,
274
- config_id ,
275
- elapsed_ms ,
276
- len (query ),
269
+ self .log_info (
270
+ f"call OK in { elapsed_ms } ms (query_len={ len (query )} )" ,
277
271
)
278
272
return resp .data
279
273
except requests .exceptions .HTTPError as e :
@@ -290,7 +284,7 @@ def _fetch_from_benchmark_ts_api(
290
284
else str (e )
291
285
)
292
286
self .log_error (
293
- f"[ { config_id } ] call FAILED in { elapsed_ms } ms: { err_msg } " ,
287
+ f"call FAILED in { elapsed_ms } ms: { err_msg } " ,
294
288
)
295
289
raise
296
290
@@ -348,6 +342,12 @@ def _get_latest_record_ts(
348
342
f"time_boundary({ format_ts_with_t (time_boundary )} )"
349
343
f"based on latest_record_ts({ format_ts_with_t (latest_record_ts )} )" ,
350
344
)
345
+ # dry_run is True, is_pass_check is True, then we allow to generate report even the time check is not met
346
+ if self .is_dry_run and self .is_pass_check :
347
+ should_generate = True
348
+ self .log_info (
349
+ f"[{ f .get_text ()} ] dry_run is True, is_pass_check is True, force generate report for print only" ,
350
+ )
351
351
return should_generate
352
352
353
353
@@ -357,7 +357,12 @@ def main(
357
357
args : Optional [argparse .Namespace ] = None ,
358
358
* ,
359
359
is_dry_run : bool = False ,
360
+ is_forced : bool = False ,
360
361
):
362
+ if not is_dry_run and is_forced :
363
+ is_forced = False
364
+ logger .info ("is_dry_run is False, force must be disabled, this is not allowed" )
365
+
361
366
if not github_access_token :
362
367
raise ValueError ("Missing environment variable GITHUB_TOKEN" )
363
368
@@ -378,7 +383,10 @@ def main(
378
383
# caution, raise exception may lead lambda to retry
379
384
try :
380
385
processor = BenchmarkSummaryProcessor (
381
- config_id = config_id , end_time = end_time_ts , is_dry_run = is_dry_run
386
+ config_id = config_id ,
387
+ end_time = end_time_ts ,
388
+ is_dry_run = is_dry_run ,
389
+ is_pass_check = is_forced ,
382
390
)
383
391
processor .process (args = args )
384
392
except Exception as e :
@@ -419,6 +427,12 @@ def parse_args() -> argparse.Namespace:
419
427
action = "store_false" ,
420
428
help = "Disable dry-run mode" ,
421
429
)
430
+ parser .add_argument (
431
+ "--force" ,
432
+ dest = "force" ,
433
+ action = "store_true" ,
434
+ help = "Enable force mode, this only allowed when dry-run is enabled" ,
435
+ )
422
436
parser .add_argument (
423
437
"--config-id" ,
424
438
type = str ,
@@ -466,6 +480,7 @@ def local_run() -> None:
466
480
github_access_token = args .github_access_token ,
467
481
args = args ,
468
482
is_dry_run = args .dry_run ,
483
+ is_forced = args .force ,
469
484
)
470
485
471
486
0 commit comments