2323 ACL_RULE_PRIORITY , ACL_TABLE_TYPE_NAME , ACL_RULE_NAME , SRV6_MY_SID_LIST ,
2424 SRV6_INNER_SRC_IP , SRV6_INNER_DST_IP , DEFAULT_QUEUE_SCHEDULER_CONFIG ,
2525 SRV6_UNIFORM_MODE , SRV6_OUTER_SRC_IPV6 , SRV6_INNER_SRC_IPV6 , ECN ,
26- SRV6_INNER_DST_IPV6 , SRV6_UN , ASYM_TC , ASYM_PORT_1_DSCP , ASYM_PORT_2_DSCP )
26+ SRV6_INNER_DST_IPV6 , SRV6_UN , ASYM_TC , ASYM_PORT_1_DSCP , ASYM_PORT_2_DSCP ,
27+ SCHEDULER_TYPE , SCHEDULER_WEIGHT , SCHEDULER_PIR )
2728
2829logger = logging .getLogger (__name__ )
2930
@@ -276,6 +277,101 @@ def generate_packet(duthost, packet_type, dst_addr, send_pkt_size, send_pkt_dscp
276277 return pkt , masked_exp_packet
277278
278279
280+ def get_scheduler_oid_by_attributes (duthost , ** kwargs ):
281+ """
282+ Find scheduler OID in ASIC_DB by matching its attributes.
283+
284+ Args:
285+ duthost: DUT host object
286+ **kwargs: Scheduler attributes to match
287+ - type: Scheduler type (e.g., "DWRR", "STRICT")
288+ - weight: Scheduling weight (e.g., 15)
289+ - pir: Peak Information Rate (e.g., 1)
290+
291+ Returns:
292+ str: OID of the matched scheduler, or None if not found
293+ """
294+ # Mapping from CONFIG_DB parameters to ASIC_DB SAI attributes
295+ param_to_sai_attr = {
296+ 'type' : 'SAI_SCHEDULER_ATTR_SCHEDULING_TYPE' ,
297+ 'weight' : 'SAI_SCHEDULER_ATTR_SCHEDULING_WEIGHT' ,
298+ 'pir' : 'SAI_SCHEDULER_ATTR_MAX_BANDWIDTH_RATE'
299+ }
300+
301+ # Mapping for type values
302+ type_value_mapping = {
303+ 'DWRR' : 'SAI_SCHEDULING_TYPE_DWRR' ,
304+ 'STRICT' : 'SAI_SCHEDULING_TYPE_STRICT'
305+ }
306+
307+ # Build expected attributes dictionary
308+ expected_attrs = {}
309+ for param , value in kwargs .items ():
310+ if param not in param_to_sai_attr :
311+ logger .warning (f"Unknown scheduler parameter: { param } " )
312+ continue
313+
314+ sai_attr = param_to_sai_attr [param ]
315+
316+ # Convert type value to SAI format
317+ if param == 'type' :
318+ if value in type_value_mapping :
319+ expected_attrs [sai_attr ] = type_value_mapping [value ]
320+ else :
321+ logger .warning (f"Unknown scheduler type: { value } " )
322+ continue
323+ else :
324+ # For numeric values, convert to string for comparison
325+ expected_attrs [sai_attr ] = str (value )
326+
327+ logger .info (f"Looking for scheduler with attributes: { expected_attrs } " )
328+
329+ # Get all scheduler OIDs from ASIC_DB
330+ cmd_get_oids = 'redis-cli -n 1 keys "ASIC_STATE:SAI_OBJECT_TYPE_SCHEDULER:oid*"'
331+ result = duthost .shell (cmd_get_oids )
332+
333+ if not result ["stdout" ].strip ():
334+ logger .warning ("No schedulers found in ASIC_DB" )
335+ return None
336+
337+ oid_keys = result ["stdout" ].strip ().split ('\n ' )
338+ logger .info (f"Found { len (oid_keys )} schedulers in ASIC_DB" )
339+
340+ # Check each scheduler to find a match
341+ for oid_key in oid_keys :
342+ # Get all attributes of this scheduler
343+ cmd_get_attrs = f'redis-cli -n 1 hgetall "{ oid_key } "'
344+ result = duthost .shell (cmd_get_attrs )
345+
346+ if not result ["stdout" ].strip ():
347+ continue
348+
349+ # Parse the attributes
350+ lines = result ["stdout" ].strip ().split ('\n ' )
351+ scheduler_attrs = {}
352+ for i in range (0 , len (lines ), 2 ):
353+ if i + 1 < len (lines ):
354+ scheduler_attrs [lines [i ]] = lines [i + 1 ]
355+
356+ # Check if all expected attributes match
357+ is_match = True
358+ for attr_name , expected_value in expected_attrs .items ():
359+ actual_value = scheduler_attrs .get (attr_name )
360+ if actual_value != expected_value :
361+ is_match = False
362+ break
363+
364+ if is_match :
365+ # Extract the OID value (e.g., "0x160000000059aa")
366+ oid_value = oid_key .split (':' )[- 1 ]
367+ logger .info (f"Found matching scheduler OID: { oid_value } " )
368+ logger .debug (f"Scheduler attributes: { scheduler_attrs } " )
369+ return oid_value
370+
371+ logger .warning (f"No scheduler found matching attributes: { expected_attrs } " )
372+ return None
373+
374+
279375def create_blocking_scheduler (duthost ):
280376 """
281377 Create a blocking scheduler for limiting egress traffic
@@ -295,7 +391,7 @@ def create_blocking_scheduler(duthost):
295391 # Create blocking scheduler
296392 cmd_create = (
297393 f'sonic-db-cli CONFIG_DB hset "SCHEDULER|{ BLOCK_DATA_PLANE_SCHEDULER_NAME } " '
298- f'"type" DWRR "weight" 15 "pir" 1 '
394+ f'"type" { SCHEDULER_TYPE } "weight" { SCHEDULER_WEIGHT } "pir" { SCHEDULER_PIR } '
299395 )
300396 duthost .shell (cmd_create )
301397 logger .info (f"Successfully created blocking scheduler: { BLOCK_DATA_PLANE_SCHEDULER_NAME } " )
@@ -351,6 +447,42 @@ def validate_scheduler_configuration(duthost, dut_port, queue, expected_schedule
351447 return False
352448
353449
450+ def validate_scheduler_apply_to_queue_in_asic_db (duthost , scheduler_oid ):
451+ """
452+ Validate that the scheduler is applied to queue in ASIC_DB.
453+
454+ Args:
455+ duthost: DUT host object
456+ scheduler_oid (str): Scheduler OID to validate (e.g., "0x160000000059aa")
457+
458+ Returns:
459+ bool: True if applied to queue in ASIC_DB, False otherwise
460+ """
461+ logger .debug (f"Validating scheduler OID { scheduler_oid } in ASIC_DB" )
462+
463+ # Dump ASIC_DB to a temporary file for faster searching
464+ tmp_file = "/tmp/asic_db_scheduler_check.json"
465+ dump_cmd = f"sonic-db-dump -n ASIC_DB -y > { tmp_file } "
466+ duthost .shell (dump_cmd )
467+
468+ # Search for the scheduler OID in SAI_SCHEDULER_GROUP_ATTR_SCHEDULER_PROFILE_ID
469+ cmd_grep_oid = f'grep "SAI_SCHEDULER_GROUP_ATTR_SCHEDULER_PROFILE_ID" { tmp_file } | grep -c "{ scheduler_oid } "'
470+ result = duthost .shell (cmd_grep_oid )
471+
472+ # Clean up temporary file
473+ duthost .shell (f"rm -f { tmp_file } " )
474+
475+ # Check if scheduler OID is found in ASIC_DB
476+ count = int (result ["stdout" ].strip ()) if result ["stdout" ].strip () else 0
477+
478+ if count > 0 :
479+ logger .debug (f"ASIC_DB scheduler validation successful: OID { scheduler_oid } found in { count } scheduler groups" )
480+ return True
481+ else :
482+ logger .debug (f"ASIC_DB scheduler validation failed: OID { scheduler_oid } not found in any scheduler group" )
483+ return False
484+
485+
354486def disable_egress_data_plane (duthost , dut_port , queue ):
355487 """
356488 Disable egress data plane for a specific queue on a specific port.
@@ -378,11 +510,20 @@ def disable_egress_data_plane(duthost, dut_port, queue):
378510 cmd_block_q = f"sonic-db-cli CONFIG_DB hset 'QUEUE|{ dut_port } |{ queue } ' scheduler { BLOCK_DATA_PLANE_SCHEDULER_NAME } "
379511 duthost .shell (cmd_block_q )
380512
381- # Wait for the blocking scheduler configuration to take effect
513+ # Wait for the blocking scheduler configuration to take effect in CONFIG_DB
382514 pytest_assert (wait_until (60 , 5 , 0 , validate_scheduler_configuration ,
383515 duthost , dut_port , queue , BLOCK_DATA_PLANE_SCHEDULER_NAME ),
384516 f"Blocking scheduler configuration failed for port { dut_port } queue { queue } " )
385517
518+ # Get the blocking scheduler OID from ASIC_DB
519+ scheduler_oid = get_scheduler_oid_by_attributes (duthost , type = SCHEDULER_TYPE ,
520+ weight = SCHEDULER_WEIGHT , pir = SCHEDULER_PIR )
521+ pytest_assert (scheduler_oid , "Failed to find blocking scheduler OID in ASIC_DB" )
522+
523+ # Wait for the blocking scheduler configuration to take effect in ASIC_DB
524+ pytest_assert (wait_until (60 , 5 , 0 , validate_scheduler_apply_to_queue_in_asic_db , duthost , scheduler_oid ),
525+ f"Scheduler OID { scheduler_oid } validation in ASIC_DB failed for port { dut_port } queue { queue } " )
526+
386527 logger .info (f"Successfully applied blocking scheduler to port { dut_port } queue { queue } " )
387528
388529 return original_scheduler
0 commit comments