[sonic-cfggen]: Update UT to run yang validation (#9700)
Why I did it Config db schema generated by minigraph should run yang validation. How I did it Modify run_script to add yang validation. How to verify it Run sonic-config-engine unit test. Signed-off-by: Gang Lv ganglv@microsoft.com
This commit is contained in:
parent
3567888b03
commit
1db50e54c8
@ -3,10 +3,14 @@ import filecmp
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import subprocess
|
||||
import argparse
|
||||
import shlex
|
||||
|
||||
PY3x = sys.version_info >= (3, 0)
|
||||
PYvX_DIR = "py3" if PY3x else "py2"
|
||||
PYTHON_INTERPRETTER = "python3" if PY3x else "python2"
|
||||
YANG_MODELS_DIR = "/usr/local/yang-models"
|
||||
|
||||
def tuple_to_str(tuplestr):
|
||||
""" Convert Python tuple '('elem1', 'elem2')' representation into string on the for "elem1|elem2" """
|
||||
@ -33,6 +37,52 @@ def liststr_to_dict(liststr):
|
||||
|
||||
return list_obj
|
||||
|
||||
class YangWrapper(object):
|
||||
def __init__(self, path=YANG_MODELS_DIR):
|
||||
"""
|
||||
sonic_yang only supports python3
|
||||
"""
|
||||
if PY3x:
|
||||
import sonic_yang
|
||||
self.yang_parser = sonic_yang.SonicYang(path)
|
||||
self.yang_parser.loadYangModel()
|
||||
self.test_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
self.script_file = PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen')
|
||||
|
||||
def validate(self, argument):
|
||||
"""
|
||||
Raise exception when yang validation failed
|
||||
"""
|
||||
if PY3x and "-m" in argument:
|
||||
import sonic_yang
|
||||
parser=argparse.ArgumentParser(description="Render configuration file from minigraph data and jinja2 template.")
|
||||
parser.add_argument("-m", "--minigraph", help="minigraph xml file", nargs='?', const='/etc/sonic/minigraph.xml')
|
||||
parser.add_argument("-k", "--hwsku", help="HwSKU")
|
||||
parser.add_argument("-n", "--namespace", help="namespace name", nargs='?', const=None, default=None)
|
||||
parser.add_argument("-p", "--port-config", help="port config file, used with -m or -k", nargs='?', const=None)
|
||||
parser.add_argument("-S", "--hwsku-config", help="hwsku config file, used with -p and -m or -k", nargs='?', const=None)
|
||||
args, unknown = parser.parse_known_args(shlex.split(argument))
|
||||
|
||||
print('\n Validating yang schema')
|
||||
cmd = self.script_file + ' -m ' + args.minigraph
|
||||
if args.hwsku is not None:
|
||||
cmd += ' -k ' + args.hwsku
|
||||
if args.hwsku_config is not None:
|
||||
cmd += ' -S ' + args.hwsku_config
|
||||
if args.port_config is not None:
|
||||
cmd += ' -p ' + args.port_config
|
||||
if args.namespace is not None:
|
||||
cmd += ' -n ' + args.namespace
|
||||
cmd += ' --print-data'
|
||||
output = subprocess.check_output(cmd, shell=True).decode()
|
||||
try:
|
||||
self.yang_parser.loadData(configdbJson=json.loads(output))
|
||||
self.yang_parser.validate_data_tree()
|
||||
except sonic_yang.SonicYangException as e:
|
||||
print("yang data generated from %s is not valid: %s"%(args.minigraph, str(e)))
|
||||
return False
|
||||
return True
|
||||
|
||||
def cmp(file1, file2):
|
||||
""" compare files """
|
||||
try:
|
||||
@ -43,4 +93,3 @@ def cmp(file1, file2):
|
||||
return obj1 == obj2
|
||||
except:
|
||||
return filecmp.cmp(file1, file2)
|
||||
|
||||
|
@ -14,6 +14,7 @@ BACKEND_LEAF_ROUTER = 'BackEndLeafRouter'
|
||||
class TestCfgGen(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.yang = utils.YangWrapper()
|
||||
self.test_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen')
|
||||
self.sample_graph = os.path.join(self.test_dir, 'sample_graph.xml')
|
||||
@ -50,6 +51,8 @@ class TestCfgGen(TestCase):
|
||||
|
||||
def run_script(self, argument, check_stderr=False, verbose=False):
|
||||
print('\n Running sonic-cfggen ' + argument)
|
||||
self.assertTrue(self.yang.validate(argument))
|
||||
|
||||
if check_stderr:
|
||||
output = subprocess.check_output(self.script_file + ' ' + argument, stderr=subprocess.STDOUT, shell=True)
|
||||
else:
|
||||
|
@ -14,6 +14,7 @@ BMC_MGMT_TOR_ROUTER = 'BmcMgmtToRRouter'
|
||||
class TestCfgGenCaseInsensitive(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.yang = utils.YangWrapper()
|
||||
self.test_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen')
|
||||
self.sample_graph = os.path.join(self.test_dir, 'simple-sample-graph-case.xml')
|
||||
@ -24,6 +25,8 @@ class TestCfgGenCaseInsensitive(TestCase):
|
||||
|
||||
def run_script(self, argument, check_stderr=False):
|
||||
print('\n Running sonic-cfggen ' + argument)
|
||||
self.assertTrue(self.yang.validate(argument))
|
||||
|
||||
if check_stderr:
|
||||
output = subprocess.check_output(self.script_file + ' ' + argument, stderr=subprocess.STDOUT, shell=True)
|
||||
else:
|
||||
|
@ -20,6 +20,7 @@ DEVICE_TYPE = 'LeafRouter'
|
||||
class TestMultiNpuCfgGen(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.yang = utils.YangWrapper()
|
||||
self.test_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
self.test_data_dir = os.path.join(self.test_dir, 'multi_npu_data')
|
||||
self.script_file = utils.PYTHON_INTERPRETTER + ' ' + os.path.join(self.test_dir, '..', 'sonic-cfggen')
|
||||
@ -34,6 +35,8 @@ class TestMultiNpuCfgGen(TestCase):
|
||||
|
||||
def run_script(self, argument, check_stderr=False):
|
||||
print('\n Running sonic-cfggen ' + argument)
|
||||
self.assertTrue(self.yang.validate(argument))
|
||||
|
||||
if check_stderr:
|
||||
output = subprocess.check_output(self.script_file + ' ' + argument, stderr=subprocess.STDOUT, shell=True)
|
||||
else:
|
||||
|
Loading…
Reference in New Issue
Block a user