diff --git a/.config/requirements-test.txt b/.config/requirements-test.txt index e416b0a8c..23ec3a6a8 100644 --- a/.config/requirements-test.txt +++ b/.config/requirements-test.txt @@ -8,7 +8,6 @@ filelock >= 3.9.0 pexpect >= 4.8.0, < 5 pytest-mock >= 3.10.0 pytest-plus >= 0.4.0 -pytest-testinfra >= 7.0.0 pytest-xdist >= 3.1.0 pytest >= 7.2.0 check-jsonschema diff --git a/.config/requirements.txt b/.config/requirements.txt index e7c57e423..dfe67fb7c 100644 --- a/.config/requirements.txt +++ b/.config/requirements.txt @@ -76,7 +76,6 @@ pymdown-extensions==10.0.1 pytest==7.4.0 pytest-mock==3.11.1 pytest-plus==0.4.0 -pytest-testinfra==8.1.0 pytest-xdist==3.3.1 python-dateutil==2.8.2 python-slugify==8.0.1 diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 9367ea7de..210449356 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -51,7 +51,7 @@ jobs: matrix: ${{ fromJson(needs.pre.outputs.matrix) }} env: - PYTEST_REQPASS: 445 + PYTEST_REQPASS: 424 steps: - uses: actions/checkout@v3 with: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ffee93fb3..719947ec1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -91,7 +91,6 @@ repos: - jsonschema - pexpect - pytest-mock - - pytest-testinfra - repo: https://github.com/jazzband/pip-tools rev: 6.14.0 hooks: diff --git a/docs/ci.md b/docs/ci.md index b9bcd31ce..72f7ff11a 100644 --- a/docs/ci.md +++ b/docs/ci.md @@ -401,8 +401,6 @@ won't create any conflict. --- dependency: name: galaxy -driver: - name: docker platforms: - name: instance1-$TOX_ENVNAME image: mariadb @@ -412,6 +410,4 @@ platforms: command: /usr/sbin/init provisioner: name: ansible -verifier: - name: testinfra ``` diff --git a/docs/configuration.md b/docs/configuration.md index 6ab64abaa..0e37380cd 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -294,7 +294,3 @@ Molecule handles role testing by invoking configurable verifiers. ### Ansible ::: molecule.verifier.ansible.Ansible - -### Testinfra - -::: molecule.verifier.testinfra.Testinfra diff --git a/docs/examples.md b/docs/examples.md index 4a86f1ba7..e7f279d3a 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -359,15 +359,6 @@ shared-tests Tests and playbooks can be shared across scenarios. -In this example the `tests` directory lives in a shared -location and `molecule.yml` points to the shared tests. - -```yaml -verifier: - name: testinfra - directory: ../resources/tests/ -``` - In this second example the actions `create`, `destroy`, `converge` and `prepare` are loaded from a shared directory. diff --git a/docs/getting-started.md b/docs/getting-started.md index 7198dd633..57659352a 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -44,8 +44,7 @@ INSTALL.rst molecule.yml converge.yml verify.yml - `verify.yml` is the Ansible file used for testing as Ansible is the default [verifier](configuration.md#verifier). This allows you to write specific tests against the state of the container after your - role has finished executing. Other verifier tools are available - Note that [testinfra](https://testinfra.readthedocs.io/en/latest/) was the default verifier prior to molecule version 3. + role has finished executing. !!! note diff --git a/docs/next.md b/docs/next.md index 8326e56ad..5a8ca9453 100644 --- a/docs/next.md +++ b/docs/next.md @@ -9,11 +9,13 @@ reduce the amount of magic and just rely on ansible core features. - `roles-path` and `collections-paths` are no longer configurable for dependencies. Users are expected to make use of `ansible.cfg` file to alter them when needed. +- testinfra verifier driver was removed but current users should be able to + keep calling their testinfra tests by using `command` or `shell` ansible + modules from within `verify.yml` playbook. # Planned changes - Removal of provisioning drivers support and documenting, with examples, how to easily migrate to a self-provisioning approach. -- Removal of testinfra verifier driver and documenting how to call testinfra from inside the converge playbook to keep using the tool. - Refactoring how dependencies are installed - Bringing ephemeral directory under scenario folder instead of the current inconvenient location under `~/.cache/molecule/...` diff --git a/pyproject.toml b/pyproject.toml index 7f62b2035..20d91a730 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,7 +51,6 @@ molecule = "molecule.__main__:main" default = "molecule.driver.delegated:Delegated" [project.entry-points."molecule.verifier.next"] -testinfra = "molecule.verifier.testinfra:Testinfra" ansible = "molecule.verifier.ansible:Ansible" [tool.coverage.run] @@ -97,7 +96,6 @@ module = [ "click_help_colors", # https://github.com/click-contrib/click-help-colors/issues/20 "pexpect", # https://github.com/pexpect/pexpect/issues/759 "pluggy", # https://github.com/pytest-dev/pluggy/pull/414 - "testinfra.*", # https://github.com/pytest-dev/pytest-testinfra/issues/619 "pytest_mock", ] ignore_missing_imports = true diff --git a/src/molecule/driver/base.py b/src/molecule/driver/base.py index c81cf1ea5..51344d1a3 100644 --- a/src/molecule/driver/base.py +++ b/src/molecule/driver/base.py @@ -58,17 +58,6 @@ def name(self, value): # pragma: no cover :returns: None """ - @property - def testinfra_options(self): - """Testinfra specific options and returns a dict. - - :returns: dict - """ - return { - "connection": "ansible", - "ansible-inventory": self._config.provisioner.inventory_directory, - } - @property @abstractmethod def login_cmd_template(self): # pragma: no cover diff --git a/src/molecule/driver/delegated.py b/src/molecule/driver/delegated.py index f6802aea9..5c712f5be 100644 --- a/src/molecule/driver/delegated.py +++ b/src/molecule/driver/delegated.py @@ -227,8 +227,6 @@ def ansible_connection_options(self, instance_name): ) if d.get("password", None): conn_dict["ansible_password"] = d.get("password") - # Based on testinfra documentation, ansible password must be passed via ansible_ssh_pass - # issue to fix this can be found https://github.com/pytest-dev/pytest-testinfra/issues/580 conn_dict["ansible_ssh_pass"] = d.get("password") return conn_dict diff --git a/src/molecule/interpolation.py b/src/molecule/interpolation.py index a09f86814..7fd45d067 100644 --- a/src/molecule/interpolation.py +++ b/src/molecule/interpolation.py @@ -32,22 +32,6 @@ def __init__(self, string: str, place: Exception) -> None: class Interpolator: """Configuration options may contain environment variables. - For example, suppose the shell contains ``VERIFIER_NAME=testinfra`` and - the following molecule.yml is supplied. - - ```yaml - verifier: - - name: ${VERIFIER_NAME} - ``` - - Molecule will substitute ``$VERIFIER_NAME`` with the value of the - ``VERIFIER_NAME`` environment variable. - - !!! warning - - If an environment variable is not set, Molecule substitutes with an - empty string. - Both ``$VARIABLE`` and ``${VARIABLE}`` syntax are supported. Extended shell-style features, such as ``${VARIABLE-default}`` and ``${VARIABLE:-default}`` are also supported. Even the default as another diff --git a/src/molecule/test/a_unit/cookiecutter/__init__.py b/src/molecule/test/a_unit/cookiecutter/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/molecule/test/a_unit/cookiecutter/test_molecule.py b/src/molecule/test/a_unit/cookiecutter/test_molecule.py deleted file mode 100644 index ee217a770..000000000 --- a/src/molecule/test/a_unit/cookiecutter/test_molecule.py +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright (c) 2015-2018 Cisco Systems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. - -import os - -import pytest - -from molecule.command.init import base - - -class CommandBase(base.Base): - """CommandBase Class.""" - - -@pytest.fixture() -def _base_class(): - return CommandBase - - -@pytest.fixture() -def _instance(_base_class): - return _base_class() - - -@pytest.fixture() -def _role_directory(): - return "." - - -@pytest.fixture() -def _command_args(): - return { - "dependency_name": "galaxy", - "driver_name": "default", - "provisioner_name": "ansible", - "scenario_name": "default", - "role_name": "test-role", - "verifier_name": "ansible", - } - - -@pytest.fixture() -def _molecule_file(_role_directory): - return os.path.join( - _role_directory, - "test-role", - "molecule", - "default", - "molecule.yml", - ) diff --git a/src/molecule/test/a_unit/driver/test_delegated.py b/src/molecule/test/a_unit/driver/test_delegated.py index 3e1b32cc7..bb49103e0 100644 --- a/src/molecule/test/a_unit/driver/test_delegated.py +++ b/src/molecule/test/a_unit/driver/test_delegated.py @@ -61,13 +61,6 @@ def test_config_private_member(_instance): assert isinstance(_instance._config, config.Config) -def test_testinfra_options_property(_instance): - assert { - "connection": "ansible", - "ansible-inventory": _instance._config.provisioner.inventory_directory, - } == _instance.testinfra_options - - def test_name_property(_instance): assert _instance.name == "default" diff --git a/src/molecule/test/a_unit/model/v2/test_verifier_section.py b/src/molecule/test/a_unit/model/v2/test_verifier_section.py index 688b9b148..b57b277e0 100644 --- a/src/molecule/test/a_unit/model/v2/test_verifier_section.py +++ b/src/molecule/test/a_unit/model/v2/test_verifier_section.py @@ -23,21 +23,6 @@ from molecule.model import schema_v3 -@pytest.fixture() -def _model_verifier_section_data(): - return { - "verifier": { - "name": "testinfra", - "enabled": True, - "directory": "foo", - "options": {"foo": "bar"}, - "env": {"FOO": "foo", "FOO_BAR": "foo_bar"}, - "additional_files_or_dirs": ["foo"], - }, - } - - -@pytest.mark.parametrize("_config", ["_model_verifier_section_data"], indirect=True) def test_verifier(_config): assert not schema_v3.validate(_config) @@ -62,11 +47,6 @@ def test_verifier_has_errors(_config): assert x == schema_v3.validate(_config) -@pytest.fixture() -def _model_verifier_allows_testinfra_section_data(): - return {"verifier": {"name": "testinfra"}} - - @pytest.fixture() def _model_verifier_allows_ansible_section_data(): return {"verifier": {"name": "ansible"}} @@ -75,7 +55,6 @@ def _model_verifier_allows_ansible_section_data(): @pytest.mark.parametrize( "_config", [ - ("_model_verifier_allows_testinfra_section_data"), ("_model_verifier_allows_ansible_section_data"), ], indirect=True, diff --git a/src/molecule/test/a_unit/test_api.py b/src/molecule/test/a_unit/test_api.py index bcf2d4d26..3f570b0f5 100644 --- a/src/molecule/test/a_unit/test_api.py +++ b/src/molecule/test/a_unit/test_api.py @@ -38,6 +38,6 @@ def test_api_drivers(): def test_api_verifiers(): - x = ["testinfra", "ansible"] + x = ["ansible"] assert all(elem in api.verifiers() for elem in x) diff --git a/src/molecule/test/a_unit/verifier/test_testinfra.py b/src/molecule/test/a_unit/verifier/test_testinfra.py deleted file mode 100644 index 379353e2f..000000000 --- a/src/molecule/test/a_unit/verifier/test_testinfra.py +++ /dev/null @@ -1,286 +0,0 @@ -# Copyright (c) 2015-2018 Cisco Systems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. - -import os - -import pytest - -from molecule import config, util -from molecule.verifier import testinfra - - -@pytest.fixture() -def _patched_testinfra_get_tests(mocker): - m = mocker.patch("molecule.verifier.testinfra.Testinfra._get_tests") - m.return_value = ["foo.py", "bar.py"] - - return m - - -@pytest.fixture() -def _verifier_section_data(): - return { - "verifier": { - "name": "testinfra", - "options": {"foo": "bar", "v": True, "verbose": True}, - "additional_files_or_dirs": ["file1.py", "file2.py", "match*.py", "dir/*"], - "env": {"FOO": "bar"}, - }, - } - - -# NOTE(retr0h): The use of the `patched_config_validate` fixture, disables -# config.Config._validate from executing. Thus preventing odd side-effects -# throughout patched.assert_called unit tests. -@pytest.fixture() -def _instance(patched_config_validate, config_instance: config.Config): - return testinfra.Testinfra(config_instance) - - -@pytest.fixture() -def inventory_file(_instance): - return _instance._config.provisioner.inventory_file - - -@pytest.fixture() -def inventory_directory(_instance): - return _instance._config.provisioner.inventory_directory - - -def test_config_private_member(_instance): - assert isinstance(_instance._config, config.Config) - - -def test_default_options_property(inventory_directory, _instance): - x = { - "connection": "ansible", - "ansible-inventory": inventory_directory, - "p": "no:cacheprovider", - } - - assert x == _instance.default_options - - -def test_default_options_property_updates_debug(inventory_directory, _instance): - _instance._config.args = {"debug": True} - x = { - "connection": "ansible", - "ansible-inventory": inventory_directory, - "debug": True, - "vvv": True, - "p": "no:cacheprovider", - } - - assert x == _instance.default_options - - -def test_default_options_property_updates_sudo( - inventory_directory, - _instance, - _patched_testinfra_get_tests, -): - _instance._config.args = {"sudo": True} - x = { - "connection": "ansible", - "ansible-inventory": inventory_directory, - "sudo": True, - "p": "no:cacheprovider", - } - - assert x == _instance.default_options - - -def test_default_env_property(_instance): - assert "MOLECULE_FILE" in _instance.default_env - assert "MOLECULE_INVENTORY_FILE" in _instance.default_env - assert "MOLECULE_SCENARIO_DIRECTORY" in _instance.default_env - assert "MOLECULE_INSTANCE_CONFIG" in _instance.default_env - - -@pytest.mark.parametrize("config_instance", ["_verifier_section_data"], indirect=True) -def test_additional_files_or_dirs_property(_instance): - tests_directory = _instance._config.verifier.directory - file1_file = os.path.join(tests_directory, "file1.py") - file2_file = os.path.join(tests_directory, "file2.py") - match1_file = os.path.join(tests_directory, "match1.py") - match2_file = os.path.join(tests_directory, "match2.py") - test_subdir = os.path.join(tests_directory, "dir") - test_subdir_file = os.path.join(test_subdir, "test_subdir_file.py") - - os.mkdir(tests_directory) - os.mkdir(test_subdir) - for f in [file1_file, file2_file, match1_file, match2_file, test_subdir_file]: - util.write_file(f, "") - - x = [file1_file, file2_file, match1_file, match2_file, test_subdir_file] - assert sorted(x) == sorted(_instance.additional_files_or_dirs) - - -@pytest.mark.parametrize("config_instance", ["_verifier_section_data"], indirect=True) -def test_env_property(_instance): - assert _instance.env["FOO"] == "bar" - assert "ANSIBLE_CONFIG" in _instance.env - assert "ANSIBLE_ROLES_PATH" in _instance.env - assert "ANSIBLE_LIBRARY" in _instance.env - assert "ANSIBLE_FILTER_PLUGINS" in _instance.env - - -def test_name_property(_instance): - assert _instance.name == "testinfra" - - -def test_enabled_property(_instance): - assert _instance.enabled - - -def test_directory_property(_instance): - parts = _instance.directory.split(os.path.sep) - - assert ["molecule", "default", "tests"] == parts[-3:] - - -@pytest.fixture() -def _verifier_testinfra_directory_section_data(): - return {"verifier": {"name": "testinfra", "directory": "/tmp/foo/bar"}} - - -@pytest.mark.parametrize( - "config_instance", - ["_verifier_testinfra_directory_section_data"], - indirect=True, -) -def test_directory_property_overridden(_instance): - assert _instance.directory == "/tmp/foo/bar" - - -@pytest.mark.parametrize("config_instance", ["_verifier_section_data"], indirect=True) -def test_options_property(inventory_directory, _instance): - x = { - "connection": "ansible", - "ansible-inventory": inventory_directory, - "foo": "bar", - "v": True, - "verbose": True, - "p": "no:cacheprovider", - } - - assert x == _instance.options - - -@pytest.mark.parametrize("config_instance", ["_verifier_section_data"], indirect=True) -def test_options_property_handles_cli_args(inventory_directory, _instance): - _instance._config.args = {"debug": True} - x = { - "connection": "ansible", - "ansible-inventory": inventory_directory, - "foo": "bar", - "debug": True, - "vvv": True, - "verbose": True, - "p": "no:cacheprovider", - } - - assert x == _instance.options - - -@pytest.mark.parametrize("config_instance", ["_verifier_section_data"], indirect=True) -def test_bake(_patched_testinfra_get_tests, inventory_directory, _instance): - _instance._tests = ["foo.py", "bar.py"] - _instance.bake() - args = [ - "pytest", - "--ansible-inventory", - inventory_directory, - "--connection", - "ansible", - "--foo", - "bar", - "-p", - "no:cacheprovider", - "foo.py", - "bar.py", - "-v", - ] - - assert _instance._testinfra_command == args - - -def test_execute( - caplog, - patched_run_command, - _patched_testinfra_get_tests, - _instance, -): - _instance.execute() - - patched_run_command.assert_called_once() - - msg = f"Executing Testinfra tests found in {_instance.directory}/..." - msg2 = "Verifier completed successfully." - assert msg in caplog.text - assert msg2 in caplog.text - assert "pytest" == patched_run_command.call_args[0][0][0] - - -def test_execute_does_not_execute( - patched_run_command, - caplog, - _instance, -): - _instance._config.config["verifier"]["enabled"] = False - _instance.execute() - - assert not patched_run_command.called - - msg = "Skipping, verifier is disabled." - assert msg in caplog.text - - -def test_does_not_execute_without_tests( - patched_run_command, - caplog, - _instance, -): - _instance.execute() - - assert not patched_run_command.called - - msg = "Skipping, no tests found." - assert msg in caplog.text - - -def test_execute_bakes(patched_run_command, _patched_testinfra_get_tests, _instance): - _instance.execute() - - assert _instance._testinfra_command is not None - - assert patched_run_command.call_count == 1 - - -def test_testinfra_executes_catches_and_exits_return_code( - patched_run_command, - _patched_testinfra_get_tests, - _instance, -): - patched_run_command.side_effect = SystemExit(1) - with pytest.raises(SystemExit) as e: - _instance.execute() - - assert e.value.code == 1 diff --git a/src/molecule/test/resources/schema_instance_files/valid/molecule.yml b/src/molecule/test/resources/schema_instance_files/valid/molecule.yml index 3bda50eb1..5d51fa645 100644 --- a/src/molecule/test/resources/schema_instance_files/valid/molecule.yml +++ b/src/molecule/test/resources/schema_instance_files/valid/molecule.yml @@ -68,4 +68,4 @@ scenario: - destroy verifier: - name: testinfra + name: ansible diff --git a/src/molecule/test/scenarios/.flake8 b/src/molecule/test/scenarios/.flake8 deleted file mode 100644 index a96838767..000000000 --- a/src/molecule/test/scenarios/.flake8 +++ /dev/null @@ -1,8 +0,0 @@ -[flake8] -# TODO(ssbarnea): Remove this file once we make entire codebase pydocstyle compliant -# Prevents tests failure when run on systems that have pytest-docstrings already installed, the other settings are copied from root version. - -# E203: https://github.com/python/black/issues/315 -ignore = D,E741,W503,W504,H,E501,E203 -# 88 is official black default: -max-line-length = 88 diff --git a/src/molecule/test/scenarios/cleanup/molecule/default/tests/test_cleanup.py b/src/molecule/test/scenarios/cleanup/molecule/default/tests/test_cleanup.py deleted file mode 100644 index e217d449b..000000000 --- a/src/molecule/test/scenarios/cleanup/molecule/default/tests/test_cleanup.py +++ /dev/null @@ -1,18 +0,0 @@ -"""Testinfra tests.""" - -import os - -import testinfra.utils.ansible_runner - -testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( - os.environ["MOLECULE_INVENTORY_FILE"], -).get_hosts("all") - - -def test_hosts_file(host): - """Validate host file.""" - f = host.file("/etc/hosts") - - assert f.exists - assert f.user == "root" - assert f.group == "root" diff --git a/src/molecule/test/scenarios/host_group_vars/molecule/links/converge.yml b/src/molecule/test/scenarios/host_group_vars/molecule/links/converge.yml deleted file mode 100644 index b149009b2..000000000 --- a/src/molecule/test/scenarios/host_group_vars/molecule/links/converge.yml +++ /dev/null @@ -1,15 +0,0 @@ ---- -- hosts: example - gather_facts: false - tasks: - - name: Host vars from host_vars links - ansible.builtin.debug: - var: host_group_vars_host_vars_linked - - - name: Group vars from group_vars links - ansible.builtin.debug: - var: host_group_vars_group_vars_linked - - - name: Variable from extra inventory link - ansible.builtin.debug: - var: hostvars['extra-host']['host_group_vars_extra_host_linked'] diff --git a/src/molecule/test/scenarios/host_group_vars/molecule/links/molecule.yml b/src/molecule/test/scenarios/host_group_vars/molecule/links/molecule.yml deleted file mode 100644 index 52356d03f..000000000 --- a/src/molecule/test/scenarios/host_group_vars/molecule/links/molecule.yml +++ /dev/null @@ -1,23 +0,0 @@ ---- -dependency: - name: galaxy -driver: - name: default -platforms: - - name: instance - image: ${TEST_BASE_IMAGE} - groups: - - example - children: - - example_1 -provisioner: - name: ansible - inventory: - links: - hosts: ../../hosts - host_vars: ../../host_vars - group_vars: ../../group_vars -scenario: - name: links -verifier: - name: testinfra diff --git a/src/molecule/test/scenarios/side_effect/molecule/default/tests/test_side_effect.py b/src/molecule/test/scenarios/side_effect/molecule/default/tests/test_side_effect.py index d4e179b0e..40a5ed59d 100644 --- a/src/molecule/test/scenarios/side_effect/molecule/default/tests/test_side_effect.py +++ b/src/molecule/test/scenarios/side_effect/molecule/default/tests/test_side_effect.py @@ -1,13 +1,5 @@ """Testinfra tests.""" -import os - -import testinfra.utils.ansible_runner - -testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( - os.environ["MOLECULE_INVENTORY_FILE"], -).get_hosts("all") - def test_side_effect_removed_file(host): """Validate that file was removed.""" diff --git a/src/molecule/test/scenarios/test_destroy_strategy/molecule/default/tests/test_destroy_strategy.py b/src/molecule/test/scenarios/test_destroy_strategy/molecule/default/tests/test_destroy_strategy.py index 3fd003e17..ddfc4fe80 100644 --- a/src/molecule/test/scenarios/test_destroy_strategy/molecule/default/tests/test_destroy_strategy.py +++ b/src/molecule/test/scenarios/test_destroy_strategy/molecule/default/tests/test_destroy_strategy.py @@ -1,13 +1,5 @@ """Testinfra tests.""" -import os - -import testinfra.utils.ansible_runner - -testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( - os.environ["MOLECULE_INVENTORY_FILE"], -).get_hosts("all") - def test_hostname(host): """Validate hostname.""" diff --git a/src/molecule/test/scenarios/verifier/.pre-commit-config.yaml b/src/molecule/test/scenarios/verifier/.pre-commit-config.yaml deleted file mode 100644 index ce9e96bd9..000000000 --- a/src/molecule/test/scenarios/verifier/.pre-commit-config.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -repos: - - repo: local - hooks: - - id: flake8 - name: flake8 - entry: python -m flake8 --max-line-length=120 - language: system - types: [python] diff --git a/src/molecule/test/scenarios/verifier/molecule/testinfra-pre-commit/converge.yml b/src/molecule/test/scenarios/verifier/molecule/testinfra-pre-commit/converge.yml deleted file mode 100644 index 8ad426dc0..000000000 --- a/src/molecule/test/scenarios/verifier/molecule/testinfra-pre-commit/converge.yml +++ /dev/null @@ -1,19 +0,0 @@ ---- -- name: Converge - hosts: all - tasks: - - name: Create /tmp/molecule - ansible.builtin.file: - dest: /etc/molecule - group: root - owner: root - mode: 0755 - state: directory - - - name: Create /etc/molecule/{{ ansible_hostname }} - ansible.builtin.copy: - dest: "/etc/molecule/{{ ansible_hostname }}" - group: root - owner: root - mode: 0644 - content: "{{ ansible_hostname }}" diff --git a/src/molecule/test/scenarios/verifier/molecule/testinfra-pre-commit/molecule.yml b/src/molecule/test/scenarios/verifier/molecule/testinfra-pre-commit/molecule.yml deleted file mode 100644 index 016c3b00c..000000000 --- a/src/molecule/test/scenarios/verifier/molecule/testinfra-pre-commit/molecule.yml +++ /dev/null @@ -1,18 +0,0 @@ ---- -dependency: - name: galaxy -driver: - name: default -platforms: - - name: instance - image: ${TEST_BASE_IMAGE} -provisioner: - name: ansible -scenario: - name: testinfra-pre-commit -verifier: - name: testinfra - options: - vvv: true - additional_files_or_dirs: - - ../shared/test_*.py diff --git a/src/molecule/test/scenarios/verifier/molecule/testinfra-pre-commit/tests/test_testinfra_pre_commit.py b/src/molecule/test/scenarios/verifier/molecule/testinfra-pre-commit/tests/test_testinfra_pre_commit.py deleted file mode 100644 index 5a55ce3f6..000000000 --- a/src/molecule/test/scenarios/verifier/molecule/testinfra-pre-commit/tests/test_testinfra_pre_commit.py +++ /dev/null @@ -1,7 +0,0 @@ -"""Testinfra tests.""" - - -def test_ansible_hostname(host): - """Validate hostname.""" - f = host.file("/tmp/molecule/instance-1") - assert not f.exists diff --git a/src/molecule/test/scenarios/verifier/molecule/testinfra/converge.yml b/src/molecule/test/scenarios/verifier/molecule/testinfra/converge.yml deleted file mode 100644 index 834b62129..000000000 --- a/src/molecule/test/scenarios/verifier/molecule/testinfra/converge.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -- name: Converge - gather_facts: false - hosts: all - roles: - - molecule diff --git a/src/molecule/test/scenarios/verifier/molecule/testinfra/molecule.yml b/src/molecule/test/scenarios/verifier/molecule/testinfra/molecule.yml deleted file mode 100644 index 441463854..000000000 --- a/src/molecule/test/scenarios/verifier/molecule/testinfra/molecule.yml +++ /dev/null @@ -1,20 +0,0 @@ ---- -dependency: - name: galaxy -driver: - name: default -platforms: - - name: instance - image: ${TEST_BASE_IMAGE} -provisioner: - name: ansible - env: - ANSIBLE_ROLES_PATH: ../../../../resources/roles/ -scenario: - name: testinfra -verifier: - name: testinfra - options: - vvv: true - additional_files_or_dirs: - - ../shared/test_*.py diff --git a/src/molecule/test/scenarios/verifier/molecule/testinfra/shared/test_shared.py b/src/molecule/test/scenarios/verifier/molecule/testinfra/shared/test_shared.py deleted file mode 100644 index 09996eaf7..000000000 --- a/src/molecule/test/scenarios/verifier/molecule/testinfra/shared/test_shared.py +++ /dev/null @@ -1,16 +0,0 @@ -"""Testinfra tests.""" - -import os - -import testinfra.utils.ansible_runner - -testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( - os.environ["MOLECULE_INVENTORY_FILE"], -).get_hosts("all") - - -def test_ansible_hostname(host): - """Validate hostname.""" - f = host.file("/tmp/molecule/instance-1") - - assert not f.exists diff --git a/src/molecule/test/scenarios/verifier/molecule/testinfra/tests/test_testinfra.py b/src/molecule/test/scenarios/verifier/molecule/testinfra/tests/test_testinfra.py deleted file mode 100644 index 09996eaf7..000000000 --- a/src/molecule/test/scenarios/verifier/molecule/testinfra/tests/test_testinfra.py +++ /dev/null @@ -1,16 +0,0 @@ -"""Testinfra tests.""" - -import os - -import testinfra.utils.ansible_runner - -testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( - os.environ["MOLECULE_INVENTORY_FILE"], -).get_hosts("all") - - -def test_ansible_hostname(host): - """Validate hostname.""" - f = host.file("/tmp/molecule/instance-1") - - assert not f.exists diff --git a/src/molecule/verifier/testinfra.py b/src/molecule/verifier/testinfra.py deleted file mode 100644 index ce3819c44..000000000 --- a/src/molecule/verifier/testinfra.py +++ /dev/null @@ -1,224 +0,0 @@ -# Copyright (c) 2015-2018 Cisco Systems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. -"""Testinfra Verifier Module.""" - -import glob -import logging -import os - -from molecule import util -from molecule.api import Verifier - -LOG = logging.getLogger(__name__) - - -class Testinfra(Verifier): - """`Testinfra`_ is no longer the default test verifier since version 3.0. - - Additional options can be passed to ``testinfra`` through the options - dict. Any option set in this section will override the defaults. - - !!! note - - Molecule will remove any options matching '^[v]+$', and pass ``-vvv`` - to the underlying ``pytest`` command when executing ``molecule - --debug``. - - ``` yaml - verifier: - name: testinfra - options: - n: 1 - ``` - - The testing can be disabled by setting ``enabled`` to False. - - ``` yaml - verifier: - name: testinfra - enabled: False - ``` - - Environment variables can be passed to the verifier. - - ``` yaml - verifier: - name: testinfra - env: - FOO: bar - ``` - - Change path to the test directory. - - ``` yaml - verifier: - name: testinfra - directory: /foo/bar/ - ``` - - Additional tests from another file or directory relative to the scenario's - tests directory (supports regexp). - - ``` yaml - verifier: - name: testinfra - additional_files_or_dirs: - - ../path/to/test_1.py - - ../path/to/test_2.py - - ../path/to/directory/* - ``` - .. _`Testinfra`: https://testinfra.readthedocs.io - """ - - def __init__(self, config=None) -> None: - """Set up the requirements to execute ``testinfra`` and returns None. - - :param config: An instance of a Molecule config. - :return: None - """ - super().__init__(config) - self._testinfra_command = None - self._tests = [] # type: ignore - - @property - def name(self): - return "testinfra" - - @property - def default_options(self): - d = self._config.driver.testinfra_options - d["p"] = "no:cacheprovider" - if self._config.debug: - d["debug"] = True - d["vvv"] = True - if self._config.args.get("sudo"): - d["sudo"] = True - - return d - - # NOTE(retr0h): Override the base classes' options() to handle - # ``ansible-galaxy`` one-off. - @property - def options(self): - o = self._config.config["verifier"]["options"] - # NOTE(retr0h): Remove verbose options added by the user while in - # debug. - if self._config.debug: - o = util.filter_verbose_permutation(o) - - return util.merge_dicts(self.default_options, o) - - @property - def default_env(self): - env = util.merge_dicts(os.environ, self._config.env) - env = util.merge_dicts(env, self._config.provisioner.env) - - return env - - @property - def additional_files_or_dirs(self): - files_list = [] - c = self._config.config - for f in c["verifier"]["additional_files_or_dirs"]: - glob_path = os.path.join(self._config.verifier.directory, f) - glob_list = glob.glob(glob_path) - if glob_list: - files_list.extend(glob_list) - - return files_list - - def bake(self): - """Bake a ``testinfra`` command so it's ready to execute and returns None. - - :return: None - """ - options = self.options - verbose_flag = util.verbose_flag(options) - args = verbose_flag - - self._testinfra_command = [ - "pytest", - *util.dict2args(options), - *self._tests, - *args, - ] - - def execute(self, action_args=None): - if not self.enabled: - msg = "Skipping, verifier is disabled." - LOG.warning(msg) - return - - if self._config: - self._tests = self._get_tests(action_args) - else: - self._tests = [] - if not len(self._tests) > 0: - msg = "Skipping, no tests found." - LOG.warning(msg) - return - - self.bake() - - msg = f"Executing Testinfra tests found in {self.directory}/..." - LOG.info(msg) - - result = util.run_command(self._testinfra_command, debug=self._config.debug) - if result.returncode == 0: - msg = "Verifier completed successfully." - LOG.info(msg) - else: - util.sysexit(result.returncode) - - def _get_tests(self, action_args=None): - """Walk the verifier's directory for tests and returns a list. - - :return: list - """ - if action_args: - tests = [] - for arg in action_args: - args_tests = list( - util.os_walk( - os.path.join(self._config.scenario.directory, arg), - "test_*.py", - followlinks=True, - ), - ) - tests.extend(args_tests) - return sorted(tests) - return sorted( - list( - util.os_walk( - self.directory, - "test_*.py", - followlinks=True, - ), - ) - + self.additional_files_or_dirs, - ) - - def schema(self): - return { - "verifier": { - "type": "dict", - "schema": {"name": {"type": "string", "allowed": ["testinfra"]}}, - }, - }