Skip to content

Commit 4ab54d6

Browse files
Builder cleanup, arch-specific streams, CLI/Runner/Compare/Coordinator enhancements, and new benchmark datasets (#312)
* Bumping version to 0.1.310 * Added gcc:8.5.0-arm64-debian-buster-default * Moved from gcc-8 to gcc-15. runner image using debian:bookworm * bumping version * Removed reference to gcc-8 on tests * Fixed missing gcc-8 removal * renamed buster->bookworm * Added extra session caching, RPUSH, and SET benchmarks * working on box plot charts on compare tool * Added command filter an extra benchmark for 1:10 set/get 1KB benchmark * bumping version to 0.1.325 * added uri support for benchmark runner * fixes for 0.1.334 * bumping version * version 0.1.338 * per arch streams * stash * Removed dump.rdb
1 parent e862c9e commit 4ab54d6

23 files changed

+2704
-200
lines changed

poetry.lock

Lines changed: 22 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "redis-benchmarks-specification"
3-
version = "0.1.323"
3+
version = "0.2.11"
44
description = "The Redis benchmarks specification describes the cross-language/tools requirements and expectations to foster performance and observability standards around redis related technologies. Members from both industry and academia, including organizations and individuals are encouraged to contribute."
55
authors = ["filipecosta90 <[email protected]>","Redis Performance Group <[email protected]>"]
66
readme = "Readme.md"
@@ -27,6 +27,7 @@ pandas = "^2.1.2"
2727
numpy = "^2.0.0"
2828
jsonpath-ng = "^1.6.1"
2929

30+
seaborn = "^0.13.2"
3031
[tool.poetry.dev-dependencies]
3132
click = "8.1.7"
3233
black = "24.4.2"

redis_benchmarks_specification/__builder__/builder.py

Lines changed: 261 additions & 16 deletions
Large diffs are not rendered by default.

redis_benchmarks_specification/__cli__/args.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ def spec_cli_args(parser):
138138
parser.add_argument("--gh_repo", type=str, default="redis")
139139
parser.add_argument("--server_name", type=str, default=None)
140140
parser.add_argument("--run_image", type=str, default="redis")
141-
parser.add_argument("--build_arch", type=str, default=None)
141+
parser.add_argument("--arch", type=str, default="amd64")
142142
parser.add_argument("--id", type=str, default="dockerhub")
143143
parser.add_argument("--mnt_point", type=str, default="")
144144
parser.add_argument("--trigger-unstable-commits", type=bool, default=True)
@@ -217,4 +217,10 @@ def spec_cli_args(parser):
217217
default=-1,
218218
help="Wait x sections for build. If -1, waits forever.",
219219
)
220+
parser.add_argument(
221+
"--command-regex",
222+
type=str,
223+
default=".*",
224+
help="Filter tests by command using regex. Only tests that include commands matching this regex will be processed.",
225+
)
220226
return parser

