Migrate Linux CI roles to test targets. (#17997)

This commit is contained in:
Matt Clay 2016-10-13 09:09:25 -07:00 committed by GitHub
commit 75e4645ee7
263 changed files with 53 additions and 53 deletions

View file

@ -0,0 +1,39 @@
# test code for the add_host action
# (c) 2015, Matt Davis <mdavis@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: add a host to the runtime inventory
add_host:
name: newdynamichost
groups: newdynamicgroup
a_var: from add_host
- debug: msg={{hostvars['newdynamichost'].group_names}}
- name: ensure that dynamically-added host is visible via hostvars, groups, etc (there are several caches that could break this)
assert:
that:
- hostvars['bogushost'] is not defined # there was a bug where an undefined host was a "type" instead of an instance- ensure this works before we rely on it
- hostvars['newdynamichost'] is defined
- hostvars['newdynamichost'].group_names is defined
- "'newdynamicgroup' in hostvars['newdynamichost'].group_names"
- hostvars['newdynamichost']['bogusvar'] is not defined
- hostvars['newdynamichost']['a_var'] is defined
- hostvars['newdynamichost']['a_var'] == 'from add_host'
- groups['bogusgroup'] is not defined # same check as above to ensure that bogus groups are undefined...
- groups['newdynamicgroup'] is defined
- "'newdynamichost' in groups['newdynamicgroup']"

View file

@ -0,0 +1,3 @@
dependencies:
- prepare_tests

View file

@ -0,0 +1,61 @@
# 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: install apache via apt
apt: name=apache2 state=present
when: "ansible_os_family == 'Debian'"
- name: install apache via zypper
zypper: name=apache2 state=present
when: "ansible_os_family == 'Suse'"
- name: disable userdir module
apache2_module: name=userdir state=absent
- name: disable userdir module, second run
apache2_module: name=userdir state=absent
register: disable
- name: ensure apache2_module is idempotent
assert:
that:
- 'not disable.changed'
- name: enable userdir module
apache2_module: name=userdir state=present
register: enable
- name: ensure changed on successful enable
assert:
that:
- 'enable.changed'
- name: enable userdir module, second run
apache2_module: name=userdir state=present
register: enabletwo
- name: ensure apache2_module is idempotent
assert:
that:
- 'not enabletwo.changed'
- name: disable userdir module, final run
apache2_module: name=userdir state=absent
register: disablefinal
- name: ensure changed on successful disable
assert:
that:
- 'disablefinal.changed'

View file

@ -0,0 +1,6 @@
---
- name: include only on supported systems
include: actualtest.yml
when: ansible_os_family in ['Debian', 'Suse']
# centos/RHEL does not have a2enmod/a2dismod

View file

@ -0,0 +1,2 @@
dependencies:
- prepare_tests

View file

@ -0,0 +1,55 @@
# test installing build-deps using netcat and quilt as test victims.
#
# Deps can be discovered like so (taken from ubuntu 12.04)
# ====
# root@localhost:~ # apt-rdepends --build-depends --follow=DEPENDS netcat
# Reading package lists... Done
# Building dependency tree
# Reading state information... Done
# netcat
# Build-Depends: debhelper (>= 8.0.0)
# Build-Depends: quilt
# root@localhost:~ #
# ====
# Since many things depend on debhelper, let's just uninstall quilt, then
# install build-dep for netcat to get it back. build-dep doesn't have an
# uninstall, so we don't need to test for reverse actions (eg, uninstall
# build-dep and ensure things are clean)
# uninstall quilt
- name: check quilt with dpkg
shell: dpkg -s quilt
register: dpkg_result
ignore_errors: true
tags: ['test_apt_builddep']
- name: uninstall quilt with apt
apt: pkg=quilt state=absent purge=yes
register: apt_result
when: dpkg_result|success
tags: ['test_apt_builddep']
# install build-dep for netcat
- name: install netcat build-dep with apt
apt: pkg=netcat state=build-dep
register: apt_result
tags: ['test_apt_builddep']
- name: verify build_dep of netcat
assert:
that:
- "'changed' in apt_result"
tags: ['test_apt_builddep']
# ensure debhelper and qilt are installed
- name: check build_deps with dpkg
shell: dpkg --get-selections | egrep '(debhelper|quilt)'
failed_when: False
register: dpkg_result
tags: ['test_apt_builddep']
- name: verify build_deps are really there
assert:
that:
- "dpkg_result.rc == 0"
tags: ['test_apt_builddep']

View file

@ -0,0 +1,150 @@
- name: show python version
debug: var=ansible_python_version
- name: use python-apt
set_fact:
python_apt: python-apt
when: ansible_python_version | version_compare('3', '<')
- name: use python3-apt
set_fact:
python_apt: python3-apt
when: ansible_python_version | version_compare('3', '>=')
# UNINSTALL 'python-apt'
# The `apt` module has the smarts to auto-install `python-apt`. To test, we
# will first uninstall `python-apt`.
- name: check {{ python_apt }} with dpkg
shell: dpkg -s {{ python_apt }}
register: dpkg_result
ignore_errors: true
- name: uninstall {{ python_apt }} with apt
apt: pkg={{ python_apt }} state=absent purge=yes
register: apt_result
when: dpkg_result|success
# UNINSTALL 'hello'
# With 'python-apt' uninstalled, the first call to 'apt' should install
# python-apt.
- name: uninstall hello with apt
apt: pkg=hello state=absent purge=yes
register: apt_result
- name: check hello with dpkg
shell: dpkg-query -l hello
failed_when: False
register: dpkg_result
- name: verify uninstallation of hello
assert:
that:
- "'changed' in apt_result"
- "dpkg_result.rc == 1"
# UNINSTALL AGAIN
- name: uninstall hello with apt
apt: pkg=hello state=absent purge=yes
register: apt_result
- name: verify no change on re-uninstall
assert:
that:
- "not apt_result.changed"
# INSTALL
- name: install hello with apt
apt: name=hello state=present
register: apt_result
- name: check hello with dpkg
shell: dpkg-query -l hello
failed_when: False
register: dpkg_result
- debug: var=apt_result
- debug: var=dpkg_result
- name: verify installation of hello
assert:
that:
- "apt_result.changed"
- "dpkg_result.rc == 0"
- name: verify apt module outputs
assert:
that:
- "'changed' in apt_result"
- "'stderr' in apt_result"
- "'stdout' in apt_result"
- "'stdout_lines' in apt_result"
# INSTALL AGAIN
- name: install hello with apt
apt: name=hello state=present
register: apt_result
- name: verify no change on re-install
assert:
that:
- "not apt_result.changed"
# UNINSTALL AGAIN
- name: uninstall hello with apt
apt: pkg=hello state=absent purge=yes
register: apt_result
# INSTALL WITH VERSION WILDCARD
- name: install hello with apt
apt: name=hello=2.* state=present
register: apt_result
- name: check hello with wildcard with dpkg
shell: dpkg-query -l hello
failed_when: False
register: dpkg_result
- debug: var=apt_result
- debug: var=dpkg_result
- name: verify installation of hello
assert:
that:
- "apt_result.changed"
- "dpkg_result.rc == 0"
- name: check hello version
shell: dpkg -s hello | grep Version | awk '{print $2}'
register: hello_version
- name: check hello architecture
shell: dpkg -s hello | grep Architecture | awk '{print $2}'
register: hello_architecture
- name: uninstall hello with apt
apt: pkg=hello state=absent purge=yes
- name: install deb file
apt: deb="/var/cache/apt/archives/hello_{{ hello_version.stdout }}_{{ hello_architecture.stdout }}.deb"
register: apt_initial
- name: install deb file again
apt: deb="/var/cache/apt/archives/hello_{{ hello_version.stdout }}_{{ hello_architecture.stdout }}.deb"
register: apt_secondary
- name: verify installation of hello
assert:
that:
- "apt_initial.changed"
- "not apt_secondary.changed"
- name: uninstall hello with apt
apt: pkg=hello state=absent purge=yes
- name: force install of deb
apt: deb="/var/cache/apt/archives/hello_{{ hello_version.stdout }}_{{ hello_architecture.stdout }}.deb" force=true
register: dpkg_force
- name: verify installation of hello
assert:
that:
- "dpkg_force.changed"

View file

@ -0,0 +1,22 @@
# (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/>.
- include: 'apt.yml'
when: ansible_distribution in ('Ubuntu', 'Debian')
- include: 'apt-builddep.yml'
when: ansible_distribution in ('Ubuntu', 'Debian')

View file

@ -0,0 +1,2 @@
dependencies:
- prepare_tests

View file

@ -0,0 +1,205 @@
---
- set_fact:
test_ppa_name: 'ppa:git-core/ppa'
test_ppa_filename: 'git-core'
test_ppa_spec: 'deb http://ppa.launchpad.net/git-core/ppa/ubuntu {{ansible_distribution_release}} main'
test_ppa_key: 'E1DF1F24' # http://keyserver.ubuntu.com:11371/pks/lookup?search=0xD06AAF4C11DAB86DF421421EFE6B20ECA7AD98A1&op=index
- name: show python version
debug: var=ansible_python_version
- name: use python-apt
set_fact:
python_apt: python-apt
when: ansible_python_version | version_compare('3', '<')
- name: use python3-apt
set_fact:
python_apt: python3-apt
when: ansible_python_version | version_compare('3', '>=')
# UNINSTALL 'python-apt'
# The `apt_repository` module has the smarts to auto-install `python-apt`. To
# test, we will first uninstall `python-apt`.
- name: check {{ python_apt }} with dpkg
shell: dpkg -s {{ python_apt }}
register: dpkg_result
ignore_errors: true
- name: uninstall {{ python_apt }} with apt
apt: pkg={{ python_apt }} state=absent purge=yes
register: apt_result
when: dpkg_result|success
#
# TEST: apt_repository: repo=<name>
#
- include: 'cleanup.yml'
- name: 'record apt cache mtime'
stat: path='/var/cache/apt/pkgcache.bin'
register: cache_before
- name: 'name=<name> (expect: pass)'
apt_repository: repo='{{test_ppa_name}}' state=present
register: result
- name: 'assert the apt cache did *NOT* change'
assert:
that:
- 'result.changed'
- 'result.state == "present"'
- 'result.repo == "{{test_ppa_name}}"'
- name: 'examine apt cache mtime'
stat: path='/var/cache/apt/pkgcache.bin'
register: cache_after
- name: 'assert the apt cache did change'
assert:
that:
- 'cache_before.stat.mtime != cache_after.stat.mtime'
- name: 'ensure ppa key is installed (expect: pass)'
apt_key: id='{{test_ppa_key}}' state=present
#
# TEST: apt_repository: repo=<name> update_cache=no
#
- include: 'cleanup.yml'
- name: 'record apt cache mtime'
stat: path='/var/cache/apt/pkgcache.bin'
register: cache_before
- name: 'name=<name> update_cache=no (expect: pass)'
apt_repository: repo='{{test_ppa_name}}' state=present update_cache=no
register: result
- assert:
that:
- 'result.changed'
- 'result.state == "present"'
- 'result.repo == "{{test_ppa_name}}"'
- name: 'examine apt cache mtime'
stat: path='/var/cache/apt/pkgcache.bin'
register: cache_after
- name: 'assert the apt cache did *NOT* change'
assert:
that:
- 'cache_before.stat.mtime == cache_after.stat.mtime'
- name: 'ensure ppa key is installed (expect: pass)'
apt_key: id='{{test_ppa_key}}' state=present
#
# TEST: apt_repository: repo=<name> update_cache=yes
#
- include: 'cleanup.yml'
- name: 'record apt cache mtime'
stat: path='/var/cache/apt/pkgcache.bin'
register: cache_before
- name: 'name=<name> update_cache=yes (expect: pass)'
apt_repository: repo='{{test_ppa_name}}' state=present update_cache=yes
register: result
- assert:
that:
- 'result.changed'
- 'result.state == "present"'
- 'result.repo == "{{test_ppa_name}}"'
- name: 'examine apt cache mtime'
stat: path='/var/cache/apt/pkgcache.bin'
register: cache_after
- name: 'assert the apt cache did change'
assert:
that:
- 'cache_before.stat.mtime != cache_after.stat.mtime'
- name: 'ensure ppa key is installed (expect: pass)'
apt_key: id='{{test_ppa_key}}' state=present
#
# TEST: apt_repository: repo=<spec>
#
- include: 'cleanup.yml'
- name: 'record apt cache mtime'
stat: path='/var/cache/apt/pkgcache.bin'
register: cache_before
- name: 'name=<spec> (expect: pass)'
apt_repository: repo='{{test_ppa_spec}}' state=present
register: result
- assert:
that:
- 'result.changed'
- 'result.state == "present"'
- 'result.repo == "{{test_ppa_spec}}"'
- name: 'examine apt cache mtime'
stat: path='/var/cache/apt/pkgcache.bin'
register: cache_after
- name: 'assert the apt cache did change'
assert:
that:
- 'cache_before.stat.mtime != cache_after.stat.mtime'
# When installing a repo with the spec, the key is *NOT* added
- name: 'ensure ppa key is absent (expect: pass)'
apt_key: id='{{test_ppa_key}}' state=absent
#
# TEST: apt_repository: repo=<spec> filename=<filename>
#
- include: 'cleanup.yml'
- name: 'record apt cache mtime'
stat: path='/var/cache/apt/pkgcache.bin'
register: cache_before
- name: 'name=<spec> filename=<filename> (expect: pass)'
apt_repository: repo='{{test_ppa_spec}}' filename='{{test_ppa_filename}}' state=present
register: result
- assert:
that:
- 'result.changed'
- 'result.state == "present"'
- 'result.repo == "{{test_ppa_spec}}"'
- name: 'examine source file'
stat: path='/etc/apt/sources.list.d/{{test_ppa_filename}}.list'
register: source_file
- name: 'assert source file exists'
assert:
that:
- 'source_file.stat.exists == True'
- name: 'examine apt cache mtime'
stat: path='/var/cache/apt/pkgcache.bin'
register: cache_after
- name: 'assert the apt cache did change'
assert:
that:
- 'cache_before.stat.mtime != cache_after.stat.mtime'
# When installing a repo with the spec, the key is *NOT* added
- name: 'ensure ppa key is absent (expect: pass)'
apt_key: id='{{test_ppa_key}}' state=absent
#
# TEARDOWN
#
- include: 'cleanup.yml'

View file

@ -0,0 +1,18 @@
---
# tasks to cleanup a repo and assert it is gone
- name: remove existing ppa
apt_repository: repo={{test_ppa_name}} state=absent
ignore_errors: true
- name: test that ppa does not exist (expect pass)
shell: cat /etc/apt/sources.list /etc/apt/sources.list.d/* | grep "{{test_ppa_spec}}"
register: command
failed_when: command.rc == 0
changed_when: false
# Should this use apt-key, maybe?
- name: remove ppa key
apt_key: id={{test_ppa_key}} state=absent
ignore_errors: true

View file

@ -0,0 +1,21 @@
# test code for the apt_repository module
# (c) 2014, James Laska <jlaska@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: 'apt.yml'
when: ansible_distribution in ('Ubuntu')

View file

@ -0,0 +1 @@
this is fragment 1

View file

@ -0,0 +1 @@
this is fragment 2

View file

@ -0,0 +1 @@
this is fragment 3

View file

@ -0,0 +1 @@
this is fragment 4

View file

@ -0,0 +1 @@
this is fragment 5

View file

@ -0,0 +1,20 @@
# test code for the assemble 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/>.
dependencies:
- prepare_tests

View file

@ -0,0 +1,93 @@
# test code for the assemble 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/>.
- name: create a new directory for file source
file: dest="{{output_dir}}/src" state=directory
register: result
- name: assert the directory was created
assert:
that:
- "result.state == 'directory'"
- name: copy the files to a new directory
copy: src="./" dest="{{output_dir}}/src"
register: result
- name: test assemble with all fragments
assemble: src="{{output_dir}}/src" dest="{{output_dir}}/assembled1"
register: result
- name: assert the fragments were assembled
assert:
that:
- "result.state == 'file'"
- "result.changed == True"
- "result.checksum == '048a1bd1951aa5ccc427eeb4ca19aee45e9c68b3'"
- name: test assemble with all fragments
assemble: src="{{output_dir}}/src" dest="{{output_dir}}/assembled1"
register: result
- name: assert that the same assemble made no changes
assert:
that:
- "result.state == 'file'"
- "result.changed == False"
- "result.checksum == '048a1bd1951aa5ccc427eeb4ca19aee45e9c68b3'"
- name: test assemble with fragments matching a regex
assemble: src="{{output_dir}}/src" dest="{{output_dir}}/assembled2" regexp="^fragment[1-3]$"
register: result
- name: assert the fragments were assembled with a regex
assert:
that:
- "result.state == 'file'"
- "result.checksum == 'edfe2d7487ef8f5ebc0f1c4dc57ba7b70a7b8e2b'"
- name: test assemble with a delimiter
assemble: src="{{output_dir}}/src" dest="{{output_dir}}/assembled3" delimiter="#--- delimiter ---#"
register: result
- name: assert the fragments were assembled with a delimiter
assert:
that:
- "result.state == 'file'"
- "result.checksum == '505359f48c65b3904127cf62b912991d4da7ed6d'"
- name: test assemble with remote_src=False
assemble: src="./" dest="{{output_dir}}/assembled4" remote_src=no
register: result
- name: assert the fragments were assembled without remote
assert:
that:
- "result.state == 'file'"
- "result.checksum == '048a1bd1951aa5ccc427eeb4ca19aee45e9c68b3'"
- name: test assemble with remote_src=False and a delimiter
assemble: src="./" dest="{{output_dir}}/assembled5" remote_src=no delimiter="#--- delimiter ---#"
register: result
- name: assert the fragments were assembled without remote
assert:
that:
- "result.state == 'file'"
- "result.checksum == '505359f48c65b3904127cf62b912991d4da7ed6d'"

View file

@ -0,0 +1,39 @@
import sys
import json
from ansible.module_utils.basic import AnsibleModule
def main():
if "--interactive" in sys.argv:
import ansible.module_utils.basic
ansible.module_utils.basic._ANSIBLE_ARGS = json.dumps(dict(
ANSIBLE_MODULE_ARGS=dict(
fail_mode="graceful"
)
))
module = AnsibleModule(argument_spec = dict(
fail_mode = dict(type='list', default=['success'])
)
)
result = dict(changed=True)
fail_mode = module.params['fail_mode']
try:
if 'leading_junk' in fail_mode:
print("leading junk before module output")
if 'graceful' in fail_mode:
module.fail_json(msg="failed gracefully")
if 'exception' in fail_mode:
raise Exception('failing via exception')
module.exit_json(**result)
finally:
if 'trailing_junk' in fail_mode:
print("trailing junk after module output")
main()

View file

@ -0,0 +1,3 @@
dependencies:
- prepare_tests

View file

@ -0,0 +1,154 @@
# 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: run a 2 second loop
shell: for i in $(seq 1 2); do echo $i ; sleep 1; done;
async: 10
poll: 1
register: async_result
- debug: var=async_result
- name: validate async returns
assert:
that:
- "'ansible_job_id' in async_result"
- "'changed' in async_result"
- "'cmd' in async_result"
- "'delta' in async_result"
- "'end' in async_result"
- "'finished' in async_result or async_result.finished == 1"
- "'rc' in async_result"
- "'start' in async_result"
- "'stderr' in async_result"
- "'stdout' in async_result"
- "'stdout_lines' in async_result"
- "async_result.rc == 0"
- name: test async without polling
command: sleep 5
async: 30
poll: 0
register: async_result
- debug: var=async_result
- name: validate async without polling returns
assert:
that:
- "'ansible_job_id' in async_result"
- "'started' in async_result"
- "'finished' not in async_result or async_result.finished == 0"
- name: test skipped task handling
command: /bin/true
async: 15
poll: 0
when: False
# test async "fire and forget, but check later"
- name: 'start a task with "fire-and-forget"'
command: sleep 3
async: 30
poll: 0
register: fnf_task
- name: assert task was successfully started
assert:
that:
- fnf_task.started
- "'ansible_job_id' in fnf_task"
- name: 'check on task started as a "fire-and-forget"'
async_status: jid={{ fnf_task.ansible_job_id }}
register: fnf_result
until: fnf_result.finished
retries: 10
delay: 1
- name: assert task was successfully checked
assert:
that:
- fnf_result.finished
- name: test graceful module failure
async_test:
fail_mode: graceful
async: 30
poll: 1
register: async_result
ignore_errors: true
- name: assert task failed correctly
assert:
that:
- async_result.ansible_job_id is match('\d+\.\d+')
- async_result.finished == 1
- async_result | changed == false
- async_result | failed
- async_result.msg == 'failed gracefully'
- name: test exception module failure
async_test:
fail_mode: exception
async: 5
poll: 1
register: async_result
ignore_errors: true
- name: validate response
assert:
that:
- async_result.ansible_job_id is match('\d+\.\d+')
- async_result.finished == 1
- async_result.changed == false
- async_result | failed == true
- async_result.stderr is search('failing via exception', multiline=True)
- name: test leading junk before JSON
async_test:
fail_mode: leading_junk
async: 5
poll: 1
register: async_result
- name: validate response
assert:
that:
- async_result.ansible_job_id is match('\d+\.\d+')
- async_result.finished == 1
- async_result.changed == true
- async_result | success
- name: test trailing junk after JSON
async_test:
fail_mode: trailing_junk
async: 5
poll: 1
register: async_result
- name: validate response
assert:
that:
- async_result.ansible_job_id is match('\d+\.\d+')
- async_result.finished == 1
- async_result.changed == true
- async_result | success
- async_result.warnings[0] is search('trailing junk after module output')

View file

@ -0,0 +1,15 @@
---
dss_key_basic: >
ssh-dss DATA_BASIC root@testing
dss_key_unquoted_option: >
idle-timeout=5m ssh-dss DATA_UNQUOTED_OPTION root@testing
dss_key_command: >
command="/bin/true" ssh-dss DATA_COMMAND root@testing
dss_key_complex_command: >
command="echo foo 'bar baz'" ssh-dss DATA_COMPLEX_COMMAND root@testing
dss_key_command_single_option: >
no-port-forwarding,command="/bin/true" ssh-dss DATA_COMMAND_SINGLE_OPTIONS root@testing
dss_key_command_multiple_options: >
no-port-forwarding,idle-timeout=5m,command="/bin/true" ssh-dss DATA_COMMAND_MULTIPLE_OPTIONS root@testing
dss_key_trailing: >
ssh-dss DATA_TRAILING root@testing foo bar baz

View file

@ -0,0 +1,2 @@
dependencies:
- prepare_tests

View file

@ -0,0 +1,272 @@
# test code for the authorized_key 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/>.
# -------------------------------------------------------------
# Setup steps
- name: touch the authorized_keys file
file: dest="{{output_dir}}/authorized_keys" state=touch
register: result
- name: assert that the authorized_keys file was created
assert:
that:
- 'result.changed == True'
- 'result.state == "file"'
# -------------------------------------------------------------
# basic ssh-dss key
- name: add basic ssh-dss key
authorized_key: user=root key="{{ dss_key_basic }}" state=present path="{{output_dir|expanduser}}/authorized_keys"
register: result
- name: assert that the key was added
assert:
that:
- 'result.changed == True'
- 'result.key == dss_key_basic'
- 'result.key_options == None'
- name: re-add basic ssh-dss key
authorized_key: user=root key="{{ dss_key_basic }}" state=present path="{{output_dir|expanduser}}/authorized_keys"
register: result
- name: assert that nothing changed
assert:
that:
- 'result.changed == False'
# -------------------------------------------------------------
# ssh-dss key with an unquoted option
- name: add ssh-dss key with an unquoted option
authorized_key:
user: root
key: "{{ dss_key_unquoted_option }}"
state: present
path: "{{output_dir|expanduser}}/authorized_keys"
register: result
- name: assert that the key was added
assert:
that:
- 'result.changed == True'
- 'result.key == dss_key_unquoted_option'
- 'result.key_options == None'
- name: re-add ssh-dss key with an unquoted option
authorized_key:
user: root
key: "{{ dss_key_unquoted_option }}"
state: present
path: "{{output_dir|expanduser}}/authorized_keys"
register: result
- name: assert that nothing changed
assert:
that:
- 'result.changed == False'
# -------------------------------------------------------------
# ssh-dss key with a leading command="/bin/foo"
- name: add ssh-dss key with a leading command
authorized_key:
user: root
key: "{{ dss_key_command }}"
state: present
path: "{{output_dir|expanduser}}/authorized_keys"
register: result
- name: assert that the key was added
assert:
that:
- 'result.changed == True'
- 'result.key == dss_key_command'
- 'result.key_options == None'
- name: re-add ssh-dss key with a leading command
authorized_key:
user: root
key: "{{ dss_key_command }}"
state: present
path: "{{output_dir|expanduser}}/authorized_keys"
register: result
- name: assert that nothing changed
assert:
that:
- 'result.changed == False'
# -------------------------------------------------------------
# ssh-dss key with a complex quoted leading command
# ie. command="/bin/echo foo 'bar baz'"
- name: add ssh-dss key with a complex quoted leading command
authorized_key:
user: root
key: "{{ dss_key_complex_command }}"
state: present
path: "{{output_dir|expanduser}}/authorized_keys"
register: result
- name: assert that the key was added
assert:
that:
- 'result.changed == True'
- 'result.key == dss_key_complex_command'
- 'result.key_options == None'
- name: re-add ssh-dss key with a complex quoted leading command
authorized_key:
user: root
key: "{{ dss_key_complex_command }}"
state: present
path: "{{output_dir|expanduser}}/authorized_keys"
register: result
- name: assert that nothing changed
assert:
that:
- 'result.changed == False'
# -------------------------------------------------------------
# ssh-dss key with a command and a single option, which are
# in a comma-separated list
- name: add ssh-dss key with a command and a single option
authorized_key:
user: root
key: "{{ dss_key_command_single_option }}"
state: present
path: "{{output_dir|expanduser}}/authorized_keys"
register: result
- name: assert that the key was added
assert:
that:
- 'result.changed == True'
- 'result.key == dss_key_command_single_option'
- 'result.key_options == None'
- name: re-add ssh-dss key with a command and a single option
authorized_key:
user: root
key: "{{ dss_key_command_single_option }}"
state: present
path: "{{output_dir|expanduser}}/authorized_keys"
register: result
- name: assert that nothing changed
assert:
that:
- 'result.changed == False'
# -------------------------------------------------------------
# ssh-dss key with a command and multiple other options
- name: add ssh-dss key with a command and multiple options
authorized_key:
user: root
key: "{{ dss_key_command_multiple_options }}"
state: present
path: "{{output_dir|expanduser}}/authorized_keys"
register: result
- name: assert that the key was added
assert:
that:
- 'result.changed == True'
- 'result.key == dss_key_command_multiple_options'
- 'result.key_options == None'
- name: re-add ssh-dss key with a command and multiple options
authorized_key:
user: root
key: "{{ dss_key_command_multiple_options }}"
state: present
path: "{{output_dir|expanduser}}/authorized_keys"
register: result
- name: assert that nothing changed
assert:
that:
- 'result.changed == False'
# -------------------------------------------------------------
# ssh-dss key with multiple trailing parts, which are space-
# separated and not quoted in any way
- name: add ssh-dss key with trailing parts
authorized_key:
user: root
key: "{{ dss_key_trailing }}"
state: present
path: "{{output_dir|expanduser}}/authorized_keys"
register: result
- name: assert that the key was added
assert:
that:
- 'result.changed == True'
- 'result.key == dss_key_trailing'
- 'result.key_options == None'
- name: re-add ssh-dss key with trailing parts
authorized_key:
user: root
key: "{{ dss_key_trailing }}"
state: present
path: "{{output_dir|expanduser}}/authorized_keys"
register: result
- name: assert that nothing changed
assert:
that:
- 'result.changed == False'
# -------------------------------------------------------------
# basic ssh-dss key with mutliple permit-open options
# https://github.com/ansible/ansible-modules-core/issues/1715
- name: add basic ssh-dss key with multi-opts
authorized_key:
user: root
key: "{{ dss_key_basic }}"
key_options: 'no-agent-forwarding,no-X11-forwarding,permitopen="10.9.8.1:8080",permitopen="10.9.8.1:9001"'
state: present
path: "{{output_dir|expanduser}}/authorized_keys"
register: result
- name: assert that the key with multi-opts was added
assert:
that:
- 'result.changed == True'
- 'result.key == dss_key_basic'
- 'result.key_options == "no-agent-forwarding,no-X11-forwarding,permitopen=\"10.9.8.1:8080\",permitopen=\"10.9.8.1:9001\""'
- name: get the file content
shell: cat "{{output_dir|expanduser}}/authorized_keys" | fgrep DATA_BASIC
register: content
- name: validate content
assert:
that:
- 'content.stdout == "no-agent-forwarding,no-X11-forwarding,permitopen=\"10.9.8.1:8080\",permitopen=\"10.9.8.1:9001\" ssh-dss DATA_BASIC root@testing"'

View file

@ -0,0 +1 @@
testing tilde expansion with become

View file

@ -0,0 +1,83 @@
- include_vars: default.yml
- name: Create test user
become: True
become_user: root
user:
name: "{{ become_test_user }}"
- name: test becoming user
shell: whoami
become: True
become_user: "{{ become_test_user }}"
register: results
- assert:
that:
- "results.stdout == '{{ become_test_user }}'"
- name: tilde expansion honors become in file
become: True
become_user: "{{ become_test_user }}"
file:
path: "~/foo.txt"
state: touch
- name: check that the path in the user's home dir was created
become: True
become_user: "{{ become_test_user }}"
stat:
path: "~{{ become_test_user }}/foo.txt"
register: results
- assert:
that:
- "results.stat.exists == True"
- "results.stat.path|dirname|basename == '{{ become_test_user }}'"
- name: tilde expansion honors become in template
become: True
become_user: "{{ become_test_user }}"
template:
src: "bar.j2"
dest: "~/bar.txt"
- name: check that the path in the user's home dir was created
become: True
become_user: "{{ become_test_user }}"
stat:
path: "~{{ become_test_user }}/bar.txt"
register: results
- assert:
that:
- "results.stat.exists == True"
- "results.stat.path|dirname|basename == '{{ become_test_user }}'"
- name: tilde expansion honors become in copy
become: True
become_user: "{{ become_test_user }}"
copy:
src: baz.txt
dest: "~/baz.txt"
- name: check that the path in the user's home dir was created
become: True
become_user: "{{ become_test_user }}"
stat:
path: "~{{ become_test_user }}/baz.txt"
register: results
- assert:
that:
- "results.stat.exists == True"
- "results.stat.path|dirname|basename == '{{ become_test_user }}'"
- name: Remove test user and their home dir
become: True
become_user: root
user:
name: "{{ become_test_user }}"
state: "absent"
remove: "yes"

View file

@ -0,0 +1 @@
{{ become_test_user }}

View file

@ -0,0 +1 @@
become_test_user: ansibletest1

View file

@ -0,0 +1 @@
Café Eñe

View file

@ -0,0 +1 @@
Café Eñe

View file

@ -0,0 +1 @@
Café Eñe

View file

@ -0,0 +1,3 @@
dependencies:
- prepare_tests

View file

@ -0,0 +1,131 @@
---
# Various ways users want to use binary data
# Could integrate into individual modules but currently these don't all work.
# Probably easier to see them all in a single block to know what we're testing.
# When we can start testing v2 we should test that all of these work.
# In v1: The following line will traceback if it's the first task in the role.
# Does not traceback if it's the second or third etc task.
- debug: msg="{{ utf8_simple_accents|b64decode}}"
# Expected values of the written files
- name: get checksums that we expect later files to have
copy:
src: from_playbook
dest: "{{ output_dir }}"
- copy:
src: b64_utf8
dest: "{{ output_dir }}"
- copy:
src: b64_latin1
dest: "{{ output_dir }}"
- stat:
path: "{{ output_dir }}/from_playbook"
register: from_playbook
- stat:
path: "{{ output_dir }}/b64_utf8"
register: b64_utf8
- stat:
path: "{{ output_dir }}/b64_latin1"
register: b64_latin1
# Tests themselves
- name: copy with utf-8 content in a playbook
copy:
content: "{{ simple_accents }}\n"
dest: "{{ output_dir }}/from_playbook.txt"
- name: Check that copying utf-8 content matches
stat:
path: "{{ output_dir }}/from_playbook.txt"
register: results
- assert:
that:
- 'results.stat.checksum == from_playbook.stat.checksum'
- name: copy with utf8 in a base64 encoded string
copy:
content: "{{ utf8_simple_accents|b64decode }}\n"
dest: "{{ output_dir }}/b64_utf8.txt"
- name: Check that utf8 in a base64 string matches
stat:
path: "{{ output_dir }}/b64_utf8.txt"
register: results
- assert:
that:
- 'results.stat.checksum == b64_utf8.stat.checksum'
- name: copy with latin1 in a base64 encoded string
copy:
content: "{{ latin1_simple_accents|b64decode }}\n"
dest: "{{ output_dir }}/b64_latin1.txt"
- name: Check that latin1 in a base64 string matches
stat:
path: "{{ output_dir }}/b64_latin1.txt"
register: results
- assert:
that:
- 'results.stat.checksum == b64_latin1.stat.checksum'
# This one depends on being able to pass binary data through
# Might be a while before we find a solution for this
ignore_errors: True
- name: Template with a unicode string from the playbook
template:
src: "from_playbook_template.j2"
dest: "{{ output_dir }}/from_playbook_template.txt"
- name: Check that writing a template from a playbook var matches
stat:
path: "{{ output_dir }}/from_playbook_template.txt"
register: results
- assert:
that:
- 'results.stat.checksum == from_playbook.stat.checksum'
- name: Template with utf8 in a base64 encoded string
template:
src: "b64_utf8_template.j2"
dest: "{{ output_dir }}/b64_utf8_template.txt"
- name: Check that writing a template from a base64 encoded utf8 string matches
stat:
path: "{{ output_dir }}/b64_utf8_template.txt"
register: results
- assert:
that:
- 'results.stat.checksum == b64_utf8.stat.checksum'
- name: Template with latin1 in a base64 encoded string
template:
src: "b64_latin1_template.j2"
dest: "{{ output_dir }}/b64_latin1_template.txt"
- name: Check that writing a template from a base64 encoded latin1 string matches
stat:
path: "{{ output_dir }}/b64_latin1_template.txt"
register: results
- assert:
that:
- 'results.stat.checksum == b64_latin1.stat.checksum'
# This one depends on being able to pass binary data through
# Might be a while before we find a solution for this
ignore_errors: True
# These might give garbled output but none of them should traceback
- debug: var=simple_accents
- debug: msg="{{ utf8_simple_accents|b64decode}}"
- debug: msg="{{ latin1_simple_accents|b64decode}}"

View file

@ -0,0 +1 @@
{{ latin1_simple_accents|b64decode }}

View file

@ -0,0 +1 @@
{{ utf8_simple_accents|b64decode }}

View file

@ -0,0 +1 @@
{{ simple_accents }}

View file

@ -0,0 +1,3 @@
simple_accents: 'Café Eñe'
utf8_simple_accents: 'Q2Fmw6kgRcOxZQ=='
latin1_simple_accents: 'Q2Fm6SBF8WU='

View file

@ -0,0 +1,3 @@
dependencies:
- prepare_tests

View file

@ -0,0 +1,42 @@
# test code for the changed_when parameter
# (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: ensure shell is always changed
shell: ls -al /tmp
register: shell_result
- debug: var=shell_result
- name: changed should always be true for shell
assert:
that:
- "shell_result.changed"
- name: test changed_when override for shell
shell: ls -al /tmp
changed_when: False
register: shell_result
- debug: var=shell_result
- name: changed should be false
assert:
that:
- "not shell_result.changed"

View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
echo "win" > "$1"

View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
rm "$1"

View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
echo -n "win"

View file

@ -0,0 +1,3 @@
dependencies:
- prepare_tests

View file

@ -0,0 +1,219 @@
# Test code for the command and shell modules.
# (c) 2014, Richard Isaacson <richard.c.isaacson@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/>.
- set_fact: output_dir_test={{output_dir}}/test_command_shell
- name: make sure our testing sub-directory does not exist
file: path="{{ output_dir_test }}" state=absent
- name: create our testing sub-directory
file: path="{{ output_dir_test }}" state=directory
- name: prep our test script
copy: src=test.sh dest="{{ output_dir_test }}" mode=0755
- name: prep our test script
copy: src=create_afile.sh dest="{{ output_dir_test }}" mode=0755
- name: prep our test script
copy: src=remove_afile.sh dest="{{ output_dir_test }}" mode=0755
- name: locate bash
shell: which bash
register: bash
- name: locate sha1sum/shasum
shell: which sha1sum || which shasum
register: sha1sum
##
## command
##
- name: execute the test.sh script via command
command: "{{output_dir_test | expanduser}}/test.sh"
register: command_result0
- name: assert that the script executed correctly
assert:
that:
- "command_result0.rc == 0"
- "command_result0.stderr == ''"
- "command_result0.stdout == 'win'"
# executable
# FIXME doesn't have the expected stdout.
#- name: execute the test.sh script with executable via command
# command: "{{output_dir_test | expanduser}}/test.sh executable={{ bash.stdout }}"
# register: command_result1
#
#- name: assert that the script executed correctly with command
# assert:
# that:
# - "command_result1.rc == 0"
# - "command_result1.stderr == ''"
# - "command_result1.stdout == 'win'"
# chdir
- name: execute the test.sh script with chdir via command
command: ./test.sh chdir="{{output_dir_test | expanduser}}"
register: command_result2
- name: assert that the script executed correctly with chdir
assert:
that:
- "command_result2.rc == 0"
- "command_result2.stderr == ''"
- "command_result2.stdout == 'win'"
# creates
- name: verify that afile.txt is absent
file: path={{output_dir_test}}/afile.txt state=absent
- name: create afile.txt with create_afile.sh via command
command: "{{output_dir_test | expanduser}}/create_afile.sh {{output_dir_test | expanduser}}/afile.txt creates={{output_dir_test | expanduser}}/afile.txt"
- name: verify that afile.txt is present
file: path={{output_dir_test}}/afile.txt state=file
- name: re-run previous command using creates with globbing
command: "{{output_dir_test | expanduser}}/create_afile.sh {{output_dir_test | expanduser}}/afile.txt creates={{output_dir_test | expanduser}}/afile.*"
register: command_result3
- name: assert that creates with globbing is working
assert:
that:
- "command_result3.changed != True"
# removes
- name: remove afile.txt with remote_afile.sh via command
command: "{{output_dir_test | expanduser}}/remove_afile.sh {{output_dir_test | expanduser}}/afile.txt removes={{output_dir_test | expanduser}}/afile.txt"
- name: verify that afile.txt is absent
file: path={{output_dir_test}}/afile.txt state=absent
- name: re-run previous command using removes with globbing
command: "{{output_dir_test | expanduser}}/remove_afile.sh {{output_dir_test | expanduser}}/afile.txt removes={{output_dir_test | expanduser}}/afile.*"
register: command_result4
- name: assert that removes with globbing is working
assert:
that:
- "command_result4.changed != True"
##
## shell
##
- name: execute the test.sh script
shell: "{{output_dir_test | expanduser}}/test.sh"
register: shell_result0
- name: assert that the script executed correctly
assert:
that:
- "shell_result0.rc == 0"
- "shell_result0.stderr == ''"
- "shell_result0.stdout == 'win'"
# executable
# FIXME doesn't pass the expected stdout
#- name: execute the test.sh script
# shell: "{{output_dir_test | expanduser}}/test.sh executable={{ bash.stdout }}"
# register: shell_result1
#
#- name: assert that the shell executed correctly
# assert:
# that:
# - "shell_result1.rc == 0"
# - "shell_result1.stderr == ''"
# - "shell_result1.stdout == 'win'"
# chdir
- name: execute the test.sh script with chdir
shell: ./test.sh chdir="{{output_dir_test | expanduser}}"
register: shell_result2
- name: assert that the shell executed correctly with chdir
assert:
that:
- "shell_result2.rc == 0"
- "shell_result2.stderr == ''"
- "shell_result2.stdout == 'win'"
# creates
- name: verify that afile.txt is absent
file: path={{output_dir_test}}/afile.txt state=absent
- name: execute the test.sh script with chdir
shell: "{{output_dir_test | expanduser}}/test.sh > {{output_dir_test | expanduser}}/afile.txt creates={{output_dir_test | expanduser}}/afile.txt"
- name: verify that afile.txt is present
file: path={{output_dir_test}}/afile.txt state=file
# multiline
- name: remove test file previously created
file: path={{output_dir_test | expanduser}}/afile.txt state=absent
- name: execute a shell command using a literal multiline block
args:
executable: "{{ bash.stdout }}"
shell: |
echo this is a \
"multiline echo" \
"with a new line
in quotes" \
| {{ sha1sum.stdout }} \
| tr -s ' ' \
| cut -f1 -d ' '
echo "this is a second line"
register: shell_result5
- debug: var=shell_result5
- name: assert the multiline shell command ran as expected
assert:
that:
- "shell_result5.changed"
- "shell_result5.stdout == '5575bb6b71c9558db0b6fbbf2f19909eeb4e3b98\nthis is a second line'"
- name: execute a shell command using a literal multiline block with arguments in it
shell: |
executable="{{ bash.stdout }}"
creates={{output_dir_test | expanduser}}/afile.txt
echo "test"
register: shell_result6
- name: assert the multiline shell command with arguments in it run as expected
assert:
that:
- "shell_result6.changed"
- "shell_result6.stdout == 'test'"
- name: remove the previously created file
file: path={{output_dir_test}}/afile.txt state=absent

View file

@ -0,0 +1,309 @@
# test code for conditional statements
# (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: test conditional '=='
shell: echo 'testing'
when: 1 == 1
register: result
- name: assert conditional '==' ran
assert:
that:
- "result.changed == true"
- "result.stdout == 'testing'"
- "result.rc == 0"
- name: test bad conditional '=='
shell: echo 'testing'
when: 0 == 1
register: result
- name: assert bad conditional '==' did NOT run
assert:
that:
- "result.skipped == true"
- name: test conditional '!='
shell: echo 'testing'
when: 0 != 1
register: result
- name: assert conditional '!=' ran
assert:
that:
- "result.changed == true"
- "result.stdout == 'testing'"
- "result.rc == 0"
- name: test bad conditional '!='
shell: echo 'testing'
when: 1 != 1
register: result
- name: assert bad conditional '!=' did NOT run
assert:
that:
- "result.skipped == true"
- name: test conditional 'in'
shell: echo 'testing'
when: 1 in [1,2,3]
register: result
- name: assert conditional 'in' ran
assert:
that:
- "result.changed == true"
- "result.stdout == 'testing'"
- "result.rc == 0"
- name: test bad conditional 'in'
shell: echo 'testing'
when: 1 in [7,8,9]
register: result
- name: assert bad conditional 'in' did NOT run
assert:
that:
- "result.skipped == true"
- name: test conditional 'not in'
shell: echo 'testing'
when: 0 not in [1,2,3]
register: result
- name: assert conditional 'not in' ran
assert:
that:
- "result.changed == true"
- "result.stdout == 'testing'"
- "result.rc == 0"
- name: test bad conditional 'not in'
shell: echo 'testing'
when: 1 not in [1,2,3]
register: result
- name: assert bad conditional 'not in' did NOT run
assert:
that:
- "result.skipped == true"
- name: test conditional 'is defined'
shell: echo 'testing'
when: test_bare is defined
register: result
- name: assert conditional 'is defined' ran
assert:
that:
- "result.changed == true"
- "result.stdout == 'testing'"
- "result.rc == 0"
- name: test bad conditional 'is defined'
shell: echo 'testing'
when: foo_asdf_xyz is defined
register: result
- name: assert bad conditional 'is defined' did NOT run
assert:
that:
- "result.skipped == true"
- name: test conditional 'is not defined'
shell: echo 'testing'
when: foo_asdf_xyz is not defined
register: result
- name: assert conditional 'is not defined' ran
assert:
that:
- "result.changed == true"
- "result.stdout == 'testing'"
- "result.rc == 0"
- name: test bad conditional 'is not defined'
shell: echo 'testing'
when: test_bare is not defined
register: result
- name: assert bad conditional 'is not defined' did NOT run
assert:
that:
- "result.skipped == true"
- name: test bad conditional 'is undefined'
shell: echo 'testing'
when: test_bare is undefined
register: result
- name: assert bad conditional 'is undefined' did NOT run
assert:
that:
- "result.skipped == true"
- name: test bare conditional
shell: echo 'testing'
when: test_bare
register: result
- name: assert bare conditional ran
assert:
that:
- "result.changed == true"
- "result.stdout == 'testing'"
- "result.rc == 0"
- name: test conditional using a variable
shell: echo 'testing'
when: test_bare_var == 123
register: result
- name: assert conditional using a variable ran
assert:
that:
- "result.changed == true"
- "result.stdout == 'testing'"
- "result.rc == 0"
- name: test good conditional based on nested variables
shell: echo 'testing'
when: test_bare_nested_good
register: result
- name: assert good conditional based on nested var ran
assert:
that:
- "result.changed == true"
- "result.stdout == 'testing'"
- "result.rc == 0"
- name: test bad conditional based on nested variables
shell: echo 'testing'
when: test_bare_nested_bad
register: result
- name: assert that the bad nested conditional did NOT run
assert:
that:
- "result.skipped == true"
#-----------------------------------------------------------------------
# proper booleanification tests (issue #8629)
- name: set fact to string 'false'
set_fact: bool_test1=false
- name: set fact to string 'False'
set_fact: bool_test2=False
- name: set fact to a proper boolean using complex args
set_fact:
bool_test3: false
- name: "test boolean value 'false' string using 'when: var'"
command: echo 'hi'
when: bool_test1
register: result
- name: assert that the task did not run for 'false'
assert:
that:
- "result.skipped == true"
- name: "test boolean value 'false' string using 'when: not var'"
command: echo 'hi'
when: not bool_test1
register: result
- name: assert that the task DID run for not 'false'
assert:
that:
- "result.changed"
- name: "test boolean value of 'False' string using 'when: var'"
command: echo 'hi'
when: bool_test2
register: result
- name: assert that the task did not run for 'False'
assert:
that:
- "result.skipped == true"
- name: "test boolean value 'False' string using 'when: not var'"
command: echo 'hi'
when: not bool_test2
register: result
- name: assert that the task DID run for not 'False'
assert:
that:
- "result.changed"
- name: "test proper boolean value of complex arg using 'when: var'"
command: echo 'hi'
when: bool_test3
register: result
- name: assert that the task did not run for proper boolean false
assert:
that:
- "result.skipped == true"
- name: "test proper boolean value of complex arg using 'when: not var'"
command: echo 'hi'
when: not bool_test3
register: result
- name: assert that the task DID run for not false
assert:
that:
- "result.changed"
- set_fact: skipped_bad_attribute=True
- block:
- name: test a with_items loop using a variable with a missing attribute
debug: var=item
with_items: "{{cond_bad_attribute.results | default('')}}"
register: result
- set_fact: skipped_bad_attribute=False
- name: assert the task was skipped
assert:
that:
- skipped_bad_attribute
when: cond_bad_attribute is defined and 'results' in cond_bad_attribute
- name: test a with_items loop skipping a single item
debug: var=item
with_items: "{{cond_list_of_items.results}}"
when: item != 'b'
register: result
- debug: var=result
- name: assert only a single item was skipped
assert:
that:
- result.results|length == 3
- result.results[1].skipped
- name: test complex templated condition
debug: msg="it works"
when: vars_file_var in things1|union([vars_file_var])

View file

@ -0,0 +1,17 @@
---
# foo is a dictionary that will be used to check that
# a conditional passes a with_items loop on a variable
# with a missing attribute (ie. foo.results)
cond_bad_attribute:
bar: a
cond_list_of_items:
results:
- a
- b
- c
things1:
- 1
- 2
vars_file_var: 321

View file

@ -0,0 +1 @@
foo.txt

View file

@ -0,0 +1 @@
baz

View file

@ -0,0 +1 @@
baz

View file

@ -0,0 +1,3 @@
dependencies:
- prepare_tests

View file

@ -0,0 +1,260 @@
# test code for the copy module and action plugin
# (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: record the output directory
set_fact: output_file={{output_dir}}/foo.txt
- name: locate sha1sum/shasum
shell: which sha1sum || which shasum
register: sha1sum
- name: initiate a basic copy, and also test the mode
copy: src=foo.txt dest={{output_file}} mode=0444
register: copy_result
- name: check the mode of the output file
file: name={{output_file}} state=file
register: file_result_check
- name: assert the mode is correct
assert:
that:
- "file_result_check.mode == '0444'"
- name: assert basic copy worked
assert:
that:
- "'changed' in copy_result"
- "'dest' in copy_result"
- "'group' in copy_result"
- "'gid' in copy_result"
- "'md5sum' in copy_result"
- "'checksum' in copy_result"
- "'owner' in copy_result"
- "'size' in copy_result"
- "'src' in copy_result"
- "'state' in copy_result"
- "'uid' in copy_result"
- name: verify that the file was marked as changed
assert:
that:
- "copy_result.changed == true"
- name: verify that the file checksums are correct
assert:
that:
- "copy_result.checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6'"
- name: verify that the legacy md5sum is correct
assert:
that:
- "copy_result.md5sum == 'c47397529fe81ab62ba3f85e9f4c71f2'"
when: ansible_fips|bool != True
- name: check the stat results of the file
stat: path={{output_file}}
register: stat_results
- debug: var=stat_results
- name: assert the stat results are correct
assert:
that:
- "stat_results.stat.exists == true"
- "stat_results.stat.isblk == false"
- "stat_results.stat.isfifo == false"
- "stat_results.stat.isreg == true"
- "stat_results.stat.issock == false"
- "stat_results.stat.checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6'"
- name: verify that the legacy md5sum is correct
assert:
that:
- "stat_results.stat.md5 == 'c47397529fe81ab62ba3f85e9f4c71f2'"
when: ansible_fips|bool != True
- name: overwrite the file via same means
copy: src=foo.txt dest={{output_file}}
register: copy_result2
- name: assert that the file was not changed
assert:
that:
- "not copy_result2|changed"
- name: overwrite the file using the content system
copy: content="modified" dest={{output_file}}
register: copy_result3
- name: assert that the file has changed
assert:
that:
- "copy_result3|changed"
- "'content' not in copy_result3"
# test recursive copy
- name: set the output subdirectory
set_fact: output_subdir={{output_dir}}/sub
- name: make an output subdirectory
file: name={{output_subdir}} state=directory
- name: test recursive copy to directory
copy: src=subdir dest={{output_subdir}} directory_mode=0700
register: recursive_copy_result
- debug: var=recursive_copy_result
- name: assert that the recursive copy did something
assert:
that:
- "recursive_copy_result|changed"
- name: check that a file in a directory was transferred
stat: path={{output_dir}}/sub/subdir/bar.txt
register: stat_bar
- name: check that a file in a deeper directory was transferred
stat: path={{output_dir}}/sub/subdir/subdir2/baz.txt
register: stat_bar2
- name: check that a file in a directory whose parent contains a directory alone was transferred
stat: path={{output_dir}}/sub/subdir/subdir2/subdir3/subdir4/qux.txt
register: stat_bar3
- name: assert recursive copy things
assert:
that:
- "stat_bar.stat.exists"
- "stat_bar2.stat.exists"
- "stat_bar3.stat.exists"
- name: stat the recursively copied directories
stat: path={{output_dir}}/sub/{{item}}
register: dir_stats
with_items:
- "subdir"
- "subdir/subdir2"
- "subdir/subdir2/subdir3"
- "subdir/subdir2/subdir3/subdir4"
- name: assert recursive copied directories mode
assert:
that:
- "{{item.stat.mode}} == 0700"
with_items: "{{dir_stats.results}}"
# errors on this aren't presently ignored so this test is commented out. But it would be nice to fix.
#
- name: overwrite the file again using the content system, also passing along file params
copy: content="modified" dest={{output_file}}
register: copy_result4
#- name: assert invalid copy input location fails
# copy: src=invalid_file_location_does_not_exist dest={{output_dir}}/file.txt
# ignore_errors: True
# register: failed_copy
- name: copy already copied directory again
copy: src=subdir dest={{output_subdir | expanduser}} owner={{ansible_ssh_user|default(omit)}}
register: copy_result5
- name: assert that the directory was not changed
assert:
that:
- "not copy_result5|changed"
# issue 8394
- name: create a file with content and a literal multiline block
copy: |
content='this is the first line
this is the second line
this line is after an empty line
this line is the last line
'
dest={{output_dir}}/multiline.txt
register: copy_result6
- debug: var=copy_result6
- name: assert the multiline file was created correctly
assert:
that:
- "copy_result6.changed"
- "copy_result6.dest == '{{output_dir|expanduser}}/multiline.txt'"
- "copy_result6.checksum == '9cd0697c6a9ff6689f0afb9136fa62e0b3fee903'"
# test overwriting a file as an unprivileged user (pull request #8624)
# this can't be relative to {{output_dir}} as ~root usually has mode 700
- name: create world writable directory
file: dest=/tmp/worldwritable state=directory mode=0777
- name: create world writable file
copy: dest=/tmp/worldwritable/file.txt content="bar" mode=0666
- name: overwrite the file as user nobody
copy: dest=/tmp/worldwritable/file.txt content="baz"
become: yes
become_user: nobody
register: copy_result7
- name: assert the file was overwritten
assert:
that:
- "copy_result7.changed"
- "copy_result7.dest == '/tmp/worldwritable/file.txt'"
- "copy_result7.checksum == 'bbe960a25ea311d21d40669e93df2003ba9b90a2'"
- name: clean up
file: dest=/tmp/worldwritable state=absent
# test overwriting a link using "follow=yes" so that the link
# is preserved and the link target is updated
- name: create a test file to symlink to
copy: dest={{output_dir}}/follow_test content="this is the follow test file\n"
- name: create a symlink to the test file
file: path={{output_dir}}/follow_link src='./follow_test' state=link
- name: update the test file using follow=True to preserve the link
copy: dest={{output_dir}}/follow_link content="this is the new content\n" follow=yes
register: replace_follow_result
- name: stat the link path
stat: path={{output_dir}}/follow_link
register: stat_link_result
- name: assert that the link is still a link
assert:
that:
- stat_link_result.stat.islnk
- name: get the checksum of the link target
shell: "{{ sha1sum.stdout }} {{output_dir}}/follow_test | cut -f1 -sd ' '"
register: target_file_result
- name: assert that the link target was updated
assert:
that:
- replace_follow_result.checksum == target_file_result.stdout

View file

@ -0,0 +1,23 @@
-----BEGIN CERTIFICATE-----
MIID3TCCAsWgAwIBAgIJAPczDjnFOjH/MA0GCSqGSIb3DQEBCwUAMIGEMQswCQYD
VQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBkR1cmhhbTEQMA4GA1UECgwH
QW5zaWJsZTEfMB0GA1UEAwwWZG9ja2VydGVzdC5hbnNpYmxlLmNvbTEkMCIGCSqG
SIb3DQEJARYVdGt1cmF0b21pQGFuc2libGUuY29tMB4XDTE1MDMxNzIyMjc1OVoX
DTQyMDgwMjIyMjc1OVowgYQxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0G
A1UEBwwGRHVyaGFtMRAwDgYDVQQKDAdBbnNpYmxlMR8wHQYDVQQDDBZkb2NrZXJ0
ZXN0LmFuc2libGUuY29tMSQwIgYJKoZIhvcNAQkBFhV0a3VyYXRvbWlAYW5zaWJs
ZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIk4D0+QY3obQM
I/BPmI4pFFu734HHz98ce6Qat7WYiGUHsnt3LHw2a6zMsgP3siD1zqGHtk1IipWR
IwZbXm1spww/8YNUEE8wbXlLGI8IPUpg2J7NS2SdYIuN/TrQMqCUt7fFb+7OQjaH
RtR0LtXhP96al3E8BR9G6AiS67XuwdTL4vrXLUWISjNyF2Vj7xQsp8KRrq0qnXhq
pefeBi1fD9DG5f76j3s8lqGiOg9FHegvfodonNGcqE16T/vBhQcf+NjenlFvR2Lh
3wb/RCo/b1IhZHKNx32fJ/WpiKXkrLYFvwtIWtLw6XIwwarc+n7AfGqKnt4h4bAG
a+5aNnlFAgMBAAGjUDBOMB0GA1UdDgQWBBRZpu6oomSlpCvy2VgOHbWwDwVl1jAf
BgNVHSMEGDAWgBRZpu6oomSlpCvy2VgOHbWwDwVl1jAMBgNVHRMEBTADAQH/MA0G
CSqGSIb3DQEBCwUAA4IBAQCqOSFzTgQDww5bkNRCQrg7lTKzXW9bJpJ5NZdTLwh6
b+e+XouRH+lBe7Cnn2RTtuFYVfm8hQ1Ra7GDM3v2mJns/s3zDkRINZMMVXddzl5S
M8QxsFJK41PaL9wepizslkcg19yQkdWJQYPDeFurlFvwtakhZE7ttawYi5bFkbCd
4fchMNBBmcigpSfoWb/L2lK2vVKBcfOdUl+V6k49lpf8u7WZD0Xi2cbBhw17tPj4
ulKZaVNdzj0GFfhpQe/MtDoqxStRpHamdk0Y6fN+CvoW7RPDeVsqkIgCu30MOFuG
A53ZtOc3caYRyGYJtIIl0Rd5uIApscec/6RGiFX6Gab8
-----END CERTIFICATE-----

View file

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAyJOA9PkGN6G0DCPwT5iOKRRbu9+Bx8/fHHukGre1mIhlB7J7
dyx8NmuszLID97Ig9c6hh7ZNSIqVkSMGW15tbKcMP/GDVBBPMG15SxiPCD1KYNie
zUtknWCLjf060DKglLe3xW/uzkI2h0bUdC7V4T/empdxPAUfRugIkuu17sHUy+L6
1y1FiEozchdlY+8ULKfCka6tKp14aqXn3gYtXw/QxuX++o97PJahojoPRR3oL36H
aJzRnKhNek/7wYUHH/jY3p5Rb0di4d8G/0QqP29SIWRyjcd9nyf1qYil5Ky2Bb8L
SFrS8OlyMMGq3Pp+wHxqip7eIeGwBmvuWjZ5RQIDAQABAoIBAQCVOumfWgf+LBlB
TxvknKRoe/Ukes6cU1S0ZGlcV4KM0i4Y4/poWHiyJLqUMX4yNB3BxNL5nfEyH6nY
Ki74m/Dd/gtnJ9GGIfxJE6pC7Sq9/pvwIjtEkutxC/vI0LeJX6GKBIZ+JyGN5EWd
sF0xdAc9Z7+/VR2ygj0bDFgUt7rMv6fLaXh6i5Ms0JV7I/HkIi0Lmy9FncJPOTjP
/Wb3Rj5twDppBqSiqU2JNQHysWzNbp8nzBGeR0+WU6xkWjjGzVyQZJq4XJQhqqot
t+v+/lF+jObujcRxPRStaA5IoQdmls3l+ubkoFeNp3j6Nigz40wjTJArMu/Q9xQ5
A+kHYNgBAoGBAPVNku0eyz1SyMM8FNoB+AfSpkslTnqfmehn1GCOOS9JPimGWS3A
UlAs/PAPW/H/FTM38eC89GsKKVV8zvwkERNwf+PIGzkQrJgYLxGwoflAKsvFoQi9
PVbIn0TBDZ3TWyNfGul62fEgNen4B46d7kG6l/C3p9eKKCo3sCBgWl8FAoGBANFS
n9YWyAYmHQAWy5R0YeTsdtiRpZWkB0Is9Jr8Zm/DQDNnsKgvXw//qxuWYMi68teK
6o8t5mgDQNWBu3rXrU73f8mMVJNmzSHFbyQEyFOJ9yvI5qMRbJfvdURUje6d3ZUw
G7olKjX0fec4cAG7hbT8sMDvIbnATdhh3VppiEVBAoGBAJKidJnaNpPJ0MkkOTK4
ypOikFWLT4ZtsYsDxiiR3A0wM0CPVu/Kb2oN+oVmKQhX+0xKvQQi79iskljP6ss+
pBaCwXBgRiWumf2xNzHT7H8apHp7APBAb1JZSxvGa2VU2r4iM+wty+of3xqlcZ8H
OU2BRSJYJrTpmWjjMR2pe1whAoGAfMTbMSlzIPcm4h60SlD06Rdp370xDfkvumpB
gwBfrs6bPgjYa+eQqmCjBValagDFL2VGWwHpDKajxqAFuDtGuoMcUG6tGw9zxmWA
0d9n6SObiSW/FAQWzpmVNJ2R3GGM6pg6bsIoXvDU+zXQzbeRA0h7swTW/Xl67Teo
UXQGHgECgYEAjckqv2e39AgBvjxvj9SylVbFNSERrbpmiIRH31MnAHpTXbxRf7K+
/79vUsRfQun9F/+KVfjUyMqRj0PE2tS4ATIjqQsa18RCB4mAE3sNsKz8HbJfzIFq
eEqAWmURm6gRmLmaTMlXS0ZtZaw/A2Usa/DJumu9CsfBu7ZJbDnrQIY=
-----END RSA PRIVATE KEY-----

View file

@ -0,0 +1 @@
D96F3E552F279F46

View file

@ -0,0 +1 @@
testdocker:$apr1$6cYd3tA9$4Dc9/I5Z.bl8/br8O/6B41

View file

@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDYTCCAkkCCQDZbz5VLyefRjANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMC
VVMxCzAJBgNVBAgMAk5DMQ8wDQYDVQQHDAZEdXJoYW0xEDAOBgNVBAoMB0Fuc2li
bGUxHzAdBgNVBAMMFmRvY2tlcnRlc3QuYW5zaWJsZS5jb20xJDAiBgkqhkiG9w0B
CQEWFXRrdXJhdG9taUBhbnNpYmxlLmNvbTAgFw0xNTAzMTcyMjMxNTBaGA8yMjg4
MTIzMDIyMzE1MFowXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5DMQ8wDQYDVQQH
DAZEdXJoYW0xEDAOBgNVBAoMB0Fuc2libGUxHzAdBgNVBAMMFmRvY2tlcnRlc3Qu
YW5zaWJsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7WpI3
QuuARgPufAA0JkGCGIUNWqFyTEngOWvBVEuk5TnDB4x78OCE9j7rr75OxZaSc6Y7
oFTl+hhlgt6sqj+GXehgCHLA97CCc8eUqGv3bwdIIg/hahCPjEWfYzocX1xmUdzN
6klbV9lSO7FGSuk7W4DNga/weRfZmVoPi6jqTvx0tFsGrHVb1evholUKpxaOEYQZ
2NJ22+UXpUyVzN/mw5TAGNG0/yR7sIgCjKYCsYF8k79SfNDMJ1VcCPy3aag45jaz
WoA+OIJJFRkAaPSM5VtnbGBv/slpDVaKfl2ei7Ey3mKx1b7jYMzRz07Gw+zqr1gJ
kBWvfjR7ioxXcN7jAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAJyF24tCq5R8SJto
EMln0m9dMoJTC5usaBYBUMMe6hV2ikUGaXVDIqY+Yypt1sIcjGnLRmehJbej8iS7
4aypuLc8Fgb4CvW+gY3I3W1iF7ZxIN/4yr237Z9KH1d1uGi+066Sk94OCXlqgsb+
RzU6XOg+PMIjYC/us5VRv8a2qfjIA8getR+19nP+hR6NgIQcEyRKG2FmhkUSAwd8
60FhpW4UmPQmn0ErZmRwdp2hNPj5g3my5iOSi7DzdK4CwZJAASOoWsbQIxP0k4JE
PMo7Ad1YxXlOvNWIA8FLMkRsq3li6KJ17WBdEYgFeuxWpf1/x1WA+WpwEIfC5cuR
A5LkaNI=
-----END CERTIFICATE-----

View file

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE REQUEST-----
MIICozCCAYsCAQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5DMQ8wDQYDVQQH
DAZEdXJoYW0xEDAOBgNVBAoMB0Fuc2libGUxHzAdBgNVBAMMFmRvY2tlcnRlc3Qu
YW5zaWJsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7WpI3
QuuARgPufAA0JkGCGIUNWqFyTEngOWvBVEuk5TnDB4x78OCE9j7rr75OxZaSc6Y7
oFTl+hhlgt6sqj+GXehgCHLA97CCc8eUqGv3bwdIIg/hahCPjEWfYzocX1xmUdzN
6klbV9lSO7FGSuk7W4DNga/weRfZmVoPi6jqTvx0tFsGrHVb1evholUKpxaOEYQZ
2NJ22+UXpUyVzN/mw5TAGNG0/yR7sIgCjKYCsYF8k79SfNDMJ1VcCPy3aag45jaz
WoA+OIJJFRkAaPSM5VtnbGBv/slpDVaKfl2ei7Ey3mKx1b7jYMzRz07Gw+zqr1gJ
kBWvfjR7ioxXcN7jAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAoPgw9dlA3Ys2
oahtr2KMNFnHnab6hUr/CuDIygkOft+MCX1cPXY1c0R72NQq42TjAFO5UnriJ0Jg
rcWgBAw8TCOHH77ZWawQFjWWoxNTy+bfXNJ002tzc4S/A4s8ytcFQN7E2irbGtUB
ratVaE+c6RvD/o48N4YLUyJbJK84FZ1xMnJI0z5R6XzDWEqYbobzkM/aUWvDTT9F
+F9H5W/3sIhNFVGLygSKbhgrb6eaC8R36fcmTRfYYdT4GrpXFePoZ4LJGCKiiaGV
p8gZzYQ9xjRYDP2OUMacBDlX1Mu5IJ2SCfjavD1hMhB54tWiiw3CRMJcNMql7ob/
ZHH8UDMqgA==
-----END CERTIFICATE REQUEST-----

View file

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAu1qSN0LrgEYD7nwANCZBghiFDVqhckxJ4DlrwVRLpOU5wweM
e/DghPY+66++TsWWknOmO6BU5foYZYLerKo/hl3oYAhywPewgnPHlKhr928HSCIP
4WoQj4xFn2M6HF9cZlHczepJW1fZUjuxRkrpO1uAzYGv8HkX2ZlaD4uo6k78dLRb
Bqx1W9Xr4aJVCqcWjhGEGdjSdtvlF6VMlczf5sOUwBjRtP8ke7CIAoymArGBfJO/
UnzQzCdVXAj8t2moOOY2s1qAPjiCSRUZAGj0jOVbZ2xgb/7JaQ1Win5dnouxMt5i
sdW+42DM0c9OxsPs6q9YCZAVr340e4qMV3De4wIDAQABAoIBABjczxSIS+pM4E6w
o/JHtV/HUzjPcydQ2mjoFdWlExjB1qV8BfeYoqLibr0mKFIZxH6Q3FmDUGDojH5E
HLq7KQzyv1inJltXQ1Q8exrOMu22DThUVNksEyCJk9+v8lE7km59pJiq46s8gDl6
dG8Il+TporEi6a820qRsxlfTx8m4EUbyPIhf2e2wYdqiscLwj49ZzMs3TFJxN3j4
lLP3QDHz9n8q+XXpUT9+rsePe4D4DVVRLhg8w35zkys36xfvBZrI+9SytSs+r1/e
X4gVhxeX9q3FkvXiw1IDGPr0l5X7SH+5zk7JWuLfFbNBK02zR/Bd2OIaYAOmyIFk
ZzsVfokCgYEA8Cj04S32Tga7lOAAUEuPjgXbCtGYqBUJ/9mlMHJBtyl4vaBRm1Z3
1YQqlL3yGM1F6ZStPWs86vsVaScypr7+RnmQ/uPjz1g2jNI9vomqRkzpzd8/bBwW
J3FCaKFIfl9uQx4ac7piAYdhNXswjQ7Kzn5xgG24i8EkUm6+UxarA38CgYEAx7X+
qOVT+kA5WU1EDIc2x3Au0PhNIXiHOGRLW0MC7Vy1xBrgxfVrz6J8flBXOxmWYjRq
3dFiHA9S7WPQStkgTjzE91sthLefJ8DKXE4IrRkvYXIIX8DqkcFxTHS/OzckTcK/
z79jNOPYA1s+z2jzgd24sslXbqxNz1LqZ/PlRp0CgYEAik8cEF72/aK0/x0uMRAD
IcjPiGCDKTHMq3M9xjPXEtQofBTLSsm2g9n05+qodY4qmEYOq1OKJs3pW8C+U/ek
2xOB5Ll75lqoN9uQwZ3o2UnMUMskbG+UdqyskTNpW5Y8Gx1IIKQTc0vzOOi0YlhF
hjydw1ftM1dNQsgShimE3aMCgYEAwITwFk7kcoTBBBZY+B7Mrtu1Ndt3N0HiUHlW
r4Zc5waNbptefVbF9GY1zuqR/LYA43CWaHj1NAmNrqye2diPrPwmADHUInGEqqTO
LsdG099Ibo6oBe6J8bJiDwsoYeQZSiDoGVPtRcoyraGjXfxVaaac6zTu5RCS/b53
m3hhWH0CgYAqi3x10NpJHInU/zNa1GhI9UVJzabE2APdbPHvoE/yyfpCGhExiXZw
MDImUzc59Ro0pCZ9Bk7pd5LwdjjeJXih7jaRZQlPD1BeM6dKdmJps1KMaltOOJ4J
W0FE34E+Kt5JeIix8zmhxgaAU9NVilaNx5tI/D65Y0inMBZpqedrtg==
-----END RSA PRIVATE KEY-----

View file

@ -0,0 +1,40 @@
# For versions of Nginx > 1.3.9 that include chunked transfer encoding support
# Replace with appropriate values where necessary
upstream docker-registry {
server localhost:5000;
}
server {
listen 8080;
server_name dockertest.ansible.com;
ssl on;
ssl_certificate /etc/pki/tls/certs/dockertest.ansible.com.crt;
ssl_certificate_key /etc/pki/tls/private/dockertest.ansible.com.key;
proxy_set_header Host $http_host; # required for Docker client sake
proxy_set_header X-Real-IP $remote_addr; # pass on real client IP
client_max_body_size 0; # disable any limits to avoid HTTP 413 for large image uploads
# required to avoid HTTP 411: see Issue #1486 (https://github.com/dotcloud/docker/issues/1486)
chunked_transfer_encoding on;
location / {
# let Nginx know about our auth file
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/docker-registry.htpasswd;
proxy_pass http://docker-registry;
}
location /_ping {
auth_basic off;
proxy_pass http://docker-registry;
}
location /v1/_ping {
auth_basic off;
proxy_pass http://docker-registry;
}
}

View file

@ -0,0 +1,20 @@
# test code for the service 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/>.
dependencies:
- prepare_tests

View file

@ -0,0 +1,6 @@
- name: Install docker packages (apt)
apt:
state: present
# Note: add docker-registry when available
name: docker.io,python-docker,netcat-openbsd,nginx

View file

@ -0,0 +1,17 @@
- name: Install docker packages (rht family)
package:
state: present
name: docker-io,docker-registry,python-docker-py,nginx
- name: Install netcat (Fedora)
package:
state: present
name: nmap-ncat
when: ansible_distribution == 'Fedora' or (ansible_os_family == 'RedHat' and ansible_distribution_version|version_compare('>=', 7))
- name: Install netcat (RHEL)
package:
state: present
name: nc
when: ansible_distribution != 'Fedora' and (ansible_os_family == 'RedHat' and ansible_distribution_version|version_compare('<', 7))

View file

@ -0,0 +1,58 @@
- name: Start docker daemon
service:
name: docker
state: started
- name: Download busybox image
docker:
image: busybox
state: present
pull: missing
- name: Run a small script in busybox
docker:
image: busybox
state: reloaded
pull: always
command: "nc -l -p 2000 -e xargs -n1 echo hello"
detach: True
- name: Get the docker container ip
set_fact: container_ip="{{docker_containers[0].NetworkSettings.IPAddress}}"
- name: Try to access the server
shell: "echo 'world' | nc {{ container_ip }} 2000"
register: docker_output
- name: check that the script ran
assert:
that:
- "'hello world' in docker_output.stdout_lines"
- name: Run a script that sets environment in busybox
docker:
image: busybox
state: reloaded
pull: always
env:
TEST: hello
command: '/bin/sh -c "nc -l -p 2000 -e xargs -n1 echo $TEST"'
detach: True
- name: Get the docker container ip
set_fact: container_ip="{{docker_containers[0].NetworkSettings.IPAddress}}"
- name: Try to access the server
shell: "echo 'world' | nc {{ container_ip }} 2000"
register: docker_output
- name: check that the script ran
assert:
that:
- "'hello world' in docker_output.stdout_lines"
- name: Remove containers
shell: "docker rm -f $(docker ps -aq)"
- name: Remove all images from the local docker
shell: "docker rmi -f $(docker images -q)"

View file

@ -0,0 +1,23 @@
#- include: docker-setup-rht.yml
# when: ansible_distribution in ['Fedora']
#- include: docker-setup-rht.yml
# Packages on RHEL and CentOS 7 are broken, broken, broken. Revisit when
# they've got that sorted out
# CentOS 6 currently broken by conflicting files in python-backports and python-backports-ssl_match_hostname
#when: ansible_distribution in ['RedHat', 'CentOS'] and ansible_lsb.major_release|int == 6
# python-docker isn't available until 14.10. Revist at the next Ubuntu LTS
#- include: docker-setup-debian.yml
# when: ansible_distribution in ['Ubuntu']
#- include: docker-tests.yml
# Add other distributions as the proper packages become available
# when: ansible_distribution in ['Fedora']
#- include: docker-tests.yml
# when: ansible_distribution in ['RedHat', 'CentOS'] and ansible_lsb.major_release|int == 6
#- include: registry-tests.yml
# Add other distributions as the proper packages become available
# when: ansible_distribution in ['Fedora']

View file

@ -0,0 +1,189 @@
- name: Configure a private docker registry
service:
name: docker-registry
state: started
- name: Retrieve busybox image from docker hub
docker:
image: busybox
state: present
pull: missing
- name: Get busybox image id
shell: "docker images | grep busybox | awk '{ print $3 }'"
register: image_id
- name: Tag docker image into the local registry
command: "docker tag {{ image_id.stdout_lines[0] }} localhost:5000/mine"
- name: Push docker image into the private registry
command: "docker push localhost:5000/mine"
- name: Remove all images from the local docker
shell: "docker rmi -f {{image_id.stdout_lines[0]}}"
- name: Get number of images in docker
command: "docker images"
register: docker_output
# docker prints a header so the header should be all that's present
- name: Check that there are no images in docker
assert:
that:
- "{{ docker_output.stdout_lines| length }} <= 1 "
- name: Retrieve the image from private docker registry
docker:
image: "localhost:5000/mine"
state: present
pull: missing
insecure_registry: True
- name: Run a small script in the new image
docker:
image: "localhost:5000/mine"
state: reloaded
pull: always
command: "nc -l -p 2000 -e xargs -n1 echo hello"
detach: True
insecure_registry: True
- name: Get the docker container id
shell: "docker ps | grep mine | awk '{ print $1 }'"
register: container_id
- name: Get the docker container ip
shell: "docker inspect {{ container_id.stdout_lines[0] }} | grep IPAddress | awk -F '\"' '{ print $4 }'"
register: container_ip
- name: Pause a few moments because docker is not reliable
pause:
seconds: 40
- name: Try to access the server
shell: "echo 'world' | nc {{ container_ip.stdout_lines[0] }} 2000"
register: docker_output
- name: check that the script ran
assert:
that:
- "'hello world' in docker_output.stdout_lines"
- name: Remove containers
shell: "docker rm -f $(docker ps -aq)"
- shell: docker images -q
- name: Remove all images from the local docker
shell: "docker rmi -f $(docker images -q)"
- name: Get number of images in docker
command: "docker images"
register: docker_output
- name: Check that there are no images in docker
assert:
that:
- "{{ docker_output.stdout_lines| length }} <= 1"
#
# Private registry secured with an SSL proxy
#
- name: Set selinux to allow docker to connect to nginx
seboolean:
name: docker_connect_any
state: yes
- name: Set selinux to allow nginx to connect to docker
seboolean:
name: httpd_can_network_connect
state: yes
- name: Setup nginx with a user/password
copy:
src: docker-registry.htpasswd
dest: /etc/nginx/docker-registry.htpasswd
- name: Setup nginx with a config file
copy:
src: nginx-docker-registry.conf
dest: /etc/nginx/conf.d/nginx-docker-registry.conf
- name: Setup nginx docker cert
copy:
src: dockertest.ansible.com.crt
dest: /etc/pki/tls/certs/dockertest.ansible.com.crt
- name: Setup nginx docker key
copy:
src: dockertest.ansible.com.key
dest: /etc/pki/tls/private/dockertest.ansible.com.key
- name: Setup the ca keys
copy:
src: devdockerCA.crt
dest: /etc/pki/ca-trust/source/anchors/devdockerCA.crt
- name: Update the ca bundle
command: update-ca-trust extract
- name: Restart docker daemon
service:
name: docker
state: restarted
- name: Start nginx
service:
name: nginx
state: restarted
- name: Add domain name to hosts
lineinfile:
line: "127.0.0.1 dockertest.ansible.com"
dest: /etc/hosts
state: present
- name: Start a container after getting it from a secured private registry
docker:
image: dockertest.ansible.com:8080/mine
registry: dockertest.ansible.com:8080
username: "testdocker"
password: "testdocker"
state: running
command: "nc -l -p 2000 -e xargs -n1 echo hello"
detach: True
- name: Get the docker container id
shell: "docker ps | grep mine | awk '{ print $1 }'"
register: container_id
- name: Get the docker container ip
shell: "docker inspect {{ container_id.stdout_lines[0] }} | grep IPAddress | awk -F '\"' '{ print $4 }'"
register: container_ip
- name: Pause a few moments because docker is not reliable
pause:
seconds: 40
- name: Try to access the server
shell: "echo 'world' | nc {{ container_ip.stdout_lines[0] }} 2000"
register: docker_output
- name: check that the script ran
assert:
that:
- "'hello world' in docker_output.stdout_lines"
- name: Remove containers
shell: "docker rm $(docker ps -aq)"
- name: Remove all images from the local docker
shell: "docker rmi -f $(docker images -q)"
- name: Remove domain name to hosts
lineinfile:
line: "127.0.0.1 dockertest.ansible.com"
dest: /etc/hosts
state: absent

View file

@ -0,0 +1,3 @@
#!/usr/bin/env python
print('{"changed":false, "msg":"this is the embedded module"}')

View file

@ -0,0 +1,9 @@
- name: run the embedded dummy module
test_integration_module:
register: result
- name: assert the embedded module ran
assert:
that:
- "'msg' in result"
- result.msg == "this is the embedded module"

View file

@ -0,0 +1,3 @@
dependencies:
- prepare_tests

View file

@ -0,0 +1,39 @@
# Test code for facts.d and setup filters
# (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/>.
- set_fact: fact_dir={{output_dir}}/facts.d
- file: path={{ fact_dir }} state=directory
- shell: echo "[general]" > {{ fact_dir }}/preferences.fact
- shell: echo "bar=loaded" >> {{ fact_dir }}/preferences.fact
- setup:
fact_path: "{{ fact_dir | expanduser }}"
filter: "*local*"
register: setup_result
- debug: var=setup_result
- assert:
that:
- "'ansible_facts' in setup_result"
- "'ansible_local' in setup_result.ansible_facts"
- "'preferences' in setup_result.ansible_facts['ansible_local']"
- "'general' in setup_result.ansible_facts['ansible_local']['preferences']"
- "'bar' in setup_result.ansible_facts['ansible_local']['preferences']['general']"
- "setup_result.ansible_facts['ansible_local']['preferences']['general']['bar'] == 'loaded'"

View file

@ -0,0 +1,69 @@
# Test code for failed_when.
# (c) 2014, Richard Isaacson <richard.c.isaacson@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: command rc 0 failed_when_result undef
shell: exit 0
ignore_errors: True
register: result
- assert:
that:
- "'failed' not in result"
- name: command rc 0 failed_when_result False
shell: exit 0
failed_when: false
ignore_errors: true
register: result
- assert:
that:
- "'failed' in result and not result.failed"
- "'failed_when_result' in result and not result.failed_when_result"
- name: command rc 1 failed_when_result True
shell: exit 1
failed_when: true
ignore_errors: true
register: result
- assert:
that:
- "'failed' in result and result.failed"
- "'failed_when_result' in result and result.failed_when_result"
- name: command rc 1 failed_when_result undef
shell: exit 1
ignore_errors: true
register: result
- assert:
that:
- "'failed' in result and result.failed"
- name: command rc 1 failed_when_result False
shell: exit 1
failed_when: false
ignore_errors: true
register: result
- assert:
that:
- "'failed' in result and not result.failed"
- "'failed_when_result' in result and not result.failed_when_result"

View file

@ -0,0 +1,3 @@
dependencies:
- prepare_tests

View file

@ -0,0 +1,97 @@
# test code for the pip 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: create a file that we can use to fetch
copy: content="test" dest={{ output_dir }}/orig
- name: fetch the motd
fetch: src={{ output_dir }}/orig dest={{ output_dir }}/fetched
register: fetched
- debug: var=fetched
# TODO: check the become and non-become forms of fetch because in one form we'll do
# the get method of the connection plugin and in the become case we'll use the
# fetch module.
- name: diff what we fetched with the original file
shell: diff {{ output_dir }}/orig {{ output_dir }}/fetched/{{inventory_hostname}}{{ output_dir | expanduser }}/orig
register: diff
- name: check the diff to make sure they are the same
assert:
that:
'diff.stdout == ""'
- name: attempt to fetch a non-existent file - do not fail on missing
fetch: src={{ output_dir }}/doesnotexist dest={{ output_dir }}/fetched
register: fetch_missing_nofail
- name: check fetch missing no fail result
assert:
that:
- "fetch_missing_nofail.msg"
- "not fetch_missing_nofail|changed"
- name: attempt to fetch a non-existent file - fail on missing
fetch: src={{ output_dir }}/doesnotexist dest={{ output_dir }}/fetched fail_on_missing=yes
register: fetch_missing
ignore_errors: true
- name: check fetch missing with failure
assert:
that:
- "fetch_missing|failed"
- "fetch_missing.msg"
- "not fetch_missing|changed"
- name: attempt to fetch a directory - should not fail but return a message
fetch: src={{ output_dir }} dest={{ output_dir }}/somedir
register: fetch_dir
- name: check fetch directory result
assert:
that:
- "not fetch_dir|changed"
- "fetch_dir.msg"
- name: create symlink to a file that we can fetch
file:
path: "{{ output_dir }}/link"
src: "{{ output_dir }}/orig"
state: "link"
- name: fetch the file via a symlink
fetch: src={{ output_dir }}/link dest={{ output_dir }}/fetched-link
register: fetched
- debug: var=fetched
# TODO: check the become and non-become forms of fetch because in one form we'll do
# the get method of the connection plugin and in the become case we'll use the
# fetch module.
- name: diff what we fetched with the original file
shell: diff {{ output_dir }}/orig {{ output_dir }}/fetched-link/{{inventory_hostname}}{{ output_dir | expanduser }}/link
register: diff
- name: check the diff to make sure they are the same
assert:
that:
'diff.stdout == ""'

View file

@ -0,0 +1 @@
foo.txt

View file

@ -0,0 +1,3 @@
dependencies:
- prepare_tests

View file

@ -0,0 +1,564 @@
# Test code for the file module.
# (c) 2014, Richard Isaacson <richard.c.isaacson@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/>.
- set_fact: output_file={{output_dir}}/foo.txt
- name: prep with a basic copy
copy: src=foo.txt dest={{output_file}}
- name: verify that we are checking a file and it is present
file: path={{output_file}} state=file
register: file_result
- name: verify that the file was marked as changed
assert:
that:
- "file_result.changed == false"
- "file_result.state == 'file'"
- name: verify that we are checking an absent file
file: path={{output_dir}}/bar.txt state=absent
register: file2_result
- name: verify that the file was marked as changed
assert:
that:
- "file2_result.changed == false"
- "file2_result.state == 'absent'"
- name: verify we can touch a file
file: path={{output_dir}}/baz.txt state=touch
register: file3_result
- name: verify that the file was marked as changed
assert:
that:
- "file3_result.changed == true"
- "file3_result.state == 'file'"
- "file3_result.mode == '0644'"
- name: change file mode
file: path={{output_dir}}/baz.txt mode=0600
register: file4_result
- name: verify that the file was marked as changed
assert:
that:
- "file4_result.changed == true"
- "file4_result.mode == '0600'"
- name: change ownership and group
file: path={{output_dir}}/baz.txt owner=1234 group=1234
- name: setup a tmp-like directory for ownership test
file: path=/tmp/worldwritable mode=1777 state=directory
- name: Ask to create a file without enough perms to change ownership
file: path=/tmp/worldwritable/baz.txt state=touch owner=root
become: yes
become_user: nobody
register: chown_result
ignore_errors: True
- name: Ask whether the new file exists
stat: path=/tmp/worldwritable/baz.txt
register: file_exists_result
- name: Verify that the file doesn't exist on failure
assert:
that:
- "chown_result.failed == True"
- "file_exists_result.stat.exists == False"
- name: clean up
file: path=/tmp/worldwritable state=absent
- name: create soft link to file
file: src={{output_file}} dest={{output_dir}}/soft.txt state=link
register: file5_result
- name: verify that the file was marked as changed
assert:
that:
- "file5_result.changed == true"
- name: create hard link to file
file: src={{output_file}} dest={{output_dir}}/hard.txt state=hard
register: file6_result
- name: verify that the file was marked as changed
assert:
that:
- "file6_result.changed == true"
- name: touch a hard link
file: src={{output_file}} dest={{output_dir}}/hard.txt state=touch
register: file6_touch_result
- name: verify that the hard link was touched
assert:
that:
- "file6_touch_result.changed == true"
- name: create a directory
file: path={{output_dir}}/foobar state=directory
register: file7_result
- name: verify that the file was marked as changed
assert:
that:
- "file7_result.changed == true"
- "file7_result.state == 'directory'"
- name: determine if selinux is installed
shell: which getenforce || exit 0
register: selinux_installed
- name: determine if selinux is enabled
shell: getenforce
register: selinux_enabled
when: selinux_installed.stdout != ""
ignore_errors: true
- name: decide to include or not include selinux tests
include: selinux_tests.yml
when: selinux_installed is defined and selinux_installed.stdout != "" and selinux_enabled.stdout != "Disabled"
- name: remote directory foobar
file: path={{output_dir}}/foobar state=absent
- name: remove file foo.txt
file: path={{output_dir}}/foo.txt state=absent
- name: remove file bar.txt
file: path={{output_dir}}/foo.txt state=absent
- name: remove file baz.txt
file: path={{output_dir}}/foo.txt state=absent
- name: copy directory structure over
copy: src=foobar dest={{output_dir}}
- name: Change ownership of a directory with recurse=no(default)
file: path={{output_dir}}/foobar owner=1234
- name: verify that the permission of the directory was set
file: path={{output_dir}}/foobar state=directory
register: file8_result
- name: assert that the directory has changed to have owner 1234
assert:
that:
- "file8_result.uid == 1234"
- name: verify that the permission of a file under the directory was not set
file: path={{output_dir}}/foobar/fileA state=file
register: file9_result
- name: assert the file owner has not changed to 1234
assert:
that:
- "file9_result.uid != 1234"
- name: change the ownership of a directory with recurse=yes
file: path={{output_dir}}/foobar owner=1235 recurse=yes
- name: verify that the permission of the directory was set
file: path={{output_dir}}/foobar state=directory
register: file10_result
- name: assert that the directory has changed to have owner 1235
assert:
that:
- "file10_result.uid == 1235"
- name: verify that the permission of a file under the directory was not set
file: path={{output_dir}}/foobar/fileA state=file
register: file11_result
- name: assert that the file has changed to have owner 1235
assert:
that:
- "file11_result.uid == 1235"
- name: fail to create soft link to non existent file
file: src=/noneexistent dest={{output_dir}}/soft2.txt state=link force=no
register: file12_result
ignore_errors: true
- name: verify that link was not created
assert:
that:
- "file12_result.failed == true"
- name: force creation soft link to non existent
file: src=/noneexistent dest={{output_dir}}/soft2.txt state=link force=yes
register: file13_result
- name: verify that link was created
assert:
that:
- "file13_result.changed == true"
- name: remove directory foobar
file: path={{output_dir}}/foobar state=absent
register: file14_result
- name: verify that the directory was removed
assert:
that:
- 'file14_result.changed == true'
- 'file14_result.state == "absent"'
- name: create a test sub-directory
file: dest={{output_dir}}/sub1 state=directory
register: file15_result
- name: verify that the new directory was created
assert:
that:
- 'file15_result.changed == true'
- 'file15_result.state == "directory"'
- name: create test files in the sub-directory
file: dest={{output_dir}}/sub1/{{item}} state=touch
with_items:
- file1
- file2
- file3
register: file16_result
- name: verify the files were created
assert:
that:
- 'item.changed == true'
- 'item.state == "file"'
with_items: "{{file16_result.results}}"
- name: try to force the sub-directory to a link
file: src={{output_dir}}/testing dest={{output_dir}}/sub1 state=link force=yes
register: file17_result
ignore_errors: true
- name: verify the directory was not replaced with a link
assert:
that:
- 'file17_result.failed == true'
- 'file17_result.state == "directory"'
- name: create soft link to directory using absolute path
file: src=/ dest={{output_dir}}/root state=link
register: file18_result
- name: verify that the result was marked as changed
assert:
that:
- "file18_result.changed == true"
- name: create another test sub-directory
file: dest={{output_dir}}/sub2 state=directory
register: file19_result
- name: verify that the new directory was created
assert:
that:
- 'file19_result.changed == true'
- 'file19_result.state == "directory"'
- name: create soft link to relative file
file: src=../sub1/file1 dest={{output_dir}}/sub2/link1 state=link
register: file20_result
- name: verify that the result was marked as changed
assert:
that:
- "file20_result.changed == true"
- name: create soft link to relative directory
file: src=sub1 dest={{output_dir}}/sub1-link state=link
register: file21_result
- name: verify that the result was marked as changed
assert:
that:
- "file21_result.changed == true"
- name: test file creation with symbolic mode
file: dest={{output_dir}}/test_symbolic state=touch mode=u=rwx,g=rwx,o=rwx
register: result
- name: assert file mode
assert:
that:
- result.mode == '0777'
- name: modify symbolic mode for all
file: dest={{output_dir}}/test_symbolic state=touch mode=a=r
register: result
- name: assert file mode
assert:
that:
- result.mode == '0444'
- name: modify symbolic mode for owner
file: dest={{output_dir}}/test_symbolic state=touch mode=u+w
register: result
- name: assert file mode
assert:
that:
- result.mode == '0644'
- name: modify symbolic mode for group
file: dest={{output_dir}}/test_symbolic state=touch mode=g+w
register: result
- name: assert file mode
assert:
that:
- result.mode == '0664'
- name: modify symbolic mode for world
file: dest={{output_dir}}/test_symbolic state=touch mode=o+w
register: result
- name: assert file mode
assert:
that:
- result.mode == '0666'
- name: modify symbolic mode for owner
file: dest={{output_dir}}/test_symbolic state=touch mode=u+x
register: result
- name: assert file mode
assert:
that:
- result.mode == '0766'
- name: modify symbolic mode for group
file: dest={{output_dir}}/test_symbolic state=touch mode=g+x
register: result
- name: assert file mode
assert:
that:
- result.mode == '0776'
- name: modify symbolic mode for world
file: dest={{output_dir}}/test_symbolic state=touch mode=o+x
register: result
- name: assert file mode
assert:
that:
- result.mode == '0777'
- name: remove symbolic mode for world
file: dest={{output_dir}}/test_symbolic state=touch mode=o-wx
register: result
- name: assert file mode
assert:
that:
- result.mode == '0774'
- name: remove symbolic mode for group
file: dest={{output_dir}}/test_symbolic state=touch mode=g-wx
register: result
- name: assert file mode
assert:
that:
- result.mode == '0744'
- name: remove symbolic mode for owner
file: dest={{output_dir}}/test_symbolic state=touch mode=u-wx
register: result
- name: assert file mode
assert:
that:
- result.mode == '0444'
- name: set sticky bit with symbolic mode
file: dest={{output_dir}}/test_symbolic state=touch mode=o+t
register: result
- name: assert file mode
assert:
that:
- result.mode == '01444'
- name: remove sticky bit with symbolic mode
file: dest={{output_dir}}/test_symbolic state=touch mode=o-t
register: result
- name: assert file mode
assert:
that:
- result.mode == '0444'
- name: add setgid with symbolic mode
file: dest={{output_dir}}/test_symbolic state=touch mode=g+s
register: result
- name: assert file mode
assert:
that:
- result.mode == '02444'
- name: remove setgid with symbolic mode
file: dest={{output_dir}}/test_symbolic state=touch mode=g-s
register: result
- name: assert file mode
assert:
that:
- result.mode == '0444'
- name: add setuid with symbolic mode
file: dest={{output_dir}}/test_symbolic state=touch mode=u+s
register: result
- name: assert file mode
assert:
that:
- result.mode == '04444'
- name: remove setuid with symbolic mode
file: dest={{output_dir}}/test_symbolic state=touch mode=u-s
register: result
- name: assert file mode
assert:
that:
- result.mode == '0444'
# test the file module using follow=yes, so that the target of a
# symlink is modified, rather than the link itself
- name: create a test file
copy: dest={{output_dir}}/test_follow content="this is a test file\n" mode=0666
- name: create a symlink to the test file
file: path={{output_dir}}/test_follow_link src="./test_follow" state=link
- name: modify the permissions on the link using follow=yes
file: path={{output_dir}}/test_follow_link mode=0644 follow=yes
register: result
- name: assert that the chmod worked
assert:
that:
- result.changed
- name: stat the link target
stat: path={{output_dir}}/test_follow
register: result
- name: assert that the link target was modified correctly
assert:
that:
- result.stat.mode == '0644'
- name: attempt to modify the permissions of the link itself
file: path={{output_dir}}/test_follow_link src="./test_follow" state=link mode=0600 follow=no
register: result
# Whether the link itself changed is platform dependent! (BSD vs Linux?)
# Just check that the underlying file was not changed
- name: stat the link target
stat: path={{output_dir}}/test_follow
register: result
- name: assert that the link target was unmodified
assert:
that:
- result.stat.mode == '0644'
ignore_errors: True
# Follow + recursive tests
- name: create a toplevel directory
file: path={{output_dir}}/test_follow_rec state=directory mode=0755
- name: create a file outside of the toplevel
file: path={{output_dir}}/test_follow_rec_target_file state=touch mode=0700
- name: create a directory outside of the toplevel
file: path={{output_dir}}/test_follow_rec_target_dir state=directory mode=0700
- name: create a file inside of the link target directory
file: path={{output_dir}}/test_follow_rec_target_dir/foo state=touch mode=0700
- name: create a symlink to the file
file: path={{output_dir}}/test_follow_rec/test_link state=link src="../test_follow_rec_target_file"
- name: create a symlink to the directory
file: path={{output_dir}}/test_follow_rec/test_link_dir state=link src="../test_follow_rec_target_dir"
- name: try to change permissions without following symlinks
file: path={{output_dir}}/test_follow_rec follow=False mode="a-x" recurse=True
- name: stat the link file target
stat: path={{output_dir}}/test_follow_rec_target_file
register: file_result
- name: stat the link dir target
stat: path={{output_dir}}/test_follow_rec_target_dir
register: dir_result
- name: stat the file inside the link dir target
stat: path={{output_dir}}/test_follow_rec_target_dir/foo
register: file_in_dir_result
- debug: var=file_result.stat.mode
- debug: var=dir_result.stat.mode
- debug: var=file_in_dir_result.stat.mode
- name: assert that the link targets were unmodified
assert:
that:
- file_result.stat.mode == '0700'
- dir_result.stat.mode == '0700'
- file_in_dir_result.stat.mode == '0700'
- name: try to change permissions with following symlinks
file: path={{output_dir}}/test_follow_rec follow=True mode="a-x" recurse=True
- name: stat the link file target
stat: path={{output_dir}}/test_follow_rec_target_file
register: file_result
- name: stat the link dir target
stat: path={{output_dir}}/test_follow_rec_target_dir
register: dir_result
- name: stat the file inside the link dir target
stat: path={{output_dir}}/test_follow_rec_target_dir/foo
register: file_in_dir_result
- debug: var=file_result.stat.mode
- debug: var=dir_result.stat.mode
- debug: var=file_in_dir_result.stat.mode
- name: assert that the link targets were modified
assert:
that:
- file_result.stat.mode == '0600'
- dir_result.stat.mode == '0600'
- file_in_dir_result.stat.mode == '0600'

View file

@ -0,0 +1,30 @@
# Test code for the file module - selinux subtasks.
# (c) 2014, Richard Isaacson <richard.c.isaacson@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: touch a file for testing
file: path={{output_dir}}/foo-se.txt state=touch
register: file_se_result
- name: verify that the file was marked as changed
assert:
that:
- "file_se_result.changed == true"
- "file_se_result.secontext == 'unconfined_u:object_r:admin_home_t:s0'"
- name: remove the file used for testing
file: path={{output_dir}}/foo-se.txt state=absent

View file

@ -0,0 +1,3 @@
[{
"k": "Quotes \"'\n"
}]

View file

@ -0,0 +1,61 @@
This is a test of various filter plugins found in Ansible (ex: core.py), and
not so much a test of the core filters in Jinja2.
Dumping the same structure to YAML
- this is a list element
- this: is a hash element in a list
warp: 9
where: endor
Dumping the same structure to JSON, but don't pretty print
["this is a list element", {"this": "is a hash element in a list", "where": "endor", "warp": 9}]
Dumping the same structure to YAML, but don't pretty print
- this is a list element
- {this: is a hash element in a list, warp: 9, where: endor}
From a recorded task, the changed, failed, success, and skipped
filters are shortcuts to ask if those tasks produced changes, failed,
succeeded, or skipped (as one might guess).
Changed = True
Failed = False
Success = True
Skipped = False
The mandatory filter fails if a variable is not defined and returns the value.
To avoid breaking this test, this variable is already defined.
a = 1
There are various casts available
int = 1
bool = True
String quoting
quoted = quoted
The fileglob module returns the list of things matching a pattern.
fileglob = []
There are also various string operations that work on paths. These do not require
files to exist and are passthrus to the python os.path functions
/etc/motd with basename = motd
/etc/motd with dirname = /etc
TODO: realpath follows symlinks. There isn't a test for this just now.
TODO: add tests for set theory operations like union
TODO: add tests for regex, match, and search

View file

@ -0,0 +1,3 @@
dependencies:
- prepare_tests

View file

@ -0,0 +1,112 @@
# test code
# (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: a dummy task to test the changed and success filters
shell: echo hi
register: some_registered_var
- debug: var=some_registered_var
- name: Verify that we workaround a py26 json bug
template: src=py26json.j2 dest={{output_dir}}/py26json.templated mode=0644
- name: 9851 - Verify that we don't trigger https://github.com/ansible/ansible/issues/9851
copy:
content: " [{{item|to_nice_json}}]"
dest: "{{output_dir}}/9851.out"
with_items:
- {"k": "Quotes \"'\n"}
- name: 9851 - copy known good output into place
copy: src=9851.txt dest={{output_dir}}/9851.txt
- name: 9851 - Compare generated json to known good
shell: diff -w {{output_dir}}/9851.out {{output_dir}}/9851.txt
register: diff_result_9851
- name: 9851 - verify generated file matches known good
assert:
that:
- 'diff_result_9851.stdout == ""'
- name: fill in a basic template
template: src=foo.j2 dest={{output_dir}}/foo.templated mode=0644
register: template_result
- name: copy known good into place
copy: src=foo.txt dest={{output_dir}}/foo.txt
- name: compare templated file to known good
shell: diff -w {{output_dir}}/foo.templated {{output_dir}}/foo.txt
register: diff_result
- name: verify templated file matches known good
assert:
that:
- 'diff_result.stdout == ""'
- name: Verify human_readable
tags: "human_readable"
assert:
that:
- '"1.00 Bytes" == 1|human_readable'
- '"1.00 bits" == 1|human_readable(isbits=True)'
- '"10.00 KB" == 10240|human_readable'
- '"97.66 MB" == 102400000|human_readable'
- '"0.10 GB" == 102400000|human_readable(unit="G")'
- '"0.10 Gb" == 102400000|human_readable(isbits=True, unit="G")'
- name: Verify human_to_bytes
tags: "human_to_bytes"
assert:
that:
- "{{'0'|human_to_bytes}} == 0"
- "{{'0.1'|human_to_bytes}} == 0"
- "{{'0.9'|human_to_bytes}} == 1"
- "{{'1'|human_to_bytes}} == 1"
- "{{'10.00 KB'|human_to_bytes}} == 10240"
- "{{ '11 MB'|human_to_bytes}} == 11534336"
- "{{ '1.1 GB'|human_to_bytes}} == 1181116006"
- "{{'10.00 Kb'|human_to_bytes(isbits=True)}} == 10240"
- name: Verify human_to_bytes (bad string)
tags: "human_to_bytes"
set_fact: bad_string="{{'10.00 foo'|human_to_bytes}}"
ignore_errors: yes
register: _
- name: Verify human_to_bytes (bad string)
tags: "human_to_bytes"
assert:
that: "{{_.failed}}"
- name: Container lookups with extract
assert:
that:
- "'x' == [0]|map('extract',['x','y'])|list|first"
- "'y' == [1]|map('extract',['x','y'])|list|first"
- "42 == ['x']|map('extract',{'x':42,'y':31})|list|first"
- "31 == ['x','y']|map('extract',{'x':42,'y':31})|list|last"
- "'local' == ['localhost']|map('extract',hostvars,'ansible_connection')|list|first"
- "'local' == ['localhost']|map('extract',hostvars,['ansible_connection'])|list|first"
- name: Test json_query filter
assert:
that:
- "users | json_query('[*].hosts[].host') == ['host_a', 'host_b', 'host_c', 'host_d']"

View file

@ -0,0 +1,55 @@
This is a test of various filter plugins found in Ansible (ex: core.py), and
not so much a test of the core filters in Jinja2.
Dumping the same structure to YAML
{{ some_structure | to_nice_yaml }}
Dumping the same structure to JSON, but don't pretty print
{{ some_structure | to_json }}
Dumping the same structure to YAML, but don't pretty print
{{ some_structure | to_yaml }}
From a recorded task, the changed, failed, success, and skipped
filters are shortcuts to ask if those tasks produced changes, failed,
succeeded, or skipped (as one might guess).
Changed = {{ some_registered_var | changed }}
Failed = {{ some_registered_var | failed }}
Success = {{ some_registered_var | success }}
Skipped = {{ some_registered_var | skipped }}
The mandatory filter fails if a variable is not defined and returns the value.
To avoid breaking this test, this variable is already defined.
a = {{ a | mandatory }}
There are various casts available
int = {{ a | int }}
bool = {{ 1 | bool }}
String quoting
quoted = {{ 'quoted' | quote }}
The fileglob module returns the list of things matching a pattern.
fileglob = {{ (output_dir + '/*') | fileglob }}
There are also various string operations that work on paths. These do not require
files to exist and are passthrus to the python os.path functions
/etc/motd with basename = {{ '/etc/motd' | basename }}
/etc/motd with dirname = {{ '/etc/motd' | dirname }}
TODO: realpath follows symlinks. There isn't a test for this just now.
TODO: add tests for set theory operations like union
TODO: add tests for regex, match, and search

View file

@ -0,0 +1,2 @@
Provoke a python2.6 json bug
{{ hostvars[inventory_hostname] | to_nice_json }}

View file

@ -0,0 +1,18 @@
some_structure:
- "this is a list element"
-
this: "is a hash element in a list"
warp: 9
where: endor
users:
- name: steve
hosts:
- host: host_a
password: abc
- host: host_b
- name: bill
hosts:
- host: host_c
password: default
- host: host_d

View file

@ -0,0 +1,3 @@
dependencies:
- prepare_tests

View file

@ -0,0 +1,40 @@
# test code for the gem module
# (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: remove a gem
gem: name=gist state=absent
- name: verify gist is not installed
shell: gem list | egrep '^gist '
register: uninstall
failed_when: "uninstall.rc != 1"
- name: install a gem
gem: name=gist state=present
register: gem_result
- name: verify module output properties
assert:
that:
- "'name' in gem_result"
- "'changed' in gem_result"
- "'state' in gem_result"
- name: verify gist is installed
shell: gem list | egrep '^gist '

View file

@ -0,0 +1,4 @@
dependencies:
- prepare_tests
- prepare_http_tests

View file

@ -0,0 +1,213 @@
# Test code for the file module.
# (c) 2014, Richard Isaacson <richard.c.isaacson@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: Determine if python looks like it will support modern ssl features like SNI
command: "{{ ansible_python.executable }} -c 'from ssl import SSLContext'"
ignore_errors: True
register: python_test
- name: Set python_has_sslcontext if we have it
set_fact:
python_has_ssl_context: True
when: python_test.rc == 0
- name: Set python_has_sslcontext False if we don't have it
set_fact:
python_has_ssl_context: False
when: python_test.rc != 0
- name: Define test files for file schema
set_fact:
geturl_srcfile: "{{ output_dir | expanduser }}/aurlfile.txt"
geturl_dstfile: "{{ output_dir | expanduser }}/aurlfile_copy.txt"
- name: Create source file
copy:
dest: "{{ geturl_srcfile }}"
content: "foobar"
- name: test file fetch
get_url:
url: "{{ 'file://' + geturl_srcfile }}"
dest: "{{ geturl_dstfile }}"
register: result
- name: assert success and change
assert:
that:
- result.changed
- '"OK" in result.msg'
- name: test nonexisting file fetch
get_url:
url: "{{ 'file://' + geturl_srcfile + 'NOFILE' }}"
dest: "{{ geturl_dstfile + 'NOFILE' }}"
register: result
ignore_errors: True
- name: assert success and change
assert:
that:
- result.failed
- name: test https fetch
get_url: url="https://{{ httpbin_host }}/get" dest={{output_dir}}/get_url.txt force=yes
register: result
- name: assert the get_url call was successful
assert:
that:
- result.changed
- '"OK" in result.msg'
- name: test https fetch to a site with mismatched hostname and certificate
get_url:
url: "https://{{ badssl_host }}/"
dest: "{{ output_dir }}/shouldnotexist.html"
ignore_errors: True
register: result
- stat:
path: "{{ output_dir }}/shouldnotexist.html"
register: stat_result
- name: Assert that the file was not downloaded
assert:
that:
- "result.failed == true"
- "'Failed to validate the SSL certificate' in result.msg"
- "stat_result.stat.exists == false"
- name: test https fetch to a site with mismatched hostname and certificate and validate_certs=no
get_url:
url: "https://{{ badssl_host }}/"
dest: "{{ output_dir }}/get_url_no_validate.html"
validate_certs: no
register: result
- stat:
path: "{{ output_dir }}/get_url_no_validate.html"
register: stat_result
- name: Assert that the file was downloaded
assert:
that:
- "result.changed == true"
- "stat_result.stat.exists == true"
# SNI Tests
# SNI is only built into the stdlib from python-2.7.9 onwards
- name: Test that SNI works
get_url:
url: 'https://{{ sni_host }}/'
dest: "{{ output_dir }}/sni.html"
register: get_url_result
ignore_errors: True
- command: "grep '{{ sni_host }}' {{ output_dir}}/sni.html"
register: data_result
when: "{{ python_has_ssl_context }}"
- debug: var=get_url_result
- name: Assert that SNI works with this python version
assert:
that:
- 'data_result.rc == 0'
- '"failed" not in get_url_result'
when: "{{ python_has_ssl_context }}"
# If the client doesn't support SNI then get_url should have failed with a certificate mismatch
- name: Assert that hostname verification failed because SNI is not supported on this version of python
assert:
that:
- 'get_url_result["failed"]'
when: "{{ not python_has_ssl_context }}"
# These tests are just side effects of how the site is hosted. It's not
# specifically a test site. So the tests may break due to the hosting changing
- name: Test that SNI works
get_url:
url: 'https://{{ sni_host }}/'
dest: "{{ output_dir }}/sni.html"
register: get_url_result
ignore_errors: True
- command: "grep '{{ sni_host }}' {{ output_dir}}/sni.html"
register: data_result
when: "{{ python_has_ssl_context }}"
- debug: var=get_url_result
- name: Assert that SNI works with this python version
assert:
that:
- 'data_result.rc == 0'
- '"failed" not in get_url_result'
when: "{{ python_has_ssl_context }}"
# If the client doesn't support SNI then get_url should have failed with a certificate mismatch
- name: Assert that hostname verification failed because SNI is not supported on this version of python
assert:
that:
- 'get_url_result["failed"]'
when: "{{ not python_has_ssl_context }}"
# End hacky SNI test section
- name: Test get_url with redirect
get_url:
url: 'http://{{ httpbin_host }}/redirect/6'
dest: "{{ output_dir }}/redirect.json"
- name: Test that setting file modes work
get_url:
url: 'http://{{ httpbin_host }}/'
dest: '{{ output_dir }}/test'
mode: '0707'
register: result
- stat:
path: "{{ output_dir }}/test"
register: stat_result
- name: Assert that the file has the right permissions
assert:
that:
- "result.changed == true"
- "stat_result.stat.mode == '0707'"
- name: Test that setting file modes on an already downlaoded file work
get_url:
url: 'http://{{ httpbin_host }}/'
dest: '{{ output_dir }}/test'
mode: '0070'
register: result
- stat:
path: "{{ output_dir }}/test"
register: stat_result
- name: Assert that the file has the right permissions
assert:
that:
- "result.changed == true"
- "stat_result.stat.mode == '0070'"
#https://github.com/ansible/ansible/issues/16191
- name: Test url split with no filename
get_url:
url: https://{{ httpbin_host }}
dest: "{{ output_dir }}"

View file

@ -0,0 +1,3 @@
dependencies:
- prepare_tests

View file

@ -0,0 +1,661 @@
# test code for the git module
# (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: set role facts
set_fact:
checkout_dir: '{{ output_dir }}/git'
repo_dir: '{{ output_dir }}/local_repos'
repo_format1: 'https://github.com/jimi-c/test_role'
repo_format2: 'git@github.com:jimi-c/test_role.git'
repo_format3: 'ssh://git@github.com/jimi-c/test_role.git'
repo_submodules: 'https://github.com/abadger/test_submodules.git'
repo_submodules_newer: 'https://github.com/abadger/test_submodules_newer.git'
repo_submodule1: 'https://github.com/abadger/test_submodules_subm1.git'
repo_submodule1_newer: 'https://github.com/abadger/test_submodules_subm1_newer.git'
repo_submodule2: 'https://github.com/abadger/test_submodules_subm2.git'
repo_update_url_1: 'https://github.com/ansible-test-robinro/git-test-old'
repo_update_url_2: 'https://github.com/ansible-test-robinro/git-test-new'
repo_depth_url: 'https://github.com/ansible-test-robinro/git-test-shallow-depth'
known_host_files:
- "{{ lookup('env','HOME') }}/.ssh/known_hosts"
- '/etc/ssh/ssh_known_hosts'
git_version_supporting_depth: 1.9.1
- name: clean out the output_dir
shell: rm -rf {{ output_dir }}/*
- name: verify that git is installed so this test can continue
shell: which git
- name: get git version, only newer than {{git_version_supporting_depth}} has fixed git depth
shell: git --version | grep 'git version' | sed 's/git version //'
register: git_version
- name: set dummy git config
shell: git config --global user.email "noreply@example.com"; git config --global user.name "Ansible Test Runner"
- name: create repo_dir
file: path={{repo_dir}} state=directory
#
# Test repo=https://github.com/...
#
- name: initial checkout
git: repo={{ repo_format1 }} dest={{ checkout_dir }}
register: git_result
- name: verify information about the initial clone
assert:
that:
- "'before' in git_result"
- "'after' in git_result"
- "not git_result.before"
- "git_result.changed"
- name: repeated checkout
git: repo={{ repo_format1 }} dest={{ checkout_dir }}
register: git_result2
- name: check for tags
stat: path={{ checkout_dir }}/.git/refs/tags
register: tags
- name: check for HEAD
stat: path={{ checkout_dir }}/.git/HEAD
register: head
- name: assert presence of tags/trunk/branches
assert:
that:
- "tags.stat.isdir"
- "head.stat.isreg"
- name: verify on a reclone things are marked unchanged
assert:
that:
- "not git_result2.changed"
#
# Test repo=git@github.com:/...
# Requires variable: github_ssh_private_key
#
- name: clear checkout_dir
file: state=absent path={{ checkout_dir }}
- name: remove known_host files
file: state=absent path={{ item }}
with_items: "{{known_host_files}}"
- name: checkout ssh://git@github.com repo without accept_hostkey (expected fail)
git: repo={{ repo_format2 }} dest={{ checkout_dir }}
register: git_result
ignore_errors: true
- assert:
that:
- 'git_result.failed'
- 'git_result.msg == "github.com has an unknown hostkey. Set accept_hostkey to True or manually add the hostkey prior to running the git module"'
- name: checkout git@github.com repo with accept_hostkey (expected pass)
git:
repo: '{{ repo_format2 }}'
dest: '{{ checkout_dir }}'
accept_hostkey: true
key_file: '{{ github_ssh_private_key }}'
register: git_result
when: github_ssh_private_key is defined
- assert:
that:
- 'git_result.changed'
when: not git_result|skipped
#
# Test repo=ssh://git@github.com/...
# Requires variable: github_ssh_private_key
#
- name: clear checkout_dir
file: state=absent path={{ checkout_dir }}
- name: checkout ssh://git@github.com repo with accept_hostkey (expected pass)
git:
repo: '{{ repo_format3 }}'
dest: '{{ checkout_dir }}'
version: 'master'
accept_hostkey: false # should already have been accepted
key_file: '{{ github_ssh_private_key }}'
register: git_result
when: github_ssh_private_key is defined
- assert:
that:
- 'git_result.changed'
when: not git_result|skipped
# Test a non-updating repo query with no destination specified
- name: get info on a repo without updating and with no destination specified
git:
repo: '{{ repo_format1 }}'
update: no
clone: no
accept_hostkey: yes
register: git_result
- assert:
that:
- 'git_result.changed'
# Test that a specific revision can be checked out
- name: clear checkout_dir
file: state=absent path={{ checkout_dir }}
- name: clone to specific revision
git:
repo: "{{ repo_format1 }}"
dest: "{{ checkout_dir }}"
version: df4612ba925fbc1b3c51cbb006f51a0443bd2ce9
- name: check HEAD after clone to revision
command: git rev-parse HEAD chdir="{{ checkout_dir }}"
register: git_result
- assert:
that:
- 'git_result.stdout == "df4612ba925fbc1b3c51cbb006f51a0443bd2ce9"'
- name: update to specific revision
git:
repo: "{{ repo_format1 }}"
dest: "{{ checkout_dir }}"
version: 4e739a34719654db7b04896966e2354e1256ea5d
register: git_result
- assert:
that:
- 'git_result.changed'
- name: check HEAD after update to revision
command: git rev-parse HEAD chdir="{{ checkout_dir }}"
register: git_result
- assert:
that:
- 'git_result.stdout == "4e739a34719654db7b04896966e2354e1256ea5d"'
# Test a revision not available under refs/heads/ or refs/tags/
- name: attempt to get unavailable revision
git:
repo: "{{ repo_format1 }}"
dest: "{{ checkout_dir }}"
version: 2cfde3668b8bb10fbe2b9d5cec486025ad8cc51b
ignore_errors: true
register: git_result
- assert:
that:
- 'git_result.failed'
# Same as the previous test, but this time we specify which ref
# contains the SHA1
- name: update to revision by specifying the refspec
git:
repo: https://github.com/ansible/ansible-examples.git
dest: '{{ checkout_dir }}'
version: 2cfde3668b8bb10fbe2b9d5cec486025ad8cc51b
refspec: refs/pull/7/merge
- name: check HEAD after update with refspec
command: git rev-parse HEAD chdir="{{ checkout_dir }}"
register: git_result
- assert:
that:
- 'git_result.stdout == "2cfde3668b8bb10fbe2b9d5cec486025ad8cc51b"'
# try out combination of refspec and depth
- name: clear checkout_dir
file: state=absent path={{ checkout_dir }}
- name: update to revision by specifying the refspec with depth=1
git:
repo: https://github.com/ansible/ansible-examples.git
dest: '{{ checkout_dir }}'
version: 2cfde3668b8bb10fbe2b9d5cec486025ad8cc51b
refspec: refs/pull/7/merge
depth: 1
- name: check HEAD after update with refspec
command: git rev-parse HEAD chdir="{{ checkout_dir }}"
register: git_result
- assert:
that:
- 'git_result.stdout == "2cfde3668b8bb10fbe2b9d5cec486025ad8cc51b"'
- name: try to access other commit
shell: git checkout 0ce1096
register: checkout_shallow
failed_when: False
args:
chdir: '{{ checkout_dir }}'
- name: make sure the old commit was not fetched
assert:
that:
- checkout_shallow.rc == 1
- checkout_shallow|failed
when: git_version.stdout | version_compare("{{git_version_supporting_depth}}", '>=')
- name: clear checkout_dir
file: state=absent path={{ checkout_dir }}
- name: clone to revision by specifying the refspec
git:
repo: https://github.com/ansible/ansible-examples.git
dest: '{{ checkout_dir }}'
version: 2cfde3668b8bb10fbe2b9d5cec486025ad8cc51b
refspec: refs/pull/7/merge
- name: check HEAD after update with refspec
command: git rev-parse HEAD chdir="{{ checkout_dir }}"
register: git_result
- assert:
that:
- 'git_result.stdout == "2cfde3668b8bb10fbe2b9d5cec486025ad8cc51b"'
#
# Submodule tests
#
# Repository A with submodules defined (repo_submodules)
# .gitmodules file points to Repository I
# Repository B forked from A that has newer commits (repo_submodules_newer)
# .gitmodules file points to Repository II instead of I
# .gitmodules file also points to Repository III
# Repository I for submodule1 (repo_submodule1)
# Has 1 file checked in
# Repository II forked from I that has newer commits (repo_submodule1_newer)
# Has 2 files checked in
# Repository III for a second submodule (repo_submodule2)
# Has 1 file checked in
- name: clear checkout_dir
file: state=absent path={{ checkout_dir }}
- name: Test that clone without recursive does not retrieve submodules
git:
repo: '{{ repo_submodules }}'
dest: '{{ checkout_dir }}'
recursive: no
- command: 'ls -1a {{ checkout_dir }}/submodule1'
register: submodule1
- assert:
that: '{{ submodule1.stdout_lines|length }} == 2'
- name: clear checkout_dir
file: state=absent path={{ checkout_dir }}
- name: Test that clone with recursive retrieves submodules
git:
repo: '{{ repo_submodules }}'
dest: '{{ checkout_dir }}'
recursive: yes
- command: 'ls -1a {{ checkout_dir }}/submodule1'
register: submodule1
- assert:
that: '{{ submodule1.stdout_lines|length }} == 4'
- name: Copy the checkout so we can run several different tests on it
command: 'cp -pr {{ checkout_dir }} {{ checkout_dir }}.bak'
- name: Test that update without recursive does not change submodules
command: 'git config --replace-all remote.origin.url {{ repo_submodules_newer }}'
args:
chdir: '{{ checkout_dir }}'
- git:
repo: '{{ repo_submodules_newer }}'
dest: '{{ checkout_dir }}'
recursive: no
update: yes
track_submodules: yes
- command: 'ls -1a {{ checkout_dir }}/submodule1'
register: submodule1
- stat:
path: '{{ checkout_dir }}/submodule2'
register: submodule2
- command: 'ls -1a {{ checkout_dir }}/submodule2'
register: submodule2
- assert:
that: '{{ submodule1.stdout_lines|length }} == 4'
- assert:
that: '{{ submodule2.stdout_lines|length }} == 2'
- name: Restore checkout to prior state
file: state=absent path={{ checkout_dir }}
- command: 'cp -pr {{ checkout_dir }}.bak {{ checkout_dir }}'
- name: Test that update with recursive updated existing submodules
command: 'git config --replace-all remote.origin.url {{ repo_submodules_newer }}'
args:
chdir: '{{ checkout_dir }}'
- git:
repo: '{{ repo_submodules_newer }}'
dest: '{{ checkout_dir }}'
update: yes
recursive: yes
track_submodules: yes
- command: 'ls -1a {{ checkout_dir }}/submodule1'
register: submodule1
- assert:
that: '{{ submodule1.stdout_lines|length }} == 5'
- name: Test that update with recursive found new submodules
command: 'ls -1a {{ checkout_dir }}/submodule2'
register: submodule2
- assert:
that: '{{ submodule2.stdout_lines|length }} == 4'
# test change of repo url
# see https://github.com/ansible/ansible-modules-core/pull/721
- name: clear checkout_dir
file: state=absent path={{ checkout_dir }}
- name: Clone example git repo
git:
repo: '{{ repo_update_url_1 }}'
dest: '{{ checkout_dir }}'
- name: Clone repo with changed url to the same place
git:
repo: '{{ repo_update_url_2 }}'
dest: '{{ checkout_dir }}'
register: clone2
- assert:
that: "clone2|success"
- name: check url updated
shell: git remote show origin | grep Fetch
register: remote_url
args:
chdir: '{{ checkout_dir }}'
environment:
LC_ALL: C
- assert:
that:
- "'git-test-new' in remote_url.stdout"
- "'git-test-old' not in remote_url.stdout"
- name: check for new content in git-test-new
stat: path={{ checkout_dir }}/newfilename
register: repo_content
- name: assert presence of new file in repo (i.e. working copy updated)
assert:
that: "repo_content.stat.exists"
# Test that checkout by branch works when the branch is not in our current repo but the sha is
- name: clear checkout_dir
file: state=absent path={{ checkout_dir }}
- name: Clone example git repo that we're going to modify
git:
repo: '{{ repo_update_url_1 }}'
dest: '{{ checkout_dir }}/repo'
- name: Clone the repo again - this is what we test
git:
repo: '{{ checkout_dir }}/repo'
dest: '{{ checkout_dir }}/checkout'
- name: Add a branch to the repo
command: git branch new-branch
args:
chdir: '{{ checkout_dir }}/repo'
- name: Checkout the new branch in the checkout
git:
repo: '{{ checkout_dir}}/repo'
version: 'new-branch'
dest: '{{ checkout_dir }}/checkout'
# Test the depth option and fetching revisions that were ignored first
- name: clear checkout_dir
file: state=absent path={{ checkout_dir }}
- name: Clone example git repo with depth=1
git:
repo: '{{ repo_depth_url }}'
dest: '{{ checkout_dir }}'
depth: 1
- name: try to access earlier commit
shell: git checkout 79624b4
register: checkout_early
failed_when: False
args:
chdir: '{{ checkout_dir }}'
- name: make sure the old commit was not fetched
assert:
that: checkout_early.rc == 1
when: git_version.stdout | version_compare("{{git_version_supporting_depth}}", '>=')
# tests https://github.com/ansible/ansible/issues/14954
- name: fetch repo again with depth=1
git:
repo: '{{ repo_depth_url }}'
dest: '{{ checkout_dir }}'
depth: 1
register: checkout2
- assert:
that: "not checkout2|changed"
when: git_version.stdout | version_compare("{{git_version_supporting_depth}}", '>=')
- name: again try to access earlier commit
shell: git checkout 79624b4
register: checkout_early
failed_when: False
args:
chdir: '{{ checkout_dir }}'
- name: again make sure the old commit was not fetched
assert:
that: checkout_early.rc == 1
when: git_version.stdout | version_compare("{{git_version_supporting_depth}}", '>=')
# make sure we are still able to fetch other versions
- name: Clone same repo with older version
git:
repo: '{{ repo_depth_url }}'
dest: '{{ checkout_dir }}'
depth: 1
version: earlytag
register: cloneold
- assert:
that: "cloneold|success"
- name: try to access earlier commit
shell: git checkout 79624b4
args:
chdir: '{{ checkout_dir }}'
# test for https://github.com/ansible/ansible-modules-core/issues/527
# clone a repo, add a tag to the same commit and try to checkout the new commit
- name: clear checkout_dir
file: state=absent path={{ checkout_dir }}
- name: checkout example repo
git: repo={{ repo_format1 }} dest={{ checkout_dir }}
- name: clone example repo locally
git: repo={{ checkout_dir }} dest={{checkout_dir}}.copy
- name: get tags of head
command: git tag --contains chdir="{{ checkout_dir }}.copy"
register: listoftags
- name: make sure the tag does not yet exist
assert:
that:
- "'newtag' not in listoftags.stdout_lines"
- name: add tag in orig repo
command: git tag newtag chdir="{{ checkout_dir }}"
- name: update copy with new tag
git: repo={{ checkout_dir }} dest={{checkout_dir}}.copy version=newtag
register: update_new_tag
- name: get tags of new head
command: git tag --contains chdir="{{ checkout_dir }}.copy"
register: listoftags
- name: check new head
assert:
that:
- not update_new_tag|changed
- "'newtag' in listoftags.stdout_lines"
- name: clear checkout_dir
file: state=absent path={{ checkout_dir }}
# Test for https://github.com/ansible/ansible-modules-core/issues/3456
# clone a repo with depth and version specified
- name: clone repo with both version and depth specified
git:
repo: '{{ repo_depth_url }}'
dest: '{{ checkout_dir }}'
depth: 1
version: master
- name: run a second time (now fetch, not clone)
git:
repo: '{{ repo_depth_url }}'
dest: '{{ checkout_dir }}'
depth: 1
version: master
register: git_fetch
- name: ensure the fetch succeeded
assert:
that: git_fetch|success
- name: clear checkout_dir
file: state=absent path={{ checkout_dir }}
- name: clone repo with both version and depth specified
git:
repo: '{{ repo_depth_url }}'
dest: '{{ checkout_dir }}'
depth: 1
version: master
- name: switch to older branch with depth=1 (uses fetch)
git:
repo: '{{ repo_depth_url }}'
dest: '{{ checkout_dir }}'
depth: 1
version: earlybranch
register: git_fetch
- name: ensure the fetch succeeded
assert:
that: git_fetch|success
- name: clear checkout_dir
file: state=absent path={{ checkout_dir }}
# test for https://github.com/ansible/ansible-modules-core/issues/3782
# make sure shallow fetch works when no version is specified
- name: prepare old git repo
shell: git init; echo "1" > a; git add a; git commit -m "1"
args:
chdir: "{{repo_dir}}"
- name: checkout old repo
git:
repo: '{{ repo_dir }}'
dest: '{{ checkout_dir }}'
depth: 1
- name: "update repo"
shell: echo "2" > a; git commit -a -m "2"
args:
chdir: "{{repo_dir}}"
- name: fetch updated repo
git:
repo: '{{ repo_dir }}'
dest: '{{ checkout_dir }}'
depth: 1
register: git_fetch
ignore_errors: yes
- name: read file
shell: cat {{ checkout_dir }}/a
- name: check update arrived
assert:
that:
- "{{ lookup('file', checkout_dir+'/a' )}} == 2"
- git_fetch|changed
- name: clear checkout_dir
file: state=absent path={{ checkout_dir }}

View file

@ -0,0 +1,3 @@
dependencies:
- prepare_tests

View file

@ -0,0 +1,78 @@
# test code for the hg module
# (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: set where to extract the repo
set_fact: checkout_dir={{ output_dir }}/epdb
- name: set what repo to use
set_fact: repo=https://bitbucket.org/rpathsync/epdb
- name: clean out the output_dir
shell: rm -rf {{ output_dir }}/*
- name: verify that mercurial is installed so this test can continue
shell: which hg
- name: initial checkout
hg: repo={{ repo }} dest={{ checkout_dir }}
register: hg_result
- debug: var=hg_result
#- shell: ls ~/ansible_testing/epdb
- shell: ls {{ checkout_dir }}
- name: verify information about the initial clone
assert:
that:
- "'before' in hg_result"
- "'after' in hg_result"
- "not hg_result.before"
- "hg_result.changed"
- name: repeated checkout
hg: repo={{ repo }} dest={{ checkout_dir }}
register: hg_result2
- debug: var=hg_result2
- name: check for tags
stat: path={{ checkout_dir }}/.hgtags
register: tags
- name: check for remotes
stat: path={{ checkout_dir }}/.hg/branch
register: branches
- debug: var=tags
- debug: var=branches
- name: assert presence of tags/trunk/branches
assert:
that:
- "tags.stat.isreg"
- "branches.stat.isreg"
- name: verify on a reclone things are marked unchanged
assert:
that:
- "not hg_result2.changed"

View file

@ -0,0 +1,3 @@
dependencies:
- prepare_tests

View file

@ -0,0 +1,23 @@
# test code
# (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: this will not stop the playbook
shell: /bin/false
register: failed
ignore_errors: True

View file

@ -0,0 +1,3 @@
---
testing: 1
base_dir: defaults

Some files were not shown because too many files have changed in this diff Show more