Skip to content

Commit

Permalink
Add following APIs and test cases: (#44)
Browse files Browse the repository at this point in the history
*     Add following APIs and test cases:
    - get Yang module's prefix
    - get the datanode's data type
    - get the data type of the node that leafref node points to

* Add new libyang python APIs:
- get_leafref_path()
- get_leafref_type_schema()
  • Loading branch information
li-pingmao authored Feb 13, 2020
1 parent 450afa1 commit 04242e7
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 1 deletion.
119 changes: 119 additions & 0 deletions src/sonic-yang-mgmt/sonic_yang.py
Original file line number Diff line number Diff line change
Expand Up @@ -540,3 +540,122 @@ def find_data_dependencies (self, data_xpath):
self.fail(e)

return ref_list

"""
get_module_prefix: get the prefix of a Yang module
input: name of the Yang module
output: prefix of the Yang module
"""
def get_module_prefix(self, module_name):
prefix = ""
try:
module = self.get_module(module_name)
except Exception as e:
self.fail(e)
return prefix
else:
return module.prefix()

"""
str_to_type: map string to type of node
input: string
output: type
"""
def str_to_type (self, type_str):
mapped_type = {
"LY_TYPE_DER":ly.LY_TYPE_DER,
"LY_TYPE_BINARY":ly.LY_TYPE_BINARY,
"LY_TYPE_BITS":ly.LY_TYPE_BITS,
"LY_TYPE_BOOL":ly.LY_TYPE_BOOL,
"LY_TYPE_DEC64":ly.LY_TYPE_DEC64,
"LY_TYPE_EMPTY":ly.LY_TYPE_EMPTY,
"LY_TYPE_ENUM":ly.LY_TYPE_ENUM,
"LY_TYPE_IDENT":ly.LY_TYPE_IDENT,
"LY_TYPE_INST":ly.LY_TYPE_INST,
"LY_TYPE_LEAFREF":ly.LY_TYPE_LEAFREF,
"LY_TYPE_STRING":ly.LY_TYPE_STRING,
"LY_TYPE_UNION":ly.LY_TYPE_UNION,
"LY_TYPE_INT8":ly.LY_TYPE_INT8,
"LY_TYPE_UINT8":ly.LY_TYPE_UINT8,
"LY_TYPE_INT16":ly.LY_TYPE_INT16,
"LY_TYPE_UINT16":ly.LY_TYPE_UINT16,
"LY_TYPE_INT32":ly.LY_TYPE_INT32,
"LY_TYPE_UINT32":ly.LY_TYPE_UINT32,
"LY_TYPE_INT64":ly.LY_TYPE_INT64,
"LY_TYPE_UINT64":ly.LY_TYPE_UINT64,
"LY_TYPE_UNKNOWN":ly.LY_TYPE_UNKNOWN
}

if type_str not in mapped_type:
return ly.LY_TYPE_UNKNOWN

return mapped_type[type_str]

def get_data_type (self, schema_xpath):
try:
schema_node = self.find_schema_node(schema_xpath)
except Exception as e:
print("get_data_type(): Failed to find schema node from xpath: {}".format(schema_xpath))
self.fail(e)
return None

if (schema_node is not None):
return schema_node.subtype().type().base()

return ly.LY_TYPE_UNKNOWN

"""
get_leafref_type: find the type of node that leafref references to
input: data_xpath - xpath of a data node
output: type of the node this leafref references to
"""
def get_leafref_type (self, data_xpath):
data_node = self.find_data_node(data_xpath)
if (data_node is not None):
subtype = data_node.subtype()
if (subtype is not None):
if data_node.schema().subtype().type().base() != ly.LY_TYPE_LEAFREF:
print("get_leafref_type() node type for data xpath: {} is not LEAFREF".format(data_xpath))
return ly.LY_TYPE_UNKNOWN
else:
return subtype.value_type()

return ly.LY_TYPE_UNKNOWN

"""
get_leafref_path(): find the leafref path
input: schema_xpath - xpath of a schema node
output: path value of the leafref node
"""
def get_leafref_path (self, schema_xpath):
schema_node = self.find_schema_node(schema_xpath)
if (schema_node is not None):
subtype = schema_node.subtype()
if (subtype is not None):
if subtype.type().base() != ly.LY_TYPE_LEAFREF:
return None
else:
return subtype.type().info().lref().path()

return None

"""
get_leafref_type_schema: find the type of node that leafref references to
input: schema_xpath - xpath of a schema node
output: type of the node this leafref references to
"""
def get_leafref_type_schema (self, schema_xpath):
schema_node = self.find_schema_node(schema_xpath)
if (schema_node is not None):
subtype = schema_node.subtype()
if (subtype is not None):
if subtype.type().base() != ly.LY_TYPE_LEAFREF:
return None
else:
leafref_path = subtype.type().info().lref().path()
target = subtype.type().info().lref().target()
target_path = target.path()
target_type = self.get_data_type(target_path)
return target_type

return None
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,43 @@
"parent":"/sonic-vlan:sonic-vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']"},
{"xpath":"/sonic-port:sonic-port/PORT/PORT_LIST[port_name='Ethernet9']/speed",
"parent":"/sonic-port:sonic-port/PORT/PORT_LIST[port_name='Ethernet9']"}
]
],
"prefix":[
{"module_name":"sonic-head", "module_prefix":"sonic-head"},
{"module_name":"sonic-port", "module_prefix":"port"},
{"module_name":"sonic-acl", "module_prefix":"acl"},
{"module_name":"sonic-interface", "module_prefix":"intf"},
{"module_name":"sonic-portchannel", "module_prefix":"lag"},
{"module_name":"sonic-vlan", "module_prefix":"vlan"}
],
"data_type":[
{"xpath":"/sonic-port:sonic-port/sonic-port:PORT/sonic-port:PORT_LIST/sonic-port:port_name", "data_type":"LY_TYPE_STRING"},
{"xpath":"/sonic-vlan:sonic-vlan/sonic-vlan:VLAN_INTERFACE/sonic-vlan:VLAN_INTERFACE_LIST/sonic-vlan:vlanid", "data_type":"LY_TYPE_LEAFREF"}
],
"leafref_type":[
{"xpath":"/sonic-vlan:sonic-vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='2000:f500:45:6709::/64']/vlanid", "data_type":"LY_TYPE_UINT16"},
{"xpath":"/sonic-interface:sonic-interface/INTERFACE/INTERFACE_LIST[interface='Ethernet8'][ip-prefix='2000:f500:40:a749::/126']/interface", "data_type":"LY_TYPE_STRING"},
{"xpath":"/sonic-vlan:sonic-vlan/VLAN_MEMBER/VLAN_MEMBER_LIST[vlanid='111'][port='Ethernet0']/port", "data_type":"LY_TYPE_STRING"},
{"xpath":"/sonic-vlan:sonic-vlan/VLAN_MEMBER/VLAN_MEMBER_LIST[vlanid='111'][port='Ethernet0']/vlanid", "data_type":"LY_TYPE_UINT16"}
],
"leafref_type_schema":[
{"xpath":"/sonic-vlan:sonic-vlan/sonic-vlan:VLAN_INTERFACE/sonic-vlan:VLAN_INTERFACE_LIST/sonic-vlan:vlanid",
"data_type":"LY_TYPE_UINT16"},
{"xpath":"/sonic-interface:sonic-interface/sonic-interface:INTERFACE/sonic-interface:INTERFACE_LIST/sonic-interface:interface",
"data_type":"LY_TYPE_STRING"},
{"xpath":"/sonic-vlan:sonic-vlan/sonic-vlan:VLAN_MEMBER/sonic-vlan:VLAN_MEMBER_LIST/sonic-vlan:port",
"data_type":"LY_TYPE_STRING"},
{"xpath":"/sonic-vlan:sonic-vlan/sonic-vlan:VLAN_MEMBER/sonic-vlan:VLAN_MEMBER_LIST/sonic-vlan:vlanid",
"data_type":"LY_TYPE_UINT16"}
],
"leafref_path":[
{"xpath":"/sonic-vlan:sonic-vlan/sonic-vlan:VLAN_INTERFACE/sonic-vlan:VLAN_INTERFACE_LIST/sonic-vlan:vlanid",
"leafref_path":"../../../VLAN/VLAN_LIST/vlanid"},
{"xpath":"/sonic-interface:sonic-interface/sonic-interface:INTERFACE/sonic-interface:INTERFACE_LIST/sonic-interface:interface",
"leafref_path":"/sonic-port:sonic-port/sonic-port:PORT/sonic-port:PORT_LIST/sonic-port:port_name"},
{"xpath":"/sonic-vlan:sonic-vlan/sonic-vlan:VLAN_MEMBER/sonic-vlan:VLAN_MEMBER_LIST/sonic-vlan:port",
"leafref_path":"/sonic-port:sonic-port/sonic-port:PORT/sonic-port:PORT_LIST/sonic-port:port_name"},
{"xpath":"/sonic-vlan:sonic-vlan/sonic-vlan:VLAN_MEMBER/sonic-vlan:VLAN_MEMBER_LIST/sonic-vlan:vlanid",
"leafref_path":"../../../VLAN/VLAN_LIST/vlanid"}
]
}
40 changes: 40 additions & 0 deletions src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,46 @@ def test_merge_data_tree(self, data, yang_s):
yang_s.merge_data(data_merge_file, yang_dir)
#yang_s.root.print_mem(ly.LYD_JSON, ly.LYP_FORMAT)

