Skip to content

Commit e8ac86d

Browse files
committed
sonic-yang-models: Port code to new libyang-py3
1 parent 2a99ff6 commit e8ac86d

File tree

2 files changed

+59
-30
lines changed

2 files changed

+59
-30
lines changed

src/sonic-yang-models/tests/yang_model_pytests/conftest.py

+13-12
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,38 @@
11
import os
22
import pytest
3-
import yang as ly
3+
import libyang as ly
44
from json import dumps
55
from glob import glob
66

7-
87
class YangModel:
98

109
def __init__(self) -> None:
1110
cur_dir = os.path.dirname(os.path.abspath(__file__))
1211
project_root = os.path.abspath(os.path.join(cur_dir, '..', '..'))
1312
self.model_dir = os.path.join(project_root, 'yang-models')
14-
1513
self._load_model()
1614

15+
def __del__(self) -> None:
16+
self.ctx.destroy()
17+
self.ctx = None
18+
1719
def _load_model(self) -> None:
18-
self.ctx = ly.Context(self.model_dir)
20+
self.ctx = ly.Context(self.model_dir, loose_json_datatypes=True)
1921
yang_files = glob(self.model_dir +"/*.yang")
20-
2122
for file in yang_files:
22-
m = self.ctx.parse_module_path(file, ly.LYS_IN_YANG)
23-
if not m:
24-
raise RuntimeError("Failed to parse '{file}' model")
23+
with open(file, 'r') as f:
24+
m = self.ctx.parse_module_file(f, "yang")
25+
if not m:
26+
raise RuntimeError("Failed to parse '{file}' model")
2527

2628
def _load_data(self, data) -> None:
27-
self.ctx.parse_data_mem(dumps(data), ly.LYD_JSON,
28-
ly.LYD_OPT_CONFIG | ly.LYD_OPT_STRICT)
29+
dnode = self.ctx.parse_data_mem(dumps(data), "json", strict=True, no_state=True)
30+
dnode.free()
2931

3032
def load_data(self, data, expected_error=None) -> None:
3133
if expected_error:
32-
with pytest.raises(RuntimeError) as exc_info:
34+
with pytest.raises(Exception) as exc_info:
3335
self._load_data(data)
34-
3536
assert expected_error in str(exc_info)
3637
else:
3738
self._load_data(data)

src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py

+46-18
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
# This script is used to
22

3-
import yang as ly
3+
import libyang as ly
44
import logging
55
import argparse
66
import sys
77
import ijson
88
import json
9+
import pytest
910
#import sonic_yang as sy
1011
from glob import glob
1112
from os import listdir
@@ -63,6 +64,7 @@ def initTest(self):
6364
}
6465

6566
self.ExceptionTests = { }
67+
self.FailedTests = []
6668

6769
for test_file in glob("./tests/yang_model_tests/tests/*.json"):
6870
try:
@@ -116,17 +118,18 @@ def loadYangModel(self, yangDir):
116118

117119
try:
118120
# create context
119-
self.ctx = ly.Context(yangDir)
121+
self.ctx = ly.Context(yangDir, loose_json_datatypes=True)
120122
# get all files
121123
yangFiles = glob(yangDir +"/*.yang")
122124
# load yang modules
123125
for file in yangFiles:
124126
log.debug(file)
125-
m = self.ctx.parse_module_path(file, ly.LYS_IN_YANG)
126-
if m is not None:
127-
log.info("module: {} is loaded successfully".format(m.name()))
128-
else:
129-
log.info("Could not load module: {}".format(file))
127+
with open(file, 'r') as f:
128+
m = self.ctx.parse_module_file(f, "yang")
129+
if m is not None:
130+
log.info("module: {} is loaded successfully".format(m.name()))
131+
else:
132+
log.info("Could not load module: {}".format(file))
130133

131134
except Exception as e:
132135
printExceptionDetails()
@@ -178,26 +181,35 @@ def logStartTest(self, desc):
178181
"""
179182
def loadConfigData(self, jInput, verify=None):
180183
s = ""
184+
node = None
185+
try:
186+
node = self.ctx.parse_data_mem(jInput, "json", strict=True, no_state=True)
187+
except Exception as e:
188+
printExceptionDetails()
189+
s = str(e)
190+
log.info(s)
191+
return s
192+
181193
try:
182-
node = self.ctx.parse_data_mem(jInput, ly.LYD_JSON, \
183-
ly.LYD_OPT_CONFIG | ly.LYD_OPT_STRICT)
184194
# verify the data tree if asked
185195
if verify is not None:
186196
xpath = verify['xpath']
187197
log.info("Verify xpath: {}".format(xpath))
188-
set = node.find_path(xpath)
189-
for dnode in set.data():
198+
nodes = node.find_all(xpath)
199+
for dnode in nodes:
190200
if (xpath == dnode.path()):
191201
log.info("Verify dnode: {}".format(dnode.path()))
192-
data = dnode.print_mem(ly.LYD_JSON, ly.LYP_WITHSIBLINGS \
193-
| ly.LYP_FORMAT | ly.LYP_WD_ALL)
202+
data = dnode.print_mem("json", with_siblings=True, pretty=True, include_implicit_defaults=True)
194203
data = json.loads(data)
195-
log.info("Verify data: {}".format(data))
204+
log.info("Verify path value {} is {} in {}".format(verify['key'], verify['value'], data))
205+
assert (verify['key'] in data)
196206
assert (data[verify['key']] == verify['value'])
197207
s = 'verified'
198208
except Exception as e:
199-
s = str(e)
200-
log.info(s)
209+
printExceptionDetails()
210+
211+
node.free()
212+
201213
return s
202214

203215
"""
@@ -221,9 +233,12 @@ def runExceptionTest(self, test):
221233
log.info(desc + " Passed\n")
222234
return PASS
223235
else:
224-
raise Exception("Mismatch {} and {}".format(eStr, s))
236+
errstr = "{}: Mismatch {} and {}".format(test, eStr, s)
237+
self.FailedTests.append(errstr)
238+
raise Exception(errstr)
225239
except Exception as e:
226240
printExceptionDetails()
241+
227242
log.info(desc + " Failed\n")
228243
return FAIL
229244

@@ -253,7 +268,9 @@ def runVlanSpecialTest(self, test):
253268
log.debug(jInput)
254269
s = self.loadConfigData(json.dumps(jInput))
255270
if s!="":
256-
raise Exception("{} in not empty".format(s))
271+
errstr="{}[{}]: {} in not empty".format(test,i,s)
272+
self.FailedTests.append(errstr)
273+
raise Exception(errstr)
257274
return PASS
258275
except Exception as e:
259276
printExceptionDetails()
@@ -282,6 +299,17 @@ def test_run_tests(self):
282299
ret = FAIL * len(self.tests)
283300
printExceptionDetails()
284301

302+
if len(self.FailedTests):
303+
print("{} Failures:".format(len(self.FailedTests)))
304+
log.error("{} Failures:".format(len(self.FailedTests)))
305+
for x in self.FailedTests:
306+
print(x)
307+
log.error(x)
308+
309+
if self.ctx:
310+
self.ctx.destroy()
311+
self.ctx = None
312+
285313
assert ret == 0
286314
return
287315
# End of Class

0 commit comments

Comments
 (0)