redis-benchmarks-specification 0.1.77__py3-none-any.whl → 0.1.79__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of redis-benchmarks-specification might be problematic. Click here for more details.
- redis_benchmarks_specification/__api__/app.py +6 -4
- redis_benchmarks_specification/__builder__/builder.py +93 -4
- redis_benchmarks_specification/__cli__/args.py +11 -1
- redis_benchmarks_specification/__cli__/cli.py +87 -4
- redis_benchmarks_specification/__common__/github.py +143 -0
- redis_benchmarks_specification/__compare__/compare.py +26 -90
- redis_benchmarks_specification/__self_contained_coordinator__/self_contained_coordinator.py +11 -7
- {redis_benchmarks_specification-0.1.77.dist-info → redis_benchmarks_specification-0.1.79.dist-info}/METADATA +1 -2
- {redis_benchmarks_specification-0.1.77.dist-info → redis_benchmarks_specification-0.1.79.dist-info}/RECORD +12 -11
- {redis_benchmarks_specification-0.1.77.dist-info → redis_benchmarks_specification-0.1.79.dist-info}/WHEEL +1 -1
- {redis_benchmarks_specification-0.1.77.dist-info → redis_benchmarks_specification-0.1.79.dist-info}/LICENSE +0 -0
- {redis_benchmarks_specification-0.1.77.dist-info → redis_benchmarks_specification-0.1.79.dist-info}/entry_points.txt +0 -0
|
@@ -86,11 +86,13 @@ def create_app(conn, user, test_config=None):
|
|
|
86
86
|
event_type = "Ignored event from webhook"
|
|
87
87
|
use_event = False
|
|
88
88
|
# Pull request labeled
|
|
89
|
+
pull_request_number = None
|
|
89
90
|
trigger_label = PULL_REQUEST_TRIGGER_LABEL
|
|
90
91
|
if "pull_request" in request_data:
|
|
91
92
|
action = request_data["action"]
|
|
92
93
|
if should_action(action):
|
|
93
94
|
pull_request_dict = request_data["pull_request"]
|
|
95
|
+
|
|
94
96
|
head_dict = pull_request_dict["head"]
|
|
95
97
|
repo_dict = head_dict["repo"]
|
|
96
98
|
labels = []
|
|
@@ -107,9 +109,8 @@ def create_app(conn, user, test_config=None):
|
|
|
107
109
|
label_name = label["name"]
|
|
108
110
|
if trigger_label == label_name:
|
|
109
111
|
use_event = True
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
)
|
|
112
|
+
pull_request_number = request_data["number"]
|
|
113
|
+
event_type = f"Pull request #{pull_request_number} labeled with '{trigger_label}'"
|
|
113
114
|
detected_label = True
|
|
114
115
|
if detected_label is False:
|
|
115
116
|
app.logger.info(
|
|
@@ -161,6 +162,8 @@ def create_app(conn, user, test_config=None):
|
|
|
161
162
|
"gh_repo": gh_repo,
|
|
162
163
|
"gh_org": gh_org,
|
|
163
164
|
}
|
|
165
|
+
if pull_request_number is not None:
|
|
166
|
+
fields_after["pull_request_number"] = pull_request_number
|
|
164
167
|
app.logger.info(
|
|
165
168
|
"Using event {} to trigger benchmark. final fields: {}".format(
|
|
166
169
|
event_type, fields_after
|
|
@@ -174,7 +177,6 @@ def create_app(conn, user, test_config=None):
|
|
|
174
177
|
event_type, response_data
|
|
175
178
|
)
|
|
176
179
|
)
|
|
177
|
-
|
|
178
180
|
else:
|
|
179
181
|
app.logger.info(
|
|
180
182
|
"{}. input json was: {}".format(event_type, request_data)
|
|
@@ -31,11 +31,19 @@ from redis_benchmarks_specification.__common__.env import (
|
|
|
31
31
|
REDIS_SOCKET_TIMEOUT,
|
|
32
32
|
REDIS_BINS_EXPIRE_SECS,
|
|
33
33
|
)
|
|
34
|
+
from redis_benchmarks_specification.__common__.github import (
|
|
35
|
+
check_github_available_and_actionable,
|
|
36
|
+
generate_build_finished_pr_comment,
|
|
37
|
+
update_comment_if_needed,
|
|
38
|
+
create_new_pr_comment,
|
|
39
|
+
)
|
|
34
40
|
from redis_benchmarks_specification.__common__.package import (
|
|
35
41
|
populate_with_poetry_data,
|
|
36
42
|
get_version_string,
|
|
37
43
|
)
|
|
38
44
|
|
|
45
|
+
PERFORMANCE_GH_TOKEN = os.getenv("PERFORMANCE_GH_TOKEN", None)
|
|
46
|
+
|
|
39
47
|
|
|
40
48
|
class ZipFileWithPermissions(ZipFile):
|
|
41
49
|
def _extract_member(self, member, targetpath, pwd):
|
|
@@ -80,6 +88,8 @@ def main():
|
|
|
80
88
|
action="store_true",
|
|
81
89
|
help="Store the docker images in redis keys.",
|
|
82
90
|
)
|
|
91
|
+
parser.add_argument("--github_token", type=str, default=PERFORMANCE_GH_TOKEN)
|
|
92
|
+
parser.add_argument("--pull-request", type=str, default=None, nargs="?", const="")
|
|
83
93
|
args = parser.parse_args()
|
|
84
94
|
if args.logname is not None:
|
|
85
95
|
print("Writting log to {}".format(args.logname))
|
|
@@ -138,7 +148,8 @@ def main():
|
|
|
138
148
|
build_spec_image_prefetch(builders_folder, different_build_specs)
|
|
139
149
|
|
|
140
150
|
builder_consumer_group_create(conn)
|
|
141
|
-
|
|
151
|
+
if args.github_token is not None:
|
|
152
|
+
logging.info("detected a github token. will update as much as possible!!! =)")
|
|
142
153
|
previous_id = args.consumer_start_id
|
|
143
154
|
while True:
|
|
144
155
|
previous_id, new_builds_count, _ = builder_process_stream(
|
|
@@ -148,6 +159,7 @@ def main():
|
|
|
148
159
|
previous_id,
|
|
149
160
|
args.docker_air_gap,
|
|
150
161
|
arch,
|
|
162
|
+
args.github_token,
|
|
151
163
|
)
|
|
152
164
|
|
|
153
165
|
|
|
@@ -172,6 +184,17 @@ def builder_consumer_group_create(conn, id="$"):
|
|
|
172
184
|
)
|
|
173
185
|
|
|
174
186
|
|
|
187
|
+
def check_benchmark_build_comment(comments):
|
|
188
|
+
res = False
|
|
189
|
+
pos = -1
|
|
190
|
+
for n, comment in enumerate(comments):
|
|
191
|
+
body = comment.body
|
|
192
|
+
if "CE Performance Automation : step 1 of 2" in body:
|
|
193
|
+
res = True
|
|
194
|
+
pos = n
|
|
195
|
+
return res, pos
|
|
196
|
+
|
|
197
|
+
|
|
175
198
|
def builder_process_stream(
|
|
176
199
|
builders_folder,
|
|
177
200
|
conn,
|
|
@@ -179,8 +202,10 @@ def builder_process_stream(
|
|
|
179
202
|
previous_id,
|
|
180
203
|
docker_air_gap=False,
|
|
181
204
|
arch="amd64",
|
|
205
|
+
github_token=None,
|
|
182
206
|
):
|
|
183
207
|
new_builds_count = 0
|
|
208
|
+
auto_approve_github_comments = True
|
|
184
209
|
build_stream_fields_arr = []
|
|
185
210
|
logging.info("Entering blocking read waiting for work.")
|
|
186
211
|
consumer_name = "{}-proc#{}".format(STREAM_GH_EVENTS_COMMIT_BUILDERS_CG, "1")
|
|
@@ -216,6 +241,12 @@ def builder_process_stream(
|
|
|
216
241
|
buffer = conn.get(binary_zip_key)
|
|
217
242
|
git_timestamp_ms = None
|
|
218
243
|
use_git_timestamp = False
|
|
244
|
+
commit_datetime = "n/a"
|
|
245
|
+
if b"commit_datetime" in testDetails:
|
|
246
|
+
commit_datetime = int(testDetails[b"commit_datetime"].decode())
|
|
247
|
+
commit_summary = "n/a"
|
|
248
|
+
if b"commit_summary" in testDetails:
|
|
249
|
+
commit_summary = int(testDetails[b"commit_summary"].decode())
|
|
219
250
|
git_branch, git_version = get_branch_version_from_test_details(testDetails)
|
|
220
251
|
if b"use_git_timestamp" in testDetails:
|
|
221
252
|
use_git_timestamp = bool(testDetails[b"use_git_timestamp"])
|
|
@@ -238,6 +269,30 @@ def builder_process_stream(
|
|
|
238
269
|
if b"tests_groups_regexp" in testDetails:
|
|
239
270
|
tests_groups_regexp = testDetails[b"tests_groups_regexp"].decode()
|
|
240
271
|
|
|
272
|
+
# github updates
|
|
273
|
+
is_actionable_pr = False
|
|
274
|
+
contains_regression_comment = False
|
|
275
|
+
github_pr = None
|
|
276
|
+
old_regression_comment_body = ""
|
|
277
|
+
pr_link = ""
|
|
278
|
+
regression_comment = ""
|
|
279
|
+
pull_request = None
|
|
280
|
+
if b"pull_request" in testDetails:
|
|
281
|
+
pull_request = testDetails[b"pull_request"].decode()
|
|
282
|
+
logging.info(f"Detected PR info in builder. PR: {pull_request}")
|
|
283
|
+
verbose = True
|
|
284
|
+
|
|
285
|
+
fn = check_benchmark_build_comment
|
|
286
|
+
(
|
|
287
|
+
contains_regression_comment,
|
|
288
|
+
github_pr,
|
|
289
|
+
is_actionable_pr,
|
|
290
|
+
old_regression_comment_body,
|
|
291
|
+
pr_link,
|
|
292
|
+
regression_comment,
|
|
293
|
+
) = check_github_available_and_actionable(
|
|
294
|
+
fn, github_token, pull_request, "redis", "redis", verbose
|
|
295
|
+
)
|
|
241
296
|
for build_spec in different_build_specs:
|
|
242
297
|
build_config, id = get_build_config(builders_folder + "/" + build_spec)
|
|
243
298
|
build_config_metadata = get_build_config_metadata(build_config)
|
|
@@ -355,6 +410,8 @@ def builder_process_stream(
|
|
|
355
410
|
"tests_priority_lower_limit": tests_priority_lower_limit,
|
|
356
411
|
"tests_groups_regexp": tests_groups_regexp,
|
|
357
412
|
}
|
|
413
|
+
if pull_request is not None:
|
|
414
|
+
build_stream_fields["pull_request"] = pull_request
|
|
358
415
|
if git_branch is not None:
|
|
359
416
|
build_stream_fields["git_branch"] = git_branch
|
|
360
417
|
if git_version is not None:
|
|
@@ -388,12 +445,44 @@ def builder_process_stream(
|
|
|
388
445
|
id, git_hash, benchmark_stream_id
|
|
389
446
|
)
|
|
390
447
|
)
|
|
391
|
-
|
|
392
|
-
|
|
448
|
+
streamId_decoded = streamId.decode()
|
|
449
|
+
benchmark_stream_id_decoded = benchmark_stream_id.decode()
|
|
450
|
+
builder_list_completed = (
|
|
451
|
+
f"builder:{streamId_decoded}:builds_completed"
|
|
452
|
+
)
|
|
453
|
+
conn.lpush(builder_list_completed, benchmark_stream_id_decoded)
|
|
393
454
|
conn.expire(builder_list_completed, REDIS_BINS_EXPIRE_SECS)
|
|
394
455
|
logging.info(
|
|
395
|
-
f"Adding information of build->benchmark stream info in list {builder_list_completed}. Adding benchmark stream id: {
|
|
456
|
+
f"Adding information of build->benchmark stream info in list {builder_list_completed}. Adding benchmark stream id: {benchmark_stream_id_decoded}"
|
|
457
|
+
)
|
|
458
|
+
benchmark_stream_ids = [benchmark_stream_id_decoded]
|
|
459
|
+
comment_body = generate_build_finished_pr_comment(
|
|
460
|
+
benchmark_stream_ids,
|
|
461
|
+
commit_datetime,
|
|
462
|
+
commit_summary,
|
|
463
|
+
git_branch,
|
|
464
|
+
git_hash,
|
|
465
|
+
tests_groups_regexp,
|
|
466
|
+
tests_priority_lower_limit,
|
|
467
|
+
tests_priority_upper_limit,
|
|
468
|
+
tests_regexp,
|
|
396
469
|
)
|
|
470
|
+
if is_actionable_pr:
|
|
471
|
+
if contains_regression_comment:
|
|
472
|
+
update_comment_if_needed(
|
|
473
|
+
auto_approve_github_comments,
|
|
474
|
+
comment_body,
|
|
475
|
+
old_regression_comment_body,
|
|
476
|
+
regression_comment,
|
|
477
|
+
verbose,
|
|
478
|
+
)
|
|
479
|
+
else:
|
|
480
|
+
create_new_pr_comment(
|
|
481
|
+
auto_approve_github_comments,
|
|
482
|
+
comment_body,
|
|
483
|
+
github_pr,
|
|
484
|
+
pr_link,
|
|
485
|
+
)
|
|
397
486
|
shutil.rmtree(temporary_dir, ignore_errors=True)
|
|
398
487
|
new_builds_count = new_builds_count + 1
|
|
399
488
|
build_stream_fields_arr.append(build_stream_fields)
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# All rights reserved.
|
|
5
5
|
#
|
|
6
6
|
import datetime
|
|
7
|
-
|
|
7
|
+
import os
|
|
8
8
|
|
|
9
9
|
from redis_benchmarks_specification.__common__.env import (
|
|
10
10
|
GH_REDIS_SERVER_HOST,
|
|
@@ -21,6 +21,7 @@ START_TIME_NOW_UTC, _, _ = get_start_time_vars()
|
|
|
21
21
|
START_TIME_LAST_YEAR_UTC = START_TIME_NOW_UTC - datetime.timedelta(days=7)
|
|
22
22
|
CLI_TOOL_STATS = "stats"
|
|
23
23
|
CLI_TOOL_TRIGGER = "trigger"
|
|
24
|
+
PERFORMANCE_GH_TOKEN = os.getenv("PERFORMANCE_GH_TOKEN", None)
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
def spec_cli_args(parser):
|
|
@@ -69,6 +70,15 @@ def spec_cli_args(parser):
|
|
|
69
70
|
action="store_true",
|
|
70
71
|
help="Include modules statistics on commandstats.",
|
|
71
72
|
)
|
|
73
|
+
parser.add_argument("--github_token", type=str, default=PERFORMANCE_GH_TOKEN)
|
|
74
|
+
parser.add_argument("--pull-request", type=str, default=None, nargs="?", const="")
|
|
75
|
+
parser.add_argument(
|
|
76
|
+
"--auto-approve",
|
|
77
|
+
required=False,
|
|
78
|
+
default=False,
|
|
79
|
+
action="store_true",
|
|
80
|
+
help="Skip interactive approval of changes to github before applying.",
|
|
81
|
+
)
|
|
72
82
|
parser.add_argument("--summary-csv", type=str, default="")
|
|
73
83
|
parser.add_argument("--group-csv", type=str, default="")
|
|
74
84
|
parser.add_argument("--commands-json-file", type=str, default="./commands.json")
|
|
@@ -17,8 +17,16 @@ import packaging
|
|
|
17
17
|
import redis
|
|
18
18
|
from packaging import version
|
|
19
19
|
import time
|
|
20
|
+
from github import Github
|
|
20
21
|
|
|
21
22
|
|
|
23
|
+
from redis_benchmarks_specification.__common__.github import (
|
|
24
|
+
update_comment_if_needed,
|
|
25
|
+
create_new_pr_comment,
|
|
26
|
+
check_github_available_and_actionable,
|
|
27
|
+
generate_build_finished_pr_comment,
|
|
28
|
+
)
|
|
29
|
+
|
|
22
30
|
from redis_benchmarks_specification.__cli__.args import spec_cli_args
|
|
23
31
|
from redis_benchmarks_specification.__cli__.stats import (
|
|
24
32
|
generate_stats_cli_command_logic,
|
|
@@ -165,6 +173,28 @@ def get_repo(args):
|
|
|
165
173
|
return redisDirPath, cleanUp
|
|
166
174
|
|
|
167
175
|
|
|
176
|
+
def check_benchmark_run_comment(comments):
|
|
177
|
+
res = False
|
|
178
|
+
pos = -1
|
|
179
|
+
for n, comment in enumerate(comments):
|
|
180
|
+
body = comment.body
|
|
181
|
+
if "CE Performance Automation" in body and "Triggered a benchmark" in body:
|
|
182
|
+
res = True
|
|
183
|
+
pos = n
|
|
184
|
+
return res, pos
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def check_benchmark_build_comment(comments):
|
|
188
|
+
res = False
|
|
189
|
+
pos = -1
|
|
190
|
+
for n, comment in enumerate(comments):
|
|
191
|
+
body = comment.body
|
|
192
|
+
if "CE Performance Automation : step 1 of 2" in body:
|
|
193
|
+
res = True
|
|
194
|
+
pos = n
|
|
195
|
+
return res, pos
|
|
196
|
+
|
|
197
|
+
|
|
168
198
|
def trigger_tests_cli_command_logic(args, project_name, project_version):
|
|
169
199
|
logging.info(
|
|
170
200
|
"Using: {project_name} {project_version}".format(
|
|
@@ -176,6 +206,23 @@ def trigger_tests_cli_command_logic(args, project_name, project_version):
|
|
|
176
206
|
logging.error("You must specify either --use-tags or --use-branch flag")
|
|
177
207
|
sys.exit(1)
|
|
178
208
|
|
|
209
|
+
github_token = args.github_token
|
|
210
|
+
pull_request = args.pull_request
|
|
211
|
+
verbose = True
|
|
212
|
+
auto_approve = args.auto_approve
|
|
213
|
+
|
|
214
|
+
fn = check_benchmark_build_comment
|
|
215
|
+
(
|
|
216
|
+
contains_regression_comment,
|
|
217
|
+
github_pr,
|
|
218
|
+
is_actionable_pr,
|
|
219
|
+
old_regression_comment_body,
|
|
220
|
+
pr_link,
|
|
221
|
+
regression_comment,
|
|
222
|
+
) = check_github_available_and_actionable(
|
|
223
|
+
fn, github_token, pull_request, "redis", "redis", verbose
|
|
224
|
+
)
|
|
225
|
+
|
|
179
226
|
redisDirPath, cleanUp = get_repo(args)
|
|
180
227
|
repo = git.Repo(redisDirPath)
|
|
181
228
|
|
|
@@ -267,10 +314,20 @@ def trigger_tests_cli_command_logic(args, project_name, project_version):
|
|
|
267
314
|
)
|
|
268
315
|
if args.platform:
|
|
269
316
|
commit_dict["platform"] = args.platform
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
317
|
+
tests_priority_upper_limit = args.tests_priority_upper_limit
|
|
318
|
+
tests_priority_lower_limit = args.tests_priority_lower_limit
|
|
319
|
+
tests_regexp = args.tests_regexp
|
|
320
|
+
tests_groups_regexp = args.tests_groups_regexp
|
|
321
|
+
commit_dict["tests_priority_upper_limit"] = tests_priority_upper_limit
|
|
322
|
+
commit_dict["tests_priority_lower_limit"] = tests_priority_lower_limit
|
|
323
|
+
commit_dict["tests_regexp"] = tests_regexp
|
|
324
|
+
commit_dict["tests_groups_regexp"] = tests_groups_regexp
|
|
325
|
+
git_hash = cdict["git_hash"]
|
|
326
|
+
git_branch = "n/a"
|
|
327
|
+
if "git_branch" in cdict:
|
|
328
|
+
git_branch = cdict["git_branch"]
|
|
329
|
+
commit_datetime = cdict["commit_datetime"]
|
|
330
|
+
commit_summary = cdict["commit_summary"]
|
|
274
331
|
if result is True:
|
|
275
332
|
stream_id = "n/a"
|
|
276
333
|
if args.dry_run is False:
|
|
@@ -292,6 +349,7 @@ def trigger_tests_cli_command_logic(args, project_name, project_version):
|
|
|
292
349
|
reply_fields,
|
|
293
350
|
)
|
|
294
351
|
)
|
|
352
|
+
|
|
295
353
|
if args.wait_build is True:
|
|
296
354
|
decoded_stream_id = stream_id.decode()
|
|
297
355
|
builder_list_streams = (
|
|
@@ -352,6 +410,31 @@ def trigger_tests_cli_command_logic(args, project_name, project_version):
|
|
|
352
410
|
f"FINAL total of {len_list} already build benchmark stream ids for this build: {benchmark_stream_ids}"
|
|
353
411
|
)
|
|
354
412
|
|
|
413
|
+
comment_body = generate_build_finished_pr_comment(
|
|
414
|
+
benchmark_stream_ids,
|
|
415
|
+
commit_datetime,
|
|
416
|
+
commit_summary,
|
|
417
|
+
git_branch,
|
|
418
|
+
git_hash,
|
|
419
|
+
tests_groups_regexp,
|
|
420
|
+
tests_priority_lower_limit,
|
|
421
|
+
tests_priority_upper_limit,
|
|
422
|
+
tests_regexp,
|
|
423
|
+
)
|
|
424
|
+
if is_actionable_pr:
|
|
425
|
+
if contains_regression_comment:
|
|
426
|
+
update_comment_if_needed(
|
|
427
|
+
auto_approve,
|
|
428
|
+
comment_body,
|
|
429
|
+
old_regression_comment_body,
|
|
430
|
+
regression_comment,
|
|
431
|
+
verbose,
|
|
432
|
+
)
|
|
433
|
+
else:
|
|
434
|
+
create_new_pr_comment(
|
|
435
|
+
auto_approve, comment_body, github_pr, pr_link
|
|
436
|
+
)
|
|
437
|
+
|
|
355
438
|
else:
|
|
356
439
|
logging.info(
|
|
357
440
|
"DRY-RUN: build for commit: {}. Date: {} Full commited info: {}".format(
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from github import Github
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def generate_build_finished_pr_comment(
|
|
6
|
+
benchmark_stream_ids,
|
|
7
|
+
commit_datetime,
|
|
8
|
+
commit_summary,
|
|
9
|
+
git_branch,
|
|
10
|
+
git_hash,
|
|
11
|
+
tests_groups_regexp,
|
|
12
|
+
tests_priority_lower_limit,
|
|
13
|
+
tests_priority_upper_limit,
|
|
14
|
+
tests_regexp,
|
|
15
|
+
):
|
|
16
|
+
comment_body = "### CE Performance Automation : step 1 of 2 (build) done\n\n"
|
|
17
|
+
comment_body += (
|
|
18
|
+
"This comment was automatically generated given a benchmark was triggered.\n"
|
|
19
|
+
)
|
|
20
|
+
comment_body += "You can check each build/benchmark progress in grafana:\n"
|
|
21
|
+
comment_body += f" - git hash: {git_hash}\n"
|
|
22
|
+
comment_body += f" - git branch: {git_branch}\n"
|
|
23
|
+
comment_body += f" - commit date and time: {commit_datetime}\n"
|
|
24
|
+
comment_body += f" - commit summary: {commit_summary}\n"
|
|
25
|
+
comment_body += f" - test filters:\n"
|
|
26
|
+
comment_body += (
|
|
27
|
+
f" - command priority lower limit: {tests_priority_lower_limit}\n"
|
|
28
|
+
)
|
|
29
|
+
comment_body += (
|
|
30
|
+
f" - command priority upper limit: {tests_priority_upper_limit}\n"
|
|
31
|
+
)
|
|
32
|
+
comment_body += f" - test name regex: {tests_regexp}\n"
|
|
33
|
+
comment_body += f" - command group regex: {tests_groups_regexp}\n\n"
|
|
34
|
+
for benchmark_stream_id in benchmark_stream_ids:
|
|
35
|
+
benchmark_stream_id = benchmark_stream_id.decode()
|
|
36
|
+
grafana_benchmark_status_link = f"https://benchmarksredisio.grafana.net/d/edsxdsrbexhc0f/ce-benchmark-run-status?orgId=1&var-benchmark_work_stream={benchmark_stream_id}"
|
|
37
|
+
print("=============================================================")
|
|
38
|
+
print(f"Check benchmark run status in: {grafana_benchmark_status_link}")
|
|
39
|
+
comment_body += f"You can check a comparison in detail via the [grafana link]({grafana_benchmark_status_link})"
|
|
40
|
+
return comment_body
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def check_github_available_and_actionable(
|
|
44
|
+
fn, github_token, pull_request, tf_github_org, tf_github_repo, verbose
|
|
45
|
+
):
|
|
46
|
+
# using an access token
|
|
47
|
+
is_actionable_pr = False
|
|
48
|
+
contains_regression_comment = False
|
|
49
|
+
regression_comment = None
|
|
50
|
+
github_pr = None
|
|
51
|
+
old_regression_comment_body = ""
|
|
52
|
+
if github_token is not None:
|
|
53
|
+
logging.info("Detected github token")
|
|
54
|
+
g = Github(github_token)
|
|
55
|
+
if pull_request is not None and pull_request != "":
|
|
56
|
+
pull_request_n = int(pull_request)
|
|
57
|
+
github_pr = (
|
|
58
|
+
g.get_user(tf_github_org)
|
|
59
|
+
.get_repo(tf_github_repo)
|
|
60
|
+
.get_issue(pull_request_n)
|
|
61
|
+
)
|
|
62
|
+
comments = github_pr.get_comments()
|
|
63
|
+
pr_link = github_pr.html_url
|
|
64
|
+
logging.info("Working on github PR already: {}".format(pr_link))
|
|
65
|
+
is_actionable_pr = True
|
|
66
|
+
contains_regression_comment, pos = fn(comments)
|
|
67
|
+
if contains_regression_comment:
|
|
68
|
+
regression_comment = comments[pos]
|
|
69
|
+
old_regression_comment_body = regression_comment.body
|
|
70
|
+
logging.info(
|
|
71
|
+
"Already contains PR comment. Link: {}".format(
|
|
72
|
+
regression_comment.html_url
|
|
73
|
+
)
|
|
74
|
+
)
|
|
75
|
+
if verbose:
|
|
76
|
+
logging.info("Printing old PR comment:")
|
|
77
|
+
print("".join(["-" for x in range(1, 80)]))
|
|
78
|
+
print(regression_comment.body)
|
|
79
|
+
print("".join(["-" for x in range(1, 80)]))
|
|
80
|
+
else:
|
|
81
|
+
logging.info("Does not contain PR comment")
|
|
82
|
+
return (
|
|
83
|
+
contains_regression_comment,
|
|
84
|
+
github_pr,
|
|
85
|
+
is_actionable_pr,
|
|
86
|
+
old_regression_comment_body,
|
|
87
|
+
pr_link,
|
|
88
|
+
regression_comment,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def create_new_pr_comment(auto_approve, comment_body, github_pr, pr_link):
|
|
93
|
+
user_input = "n"
|
|
94
|
+
if auto_approve:
|
|
95
|
+
print("auto approving...")
|
|
96
|
+
else:
|
|
97
|
+
user_input = input("Do you wish to add a comment in {} (y/n): ".format(pr_link))
|
|
98
|
+
if user_input.lower() == "y" or auto_approve:
|
|
99
|
+
print("creating an comment in PR {}".format(pr_link))
|
|
100
|
+
regression_comment = github_pr.create_comment(comment_body)
|
|
101
|
+
html_url = regression_comment.html_url
|
|
102
|
+
print("created comment. Access it via {}".format(html_url))
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def update_comment_if_needed(
|
|
106
|
+
auto_approve, comment_body, old_regression_comment_body, regression_comment, verbose
|
|
107
|
+
):
|
|
108
|
+
same_comment = False
|
|
109
|
+
user_input = "n"
|
|
110
|
+
if comment_body == old_regression_comment_body:
|
|
111
|
+
logging.info(
|
|
112
|
+
"The old regression comment is the same as the new comment. skipping..."
|
|
113
|
+
)
|
|
114
|
+
same_comment = True
|
|
115
|
+
else:
|
|
116
|
+
logging.info(
|
|
117
|
+
"The old regression comment is different from the new comment. updating it..."
|
|
118
|
+
)
|
|
119
|
+
comment_body_arr = comment_body.split("\n")
|
|
120
|
+
old_regression_comment_body_arr = old_regression_comment_body.split("\n")
|
|
121
|
+
if verbose:
|
|
122
|
+
DF = [
|
|
123
|
+
x for x in comment_body_arr if x not in old_regression_comment_body_arr
|
|
124
|
+
]
|
|
125
|
+
print("---------------------")
|
|
126
|
+
print(DF)
|
|
127
|
+
print("---------------------")
|
|
128
|
+
if same_comment is False:
|
|
129
|
+
if auto_approve:
|
|
130
|
+
print("auto approving...")
|
|
131
|
+
else:
|
|
132
|
+
user_input = input(
|
|
133
|
+
"Do you wish to update the comment {} (y/n): ".format(
|
|
134
|
+
regression_comment.html_url
|
|
135
|
+
)
|
|
136
|
+
)
|
|
137
|
+
if user_input.lower() == "y" or auto_approve:
|
|
138
|
+
print("Updating comment {}".format(regression_comment.html_url))
|
|
139
|
+
regression_comment.edit(comment_body)
|
|
140
|
+
html_url = regression_comment.html_url
|
|
141
|
+
print(
|
|
142
|
+
"Updated comment. Access it via {}".format(regression_comment.html_url)
|
|
143
|
+
)
|
|
@@ -14,8 +14,13 @@ import humanize
|
|
|
14
14
|
import datetime as dt
|
|
15
15
|
import os
|
|
16
16
|
from tqdm import tqdm
|
|
17
|
-
from github import Github
|
|
18
17
|
import argparse
|
|
18
|
+
|
|
19
|
+
from redis_benchmarks_specification.__common__.github import (
|
|
20
|
+
update_comment_if_needed,
|
|
21
|
+
create_new_pr_comment,
|
|
22
|
+
check_github_available_and_actionable,
|
|
23
|
+
)
|
|
19
24
|
from redis_benchmarks_specification.__compare__.args import create_compare_arguments
|
|
20
25
|
|
|
21
26
|
|
|
@@ -276,11 +281,7 @@ def compare_command_logic(args, project_name, project_version):
|
|
|
276
281
|
auto_approve = args.auto_approve
|
|
277
282
|
running_platform = args.running_platform
|
|
278
283
|
grafana_base_dashboard = args.grafana_base_dashboard
|
|
279
|
-
|
|
280
|
-
is_actionable_pr = False
|
|
281
|
-
contains_regression_comment = False
|
|
282
|
-
regression_comment = None
|
|
283
|
-
github_pr = None
|
|
284
|
+
|
|
284
285
|
if running_platform is not None:
|
|
285
286
|
logging.info(
|
|
286
287
|
"Using platform named: {} to do the comparison.\n\n".format(
|
|
@@ -288,37 +289,17 @@ def compare_command_logic(args, project_name, project_version):
|
|
|
288
289
|
)
|
|
289
290
|
)
|
|
290
291
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
comments = github_pr.get_comments()
|
|
303
|
-
pr_link = github_pr.html_url
|
|
304
|
-
logging.info("Working on github PR already: {}".format(pr_link))
|
|
305
|
-
is_actionable_pr = True
|
|
306
|
-
contains_regression_comment, pos = check_regression_comment(comments)
|
|
307
|
-
if contains_regression_comment:
|
|
308
|
-
regression_comment = comments[pos]
|
|
309
|
-
old_regression_comment_body = regression_comment.body
|
|
310
|
-
logging.info(
|
|
311
|
-
"Already contains regression comment. Link: {}".format(
|
|
312
|
-
regression_comment.html_url
|
|
313
|
-
)
|
|
314
|
-
)
|
|
315
|
-
if verbose:
|
|
316
|
-
logging.info("Printing old regression comment:")
|
|
317
|
-
print("".join(["-" for x in range(1, 80)]))
|
|
318
|
-
print(regression_comment.body)
|
|
319
|
-
print("".join(["-" for x in range(1, 80)]))
|
|
320
|
-
else:
|
|
321
|
-
logging.info("Does not contain regression comment")
|
|
292
|
+
fn = check_regression_comment
|
|
293
|
+
(
|
|
294
|
+
contains_regression_comment,
|
|
295
|
+
github_pr,
|
|
296
|
+
is_actionable_pr,
|
|
297
|
+
old_regression_comment_body,
|
|
298
|
+
pr_link,
|
|
299
|
+
regression_comment,
|
|
300
|
+
) = check_github_available_and_actionable(
|
|
301
|
+
fn, github_token, pull_request, tf_github_org, tf_github_repo, verbose
|
|
302
|
+
)
|
|
322
303
|
|
|
323
304
|
grafana_dashboards_uids = {
|
|
324
305
|
"redisgraph": "SH9_rQYGz",
|
|
@@ -464,60 +445,15 @@ def compare_command_logic(args, project_name, project_version):
|
|
|
464
445
|
)
|
|
465
446
|
|
|
466
447
|
if contains_regression_comment:
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
logging.info(
|
|
475
|
-
"The old regression comment is different from the new comment. updating it..."
|
|
476
|
-
)
|
|
477
|
-
comment_body_arr = comment_body.split("\n")
|
|
478
|
-
old_regression_comment_body_arr = old_regression_comment_body.split(
|
|
479
|
-
"\n"
|
|
480
|
-
)
|
|
481
|
-
if verbose:
|
|
482
|
-
DF = [
|
|
483
|
-
x
|
|
484
|
-
for x in comment_body_arr
|
|
485
|
-
if x not in old_regression_comment_body_arr
|
|
486
|
-
]
|
|
487
|
-
print("---------------------")
|
|
488
|
-
print(DF)
|
|
489
|
-
print("---------------------")
|
|
490
|
-
if same_comment is False:
|
|
491
|
-
if auto_approve:
|
|
492
|
-
print("auto approving...")
|
|
493
|
-
else:
|
|
494
|
-
user_input = input(
|
|
495
|
-
"Do you wish to update the comment {} (y/n): ".format(
|
|
496
|
-
regression_comment.html_url
|
|
497
|
-
)
|
|
498
|
-
)
|
|
499
|
-
if user_input.lower() == "y" or auto_approve:
|
|
500
|
-
print("Updating comment {}".format(regression_comment.html_url))
|
|
501
|
-
regression_comment.edit(comment_body)
|
|
502
|
-
html_url = regression_comment.html_url
|
|
503
|
-
print(
|
|
504
|
-
"Updated comment. Access it via {}".format(
|
|
505
|
-
regression_comment.html_url
|
|
506
|
-
)
|
|
507
|
-
)
|
|
508
|
-
|
|
448
|
+
update_comment_if_needed(
|
|
449
|
+
auto_approve,
|
|
450
|
+
comment_body,
|
|
451
|
+
old_regression_comment_body,
|
|
452
|
+
regression_comment,
|
|
453
|
+
verbose,
|
|
454
|
+
)
|
|
509
455
|
else:
|
|
510
|
-
|
|
511
|
-
print("auto approving...")
|
|
512
|
-
else:
|
|
513
|
-
user_input = input(
|
|
514
|
-
"Do you wish to add a comment in {} (y/n): ".format(pr_link)
|
|
515
|
-
)
|
|
516
|
-
if user_input.lower() == "y" or auto_approve:
|
|
517
|
-
print("creating an comment in PR {}".format(pr_link))
|
|
518
|
-
regression_comment = github_pr.create_comment(comment_body)
|
|
519
|
-
html_url = regression_comment.html_url
|
|
520
|
-
print("created comment. Access it via {}".format(html_url))
|
|
456
|
+
create_new_pr_comment(auto_approve, comment_body, github_pr, pr_link)
|
|
521
457
|
|
|
522
458
|
else:
|
|
523
459
|
logging.error("There was no comparison points to produce a table...")
|
|
@@ -476,15 +476,19 @@ def process_self_contained_coordinator_stream(
|
|
|
476
476
|
|
|
477
477
|
filtered_test_files = []
|
|
478
478
|
|
|
479
|
-
|
|
480
|
-
|
|
479
|
+
stream_time_ms = stream_id.split("-")[0]
|
|
480
|
+
zset_running_platform_benchmarks = f"ci.benchmarks.redis/ci/redis/redis:benchmarks:{running_platform}:zset"
|
|
481
|
+
res = conn.zadd(
|
|
482
|
+
zset_running_platform_benchmarks,
|
|
483
|
+
{stream_id: stream_time_ms},
|
|
481
484
|
)
|
|
482
|
-
|
|
483
|
-
f"{stream_id}
|
|
484
|
-
)
|
|
485
|
-
stream_test_list_completed = (
|
|
486
|
-
f"{stream_id}:{running_platform}:tests_completed"
|
|
485
|
+
logging.info(
|
|
486
|
+
f"Added stream with id {stream_id} to zset {zset_running_platform_benchmarks}"
|
|
487
487
|
)
|
|
488
|
+
|
|
489
|
+
stream_test_list_pending = f"ci.benchmarks.redis/ci/redis/redis:benchmarks:{stream_id}:{running_platform}:tests_pending"
|
|
490
|
+
stream_test_list_running = f"ci.benchmarks.redis/ci/redis/redis:benchmarks:{stream_id}:{running_platform}:tests_running"
|
|
491
|
+
stream_test_list_completed = f"ci.benchmarks.redis/ci/redis/redis:benchmarks:{stream_id}:{running_platform}:tests_completed"
|
|
488
492
|
for test_file in testsuite_spec_files:
|
|
489
493
|
if defaults_filename in test_file:
|
|
490
494
|
continue
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: redis-benchmarks-specification
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.79
|
|
4
4
|
Summary: 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.
|
|
5
5
|
Author: filipecosta90
|
|
6
6
|
Author-email: filipecosta.90@gmail.com
|
|
@@ -9,7 +9,6 @@ Classifier: Programming Language :: Python :: 3
|
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.9
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.10
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
13
12
|
Requires-Dist: Flask (>=2.0.3,<3.0.0)
|
|
14
13
|
Requires-Dist: Flask-HTTPAuth (>=4.4.0,<5.0.0)
|
|
15
14
|
Requires-Dist: GitPython (>=3.1.20,<4.0.0)
|
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
redis_benchmarks_specification/__api__/Readme.md,sha256=RbaYRIIJkCq7bH7-t_0ZgPA8qmMBlrpVE2Y9m6UVmuo,107
|
|
2
2
|
redis_benchmarks_specification/__api__/__init__.py,sha256=4uNmle9t2lYpOvOtZU4basJF1EJJ1iEuXuQC00EGHn0,93
|
|
3
3
|
redis_benchmarks_specification/__api__/api.py,sha256=k_CMICtMm1z8jY3hByaL0hIr_5vBhaFoCaeRv_CDm9g,2730
|
|
4
|
-
redis_benchmarks_specification/__api__/app.py,sha256=
|
|
4
|
+
redis_benchmarks_specification/__api__/app.py,sha256=ynFwqX9_arzcYsCt6I20tTpJ8BbucS32Yne3LE0aBI8,7070
|
|
5
5
|
redis_benchmarks_specification/__builder__/Readme.md,sha256=O6MV_J3OSgzW-ir2TbukP8Vhkm_LOzQJJndG1Cykqic,111
|
|
6
6
|
redis_benchmarks_specification/__builder__/__init__.py,sha256=l-G1z-t6twUgi8QLueqoTQLvJmv3hJoEYskGm6H7L6M,83
|
|
7
|
-
redis_benchmarks_specification/__builder__/builder.py,sha256=
|
|
7
|
+
redis_benchmarks_specification/__builder__/builder.py,sha256=Yb49RcjmDOWTqTy9wEwTnULJQIZriq1O7lU3rpx74VY,22691
|
|
8
8
|
redis_benchmarks_specification/__builder__/schema.py,sha256=1wcmyVJBcWrBvK58pghN9NCoWLCO3BzPsmdKWYfkVog,584
|
|
9
9
|
redis_benchmarks_specification/__cli__/__init__.py,sha256=l-G1z-t6twUgi8QLueqoTQLvJmv3hJoEYskGm6H7L6M,83
|
|
10
|
-
redis_benchmarks_specification/__cli__/args.py,sha256=
|
|
11
|
-
redis_benchmarks_specification/__cli__/cli.py,sha256=
|
|
10
|
+
redis_benchmarks_specification/__cli__/args.py,sha256=GU7lJBTLtufypa1R25Ey2PeBUu9fr0Tv4iGk6wfrsRQ,6186
|
|
11
|
+
redis_benchmarks_specification/__cli__/cli.py,sha256=JRWSxPyKZfebwMJEy_6pRirke2wZMmJzTgmDmBsO-XE,16863
|
|
12
12
|
redis_benchmarks_specification/__cli__/stats.py,sha256=wahzZRbpfokv8dQU8O4BH5JFrOZk-l6k8LWdKfue9_0,20204
|
|
13
13
|
redis_benchmarks_specification/__common__/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
14
|
redis_benchmarks_specification/__common__/builder_schema.py,sha256=LW00BSz_LXa83wbgRFylOCyRMMH4-3YpWgYh2hevOFM,5693
|
|
15
15
|
redis_benchmarks_specification/__common__/env.py,sha256=l58AH5LC2jQcyPRJA4ue_4kMloOewcqnLvkLWfzph_A,3119
|
|
16
|
+
redis_benchmarks_specification/__common__/github.py,sha256=u0XGH0uFt4p5pmjXKmuxpEAMlIAPLsRxG5uZwDF_v44,5721
|
|
16
17
|
redis_benchmarks_specification/__common__/package.py,sha256=4uVt1BAZ999LV2rZkq--Tk6otAVIf9YR3g3KGeUpiW4,834
|
|
17
18
|
redis_benchmarks_specification/__common__/runner.py,sha256=6x1L8UAo-gmxLMcsUU4FGQ5OLV08fqygDnoVZ1rVUVQ,6642
|
|
18
19
|
redis_benchmarks_specification/__common__/spec.py,sha256=3hvfAb7RuAsqB_PNEo_-iuOtgz1ZCWe3ouMwS5Mw54A,1002
|
|
19
20
|
redis_benchmarks_specification/__compare__/__init__.py,sha256=DtBXRp0Q01XgCFmY-1OIePMyyYihVNAjZ1Y8zwqSDN0,101
|
|
20
21
|
redis_benchmarks_specification/__compare__/args.py,sha256=71-pYjlbTQNAXQMbAiet898yhWRIplBBNU5USQqFar4,5341
|
|
21
|
-
redis_benchmarks_specification/__compare__/compare.py,sha256=
|
|
22
|
+
redis_benchmarks_specification/__compare__/compare.py,sha256=6LuWtVxfjwNgCOeS5tuLexp9ap5bF1hP092Pfts1wZE,36584
|
|
22
23
|
redis_benchmarks_specification/__init__.py,sha256=YQIEx2sLPPA0JR9OuCuMNMNtm-f_gqDKgzvNJnkGNKY,491
|
|
23
24
|
redis_benchmarks_specification/__runner__/__init__.py,sha256=l-G1z-t6twUgi8QLueqoTQLvJmv3hJoEYskGm6H7L6M,83
|
|
24
25
|
redis_benchmarks_specification/__runner__/args.py,sha256=lYvbPd_3ppHZv4f2sRwXcF-fcBrwRSn3H2RMmNVkojY,7221
|
|
@@ -32,7 +33,7 @@ redis_benchmarks_specification/__self_contained_coordinator__/cpuset.py,sha256=s
|
|
|
32
33
|
redis_benchmarks_specification/__self_contained_coordinator__/docker.py,sha256=iivxZ55vL2kVHHkqVbXY2ftvxvceqH_Zw079KLCv9N8,2507
|
|
33
34
|
redis_benchmarks_specification/__self_contained_coordinator__/prepopulation.py,sha256=ajhpzxsBy6tiHrO79gEIKQYxZR-Us6B4rC6NYg1EZjM,2875
|
|
34
35
|
redis_benchmarks_specification/__self_contained_coordinator__/runners.py,sha256=Ul8UoxvWRxCVWmyaCBadpLMDOVEoNSp-A9KMPtPmUwM,28483
|
|
35
|
-
redis_benchmarks_specification/__self_contained_coordinator__/self_contained_coordinator.py,sha256=
|
|
36
|
+
redis_benchmarks_specification/__self_contained_coordinator__/self_contained_coordinator.py,sha256=coRIM_XS4pq3GFnSIuTO26WIoN_qfg-s3zWZ08H5yIA,50016
|
|
36
37
|
redis_benchmarks_specification/__setups__/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
38
|
redis_benchmarks_specification/__setups__/topologies.py,sha256=xQ1IJkcTji_ZjLiJd3vOxZpvbNtBLZw9cPkw5hGJKHU,481
|
|
38
39
|
redis_benchmarks_specification/__spec__/__init__.py,sha256=l-G1z-t6twUgi8QLueqoTQLvJmv3hJoEYskGm6H7L6M,83
|
|
@@ -149,8 +150,8 @@ redis_benchmarks_specification/test-suites/memtier_benchmark-2keys-set-10-100-el
|
|
|
149
150
|
redis_benchmarks_specification/test-suites/memtier_benchmark-2keys-stream-5-entries-xread-all-entries-pipeline-10.yml,sha256=RSkNgV5SsjdkXhM0mifi2GlwIxtiHR8N3u-ieI23BoQ,1126
|
|
150
151
|
redis_benchmarks_specification/test-suites/memtier_benchmark-2keys-stream-5-entries-xread-all-entries.yml,sha256=w7-dOIU-eATHXCvJbSeih6Vt54oygtkXKskQdzCll3o,1100
|
|
151
152
|
redis_benchmarks_specification/test-suites/template.txt,sha256=qrci_94QV9bPUJe0cL8lsUaQmX5Woz-jT-pDF0629AE,423
|
|
152
|
-
redis_benchmarks_specification-0.1.
|
|
153
|
-
redis_benchmarks_specification-0.1.
|
|
154
|
-
redis_benchmarks_specification-0.1.
|
|
155
|
-
redis_benchmarks_specification-0.1.
|
|
156
|
-
redis_benchmarks_specification-0.1.
|
|
153
|
+
redis_benchmarks_specification-0.1.79.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
154
|
+
redis_benchmarks_specification-0.1.79.dist-info/METADATA,sha256=YA_2heKbmcb--nH5HmOjpVo0F8BSiYutwVIWn6JrZpw,22482
|
|
155
|
+
redis_benchmarks_specification-0.1.79.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
|
|
156
|
+
redis_benchmarks_specification-0.1.79.dist-info/entry_points.txt,sha256=x5WBXCZsnDRTZxV7SBGmC65L2k-ygdDOxV8vuKN00Nk,715
|
|
157
|
+
redis_benchmarks_specification-0.1.79.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|