diff options
Diffstat (limited to 'test/TestNestedJinjaRule.py')
-rw-r--r-- | test/TestNestedJinjaRule.py | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/test/TestNestedJinjaRule.py b/test/TestNestedJinjaRule.py new file mode 100644 index 0000000..f8367b0 --- /dev/null +++ b/test/TestNestedJinjaRule.py @@ -0,0 +1,208 @@ +# -*- coding: utf-8 -*- +# Author: Adrián Tóth <adtoth@redhat.com> +# +# Copyright (c) 2020, Red Hat, 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. + +from collections import namedtuple + +import pytest + +from ansiblelint.runner import Runner + +PlayFile = namedtuple('PlayFile', ['name', 'content']) + + +FAIL_TASK_1LN = PlayFile('playbook.yml', ''' +- hosts: all + tasks: + - name: one-level nesting + set_fact: + var_one: "2*(1+2) is {{ 2 * {{ 1 + 2 }} }}" +''') + +FAIL_TASK_1LN_M = PlayFile('playbook.yml', ''' +- hosts: all + tasks: + - name: one-level multiline nesting + set_fact: + var_one_ml: > + 2*(1+2) is {{ 2 * + {{ 1 + 2 }} + }} +''') + +FAIL_TASK_2LN = PlayFile('playbook.yml', ''' +- hosts: all + tasks: + - name: two-level nesting + set_fact: + var_two: "2*(1+(3-1)) is {{ 2 * {{ 1 + {{ 3 - 1 }} }} }}" +''') + +FAIL_TASK_2LN_M = PlayFile('playbook.yml', ''' +- hosts: all + tasks: + - name: two-level multiline nesting + set_fact: + var_two_ml: > + 2*(1+(3-1)) is {{ 2 * + {{ 1 + + {{ 3 - 1 }} + }} }} +''') + +FAIL_TASK_W_5LN = PlayFile('playbook.yml', ''' +- hosts: all + tasks: + - name: five-level wild nesting + set_fact: + var_three_wld: "{{ {{ {{ {{ {{ 234 }} }} }} }} }}" +''') + +FAIL_TASK_W_5LN_M = PlayFile('playbook.yml', ''' +- hosts: all + tasks: + - name: five-level wild multiline nesting + set_fact: + var_three_wld_ml: > + {{ + {{ + {{ + {{ + {{ 234 }} + }} + }} + }} + }} +''') + +SUCCESS_TASK_P = PlayFile('playbook.yml', ''' +- hosts: all + tasks: + - name: non-nested example + set_fact: + var_one: "number for 'one' is {{ 2 * 1 }}" +''') + +SUCCESS_TASK_P_M = PlayFile('playbook.yml', ''' +- hosts: all + tasks: + - name: multiline non-nested example + set_fact: + var_one_ml: > + number for 'one' is {{ + 2 * 1 }} +''') + +SUCCESS_TASK_2P = PlayFile('playbook.yml', ''' +- hosts: all + tasks: + - name: nesting far from each other + set_fact: + var_two: "number for 'two' is {{ 2 * 1 }} and number for 'three' is {{ 4 - 1 }}" +''') + +SUCCESS_TASK_2P_M = PlayFile('playbook.yml', ''' +- hosts: all + tasks: + - name: multiline nesting far from each other + set_fact: + var_two_ml: > + number for 'two' is {{ 2 * 1 + }} and number for 'three' is {{ + 4 - 1 }} +''') + +SUCCESS_TASK_C_2P = PlayFile('playbook.yml', ''' +- hosts: all + tasks: + - name: nesting close to each other + set_fact: + var_three: "number for 'ten' is {{ 2 - 1 }}{{ 3 - 3 }}" +''') + +SUCCESS_TASK_C_2P_M = PlayFile('playbook.yml', ''' +- hosts: all + tasks: + - name: multiline nesting close to each other + set_fact: + var_three_ml: > + number for 'ten' is {{ + 2 - 1 + }}{{ 3 - 3 }} +''') + + +@pytest.fixture +def runner(tmp_path, default_rules_collection): + return Runner( + default_rules_collection, + str(tmp_path / 'playbook.yml'), + [], [], [], + ) + + +@pytest.fixture +def _playbook_file(tmp_path, request): + if request.param is None: + return + for play_file in request.param: + p = tmp_path / play_file.name + p.write_text(play_file.content) + + +@pytest.mark.parametrize( + '_playbook_file', + ( + pytest.param([FAIL_TASK_1LN], id='file includes one-level nesting'), + pytest.param([FAIL_TASK_1LN_M], id='file includes one-level multiline nesting'), + pytest.param([FAIL_TASK_2LN], id='file includes two-level nesting'), + pytest.param([FAIL_TASK_2LN_M], id='file includes two-level multiline nesting'), + pytest.param([FAIL_TASK_W_5LN], id='file includes five-level wild nesting'), + pytest.param([FAIL_TASK_W_5LN_M], id='file includes five-level wild multiline nesting'), + ), + indirect=['_playbook_file'], +) +@pytest.mark.usefixtures('_playbook_file') +def test_including_wrong_nested_jinja(runner): + rule_violations = runner.run() + assert rule_violations[0].rule.id == '207' + + +@pytest.mark.parametrize( + '_playbook_file', + ( + pytest.param([SUCCESS_TASK_P], id='file includes non-nested example'), + pytest.param([SUCCESS_TASK_P_M], id='file includes multiline non-nested example'), + pytest.param([SUCCESS_TASK_2P], id='file includes nesting far from each other'), + pytest.param([SUCCESS_TASK_2P_M], id='file includes multiline nesting far from each other'), + pytest.param([SUCCESS_TASK_C_2P], id='file includes nesting close to each other'), + pytest.param( + [SUCCESS_TASK_C_2P_M], + id='file includes multiline nesting close to each other', + ), + ), + indirect=['_playbook_file'], +) +@pytest.mark.usefixtures('_playbook_file') +def test_including_proper_nested_jinja(runner): + rule_violations = runner.run() + assert not rule_violations |