8
8
9
9
from redis_benchmarks_specification .__common__ .runner import get_benchmark_specs
10
10
11
+
11
12
# logging settings
12
13
logging .basicConfig (
13
14
format = "%(asctime)s %(levelname)-4s %(message)s" ,
16
17
)
17
18
18
19
20
+ def clean_number (value ):
21
+ """Cleans and converts numeric values from CSV, handling B (billion), M (million), K (thousand)."""
22
+ try :
23
+ value = value .replace ("," , "" ).strip () # Remove commas and spaces
24
+
25
+ # Determine the scale factor
26
+ multiplier = 1
27
+ if value .endswith ("B" ):
28
+ multiplier = 1_000_000_000 # Billion
29
+ value = value [:- 1 ] # Remove "B"
30
+ elif value .endswith ("M" ):
31
+ multiplier = 1_000_000 # Million
32
+ value = value [:- 1 ] # Remove "M"
33
+ elif value .endswith ("K" ):
34
+ multiplier = 1_000 # Thousand
35
+ value = value [:- 1 ] # Remove "K"
36
+
37
+ return int (float (value ) * multiplier ) # Convert to full number
38
+ except ValueError :
39
+ logging .error (f"Skipping invalid count value: { value } " )
40
+ return 0 # Default to 0 if invalid
41
+
42
+
43
+ def get_arg_value (args , flag , default ):
44
+ """Extract integer values safely from CLI arguments"""
45
+ if flag in args :
46
+ try :
47
+ val = (
48
+ args [args .index (flag ) + 1 ].lstrip ("=" ).strip ()
49
+ ) # Remove any leading '='
50
+ return int (val ) # Convert to integer safely
51
+ except (IndexError , ValueError ):
52
+ logging .error (f"Failed to extract { flag } , using default: { default } " )
53
+ return default # Return default if not found or invalid
54
+
55
+
19
56
def generate_stats_cli_command_logic (args , project_name , project_version ):
20
57
logging .info (
21
58
"Using: {project_name} {project_version}" .format (
@@ -55,10 +92,14 @@ def generate_stats_cli_command_logic(args, project_name, project_version):
55
92
)
56
93
priority_json = json .load (fd )
57
94
tracked_groups = []
95
+ tracked_groups_hist = {}
58
96
override_enabled = args .override_tests
59
97
fail_on_required_diff = args .fail_on_required_diff
60
98
overall_result = True
61
99
test_names = []
100
+ pipelines = {}
101
+ connections = {}
102
+ data_sizes = {}
62
103
defaults_filename = args .defaults_filename
63
104
64
105
for test_file in testsuite_spec_files :
@@ -83,6 +124,13 @@ def generate_stats_cli_command_logic(args, project_name, project_version):
83
124
test_names .append (test_name )
84
125
group = ""
85
126
is_memtier = False
127
+
128
+ ## defaults
129
+ pipeline_size = 1
130
+ clients = 50
131
+ threads = 4
132
+ data_size = 32
133
+
86
134
if "memtier" in test_name :
87
135
is_memtier = True
88
136
tested_groups = []
@@ -101,6 +149,32 @@ def generate_stats_cli_command_logic(args, project_name, project_version):
101
149
tested_commands .append (tested_command .lower ())
102
150
if is_memtier :
103
151
arguments = benchmark_config ["clientconfig" ]["arguments" ]
152
+ arg_list = (
153
+ benchmark_config ["clientconfig" ]["arguments" ]
154
+ .replace ('"' , "" )
155
+ .split ()
156
+ )
157
+
158
+ data_size = get_arg_value (arg_list , "--data-size" , data_size )
159
+ data_size = get_arg_value (arg_list , "-d" , data_size )
160
+
161
+ # Extract values using the safer parsing function
162
+ pipeline_size = get_arg_value (arg_list , "--pipeline" , pipeline_size )
163
+ pipeline_size = get_arg_value (
164
+ arg_list , "-P" , pipeline_size
165
+ ) # Support short form
166
+
167
+ # Extract values using the safer parsing function
168
+ clients = get_arg_value (arg_list , "--clients" , clients )
169
+ clients = get_arg_value (
170
+ arg_list , "-c" , clients
171
+ ) # Support short form
172
+
173
+ threads = get_arg_value (arg_list , "--threads" , threads )
174
+ threads = get_arg_value (
175
+ arg_list , "-t" , threads
176
+ ) # Support short form
177
+
104
178
arguments_split = arguments .split ("--command" )
105
179
106
180
if len (arguments_split ) == 1 :
@@ -133,9 +207,27 @@ def generate_stats_cli_command_logic(args, project_name, project_version):
133
207
134
208
group = command_json ["group" ]
135
209
if group not in tested_groups :
210
+
136
211
tested_groups .append (group )
137
212
if group not in tracked_groups :
138
213
tracked_groups .append (group )
214
+ tracked_groups_hist [group ] = 0
215
+ tracked_groups_hist [group ] = tracked_groups_hist [group ] + 1
216
+
217
+ # Calculate total connections
218
+ total_connections = clients * threads
219
+
220
+ if pipeline_size not in pipelines :
221
+ pipelines [pipeline_size ] = 0
222
+ pipelines [pipeline_size ] = pipelines [pipeline_size ] + 1
223
+
224
+ if total_connections not in connections :
225
+ connections [total_connections ] = 0
226
+ connections [total_connections ] = connections [total_connections ] + 1
227
+
228
+ if data_size not in data_sizes :
229
+ data_sizes [data_size ] = 0
230
+ data_sizes [data_size ] = data_sizes [data_size ] + 1
139
231
140
232
if tested_commands != origin_tested_commands :
141
233
requires_override = True
@@ -281,10 +373,10 @@ def generate_stats_cli_command_logic(args, project_name, project_version):
281
373
if "cmdstat_" not in cmdstat :
282
374
continue
283
375
cmdstat = cmdstat .replace ("cmdstat_" , "" )
284
- count = int (row [1 ])
376
+ count = clean_number (row [1 ])
285
377
usecs = None
286
378
if len (row ) > 2 :
287
- usecs = int (row [2 ])
379
+ usecs = clean_number (row [2 ])
288
380
total_usecs += usecs
289
381
if count == 0 :
290
382
continue
@@ -470,11 +562,15 @@ def generate_stats_cli_command_logic(args, project_name, project_version):
470
562
logging .info ("Top 10 fully tracked?: {}" .format (len (top_10_missing ) == 0 ))
471
563
logging .info ("Top 30 fully tracked?: {}" .format (len (top_30_missing ) == 0 ))
472
564
if len (top_30_missing ) > 0 :
473
- logging .info ("\t \t Total missing for Top 30: {}" .format (len (top_30_missing )))
565
+ logging .info (
566
+ f"\t \t Total missing for Top 30: { len (top_30_missing )} . { top_30_missing } "
567
+ )
474
568
475
569
logging .info ("Top 50 fully tracked?: {}" .format (len (top_50_missing ) == 0 ))
476
570
if len (top_50_missing ) > 0 :
477
- logging .info ("\t \t Total missing for Top 50: {}" .format (len (top_50_missing )))
571
+ logging .info (
572
+ f"\t \t Total missing for Top 50: { len (top_50_missing )} . { top_50_missing } "
573
+ )
478
574
479
575
if overall_result is False and fail_on_required_diff :
480
576
logging .error (
@@ -500,3 +596,71 @@ def generate_stats_cli_command_logic(args, project_name, project_version):
500
596
conn .sadd (tested_groups_key , group )
501
597
for command in list (tracked_commands_json .keys ()):
502
598
conn .sadd (tested_commands_key , command )
599
+
600
+ logging .info (f"There is a total of : { len (tracked_groups )} tracked command groups." )
601
+ logging .info (
602
+ f"There is a total of : { len (list (tracked_commands_json .keys ()))} tracked commands."
603
+ )
604
+ # Save pipeline count to CSV
605
+ csv_filename = "memtier_pipeline_count.csv"
606
+ with open (csv_filename , "w" , newline = "" ) as csvfile :
607
+ fieldnames = ["pipeline" , "count" ]
608
+ writer = csv .DictWriter (csvfile , fieldnames = fieldnames )
609
+ writer .writeheader ()
610
+ for pipeline_size in sorted (pipelines .keys ()):
611
+ writer .writerow (
612
+ {"pipeline" : pipeline_size , "count" : pipelines [pipeline_size ]}
613
+ )
614
+
615
+ logging .info (f"Pipeline count data saved to { csv_filename } " )
616
+
617
+ csv_filename = "memtier_connection_count.csv"
618
+ with open (csv_filename , "w" , newline = "" ) as csvfile :
619
+ fieldnames = ["connections" , "count" ]
620
+ writer = csv .DictWriter (csvfile , fieldnames = fieldnames )
621
+ writer .writeheader ()
622
+
623
+ # Sort connections dictionary by keys before writing
624
+ for connection_count in sorted (connections .keys ()):
625
+ writer .writerow (
626
+ {
627
+ "connections" : connection_count ,
628
+ "count" : connections [connection_count ],
629
+ }
630
+ )
631
+
632
+ logging .info (f"Sorted connection count data saved to { csv_filename } " )
633
+
634
+ csv_filename = "memtier_data_size_histogram.csv"
635
+ with open (csv_filename , "w" , newline = "" ) as csvfile :
636
+ fieldnames = ["data_size" , "count" ]
637
+ writer = csv .DictWriter (csvfile , fieldnames = fieldnames )
638
+ writer .writeheader ()
639
+
640
+ # Sort connections dictionary by keys before writing
641
+ for data_size in sorted (data_sizes .keys ()):
642
+ writer .writerow (
643
+ {
644
+ "data_size" : data_size ,
645
+ "count" : data_sizes [data_size ],
646
+ }
647
+ )
648
+
649
+ logging .info (f"Sorted data size count data saved to { csv_filename } " )
650
+
651
+ csv_filename = "memtier_groups_histogram.csv"
652
+ with open (csv_filename , "w" , newline = "" ) as csvfile :
653
+ fieldnames = ["group" , "count" ]
654
+ writer = csv .DictWriter (csvfile , fieldnames = fieldnames )
655
+ writer .writeheader ()
656
+
657
+ # Sort connections dictionary by keys before writing
658
+ for group in sorted (tracked_groups_hist .keys ()):
659
+ writer .writerow (
660
+ {
661
+ "group" : group ,
662
+ "count" : tracked_groups_hist [group ],
663
+ }
664
+ )
665
+
666
+ logging .info (f"Sorted command groups count data saved to { csv_filename } " )
0 commit comments