Skip to content

Commit

Permalink
Simplify transformer testing (#3820)
Browse files Browse the repository at this point in the history
  • Loading branch information
ssbarnea authored Oct 9, 2023
1 parent 1ede26a commit 5ca5679
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 86 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,4 @@ test/schemas/node_modules
collections
site
_readthedocs
*.tmp.*
10 changes: 8 additions & 2 deletions src/ansiblelint/file_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,10 +371,16 @@ def write(self, *, force: bool = False) -> None:
lintable.write(force=True)
"""
if not force and not self.updated:
dump_filename = self.path.expanduser().resolve()
if os.environ.get("ANSIBLE_LINT_WRITE_TMP", "0") == "1":
dump_filename = dump_filename.with_suffix(
f".tmp{dump_filename.suffix}",
)
elif not force and not self.updated:
# No changes to write.
return
self.path.expanduser().resolve().write_text(

dump_filename.write_text(
self._content or "",
encoding="utf-8",
)
Expand Down
33 changes: 17 additions & 16 deletions src/ansiblelint/rules/deprecated_local_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@

import copy
import logging
import os
import sys
from pathlib import Path
from typing import TYPE_CHECKING

from ansiblelint.rules import AnsibleLintRule, TransformMixin
from ansiblelint.runner import get_matches
from ansiblelint.transformer import Transformer

if TYPE_CHECKING:
from pathlib import Path

from ruamel.yaml.comments import CommentedMap, CommentedSeq

from ansiblelint.config import Options
Expand Down Expand Up @@ -84,6 +84,8 @@ def transform(

# testing code to be loaded only with pytest or when executed the rule file
if "pytest" in sys.modules:
from unittest import mock

from ansiblelint.rules import RulesCollection
from ansiblelint.runner import Runner

Expand All @@ -97,34 +99,33 @@ def test_local_action(default_rules_collection: RulesCollection) -> None:
assert len(results) == 1
assert results[0].tag == "deprecated-local-action"

@mock.patch.dict(os.environ, {"ANSIBLE_LINT_WRITE_TMP": "1"}, clear=True)
def test_local_action_transform(
config_options: Options,
copy_examples_dir: tuple[Path, Path],
default_rules_collection: RulesCollection,
) -> None:
"""Test transform functionality for no-log-password rule."""
playbook: str = "examples/playbooks/tasks/local_action.yml"
playbook = Path("examples/playbooks/tasks/local_action.yml")
config_options.write_list = ["all"]

config_options.lintables = [playbook]
config_options.lintables = [str(playbook)]
runner_result = get_matches(
rules=default_rules_collection,
options=config_options,
)
transformer = Transformer(result=runner_result, options=config_options)
transformer.run()

matches = runner_result.matches
assert len(matches) == 3

orig_dir, tmp_dir = copy_examples_dir
orig_playbook = orig_dir / playbook
expected_playbook = orig_dir / playbook.replace(".yml", ".transformed.yml")
transformed_playbook = tmp_dir / playbook

orig_playbook_content = orig_playbook.read_text()
expected_playbook_content = expected_playbook.read_text()
transformed_playbook_content = transformed_playbook.read_text()
orig_content = playbook.read_text(encoding="utf-8")
expected_content = playbook.with_suffix(
f".transformed{playbook.suffix}",
).read_text(encoding="utf-8")
transformed_content = playbook.with_suffix(f".tmp{playbook.suffix}").read_text(
encoding="utf-8",
)

assert orig_playbook_content != transformed_playbook_content
assert transformed_playbook_content == expected_playbook_content
assert orig_content != transformed_content
assert expected_content == transformed_content
playbook.with_suffix(f".tmp{playbook.suffix}").unlink()
29 changes: 16 additions & 13 deletions src/ansiblelint/rules/jinja.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from __future__ import annotations

import logging
import os
import re
import sys
from dataclasses import dataclass
Expand Down Expand Up @@ -477,6 +478,8 @@ def blacken(text: str) -> str:


if "pytest" in sys.modules:
from unittest import mock

import pytest

# pylint: disable=ungrouped-imports
Expand Down Expand Up @@ -824,16 +827,16 @@ def test_jinja_valid() -> None:
errs = Runner(success, rules=collection).run()
assert len(errs) == 0

@mock.patch.dict(os.environ, {"ANSIBLE_LINT_WRITE_TMP": "1"}, clear=True)
def test_jinja_transform(
config_options: Options,
copy_examples_dir: tuple[Path, Path],
default_rules_collection: RulesCollection,
) -> None:
"""Test transform functionality for jinja rule."""
playbook: str = "examples/playbooks/rule-jinja-before.yml"
playbook = Path("examples/playbooks/rule-jinja-before.yml")
config_options.write_list = ["all"]

config_options.lintables = [playbook]
config_options.lintables = [str(playbook)]
runner_result = get_matches(
rules=default_rules_collection,
options=config_options,
Expand All @@ -844,17 +847,17 @@ def test_jinja_transform(
matches = runner_result.matches
assert len(matches) == 2

orig_dir, tmp_dir = copy_examples_dir
orig_playbook = orig_dir / playbook
expected_playbook = orig_dir / playbook.replace(".yml", ".transformed.yml")
transformed_playbook = tmp_dir / playbook

orig_playbook_content = orig_playbook.read_text()
expected_playbook_content = expected_playbook.read_text()
transformed_playbook_content = transformed_playbook.read_text()
orig_content = playbook.read_text(encoding="utf-8")
expected_content = playbook.with_suffix(
f".transformed{playbook.suffix}",
).read_text(encoding="utf-8")
transformed_content = playbook.with_suffix(f".tmp{playbook.suffix}").read_text(
encoding="utf-8",
)

assert orig_playbook_content != transformed_playbook_content
assert transformed_playbook_content == expected_playbook_content
assert orig_content != transformed_content
assert expected_content == transformed_content
playbook.with_suffix(f".tmp{playbook.suffix}").unlink()


def _get_error_line(task: dict[str, Any], path: list[str | int]) -> int:
Expand Down
32 changes: 17 additions & 15 deletions src/ansiblelint/rules/no_log_password.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
"""NoLogPasswordsRule used with ansible-lint."""
from __future__ import annotations

import os
import sys
from pathlib import Path
from typing import TYPE_CHECKING

from ansiblelint.rules import AnsibleLintRule, RulesCollection, TransformMixin
Expand All @@ -24,8 +26,6 @@
from ansiblelint.utils import Task, convert_to_boolean

if TYPE_CHECKING:
from pathlib import Path

from ruamel.yaml.comments import CommentedMap, CommentedSeq

from ansiblelint.config import Options
Expand Down Expand Up @@ -94,6 +94,8 @@ def transform(


if "pytest" in sys.modules:
from unittest import mock

import pytest

if TYPE_CHECKING:
Expand Down Expand Up @@ -325,32 +327,32 @@ def test_password_lock_false(rule_runner: RunFromText) -> None:
results = rule_runner.run_playbook(PASSWORD_LOCK_FALSE)
assert len(results) == 0

@mock.patch.dict(os.environ, {"ANSIBLE_LINT_WRITE_TMP": "1"}, clear=True)
def test_no_log_password_transform(
config_options: Options,
copy_examples_dir: tuple[Path, Path],
) -> None:
"""Test transform functionality for no-log-password rule."""
playbook: str = "examples/playbooks/transform-no-log-password.yml"
playbook = Path("examples/playbooks/transform-no-log-password.yml")
config_options.write_list = ["all"]
rules = RulesCollection(options=config_options)
rules.register(NoLogPasswordsRule())

config_options.lintables = [playbook]
config_options.lintables = [str(playbook)]
runner_result = get_matches(rules=rules, options=config_options)
transformer = Transformer(result=runner_result, options=config_options)
transformer.run()

matches = runner_result.matches
assert len(matches) == 2

orig_dir, tmp_dir = copy_examples_dir
orig_playbook = orig_dir / playbook
expected_playbook = orig_dir / playbook.replace(".yml", ".transformed.yml")
transformed_playbook = tmp_dir / playbook

orig_playbook_content = orig_playbook.read_text()
expected_playbook_content = expected_playbook.read_text()
transformed_playbook_content = transformed_playbook.read_text()
orig_content = playbook.read_text(encoding="utf-8")
expected_content = playbook.with_suffix(
f".transformed{playbook.suffix}",
).read_text(encoding="utf-8")
transformed_content = playbook.with_suffix(f".tmp{playbook.suffix}").read_text(
encoding="utf-8",
)

assert orig_playbook_content != transformed_playbook_content
assert transformed_playbook_content == expected_playbook_content
assert orig_content != transformed_content
assert expected_content == transformed_content
playbook.with_suffix(f".tmp{playbook.suffix}").unlink()
22 changes: 0 additions & 22 deletions src/ansiblelint/testing/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
from __future__ import annotations

import copy
import os
import shutil
from pathlib import Path
from typing import TYPE_CHECKING

import pytest
Expand All @@ -21,7 +18,6 @@
from ansiblelint.testing import RunFromText

if TYPE_CHECKING:
from argparse import Namespace
from collections.abc import Iterator

from _pytest.fixtures import SubRequest
Expand Down Expand Up @@ -65,21 +61,3 @@ def fixture_config_options() -> Iterator[Options]:
original_options = copy.deepcopy(options)
yield options
options = original_options


@pytest.fixture(name="copy_examples_dir")
def fixture_copy_examples_dir(
tmp_path: Path,
config_options: Namespace,
) -> Iterator[tuple[Path, Path]]:
"""Fixture that copies the examples/ dir into a tmpdir."""
examples_dir = Path("examples")

shutil.copytree(examples_dir, tmp_path / "examples")
old_cwd = Path.cwd()
try:
os.chdir(tmp_path)
config_options.cwd = tmp_path
yield old_cwd, tmp_path
finally:
os.chdir(old_cwd)
36 changes: 18 additions & 18 deletions test/test_transformer.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
"""Tests for Transformer."""
from __future__ import annotations

import os
import shutil
from pathlib import Path
from typing import TYPE_CHECKING
from unittest import mock

import pytest

Expand All @@ -23,16 +25,16 @@
def fixture_runner_result(
config_options: Options,
default_rules_collection: RulesCollection,
playbook: str,
playbook_str: str,
) -> LintResult:
"""Fixture that runs the Runner to populate a LintResult for a given file."""
config_options.lintables = [playbook]
config_options.lintables = [playbook_str]
result = get_matches(rules=default_rules_collection, options=config_options)
return result


@pytest.mark.parametrize(
("playbook", "matches_count", "transformed"),
("playbook_str", "matches_count", "transformed"),
(
# reuse TestRunner::test_runner test cases to ensure transformer does not mangle matches
pytest.param(
Expand Down Expand Up @@ -127,10 +129,10 @@ def fixture_runner_result(
),
),
)
@mock.patch.dict(os.environ, {"ANSIBLE_LINT_WRITE_TMP": "1"}, clear=True)
def test_transformer( # pylint: disable=too-many-arguments, too-many-locals
config_options: Options,
copy_examples_dir: tuple[Path, Path],
playbook: str,
playbook_str: str,
runner_result: LintResult,
transformed: bool,
matches_count: int,
Expand All @@ -139,28 +141,26 @@ def test_transformer( # pylint: disable=too-many-arguments, too-many-locals
Based on TestRunner::test_runner
"""
playbook = Path(playbook_str)
config_options.write_list = ["all"]
transformer = Transformer(result=runner_result, options=config_options)
transformer.run()

matches = runner_result.matches
assert len(matches) == matches_count

orig_dir, tmp_dir = copy_examples_dir
orig_playbook = orig_dir / playbook
expected_playbook = orig_dir / playbook.replace(".yml", ".transformed.yml")
transformed_playbook = tmp_dir / playbook

orig_playbook_content = orig_playbook.read_text()
expected_playbook_content = expected_playbook.read_text()
transformed_playbook_content = transformed_playbook.read_text()

orig_content = playbook.read_text(encoding="utf-8")
if transformed:
assert orig_playbook_content != transformed_playbook_content
else:
assert orig_playbook_content == transformed_playbook_content
expected_content = playbook.with_suffix(
f".transformed{playbook.suffix}",
).read_text(encoding="utf-8")
transformed_content = playbook.with_suffix(f".tmp{playbook.suffix}").read_text(
encoding="utf-8",
)

assert transformed_playbook_content == expected_playbook_content
assert orig_content != transformed_content
assert expected_content == transformed_content
playbook.with_suffix(f".tmp{playbook.suffix}").unlink()


@pytest.mark.parametrize(
Expand Down

0 comments on commit 5ca5679

Please sign in to comment.