Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
Please login to access the resource
systemsmanagement:saltstack:bundle:next:python311
venv-salt-minion
several-fixes-for-tests-to-avoid-errors-and-fai...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File several-fixes-for-tests-to-avoid-errors-and-failures.patch of Package venv-salt-minion
From 30fd274d606b565a0a63fbc7f2fd67aec3c495b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?= <psuarezhernandez@suse.com> Date: Mon, 27 May 2024 12:01:53 +0100 Subject: [PATCH] Several fixes for tests to avoid errors and failures in some OSes * test_pip_state: skip tests which requires virtualenv CLI * test_syndic_eauth: skip when using an incompatible Docker version * test_pip: skip tests which requires virtualenv CLI * Some more extra fixes for tests * Enhance paths to look for 'sftp-server' * Do trigger errors on newer docker-py version * Make test_search_not_found to not fail on transactional systems * Add `@pytest.mark.flaky_jail` to `tests/pytests/integration/ssh/test_ssh_setup.py::test_setup` Signed-off-by: Pedro Algarvio <palgarvio@vmware.com> * Prevent crashing if mountpoint does not exist anymore * Skip failing tests on transactional systems * test_consul.py: do not produce error if consul is not available * Redefine max retries for some flaky tests * test_virt.py: skip as CI containers are not compatible with Salt 3006 * test_schema.py: Adjust expectations to newer jsonschema versions * Apply suggestions from code review Co-authored-by: Pedro Algarvio <pedro@algarvio.me> --------- Signed-off-by: Pedro Algarvio <palgarvio@vmware.com> Co-authored-by: Pedro Algarvio <palgarvio@vmware.com> Co-authored-by: Pedro Algarvio <pedro@algarvio.me> --- salt/modules/status.py | 11 +++--- tests/conftest.py | 2 + tests/integration/modules/test_pip.py | 4 ++ tests/pytests/functional/cache/test_consul.py | 4 ++ tests/pytests/functional/modules/test_pip.py | 1 + .../functional/states/test_pip_state.py | 11 ++++++ tests/pytests/functional/states/test_pkg.py | 4 ++ .../integration/cli/test_syndic_eauth.py | 4 +- .../integration/daemons/test_memory_leak.py | 2 +- .../integration/modules/test_cmdmod.py | 1 + .../pytests/integration/modules/test_virt.py | 4 ++ .../integration/ssh/test_pre_flight.py | 4 ++ .../pytests/integration/ssh/test_ssh_setup.py | 1 + tests/pytests/scenarios/setup/test_man.py | 6 +++ .../unit/modules/dockermod/test_module.py | 20 +++++----- tests/unit/modules/test_zypperpkg.py | 1 + tests/unit/utils/test_schema.py | 37 +++++++++++++++---- 17 files changed, 92 insertions(+), 25 deletions(-) diff --git a/salt/modules/status.py b/salt/modules/status.py index 4b0a3b0d400..33e5d7b8df5 100644 --- a/salt/modules/status.py +++ b/salt/modules/status.py @@ -1052,11 +1052,12 @@ def diskusage(*args): # query the filesystems disk usage ret = {} for path in selected: - fsstats = os.statvfs(path) - blksz = fsstats.f_bsize - available = fsstats.f_bavail * blksz - total = fsstats.f_blocks * blksz - ret[path] = {"available": available, "total": total} + if os.path.exists(path): + fsstats = os.statvfs(path) + blksz = fsstats.f_bsize + available = fsstats.f_bavail * blksz + total = fsstats.f_blocks * blksz + ret[path] = {"available": available, "total": total} return ret diff --git a/tests/conftest.py b/tests/conftest.py index a7777c2cea6..ad57b4adef4 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1428,6 +1428,8 @@ def sshd_server(salt_factories, sshd_config_dir, salt_master, grains): "/usr/libexec/openssh/sftp-server", # Arch Linux "/usr/lib/ssh/sftp-server", + # openSUSE Tumbleweed and SL Micro 6.0 + "/usr/libexec/ssh/sftp-server", ] sftp_server_path = None for path in sftp_server_paths: diff --git a/tests/integration/modules/test_pip.py b/tests/integration/modules/test_pip.py index 83457b467c8..d57e9cd2aea 100644 --- a/tests/integration/modules/test_pip.py +++ b/tests/integration/modules/test_pip.py @@ -557,6 +557,10 @@ class PipModuleTest(ModuleCase): @pytest.mark.skip_initial_gh_actions_failure( reason="This was skipped on older golden images and is failing on newer." ) + @pytest.mark.skipif( + bool(salt.utils.path.which("transactional-update")), + reason="Skipping on transactional systems", + ) def test_system_pip3(self): self.run_function( diff --git a/tests/pytests/functional/cache/test_consul.py b/tests/pytests/functional/cache/test_consul.py index 30dc6925f26..996a1e932b6 100644 --- a/tests/pytests/functional/cache/test_consul.py +++ b/tests/pytests/functional/cache/test_consul.py @@ -11,6 +11,10 @@ import salt.loader from salt.utils.versions import Version from tests.pytests.functional.cache.helpers import run_common_cache_tests +pytest.importorskip( + "consul", + reason="Please install python-consul package to use consul data cache driver", +) docker = pytest.importorskip("docker") log = logging.getLogger(__name__) diff --git a/tests/pytests/functional/modules/test_pip.py b/tests/pytests/functional/modules/test_pip.py index 9b87735b68f..e04baa7c43f 100644 --- a/tests/pytests/functional/modules/test_pip.py +++ b/tests/pytests/functional/modules/test_pip.py @@ -22,6 +22,7 @@ from tests.support.helpers import VirtualEnv ) @pytest.mark.requires_network @pytest.mark.slow_test +@pytest.mark.skip_if_binaries_missing("virtualenv", reason="Needs virtualenv binary") def test_list_available_packages(modules, pip_version, tmp_path): with VirtualEnv(venv_dir=tmp_path, pip_requirement=pip_version) as virtualenv: virtualenv.install("-U", pip_version) diff --git a/tests/pytests/functional/states/test_pip_state.py b/tests/pytests/functional/states/test_pip_state.py index 3fc6ac7a1df..1921751b5dc 100644 --- a/tests/pytests/functional/states/test_pip_state.py +++ b/tests/pytests/functional/states/test_pip_state.py @@ -94,6 +94,7 @@ def test_pip_installed_removed(modules, states): @pytest.mark.slow_test +@pytest.mark.skip_if_binaries_missing("virtualenv", reason="Needs virtualenv binary") def test_pip_installed_removed_venv(tmp_path, create_virtualenv, states): venv_dir = tmp_path / "pip_installed_removed" create_virtualenv(str(venv_dir)) @@ -105,6 +106,7 @@ def test_pip_installed_removed_venv(tmp_path, create_virtualenv, states): @pytest.mark.slow_test +@pytest.mark.skip_if_binaries_missing("virtualenv", reason="Needs virtualenv binary") def test_pip_installed_errors(tmp_path, modules, state_tree): venv_dir = tmp_path / "pip-installed-errors" # Since we don't have the virtualenv created, pip.installed will @@ -141,6 +143,7 @@ pep8-pip: assert state_return.result is True +@pytest.mark.skip_if_binaries_missing("virtualenv", reason="Needs virtualenv binary") def test_pip_installed_name_test_mode(tmp_path, create_virtualenv, states): """ Test pip.installed state while test=true @@ -154,6 +157,7 @@ def test_pip_installed_name_test_mode(tmp_path, create_virtualenv, states): assert name in ret.comment +@pytest.mark.skip_if_binaries_missing("virtualenv", reason="Needs virtualenv binary") def test_pip_installed_pkgs_test_mode(tmp_path, create_virtualenv, states): """ Test pip.installed state while test=true @@ -168,6 +172,7 @@ def test_pip_installed_pkgs_test_mode(tmp_path, create_virtualenv, states): @pytest.mark.slow_test +@pytest.mark.skip_if_binaries_missing("virtualenv", reason="Needs virtualenv binary") def test_issue_2028_pip_installed_state( tmp_path, modules, state_tree, get_python_executable ): @@ -226,6 +231,7 @@ pep8-pip: @pytest.mark.slow_test +@pytest.mark.skip_if_binaries_missing("virtualenv", reason="Needs virtualenv binary") def test_issue_2087_missing_pip(tmp_path, create_virtualenv, modules): venv_dir = tmp_path / "issue-2087-missing-pip" @@ -271,6 +277,7 @@ pip.installed: @pytest.mark.destructive_test @pytest.mark.slow_test @pytest.mark.skip_if_not_root +@pytest.mark.skip_if_binaries_missing("virtualenv", reason="Needs virtualenv binary") def test_issue_6912_wrong_owner(tmp_path, create_virtualenv, modules, states): # Setup virtual environment directory to be used throughout the test venv_dir = tmp_path / "6912-wrong-owner" @@ -338,6 +345,7 @@ def test_issue_6912_wrong_owner(tmp_path, create_virtualenv, modules, states): @pytest.mark.skip_on_darwin(reason="Test is flaky on macosx") @pytest.mark.slow_test @pytest.mark.skip_if_not_root +@pytest.mark.skip_if_binaries_missing("virtualenv", reason="Needs virtualenv binary") def test_issue_6912_wrong_owner_requirements_file( tmp_path, create_virtualenv, state_tree, modules, states ): @@ -409,6 +417,7 @@ def test_issue_6912_wrong_owner_requirements_file( @pytest.mark.destructive_test @pytest.mark.slow_test +@pytest.mark.skip_if_binaries_missing("virtualenv", reason="Needs virtualenv binary") def test_issue_6833_pip_upgrade_pip(tmp_path, create_virtualenv, modules, states): # Create the testing virtualenv if sys.platform == "win32": @@ -465,6 +474,7 @@ def test_issue_6833_pip_upgrade_pip(tmp_path, create_virtualenv, modules, states @pytest.mark.slow_test +@pytest.mark.skip_if_binaries_missing("virtualenv", reason="Needs virtualenv binary") def test_pip_installed_specific_env( tmp_path, state_tree_prod, states, create_virtualenv ): @@ -514,6 +524,7 @@ def test_pip_installed_specific_env( @pytest.mark.slow_test +@pytest.mark.skip_if_binaries_missing("virtualenv", reason="Needs virtualenv binary") def test_22359_pip_installed_unless_does_not_trigger_warnings( create_virtualenv, tmp_path, states ): diff --git a/tests/pytests/functional/states/test_pkg.py b/tests/pytests/functional/states/test_pkg.py index 864c1d025f3..9e5a8350ad9 100644 --- a/tests/pytests/functional/states/test_pkg.py +++ b/tests/pytests/functional/states/test_pkg.py @@ -19,6 +19,10 @@ pytestmark = [ pytest.mark.slow_test, pytest.mark.skip_if_not_root, pytest.mark.destructive_test, + pytest.mark.skipif( + bool(salt.utils.path.which("transactional-update")), + reason="Skipping on transactional systems", + ), ] diff --git a/tests/pytests/integration/cli/test_syndic_eauth.py b/tests/pytests/integration/cli/test_syndic_eauth.py index 218022b9e3c..8dcdd3fbd28 100644 --- a/tests/pytests/integration/cli/test_syndic_eauth.py +++ b/tests/pytests/integration/cli/test_syndic_eauth.py @@ -6,7 +6,9 @@ import time import pytest -docker = pytest.importorskip("docker") +from tests.conftest import CODE_DIR + +docker = pytest.importorskip("docker", minversion="4.0.0") INSIDE_CONTAINER = os.getenv("HOSTNAME", "") == "salt-test-container" diff --git a/tests/pytests/integration/daemons/test_memory_leak.py b/tests/pytests/integration/daemons/test_memory_leak.py index 8157091c44e..f2c5307f1a5 100644 --- a/tests/pytests/integration/daemons/test_memory_leak.py +++ b/tests/pytests/integration/daemons/test_memory_leak.py @@ -49,7 +49,7 @@ def file_add_delete_sls(testfile_path, base_env_state_tree_root_dir): @pytest.mark.skip_on_darwin(reason="MacOS is a spawning platform, won't work") @pytest.mark.skipif(GITHUB_ACTIONS, reason="Test is failing in GitHub Actions") -@pytest.mark.flaky(max_runs=4) +@pytest.mark.flaky(max_runs=10) def test_memory_leak(salt_cli, salt_minion, file_add_delete_sls): max_usg = None diff --git a/tests/pytests/integration/modules/test_cmdmod.py b/tests/pytests/integration/modules/test_cmdmod.py index d9c326c3f0a..d0b993ddbcf 100644 --- a/tests/pytests/integration/modules/test_cmdmod.py +++ b/tests/pytests/integration/modules/test_cmdmod.py @@ -63,6 +63,7 @@ def test_avoid_injecting_shell_code_as_root( @pytest.mark.slow_test +@pytest.mark.flaky(max_runs=4) def test_blacklist_glob(salt_call_cli): """ cmd_blacklist_glob diff --git a/tests/pytests/integration/modules/test_virt.py b/tests/pytests/integration/modules/test_virt.py index 572923764bb..a1cd577fe76 100644 --- a/tests/pytests/integration/modules/test_virt.py +++ b/tests/pytests/integration/modules/test_virt.py @@ -26,6 +26,10 @@ pytestmark = [ Version(docker.__version__) < Version("4.0.0"), reason="Test does not work in this version of docker-py", ), + pytest.mark.skipif( + salt.version.__saltstack_version__.major <= 3006, + reason="CI containers are not compatible with this Salt version", + ), ] diff --git a/tests/pytests/integration/ssh/test_pre_flight.py b/tests/pytests/integration/ssh/test_pre_flight.py index 09c65d29430..ac32b8d90fd 100644 --- a/tests/pytests/integration/ssh/test_pre_flight.py +++ b/tests/pytests/integration/ssh/test_pre_flight.py @@ -235,6 +235,10 @@ def demote(user_uid, user_gid): @pytest.mark.slow_test +@pytest.mark.skipif( + bool(salt.utils.path.which("transactional-update")), + reason="Skipping on transactional systems", +) def test_ssh_pre_flight_perms(salt_ssh_cli, caplog, _create_roster, account): """ Test to ensure standard user cannot run pre flight script diff --git a/tests/pytests/integration/ssh/test_ssh_setup.py b/tests/pytests/integration/ssh/test_ssh_setup.py index 97494bed36b..3b4cede85f8 100644 --- a/tests/pytests/integration/ssh/test_ssh_setup.py +++ b/tests/pytests/integration/ssh/test_ssh_setup.py @@ -161,6 +161,7 @@ def salt_ssh_cli( ) +@pytest.mark.flaky_jail def test_setup(salt_ssh_cli, ssh_container_name, ssh_sub_container_name, ssh_password): """ Test salt-ssh setup works diff --git a/tests/pytests/scenarios/setup/test_man.py b/tests/pytests/scenarios/setup/test_man.py index 28f0d6285a3..f10fe711f2d 100644 --- a/tests/pytests/scenarios/setup/test_man.py +++ b/tests/pytests/scenarios/setup/test_man.py @@ -9,6 +9,9 @@ import pytest import salt.utils.platform from salt.modules.virtualenv_mod import KNOWN_BINARY_NAMES +from tests.conftest import CODE_DIR + +MISSING_SETUP_PY_FILE = not CODE_DIR.joinpath("setup.py").exists() pytestmark = [ pytest.mark.core_test, @@ -16,6 +19,9 @@ pytestmark = [ pytest.mark.skip_on_aix, pytest.mark.skip_initial_onedir_failure, pytest.mark.skip_if_binaries_missing(*KNOWN_BINARY_NAMES, check_all=False), + pytest.mark.skipif( + MISSING_SETUP_PY_FILE, reason="This test only work if setup.py is available" + ), ] diff --git a/tests/pytests/unit/modules/dockermod/test_module.py b/tests/pytests/unit/modules/dockermod/test_module.py index 1ac7dff52a5..a87d1add167 100644 --- a/tests/pytests/unit/modules/dockermod/test_module.py +++ b/tests/pytests/unit/modules/dockermod/test_module.py @@ -357,7 +357,7 @@ def test_update_mine(): @pytest.mark.skipif( - docker_mod.docker.version_info < (1, 5, 0), + docker_mod._get_docker_py_versioninfo() < (1, 5, 0), reason="docker module must be installed to run this test or is too old. >=1.5.0", ) def test_list_networks(): @@ -381,7 +381,7 @@ def test_list_networks(): @pytest.mark.skipif( - docker_mod.docker.version_info < (1, 5, 0), + docker_mod._get_docker_py_versioninfo() < (1, 5, 0), reason="docker module must be installed to run this test or is too old. >=1.5.0", ) def test_create_network(): @@ -425,7 +425,7 @@ def test_create_network(): @pytest.mark.skipif( - docker_mod.docker.version_info < (1, 5, 0), + docker_mod._get_docker_py_versioninfo() < (1, 5, 0), reason="docker module must be installed to run this test or is too old. >=1.5.0", ) def test_remove_network(): @@ -447,7 +447,7 @@ def test_remove_network(): @pytest.mark.skipif( - docker_mod.docker.version_info < (1, 5, 0), + docker_mod._get_docker_py_versioninfo() < (1, 5, 0), reason="docker module must be installed to run this test or is too old. >=1.5.0", ) def test_inspect_network(): @@ -469,7 +469,7 @@ def test_inspect_network(): @pytest.mark.skipif( - docker_mod.docker.version_info < (1, 5, 0), + docker_mod._get_docker_py_versioninfo() < (1, 5, 0), reason="docker module must be installed to run this test or is too old. >=1.5.0", ) def test_connect_container_to_network(): @@ -494,7 +494,7 @@ def test_connect_container_to_network(): @pytest.mark.skipif( - docker_mod.docker.version_info < (1, 5, 0), + docker_mod._get_docker_py_versioninfo() < (1, 5, 0), reason="docker module must be installed to run this test or is too old. >=1.5.0", ) def test_disconnect_container_from_network(): @@ -516,7 +516,7 @@ def test_disconnect_container_from_network(): @pytest.mark.skipif( - docker_mod.docker.version_info < (1, 5, 0), + docker_mod._get_docker_py_versioninfo() < (1, 5, 0), reason="docker module must be installed to run this test or is too old. >=1.5.0", ) def test_list_volumes(): @@ -542,7 +542,7 @@ def test_list_volumes(): @pytest.mark.skipif( - docker_mod.docker.version_info < (1, 5, 0), + docker_mod._get_docker_py_versioninfo() < (1, 5, 0), reason="docker module must be installed to run this test or is too old. >=1.5.0", ) def test_create_volume(): @@ -572,7 +572,7 @@ def test_create_volume(): @pytest.mark.skipif( - docker_mod.docker.version_info < (1, 5, 0), + docker_mod._get_docker_py_versioninfo() < (1, 5, 0), reason="docker module must be installed to run this test or is too old. >=1.5.0", ) def test_remove_volume(): @@ -594,7 +594,7 @@ def test_remove_volume(): @pytest.mark.skipif( - docker_mod.docker.version_info < (1, 5, 0), + docker_mod._get_docker_py_versioninfo() < (1, 5, 0), reason="docker module must be installed to run this test or is too old. >=1.5.0", ) def test_inspect_volume(): diff --git a/tests/unit/modules/test_zypperpkg.py b/tests/unit/modules/test_zypperpkg.py index 6e5ca88895f..bd67b16745c 100644 --- a/tests/unit/modules/test_zypperpkg.py +++ b/tests/unit/modules/test_zypperpkg.py @@ -2602,6 +2602,7 @@ pattern() = package-c""" zypp_mock.assert_called_with(root=None, ignore_not_found=True) xml_mock.nolock.noraise.xml.call.assert_called_with("search", "emacs") + @patch("salt.utils.files.is_fcntl_available", MagicMock(return_value=False)) def test_search_not_found(self): """Test zypperpkg.search()""" ret = { diff --git a/tests/unit/utils/test_schema.py b/tests/unit/utils/test_schema.py index 113c6836e07..a531dd93111 100644 --- a/tests/unit/utils/test_schema.py +++ b/tests/unit/utils/test_schema.py @@ -531,7 +531,9 @@ class ConfigTestCase(TestCase): jsonschema.validate( {"personal_access_token": "foo"}, Requirements.serialize() ) - if JSONSCHEMA_VERSION >= Version("3.0.0"): + if JSONSCHEMA_VERSION >= Version("3.0.0") and JSONSCHEMA_VERSION < Version( + "4.8.0" + ): self.assertIn( "'ssh_key_file' is a required property", excinfo.exception.message ) @@ -899,13 +901,20 @@ class ConfigTestCase(TestCase): except jsonschema.exceptions.ValidationError as exc: self.fail("ValidationError raised: {}".format(exc)) - with self.assertRaises(jsonschema.exceptions.ValidationError) as excinfo: + if JSONSCHEMA_VERSION < Version("4.0.0"): + with self.assertRaises(jsonschema.exceptions.ValidationError) as excinfo: + jsonschema.validate( + {"item": "3"}, + TestConf.serialize(), + format_checker=jsonschema.FormatChecker(), + ) + self.assertIn("is not a", excinfo.exception.message) + else: jsonschema.validate( {"item": "3"}, TestConf.serialize(), format_checker=jsonschema.FormatChecker(), ) - self.assertIn("is not a", excinfo.exception.message) def test_datetime_config(self): item = schema.DateTimeItem(title="Foo", description="Foo Item") @@ -1878,7 +1887,9 @@ class ConfigTestCase(TestCase): jsonschema.validate( {"item": {"sides": "4", "color": "blue"}}, TestConf.serialize() ) - if JSONSCHEMA_VERSION >= Version("3.0.0"): + if JSONSCHEMA_VERSION >= Version("3.0.0") and JSONSCHEMA_VERSION < Version( + "4.8.0" + ): self.assertIn("'4'", excinfo.exception.message) self.assertIn("is not of type", excinfo.exception.message) self.assertIn("'boolean'", excinfo.exception.message) @@ -2003,7 +2014,9 @@ class ConfigTestCase(TestCase): with self.assertRaises(jsonschema.exceptions.ValidationError) as excinfo: jsonschema.validate({"item": ["maybe"]}, TestConf.serialize()) - if JSONSCHEMA_VERSION >= Version("3.0.0"): + if JSONSCHEMA_VERSION >= Version("3.0.0") and JSONSCHEMA_VERSION < Version( + "4.8.0" + ): self.assertIn("'maybe'", excinfo.exception.message) self.assertIn("is not one of", excinfo.exception.message) self.assertIn("'yes'", excinfo.exception.message) @@ -2067,7 +2080,9 @@ class ConfigTestCase(TestCase): with self.assertRaises(jsonschema.exceptions.ValidationError) as excinfo: jsonschema.validate({"item": ["maybe"]}, TestConf.serialize()) - if JSONSCHEMA_VERSION >= Version("3.0.0"): + if JSONSCHEMA_VERSION >= Version("3.0.0") and JSONSCHEMA_VERSION < Version( + "4.8.0" + ): self.assertIn("'maybe'", excinfo.exception.message) self.assertIn("is not one of", excinfo.exception.message) self.assertIn("'yes'", excinfo.exception.message) @@ -2154,11 +2169,17 @@ class ConfigTestCase(TestCase): with self.assertRaises(jsonschema.exceptions.ValidationError) as excinfo: jsonschema.validate({"item": [True]}, TestConf.serialize()) - self.assertIn("is not allowed for", excinfo.exception.message) + if JSONSCHEMA_VERSION >= Version("4.0.0"): + self.assertIn("should not be valid under", excinfo.exception.message) + else: + self.assertIn("is not allowed for", excinfo.exception.message) with self.assertRaises(jsonschema.exceptions.ValidationError) as excinfo: jsonschema.validate({"item": [False]}, TestConf.serialize()) - self.assertIn("is not allowed for", excinfo.exception.message) + if JSONSCHEMA_VERSION >= Version("4.0.0"): + self.assertIn("should not be valid under", excinfo.exception.message) + else: + self.assertIn("is not allowed for", excinfo.exception.message) def test_item_name_override_class_attrname(self): class TestConf(schema.Schema): -- 2.44.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor