diff --git a/.gitignore b/.gitignore index 35199b42..6187e7c5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,10 @@ +# molecule +# Remove the following once tox-ansible is molecule aware +# molecule/ +# !molecule/default/ +# !molecule/resources/ +# !molecule/.env.yml + # sanity artifacts tests/output/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 00b5af3c..bfe0aa1b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -85,8 +85,7 @@ repos: additional_dependencies: - ansible-core - pytest - - tox - - git+https://github.com/ansible-network/pytest-ansible-network-integration.git + - pytest-ansible - repo: https://github.com/pre-commit/mirrors-mypy.git rev: v1.3.0 diff --git a/.vscode/settings.json b/.vscode/settings.json index 5833b1ae..eb6042c4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,6 +11,7 @@ "python.linting.mypyEnabled": true, "prettier.enable": true, "python.testing.pytestArgs": [ + "--capture=fd", "tests" ], "python.testing.unittestEnabled": false, diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5ad3d1b2..5d92f8ae 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,6 +5,9 @@ The Ansible SCM (ansible.scm) Collection Release Notes .. contents:: Topics +v1.1.1 +====== + v1.1.0 ====== diff --git a/changelogs/.plugin-cache.yaml b/changelogs/.plugin-cache.yaml index 61881b18..0c67ab4e 100644 --- a/changelogs/.plugin-cache.yaml +++ b/changelogs/.plugin-cache.yaml @@ -27,4 +27,4 @@ plugins: shell: {} strategy: {} vars: {} -version: 1.1.0 +version: 1.1.1 diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 203ff6bf..058191ac 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -1,6 +1,9 @@ --- ancestor: releases: + 1.1.1: + changes: {} + release_date: "2023-08-01" 1.1.0: changes: minor_changes: diff --git a/extensions/molecule/default/create.yml b/extensions/molecule/default/create.yml new file mode 100644 index 00000000..192c19e0 --- /dev/null +++ b/extensions/molecule/default/create.yml @@ -0,0 +1,39 @@ +- name: Default create playbook + hosts: localhost + gather_facts: false + vars_files: + - ../resources/vars/vars.yml + tasks: + - name: Find integration test targets + ansible.builtin.find: + file_type: directory + paths: "{{ integration_tests_path }}" + recurse: false + register: _targets + + - name: Create directories + ansible.builtin.file: + path: "{{ directory }}" + state: directory + mode: "0700" + loop: "{{ _targets.files }}" + loop_control: + loop_var: target + label: "{{ directory }}" + vars: + directory: "../integration_{{ target.path | basename }}" + + - name: Copy the template vars_files + ansible.builtin.template: + src: "{{ source }}" + dest: "{{ destination }}" + mode: "0600" + loop: "{{ _targets.files | product(files) | list }}" + loop_control: + loop_var: product + label: "{{ destination }}" + vars: + source: "{{ product[1] }}" + destination: "../integration_{{ product[0].path | basename }}/{{ product[1] | basename }}" + files: + - ../resources/templates/molecule.yml diff --git a/extensions/molecule/default/molecule.yml b/extensions/molecule/default/molecule.yml new file mode 100644 index 00000000..6c36cce8 --- /dev/null +++ b/extensions/molecule/default/molecule.yml @@ -0,0 +1,16 @@ +platforms: + - name: na + +provisioner: + name: ansible + playbooks: + destroy: ../resources/playbooks/noop.yml + prepare: ../resources/playbooks/noop.yml + +scenario: + create_sequence: + - create + test_sequence: + - prepare + destroy_sequence: + - destroy diff --git a/extensions/molecule/integration_failure/molecule.yml b/extensions/molecule/integration_failure/molecule.yml new file mode 100644 index 00000000..63b109cd --- /dev/null +++ b/extensions/molecule/integration_failure/molecule.yml @@ -0,0 +1,19 @@ +platforms: + - name: na + +provisioner: + name: ansible + playbooks: + cleanup: ../resources/playbooks/noop.yml + converge: ../resources/playbooks/converge.yml + destroy: ../resources/playbooks/noop.yml + prepare: ../resources/playbooks/noop.yml + config_options: + defaults: + collections_path: ${ANSIBLE_COLLECTIONS_PATH} +scenario: + test_sequence: + - prepare + - converge + destroy_sequence: + - destroy diff --git a/extensions/molecule/integration_key_checking/molecule.yml b/extensions/molecule/integration_key_checking/molecule.yml new file mode 100644 index 00000000..63b109cd --- /dev/null +++ b/extensions/molecule/integration_key_checking/molecule.yml @@ -0,0 +1,19 @@ +platforms: + - name: na + +provisioner: + name: ansible + playbooks: + cleanup: ../resources/playbooks/noop.yml + converge: ../resources/playbooks/converge.yml + destroy: ../resources/playbooks/noop.yml + prepare: ../resources/playbooks/noop.yml + config_options: + defaults: + collections_path: ${ANSIBLE_COLLECTIONS_PATH} +scenario: + test_sequence: + - prepare + - converge + destroy_sequence: + - destroy diff --git a/extensions/molecule/integration_success/molecule.yml b/extensions/molecule/integration_success/molecule.yml new file mode 100644 index 00000000..63b109cd --- /dev/null +++ b/extensions/molecule/integration_success/molecule.yml @@ -0,0 +1,19 @@ +platforms: + - name: na + +provisioner: + name: ansible + playbooks: + cleanup: ../resources/playbooks/noop.yml + converge: ../resources/playbooks/converge.yml + destroy: ../resources/playbooks/noop.yml + prepare: ../resources/playbooks/noop.yml + config_options: + defaults: + collections_path: ${ANSIBLE_COLLECTIONS_PATH} +scenario: + test_sequence: + - prepare + - converge + destroy_sequence: + - destroy diff --git a/extensions/molecule/integration_user_dir/molecule.yml b/extensions/molecule/integration_user_dir/molecule.yml new file mode 100644 index 00000000..63b109cd --- /dev/null +++ b/extensions/molecule/integration_user_dir/molecule.yml @@ -0,0 +1,19 @@ +platforms: + - name: na + +provisioner: + name: ansible + playbooks: + cleanup: ../resources/playbooks/noop.yml + converge: ../resources/playbooks/converge.yml + destroy: ../resources/playbooks/noop.yml + prepare: ../resources/playbooks/noop.yml + config_options: + defaults: + collections_path: ${ANSIBLE_COLLECTIONS_PATH} +scenario: + test_sequence: + - prepare + - converge + destroy_sequence: + - destroy diff --git a/extensions/molecule/resources/playbooks/converge.yml b/extensions/molecule/resources/playbooks/converge.yml new file mode 100644 index 00000000..990d024e --- /dev/null +++ b/extensions/molecule/resources/playbooks/converge.yml @@ -0,0 +1,16 @@ +--- +- name: Shared integration test runner + hosts: localhost + gather_facts: false + + tasks: + - name: Load the vars + ansible.builtin.include_vars: + file: ../../resources/vars/vars.yml + + - name: "Integration test: {{ test_name }}" + ansible.builtin.include_role: + name: "{{ test_path }}" + vars: + test_path: "{{ integration_tests_path }}{{ test_name }}" + test_name: "{{ molecule_scenario_name.replace('integration_', '') }}" diff --git a/extensions/molecule/resources/playbooks/noop.yml b/extensions/molecule/resources/playbooks/noop.yml new file mode 100644 index 00000000..3d152a9b --- /dev/null +++ b/extensions/molecule/resources/playbooks/noop.yml @@ -0,0 +1,4 @@ +- name: noop + hosts: localhost + gather_facts: false + tasks: diff --git a/extensions/molecule/resources/templates/molecule.yml b/extensions/molecule/resources/templates/molecule.yml new file mode 100644 index 00000000..63b109cd --- /dev/null +++ b/extensions/molecule/resources/templates/molecule.yml @@ -0,0 +1,19 @@ +platforms: + - name: na + +provisioner: + name: ansible + playbooks: + cleanup: ../resources/playbooks/noop.yml + converge: ../resources/playbooks/converge.yml + destroy: ../resources/playbooks/noop.yml + prepare: ../resources/playbooks/noop.yml + config_options: + defaults: + collections_path: ${ANSIBLE_COLLECTIONS_PATH} +scenario: + test_sequence: + - prepare + - converge + destroy_sequence: + - destroy diff --git a/extensions/molecule/resources/vars/vars.yml b/extensions/molecule/resources/vars/vars.yml new file mode 100644 index 00000000..ca6f25a6 --- /dev/null +++ b/extensions/molecule/resources/vars/vars.yml @@ -0,0 +1,3 @@ +collection_root: "{{ lookup( 'pipe', 'git rev-parse --show-toplevel') }}" +integration_tests_path: "{{ collection_root }}/tests/integration/targets/" +molecule_scenario_name: "{{ molecule_scenario_directory | basename }}" diff --git a/galaxy.yml b/galaxy.yml index 0fff02c3..2a0e5dcc 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -22,7 +22,7 @@ tags: - storage - tools - windows -version: 1.1.0 +version: 1.1.1 build_ignore: - .github - .gitignore diff --git a/mypy.ini b/mypy.ini index cd56a58f..30b8aa8f 100644 --- a/mypy.ini +++ b/mypy.ini @@ -21,8 +21,8 @@ ignore_missing_imports = true # No type hints as of version 2.6.1 ignore_missing_imports = true -[mypy-pytest_ansible_network_integration] -# No type hints as of 6/8/2022 +[mypy-pytest_ansible.*] +# No type hints as of 8/7/2023 ignore_missing_imports = true [mypy-ansible_collections.*] diff --git a/pyproject.toml b/pyproject.toml index 4f897cc8..da151d32 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,12 +30,11 @@ enable = [ ] +# Run with xdist 1 until molecule has shared scenario state [tool.pytest.ini_options] addopts = [ - "--integration-tests-path=tests/integration/targets", - "-vvv", "-n", - "2", + "1", "--log-level", "WARNING", "--color", @@ -69,8 +68,9 @@ target-version = "py38" # S603, subprocess ok "plugins/plugin_utils/git_base.py" = ["S603"] # +# S101 allow assert in tests # T201 allow print in tests -"tests/**" = ["T201"] +"tests/**" = ["S101", "T201"] # # UP001 until __metaclass__ is not required # UP010 until from __future__ is gone diff --git a/test-requirements.txt b/test-requirements.txt index 58d0ba24..a0a90047 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,5 +1,6 @@ black -git+https://github.com/ansible-network/pytest-ansible-network-integration.git +molecule ; python_version < '3.9' +molecule==v6.0.0b0 ; python_version > '3.8' mypy pre-commit pylint diff --git a/tests/integration/targets/timeout/tasks/main.yaml b/tests/integration/targets/failure/tasks/main.yaml similarity index 66% rename from tests/integration/targets/timeout/tasks/main.yaml rename to tests/integration/targets/failure/tasks/main.yaml index 2ebdc484..dd337d01 100644 --- a/tests/integration/targets/timeout/tasks/main.yaml +++ b/tests/integration/targets/failure/tasks/main.yaml @@ -7,8 +7,7 @@ register: repository ignore_errors: true -- name: Confirm the timeout return code and message +- name: Confirm the return code and message ansible.builtin.assert: that: - - repository["output"][0]["return_code"] == 62 - - repository["msg"].startswith("Timeout:") + - repository["output"][0]["return_code"] != 0 diff --git a/tests/integration/test_integration.py b/tests/integration/test_integration.py index d5d181f0..ddb7a347 100644 --- a/tests/integration/test_integration.py +++ b/tests/integration/test_integration.py @@ -1,66 +1,13 @@ -"""Run the integration tests.""" +"""Tests for molecule scenarios.""" from __future__ import absolute_import, division, print_function -import subprocess +from pytest_ansible.molecule import MoleculeScenario -from typing import Dict -import pytest +def test_integration(molecule_scenario: MoleculeScenario) -> None: + """Run molecule for each scenario. -from pytest_ansible_network_integration import AnsibleProject - - -# pylint: disable=invalid-name -__metaclass__ = type -# pylint: enable=invalid-name - - -def run(localhost_project: AnsibleProject, environment: Dict[str, str]) -> None: - """Run the integration tests. - - :param localhost_project: The localhost project. - :param environment: The environment. - """ - __tracebackhide__ = True # pylint: disable=unused-variable - args = [ - "ansible-navigator", - "run", - str(localhost_project.playbook), - "--ee", - "false", - "--mode", - "stdout", - "--pas", - str(localhost_project.playbook_artifact), - "--ll", - "debug", - "--lf", - str(localhost_project.log_file), - "--cdcp", - str(localhost_project.collection_doc_cache), - "-vvvv", - ] - process = subprocess.run( - args=args, - env=environment, - capture_output=True, - check=False, - shell=False, - ) - if process.returncode: - print(process.stdout.decode("utf-8")) - print(process.stderr.decode("utf-8")) - - pytest.fail(msg=f"Integration test failed: {localhost_project.role}") - - -def test_integration( - localhost_project: AnsibleProject, - environment: Dict[str, str], -) -> None: - """Run the integration tests. - - :param localhost_project: The localhost project. - :param environment: The environment. + :param molecule_scenario: The molecule scenario object """ - run(localhost_project, environment) + proc = molecule_scenario.test() + assert proc.returncode == 0 diff --git a/tox-ansible.ini b/tox-ansible.ini index 48064422..be869e37 100644 --- a/tox-ansible.ini +++ b/tox-ansible.ini @@ -2,3 +2,4 @@ skip = py3.7 + 2.9 # molecule is >= 2.12