Skip to content

Commit 4fc09b1

Browse files
authored
[GCU] Handling non-compliant leaf-list with string values (#2174)
#### What I did Fixes #2170 Converting xpath to path: - There is only 1 case where the path is referring to the list itself. Example: ``` path="/BUFFER_PORT_EGRESS_PROFILE_LIST/Ethernet9/profile_list", xpath="/sonic-buffer-port-egress-profile-list:sonic-buffer-port-egress-profile-list/BUFFER_PORT_EGRESS_PROFILE_LIST/BUFFER_PORT_EGRESS_PROFILE_LIST_LIST[port='Ethernet9']/profile_list", ``` - There is no other case as we the list is just a single string, and we cannot refer to individual elements in string in ConfigDb. Converting path to xpath, there are 2 cases: - Xpath is pointing to leaf-list as a whole, return path of whole list ``` xpath="/sonic-buffer-port-egress-profile-list:sonic-buffer-port-egress-profile-list/BUFFER_PORT_EGRESS_PROFILE_LIST/BUFFER_PORT_EGRESS_PROFILE_LIST_LIST[port='Ethernet9']/profile_list", path="/BUFFER_PORT_EGRESS_PROFILE_LIST/Ethernet9/profile_list", ``` - Xpath is pointing to an element of the leaf-list, return path of whole list as well since it is not possible to point to specific element -- here we are pointing to the element `egress_lossy_profile` ``` xpath="/sonic-buffer-port-egress-profile-list:sonic-buffer-port-egress-profile-list/BUFFER_PORT_EGRESS_PROFILE_LIST/BUFFER_PORT_EGRESS_PROFILE_LIST_LIST[port='Ethernet9']/profile_list[.='egress_lossy_profile']", path="/BUFFER_PORT_EGRESS_PROFILE_LIST/Ethernet9/profile_list", ``` #### How I did it Only a single change if the xpath is pointing to a specific element, just return whole list token from ConfigDb format. Please note this solution is future proof, if ConfigDb changes how a list is saved as a string or json list, we don't care. #### How to verify it unit-test #### Previous command output (if the output of a command-line utility has changed) #### New command output (if the output of a command-line utility has changed)
1 parent 675c7b6 commit 4fc09b1

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed

generic_config_updater/gu_common.py

+13
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,19 @@ def _get_path_tokens_from_leaf(self, model, token_index, xpath_tokens, config):
750750
# leaf_list_name = match.group(1)
751751
leaf_list_value = match.group(1)
752752
list_config = config[leaf_list_name]
753+
# Workaround for those fields who is defined as leaf-list in YANG model but have string value in config DB
754+
# No need to lookup the item index in ConfigDb since the list is represented as a string, return path to string immediately
755+
# Example:
756+
# xpath: /sonic-buffer-port-egress-profile-list:sonic-buffer-port-egress-profile-list/BUFFER_PORT_EGRESS_PROFILE_LIST/BUFFER_PORT_EGRESS_PROFILE_LIST_LIST[port='Ethernet9']/profile_list[.='egress_lossy_profile']
757+
# path: /BUFFER_PORT_EGRESS_PROFILE_LIST/Ethernet9/profile_list
758+
if isinstance(list_config, str):
759+
return [leaf_list_name]
760+
761+
if not isinstance(list_config, list):
762+
raise ValueError(f"list_config is expected to be of type list or string. Found {type(list_config)}.\n " + \
763+
f"model: {model}\n token_index: {token_index}\n " + \
764+
f"xpath_tokens: {xpath_tokens}\n config: {config}")
765+
753766
list_idx = list_config.index(leaf_list_value)
754767
return [leaf_list_name, list_idx]
755768

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"BUFFER_POOL": {
3+
"egress_lossless_pool": {
4+
"mode": "static",
5+
"size": "33004032",
6+
"xoff": "196608",
7+
"type": "egress"
8+
},
9+
"egress_lossy_pool": {
10+
"size": "12766208",
11+
"type": "egress",
12+
"mode": "dynamic"
13+
}
14+
},
15+
"BUFFER_PROFILE": {
16+
"egress_lossless_profile": {
17+
"pool":"egress_lossless_pool",
18+
"size":"1518",
19+
"dynamic_th":"3"
20+
},
21+
"egress_lossy_profile": {
22+
"pool":"egress_lossy_pool",
23+
"size":"1518",
24+
"dynamic_th":"3"
25+
}
26+
},
27+
"BUFFER_PORT_EGRESS_PROFILE_LIST": {
28+
"Ethernet9": {
29+
"profile_list": "egress_lossless_profile,egress_lossy_profile"
30+
}
31+
},
32+
"PORT": {
33+
"Ethernet9": {
34+
"alias": "Eth3/2",
35+
"lanes": "74",
36+
"description": "",
37+
"speed": "11100",
38+
"tpid": "0x8100",
39+
"admin_status": "up"
40+
}
41+
}
42+
}

