diff --git a/sonic-slave/Dockerfile b/sonic-slave/Dockerfile index f1d68c680cb8..b97d08a4399e 100644 --- a/sonic-slave/Dockerfile +++ b/sonic-slave/Dockerfile @@ -89,6 +89,9 @@ RUN apt-get update && apt-get install -y libmysqlclient-dev libmysqld-dev libper # For mpdecimal RUN apt-get update && apt-get install -y docutils-common libjs-sphinxdoc libjs-underscore python-docutils python-jinja2 python-markupsafe python-pygments python-roman python-sphinx sphinx-common python3-sphinx +# For sonic config engine testing +RUN apt-get install -y python-lxml python-jinja2 python-netaddr python-ipaddr python-yaml + # For templating RUN pip install j2cli diff --git a/src/sonic-config-engine/MANIFEST.in b/src/sonic-config-engine/MANIFEST.in index a98b68c2a5bb..c228a249adfb 100644 --- a/src/sonic-config-engine/MANIFEST.in +++ b/src/sonic-config-engine/MANIFEST.in @@ -1 +1,2 @@ recursive-include platform *.json *.ini *.conf +recursive-include tests *.j2 *.yml *.xml diff --git a/src/sonic-config-engine/setup.py b/src/sonic-config-engine/setup.py index 37c61b84ae5f..1a0cae5882fb 100644 --- a/src/sonic-config-engine/setup.py +++ b/src/sonic-config-engine/setup.py @@ -2,6 +2,7 @@ from setuptools import setup import os.path +import unittest def get_platform_file_list(): data_files = [] @@ -15,6 +16,11 @@ def get_platform_file_list(): data_files.append( (os.path.join('/usr/share/sonic', platform), files) ) return data_files +def get_test_suite(): + test_loader = unittest.TestLoader() + test_suite = test_loader.discover('tests', pattern='*.py') + return test_suite + setup(name='sonic-config-engine', version='1.0', description='Utilities for generating SONiC configuration files', @@ -25,4 +31,5 @@ def get_platform_file_list(): scripts=['sonic-cfggen'], data_files=get_platform_file_list(), install_requires=['lxml', 'jinja2', 'netaddr', 'ipaddr', 'pyyaml'], + test_suite='setup.get_test_suite', ) diff --git a/src/sonic-config-engine/tests/__init__.py b/src/sonic-config-engine/tests/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/sonic-config-engine/tests/sample_graph.xml b/src/sonic-config-engine/tests/sample_graph.xml new file mode 100644 index 000000000000..47efabf7d81c --- /dev/null +++ b/src/sonic-config-engine/tests/sample_graph.xml @@ -0,0 +1,129 @@ + + + + + + OCPSCH0104001MS + 10.10.1.14 + OCPSCH01040DDLF + 10.10.1.13 + 1 + 10 + 3 + + + OCPSCH0104002MS + 10.10.2.14 + OCPSCH01040DDLF + 10.10.2.13 + 1 + 10 + 3 + + + + + 64536 + OCPSCH01040DDLF + + +
10.10.1.14
+ + +
+ +
10.10.2.14
+ + +
+
+ +
+ + 64542 + OCPSCH0104001MS + + + + 64543 + OCPSCH0104002MS + + +
+
+ + + + + + HostIP + Loopback0 + + 100.0.0.6/32 + + 100.0.0.6/32 + + + + + ManagementIP1 + Management0 + + 192.168.200.15/24 + + 192.168.200.15/24 + + + + + + OCPSCH01040DDLF + + + + + + Ethernet0 + 10.10.1.13/30 + + + + Ethernet1 + 10.10.2.13/30 + + + + + + + + + + + + 40000 + DeviceInterfaceLink + OCPSCH01040DDLF + Ethernet0 + OCPSCH0104012MS + Ethernet12 + + + 40000 + DeviceInterfaceLink + OCPCH01040DDLF + Ethernet1 + OCPSCH0104002MS + Ethernet12 + + + + + OCPSCH01040DDLF + Force10-Z9100 + + + + OCPSCH01040DDLF + Force10-Z9100 +
diff --git a/src/sonic-config-engine/tests/test.j2 b/src/sonic-config-engine/tests/test.j2 new file mode 100644 index 000000000000..787a1f0a2c41 --- /dev/null +++ b/src/sonic-config-engine/tests/test.j2 @@ -0,0 +1,3 @@ +{% for item in yml_item -%} +{{ item }} +{% endfor %} diff --git a/src/sonic-config-engine/tests/test.yml b/src/sonic-config-engine/tests/test.yml new file mode 100644 index 000000000000..dc08eb66bed1 --- /dev/null +++ b/src/sonic-config-engine/tests/test.yml @@ -0,0 +1,3 @@ +yml_item: + - value1 + - value2 diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py new file mode 100644 index 000000000000..894f069c1ef8 --- /dev/null +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -0,0 +1,61 @@ +from unittest import TestCase +import subprocess +import os + +class TestCfgGen(TestCase): + + def setUp(self): + self.test_dir = os.path.dirname(os.path.realpath(__file__)) + self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.sample_graph = os.path.join(self.test_dir, 'sample_graph.xml') + + def run_script(self, argument): + print '\n Running sonic-cfggen ' + argument + output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + linecount = output.strip().count('\n') + if linecount <= 0: + print ' Output: ' + output.strip() + else: + print ' Output: ({0} lines, {1} bytes)'.format(linecount + 1, len(output)) + return output + + def test_dummy_run(self): + argument = '' + output = self.run_script(argument) + self.assertEqual(output, '') + + def test_minigraph_sku(self): + argument = '-v minigraph_hwsku -m "' + self.sample_graph + '"' + output = self.run_script(argument) + self.assertEqual(output.strip(), 'Force10-Z9100') + + def test_print_data(self): + argument = '-m "' + self.sample_graph + '" --print-data' + output = self.run_script(argument) + self.assertTrue(len(output.strip()) > 0) + + def test_jinja_expression(self): + argument = '-m "' + self.sample_graph + '" -v "minigraph_devices[minigraph_hostname][\'type\']"' + output = self.run_script(argument) + self.assertEqual(output.strip(), 'LeafRouter') + + def test_print_alias_mapping(self): + argument = '-s' + output = self.run_script(argument) + self.assertTrue(len(output.strip()) > 0) + + def test_additional_json_data(self): + argument = '-a \'{"key1":"value1"}\' -v key1' + output = self.run_script(argument) + self.assertEqual(output.strip(), 'value1') + + def test_read_yaml(self): + argument = '-v yml_item -y ' + os.path.join(self.test_dir, 'test.yml') + output = self.run_script(argument) + self.assertEqual(output.strip(), '[\'value1\', \'value2\']') + + def test_render_template(self): + argument = '-y ' + os.path.join(self.test_dir, 'test.yml') + ' -t' + os.path.join(self.test_dir, 'test.j2') + output = self.run_script(argument) + self.assertEqual(output.strip(), 'value1\nvalue2') +