From b39f383007e01153e0dec8b4a2e83d91c82f83aa Mon Sep 17 00:00:00 2001 From: Al Bailey Date: Mon, 25 Feb 2019 14:08:09 -0600 Subject: [PATCH] Adding unit tests to tsconfig and clean it up a bit Adding simple unit tests to tsconfig. - test the behaviour when build.info is not present - test the behaviour when platform.conf is not present - test the behaviour when both files are found This works in py27 and py35. Coverage for tsconfig is 100% Added requirements.txt and test-requirements.txt Added a setup.cfg file so that the wheel can be built in universal mode (python 2 and 3) Properly set some of the setup.cfg variables. These unit tests are wired into zuul. Story: 2004515 Task: 29783 Change-Id: Ifb4f5403592ccc9223659bb188055ffeccc113b5 Signed-off-by: Al Bailey --- .gitignore | 1 + .zuul.yaml | 4 + tox.ini | 5 + tsconfig/tsconfig/.coveragerc | 7 + tsconfig/tsconfig/.stestr.conf | 2 + tsconfig/tsconfig/requirements.txt | 4 + tsconfig/tsconfig/setup.cfg | 25 +++ tsconfig/tsconfig/test-requirements.txt | 10 + tsconfig/tsconfig/tox.ini | 37 ++++ tsconfig/tsconfig/tsconfig/tests/__init__.py | 0 .../tsconfig/tsconfig/tests/test_basics.py | 197 ++++++++++++++++++ 11 files changed, 292 insertions(+) create mode 100644 tsconfig/tsconfig/.coveragerc create mode 100644 tsconfig/tsconfig/.stestr.conf create mode 100644 tsconfig/tsconfig/requirements.txt create mode 100644 tsconfig/tsconfig/setup.cfg create mode 100644 tsconfig/tsconfig/test-requirements.txt create mode 100644 tsconfig/tsconfig/tox.ini create mode 100644 tsconfig/tsconfig/tsconfig/tests/__init__.py create mode 100644 tsconfig/tsconfig/tsconfig/tests/test_basics.py diff --git a/.gitignore b/.gitignore index aa1b5ce4..68155890 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ .*.swp .coverage .installed.cfg +.stestr .testrepository .tox .venv diff --git a/.zuul.yaml b/.zuul.yaml index 6c0ce033..3b4f4bac 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -8,6 +8,8 @@ - build-openstack-releasenotes - openstack-tox-linters - openstack-tox-pep8 + - openstack-tox-py27 + - openstack-tox-py35 - stx-updates-pylint - stx-devstack-update: voting: false @@ -17,6 +19,8 @@ - build-openstack-releasenotes - openstack-tox-linters - openstack-tox-pep8 + - openstack-tox-py27 + - openstack-tox-py35 - stx-updates-pylint post: jobs: diff --git a/tox.ini b/tox.ini index 3cf5e33d..bef44614 100644 --- a/tox.ini +++ b/tox.ini @@ -98,16 +98,20 @@ basepython = python2.7 deps = {[testenv]deps} whitelist_externals = cp find + tox recreate = True commands = {[testenv]commands} + tox -c tsconfig/tsconfig -e py27 [testenv:py35] basepython = python3 deps = {[testenv]deps} whitelist_externals = cp find + tox recreate = True commands = {[testenv]commands} + tox -c tsconfig/tsconfig -e py35 [testenv:pylint] deps = {[testenv]deps} @@ -118,6 +122,7 @@ deps = {[testenv]deps} daemon keystoneauth1 keystonemiddleware + mock netaddr oslo_config pecan diff --git a/tsconfig/tsconfig/.coveragerc b/tsconfig/tsconfig/.coveragerc new file mode 100644 index 00000000..61c27b8f --- /dev/null +++ b/tsconfig/tsconfig/.coveragerc @@ -0,0 +1,7 @@ +[run] +branch = True +source = tsconfig +omit = tsconfig/tests/* + +[report] +ignore_errors = True diff --git a/tsconfig/tsconfig/.stestr.conf b/tsconfig/tsconfig/.stestr.conf new file mode 100644 index 00000000..9a845ee0 --- /dev/null +++ b/tsconfig/tsconfig/.stestr.conf @@ -0,0 +1,2 @@ +[DEFAULT] +test_path=tsconfig/tests diff --git a/tsconfig/tsconfig/requirements.txt b/tsconfig/tsconfig/requirements.txt new file mode 100644 index 00000000..2683dd48 --- /dev/null +++ b/tsconfig/tsconfig/requirements.txt @@ -0,0 +1,4 @@ +# The order of packages is significant, because pip processes them in the order +# of appearance. Changing the order has an impact on the overall integration +# process, which may cause wedges in the gate later. + diff --git a/tsconfig/tsconfig/setup.cfg b/tsconfig/tsconfig/setup.cfg new file mode 100644 index 00000000..dabef82b --- /dev/null +++ b/tsconfig/tsconfig/setup.cfg @@ -0,0 +1,25 @@ +[metadata] +license_files = LICENSE +name = tsconfig +classifier = + Environment :: OpenStack + Intended Audience :: Information Technology + Intended Audience :: System Administrators + License :: OSI Approved :: Apache Software License + Operating System :: POSIX :: Linux + Programming Language :: Python + Programming Language :: Python :: 2 + Programming Language :: Python :: 2.7 + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.5 + +[files] +packages = + tsconfig + +[nosetests] +cover-erase = true +verbosity = 2 + +[wheel] +universal = 1 diff --git a/tsconfig/tsconfig/test-requirements.txt b/tsconfig/tsconfig/test-requirements.txt new file mode 100644 index 00000000..56e48064 --- /dev/null +++ b/tsconfig/tsconfig/test-requirements.txt @@ -0,0 +1,10 @@ +# The order of packages is significant, because pip processes them in the order +# of appearance. Changing the order has an impact on the overall integration +# process, which may cause wedges in the gate later. + +hacking>=1.1.0 # Apache-2.0 + +coverage!=4.4,>=4.0 # Apache-2.0 +mock>=2.0.0 # BSD +stestr>=1.0.0 # Apache-2.0 +testtools>=2.2.0 # MIT diff --git a/tsconfig/tsconfig/tox.ini b/tsconfig/tsconfig/tox.ini new file mode 100644 index 00000000..abb70a06 --- /dev/null +++ b/tsconfig/tsconfig/tox.ini @@ -0,0 +1,37 @@ +[tox] +envlist = py27,py35,cover +minversion = 2.3.2 + +[testenv] +setenv = VIRTUAL_ENV={envdir} + PYTHONWARNINGS=default::DeprecationWarning + OS_STDOUT_CAPTURE=1 + OS_STDERR_CAPTURE=1 + OS_TEST_TIMEOUT=60 + OS_TEST_PATH=./tsconfig/tests +usedevelop = True +install_command = pip install {opts} {packages} + +deps = -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} + -r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt + +commands = + find . -name "*.pyc" -delete + stestr run {posargs} + stestr slowest + +whitelist_externals = find + sh + +[testenv:cover] +setenv = + PYTHON=coverage run --parallel-mode + PYTHONDONTWRITEBYTECODE=True +commands = coverage erase + find . -name "*.pyc" -delete + stestr run {posargs} + coverage combine + coverage html -d cover + coverage xml -o cover/coverage.xml + coverage report diff --git a/tsconfig/tsconfig/tsconfig/tests/__init__.py b/tsconfig/tsconfig/tsconfig/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tsconfig/tsconfig/tsconfig/tests/test_basics.py b/tsconfig/tsconfig/tsconfig/tests/test_basics.py new file mode 100644 index 00000000..e79b0ffe --- /dev/null +++ b/tsconfig/tsconfig/tsconfig/tests/test_basics.py @@ -0,0 +1,197 @@ +# +# SPDX-License-Identifier: Apache-2.0 +# + +import io +import mock +import six # pylint: disable=unused-import +import sys +import testtools + + +class TsConfigTestCase(testtools.TestCase): + + mock_19_01_build = u""" +### +### StarlingX +### Release 19.01 +### + +OS="centos" +SW_VERSION="19.01" +BUILD_TARGET="Host Installer" +BUILD_TYPE="Formal" +BUILD_ID="f/stein" + +JOB="STX_build_stein_master" +BUILD_BY="starlingx.build@cengn.ca" +BUILD_NUMBER="52" +BUILD_HOST="starlingx_mirror" +BUILD_DATE="2019-02-22 19:18:29 +0000" +""" + + mock_malformed_build = u""" +### +### StarlingX +### Release 19.01 +nodetype= +""" + + mock_platform_conf_empty = u"" + + # Note: subfunction list cannot contain spaces + mock_platform_conf_minimal = u""" +nodetype=something +subfunction= subfunction1,subfunction2 +""" + + mock_platform_conf = u""" +nodetype=controller +subfunction=controller +system_type=Standard +security_profile=extended +management_interface=enp10s0f1 +http_port=8080 +INSTALL_UUID=ab0a5348-cea7-4b08-b1b0-09d5527dd227 +UUID=a1c581fc-0c74-4e68-b78e-4e26a0695f5d +oam_interface=enp0s3 +infrastructure_interface=enp0s4 +sdn_enabled=no +region_config=no +system_mode=duplex +sw_version=19.01 +security_feature="nopti nospectre_v2" +vswitch_type=ovs-dpdk +""" + + mock_platform_conf_regions = u""" +nodetype=controller +subfunction=controller +system_type=Standard +security_profile=extended +management_interface=enp10s0f1 +http_port=8081 +INSTALL_UUID=ab0a5348-cea7-4b08-b1b0-09d5527dd227 +UUID=a1c581fc-0c74-4e68-b78e-4e26a0695f5d +oam_interface=enp0s3 +infrastructure_interface=enp0s4 +sdn_enabled=no +region_config=no +region_1_name=Region1 +region_2_name=Region2 +distributed_cloud_role=CloudRole +system_mode=duplex +sw_version=19.01 +security_feature="nopti nospectre_v2" +vswitch_type=ovs-dpdk +""" + + def tearDown(self): + super(TsConfigTestCase, self).tearDown() + # These are import tests so unimport tsconfig and tsconfig.tsconfig + # during teardown, otherwise all the other tests will fail + try: + del sys.modules['tsconfig.tsconfig'] + del sys.modules['tsconfig'] + except KeyError: + print('tsconfig modules failed to import, so no cleanup required') + + # If the build.info file is missing, a special version is returned + def test_tconfig_missing_build_info(self): + from tsconfig import tsconfig + ver = tsconfig.SW_VERSION # pylint: disable=no-member + self.assertEqual(ver, "TEST.SW.VERSION") + + # If build info is malformed, the platform.conf is not loaded + @mock.patch('logging.exception') + @mock.patch('six.moves.builtins.open') + @mock.patch('os.path.isfile', return_value=True) + def test_tsconfig_missing_version(self, + mock_isfile, + mock_open, + mock_logging_exception): + # two files are opened by tsconfig. + # 1st: /etc/build.info + # 2nd: /etc/platform/platform.conf + mock_open.return_value = io.StringIO(self.mock_malformed_build) + from tsconfig import tsconfig + mock_logging_exception.assert_called_once() + + # This tests the behaviour when the platform.conf is missing + @mock.patch('logging.exception') + @mock.patch('six.moves.builtins.open') + @mock.patch('os.path.isfile', return_value=True) + def test_tsconfig_missing_platform_conf(self, + mock_isfile, + mock_open, + mock_logging_exception): + # two files are opened by tsconfig. + # 1st: /etc/build.info + # 2nd: /etc/platform/platform.conf + mock_open.return_value = io.StringIO(self.mock_19_01_build) + from tsconfig import tsconfig + mock_logging_exception.assert_called_once() + + # This tests the behaviour when the platform.conf is empty + @mock.patch('logging.exception') + @mock.patch('six.moves.builtins.open') + @mock.patch('os.path.isfile', return_value=True) + def test_tsconfig_empty(self, + mock_isfile, + mock_open, + mock_logging_exception): + # two files are opened by tsconfig. + # 1st: /etc/build.info + # 2nd: /etc/platform/platform.conf + mock_open.side_effect = [io.StringIO(self.mock_19_01_build), + io.StringIO(self.mock_platform_conf_empty)] + from tsconfig import tsconfig + mock_logging_exception.assert_called_once() + + # This tests the behaviour when the platform.conf has the minimal entries + @mock.patch('six.moves.builtins.open') + @mock.patch('os.path.isfile', return_value=True) + def test_tsconfig_minimal(self, mock_isfile, mock_open): + # two files are opened by tsconfig. + # 1st: /etc/build.info + # 2nd: /etc/platform/platform.conf + mock_open.side_effect = [io.StringIO(self.mock_19_01_build), + io.StringIO(self.mock_platform_conf_minimal)] + from tsconfig import tsconfig + val = tsconfig.nodetype + self.assertEqual(val, "something") + val = tsconfig.subfunctions + self.assertEqual(set(val), set(["subfunction1", "subfunction2"])) + + @mock.patch('six.moves.builtins.open') + @mock.patch('os.path.isfile', return_value=True) + def test_tsconfig(self, mock_isfile, mock_open): + # two files are opened by tsconfig. + # 1st: /etc/build.info + # 2nd: /etc/platform/platform.conf + mock_open.side_effect = [io.StringIO(self.mock_19_01_build), + io.StringIO(self.mock_platform_conf)] + from tsconfig import tsconfig + ver = tsconfig.SW_VERSION + self.assertEqual(ver, "19.01") + + @mock.patch('six.moves.builtins.open') + @mock.patch('os.path.isfile', return_value=True) + def test_tsconfig_reload(self, mock_isfile, mock_open): + # two files are opened by tsconfig. + # 1st: /etc/build.info + # 2nd: /etc/platform/platform.conf + # Next two files are loaded as part of reload + mock_open.side_effect = [io.StringIO(self.mock_19_01_build), + io.StringIO(self.mock_platform_conf), + io.StringIO(self.mock_19_01_build), + io.StringIO(self.mock_platform_conf_regions)] + from tsconfig import tsconfig + # Initial platform.conf has no region names + # reload will set the region 1 and region 2 names + self.assertIsNone(tsconfig.region_1_name) + self.assertIsNone(tsconfig.region_2_name) + # the platform.conf is changed, call load again to see the change + tsconfig._load() # pylint: disable=protected-access + self.assertIsNotNone(tsconfig.region_1_name) + self.assertIsNotNone(tsconfig.region_2_name)