From 4f39f9fd21362193c7e1161d5b0ce74eb279dd2b Mon Sep 17 00:00:00 2001 From: Mohamed Ghoneim Date: Tue, 21 Dec 2021 11:03:46 -0800 Subject: [PATCH] [GCU] Moving PatchSorter unit-test to json file to make it easier to read/maintain (#1977) #### What I did Moved PatchSorter unit-test to json file to make it easier to read/maintain In the future this test json file can be used for adding nightly tests. While testing I had to set `skip_exact_change_list_match=True` because different runs of the same input produce correct but different changes. It is better to always generate the same steps for easier debugging. Created issue: #1976 #### How I did it Copied to Json file the following: - current_config i.e. current running config - patch - expected change list #### How to verify it unit-tests --- .../files/patch_sorter_test_failure.json | 71 + .../files/patch_sorter_test_success.json | 2782 +++++++++++++++++ .../patch_sorter_test.py | 258 +- 3 files changed, 2934 insertions(+), 177 deletions(-) create mode 100644 tests/generic_config_updater/files/patch_sorter_test_failure.json create mode 100644 tests/generic_config_updater/files/patch_sorter_test_success.json diff --git a/tests/generic_config_updater/files/patch_sorter_test_failure.json b/tests/generic_config_updater/files/patch_sorter_test_failure.json new file mode 100644 index 000000000000..7d5ea0ad9398 --- /dev/null +++ b/tests/generic_config_updater/files/patch_sorter_test_failure.json @@ -0,0 +1,71 @@ +{ + "EMPTYING_A_CONFIGDB_TABLE__FAILURE": { + "desc": "Emptying a configdb table fails because empty tables are not allowed in configdb. User should remove whole table instead e.g. remove /ACL_TABLE in this case.", + "current_config": { + "ACL_TABLE": { + "EVERFLOW": { + "policy_desc": "EVERFLOW", + "ports": [ + "Ethernet0" + ], + "stage": "ingress", + "type": "MIRROR" + } + }, + "PORT": { + "Ethernet0": { + "alias": "Eth1", + "lanes": "65, 66, 67, 68", + "description": "Ethernet0 100G link", + "speed": "100000" + } + } + }, + "patch": [ + {"op": "remove", "path": "/ACL_TABLE/EVERFLOW"} + ], + "expected_error_substrings": [ + "There is no possible sorting" + ] + }, + "ADDING_AN_EMPTY_CONFIGDB_TABLE__FAILURE": { + "desc": "Adding an empty configdb table fail because empty tables are not allowed in configdb.", + "current_config": {}, + "patch": [ + {"op": "add", "path": "/VLAN", "value": {}} + ], + "expected_error_substrings": [ + "There is no possible sorting" + ] + }, + "EMPTYING_MULTIPLE_CONFIGDB_TABLE__FAILURE": { + "desc": "Emptying multiple configdb table fails because empty tables are not allowed in configdb. User should remove whole tables instead e.g. remove /PORT and /ACL_TABLE in this case.", + "current_config": { + "ACL_TABLE": { + "EVERFLOW": { + "policy_desc": "EVERFLOW", + "ports": [ + "Ethernet0" + ], + "stage": "ingress", + "type": "MIRROR" + } + }, + "PORT": { + "Ethernet0": { + "alias": "Eth1", + "lanes": "65, 66, 67, 68", + "description": "Ethernet0 100G link", + "speed": "100000" + } + } + }, + "patch": [ + {"op": "remove", "path": "/ACL_TABLE/EVERFLOW"}, + {"op": "remove", "path": "/PORT/Ethernet0"} + ], + "expected_error_substrings": [ + "There is no possible sorting" + ] + } +} \ No newline at end of file diff --git a/tests/generic_config_updater/files/patch_sorter_test_success.json b/tests/generic_config_updater/files/patch_sorter_test_success.json new file mode 100644 index 000000000000..8d7b92d32fb7 --- /dev/null +++ b/tests/generic_config_updater/files/patch_sorter_test_success.json @@ -0,0 +1,2782 @@ +{ + "ADD_2_ITEMS_WITH_DEPENDENCY_FROM_DIFFERENT_TABLES__SUCCESS": { + "desc": "Add 2 items with dependency from different tables success.", + "current_config": { + "VLAN_MEMBER": { + "Vlan1000|Ethernet4": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet8": { + "tagging_mode": "untagged" + } + }, + "VLAN": { + "Vlan1000": { + "vlanid": "1000", + "dhcp_servers": [ + "192.0.0.1", + "192.0.0.2", + "192.0.0.3", + "192.0.0.4" + ] + } + }, + "ACL_TABLE": { + "DATAACL": { + "policy_desc": "DATAACL", + "ports": [ + "Ethernet4" + ], + "stage": "ingress", + "type": "L3" + }, + "EVERFLOW": { + "policy_desc": "EVERFLOW", + "ports": [ + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRROR" + }, + "EVERFLOWV6": { + "policy_desc": "EVERFLOWV6", + "ports": [ + "Ethernet4", + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRRORV6" + } + }, + "PORT": { + "Ethernet4": { + "admin_status": "up", + "alias": "fortyGigE0/4", + "description": "Servers0:eth0", + "index": "1", + "lanes": "29,30,31,32", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + }, + "Ethernet8": { + "admin_status": "up", + "alias": "fortyGigE0/8", + "description": "Servers1:eth0", + "index": "2", + "lanes": "33,34,35,36", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + } + } + }, + "patch": [ + { + "op": "add", + "path": "/VLAN_MEMBER/Vlan1000|Ethernet0", + "value": { + "tagging_mode": "untagged" + } + }, + { + "op": "add", + "path": "/PORT/Ethernet0", + "value": { + "alias": "Eth1", + "lanes": "65, 66, 67, 68", + "description": "Ethernet0 100G link", + "speed": "100000" + } + } + ], + "expected_changes": [ + [ + { + "op": "add", + "path": "/PORT/Ethernet0", + "value": { + "alias": "Eth1", + "lanes": "65, 66, 67, 68", + "description": "Ethernet0 100G link", + "speed": "100000" + } + } + ], + [ + { + "op": "add", + "path": "/VLAN_MEMBER/Vlan1000|Ethernet0", + "value": { + "tagging_mode": "untagged" + } + } + ] + ] + }, + "ADD_2_ITEMS_WITH_DEPENDENCY_FROM_SAME_TABLE__SUCCESS": { + "desc": "Add 2 items with dependency from same table success.", + "current_config": { + "INTERFACE": { + "Ethernet9": {} + }, + "PORT": { + "Ethernet8": { + "admin_status": "up", + "alias": "eth8", + "description": "Ethernet8", + "fec": "rs", + "lanes": "65", + "mtu": "9000", + "speed": "25000" + }, + "Ethernet9": { + "admin_status": "up", + "alias": "eth9", + "description": "Ethernet9", + "fec": "rs", + "lanes": "6", + "mtu": "9000", + "speed": "25000" + } + } + }, + "patch": [ + { + "op": "add", + "path": "/INTERFACE/Ethernet8", + "value": {} + }, + { + "op": "add", + "path": "/INTERFACE/Ethernet8|10.0.0.1~130", + "value": { + "family": "IPv4", + "scope": "global" + } + } + ], + "expected_changes": [ + [ + { + "op": "add", + "path": "/INTERFACE/Ethernet8", + "value": {} + } + ], + [ + { + "op": "add", + "path": "/INTERFACE/Ethernet8|10.0.0.1~130", + "value": { + "family": "IPv4" + } + } + ], + [ + { + "op": "add", + "path": "/INTERFACE/Ethernet8|10.0.0.1~130/scope", + "value": "global" + } + ] + ] + }, + "ADD_NEW_KEY_TO_EXISTING_TABLE__SUCCESS": { + "desc": "Add new key to existing table success.", + "current_config": { + "VLAN_MEMBER": { + "Vlan1000|Ethernet0": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet4": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet8": { + "tagging_mode": "untagged" + } + }, + "VLAN": { + "Vlan1000": { + "vlanid": "1000", + "dhcp_servers": [ + "192.0.0.1", + "192.0.0.2", + "192.0.0.3", + "192.0.0.4" + ] + } + }, + "ACL_TABLE": { + "NO-NSW-PACL-V4": { + "type": "L3", + "policy_desc": "NO-NSW-PACL-V4", + "ports": [ + "Ethernet0" + ] + }, + "DATAACL": { + "policy_desc": "DATAACL", + "ports": [ + "Ethernet4" + ], + "stage": "ingress", + "type": "L3" + }, + "EVERFLOW": { + "policy_desc": "EVERFLOW", + "ports": [ + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRROR" + } + }, + "PORT": { + "Ethernet0": { + "alias": "Eth1", + "lanes": "65, 66, 67, 68", + "description": "Ethernet0 100G link", + "speed": "100000" + }, + "Ethernet4": { + "admin_status": "up", + "alias": "fortyGigE0/4", + "description": "Servers0:eth0", + "index": "1", + "lanes": "29,30,31,32", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + }, + "Ethernet8": { + "admin_status": "up", + "alias": "fortyGigE0/8", + "description": "Servers1:eth0", + "index": "2", + "lanes": "33,34,35,36", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + } + } + }, + "patch": [ + { + "op": "add", + "path": "/ACL_TABLE/EVERFLOWV6", + "value": { + "policy_desc": "EVERFLOWV6", + "ports": [ + "Ethernet4", + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRRORV6" + } + } + ], + "expected_changes": [ + [ + { + "op": "add", + "path": "/ACL_TABLE/EVERFLOWV6", + "value": { + "type": "MIRRORV6" + } + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/EVERFLOWV6/policy_desc", + "value": "EVERFLOWV6" + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/EVERFLOWV6/ports", + "value": [ + "Ethernet4" + ] + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/EVERFLOWV6/ports/1", + "value": "Ethernet8" + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/EVERFLOWV6/stage", + "value": "ingress" + } + ] + ] + }, + "ADD_TABLE__SUCCESS": { + "desc": "Add table success.", + "current_config": { + "VLAN_MEMBER": { + "Vlan1000|Ethernet0": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet4": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet8": { + "tagging_mode": "untagged" + } + }, + "VLAN": { + "Vlan1000": { + "vlanid": "1000", + "dhcp_servers": [ + "192.0.0.1", + "192.0.0.2", + "192.0.0.3", + "192.0.0.4" + ] + } + }, + "PORT": { + "Ethernet0": { + "alias": "Eth1", + "lanes": "65, 66, 67, 68", + "description": "Ethernet0 100G link", + "speed": "100000" + }, + "Ethernet4": { + "admin_status": "up", + "alias": "fortyGigE0/4", + "description": "Servers0:eth0", + "index": "1", + "lanes": "29,30,31,32", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + }, + "Ethernet8": { + "admin_status": "up", + "alias": "fortyGigE0/8", + "description": "Servers1:eth0", + "index": "2", + "lanes": "33,34,35,36", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + } + } + }, + "patch": [ + { + "op": "add", + "path": "/ACL_TABLE", + "value": { + "NO-NSW-PACL-V4": { + "type": "L3", + "policy_desc": "NO-NSW-PACL-V4", + "ports": [ + "Ethernet0" + ] + }, + "DATAACL": { + "policy_desc": "DATAACL", + "ports": [ + "Ethernet4" + ], + "stage": "ingress", + "type": "L3" + }, + "EVERFLOW": { + "policy_desc": "EVERFLOW", + "ports": [ + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRROR" + }, + "EVERFLOWV6": { + "policy_desc": "EVERFLOWV6", + "ports": [ + "Ethernet4", + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRRORV6" + } + } + } + ], + "expected_changes": [ + [ + { + "op": "add", + "path": "/ACL_TABLE", + "value": { + "NO-NSW-PACL-V4": { + "type": "L3" + } + } + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/policy_desc", + "value": "NO-NSW-PACL-V4" + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/ports", + "value": [ + "Ethernet0" + ] + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/DATAACL", + "value": { + "type": "L3" + } + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/DATAACL/policy_desc", + "value": "DATAACL" + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/DATAACL/ports", + "value": [ + "Ethernet4" + ] + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/DATAACL/stage", + "value": "ingress" + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/EVERFLOW", + "value": { + "type": "MIRROR" + } + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/EVERFLOW/policy_desc", + "value": "EVERFLOW" + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/EVERFLOW/ports", + "value": [ + "Ethernet8" + ] + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/EVERFLOW/stage", + "value": "ingress" + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/EVERFLOWV6", + "value": { + "type": "MIRRORV6" + } + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/EVERFLOWV6/policy_desc", + "value": "EVERFLOWV6" + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/EVERFLOWV6/ports", + "value": [ + "Ethernet4" + ] + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/EVERFLOWV6/ports/1", + "value": "Ethernet8" + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/EVERFLOWV6/stage", + "value": "ingress" + } + ] + ] + }, + "ADD_VALUE_TO_EXISTING_ARRAY__SUCCESS": { + "desc": "Add value to existing array success.", + "current_config": { + "VLAN_MEMBER": { + "Vlan1000|Ethernet0": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet4": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet8": { + "tagging_mode": "untagged" + } + }, + "VLAN": { + "Vlan1000": { + "vlanid": "1000", + "dhcp_servers": [ + "192.0.0.1", + "192.0.0.2", + "192.0.0.3", + "192.0.0.4" + ] + } + }, + "ACL_TABLE": { + "NO-NSW-PACL-V4": { + "type": "L3", + "policy_desc": "NO-NSW-PACL-V4", + "ports": [ + "Ethernet0" + ] + }, + "DATAACL": { + "policy_desc": "DATAACL", + "ports": [ + "Ethernet4" + ], + "stage": "ingress", + "type": "L3" + }, + "EVERFLOW": { + "policy_desc": "EVERFLOW", + "ports": [ + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRROR" + }, + "EVERFLOWV6": { + "policy_desc": "EVERFLOWV6", + "ports": [ + "Ethernet4", + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRRORV6" + } + }, + "PORT": { + "Ethernet0": { + "alias": "Eth1", + "lanes": "65, 66, 67, 68", + "description": "Ethernet0 100G link", + "speed": "100000" + }, + "Ethernet4": { + "admin_status": "up", + "alias": "fortyGigE0/4", + "description": "Servers0:eth0", + "index": "1", + "lanes": "29,30,31,32", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + }, + "Ethernet8": { + "admin_status": "up", + "alias": "fortyGigE0/8", + "description": "Servers1:eth0", + "index": "2", + "lanes": "33,34,35,36", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + } + } + }, + "patch": [ + { + "op": "add", + "path": "/ACL_TABLE/EVERFLOWV6/ports/0", + "value": "Ethernet0" + } + ], + "expected_changes": [ + [ + { + "op": "add", + "path": "/ACL_TABLE/EVERFLOWV6/ports/0", + "value": "Ethernet0" + } + ] + ] + }, + "ADDING_CREATE_ONLY_FIELD__SUCCESS": { + "desc": "Adding create only field success.", + "current_config": { + "LOOPBACK_INTERFACE": { + "Loopback0": {}, + "Loopback0|10.1.0.32/32": {}, + "Loopback0|1100:1::32/128": {}, + "Loopback1": { + "vrf_name": "Vrf_02" + }, + "Loopback1|20.2.0.32/32": {}, + "Loopback1|2200:2::32/128": {} + }, + "VRF": { + "Vrf_01": {}, + "Vrf_02": {} + } + }, + "patch": [ + { + "op": "add", + "path": "/LOOPBACK_INTERFACE/Loopback0/vrf_name", + "value": "Vrf_01" + } + ], + "expected_changes": [ + [ + { + "op": "remove", + "path": "/LOOPBACK_INTERFACE/Loopback0|10.1.0.32~132" + } + ], + [ + { + "op": "remove", + "path": "/LOOPBACK_INTERFACE/Loopback0|1100:1::32~1128" + } + ], + [ + { + "op": "add", + "path": "/LOOPBACK_INTERFACE/Loopback0|10.1.0.32~132", + "value": {} + } + ], + [ + { + "op": "remove", + "path": "/LOOPBACK_INTERFACE/Loopback1|2200:2::32~1128" + } + ], + [ + { + "op": "add", + "path": "/LOOPBACK_INTERFACE/Loopback0|1100:1::32~1128", + "value": {} + } + ], + [ + { + "op": "remove", + "path": "/LOOPBACK_INTERFACE/Loopback0|10.1.0.32~132" + } + ], + [ + { + "op": "remove", + "path": "/LOOPBACK_INTERFACE/Loopback0|1100:1::32~1128" + } + ], + [ + { + "op": "remove", + "path": "/LOOPBACK_INTERFACE/Loopback0" + } + ], + [ + { + "op": "add", + "path": "/LOOPBACK_INTERFACE/Loopback0", + "value": { + "vrf_name": "Vrf_01" + } + } + ], + [ + { + "op": "add", + "path": "/LOOPBACK_INTERFACE/Loopback0|10.1.0.32~132", + "value": {} + } + ], + [ + { + "op": "add", + "path": "/LOOPBACK_INTERFACE/Loopback0|1100:1::32~1128", + "value": {} + } + ], + [ + { + "op": "add", + "path": "/LOOPBACK_INTERFACE/Loopback1|2200:2::32~1128", + "value": {} + } + ] + ] + }, + "DPB_1_TO_4__SUCCESS": { + "desc": "Dpb 1 to 4 success.", + "current_config": { + "PORT": { + "Ethernet0": { + "alias": "Eth1", + "lanes": "65, 66, 67, 68", + "description": "Ethernet0 100G link", + "speed": "100000" + } + }, + "ACL_TABLE": { + "NO-NSW-PACL-V4": { + "type": "L3", + "policy_desc": "NO-NSW-PACL-V4", + "ports": [ + "Ethernet0" + ] + } + }, + "VLAN_MEMBER": { + "Vlan100|Ethernet0": { + "tagging_mode": "untagged" + } + }, + "VLAN": { + "Vlan100": { + "vlanid": "100", + "dhcp_servers": [ + "192.0.0.1", + "192.0.0.2", + "192.0.0.3", + "192.0.0.4" + ] + } + } + }, + "patch": [ + { + "op": "add", + "path": "/VLAN_MEMBER/Vlan100|Ethernet1", + "value": { + "tagging_mode": "untagged" + } + }, + { + "op": "add", + "path": "/VLAN_MEMBER/Vlan100|Ethernet3", + "value": { + "tagging_mode": "untagged" + } + }, + { + "op": "add", + "path": "/VLAN_MEMBER/Vlan100|Ethernet2", + "value": { + "tagging_mode": "untagged" + } + }, + { + "op": "add", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/ports/1", + "value": "Ethernet1" + }, + { + "op": "add", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/ports/2", + "value": "Ethernet2" + }, + { + "op": "add", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/ports/3", + "value": "Ethernet3" + }, + { + "op": "add", + "path": "/PORT/Ethernet3", + "value": { + "alias": "Eth1/4", + "lanes": "68", + "description": "", + "speed": "10000" + } + }, + { + "op": "add", + "path": "/PORT/Ethernet2", + "value": { + "alias": "Eth1/3", + "lanes": "67", + "description": "", + "speed": "10000" + } + }, + { + "op": "add", + "path": "/PORT/Ethernet1", + "value": { + "alias": "Eth1/2", + "lanes": "66", + "description": "", + "speed": "10000" + } + }, + { + "op": "replace", + "path": "/PORT/Ethernet0/alias", + "value": "Eth1/1" + }, + { + "op": "replace", + "path": "/PORT/Ethernet0/description", + "value": "" + }, + { + "op": "replace", + "path": "/PORT/Ethernet0/lanes", + "value": "65" + }, + { + "op": "replace", + "path": "/PORT/Ethernet0/speed", + "value": "10000" + } + ], + "expected_changes": [ + [ + { + "op": "replace", + "path": "/PORT/Ethernet0/alias", + "value": "Eth1/1" + } + ], + [ + { + "op": "replace", + "path": "/PORT/Ethernet0/description", + "value": "" + } + ], + [ + { + "op": "replace", + "path": "/PORT/Ethernet0/speed", + "value": "10000" + } + ], + [ + { + "op": "remove", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/ports" + } + ], + [ + { + "op": "remove", + "path": "/ACL_TABLE" + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE", + "value": { + "NO-NSW-PACL-V4": { + "type": "L3" + } + } + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/ports", + "value": [ + "Ethernet0" + ] + } + ], + [ + { + "op": "remove", + "path": "/VLAN_MEMBER" + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/policy_desc", + "value": "NO-NSW-PACL-V4" + } + ], + [ + { + "op": "remove", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/ports" + } + ], + [ + { + "op": "remove", + "path": "/PORT" + } + ], + [ + { + "op": "add", + "path": "/PORT", + "value": { + "Ethernet0": { + "alias": "Eth1/1", + "lanes": "65", + "description": "", + "speed": "10000" + } + } + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/ports", + "value": [ + "Ethernet0" + ] + } + ], + [ + { + "op": "add", + "path": "/VLAN_MEMBER", + "value": { + "Vlan100|Ethernet0": { + "tagging_mode": "untagged" + } + } + } + ], + [ + { + "op": "add", + "path": "/PORT/Ethernet3", + "value": { + "alias": "Eth1/4", + "lanes": "68", + "description": "", + "speed": "10000" + } + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/ports/1", + "value": "Ethernet3" + } + ], + [ + { + "op": "add", + "path": "/VLAN_MEMBER/Vlan100|Ethernet3", + "value": { + "tagging_mode": "untagged" + } + } + ], + [ + { + "op": "add", + "path": "/PORT/Ethernet2", + "value": { + "alias": "Eth1/3", + "lanes": "67", + "description": "", + "speed": "10000" + } + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/ports/2", + "value": "Ethernet2" + } + ], + [ + { + "op": "add", + "path": "/VLAN_MEMBER/Vlan100|Ethernet2", + "value": { + "tagging_mode": "untagged" + } + } + ], + [ + { + "op": "add", + "path": "/PORT/Ethernet1", + "value": { + "alias": "Eth1/2", + "lanes": "66", + "description": "", + "speed": "10000" + } + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/ports/1", + "value": "Ethernet1" + } + ], + [ + { + "op": "replace", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/ports", + "value": [ + "Ethernet0", + "Ethernet1", + "Ethernet2", + "Ethernet3" + ] + } + ], + [ + { + "op": "add", + "path": "/VLAN_MEMBER/Vlan100|Ethernet1", + "value": { + "tagging_mode": "untagged" + } + } + ] + ] + }, + "DPB_4_TO_1__SUCCESS": { + "desc": "Dpb 4 to 1 success.", + "current_config": { + "PORT": { + "Ethernet0": { + "alias": "Eth1/1", + "lanes": "65", + "description": "", + "speed": "10000" + }, + "Ethernet1": { + "alias": "Eth1/2", + "lanes": "66", + "description": "", + "speed": "10000" + }, + "Ethernet2": { + "alias": "Eth1/3", + "lanes": "67", + "description": "", + "speed": "10000" + }, + "Ethernet3": { + "alias": "Eth1/4", + "lanes": "68", + "description": "", + "speed": "10000" + } + }, + "ACL_TABLE": { + "NO-NSW-PACL-V4": { + "type": "L3", + "policy_desc": "NO-NSW-PACL-V4", + "ports": [ + "Ethernet0", + "Ethernet1", + "Ethernet2", + "Ethernet3" + ] + } + }, + "VLAN_MEMBER": { + "Vlan100|Ethernet0": { + "tagging_mode": "untagged" + }, + "Vlan100|Ethernet1": { + "tagging_mode": "untagged" + }, + "Vlan100|Ethernet2": { + "tagging_mode": "untagged" + }, + "Vlan100|Ethernet3": { + "tagging_mode": "untagged" + } + }, + "VLAN": { + "Vlan100": { + "vlanid": "100", + "dhcp_servers": [ + "192.0.0.1", + "192.0.0.2", + "192.0.0.3", + "192.0.0.4" + ] + } + } + }, + "patch": [ + { + "op": "remove", + "path": "/VLAN_MEMBER/Vlan100|Ethernet1" + }, + { + "op": "remove", + "path": "/VLAN_MEMBER/Vlan100|Ethernet3" + }, + { + "op": "remove", + "path": "/VLAN_MEMBER/Vlan100|Ethernet2" + }, + { + "op": "remove", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/ports/1" + }, + { + "op": "remove", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/ports/1" + }, + { + "op": "remove", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/ports/1" + }, + { + "op": "remove", + "path": "/PORT/Ethernet3" + }, + { + "op": "remove", + "path": "/PORT/Ethernet2" + }, + { + "op": "remove", + "path": "/PORT/Ethernet1" + }, + { + "op": "replace", + "path": "/PORT/Ethernet0/alias", + "value": "Eth1" + }, + { + "op": "replace", + "path": "/PORT/Ethernet0/description", + "value": "Ethernet0 100G link" + }, + { + "op": "replace", + "path": "/PORT/Ethernet0/lanes", + "value": "65, 66, 67, 68" + }, + { + "op": "replace", + "path": "/PORT/Ethernet0/speed", + "value": "100000" + } + ], + "expected_changes": [ + [ + { + "op": "replace", + "path": "/PORT/Ethernet0/alias", + "value": "Eth1" + } + ], + [ + { + "op": "replace", + "path": "/PORT/Ethernet0/description", + "value": "Ethernet0 100G link" + } + ], + [ + { + "op": "replace", + "path": "/PORT/Ethernet0/speed", + "value": "100000" + } + ], + [ + { + "op": "remove", + "path": "/PORT/Ethernet1/alias" + } + ], + [ + { + "op": "remove", + "path": "/PORT/Ethernet1/description" + } + ], + [ + { + "op": "remove", + "path": "/PORT/Ethernet2/alias" + } + ], + [ + { + "op": "remove", + "path": "/PORT/Ethernet2/description" + } + ], + [ + { + "op": "remove", + "path": "/PORT/Ethernet3/alias" + } + ], + [ + { + "op": "remove", + "path": "/PORT/Ethernet3/description" + } + ], + [ + { + "op": "remove", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/ports/1" + } + ], + [ + { + "op": "remove", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/ports/1" + } + ], + [ + { + "op": "remove", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/ports/1" + } + ], + [ + { + "op": "remove", + "path": "/VLAN_MEMBER/Vlan100|Ethernet1" + } + ], + [ + { + "op": "remove", + "path": "/PORT/Ethernet1" + } + ], + [ + { + "op": "remove", + "path": "/VLAN_MEMBER/Vlan100|Ethernet2" + } + ], + [ + { + "op": "remove", + "path": "/PORT/Ethernet2" + } + ], + [ + { + "op": "remove", + "path": "/VLAN_MEMBER/Vlan100|Ethernet3" + } + ], + [ + { + "op": "remove", + "path": "/PORT/Ethernet3" + } + ], + [ + { + "op": "remove", + "path": "/VLAN_MEMBER" + } + ], + [ + { + "op": "remove", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/ports" + } + ], + [ + { + "op": "remove", + "path": "/PORT" + } + ], + [ + { + "op": "add", + "path": "/PORT", + "value": { + "Ethernet0": { + "alias": "Eth1", + "lanes": "65, 66, 67, 68", + "description": "Ethernet0 100G link", + "speed": "100000" + } + } + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/ports", + "value": [ + "Ethernet0" + ] + } + ], + [ + { + "op": "add", + "path": "/VLAN_MEMBER", + "value": { + "Vlan100|Ethernet0": { + "tagging_mode": "untagged" + } + } + } + ] + ] + }, + "EMPTY_PATCH__RETURNS_EMPTY_CHANGES_LIST": { + "desc": "Empty patch returns empty changes list.", + "current_config": { + "VLAN_MEMBER": { + "Vlan1000|Ethernet0": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet4": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet8": { + "tagging_mode": "untagged" + } + }, + "VLAN": { + "Vlan1000": { + "vlanid": "1000", + "dhcp_servers": [ + "192.0.0.1", + "192.0.0.2", + "192.0.0.3", + "192.0.0.4" + ] + } + }, + "ACL_TABLE": { + "NO-NSW-PACL-V4": { + "type": "L3", + "policy_desc": "NO-NSW-PACL-V4", + "ports": [ + "Ethernet0" + ] + }, + "DATAACL": { + "policy_desc": "DATAACL", + "ports": [ + "Ethernet4" + ], + "stage": "ingress", + "type": "L3" + }, + "EVERFLOW": { + "policy_desc": "EVERFLOW", + "ports": [ + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRROR" + }, + "EVERFLOWV6": { + "policy_desc": "EVERFLOWV6", + "ports": [ + "Ethernet4", + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRRORV6" + } + }, + "PORT": { + "Ethernet0": { + "alias": "Eth1", + "lanes": "65, 66, 67, 68", + "description": "Ethernet0 100G link", + "speed": "100000" + }, + "Ethernet4": { + "admin_status": "up", + "alias": "fortyGigE0/4", + "description": "Servers0:eth0", + "index": "1", + "lanes": "29,30,31,32", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + }, + "Ethernet8": { + "admin_status": "up", + "alias": "fortyGigE0/8", + "description": "Servers1:eth0", + "index": "2", + "lanes": "33,34,35,36", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + } + } + }, + "patch": [], + "expected_changes": [] + }, + "INTER_DEPENDENCY_WITHIN_SAME_TABLE__SUCCESS": { + "desc": "Inter dependency within same table success.", + "current_config": { + "VLAN_MEMBER": { + "Vlan1000|Ethernet0": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet4": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet8": { + "tagging_mode": "untagged" + } + }, + "VLAN": { + "Vlan1000": { + "vlanid": "1000", + "dhcp_servers": [ + "192.0.0.1", + "192.0.0.2", + "192.0.0.3", + "192.0.0.4" + ] + } + }, + "ACL_TABLE": { + "NO-NSW-PACL-V4": { + "type": "L3", + "policy_desc": "NO-NSW-PACL-V4", + "ports": [ + "Ethernet0" + ] + }, + "DATAACL": { + "policy_desc": "DATAACL", + "ports": [ + "Ethernet4" + ], + "stage": "ingress", + "type": "L3" + }, + "EVERFLOW": { + "policy_desc": "EVERFLOW", + "ports": [ + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRROR" + }, + "EVERFLOWV6": { + "policy_desc": "EVERFLOWV6", + "ports": [ + "Ethernet4", + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRRORV6" + } + }, + "PORT": { + "Ethernet0": { + "alias": "Eth1", + "lanes": "65, 66, 67, 68", + "description": "Ethernet0 100G link", + "speed": "100000" + }, + "Ethernet4": { + "admin_status": "up", + "alias": "fortyGigE0/4", + "description": "Servers0:eth0", + "index": "1", + "lanes": "29,30,31,32", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + }, + "Ethernet8": { + "admin_status": "up", + "alias": "fortyGigE0/8", + "description": "Servers1:eth0", + "index": "2", + "lanes": "33,34,35,36", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + } + } + }, + "patch": [ + { + "op": "add", + "path": "/VLAN_INTERFACE", + "value": { + "Vlan1000|fc02:1000::1/64": {}, + "Vlan1000|192.168.0.1/21": {}, + "Vlan1000": {} + } + } + ], + "expected_changes": [ + [ + { + "op": "add", + "path": "/VLAN_INTERFACE", + "value": { + "Vlan1000": {} + } + } + ], + [ + { + "op": "add", + "path": "/VLAN_INTERFACE/Vlan1000|fc02:1000::1~164", + "value": {} + } + ], + [ + { + "op": "add", + "path": "/VLAN_INTERFACE/Vlan1000|192.168.0.1~121", + "value": {} + } + ] + ] + }, + "MODIFY_ITEMS_WITH_DEPENDENCIES_USING_MUST__SUCCESS": { + "desc": "Modify items with dependencies using must success.", + "current_config": { + "CRM": { + "Config": { + "acl_counter_high_threshold": "90", + "acl_counter_low_threshold": "70", + "acl_counter_threshold_type": "free" + } + } + }, + "patch": [ + { + "op": "replace", + "path": "/CRM/Config/acl_counter_low_threshold", + "value": "60" + }, + { + "op": "replace", + "path": "/CRM/Config/acl_counter_high_threshold", + "value": "80" + } + ], + "expected_changes": [ + [ + { + "op": "replace", + "path": "/CRM/Config/acl_counter_high_threshold", + "value": "80" + } + ], + [ + { + "op": "replace", + "path": "/CRM/Config/acl_counter_low_threshold", + "value": "60" + } + ] + ] + }, + "MODIFY_VALUE_IN_EXISTING_ARRAY__SUCCESS": { + "desc": "Modify value in existing array success.", + "current_config": { + "VLAN_MEMBER": { + "Vlan1000|Ethernet0": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet4": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet8": { + "tagging_mode": "untagged" + } + }, + "VLAN": { + "Vlan1000": { + "vlanid": "1000", + "dhcp_servers": [ + "192.0.0.1", + "192.0.0.2", + "192.0.0.3", + "192.0.0.4" + ] + } + }, + "ACL_TABLE": { + "NO-NSW-PACL-V4": { + "type": "L3", + "policy_desc": "NO-NSW-PACL-V4", + "ports": [ + "Ethernet0" + ] + }, + "DATAACL": { + "policy_desc": "DATAACL", + "ports": [ + "Ethernet4" + ], + "stage": "ingress", + "type": "L3" + }, + "EVERFLOW": { + "policy_desc": "EVERFLOW", + "ports": [ + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRROR" + }, + "EVERFLOWV6": { + "policy_desc": "EVERFLOWV6", + "ports": [ + "Ethernet4", + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRRORV6" + } + }, + "PORT": { + "Ethernet0": { + "alias": "Eth1", + "lanes": "65, 66, 67, 68", + "description": "Ethernet0 100G link", + "speed": "100000" + }, + "Ethernet4": { + "admin_status": "up", + "alias": "fortyGigE0/4", + "description": "Servers0:eth0", + "index": "1", + "lanes": "29,30,31,32", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + }, + "Ethernet8": { + "admin_status": "up", + "alias": "fortyGigE0/8", + "description": "Servers1:eth0", + "index": "2", + "lanes": "33,34,35,36", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + } + } + }, + "patch": [ + { + "op": "replace", + "path": "/ACL_TABLE/EVERFLOWV6/ports/0", + "value": "Ethernet0" + } + ], + "expected_changes": [ + [ + { + "op": "remove", + "path": "/ACL_TABLE/EVERFLOWV6/ports/0" + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/EVERFLOWV6/ports/0", + "value": "Ethernet0" + } + ] + ] + }, + "MODIFY_VALUE_IN_EXISTING_TABLE__SUCCESS": { + "desc": "Modify value in existing table success.", + "current_config": { + "VLAN_MEMBER": { + "Vlan1000|Ethernet0": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet4": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet8": { + "tagging_mode": "untagged" + } + }, + "VLAN": { + "Vlan1000": { + "vlanid": "1000", + "dhcp_servers": [ + "192.0.0.1", + "192.0.0.2", + "192.0.0.3", + "192.0.0.4" + ] + } + }, + "ACL_TABLE": { + "NO-NSW-PACL-V4": { + "type": "L3", + "policy_desc": "NO-NSW-PACL-V4", + "ports": [ + "Ethernet0" + ] + }, + "DATAACL": { + "policy_desc": "DATAACL", + "ports": [ + "Ethernet4" + ], + "stage": "ingress", + "type": "L3" + }, + "EVERFLOW": { + "policy_desc": "EVERFLOW", + "ports": [ + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRROR" + }, + "EVERFLOWV6": { + "policy_desc": "EVERFLOWV6", + "ports": [ + "Ethernet4", + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRRORV6" + } + }, + "PORT": { + "Ethernet0": { + "alias": "Eth1", + "lanes": "65, 66, 67, 68", + "description": "Ethernet0 100G link", + "speed": "100000" + }, + "Ethernet4": { + "admin_status": "up", + "alias": "fortyGigE0/4", + "description": "Servers0:eth0", + "index": "1", + "lanes": "29,30,31,32", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + }, + "Ethernet8": { + "admin_status": "up", + "alias": "fortyGigE0/8", + "description": "Servers1:eth0", + "index": "2", + "lanes": "33,34,35,36", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + } + } + }, + "patch": [ + { + "op": "replace", + "path": "/ACL_TABLE/EVERFLOW/stage", + "value": "egress" + } + ], + "expected_changes": [ + [ + { + "op": "replace", + "path": "/ACL_TABLE/EVERFLOW/stage", + "value": "egress" + } + ] + ] + }, + "PATCH_WITH_SINGLE_SIMPLE_OPERATION__RETURNS_ONE_CHANGE": { + "desc": "Patch with single simple operation returns one change.", + "current_config": { + "VLAN_MEMBER": { + "Vlan1000|Ethernet0": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet4": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet8": { + "tagging_mode": "untagged" + } + }, + "VLAN": { + "Vlan1000": { + "vlanid": "1000", + "dhcp_servers": [ + "192.0.0.1", + "192.0.0.2", + "192.0.0.3", + "192.0.0.4" + ] + } + }, + "ACL_TABLE": { + "NO-NSW-PACL-V4": { + "type": "L3", + "policy_desc": "NO-NSW-PACL-V4", + "ports": [ + "Ethernet0" + ] + }, + "DATAACL": { + "policy_desc": "DATAACL", + "ports": [ + "Ethernet4" + ], + "stage": "ingress", + "type": "L3" + }, + "EVERFLOW": { + "policy_desc": "EVERFLOW", + "ports": [ + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRROR" + }, + "EVERFLOWV6": { + "policy_desc": "EVERFLOWV6", + "ports": [ + "Ethernet4", + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRRORV6" + } + }, + "PORT": { + "Ethernet0": { + "alias": "Eth1", + "lanes": "65, 66, 67, 68", + "description": "Ethernet0 100G link", + "speed": "100000" + }, + "Ethernet4": { + "admin_status": "up", + "alias": "fortyGigE0/4", + "description": "Servers0:eth0", + "index": "1", + "lanes": "29,30,31,32", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + }, + "Ethernet8": { + "admin_status": "up", + "alias": "fortyGigE0/8", + "description": "Servers1:eth0", + "index": "2", + "lanes": "33,34,35,36", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + } + } + }, + "patch": [ + { + "op": "remove", + "path": "/VLAN/Vlan1000/dhcp_servers/0" + } + ], + "expected_changes": [ + [ + { + "op": "remove", + "path": "/VLAN/Vlan1000/dhcp_servers/0" + } + ] + ] + }, + "REMOVE_2_ITEMS_WITH_DEPENDENCY_FROM_DIFFERENT_TABLES__SUCCESS": { + "desc": "Remove 2 items with dependency from different tables success.", + "current_config": { + "VLAN_MEMBER": { + "Vlan1000|Ethernet0": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet4": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet8": { + "tagging_mode": "untagged" + } + }, + "VLAN": { + "Vlan1000": { + "vlanid": "1000", + "dhcp_servers": [ + "192.0.0.1", + "192.0.0.2", + "192.0.0.3", + "192.0.0.4" + ] + } + }, + "ACL_TABLE": { + "DATAACL": { + "policy_desc": "DATAACL", + "ports": [ + "Ethernet4" + ], + "stage": "ingress", + "type": "L3" + }, + "EVERFLOW": { + "policy_desc": "EVERFLOW", + "ports": [ + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRROR" + }, + "EVERFLOWV6": { + "policy_desc": "EVERFLOWV6", + "ports": [ + "Ethernet4", + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRRORV6" + } + }, + "PORT": { + "Ethernet0": { + "alias": "Eth1", + "lanes": "65, 66, 67, 68", + "description": "Ethernet0 100G link", + "speed": "100000" + }, + "Ethernet4": { + "admin_status": "up", + "alias": "fortyGigE0/4", + "description": "Servers0:eth0", + "index": "1", + "lanes": "29,30,31,32", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + }, + "Ethernet8": { + "admin_status": "up", + "alias": "fortyGigE0/8", + "description": "Servers1:eth0", + "index": "2", + "lanes": "33,34,35,36", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + } + } + }, + "patch": [ + { + "op": "remove", + "path": "/VLAN_MEMBER/Vlan1000|Ethernet0" + }, + { + "op": "remove", + "path": "/PORT/Ethernet0" + } + ], + "expected_changes": [ + [ + { + "op": "remove", + "path": "/PORT/Ethernet0/alias" + } + ], + [ + { + "op": "remove", + "path": "/PORT/Ethernet0/description" + } + ], + [ + { + "op": "remove", + "path": "/VLAN_MEMBER/Vlan1000|Ethernet0" + } + ], + [ + { + "op": "remove", + "path": "/PORT/Ethernet0" + } + ] + ] + }, + "REMOVE_2_ITEMS_WITH_DEPENDENCY_FROM_SAME_TABLE__SUCCESS": { + "desc": "Remove 2 items with dependency from same table success.", + "current_config": { + "INTERFACE": { + "Ethernet8": {}, + "Ethernet8|10.0.0.1/30": { + "family": "IPv4", + "scope": "global" + }, + "Ethernet9": {} + }, + "PORT": { + "Ethernet8": { + "admin_status": "up", + "alias": "eth8", + "description": "Ethernet8", + "fec": "rs", + "lanes": "65", + "mtu": "9000", + "speed": "25000" + }, + "Ethernet9": { + "admin_status": "up", + "alias": "eth9", + "description": "Ethernet9", + "fec": "rs", + "lanes": "6", + "mtu": "9000", + "speed": "25000" + } + } + }, + "patch": [ + { + "op": "remove", + "path": "/INTERFACE/Ethernet8" + }, + { + "op": "remove", + "path": "/INTERFACE/Ethernet8|10.0.0.1~130" + } + ], + "expected_changes": [ + [ + { + "op": "remove", + "path": "/INTERFACE/Ethernet8|10.0.0.1~130/family" + } + ], + [ + { + "op": "remove", + "path": "/INTERFACE/Ethernet8|10.0.0.1~130/scope" + } + ], + [ + { + "op": "remove", + "path": "/INTERFACE/Ethernet8|10.0.0.1~130" + } + ], + [ + { + "op": "remove", + "path": "/INTERFACE/Ethernet8" + } + ] + ] + }, + "REMOVE_AN_ITEM_WITH_DEFAULT_VALUE__SUCCESS": { + "desc": "Remove an item with default value success.", + "current_config": { + "VLAN_MEMBER": { + "Vlan1000|Ethernet0": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet4": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet8": { + "tagging_mode": "untagged" + } + }, + "VLAN": { + "Vlan1000": { + "vlanid": "1000", + "dhcp_servers": [ + "192.0.0.1", + "192.0.0.2", + "192.0.0.3", + "192.0.0.4" + ] + } + }, + "ACL_TABLE": { + "NO-NSW-PACL-V4": { + "type": "L3", + "policy_desc": "NO-NSW-PACL-V4", + "ports": [ + "Ethernet0" + ] + }, + "DATAACL": { + "policy_desc": "DATAACL", + "ports": [ + "Ethernet4" + ], + "stage": "ingress", + "type": "L3" + }, + "EVERFLOW": { + "policy_desc": "EVERFLOW", + "ports": [ + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRROR" + }, + "EVERFLOWV6": { + "policy_desc": "EVERFLOWV6", + "ports": [ + "Ethernet4", + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRRORV6" + } + }, + "PORT": { + "Ethernet0": { + "alias": "Eth1", + "lanes": "65, 66, 67, 68", + "description": "Ethernet0 100G link", + "speed": "100000" + }, + "Ethernet4": { + "admin_status": "up", + "alias": "fortyGigE0/4", + "description": "Servers0:eth0", + "index": "1", + "lanes": "29,30,31,32", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + }, + "Ethernet8": { + "admin_status": "up", + "alias": "fortyGigE0/8", + "description": "Servers1:eth0", + "index": "2", + "lanes": "33,34,35,36", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + } + } + }, + "patch": [ + { + "op": "remove", + "path": "/ACL_TABLE/EVERFLOW/stage" + } + ], + "expected_changes": [ + [ + { + "op": "remove", + "path": "/ACL_TABLE/EVERFLOW/stage" + } + ] + ] + }, + "REMOVE_TABLE__SUCCESS": { + "desc": "Remove table success.", + "current_config": { + "VLAN_MEMBER": { + "Vlan1000|Ethernet0": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet4": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet8": { + "tagging_mode": "untagged" + } + }, + "VLAN": { + "Vlan1000": { + "vlanid": "1000", + "dhcp_servers": [ + "192.0.0.1", + "192.0.0.2", + "192.0.0.3", + "192.0.0.4" + ] + } + }, + "ACL_TABLE": { + "NO-NSW-PACL-V4": { + "type": "L3", + "policy_desc": "NO-NSW-PACL-V4", + "ports": [ + "Ethernet0" + ] + }, + "DATAACL": { + "policy_desc": "DATAACL", + "ports": [ + "Ethernet4" + ], + "stage": "ingress", + "type": "L3" + }, + "EVERFLOW": { + "policy_desc": "EVERFLOW", + "ports": [ + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRROR" + }, + "EVERFLOWV6": { + "policy_desc": "EVERFLOWV6", + "ports": [ + "Ethernet4", + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRRORV6" + } + }, + "PORT": { + "Ethernet0": { + "alias": "Eth1", + "lanes": "65, 66, 67, 68", + "description": "Ethernet0 100G link", + "speed": "100000" + }, + "Ethernet4": { + "admin_status": "up", + "alias": "fortyGigE0/4", + "description": "Servers0:eth0", + "index": "1", + "lanes": "29,30,31,32", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + }, + "Ethernet8": { + "admin_status": "up", + "alias": "fortyGigE0/8", + "description": "Servers1:eth0", + "index": "2", + "lanes": "33,34,35,36", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + } + } + }, + "patch": [ + { + "op": "remove", + "path": "/ACL_TABLE" + } + ], + "expected_changes": [ + [ + { + "op": "remove", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/policy_desc" + } + ], + [ + { + "op": "remove", + "path": "/ACL_TABLE/DATAACL/policy_desc" + } + ], + [ + { + "op": "remove", + "path": "/ACL_TABLE/DATAACL/stage" + } + ], + [ + { + "op": "remove", + "path": "/ACL_TABLE/EVERFLOW/policy_desc" + } + ], + [ + { + "op": "remove", + "path": "/ACL_TABLE/EVERFLOW/stage" + } + ], + [ + { + "op": "remove", + "path": "/ACL_TABLE/EVERFLOWV6/policy_desc" + } + ], + [ + { + "op": "remove", + "path": "/ACL_TABLE/EVERFLOWV6/ports/0" + } + ], + [ + { + "op": "remove", + "path": "/ACL_TABLE/EVERFLOWV6/stage" + } + ], + [ + { + "op": "remove", + "path": "/ACL_TABLE/NO-NSW-PACL-V4" + } + ], + [ + { + "op": "remove", + "path": "/ACL_TABLE/DATAACL/ports" + } + ], + [ + { + "op": "remove", + "path": "/ACL_TABLE/DATAACL" + } + ], + [ + { + "op": "remove", + "path": "/ACL_TABLE/EVERFLOW/ports" + } + ], + [ + { + "op": "remove", + "path": "/ACL_TABLE/EVERFLOW" + } + ], + [ + { + "op": "remove", + "path": "/ACL_TABLE/EVERFLOWV6/ports" + } + ], + [ + { + "op": "remove", + "path": "/ACL_TABLE" + } + ] + ] + }, + "REMOVING_CREATE_ONLY_FIELD__SUCCESS": { + "desc": "Removing create only field success.", + "current_config": { + "LOOPBACK_INTERFACE": { + "Loopback0": {}, + "Loopback0|10.1.0.32/32": {}, + "Loopback0|1100:1::32/128": {}, + "Loopback1": { + "vrf_name": "Vrf_02" + }, + "Loopback1|20.2.0.32/32": {}, + "Loopback1|2200:2::32/128": {} + }, + "VRF": { + "Vrf_01": {}, + "Vrf_02": {} + } + }, + "patch": [ + { + "op": "remove", + "path": "/LOOPBACK_INTERFACE/Loopback1/vrf_name" + } + ], + "expected_changes": [ + [ + { + "op": "remove", + "path": "/LOOPBACK_INTERFACE/Loopback1|2200:2::32~1128" + } + ], + [ + { + "op": "remove", + "path": "/LOOPBACK_INTERFACE/Loopback1|20.2.0.32~132" + } + ], + [ + { + "op": "add", + "path": "/LOOPBACK_INTERFACE/Loopback1|2200:2::32~1128", + "value": {} + } + ], + [ + { + "op": "remove", + "path": "/LOOPBACK_INTERFACE/Loopback0|10.1.0.32~132" + } + ], + [ + { + "op": "add", + "path": "/LOOPBACK_INTERFACE/Loopback1|20.2.0.32~132", + "value": {} + } + ], + [ + { + "op": "remove", + "path": "/LOOPBACK_INTERFACE/Loopback1|2200:2::32~1128" + } + ], + [ + { + "op": "remove", + "path": "/LOOPBACK_INTERFACE/Loopback1|20.2.0.32~132" + } + ], + [ + { + "op": "remove", + "path": "/LOOPBACK_INTERFACE/Loopback1" + } + ], + [ + { + "op": "add", + "path": "/LOOPBACK_INTERFACE/Loopback0|10.1.0.32~132", + "value": {} + } + ], + [ + { + "op": "add", + "path": "/LOOPBACK_INTERFACE/Loopback1", + "value": {} + } + ], + [ + { + "op": "add", + "path": "/LOOPBACK_INTERFACE/Loopback1|20.2.0.32~132", + "value": {} + } + ], + [ + { + "op": "add", + "path": "/LOOPBACK_INTERFACE/Loopback1|2200:2::32~1128", + "value": {} + } + ] + ] + }, + "REPLACE_MANDATORY_ITEM__SUCCESS": { + "desc": "Replace mandatory item success.", + "current_config": { + "VLAN_MEMBER": { + "Vlan1000|Ethernet0": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet4": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet8": { + "tagging_mode": "untagged" + } + }, + "VLAN": { + "Vlan1000": { + "vlanid": "1000", + "dhcp_servers": [ + "192.0.0.1", + "192.0.0.2", + "192.0.0.3", + "192.0.0.4" + ] + } + }, + "ACL_TABLE": { + "NO-NSW-PACL-V4": { + "type": "L3", + "policy_desc": "NO-NSW-PACL-V4", + "ports": [ + "Ethernet0" + ] + }, + "DATAACL": { + "policy_desc": "DATAACL", + "ports": [ + "Ethernet4" + ], + "stage": "ingress", + "type": "L3" + }, + "EVERFLOW": { + "policy_desc": "EVERFLOW", + "ports": [ + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRROR" + }, + "EVERFLOWV6": { + "policy_desc": "EVERFLOWV6", + "ports": [ + "Ethernet4", + "Ethernet8" + ], + "stage": "ingress", + "type": "MIRRORV6" + } + }, + "PORT": { + "Ethernet0": { + "alias": "Eth1", + "lanes": "65, 66, 67, 68", + "description": "Ethernet0 100G link", + "speed": "100000" + }, + "Ethernet4": { + "admin_status": "up", + "alias": "fortyGigE0/4", + "description": "Servers0:eth0", + "index": "1", + "lanes": "29,30,31,32", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + }, + "Ethernet8": { + "admin_status": "up", + "alias": "fortyGigE0/8", + "description": "Servers1:eth0", + "index": "2", + "lanes": "33,34,35,36", + "mtu": "9100", + "pfc_asym": "off", + "speed": "40000" + } + } + }, + "patch": [ + { + "op": "replace", + "path": "/ACL_TABLE/EVERFLOWV6/type", + "value": "L2" + } + ], + "expected_changes": [ + [ + { + "op": "replace", + "path": "/ACL_TABLE/EVERFLOWV6/type", + "value": "L2" + } + ] + ] + }, + "REPLACING_CREATE_ONLY_FIELD__SUCCESS": { + "desc": "Replacing create only field success.", + "current_config": { + "PORT": { + "Ethernet0": { + "alias": "Eth1", + "lanes": "65, 66, 67, 68", + "description": "Ethernet0 100G link", + "speed": "100000" + } + }, + "ACL_TABLE": { + "NO-NSW-PACL-V4": { + "type": "L3", + "policy_desc": "NO-NSW-PACL-V4", + "ports": [ + "Ethernet0" + ] + } + }, + "VLAN_MEMBER": { + "Vlan100|Ethernet0": { + "tagging_mode": "untagged" + } + }, + "VLAN": { + "Vlan100": { + "vlanid": "100", + "dhcp_servers": [ + "192.0.0.1", + "192.0.0.2", + "192.0.0.3", + "192.0.0.4" + ] + } + } + }, + "patch": [ + { + "op": "replace", + "path": "/PORT/Ethernet0/lanes", + "value": "67" + } + ], + "expected_changes": [ + [ + { + "op": "remove", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/ports" + } + ], + [ + { + "op": "remove", + "path": "/VLAN_MEMBER" + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/ports", + "value": [ + "Ethernet0" + ] + } + ], + [ + { + "op": "remove", + "path": "/ACL_TABLE" + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE", + "value": { + "NO-NSW-PACL-V4": { + "type": "L3" + } + } + } + ], + [ + { + "op": "remove", + "path": "/PORT" + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/policy_desc", + "value": "NO-NSW-PACL-V4" + } + ], + [ + { + "op": "add", + "path": "/PORT", + "value": { + "Ethernet0": { + "alias": "Eth1", + "lanes": "67", + "description": "Ethernet0 100G link", + "speed": "100000" + } + } + } + ], + [ + { + "op": "add", + "path": "/ACL_TABLE/NO-NSW-PACL-V4/ports", + "value": [ + "Ethernet0" + ] + } + ], + [ + { + "op": "add", + "path": "/VLAN_MEMBER", + "value": { + "Vlan100|Ethernet0": { + "tagging_mode": "untagged" + } + } + } + ] + ] + } +} \ No newline at end of file diff --git a/tests/generic_config_updater/patch_sorter_test.py b/tests/generic_config_updater/patch_sorter_test.py index ef809ef929c1..4ac0c574a4a1 100644 --- a/tests/generic_config_updater/patch_sorter_test.py +++ b/tests/generic_config_updater/patch_sorter_test.py @@ -1746,6 +1746,87 @@ def verify(self, algo, algo_class): self.assertCountEqual(expected_validator, actual_validators) class TestPatchSorter(unittest.TestCase): + def test_patch_sorter_success(self): + # Format of the JSON file containing the test-cases: + # + # { + # "":{ + # "desc":"", + # "current_config":, + # "patch":, + # "expected_changes":[] + # }, + # . + # . + # . + # } + data = Files.PATCH_SORTER_TEST_SUCCESS + # TODO: Investigate issue where different runs of patch-sorter generated different but correct steps + # Once investigation is complete remove the flag 'skip_exact_change_list_match' + skip_exact_change_list_match = True + for test_case_name in data: + with self.subTest(name=test_case_name): + self.run_single_success_case(data[test_case_name], skip_exact_change_list_match) + + def run_single_success_case(self, data, skip_exact_change_list_match): + current_config = data["current_config"] + patch = jsonpatch.JsonPatch(data["patch"]) + expected_changes = [] + for item in data["expected_changes"]: + expected_changes.append(JsonChange(jsonpatch.JsonPatch(item))) + + sorter = self.create_patch_sorter(current_config) + + actual_changes = sorter.sort(patch) + + if not skip_exact_change_list_match: + self.assertEqual(expected_changes, actual_changes) + + target_config = patch.apply(current_config) + simulated_config = current_config + for change in actual_changes: + simulated_config = change.apply(simulated_config) + self.assertTrue(ConfigWrapper().validate_config_db_config(simulated_config)) + self.assertEqual(target_config, simulated_config) + + def test_patch_sorter_failure(self): + # Format of the JSON file containing the test-cases: + # + # { + # "":{ + # "desc":"", + # "current_config":, + # "patch":, + # "expected_error_substrings":[] + # }, + # . + # . + # . + # } + data = Files.PATCH_SORTER_TEST_FAILURE + for test_case_name in data: + with self.subTest(name=test_case_name): + self.run_single_failure_case(data[test_case_name]) + + def run_single_failure_case(self, data): + current_config = data["current_config"] + patch = jsonpatch.JsonPatch(data["patch"]) + expected_error_substrings = data["expected_error_substrings"] + + try: + sorter = self.create_patch_sorter(current_config) + sorter.sort(patch) + self.fail("An exception was supposed to be thrown") + except Exception as ex: + notfound_substrings = [] + error = str(ex) + for substring in expected_error_substrings: + if substring not in error: + notfound_substrings.append(substring) + + if notfound_substrings: + self.fail(f"Did not find the substrings {notfound_substrings} in the error: '{error}'") + def create_patch_sorter(self, config=None): if config is None: config=Files.CROPPED_CONFIG_DB_AS_JSON @@ -1758,183 +1839,6 @@ def create_patch_sorter(self, config=None): return ps.PatchSorter(config_wrapper, patch_wrapper, sort_algorithm_factory) - def test_sort__empty_patch__returns_empty_changes_list(self): - # Arrange - patch = jsonpatch.JsonPatch([]) - expected = [] - - # Act - actual = self.create_patch_sorter().sort(patch) - - # Assert - self.assertCountEqual(expected, actual) - - def test_sort__patch_with_single_simple_operation__returns_one_change(self): - # Arrange - patch = jsonpatch.JsonPatch([{"op":"remove", "path":"/VLAN/Vlan1000/dhcp_servers/0"}]) - expected = [JsonChange(patch)] - - # Act - actual = self.create_patch_sorter().sort(patch) - - # Assert - self.assertCountEqual(expected, actual) - - def test_sort__replacing_create_only_field__success(self): - # Arrange - patch = jsonpatch.JsonPatch([{"op":"replace", "path": "/PORT/Ethernet0/lanes", "value":"67"}]) - - # Act - actual = self.create_patch_sorter(Files.DPB_1_SPLIT_FULL_CONFIG).sort(patch) - - # Assert - self.assertNotEqual(None, actual) - - def test_sort__adding_create_only_field__success(self): - # Arrange - patch = jsonpatch.JsonPatch([{"op":"add", "path": "/LOOPBACK_INTERFACE/Loopback0/vrf_name", "value":"Vrf_01"}]) - - # Act - actual = self.create_patch_sorter(Files.CONFIG_DB_WITH_LOOPBACK_INTERFACES).sort(patch) - - # Assert - self.assertNotEqual(None, actual) - - def test_sort__removing_create_only_field__success(self): - # Arrange - patch = jsonpatch.JsonPatch([{"op":"remove", "path": "/LOOPBACK_INTERFACE/Loopback1/vrf_name"}]) - - # Act - actual = self.create_patch_sorter(Files.CONFIG_DB_WITH_LOOPBACK_INTERFACES).sort(patch) - - # Assert - self.assertNotEqual(None, actual) - - def test_sort__inter_dependency_within_same_table__success(self): - # Arrange - patch = jsonpatch.JsonPatch([{"op":"add", "path":"/VLAN_INTERFACE", "value": { - "Vlan1000|fc02:1000::1/64": {}, - "Vlan1000|192.168.0.1/21": {}, - "Vlan1000": {} - }}]) - expected = [ - JsonChange(jsonpatch.JsonPatch([{"op": "add", "path": "/VLAN_INTERFACE", "value": {"Vlan1000": {}}}])), - JsonChange(jsonpatch.JsonPatch([{"op": "add", "path": "/VLAN_INTERFACE/Vlan1000|fc02:1000::1~164", "value": {}}])), - JsonChange(jsonpatch.JsonPatch([{"op": "add", "path": "/VLAN_INTERFACE/Vlan1000|192.168.0.1~121", "value": {}}])) - ] - - # Act - actual = self.create_patch_sorter().sort(patch) - - # Assert - self.assertListEqual(expected, actual) - - def test_sort__add_table__success(self): - self.verify(cc_ops=[{"op":"remove", "path":"/ACL_TABLE"}]) - - def test_sort__remove_table__success(self): - self.verify(tc_ops=[{"op":"remove", "path":"/ACL_TABLE"}]) - - def test_sort__modify_value_in_existing_table__success(self): - self.verify(tc_ops=[{"op":"replace", "path":"/ACL_TABLE/EVERFLOW/stage", "value":"egress"}]) - - def test_sort__modify_value_in_existing_array__success(self): - self.verify(tc_ops=[{"op":"replace", "path":"/ACL_TABLE/EVERFLOWV6/ports/0", "value":"Ethernet0"}]) - - def test_sort__add_value_to_existing_array__success(self): - self.verify(tc_ops=[{"op":"add", "path":"/ACL_TABLE/EVERFLOWV6/ports/0", "value":"Ethernet0"}]) - - def test_sort__add_new_key_to_existing_table__success(self): - self.verify(cc_ops=[{"op":"remove", "path":"/ACL_TABLE/EVERFLOWV6"}]) - - def test_sort__remove_2_items_with_dependency_from_different_tables__success(self): - self.verify(tc_ops=[{"op":"remove", "path":"/PORT/Ethernet0"}, - {"op":"remove", "path":"/VLAN_MEMBER/Vlan1000|Ethernet0"}, - {"op":"remove", "path":"/ACL_TABLE/NO-NSW-PACL-V4"}], # removing ACL from current and target - cc_ops=[{"op":"remove", "path":"/ACL_TABLE/NO-NSW-PACL-V4"}]) - - def test_sort__add_2_items_with_dependency_from_different_tables__success(self): - self.verify(tc_ops=[{"op":"remove", "path":"/ACL_TABLE/NO-NSW-PACL-V4"}], # removing ACL from current and target - cc_ops=[{"op":"remove", "path":"/PORT/Ethernet0"}, - {"op":"remove", "path":"/VLAN_MEMBER/Vlan1000|Ethernet0"}, - {"op":"remove", "path":"/ACL_TABLE/NO-NSW-PACL-V4"}]) - - def test_sort__remove_2_items_with_dependency_from_same_table__success(self): - self.verify(tc_ops=[{"op":"replace", "path":"", "value":Files.CONFIG_DB_WITH_INTERFACE}, - {"op":"remove", "path":"/INTERFACE/Ethernet8"}, - {"op":"remove", "path":"/INTERFACE/Ethernet8|10.0.0.1~130"}], - cc_ops=[{"op":"replace", "path":"", "value":Files.CONFIG_DB_WITH_INTERFACE}]) - - def test_sort__add_2_items_with_dependency_from_same_table__success(self): - self.verify(tc_ops=[{"op":"replace", "path":"", "value":Files.CONFIG_DB_WITH_INTERFACE}], - cc_ops=[{"op":"replace", "path":"", "value":Files.CONFIG_DB_WITH_INTERFACE}, - {"op":"remove", "path":"/INTERFACE/Ethernet8"}, - {"op":"remove", "path":"/INTERFACE/Ethernet8|10.0.0.1~130"}]) - - def test_sort__replace_mandatory_item__success(self): - self.verify(tc_ops=[{"op":"replace", "path":"/ACL_TABLE/EVERFLOWV6/type", "value":"L2"}]) - - def test_sort__dpb_1_to_4__success(self): - self.verify(tc_ops=[{"op":"replace", "path":"", "value":Files.DPB_4_SPLITS_FULL_CONFIG}], - cc_ops=[{"op":"replace", "path":"", "value":Files.DPB_1_SPLIT_FULL_CONFIG}]) - - def test_sort__dpb_4_to_1__success(self): - self.verify(tc_ops=[{"op":"replace", "path":"", "value":Files.DPB_1_SPLIT_FULL_CONFIG}], - cc_ops=[{"op":"replace", "path":"", "value":Files.DPB_4_SPLITS_FULL_CONFIG}]) - - def test_sort__remove_an_item_with_default_value__success(self): - self.verify(tc_ops=[{"op":"remove", "path":"/ACL_TABLE/EVERFLOW/stage"}]) - - def test_sort__modify_items_with_dependencies_using_must__success(self): - self.verify(tc_ops=[{"op":"replace", "path":"", "value":Files.CONFIG_DB_WITH_CRM}, - {"op":"replace", "path":"/CRM/Config/acl_counter_high_threshold", "value":"60"}, - {"op":"replace", "path":"/CRM/Config/acl_counter_low_threshold", "value":"50"}], - cc_ops=[{"op":"replace", "path":"", "value":Files.CONFIG_DB_WITH_CRM}]) - - # in the following example, it is possible to start with acl_counter_high_threshold - self.verify(tc_ops=[{"op":"replace", "path":"", "value":Files.CONFIG_DB_WITH_CRM}, - {"op":"replace", "path":"/CRM/Config/acl_counter_high_threshold", "value":"80"}, - {"op":"replace", "path":"/CRM/Config/acl_counter_low_threshold", "value":"60"}], - cc_ops=[{"op":"replace", "path":"", "value":Files.CONFIG_DB_WITH_CRM}]) - - def test_sort__modify_items_result_in_empty_table__failure(self): - # Emptying a table - self.assertRaises(GenericConfigUpdaterError, - self.verify, - cc_ops=[{"op":"replace", "path":"", "value":Files.SIMPLE_CONFIG_DB_INC_DEPS}], - tc_ops=[{"op":"replace", "path":"", "value":Files.SIMPLE_CONFIG_DB_INC_DEPS}, - {"op":"replace", "path":"/ACL_TABLE", "value":{}}]) - # Adding an empty table - self.assertRaises(GenericConfigUpdaterError, - self.verify, - cc_ops=[{"op":"replace", "path":"", "value":Files.ANY_CONFIG_DB}], - tc_ops=[{"op":"replace", "path":"", "value":Files.ANY_CONFIG_DB}, - {"op":"add", "path":"/VLAN", "value":{}}]) - # Emptying multiple tables - self.assertRaises(GenericConfigUpdaterError, - self.verify, - cc_ops=[{"op":"replace", "path":"", "value":Files.SIMPLE_CONFIG_DB_INC_DEPS}], - tc_ops=[{"op":"replace", "path":"", "value":Files.SIMPLE_CONFIG_DB_INC_DEPS}, - {"op":"replace", "path":"/ACL_TABLE", "value":{}}, - {"op":"replace", "path":"/PORT", "value":{}}]) - - def verify(self, cc_ops=[], tc_ops=[]): - # Arrange - config_wrapper=ConfigWrapper() - target_config=jsonpatch.JsonPatch(tc_ops).apply(Files.CROPPED_CONFIG_DB_AS_JSON) - current_config=jsonpatch.JsonPatch(cc_ops).apply(Files.CROPPED_CONFIG_DB_AS_JSON) - patch=jsonpatch.make_patch(current_config, target_config) - - # Act - actual = self.create_patch_sorter(current_config).sort(patch) - - # Assert - simulated_config = current_config - for move in actual: - simulated_config = move.apply(simulated_config) - self.assertTrue(config_wrapper.validate_config_db_config(simulated_config)) - self.assertEqual(target_config, simulated_config) - class TestChangeWrapper(unittest.TestCase): def setUp(self): config_splitter = ps.ConfigSplitter(ConfigWrapper(), [])