#test get module prefix
def test_get_module_prefix(self, yang_s, data):
for node in data['prefix']:
xpath = str(node['module_name'])
expected = node['module_prefix']
prefix = yang_s.get_module_prefix(xpath)
assert expected == prefix

#test get data type
def test_get_data_type(self, yang_s, data):
for node in data['data_type']:
xpath = str(node['xpath'])
expected = node['data_type']
expected_type = yang_s.str_to_type(expected)
data_type = yang_s.get_data_type(xpath)
assert expected_type == data_type

def test_get_leafref_type(self, yang_s, data):
for node in data['leafref_type']:
xpath = str(node['xpath'])
expected = node['data_type']
expected_type = yang_s.str_to_type(expected)
data_type = yang_s.get_leafref_type(xpath)
assert expected_type == data_type

def test_get_leafref_path(self, yang_s, data):
for node in data['leafref_path']:
xpath = str(node['xpath'])
expected_path = node['leafref_path']
path = yang_s.get_leafref_path(xpath)
assert expected_path == path

def test_get_leafref_type_schema(self, yang_s, data):
for node in data['leafref_type_schema']:
xpath = str(node['xpath'])
expected = node['data_type']
expected_type = yang_s.str_to_type(expected)
data_type = yang_s.get_leafref_type_schema(xpath)
assert expected_type == data_type

def test_xlate_rev_xlate(self):
# This Test is with Sonic YANG model, so create class from start
# read the config
Expand Down

0 comments on commit 04242e7

Please sign in to comment.