Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions generic_config_updater/field_operation_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,30 @@ def rdma_config_update_validator(scope, patch_element):


def buffer_profile_config_update_validator(scope, patch_element):
"""
Enhanced buffer profile validator that handles both field-level and object-level operations.
- Field-level operations (e.g., /BUFFER_PROFILE/profile/dynamic_th) follow existing rules
- Object-level operations (e.g., /BUFFER_PROFILE/profile) allow remove operations
"""
path = patch_element["path"]
path_parts = jsonpointer.JsonPointer(path).parts

# Determine if this is an object-level operation (entire profile) or field-level operation
# Object-level: /BUFFER_PROFILE/profile_name (2 parts)
# Field-level: /BUFFER_PROFILE/profile_name/field_name (3+ parts)
is_object_level = len(path_parts) == 2 # table + profile_name only

if is_object_level:
# For object-level operations, we're more permissive
# Allow add/remove/replace operations for entire profile objects
allowed_object_operations = ['add', 'remove', 'replace']

if patch_element['op'] in allowed_object_operations:
return True # Allow object-level operations
else:
return False # Disallow unsupported operations

# For field-level operations, use the existing validation logic
return rdma_config_update_validator_common(scope, patch_element)


Expand Down
44 changes: 44 additions & 0 deletions tests/generic_config_updater/field_operation_validator_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,50 @@ def test_buffer_profile_config_update_validator(self, scope, asic, field, value,
):
assert fov.buffer_profile_config_update_validator(scope, patch_element) is True

def test_buffer_profile_config_update_validator_object_level_remove(self):
"""Test that object-level remove operations are allowed (fixes rollback issue)"""
patch_element = {
"path": "/BUFFER_PROFILE/pg_lossless_40000_5m_profile",
"op": "remove"
}

# Object-level remove should be allowed without ASIC/version validation
assert fov.buffer_profile_config_update_validator("localhost", patch_element) is True

def test_buffer_profile_config_update_validator_object_level_add(self):
"""Test that object-level add operations are allowed"""
patch_element = {
"path": "/BUFFER_PROFILE/new_profile",
"op": "add",
"value": {"size": "1024", "pool": "ingress_lossless_pool"}
}

# Object-level add should be allowed
assert fov.buffer_profile_config_update_validator("localhost", patch_element) is True

def test_buffer_profile_config_update_validator_object_level_unsupported_op(self):
"""Test that unsupported operations on object-level are denied"""
patch_element = {
"path": "/BUFFER_PROFILE/my_profile",
"op": "move", # Unsupported operation
"from": "/BUFFER_PROFILE/old_profile"
}

assert fov.buffer_profile_config_update_validator("localhost", patch_element) is False

def test_buffer_profile_config_update_validator_field_level_uses_existing_validation(self):
"""Test that field-level operations use existing validation logic"""
patch_element = {
"path": "/BUFFER_PROFILE/my_profile/dynamic_th",
"op": "replace",
"value": "2"
}

# Mock the existing validation to return True
with patch("generic_config_updater.field_operation_validators.rdma_config_update_validator_common",
return_value=True):
assert fov.buffer_profile_config_update_validator("localhost", patch_element) is True

@patch("sonic_py_common.device_info.get_sonic_version_info",
mock.Mock(return_value={"build_version": "SONiC.20220530"}))
@patch("generic_config_updater.field_operation_validators.get_asic_name",
Expand Down
Loading