Skip to content

Commit c3766c6

Browse files
feat: enhance run-remote robustness and reliability
• Fixed massive variance blocking regression detection - Added proper variance-based validation that prevents false positives when latency data is too unstable for reliable analysis • Fixed missing test links in performance summaries - Corrected regression counting logic so clickable Grafana links appear in bullet lists for confirmed regressions • Added conditional AWS credentials checking - Credentials are only required when actually needed (for infrastructure deployment or S3 upload, not when using existing infrastructure with --inventory) • Added automatic tool installation - Missing dependencies like redis-server, zip, and memtier_benchmark are automatically installed on remote nodes using official Redis APT repository • Enhanced S3 upload error handling - Upload failures don't crash the process but continue with warnings, ensuring benchmark results are preserved locally even when S3 is unavailable These changes make run-remote much more robust, user-friendly, and reliable by eliminating false regression alerts, providing better diagnostic information, reducing setup requirements, and gracefully handling common failure scenarios.
1 parent 45a8bbd commit c3766c6

File tree

18 files changed

+936
-376
lines changed

18 files changed

+936
-376
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "redisbench-admin"
3-
version = "0.11.38"
3+
version = "0.11.39"
44
description = "Redis benchmark run helper. A wrapper around Redis and Redis Modules benchmark tools ( ftsb_redisearch, memtier_benchmark, redis-benchmark, aibench, etc... )."
55
authors = ["filipecosta90 <[email protected]>","Redis Performance Group <[email protected]>"]
66
readme = "README.md"

redisbench_admin/compare/compare.py

Lines changed: 582 additions & 201 deletions
Large diffs are not rendered by default.

redisbench_admin/deploy/deploy.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,7 @@ def deploy_command_logic(args, project_name, project_version):
7373
tf_triggering_env = "redisbench-admin-deploy"
7474
logging.info("Setting an infra timeout of {} secs".format(infra_timeout_secs))
7575
if args.destroy is False:
76-
(
77-
tf_return_code,
78-
_,
79-
_,
80-
_,
81-
_,
82-
_,
83-
_,
84-
) = setup_remote_environment(
76+
(tf_return_code, _, _, _, _, _, _,) = setup_remote_environment(
8577
tf,
8678
tf_github_sha,
8779
tf_github_actor,

redisbench_admin/export/export.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,7 @@ def export_command_logic(args, project_name, project_version):
4242
deployment_name = args.deployment_name
4343
deployment_type = args.deployment_type
4444
results_format = args.results_format
45-
(
46-
_,
47-
github_branch,
48-
github_org,
49-
github_repo,
50-
_,
51-
) = git_vars_crosscheck(
45+
(_, github_branch, github_org, github_repo, _,) = git_vars_crosscheck(
5246
None, args.github_branch, args.github_org, args.github_repo, None
5347
)
5448
exporter_timemetric_path = None

redisbench_admin/profilers/perf.py

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -400,9 +400,9 @@ def generate_outputs(self, use_case, **kwargs):
400400
"Main THREAD Flame Graph: " + use_case, details
401401
)
402402
if artifact_result is True:
403-
outputs["Main THREAD Flame Graph {}".format(identifier)] = (
404-
flame_graph_output
405-
)
403+
outputs[
404+
"Main THREAD Flame Graph {}".format(identifier)
405+
] = flame_graph_output
406406
result &= artifact_result
407407

408408
tid = self.pid
@@ -440,9 +440,9 @@ def generate_outputs(self, use_case, **kwargs):
440440
)
441441

442442
if artifact_result is True:
443-
outputs["perf report per dso,sym {}".format(identifier)] = (
444-
perf_report_artifact
445-
)
443+
outputs[
444+
"perf report per dso,sym {}".format(identifier)
445+
] = perf_report_artifact
446446
result &= artifact_result
447447

448448
# generate perf report per dso,sym
@@ -460,9 +460,9 @@ def generate_outputs(self, use_case, **kwargs):
460460
)
461461

462462
if artifact_result is True:
463-
outputs["perf report per dso,sym with callgraph {}".format(identifier)] = (
464-
perf_report_artifact
465-
)
463+
outputs[
464+
"perf report per dso,sym with callgraph {}".format(identifier)
465+
] = perf_report_artifact
466466
result &= artifact_result
467467

468468
# generate perf report per dso,sym,srcline
@@ -487,9 +487,9 @@ def generate_outputs(self, use_case, **kwargs):
487487
)
488488

