Add the start of an integration test structure using Ansible playbooks, also added an assert action plugin to make writing those easier.
This commit is contained in:
parent
6c3b4570d7
commit
c91ceddfac
20 changed files with 290 additions and 2 deletions
|
@ -17,7 +17,7 @@ Major features/changes:
|
|||
* play_hosts is a new magic variable to provide a list of hosts in scope for the current play.
|
||||
* ec2 module now accepts 'exact_count' and 'count_tag' as a way to enforce a running number of nodes by tags.
|
||||
* all ec2 modules that work with Eucalyptus also now support a 'validate_certs' option, which can be set to 'off' for installations using self-signed certs.
|
||||
|
||||
* Start of new integration test infrastructure (WIP, more details TBD)
|
||||
|
||||
New modules:
|
||||
|
||||
|
@ -31,7 +31,7 @@ New modules:
|
|||
* cloud: rax_queue
|
||||
* messaging: rabbitmq_policy
|
||||
* system: at
|
||||
|
||||
* utilities: assert
|
||||
|
||||
Misc:
|
||||
|
||||
|
|
56
lib/ansible/runner/action_plugins/assert.py
Normal file
56
lib/ansible/runner/action_plugins/assert.py
Normal file
|
@ -0,0 +1,56 @@
|
|||
# Copyright 2012, Dag Wieers <dag@wieers.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/>.
|
||||
|
||||
import ansible
|
||||
|
||||
from ansible import utils
|
||||
from ansible.runner.return_data import ReturnData
|
||||
|
||||
class ActionModule(object):
|
||||
''' Fail with custom message '''
|
||||
|
||||
TRANSFERS_FILES = False
|
||||
|
||||
def __init__(self, runner):
|
||||
self.runner = runner
|
||||
|
||||
def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs):
|
||||
|
||||
# note: the fail module does not need to pay attention to check mode
|
||||
# it always runs.
|
||||
|
||||
args = {}
|
||||
if complex_args:
|
||||
args.update(complex_args)
|
||||
args.update(utils.parse_kv(module_args))
|
||||
|
||||
msg = ''
|
||||
|
||||
if 'msg' in args:
|
||||
msg = args['msg']
|
||||
|
||||
if not 'that' in args:
|
||||
raise errors.AnsibleError('conditional required in "that" string')
|
||||
|
||||
result = utils.check_conditional(args['that'], self.runner.basedir, inject, fail_on_undefined=True)
|
||||
|
||||
if not result:
|
||||
result = dict(failed=True, assertion=args['that'], evaluated_to=result)
|
||||
else:
|
||||
result = dict(msg='ok', assertion=args['that'], evaluated_to=result)
|
||||
|
||||
return ReturnData(conn=conn, result=result)
|
39
library/utilities/assert
Normal file
39
library/utilities/assert
Normal file
|
@ -0,0 +1,39 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2012 Dag Wieers <dag@wieers.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/>.
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: assert
|
||||
short_description: Fail with custom message
|
||||
description:
|
||||
- This module asserts that a given expression is true and can be a simpler alternative to the 'fail' module in some cases.
|
||||
version_added: "1.5"
|
||||
options:
|
||||
that:
|
||||
description:
|
||||
- "A string expression of the same form that can be passed to the 'when' statement"
|
||||
required: true
|
||||
author: Michael DeHaan
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
- assert: ansible_os_family != "RedHat"
|
||||
- assert: "'foo' in some_command_result.stdout"
|
||||
'''
|
7
test/README.md
Normal file
7
test/README.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
Legacy tests
|
||||
============
|
||||
|
||||
These tests are active but are being refactored.
|
||||
|
||||
See 'new_tests' directory for what will soon replace them.
|
||||
|
22
tests_new/README.md
Normal file
22
tests_new/README.md
Normal file
|
@ -0,0 +1,22 @@
|
|||
Ansible Test System
|
||||
===================
|
||||
|
||||
Folders
|
||||
|
||||
unit
|
||||
----
|
||||
|
||||
New and approved unit tests, that test small pieces of code not suited for the integration test layer
|
||||
|
||||
Not yet ready for pull requests. Opening this up soon.
|
||||
|
||||
integration
|
||||
-----------
|
||||
|
||||
New integration test layer, constructed using playbooks.
|
||||
|
||||
Not yet ready for pull requests. Opening this up soon.
|
||||
|
||||
Some tests may require cloud credentials, others will not, and destructive tests will be seperated from non-destructive so a subset
|
||||
can be run on development machines.
|
||||
|
13
tests_new/integration/README.md
Normal file
13
tests_new/integration/README.md
Normal file
|
@ -0,0 +1,13 @@
|
|||
Integration tests
|
||||
=================
|
||||
|
||||
The ansible integration system.
|
||||
|
||||
Tests for playbooks, by playbooks.
|
||||
|
||||
Some tests may require cloud credentials.
|
||||
|
||||
Instructions
|
||||
============
|
||||
|
||||
Pending
|
6
tests_new/integration/all.yml
Normal file
6
tests_new/integration/all.yml
Normal file
|
@ -0,0 +1,6 @@
|
|||
- include: test_setup.yml
|
||||
- include: non_destructive.yml
|
||||
- include: destructive.yml
|
||||
- include: rackspace.yml
|
||||
- include: amazon.yml
|
||||
|
4
tests_new/integration/amazon.yml
Normal file
4
tests_new/integration/amazon.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
- hosts: testhost
|
||||
gather_facts: True
|
||||
roles: []
|
||||
|
4
tests_new/integration/destructive.yml
Normal file
4
tests_new/integration/destructive.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
- hosts: testhost
|
||||
gather_facts: True
|
||||
roles: []
|
||||
|
2
tests_new/integration/inventory
Normal file
2
tests_new/integration/inventory
Normal file
|
@ -0,0 +1,2 @@
|
|||
[local]
|
||||
testhost ansible_ssh_host=127.0.0.1 ansible_connection=local
|
5
tests_new/integration/non_destructive.yml
Normal file
5
tests_new/integration/non_destructive.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
- hosts: testhost
|
||||
gather_facts: True
|
||||
roles:
|
||||
- { role: test_copy, tags: test_copy }
|
||||
|
4
tests_new/integration/rackspace.yml
Normal file
4
tests_new/integration/rackspace.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
- hosts: testhost
|
||||
gather_facts: True
|
||||
roles: []
|
||||
|
26
tests_new/integration/roles/prepare_tests/tasks/main.yml
Normal file
26
tests_new/integration/roles/prepare_tests/tasks/main.yml
Normal file
|
@ -0,0 +1,26 @@
|
|||
# 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: clean out the test directory
|
||||
file: name={{output_dir|mandatory}} state=absent
|
||||
|
||||
- name: create the test directory
|
||||
file: name={{output_dir}} state=directory
|
||||
|
||||
|
1
tests_new/integration/roles/test_copy/files/foo.txt
Normal file
1
tests_new/integration/roles/test_copy/files/foo.txt
Normal file
|
@ -0,0 +1 @@
|
|||
foo.txt
|
1
tests_new/integration/roles/test_copy/foo.txt
Normal file
1
tests_new/integration/roles/test_copy/foo.txt
Normal file
|
@ -0,0 +1 @@
|
|||
foo.txt
|
3
tests_new/integration/roles/test_copy/meta/main.yml
Normal file
3
tests_new/integration/roles/test_copy/meta/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
dependencies:
|
||||
- prepare_tests
|
||||
|
84
tests_new/integration/roles/test_copy/tasks/main.yml
Normal file
84
tests_new/integration/roles/test_copy/tasks/main.yml
Normal file
|
@ -0,0 +1,84 @@
|
|||
# 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/>.
|
||||
|
||||
# FIXME: replace all fail_when's with asserts
|
||||
|
||||
- set_fact: output_file={{output_dir}}/foo.txt
|
||||
|
||||
- name: initiate a basic copy
|
||||
copy: src=foo.txt dest={{output_file}}
|
||||
register: copy_result
|
||||
|
||||
- assert: { that: "'changed' in copy_result" }
|
||||
- assert: { that: "'dest' in copy_result" }
|
||||
- assert: { that: "'group' in copy_result" }
|
||||
- assert: { that: "'gid' in copy_result" }
|
||||
- assert: { that: "'md5sum' in copy_result" }
|
||||
- assert: { that: "'owner' in copy_result" }
|
||||
- assert: { that: "'size' in copy_result" }
|
||||
- assert: { that: "'src' in copy_result" }
|
||||
- assert: { that: "'state' in copy_result" }
|
||||
- assert: { that: "'uid' in copy_result" }
|
||||
|
||||
|
||||
- name: verify that the file was marked as changed
|
||||
assert: { that: "copy_result.changed == true" }
|
||||
|
||||
- name: verify that the file md5sum is correct
|
||||
assert: { that: "copy_result.md5sum == 'c47397529fe81ab62ba3f85e9f4c71f2'" }
|
||||
|
||||
- name: check the stat results of the file
|
||||
stat: path={{output_file}}
|
||||
register: stat_results
|
||||
|
||||
- debug: var=stat_results
|
||||
|
||||
- assert: { that: "stat_results.stat.exists == true" }
|
||||
- assert: { that: "stat_results.stat.isblk == false" }
|
||||
- assert: { that: "stat_results.stat.isfifo == false" }
|
||||
- assert: { that: "stat_results.stat.isreg == true" }
|
||||
- assert: { that: "stat_results.stat.issock == false" }
|
||||
- assert: { that: "stat_results.stat.md5 == 'c47397529fe81ab62ba3f85e9f4c71f2'" }
|
||||
|
||||
- name: overwrite the file via same means
|
||||
copy: src=foo.txt dest={{output_file}}
|
||||
register: copy_result2
|
||||
|
||||
- name: verify the copy was marked unchanged
|
||||
assert: { that: "not copy_result2|changed" }
|
||||
|
||||
- name: overwrite the file using the content system
|
||||
copy: content="modified" dest={{output_file}}
|
||||
register: copy_result3
|
||||
|
||||
- name: verify the copy result was marked changed
|
||||
assert: { that: "copy_result3|changed" }
|
||||
|
||||
- name: overwrite the file again using the content system
|
||||
copy: content="modified" dest={{output_file}}
|
||||
register: copy_result4
|
||||
|
||||
- name: verify the copy result was marked unchanged
|
||||
assert: { that: "not copy_result4|changed" }
|
||||
|
||||
# TODO: test recursive copy
|
||||
# TODO: test copy where destination is a directory like {{output_dir}}/
|
||||
# TODO: test that copy fails if the path does not exist
|
||||
# TODO: ...
|
||||
|
||||
|
1
tests_new/integration/test.sh
Normal file
1
tests_new/integration/test.sh
Normal file
|
@ -0,0 +1 @@
|
|||
ansible-playbook non_destructive.yml -i inventory -e output_dir=~/ansible_testing -v
|
5
tests_new/integration/test_setup.yml
Normal file
5
tests_new/integration/test_setup.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
- hosts: testhost
|
||||
gather_facts: False
|
||||
roles:
|
||||
- test_setup
|
||||
|
5
tests_new/units/README.md
Normal file
5
tests_new/units/README.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
Unit tests
|
||||
==========
|
||||
|
||||
Tests at code level. Should be concise and to the point, and organized by subject.
|
||||
|
Loading…
Reference in a new issue