summaryrefslogtreecommitdiffstats
path: root/test/test_skiputils.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_skiputils.py')
-rw-r--r--test/test_skiputils.py230
1 files changed, 230 insertions, 0 deletions
diff --git a/test/test_skiputils.py b/test/test_skiputils.py
new file mode 100644
index 0000000..5aff266
--- /dev/null
+++ b/test/test_skiputils.py
@@ -0,0 +1,230 @@
+"""Validate ansiblelint.skip_utils."""
+from __future__ import annotations
+
+from pathlib import Path
+from typing import TYPE_CHECKING, Any
+
+import pytest
+
+from ansiblelint.constants import SKIPPED_RULES_KEY
+from ansiblelint.file_utils import Lintable
+from ansiblelint.skip_utils import (
+ append_skipped_rules,
+ get_rule_skips_from_line,
+ is_nested_task,
+)
+from ansiblelint.testing import RunFromText
+
+if TYPE_CHECKING:
+ from ansible.parsing.yaml.objects import AnsibleBaseYAMLObject
+
+PLAYBOOK_WITH_NOQA = """\
+---
+- name: Fixture
+ hosts: all
+ vars:
+ SOME_VAR_NOQA: "Foo" # noqa: var-naming
+ SOME_VAR: "Bar"
+ tasks:
+ - name: "Set the SOME_OTHER_VAR"
+ ansible.builtin.set_fact:
+ SOME_OTHER_VAR_NOQA: "Baz" # noqa: var-naming
+ SOME_OTHER_VAR: "Bat"
+"""
+
+
+@pytest.mark.parametrize(
+ ("line", "expected"),
+ (
+ ("foo # noqa: bar", "bar"),
+ ("foo # noqa bar", "bar"),
+ ),
+)
+def test_get_rule_skips_from_line(line: str, expected: str) -> None:
+ """Validate get_rule_skips_from_line."""
+ v = get_rule_skips_from_line(line)
+ assert v == [expected]
+
+
+def test_playbook_noqa(default_text_runner: RunFromText) -> None:
+ """Check that noqa is properly taken into account on vars and tasks."""
+ results = default_text_runner.run_playbook(PLAYBOOK_WITH_NOQA)
+ # Should raise error at "SOME_VAR".
+ assert len(results) == 1
+
+
+def test_playbook_noqa2(default_text_runner: RunFromText) -> None:
+ """Check that noqa is properly taken into account on vars and tasks."""
+ results = default_text_runner.run_playbook(PLAYBOOK_WITH_NOQA, "test")
+ # Should raise error at "SOME_VAR".
+ assert len(results) == 1
+
+
+@pytest.mark.parametrize(
+ ("lintable", "yaml", "expected_form"),
+ (
+ pytest.param(
+ Lintable("examples/playbooks/noqa.yml", kind="playbook"),
+ [
+ {
+ "hosts": "localhost",
+ "tasks": [
+ {
+ "name": "This would typically fire latest[git] and partial-become",
+ "become_user": "alice",
+ "git": "src=/path/to/git/repo dest=checkout",
+ "__line__": 4,
+ "__file__": Path("examples/playbooks/noqa.yml"),
+ }
+ ],
+ "__line__": 2,
+ "__file__": Path("examples/playbooks/noqa.yml"),
+ }
+ ],
+ [
+ {
+ "hosts": "localhost",
+ "tasks": [
+ {
+ "name": "This would typically fire latest[git] and partial-become",
+ "become_user": "alice",
+ "git": "src=/path/to/git/repo dest=checkout",
+ "__line__": 4,
+ "__file__": Path("examples/playbooks/noqa.yml"),
+ SKIPPED_RULES_KEY: ["latest[git]", "partial-become"],
+ }
+ ],
+ "__line__": 2,
+ "__file__": Path("examples/playbooks/noqa.yml"),
+ }
+ ],
+ ),
+ pytest.param(
+ Lintable("examples/playbooks/noqa-nested.yml", kind="playbook"),
+ [
+ {
+ "hosts": "localhost",
+ "tasks": [
+ {
+ "name": "Example of multi-level block",
+ "block": [
+ {
+ "name": "2nd level",
+ "block": [
+ {
+ "ansible.builtin.debug": {
+ "msg": "Test unnamed task in block",
+ "__line__": 9,
+ "__file__": Path(
+ "examples/playbooks/noqa-nested.yml"
+ ),
+ },
+ "__line__": 8,
+ "__file__": Path(
+ "examples/playbooks/noqa-nested.yml"
+ ),
+ }
+ ],
+ "__line__": 6,
+ "__file__": Path(
+ "examples/playbooks/noqa-nested.yml"
+ ),
+ }
+ ],
+ "__line__": 4,
+ "__file__": Path("examples/playbooks/noqa-nested.yml"),
+ }
+ ],
+ "__line__": 2,
+ "__file__": Path("examples/playbooks/noqa-nested.yml"),
+ }
+ ],
+ [
+ {
+ "hosts": "localhost",
+ "tasks": [
+ {
+ "name": "Example of multi-level block",
+ "block": [
+ {
+ "name": "2nd level",
+ "block": [
+ {
+ "ansible.builtin.debug": {
+ "msg": "Test unnamed task in block",
+ "__line__": 9,
+ "__file__": Path(
+ "examples/playbooks/noqa-nested.yml"
+ ),
+ },
+ "__line__": 8,
+ "__file__": Path(
+ "examples/playbooks/noqa-nested.yml"
+ ),
+ SKIPPED_RULES_KEY: ["name[missing]"],
+ }
+ ],
+ "__line__": 6,
+ "__file__": Path(
+ "examples/playbooks/noqa-nested.yml"
+ ),
+ SKIPPED_RULES_KEY: ["name[missing]"],
+ }
+ ],
+ "__line__": 4,
+ "__file__": Path("examples/playbooks/noqa-nested.yml"),
+ SKIPPED_RULES_KEY: ["name[missing]"],
+ }
+ ],
+ "__line__": 2,
+ "__file__": Path("examples/playbooks/noqa-nested.yml"),
+ }
+ ],
+ ),
+ ),
+)
+def test_append_skipped_rules(
+ lintable: Lintable,
+ yaml: AnsibleBaseYAMLObject,
+ expected_form: AnsibleBaseYAMLObject,
+) -> None:
+ """Check that it appends skipped_rules properly."""
+ assert append_skipped_rules(yaml, lintable) == expected_form
+
+
+@pytest.mark.parametrize(
+ ("task", "expected"),
+ (
+ pytest.param(
+ {
+ "name": "ensure apache is at the latest version",
+ "yum": {"name": "httpd", "state": "latest"},
+ },
+ False,
+ ),
+ pytest.param(
+ {
+ "name": "Attempt and graceful roll back",
+ "block": [
+ {"name": "Force a failure", "ansible.builtin.command": "/bin/false"}
+ ],
+ "rescue": [
+ {
+ "name": "Force a failure in middle of recovery!",
+ "ansible.builtin.command": "/bin/false",
+ }
+ ],
+ "always": [
+ {
+ "name": "Always do this",
+ "ansible.builtin.debug": {"msg": "This always executes"},
+ }
+ ],
+ },
+ True,
+ ),
+ ),
+)
+def test_is_nested_task(task: dict[str, Any], expected: bool) -> None:
+ """Test is_nested_task() returns expected bool."""
+ assert is_nested_task(task) == expected