redis_benchmarks_specification/__cli__/cli.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
STREAM_KEYNAME_GH_EVENTS_COMMIT,
4545
STREAM_GH_EVENTS_COMMIT_BUILDERS_CG,
4646
STREAM_KEYNAME_NEW_BUILD_EVENTS,
47+
get_arch_specific_stream_name,
4748
)
4849
from redis_benchmarks_specification.__common__.package import (
4950
get_version_string,
@@ -84,7 +85,7 @@ def trigger_tests_dockerhub_cli_command_logic(args, project_name, project_versio
8485
args.id,
8586
conn,
8687
args.run_image,
87-
args.build_arch,
88+
args.arch,
8889
testDetails,
8990
"n/a",
9091
[],
@@ -104,6 +105,12 @@ def trigger_tests_dockerhub_cli_command_logic(args, project_name, project_versio
104105
0,
105106
10000,
106107
args.tests_regexp,
108+
".*", # command_regexp
109+
False, # use_git_timestamp
110+
"redis", # server_name
111+
"redis", # github_org
112+
"redis", # github_repo
113+
None, # existing_artifact_keys
107114
)
108115
build_stream_fields["github_repo"] = args.gh_repo
109116
build_stream_fields["github_org"] = args.gh_org
@@ -118,9 +125,12 @@ def trigger_tests_dockerhub_cli_command_logic(args, project_name, project_versio
118125
store_airgap_image_redis(conn, docker_client, args.run_image)
119126

120127
if result is True:
121-
benchmark_stream_id = conn.xadd(
122-
STREAM_KEYNAME_NEW_BUILD_EVENTS, build_stream_fields
128+
# Use architecture-specific stream
129+
arch_specific_stream = get_arch_specific_stream_name(args.arch)
130+
logging.info(
131+
f"CLI adding work to architecture-specific stream: {arch_specific_stream}"
123132
)
133+
benchmark_stream_id = conn.xadd(arch_specific_stream, build_stream_fields)
124134
logging.info(
125135
"sucessfully requested a new run {}. Stream id: {}".format(
126136
build_stream_fields, benchmark_stream_id
@@ -432,9 +442,9 @@ def trigger_tests_cli_command_logic(args, project_name, project_version):
432442
commit_dict["tests_groups_regexp"] = tests_groups_regexp
433443
commit_dict["github_org"] = args.gh_org
434444
commit_dict["github_repo"] = args.gh_repo
435-
if args.build_arch is not None:
436-
commit_dict["build_arch"] = args.build_arch
437-
commit_dict["arch"] = args.build_arch
445+
if args.arch is not None:
446+
commit_dict["build_arch"] = args.arch
447+
commit_dict["arch"] = args.arch
438448
if args.server_name is not None and args.server_name != "":
439449
commit_dict["server_name"] = args.server_name
440450
if args.build_artifacts != "":

redis_benchmarks_specification/__common__/env.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,20 @@
3232
"STREAM_KEYNAME_NEW_BUILD_EVENTS", "oss:api:gh/redis/redis/builds"
3333
)
3434

35+
36+
# Function to get architecture-specific build events stream name
37+
def get_arch_specific_stream_name(arch):
38+
"""Get architecture-specific stream name for build events"""
39+
base_stream = STREAM_KEYNAME_NEW_BUILD_EVENTS
40+
if arch in ["amd64", "x86_64"]:
41+
return f"{base_stream}:amd64"
42+
elif arch in ["arm64", "aarch64"]:
43+
return f"{base_stream}:arm64"
44+
else:
45+
# Fallback to base stream for unknown architectures
46+
return base_stream
47+
48+
3549
STREAM_GH_NEW_BUILD_RUNNERS_CG = os.getenv(
3650
"STREAM_GH_NEW_BUILD_RUNNERS_CG", "runners-cg:redis/redis/commits"
3751
)

redis_benchmarks_specification/__common__/runner.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ def get_benchmark_specs(testsuites_folder, test="", test_regex=".*"):
101101
for test_name in original_files:
102102
match_obj = re.search(test_regexp_string, test_name)
103103
if match_obj is None:
104-
logging.info(
104+
logging.debug(
105105
"Skipping test file: {} given it does not match regex {}".format(
106106
test_name, test_regexp_string
107107
)
@@ -291,13 +291,7 @@ def export_redis_metrics(
291291
metric_name,
292292
metric_value,
293293
) in overall_end_time_metrics.items():
294-
tsname_metric = "{}/{}/{}/benchmark_end/{}/{}".format(
295-
sprefix,
296-
test_name,
297-
by_variant,
298-
setup_name,
299-
metric_name,
300-
)
294+
tsname_metric = f"{sprefix}/{test_name}/{by_variant}/benchmark_end/{running_platform}/{setup_name}/{metric_name}"
301295

302296
logging.debug(
303297
"Adding a redis server side metric collected at the end of benchmark."
@@ -404,6 +398,7 @@ def exporter_datasink_common(
404398
running_platform,
405399
None,
406400
git_hash,
401+
disable_target_tables=True,
407402
)
408403
if collect_memory_metrics:
409404
logging.info("Collecting memory metrics")
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
"""
2+
Warning suppression module that should be imported first to suppress known warnings.
3+
"""
4+
5+
import warnings
6+
7+
# Suppress cryptography deprecation warnings from paramiko
8+
warnings.filterwarnings("ignore", category=DeprecationWarning, module="paramiko")
9+
warnings.filterwarnings("ignore", message=".*TripleDES.*", category=DeprecationWarning)
10+
warnings.filterwarnings(
11+
"ignore", message=".*cryptography.*", category=DeprecationWarning
12+
)
13+
14+
# Also suppress the specific CryptographyDeprecationWarning if it exists
15+
try:
16+
from cryptography.utils import CryptographyDeprecationWarning
17+
18+
warnings.filterwarnings("ignore", category=CryptographyDeprecationWarning)
19+
except ImportError:
20+
pass

redis_benchmarks_specification/__common__/timeseries.py

Lines changed: 60 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -838,34 +838,47 @@ def common_exporter_logic(
838838
and artifact_version != ""
839839
and artifact_version != "N/A"
840840
):
841-
# extract per-version datapoints
842-
total_hs_ts = len(per_hash_time_series_dict.keys())
843-
logging.info(
844-
f"Extending the by.hash {git_hash} timeseries ({total_hs_ts}) with version info {artifact_version}"
845-
)
846-
for hash_timeserie in per_hash_time_series_dict.values():
847-
hash_timeserie["labels"]["version"] = artifact_version
848-
(
849-
_,
850-
per_version_time_series_dict,
851-
version_target_tables,
852-
) = extract_perversion_timeseries_from_results(
853-
used_ts,
854-
metrics,
855-
results_dict,
856-
artifact_version,
857-
tf_github_org,
858-
tf_github_repo,
859-
deployment_name,
860-
deployment_type,
861-
test_name,
862-
tf_triggering_env,
863-
metadata_tags,
864-
build_variant_name,
865-
running_platform,
866-
testcase_metric_context_paths,
867-
)
868-
total_break_by_added += 1
841+
# Check if version 255.255.255 should only be pushed for unstable branch
842+
should_push_version = True
843+
if artifact_version == "255.255.255":
844+
if tf_github_branch != "unstable":
845+
logging.info(
846+
f"Skipping version 255.255.255 data push for branch '{tf_github_branch}' "
847+
f"(only pushing for 'unstable' branch)"
848+
)
849+
should_push_version = False
850+
else:
851+
logging.info(f"Pushing version 255.255.255 data for unstable branch")
852+
853+
if should_push_version:
854+
# extract per-version datapoints
855+
total_hs_ts = len(per_hash_time_series_dict.keys())
856+
logging.info(
857+
f"Extending the by.hash {git_hash} timeseries ({total_hs_ts}) with version info {artifact_version}"
858+
)
859+
for hash_timeserie in per_hash_time_series_dict.values():
860+
hash_timeserie["labels"]["version"] = artifact_version
861+
(
862+
_,
863+
per_version_time_series_dict,
864+
version_target_tables,
865+
) = extract_perversion_timeseries_from_results(
866+
used_ts,
867+
metrics,
868+
results_dict,
869+
artifact_version,
870+
tf_github_org,
871+
tf_github_repo,
872+
deployment_name,
873+
deployment_type,
874+
test_name,
875+
tf_triggering_env,
876+
metadata_tags,
877+
build_variant_name,
878+
running_platform,
879+
testcase_metric_context_paths,
880+
)
881+
total_break_by_added += 1
869882
else:
870883
logging.warning(
871884
"there was no git VERSION information to push data brokedown by VERSION"
@@ -1054,6 +1067,9 @@ def add_standardized_metric_bybranch(
10541067
labels["deployment_name+branch"] = "{} {}".format(
10551068
deployment_name, tf_github_branch
10561069
)
1070+
labels["running_platform+branch"] = "{} {}".format(
1071+
running_platform, tf_github_branch
1072+
)
10571073
labels["test_name"] = str(test_name)
10581074
labels["metric"] = str(metric_name)
10591075
logging.info(
@@ -1118,11 +1134,15 @@ def add_standardized_metric_byversion(
11181134
tf_triggering_env,
11191135
metadata_tags,
11201136
build_variant_name,
1137+
running_platform,
11211138
)
11221139
labels["version"] = artifact_version
11231140
labels["deployment_name+version"] = "{} {}".format(
11241141
deployment_name, artifact_version
11251142
)
1143+
labels["running_platform+version"] = "{} {}".format(
1144+
running_platform, artifact_version
1145+
)
11261146
labels["test_name"] = str(test_name)
11271147
labels["metric"] = str(metric_name)
11281148
logging.info(
@@ -1169,6 +1189,7 @@ def timeseries_test_sucess_flow(
11691189
running_platform=None,
11701190
timeseries_dict=None,
11711191
git_hash=None,
1192+
disable_target_tables=False,
11721193
):
11731194
testcase_metric_context_paths = []
11741195
version_target_tables = None
@@ -1205,7 +1226,7 @@ def timeseries_test_sucess_flow(
12051226
)
12061227
)
12071228
push_data_to_redistimeseries(rts, timeseries_dict)
1208-
if version_target_tables is not None:
1229+
if not disable_target_tables and version_target_tables is not None:
12091230
logging.info(
12101231
"There are a total of {} distinct target tables by version".format(
12111232
len(version_target_tables.keys())
@@ -1225,7 +1246,12 @@ def timeseries_test_sucess_flow(
12251246
rts.hset(
12261247
version_target_table_keyname, None, None, version_target_table_dict
12271248
)
1228-
if branch_target_tables is not None:
1249+
elif disable_target_tables:
1250+
logging.info(
1251+
"Target tables disabled - skipping version target table creation"
1252+
)
1253+
1254+
if not disable_target_tables and branch_target_tables is not None:
12291255
logging.info(
12301256
"There are a total of {} distinct target tables by branch".format(
12311257
len(branch_target_tables.keys())
@@ -1246,6 +1272,10 @@ def timeseries_test_sucess_flow(
12461272
rts.hset(
12471273
branch_target_table_keyname, None, None, branch_target_table_dict
12481274
)
1275+
elif disable_target_tables:
1276+
logging.info(
1277+
"Target tables disabled - skipping branch target table creation"
1278+
)
12491279
if test_name is not None:
12501280
if type(test_name) is str:
12511281
update_secondary_result_keys(

redis_benchmarks_specification/__compare__/args.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,30 @@ def create_compare_arguments(parser):
4646
default="",
4747
help="specify a test (or a comma separated list of tests) to use for comparison. If none is specified by default will use all of them.",
4848
)
49+
parser.add_argument(
50+
"--extra-filters",
51+
type=str,
52+
default="",
53+
help="specify extra filters to pass to baseline and comparison.",
54+
)
55+
parser.add_argument(
56+
"--use-test-suites-folder",
57+
action="store_true",
58+
default=False,
59+
help="Use test names from YAML files in test-suites folder instead of database",
60+
)
61+
parser.add_argument(
62+
"--generate-boxplot",
63+
action="store_true",
64+
default=False,
65+
help="Generate box plot showing performance change distribution per command",
66+
)
67+
parser.add_argument(
68+
"--boxplot-output",
69+
type=str,
70+
default="command_performance_boxplot.png",
71+
help="Output filename for the box plot (supports .png, .svg, .pdf)",
72+
)
4973
parser.add_argument(
5074
"--defaults_filename",
5175
type=str,
@@ -155,6 +179,20 @@ def create_compare_arguments(parser):
155179
parser.add_argument("--simple-table", type=bool, default=False)
156180
parser.add_argument("--use_metric_context_path", type=bool, default=False)
157181
parser.add_argument("--testname_regex", type=str, default=".*", required=False)
182+
parser.add_argument(
183+
"--command-group-regex",
184+
type=str,
185+
default=".*",
186+
required=False,
187+
help="Filter commands by command group using regex. Only commands belonging to matching groups will be included in boxplot and summary.",
188+
)
189+
parser.add_argument(
190+
"--command-regex",
191+
type=str,
192+
default=".*",
193+
required=False,
194+
help="Filter tests by command using regex. Only tests that include commands matching this regex will be processed.",
195+
)
158196
parser.add_argument(
159197
"--regression_str", type=str, default="REGRESSION", required=False
160198
)

0 commit comments

Comments
 (0)