489489
if artifact_result is True:
490-
outputs["perf report per dso,sym,srcline {}".format(identifier)] = (
491-
perf_report_artifact
492-
)
490+
outputs[
491+
"perf report per dso,sym,srcline {}".format(identifier)
492+
] = perf_report_artifact
493493
result &= artifact_result
494494

495495
self.logger.info(
@@ -527,9 +527,9 @@ def generate_outputs(self, use_case, **kwargs):
527527
)
528528

529529
if artifact_result is True:
530-
outputs["perf report top self-cpu {}".format(identifier)] = (
531-
perf_report_artifact
532-
)
530+
outputs[
531+
"perf report top self-cpu {}".format(identifier)
532+
] = perf_report_artifact
533533
result &= artifact_result
534534

535535
# generate perf report --stdio report
@@ -546,9 +546,9 @@ def generate_outputs(self, use_case, **kwargs):
546546
)
547547

548548
if artifact_result is True:
549-
outputs["perf report top self-cpu (dso={})".format(binary)] = (
550-
perf_report_artifact
551-
)
549+
outputs[
550+
"perf report top self-cpu (dso={})".format(binary)
551+
] = perf_report_artifact
552552
result &= artifact_result
553553

554554
if self.callgraph_mode == "dwarf":
@@ -590,9 +590,9 @@ def generate_outputs(self, use_case, **kwargs):
590590
)
591591
result &= artifact_result
592592
if artifact_result is True:
593-
outputs["Top entries in text form by LOC"] = (
594-
pprof_artifact_text_output
595-
)
593+
outputs[
594+
"Top entries in text form by LOC"
595+
] = pprof_artifact_text_output
596596
tabular_data_map["text-lines"] = tabular_data
597597
self.logger.info("Generating pprof png output")
598598
pprof_png_output = self.output + ".pprof.png"
@@ -604,9 +604,9 @@ def generate_outputs(self, use_case, **kwargs):
604604
self.output,
605605
)
606606
if artifact_result is True:
607-
outputs["Output graph image in PNG format"] = (
608-
pprof_artifact_png_output
609-
)
607+
outputs[
608+
"Output graph image in PNG format"
609+
] = pprof_artifact_png_output
610610
result &= artifact_result
611611

612612
# save stack collapsed

redisbench_admin/run/cluster.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ def spin_up_redis_cluster_remote_redis(
115115
logname,
116116
redis_7=True,
117117
):
118+
# Import the function from standalone module
119+
from redisbench_admin.run_remote.standalone import ensure_redis_server_available
120+
121+
# Ensure redis-server is available before trying to start cluster
122+
ensure_redis_server_available(server_public_ip, username, private_key, ssh_port)
123+
118124
logging.info("Generating the remote redis-server command arguments")
119125
redis_process_commands = []
120126
logfiles = []

