From 194a0134c708d4528f5be3df4398285566038bc6 Mon Sep 17 00:00:00 2001 From: Dev Ojha <47282568+developfast@users.noreply.github.com> Date: Fri, 23 Jan 2026 17:33:40 -0800 Subject: [PATCH 1/8] Update WRED_PROFILE and BUFFER_POOL validators --- .../gcu_field_operation_validators.conf.json | 58 +------------------ 1 file changed, 2 insertions(+), 56 deletions(-) diff --git a/generic_config_updater/gcu_field_operation_validators.conf.json b/generic_config_updater/gcu_field_operation_validators.conf.json index 8ec7b8bd93..641cb03bca 100644 --- a/generic_config_updater/gcu_field_operation_validators.conf.json +++ b/generic_config_updater/gcu_field_operation_validators.conf.json @@ -68,7 +68,7 @@ "th2": "20181100", "th3": "20240500", "th4": "20240500", - "th5": "20240500", + "th5": "20241200", "td3": "20201200", "td4": "20241100", "q2c+": "20241100", @@ -87,29 +87,9 @@ "rdma_config_update_validator": { "Shared/headroom pool size changes": { "fields": [ - "ingress_lossless_pool/xoff", - "ingress_lossless_pool/size", - "egress_lossy_pool/size" ], - "operations": ["replace"], + "operations": [], "platforms": { - "spc1": "20191100", - "spc2": "20191100", - "spc3": "20220500", - "spc4": "20221100", - "spc5": "20241200", - "td2": "", - "th": "20221100", - "th2": "20221100", - "th3": "20240500", - "th4": "20240500", - "th5": "20240500", - "td3": "20221100", - "td4": "20241100", - "q2c+": "20241100", - "j2c+": "20220500", - "q3d": "20251100", - "cisco-8000": "20201200" } } } @@ -193,40 +173,6 @@ } } }, - "WRED_PROFILE": { - "field_operation_validators": [ "generic_config_updater.field_operation_validators.wred_profile_config_update_validator" ], - "validator_data": { - "rdma_config_update_validator": { - "ECN tuning": { - "fields": [ - "green_min_threshold", - "green_max_threshold", - "green_drop_probability" - ], - "operations": ["replace"], - "platforms": { - "spc1": "20181100", - "spc2": "20191100", - "spc3": "20220500", - "spc4": "20221100", - "spc5": "20241200", - "td2": "20181100", - "th": "20181100", - "th2": "20181100", - "th3": "20240500", - "th4": "20240500", - "th5": "20240500", - "td3": "20201200", - "td4": "20241100", - "q2c+": "20241100", - "j2c+": "20220500", - "q3d": "20251100", - "cisco-8000": "20201200" - } - } - } - } - }, "PORT": { "field_operation_validators": [ "generic_config_updater.field_operation_validators.port_config_update_validator" ] } From 18b49bda616c31c93cf56bfacb2942a7f478f506 Mon Sep 17 00:00:00 2001 From: Dev <47282568+developfast@users.noreply.github.com> Date: Tue, 27 Jan 2026 03:08:33 +0000 Subject: [PATCH 2/8] revert min os version change --- generic_config_updater/gcu_field_operation_validators.conf.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic_config_updater/gcu_field_operation_validators.conf.json b/generic_config_updater/gcu_field_operation_validators.conf.json index 641cb03bca..25e5277cbd 100644 --- a/generic_config_updater/gcu_field_operation_validators.conf.json +++ b/generic_config_updater/gcu_field_operation_validators.conf.json @@ -68,7 +68,7 @@ "th2": "20181100", "th3": "20240500", "th4": "20240500", - "th5": "20241200", + "th5": "20240500", "td3": "20201200", "td4": "20241100", "q2c+": "20241100", From 368c091fba9c6a5eb66f507388564eac17f2058d Mon Sep 17 00:00:00 2001 From: Dev <47282568+developfast@users.noreply.github.com> Date: Tue, 27 Jan 2026 03:09:00 +0000 Subject: [PATCH 3/8] add unit tests for non-validator tables --- .../field_operation_validator_test.py | 153 ++++++++++++++++++ 1 file changed, 153 insertions(+) diff --git a/tests/generic_config_updater/field_operation_validator_test.py b/tests/generic_config_updater/field_operation_validator_test.py index 5106235f10..90f235b720 100644 --- a/tests/generic_config_updater/field_operation_validator_test.py +++ b/tests/generic_config_updater/field_operation_validator_test.py @@ -604,6 +604,159 @@ def test_validate_field_operation_illegal__rm_loopback0(self): target_config ) + def test_validate_field_operation_buffer_queue_replace_profile(self): + old_config = { + "BUFFER_QUEUE": { + "Ethernet0|3": {"profile": "ingress_lossless_profile"} + } + } + target_config = { + "BUFFER_QUEUE": { + "Ethernet0|3": {"profile": "ingress_lossless_profile_new"} + } + } + config_wrapper = gu_common.ConfigWrapper() + config_wrapper.validate_field_operation(old_config, target_config) + + def test_validate_field_operation_buffer_queue_add_profile(self): + old_config = {"BUFFER_QUEUE": {}} + target_config = { + "BUFFER_QUEUE": { + "Ethernet0|4": {"profile": "ingress_lossless_profile"} + } + } + config_wrapper = gu_common.ConfigWrapper() + config_wrapper.validate_field_operation(old_config, target_config) + + def test_validate_field_operation_buffer_queue_remove_entry(self): + old_config = { + "BUFFER_QUEUE": { + "Ethernet0|5": {"profile": "ingress_lossless_profile"} + } + } + target_config = {"BUFFER_QUEUE": {}} + config_wrapper = gu_common.ConfigWrapper() + config_wrapper.validate_field_operation(old_config, target_config) + + def test_validate_field_operation_buffer_pg_replace_profile(self): + old_config = { + "BUFFER_PG": { + "Ethernet0|3-4": {"profile": "pg_lossless_40000_5m_profile"} + } + } + target_config = { + "BUFFER_PG": { + "Ethernet0|3-4": {"profile": "pg_lossless_40000_10m_profile"} + } + } + config_wrapper = gu_common.ConfigWrapper() + config_wrapper.validate_field_operation(old_config, target_config) + + def test_validate_field_operation_buffer_pg_add_profile(self): + old_config = {"BUFFER_PG": {}} + target_config = { + "BUFFER_PG": { + "Ethernet0|5-6": {"profile": "pg_lossless_40000_5m_profile"} + } + } + config_wrapper = gu_common.ConfigWrapper() + config_wrapper.validate_field_operation(old_config, target_config) + + def test_validate_field_operation_buffer_pg_remove_entry(self): + old_config = { + "BUFFER_PG": { + "Ethernet0|7": {"profile": "pg_lossless_40000_5m_profile"} + } + } + target_config = {"BUFFER_PG": {}} + config_wrapper = gu_common.ConfigWrapper() + config_wrapper.validate_field_operation(old_config, target_config) + + @pytest.mark.parametrize( + "table", [ + "BUFFER_PORT_EGRESS_PROFILE_LIST", + "BUFFER_PORT_INGRESS_PROFILE_LIST" + ] + ) + def test_validate_field_operation_buffer_port_profile_list_add(self, table): + old_config = {table: {"Ethernet0": {}}} + target_config = {table: {"Ethernet0": {"profile_list": "AZURE_PROFILE"}}} + config_wrapper = gu_common.ConfigWrapper() + config_wrapper.validate_field_operation(old_config, target_config) + + @pytest.mark.parametrize( + "table", [ + "BUFFER_PORT_EGRESS_PROFILE_LIST", + "BUFFER_PORT_INGRESS_PROFILE_LIST" + ] + ) + def test_validate_field_operation_buffer_port_profile_list_replace(self, table): + old_config = {table: {"Ethernet0": {"profile_list": "AZURE_PROFILE"}}} + target_config = {table: {"Ethernet0": {"profile_list": "NEW_PROFILE"}}} + config_wrapper = gu_common.ConfigWrapper() + config_wrapper.validate_field_operation(old_config, target_config) + + @pytest.mark.parametrize( + "table", [ + "BUFFER_PORT_EGRESS_PROFILE_LIST", + "BUFFER_PORT_INGRESS_PROFILE_LIST" + ] + ) + def test_validate_field_operation_buffer_port_profile_list_remove(self, table): + old_config = {table: {"Ethernet0": {"profile_list": "AZURE_PROFILE"}}} + target_config = {table: {"Ethernet0": {}}} + config_wrapper = gu_common.ConfigWrapper() + config_wrapper.validate_field_operation(old_config, target_config) + + def test_validate_field_operation_queue_scheduler_replace(self): + old_config = {"QUEUE": {"Ethernet0|0": {"scheduler": "sched0"}}} + target_config = {"QUEUE": {"Ethernet0|0": {"scheduler": "sched1"}}} + config_wrapper = gu_common.ConfigWrapper() + config_wrapper.validate_field_operation(old_config, target_config) + + def test_validate_field_operation_queue_wred_profile_add(self): + old_config = {"QUEUE": {"Ethernet0|1": {}}} + target_config = {"QUEUE": {"Ethernet0|1": {"wred_profile": "WRED_PROFILE"}}} + config_wrapper = gu_common.ConfigWrapper() + config_wrapper.validate_field_operation(old_config, target_config) + + def test_validate_field_operation_queue_wred_profile_replace(self): + old_config = {"QUEUE": {"Ethernet0|1": {"wred_profile": "WRED_PROFILE"}}} + target_config = {"QUEUE": {"Ethernet0|1": {"wred_profile": "WRED_PROFILE_NEW"}}} + config_wrapper = gu_common.ConfigWrapper() + config_wrapper.validate_field_operation(old_config, target_config) + + @pytest.mark.parametrize( + "field,new_value", [ + ("dscp_to_tc_map", "AZURE"), + ("tc_to_pg_map", "AZURE"), + ("tc_to_queue_map", "AZURE") + ] + ) + def test_validate_field_operation_port_qos_map_replace(self, field, new_value): + old_config = {"PORT_QOS_MAP": {"Ethernet0": {field: "DEFAULT"}}} + target_config = {"PORT_QOS_MAP": {"Ethernet0": {field: new_value}}} + config_wrapper = gu_common.ConfigWrapper() + config_wrapper.validate_field_operation(old_config, target_config) + + def test_validate_field_operation_port_qos_map_tc_to_dscp_add(self): + old_config = {"PORT_QOS_MAP": {"Ethernet0": {}}} + target_config = {"PORT_QOS_MAP": {"Ethernet0": {"tc_to_dscp_map": "AZURE"}}} + config_wrapper = gu_common.ConfigWrapper() + config_wrapper.validate_field_operation(old_config, target_config) + + def test_validate_field_operation_port_qos_map_tc_to_dscp_replace(self): + old_config = {"PORT_QOS_MAP": {"Ethernet0": {"tc_to_dscp_map": "DEFAULT"}}} + target_config = {"PORT_QOS_MAP": {"Ethernet0": {"tc_to_dscp_map": "AZURE"}}} + config_wrapper = gu_common.ConfigWrapper() + config_wrapper.validate_field_operation(old_config, target_config) + + def test_validate_field_operation_scheduler_weight_replace(self): + old_config = {"SCHEDULER": {"scheduler.0": {"weight": "10", "type": "DWRR"}}} + target_config = {"SCHEDULER": {"scheduler.0": {"weight": "20", "type": "DWRR"}}} + config_wrapper = gu_common.ConfigWrapper() + config_wrapper.validate_field_operation(old_config, target_config) + class TestGetAsicName(unittest.TestCase): @patch('sonic_py_common.device_info.get_sonic_version_info') From f1ceb3936e6624b0740388926dcb4c0ac154617d Mon Sep 17 00:00:00 2001 From: Dev <47282568+developfast@users.noreply.github.com> Date: Tue, 27 Jan 2026 03:27:29 +0000 Subject: [PATCH 4/8] remove orphaned wred code --- generic_config_updater/field_operation_validators.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/generic_config_updater/field_operation_validators.py b/generic_config_updater/field_operation_validators.py index 59603ca111..361abd9915 100644 --- a/generic_config_updater/field_operation_validators.py +++ b/generic_config_updater/field_operation_validators.py @@ -198,10 +198,6 @@ def buffer_profile_config_update_validator(scope, patch_element): return rdma_config_update_validator_common(scope, patch_element) -def wred_profile_config_update_validator(scope, patch_element): - return rdma_config_update_validator_common(scope, patch_element) - - def read_statedb_entry(scope, table, key, field): state_db = swsscommon.DBConnector(STATE_DB_NAME, REDIS_TIMEOUT_MSECS, True, scope) tbl = swsscommon.Table(state_db, table) From cf99b57439e659a13fe52c47862cc504326d965a Mon Sep 17 00:00:00 2001 From: Dev <47282568+developfast@users.noreply.github.com> Date: Tue, 27 Jan 2026 03:27:53 +0000 Subject: [PATCH 5/8] add more unit tests --- .../field_operation_validator_test.py | 184 ++++++------------ 1 file changed, 61 insertions(+), 123 deletions(-) diff --git a/tests/generic_config_updater/field_operation_validator_test.py b/tests/generic_config_updater/field_operation_validator_test.py index 90f235b720..9385a17116 100644 --- a/tests/generic_config_updater/field_operation_validator_test.py +++ b/tests/generic_config_updater/field_operation_validator_test.py @@ -426,135 +426,38 @@ def test_rdma_config_update_validator_spc_asic_pfc_stat_history(self): assert generic_config_updater.field_operation_validators.\ rdma_config_update_validator(scope, patch_element) is True - @patch("sonic_py_common.device_info.get_sonic_version_info", - mock.Mock(return_value={"build_version": "20250530.12"})) - @patch("generic_config_updater.field_operation_validators.get_asic_name", - mock.Mock(return_value="th5")) - @patch("os.path.exists", mock.Mock(return_value=True)) - @patch("builtins.open", mock_open(read_data='''{"tables": {"WRED_PROFILE": {"validator_data": { - "rdma_config_update_validator": {"ECN tuning": {"fields": [ - "green_min_threshold", "green_max_threshold", "green_drop_probability" - ], "operations": ["replace"], "platforms": {"th5": "20240500"}}}}}}}''')) - def test_wred_profile_config_update_validator_lossless(self): - patch_element = { - "path": "/WRED_PROFILE/AZURE_LOSSLESS/green_min_threshold", - "op": "replace", - "value": "1234" - } - for scope in ["localhost", "asic0"]: - assert generic_config_updater.field_operation_validators.\ - wred_profile_config_update_validator(scope, patch_element) is True - - @patch("sonic_py_common.device_info.get_sonic_version_info", - mock.Mock(return_value={"build_version": "20250530.12"})) - @patch("generic_config_updater.field_operation_validators.get_asic_name", - mock.Mock(return_value="th5")) - @patch("os.path.exists", mock.Mock(return_value=True)) - @patch("builtins.open", mock_open(read_data='''{"tables": {"WRED_PROFILE": {"validator_data": { - "rdma_config_update_validator": {"ECN tuning": {"fields": [ - "green_min_threshold", "green_max_threshold", "green_drop_probability" - ], "operations": ["replace"], "platforms": {"th5": "20240500"}}}}}}}''')) - def test_wred_profile_config_update_validator_lossy(self): - patch_element = { - "path": "/WRED_PROFILE/AZURE_LOSSY/green_min_threshold", - "op": "replace", - "value": "1234" - } - for scope in ["localhost", "asic0"]: - assert generic_config_updater.field_operation_validators.\ - wred_profile_config_update_validator(scope, patch_element) is True - - @patch("sonic_py_common.device_info.get_sonic_version_info", - mock.Mock(return_value={"build_version": "20250530.12"})) - @patch("generic_config_updater.field_operation_validators.get_asic_name", - mock.Mock(return_value="th5")) - @patch("os.path.exists", mock.Mock(return_value=True)) - @patch("builtins.open", mock_open(read_data='''{"tables": {"WRED_PROFILE": {"validator_data": { - "rdma_config_update_validator": {"ECN tuning": {"fields": [ - "green_min_threshold", "green_max_threshold", "green_drop_probability" - ], "operations": ["replace"], "platforms": {"th5": "20240500"}}}}}}}''')) - def test_wred_profile_config_update_validator_invalid_field(self): - patch_element = { - "path": "/WRED_PROFILE/AZURE_LOSSY/invalid", - "op": "replace", - "value": "1234" - } - for scope in ["localhost", "asic0"]: - assert generic_config_updater.field_operation_validators.\ - wred_profile_config_update_validator(scope, patch_element) is False - - @patch("generic_config_updater.field_operation_validators.get_asic_name", - mock.Mock(return_value="unknown")) - def test_wred_profile_config_update_validator_unknown_asic(self): - patch_element = { - "path": "/WRED_PROFILE/AZURE_LOSSY/green_min_threshold", - "op": "replace", - "value": "1234" - } - for scope in ["localhost", "asic0"]: - assert generic_config_updater.field_operation_validators.\ - wred_profile_config_update_validator(scope, patch_element) is False - - @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", - mock.Mock(return_value="th5")) - @patch("os.path.exists", mock.Mock(return_value=True)) - @patch("builtins.open", mock_open(read_data='''{"tables": {"WRED_PROFILE": {"validator_data": { - "rdma_config_update_validator": {"ECN tuning": {"fields": [ - "green_min_threshold", "green_max_threshold", "green_drop_probability" - ], "operations": ["replace"], "platforms": {"th5": "20240500"}}}}}}}''')) - def test_wred_profile_config_update_validator_old_version(self): - patch_element = { - "path": "/WRED_PROFILE/AZURE_LOSSY/green_min_threshold", - "op": "replace", - "value": "1234" - } - for scope in ["localhost", "asic0"]: - assert generic_config_updater.field_operation_validators.\ - wred_profile_config_update_validator(scope, patch_element) is False - - @patch("sonic_py_common.device_info.get_sonic_version_info", - mock.Mock(return_value={"build_version": "20250530.12"})) - @patch("generic_config_updater.field_operation_validators.get_asic_name", - mock.Mock(return_value="th5")) - @patch("os.path.exists", mock.Mock(return_value=True)) - @patch("builtins.open", mock_open(read_data='''{"tables": {"WRED_PROFILE": {"validator_data": { - "rdma_config_update_validator": {"ECN tuning": {"fields": [ - "green_min_threshold", "green_max_threshold", "green_drop_probability" - ], "operations": ["replace"], "platforms": {"th5": "20240500"}}}}}}}''')) - def test_wred_profile_config_update_validator_invalid_op(self): - patch_element = { - "path": "/WRED_PROFILE/AZURE_LOSSY/green_min_threshold", - "op": "add", - "value": "1234" - } - for scope in ["localhost", "asic0"]: - assert generic_config_updater.field_operation_validators.\ - wred_profile_config_update_validator(scope, patch_element) is False + def test_validate_field_operation_illegal__pfcwd(self): + old_config = {"PFC_WD": {"GLOBAL": {"POLL_INTERVAL": "60"}}} + target_config = {"PFC_WD": {"GLOBAL": {}}} + config_wrapper = gu_common.ConfigWrapper() + pytest.raises( + gu_common.IllegalPatchOperationError, + config_wrapper.validate_field_operation, + old_config, + target_config + ) @patch("sonic_py_common.device_info.get_sonic_version_info", - mock.Mock(return_value={"build_version": "20250530.12"})) + mock.Mock(return_value={"build_version": "20241211.49"})) @patch("generic_config_updater.field_operation_validators.get_asic_name", mock.Mock(return_value="spc1")) @patch("os.path.exists", mock.Mock(return_value=True)) - @patch("builtins.open", mock_open(read_data='''{"tables": {"WRED_PROFILE": {"validator_data": { - "rdma_config_update_validator": {"ECN tuning": {"fields": [ - "green_min_threshold", "green_max_threshold", "green_drop_probability" - ], "operations": ["replace"], "platforms": {"th5": "20240500"}}}}}}}''')) - def test_wred_profile_config_update_validator_invalid_asic(self): - patch_element = { - "path": "/WRED_PROFILE/AZURE_LOSSY/green_min_threshold", - "op": "replace", - "value": "1234" + @patch("builtins.open", mock_open(read_data='''{"tables": {"BUFFER_POOL": { + "field_operation_validators": ["generic_config_updater.field_operation_validators.rdma_config_update_validator"], + "validator_data": {"rdma_config_update_validator": {"Blocked ops": {"fields": [ + "ingress_lossless_pool/xoff", "ingress_lossless_pool/size", "egress_lossy_pool/size" + ], "operations": [], "platforms": {"spc1": "20181100"}}}}}}}''')) + def test_validate_field_operation_illegal__buffer_pool(self): + old_config = { + "BUFFER_POOL": { + "ingress_lossless_pool": {"xoff": "1000"} + } + } + target_config = { + "BUFFER_POOL": { + "ingress_lossless_pool": {"xoff": "2000"} + } } - for scope in ["localhost", "asic0"]: - assert generic_config_updater.field_operation_validators.\ - wred_profile_config_update_validator(scope, patch_element) is False - - def test_validate_field_operation_illegal__pfcwd(self): - old_config = {"PFC_WD": {"GLOBAL": {"POLL_INTERVAL": "60"}}} - target_config = {"PFC_WD": {"GLOBAL": {}}} config_wrapper = gu_common.ConfigWrapper() pytest.raises( gu_common.IllegalPatchOperationError, @@ -672,6 +575,41 @@ def test_validate_field_operation_buffer_pg_remove_entry(self): config_wrapper = gu_common.ConfigWrapper() config_wrapper.validate_field_operation(old_config, target_config) + @pytest.mark.parametrize( + "field,old_value,new_value,op", [ + ("green_min_threshold", "1000", "1200", "replace"), + ("yellow_max_threshold", "2000", "2400", "replace"), + ("red_min_threshold", "3000", "3200", "replace"), + ("green_drop_probability", "5", "10", "replace"), + ("wred_green_enable", "true", "false", "replace"), + ("wred_yellow_enable", "false", "true", "replace"), + ("wred_red_enable", "false", "true", "replace"), + ("ecn", "ecn_all", "ecn_mark", "replace") + ] + ) + def test_validate_field_operation_wred_profile_replace(self, field, old_value, new_value, op): + old_config = {"WRED_PROFILE": {"AZURE_LOSSY": {field: old_value}}} + target_config = {"WRED_PROFILE": {"AZURE_LOSSY": {field: new_value}}} + config_wrapper = gu_common.ConfigWrapper() + config_wrapper.validate_field_operation(old_config, target_config) + + @pytest.mark.parametrize( + "field,value", [ + ("green_min_threshold", "1200"), + ("yellow_max_threshold", "2400"), + ("red_min_threshold", "3200"), + ("green_drop_probability", "10"), + ("wred_green_enable", "true"), + ("wred_yellow_enable", "true"), + ("wred_red_enable", "true") + ] + ) + def test_validate_field_operation_wred_profile_add(self, field, value): + old_config = {"WRED_PROFILE": {"AZURE_LOSSY": {}}} + target_config = {"WRED_PROFILE": {"AZURE_LOSSY": {field: value}}} + config_wrapper = gu_common.ConfigWrapper() + config_wrapper.validate_field_operation(old_config, target_config) + @pytest.mark.parametrize( "table", [ "BUFFER_PORT_EGRESS_PROFILE_LIST", From 3999c545e1023a4bc41db8bccdaee757ba9d8ed0 Mon Sep 17 00:00:00 2001 From: Dev <47282568+developfast@users.noreply.github.com> Date: Tue, 27 Jan 2026 03:32:52 +0000 Subject: [PATCH 6/8] flake8 fix --- .../field_operation_validator_test.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/tests/generic_config_updater/field_operation_validator_test.py b/tests/generic_config_updater/field_operation_validator_test.py index 9385a17116..b2e637b51b 100644 --- a/tests/generic_config_updater/field_operation_validator_test.py +++ b/tests/generic_config_updater/field_operation_validator_test.py @@ -442,11 +442,20 @@ def test_validate_field_operation_illegal__pfcwd(self): @patch("generic_config_updater.field_operation_validators.get_asic_name", mock.Mock(return_value="spc1")) @patch("os.path.exists", mock.Mock(return_value=True)) - @patch("builtins.open", mock_open(read_data='''{"tables": {"BUFFER_POOL": { - "field_operation_validators": ["generic_config_updater.field_operation_validators.rdma_config_update_validator"], - "validator_data": {"rdma_config_update_validator": {"Blocked ops": {"fields": [ - "ingress_lossless_pool/xoff", "ingress_lossless_pool/size", "egress_lossy_pool/size" - ], "operations": [], "platforms": {"spc1": "20181100"}}}}}}}''')) + @patch( + "builtins.open", + mock_open( + read_data=( + '{"tables": {"BUFFER_POOL": {' + '"field_operation_validators": [' + '"generic_config_updater.field_operation_validators.rdma_config_update_validator"' + '], "validator_data": {"rdma_config_update_validator": {"Blocked ops": ' + '{"fields": ["ingress_lossless_pool/xoff", ' + '"ingress_lossless_pool/size", "egress_lossy_pool/size"], ' + '"operations": [], "platforms": {"spc1": "20181100"}}}}}}}' + ) + ) + ) def test_validate_field_operation_illegal__buffer_pool(self): old_config = { "BUFFER_POOL": { From ba885deaec023127a21afd261990ac4fed39aa4a Mon Sep 17 00:00:00 2001 From: Dev <47282568+developfast@users.noreply.github.com> Date: Tue, 27 Jan 2026 18:07:06 +0000 Subject: [PATCH 7/8] add all fields for wred changes --- .../field_operation_validator_test.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/tests/generic_config_updater/field_operation_validator_test.py b/tests/generic_config_updater/field_operation_validator_test.py index b2e637b51b..ed3f2c7040 100644 --- a/tests/generic_config_updater/field_operation_validator_test.py +++ b/tests/generic_config_updater/field_operation_validator_test.py @@ -586,14 +586,19 @@ def test_validate_field_operation_buffer_pg_remove_entry(self): @pytest.mark.parametrize( "field,old_value,new_value,op", [ - ("green_min_threshold", "1000", "1200", "replace"), - ("yellow_max_threshold", "2000", "2400", "replace"), - ("red_min_threshold", "3000", "3200", "replace"), - ("green_drop_probability", "5", "10", "replace"), - ("wred_green_enable", "true", "false", "replace"), - ("wred_yellow_enable", "false", "true", "replace"), + ("ecn", "ecn_all", "ecn_green", "replace"), + ("green_drop_probability", "5", "6", "replace"), + ("green_max_threshold", "136200192", "136200193", "replace"), + ("green_min_threshold", "136200192", "136200193", "replace"), + ("red_drop_probability", "5", "6", "replace"), + ("red_max_threshold", "282624", "282625", "replace"), + ("red_min_threshold", "166912", "166913", "replace"), + ("wred_green_enable", "false", "true", "replace"), ("wred_red_enable", "false", "true", "replace"), - ("ecn", "ecn_all", "ecn_mark", "replace") + ("wred_yellow_enable", "false", "true", "replace"), + ("yellow_drop_probability", "5", "6", "replace"), + ("yellow_max_threshold", "282624", "282625", "replace"), + ("yellow_min_threshold", "166912", "166913", "replace") ] ) def test_validate_field_operation_wred_profile_replace(self, field, old_value, new_value, op): From 3c4bac2f0a5593f3e81238c1d9c7fc8fe771449b Mon Sep 17 00:00:00 2001 From: Dev <47282568+developfast@users.noreply.github.com> Date: Tue, 27 Jan 2026 18:27:40 +0000 Subject: [PATCH 8/8] add more port qos unit tests --- .../field_operation_validator_test.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/generic_config_updater/field_operation_validator_test.py b/tests/generic_config_updater/field_operation_validator_test.py index ed3f2c7040..866e040155 100644 --- a/tests/generic_config_updater/field_operation_validator_test.py +++ b/tests/generic_config_updater/field_operation_validator_test.py @@ -703,6 +703,24 @@ def test_validate_field_operation_port_qos_map_tc_to_dscp_replace(self): config_wrapper = gu_common.ConfigWrapper() config_wrapper.validate_field_operation(old_config, target_config) + def test_validate_field_operation_port_qos_map_dscp_to_tc_replace(self): + old_config = {"PORT_QOS_MAP": {"Ethernet0": {"dscp_to_tc_map": "DEFAULT"}}} + target_config = {"PORT_QOS_MAP": {"Ethernet0": {"dscp_to_tc_map": "AZURE"}}} + config_wrapper = gu_common.ConfigWrapper() + config_wrapper.validate_field_operation(old_config, target_config) + + def test_validate_field_operation_port_qos_map_tc_to_pg_replace(self): + old_config = {"PORT_QOS_MAP": {"Ethernet0": {"tc_to_pg_map": "DEFAULT"}}} + target_config = {"PORT_QOS_MAP": {"Ethernet0": {"tc_to_pg_map": "AZURE"}}} + config_wrapper = gu_common.ConfigWrapper() + config_wrapper.validate_field_operation(old_config, target_config) + + def test_validate_field_operation_port_qos_map_tc_to_queue_replace(self): + old_config = {"PORT_QOS_MAP": {"Ethernet0": {"tc_to_queue_map": "DEFAULT"}}} + target_config = {"PORT_QOS_MAP": {"Ethernet0": {"tc_to_queue_map": "AZURE"}}} + config_wrapper = gu_common.ConfigWrapper() + config_wrapper.validate_field_operation(old_config, target_config) + def test_validate_field_operation_scheduler_weight_replace(self): old_config = {"SCHEDULER": {"scheduler.0": {"weight": "10", "type": "DWRR"}}} target_config = {"SCHEDULER": {"scheduler.0": {"weight": "20", "type": "DWRR"}}}