From 1825ec220b7ec717faf07fb182d9f7424a1679a9 Mon Sep 17 00:00:00 2001 From: Corey Bryant Date: Thu, 15 Jun 2023 14:40:15 +0000 Subject: [PATCH 1/8] Add overlay_ppa to tests_options (cherry picked from commit 0c07920ad8e113bfe0ca3dfd6dd8df1f53c58d4d) --- zaza/charm_lifecycle/utils.py | 29 +++++++++++++++++++++++++++++ zaza/utilities/deployment_env.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/zaza/charm_lifecycle/utils.py b/zaza/charm_lifecycle/utils.py index 74903570c..c58ae6f07 100644 --- a/zaza/charm_lifecycle/utils.py +++ b/zaza/charm_lifecycle/utils.py @@ -498,6 +498,35 @@ def is_config_deploy_trusted_for_bundle( return False +def get_overlay_ppa(yaml_file=None, fatal=True): + """Get overlay_ppa from tests_options. + + In the config file for the tests, the tests_options.overlay_ppa option + may be used to specify a PPA that will be enabled for all units in + the model. + + The tests_options section needs to look like: + + tests_options: + overlay_ppa: ppa:ubuntu-security-proposed/ppa + + :param yaml_file: the YAML file that contains the tests specification + :type yaml_file: Optional[str] + :param fatal: whether any errors cause an exception or are just logged. + :type fatal: bool + :returns: overlay PPA name + :rtype: str + :raises: OSError if the YAML file doesn't exist and fatal=True + """ + config = get_charm_config(yaml_file, fatal) + try: + return config['tests_options']['overlay_ppa'] + # Type error is if the force_deploy is present, but with no value + except (KeyError, TypeError): + pass + return None + + def get_class(class_str): """Get the class represented by the given string. diff --git a/zaza/utilities/deployment_env.py b/zaza/utilities/deployment_env.py index 543051c33..3a32d9c51 100644 --- a/zaza/utilities/deployment_env.py +++ b/zaza/utilities/deployment_env.py @@ -20,6 +20,7 @@ import yaml import zaza.model +import zaza.charm_lifecycle.utils as utils ZAZA_SETUP_FILE_LOCATIONS = [ '{home}/.zaza.yaml'] @@ -83,6 +84,27 @@ def parse_option_list_string(option_list, delimiter=None): settings[key.strip()] = value.strip() return settings +def get_cloudinit_userdata(): + """Return cloudinit_userdata based on tests_options config. + + :returns: YAML-formatted string of cloudinit_userdata + :rtype: str + """ + cloudinit_userdata = None + overlay_ppa = utils.get_overlay_ppa() + if overlay_ppa: + cloud_config = { + "apt": { + "sources": { + "overlay-ppa": { + "source": overlay_ppa + } + } + } + } + cloudinit_userdata = "#cloud-config\n{}".format( + yaml.safe_dump(cloud_config)) + return cloudinit_userdata def get_model_settings(): """Return model settings from defaults, config file and env variables. @@ -94,6 +116,12 @@ def get_model_settings(): model_settings.update(get_setup_file_section(MODEL_SETTINGS_SECTION)) env_settings = os.environ.get('MODEL_SETTINGS', '') test_env_settings = os.environ.get('TEST_MODEL_SETTINGS', '') + cloudinit_userdata = get_cloudinit_userdata() + if cloudinit_userdata: + if 'cloudinit-userdata' in test_env_settings: + logging.warn('TEST_MODEL_SETTINGS contains cloudinit-userdata ' + 'which overrides tests_options overlay_ppa') + model_settings.update({'cloudinit-userdata': cloudinit_userdata}) model_settings.update( parse_option_list_string(test_env_settings or env_settings)) if env_settings: From c64f40983edf55995b33f4977faec5ed8902430b Mon Sep 17 00:00:00 2001 From: Corey Bryant Date: Thu, 15 Jun 2023 16:31:43 +0000 Subject: [PATCH 2/8] Updates to overlay_ppa * Rename overlay_ppa to overlay_ppas and it now accepts a list of PPAs. * get_overlay_ppas() is moved to deployment_env.py because it introduced a circular import when it lived in utils.py. * Updated to use the zaza global_options feature. * Unit tests are added. (cherry picked from commit 9cc938af1135f20e6fabf9796dffa3e15ed59962) --- unit_tests/utilities/test_deployment_env.py | 106 +++++++++++++++----- zaza/charm_lifecycle/utils.py | 29 ------ zaza/utilities/deployment_env.py | 49 +++++++-- 3 files changed, 121 insertions(+), 63 deletions(-) diff --git a/unit_tests/utilities/test_deployment_env.py b/unit_tests/utilities/test_deployment_env.py index 65ecf0a9e..69c987d7b 100644 --- a/unit_tests/utilities/test_deployment_env.py +++ b/unit_tests/utilities/test_deployment_env.py @@ -12,11 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. +import collections import copy import mock import yaml import zaza.utilities.deployment_env as deployment_env +import zaza.utilities.ro_types as ro_types import unit_tests.utils as ut_utils @@ -52,40 +54,98 @@ def test_parse_option_list_string_whitespace(self): 'test-mode': 'false', 'image-stream': 'released'}) + def test_get_overlay_ppas(self): + with mock.patch('zaza.global_options.get_options') as get_options_mock: + config = collections.OrderedDict({'overlay_ppas': + ['ppa:ppa1', 'ppa:ppa2']}) + get_options_mock.return_value = ro_types.resolve_immutable(config) + self.assertEqual(deployment_env.get_overlay_ppas(), + ro_types.ReadOnlyList(['ppa:ppa1', 'ppa:ppa2'])) + + config = collections.OrderedDict({'force_deploy': 'x-y'}) + get_options_mock.return_value = ro_types.resolve_immutable(config) + self.assertEqual(deployment_env.get_overlay_ppas(), None) + + def test_get_cloudinit_userdata(self): + with mock.patch.object(deployment_env, 'get_overlay_ppas', + return_value=['ppa:ppa0', 'ppa:ppa1']): + cloud_config = { + 'apt': { + 'sources': { + 'overlay-ppa-0': { + 'source': 'ppa:ppa0' + }, + 'overlay-ppa-1': { + 'source': 'ppa:ppa1' + } + } + } + } + cloudinit_userdata = "#cloud-config\n{}".format( + yaml.safe_dump(cloud_config)) + self.assertEqual( + deployment_env.get_cloudinit_userdata(), + cloudinit_userdata) + def base_get_model_settings(self, env, expect): with mock.patch.dict(deployment_env.os.environ, env): self.assertEqual(deployment_env.get_model_settings(), expect) def test_get_model_settings_no_config(self): - self.base_get_model_settings({}, self.MODEL_CONFIG_DEFAULTS) + with mock.patch.object(deployment_env, 'get_cloudinit_userdata', + return_value=None): + self.base_get_model_settings({}, self.MODEL_CONFIG_DEFAULTS) def test_get_model_settings_multiple_values_override(self): - expect_config = copy.deepcopy(self.MODEL_CONFIG_DEFAULTS) - expect_config.update({'test-mode': 'false'}) - self.base_get_model_settings( - {'TEST_MODEL_SETTINGS': 'test-mode=false'}, - expect_config) + with mock.patch.object(deployment_env, 'get_cloudinit_userdata', + return_value=None): + expect_config = copy.deepcopy(self.MODEL_CONFIG_DEFAULTS) + expect_config.update({'test-mode': 'false'}) + self.base_get_model_settings( + {'TEST_MODEL_SETTINGS': 'test-mode=false'}, + expect_config) def test_get_model_settings_file_override(self): - expect_config = copy.deepcopy(self.MODEL_CONFIG_DEFAULTS) - expect_config.update({'default-series': 'file-setting'}) - self.patch_object( - deployment_env, - 'get_setup_file_section', - return_value={'default-series': 'file-setting'}) - self.base_get_model_settings({}, expect_config) + with mock.patch.object(deployment_env, 'get_cloudinit_userdata', + return_value=None): + expect_config = copy.deepcopy(self.MODEL_CONFIG_DEFAULTS) + expect_config.update({'default-series': 'file-setting'}) + self.patch_object( + deployment_env, + 'get_setup_file_section', + return_value={'default-series': 'file-setting'}) + self.base_get_model_settings({}, expect_config) def test_get_model_settings_file_override_env_override(self): - # Check that env variables override defaults and file - expect_config = copy.deepcopy(self.MODEL_CONFIG_DEFAULTS) - expect_config.update({'default-series': 'env-setting'}) - self.patch_object( - deployment_env, - 'get_setup_file_section', - return_value={'default-series': 'file-setting'}) - self.base_get_model_settings( - {'TEST_MODEL_SETTINGS': 'default-series=env-setting'}, - expect_config) + with mock.patch.object(deployment_env, 'get_cloudinit_userdata', + return_value=None): + # Check that env variables override defaults and file + expect_config = copy.deepcopy(self.MODEL_CONFIG_DEFAULTS) + expect_config.update({'default-series': 'env-setting'}) + self.patch_object( + deployment_env, + 'get_setup_file_section', + return_value={'default-series': 'file-setting'}) + self.base_get_model_settings( + {'TEST_MODEL_SETTINGS': 'default-series=env-setting'}, + expect_config) + + def test_get_model_settings_cloudinit_userdata(self): + with mock.patch.object(deployment_env, 'get_cloudinit_userdata', + return_value='x'): + expect_config = copy.deepcopy(self.MODEL_CONFIG_DEFAULTS) + expect_config.update({'cloudinit-userdata': 'x'}) + self.base_get_model_settings({}, expect_config) + + with mock.patch.object(deployment_env.logging, 'warn') as warn: + with mock.patch.dict(deployment_env.os.environ, + {'TEST_MODEL_SETTINGS': + "cloudinit-userdata=y"}): + expect_config.update({'cloudinit-userdata': 'y'}) + self.base_get_model_settings({}, expect_config) + warn.assert_called_once_with( + 'TEST_MODEL_SETTINGS contains cloudinit-userdata ' + 'which overrides tests_options overlay_ppas') def base_get_model_constraints(self, env, expect): with mock.patch.dict(deployment_env.os.environ, env): diff --git a/zaza/charm_lifecycle/utils.py b/zaza/charm_lifecycle/utils.py index c58ae6f07..74903570c 100644 --- a/zaza/charm_lifecycle/utils.py +++ b/zaza/charm_lifecycle/utils.py @@ -498,35 +498,6 @@ def is_config_deploy_trusted_for_bundle( return False -def get_overlay_ppa(yaml_file=None, fatal=True): - """Get overlay_ppa from tests_options. - - In the config file for the tests, the tests_options.overlay_ppa option - may be used to specify a PPA that will be enabled for all units in - the model. - - The tests_options section needs to look like: - - tests_options: - overlay_ppa: ppa:ubuntu-security-proposed/ppa - - :param yaml_file: the YAML file that contains the tests specification - :type yaml_file: Optional[str] - :param fatal: whether any errors cause an exception or are just logged. - :type fatal: bool - :returns: overlay PPA name - :rtype: str - :raises: OSError if the YAML file doesn't exist and fatal=True - """ - config = get_charm_config(yaml_file, fatal) - try: - return config['tests_options']['overlay_ppa'] - # Type error is if the force_deploy is present, but with no value - except (KeyError, TypeError): - pass - return None - - def get_class(class_str): """Get the class represented by the given string. diff --git a/zaza/utilities/deployment_env.py b/zaza/utilities/deployment_env.py index 3a32d9c51..8a58809b6 100644 --- a/zaza/utilities/deployment_env.py +++ b/zaza/utilities/deployment_env.py @@ -19,8 +19,8 @@ import functools import yaml +import zaza.global_options import zaza.model -import zaza.charm_lifecycle.utils as utils ZAZA_SETUP_FILE_LOCATIONS = [ '{home}/.zaza.yaml'] @@ -84,6 +84,31 @@ def parse_option_list_string(option_list, delimiter=None): settings[key.strip()] = value.strip() return settings + +def get_overlay_ppas(): + """Get overlay_ppas from global_config. + + In the config file for the tests, the tests_options.overlay_ppa option + may be used to specify one or more PPAs that will be enabled for all + units in the model. + + The tests_options section needs to look like: + + tests_options: + overlay_ppas: + - ppa:ubuntu-security-proposed/ppa + + :returns: List of overlay PPAs + :rtype: list[str] + """ + config = zaza.global_options.get_options() + try: + return config.overlay_ppas + except KeyError: + pass + return None + + def get_cloudinit_userdata(): """Return cloudinit_userdata based on tests_options config. @@ -91,21 +116,23 @@ def get_cloudinit_userdata(): :rtype: str """ cloudinit_userdata = None - overlay_ppa = utils.get_overlay_ppa() - if overlay_ppa: - cloud_config = { - "apt": { - "sources": { - "overlay-ppa": { - "source": overlay_ppa - } - } + overlay_ppas = get_overlay_ppas() + cloud_config = { + 'apt': { + 'sources': { } } + } + for index, overlay_ppa in enumerate(overlay_ppas): + cloud_config['apt']['sources']["overlay-ppa-{}".format(index)] = { + 'source': overlay_ppa + } + if cloud_config['apt']['sources']: cloudinit_userdata = "#cloud-config\n{}".format( yaml.safe_dump(cloud_config)) return cloudinit_userdata + def get_model_settings(): """Return model settings from defaults, config file and env variables. @@ -120,7 +147,7 @@ def get_model_settings(): if cloudinit_userdata: if 'cloudinit-userdata' in test_env_settings: logging.warn('TEST_MODEL_SETTINGS contains cloudinit-userdata ' - 'which overrides tests_options overlay_ppa') + 'which overrides tests_options overlay_ppas') model_settings.update({'cloudinit-userdata': cloudinit_userdata}) model_settings.update( parse_option_list_string(test_env_settings or env_settings)) From ca3294568665b1dd890fc1c76d3b489426361482 Mon Sep 17 00:00:00 2001 From: Corey Bryant Date: Fri, 16 Jun 2023 13:50:52 -0400 Subject: [PATCH 3/8] Fix NoneType error in enumerate(overlay_ppas) (cherry picked from commit 986474bdc495fa3d55b633a61185999d448d645a) --- zaza/utilities/deployment_env.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/zaza/utilities/deployment_env.py b/zaza/utilities/deployment_env.py index 8a58809b6..f90e67258 100644 --- a/zaza/utilities/deployment_env.py +++ b/zaza/utilities/deployment_env.py @@ -116,18 +116,18 @@ def get_cloudinit_userdata(): :rtype: str """ cloudinit_userdata = None - overlay_ppas = get_overlay_ppas() cloud_config = { 'apt': { 'sources': { } } } - for index, overlay_ppa in enumerate(overlay_ppas): - cloud_config['apt']['sources']["overlay-ppa-{}".format(index)] = { - 'source': overlay_ppa - } - if cloud_config['apt']['sources']: + overlay_ppas = get_overlay_ppas() + if overlay_ppas: + for index, overlay_ppa in enumerate(overlay_ppas): + cloud_config['apt']['sources']["overlay-ppa-{}".format(index)] = { + 'source': overlay_ppa + } cloudinit_userdata = "#cloud-config\n{}".format( yaml.safe_dump(cloud_config)) return cloudinit_userdata From f69531582e79047a271dbecbaac43090fb9ccb9d Mon Sep 17 00:00:00 2001 From: James Page Date: Thu, 23 Feb 2023 10:01:25 +0000 Subject: [PATCH 4/8] Misc fixes for failing github workflows Add separate workflow for testing on Python 3.6 as this requires an older Ubuntu release. Fixup unit tests for compatibility with newer versions of mock. Drop latest/stable functional test targets - this is actually 2.9.x of Juju and is already covered by the 2.9 targets and we want to avoid suddenly picking up a new Juju version because this will break with the new approach to version alignment in the Python module for Juju. Drop 2.8 functional test target - its broken and we don't really support this version any longer. Fixup iptables forwarding issues from LXD containers with a flush and re-create of rules. (cherry picked from commit 9277a94c155da8dabb4d2d60c629bbc7fa9c6ccc) (cherry picked from commit ee92b9be26d4ae53157878df0a3a0771706a1ebd) --- .github/workflows/tox.yaml | 39 +++++++++++++------ unit_tests/test_zaza_model.py | 8 +++- .../utilities/test_zaza_utilities_generic.py | 2 +- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/.github/workflows/tox.yaml b/.github/workflows/tox.yaml index 9379c9f94..fdd0ee956 100644 --- a/.github/workflows/tox.yaml +++ b/.github/workflows/tox.yaml @@ -5,11 +5,36 @@ on: - pull_request jobs: + build_old_versions: + runs-on: ubuntu-20.04 + strategy: + matrix: + python-version: ['3.6'] + + steps: + - uses: actions/checkout@v1 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install codecov tox tox-gh-actions + - name: Lint with tox + run: tox -e pep8 + - name: Test with tox + run: tox -e py + - name: Codecov + run: | + set -euxo pipefail + codecov --verbose --gcov-glob unit_tests/* + build: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.6', '3.7', '3.8', '3.9', '3.10'] + python-version: ['3.7', '3.8', '3.9', '3.10'] steps: - uses: actions/checkout@v1 @@ -35,21 +60,11 @@ jobs: fail-fast: false matrix: juju_channel: - - latest/stable - 2.9/stable - - 2.8/stable bundle: - first - second - third - exclude: - # disable 'first' and 'second' bundles for juju 2.8 since 'magpie' - # is not a promulgated charm in the charmstore, only on charmhub - # which 2.8 can't talk to. - - juju_channel: 2.8/stable - bundle: first - - juju_channel: 2.8/stable - bundle: second env: TEST_ZAZA_BUG_LP1987332: "on" # http://pad.lv/1987332 needs: build @@ -67,6 +82,8 @@ jobs: sudo chmod 666 /var/snap/lxd/common/lxd/unix.socket # until Juju provides stable IPv6-support we unfortunately need this lxc network set lxdbr0 ipv6.address none + sudo iptables -F FORWARD + sudo iptables -P FORWARD ACCEPT # pull images lxc image copy --alias juju/bionic/amd64 --copy-aliases ubuntu-daily:bionic local: lxc image copy --alias juju/focal/amd64 --copy-aliases ubuntu-daily:focal local: diff --git a/unit_tests/test_zaza_model.py b/unit_tests/test_zaza_model.py index 5fecd8d77..67d8b8b8b 100644 --- a/unit_tests/test_zaza_model.py +++ b/unit_tests/test_zaza_model.py @@ -493,7 +493,9 @@ def test_block_until_auto_reconnect_model_disconnected_sync(self): with mock.patch.object(zaza, 'RUN_LIBJUJU_IN_THREAD', new=False): model.sync_wrapper(self._wrapper)() self.Model_mock.disconnect.assert_has_calls([mock.call()]) - self.Model_mock.connect_model.has_calls([mock.call('modelname')]) + self.Model_mock.connect_model.assert_has_calls( + [mock.call('testmodel')] + ) def test_block_until_auto_reconnect_model_disconnected_async(self): self._mocks_for_block_until_auto_reconnect_model( @@ -506,7 +508,9 @@ async def _async_true(): with mock.patch.object(zaza, 'RUN_LIBJUJU_IN_THREAD', new=False): model.sync_wrapper(self._wrapper)() self.Model_mock.disconnect.assert_has_calls([mock.call()]) - self.Model_mock.connect_model.has_calls([mock.call('modelname')]) + self.Model_mock.connect_model.assert_has_calls( + [mock.call('testmodel')] + ) def test_block_until_auto_reconnect_model_blocks_till_true(self): self._mocks_for_block_until_auto_reconnect_model(True, True) diff --git a/unit_tests/utilities/test_zaza_utilities_generic.py b/unit_tests/utilities/test_zaza_utilities_generic.py index 5d3fb7759..038d53e0b 100644 --- a/unit_tests/utilities/test_zaza_utilities_generic.py +++ b/unit_tests/utilities/test_zaza_utilities_generic.py @@ -254,7 +254,7 @@ def test_series_upgrade(self): _unit, _machine_num, origin=_origin, to_series=_to_series, from_series=_from_series, workaround_script=_workaround_script, files=_files) - self.block_until_all_units_idle.called_with() + self.block_until_all_units_idle.assert_called_with() self.prepare_series_upgrade.assert_called_once_with( _machine_num, to_series=_to_series) self.wrap_do_release_upgrade.assert_called_once_with( From d87df2589e6de6fbdbab27368889555457138b06 Mon Sep 17 00:00:00 2001 From: Corey Bryant Date: Fri, 16 Jun 2023 11:32:45 -0400 Subject: [PATCH 5/8] Drop py36, py37, and py39 from github runners These are no longer needed on the master branch. (cherry picked from commit 6122daa374281224da65c79b78fd6d52ade1460e) --- .github/workflows/tox.yaml | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/.github/workflows/tox.yaml b/.github/workflows/tox.yaml index fdd0ee956..5f66ab5a6 100644 --- a/.github/workflows/tox.yaml +++ b/.github/workflows/tox.yaml @@ -5,36 +5,11 @@ on: - pull_request jobs: - build_old_versions: - runs-on: ubuntu-20.04 - strategy: - matrix: - python-version: ['3.6'] - - steps: - - uses: actions/checkout@v1 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install codecov tox tox-gh-actions - - name: Lint with tox - run: tox -e pep8 - - name: Test with tox - run: tox -e py - - name: Codecov - run: | - set -euxo pipefail - codecov --verbose --gcov-glob unit_tests/* - build: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.7', '3.8', '3.9', '3.10'] + python-version: ['3.8', '3.10'] steps: - uses: actions/checkout@v1 From a84d507bd82316e2e813498c537319cb07f388c5 Mon Sep 17 00:00:00 2001 From: Felipe Reyes Date: Tue, 23 May 2023 15:36:23 -0400 Subject: [PATCH 6/8] Unpin pip and virtualenv (cherry picked from commit 55c3f3f94ac064eab7755d88b82f641f57bcc4a4) --- pip.sh | 3 --- tox.ini | 30 +++++++++++++----------------- 2 files changed, 13 insertions(+), 20 deletions(-) delete mode 100755 pip.sh diff --git a/pip.sh b/pip.sh deleted file mode 100755 index 63b05f7de..000000000 --- a/pip.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -pip install pip==20.2.3 -pip "$@" diff --git a/tox.ini b/tox.ini index 26566bc55..dcd65b497 100644 --- a/tox.ini +++ b/tox.ini @@ -2,27 +2,23 @@ envlist = pep8,py3 skipsdist = True -# NOTES: -# * We avoid the new dependency resolver by pinning pip < 20.3, see -# https://github.com/pypa/pip/issues/9187 -# * Pinning dependencies requires tox >= 3.2.0, see -# https://tox.readthedocs.io/en/latest/config.html#conf-requires -# * It is also necessary to pin virtualenv as a newer virtualenv would still -# lead to fetching the latest pip in the func* tox targets, see -# https://stackoverflow.com/a/38133283 -requires = pip < 20.3 - virtualenv < 20.0 # NOTE: https://wiki.canonical.com/engineering/OpenStack/InstallLatestToxOnOsci minversion = 3.2.0 [testenv] -setenv = VIRTUAL_ENV={envdir} - PYTHONHASHSEED=0 -whitelist_external = juju -passenv = HOME TERM CS_* OS_* TEST_* -deps = -r{toxinidir}/test-requirements.txt -install_command = - {toxinidir}/pip.sh install {opts} {packages} +setenv = + VIRTUAL_ENV={envdir} + PYTHONHASHSEED=0 +allowlist_external = + juju +passenv = + HOME + TERM + CS_* + OS_* + TEST_* +deps = + -r{toxinidir}/test-requirements.txt commands = nosetests --with-coverage --processes=0 --cover-package=zaza {posargs} {toxinidir}/unit_tests [testenv:py3] From 01fc1327dc2bb2f912fd78c2f68a224ac6f213bc Mon Sep 17 00:00:00 2001 From: Felipe Reyes Date: Wed, 24 May 2023 16:35:54 -0400 Subject: [PATCH 7/8] Bump up flake8 Fixes `AttributeError: 'FlakesChecker' object has no attribute 'CONSTANT'` (cherry picked from commit a9d681259623b915295bdeb2e265d29ed5a4cea2) --- test-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-requirements.txt b/test-requirements.txt index a4a067b23..0b70d5f7e 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,5 +1,5 @@ aiounittest -flake8>=2.2.4 +flake8>=5 # Python 3.8 compatibility in pyflakes 2.1.0+ flake8-docstrings flake8-per-file-ignores pydocstyle<4.0.0 From 153f79f362c5a032927e506601f2c2e1e8f60cc3 Mon Sep 17 00:00:00 2001 From: Felipe Reyes Date: Wed, 24 May 2023 16:25:24 -0400 Subject: [PATCH 8/8] Migrate from nosetest to pytest nosetest has been deprecated long time ago, adopting a more established unit test runner give us less problems as we move forward. (cherry picked from commit 4b0d23ec92e1d3084dfaa79373af39a959cbdaa1) --- test-requirements.txt | 7 +++---- tox.ini | 2 +- unit_tests/test_zaza_model.py | 2 ++ 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/test-requirements.txt b/test-requirements.txt index 0b70d5f7e..120fe98dd 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -5,10 +5,9 @@ flake8-per-file-ignores pydocstyle<4.0.0 coverage mock>=1.2 -# For some reason the PyPi distributed wheel of nose differ from the one on -# GitHub, and it does not work with Python 3.10. -nose>=1.3.7;python_version<'3.10' -git+https://github.com/nose-devs/nose.git@release_1.3.7#egg=nose;python_version=='3.10' +pytest +pytest-cov +pytest-asyncio # TODO: these requirements should be mocked out in unit_tests/__init__.py async_generator diff --git a/tox.ini b/tox.ini index dcd65b497..1a7963a2d 100644 --- a/tox.ini +++ b/tox.ini @@ -19,7 +19,7 @@ passenv = TEST_* deps = -r{toxinidir}/test-requirements.txt -commands = nosetests --with-coverage --processes=0 --cover-package=zaza {posargs} {toxinidir}/unit_tests +commands = pytest --cov=./zaza/ {posargs} {toxinidir}/unit_tests [testenv:py3] basepython = python3 diff --git a/unit_tests/test_zaza_model.py b/unit_tests/test_zaza_model.py index 67d8b8b8b..e97de80a8 100644 --- a/unit_tests/test_zaza_model.py +++ b/unit_tests/test_zaza_model.py @@ -32,6 +32,7 @@ import concurrent import datetime import mock +import pytest import yaml import unit_tests.utils as ut_utils @@ -100,6 +101,7 @@ def tearDownModule(): }}}}}} +@pytest.mark.asyncio class TestModel(ut_utils.BaseTestCase): def setUp(self):