diff options
Diffstat (limited to 'test/test_runner.py')
-rw-r--r-- | test/test_runner.py | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/test/test_runner.py b/test/test_runner.py new file mode 100644 index 0000000..0cd1c77 --- /dev/null +++ b/test/test_runner.py @@ -0,0 +1,159 @@ +"""Tests for runner submodule.""" +# Copyright (c) 2013-2014 Will Thames <will@thames.id.au> +# +# 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. +from __future__ import annotations + +import os +from typing import Any + +import pytest + +from ansiblelint import formatters +from ansiblelint.file_utils import Lintable, abspath +from ansiblelint.rules import RulesCollection +from ansiblelint.runner import Runner + +LOTS_OF_WARNINGS_PLAYBOOK = abspath( + "examples/playbooks/lots_of_warnings.yml", os.getcwd() +) + + +@pytest.mark.parametrize( + ("playbook", "exclude", "length"), + ( + pytest.param("examples/playbooks/nomatchestest.yml", [], 0, id="nomatchestest"), + pytest.param("examples/playbooks/unicode.yml", [], 1, id="unicode"), + pytest.param( + LOTS_OF_WARNINGS_PLAYBOOK, + [LOTS_OF_WARNINGS_PLAYBOOK], + 0, + id="lots_of_warnings", + ), + pytest.param("examples/playbooks/become.yml", [], 0, id="become"), + pytest.param( + "examples/playbooks/contains_secrets.yml", [], 0, id="contains_secrets" + ), + ), +) +def test_runner( + default_rules_collection: RulesCollection, + playbook: str, + exclude: list[str], + length: int, +) -> None: + """Test that runner can go through any corner cases.""" + runner = Runner(playbook, rules=default_rules_collection, exclude_paths=exclude) + + matches = runner.run() + + assert len(matches) == length + + +def test_runner_exclude_paths(default_rules_collection: RulesCollection) -> None: + """Test that exclude paths do work.""" + runner = Runner( + "examples/playbooks/example.yml", + rules=default_rules_collection, + exclude_paths=["examples/"], + ) + + matches = runner.run() + assert len(matches) == 0 + + +@pytest.mark.parametrize(("exclude_path"), ("**/playbooks/*.yml",)) +def test_runner_exclude_globs( + default_rules_collection: RulesCollection, exclude_path: str +) -> None: + """Test that globs work.""" + runner = Runner( + "examples/playbooks", + rules=default_rules_collection, + exclude_paths=[exclude_path], + ) + + matches = runner.run() + # we expect to find one error from the only .yaml file we have there. + assert len(matches) == 1 + + +@pytest.mark.parametrize( + ("formatter_cls"), + ( + pytest.param(formatters.Formatter, id="Formatter-plain"), + pytest.param(formatters.ParseableFormatter, id="ParseableFormatter-colored"), + pytest.param(formatters.QuietFormatter, id="QuietFormatter-colored"), + pytest.param(formatters.Formatter, id="Formatter-colored"), + ), +) +def test_runner_unicode_format( + default_rules_collection: RulesCollection, + formatter_cls: type[formatters.BaseFormatter[Any]], +) -> None: + """Check that all formatters are unicode-friendly.""" + formatter = formatter_cls(os.getcwd(), display_relative_path=True) + runner = Runner( + Lintable("examples/playbooks/unicode.yml", kind="playbook"), + rules=default_rules_collection, + ) + + matches = runner.run() + + formatter.format(matches[0]) + + +@pytest.mark.parametrize("directory_name", ("test/", os.path.abspath("test"))) +def test_runner_with_directory( + default_rules_collection: RulesCollection, directory_name: str +) -> None: + """Check that runner detects a directory as role.""" + runner = Runner(directory_name, rules=default_rules_collection) + + expected = Lintable(name=directory_name, kind="role") + assert expected in runner.lintables + + +def test_files_not_scanned_twice(default_rules_collection: RulesCollection) -> None: + """Ensure that lintables aren't double-checked.""" + checked_files: set[Lintable] = set() + + filename = os.path.abspath("examples/playbooks/common-include-1.yml") + runner = Runner( + filename, + rules=default_rules_collection, + verbosity=0, + checked_files=checked_files, + ) + run1 = runner.run() + assert len(runner.checked_files) == 2 + assert len(run1) == 1 + + filename = os.path.abspath("examples/playbooks/common-include-2.yml") + runner = Runner( + filename, + rules=default_rules_collection, + verbosity=0, + checked_files=checked_files, + ) + run2 = runner.run() + assert len(runner.checked_files) == 3 + # this second run should return 0 because the included filed was already + # processed and added to checked_files, which acts like a bypass list. + assert len(run2) == 0 |