diff options
author | Matt Clay <matt@mystile.com> | 2016-10-12 23:57:53 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-10-12 23:57:53 +0200 |
commit | 80a5c70ad795f3cd1e6e3edde7077a8dfd65470b (patch) | |
tree | 50ab0ad670d2631fa32cad47019d9a970ed81596 /test/integration/targets | |
parent | Only dispkay failure to use cryptography at a higher verbosity (diff) | |
download | ansible-80a5c70ad795f3cd1e6e3edde7077a8dfd65470b.tar.xz ansible-80a5c70ad795f3cd1e6e3edde7077a8dfd65470b.zip |
Split integration tests out from Makefile. (#17976)
Diffstat (limited to 'test/integration/targets')
155 files changed, 2809 insertions, 0 deletions
diff --git a/test/integration/targets/args/runme.sh b/test/integration/targets/args/runme.sh new file mode 100755 index 0000000000..af1c31d79b --- /dev/null +++ b/test/integration/targets/args/runme.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +set -eu + +echo "arg[#]: $#" +echo "arg[0]: $0" + +i=0 +for arg in "$@"; do + i=$((i+1)) + echo "arg[$i]: ${arg}" +done diff --git a/test/integration/targets/async_extra_data/runme.sh b/test/integration/targets/async_extra_data/runme.sh new file mode 100755 index 0000000000..bdc3b4209d --- /dev/null +++ b/test/integration/targets/async_extra_data/runme.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -eux + +# Verify that extra data before module JSON output during async call is ignored. +ANSIBLE_DEBUG=0 LC_ALL=bogus ansible-playbook test_async.yml -i localhost, -e ansible_connection=ssh -v "$@" +# Verify that the warning exists by examining debug output. +ANSIBLE_DEBUG=1 LC_ALL=bogus ansible-playbook test_async.yml -i localhost, -e ansible_connection=ssh -v "$@" \ + | grep 'bash: warning: setlocale: LC_ALL: cannot change locale (bogus)' > /dev/null diff --git a/test/integration/targets/async_extra_data/test_async.yml b/test/integration/targets/async_extra_data/test_async.yml new file mode 100644 index 0000000000..e54ffd3d47 --- /dev/null +++ b/test/integration/targets/async_extra_data/test_async.yml @@ -0,0 +1,10 @@ +- hosts: localhost + gather_facts: false + tasks: + # make sure non-JSON data before module output is ignored + - name: async ping with invalid locale via ssh + ping: + async: 10 + poll: 1 + register: result + - debug: var=result diff --git a/test/integration/targets/binary_modules/Makefile b/test/integration/targets/binary_modules/Makefile new file mode 100644 index 0000000000..d6b791730f --- /dev/null +++ b/test/integration/targets/binary_modules/Makefile @@ -0,0 +1,14 @@ +.PHONY: all clean + +all: + # Compiled versions of these binary modules are available at the url below. + # This avoids a dependency on go and keeps the binaries out of our git repository. + # https://ansible-ci-files.s3.amazonaws.com/test/integration/roles/test_binary_modules/ + cd library; \ + GOOS=linux GOARCH=amd64 go build -o helloworld_linux helloworld.go; \ + GOOS=windows GOARCH=amd64 go build -o helloworld_win32nt.exe helloworld.go; \ + GOOS=darwin GOARCH=amd64 go build -o helloworld_darwin helloworld.go; \ + GOOS=freebsd GOARCH=amd64 go build -o helloworld_freebsd helloworld.go + +clean: + rm -f library/helloworld_* diff --git a/test/integration/targets/binary_modules/download_binary_modules.yml b/test/integration/targets/binary_modules/download_binary_modules.yml new file mode 100644 index 0000000000..456ddb4a79 --- /dev/null +++ b/test/integration/targets/binary_modules/download_binary_modules.yml @@ -0,0 +1,21 @@ +- hosts: testhost_binary_modules + tasks: + - debug: var=ansible_system + + - name: set module filename (POSIX) + set_fact: + module_filename: "helloworld_{{ ansible_system | lower }}" + when: ansible_system != 'Win32NT' + + - name: set module filename (Win32NT) + set_fact: + module_filename: "helloworld_{{ ansible_system | lower }}.exe" + when: ansible_system == 'Win32NT' + + - name: download binary module + tags: test_binary_modules + local_action: + module: get_url + url: "https://ansible-ci-files.s3.amazonaws.com/test/integration/roles/test_binary_modules/{{ module_filename }}" + dest: "{{ playbook_dir }}/library/{{ module_filename }}" + mode: 0755 diff --git a/test/integration/targets/binary_modules/library/.gitignore b/test/integration/targets/binary_modules/library/.gitignore new file mode 100644 index 0000000000..d034a06ac7 --- /dev/null +++ b/test/integration/targets/binary_modules/library/.gitignore @@ -0,0 +1 @@ +helloworld_* diff --git a/test/integration/targets/binary_modules/library/helloworld.go b/test/integration/targets/binary_modules/library/helloworld.go new file mode 100644 index 0000000000..a4c16b20e5 --- /dev/null +++ b/test/integration/targets/binary_modules/library/helloworld.go @@ -0,0 +1,89 @@ +// This file is part of Ansible +// +// Ansible is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Ansible is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" +) + +type ModuleArgs struct { + Name string +} + +type Response struct { + Msg string `json:"msg"` + Changed bool `json:"changed"` + Failed bool `json:"failed"` +} + +func ExitJson(responseBody Response) { + returnResponse(responseBody) +} + +func FailJson(responseBody Response) { + responseBody.Failed = true + returnResponse(responseBody) +} + +func returnResponse(responseBody Response) { + var response []byte + var err error + response, err = json.Marshal(responseBody) + if err != nil { + response, _ = json.Marshal(Response{Msg: "Invalid response object"}) + } + fmt.Println(string(response)) + if responseBody.Failed { + os.Exit(1) + } else { + os.Exit(0) + } +} + +func main() { + var response Response + + if len(os.Args) != 2 { + response.Msg = "No argument file provided" + FailJson(response) + } + + argsFile := os.Args[1] + + text, err := ioutil.ReadFile(argsFile) + if err != nil { + response.Msg = "Could not read configuration file: " + argsFile + FailJson(response) + } + + var moduleArgs ModuleArgs + err = json.Unmarshal(text, &moduleArgs) + if err != nil { + response.Msg = "Configuration file not valid JSON: " + argsFile + FailJson(response) + } + + var name string = "World" + if moduleArgs.Name != "" { + name = moduleArgs.Name + } + + response.Msg = "Hello, " + name + "!" + ExitJson(response) +} diff --git a/test/integration/targets/binary_modules/roles/test_binary_modules/tasks/main.yml b/test/integration/targets/binary_modules/roles/test_binary_modules/tasks/main.yml new file mode 100644 index 0000000000..e7139dbf37 --- /dev/null +++ b/test/integration/targets/binary_modules/roles/test_binary_modules/tasks/main.yml @@ -0,0 +1,54 @@ +- debug: var=ansible_system + +- name: ping + ping: + when: ansible_system != 'Win32NT' + +- name: win_ping + win_ping: + when: ansible_system == 'Win32NT' + +- name: Hello, World! + action: "helloworld_{{ ansible_system|lower }}" + register: hello_world + +- assert: + that: + - 'hello_world.msg == "Hello, World!"' + +- name: Hello, Ansible! + action: "helloworld_{{ ansible_system|lower }}" + args: + name: Ansible + register: hello_ansible + +- assert: + that: + - 'hello_ansible.msg == "Hello, Ansible!"' + +- name: Async Hello, World! + action: "helloworld_{{ ansible_system|lower }}" + async: 10 + poll: 1 + when: ansible_system != 'Win32NT' + register: async_hello_world + +- assert: + that: + - 'async_hello_world.msg == "Hello, World!"' + when: not async_hello_world|skipped + +- name: Async Hello, Ansible! + action: "helloworld_{{ ansible_system|lower }}" + args: + name: Ansible + async: 10 + poll: 1 + when: ansible_system != 'Win32NT' + register: async_hello_ansible + +- assert: + that: + - 'async_hello_ansible.msg == "Hello, Ansible!"' + when: not async_hello_ansible|skipped + diff --git a/test/integration/targets/binary_modules/test.sh b/test/integration/targets/binary_modules/test.sh new file mode 100755 index 0000000000..7f046670f7 --- /dev/null +++ b/test/integration/targets/binary_modules/test.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +set -eux + +[ -f "${INVENTORY}" ] + +ANSIBLE_HOST_KEY_CHECKING=false ansible-playbook download_binary_modules.yml -i "${INVENTORY}" -v "$@" +ANSIBLE_HOST_KEY_CHECKING=false ansible-playbook test_binary_modules.yml -i "${INVENTORY}" -v "$@" diff --git a/test/integration/targets/binary_modules/test_binary_modules.yml b/test/integration/targets/binary_modules/test_binary_modules.yml new file mode 100644 index 0000000000..e5fd341cf2 --- /dev/null +++ b/test/integration/targets/binary_modules/test_binary_modules.yml @@ -0,0 +1,6 @@ +- hosts: testhost_binary_modules + roles: + - role: test_binary_modules + tags: + - test_binary_modules + diff --git a/test/integration/targets/binary_modules_posix/runme.sh b/test/integration/targets/binary_modules_posix/runme.sh new file mode 100755 index 0000000000..670477d186 --- /dev/null +++ b/test/integration/targets/binary_modules_posix/runme.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +set -eux + +cd ../binary_modules +INVENTORY=../../inventory ./test.sh "$@" diff --git a/test/integration/targets/binary_modules_winrm/runme.sh b/test/integration/targets/binary_modules_winrm/runme.sh new file mode 100755 index 0000000000..f182c2d66f --- /dev/null +++ b/test/integration/targets/binary_modules_winrm/runme.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +set -eux + +cd ../binary_modules +INVENTORY=../../inventory.winrm ./test.sh "$@" diff --git a/test/integration/targets/blocks/fail.yml b/test/integration/targets/blocks/fail.yml new file mode 100644 index 0000000000..ae94655136 --- /dev/null +++ b/test/integration/targets/blocks/fail.yml @@ -0,0 +1,2 @@ +- name: EXPECTED FAILURE + fail: msg="{{msg}}" diff --git a/test/integration/targets/blocks/main.yml b/test/integration/targets/blocks/main.yml new file mode 100644 index 0000000000..a80a62b753 --- /dev/null +++ b/test/integration/targets/blocks/main.yml @@ -0,0 +1,103 @@ +- name: simple block test + hosts: localhost + gather_facts: yes + strategy: "{{test_strategy|default('linear')}}" + vars: + block_tasks_run: false + block_rescue_run: false + block_always_run: false + nested_block_always_run: false + tasks_run_after_failure: false + rescue_run_after_failure: false + always_run_after_failure: false + tasks: + - block: + - name: set block tasks run flag + set_fact: + block_tasks_run: true + - name: EXPECTED FAILURE fail in tasks + fail: + - name: tasks flag should not be set after failure + set_fact: + tasks_run_after_failure: true + rescue: + - name: set block rescue run flag + set_fact: + block_rescue_run: true + - name: EXPECTED FAILURE fail in rescue + fail: + - name: tasks flag should not be set after failure in rescue + set_fact: + rescue_run_after_failure: true + always: + - name: set block always run flag + set_fact: + block_always_run: true + #- block: + # - meta: noop + # always: + # - name: set nested block always run flag + # set_fact: + # nested_block_always_run: true + # - name: fail in always + # fail: + # - name: tasks flag should not be set after failure in always + # set_fact: + # always_run_after_failure: true + - meta: clear_host_errors + + post_tasks: + - assert: + that: + - block_tasks_run + - block_rescue_run + - block_always_run + #- nested_block_always_run + - not tasks_run_after_failure + - not rescue_run_after_failure + - not always_run_after_failure + - debug: msg="TEST COMPLETE" + +- name: block with includes + hosts: localhost + gather_facts: yes + strategy: "{{test_strategy|default('linear')}}" + vars: + rescue_run_after_include_fail: false + always_run_after_include_fail_in_rescue: false + tasks_run_after_failure: false + rescue_run_after_failure: false + always_run_after_failure: false + tasks: + - block: + - name: include fail.yml in tasks + include: fail.yml + args: + msg: "failed from tasks" + - name: tasks flag should not be set after failure + set_fact: + tasks_run_after_failure: true + rescue: + - set_fact: + rescue_run_after_include_fail: true + - name: include fail.yml in rescue + include: fail.yml + args: + msg: "failed from rescue" + - name: flag should not be set after failure in rescue + set_fact: + rescue_run_after_failure: true + always: + - set_fact: + always_run_after_include_fail_in_rescue: true + - meta: clear_host_errors + + post_tasks: + - assert: + that: + - rescue_run_after_include_fail + - always_run_after_include_fail_in_rescue + - not tasks_run_after_failure + - not rescue_run_after_failure + - not always_run_after_failure + - debug: msg="TEST COMPLETE" diff --git a/test/integration/targets/blocks/nested_fail.yml b/test/integration/targets/blocks/nested_fail.yml new file mode 100644 index 0000000000..31ae870e37 --- /dev/null +++ b/test/integration/targets/blocks/nested_fail.yml @@ -0,0 +1,3 @@ +- include: fail.yml + args: + msg: "nested {{msg}}" diff --git a/test/integration/targets/blocks/nested_nested_fail.yml b/test/integration/targets/blocks/nested_nested_fail.yml new file mode 100644 index 0000000000..e9a050fb98 --- /dev/null +++ b/test/integration/targets/blocks/nested_nested_fail.yml @@ -0,0 +1,3 @@ +- include: nested_fail.yml + args: + msg: "nested {{msg}}" diff --git a/test/integration/targets/blocks/runme.sh b/test/integration/targets/blocks/runme.sh new file mode 100755 index 0000000000..dd15a10083 --- /dev/null +++ b/test/integration/targets/blocks/runme.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -eux + +# remove old output log +rm -f block_test.out +# run the test and check to make sure the right number of completions was logged +ansible-playbook -vv main.yml -i ../../inventory "$@" | tee block_test.out +env python -c \ + 'import sys, re; sys.stdout.write(re.sub("\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]", "", sys.stdin.read()))' \ + <block_test.out >block_test_wo_colors.out +[ "$(grep -c 'TEST COMPLETE' block_test.out)" = "$(egrep '^[0-9]+ plays in' block_test_wo_colors.out | cut -f1 -d' ')" ] +# cleanup the output log again, to make sure the test is clean +rm -f block_test.out block_test_wo_colors.out +# run test with free strategy and again count the completions +ansible-playbook -vv main.yml -i ../../inventory -e test_strategy=free "$@" | tee block_test.out +env python -c \ + 'import sys, re; sys.stdout.write(re.sub("\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]", "", sys.stdin.read()))' \ + <block_test.out >block_test_wo_colors.out +[ "$(grep -c 'TEST COMPLETE' block_test.out)" = "$(egrep '^[0-9]+ plays in' block_test_wo_colors.out | cut -f1 -d' ')" ] diff --git a/test/integration/targets/check_mode/check_mode.yml b/test/integration/targets/check_mode/check_mode.yml new file mode 100644 index 0000000000..0f4fde4da0 --- /dev/null +++ b/test/integration/targets/check_mode/check_mode.yml @@ -0,0 +1,6 @@ +- hosts: testhost + vars: + - output_dir: . + roles: + - { role: test_always_run, tags: test_always_run } + - { role: test_check_mode, tags: test_check_mode } diff --git a/test/integration/targets/check_mode/roles/test_always_run/meta/main.yml b/test/integration/targets/check_mode/roles/test_always_run/meta/main.yml new file mode 100644 index 0000000000..b7cb12f7b6 --- /dev/null +++ b/test/integration/targets/check_mode/roles/test_always_run/meta/main.yml @@ -0,0 +1,18 @@ +# test code for the always_run option +# (c) 2014, James Cammarata <jcammarata@ansible.com> + +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + diff --git a/test/integration/targets/check_mode/roles/test_always_run/tasks/main.yml b/test/integration/targets/check_mode/roles/test_always_run/tasks/main.yml new file mode 100644 index 0000000000..eb27785ad6 --- /dev/null +++ b/test/integration/targets/check_mode/roles/test_always_run/tasks/main.yml @@ -0,0 +1,29 @@ +# test code for the always_run option +# (c) 2014, James Cammarata <jcammarata@ansible.com> + +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +- name: run a command while in check mode + shell: echo "running" + check_mode: no + register: result + +- name: assert that the command was run + assert: + that: + - "result.changed == true" + - "result.stdout == 'running'" + - "result.rc == 0" diff --git a/test/integration/targets/check_mode/roles/test_check_mode/files/foo.txt b/test/integration/targets/check_mode/roles/test_check_mode/files/foo.txt new file mode 100644 index 0000000000..3e96db9b3e --- /dev/null +++ b/test/integration/targets/check_mode/roles/test_check_mode/files/foo.txt @@ -0,0 +1 @@ +templated_var_loaded diff --git a/test/integration/targets/check_mode/roles/test_check_mode/tasks/main.yml b/test/integration/targets/check_mode/roles/test_check_mode/tasks/main.yml new file mode 100644 index 0000000000..637e9e193c --- /dev/null +++ b/test/integration/targets/check_mode/roles/test_check_mode/tasks/main.yml @@ -0,0 +1,50 @@ +# test code for the template module +# (c) 2014, Michael DeHaan <michael.dehaan@gmail.com> + +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +- name: fill in a basic template in check mode + template: src=foo.j2 dest={{output_dir}}/checkmode_foo.templated mode=0644 + register: template_result + +- name: check whether file exists + stat: path={{output_dir}}/checkmode_foo.templated + register: foo + +- name: verify that the file was marked as changed in check mode + assert: + that: + - "template_result|changed" + - "not foo.stat.exists" + +- name: Actually create the file, disable check mode + template: src=foo.j2 dest={{output_dir}}/checkmode_foo.templated2 mode=0644 + check_mode: no + register: checkmode_disabled + +- name: fill in template with new content + template: src=foo.j2 dest={{output_dir}}/checkmode_foo.templated2 mode=0644 + register: template_result2 + +- name: remove templated file + file: path={{output_dir}}/checkmode_foo.templated2 state=absent + check_mode: no + +- name: verify that the file was not changed + assert: + that: + - "checkmode_disabled|changed" + - "not template_result2|changed" diff --git a/test/integration/targets/check_mode/roles/test_check_mode/templates/foo.j2 b/test/integration/targets/check_mode/roles/test_check_mode/templates/foo.j2 new file mode 100644 index 0000000000..55aab8f1ea --- /dev/null +++ b/test/integration/targets/check_mode/roles/test_check_mode/templates/foo.j2 @@ -0,0 +1 @@ +{{ templated_var }} diff --git a/test/integration/targets/check_mode/roles/test_check_mode/vars/main.yml b/test/integration/targets/check_mode/roles/test_check_mode/vars/main.yml new file mode 100644 index 0000000000..1e8f64ccf4 --- /dev/null +++ b/test/integration/targets/check_mode/roles/test_check_mode/vars/main.yml @@ -0,0 +1 @@ +templated_var: templated_var_loaded diff --git a/test/integration/targets/check_mode/runme.sh b/test/integration/targets/check_mode/runme.sh new file mode 100755 index 0000000000..184ecb7c27 --- /dev/null +++ b/test/integration/targets/check_mode/runme.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -eux + +ansible-playbook check_mode.yml -i ../../inventory -v --check "$@" diff --git a/test/integration/targets/connection/test.sh b/test/integration/targets/connection/test.sh new file mode 100755 index 0000000000..4e7aa8dda1 --- /dev/null +++ b/test/integration/targets/connection/test.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -eux + +[ -f "${INVENTORY}" ] + +# Run connection tests with both the default and C locale. + + ansible-playbook test_connection.yml -i "${INVENTORY}" "$@" +LC_ALL=C LANG=C ansible-playbook test_connection.yml -i "${INVENTORY}" "$@" diff --git a/test/integration/targets/connection/test_connection.yml b/test/integration/targets/connection/test_connection.yml new file mode 100644 index 0000000000..2f0a98ccdf --- /dev/null +++ b/test/integration/targets/connection/test_connection.yml @@ -0,0 +1,40 @@ +- hosts: "{{ hosts }}" + gather_facts: no + serial: 1 + tasks: + + ### raw with unicode arg and output + + - name: raw with unicode arg and output + raw: echo 汉语 + register: command + - name: check output of raw with unicode arg and output + assert: + that: + - "'汉语' in command.stdout" + - command | changed # as of 2.2, raw should default to changed: true for consistency w/ shell/command/script modules + + ### copy local file with unicode filename and content + + - name: create local file with unicode filename and content + local_action: lineinfile dest={{ local_tmp }}-汉语/汉语.txt create=true line=汉语 + - name: remove remote file with unicode filename and content + action: "{{ action_prefix }}file path={{ remote_tmp }}-汉语/汉语.txt state=absent" + - name: create remote directory with unicode name + action: "{{ action_prefix }}file path={{ remote_tmp }}-汉语 state=directory" + - name: copy local file with unicode filename and content + action: "{{ action_prefix }}copy src={{ local_tmp }}-汉语/汉语.txt dest={{ remote_tmp }}-汉语/汉语.txt" + + ### fetch remote file with unicode filename and content + + - name: remove local file with unicode filename and content + local_action: file path={{ local_tmp }}-汉语/汉语.txt state=absent + - name: fetch remote file with unicode filename and content + fetch: src={{ remote_tmp }}-汉语/汉语.txt dest={{ local_tmp }}-汉语/汉语.txt fail_on_missing=true validate_checksum=true flat=true + + ### remove local and remote temp files + + - name: remove local temp file + local_action: file path={{ local_tmp }}-汉语 state=absent + - name: remove remote temp file + action: "{{ action_prefix }}file path={{ remote_tmp }}-汉语 state=absent" diff --git a/test/integration/targets/connection_chroot/runme.sh b/test/integration/targets/connection_chroot/runme.sh new file mode 120000 index 0000000000..70aa5dbdba --- /dev/null +++ b/test/integration/targets/connection_chroot/runme.sh @@ -0,0 +1 @@ +../connection_posix/test.sh
\ No newline at end of file diff --git a/test/integration/targets/connection_chroot/test_connection.inventory b/test/integration/targets/connection_chroot/test_connection.inventory new file mode 100644 index 0000000000..9e0302c7d0 --- /dev/null +++ b/test/integration/targets/connection_chroot/test_connection.inventory @@ -0,0 +1,6 @@ +[chroot] +chroot-pipelining ansible_ssh_pipelining=true +chroot-no-pipelining ansible_ssh_pipelining=false +[chroot:vars] +ansible_host=/ +ansible_connection=chroot diff --git a/test/integration/targets/connection_docker/runme.sh b/test/integration/targets/connection_docker/runme.sh new file mode 120000 index 0000000000..70aa5dbdba --- /dev/null +++ b/test/integration/targets/connection_docker/runme.sh @@ -0,0 +1 @@ +../connection_posix/test.sh
\ No newline at end of file diff --git a/test/integration/targets/connection_docker/test_connection.inventory b/test/integration/targets/connection_docker/test_connection.inventory new file mode 100644 index 0000000000..42940ac3b7 --- /dev/null +++ b/test/integration/targets/connection_docker/test_connection.inventory @@ -0,0 +1,6 @@ +[docker] +docker-pipelining ansible_ssh_pipelining=true +docker-no-pipelining ansible_ssh_pipelining=false +[docker:vars] +ansible_host=ubuntu-latest +ansible_connection=docker diff --git a/test/integration/targets/connection_jail/runme.sh b/test/integration/targets/connection_jail/runme.sh new file mode 120000 index 0000000000..70aa5dbdba --- /dev/null +++ b/test/integration/targets/connection_jail/runme.sh @@ -0,0 +1 @@ +../connection_posix/test.sh
\ No newline at end of file diff --git a/test/integration/targets/connection_jail/test_connection.inventory b/test/integration/targets/connection_jail/test_connection.inventory new file mode 100644 index 0000000000..a525c72f43 --- /dev/null +++ b/test/integration/targets/connection_jail/test_connection.inventory @@ -0,0 +1,7 @@ +[jail] +jail-pipelining ansible_ssh_pipelining=true +jail-no-pipelining ansible_ssh_pipelining=false +[jail:vars] +ansible_host=freebsd_10_2 +ansible_connection=jail +ansible_python_interpreter=/usr/local/bin/python diff --git a/test/integration/targets/connection_libvirt_lxc/runme.sh b/test/integration/targets/connection_libvirt_lxc/runme.sh new file mode 120000 index 0000000000..70aa5dbdba --- /dev/null +++ b/test/integration/targets/connection_libvirt_lxc/runme.sh @@ -0,0 +1 @@ +../connection_posix/test.sh
\ No newline at end of file diff --git a/test/integration/targets/connection_libvirt_lxc/test_connection.inventory b/test/integration/targets/connection_libvirt_lxc/test_connection.inventory new file mode 100644 index 0000000000..ff98a25542 --- /dev/null +++ b/test/integration/targets/connection_libvirt_lxc/test_connection.inventory @@ -0,0 +1,6 @@ +[libvirt_lxc] +libvirt_lxc-pipelining ansible_ssh_pipelining=true +libvirt_lxc-no-pipelining ansible_ssh_pipelining=false +[libvirt_lxc:vars] +ansible_host=lv-ubuntu-wily-amd64 +ansible_connection=libvirt_lxc diff --git a/test/integration/targets/connection_local/runme.sh b/test/integration/targets/connection_local/runme.sh new file mode 120000 index 0000000000..70aa5dbdba --- /dev/null +++ b/test/integration/targets/connection_local/runme.sh @@ -0,0 +1 @@ +../connection_posix/test.sh
\ No newline at end of file diff --git a/test/integration/targets/connection_local/test_connection.inventory b/test/integration/targets/connection_local/test_connection.inventory new file mode 100644 index 0000000000..7178291040 --- /dev/null +++ b/test/integration/targets/connection_local/test_connection.inventory @@ -0,0 +1,6 @@ +[local] +local-pipelining ansible_ssh_pipelining=true +local-no-pipelining ansible_ssh_pipelining=false +[local:vars] +ansible_host=localhost +ansible_connection=local diff --git a/test/integration/targets/connection_lxc/runme.sh b/test/integration/targets/connection_lxc/runme.sh new file mode 120000 index 0000000000..70aa5dbdba --- /dev/null +++ b/test/integration/targets/connection_lxc/runme.sh @@ -0,0 +1 @@ +../connection_posix/test.sh
\ No newline at end of file diff --git a/test/integration/targets/connection_lxc/test_connection.inventory b/test/integration/targets/connection_lxc/test_connection.inventory new file mode 100644 index 0000000000..8737a9e8f9 --- /dev/null +++ b/test/integration/targets/connection_lxc/test_connection.inventory @@ -0,0 +1,17 @@ +[lxc] +lxc-pipelining ansible_ssh_pipelining=true +lxc-no-pipelining ansible_ssh_pipelining=false +[lxc:vars] +# 1. install lxc +# 2. install python2-lxc +# $ pip install git+https://github.com/lxc/python2-lxc.git +# 3. create container: +# $ sudo lxc-create -t download -n centos-7-amd64 -- -d centos -r 7 -a amd64 +# 4. start container: +# $ sudo lxc-start -n centos-7-amd64 -d +# 5. run test: +# $ sudo -E make test_connection_lxc +# 6. stop container +# $ sudo lxc-stop -n centos-7-amd64 +ansible_host=centos-7-amd64 +ansible_connection=lxc diff --git a/test/integration/targets/connection_lxd/runme.sh b/test/integration/targets/connection_lxd/runme.sh new file mode 120000 index 0000000000..70aa5dbdba --- /dev/null +++ b/test/integration/targets/connection_lxd/runme.sh @@ -0,0 +1 @@ +../connection_posix/test.sh
\ No newline at end of file diff --git a/test/integration/targets/connection_lxd/test_connection.inventory b/test/integration/targets/connection_lxd/test_connection.inventory new file mode 100644 index 0000000000..9c5998eced --- /dev/null +++ b/test/integration/targets/connection_lxd/test_connection.inventory @@ -0,0 +1,6 @@ +[lxd] +lxd-pipelining ansible_ssh_pipelining=true +lxd-no-pipelining ansible_ssh_pipelining=false +[lxd:vars] +ansible_host=centos-7-amd64 +ansible_connection=lxd diff --git a/test/integration/targets/connection_paramiko_ssh/runme.sh b/test/integration/targets/connection_paramiko_ssh/runme.sh new file mode 120000 index 0000000000..70aa5dbdba --- /dev/null +++ b/test/integration/targets/connection_paramiko_ssh/runme.sh @@ -0,0 +1 @@ +../connection_posix/test.sh
\ No newline at end of file diff --git a/test/integration/targets/connection_paramiko_ssh/test_connection.inventory b/test/integration/targets/connection_paramiko_ssh/test_connection.inventory new file mode 100644 index 0000000000..8c430f0d0f --- /dev/null +++ b/test/integration/targets/connection_paramiko_ssh/test_connection.inventory @@ -0,0 +1,6 @@ +[paramiko_ssh] +paramiko_ssh-pipelining ansible_ssh_pipelining=true +paramiko_ssh-no-pipelining ansible_ssh_pipelining=false +[paramiko_ssh:vars] +ansible_host=localhost +ansible_connection=paramiko_ssh diff --git a/test/integration/targets/connection_posix/test.sh b/test/integration/targets/connection_posix/test.sh new file mode 100755 index 0000000000..e133ad74a6 --- /dev/null +++ b/test/integration/targets/connection_posix/test.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +set -eux + +# Connection tests for POSIX platforms use this script by linking to it from the appropriate 'connection_' target dir. +# The name of the inventory group to test is extracted from the directory name following the 'connection_' prefix. + +group=$(python -c \ + "from os import path; print(path.basename(path.abspath(path.dirname('$0'))).replace('connection_', ''))") + +cd ../connection + +INVENTORY="../connection_${group}/test_connection.inventory" ./test.sh \ + -e hosts="${group}" \ + -e action_prefix= \ + -e local_tmp=/tmp/ansible-local \ + -e remote_tmp=/tmp/ansible-remote \ + "$@" diff --git a/test/integration/targets/connection_ssh/runme.sh b/test/integration/targets/connection_ssh/runme.sh new file mode 120000 index 0000000000..70aa5dbdba --- /dev/null +++ b/test/integration/targets/connection_ssh/runme.sh @@ -0,0 +1 @@ +../connection_posix/test.sh
\ No newline at end of file diff --git a/test/integration/targets/connection_ssh/test_connection.inventory b/test/integration/targets/connection_ssh/test_connection.inventory new file mode 100644 index 0000000000..0f0ad23ebb --- /dev/null +++ b/test/integration/targets/connection_ssh/test_connection.inventory @@ -0,0 +1,6 @@ +[ssh] +ssh-pipelining ansible_ssh_pipelining=true +ssh-no-pipelining ansible_ssh_pipelining=false +[ssh:vars] +ansible_host=localhost +ansible_connection=ssh diff --git a/test/integration/targets/connection_winrm/runme.sh b/test/integration/targets/connection_winrm/runme.sh new file mode 100755 index 0000000000..05afcc83b4 --- /dev/null +++ b/test/integration/targets/connection_winrm/runme.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +set -eux + +cd ../connection + +INVENTORY=../../inventory.winrm ./test.sh \ + -e hosts=winrm \ + -e action_prefix=win_ \ + -e local_tmp=/tmp/ansible-local \ + -e remote_tmp=c:/windows/temp/ansible-remote \ + "$@" diff --git a/test/integration/targets/delegate_to/roles/test_template/templates/foo.j2 b/test/integration/targets/delegate_to/roles/test_template/templates/foo.j2 new file mode 100644 index 0000000000..22187f9130 --- /dev/null +++ b/test/integration/targets/delegate_to/roles/test_template/templates/foo.j2 @@ -0,0 +1,3 @@ +{{ templated_var }} + +{{ templated_dict | to_nice_json }} diff --git a/test/integration/targets/delegate_to/runme.sh b/test/integration/targets/delegate_to/runme.sh new file mode 100755 index 0000000000..782ec0902e --- /dev/null +++ b/test/integration/targets/delegate_to/runme.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -eux + +ANSIBLE_HOST_KEY_CHECKING=false ansible-playbook test_delegate_to.yml -i ../../inventory -v "$@" diff --git a/test/integration/targets/delegate_to/test_delegate_to.yml b/test/integration/targets/delegate_to/test_delegate_to.yml new file mode 100644 index 0000000000..d75857cc6c --- /dev/null +++ b/test/integration/targets/delegate_to/test_delegate_to.yml @@ -0,0 +1,56 @@ +- hosts: testhost3 + vars: + - template_role: ./roles/test_template + - output_dir: "{{ playbook_dir }}" + - templated_var: foo + - templated_dict: { 'hello': 'world' } + tasks: + - name: Test no delegate_to + setup: + register: setup_results + + - assert: + that: + - '"127.0.0.3" in setup_results.ansible_facts.ansible_env["SSH_CONNECTION"]' + + - name: Test delegate_to with host in inventory + setup: + register: setup_results + delegate_to: testhost4 + + - assert: + that: + - '"127.0.0.4" in setup_results.ansible_facts.ansible_env["SSH_CONNECTION"]' + + - name: Test delegate_to with host not in inventory + setup: + register: setup_results + delegate_to: 127.0.0.254 + + - assert: + that: + - '"127.0.0.254" in setup_results.ansible_facts.ansible_env["SSH_CONNECTION"]' +# +# Smoketest some other modules do not error as a canary +# + - name: Test file works with delegate_to and a host in inventory + file: path={{ output_dir }}/foo.txt mode=0644 state=touch + delegate_to: testhost4 + + - name: Test file works with delegate_to and a host not in inventory + file: path={{ output_dir }}/tmp.txt mode=0644 state=touch + delegate_to: 127.0.0.254 + + - name: Test template works with delegate_to and a host in inventory + template: src={{ template_role }}/templates/foo.j2 dest={{ output_dir }}/foo.txt + delegate_to: testhost4 + + - name: Test template works with delegate_to and a host not in inventory + template: src={{ template_role }}/templates/foo.j2 dest={{ output_dir }}/foo.txt + delegate_to: 127.0.0.254 + + - name: remove test file + file: path={{ output_dir }}/foo.txt state=absent + + - name: remove test file + file: path={{ output_dir }}/tmp.txt state=absent diff --git a/test/integration/targets/environment/runme.sh b/test/integration/targets/environment/runme.sh new file mode 100755 index 0000000000..c556a17c9d --- /dev/null +++ b/test/integration/targets/environment/runme.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -eux + +ansible-playbook test_environment.yml -i ../../inventory "$@" diff --git a/test/integration/targets/environment/test_environment.yml b/test/integration/targets/environment/test_environment.yml new file mode 100644 index 0000000000..e72224ba76 --- /dev/null +++ b/test/integration/targets/environment/test_environment.yml @@ -0,0 +1,66 @@ +- hosts: testhost + vars: + - test1: + key1: val1 + tasks: + - name: check that envvar does not exist + shell: echo $key1 + register: test_env + + - name: assert no val in stdout + assert: + that: + - '"val1" not in test_env.stdout_lines' + + - name: check that envvar does exist + shell: echo $key1 + environment: "{{test1}}" + register: test_env2 + + - name: assert val1 in stdout + assert: + that: + - '"val1" in test_env2.stdout_lines' + +- hosts: testhost + vars: + - test1: + key1: val1 + - test2: + key1: not1 + other1: val2 + environment: "{{test1}}" + tasks: + - name: check that play envvar does exist + shell: echo $key1 + register: test_env3 + + - name: assert val1 in stdout + assert: + that: + - '"val1" in test_env3.stdout_lines' + + - name: check that task envvar does exist + shell: echo $key1; echo $other1 + register: test_env4 + environment: "{{test2}}" + + - name: assert all vars appear as expected + assert: + that: + - '"val1" not in test_env4.stdout_lines' + - '"not1" in test_env4.stdout_lines' + - '"val2" in test_env4.stdout_lines' + + - block: + - name: check that task envvar does exist in block + shell: echo $key1; echo $other1 + register: test_env5 + + - name: assert all vars appear as expected in block + assert: + that: + - '"val1" not in test_env5.stdout_lines' + - '"not1" in test_env5.stdout_lines' + - '"val2" in test_env5.stdout_lines' + environment: "{{test2}}" diff --git a/test/integration/targets/gathering_facts/runme.sh b/test/integration/targets/gathering_facts/runme.sh new file mode 100755 index 0000000000..925910b226 --- /dev/null +++ b/test/integration/targets/gathering_facts/runme.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -eux + +ansible-playbook test_gathering_facts.yml -i ../../inventory -v "$@" diff --git a/test/integration/targets/gathering_facts/test_gathering_facts.yml b/test/integration/targets/gathering_facts/test_gathering_facts.yml new file mode 100644 index 0000000000..ed3fa841ba --- /dev/null +++ b/test/integration/targets/gathering_facts/test_gathering_facts.yml @@ -0,0 +1,133 @@ +--- + +- hosts: facthost0 + tags: [ 'fact_min' ] + connection: local + gather_subset: "all" + gather_facts: yes + tasks: + - setup: + register: facts + - debug: var=facts + - name: Test that retrieving all facts works + assert: + that: + - '"{{ ansible_user_id|default("UNDEF_MIN") }}" != "UNDEF_MIN"' + - '"{{ ansible_interfaces|default("UNDEF_NET") }}" != "UNDEF_NET"' + - '"{{ ansible_mounts|default("UNDEF_HW") }}" != "UNDEF_HW"' + - '"{{ ansible_virtualization_role|default("UNDEF_VIRT") }}" != "UNDEF_VIRT"' + +- hosts: facthost1 + tags: [ 'fact_min' ] + connection: local + gather_subset: "!all" + gather_facts: yes + tasks: + - name: Test that only retrieving minimal facts work + assert: + that: + - '"{{ ansible_user_id|default("UNDEF_MIN") }}" != "UNDEF_MIN"' + - '"{{ ansible_interfaces|default("UNDEF_NET") }}" == "UNDEF_NET"' + - '"{{ ansible_mounts|default("UNDEF_HW") }}" == "UNDEF_HW"' + - '"{{ ansible_virtualization_role|default("UNDEF_VIRT") }}" == "UNDEF_VIRT"' + +- hosts: facthost2 + tags: [ 'fact_network' ] + connection: local + gather_subset: "network" + gather_facts: yes + tasks: + - name: Test that retrieving network facts work + assert: + that: + - '"{{ ansible_user_id|default("UNDEF_MIN") }}" != "UNDEF_MIN"' + - '"{{ ansible_interfaces|default("UNDEF_NET") }}" != "UNDEF_NET"' + - '"{{ ansible_mounts|default("UNDEF_HW") }}" == "UNDEF_HW"' + - '"{{ ansible_virtualization_role|default("UNDEF_VIRT") }}" == "UNDEF_VIRT"' + +- hosts: facthost3 + tags: [ 'fact_hardware' ] + connection: local + gather_subset: "hardware" + gather_facts: yes + tasks: + - name: Test that retrieving hardware facts work + assert: + that: + - '"{{ ansible_user_id|default("UNDEF_MIN") }}" != "UNDEF_MIN"' + - '"{{ ansible_interfaces|default("UNDEF_NET") }}" == "UNDEF_NET"' + - '"{{ ansible_mounts|default("UNDEF_HW") }}" != "UNDEF_HW"' + - '"{{ ansible_virtualization_role|default("UNDEF_VIRT") }}" == "UNDEF_VIRT"' + +- hosts: facthost4 + tags: [ 'fact_virtual' ] + connection: local + gather_subset: "virtual" + gather_facts: yes + tasks: + - name: Test that retrieving virtualization facts work + assert: + that: + - '"{{ ansible_user_id|default("UNDEF_MIN") }}" != "UNDEF_MIN"' + - '"{{ ansible_interfaces|default("UNDEF_NET") }}" == "UNDEF_NET"' + - '"{{ ansible_mounts|default("UNDEF_HW") }}" == "UNDEF_HW"' + - '"{{ ansible_virtualization_role|default("UNDEF_VIRT") }}" != "UNDEF_VIRT"' + +- hosts: facthost5 + tags: [ 'fact_comma_string' ] + connection: local + gather_subset: "virtual,network" + gather_facts: yes + tasks: + - name: Test that retrieving virtualization and network as a string works + assert: + that: + - '"{{ ansible_user_id|default("UNDEF_MIN") }}" != "UNDEF_MIN"' + - '"{{ ansible_interfaces|default("UNDEF_NET") }}" != "UNDEF_NET"' + - '"{{ ansible_mounts|default("UNDEF_HW") }}" == "UNDEF_HW"' + - '"{{ ansible_virtualization_role|default("UNDEF_VIRT") }}" != "UNDEF_VIRT"' + +- hosts: facthost6 + tags: [ 'fact_yaml_list' ] + connection: local + gather_subset: + - virtual + - network + gather_facts: yes + tasks: + - name: Test that retrieving virtualization and network as a string works + assert: + that: + - '"{{ ansible_user_id|default("UNDEF_MIN") }}" != "UNDEF_MIN"' + - '"{{ ansible_interfaces|default("UNDEF_NET") }}" != "UNDEF_NET"' + - '"{{ ansible_mounts|default("UNDEF_HW") }}" == "UNDEF_HW"' + - '"{{ ansible_virtualization_role|default("UNDEF_VIRT") }}" != "UNDEF_VIRT"' + +- hosts: facthost7 + tags: [ 'fact_negation' ] + connection: local + gather_subset: "!hardware" + gather_facts: yes + tasks: + - name: Test that negation of fact subsets work + assert: + that: + - '"{{ ansible_user_id|default("UNDEF_MIN") }}" != "UNDEF_MIN"' + - '"{{ ansible_interfaces|default("UNDEF_NET") }}" != "UNDEF_NET"' + - '"{{ ansible_mounts|default("UNDEF_HW") }}" == "UNDEF_HW"' + - '"{{ ansible_virtualization_role|default("UNDEF_VIRT") }}" != "UNDEF_VIRT"' + +- hosts: facthost8 + tags: [ 'fact_mixed_negation_addition' ] + connection: local + gather_subset: "!hardware,network" + gather_facts: yes + tasks: + - name: Test that negation and additional subsets work together + assert: + that: + - '"{{ ansible_user_id|default("UNDEF_MIN") }}" != "UNDEF_MIN"' + - '"{{ ansible_interfaces|default("UNDEF_NET") }}" != "UNDEF_NET"' + - '"{{ ansible_mounts|default("UNDEF_HW") }}" == "UNDEF_HW"' + - '"{{ ansible_virtualization_role|default("UNDEF_VIRT") }}" == "UNDEF_VIRT"' + diff --git a/test/integration/targets/group_by/inventory.group_by b/test/integration/targets/group_by/inventory.group_by new file mode 100644 index 0000000000..d8d285dee5 --- /dev/null +++ b/test/integration/targets/group_by/inventory.group_by @@ -0,0 +1,6 @@ +[lamini] +alpaca genus=vicugna +llama genus=lama + +[lamini:vars] +ansible_connection=local diff --git a/test/integration/targets/group_by/runme.sh b/test/integration/targets/group_by/runme.sh new file mode 100755 index 0000000000..c6f6841e5c --- /dev/null +++ b/test/integration/targets/group_by/runme.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -eux + +ansible-playbook test_group_by.yml -i inventory.group_by -v "$@" diff --git a/test/integration/targets/group_by/test_group_by.yml b/test/integration/targets/group_by/test_group_by.yml new file mode 100644 index 0000000000..87d1809e8d --- /dev/null +++ b/test/integration/targets/group_by/test_group_by.yml @@ -0,0 +1,127 @@ +# test code for the group_by module +# (c) 2014, Chris Church <cchurch@ansible.com> + +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +- name: Create overall groups + hosts: lamini + gather_facts: false + tasks: + - debug: var=genus + - name: group by genus + group_by: key={{ genus }} + + - name: group by first three letters of genus with key in quotes + group_by: key="{{ genus | truncate(3, true, '') }}" + + - name: group by first two letters of genus with key not in quotes + group_by: key={{ genus | truncate(2, true, '') }} + + - name: group by genus in uppercase using complex args + group_by: { key: "{{ genus | upper() }}" } + +- name: Vicunga group validation + hosts: vicugna + gather_facts: false + tasks: + - name: verify that only the alpaca is in this group + assert: { that: "inventory_hostname == 'alpaca'" } + - name: set a fact to check that we ran this play + set_fact: genus_vicugna=true + +- name: Lama group validation + hosts: lama + gather_facts: false + tasks: + - name: verify that only the llama is in this group + assert: { that: "inventory_hostname == 'llama'" } + - name: set a fact to check that we ran this play + set_fact: genus_lama=true + +- name: Vic group validation + hosts: vic + gather_facts: false + tasks: + - name: verify that only the alpaca is in this group + assert: { that: "inventory_hostname == 'alpaca'" } + - name: set a fact to check that we ran this play + set_fact: genus_vic=true + +- name: Lam group validation + hosts: lam + gather_facts: false + tasks: + - name: verify that only the llama is in this group + assert: { that: "inventory_hostname == 'llama'" } + - name: set a fact to check that we ran this play + set_fact: genus_lam=true + +- name: Vi group validation + hosts: vi + gather_facts: false + tasks: + - name: verify that only the alpaca is in this group + assert: { that: "inventory_hostname == 'alpaca'" } + - name: set a fact to check that we ran this play + set_fact: genus_vi=true + +- name: La group validation + hosts: la + gather_facts: false + tasks: + - name: verify that only the llama is in this group + assert: { that: "inventory_hostname == 'llama'" } + - name: set a fact to check that we ran this play + set_fact: genus_la=true + +- name: VICUGNA group validation + hosts: VICUGNA + gather_facts: false + tasks: + - name: verify that only the alpaca is in this group + assert: { that: "inventory_hostname == 'alpaca'" } + - name: set a fact to check that we ran this play + set_fact: genus_VICUGNA=true + +- name: LAMA group validation + hosts: LAMA + gather_facts: false + tasks: + - name: verify that only the llama is in this group + assert: { that: "inventory_hostname == 'llama'" } + - name: set a fact to check that we ran this play + set_fact: genus_LAMA=true + +- name: genus group validation (expect skipped) + hosts: 'genus' + gather_facts: false + tasks: + - name: no hosts should match this group + fail: msg="should never get here" + +- name: alpaca validation of groups + hosts: alpaca + gather_facts: false + tasks: + - name: check that alpaca matched all four groups + assert: { that: ["genus_vicugna", "genus_vic", "genus_vi", "genus_VICUGNA"] } + +- name: llama validation of groups + hosts: llama + gather_facts: false + tasks: + - name: check that llama matched all four groups + assert: { that: ["genus_lama", "genus_lam", "genus_la", "genus_LAMA"] } diff --git a/test/integration/targets/handlers/inventory.handlers b/test/integration/targets/handlers/inventory.handlers new file mode 100644 index 0000000000..905026f12e --- /dev/null +++ b/test/integration/targets/handlers/inventory.handlers @@ -0,0 +1,6 @@ +[testgroup] +A +B +C +D +E diff --git a/test/integration/targets/handlers/roles/test_force_handlers/handlers/main.yml b/test/integration/targets/handlers/roles/test_force_handlers/handlers/main.yml new file mode 100644 index 0000000000..2cfb1ef710 --- /dev/null +++ b/test/integration/targets/handlers/roles/test_force_handlers/handlers/main.yml @@ -0,0 +1,2 @@ +- name: echoing handler + command: echo CALLED_HANDLER_{{ inventory_hostname }}
\ No newline at end of file diff --git a/test/integration/targets/handlers/roles/test_force_handlers/tasks/main.yml b/test/integration/targets/handlers/roles/test_force_handlers/tasks/main.yml new file mode 100644 index 0000000000..ea01660ba7 --- /dev/null +++ b/test/integration/targets/handlers/roles/test_force_handlers/tasks/main.yml @@ -0,0 +1,26 @@ +--- + +# We notify for A and B, and hosts B and C fail. +# When forcing, we expect A and B to run handlers +# When not forcing, we expect only B to run handlers + +- name: notify the handler for host A and B + shell: echo + notify: + - echoing handler + when: inventory_hostname == 'A' or inventory_hostname == 'B' + +- name: EXPECTED FAILURE fail task for all + fail: msg="Fail All" + when: fail_all is defined and fail_all + +- name: EXPECTED FAILURE fail task for A + fail: msg="Fail A" + when: inventory_hostname == 'A' + +- name: EXPECTED FAILURE fail task for C + fail: msg="Fail C" + when: inventory_hostname == 'C' + +- name: echo after A and C have failed + command: echo CALLED_TASK_{{ inventory_hostname }}
\ No newline at end of file diff --git a/test/integration/targets/handlers/roles/test_handlers/handlers/main.yml b/test/integration/targets/handlers/roles/test_handlers/handlers/main.yml new file mode 100644 index 0000000000..b8ee48b5c8 --- /dev/null +++ b/test/integration/targets/handlers/roles/test_handlers/handlers/main.yml @@ -0,0 +1,5 @@ +- name: set handler fact + set_fact: + handler_called: True +- name: test handler + debug: msg="handler called" diff --git a/test/integration/targets/handlers/roles/test_handlers/meta/main.yml b/test/integration/targets/handlers/roles/test_handlers/meta/main.yml new file mode 100644 index 0000000000..74d2c33354 --- /dev/null +++ b/test/integration/targets/handlers/roles/test_handlers/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: [] + diff --git a/test/integration/targets/handlers/roles/test_handlers/tasks/main.yml b/test/integration/targets/handlers/roles/test_handlers/tasks/main.yml new file mode 100644 index 0000000000..1c1d819269 --- /dev/null +++ b/test/integration/targets/handlers/roles/test_handlers/tasks/main.yml @@ -0,0 +1,52 @@ +# test code for the async keyword +# (c) 2014, James Tanner <tanner.jc@gmail.com> + +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + + +- name: reset handler_called variable to false for all hosts + set_fact: + handler_called: False + tags: scenario1 + +- name: notify the handler for host A only + shell: echo + notify: + - set handler fact + when: inventory_hostname == 'A' + tags: scenario1 + +- name: force handler execution now + meta: "flush_handlers" + tags: scenario1 + +- debug: var=handler_called + tags: scenario1 + +- name: validate the handler only ran on one host + assert: + that: + - "inventory_hostname == 'A' and handler_called == True or handler_called == False" + tags: scenario1 + +- name: 'test notify with loop' + debug: msg='a task' + changed_when: item == 1 + notify: test handler + with_items: + - 1 + - 2 + tags: scenario2 diff --git a/test/integration/targets/handlers/roles/test_handlers_meta/handlers/main.yml b/test/integration/targets/handlers/roles/test_handlers_meta/handlers/main.yml new file mode 100644 index 0000000000..634e6eca2a --- /dev/null +++ b/test/integration/targets/handlers/roles/test_handlers_meta/handlers/main.yml @@ -0,0 +1,7 @@ +- name: set_handler_fact_1 + set_fact: + handler1_called: True + +- name: set_handler_fact_2 + set_fact: + handler2_called: True diff --git a/test/integration/targets/handlers/roles/test_handlers_meta/tasks/main.yml b/test/integration/targets/handlers/roles/test_handlers_meta/tasks/main.yml new file mode 100644 index 0000000000..047b61ce88 --- /dev/null +++ b/test/integration/targets/handlers/roles/test_handlers_meta/tasks/main.yml @@ -0,0 +1,41 @@ +# test code for the async keyword +# (c) 2014, James Tanner <tanner.jc@gmail.com> + +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +- name: notify the first handler + shell: echo + notify: + - set_handler_fact_1 + +- name: force handler execution now + meta: "flush_handlers" + +- name: assert handler1 ran and not handler2 + assert: + that: + - "handler1_called is defined" + - "handler2_called is not defined" + +- name: reset handler1_called + set_fact: + handler1_called: False + +- name: notify the second handler + shell: echo + notify: + - set_handler_fact_2 + diff --git a/test/integration/targets/handlers/runme.sh b/test/integration/targets/handlers/runme.sh new file mode 100755 index 0000000000..48dfd8368b --- /dev/null +++ b/test/integration/targets/handlers/runme.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +set -eux + +ansible-playbook test_handlers.yml -i inventory.handlers -v "$@" --tags scenario1 + +[ "$(ansible-playbook test_handlers.yml -i inventory.handlers -v "$@" --tags scenario2 -l A \ +| egrep -o 'RUNNING HANDLER \[test_handlers : .*?]')" = "RUNNING HANDLER [test_handlers : test handler]" ] + +# Not forcing, should only run on successful host +[ "$(ansible-playbook test_force_handlers.yml -i inventory.handlers -v "$@" --tags normal \ +| egrep -o CALLED_HANDLER_. | sort | uniq | xargs)" = "CALLED_HANDLER_B" ] + +# Forcing from command line +[ "$(ansible-playbook test_force_handlers.yml -i inventory.handlers -v "$@" --tags normal --force-handlers \ +| egrep -o CALLED_HANDLER_. | sort | uniq | xargs)" = "CALLED_HANDLER_A CALLED_HANDLER_B" ] + +# Forcing from command line, should only run later tasks on unfailed hosts +[ "$(ansible-playbook test_force_handlers.yml -i inventory.handlers -v "$@" --tags normal --force-handlers \ +| egrep -o CALLED_TASK_. | sort | uniq | xargs)" = "CALLED_TASK_B CALLED_TASK_D CALLED_TASK_E" ] + +# Forcing from command line, should call handlers even if all hosts fail +[ "$(ansible-playbook test_force_handlers.yml -i inventory.handlers -v "$@" --tags normal --force-handlers -e fail_all=yes \ +| egrep -o CALLED_HANDLER_. | sort | uniq | xargs)" = "CALLED_HANDLER_A CALLED_HANDLER_B" ] + +# Forcing from ansible.cfg +[ "$(ANSIBLE_FORCE_HANDLERS=true ansible-playbook test_force_handlers.yml -i inventory.handlers -v "$@" --tags normal \ +| egrep -o CALLED_HANDLER_. | sort | uniq | xargs)" = "CALLED_HANDLER_A CALLED_HANDLER_B" ] + +# Forcing true in play +[ "$(ansible-playbook test_force_handlers.yml -i inventory.handlers -v "$@" --tags force_true_in_play \ +| egrep -o CALLED_HANDLER_. | sort | uniq | xargs)" = "CALLED_HANDLER_A CALLED_HANDLER_B" ] + +# Forcing false in play, which overrides command line +[ "$(ansible-playbook test_force_handlers.yml -i inventory.handlers -v "$@" --tags force_false_in_play --force-handlers \ +| egrep -o CALLED_HANDLER_. | sort | uniq | xargs)" = "CALLED_HANDLER_B" ] diff --git a/test/integration/targets/handlers/test_force_handlers.yml b/test/integration/targets/handlers/test_force_handlers.yml new file mode 100644 index 0000000000..f7cadbd86d --- /dev/null +++ b/test/integration/targets/handlers/test_force_handlers.yml @@ -0,0 +1,30 @@ +--- + +- name: test force handlers (default) + tags: normal + hosts: testgroup + gather_facts: False + connection: local + roles: + - { role: test_force_handlers } + tasks: + - debug: msg="you should see this with --tags=normal" + +- name: test force handlers (set to true) + tags: force_true_in_play + hosts: testgroup + gather_facts: False + connection: local + force_handlers: True + roles: + - { role: test_force_handlers, tags: force_true_in_play } + + +- name: test force handlers (set to false) + tags: force_false_in_play + hosts: testgroup + gather_facts: False + connection: local + force_handlers: False + roles: + - { role: test_force_handlers, tags: force_false_in_play } diff --git a/test/integration/targets/handlers/test_handlers.yml b/test/integration/targets/handlers/test_handlers.yml new file mode 100644 index 0000000000..dafa9ceebe --- /dev/null +++ b/test/integration/targets/handlers/test_handlers.yml @@ -0,0 +1,26 @@ +--- +- name: run handlers + hosts: A + gather_facts: False + connection: local + roles: + - { role: test_handlers_meta, tags: ['scenario1'] } + +- name: verify final handler was run + hosts: A + gather_facts: False + connection: local + tasks: + - name: verify handler2 ran + assert: + that: + - "not hostvars[inventory_hostname]['handler1_called']" + - "'handler2_called' in hostvars[inventory_hostname]" + tags: ['scenario1'] + +- name: test handlers + hosts: testgroup + gather_facts: False + connection: local + roles: + - { role: test_handlers } diff --git a/test/integration/targets/hash/roles/test_hash_behavior/defaults/main.yml b/test/integration/targets/hash/roles/test_hash_behavior/defaults/main.yml new file mode 100644 index 0000000000..10cc09f31c --- /dev/null +++ b/test/integration/targets/hash/roles/test_hash_behavior/defaults/main.yml @@ -0,0 +1,21 @@ +# test code for the hash variable behavior +# (c) 2014, James Cammarata <jcammarata@ansible.com> + +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +--- +test_hash: + default_vars: "this is in role defaults/main.yml" diff --git a/test/integration/targets/hash/roles/test_hash_behavior/meta/main.yml b/test/integration/targets/hash/roles/test_hash_behavior/meta/main.yml new file mode 100644 index 0000000000..c3dcf7aaf9 --- /dev/null +++ b/test/integration/targets/hash/roles/test_hash_behavior/meta/main.yml @@ -0,0 +1,18 @@ +# test code for the hash variable behavior +# (c) 2014, James Cammarata <jcammarata@ansible.com> + +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + diff --git a/test/integration/targets/hash/roles/test_hash_behavior/tasks/main.yml b/test/integration/targets/hash/roles/test_hash_behavior/tasks/main.yml new file mode 100644 index 0000000000..463141edd3 --- /dev/null +++ b/test/integration/targets/hash/roles/test_hash_behavior/tasks/main.yml @@ -0,0 +1,42 @@ +# test code for the hash variable behavior +# (c) 2014, James Cammarata <jcammarata@ansible.com> + +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +- name: get the hash behavior env setting + shell: env | grep ^ANSIBLE_HASH_BEHAVIOUR'=' | cut -f2- -d'=' + register: hash_behavior + # This only works with the local connection. The way this test is run means the + connection: local + delegate_to: localhost + + +- name: debug hash behavior result + debug: var=hash_behavior.stdout + +- name: assert hash behavior is merge or replace + assert: + that: + - "hash_behavior.stdout in ('merge', 'replace')" + +- name: debug test_hash var + debug: var=test_hash + +- name: assert the dictionary values match + assert: + that: + - "hash_behavior.stdout == 'merge' and test_hash == merged_hash or hash_behavior.stdout == 'replace' and test_hash == replaced_hash" + diff --git a/test/integration/targets/hash/roles/test_hash_behavior/vars/main.yml b/test/integration/targets/hash/roles/test_hash_behavior/vars/main.yml new file mode 100644 index 0000000000..2068e9fbaf --- /dev/null +++ b/test/integration/targets/hash/roles/test_hash_behavior/vars/main.yml @@ -0,0 +1,21 @@ +# test code for the hash variable behavior +# (c) 2014, James Cammarata <jcammarata@ansible.com> + +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +--- +test_hash: + role_vars: "this is in role vars/main.yml" diff --git a/test/integration/targets/hash/runme.sh b/test/integration/targets/hash/runme.sh new file mode 100755 index 0000000000..9448e4e098 --- /dev/null +++ b/test/integration/targets/hash/runme.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +set -eux + +JSON_ARG='{"test_hash":{"extra_args":"this is an extra arg"}}' + +ANSIBLE_HASH_BEHAVIOUR=replace ansible-playbook test_hash.yml -i ../../inventory -v "$@" -e "${JSON_ARG}" +ANSIBLE_HASH_BEHAVIOUR=merge ansible-playbook test_hash.yml -i ../../inventory -v "$@" -e "${JSON_ARG}" diff --git a/test/integration/targets/hash/test_hash.yml b/test/integration/targets/hash/test_hash.yml new file mode 100644 index 0000000000..271563355b --- /dev/null +++ b/test/integration/targets/hash/test_hash.yml @@ -0,0 +1,20 @@ +--- +- hosts: testhost + vars_files: + - vars/test_hash_vars.yml + vars: + test_hash: + playbook_vars: "this is a playbook variable" + replaced_hash: + extra_args: "this is an extra arg" + merged_hash: + default_vars: "this is in role defaults/main.yml" + extra_args: "this is an extra arg" + group_vars_all: "this is in group_vars/all" + host_vars_testhost: "this is in host_vars/testhost" + playbook_vars: "this is a playbook variable" + role_argument: "this is a role argument variable" + role_vars: "this is in role vars/main.yml" + vars_file: "this is in a vars_file" + roles: + - { role: test_hash_behavior, test_hash: {'role_argument':'this is a role argument variable'} } diff --git a/test/integration/targets/hash/vars/test_hash_vars.yml b/test/integration/targets/hash/vars/test_hash_vars.yml new file mode 100644 index 0000000000..e25f8576c3 --- /dev/null +++ b/test/integration/targets/hash/vars/test_hash_vars.yml @@ -0,0 +1,3 @@ +--- +test_hash: + vars_file: "this is in a vars_file" diff --git a/test/integration/targets/hosts_field/inventory.hosts_field b/test/integration/targets/hosts_field/inventory.hosts_field new file mode 100644 index 0000000000..81efd478f8 --- /dev/null +++ b/test/integration/targets/hosts_field/inventory.hosts_field @@ -0,0 +1 @@ +42 ansible_host=127.0.0.42 ansible_connection=local diff --git a/test/integration/targets/hosts_field/runme.sh b/test/integration/targets/hosts_field/runme.sh new file mode 100755 index 0000000000..1291933c5b --- /dev/null +++ b/test/integration/targets/hosts_field/runme.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +set -eux + +# Hosts in playbook has a list of strings consisting solely of digits +ansible-playbook test_hosts_field.yml -i inventory.hosts_field -e 'target_kv=42' \ + -e '{ "target_json_cli": "42", "target_json_cli_list": ["42", "localhost"] }' -e "@test_hosts_field.json" \ + -t string_digit_host_in_list -v "$@" | tee test_hosts_field.out +grep 'Running on 42' test_hosts_field.out 2>&1 +test "$(grep -c 'ok=1' test_hosts_field.out)" = 1 + +# Hosts taken from kv extra_var on the CLI +ansible-playbook test_hosts_field.yml -i inventory.hosts_field -e 'target_kv=42' \ + -e '{ "target_json_cli": "42", "target_json_cli_list": ["42", "localhost"] }' -e "@test_hosts_field.json" \ + -t hosts_from_kv_string -v "$@" | tee test_hosts_field.out +grep 'Running on 42' test_hosts_field.out 2>&1 +test "$(grep -c 'ok=1' test_hosts_field.out)" = 1 + +# hosts is taken from an all digit json extra_vars string on the CLI +ansible-playbook test_hosts_field.yml -i inventory.hosts_field -e 'target_kv=42' \ + -e '{ "target_json_cli": "42", "target_json_cli_list": ["42", "localhost"] }' -e "@test_hosts_field.json" \ + -t hosts_from_cli_json_string -v "$@" | tee test_hosts_field.out +grep 'Running on 42' test_hosts_field.out 2>&1 +test "$(grep -c 'ok=1' test_hosts_field.out)" = 1 + +# hosts is taken from a json list in extra_vars on the CLI +ansible-playbook test_hosts_field.yml -i inventory.hosts_field -e 'target_kv=42' \ + -e '{ "target_json_cli": "42", "target_json_cli_list": ["42", "localhost"] }' -e "@test_hosts_field.json" \ + -t hosts_from_cli_json_list -v "$@" | tee test_hosts_field.out +grep 'Running on 42' test_hosts_field.out 2>&1 +grep 'Running on localhost' test_hosts_field.out 2>&1 +test "$(grep -c 'ok=1' test_hosts_field.out)" = 2 + +# hosts is taken from a json string in an extra_vars file +ansible-playbook test_hosts_field.yml -i inventory.hosts_field -e 'target_kv=42' \ + -e '{ "target_json_cli": "42", "target_json_cli_list": ["42", "localhost"] }' -e "@test_hosts_field.json" \ + -t hosts_from_json_file_string -v "$@" | tee test_hosts_field.out +grep 'Running on 42' test_hosts_field.out 2>&1 +test "$(grep -c 'ok=1' test_hosts_field.out)" = 1 + +# hosts is taken from a json list in an extra_vars file +ansible-playbook test_hosts_field.yml -i inventory.hosts_field -e 'target_kv=42' \ + -e '{ "target_json_cli": "42", "target_json_cli_list": ["42", "localhost"] }' -e "@test_hosts_field.json" \ + -t hosts_from_json_file_list -v "$@" | tee test_hosts_field.out +grep 'Running on 42' test_hosts_field.out 2>&1 +grep 'Running on localhost' test_hosts_field.out 2>&1 +test "$(grep -c 'ok=1' test_hosts_field.out)" = 2 + +rm test_hosts_field.out diff --git a/test/integration/targets/hosts_field/test_hosts_field.json b/test/integration/targets/hosts_field/test_hosts_field.json new file mode 100644 index 0000000000..2687556093 --- /dev/null +++ b/test/integration/targets/hosts_field/test_hosts_field.json @@ -0,0 +1 @@ +{ "target_json_file": "42", "target_json_file_list": ["42", "localhost"] } diff --git a/test/integration/targets/hosts_field/test_hosts_field.yml b/test/integration/targets/hosts_field/test_hosts_field.yml new file mode 100644 index 0000000000..568d702503 --- /dev/null +++ b/test/integration/targets/hosts_field/test_hosts_field.yml @@ -0,0 +1,62 @@ +--- +#- name: Host in playbook is an integer +# hosts: 42 +# tags: numeric_host +# tasks: +# - command: echo 'Running on {{ inventory_hostname }}' + +#- name: Host in playbook is a string of digits +# hosts: "42" +# tags: string_digit_host +# tasks: +# - command: echo 'Running on {{ inventory_hostname }}' + +#- name: Host in playbook is a list of integer +# hosts: +# - 42 +# tags: numeric_host_in_list +# tasks: +# - command: echo 'Running on {{ inventory_hostname }}' + +- name: Host in playbook is a list of strings of digits + hosts: + - "42" + gather_facts: False + tags: string_digit_host_in_list + tasks: + - command: echo 'Running on {{ inventory_hostname }}' + +- name: Hosts taken from kv extra_var on the CLI + hosts: "{{ target_kv }}" + gather_facts: False + tags: hosts_from_kv_string + tasks: + - command: echo 'Running on {{ inventory_hostname }}' + +- name: Hosts taken from a json string on the CLI + hosts: "{{ target_json_cli }}" + gather_facts: False + tags: hosts_from_cli_json_string + tasks: + - command: echo 'Running on {{ inventory_hostname }}' + +- name: Hosts taken from a json list on the CLI + hosts: "{{ target_json_cli_list }}" + gather_facts: False + tags: hosts_from_cli_json_list + tasks: + - command: echo 'Running on {{ inventory_hostname }}' + +- name: Hosts is taken from a json string in an extra_vars file + hosts: "{{ target_json_file }}" + gather_facts: False + tags: hosts_from_json_file_string + tasks: + - command: echo 'Running on {{ inventory_hostname }}' + +- name: Hosts is taken from a json list in an extra_vars file + hosts: "{{ target_json_file_list }}" + gather_facts: False + tags: hosts_from_json_file_list + tasks: + - command: echo 'Running on {{ inventory_hostname }}' diff --git a/test/integration/targets/includes/roles/test_includes/handlers/main.yml b/test/integration/targets/includes/roles/test_includes/handlers/main.yml new file mode 100644 index 0000000000..25e7d3886f --- /dev/null +++ b/test/integration/targets/includes/roles/test_includes/handlers/main.yml @@ -0,0 +1,2 @@ +- include: more_handlers.yml + diff --git a/test/integration/targets/includes/roles/test_includes/handlers/more_handlers.yml b/test/integration/targets/includes/roles/test_includes/handlers/more_handlers.yml new file mode 100644 index 0000000000..947ede8d91 --- /dev/null +++ b/test/integration/targets/includes/roles/test_includes/handlers/more_handlers.yml @@ -0,0 +1,14 @@ +- name: included_handler + set_fact: + ca: 4001 + cb: 4002 + cc: 4003 + +- name: verify_handler + assert: + that: + - "ca == 4001" + - "cb == 4002" + - "cc == 4003" + + diff --git a/test/integration/targets/includes/roles/test_includes/tasks/empty.yml b/test/integration/targets/includes/roles/test_includes/tasks/empty.yml new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/integration/targets/includes/roles/test_includes/tasks/empty.yml diff --git a/test/integration/targets/includes/roles/test_includes/tasks/included_task1.yml b/test/integration/targets/includes/roles/test_includes/tasks/included_task1.yml new file mode 100644 index 0000000000..8fe79a1cb7 --- /dev/null +++ b/test/integration/targets/includes/roles/test_includes/tasks/included_task1.yml @@ -0,0 +1,10 @@ +- set_fact: + ca: "{{ a }}" +- debug: var=ca +- set_fact: + cb: "{{b}}" +- debug: var=cb +- set_fact: + cc: "{{ c }}" +- debug: var=cc + diff --git a/test/integration/targets/includes/roles/test_includes/tasks/main.yml b/test/integration/targets/includes/roles/test_includes/tasks/main.yml new file mode 100644 index 0000000000..33aefe8959 --- /dev/null +++ b/test/integration/targets/includes/roles/test_includes/tasks/main.yml @@ -0,0 +1,84 @@ +# test code for the ping module +# (c) 2014, James Cammarata <jcammarata@ansible.com> + +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + + +- include: included_task1.yml a=1 b=2 c=3 + +- name: verify non-variable include params + assert: + that: + - "ca == '1'" + - "cb == '2'" + - "cc == '3'" + +- set_fact: + a: 101 + b: 102 + c: 103 + +- include: included_task1.yml a={{a}} b={{b}} c=103 + +- name: verify variable include params + assert: + that: + - "ca == 101" + - "cb == 102" + - "cc == 103" + +# Test that strings are not turned into numbers +- set_fact: + a: "101" + b: "102" + c: "103" + +- include: included_task1.yml a={{a}} b={{b}} c=103 + +- name: verify variable include params + assert: + that: + - "ca == '101'" + - "cb == '102'" + - "cc == '103'" + +# now try long form includes + +- include: included_task1.yml + vars: + a: 201 + b: 202 + c: 203 + +- debug: var=a +- debug: var=b +- debug: var=c + +- name: verify long-form include params + assert: + that: + - "ca == 201" + - "cb == 202" + - "cc == 203" + +- name: test handlers with includes + shell: echo 1 + notify: + # both these via a handler include + - included_handler + - verify_handler + + diff --git a/test/integration/targets/includes/roles/test_includes/tasks/not_a_role_task.yml b/test/integration/targets/includes/roles/test_includes/tasks/not_a_role_task.yml new file mode 100644 index 0000000000..862b051ce5 --- /dev/null +++ b/test/integration/targets/includes/roles/test_includes/tasks/not_a_role_task.yml @@ -0,0 +1,4 @@ +- set_fact: + ca: 33000 + cb: 33001 + cc: 33002 diff --git a/test/integration/targets/includes/runme.sh b/test/integration/targets/includes/runme.sh new file mode 100755 index 0000000000..dff40029b1 --- /dev/null +++ b/test/integration/targets/includes/runme.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -eux + +ansible-playbook test_includes.yml -i ../../inventory "$@" diff --git a/test/integration/targets/includes/test_includes.yml b/test/integration/targets/includes/test_includes.yml new file mode 100644 index 0000000000..d7303880f1 --- /dev/null +++ b/test/integration/targets/includes/test_includes.yml @@ -0,0 +1,3 @@ +- include: test_includes2.yml parameter1=asdf parameter2=jkl + +- include: test_includes3.yml diff --git a/test/integration/targets/includes/test_includes2.yml b/test/integration/targets/includes/test_includes2.yml new file mode 100644 index 0000000000..1b15682d70 --- /dev/null +++ b/test/integration/targets/includes/test_includes2.yml @@ -0,0 +1,22 @@ + +- name: verify playbook includes can take parameters + hosts: testhost + tasks: + - assert: + that: + - "parameter1 == 'asdf'" + - "parameter2 == 'jkl'" + +- name: verify task include logic + hosts: testhost + gather_facts: True + roles: + - { role: test_includes, tags: test_includes } + tasks: + - include: roles/test_includes/tasks/not_a_role_task.yml + - include: roles/test_includes/tasks/empty.yml + - assert: + that: + - "ca == 33000" + - "cb == 33001" + - "cc == 33002" diff --git a/test/integration/targets/includes/test_includes3.yml b/test/integration/targets/includes/test_includes3.yml new file mode 100644 index 0000000000..012ee20568 --- /dev/null +++ b/test/integration/targets/includes/test_includes3.yml @@ -0,0 +1,7 @@ +--- +- hosts: localhost + tasks: + - include: test_includes4.yml + with_items: ["a"] + loop_control: + loop_var: r diff --git a/test/integration/targets/includes/test_includes4.yml b/test/integration/targets/includes/test_includes4.yml new file mode 100644 index 0000000000..bee906bdfb --- /dev/null +++ b/test/integration/targets/includes/test_includes4.yml @@ -0,0 +1,2 @@ +- set_fact: + p: 1 diff --git a/test/integration/targets/lookup_paths/play.yml b/test/integration/targets/lookup_paths/play.yml new file mode 100644 index 0000000000..26a9ce10b9 --- /dev/null +++ b/test/integration/targets/lookup_paths/play.yml @@ -0,0 +1,64 @@ +- name: setup state + hosts: testhost + connection: local + gather_facts: false + tasks: + - file: path={{playbook_dir}}/files state=directory + - file: path={{playbook_dir}}/roles/showfile/files state=directory + - copy: dest={{playbook_dir}}/roles/showfile/files/testfile content='in role files' + - copy: dest={{playbook_dir}}/roles/showfile/tasks/testfile content='in role tasks' + - copy: dest={{playbook_dir}}/roles/showfile/testfile content='in role' + - copy: dest={{playbook_dir}}/files/testfile content='in files' + - copy: dest={{playbook_dir}}/testfile content='in local' + - set_fact: role_out="in role files" play_out="in files" stage='setup' + +- include: testplay.yml + +- name: remove from role/files + hosts: testhost + connection: local + gather_facts: false + tasks: + - file: path={{playbook_dir}}/roles/showfile/files/testfile state=absent + - set_fact: role_out="in role tasks" play_out="in files" stage='remove 1' + +- include: testplay.yml + +- name: remove from role/tasks + hosts: testhost + connection: local + gather_facts: false + tasks: + - file: path={{playbook_dir}}/roles/showfile/tasks/testfile state=absent + - set_fact: role_out="in files" play_out="in files" stage='remote 2' + +- include: testplay.yml + +- name: remove from role dir + hosts: testhost + connection: local + gather_facts: false + tasks: + - file: path={{playbook_dir}}/roles/showfile/testfile state=absent + - set_fact: role_out="in files" play_out="in files" stage='remove 3' + +- include: testplay.yml + +- name: remove from play/files + hosts: testhost + connection: local + gather_facts: false + tasks: + - file: path={{playbook_dir}}/files/testfile state=absent + - set_fact: role_out="in local" play_out="in local" stage='remove 4' + +- include: testplay.yml + +- name: cleanup + hosts: testhost + connection: local + gather_facts: false + tasks: + - file: path={{playbook_dir}}/testfile state=absent + - file: path={{playbook_dir}}/files state=absent + - file: path={{playbook_dir}}/roles/showfile/files state=absent diff --git a/test/integration/targets/lookup_paths/roles/showfile/tasks/main.yml b/test/integration/targets/lookup_paths/roles/showfile/tasks/main.yml new file mode 100644 index 0000000000..1b3805798d --- /dev/null +++ b/test/integration/targets/lookup_paths/roles/showfile/tasks/main.yml @@ -0,0 +1,2 @@ +- name: relative to role + set_fact: role_result="{{lookup('file', 'testfile')}}" diff --git a/test/integration/targets/lookup_paths/runme.sh b/test/integration/targets/lookup_paths/runme.sh new file mode 100755 index 0000000000..754150b4c7 --- /dev/null +++ b/test/integration/targets/lookup_paths/runme.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -eux + +ansible-playbook play.yml -i ../../inventory -v "$@" diff --git a/test/integration/targets/lookup_paths/testplay.yml b/test/integration/targets/lookup_paths/testplay.yml new file mode 100644 index 0000000000..8bf4be2c08 --- /dev/null +++ b/test/integration/targets/lookup_paths/testplay.yml @@ -0,0 +1,19 @@ +- name: test initial state + hosts: testhost + connection: local + gather_facts: false + roles: + - showfile + tasks: + - name: from play + set_fact: play_result="{{lookup('file', 'testfile')}}" + + - name: output output {{stage}} + debug: msg="play> {{play_out}}, role> {{role_out}}" + + - name: verify that result match expected + assert: + that: + - 'play_result == play_out' + - 'role_result == role_out' + diff --git a/test/integration/targets/lookup_properties/lookup.ini b/test/integration/targets/lookup_properties/lookup.ini new file mode 100644 index 0000000000..16500fd899 --- /dev/null +++ b/test/integration/targets/lookup_properties/lookup.ini @@ -0,0 +1,24 @@ +[global] +# A comment +value1=Text associated with value1 and global section +value2=Same for value2 and global section +value.dot=Properties with dot +field.with.space = another space + +[section1] +value1=section1/value1 +value2=section1/value2 + +[value_section] +value1=1 +value2=2 +value3=3 +other1=4 +other2=5 + +[other_section] +value1=1 +value2=2 +value3=3 +other1=4 +other2=5 diff --git a/test/integration/targets/lookup_properties/lookup.properties b/test/integration/targets/lookup_properties/lookup.properties new file mode 100644 index 0000000000..f388d8cfbf --- /dev/null +++ b/test/integration/targets/lookup_properties/lookup.properties @@ -0,0 +1,5 @@ +# A comment +value1=Text associated with value1 +value2=Same for value2 +value.dot=Properties with dot +field.with.space = another space diff --git a/test/integration/targets/lookup_properties/runme.sh b/test/integration/targets/lookup_properties/runme.sh new file mode 100755 index 0000000000..71a507de42 --- /dev/null +++ b/test/integration/targets/lookup_properties/runme.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -eux + +ansible-playbook test_lookup_properties.yml -i ../../inventory -v "$@" diff --git a/test/integration/targets/lookup_properties/test_lookup_properties.yml b/test/integration/targets/lookup_properties/test_lookup_properties.yml new file mode 100644 index 0000000000..4d22ce642c --- /dev/null +++ b/test/integration/targets/lookup_properties/test_lookup_properties.yml @@ -0,0 +1,40 @@ +--- +- name: "Lookup test" + hosts: "localhost" +# connection: local + tasks: + - name: "read properties value" + set_fact: + test1: "{{lookup('ini', 'value1 type=properties file=lookup.properties')}}" + test2: "{{lookup('ini', 'value2 type=properties file=lookup.properties')}}" + test_dot: "{{lookup('ini', 'value.dot type=properties file=lookup.properties')}}" + field_with_space: "{{lookup('ini', 'field.with.space type=properties file=lookup.properties')}}" + - debug: var={{item}} + with_items: [ 'test1', 'test2', 'test_dot', 'field_with_space' ] + - name: "read ini value" + set_fact: + value1_global: "{{lookup('ini', 'value1 section=global file=lookup.ini')}}" + value2_global: "{{lookup('ini', 'value2 section=global file=lookup.ini')}}" + value1_section1: "{{lookup('ini', 'value1 section=section1 file=lookup.ini')}}" + - debug: var={{item}} + with_items: [ 'value1_global', 'value2_global', 'value1_section1' ] + - name: "read ini value with section and regexp" + set_fact: + value_section: "{{lookup('ini', 'value[1-2] section=value_section file=lookup.ini re=true')}}" + other_section: "{{lookup('ini', 'other[1-2] section=other_section file=lookup.ini re=true')}}" + - debug: var={{item}} + with_items: [ 'value_section', 'other_section' ] + - name: "Reading unknown value" + set_fact: + unknown: "{{lookup('ini', 'value2 default=unknown section=section1 file=lookup.ini')}}" + - debug: var=unknown + - name: "Looping over section section1" + debug: msg="{{item}}" + with_ini: value[1-2] section=section1 file=lookup.ini re=true + - name: "Looping over section value_section" + debug: msg="{{item}}" + with_ini: value[1-2] section=value_section file=lookup.ini re=true + - debug: msg="{{item}}" + with_ini: value[1-2] section=section1 file=lookup.ini re=true + register: _ + - debug: var=_ diff --git a/test/integration/targets/no_log/no_log_local.yml b/test/integration/targets/no_log/no_log_local.yml new file mode 100644 index 0000000000..87d76ff082 --- /dev/null +++ b/test/integration/targets/no_log/no_log_local.yml @@ -0,0 +1,66 @@ +# TODO: test against real connection plugins to ensure they're not leaking module args + +- name: normal play + hosts: testhost + gather_facts: no + tasks: + - name: args should be logged in the absence of no_log + shell: echo "LOG_ME_TASK_SUCCEEDED" + + - name: failed args should be logged in the absence of no_log + shell: echo "LOG_ME_TASK_FAILED" + failed_when: true + ignore_errors: true + + - name: item args should be logged in the absence of no_log + shell: echo {{ item }} + with_items: [ "LOG_ME_ITEM", "LOG_ME_SKIPPED", "LOG_ME_ITEM_FAILED" ] + when: item != "LOG_ME_SKIPPED" + failed_when: item == "LOG_ME_ITEM_FAILED" + ignore_errors: true + + - name: args should not be logged when task-level no_log set + shell: echo "DO_NOT_LOG_TASK_SUCCEEDED" + no_log: true + + - name: failed args should not be logged when task-level no_log set + shell: echo "DO_NOT_LOG_TASK_FAILED" + no_log: true + failed_when: true + ignore_errors: true + + - name: skipped task args should be suppressed with no_log + shell: echo "DO_NOT_LOG_TASK_SKIPPED" + no_log: true + when: false + + - name: items args should be suppressed with no_log in every state + shell: echo {{ item }} + no_log: true + with_items: [ "DO_NOT_LOG_ITEM", "DO_NOT_LOG_ITEM_SKIPPED", "DO_NOT_LOG_ITEM_FAILED" ] + when: item != "DO_NOT_LOG_ITEM_SKIPPED" + failed_when: item == "DO_NOT_LOG_ITEM_FAILED" + ignore_errors: yes + + - name: async task args should suppressed with no_log + async: 10 + poll: 1 + shell: echo "DO_NOT_LOG_ASYNC_TASK_SUCCEEDED" + no_log: true + +- name: play-level no_log set + hosts: testhost + gather_facts: no + no_log: true + tasks: + - name: args should not be logged when play-level no_log set + shell: echo "DO_NOT_LOG_PLAY" + + - name: args should not be logged when both play- and task-level no_log set + shell: echo "DO_NOT_LOG_TASK_AND_PLAY" + no_log: true + + - name: args should be logged when task-level no_log overrides play-level + shell: echo "LOG_ME_OVERRIDE" + no_log: false + diff --git a/test/integration/targets/no_log/runme.sh b/test/integration/targets/no_log/runme.sh new file mode 100755 index 0000000000..e20bb08c4f --- /dev/null +++ b/test/integration/targets/no_log/runme.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -eux + +# This test expects 7 loggable vars and 0 non-loggable ones. +# If either mismatches it fails, run the ansible-playbook command to debug. + +[ "$(ansible-playbook no_log_local.yml -i ../../inventory -vvvvv "$@" | awk \ +'BEGIN { logme = 0; nolog = 0; } /LOG_ME/ { logme += 1;} /DO_NOT_LOG/ { nolog += 1;} END { printf "%d/%d", logme, nolog; }')" = "26/0" ] diff --git a/test/integration/targets/parsing/bad_parsing.yml b/test/integration/targets/parsing/bad_parsing.yml new file mode 100644 index 0000000000..110b2903ec --- /dev/null +++ b/test/integration/targets/parsing/bad_parsing.yml @@ -0,0 +1,12 @@ +- hosts: testhost + + # the following commands should all parse fine and execute fine + # and represent quoting scenarios that should be legit + + gather_facts: False + + roles: + + # this one has a lot of things that should fail, see makefile for operation w/ tags + + - { role: test_bad_parsing } diff --git a/test/integration/targets/parsing/good_parsing.yml b/test/integration/targets/parsing/good_parsing.yml new file mode 100644 index 0000000000..8fc8d88ec9 --- /dev/null +++ b/test/integration/targets/parsing/good_parsing.yml @@ -0,0 +1,9 @@ +- hosts: testhost + + # the following commands should all parse fine and execute fine + # and represent quoting scenarios that should be legit + + gather_facts: False + + roles: + - { role: test_good_parsing, tags: test_good_parsing } diff --git a/test/integration/targets/parsing/roles/test_bad_parsing/tasks/main.yml b/test/integration/targets/parsing/roles/test_bad_parsing/tasks/main.yml new file mode 100644 index 0000000000..da8ad3d25b --- /dev/null +++ b/test/integration/targets/parsing/roles/test_bad_parsing/tasks/main.yml @@ -0,0 +1,60 @@ +# test code for the ping module +# (c) 2014, Michael DeHaan <michael@ansible.com> + +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# the following tests all raise errors, to use them in a Makefile, we run them with different flags, as +# otherwise ansible stops at the first one and we want to ensure STOP conditions for each + +- set_fact: + test_file: "{{ output_dir }}/ansible_test_file" # FIXME, use set tempdir + test_input: "owner=test" + bad_var: "{{ output_dir }}' owner=test" + chdir: "mom chdir=/tmp" + tags: common + +- file: name={{test_file}} state=touch + tags: common + +- name: remove touched file + file: name={{test_file}} state=absent + tags: common + +- name: include test that we cannot insert arguments + include: scenario1.yml + tags: scenario1 + +- name: include test that we cannot duplicate arguments + include: scenario2.yml + tags: scenario2 + +- name: include test that we can't do this for the shell module + include: scenario3.yml + tags: scenario3 + +- name: include test that we can't go all Little Bobby Droptables on a quoted var to add more + include: scenario4.yml + tags: scenario4 + +- name: test that a missing/malformed jinja2 filter fails + debug: msg="{{output_dir|badfiltername}}" + tags: scenario5 + register: filter_fail + ignore_errors: yes + +- assert: + that: + - filter_fail|failed diff --git a/test/integration/targets/parsing/roles/test_bad_parsing/tasks/scenario1.yml b/test/integration/targets/parsing/roles/test_bad_parsing/tasks/scenario1.yml new file mode 100644 index 0000000000..dab20be749 --- /dev/null +++ b/test/integration/targets/parsing/roles/test_bad_parsing/tasks/scenario1.yml @@ -0,0 +1,5 @@ +- name: test that we cannot insert arguments + file: path={{ test_file }} {{ test_input }} + failed_when: False # ignore the module, just test the parser + tags: scenario1 + diff --git a/test/integration/targets/parsing/roles/test_bad_parsing/tasks/scenario2.yml b/test/integration/targets/parsing/roles/test_bad_parsing/tasks/scenario2.yml new file mode 100644 index 0000000000..4f14f81b23 --- /dev/null +++ b/test/integration/targets/parsing/roles/test_bad_parsing/tasks/scenario2.yml @@ -0,0 +1,5 @@ +- name: test that we cannot duplicate arguments + file: path={{ test_file }} owner=test2 {{ test_input }} + failed_when: False # ignore the module, just test the parser + tags: scenario2 + diff --git a/test/integration/targets/parsing/roles/test_bad_parsing/tasks/scenario3.yml b/test/integration/targets/parsing/roles/test_bad_parsing/tasks/scenario3.yml new file mode 100644 index 0000000000..cd4da7baba --- /dev/null +++ b/test/integration/targets/parsing/roles/test_bad_parsing/tasks/scenario3.yml @@ -0,0 +1,5 @@ +- name: test that we can't do this for the shell module + shell: echo hi {{ chdir }} + failed_when: False + tags: scenario3 + diff --git a/test/integration/targets/parsing/roles/test_bad_parsing/tasks/scenario4.yml b/test/integration/targets/parsing/roles/test_bad_parsing/tasks/scenario4.yml new file mode 100644 index 0000000000..9ed1eae0b5 --- /dev/null +++ b/test/integration/targets/parsing/roles/test_bad_parsing/tasks/scenario4.yml @@ -0,0 +1,5 @@ +- name: test that we can't go all Little Bobby Droptables on a quoted var to add more + file: "name={{ bad_var }}" + failed_when: False + tags: scenario4 + diff --git a/test/integration/targets/parsing/roles/test_bad_parsing/vars/main.yml b/test/integration/targets/parsing/roles/test_bad_parsing/vars/main.yml new file mode 100644 index 0000000000..1aaeac7730 --- /dev/null +++ b/test/integration/targets/parsing/roles/test_bad_parsing/vars/main.yml @@ -0,0 +1,2 @@ +--- +output_dir: . diff --git a/test/integration/targets/parsing/roles/test_good_parsing/tasks/main.yml b/test/integration/targets/parsing/roles/test_good_parsing/tasks/main.yml new file mode 100644 index 0000000000..418b6d4040 --- /dev/null +++ b/test/integration/targets/parsing/roles/test_good_parsing/tasks/main.yml @@ -0,0 +1,204 @@ +# test code for the ping module +# (c) 2014, Michael DeHaan <michael@ansible.com> + +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# various tests of things that should not cause parsing problems + +- set_fact: + test_input: "a=1 a=2 a=3" + +- set_fact: + multi_line: | + echo old + echo mcdonald + echo had + echo a + echo farm + +- shell: echo "dog" + register: result + +- assert: + that: + result.cmd == 'echo "dog"' + +- shell: echo 'dog' + register: result + +- assert: + that: + result.cmd == 'echo \'dog\'' + +- name: a quoted argument is not sent to the shell module as anything but a string parameter + shell: echo 'dog' 'executable=/usr/bin/python' + register: result + +- debug: var=result.cmd + +- assert: + that: + result.cmd == "echo 'dog' 'executable=/usr/bin/python'" + +- name: it is valid to pass multiple key=value arguments because the shell doesn't check key=value arguments + shell: echo quackquack=here quackquack=everywhere + register: result + +- assert: + that: + result.cmd == 'echo quackquack=here quackquack=everywhere' + +- name: the same is true with quoting + shell: echo "quackquack=here quackquack=everywhere" + register: result + +- assert: + that: + result.cmd == 'echo "quackquack=here quackquack=everywhere"' + +- name: the same is true with quoting (B) + shell: echo "quackquack=here" "quackquack=everywhere" + register: result + +- name: the same is true with quoting (C) + shell: echo "quackquack=here" 'quackquack=everywhere' + register: result + +- name: the same is true with quoting (D) + shell: echo "quackquack=here" 'quackquack=everywhere' + register: result + +- name: the same is true with quoting (E) + shell: echo {{ test_input }} + register: result + +- assert: + that: + result.cmd == "echo a=1 a=2 a=3" + +- name: more shell duplicates + shell: echo foo=bar foo=bar + register: result + +- assert: + that: + result.cmd == "echo foo=bar foo=bar" + +- name: raw duplicates, noop + raw: env true foo=bar foo=bar + +- name: multi-line inline shell commands (should use script module but hey) are a thing + shell: "{{ multi_line }}" + register: result + +- debug: var=result + +- assert: + that: + result.stdout_lines == [ 'old', 'mcdonald', 'had', 'a', 'farm' ] + +- name: passing same arg to shell command is legit + shell: echo foo --arg=a --arg=b + failed_when: False # just catch the exit code, parse error is what I care about, but should register and compare result + register: result + +- assert: + that: + # command shouldn't end in spaces, amend test once fixed + - result.cmd == "echo foo --arg=a --arg=b" + +- name: test includes with params + include: test_include.yml fact_name=include_params param="{{ test_input }}" + +- name: assert the include set the correct fact for the param + assert: + that: + - include_params == test_input + +- name: test includes with quoted params + include: test_include.yml fact_name=double_quoted_param param="this is a param with double quotes" + +- name: assert the include set the correct fact for the double quoted param + assert: + that: + - double_quoted_param == "this is a param with double quotes" + +- name: test includes with single quoted params + include: test_include.yml fact_name=single_quoted_param param='this is a param with single quotes' + +- name: assert the include set the correct fact for the single quoted param + assert: + that: + - single_quoted_param == "this is a param with single quotes" + +- name: test includes with quoted params in complex args + include: test_include.yml + vars: + fact_name: complex_param + param: "this is a param in a complex arg with double quotes" + +- name: assert the include set the correct fact for the params in complex args + assert: + that: + - complex_param == "this is a param in a complex arg with double quotes" + +- name: test variable module name + action: "{{ variable_module_name }} msg='this should be debugged'" + register: result + +- name: assert the task with variable module name ran + assert: + that: + - result.msg == "this should be debugged" + +- name: test conditional includes + include: test_include_conditional.yml + when: false + +- name: assert the nested include from test_include_conditional was not set + assert: + that: + - nested_include_var is undefined + +- name: test omit in complex args + set_fact: + foo: bar + spam: "{{ omit }}" + should_not_omit: "prefix{{ omit }}" + +- assert: + that: + - foo == 'bar' + - spam is undefined + - should_not_omit is defined + +- name: test omit in module args + set_fact: > + yo=whatsup + eggs="{{ omit }}" + default_omitted="{{ not_exists|default(omit) }}" + should_not_omit_1="prefix{{ omit }}" + should_not_omit_2="{{ omit }}suffix" + should_not_omit_3="__omit_place_holder__afb6b9bc3d20bfeaa00a1b23a5930f89" + +- assert: + that: + - yo == 'whatsup' + - eggs is undefined + - default_omitted is undefined + - should_not_omit_1 is defined + - should_not_omit_2 is defined + - should_not_omit_3 == "__omit_place_holder__afb6b9bc3d20bfeaa00a1b23a5930f89" diff --git a/test/integration/targets/parsing/roles/test_good_parsing/tasks/test_include.yml b/test/integration/targets/parsing/roles/test_good_parsing/tasks/test_include.yml new file mode 100644 index 0000000000..4ba5035805 --- /dev/null +++ b/test/integration/targets/parsing/roles/test_good_parsing/tasks/test_include.yml @@ -0,0 +1 @@ +- set_fact: "{{fact_name}}='{{param}}'" diff --git a/test/integration/targets/parsing/roles/test_good_parsing/tasks/test_include_conditional.yml b/test/integration/targets/parsing/roles/test_good_parsing/tasks/test_include_conditional.yml new file mode 100644 index 0000000000..070888dad3 --- /dev/null +++ b/test/integration/targets/parsing/roles/test_good_parsing/tasks/test_include_conditional.yml @@ -0,0 +1 @@ +- include: test_include_nested.yml diff --git a/test/integration/targets/parsing/roles/test_good_parsing/tasks/test_include_nested.yml b/test/integration/targets/parsing/roles/test_good_parsing/tasks/test_include_nested.yml new file mode 100644 index 0000000000..f1f6fcc465 --- /dev/null +++ b/test/integration/targets/parsing/roles/test_good_parsing/tasks/test_include_nested.yml @@ -0,0 +1,2 @@ +- name: set the nested include fact + set_fact: nested_include_var=1 diff --git a/test/integration/targets/parsing/roles/test_good_parsing/vars/main.yml b/test/integration/targets/parsing/roles/test_good_parsing/vars/main.yml new file mode 100644 index 0000000000..ea7a0b846e --- /dev/null +++ b/test/integration/targets/parsing/roles/test_good_parsing/vars/main.yml @@ -0,0 +1,2 @@ +--- +variable_module_name: debug diff --git a/test/integration/targets/parsing/runme.sh b/test/integration/targets/parsing/runme.sh new file mode 100755 index 0000000000..022ce4cf39 --- /dev/null +++ b/test/integration/targets/parsing/runme.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +set -eux + +ansible-playbook bad_parsing.yml -i ../../inventory -vvv "$@" --tags prepare,common,scenario5 +ansible-playbook good_parsing.yml -i ../../inventory -v "$@" diff --git a/test/integration/targets/pull_limit_inventory/runme.sh b/test/integration/targets/pull_limit_inventory/runme.sh new file mode 100755 index 0000000000..74b2fe625f --- /dev/null +++ b/test/integration/targets/pull_limit_inventory/runme.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -eux + +# http://unix.stackexchange.com/questions/30091/fix-or-alternative-for-mktemp-in-os-x +MYTMPDIR=$(shell mktemp -d 2>/dev/null || mktemp -d -t 'ansible-testing-XXXXXXXXXX') +trap 'rm -rf "${MYTMPDIR}"' EXIT + +# test for https://github.com/ansible/ansible/issues/13688 +ansible-pull -d "${MYTMPDIR}" -U https://github.com/ansible-test-robinro/pull-integration-test "$@" diff --git a/test/integration/targets/pull_no_127/runme.sh b/test/integration/targets/pull_no_127/runme.sh new file mode 100755 index 0000000000..cdb8e057a4 --- /dev/null +++ b/test/integration/targets/pull_no_127/runme.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +set -eux + +# http://unix.stackexchange.com/questions/30091/fix-or-alternative-for-mktemp-in-os-x +MYTMPDIR=$(shell mktemp -d 2>/dev/null || mktemp -d -t 'ansible-testing-XXXXXXXXXX') +trap 'rm -rf "${MYTMPDIR}"' EXIT + +# test for https://github.com/ansible/ansible/issues/13681 +ansible-pull -d "${MYTMPDIR}" -U https://github.com/ansible-test-robinro/pull-integration-test "$@" \ + | grep -v '127\.0\.0\.1' diff --git a/test/integration/targets/pull_run/runme.sh b/test/integration/targets/pull_run/runme.sh new file mode 100755 index 0000000000..854698b2fc --- /dev/null +++ b/test/integration/targets/pull_run/runme.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -eux + +# http://unix.stackexchange.com/questions/30091/fix-or-alternative-for-mktemp-in-os-x +MYTMPDIR=$(shell mktemp -d 2>/dev/null || mktemp -d -t 'ansible-testing-XXXXXXXXXX') +trap 'rm -rf "${MYTMPDIR}"' EXIT + +ansible-pull -d "${MYTMPDIR}" -U https://github.com/ansible-test-robinro/pull-integration-test "$@" \ + | grep MAGICKEYWORD diff --git a/test/integration/targets/tags/runme.sh b/test/integration/targets/tags/runme.sh new file mode 100755 index 0000000000..d1f26c41d0 --- /dev/null +++ b/test/integration/targets/tags/runme.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +set -eu + +# Using set -x for this test causes the Shippable console to stop receiving updates and the job to time out for OS X. +# Once that issue is resolved the set -x option can be added above. + +# Run these using en_US.UTF-8 because list-tasks is a user output function and so it tailors its output to the +# user's locale. For unicode tags, this means replacing non-ascii chars with "?" + +COMMAND=(ansible-playbook -i ../../inventory test_tags.yml -v --list-tasks) + +export LC_ALL=en_US.UTF-8 + +# Run everything by default +[ "$("${COMMAND[@]}" | grep -F Task_with | xargs)" = \ +"Task_with_tag TAGS: [tag] Task_with_always_tag TAGS: [always] Task_with_unicode_tag TAGS: [くらとみ] Task_with_list_of_tags TAGS: [café, press] Task_without_tag TAGS: []" ] + +# Run the exact tags, and always +[ "$("${COMMAND[@]}" --tags tag | grep -F Task_with | xargs)" = \ +"Task_with_tag TAGS: [tag] Task_with_always_tag TAGS: [always]" ] + +# Skip one tag +[ "$("${COMMAND[@]}" --skip-tags tag | grep -F Task_with | xargs)" = \ +"Task_with_always_tag TAGS: [always] Task_with_unicode_tag TAGS: [くらとみ] Task_with_list_of_tags TAGS: [café, press] Task_without_tag TAGS: []" ] + +# Skip a unicode tag +[ "$("${COMMAND[@]}" --skip-tags 'くらとみ' | grep -F Task_with | xargs)" = \ +"Task_with_tag TAGS: [tag] Task_with_always_tag TAGS: [always] Task_with_list_of_tags TAGS: [café, press] Task_without_tag TAGS: []" ] + +# Run just a unicode tag and always +[ "$("${COMMAND[@]}" --tags 'くらとみ' | grep -F Task_with | xargs)" = \ +"Task_with_always_tag TAGS: [always] Task_with_unicode_tag TAGS: [くらとみ]" ] + +# Run a tag from a list of tags and always +[ "$("${COMMAND[@]}" --tags café | grep -F Task_with | xargs)" = \ +"Task_with_always_tag TAGS: [always] Task_with_list_of_tags TAGS: [café, press]" ] diff --git a/test/integration/targets/tags/test_tags.yml b/test/integration/targets/tags/test_tags.yml new file mode 100644 index 0000000000..d450de7b39 --- /dev/null +++ b/test/integration/targets/tags/test_tags.yml @@ -0,0 +1,23 @@ +--- +- name: verify tags work as expected + hosts: localhost + gather_facts: False + connection: local + tasks: + - name: Task_with_tag + debug: msg= + tags: tag + - name: Task_with_always_tag + debug: msg= + tags: always + - name: Task_with_unicode_tag + debug: msg= + tags: くらとみ + - name: Task_with_list_of_tags + debug: msg= + tags: + - café + - press + - name: Task_without_tag + debug: msg= + diff --git a/test/integration/targets/templating_settings/runme.sh b/test/integration/targets/templating_settings/runme.sh new file mode 100755 index 0000000000..4af73bfd94 --- /dev/null +++ b/test/integration/targets/templating_settings/runme.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -eux + +ansible-playbook test_templating_settings.yml -i ../../inventory -v "$@" diff --git a/test/integration/targets/templating_settings/test_templating_settings.yml b/test/integration/targets/templating_settings/test_templating_settings.yml new file mode 100644 index 0000000000..524b869e63 --- /dev/null +++ b/test/integration/targets/templating_settings/test_templating_settings.yml @@ -0,0 +1,16 @@ +--- +- name: 'Test templating in name' + hosts: localhost + connection: local + vars: + a_list: + - 'part' + - 'of a' + - 'name' + + tasks: + # Note: this only tests that we do not traceback. It doesn't test that the + # name goes through templating correctly + - name: 'Task: {{ a_list | to_json }}' + debug: msg='{{ a_list | to_json }}' + diff --git a/test/integration/targets/test_infra/inventory.local b/test/integration/targets/test_infra/inventory.local new file mode 100644 index 0000000000..2baa1f88fb --- /dev/null +++ b/test/integration/targets/test_infra/inventory.local @@ -0,0 +1,2 @@ +testhost ansible_connection=local + diff --git a/test/integration/targets/test_infra/runme.sh b/test/integration/targets/test_infra/runme.sh new file mode 100755 index 0000000000..b5932868e2 --- /dev/null +++ b/test/integration/targets/test_infra/runme.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +set -ux + +# ensure fail/assert work locally and can stop execution with non-zero exit code +PB_OUT=$(ansible-playbook -i inventory.local test_test_infra.yml) +APB_RC=$? +echo "$PB_OUT" +echo "rc was $APB_RC (must be non-zero)" +[ $$APB_RC -ne 0 ] +echo "ensure playbook output shows assert/fail works (True)" +echo "$PB_OUT" | grep -F "fail works (True)" || exit 1 +echo "$PB_OUT" | grep -F "assert works (True)" || exit 1 + +# ensure we work using all specified test args, overridden inventory, etc +PB_OUT=$(ansible-playbook -i ../../inventory test_test_infra.yml "$@") +APB_RC=$? +echo "$PB_OUT" +echo "rc was $APB_RC (must be non-zero)" +[ $$APB_RC -ne 0 ] +echo "ensure playbook output shows assert/fail works (True)" +echo "$PB_OUT" | grep -F "fail works (True)" || exit 1 +echo "$PB_OUT" | grep -F "assert works (True)" || exit 1 diff --git a/test/integration/targets/test_infra/test_test_infra.yml b/test/integration/targets/test_infra/test_test_infra.yml new file mode 100644 index 0000000000..13c570530a --- /dev/null +++ b/test/integration/targets/test_infra/test_test_infra.yml @@ -0,0 +1,26 @@ +- hosts: testhost + gather_facts: no + tags: + - always + tasks: + - name: ensure fail action produces a failing result + fail: + ignore_errors: yes + register: fail_out + + - debug: + msg: fail works ({{ fail_out.failed }}) + + - name: ensure assert produces a failing result + assert: + that: false + ignore_errors: yes + register: assert_out + + - debug: + msg: assert works ({{ assert_out.failed }}) + + - name: EXPECTED FAILURE ensure fail action stops execution + fail: + msg: fail actually failed (this is expected) + diff --git a/test/integration/targets/unicode/runme.sh b/test/integration/targets/unicode/runme.sh new file mode 100755 index 0000000000..0182093f41 --- /dev/null +++ b/test/integration/targets/unicode/runme.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +set -eux + +ansible-playbook unicode.yml -i ../../inventory -v -e 'extra_var=café' "$@" +# Test the start-at-task flag #9571 +ansible-playbook unicode.yml -i ../../inventory -v --start-at-task '*¶' -e 'start_at_task=True' "$@" diff --git a/test/integration/targets/unicode/unicode-test-script b/test/integration/targets/unicode/unicode-test-script new file mode 100755 index 0000000000..340f2a9f5b --- /dev/null +++ b/test/integration/targets/unicode/unicode-test-script @@ -0,0 +1,7 @@ +#!/bin/sh + +echo "Non-ascii arguments:" +echo $@ + +echo "Non-ascii Env var:" +echo $option diff --git a/test/integration/targets/unicode/unicode.yml b/test/integration/targets/unicode/unicode.yml new file mode 100644 index 0000000000..b22415a45d --- /dev/null +++ b/test/integration/targets/unicode/unicode.yml @@ -0,0 +1,149 @@ +--- +- name: 'A play with unicode: ¢ £ ¤ ¥' + hosts: localhost + connection: local + vars: + test_var: 'Ī ī Ĭ ĭ Į į İ ı IJ ij Ĵ ĵ Ķ ķ ĸ Ĺ ĺ Ļ ļ Ľ ľ Ŀ ŀ Ł ł Ń ń Ņ ņ Ň ň ʼn Ŋ ŋ Ō ō Ŏ ŏ Ő ő Œ' + hostnames: + - 'host-ϬϭϮϯϰ' + - 'host-fóöbär' + - 'host-ΙΚΛΜΝΞ' + - 'host-στυφχψ' + - 'host-ϬϭϮϯϰϱ' + + tasks: + - name: 'A task name with unicode: è é ê ë' + debug: msg='hi there' + + - name: 'A task with unicode parameters' + debug: var=test_var + + # € ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ Ž ‘ ’ “ ” • – — ˜ ™ š › œ ž Ÿ ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ®' + + - name: 'A task using with_items containing unicode' + debug: msg='{{item}}' + with_items: + - '¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö ×' + - 'Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ Ā' + - 'ā Ă ă Ą ą Ć ć Ĉ ĉ Ċ ċ Č č Ď ď Đ đ Ē ē Ĕ ĕ Ė ė Ę ę Ě ě Ĝ ĝ Ğ ğ Ġ ġ Ģ ģ Ĥ ĥ Ħ ħ Ĩ ĩ' + + - add_host: + name: '{{item}}' + groups: 'ĪīĬĭ' + ansible_ssh_host: 127.0.0.1 + ansible_connection: local + with_items: "{{ hostnames }}" + + - name: 'A task with unicode extra vars' + debug: var=extra_var + + - name: 'A task with unicode host vars' + debug: var=unicode_host_var + + - name: 'A task with unicode shell parameters' + shell: echo '¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö ×' + register: output + + - name: 'Assert that the unicode was echoed' + assert: + that: + - "'¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö ×' in output.stdout_lines" + + - name: Run raw with non-ascii options + raw: "/bin/echo Zażółć gęślą jaźń" + register: results + + - name: Check that raw output the right thing + assert: + that: + - "'Zażółć gęślą jaźń' in results.stdout_lines" + + - name: Run a script with non-ascii options and environment + script: unicode-test-script --option "Zażółć gęślą jaźń" + environment: + option: Zażółć + register: results + + - name: Check that script output includes the nonascii arguments and environment values + assert: + that: + - "'--option Zażółć gęślą jaźń' in results.stdout_lines" + - "'Zażółć' in results.stdout_lines" + + - name: Ping with non-ascii environment variable and option + ping: + data: "Zażółć gęślą jaźń" + environment: + option: Zażółć + register: results + + - name: Check that ping with non-ascii data was correct + assert: + that: + - "'Zażółć gęślą jaźń' == results.ping" + + - name: Command that echos a non-ascii env var + command: "echo $option" + environment: + option: Zażółć + register: results + + - name: Check that a non-ascii env var was passed to the command module + assert: + that: + - "'Zażółć' in results.stdout_lines" + + - name: Clean a temp directory + file: + path: /var/tmp/ansible_test_unicode_get_put + state: absent + + - name: Create a temp directory + file: + path: /var/tmp/ansible_test_unicode_get_put + state: directory + + - name: Create a file with a non-ascii filename + file: + path: /var/tmp/ansible_test_unicode_get_put/Zażółć + state: touch + delegate_to: localhost + + - name: Put with unicode filename + copy: + src: /var/tmp/ansible_test_unicode_get_put/Zażółć + dest: /var/tmp/ansible_test_unicode_get_put/Zażółć2 + + - name: Fetch with unicode filename + fetch: + src: /var/tmp/ansible_test_unicode_get_put/Zażółć2 + dest: /var/tmp/ansible_test_unicode_get_put/ + + - name: Clean a temp directory + file: + path: /var/tmp/ansible_test_unicode_get_put + state: absent + +- name: 'A play for hosts in group: ĪīĬĭ' + hosts: 'ĪīĬĭ' + gather_facts: true + tasks: + - debug: msg='Unicode is a good thing ™' + - debug: msg=АБВГД + +# Run this test by adding to the CLI: -e start_at_task=True --start-at-task '*¶' +- name: 'Show that we can skip to unicode named tasks' + hosts: localhost + gather_facts: false + vars: + flag: 'original' + start_at_task: False + tasks: + - name: 'Override flag var' + set_fact: flag='new' + + - name: 'A unicode task at the end of the playbook: ¶' + assert: + that: + - 'flag == "original"' + when: start_at_task|bool diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence/meta/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence/meta/main.yml new file mode 100644 index 0000000000..423b94e31c --- /dev/null +++ b/test/integration/targets/var_precedence/roles/test_var_precedence/meta/main.yml @@ -0,0 +1,4 @@ +dependencies: + - { role: test_var_precedence_role1, param_var: "param_var_role1" } + - { role: test_var_precedence_role2, param_var: "param_var_role2" } + - { role: test_var_precedence_role3, param_var: "param_var_role3" } diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence/tasks/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence/tasks/main.yml new file mode 100644 index 0000000000..7850e6b646 --- /dev/null +++ b/test/integration/targets/var_precedence/roles/test_var_precedence/tasks/main.yml @@ -0,0 +1,10 @@ +- debug: var=extra_var +- debug: var=vars_var +- debug: var=vars_files_var +- debug: var=vars_files_var_role +- assert: + that: + - 'extra_var == "extra_var"' + - 'vars_var == "vars_var"' + - 'vars_files_var == "vars_files_var"' + - 'vars_files_var_role == "vars_files_var_role3"' diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_dep/defaults/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_dep/defaults/main.yml new file mode 100644 index 0000000000..dda4224c35 --- /dev/null +++ b/test/integration/targets/var_precedence/roles/test_var_precedence_dep/defaults/main.yml @@ -0,0 +1,5 @@ +--- +# should be overridden by vars_files in the main play +vars_files_var: "BAD!" +# should be seen in role1 (no override) +defaults_file_var_role1: "defaults_file_var_role1" diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_dep/tasks/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_dep/tasks/main.yml new file mode 100644 index 0000000000..2f8e17096b --- /dev/null +++ b/test/integration/targets/var_precedence/roles/test_var_precedence_dep/tasks/main.yml @@ -0,0 +1,14 @@ +- debug: var=extra_var +- debug: var=param_var +- debug: var=vars_var +- debug: var=vars_files_var +- debug: var=vars_files_var_role +- debug: var=defaults_file_var_role1 +- assert: + that: + - 'extra_var == "extra_var"' + - 'param_var == "param_var_role1"' + - 'vars_var == "vars_var"' + - 'vars_files_var == "vars_files_var"' + - 'vars_files_var_role == "vars_files_var_dep"' + - 'defaults_file_var_role1 == "defaults_file_var_role1"' diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_dep/vars/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_dep/vars/main.yml new file mode 100644 index 0000000000..a69efad537 --- /dev/null +++ b/test/integration/targets/var_precedence/roles/test_var_precedence_dep/vars/main.yml @@ -0,0 +1,4 @@ +--- +# should override the global vars_files_var since it's local to the role +# but will be set to the value in the last role included which defines it +vars_files_var_role: "vars_files_var_dep" diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_inven_override/tasks/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_inven_override/tasks/main.yml new file mode 100644 index 0000000000..942ae4ec05 --- /dev/null +++ b/test/integration/targets/var_precedence/roles/test_var_precedence_inven_override/tasks/main.yml @@ -0,0 +1,5 @@ +--- +- debug: var=foo +- assert: + that: + - 'foo == "bar"' diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_role1/defaults/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_role1/defaults/main.yml new file mode 100644 index 0000000000..dda4224c35 --- /dev/null +++ b/test/integration/targets/var_precedence/roles/test_var_precedence_role1/defaults/main.yml @@ -0,0 +1,5 @@ +--- +# should be overridden by vars_files in the main play +vars_files_var: "BAD!" +# should be seen in role1 (no override) +defaults_file_var_role1: "defaults_file_var_role1" diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_role1/meta/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_role1/meta/main.yml new file mode 100644 index 0000000000..c8b410b59c --- /dev/null +++ b/test/integration/targets/var_precedence/roles/test_var_precedence_role1/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: + - test_var_precedence_dep diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_role1/tasks/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_role1/tasks/main.yml new file mode 100644 index 0000000000..95b2a0bb5a --- /dev/null +++ b/test/integration/targets/var_precedence/roles/test_var_precedence_role1/tasks/main.yml @@ -0,0 +1,14 @@ +- debug: var=extra_var +- debug: var=param_var +- debug: var=vars_var +- debug: var=vars_files_var +- debug: var=vars_files_var_role +- debug: var=defaults_file_var_role1 +- assert: + that: + - 'extra_var == "extra_var"' + - 'param_var == "param_var_role1"' + - 'vars_var == "vars_var"' + - 'vars_files_var == "vars_files_var"' + - 'vars_files_var_role == "vars_files_var_role1"' + - 'defaults_file_var_role1 == "defaults_file_var_role1"' diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_role1/vars/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_role1/vars/main.yml new file mode 100644 index 0000000000..2f7613d30a --- /dev/null +++ b/test/integration/targets/var_precedence/roles/test_var_precedence_role1/vars/main.yml @@ -0,0 +1,4 @@ +--- +# should override the global vars_files_var since it's local to the role +# but will be set to the value in the last role included which defines it +vars_files_var_role: "vars_files_var_role1" diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_role2/defaults/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_role2/defaults/main.yml new file mode 100644 index 0000000000..8ed63ced96 --- /dev/null +++ b/test/integration/targets/var_precedence/roles/test_var_precedence_role2/defaults/main.yml @@ -0,0 +1,5 @@ +--- +# should be overridden by vars_files in the main play +vars_files_var: "BAD!" +# should be overridden by the vars file in role2 +defaults_file_var_role2: "BAD!" diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_role2/tasks/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_role2/tasks/main.yml new file mode 100644 index 0000000000..a862389cd3 --- /dev/null +++ b/test/integration/targets/var_precedence/roles/test_var_precedence_role2/tasks/main.yml @@ -0,0 +1,14 @@ +- debug: var=extra_var +- debug: var=param_var +- debug: var=vars_var +- debug: var=vars_files_var +- debug: var=vars_files_var_role +- debug: var=defaults_file_var_role1 +- assert: + that: + - 'extra_var == "extra_var"' + - 'param_var == "param_var_role2"' + - 'vars_var == "vars_var"' + - 'vars_files_var == "vars_files_var"' + - 'vars_files_var_role == "vars_files_var_role2"' + - 'defaults_file_var_role2 == "overridden by role vars"' diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_role2/vars/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_role2/vars/main.yml new file mode 100644 index 0000000000..483c5ea245 --- /dev/null +++ b/test/integration/targets/var_precedence/roles/test_var_precedence_role2/vars/main.yml @@ -0,0 +1,5 @@ +--- +# should override the global vars_files_var since it's local to the role +vars_files_var_role: "vars_files_var_role2" +# should override the value in defaults/main.yml for role 2 +defaults_file_var_role2: "overridden by role vars" diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_role3/defaults/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_role3/defaults/main.yml new file mode 100644 index 0000000000..763b0d508e --- /dev/null +++ b/test/integration/targets/var_precedence/roles/test_var_precedence_role3/defaults/main.yml @@ -0,0 +1,7 @@ +--- +# should be overridden by vars_files in the main play +vars_files_var: "BAD!" +# should override the defaults var for role 1 and 2 +defaults_file_var: "last one wins" +# should be overridden from the inventory value +defaults_file_var_role3: "BAD!" diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_role3/tasks/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_role3/tasks/main.yml new file mode 100644 index 0000000000..12346ecdc8 --- /dev/null +++ b/test/integration/targets/var_precedence/roles/test_var_precedence_role3/tasks/main.yml @@ -0,0 +1,14 @@ +- debug: var=extra_var +- debug: var=param_var +- debug: var=vars_var +- debug: var=vars_files_var +- debug: var=vars_files_var_role +- debug: var=defaults_file_var_role1 +- assert: + that: + - 'extra_var == "extra_var"' + - 'param_var == "param_var_role3"' + - 'vars_var == "vars_var"' + - 'vars_files_var == "vars_files_var"' + - 'vars_files_var_role == "vars_files_var_role3"' + - 'defaults_file_var_role3 == "overridden from inventory"' diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_role3/vars/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_role3/vars/main.yml new file mode 100644 index 0000000000..3cfb1b1c68 --- /dev/null +++ b/test/integration/targets/var_precedence/roles/test_var_precedence_role3/vars/main.yml @@ -0,0 +1,3 @@ +--- +# should override the global vars_files_var since it's local to the role +vars_files_var_role: "vars_files_var_role3" diff --git a/test/integration/targets/var_precedence/runme.sh b/test/integration/targets/var_precedence/runme.sh new file mode 100755 index 0000000000..454c35333e --- /dev/null +++ b/test/integration/targets/var_precedence/runme.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +set -eux + +ansible-playbook test_var_precedence.yml -i ../../inventory -v "$@" \ + -e 'extra_var=extra_var' \ + -e 'extra_var_override=extra_var_override' diff --git a/test/integration/targets/var_precedence/test_var_precedence.yml b/test/integration/targets/var_precedence/test_var_precedence.yml new file mode 100644 index 0000000000..df09914158 --- /dev/null +++ b/test/integration/targets/var_precedence/test_var_precedence.yml @@ -0,0 +1,45 @@ +--- +- hosts: testhost + vars: + - ansible_hostname: "BAD!" + - vars_var: "vars_var" + - param_var: "BAD!" + - vars_files_var: "BAD!" + - extra_var_override_once_removed: "{{ extra_var_override }}" + - from_inventory_once_removed: "{{ inven_var | default('BAD!') }}" + vars_files: + - vars/test_var_precedence.yml + roles: + - { role: test_var_precedence, param_var: "param_var" } + tasks: + - name: register a result + command: echo 'BAD!' + register: registered_var + - name: use set_fact to override the registered_var + set_fact: registered_var="this is from set_fact" + - debug: var=extra_var + - debug: var=extra_var_override_once_removed + - debug: var=vars_var + - debug: var=vars_files_var + - debug: var=vars_files_var_role + - debug: var=registered_var + - debug: var=from_inventory_once_removed + - assert: + that: item + with_items: + - 'extra_var == "extra_var"' + - 'extra_var_override == "extra_var_override"' + - 'extra_var_override_once_removed == "extra_var_override"' + - 'vars_var == "vars_var"' + - 'vars_files_var == "vars_files_var"' + - 'vars_files_var_role == "vars_files_var_role3"' + - 'registered_var == "this is from set_fact"' + - 'from_inventory_once_removed == "inventory_var"' + +- hosts: inven_overridehosts + vars_files: + - "test_var_precedence.yml" + roles: + - role: test_var_precedence_inven_override + foo: bar + diff --git a/test/integration/targets/var_precedence/vars/test_var_precedence.yml b/test/integration/targets/var_precedence/vars/test_var_precedence.yml new file mode 100644 index 0000000000..19d65cba3e --- /dev/null +++ b/test/integration/targets/var_precedence/vars/test_var_precedence.yml @@ -0,0 +1,5 @@ +--- +extra_var: "BAD!" +role_var: "BAD!" +vars_files_var: "vars_files_var" +vars_files_var_role: "should be overridden by roles" diff --git a/test/integration/targets/vault/roles/test_vault/tasks/main.yml b/test/integration/targets/vault/roles/test_vault/tasks/main.yml new file mode 100644 index 0000000000..2c18e41815 --- /dev/null +++ b/test/integration/targets/vault/roles/test_vault/tasks/main.yml @@ -0,0 +1,10 @@ + +- assert: + that: + - 'secret_var == "secret"' + + +- copy: src=vault-secret.txt dest={{output_dir}}/secret.txt + +- name: cleanup decrypted file + file: path={{ output_dir }}/secret.txt state=absent diff --git a/test/integration/targets/vault/roles/test_vault/vars/main.yml b/test/integration/targets/vault/roles/test_vault/vars/main.yml new file mode 100644 index 0000000000..cfac107aed --- /dev/null +++ b/test/integration/targets/vault/roles/test_vault/vars/main.yml @@ -0,0 +1,9 @@ +$ANSIBLE_VAULT;1.1;AES256 +31626536666232643662346539623662393436386162643439643434656231343435653936343235 +6139346364396166336636383734333430373763336434310a303137623539653939336132626234 +64613232396532313731313935333433353330666466646663303233323331636234326464643166 +6538653264636166370a613161313064653566323037393962643032353230396536313865326362 +34396262303130326632623162623230346238633932393938393766313036643835613936356233 +33323730373331386337353339613165373064323134343930333031623036326164353534646631 +31313963666234623731316238656233396638643331306231373539643039383434373035306233 +30386230363730643561 diff --git a/test/integration/targets/vault/roles/test_vault_embedded/tasks/main.yml b/test/integration/targets/vault/roles/test_vault_embedded/tasks/main.yml new file mode 100644 index 0000000000..4dda2acbcd --- /dev/null +++ b/test/integration/targets/vault/roles/test_vault_embedded/tasks/main.yml @@ -0,0 +1,14 @@ +--- +- name: Assert that a embedded vault of a string with no newline works + assert: + that: + - '"{{ vault_encrypted_one_line_var }}" == "Setec Astronomy"' + +- name: Assert that a multi line embedded vault works, including new line + assert: + that: + - vault_encrypted_var == "Setec Astronomy\n" + +# TODO: add a expected fail here +# - debug: var=vault_encrypted_one_line_var_with_embedded_template + diff --git a/test/integration/targets/vault/roles/test_vault_embedded/vars/main.yml b/test/integration/targets/vault/roles/test_vault_embedded/vars/main.yml new file mode 100644 index 0000000000..e9c568eac1 --- /dev/null +++ b/test/integration/targets/vault/roles/test_vault_embedded/vars/main.yml @@ -0,0 +1,17 @@ +# If you use normal 'ansible-vault create' or edit, files always have at least one new line +# so c&p from a vault encrypted that wasn't specifically created sans new line ends up with one. +# (specifically created, as in 'echo -n "just one line" > my_secret.yml' +vault_encrypted_var: !vault-encrypted | + $ANSIBLE_VAULT;1.1;AES256 + 66386439653236336462626566653063336164663966303231363934653561363964363833313662 + 6431626536303530376336343832656537303632313433360a626438346336353331386135323734 + 62656361653630373231613662633962316233633936396165386439616533353965373339616234 + 3430613539666330390a313736323265656432366236633330313963326365653937323833366536 + 34623731376664623134383463316265643436343438623266623965636363326136 +vault_encrypted_one_line_var: !vault-encrypted | + $ANSIBLE_VAULT;1.1;AES256 + 33363965326261303234626463623963633531343539616138316433353830356566396130353436 + 3562643163366231316662386565383735653432386435610a306664636137376132643732393835 + 63383038383730306639353234326630666539346233376330303938323639306661313032396437 + 6233623062366136310a633866373936313238333730653739323461656662303864663666653563 + 3138 diff --git a/test/integration/targets/vault/runme.sh b/test/integration/targets/vault/runme.sh new file mode 100755 index 0000000000..a78ee4d4b2 --- /dev/null +++ b/test/integration/targets/vault/runme.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -eux + +ansible-playbook test_vault.yml -i ../../inventory -v "$@" --vault-password-file vault-password --list-tasks +ansible-playbook test_vault.yml -i ../../inventory -v "$@" --vault-password-file vault-password --list-hosts +ansible-playbook test_vault.yml -i ../../inventory -v "$@" --vault-password-file vault-password --syntax-check +ansible-playbook test_vault.yml -i ../../inventory -v "$@" --vault-password-file vault-password +ansible-playbook test_vault_embedded.yml -i ../../inventory -v "$@" --vault-password-file vault-password --syntax-check +ansible-playbook test_vault_embedded.yml -i ../../inventory -v "$@" --vault-password-file vault-password diff --git a/test/integration/targets/vault/test_vault.yml b/test/integration/targets/vault/test_vault.yml new file mode 100644 index 0000000000..7f8ed11570 --- /dev/null +++ b/test/integration/targets/vault/test_vault.yml @@ -0,0 +1,6 @@ +- hosts: testhost + gather_facts: False + vars: + - output_dir: . + roles: + - { role: test_vault, tags: test_vault} diff --git a/test/integration/targets/vault/test_vault_embedded.yml b/test/integration/targets/vault/test_vault_embedded.yml new file mode 100644 index 0000000000..ee9739f8bb --- /dev/null +++ b/test/integration/targets/vault/test_vault_embedded.yml @@ -0,0 +1,4 @@ +- hosts: testhost + gather_facts: False + roles: + - { role: test_vault_embedded, tags: test_vault_embedded} diff --git a/test/integration/targets/vault/vault-password b/test/integration/targets/vault/vault-password new file mode 100644 index 0000000000..969739294d --- /dev/null +++ b/test/integration/targets/vault/vault-password @@ -0,0 +1 @@ +test-vault-password diff --git a/test/integration/targets/vault/vault-secret.txt b/test/integration/targets/vault/vault-secret.txt new file mode 100644 index 0000000000..b6bc9bfb17 --- /dev/null +++ b/test/integration/targets/vault/vault-secret.txt @@ -0,0 +1,6 @@ +$ANSIBLE_VAULT;1.1;AES256 +39303432393062643236616234306333383838333662386165616633303735336537613337396337 +6662666233356462326631653161663663363166323338320a653131656636666339633863346530 +32326238646631653133643936306666643065393038386234343736663239363665613963343661 +3230353633643361650a363034323631613864326438396665343237383566336339323837326464 +3930 |