tests/generic_config_updater/gu_common_test.py

+22
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,19 @@ def test_find_ref_paths__does_not_remove_tables_without_yang(self):
779779
# Assert
780780
self.assertEqual(expected_config, config)
781781

782+
def test_find_ref_paths__ref_path_is_leaflist_in_yang_but_string_in_config_db__path_to_string_returned(self):
783+
# Arrange
784+
path = "/BUFFER_PROFILE/egress_lossless_profile"
785+
expected = [
786+
"/BUFFER_PORT_EGRESS_PROFILE_LIST/Ethernet9/profile_list",
787+
]
788+
789+
# Act
790+
actual = self.path_addressing.find_ref_paths(path, Files.CONFIG_DB_WITH_PROFILE_LIST)
791+
792+
# Assert
793+
self.assertEqual(expected, actual)
794+
782795
def test_convert_path_to_xpath(self):
783796
def check(path, xpath, config=None):
784797
if not config:
@@ -839,6 +852,9 @@ def check(path, xpath, config=None):
839852
check(path="/LLDP/GLOBAL/mode",
840853
xpath="/sonic-lldp:sonic-lldp/LLDP/GLOBAL/mode",
841854
config=Files.CONFIG_DB_WITH_LLDP)
855+
check(path="/BUFFER_PORT_EGRESS_PROFILE_LIST/Ethernet9/profile_list",
856+
xpath="/sonic-buffer-port-egress-profile-list:sonic-buffer-port-egress-profile-list/BUFFER_PORT_EGRESS_PROFILE_LIST/BUFFER_PORT_EGRESS_PROFILE_LIST_LIST[port='Ethernet9']/profile_list",
857+
config=Files.CONFIG_DB_WITH_PROFILE_LIST)
842858

843859
def test_convert_xpath_to_path(self):
844860
def check(xpath, path, config=None):
@@ -914,6 +930,12 @@ def check(xpath, path, config=None):
914930
check(xpath="/sonic-lldp:sonic-lldp/LLDP/GLOBAL/mode",
915931
path="/LLDP/GLOBAL/mode",
916932
config=Files.CONFIG_DB_WITH_LLDP)
933+
check(xpath="/sonic-buffer-port-egress-profile-list:sonic-buffer-port-egress-profile-list/BUFFER_PORT_EGRESS_PROFILE_LIST/BUFFER_PORT_EGRESS_PROFILE_LIST_LIST[port='Ethernet9']/profile_list",
934+
path="/BUFFER_PORT_EGRESS_PROFILE_LIST/Ethernet9/profile_list",
935+
config=Files.CONFIG_DB_WITH_PROFILE_LIST)
936+
check(xpath="/sonic-buffer-port-egress-profile-list:sonic-buffer-port-egress-profile-list/BUFFER_PORT_EGRESS_PROFILE_LIST/BUFFER_PORT_EGRESS_PROFILE_LIST_LIST[port='Ethernet9']/profile_list[.='egress_lossy_profile']",
937+
path="/BUFFER_PORT_EGRESS_PROFILE_LIST/Ethernet9/profile_list",
938+
config=Files.CONFIG_DB_WITH_PROFILE_LIST)
917939

918940
def test_has_path(self):
919941
def check(config, path, expected):

0 commit comments

Comments
 (0)