redisbench_admin/run/common.py

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,7 @@ def prepare_benchmark_parameters_specif_tooling(
206206
if isremote is True:
207207
benchmark_tool = "/tmp/{}".format(benchmark_tool)
208208
input_data_file = "/tmp/input.data"
209-
(
210-
command_arr,
211-
command_str,
212-
) = prepare_tsbs_benchmark_command(
209+
(command_arr, command_str,) = prepare_tsbs_benchmark_command(
213210
benchmark_tool,
214211
server_private_ip,
215212
server_plaintext_port,
@@ -221,10 +218,7 @@ def prepare_benchmark_parameters_specif_tooling(
221218
cluster_api_enabled,
222219
)
223220
if "memtier_benchmark" in benchmark_tool:
224-
(
225-
command_arr,
226-
command_str,
227-
) = prepare_memtier_benchmark_command(
221+
(command_arr, command_str,) = prepare_memtier_benchmark_command(
228222
benchmark_tool,
229223
server_private_ip,
230224
server_plaintext_port,
@@ -242,10 +236,7 @@ def prepare_benchmark_parameters_specif_tooling(
242236
ann_path = stdout[0].strip() + "/run/ann/pkg/multirun.py"
243237
logging.info("Remote ann-benchmark path: {}".format(ann_path))
244238

245-
(
246-
command_arr,
247-
command_str,
248-
) = prepare_ann_benchmark_command(
239+
(command_arr, command_str,) = prepare_ann_benchmark_command(
249240
server_private_ip,
250241
server_plaintext_port,
251242
cluster_api_enabled,
@@ -259,10 +250,7 @@ def prepare_benchmark_parameters_specif_tooling(
259250
if isremote is True:
260251
benchmark_tool = "/tmp/{}".format(benchmark_tool)
261252
input_data_file = "/tmp/input.data"
262-
(
263-
command_arr,
264-
command_str,
265-
) = prepare_ftsb_benchmark_command(
253+
(command_arr, command_str,) = prepare_ftsb_benchmark_command(
266254
benchmark_tool,
267255
server_private_ip,
268256
server_plaintext_port,
@@ -279,10 +267,7 @@ def prepare_benchmark_parameters_specif_tooling(
279267
if isremote is True:
280268
benchmark_tool = "/tmp/{}".format(benchmark_tool)
281269
input_data_file = "/tmp/input.data"
282-
(
283-
command_arr,
284-
command_str,
285-
) = prepare_aibench_benchmark_command(
270+
(command_arr, command_str,) = prepare_aibench_benchmark_command(
286271
benchmark_tool,
287272
server_private_ip,
288273
server_plaintext_port,
@@ -787,10 +772,7 @@ def print_results_table_stdout(
787772
metric_names=[],
788773
):
789774
# check which metrics to extract
790-
(
791-
_,
792-
metrics,
793-
) = merge_default_and_config_metrics(
775+
(_, metrics,) = merge_default_and_config_metrics(
794776
benchmark_config,
795777
default_metrics,
796778
None,

redisbench_admin/run_async/async_terraform.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,7 @@ def common_properties_log(self, private_key):
114114
def async_runner_setup(
115115
self,
116116
):
117-
(
118-
remote_setup,
119-
deployment_type,
120-
remote_id,
121-
) = fetch_remote_setup_from_config(
117+
(remote_setup, deployment_type, remote_id,) = fetch_remote_setup_from_config(
122118
[{"type": "async", "setup": "runner"}],
123119
"https://github.com/RedisLabsModules/testing-infrastructure.git",
124120
"master",
@@ -233,11 +229,7 @@ def terraform_spin_or_reuse_env(
233229
tf_override_name=None,
234230
tf_folder_path=None,
235231
):
236-
(
237-
remote_setup,
238-
deployment_type,
239-
remote_id,
240-
) = fetch_remote_setup_from_config(
232+
(remote_setup, deployment_type, remote_id,) = fetch_remote_setup_from_config(
241233
benchmark_config["remote"],
242234
"https://github.com/RedisLabsModules/testing-infrastructure.git",
243235
"master",

redisbench_admin/run_async/render_files.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ def renderServiceFile(access_key, region, secret_key, gh_token, job_name, args,
2828
argv.append("--private_key")
2929
argv.append("/home/ubuntu/work_dir/tests/benchmarks/benchmarks.redislabs.pem")
3030
else:
31-
argv[argv.index(args.private_key)] = (
32-
"/home/ubuntu/work_dir/tests/benchmarks/benchmarks.redislabs.pem"
33-
)
31+
argv[
32+
argv.index(args.private_key)
33+
] = "/home/ubuntu/work_dir/tests/benchmarks/benchmarks.redislabs.pem"
3434
if len(args.module_path) != 0:
3535
argv[argv.index(args.module_path[0])] = (
3636
"/home/ubuntu/work_dir/tests/benchmarks/"

redisbench_admin/run_local/run_local.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -687,17 +687,17 @@ def commandstats_latencystats_process_name(
687687
branch = variant_labels_dict["branch"]
688688

689689
if version is not None:
690-
variant_labels_dict["command_and_metric_and_version"] = (
691-
"{} - {} - {}".format(command, metric, version)
692-
)
693-
variant_labels_dict["command_and_metric_and_setup_and_version"] = (
694-
"{} - {} - {} - {}".format(command, metric, setup_name, version)
695-
)
690+
variant_labels_dict[
691+
"command_and_metric_and_version"
692+
] = "{} - {} - {}".format(command, metric, version)
693+
variant_labels_dict[
694+
"command_and_metric_and_setup_and_version"
695+
] = "{} - {} - {} - {}".format(command, metric, setup_name, version)
696696

697697
if branch is not None:
698-
variant_labels_dict["command_and_metric_and_branch"] = (
699-
"{} - {} - {}".format(command, metric, branch)
700-
)
701-
variant_labels_dict["command_and_metric_and_setup_and_branch"] = (
702-
"{} - {} - {} - {}".format(command, metric, setup_name, branch)
703-
)
698+
variant_labels_dict[
699+
"command_and_metric_and_branch"
700+
] = "{} - {} - {}".format(command, metric, branch)
701+
variant_labels_dict[
702+
"command_and_metric_and_setup_and_branch"
703+
] = "{} - {} - {} - {}".format(command, metric, setup_name, branch)

0 commit comments

Comments
 (0)