From 9295bb5b5d12b7d1ac9f24c7adc1e96d5e5893b5 Mon Sep 17 00:00:00 2001 From: Matt Clay Date: Wed, 11 Oct 2023 17:31:04 -0700 Subject: [PATCH] Unit test cleanup (#81958) Remove obsolete Python 2.7 and 3.6 support code and fix up existing tests. --- test/sanity/ignore.txt | 1 + .../module_utils/basic/test_exit_json.py | 4 +-- .../test_get_available_hash_algorithms.py | 31 ------------------- test/units/module_utils/basic/test_imports.py | 27 ---------------- .../testcoll/plugins/module_utils/my_util.py | 4 +-- .../test_collection_loader.py | 14 +++------ 6 files changed, 8 insertions(+), 73 deletions(-) diff --git a/test/sanity/ignore.txt b/test/sanity/ignore.txt index 78fb64db38a..75e123405c0 100644 --- a/test/sanity/ignore.txt +++ b/test/sanity/ignore.txt @@ -170,6 +170,7 @@ test/units/utils/collection_loader/fixtures/collections_masked/ansible_collectio test/units/utils/collection_loader/fixtures/collections_masked/ansible_collections/testns/__init__.py empty-init # testing that collections don't need inits test/units/utils/collection_loader/fixtures/collections_masked/ansible_collections/testns/testcoll/__init__.py empty-init # testing that collections don't need inits test/units/utils/collection_loader/test_collection_loader.py pylint:undefined-variable # magic runtime local var splatting +test/units/utils/collection_loader/fixtures/collections/ansible_collections/testns/testcoll/plugins/module_utils/my_util.py boilerplate # test requires missing boilerplate .github/CONTRIBUTING.md pymarkdown:line-length hacking/backport/README.md pymarkdown:no-bare-urls hacking/ticket_stubs/bug_internal_api.md pymarkdown:no-bare-urls diff --git a/test/units/module_utils/basic/test_exit_json.py b/test/units/module_utils/basic/test_exit_json.py index 803f20e8979..ef44cecfa01 100644 --- a/test/units/module_utils/basic/test_exit_json.py +++ b/test/units/module_utils/basic/test_exit_json.py @@ -100,9 +100,7 @@ class TestAnsibleModuleExitJson: with pytest.raises(TypeError) as ctx: am.fail_json() - if sys.version_info < (3,): - error_msg = "fail_json() takes exactly 2 arguments (1 given)" - elif sys.version_info >= (3, 10): + if sys.version_info >= (3, 10): error_msg = "AnsibleModule.fail_json() missing 1 required positional argument: 'msg'" else: error_msg = "fail_json() missing 1 required positional argument: 'msg'" diff --git a/test/units/module_utils/basic/test_get_available_hash_algorithms.py b/test/units/module_utils/basic/test_get_available_hash_algorithms.py index d22efc8f745..e7fb76b2b51 100644 --- a/test/units/module_utils/basic/test_get_available_hash_algorithms.py +++ b/test/units/module_utils/basic/test_get_available_hash_algorithms.py @@ -2,16 +2,9 @@ from __future__ import annotations - -import hashlib -import sys - -import pytest - from ansible.module_utils.basic import _get_available_hash_algorithms -@pytest.mark.skipif(sys.version_info < (2, 7, 9), reason="requires Python 2.7.9 or later") def test_unavailable_algorithm(mocker): """Simulate an available algorithm that isn't.""" expected_algorithms = {'sha256', 'sha512'} # guaranteed to be available @@ -23,7 +16,6 @@ def test_unavailable_algorithm(mocker): assert sorted(expected_algorithms) == sorted(available_algorithms) -@pytest.mark.skipif(sys.version_info < (2, 7, 9), reason="requires Python 2.7.9 or later") def test_fips_mode(mocker): """Simulate running in FIPS mode on Python 2.7.9 or later.""" expected_algorithms = {'sha256', 'sha512'} # guaranteed to be available @@ -34,26 +26,3 @@ def test_fips_mode(mocker): available_algorithms = _get_available_hash_algorithms() assert sorted(expected_algorithms) == sorted(available_algorithms) - - -@pytest.mark.skipif(sys.version_info < (2, 7, 9) or sys.version_info[:2] != (2, 7), reason="requires Python 2.7 (2.7.9 or later)") -def test_legacy_python(mocker): - """Simulate behavior on Python 2.7.x earlier than Python 2.7.9.""" - expected_algorithms = {'sha256', 'sha512'} # guaranteed to be available - - # This attribute is exclusive to Python 2.7. - # Since `hashlib.algorithms_available` is used on Python 2.7.9 and later, only Python 2.7.0 through 2.7.8 utilize this attribute. - mocker.patch('hashlib.algorithms', expected_algorithms) - - saved_algorithms = hashlib.algorithms_available - - # Make sure that this attribute is unavailable, to simulate running on Python 2.7.0 through 2.7.8. - # It will be restored immediately after performing the test. - del hashlib.algorithms_available - - try: - available_algorithms = _get_available_hash_algorithms() - finally: - hashlib.algorithms_available = saved_algorithms - - assert sorted(expected_algorithms) == sorted(available_algorithms) diff --git a/test/units/module_utils/basic/test_imports.py b/test/units/module_utils/basic/test_imports.py index 93b357bb365..0d4f0027b8a 100644 --- a/test/units/module_utils/basic/test_imports.py +++ b/test/units/module_utils/basic/test_imports.py @@ -10,7 +10,6 @@ import sys from units.mock.procenv import ModuleTestCase -from units.compat import unittest from units.compat.mock import patch from ansible.module_utils.six.moves import builtins @@ -66,32 +65,6 @@ class TestImports(ModuleTestCase): # mock_bytes.side_effect = NameError() # from ansible.module_utils import basic - @patch.object(builtins, '__import__') - @unittest.skipIf(sys.version_info[0] >= 3, "literal_eval is available in every version of Python3") - def test_module_utils_basic_import_literal_eval(self, mock_import): - def _mock_import(name, *args, **kwargs): - try: - fromlist = kwargs.get('fromlist', args[2]) - except IndexError: - fromlist = [] - if name == 'ast' and 'literal_eval' in fromlist: - raise ImportError - return realimport(name, *args, **kwargs) - - mock_import.side_effect = _mock_import - self.clear_modules(['ast', 'ansible.module_utils.basic']) - mod = builtins.__import__('ansible.module_utils.basic') - self.assertEqual(mod.module_utils.basic.literal_eval("'1'"), "1") - self.assertEqual(mod.module_utils.basic.literal_eval("1"), 1) - self.assertEqual(mod.module_utils.basic.literal_eval("-1"), -1) - self.assertEqual(mod.module_utils.basic.literal_eval("(1,2,3)"), (1, 2, 3)) - self.assertEqual(mod.module_utils.basic.literal_eval("[1]"), [1]) - self.assertEqual(mod.module_utils.basic.literal_eval("True"), True) - self.assertEqual(mod.module_utils.basic.literal_eval("False"), False) - self.assertEqual(mod.module_utils.basic.literal_eval("None"), None) - # self.assertEqual(mod.module_utils.basic.literal_eval('{"a": 1}'), dict(a=1)) - self.assertRaises(ValueError, mod.module_utils.basic.literal_eval, "asdfasdfasdf") - @patch.object(builtins, '__import__') def test_module_utils_basic_import_systemd_journal(self, mock_import): def _mock_import(name, *args, **kwargs): diff --git a/test/units/utils/collection_loader/fixtures/collections/ansible_collections/testns/testcoll/plugins/module_utils/my_util.py b/test/units/utils/collection_loader/fixtures/collections/ansible_collections/testns/testcoll/plugins/module_utils/my_util.py index 65c00b85daf..f551875fe87 100644 --- a/test/units/utils/collection_loader/fixtures/collections/ansible_collections/testns/testcoll/plugins/module_utils/my_util.py +++ b/test/units/utils/collection_loader/fixtures/collections/ansible_collections/testns/testcoll/plugins/module_utils/my_util.py @@ -1,6 +1,6 @@ # WARNING: Changing line numbers of code in this file will break collection tests that use tracing to check paths and line numbers. -from __future__ import annotations +# Also, do not import annotations from __future__ as this will break detection of __future__ inheritance. -def question(): +def question() -> float: return 3 / 2 diff --git a/test/units/utils/collection_loader/test_collection_loader.py b/test/units/utils/collection_loader/test_collection_loader.py index 778e122c72a..06e27a1e785 100644 --- a/test/units/utils/collection_loader/test_collection_loader.py +++ b/test/units/utils/collection_loader/test_collection_loader.py @@ -1,5 +1,6 @@ from __future__ import annotations +import inspect import os import pkgutil import pytest @@ -484,11 +485,8 @@ def test_import_from_collection(monkeypatch): import ansible_collections.testns.testcoll.plugins.action.my_action # verify that code loaded from a collection does not inherit __future__ statements from the collection loader - if sys.version_info[0] == 2: - # if the collection code inherits the division future feature from the collection loader this will fail - assert answer == 1 - else: - assert answer == 1.5 + # if the collection code inherits the annotations future feature from the collection loader this will fail + assert inspect.get_annotations(question)['return'] is float # verify that the filename and line number reported by the trace is correct # this makes sure that collection loading preserves file paths and line numbers @@ -845,12 +843,8 @@ def test_collectionref_components_invalid(name, subdirs, resource, ref_type, exp assert re.search(expected_error_expression, str(curerr.value)) -@pytest.mark.skipif(not PY3, reason='importlib.resources only supported for py3') def test_importlib_resources(): - if sys.version_info < (3, 10): - from importlib_resources import files - else: - from importlib.resources import files + from importlib.resources import files from pathlib import Path f = get_default_finder()